level 1
首先是timerdatasystem... 下面每个函数都需要的
library TDS initializer TDS_init
globals
integer udg_Max = 0
integer array udg_Flu
integer udg_TDSid
timer array udg_Timer
boolean array udg_DS_Used //占用判定
real MOVETIMER_TIMEOUT=0.02 //移动函数循环时间
//_____________________可用数据______________________________
real array udg_DS_angle
real array udg_DS_speed
real array udg_DS_distance
real array udg_DS_x
real array udg_DS_y
real array udg_DS_speed_x
real array udg_DS_speed_y
integer array udg_DS_times
boolean array udg_DS_hastarget
player array udg_DS_player
effect array udg_DS_effect
string array udg_DS_effectPath
unit array udg_DS_whichUnit
//___________________________________________________________
endglobals
function CreateTimerId takes nothing returns integer
set udg_Max = udg_Max + 1
if udg_Flu[udg_Max] == 0 then
set udg_DS_Used[udg_Max] = true
return udg_Max
endif
set udg_DS_Used[udg_Flu[udg_Max]] = true
return udg_Flu[udg_Max]
endfunction
function GetTimerId takes nothing returns integer
return GetHandleId(GetExpiredTimer()) - udg_TDSid
endfunction
function DestroyTimerId takes integer tid returns nothing
if udg_DS_Used[tid] then //只对占用的id操作
call PauseTimer(udg_Timer[tid])
set udg_Flu[udg_Max] = tid
set udg_DS_Used[tid] = false
set udg_Max = udg_Max - 1
debug call BJDebugMsg("TimerIdMax="+I2S(udg_Max))
endif
endfunction
function TDS_init takes nothing returns nothing
local integer c = 1
local location l = Location(0,0)
set udg_TDSid = GetHandleId(l)
call RemoveLocation(l)
set l = null
loop
exitwhen c >= 8000
set udg_Timer[c] = CreateTimer()
set c = c + 1
endloop
endfunction
endlibrary
2011年03月09日 02点03分
1
level 1
只是个普通的移动函数
function Move_Action takes nothing returns nothing
local integer id=GetTimerId()
if udg_DS_effectPath[id]!=null then //特效在经过的位置创建
call DestroyEffect(AddSpecialEffect(udg_DS_effectPath[id],udg_DS_x[id],udg_DS_y[id]))
endif
set udg_DS_x[id]=udg_DS_x[id]+udg_DS_speed_x[id]
set udg_DS_y[id]=udg_DS_y[id]+udg_DS_speed_y[id]
if udg_DS_hastarget[id] then //拥有蝗虫技能
if IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_FLYABILITY) then
//不可通行停止移动
call DestroyTimerId(id)
else
//可通行直接移动
call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
if udg_DS_distance[id]<=0 then
call DestroyTimerId(id)
endif
endif
else
if IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_WALKABILITY) then
//不可通行停止移动
call DestroyTimerId(id)
else
//可通行直接移动
call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
if udg_DS_distance[id]<=0 then
call DestroyTimerId(id)
endif
endif
endif
endfunction
function Move takes unit u,real x,real y,real angle,real speed,real distance,string effpath returns nothing
//call Move(u,x,y,angle,speed,distance,effpath)
local integer id=CreateTimerId()
set udg_DS_speed[id]=speed*MOVETIMER_TIMEOUT //速度具体化
set udg_DS_whichUnit[id]=u
set udg_DS_x[id]=x
set udg_DS_y[id]=y
set udg_DS_angle[id]=angle
set udg_DS_distance[id]=distance
set udg_DS_speed_x[id]=udg_DS_speed[id]*Cos(angle) //x,y速度分量
set udg_DS_speed_y[id]=udg_DS_speed[id]*Sin(angle)
set udg_DS_effectPath[id]=effpath
set udg_DS_hastarget[id]=(GetUnitAbilityLevel(u,'Aloc')>0) //拥有蝗虫技能
call SetUnitX(u,x)
call SetUnitY(u,y)
call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function Move_Action)
endfunction
2011年03月09日 02点03分
2
为什么用destroytimer啊,那一开始新建的计时器不就被删掉了,以后不能用了么?
2014年03月11日 15点03分
回复 landvin :
![[委屈]](/static/emoticons/u59d4u5c48.png)
哎哟,眼拙了,DestroyTimerId那是之前的函数
2014年03月11日 15点03分
level 1
击退函数, 路径特效是花岗石怪的攻击投射物不可更改
function Back_Action takes nothing returns nothing
local integer id=GetTimerId()
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl",udg_DS_x[id],udg_DS_y[id]))
//特效在经过的位置创建
set udg_DS_x[id]=udg_DS_x[id]+udg_DS_speed_x[id]
set udg_DS_y[id]=udg_DS_y[id]+udg_DS_speed_y[id]
if not IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_WALKABILITY) then
//可通行直接移动
call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
if udg_DS_distance[id]<=0 then
call DestroyTimerId(id)
endif
else
//不可通行停止移动
call DestroyTimerId(id)
endif
endfunction
function Back takes unit u,real angle,real speed,real distance returns nothing
//call Back(u,angle,speed,distance)
local integer id
if not IsUnitType(u, UNIT_TYPE_ANCIENT) then //无法击退古树类单位
set id=CreateTimerId()
set udg_DS_speed[id]=speed*MOVETIMER_TIMEOUT //速度具体化
set udg_DS_whichUnit[id]=u
set udg_DS_x[id]=GetUnitX(u)
set udg_DS_y[id]=GetUnitY(u)
set udg_DS_angle[id]=angle
set udg_DS_distance[id]=distance
set udg_DS_speed_x[id]=udg_DS_speed[id]*Cos(angle) //x,y速度分量
set udg_DS_speed_y[id]=udg_DS_speed[id]*Sin(angle)
call SetUnitFacing(u,180+angle*bj_RADTODEG)
call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function Back_Action)
endif
endfunction
2011年03月09日 02点03分
3
level 1
另一个击退, 自己指定特效. 输入null则不创建特效
function BackEff_Action takes nothing returns nothing
local integer id=GetTimerId()
if udg_DS_effectPath[id]!=null then
call DestroyEffect(AddSpecialEffectTarget(udg_DS_effectPath[id],udg_DS_whichUnit[id],"origin"))
endif
//特效在单位身上创建
set udg_DS_x[id]=udg_DS_x[id]+udg_DS_speed_x[id]
set udg_DS_y[id]=udg_DS_y[id]+udg_DS_speed_y[id]
if not IsTerrainPathable(udg_DS_x[id], udg_DS_y[id], PATHING_TYPE_WALKABILITY) then
//可通行直接移动
call SetUnitX(udg_DS_whichUnit[id],udg_DS_x[id])
call SetUnitY(udg_DS_whichUnit[id],udg_DS_y[id])
set udg_DS_distance[id]=udg_DS_distance[id]-udg_DS_speed[id]
if udg_DS_distance[id]<=0 then
call DestroyTimerId(id)
endif
else
//不可通行停止移动
call DestroyTimerId(id)
endif
endfunction
function BackEff takes unit u,real angle,real speed,real distance,string effpath returns nothing
//call Back(u,angle,speed,distance)
local integer id
if not IsUnitType(u, UNIT_TYPE_ANCIENT) then //无法击退古树类单位
set id=CreateTimerId()
set udg_DS_speed[id]=speed*MOVETIMER_TIMEOUT //速度具体化
set udg_DS_whichUnit[id]=u
set udg_DS_x[id]=GetUnitX(u)
set udg_DS_y[id]=GetUnitY(u)
set udg_DS_angle[id]=angle
set udg_DS_distance[id]=distance
set udg_DS_speed_x[id]=udg_DS_speed[id]*Cos(angle) //x,y速度分量
set udg_DS_speed_y[id]=udg_DS_speed[id]*Sin(angle)
set udg_DS_effectPath[id]=effpath
call SetUnitFacing(u,180+angle*bj_RADTODEG)
call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function BackEff_Action)
endif
endfunction
2011年03月09日 02点03分
4
level 1
跳跃函数,从地面往高处跳,然后落下, 仅仅是跳跃, 没有改变位置的跳跃,
配合移动函数可以做向某方向的跳跃
function Jump_Action takes nothing returns nothing
local integer id=GetTimerId()
set udg_DS_distance[id]=udg_DS_distance[id]+udg_DS_speed[id] //速度改变高度
set udg_DS_speed[id]=udg_DS_speed[id]+udg_DS_angle[id] //加速度改变速度
call SetUnitFlyHeight(udg_DS_whichUnit[id],udg_DS_distance[id],0)
set udg_DS_times[id]=udg_DS_times[id]-1 //次数减1
if udg_DS_times[id]<=0 or GetUnitState(udg_DS_whichUnit[id],UNIT_STATE_LIFE)<=0 then
call SetUnitFlyHeight(udg_DS_whichUnit[id],GetUnitDefaultFlyHeight(udg_DS_whichUnit[id]),0)
call DestroyTimerId(id)
endif
endfunction
function Jump takes unit u,real height,real time returns nothing
//call Jump(u,height,time)
local integer id=CreateTimerId()
set udg_DS_whichUnit[id]=u
set udg_DS_times[id]=R2I(time/MOVETIMER_TIMEOUT)
set udg_DS_angle[id]=-height*8/time/time*MOVETIMER_TIMEOUT*MOVETIMER_TIMEOUT //设置加速度(运动过程中为常量) 向下为负
set udg_DS_speed[id]=height*4/time*MOVETIMER_TIMEOUT //设置当前速度(向上为正方向,不断变化)
set udg_DS_distance[id]=GetUnitDefaultFlyHeight(u) //设置初始高度(不断变化)
if UnitAddAbility(u,'Amrf') then
call UnitRemoveAbility(u,'Amrf')
endif
call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function Jump_Action)
endfunction
2011年03月09日 02点03分
5
level 1
function JumpDown_Action takes nothing returns nothing
local integer id=GetTimerId()
set udg_DS_distance[id]=udg_DS_distance[id]+udg_DS_speed[id] //速度改变高度
set udg_DS_speed[id]=udg_DS_speed[id]+udg_DS_angle[id] //加速度改变速度
call SetUnitFlyHeight(udg_DS_whichUnit[id],udg_DS_distance[id],0)
set udg_DS_times[id]=udg_DS_times[id]-1 //次数减1
if udg_DS_times[id]<=0 or GetUnitState(udg_DS_whichUnit[id],UNIT_STATE_LIFE)<=0 then
call SetUnitFlyHeight(udg_DS_whichUnit[id],GetUnitDefaultFlyHeight(udg_DS_whichUnit[id]),0)
call DestroyTimerId(id)
endif
endfunction
从最高点往下跳.. 自由落体, 配合移动函数就是平抛运动
function JumpDown takes unit u,real height,real time returns nothing
//call JumpDown(u,height,time)
local integer id=CreateTimerId()
set udg_DS_whichUnit[id]=u
set udg_DS_times[id]=R2I(time/MOVETIMER_TIMEOUT)
set udg_DS_angle[id]=-height*2/time/time*MOVETIMER_TIMEOUT*MOVETIMER_TIMEOUT //设置加速度(运动过程中为常量) 向下为负
set udg_DS_speed[id]=0 //设置当前速度(向上为正方向,不断变化)
set udg_DS_distance[id]=height //设置初始高度(不断变化)
call TimerStart(udg_Timer[id],MOVETIMER_TIMEOUT,true,function JumpDown_Action)
endfunction
2011年03月09日 02点03分
6
level 1
//普通的移动类函数
//call Move(u,x,y,angle,speed,distance,effpath) //普通移动函数(可带轨迹特效)
//call Back(u,angle,speed,distance) //普通击退函数(自带轨迹特效)
//call BackEff(u,angle,speed,distance,effpath) //普通击退函数(指定特效)
//call Jump(u,height,time) //普通跳跃函数
//call JumpDown(u,height,time) //从高处跳下
// u单位 x,y坐标 angle方向(弧度制) speed速度(距离/秒) distance距离
// effpath轨迹特效 height高度 time所需时间
2011年03月09日 02点03分
7
level 1
timer data system 就是用全局数组变量储存数据的
可以同时支持8192个timer同时运行.所以不用担心多人使用的问题... 而且效率很高
2011年03月09日 08点03分
9
level 15
全局数组效率的确高,但是发函数的全局还是globals新建吧否则看得不太直观
2011年03月09日 23点03分
10
level 15
额搞错…应该说为什么都加了一堆udg_,没有替换功能就是麻烦。
2011年03月09日 23点03分
11
level 15
判断可通行方面还是用布尔建造方法比较理想,直接判定通行卡装饰物卡单位。
接下来是击退一直以来存在的难点,即判定不可击退地区,比如悬崖、树木、水域、单位等等,无视这些的话会导致被击退单位卡住无法动弹。以 前的方法是设置一个“探路者”的角色先行移动,并匹配“探路者”的实际坐标与所要移动的坐标是否一致,不一致的话就停止击退,这个方法虽然能解决判定问 题,但是效率的话仍稍有欠缺。因此在这里感谢<大师与天才>前不久发明的布尔值建造法,能更高效且巧妙地完成这个判断。原理:1、发布命令给单位会返回一个成功与否的布尔值。2、建造单位(不是建筑)需要所建造区域符合单位的移动类型与触碰。3、拥有“幽灵”的单位不会阻碍单位的建造。
2011年03月09日 23点03分
12