找回密码
 点一下
查看: 3897|回复: 12

禁用 动态注册事件的一些 问题.

[复制链接]
发表于 2011-4-6 00:25:03 | 显示全部楼层 |阅读模式
我自己不知道 是什么原因....这是一个无CD的函数...我无意拿此来做坏事..
只是好奇里面的RB使用....所以才翻来看...不过遇到了一些问题.
想把它改写成可开关型.
我本来想用关闭触发 或 删除触发...结果这些函数不是触发.不让 我删除.
我加入一个整数判断.然后游戏开始时,玩家点击对话框来更改 变量整数 的大小.成功一半,就是 只能关闭一次.关闭后再开启就关不了...
想问问有什么办法可以让动态注册事件 可以随时开关....希望指教.

令外想问问下面这个函数中
local trigger tri = CreateTrigger() 却没有 call DestroyTrigger(tri)
这样不会泄漏吗?
下面的 2 ,3 是什么意思呢....擦汗.
[jass]   call SetUnitState(I2U(uid), ConvertUnitState(2), GetUnitState(I2U(uid), ConvertUnitState(3)))
[/jass]

最后...发现里面有些 函数 没有对应的BJ找不到什么意思. 连百度加谷歌都找不到....想问问.这些函数.是不是只能通过背单词加巩固基础来得知呢....

[jass]
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function H2S takes handle h returns string
    return I2S(H2I(h))
endfunction

function I2U takes integer i returns unit
    return i
    return null
endfunction


function SetInt takes string h,string s,integer i returns nothing
   
    if i==0 then
        call FlushStoredInteger(udg_GC,h,s) //清空缓存吧...
    else
        call StoreInteger(udg_GC,h,s,i) //储存单位 请注意 这个  i
    endif
endfunction

function GetUnit takes string h,string s returns unit
    return GetStoredInteger(udg_GC,h,s) //获得整数
    return null
endfunction


function FlushMission takes string h returns nothing
    call FlushStoredMission(udg_GC,h) //清空该类别下的所有缓存数据
endfunction
function ClearCD takes nothing returns nothing
    local timer t = GetExpiredTimer()    //计时器
    call UnitResetCooldown( GetUnit(H2S(t),"u") ) //清除CD UnitResetCooldown
    call FlushMission(H2S(t))  // FlushMission
    call DestroyTimer(t) //删除 计时器 t
    set t = null    //空
endfunction

function ClearCDCond takes nothing returns boolean
    local timer t = CreateTimer()    //触发
    local integer uid = H2I(GetTriggerUnit())   //触发单位 变整数.
    call SetUnitManaPercentBJ( I2U(uid), 100 )

    call SetUnitState(I2U(uid), ConvertUnitState(2), GetUnitState(I2U(uid), ConvertUnitState(3)))
    call SetInt(H2S(t),"u",uid)  //计时器给存起来了.
    call TimerStart(t,0.001,false,function ClearCD) //0.001秒 运行一次....暴汗..
    set t = null
    return false
endfunction

function InitNoCD takes nothing returns nothing
    local trigger tri = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( tri, Condition( function ClearCDCond ) )
    set tri = null
endfunction

//===================================================
function InitTrig_CD1 takes nothing returns nothing
    set udg_GC = InitGameCacheBJ( "ZuiJiuShaoNv.w3v" )
    call InitNoCD()
endfunction

[/jass]
发表于 2011-4-6 03:22:53 | 显示全部楼层
直接在加条件。
如:
[jass]
function ClearCDCond takes nothing returns boolean
    local timer t = null
    local integer uid = 0
"加条件"
if not AllFlag then
return false
endif
if not PlayerFlag[GetPlayerId(GetTriggerPlayer())] then
return false
endif
"条件不通过结束"
"即 AllFlag 或 PlayerFlag[GetPlayerId(GetTriggerPlayer())] 为false结束"
set t = CreateTimer() "改这里建计时器"
set uid = H2I(GetTriggerUnit()) "改之里算触发单位Handle"
"条件不通过就不用建计时器和计算单位Handle了"
    call SetUnitManaPercentBJ( I2U(uid), 100 )

    call SetUnitState(I2U(uid), ConvertUnitState(2), GetUnitState(I2U(uid), ConvertUnitState(3)))
    call SetInt(H2S(t),"u",uid)  //计时器给存起来了.
    call TimerStart(t,0.001,false,function ClearCD) "这里怎么....暴汗.." //0.001秒 运行一次....暴汗..
    set t = null
    return false
