找回密码
 点一下
查看: 2445|回复: 1

【原创】牵引技能模板(更新)

  [复制链接]
发表于 2009-2-18 13:00:26 | 显示全部楼层 |阅读模式
又一个强大的模板……加入了code+自定义变量,几乎可以让你得到任何效果。

这个模板可单独直接制作的技能:Dota:谜团-大招。
最形象的名字是【黑洞】
(效果相反的排斥效果可以通过设置速度为负数来达到)

更新啦~~2009.2.21更新啦~~

代码:
[codes=jass]globals
    gamecache Tow_GC = null
    //游戏缓存
    integer Tow_Data_Int = 0
    real Tow_Data_Real = 0.0
    boolean Tow_Data_Bool = false
    string Tow_Data_Str = null
    real Tow_X = 0.0
    real Tow_Y = 0.0
    group Tow_TheGroup = null
    timer Tow_TheTimer = null
    boolexpr Tow_TheCond = null
    real Tow_speed = 0.0
    real Tow_speed_add = 0.0
    //对code-action的辅助参数。
endglobals
//Copy这个

function TowInit takes nothing returns nothing
    call FlushGameCache(InitGameCache( "Tow.w3v" ))
    set Tow_GC = InitGameCache( "Tow.w3v" )
endfunction
//你把Tow_GC设置成你的GameCache(推荐)或者这样都可以(但你要保证Tow_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 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 TowAbility_UnPause takes nothing returns nothing
    call PauseUnit( GetEnumUnit(), false )
endfunction

function TowAbility_Pause takes nothing returns nothing
    call PauseUnit( GetEnumUnit(), true )
endfunction

function TowAbility_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, Tow_X, Tow_Y )
    local real angle = AngleBetweenTwoLocs2Angle_Second( Tow_X, Tow_Y, x, y )
    local real speed = Tow_speed + Tow_speed_add * distance
    if distance <= speed then
        set x = Tow_X
        set y = Tow_Y
    else
        set x = x + speed * Cos( angle * bj_DEGTORAD )
        set y = y + speed * Sin( angle * bj_DEGTORAD )
    endif
    call SetUnitX( u, x )
    call SetUnitY( u, y )
    set u = null
endfunction

function TowAbility_Action takes nothing returns nothing
    local timer ti = GetExpiredTimer()
    local string ti_s = I2S(H2I( ti ))
    local real timeout = GetStoredReal( Tow_GC, ti_s, "timeout" )
    local real elapsed = GetStoredReal( Tow_GC, ti_s, "elapsed" )
    local real time = GetStoredReal( Tow_GC, ti_s, "time" )
    local unit u = I2U( GetStoredInteger( Tow_GC, ti_s, "target" ) )
    local real x = GetStoredReal( Tow_GC, ti_s, "target_x" )
    local real y = GetStoredReal( Tow_GC, ti_s, "target_y" )
    local group g = I2G( GetStoredInteger( Tow_GC, ti_s, "group" ) )
    local code c = I2C( GetStoredInteger( Tow_GC, ti_s, "action" ) )
    local real action_time = GetStoredReal( Tow_GC, ti_s, "action_time" )
    local boolean pause = GetStoredBoolean( Tow_GC, ti_s, "pause" )
    local boolean destroy = GetStoredBoolean( Tow_GC, ti_s, "destroy" )
    local real speed = GetStoredReal( Tow_GC, ti_s, "speed" )
    local real speed_add = GetStoredReal( Tow_GC, ti_s, "speed_add" )
    local real radius = GetStoredReal( Tow_GC, ti_s, "radius" )
    local boolexpr be = I2BE( GetStoredInteger( Tow_GC, ti_s, "condition" ) )
    if elapsed > time then
        if pause then
            call ForGroup( g, function TowAbility_UnPause )
        endif
        if destroy then
            call PauseTimer( ti )
            call DestroyTimer( ti )
            call DestroyGroup( g )
            if be != null then
                call DestroyBoolExpr( be )
            endif
            call FlushStoredMission( Tow_GC, ti_s )
        endif
    else
        if u != null then
            set x = GetUnitX( u )
            set y = GetUnitY( u )
        endif
        if pause then
            call ForGroup( g, function TowAbility_UnPause )
        endif        
        call GroupClear( g )
        call GroupEnumUnitsInRange( g, x, y, radius, be )
        if u != null then
            call GroupRemoveUnit( g, u )
        endif
        if pause then
            call ForGroup( g, function TowAbility_Pause )
        endif
        set Tow_X = x
        set Tow_Y = y
        set Tow_speed = speed
        set Tow_speed_add = speed_add
        call ForGroup( g, function TowAbility_Move )
        set Tow_speed = speed / timeout
        set Tow_speed_add = speed_add / timeout
        set Tow_TheGroup = g
        set Tow_TheTimer = ti
        set Tow_TheCond = be
        if c != null and ModuloReal( elapsed, action_time ) == 0.0 then
            set Tow_Data_Int = GetStoredInteger( Tow_GC, ti_s, "help" )
            set Tow_Data_Real = GetStoredReal( Tow_GC, ti_s, "help" )
            set Tow_Data_Bool = GetStoredBoolean( Tow_GC, ti_s, "help" )
            set Tow_Data_Str = GetStoredString( Tow_GC, ti_s, "help" )
            call ForGroup( g, c )
            call StoreInteger( Tow_GC, ti_s, "help", Tow_Data_Int )
            call StoreReal( Tow_GC, ti_s, "help", Tow_Data_Real )
            call StoreBoolean( Tow_GC, ti_s, "help", Tow_Data_Bool )
            call StoreString( Tow_GC, ti_s, "help", Tow_Data_Str )            
            set Tow_Data_Int = 0
            set Tow_Data_Real = 0.0
            set Tow_Data_Bool = false
            set Tow_Data_Str = null
        endif
        set Tow_X = 0.0
        set Tow_Y = 0.0
        call StoreReal( Tow_GC, ti_s, "speed", Tow_speed * timeout )
        call StoreReal( Tow_GC, ti_s, "speed_add", Tow_speed_add * timeout )
        call StoreInteger( Tow_GC, ti_s, "group", H2I( Tow_TheGroup ) )
        call StoreInteger( Tow_GC, ti_s, "condition", H2I( Tow_TheCond ) )
        set Tow_speed = 0.0
        set Tow_speed_add = 0.0
        set Tow_TheGroup = null
        set Tow_TheTimer = null
        set Tow_TheCond = null
        call StoreReal( Tow_GC, ti_s, "elapsed", elapsed + timeout )
    endif
    set ti = null
    set ti_s = null
    set u = null
    set g = null
    set c = null
    set be = null
