|
已经有点对移动单位这种东西没兴趣了…………
(被自己忍无可忍的和谐掉了)
不说了……
可以实现:Dota:裂魂人的加速冲刺、屠夫钩锁的一部分效果
(效果相反的迅速远离可以通过设置速度为负数来达到)
更新了更新了~~2009.2.21更新了~~
代码:
[codes=jass]globals
gamecache Chase_GC = null
//游戏缓存
integer Chase_Data_Int = 0
real Chase_Data_Real = 0.0
boolean Chase_Data_Bool = false
string Chase_Data_Str = null
real Chase_X = 0.0
real Chase_Y = 0.0
real Chase_speed = 0.0
real Chase_speed_add = 0.0
real Chase_radius = 0.0
unit Chase_Target = null
group Chase_TheGroup = null
timer Chase_TheTimer = null
group Chase_GetGroup = null
//对code-action的辅助参数。
boolean Chase_CanAttack = false
boolean Chase_IsFacing = false
//内部辅助参数。
endglobals
//Copy这个
function ChaseInit takes nothing returns nothing
call FlushGameCache(InitGameCache( "Chase.w3v" ))
set Chase_GC = InitGameCache( "Chase.w3v" )
set Chase_GetGroup = CreateGroup()
endfunction
//你把Chase_GC设置成你的GameCache(推荐)或者这样都可以(但你要保证Chase_GC不为空)
//必须将Chase_GetGroup设置为一个非空group
function H2I takes handle h returns integer
return h
return 0
endfunction
function I2U takes integer i returns unit
return i
return null
endfunction
function I2G takes integer i returns group
return i
return null
endfunction
function I2BE takes integer i returns boolexpr
return i
return null
endfunction
function C2I takes code c returns integer
return c
return 0
endfunction
function I2C takes integer i returns code
return i
return null
endfunction
function DistanceBetweenLocs takes real x1, real y1, real x2, real y2 returns real
local real dx = x2 - x1
local real dy = y2 - y1
return SquareRoot( dx * dx + dy * dy )
endfunction
function AngleBetweenTwoLocs2Angle_Second takes real x1, real y1, real x2, real y2 returns real
return bj_RADTODEG * Atan2( y2 - y1, x2 - x1) + 180.0
endfunction
function ChaseAbility_Flush takes timer ti, string ti_s, boolean destroy, group g returns nothing
if destroy then
call PauseTimer( ti )
call DestroyTimer( ti )
call DestroyGroup( g )
call FlushStoredMission( Chase_GC, ti_s )
endif
endfunction
function ChaseAbility_Move takes nothing returns nothing
local unit u = GetEnumUnit()
local real x = GetUnitX( u )
local real y = GetUnitY( u )
local real distance = DistanceBetweenLocs( x, y, Chase_X, Chase_Y )
local real angle = AngleBetweenTwoLocs2Angle_Second( Chase_X, Chase_Y, x, y )
if distance <= Chase_speed or distance <= Chase_radius then
set x = Chase_X
set y = Chase_Y
set Chase_CanAttack = true
call GroupAddUnit( Chase_GetGroup, u )
else
set x = x + Chase_speed * Cos( angle * bj_DEGTORAD )
set y = y + Chase_speed * Sin( angle * bj_DEGTORAD )
endif
if Chase_IsFacing then
call SetUnitFacing( u, angle )
endif
call SetUnitX( u, x )
call SetUnitY( u, y )
set u = null
endfunction
function ChaseAbility_Action takes nothing returns nothing
local timer ti = GetExpiredTimer()
local string ti_s = I2S(H2I( ti ))
local unit u = I2U( GetStoredInteger( Chase_GC, ti_s, "target" ) )
local real x = GetStoredReal( Chase_GC, ti_s, "target_x" )
local real y = GetStoredReal( Chase_GC, ti_s, "target_y" )
local group g = I2G( GetStoredInteger( Chase_GC, ti_s, "group" ) )
local real timeout = GetStoredReal( Chase_GC, ti_s, "timeout" )
local real elapsed = GetStoredReal( Chase_GC, ti_s, "elapsed" )
local real time = GetStoredReal( Chase_GC, ti_s, "time" )
local real action_time = GetStoredReal( Chase_GC, ti_s, "time_group_action_run" )
local real speed = GetStoredReal( Chase_GC, ti_s, "speed" )
local real speed_add = GetStoredReal( Chase_GC, ti_s, "speed_add" )
local code chase_c = I2C( GetStoredInteger( Chase_GC, ti_s, "chase_group_action" ) )
local code target_c = I2C( GetStoredInteger( Chase_GC, ti_s, "target_action" ) )
local boolean destroy = GetStoredBoolean( Chase_GC, ti_s, "destroy" )
local boolean stop = GetStoredBoolean( Chase_GC, ti_s, "stop" )
local real radius = GetStoredReal( Chase_GC, ti_s, "getradius" )
local boolean IsFacing = GetStoredBoolean( Chase_GC, ti_s, "facing" )
if elapsed < time or time <= 0.0 then
if u != null then
set x = GetUnitX( u )
set y = GetUnitY( u )
endif
set Chase_Target = u
set Chase_X = x
set Chase_Y = y
set Chase_radius = radius
set Chase_speed = speed
set Chase_speed_add = speed_add
set Chase_CanAttack = false
set Chase_IsFacing = IsFacing
call GroupClear( Chase_GetGroup )
call ForGroup( g, function ChaseAbility_Move )
set Chase_TheGroup = g
set Chase_TheTimer = ti
set Chase_speed = speed / timeout
set Chase_speed_add = speed_add / timeout
if chase_c != null and ModuloReal( elapsed, action_time ) == 0.0 then
set Chase_Data_Int = GetStoredInteger( Chase_GC, ti_s, "help" )
set Chase_Data_Real = GetStoredReal( Chase_GC, ti_s, "help" )
set Chase_Data_Bool = GetStoredBoolean( Chase_GC, ti_s, "help" )
set Chase_Data_Str = GetStoredString( Chase_GC, ti_s, "help" )
call ForGroup( g, chase_c )
endif
call StoreReal( Chase_GC, ti_s, "elapsed", elapsed + timeout )
if Chase_CanAttack and target_c != null then
call ForGroup( Chase_GetGroup, target_c )
endif
call StoreReal( Chase_GC, ti_s, "speed_add", Chase_speed_add * timeout )
call StoreReal( Chase_GC, ti_s, "speed", Chase_speed * timeout + Chase_speed_add * timeout )
call StoreReal( Chase_GC, ti_s, "getradius", Chase_radius )
call GroupRemoveGroup( Chase_GetGroup, g )
call StoreInteger( Chase_GC, ti_s, "help", Chase_Data_Int )
call StoreReal( Chase_GC, ti_s, "help", Chase_Data_Real )
call StoreBoolean( Chase_GC, ti_s, "help", Chase_Data_Bool )
call StoreString( Chase_GC, ti_s, "help", Chase_Data_Str )
set Chase_Data_Int = 0
set Chase_Data_Real = 0.0
set Chase_Data_Bool = false
set Chase_Data_Str = null
set Chase_TheGroup = null
set Chase_TheTimer = null
if (stop and Chase_CanAttack) or FirstOfGroup( g ) == null then
call ChaseAbility_Flush( ti, ti_s, destroy, g )
endif
//-------------------------
set Chase_Target = null
set Chase_X = 0.0
set Chase_Y = 0.0
set Chase_radius = 0.0
set Chase_speed = 0.0
set Chase_speed_add = 0.0
set Chase_CanAttack = false
set Chase_IsFacing = false
call GroupClear( Chase_GetGroup )
else
call ChaseAbility_Flush( ti, ti_s, destroy, g )
endif
set u = null
set g = null
set chase_c = null
set target_c = null
set ti_s = null
set ti = null
endfunction
function ChaseAbility takes timer TheTimer, unit target, real x, real y, group g, real getradius, real timeout, real maxtime, real speed, real speed_add, real time_group_action_run, boolean destroy, boolean stopwhen_firstunit_hit_target, boolean Isfacing, code chase_group_action, code target_action returns nothing
local timer ti = null
local string ti_s = null
if TheTimer == null then
set ti = CreateTimer()
else
set ti = TheTimer
endif
set ti_s = I2S(H2I( ti ))
call StoreInteger( Chase_GC, ti_s, "help", Chase_Data_Int )
call StoreReal( Chase_GC, ti_s, "help", Chase_Data_Real )
call StoreBoolean( Chase_GC, ti_s, "help", Chase_Data_Bool )
call StoreString( Chase_GC, ti_s, "help", Chase_Data_Str )
if target != null then
call StoreInteger( Chase_GC, ti_s, "target", H2I( target ) )
else
call StoreReal( Chase_GC, ti_s, "target_x", x )
call StoreReal( Chase_GC, ti_s, "target_y", y )
endif
call StoreInteger( Chase_GC, ti_s, "group", H2I( g ) )
call StoreReal( Chase_GC, ti_s, "speed", speed * timeout )
call StoreReal( Chase_GC, ti_s, "speed_add", speed_add * timeout )
call StoreReal( Chase_GC, ti_s, "getradius", getradius )
call StoreReal( Chase_GC, ti_s, "time", maxtime )
call StoreReal( Chase_GC, ti_s, "timeout", timeout )
call StoreReal( Chase_GC, ti_s, "time_group_action_run", time_group_action_run )
call StoreInteger( Chase_GC, ti_s, "chase_group_action", C2I( chase_group_action ) )
call StoreInteger( Chase_GC, ti_s, "target_action", C2I( target_action ) )
call StoreBoolean( Chase_GC, ti_s, "destroy", destroy )
call StoreBoolean( Chase_GC, ti_s, "facing", Isfacing )
call StoreBoolean( Chase_GC, ti_s, "stop", stopwhen_firstunit_hit_target )
call TimerStart( ti, timeout, true, function ChaseAbility_Action )
set ti_s = null
set ti = null
endfunction[/codes]
函数说明:
更新:timer TheTimer 用来计时的Timer(如果为null则函数自动创建一个)
unit target 被追击的目标(可以设为null,但x和y必需)
real x 目标点的X坐标(若x和y设为无意义值,则单位必需)
real y 目标点的Y坐标(若x和y设为无意义值,则单位必需)
group g 追击的一群/个人
real getradius 当距离小于getradius时,算是追上了目标
real timeout 每多少秒位移
real maxtime 最多追击多少秒(设为负数,永久追击)
real speed 初始追击速度(距离/秒)
real speed_add 加速度(速度/秒)
real time_group_action_run 每多少秒运行chase_group_action(此real必须为timeout倍数)
boolean destroy 是否在停止后删除group(更新:如果设为false,则Timer也会保留,并且不会清空Timer的缓存内容,反之则清除timer)
boolean stopwhen_firstunit_hit_target 是否停止在【追击单位中的第一波单位追上了目标】
更新:boolean Isfacing 设置是否让追击的单位朝向被追击者
code chase_group_action 一个函数:在追击过程中运行
code target_action 当每一个单位追上目标时,运行此函数。
以上两个函数说明:
GetEnumUnit():获得追击的单位
你可以在调用ChaseAbility之前设置这四个全局变量:
[codes=jass] integer Chase_Data_Int = 0
real Chase_Data_Real = 0.0
boolean Chase_Data_Bool = false
string Chase_Data_Str = null[/codes]
然后,当这个action执行时,这四个全局变量储存的值就是你赋给他们的值(如果没赋值则是默认的0/0.0/false/null)。
在action运行中,可以为这四个全局变量赋值
action执行后,这四个全局变量值将传递给下一个被牵引单位运行的action。
这一次所有的单位action全部运行完毕后,这四个全局变量值将被存储起来,再下一次运行时,四个全局变量的值就是上一次赋的值。
注意!当运行完ChaseAbility后,这四个全局变量就会被自动清空。
这两个函数的全局变量参数说明:
real Chase_X = 0.0 目标的X坐标
real Chase_Y = 0.0 目标的Y坐标
real Chase_speed = 0.0 追击的速度(已包括加速度,是按距离/秒来算的)
real Chase_speed_add = 0.0 追击的加速度(是按速度/秒来算的)
real Chase_radius = 0.0 能算是追上了的半径范围
unit Chase_Target = null 目标
更新:
group Chase_TheGroup = null 追击单位组(其中不包含已追上的)
timer Chase_TheTimer = null 用来计时的Timer
group Chase_GetGroup = null 追上的单位组
特殊说明:
Chase_GetGroup 应是一个常量,也就是说,你只能引用它里面的单位,对他ForGroup遍历单位,但绝不可以GroupClear什么对Group本身的动作、对它用GroupRemoveXX和GroupAddXX,也是一种高危行为。至于设置它为空,那你就祈祷在你把它又一次赋以一个group之前,不会因你的技能而魔兽崩坏就是了。
更新:特殊说明(可以说是指导):
你现在可以先创建一个自己的TheTimer,然后用ReturnBug+GameCache为它存储自定义的值了,在code执行时,你可以从Chase_TheTimer获得你的TheTimer,最后……这些存储的数据你就可以读取了。也就是说,你现在可以有无数个自定义值了。
有些危险,但一个很好的东东:
在<GameCache>, <Timer Handle String>的目录(GameCache中)下,
你可以改动/引用这些string key中的值:
integer(unit) "target" : 你可以在中途改变目标(H2I)
real "target_x" : 你可以在中途改变目标点(与目标不是一回事)的X坐标
real "target_y" : 你可以在中途改变目标点(与目标不是一回事)的Y坐标
integer(group) "group" : 你可以在中途改变追击的单位们(H2I)
real "timeout" : 你可以在中途改变运行时间的间隔(不幸的是,这只是认为而已,真正的timer运行间隔不是按这个来的)
real "elapsed" : 你可以在中途改变已运行时间
real "time" : 你可以在中途改变总运行时间
real "time_group_action_run" : 你可以在中途改变在追击过程中运行的函数运行间隔
real "speed" : 你可以在中途改变速度(距离/秒*间隔),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
real "speed_add" : 你可以在中途改变加速度(速度/秒*间隔),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
integer(code) "chase_group_action" : 你可以在中途改变在追击过程中运行的函数(C2I)
integer(code) "target_action" : 你可以在中途改变追击到后运行的函数(C2I)
boolean "destroy" : 你可以在中途改变是否删除Group和Timer并清除Timer的缓存
boolean "stop" : 你可以在中途改变是否停止在【追击单位中的第一波单位追上了目标】
real "getradius" : 你可以在中途改变算是追击到的距离。
boolean "facing" : 你可以在中途改变是否让追击的单位朝向被追击者。
好吧,我承认在模板code中,我又进步了一步……~~
更新:特殊说明:
你可以在code中设置Chase_speed和Chase_radius,然后这两个量就会在下一次timer执行时起作用。
截图:无(我没有动态截图的工具)
希望大家多多支持我~~有Bug一定要回帖/发短消息给我这个帐号~~
最后,照例为我的JASS技能教程求精~~
最后的最后,哀叹:为什么没人给我的技能模板奖励呢?为啥呢? |
评分
-
查看全部评分
|