endfunction
[/jass]
回复

使用道具 举报

发表于 2011-4-6 09:30:29 | 显示全部楼层
另外想问问下面这个函数中
local trigger tri = CreateTrigger() 却没有 call DestroyTrigger(tri)
这样不会泄漏吗?
排泄只是防止物体在不需要使用时仍继续占用内存的措施。
而这个触发由于需要一直使用到,所以自然不能删除掉。
而既然不能删除,自然不会有“泄漏”一说。
当然,既然没有删除,set null也是没有用的,这只是作者的一个很好的习惯而已。
下面的 2 ,3 是什么意思呢....擦汗.
0:生命 1:最大生命 2:魔法 3:最大魔法
最后...发现里面有些 函数 没有对应的BJ找不到什么意思. 连百度加谷歌都找不到....想问问.这些函数.是不是只能通过背单词加巩固基础来得知呢....
http://bbs.islga.org/read-htm-tid-7580-fpage-3.html
推荐这个东东……不知道的就查一下好了
想问问有什么办法可以让动态注册事件 可以随时开关....
楼上已经回答得很好了,补充一点:
可以使用一个全局变量来储存“tri”这个触发
(local trigger tri = CreateTrigger()改成set udg_tri = CreateTrigger())
然后不用的时候就DisableTrigger掉它好了。

另外:创建的计时器会在运行一次之后就被删除掉,所以触发并不是每0.001秒运行一次,而是0.001秒后运行一次。
回复

使用道具 举报

 楼主| 发表于 2011-4-6 11:36:20 | 显示全部楼层
感谢LS们....非常感谢哦.~~~
引用第2楼希瓦于2011-04-06 09:30发表的 :

楼上已经回答得很好了,补充一点:
可以使用一个全局变量来储存“tri”这个触发
(local trigger tri = CreateTrigger()改成set udg_tri = CreateTrigger())
然后不用的时候就DisableTrigger掉它好了。
.......

擦汗.自己想想又想不通了....
那个 local trigger tri = GrateTrigger()
我原来以为,是声明一次.就创建一个触发.声明100次.就创建100个....不过现在看来.不是如此啊...
我原来的理解.比如,创建单位的话.
local  unit u = GtateUnit............这样的话.声明一次就创建1个.100次就是100个,占用100个内存,
其中99个内存的引用数为0 , 1个为1.就是最后那个....
为0的单位死亡后施放内存?但是引用数为1要 set null 这样理解对不对?...点的话.也是吧...


但是这个 local trigger tri = GrateTrigger()  我就不理解了.如果我创建100次.
那么占用100个...1000次.就是占用1000个....擦汗. ..不删除和不set null不是会无限占用吗.....
但是看希瓦的意思.它应该是声明100次也只占用同一个? 无法理解了...求教....

另外像计时器等 这样  local timer t = CreateTimer()     是不是也是如此....
抱歉..非计算机专业的.
我现在比较晕的时,感觉
回复

使用道具 举报

发表于 2011-4-6 14:13:06 | 显示全部楼层
那个 local trigger tri = GrateTrigger()
我原来以为,是声明一次.就创建一个触发.声明100次.就创建100个....不过现在看来.不是如此啊...
我原来的理解.比如,创建单位的话.
local  unit u = GtateUnit............这样的话.声明一次就创建1个.100次就是100个,占用100个内存,
其中99个内存的引用数为0 , 1个为1.就是最后那个....
为0的单位死亡后施放内存?但是引用数为1要 set null 这样理解对不对?...点的话.也是吧...
你的认识是正确的,只有一点需要纠正:
不是引用数为1的物体需要set null
而是set null会减少变量指向的物体的引用数
要知道,是变量被set null,而不是物体被set null
但是这个 local trigger tri = GrateTrigger()  我就不理解了.如果我创建100次.
那么占用100个...1000次.就是占用1000个....擦汗. ..不删除和不set null不是会无限占用吗.....
但是看希瓦的意思.它应该是声明100次也只占用同一个? 无法理解了...求教....
我可没有这么说……
我的意思是:由于InitNoCD函数只会被运行一次,所以自然只会创建一个触发。
回复

