找回密码
 点一下
查看: 7219|回复: 13

Hash方法--钩肥的演示V2.0(代码重写)

[复制链接]
发表于 2008-11-6 16:26:07 | 显示全部楼层 |阅读模式
我不把这个发在技能区是因为这不单单只是一个技能,这个是关于Hash方法的第三贴,也是最后一个演示了。
我想,关于Hash的用法,关注的同学可能已经理解了。它的本质就是将任意handle元素的值Hash为一个小于
8191的值,从而可以使用全局变量来存储与之相关的变量,进而模拟缓存的方法。
大家可以比较一下它和缓存的区别。

下面说说关于本演示的一些东西:
1,参照了钩肥大战的效果,模拟度超过90%。
2,钩子弯转的判断未使用区域,而是根据地形的高度判断,请移植的同学自行调整高度限制。
3,改变锁链单位之后,链子才会变化,之前的不会改变,这个与钩肥里面是一样的,全部都变是可以的,添加混乱技能即可。
4,目前的钩子并没有伤害,请移植的同学自行添加。
5,当两个单位之间的距离小于钩子钩取单位的范围时,钩子会自动回收,另一个单位不会移动。
6,可以在钩锁数量过多的情况下自动调整钩锁之间的距离,不再是越长的链子越占用资源了。
7,本演示使用了Hash方法,不理解的可以参考我在Ga中的另外俩贴。(其实关系不大啦,编写顺序和缓存的使用没有本质的区别)
8,钩子的简单原理,钩子头的移动有专门的一个函数用来判断,后面的锁链就是依次移动向前一个单位,这样锁链会很平滑。

2009-1-14
1,重写了主要的代码,大大改善了其运行效率。注意了首行缩进,不再像之前一样火星了。
2,恢复了之前的一个测试技能,可以查看钩子头的飞行路径。(期待一个更好的判断方法)
3,在单位被勾取之后会创建一个特效,可有可无的一个改变。
4,有必要的话会再次更新。

2009-2-8
嗯,看到有人挖坟...我在这里编辑下。回11楼的提问,应该是你的编辑器不支持的缘故,所以参考链接
http://www.islga.org/bbs/read.php?tid=15253
回12楼的提问,碰撞的角度再8楼已经有回答,其实只考虑了垂直和水平两个面。
还有,演示里面的方法在现在看来,还不是最有效率的,所以等我去了学校还要更新下,到时另发一贴吧,嗯,还要配上截图,更直观一些吧。

2009-2-15
好了,更新了,计时器和单位使用了DataSystem,由于在地图过程中省去了计时器的创建和删除以及几乎所有的数组都使用了整数数组,导致的结果是排泄的意外的好。
钩锁的移动做了一些进化,使用了一个链表和双向链表来提高效率。
可惜承诺的截图还是懒得做了,2.0和2.1版本都保留下来,这样大家可以很方便的比较它们的优劣,我希望大家可以很好的运用它们。
有兴趣的可以查看链接http://www.islga.org/bbs/read.php?tid=24648

屠夫山寨V2.0.w3x

47 KB, 下载次数: 337

Hash版的

屠夫山寨V2.1.w3x

49 KB, 下载次数: 187

DataSystem版的

评分

参与人数 2威望 +6 收起 理由
狡猾的兔子 + 1 十分强大。
kook + 5 好物

查看全部评分

恶声恶气 该用户已被删除
发表于 2008-11-6 16:33:14 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

恶声恶气 该用户已被删除
发表于 2008-11-6 16:39:37 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2008-11-6 18:51:29 | 显示全部楼层
哇,山寨版屠夫。
回复

使用道具 举报

