找回密码
 点一下
查看: 4782|回复: 16

DotA 6.67c 中风行者的强力击逆向

[复制链接]
发表于 2010-5-12 22:27:35 | 显示全部楼层 |阅读模式
强力击的基础技能是ANcl(引导),所以就是纯Jass实现的了

原理就是创建一个箭,不停地向前移动,对箭所在位置的单位造成伤害

很多辅助函数没有给出,还有一些变量没有改名(太懒了)

PS: 刚才看到一个帖子在问怎么让单位只被伤害1次,这些代码就考虑到了这个

[jass]
function windrunnerPowershotDoDamage takes nothing returns nothing // 做出伤害的函数
    if  IsUnitInGroup(GetEnumUnit(), windrunnerPowershotDamagedUnits)  == false and  GetUnitAbilityLevel(GetEnumUnit(), 'Bcyc')  == 0 then
        call doDamage((windrunnerPowershotArrow), (GetEnumUnit()), 1, (((windrunnerPowershotInitialDamage)*1.0))* Pow(0.9, (windrunnerPowershotDamagedUnitCount)) * Pow(0.99, (windrunnerPowershotDamagedDestructableCount)) )
        call GroupAddUnit(windrunnerPowershotDamagedUnits, GetEnumUnit())
        set windrunnerPowershotDamagedUnitCount = windrunnerPowershotDamagedUnitCount + 1
    endif
endfunction

function windrunnerPowershotLoop takes nothing returns boolean  // 箭在飞行的时候
    local trigger t = GetTriggeringTrigger()
    local integer hTrig = GetHandleId(t)
    local unit unitPowershotArrow = ( LoadUnitHandle(hashTable, (hTrig), (45)) )
    local real HMI = ( LoadReal(hashTable, (hTrig), (47)) )
    local real HNI = ( LoadReal(hashTable, (hTrig), (48)) )
    local real LPO = ( LoadReal(hashTable, (hTrig), (13)) )
    local real GFI = ( LoadReal(hashTable, (hTrig), (20)) )
    local integer LN2 = ( LoadInteger(hashTable, (hTrig), (354)) )
    local integer LS2 = ( LoadInteger(hashTable, (hTrig), (355)) )
    local group LQO = ( LoadGroupHandle(hashTable, (hTrig), (187)) )
    local real x = constrainX(GetUnitX(unitPowershotArrow) + (60* Pow(0.9, LS2) * Pow(0.99, LN2) )*Cos(LPO)) // constrainX 防止坐标跑到地图外
    local real y = constrainY(GetUnitY(unitPowershotArrow) + (60* Pow(0.9, LS2) * Pow(0.99, LN2) )*Sin(LPO)) // 同上
    local group g = allocGroup()
    local real d
    if GetTriggerEvalCount(t) > 2 then
        set d = 150
    else
        set d = 75
    endif
    call DestroyEffect( AddSpecialEffect("effects\\Tornado.mdx", x, y) ) // 箭底下的小旋风的效果
    set LN2 = LN2 +  killDestructables(x, y, 75)
    call SaveInteger(hashTable, (hTrig), (354), (LN2))
    set windrunnerPowershotDamagedUnits = LQO  // 这几个变量名很长的都是全局变量,为了给下面的windrunnerPowershotDoDamage函数传递信息
    set windrunnerPowershotArrow = unitPowershotArrow
    set windrunnerPowershotInitialDamage = GFI
    set windrunnerPowershotDamagedDestructableCount = LN2
    set windrunnerPowershotDamagedUnitCount = LS2
    set FK = unitPowershotArrow
    call GroupEnumUnitsInRange(g, x, y, d, Condition(function filterUnitInjurable))
    call ForGroup(g, function windrunnerPowershotDoDamage)
    call releaseGroup(g)
    call SaveInteger(hashTable, (hTrig), (355), (windrunnerPowershotDamagedUnitCount))
    call SetUnitX(unitPowershotArrow, x)
    call SetUnitY(unitPowershotArrow, y)
    if GetTriggerEvalCount(t) > 29 then // 到地方了
        call KillUnit(unitPowershotArrow)
        call releaseGroup(LQO)
        call FlushChildHashtable(hashTable, (hTrig))
        call disableTriggerAndDestroyAfter1Min(t)
    endif
    set t = null
    set unitPowershotArrow = null
    set LQO = null
    set g = null
    return false
endfunction