endfunction

function TowAbility takes timer TheTimer, unit u, real x, real y, real radius, real timeout, real time, real speed, real speed_add, boolean pause, boolean destroygroupandboolexpr, real time_action_run, boolexpr condition, code 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( Tow_GC, ti_s, "help", Tow_Data_Int )
    call StoreReal( Tow_GC, ti_s, "help", Tow_Data_Real )
    call StoreBoolean( Tow_GC, ti_s, "help", Tow_Data_Bool )
    call StoreString( Tow_GC, ti_s, "help", Tow_Data_Str )
    set Tow_Data_Int = 0
    set Tow_Data_Real = 0.0
    set Tow_Data_Bool = false
    set Tow_Data_Str = null
    if u != null then
        call StoreInteger( Tow_GC, ti_s, "target", H2I( u ) )
    else
        call StoreReal( Tow_GC, ti_s, "target_x", x )
        call StoreReal( Tow_GC, ti_s, "target_y", y )
    endif
    call StoreInteger( Tow_GC, ti_s, "group", H2I( CreateGroup() ) )
    call StoreReal( Tow_GC, ti_s, "radius", radius )
    call StoreReal( Tow_GC, ti_s, "timeout", timeout )
    call StoreReal( Tow_GC, ti_s, "time", time )
    if action != null then
        call StoreInteger( Tow_GC, ti_s, "action", C2I( action ) )
        call StoreReal( Tow_GC, ti_s, "action_time", time_action_run )
    endif
    if condition != null then
        call StoreInteger( Tow_GC, ti_s, "condition", H2I( condition ) )
    endif
    call StoreBoolean( Tow_GC, ti_s, "pause", pause )
    call StoreBoolean( Tow_GC, ti_s, "destroy", destroygroupandboolexpr )
    call StoreReal( Tow_GC, ti_s, "speed", speed * timeout )
    call StoreReal( Tow_GC, ti_s, "speed_add", speed_add * timeout )
    call TimerStart( ti, timeout, true, function TowAbility_Action )
    set ti = null
    set ti_s = null
endfunction[/codes]

参数说明:
更新:timer TheTimer  用来计时的Timer(如果为null则函数自动创建一个)
unit u    牵引中央的单位(可以设为null,但x和y必需)
real x    牵引中央的X坐标(若x和y设为无意义值,则单位必需)
real y    牵引中央的Y坐标(若x和y设为无意义值,则单位必需)
real radius    牵引多少范围以内的单位
real timeout   多少秒位移一次(最好设为0.03)
real time      牵引效果持续多少秒
real speed     牵引的速度(按距离/秒算)
real speed_add 牵引的加速度(按速度/离中心点的距离算)
boolean pause  是否将被牵引的单位暂停
boolean destroygroupandboolexpr  是否在牵引效果结束后删除condition和group(更新:如果设为false,则Timer也会保留,并且不会清空Timer的缓存内容,反之则清除timer)
real time_action_run  每多少秒运行一次action(这个必须是timeout的倍数)
boolexpr condition  被牵引单位的condition(请勿将应写进action里的动作写进condition里)
code action  动作

