|
群体技能模板,它的特点在于使用者可以通过code变量(即无参数函数指针)和自定义integer、real、boolean、string(各一个)来对单位做任何事情。
(被自己忍无可忍的和谐掉了)
更新啦~~2009.2.22更新啦~~
代码:
[codes=jass]globals
gamecache Rebound_GC = null
//游戏缓存
integer Rebound_Data_Int = 0
real Rebound_Data_Real = 0.0
boolean Rebound_Data_Bool = false
string Rebound_Data_Str = null
integer Rebound_Data_Num = 0
unit Rebound_TheNextTarget = null
real Rebound_MoveSpeed = 0.0
group Rebound_TheGroup = null
group Rebound_TargetGroup = null
timer Rebound_TheTimer = null
boolexpr Rebound_TheCond = null
//对code-action的辅助参数。
endglobals
//Copy这个
function ReboundInit takes nothing returns nothing
call FlushGameCache(InitGameCache( "Rebound.w3v" ))
set Rebound_GC = InitGameCache( "Rebound.w3v" )
endfunction
//你把Rebound_GC设置成你的GameCache(推荐)或者这样都可以(但你要保证Rebound_GC不为空)
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 I2LI takes integer i returns lightning
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
//以上是基础函数,如果有,就不用copy了
//Copy以下所有函数
function ReboundAbility_Flush takes timer ti, string ti_s returns nothing
if GetStoredBoolean( Rebound_GC, ti_s, "destroy" ) then
call PauseTimer( ti )
call DestroyTimer( ti )
call DestroyBoolExpr( I2BE( GetStoredInteger( Rebound_GC, ti_s, "condition" ) ) )
call DestroyGroup( I2G( GetStoredInteger( Rebound_GC, ti_s, "g" ) ) )
call DestroyGroup( I2G( GetStoredInteger( Rebound_GC, ti_s, "targetgroup" ) ) )
call RemoveUnit( I2U( GetStoredInteger( Rebound_GC, ti_s, "mov_u" ) ) )
call DestroyLightning( I2LI( GetStoredInteger( Rebound_GC, ti_s, "lightning" ) ) )
call FlushStoredMission( Rebound_GC, ti_s )
endif
endfunction
function ReboundAbility_Change takes timer ti, unit target, real x, real y, string ti_s, integer num, unit mov_u, real mov_speed, lightning light, real light_z returns nothing
local real radius = GetStoredReal( Rebound_GC, ti_s, "radius" )
local group g = I2G( GetStoredInteger( Rebound_GC, ti_s, "g" ) )
local string targeteffectpath = GetStoredString( Rebound_GC, ti_s, "targeteffectpath" )
local string targeteffectpoint = GetStoredString( Rebound_GC, ti_s, "targeteffectpoint" )
local string targetpointeffectpath = GetStoredString( Rebound_GC, ti_s, "targetpointeffectpath" )
local boolexpr be = I2BE( GetStoredInteger( Rebound_GC, ti_s, "condition" ) )
local code c = I2C( GetStoredInteger( Rebound_GC, ti_s, "action" ) )
local effect e = null
local unit next = null
local group targetgroup = I2G( GetStoredInteger( Rebound_GC, ti_s, "targetgroup" ) )
local real timeout = GetStoredReal( Rebound_GC, ti_s, "timeout" )
if targeteffectpath != null then
set e = AddSpecialEffectTarget( targeteffectpath, target, targeteffectpoint )
call DestroyEffect( e )
set e = null
endif
if targetpointeffectpath != null then
set e = AddSpecialEffect( targetpointeffectpath, x, y )
call DestroyEffect( e )
set e = null
endif
call GroupClear( g )
call GroupEnumUnitsInRange( g, x, y, radius, be )
if targetgroup != null then
call GroupRemoveGroup( targetgroup, g )
endif
call GroupRemoveUnit( g, target )
set next = GroupPickRandomUnit( g )
if next != null and num - 1 > 0 then
if targetgroup != null then
call GroupAddUnit( targetgroup, next )
endif
call StoreInteger( Rebound_GC, ti_s, "target", H2I( next ) )
call StoreInteger( Rebound_GC, ti_s, "source", H2I( target ) )
call StoreReal( Rebound_GC, ti_s, "source_x", x )
call StoreReal( Rebound_GC, ti_s, "source_y", y )
call StoreReal( Rebound_GC, ti_s, "target_x", GetUnitX( next ) )
call StoreReal( Rebound_GC, ti_s, "target_y", GetUnitY( next ) )
if light != null then
call MoveLightningEx( light, false, x, y, light_z, GetUnitX( next ), GetUnitY( next ), light_z )
endif
call StoreInteger( Rebound_GC, ti_s, "number", num - 1 )
call StoreInteger( Rebound_GC, ti_s, "attnumber", GetStoredInteger( Rebound_GC, ti_s, "attnumber" ) + 1 )
if mov_u != null then
call SetUnitFacing( mov_u, AngleBetweenTwoLocs2Angle_Second( GetUnitX( next ), GetUnitY( next ), x, y ) )
endif
if c != null then
call GroupClear( g )
call GroupAddUnit( g, target )
set Rebound_Data_Int = GetStoredInteger( Rebound_GC, ti_s, "help" )
set Rebound_Data_Real = GetStoredReal( Rebound_GC, ti_s, "help" )
set Rebound_Data_Bool = GetStoredBoolean( Rebound_GC, ti_s, "help" )
set Rebound_Data_Str = GetStoredString( Rebound_GC, ti_s, "help" )
set Rebound_Data_Num = GetStoredInteger( Rebound_GC, ti_s, "attnumber" )
set Rebound_TheNextTarget = next
set Rebound_MoveSpeed = mov_speed / timeout
set Rebound_TheGroup = g
set Rebound_TargetGroup = targetgroup
set Rebound_TheTimer = ti
set Rebound_TheCond = be
call ForGroup( g, c )
call StoreInteger( Rebound_GC, ti_s, "help", Rebound_Data_Int )
call StoreReal( Rebound_GC, ti_s, "help", Rebound_Data_Real )
call StoreBoolean( Rebound_GC, ti_s, "help", Rebound_Data_Bool )
call StoreString( Rebound_GC, ti_s, "help", Rebound_Data_Str )
call StoreInteger( Rebound_GC, ti_s, "attnumber", Rebound_Data_Num )
call StoreReal( Rebound_GC, ti_s, "mov_speed", Rebound_MoveSpeed * timeout )
if next != Rebound_TheNextTarget then
set next = Rebound_TheNextTarget
call StoreInteger( Rebound_GC, ti_s, "target", H2I( next ) )
call StoreReal( Rebound_GC, ti_s, "target_x", GetUnitX( next ) )
call StoreReal( Rebound_GC, ti_s, "target_y", GetUnitY( next ) )
endif
if Rebound_TheGroup != g then
set g = Rebound_TheGroup
call StoreInteger( Rebound_GC, ti_s, "g", H2I( g ) )
endif
if Rebound_TargetGroup != targetgroup then
set targetgroup = Rebound_TargetGroup
call StoreInteger( Rebound_GC, ti_s, "targetgroup", H2I( targetgroup ) )
endif
if Rebound_TheCond != be then
set be = Rebound_TheCond
call StoreInteger( Rebound_GC, ti_s, "condition", H2I( be ) )
endif
set Rebound_Data_Int = 0
set Rebound_Data_Real = 0.0
set Rebound_Data_Bool = false
set Rebound_Data_Str = null
set Rebound_Data_Num = 0
set Rebound_TheNextTarget = null
set Rebound_MoveSpeed = 0.0
set Rebound_TheGroup = null
set Rebound_TargetGroup = null
set Rebound_TheTimer = null
set Rebound_TheCond = null
endif
call GroupClear( g )
call GroupAddUnit( g, next )
else
call ReboundAbility_Flush( ti, ti_s )
endif
set g = null
set targeteffectpath = null
set targeteffectpoint = null
set targetpointeffectpath = null
set be = null
set e = null
set c = null
set next = null
set targetgroup = null
endfunction
function ReboundAbility_Target takes timer ti, string ti_s, integer num returns nothing
local unit target = I2U( GetStoredInteger( Rebound_GC, ti_s, "target" ) )
local real attackradius = GetStoredReal( Rebound_GC, ti_s, "getattackradius" )
local real mov_speed = GetStoredReal( Rebound_GC, ti_s, "mov_speed" )
local real x = GetStoredReal( Rebound_GC, ti_s, "x" )
local real y = GetStoredReal( Rebound_GC, ti_s, "y" )
local real u_x = GetUnitX( target )
local real u_y = GetUnitY( target )
local real distance = DistanceBetweenLocs( x, y, u_x, u_y )
local real angle = AngleBetweenTwoLocs2Angle_Second( u_x, u_y, x, y )
local unit mov_u = I2U( GetStoredInteger( Rebound_GC, ti_s, "mov_u" ) )
local lightning light = I2LI( GetStoredInteger( Rebound_GC, ti_s, "lightning" ) )
local real light_z = GetStoredReal( Rebound_GC, ti_s, "lightning_z" )
local unit source = I2U( GetStoredInteger( Rebound_GC, ti_s, "source" ) )
if target == null then
set u_x = GetStoredReal( Rebound_GC, ti_s, "target_x" )
set u_y = GetStoredReal( Rebound_GC, ti_s, "target_y" )
set distance = DistanceBetweenLocs( x, y, u_x, u_y )
set angle = AngleBetweenTwoLocs2Angle_Second( u_x, u_y, x, y )
endif
if distance <= mov_speed then
set distance = 0.0
else
set x = x + mov_speed * Cos( angle * bj_DEGTORAD )
set y = y + mov_speed * Sin( angle * bj_DEGTORAD )
set distance = DistanceBetweenLocs( x, y, u_x, u_y )
endif
if distance <= attackradius then
call StoreReal( Rebound_GC, ti_s, "x", u_x )
call StoreReal( Rebound_GC, ti_s, "y", u_y )
if mov_u != null then
call SetUnitX( mov_u, u_x )
call SetUnitY( mov_u, u_y )
endif
call ReboundAbility_Change( ti, target, u_x, u_y, ti_s, num, mov_u, mov_speed, light, light_z )
else
call StoreReal( Rebound_GC, ti_s, "x", x )
call StoreReal( Rebound_GC, ti_s, "y", y )
if target != null then
call StoreReal( Rebound_GC, ti_s, "target_x", u_x )
call StoreReal( Rebound_GC, ti_s, "target_y", u_y )
endif
if source != null then
call StoreReal( Rebound_GC, ti_s, "source_x", GetUnitX( source ) )
call StoreReal( Rebound_GC, ti_s, "source_y", GetUnitY( source ) )
endif
if mov_u != null then
call SetUnitX( mov_u, x )
call SetUnitY( mov_u, y )
call SetUnitFacing( mov_u, angle )
endif
if light != null then
if source != null then
call MoveLightningEx( light, false, GetUnitX( source ), GetUnitY( source ), light_z, u_x, u_y, light_z )
else
call MoveLightningEx( light, false, GetStoredReal( Rebound_GC, ti_s, "source_x" ), GetStoredReal( Rebound_GC, ti_s, "source_y" ), light_z, u_x, u_y, light_z )
endif
endif
endif
set target = null
set light = null
set mov_u = null
set source = null
endfunction
function ReboundAbility_Action takes nothing returns nothing
local timer ti = GetExpiredTimer()
local string ti_s = I2S(H2I( ti ))
local integer num = GetStoredInteger( Rebound_GC, ti_s, "number" )
if num <= 0 then
call ReboundAbility_Flush( ti, ti_s )
else
call ReboundAbility_Target( ti, ti_s, num )
endif
set ti = null
set ti_s = null
endfunction
function ReboundAbility takes timer TheTimer, unit source, real x, real y, unit target, integer number, real timeout, real getattackradius, real radius, unit mov_u, boolean mov_u_IsMissile, real mov_speed, string lightningpath, real lightningz, string targeteffectpath, string targeteffectpoint, string targetpointeffectpath, boolean CanEcho, boolean destroy, boolexpr condition, code action returns nothing
local timer ti = null
local string ti_s = null
local group g = CreateGroup()
local group g2 = null
if TheTimer == null then
set ti = CreateTimer()
else
set ti = TheTimer
endif
set ti_s = I2S(H2I( ti ))
call GroupAddUnit( g, target )
call StoreReal( Rebound_GC, ti_s, "x", x )
call StoreReal( Rebound_GC, ti_s, "y", y )
if source != null then
call StoreInteger( Rebound_GC, ti_s, "source", H2I( source ) )
endif
call StoreReal( Rebound_GC, ti_s, "source_x", x )
call StoreReal( Rebound_GC, ti_s, "source_y", y )
call StoreReal( Rebound_GC, ti_s, "target_x", GetUnitX( target ) )
call StoreReal( Rebound_GC, ti_s, "target_y", GetUnitY( target ) )
call StoreInteger( Rebound_GC, ti_s, "target", H2I( target ) )
call StoreInteger( Rebound_GC, ti_s, "g", H2I( g ) )
call StoreReal( Rebound_GC, ti_s, "getattackradius", getattackradius )
call StoreReal( Rebound_GC, ti_s, "radius", radius )
call StoreInteger( Rebound_GC, ti_s, "number", number )
call StoreInteger( Rebound_GC, ti_s, "attnumber", 1 )
call StoreReal( Rebound_GC, ti_s, "mov_speed", mov_speed * timeout )
call StoreReal( Rebound_GC, ti_s, "timeout", timeout )
call StoreBoolean( Rebound_GC, ti_s, "destroy", destroy )
if mov_u != null then
call StoreInteger( Rebound_GC, ti_s, "mov_u", H2I( mov_u ) )
if mov_u_IsMissile then
call UnitAddAbility( mov_u, 'Aloc' )
call SetUnitPathing( mov_u, false )
call SetUnitInvulnerable( mov_u, true )
call SetUnitUseFood( mov_u, false )
call PauseUnit( mov_u, true )
endif
endif
if lightningpath != null and lightningpath != "" then
call StoreInteger( Rebound_GC, ti_s, "lightning", H2I( AddLightningEx( lightningpath, false, x, y, lightningz, GetUnitX( target ), GetUnitY( target ), lightningz ) ) )
call StoreReal( Rebound_GC, ti_s, "lightning_z", lightningz )
endif
if targeteffectpath != null and targeteffectpath != "" then
call StoreString( Rebound_GC, ti_s, "targeteffectpath", targeteffectpath )
call StoreString( Rebound_GC, ti_s, "targeteffectpoint", targeteffectpoint )
endif
if targetpointeffectpath != null and targetpointeffectpath != "" then
call StoreString( Rebound_GC, ti_s, "targetpointeffectpath", targetpointeffectpath )
endif
if not CanEcho then
set g2 = CreateGroup()
call StoreInteger( Rebound_GC, ti_s, "targetgroup", H2I( g2 ) )
call GroupAddUnit( g2, target )
set g2 = null
endif
call StoreInteger( Rebound_GC, ti_s, "condition", H2I( condition ) )
call StoreInteger( Rebound_GC, ti_s, "action", C2I( action ) )
call StoreInteger( Rebound_GC, ti_s, "help", Rebound_Data_Int )
call StoreReal( Rebound_GC, ti_s, "help", Rebound_Data_Real )
call StoreBoolean( Rebound_GC, ti_s, "help", Rebound_Data_Bool )
call StoreString( Rebound_GC, ti_s, "help", Rebound_Data_Str )
set Rebound_Data_Int = 0
set Rebound_Data_Real = 0.0
set Rebound_Data_Bool = false
set Rebound_Data_Str = null
call TimerStart( ti, timeout, true, function ReboundAbility_Action )
set ti = null
set g = null
set g2 = null
set ti_s = null
endfunction[/codes]
使用者手册:
通过ReboundAbility函数开始弹射。
ReboundAbility参数:
更新:timer TheTimer 用来计时的Timer(如果为null则函数自动创建一个)
unit source 开始的单位(可以设为null,但x和y必需)
real x 开始的地点的X坐标(若x和y设为无意义值,但单位必需)
real y 开始的地点的Y坐标(若x和y设为无意义值,但单位必需)
(优先引用的数据是source的数据,source的优先值高)
unit target
(开始的目标,不受后面的radius限制)
integer number
(弹射几次)
real timeout
(位移的间隔)
real getattackradius
(进入多少半径,算是攻击到目标)
real radius
(选取多少半径内的单位,算是下一个目标的候补(下一个目标它们中产生))
unit mov_u
(伴随位移的单位)
更新:boolean mov_u_IsMissile
(设置mov_u,是否是用来模拟投射物的,true则函数自动初始化它)
real mov_speed
(位移的速率(按距离/秒算))
string lightningpath
(闪电效果的路径)
real lightningz
(闪电的高度)
string targeteffectpath
(当击中目标时,对目标添加的特殊效果)
string targeteffectpoint
(当击中目标时,对目标添加的特殊效果在目标的哪一个附加点上)
string targetpointeffectpath
(当击中目标时,对目标的点添加的特殊效果)
boolean CanEcho
(被击中的单位是否可以再被击中)
更新:boolean destroy
(是否在所有弹射结束后删除condition、group和timer,并且清空timer的缓存)
boolexpr condition
(选取目标候补的条件,请勿在这里写上本应是动作的代码)
code action
(击中目标后执行这一code)
对于action的特殊说明:
在action中调用函数:
GetEnumUnit(),得到这个被击中的目标。
你可以在调用ReboundAbility之前设置这四个全局变量:
[codes=jass] integer Rebound_Data_Int = 0
real Rebound_Data_Real = 0.0
boolean Rebound_Data_Bool = false
string Rebound_Data_Str = null[/codes]
然后,当这个action执行时,这四个全局变量储存的值就是你赋给他们的值(如果没赋值则是默认的0/0.0/false/null)。
你可以在action执行时为他们赋值,下一次action执行时,这些全局变量就是你赋给他们的值。
注意!当运行完ReboundAbility后,这四个全局变量就会被自动清空。
当action执行时,Rebound_Data_Num这个全局变量,储存的是这是第几个被弹射击中的目标。
(更新:你可以赋值给他并在下一次action时引用,但是无法改变这个弹射技能弹多少次)
更新:
action的全局变量参数(半新半旧):
unit Rebound_TheNextTarget = 当弹射击中目标时,模板为你选取的下一个目标
real Rebound_MoveSpeed = 弹射的速度(距离/秒)
group Rebound_TheGroup = 用来选取单位和运行action的group
group Rebound_TargetGroup = 用来保存已被击中过的单位的单位组(如过CanEcho==true,那么这个应该是null)
timer Rebound_TheTimer = 用来计时的Timer
boolexpr Rebound_TheCond = 用来选取单位的条件
你可以赋值给这些全局变量,然后模板内部的参数值就会被这些全局变量的值覆盖。
更新:特殊说明(可以说是指导):
你现在可以先创建一个自己的TheTimer,然后用ReturnBug+GameCache为它存储自定义的值了,在code执行时,你可以从Rebound_TheTimer获得你的TheTimer,最后……这些存储的数据你就可以读取了。也就是说,你现在可以有无数个自定义值了。
有些危险,但一个很好的东东:
在<GameCache>, <Timer Handle String>的目录(GameCache中)下,
你可以改动/引用这些string key中的值:
real "timeout" : 你可以在中途改变运行时间的间隔(不幸的是,这只是认为而已,真正的timer运行间隔不是按这个来的)
integer(unit) "target" : 你可以在中途改变下一次的目标(H2I),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
real "target_x" : 你可以在中途改变目标的X坐标(不过在99.9%的情况下,排不上用场)
real "target_y" : 你可以在中途改变目标的Y坐标(不过在99.9%的情况下,排不上用场)
integer(unit) "source" : 你可以在中途改变上一次(也就是刚刚被击中)的目标(H2I)
real "source_x" : 你可以在中途改变上一次目标的X坐标(不过在99.9%的情况下,排不上用场)
real "source_y" : 你可以在中途改变上一次目标的Y坐标(不过在99.9%的情况下,排不上用场)
integer(group) "group" : 你可以在中途改变存储目标的group(H2I),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
integer(code) "action" : 你可以在中途改变击中后运行的函数(C2I)
real "speed" : 你可以在中途改变速度(距离/秒*间隔),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
boolean "destroy" : 你可以在中途改变是否删除Group、Condition和Timer并清除Timer的缓存
real "radius" : 你可以在中途改变选取单位的半径。
integer(boolexpr) "condition" : 你可以在中途改变选取单位的条件,不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
integer(lightning) "lightning" : 你可以在中途改变闪电效果。
real "lightning_z": 你可以在中途改变闪电效果的Z轴高度。
string "targeteffectpath": 你可以在中途改变添加给目标的特殊效果的路径。
string "targeteffectpoint": 你可以在中途改变添加给目标的特殊效果的附加点(如:"weapon"等)。
string "targetpointeffectpath": 你可以在中途改变添加给【目标的点】的特殊效果的路径。
real "getattackradius": 你可以在中途改变进入多少半径以内算击中了目标。
integer "number": 你可以在中途改变还有多少次弹射。
integer "attnumber": 你可以在中途改变弹射了多少次,不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
integer(unit) "mov_u": 你可以在中途改变追击目标的单位(投射物)
正是由于这个code变量和自定义的变量存在,所以这个模板的开放性大大的提高了(应该说的是在普通function里能干的事,在这个code变量里全都能完成)。
这个模板可单独直接制作的技能:Dota:巫医-麻痹药剂、巫妖-连环冰冻、先知-大招……魔兽:闪电链。
截图:这个模板怎么弄截图……好吧……把我测试时用的弄出来…………
[upload=1]
[upload=2]
[upload=3]
最后,谢谢大家能看完我这张语气有点高傲的帖子,实在是新学期开始了,心情不太好,大家请见谅…………(*^__^*) 嘻嘻…… |
评分
-
查看全部评分
|