发表于 2008-11-6 18:58:31 | 显示全部楼层
下载 看下`
回复

使用道具 举报

发表于 2008-11-7 16:37:08 | 显示全部楼层
十分强大的演示,美中不足的就是可读性实在太差了。
回复

使用道具 举报

 楼主| 发表于 2008-11-7 22:09:50 | 显示全部楼层

屠夫山寨V1.5

---修改参数的技能现在移植到了物品上,修正了之前钩子放空的Bug。
---去除了代码中的冗余,使之运行时更有效率。
---添加了一个判断,使得在锁链过长时,适当增加锁链之间的距离,不再是越长的链子越占用资源了。
---修改了各色锁链的模型,有些更漂亮了。
---爆头依然没有添加,因为一个肥仔可以放出超过3条的链子,单位太容易死亡。
---去除了英雄头像,添加一个测试技能。
---依然会更新。2008年11月7日21:45:21

---地图在顶楼
回复

使用道具 举报

 楼主| 发表于 2008-11-7 22:25:19 | 显示全部楼层

屠夫山寨V1.5

可读行差我也看出来了,本人之前没接触过编程,e文也很差,所以光全局变量的命名就让人看起来很头疼。我也看的晕忽忽的...在这里稍微解释下吧。

[codes=全局变量的一些解释jass]globals
constant integer Gz_id='e001'
//钩子头单位的ID
constant integer Gz_id1='e002'
//锁链单位的ID,另外两个是+1再+1
constant real Gz_tmr=.04
//计时器的运行间隔
constant real Gz_sp=600
//钩子的初始速度
constant real Gz_sp1=100
//钩子速度每级的增长值
constant real Gz_h=1
//钩子返回时速度倍率,可以小于1,但是不要为负值!
constant real Gz_l=1300
//钩子的范围
constant real Gz_l1=200
//钩子范围的每级增长值
constant real Gz_r=100
//钩子头钩取单位的范围
constant real Gz_r1=20
//钩子头钩取范围的每级增长值
constant real Gz_z=180/3.14159
//弧度转角度
//(以上在游戏中一般是不会改变的)
integer array Gu_i1
integer array Gu_i2
//锁链中相邻单位是相互记录的,i1是前一单位,i2是后一单位,前或后为0,则判定为对首或尾。Gu表示与单位相关的变量。
real array Gsf_sp
integer array Gsf_l
real array Gsf_r
integer array Gsf_id
integer array Gsf_b
//Gsf表示与施法者挂接的变量,分别表示钩子的速度,钩子的长度,钩子钩取单位的范围,钩锁的单位ID,创建钩锁的间隔。
unit array Gn_u
unit array Gn_u1
unit array Gn_u2
unit array Gn_u3
integer array Gn_i
integer array Gn_l
real array Gn_f
integer array Gn_b
//Gn表示与计时器挂接的变量,分别为施法者,钩子头,钩子尾,钩取单位,指向Gsf下脚标,计时器运行剩余次数(发出时),钩子头移动方向,Gn_b与Gsf_b对应,相等时创建一个钩锁单位
endglobals[/codes]

完毕!
回复

使用道具 举报

 楼主| 发表于 2008-11-9 19:45:20 | 显示全部楼层
还是发下该演示的一些解释吧。其实做这个钩子的效果分为两个部分就可以了。其一是钩子头的碰撞效果。代码如下:

[codes=钩子头的碰撞改变jass]function Gztm_f takes integer n returns nothing
local unit u=Gn_u1[n]
local real sp=Gsf_sp[Gn_i[n]]
local real x=GetUnitX(u)
local real y=GetUnitY(u)
local real x1
local real y1
local location l
loop
set x1=x+Cos(Gn_f[n])*sp
set y1=y+Sin(Gn_f[n])*sp
set l=Location(x1,y1)
exitwhen GetLocationZ(l)<=30 and not IsTerrainPathable(x1,y1,PATHING_TYPE_FLYABILITY)
set Gn_f[n]=-Gn_f[n]+3.14159
set x1=x+Cos(Gn_f[n])*sp
set y1=y+Sin(Gn_f[n])*sp
call MoveLocation(l,x1,y1)
exitwhen GetLocationZ(l)<=30 and not IsTerrainPathable(x1,y1,PATHING_TYPE_FLYABILITY)
set Gn_f[n]=Gn_f[n]+3.14159
set x1=x+Cos(Gn_f[n])*sp*2
set y1=y+Sin(Gn_f[n])*sp*2
call MoveLocation(l,x1,y1)
exitwhen GetLocationZ(l)<=50 and not IsTerrainPathable(x1,y1,PATHING_TYPE_FLYABILITY)
set Gn_f[n]=-Gn_f[n]+3.14159
set x1=x+Cos(Gn_f[n])*sp
set y1=y+Sin(Gn_f[n])*sp
exitwhen true
endloop
call SetUnitX(u,x1)
call SetUnitY(u,y1)
call RemoveLocation(l)
set l=null
set u=null
endfunction[/codes]

代码中的unit u就是钩子头,sp就是钩子头应当移动的距离,这些数据是已经在屠夫释放技能时记录下来的。
关于location l,因为本演示中没有使用区域判断钩子是否发生碰撞,而是根据地形的高度来判断,所以点的创建就是必需的了。
第一个exitwhen以前的代码是判断钩子头沿直线飞行的话,下一次到达的点的高度是否超过了30以及下个坐标飞行单位是否可以通过,这样就排除了高低以及单位不能到达的地方(就是地图的边界)。
如果跳出循环了,那么我们就得到了钩子头下次应该到达的坐标的x,y的值,如果没有跳出,接着往下看。
代码中改变了钩子头的移动的方向,角度的改变是先假设遇到了南北方向的障碍物而做出的,经过相同预算之后还未跳出的话就再假设是遇到了东西向的障碍物,还不跳出的话,让钩子头原路返回吧,这个就不需要判断了。
代码中的循环其实并没有循环,这个大家应该都看出来了,使用它只是想得到一个跳出的效果。同时从这些可以看出,钩子头如果遇到斜向的障碍是没有办法的,它只有3个可选的方向,但是基本上是可以的了。
需要补充的是,东西向的障碍物,我将移动距离乘倍而且高度判断增加到了50,这是实际测验得出的数据,大家可以自己调整看看效果。



解释完毕。再看第二,那就是钩锁的平滑的移动效果,原理我之前说过了,就是一个跟一个,看代码:

[codes=钩锁发出时运行代码jass]loop
set I=Gu_i2[Gz_Hash(0,ug,false)]
exitwhen I==0
set x=GetUnitX(U)
set y=GetUnitY(U)
set f=Atan2(GetUnitY(ug)-y,GetUnitX(ug)-x)
call SetUnitFacing(U,f*Gz_z)
call SetUnitX(U,x+Cos(f)*Gsf_sp[th])
call SetUnitY(U,y+Sin(f)*Gsf_sp[th])
set ug=U
endloop[/codes]

代码运行之前,我已经定义局域变量ug为钩子头,这是起始,循环中ug的指向会变化,整数变量Gu_i2记录的是紧接钩子头的下一单位的handle值,我们逐步看下。
[codes=钩锁发出时运行代码jass]loop
循环开始...
set I=Gu_i2[Gz_Hash(0,ug,false)]
设置integer I为ug单位记录的下一单位的handle值
exitwhen I==0
如果I==0,则跳出,因为如果I为0的话就说明这个ug已经是钩锁中最后一个单位了,钩锁已经整体的移动完毕了
set x=GetUnitX(U)
set y=GetUnitY(U)
set f=Atan2(GetUnitY(ug)-y,GetUnitX(ug)-x)
call SetUnitFacing(U,f*Gz_z)
call SetUnitX(U,x+Cos(f)*Gsf_sp[th])
call SetUnitY(U,y+Sin(f)*Gsf_sp[th])
如果没有跳出,则说明I取得了一个handle值,此时unit U已经指向ug的下一个单位了(此处的原理就是Union bug),那么这5行代码就是取得了U的位置以及U与ug之间的方向,然后移动U并设置它的面向角度。
set ug=U
endloop
设置ug为U,然后循环回到初始,这样就可以一个一个移动所有的钩锁来使得锁链变的很光滑[/codes]

钩子返回时的代码跟这个是对称的,如下:

[codes=钩锁返回时运行代码jass]loop
set x=GetUnitX(U)
set y=GetUnitY(U)
set f=Atan2(GetUnitY(ux)-y,GetUnitX(ux)-x)
call SetUnitX(U,x+Cos(f)*s)
call SetUnitY(U,y+Sin(f)*s)
call SetUnitFacing(U,180+f*Gz_z)
set ux=U
set I=Gu_i1[Gz_Hash(0,U,false)]
exitwhen I==0
endloop[/codes]
循环开始前。我设置了ux为放出钩子的屠夫,U就是最接近屠夫的一个钩锁,对应的Gu_i1记录的是钩锁的前一个单位。

以上就是钩肥演示中最核心的代码,其他所有的代码在大家理解了运行方式之后可以自己来编写。甚至以上的代码你也可以使用别的方法来编写,我是使用了Hash的方法,而你可以使用缓存用来记录钩锁单位前一和后一单位,当然,只要能用于记录,任何方法都是可行的。

这个演示只做出了一个基本的钩子的效果,伤害效果,拖拽特效,火焰效果还有可以把自己钩向标杆的钩子都没有添加进去,这也是为了保证演示能够到达最简的效果。
大家如果理解了上述的方法,甚至都不需要下载我的演示了,因为个人感觉这还算是一个比较简单的技能,大家可以自己尝试编写自己的钩子的代码。

这近10天来我发了3个贴来和大家研究关于Hash方法的适用范围的问题,结论似乎还没有。而我今后一段时间会比较忙,讨论就此停止吧,我继续潜了。
最后再说下,如果你喜欢Hash方法的话,请务必注意以下几点问题:
1,Hash函数为了达到最简效果并没有设置防出错的措施,请避免使用它来获取还未存储的数据的指针,否则函数会终止运行,但不会使魔兽出错跳出。
2,Hash函数可以记录的数据是有上限的,如果你要记录大量的数据的话,请一定要及时排泄。如果还不够用的话,你可以修改上限使用两组数组来记录或再创建另一个Hash函数,起一个不同的函数名,配备另一个整数数组。
3,Hash函数是良好的缓存方法的替代品,但是无法完全胜任全部功能。

最终的演示修改了一个比较严重的bug,请不要再使用之前的所有版本,地图我将在顶楼更新。
回复

使用道具 举报

发表于 2008-11-10 11:40:42 | 显示全部楼层
[codes=jass]
globals
    constant integer Ha=8191
    constant integer Hb=1987
    integer I
    handle H
    unit U
    integer array Gz_Hi
endglobals

function Gz_Hash takes integer I,handle H,boolean b returns integer
    local integer ha=I-I/Ha*Ha
    local integer hb=(I/Hb+1)*Hb-I
    loop
    exitwhen (b and Gz_Hi[ha]==0)or(not b and Gz_Hi[ha]==I)
    set ha=ha+hb
    if ha>=Ha then
    set ha=ha-Ha
    endif
    endloop
    if b then
    set Gz_Hi[ha]=I
    endif
    return ha
endfunction

globals
    constant integer Gz_id='e001'   //钩子头单位的ID
    constant integer Gz_id1='e002'   //锁链单位的ID,另外两个是+1再+1
    constant real Gz_tmr=.04        //计时器的运行间隔
    constant real Gz_sp=600       //钩子的初始速度
    constant real Gz_sp1=100       //钩子速度每级的增长值
    constant real Gz_h=1         //钩子返回时速度倍率
    constant real Gz_l=1300        //钩子的范围
    constant real Gz_l1=200        //钩子范围的每级增长值
    constant real Gz_r=100        //钩子头钩取单位的范围
    constant real Gz_r1=20       //钩子头钩取范围的每级增长值
    constant real Gz_z=180/3.14159    //弧度转角度
    integer array Gu_i1
    integer array Gu_i2
    real array Gsf_sp
    integer array Gsf_l
    real array Gsf_r
    integer array Gsf_id
    integer array Gsf_b
    unit array Gn_u
    unit array Gn_u1
    unit array Gn_u2
    unit array Gn_u3
    integer array Gn_i
    integer array Gn_l
    real array Gn_f
    integer array Gn_b
endglobals

function Gztm_f takes unit u,integer n,location l returns nothing
    local integer this=Gn_i[n]
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)
    set x=x+Cos(Gn_f[n])*Gsf_sp[this]
    set y=y+Sin(Gn_f[n])*Gsf_sp[this]
    set l=Location(x,y)
    if GetLocationZ(l)<=30 and not IsTerrainPathable(x,y,PATHING_TYPE_FLYABILITY) then
        call SetUnitX(u,x)
        call SetUnitY(u,y)
        call RemoveLocation(l)
        return
    endif
    call RemoveLocation(l)
    set Gn_f[n]=-Gn_f[n]+3.14159
    set x=x+Cos(Gn_f[n])*Gsf_sp[this]
    set y=y+Sin(Gn_f[n])*Gsf_sp[this]
    set l=Location(x,y)
    if GetLocationZ(l)<=30 and not IsTerrainPathable(x,y,PATHING_TYPE_FLYABILITY) then
        call SetUnitX(u,x)
        call SetUnitY(u,y)
        call RemoveLocation(l)
        return
    endif
    call RemoveLocation(l)
    set Gn_f[n]=Gn_f[n]+3.14159
    set x=x+Cos(Gn_f[n])*Gsf_sp[this]*2
    set y=y+Sin(Gn_f[n])*Gsf_sp[this]*2
    set l=Location(x,y)
    if GetLocationZ(l)<=50 and not IsTerrainPathable(x,y,PATHING_TYPE_FLYABILITY) then
        call SetUnitX(u,x)
        call SetUnitY(u,y)
        call RemoveLocation(l)
        return
    endif
    call RemoveLocation(l)
    set Gn_f[n]=-Gn_f[n]+3.14159
    set x=x+Cos(Gn_f[n])*Gsf_sp[this]*1.5
    set y=y+Sin(Gn_f[n])*Gsf_sp[this]*1.5
    call SetUnitX(u,x)
    call SetUnitY(u,y)
endfunction

function Gztm_g takes unit ug,integer n returns integer
    local unit u=Gn_u1[n]
    local unit ux=Gn_u[n]
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)
    local real s=Gsf_r[Gn_i[n]]
    local real x1
    local real y1
    local real s1
    local group g=CreateGroup()
    call GroupEnumUnitsInRange(g,x,y,s,null)
    set s=s*s
    loop
        set u=FirstOfGroup(g)
        exitwhen u==null
        call GroupRemoveUnit(g,u)
        if u!=ux and not IsUnitType(u,UNIT_TYPE_STRUCTURE) then
            set x1=x-GetUnitX(u)
            set y1=y-GetUnitY(u)
            set s1=x1*x1+y1*y1
            if s1<=s then
                set ug=u
                set s=s1
            endif
        endif
    endloop
    call DestroyGroup(g)
    set g=null
    set ux=null
    return ug
    return 0
endfunction

function Gztm_tm2 takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer n=Gz_Hash(0,t,false)
    local integer th=Gn_i[n]
    local integer this
    local unit ux=Gn_u[n]
    local integer I
    local unit U=Gn_u2[n]
    local unit ug=Gn_u1[n]
    local real x=GetUnitX(Gn_u[n])
    local real y=GetUnitY(Gn_u[n])
    local real x1
    local real y1
    local real f
    local boolean b=false
    if U!=ug then
        set f=Gsf_sp[Gn_i[n]]*Gz_h
        set f=f*f
        loop
            set x1=x-GetUnitX(U)
            set y1=y-GetUnitY(U)
            set this=Gz_Hash(0,U,false)
            if x1*x1+y1*y1<=f then
                call RemoveUnit(U)
                set Gz_Hi[this]=0
            else
                set Gn_u2[n]=U
                set U=Gn_u[n]
                set Gu_i2[this]=I
                set b=true
                exitwhen true
            endif
            set I=Gu_i1[this]
            exitwhen U==ug
        endloop
    endif
    if b then
        set U=Gn_u2[n]
        loop
            set x=GetUnitX(U)
            set y=GetUnitY(U)
            set f=Atan2(GetUnitY(ux)-y,GetUnitX(ux)-x)
            call SetUnitX(U,x+Cos(f)*Gsf_sp[th]*Gz_h)
            call SetUnitY(U,y+Sin(f)*Gsf_sp[th]*Gz_h)
            call SetUnitFacing(U,180+f*Gz_z)
            set this=Gz_Hash(0,U,false)
            set ux=U
            set I=Gu_i1[this]
            exitwhen I==0
        endloop
        if Gn_u3[n]!=null then
            call SetUnitX(Gn_u3[n],GetUnitX(ux))
            call SetUnitY(Gn_u3[n],GetUnitY(ux))
        else
            set I=Gztm_g(null,n)
            set Gn_u3[n]=U
        endif
        else
            set Gz_Hi[Gz_Hash(0,Gn_u1[n],false)]=0
            call RemoveUnit(Gn_u1[n])
            set Gn_u3[n]=null
            call PauseTimer(t)
            call DestroyTimer(t)
        endif
    set t=null
    set I=0
    set ug=null
    set ux=null
endfunction

function Gztm_tm1 takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer n=Gz_Hash(0,t,false)
    local integer this
    local real x
    local real y
    local real f
    local unit ug=Gn_u1[n]
    local integer th=Gn_i[n]
    local unit U
    local integer I=Gztm_g(null,n)
    if I==0 then
        call Gztm_f(ug,n,null)
        set Gn_l[n]=Gn_l[n]-1
        loop
            set this=Gz_Hash(0,ug,false)
            set I=Gu_i2[this]
            exitwhen I==0
            set x=GetUnitX(U)
            set y=GetUnitY(U)
            set f=Atan2(GetUnitY(ug)-y,GetUnitX(ug)-x)
            call SetUnitFacing(U,f*Gz_z)
            call SetUnitX(U,x+Cos(f)*Gsf_sp[th])
            call SetUnitY(U,y+Sin(f)*Gsf_sp[th])
            set ug=U
        endloop
        if Gn_b[n]>=Gsf_b[th] then
            set U=Gn_u[n]
            set U=CreateUnit(GetOwningPlayer(ug),Gsf_id[th],GetUnitX(U),GetUnitY(U),Atan2(GetUnitY(ug)-GetUnitY(U),GetUnitX(ug)-GetUnitX(U))*Gz_z)
            set Gn_u2[n]=U
            set Gu_i2[this]=I
            set Gn_b[n]=0
            set th=Gz_Hash(0,U,true)
            set Gu_i1[th]=Gz_Hi[this]
            set Gu_i2[th]=0
        else
            set Gn_b[n]=Gn_b[n]+1
        endif
    else
        set Gn_u3[n]=U
    endif
    if Gn_l[n]==0 or Gn_u3[n]!=null then
        call PauseTimer(t)
        call TimerStart(t,Gz_tmr,true,function Gztm_tm2)
    endif
    set I=0
    set ug=null
    set t=null
endfunction

function Gztm_func1 takes unit u,location l returns nothing
    local timer t=CreateTimer()
    local integer n=Gz_Hash(0,t,true)
    local integer this=Gz_Hash(0,u,false)
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)
    set Gn_u[n]=u
    set Gn_f[n]=Atan2(GetLocationY(l)-y,GetLocationX(l)-x)
    set u=CreateUnit(GetOwningPlayer(u),Gz_id,x,y,0)
    set Gn_u1[n]=u
    set Gn_u2[n]=u
    set Gn_i[n]=this
    set Gn_l[n]=Gsf_l[this]
    set Gn_b[n]=0
    set this=Gz_Hash(0,u,true)
    set Gu_i1[this]=0
    set Gu_i2[this]=0
    call TimerStart(t,Gz_tmr,true,function Gztm_tm1)
endfunction

function Gztm_tm0 takes nothing returns nothing
    local integer n=Gz_Hash(0,GetExpiredTimer(),false)
    call Gztm_f(Gn_u[n],n,null)
endfunction

function Gztm_func0 takes unit u,location l returns nothing
    local timer t=CreateTimer()
    local integer n=Gz_Hash(0,t,true)
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)
    set Gn_u[n]=CreateUnit(GetOwningPlayer(u),Gz_id,x,y,0)
    set Gn_f[n]=Atan2(GetLocationY(l)-y,GetLocationX(l)-x)
    set Gn_i[n]=Gz_Hash(0,u,false)
    call TimerStart(t,Gz_tmr,true,function Gztm_tm0)
    set t=null
endfunction

function Gztm_func takes nothing returns nothing
    local location l
    if GetSpellAbilityId()=='A002' then
        call Gztm_func1(GetTriggerUnit(),GetSpellTargetLoc())
        call RemoveLocation(l)
    elseif GetSpellAbilityId()=='A000' then
        call Gztm_func0(GetTriggerUnit(),GetSpellTargetLoc())
        call RemoveLocation(l)
    endif
    set l=null
endfunction
[/codes]
回复

使用道具 举报

发表于 2008-11-10 11:41:23 | 显示全部楼层
把LZ的代码进行了缩进整理, 方便大家阅读.
回复

使用道具 举报

发表于 2009-2-8 17:42:59 | 显示全部楼层
为什么不可以保存..  一保存就提示错误,然后地图就变小了..
回复

使用道具 举报

发表于 2009-2-9 23:28:53 | 显示全部楼层
晕,我自己没好好看帖子啊
回复

使用道具 举报

发表于 2009-3-7 14:18:52 | 显示全部楼层
以前因为弹射的角度而麻痹了很久,现在看来,只考虑成4个面其实也挺真实的
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-4 11:09 , Processed in 0.215537 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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