找回密码
 点一下
查看: 1905|回复: 11

关于hastable教程的疑问

[复制链接]
发表于 2016-2-21 18:49:58 | 显示全部楼层 |阅读模式
这个教程里的一个演示,然而如何声明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
 楼主| 发表于 2016-2-21 20:30:24 | 显示全部楼层
好吧,无需声明unit target
回复

使用道具 举报

 楼主| 发表于 2016-2-21 20:31:54 | 显示全部楼层
要求是:
takes unit source, unit target, real damage
当target受到来自source的伤害(此伤害必须大于20.0)时,source对target额外造成此次伤害40%的伤害
伤害函数:
[jass]call UnitDamageTargetBJ( source, target, damage, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC )[/jass]
此效果从函数被调用开始,target受到5次符合要求的伤害之后,效果消失。
要求:利用hashtable给trigger绑定参数。并且要求对trigger进行排泄。


那么伤害函数写在哪里?
回复

使用道具 举报

 楼主| 发表于 2016-2-21 21:40:43 | 显示全部楼层
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
回复

使用道具 举报

 楼主| 发表于 2016-2-21 21:41:57 | 显示全部楼层
嗯,我自己做了一个,但是call UnitDamageTargetBJ(u,gg_unit_hpea_0067,ra,ATTACK_TYPE_HERO,DAMAGE_TYPE_UNIVERSAL)并不会被执行
回复

使用道具 举报

发表于 2016-2-22 00:07:27 | 显示全部楼层
你的问题出在触发逻辑上

函数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次效果后就不会再发动了

点评

啊呀,看了下动态注册触发器的教程,和这个演示有点像,难道正确的姿势是动注册吗?  详情 回复 发表于 2016-2-22 20:37
关于伤害判断,我判断的是伤害大于1(方便测试)——r>1  详情 回复 发表于 2016-2-22 09:46
GA居然还有人! 我试验了N次,都达不到演示里的效果,不知道他究竟是怎么做的(蛋疼的教程!)。 local unit u=LoadUnitHandle(hs,i,1)这个只是照搬教程写的。 我不明白的是:作者用的都是局部变量,不知道他怎么  详情 回复 发表于 2016-2-22 09:45
回复

使用道具 举报

 楼主| 发表于 2016-2-22 09:45:17 | 显示全部楼层
本帖最后由 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,来作为触发事件的单位),该怎么激活事件。但我想达到教程里的效果只能用全局变量
回复

使用道具 举报

 楼主| 发表于 2016-2-22 09:46:06 | 显示全部楼层
本帖最后由 CarlGJung 于 2016-2-22 09:47 编辑
chyj4747 发表于 2016-2-22 00:07
你的问题出在触发逻辑上

函数InitTrig_ts里:

关于伤害判断,我判断的是伤害大于1(方便测试)——r>1.至于动态注册.......我现在只希望这个触发能达到正常的效果,所以没考虑
回复

使用道具 举报

 楼主| 发表于 2016-2-22 20:37:23 | 显示全部楼层
chyj4747 发表于 2016-2-22 00:07
你的问题出在触发逻辑上

函数InitTrig_ts里:

啊呀,看了下动态注册触发器的教程,和这个演示有点像,难道正确的姿势是动注册吗?
回复

使用道具 举报