对于action的特殊说明:
在action中调用函数:
GetEnumUnit(),得到这个被牵引的目标(其中不包括被当作牵引中心的单位)。
你可以在调用TowAbility之前设置这四个全局变量:
[codes=jass]    integer Tow_Data_Int = 0
    real Tow_Data_Real = 0.0
    boolean Tow_Data_Bool = false
    string Tow_Data_Str = null[/codes]
然后,当这个action执行时,这四个全局变量储存的值就是你赋给他们的值(如果没赋值则是默认的0/0.0/false/null)。
在action运行中,可以为这四个全局变量赋值
action执行后,这四个全局变量值将传递给下一个被牵引单位运行的action。
这一次所有的单位action全部运行完毕后,这四个全局变量值将被存储起来,再下一次运行时,四个全局变量的值就是上一次赋的值(相比昨天我发的初版ReboundAbility【弹射技能模板】我的改进,已经将这个改进加入下一个版本的模板)。
注意!当运行完TowAbility后,这四个全局变量就会被自动清空。

正是由于这个code变量和自定义的变量存在,所以这个模板的开放性大大的提高了(应该说的是在普通function里能干的事,在这个code变量里全都能完成)。

更新:
action的全局变量参数(半新半旧):
real Tow_X    牵引中央的目标的X坐标
real Tow_Y    牵引中央的目标的Y坐标
group Tow_TheGroup 被牵引的单位组
timer Tow_TheTimer 用来计时的Timer
boolexpr Tow_TheCond 用来检查单位条件
real Tow_speed 被牵引单位的基本被牵引速度(距离/秒)
real Tow_speed_add = 被牵引单位的被牵引加速度(这取决于被牵引单位和牵引中央的距离)(速度/距离)
(最终牵引速度 = 基本被牵引速度 + 被牵引加速度 * 被牵引单位和牵引中央的距离)

更新:特殊说明(可以说是指导):
你现在可以先创建一个自己的TheTimer,然后用ReturnBug+GameCache为它存储自定义的值了,在code执行时,你可以从Tow_TheTimer获得你的TheTimer,最后……这些存储的数据你就可以读取了。也就是说,你现在可以有无数个自定义值了。
有些危险,但一个很好的东东:
在<GameCache>, <Timer Handle String>的目录(GameCache中)下,
你可以改动/引用这些string key中的值:
real "timeout" : 你可以在中途改变运行时间的间隔(不幸的是,这只是认为而已,真正的timer运行间隔不是按这个来的)
real "elapsed" : 你可以在中途改变已运行时间
real "time" : 你可以在中途改变总运行时间
integer(unit) "target" : 你可以在中途改变目标(H2I)
real "target_x" : 你可以在中途改变目标点(与目标不是一回事)的X坐标
real "target_y" : 你可以在中途改变目标点(与目标不是一回事)的Y坐标
integer(group) "group" : 你可以在中途改变被牵引的单位们(H2I),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
integer(code) "action" : 你可以在中途改变在被牵引过程中运行的函数(C2I)
real "action_time" : 你可以在中途改变在被牵引过程中运行的函数运行间隔
real "speed" : 你可以在中途改变速度(距离/秒*间隔),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
real "speed_add" : 你可以在中途改变加速度(速度/秒*间隔),不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。
boolean "pause" : 你可以在中途改变是否将被牵引的单位暂停
boolean "destroy" : 你可以在中途改变是否删除Group、Condition和Timer并清除Timer的缓存
real "radius" : 你可以在中途改变选取单位的半径。
integer(boolexpr) "condition" : 你可以在中途改变选取单位的条件,不过正确的方式是用全局变量传递,因为全局变量的值会覆盖你存储的值。

更新:
你可以在code中设置Tow_speed和Tow_speed_add然后这两个量就会在下一次timer执行时起作用。

截图:无(我没有动态截图的工具)

希望大家多多支持我~~有Bug一定要回帖/发短消息给我这个帐号~~

最后,照例为我的JASS技能教程求精~~

Tow.w3x

28 KB, 下载次数: 51

TowAbility.txt

9 KB, 下载次数: 28

评分

参与人数 2威望 +2 收起 理由
hydralisk + 1
扎克斯fair + 1 优秀文章

查看全部评分

发表于 2009-2-18 13:19:28 | 显示全部楼层
很好很强大,受用了
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-28 04:05 , Processed in 0.263780 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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