function windrunnerPowershotStart takes nothing returns nothing // 开始射箭
    local unit u = GetTriggerUnit()
    local real x2 = ( LoadReal(hashTable, (GetHandleId(u)), (356)) )
    local real y2 = ( LoadReal(hashTable, (GetHandleId(u)), (357)) )
    local real damageFactor =  min((TimerGetElapsed(M)) - ( LoadReal(hashTable, (GetHandleId(u)), (358)) ), 1.0)
    // 上一句... 刚才在网上看到有人问,为什么强力击伤害不到360,楼下的人回复说LZ早泄,没有坚持1秒... 就是这一句搞的鬼了
    local real angle =  Atan2(y2 - GetUnitY(u), x2 - GetUnitX(u))
    local trigger t
    local integer hTrig
    local unit VDI
    local integer lvl =  GetUnitAbilityLevel(u, 'A12K') // A12K是强力击技能的id
    local real initialDamage = (40 + 80*lvl)*(damageFactor) // 计算初始伤害的时候考虑了早泄....
    set t = CreateTrigger()
    set hTrig = GetHandleId(t)
    set VDI =  CreateUnit(GetOwningPlayer(u), 'h078', GetUnitX(u), GetUnitY(u), angle*bj_RADTODEG)  // h078是箭的id
    set x2 = GetUnitX(u) + 1700*Cos(angle)
    set y2 = GetUnitY(u) + 1700*Sin(angle)
    call SaveUnitHandle(hashTable, (hTrig), (45), (VDI))
    call SaveReal(hashTable, (hTrig), (47), ((x2)*1.0))
    call SaveReal(hashTable, (hTrig), (48), ((y2)*1.0))
    call SaveReal(hashTable, (hTrig), (13), ((angle)*1.0))
    call SaveReal(hashTable, (hTrig), (20), ((initialDamage)*1.0))
    call SaveInteger(hashTable, (hTrig), (354), (0))
    call SaveInteger(hashTable, (hTrig), (355), (0))
    call SaveGroupHandle(hashTable, (hTrig), (187), (allocGroup()))
    call TriggerRegisterTimerEvent(t, 0.02, true)
    call TriggerAddCondition(t, Condition(function windrunnerPowershotLoop))
    set u = null
    set t = null
    set VDI = null
endfunction

function windrunnerPowershotPrepareFinish takes nothing returns boolean  // 结束吟唱
    local trigger t = GetTriggeringTrigger()
    local integer DMI = GetHandleId(t)
    local unit E1I = ( LoadUnitHandle(hashTable, (DMI), (14)) )
    call SetUnitTimeScale(E1I, 1)
    call FlushChildHashtable(hashTable, (DMI))
    call disableTriggerAndDestroyAfter1Min(t)
    set t = null
    set E1I = null
    return false
endfunction

function windrunnerPowershotPrepare takes nothing returns nothing // 开始吟唱
    local trigger t = CreateTrigger()
    local integer DMI = GetHandleId(t)
    local unit E1I = GetTriggerUnit()
    local location l = GetSpellTargetLoc()
    local real x = GetLocationX(l)
    local real y = GetLocationY(l)
    call RemoveLocation(l)
    call SaveReal(hashTable, (GetHandleId(E1I)), (356), ((x)*1.0))
    call SaveReal(hashTable, (GetHandleId(E1I)), (357), ((y)*1.0))
    call SaveReal(hashTable, (GetHandleId(E1I)), (358), (((TimerGetElapsed(M)))*1.0))
    call SetUnitTimeScale(E1I, 0.75)
    call SaveUnitHandle(hashTable, (DMI), (14), (E1I))
    call TriggerRegisterTimerEvent(t, 0.75, false)
    call TriggerRegisterUnitEvent(t, E1I, EVENT_UNIT_DEATH)
    call TriggerAddCondition(t, Condition(function windrunnerPowershotPrepareFinish))
    set t = null
    set E1I = null
endfunction

function windrunnerPowershot takes nothing returns boolean  // 入口
    if GetSpellAbilityId() == 'A12K' then
        if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_CAST then
            call SaveBoolean(hashTable, (GetHandleId(GetTriggerUnit())), (360), (false))
            call windrunnerPowershotPrepare()
        elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT then
            call SaveBoolean(hashTable, (GetHandleId(GetTriggerUnit())), (360), (true))
        elseif ( LoadBoolean(hashTable, (GetHandleId(GetTriggerUnit())), (360)) ) == true then
            call windrunnerPowershotStart()
        endif
    endif
    return false
endfunction

