关于hastable教程的疑问
这个教程里的一个演示,然而如何声明unit target?globals
hashtable HT = null
endglobals
function Init takes nothing returns nothing
call FlushParentHashtable( HT )
set HT = InitHashtable()
endfunction
function Damage_Act takes nothing returns boolean
local integer parentKey = GetHandleId( GetTriggeringTrigger() )
local unit source = LoadUnitHandle( HT, parentKey, 1 )
local unit target = LoadUnitHandle( HT, parentKey, 2 )
call FlushChildHashtable( HT, parentKey )
call TriggerRemoveCondition( GetTriggeringTrigger(), LoadTriggerConditionHandle( HT, parentKey, 3 ) )
call DestroyTrigger( GetTriggeringTrigger() )
set source = null
set target = null
return false
endfunction
function Damage takes unit source, unit target returns nothing
local trigger t = CreateTrigger()
local integer parentKey = GetHandleId( t )
local boolexpr cond = Condition( function Damage_Act )
call SaveUnitHandle( HT, parentKey, 1, source )
call SaveUnitHandle( HT, parentKey, 2, target )
call TriggerRegisterUnitEvent( t, target, EVENT_UNIT_DAMAGED )
call SaveTriggerConditionHandle( HT, parentKey, 3, TriggerAddCondition( t, cond ) )
set t = null
set cond = null
endfunction 好吧,无需声明unit target 要求是:
takes unit source, unit target, real damage
当target受到来自source的伤害(此伤害必须大于20.0)时,source对target额外造成此次伤害40%的伤害
伤害函数:
call UnitDamageTargetBJ( source, target, damage, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC )
此效果从函数被调用开始,target受到5次符合要求的伤害之后,效果消失。
要求:利用hashtable给trigger绑定参数。并且要求对trigger进行排泄。
那么伤害函数写在哪里? globals
hashtable hs=InitHashtable()
endglobals
//con的作用是判断条件是否成立,同时执行伤害动作
function con takes nothing returns boolean
local integer i=GetHandleId(GetTriggeringTrigger())
local integer js=LoadInteger(hs,i,4)
//js,为条件达成次数
local unit u=LoadUnitHandle(hs,i,1)
local real r=GetEventDamage()
local real ra=r*.4
//ra为伤害值的40%
call UnitDamageTargetBJ(u,gg_unit_hpea_0067,ra,ATTACK_TYPE_HERO,DAMAGE_TYPE_UNIVERSAL)
//命令单位对gg_unit_hpea_0067造成伤害
if r>1 then
//如果条件成立(伤害值大于1),js自增1
call SaveInteger(hs,i,4,js+1)
call BJDebugMsg(R2S(r))
endif
if js==3then
//当js等于3时,移除触发器条件,摧毁触发器
call FlushChildHashtable(hs,i)
call TriggerRemoveCondition(GetTriggeringTrigger(),LoadTriggerConditionHandle(hs,i,3))
call DestroyTrigger(GetTriggeringTrigger())
endif
set u=null
return false
endfunction
function InitTrig_ts takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=GetHandleId(t)
local boolexpr cond=Condition(function con)
local unit u=GetEventDamageSource()
call SaveUnitHandle(hs,i,1,u)
call TriggerRegisterUnitEvent(t,gg_unit_hpea_0067,EVENT_UNIT_DAMAGED)
call SaveTriggerConditionHandle(hs,i,3,TriggerAddCondition(t,cond))
set t=null
set cond=null
endfunction
嗯,我自己做了一个,但是call UnitDamageTargetBJ(u,gg_unit_hpea_0067,ra,ATTACK_TYPE_HERO,DAMAGE_TYPE_UNIVERSAL)并不会被执行 你的问题出在触发逻辑上
函数InitTrig_ts里:
local unit u=GetEventDamageSource(),触发器才刚刚创建,连事件都没注册哪来的伤害来源,所以这里相当于u=null
最后没有u=null,也就是没有排泄,当然因为这里声明u的时候本来就是null,所以也没有泄露
触发条件的话应该是不需要移除的,以前有前辈做过测试,动作才会泄露,需要移除,反正我条件从来都不移除的
函数con里:
local unit u=LoadUnitHandle(hs,i,1)改为GetEventDamageSource()
if js==3then,这么写的话相当于在第四次就结束了,而不是你说的五次后结束
并没有判断受到的伤害是否大于20
另外以防万一问下,这个InitTrig_ts你是开始时直接注册的呢还是游戏中动态注册?
如果是开始时直接注册的,那么这个触发整个游戏就只能用一次,也就是5次效果后就不会再发动了 本帖最后由 CarlGJung 于 2016-2-22 09:49 编辑
chyj4747 发表于 2016-2-22 00:07
你的问题出在触发逻辑上
函数InitTrig_ts里:
GA居然还有人!谢谢解答!“local unit u=GetEventDamageSource(),触发器才刚刚创建,连事件都没注册哪来的伤害来源”这个错误,我真揪不出来......
我试验了N次,都达不到演示里的效果,不知道他究竟是怎么做的(蛋疼的教程!)。
local unit u=LoadUnitHandle(hs,i,1)这个只是照搬教程写的。
我不明白的是:作者用的都是局部变量,不知道他怎么进行局部变量的传递的,事件里用局部变量的话(指定单位伤害事件里,作者用局部变量target,来作为触发事件的单位),该怎么激活事件。但我想达到教程里的效果只能用全局变量
本帖最后由 CarlGJung 于 2016-2-22 09:47 编辑
chyj4747 发表于 2016-2-22 00:07
你的问题出在触发逻辑上
函数InitTrig_ts里:
关于伤害判断,我判断的是伤害大于1(方便测试)——r>1.至于动态注册.......我现在只希望这个触发能达到正常的效果,所以没考虑 chyj4747 发表于 2016-2-22 00:07
你的问题出在触发逻辑上
函数InitTrig_ts里:
啊呀,看了下动态注册触发器的教程,和这个演示有点像,难道正确的姿势是动注册吗? 假设LZ要的效果是发动技能产生的:
比如,对目标发动技能后,30秒内5次伤害会造成40%额外伤害
globals
hashtable HT = InitHashtable()
endglobals
function Trig_testDmged takes nothing returns boolean
local trigger trg = GetTriggeringTrigger()
local boolean do_destroy = false
local integer pkey = GetHandleId(trg)
local unit source // 伤害来源
local integer count // 计数器
local real dmg // 受到的伤害
local real rate = 0.4 // 系数
if GetTriggerEventId() == EVENT_UNIT_DAMAGED then
// 单位受到伤害
set source = LoadUnitHandle(HT, pkey, 0)
set dmg = GetEventDamage()
if dmg > 1 and GetEventDamageSource() == source then
// 伤害大于1且伤害来源是施法者
call DisableTrigger(trg) // 防止下面的造成伤害动作反复触发受伤事件造成死循环
call UnitDamageTarget(source, GetTriggerUnit(), dmg*rate, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger(trg)
set count = LoadInteger(HT, pkey, 1) + 1
if count >= 5 then
set do_destroy = true
else
call SaveInteger(HT, pkey, 1, count)
endif
endif
set source = null
else
// 30秒到期
set do_destroy = true
endif
if do_destroy then
// 销毁触发器
call FlushChildHashtable(HT, pkey)
call DestroyTrigger(trg)
endif
set trg = null
return false
endfunction
function Trig_testAct takes nothing returns boolean
local trigger trg
local integer pkey
if GetSpellAbilityId() == '1234' then // 1234换成自定义技能ID
set trg = CreateTrigger()
set pkey = GetHandleId(trg)
call SaveUnitHandle(HT, pkey, 0, GetTriggerUnit()) // 绑定施法者
call SaveInteger(HT, pkey, 1, 0) // 计数器,记录技能效果触发的次数
call TriggerRegisterUnitEvent(trg, GetSpellTargetUnit(), EVENT_UNIT_DAMAGED) // 注册施法目标受伤事件
call TriggerRegisterTimerEvent(trg, 30, false) // 注册30秒到期事件,即技能效果结束
call TriggerAddCondition(trg, Condition(function Trig_testDmged))
set trg = null
endif
return false
endfunction
//===========================================================================
function InitTrig_test takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trg, Condition(function Trig_testAct))
set trg = null
endfunction
chyj4747 发表于 2016-2-22 23:22
假设LZ要的效果是发动技能产生的:
比如,对目标发动技能后,30秒内5次伤害会造成40%额外伤害
泪奔啊!多方求助无人解答,想不到是在貌似已经死了的GA得到了解答!真是太感谢你了!辛苦你写这么长的代码!————果然是动态注册,我刚开始试着补全这个演示时,完全不知道动态注册是什么鬼,然后,就卡了五天————直到今天....... CarlGJung 发表于 2016-2-23 19:23
泪奔啊!多方求助无人解答,想不到是在貌似已经死了的GA得到了解答!真是太感谢你了!辛苦你写这么长的代 ...
死是没死,人还是有几个在的,只不过因为人少,所以都是隔两天才来看看,不像几年前论坛都是隔几小时刷新一次的,现在玩魔兽的都没多少人了,更别说WE了
页:
[1]