使用道具 举报

 楼主| 发表于 2011-4-6 14:24:16 | 显示全部楼层
引用第4楼希瓦于2011-04-06 14:13发表的 :

我可没有这么说……
我的意思是:由于InitNoCD函数只会被运行一次,所以自然只会创建一个触发。

抱歉.是我误解了.还要再问..
自己没看明白这一句.
由于InitNoCD函数只会被运行一次,所以自然只会创建一个触发

看到InitNoCD函数的事件,应该是发动技能效果吧.
我以为是玩家发动一次技能.就触发一次.
也没有看到关闭触发的函数.为何只会运行一次呢?
我以为会被创建很多次呢....
这个能指点一下吗?
回复

使用道具 举报

发表于 2011-4-6 14:35:30 | 显示全部楼层
InitNoCD只是注册触发的函数,function ClearCDCond才是触发的条件。

单位每次释放技能后,运行的函数是 ClearCDCond而不是InitNoCD
回复

使用道具 举报

 楼主| 发表于 2011-4-6 16:43:15 | 显示全部楼层
引用第6楼希瓦于2011-04-06 14:35发表的 :
InitNoCD只是注册触发的函数,function ClearCDCond才是触发的条件。

单位每次释放技能后,运行的函数是 ClearCDCond而不是InitNoCD

注册触发的函数
都是只运行一次的吗?---我这里卡住了.

这样的.我在上面那个无CD和GA的JASS教程中的注册触发函数中加入
call DestroyTrigger(XXX)
    set XX = null
那么.那个动态注册事件就没有效果了.似乎是刚出来就被毁了吧...
然而我在这前面加个等待.
call TriggerSleepAction(X)
那么这个动态注册事件就可以正常的运行了....当然...根据情况而不同...我改动了很多次...

觉得自己 被 自己搞糊涂了.
这样问吧.我就是担心泄漏.
注册触发的函数,都只是运行一次的.所以可以不删除里面的 local trigger....对吧?

不过这样的话.我又无法理解什么时候才需要下面这样呢?
call DestroyTrigger(rTrg)
set rTrg = null

何时需要排泄触发变量.何时不需要排泄触发变量?
这是我的困惑....
求教.
回复

使用道具 举报

发表于 2011-4-6 18:47:13 | 显示全部楼层
注册触发的函数的作用在于:创建触发。
如果只需要一个触发就能完成效果,那么自然只创建一个触发就可以了。

上面的触发的的大致流程如下:
事件:
任意单位施放技能
条件:
开启计时器清除单位CD

那么只需要一个“任意单位释放技能”的触发就能完成,自然就只用创建一个触发。

如果要终止NOCD的效果,那么只需要disabletrigger而不需要destroytrigger。

群体技能2.w3x (16 KB, 下载次数: 9)
需要destroy的演示在此……这是很久以前我做的了……可能没有排泄完全,但是大致可以参考下。
回复

使用道具 举报

发表于 2011-4-6 19:19:29 | 显示全部楼层
补充:
动态创建/删除触发,一般用在需要绑定数据在触发上的时候。
比如上面的触发中,我把“马甲单位组”和“停止施法触发”绑定在了一起,用于实现“黑暗游侠”停止“生命汲取”,马甲单位也停止“生命汲取”的效果。
再比如DOTA“盛宴”,也是这样的,将伤害触发和单位以及计时器绑在了一起。
回复

使用道具 举报

 楼主| 发表于 2011-4-6 22:47:14 | 显示全部楼层
引用第9楼希瓦于2011-04-06 19:19发表的 :
补充:
动态创建/删除触发,一般用在需要绑定数据在触发上的时候。
比如上面的触发中,我把“马甲单位组”和“停止施法触发”绑定在了一起,用于实现“黑暗游侠”停止“生命汲取”,马甲单位也停止“生命汲取”的效果。
再比如DOTA“盛宴”,也是这样的,将伤害触发和单位以及计时器绑在了一起。

