找回密码
 点一下
查看: 2991|回复: 5

Group内单位顺序的一个问题

[复制链接]
发表于 2009-7-24 09:32:18 | 显示全部楼层 |阅读模式
先传送门(一个关于FirstOfGroup()的测试  -- 狡猾的兔子):
http://bbs.islga.org/read-htm-tid-5365-keyword-firstofgroup.html

再看一下以下一段代码:
[jass]
            set g = CreateGroup()
            if i == 0 then         // 测试用
            set i = 1        // 测试用
            loop
                set u2 = u
                set u = FirstOfGroup(C_Group[id])
                exitwhen u == null
                    call sMsg(I2S(H2I(u)))
                    call GroupRemoveUnit(C_Group[id], u)
                    call GroupAddUnit(g, u)
            endloop
            call sReleaseTempGroup(g, C_Group[id])
            call sMsg("---------------------------------------------------")
            else        // 测试用
            loop
                set u2 = u
                set u = FirstOfGroup(C_Group[id])
                exitwhen u == null
                    call GroupRemoveUnit(C_Group[id], u)
                    call GroupAddUnit(g, u)
            endloop
            call sReleaseTempGroup(g, C_Group[id])
            endif        // 测试用
            set u = u2
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            
            if DistanceBetweenPointsXY(GetUnitX(C_Caster[id]), GetUnitY(C_Caster[id]), x, y) < 64. then
                call RemoveUnit(C_Head[id])
                set C_Head[id] = null
                loop
                    set u = FirstOfGroup(C_Group[id])
                    exitwhen u == null
                        call GroupRemoveUnit(C_Group[id], u)
                        call RemoveUnit(u)
                        set u = null
                endloop
                set u = null
                set C_Head[id] = null
                set C_Caster[id] = null
                set C_Target[id] = null
                call RemoveLocation(C_Loc[id])
                set C_Loc[id] = null
                call TDS_Release(id)
            else
                call SetUnitX(C_Head[id], x)
                call SetUnitY(C_Head[id], y)
            endif
            call GroupRemoveUnit(C_Group[id], u)
            call RemoveUnit(u)
        endif
[/jass]

就是一个钩子的函数,我原本想用FirstofGroup+loop进行钩子的释放、回收,通过以下的一段:
[jass]
        loop
            set u2 = u
            set u = FirstOfGroup(C_Group[id])
            exitwhen u == null
                call GroupRemoveUnit(C_Group[id], u)
                call GroupAddUnit(g, u)
        endloop
        set u = u2
[/jass]
就是选取单位组中最后的一个单位。

注意第26,27行,乍看之下就是两行获取单位的X,Y,但是在这里问题产生了,加上那两行后你会发现钩链单位的顺序变得极其混乱(使用该技能3次以上),而且这个混乱程度是随使用次数的增大而增大的。

如果把这两行改成其他什么的,比如说GetUnitFlyingHeight,也会如此。

去掉那两行后虽然偶尔也会有1-2次的不正常,但是明显要好许多。



难道说获取单位数值会导致单位组内排列顺序变化??魔兽内部的group运作机制到底是怎么回事.......

chain.w3x

27 KB, 下载次数: 10

发表于 2009-7-24 10:50:34 | 显示全部楼层
建议检测2627行的u是否为null。
还有Group是否没有单位。
一般来说group不会有问题。
回复

使用道具 举报

发表于 2009-7-24 15:40:54 | 显示全部楼层
我昨天做链子也发现了...  不知道这个group 是个堆 还是个栈
我有次用GroupAddUnit进去一个 FristOfGroup出来的就是刚添加进去一个 我猜想他是个栈
昨天我弄钩子 发现ForGroup  设置单位声明周期 发现他又是 按堆的顺序来
而且技能重复使用了几次 就开始灵异  感觉有随机之势
回复

使用道具 举报

发表于 2009-7-24 15:47:25 | 显示全部楼层
group大概只是个列表或者向量之类的东西……
回复

使用道具 举报

发表于 2009-7-24 16:18:30 | 显示全部楼层
总之group这玩意不太正常,不要依赖他内在的排序来做存储结构。
要用就用自己写的table。
感觉有用的两个贴:
http://bbs.islga.org/read-htm-tid=25647.html
http://bbs.islga.org/read-htm-tid-28554.html
回复

使用道具 举报

 楼主| 发表于 2009-7-24 16:35:26 | 显示全部楼层
引用第2楼hunluan89于2009-07-24 15:40发表的  :
我昨天做链子也发现了...  不知道这个group 是个堆 还是个栈
我有次用GroupAddUnit进去一个 FristOfGroup出来的就是刚添加进去一个 我猜想他是个栈
昨天我弄钩子 发现ForGroup  设置单位声明周期 发现他又是 按堆的顺序来
而且技能重复使用了几次 就开始灵异  感觉有随机之势

嗯,我做出来也是这样。而且这个随机的趋势好像还跟group是否是新建的无关,只跟这个函数运行多少趟有关系。对group内的单位数据进行读取后这个随机的趋势更是大了很多,所以我想还是把group当成一个只能I/O的东西好了......
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 16:21 , Processed in 0.092519 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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