发表于 2016-2-22 23:22:38 | 显示全部楼层
假设LZ要的效果是发动技能产生的:
比如,对目标发动技能后,30秒内5次伤害会造成40%额外伤害
  1. globals
  2.     hashtable HT = InitHashtable()
  3. endglobals

  4. function Trig_testDmged takes nothing returns boolean
  5.     local trigger trg = GetTriggeringTrigger()
  6.     local boolean do_destroy = false
  7.     local integer pkey = GetHandleId(trg)
  8.     local unit source           // 伤害来源
  9.     local integer count         // 计数器
  10.     local real dmg              // 受到的伤害
  11.     local real rate = 0.4       // 系数
  12.     if GetTriggerEventId() == EVENT_UNIT_DAMAGED then
  13.         // 单位受到伤害
  14.         set source = LoadUnitHandle(HT, pkey, 0)
  15.         set dmg = GetEventDamage()
  16.         if dmg > 1 and GetEventDamageSource() == source then
  17.             // 伤害大于1且伤害来源是施法者
  18.             call DisableTrigger(trg) // 防止下面的造成伤害动作反复触发受伤事件造成死循环
  19.             call UnitDamageTarget(source, GetTriggerUnit(), dmg*rate, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
  20.             call EnableTrigger(trg)
  21.             
  22.             set count = LoadInteger(HT, pkey, 1) + 1
  23.             if count >= 5 then
  24.                 set do_destroy = true
  25.             else
  26.                 call SaveInteger(HT, pkey, 1, count)
  27.             endif
  28.         endif
  29.         set source = null
  30.     else
  31.         // 30秒到期
  32.         set do_destroy = true
  33.     endif
  34.    
  35.     if do_destroy then
  36.         // 销毁触发器
  37.         call FlushChildHashtable(HT, pkey)
  38.         call DestroyTrigger(trg)
  39.     endif
  40.    
  41.     set trg = null
  42.    
  43.     return false
  44. endfunction

  45. function Trig_testAct takes nothing returns boolean
  46.     local trigger trg
  47.     local integer pkey
  48.     if GetSpellAbilityId() == '1234' then // 1234换成自定义技能ID
  49.         set trg = CreateTrigger()
  50.         set pkey = GetHandleId(trg)
  51.         call SaveUnitHandle(HT, pkey, 0, GetTriggerUnit()) // 绑定施法者
  52.         call SaveInteger(HT, pkey, 1, 0) // 计数器,记录技能效果触发的次数
  53.         call TriggerRegisterUnitEvent(trg, GetSpellTargetUnit(), EVENT_UNIT_DAMAGED) // 注册施法目标受伤事件
  54.         call TriggerRegisterTimerEvent(trg, 30, false) // 注册30秒到期事件,即技能效果结束
  55.         call TriggerAddCondition(trg, Condition(function Trig_testDmged))
  56.         set trg = null
  57.     endif
  58.     return false
  59. endfunction

  60. //===========================================================================
  61. function InitTrig_test takes nothing returns nothing
  62.     local trigger trg = CreateTrigger()
  63.     call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
  64.     call TriggerAddCondition(trg, Condition(function Trig_testAct))
  65.     set trg = null
  66. endfunction
复制代码


点评

泪奔啊!多方求助无人解答,想不到是在貌似已经死了的GA得到了解答!真是太感谢你了!辛苦你写这么长的代码!————果然是动态注册,我刚开始试着补全这个演示时,完全不知道动态注册是什么鬼,然后,就卡了五天—  详情 回复 发表于 2016-2-23 19:23
回复

使用道具 举报

 楼主| 发表于 2016-2-23 19:23:50 | 显示全部楼层
chyj4747 发表于 2016-2-22 23:22
假设LZ要的效果是发动技能产生的:
比如,对目标发动技能后,30秒内5次伤害会造成40%额外伤害

泪奔啊!多方求助无人解答,想不到是在貌似已经死了的GA得到了解答!真是太感谢你了!辛苦你写这么长的代码!————果然是动态注册,我刚开始试着补全这个演示时,完全不知道动态注册是什么鬼,然后,就卡了五天————直到今天.......
回复

使用道具 举报

发表于 2016-2-23 22:28:30 | 显示全部楼层
CarlGJung 发表于 2016-2-23 19:23
泪奔啊!多方求助无人解答,想不到是在貌似已经死了的GA得到了解答!真是太感谢你了!辛苦你写这么长的代 ...

死是没死,人还是有几个在的,只不过因为人少,所以都是隔两天才来看看,不像几年前论坛都是隔几小时刷新一次的,现在玩魔兽的都没多少人了,更别说WE了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-23 21:58 , Processed in 0.205891 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表