希瓦.你是天使......
我很好奇.为何一开始就是一句 最后创建的单位 为 类... 这个生命状态..我学没有看到单位被创建呢...擦汗. ...

话说看了希瓦的代码.巨晕....
希瓦.能不能讲解一下你的代码...特别下面这样的语句....它们再次颠覆了我对J的认识....

[jass]局部 和 全局 混着用....
set udg_trigger[ia]=tr
local integer ia=fun_int_trigger(null)
local integer ia=0
loop
exitwhen udg_trigger[ia]==tr
[/jass][trigger]
未命名触发器 002
    事件
        单位 - 任意单位 开始施放技能
    条件
        ((触发单位) 是 英雄) 等于 TRUE
    动作
        单位 - 设置 10.00 秒 类 类型的生命周期对 (最后创建的单位)
        设置 ab = (施放技能)
        设置 dwz = (新建的空单位组)
        单位组 - 选取 (半径为 512.00 圆心为 (技能施放点) 且满足 ((((匹配单位) 是存活的) 等于 TRUE) 且 ((((匹配单位) 的类型) 不等于 女巫) 且 (((匹配单位) 不等于 (技能施放目标)) 且 ((((匹配单位) 是 ((触发单位) 的所有者 内所有单位做动作
            Loop - 动作
                单位 - 创建 1 女巫 给 ((触发单位) 的所有者) 在 ((触发单位) 的位置) ,面向 ((触发单位) 的位置)
                单位 - 隐藏 (最后创建的单位)
                单位 - 设置 10.00 秒 类 类型的生命周期对 (最后创建的单位)
                单位组 - 添加 (最后创建的单位) 到 dwz
                单位 - 添加 ab 给 (最后创建的单位)
                单位 - 设置 ab 等级对 (最后创建的单位) 为 (ab 的等级对 (触发单位))
                自定义代码:   call IssueTargetOrder( GetLastCreatedUnit(),OrderId2StringBJ(GetUnitCurrentOrder(GetTriggerUnit())), GetEnumUnit() )
        自定义代码:   call stopkill(GetTriggerUnit(),udg_dwz)
[/trigger]
回复

使用道具 举报

发表于 2011-4-7 00:09:48 | 显示全部楼层
(⊙o⊙)…额,使你变得更“晕”了我真的很抱歉……
这是我很久以前(才学J的时候的)的测试地图,今天被我不小心翻了出来……看来实在是起不到参考的作用了……如果看不懂的话完全可以跳过。
开篇第一句“单位 - 设置 10.00 秒 类 类型的生命周期对 (最后创建的单位)”只是测试语句忘了删,是完全没用的……
至于局部全局混用,这是完全可以的……
在returnbug被发现之前,都是使用全局变量数组来储存数据的。
局部变量负责数据的暂时存放,全局变量用来永久储存数据,两者并没有什么冲突……
回复

使用道具 举报

 楼主| 发表于 2011-4-7 04:10:26 | 显示全部楼层
引用第11楼希瓦于2011-04-07 00:09发表的 :
(⊙o⊙)…额,使你变得更“晕”了我真的很抱歉……
这是我很久以前(才学J的时候的)的测试地图,今天被我不小心翻了出来……看来实在是起不到参考的作用了……如果看不懂的话完全可以跳过。
开篇第一句“单位 - 设置 10.00 秒 类 类型的生命周期对 (最后创建的单位)”只是测试语句忘了删,是完全没用的……
至于局部全局混用,这是完全可以的……
在returnbug被发现之前,都是使用全局变量数组来储存数据的。
.......

嗯.感谢.
可能是我打字的时候.用错了词.我不是说局部和全局不能混用..而是它们混用了以后..我更看不明白了...
我很想知道下面这些J代表什么呢...
特别是 local integer ia=fun_int_trigger(null)
integer类型 可以 等于 触发变量? 那它后边的(null) 空..又是什么意思?
它的意思是 ia = fun_int_trigger 为空?

    [li]local integer ia=fun_int_trigger(null)
    [li]local integer ia=0
    [li]loop
    [li]exitwhen udg_trigger[ia]==tr [/li]

又是没有学会多少..不过总算是有进步...要去睡了...
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 13:41 , Processed in 0.083187 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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