|
本帖最后由 chyj4747 于 2013-3-6 02:45 编辑
此帖仅在疑难区投影一个月,错过的孩子们请到综合区翻找……
修正:错过的孩子们应该不会知道这个帖。。
【本教程附带演示在38楼】
庆祝一下吧~ 本教程前言只有一句废话:
本教程使用YDWE 1.20 中的动作作为T教材。
你确定这里是正文?:
风和日丽的某天,一块空荡荡的荒地上建起了一座哈希小区(禁止吐槽这设定!不然我跟你急!)。哈希小区不是一般的大,放眼望去成千上万的公寓,每幢公寓的门牌号也是从0到……这房子太高了看不到顶上的门牌号。。
一天,一位骑着白马的……王子?骑白马的不一定是王子,也有可能是大法~ 。。。 总之就是来入住了,向哈希中介申请了第1幢1号房,进门一看。。。“!!这不坑人嘛。。这两平米的房间怎么住啊!!”然后就被中介踹了进去……
第二天,来了一个扛着金袋的……小偷?强盗?错了!是农民。。。这位农民大伯也想住第1幢1号房,中介查了一下记录:“非常抱歉,那间房已经住了一个老头和一匹老马。您可以选择别的房间,都是空着的。”农民大伯怒了:“你们这种城里人,就知道欺负乡下人!”中介:“⊙﹏⊙b汗… 那好吧,如果您一定要住那间房我们倒是不介意~”于是大法被踹出了门。。。【默哀三分钟……】
第三天,农民大伯也受不了那两平米大小的房间。。决定搬走……中介说:“不行!你不能走!”大伯:“靠!你们又欺负乡下人!”中介:“……不是。。我们是真没这种单独一个住户退房的服务”这时中介老板来了电话:“算了,别跟自称乡下人一般见识,开个特别J服务给他办退房手续吧”…………于是大伯退了房
第四天,为了解决这种不同住户要住同一间房这种的冲突,哈希中介决定采用住户的身份证号码来分配房间,于是不幸路过的剑圣被塞进了第1幢第xxxxxxxxx号房。。
第五天来了个行李很多的旅人,哈希中介给了他第yyyyyyyyy幢1号房,然后为了不跟别的住户的东西弄混,他的东西全部塞进了同一幢的2号房、3号房、4号房……
……几年后,哈希小区住满了各式各样的住户,有的叫整数,有的叫实数,有的叫字符串,还有的叫句柄(小学每次考“有的…有的…还有的…”句式我都是满分你信不信~)
某一天,哈希小区要整顿第1幢房,于是就将里面的用户全赶了出来……
另一个某一天,哈希小区要整顿所有的房子,于是将全小区的人赶了出来……
你没瞎,这里才是正文!:
如果你坚持看完了上面某龙YY的东西呢,那么恭喜你学会了哈希表几乎所有功能~
现在开始逐条转成T:
风和日丽的某天,一块空荡荡的荒地上建起了一座哈希小区
首先呢,在ctrl+b里新建一个哈希表变量,我惯用的名字是HT(哈希表英文:HashTable,取两个大写字母)。
[trigger]
动作
哈希表 - 创建一个新的哈希表
设置 HT = (最后创建的哈希表)
[/trigger]
于是哈希小区就建好了~
注:除了这个“创建一个新的哈希表”,其它哈希表动作推荐全部使用后缀带[ci]的动作
这里先说明一下,如果平时做图不使用YDWE的智能注入的话,有几个动作需要写自定义代码,其实并不是什么麻烦的事,原版UI连删除点都要自己写RemoveLocation呢~
[trigger]
动作
哈希表 - 在 HT 的主索引 1 子索引 1 中保存单位 大魔法师 0000 <预设>
[/trigger]
就这么简单~ 主索引就是第几幢,子索引就是第几间
中介所查的就是第几幢第几间里有没有住人。
[trigger]
条件
(子索引为 1 的 handle 类数据被保存在主索引为 1 的 HT 中) 等于 TRUE
[/trigger]
这个条件在布尔值里,那个handle呢是句柄,这里简单地记一下就是除了整数、实数、布尔值、字符串以外的所有数据类型都是句柄(比如单位、计时器)
这个条件的作用呢是判断第几幢第几间里是否有人住着~ 如果有就是TRUE,没有就是FALSE
某龙的温馨提示:
不过这里要注意的一点是:这个条件是没法判断句柄数据是否被保存在哈希表里的!!!
或者说,只要判断句柄,这个条件返回的肯定是FALSE这个结果!!!
为什么呢???
这个就是暴雪的问题了(也可能是YDWE的BJ文件有问题)。。。
这个条件开始判断的时候,会先看你要判断哪种类型的数据,是整数?实数?布尔值?字符串?还是字符串?不符合以上的数据类型就判断为FALSE,看完数据类型再去判断在还是不在。
??? “字符串?还是字符串?”
所以说,句柄这个数据根本就不会被判断到,于是判断句柄就只有FALSE……
那么上面这个问题怎么解决呢……
像RemoveLocation那样写J呗~
[trigger]
条件
(HaveSavedHandle( udg_HT, 1, 1 )) 等于 TRUE
[/trigger]
幸好YDWE支持任意地方写自定义代码~
Have:有;
Saved:被保存的;
Handle:句柄
udg_HT:这个就是哈希表变量HT,写入的时候记得加udg_,这个属于J的范畴所以不解释了,记住就好~
第一个1是主索引,第二个1就是子索引
放到原文的环境中:
[trigger]条件:(有没有人住呢( 哈希小区, 第一幢, 第一间 )) 等于 TRUE[/trigger]
“……那好吧,如果您一定要住那间房我们倒是不介意~”于是大法被踹出了门
若将数据存在同一个地方是会冲突的,就像变量那样:
[trigger]设置 A = 1
设置 A = 2[/trigger]
那么A就是2而不是1
也就是说,如果一开始在HT的主索引1子索引1里存了大法,之后又在同一个地方存了农民的话,那么之前存的大法就没了……
我很好奇为什么果子不把这个动作加进去。。
单独删除某哈希表某主索引某子索引里的数据的时候就要用到J了
[trigger]
动作
自定义代码: call RemoveSavedInteger( udg_HT, 1, 1 )
自定义代码: call RemoveSavedReal( udg_HT, 1, 1 )
自定义代码: call RemoveSavedBoolean( udg_HT, 1, 1 )
自定义代码: call RemoveSavedString( udg_HT, 1, 1 )
自定义代码: call RemoveSavedHandle( udg_HT, 1, 1 )
[/trigger]
神马!你看晕了……别学了,直接按后退键吧~
咳咳。。
仔细一看格式几乎一样呢~ 非常好记~
call:调用(某个函数,或者说动作)
Remove:移除、删除
Saved:被储存的、已储存的
Integer:整数 | Real:实数 | Boolean:布尔值 | String:字符串 | Handle:句柄
后面的参数与之前那个条件顺序相同:哈希表变量名(记得加 udg_ 前缀),主索引,子索引
注:除了整数、实数、布尔、字符以外,所有的数据都用Handle(句柄)来删除
为了解决这种不同住户要住同一间房这种的冲突,哈希中介决定采用住户的身份证号码来分配房间
嘛。。这里需要知道的一点就是,所有的句柄都有个类似身份证的数字,每个句柄的这个数字跟身份证一样是互不相同的,所以可以用这个数字来做主索引或子索引就可以避免冲突的产生~
同时这也是哈希表的关键,比如可以利用这个不同特征给单位A绑计时器,之后可以从单位A获取绑定的计时器,这样读取的计时器绝对是给单位A用的而不是给别的单位
然后就有个用不用YD的智能注入功能的分支了:
获得某个句柄的身份证号码要用下面这个动作:
[trigger]
动作
设置 Int = (获取 大魔法师 0000 <预设> 的整数地址)
[/trigger]
Int是整数变量,身份证号码你们不可能见过小数的吧……谁见过我核弹谁!!!
在YD的T动作里,获取不同类型的句柄的句柄值(身份证号码)被分成了很多不同的动作,上面这个T里用的是“获取单位的整数地址”,如果是计时器,那么就要用“获取计时器的整数地址”
现在来讲讲分支何在~
YDWE对这个动作做过处理的,也就是实际上这个动作是YDWE专有动作,需要用智能注入功能才能使用
那么从来不用智能注入或怕智能注入给地图增加不必要的大小的同学呢就必须自己写J了~
放心,这次总共就一句J~~~
[trigger]
动作
设置 Unit = 大魔法师 0000 <预设>
自定义代码: set udg_Int = GetHandleId( udg_Unit )
[/trigger]
Get:获取
Handle:句柄
Id:值(身份证ID神马的就类似这个意思~)
括号里面是上面那个Unit变量,前缀加udg_
于是不幸路过的剑圣被塞进了第1幢xxxxxxxxx号房
稍微修改下。。剑圣换大法吧……我懒得换单位。。
[trigger]
动作
设置 Unit = 大魔法师 0000 <预设>
注释 ------ 用智能注入 ------
设置 Int = (获取 大魔法师 0000 <预设> 的整数地址)
注释 ------ 不用智能注入 ------
自定义代码: set udg_Int = GetHandleId( udg_Unit )
哈希表 - 在 HT 的主索引 1 子索引 Int 中保存单位 Unit
[/trigger]
于是那个子索引就是这位大法的身份证Id号了~
即便还有另一个大法,根据法律每个公民必须拥有不同的身份证号码,所以获得的句柄值跟第一个大法是不同的~ 于是就不会冲突~ 来多少人都可以入住第1栋公寓
情景化说明:
比如第一个大法的句柄值(身份证号码)是12345
那么第二个大法的句柄值就绝对不可能是12345,这里假设是67890好了
两个大法都入住第一幢,由于是用句柄值作为门牌号,所以第一个大法住12345号房,第二个住67890号房,于是没有冲突
第五天来了个行李很多的旅人,哈希中介给了他第8xxxxxxxx幢1号房,然后为了不跟别的住户的东西弄混,他的东西全部塞进了同一幢的2号房、3号房、4号房……
比如要给一个单位绑定很多数据的时候就可以用这个单位的句柄值作为主索引,数据全部存在子索引,这样由于不存在别的相同的句柄值,给别人绑定的数据肯定不会与这个单位的冲突~
[trigger]某龙的哈希教程
事件
单位 - 大魔法师 0000 <预设> 接受伤害
条件
动作
设置 Unit = (触发单位)
自定义代码: set udg_Int = GetHandleId( udg_Unit )
哈希表 - 在 HT 的主索引 Int 子索引 1 中保存单位 (伤害来源)
哈希表 - 在 HT 的主索引 Int 子索引 2 中保存实数 (单位所受伤害)
[/trigger]
某一天,哈希小区要整顿第1幢房,于是就将里面的用户全赶了出来……
另一个某一天,哈希小区要整顿所有的房子,于是将全小区的人赶了出来……
这两个一起吧~
[trigger]未命名触发器 001
事件
单位 - 大魔法师 0000 <预设> 接受伤害
条件
动作
设置 Unit = (触发单位)
自定义代码: set udg_Int = GetHandleId( udg_Unit )
哈希表 - 在 HT 的主索引 Int 子索引 1 中保存单位 (伤害来源)
哈希表 - 在 HT 的主索引 Int 子索引 2 中保存实数 (单位所受伤害)
哈希表 - 清空 HT 中位于主索引 Int 之内的所有数据
哈希表 - 清空 HT
[/trigger]
运行了倒数第二句动作后,在主索引Int里储存的全部数据全都被删除了,也就是之前保存的伤害来源和所受伤害全都从哈希表里清除了
运行了最后一句动作后不管你在HT里储存了多少数据,不管这些数据是存在哪些索引下的,通通删除
某龙的保存点:
整理下到目前为止学过的内容吧:
1. 创建哈希表
2. 储存数据
3. 判断是否储存数据
4. 移除某个子索引下的数据
5. 获取句柄值
6. 以句柄作为子索引
7. 以句柄作为主索引 (一般绑定用的是这个~)
8-9. 清除某个主索引下的所有数据;清除某个哈希表内的所有数据
如果你坚持看完了上面某龙YY的东西呢,那么恭喜你学会了哈希表几乎所有功能~
知道为什么是几乎所有吗~
因为你们还不会读取数据。。。像之前那样存了伤害来源和所受伤害后要如何取出来用呢……
[trigger]未命名触发器 001
事件
单位 - 大魔法师 0000 <预设> 接受伤害
条件
动作
设置 Unit = (触发单位)
自定义代码: set udg_Int = GetHandleId( udg_Unit )
哈希表 - 在 HT 的主索引 Int 子索引 1 中保存单位 (伤害来源)
哈希表 - 在 HT 的主索引 Int 子索引 2 中保存实数 (单位所受伤害)
设置 Unit = (在 HT 的主索引 Int 子索引 1 内提取单位)
设置 Real = (在 HT 的主索引 Int 子索引 2 内提取实数)
哈希表 - 清空 HT 中位于主索引 Int 之内的所有数据
[/trigger]
做了如上的处理后,Unit就是伤害来源了,而Real就是所受伤害值~
千万记得在用完之后要排泄哦~~~
所谓哈希表的排泄就是清除里面的数据,一般是直接清除某个主索引下的所有值~
还有一件事~
将句柄值作为索引的时候还可以这样写:
[trigger]未命名触发器 001
事件
单位 - 大魔法师 0000 <预设> 接受伤害
条件
动作
设置 Unit = (触发单位)
-------- 不用智能注入的同学: --------
哈希表 - 在 HT 的主索引 (GetHandleId( udg_Unit )) 子索引 1 中保存单位 (伤害来源)
-------- 用智能注入或不想写J的同学: --------
哈希表 - 在 HT 的主索引 (获取 Unit 的整数地址) 子索引 2 中保存实数 (单位所受伤害)
[/trigger]
不过这种写法在需要多次获得同一个句柄值的时候完全不推荐,因为获取句柄值的运行效率比从变量读取数据要慢
唔。。这个东东……对于T来说似乎没什么用嘛……
嘛。。做个简单的东西给你们看下好了,虽然不用哈希表一样实现。。
[trigger]某龙的哈希教程1
事件
玩家 - 玩家1(红色) 按下Esc键(跳过电影)
条件
动作
设置 Unit = (新建 玩家1(红色) 的 大魔法师 在(0.00,0.00),面向角度:0.00 度)
设置 Eff = (新建特效 Abilities\Spells\Other\TalkToMe\TalkToMe.mdl 并绑定到 Unit 的 head 附加点上)
设置 Timer = (新建的计时器)
设置 Int = (GetHandleId( udg_Timer ))
哈希表 - 在 HT 的主索引 Int 子索引 1 中保存单位 Unit
哈希表 - 在 HT 的主索引 Int 子索引 2 中保存特效 Eff
计时器 - 启动 Timer,应用计时方式: 一次性,计时周期为 3.00 秒
触发器 - 为 某龙的哈希教程2 添加事件: (时间 - Timer 到期)
[/trigger]
[trigger] 某龙的哈希教程2
事件
条件
动作
设置 Timer = (到期的计时器)
设置 Int = (获取 Timer 的整数地址)
设置 Unit = (在 HT 的主索引 Int 子索引 1 内提取单位)
设置 Eff = (在 HT 的主索引 Int 子索引 2 内提取特效)
单位 - 杀死 Unit
特殊效果 - 删除 Eff
哈希表 - 清空 HT 中位于主索引 Int 之内的所有数据
计时器 - 删除 Timer
[/trigger]
如果在“某龙的哈希教程2”里直接用之前变量保存的值而不用哈希表储存会怎样呢?
3秒内第二次按了ESC的话这些变量的值就变了,第一次3秒到期后删除的是第二次创建的单位和特效,也就是全局变量冲突~
再庆祝一下吧~ 本教程尾声只有两句废话:
教程到此为止……
要如何使用或者如何灵活使用完全取决于你们的想象力了~
额。。。又忘了……写J教程的时候已经忘过一次了
字符串也是有身份证的,不同的字符串的身份号码是不同的,不过字符串的身份号码不叫句柄值,叫什么无所谓啦~
当然,字符串的身份号码也不会和句柄的重复~
[trigger]
动作
设置 Int = (转换 abc 为整数)
[/trigger]
abc是字符串~
这个动作不跟那些“获取XX的整数地址”在一起,这个动作YD1.20中在最下面,“哈希表 - <1.24>获取字符串的哈希值[ci]” |
|