function windrunnerPowershotRegister takes nothing returns nothing // 初始化用的函数(在选择英雄选了风行的时候运行一下)
    local trigger t = CreateTrigger()
    call triggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_SPELL_ENDCAST)
    call triggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_SPELL_CAST)
    call triggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function windrunnerPowershot))
    set t = null
endfunction
[/jass]
发表于 2010-5-17 21:41:47 | 显示全部楼层
作为一个j盲,我还是大概看懂了,问一个小白问题,j中用到的局部变量要在we里的变量中建立吗?哈希表到底是什么用,记录实数,单位那些数据的?一般set x = null就是排泄吧
回复

使用道具 举报

 楼主| 发表于 2010-5-18 22:15:24 | 显示全部楼层

回 1楼(yplayers) 的帖子

T我不会用......很雷人但是是真的。。。 貌似T里面没有局部变量(听说)

哈希表可以理解成有两个下标(2维)的无限大的数组

一般 set xx = null 就是排泄
回复

使用道具 举报

发表于 2010-5-18 22:57:53 | 显示全部楼层
LS赐教了,J确实好用,一个触发就把四个触发全不搞定,虽然实质也是多个触发,但是编写起来人性化多了,尤其是那个dodamage
不过感觉save许多
回复

使用道具 举报

发表于 2010-5-19 11:57:24 | 显示全部楼层
J的优势主要在于效率,和更多的功能,也方便修改,哈希表是一个存储表,优点在于无限大小和嵌套,可以组成多维表,速度也不慢。用法有教程
回复

使用道具 举报

发表于 2010-5-20 09:04:36 | 显示全部楼层
T直接排掉了?
也就是说在游戏中不能再次查找这个T了。
回复

使用道具 举报

 楼主| 发表于 2010-5-20 16:52:35 | 显示全部楼层

回 5楼(darkcyan) 的帖子

不知道你是说的哪个T?

话说直接排掉的的T都是在T的回调中用GetTriggeringTrigger取得的,用完了就会Destroy掉

windrunnerPowershotRegister里面的t需要一直用,所以就直接扔掉了
回复

使用道具 举报

发表于 2010-5-20 19:49:18 | 显示全部楼层
排泄……
回复

使用道具 举报

发表于 2010-5-23 16:11:53 | 显示全部楼层
你用的是什么牌子的we啊?我的1.24补丁带的we怎么不能在j里面声明全局哈希表变量啊?
回复

使用道具 举报

 楼主| 发表于 2010-5-24 08:12:56 | 显示全部楼层

回 8楼(frozenleave) 的帖子

...
我用的jasscraft
回复

使用道具 举报

发表于 2010-5-24 14:02:55 | 显示全部楼层
disableTriggerAndDestroyAfter1Min(),这个什么函数来的,中文意思好像是关闭并在一分钟后破坏?jasscraft上面没这个函数,不知道we会不会报错,试试先,不过楼主你的这个代码怎么复制上去会报错啊?
回复

使用道具 举报

发表于 2010-5-24 14:46:45 | 显示全部楼层
显然很多自定义函数的实现没写出来,自然会报错
回复

使用道具 举报

发表于 2010-5-25 00:15:51 | 显示全部楼层
jasscraf都米有哈希表的储存和读取,用那个就比在那个触发器函数里面好一点点,就是打出函数会写参数类型上去,可怜我那个魔兽不知道为啥装不了wehelper那些插件

----------- 帖子于 00:15 更新 --------- 之前内容发布于 00:13 ------------

看得我很晕,楼主你创建的箭是怎么移动的,为啥不见你用timerstart函数控制箭的位置呢?
回复

使用道具 举报

发表于 2010-5-25 00:19:33 | 显示全部楼层
你把新的common.j和blizzard.j解压出来替换掉jasscraft里原来的就可以了,不过需要注意的是jasscraft不认识制表符这个whitespace,而新的j文件里新函数的whitespace都用的制表符而不是连续空格,如果有必要你可以自己处理下
回复

使用道具 举报

 楼主| 发表于 2010-6-25 21:30:57 | 显示全部楼层

回 12楼(frozenleave) 的帖子

呃 挖自己的坟了。。。 很久没上来看了,最近都在做技能

用的TriggerRegisterTimerEvent函数,直接把timer关联到trigger上去了
回复

使用道具 举报

发表于 2010-7-4 01:45:23 | 显示全部楼层
有damage的函数吗?
回复

使用道具 举报

发表于 7 天前 | 显示全部楼层
1111111111111111111
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-4 05:48 , Processed in 0.038705 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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