Анонс ещё одного спеллпака, возможно на этот раз пригодного к импорту
Тема
13 657
7
rsfghd:
Гуванч, держи дружище свою кнопочку
Бля, отдуши за кнопку. Я просидел 5 минут, даже забыл зачем зашел на хгм...
Э... кря (?)
Тема
4 506
делал для друга спелл, феникс летит по параболе, задумывается о жизни и его маленький куриный мозг взрывается, нанося урон окружающим и вызывая огненную стенку вдоль крыльев, если шарите за код то можете спокойно (или беспокойно) импортировать, карта с видосом в комментах
Тема
4 343
28
раскрыть
library mylib
globals
    constant hashtable H = InitHashtable()
    private constant group TempG = CreateGroup()
    private constant group TempG1 = CreateGroup()
    private constant location LFZ = Location(0,0)
    private conditionfunc Cond
    private attacktype AttackType
    private damagetype DamageType
    private unit bj_lastFilterUnit
    private unit TempUnit
    private unit CUEX
    private real TempReal
    private real TempReal1
    
    private real MaxX
    private real MinX
    private real MaxY
    private real MinY
endglobals

native UnitAlive takes unit id returns boolean

private struct Phoenix
    unit caster
    unit dummy
    real x
    real y
    real speed
    real speedx
    real speedy
    real angle
    real dist
    real dist1
    real dist2
    real fly
    real fly1
    real height
    real height1
    real radius
    real radius1
    real dmg
    real dmg1
    real tm
    real tm1
    real tm2
    real sc
    real sc1
    group g
    effect Effect
    integer count
    attacktype AttackType
    damagetype DamageType
endstruct

private function SetUnitPositionEx takes unit u, real x, real y returns nothing
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
endfunction

private function CreateUnitEx takes player id, integer unitid, real x, real y, real face returns unit
    set CUEX = CreateUnit(id,unitid,x,y,face)
    call SetUnitPathing(CUEX,false)
    call UnitAddAbility(CUEX,'Arav')
    call SetUnitPositionEx(CUEX,x,y)
    return CUEX
endfunction

private function GetLocZ takes real x, real y returns real
    call MoveLocation(LFZ,x,y)
    return GetLocationZ(LFZ)
endfunction

private function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
    return (2*(y0 + y1 - 2*h)*(x/d - 1) + (y1 - y0))*(x/d) + y0
endfunction

private function DamageCond takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit()
    if UnitAlive(bj_lastFilterUnit) and IsUnitEnemy(bj_lastFilterUnit,bj_groupEnumOwningPlayer) and not IsUnitInGroup(bj_lastFilterUnit,TempG1) then
        call UnitDamageTarget(TempUnit,bj_lastFilterUnit,TempReal,false,false,AttackType,DamageType,null)
        call GroupAddUnit(TempG1,bj_lastFilterUnit)
    endif
    return false
endfunction

private function Damage takes nothing returns nothing
    call GroupEnumUnitsInRange(TempG,GetUnitX(GetEnumUnit()),GetUnitY(GetEnumUnit()),TempReal1,Cond)
endfunction

private function PeriodicDamage takes nothing returns nothing
    local Phoenix A = LoadInteger(H,GetHandleId(GetExpiredTimer()),0)
    
    set TempUnit = A.caster
    set TempReal = A.dmg1
    set TempReal1 = A.radius1
    set AttackType = A.AttackType
    set DamageType = A.DamageType
    call ForGroup(A.g,function Damage)
    call GroupClear(TempG1)
    
    if not UnitAlive(FirstOfGroup(A.g)) then
        call DestroyGroup(A.g)
        call FlushChildHashtable(H,GetHandleId(GetExpiredTimer()))
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
        set A.caster = null
        set A.dummy = null
        set A.Effect = null
        call A.destroy()
    else
        call TimerStart(GetExpiredTimer(),A.tm,false,function PeriodicDamage)
    endif
endfunction

private function move takes nothing returns nothing
    local Phoenix A = LoadInteger(H,GetHandleId(GetExpiredTimer()),0)
    local boolean b
    local real fly = GetUnitFlyHeight(A.dummy)+GetLocZ(A.x,A.y)
    local real d
    local real a
    local real x
    local real y
    set A.x = A.x+A.speedx
    set A.y = A.y+A.speedy
    set A.dist = A.dist-A.speed
    call SetUnitPositionEx(A.dummy,A.x,A.y)
    call SetUnitFlyHeight(A.dummy,ParabolaZ2(A.fly,A.height,A.fly1,A.dist1,A.dist),0)
    call SetUnitAnimationByIndex(A.dummy,R2I(Atan2((GetUnitFlyHeight(A.dummy)+GetLocZ(A.x,A.y))-fly,SquareRoot(((A.x-A.speedx)-A.x)*((A.x-A.speedx)-A.x)+((A.y-A.speedy)-A.y)*((A.y-A.speedy)-A.y)))*bj_RADTODEG+90.5))
    
    if A.dist <= 0. then
        call DestroyEffect(A.Effect)
        call KillUnit(A.dummy)
        
        set bj_groupEnumOwningPlayer = GetOwningPlayer(A.caster)
        set TempUnit = A.caster
        set TempReal = A.dmg
        set AttackType = A.AttackType
        set DamageType = A.DamageType
        call GroupEnumUnitsInRange(TempG,A.x,A.y,A.radius,Cond)
        
        set A.g = CreateGroup()
        set a = A.angle-(90*bj_DEGTORAD)
        set d = A.dist2
        set x = A.x
        set y = A.y
        set b = false
        call GroupAddUnit(A.g,CreateUnitEx(bj_groupEnumOwningPlayer,'u001',x,y,GetRandomReal(0,360)))
        call UnitApplyTimedLife(CUEX,'BTLF',A.tm1)
        call SetUnitScale(CUEX,A.sc,A.sc,A.sc)
        loop
            exitwhen A.count <= 0
            set x = A.x+d*Cos(a)
            set y = A.y+d*Sin(a)
            call GroupAddUnit(A.g,CreateUnitEx(bj_groupEnumOwningPlayer,'u001',x,y,GetRandomReal(0,360)))
            call UnitApplyTimedLife(CUEX,'BTLF',A.tm1)
            call SetUnitScale(CUEX,A.sc,A.sc,A.sc)
            if b then
                set a = A.angle-(90*bj_DEGTORAD)
                set d = d+A.dist2
                set A.count = A.count-1
                set b = false
            else
                set a = A.angle+(90*bj_DEGTORAD)
                set b = true
            endif
        endloop
        
        call CreateUnitEx(Player(0x0F),'u000',A.x,A.y,A.angle*bj_RADTODEG+90)
        call SetUnitFlyHeight(CUEX,100,0)
        call SetUnitScale(CUEX,A.sc1,A.sc1,A.sc1)
        call SetUnitAnimationByIndex(CUEX,0)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl",CUEX,"chest"))
        call KillUnit(CUEX)
        
        call CreateUnitEx(Player(0x0F),'u000',A.x,A.y,A.angle*bj_RADTODEG-90)
        call SetUnitFlyHeight(CUEX,100,0)
        call SetUnitScale(CUEX,A.sc1,A.sc1,A.sc1)
        call SetUnitAnimationByIndex(CUEX,0)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl",CUEX,"chest"))
        call KillUnit(CUEX)
        
        call CreateUnitEx(Player(0x0F),'u000',A.x,A.y,A.angle*bj_RADTODEG)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl",CUEX,"chest"))
        call KillUnit(CUEX)
        
        call CreateUnitEx(Player(0x0F),'u000',A.x,A.y,A.angle*bj_RADTODEG)
        call SetUnitScale(CUEX,A.sc,A.sc,A.sc)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl",CUEX,"chest"))
        call KillUnit(CUEX)
        
        call TimerStart(GetExpiredTimer(),0.,false,function PeriodicDamage)
    endif
endfunction

private function Phoenix_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local Phoenix A = Phoenix.create()
    local integer lvl
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real sc
    set A.caster = GetTriggerUnit()
    set A.x = GetUnitX(A.caster)
    set A.y = GetUnitY(A.caster)
    set A.angle = Atan2(y-A.y,x-A.x)
    set A.x = A.x+50*Cos(A.angle)
    set A.y = A.y+50*Sin(A.angle)
    set A.dist = SquareRoot((A.x-x)*(A.x-x)+(A.y-y)*(A.y-y))
    set A.dist1 = A.dist
    set A.fly = GetLocZ(x,y)
    set A.fly1 = A.dist/1.5
    set A.height = GetLocZ(A.x,A.y)+GetUnitFlyHeight(A.caster)
    set A.dummy = CreateUnitEx(GetOwningPlayer(A.caster),'u000',A.x,A.y,A.angle*bj_RADTODEG)
    set lvl = GetUnitAbilityLevel(A.caster,'A000')
    
    if     lvl == 1 then // уровень
        set A.sc = 1.00 // размер стены
        set A.sc1 = 0.50 // размер эффектов
        set sc = 0.70 // размер феникса
        set A.count = 5 // кол-во стенок
        set A.dist2 = 50.00 // дистанция между стенками
        set A.dmg = 100.00 // урон взрыва феникса
        set A.dmg1 = 25.00 // урон стенки
        set A.radius = 125.00 // радиус взрыва феникса
        set A.radius1 = 95.00 // радиус стенки
        set A.tm1 = 2.00 // продолжительность существования стенки
    elseif lvl == 2 then
        set A.sc = 1.50
        set A.sc1 = 0.70
        set sc = 1.00
        set A.count = 7
        set A.dist2 = 50.00
        set A.dmg = 150.00
        set A.dmg1 = 40.00
        set A.radius = 175.00
        set A.radius1 = 105.00
        set A.tm1 = 3.00
    else
        set A.sc = 1.90
        set A.sc1 = 1.00
        set sc = 1.30
        set A.count = 10
        set A.dist2 = 50.00
        set A.dmg = 225.00
        set A.dmg1 = 60.00
        set A.radius = 250.00
        set A.radius1 = 115.00
        set A.tm1 = 5.00
        if lvl > 3 then
            call BJDebugMsg("Phoenix_Actions error: Ability level > 3")
        endif
    endif
    set A.Effect = AddSpecialEffectTarget("units\\human\\phoenix\\phoenix.mdx",A.dummy,"chest") // эффект феникса
    set A.AttackType = ATTACK_TYPE_NORMAL // тип атаки
    set A.DamageType = DAMAGE_TYPE_NORMAL // тип урона
    set A.speed = 15.00 // скорость полёта
    set A.tm = 0.25 // периодичность урона стен
    
    set A.speedx = A.speed*Cos(A.angle)
    set A.speedy = A.speed*Sin(A.angle)
    call SetUnitScale(A.dummy,sc,sc,sc)
    
    call SaveInteger(H,GetHandleId(t),0,A)
    call TimerStart(t,.03125,true,function move)
    set t = null
endfunction

//===========================================================================
private function mycond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call Phoenix_Actions()
    endif
    return false
endfunction

function InitTrig_Phoenix takes nothing returns nothing
    local rect r = GetWorldBounds()
    set gg_trg_Phoenix = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEvent(gg_trg_Phoenix,Player(0x00),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    call TriggerAddCondition( gg_trg_Phoenix, Condition(function mycond) )
    
    call RemoveUnit(CreateUnit(Player(0x0F),'u000',0,0,0))
    call RemoveUnit(CreateUnit(Player(0x0F),'u001',0,0,0))
    set Cond = Condition(function DamageCond)
    set MaxX = GetRectMaxX(r)
    set MinX = GetRectMinX(r)
    set MaxY = GetRectMaxY(r)
    set MinY = GetRectMinY(r)
    call RemoveRect(r)
    set r = null
endfunction
endlibrary




делал свой первый ии, который в итоге пошёл в карту другому челу
ии вышел достаточно крут
Тема
1 296
возвращает говно
Тема
1 373
28
раскрыть
library mylib initializer init // initializer (с англ.) инициализирует, в нашем случае оно инициализирует функцию init в самом низу
globals
    private constant hashtable H = InitHashtable() // константные переменные - те, что по коду не должны изменяться, то есть если где-то попытаешься задать другое значение этой переменной - выдаст ошибку
    private constant group TempG = CreateGroup()
    private group TempG1
    private real TempR
    
    private real MaxX // значения этим переменным присваиваются в функции инициализации
    private real MinX
    private real MaxY
    private real MinY
    
    // приставки private нужны, чтобы не конфликтовать с функциями извне библиотеки, удобно для импорта в чужую карту
endglobals

native UnitAlive takes unit id returns boolean // объявление нативной функции проверки жив ли юнит, находящаяся в common.j

function DBC takes real x, real y, real x1, real y1 returns real //Distance Between Coordinates (DBC)
   return SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1)) 
endfunction

private function SetUnitPositionEx takes unit u, real x, real y returns nothing // самодельная функция перемещения юнита, тут проверяются координаты, чтобы они не выходили за границу карты и не крашнули игру
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
endfunction

private struct mys // структура это такая таблица данных, при компиляции это всё превращается в обычные глобальные переменные
    unit caster // применяющий
    unit dummy // дамми
    real damage // урон
    real speed // скорость
    real radius // радиус
    real angle // угол
    real distance // дистанция
    group g // группа юнитов, которые получили урон
    boolean b // нужно для разовой очистки группы получивших урон
    
    method Destroy takes nothing returns nothing // методы - функции используемые в структурах, в нашем случае при уничтожении удаляется даммик с группой и обнуляются переменные
        call KillUnit(this.dummy)
        call GroupClear(this.g)
        call DestroyGroup(this.g)
        set this.caster = null
        set this.dummy = null
        set this.g = null
        call this.destroy()
    endmethod
endstruct

private function DamageCond takes nothing returns boolean
    set bj_lastReplacedUnit = GetFilterUnit()
    if not IsUnitInGroup(bj_lastReplacedUnit,TempG1) and UnitAlive(bj_lastReplacedUnit) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit)) then
        call UnitDamageTarget(bj_lastCreatedUnit,bj_lastReplacedUnit,TempR,false,false,null,null,null)
        call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl",bj_lastReplacedUnit,"chest"))
        call GroupAddUnit(TempG1,bj_lastReplacedUnit)
    endif
    return false
endfunction

private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local real x = GetUnitX(A.dummy)
    local real y = GetUnitY(A.dummy)
    
    if A.distance > 0 then // если юнит не достиг конечной точки, то двигать к ней
        set A.distance = A.distance-A.speed
    else // иначе сменить угол и двигать к кастеру
        call SetUnitFacing(A.dummy,Atan2(GetUnitY(A.caster)-y,GetUnitX(A.caster)-x)*bj_RADTODEG)
        set A.angle = GetUnitFacing(A.dummy)*bj_DEGTORAD
        
        if A.b then // очистить группу получивших урон
            set A.b = false
            call GroupClear(A.g)
        endif
    endif
    set x = x+A.speed*Cos(A.angle)
    set y = y+A.speed*Sin(A.angle)
    call SetUnitPositionEx(A.dummy,x,y)
    
    set TempG1 = A.g
    set TempR = A.damage
    set bj_lastCreatedUnit = A.caster
    call GroupEnumUnitsInRange(TempG,x,y,A.radius,Condition(function DamageCond))
    
    if A.distance <= 0 and DBC(x,y,GetUnitX(A.caster),GetUnitY(A.caster)) <= 50. then
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.Destroy() // вызываем метод уничтожения этой структуры
    endif
    
    set t = null
endfunction

private function myfunc takes nothing returns nothing
    local timer t = CreateTimer()
    local mys A = mys.create() // таким образом объявляется структура. А - название, к которому мы будем обращаться, а mys - название структуры, которую хотим создать
    local integer lvl
    local real x
    local real y
    local real sc
    
    set A.g = CreateGroup()
    set A.caster = GetTriggerUnit()
    set x = GetUnitX(A.caster)
    set y = GetUnitY(A.caster)
    set A.angle = Atan2(GetSpellTargetY()-y,GetSpellTargetX()-x)
    set lvl = GetUnitAbilityLevel(A.caster,'A000')
    set A.dummy = CreateUnit(GetOwningPlayer(A.caster),'u000',x,y,A.angle*bj_RADTODEG)
    call SetUnitPathing(A.dummy,false)
    call UnitAddAbility(A.dummy,'Arav')
    call SetUnitPositionEx(A.dummy,x+50*Cos(A.angle),y+50*Sin(A.angle)) // если юниту что-то помешало заспавниться строго так, как задумано - переместить его в нужную точку
    call SetUnitFlyHeight(A.dummy,50,0)
    
    if     lvl == 1 then // в зависимости от уровня способности определить параметры
        set A.damage = 50.
        set A.speed = 10.
        set A.radius = 100.
        set A.distance = 400.
        set sc = 1.
    elseif lvl == 2 then
        set A.damage = 75.
        set A.speed = 12.
        set A.radius = 150.
        set A.distance = 500.
        set sc = 1.5
    elseif lvl == 3 then
        set A.damage = 130.
        set A.speed = 17.
        set A.radius = 225.
        set A.distance = 700.
        set sc = 2.25
    endif
    set A.damage = A.damage+GetHeroStr(A.caster,true)
    
    call SetUnitScale(A.dummy,sc,sc,sc)
    call SaveInteger(H,GetHandleId(t),0,A) // сохраняем структуру в таймер, структура на самом деле это целочисленная
    call TimerStart(t,.02,true,function move)
    set t = null
endfunction

private function mycond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call myfunc()
    endif
    return false
endfunction
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()

    call TriggerRegisterPlayerUnitEvent(t,Player(0x00),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    call TriggerAddCondition(t,Condition(function mycond))
    
    set MaxX = GetRectMaxX(GetWorldBounds()) // задаём значения глобалкам, чтобы юнит не мог вылететь за карту и не крашнул нам игру
    set MaxY = GetRectMaxY(GetWorldBounds())
    set MinX = GetRectMinX(GetWorldBounds())
    set MinY = GetRectMinY(GetWorldBounds())

    set t = null
endfunction
endlibrary

library mylib1 initializer init // либа для показа урона
globals
    private trigger trg = CreateTrigger()
endglobals
private function myfunc takes nothing returns boolean
    local texttag t = CreateTextTag()
    
    call SetTextTagText(t,I2S(R2I(GetEventDamage())),10*0.023/10)
    call SetTextTagVelocity(t,64*0.071/128*Cos(90*bj_DEGTORAD),64*0.071/128*Sin(90*bj_DEGTORAD))
    call SetTextTagColor(t,255,0,255,255)
    call SetTextTagPosUnit(t,GetTriggerUnit(),0)
    call SetTextTagPermanent(t,false)
    call SetTextTagLifespan(t,.5)
    call SetTextTagFadepoint(t,0.)
    
    set t = null
    return false
endfunction
private function mycond takes nothing returns boolean
    call TriggerRegisterUnitEvent(trg,GetFilterUnit(),EVENT_UNIT_DAMAGED)
    return false
endfunction
private function init takes nothing returns nothing
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,Condition(function mycond))
    call DestroyGroup(g)
    call TriggerAddCondition(trg,Condition(function myfunc))
    set g = null
endfunction
endlibrary



library HC initializer init // счётчик хэндлов чтобы понимать наличие утечек
    globals
    private leaderboard HB
    endglobals
    private function HCU takes nothing returns nothing
        local integer i = 0
        local integer id
        local location array P
        local real result = 0
        loop
            exitwhen i >= 50
            set i = i+1
            set P[i] = Location(0,0)
            set id = GetHandleId(P[i])
            set result = result+(id-0x100000)
        endloop
        set result = result/i-i/2
        loop
            call RemoveLocation(P[i])
            set P[i] = null
            exitwhen i <= 1
            set i = i-1
        endloop
        call LeaderboardSetItemValue(HB,0,R2I(result))
    endfunction

    private function HCA takes nothing returns nothing
        set HB = CreateLeaderboard()
        call LeaderboardSetLabel(HB,"Handle Counter")
        call PlayerSetLeaderboard(GetLocalPlayer(),HB)
        call LeaderboardDisplay(HB,true)
        call LeaderboardAddItem(HB,"Handles",0,Player(0))
        call LeaderboardSetSizeByItemCount(HB,1)
        call HCU()
        call TimerStart(GetExpiredTimer(),.05,true,function HCU)
    endfunction

    private function init takes nothing returns nothing
        call TimerStart(CreateTimer(),0,false,function HCA)
    endfunction
endlibrary
Загруженные файлы
это я делал для друга, мы хотели посмотреть как подобное взаимодействие в варе смотреться будет, код я писал на коленке и никак соответственно не оформлял, так что если хочется блевануть, вы по адресу
это не точная копия само собой (над выстрелами я вообще поленился и взял пламя феникса) но мне в принципе…
Тема
3 387
28
можно цепляться за юнитов
раскрыть
library mylib1 requires functions
globals
    private group TempG = CreateGroup()
    private item TempItem
    private real MaxX
    private real MinX
    private real MaxY
    private real MinY
    private unit CUEX
endglobals

private function SetUnitPositionEx takes unit u, real x, real y returns nothing
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
endfunction

private function CreateUnitEx takes player id, integer unitid, real x, real y, real face returns unit
    set CUEX = CreateUnit(id,unitid,x,y,face*bj_RADTODEG)
    call UnitAddAbility(CUEX,'Arav')
    call SetUnitPathing(CUEX,false)
    call SetUnitPositionEx(CUEX,x,y)
    
    return CUEX
endfunction

// булевые переменные для разных проверок
private struct mys2
    boolean b = false // отменить полёт, если рывок
    boolean b1 = false // возможность юзануть рывок во время полёта
    boolean b2 = false // условие, что можно выбрать направление при столкновении крюка с непроходимой точкой
    boolean b3 = false // условие, что во время полёта крюка было выбрано направление
    real x
    real y
    method Destroy takes nothing returns nothing
        set this.b = false
        set this.b1 = false
        set this.b2 = false
        set this.b3 = false
    endmethod
endstruct

// рывок после полёта
private struct mys1
    unit caster
    real angle
    real dist
endstruct

// полёт
private struct mys
    unit caster
    unit dummy
    unit target
    real angle
    real dist
    real time
    real time1
    real fly
    real a
    real tdist
    real ta
    boolean b
    lightning l
    
    method Destroy takes nothing returns nothing
        call KillUnit(this.dummy)
        call DestroyLightning(this.l)
        call UnitRemoveAbility(this.caster,'A002')
        call UnitRemoveAbility(this.caster,'Abun')
        
        set this.caster = null
        set this.dummy = null
        set this.target = null
        set this.l = null
        call this.destroy()
    endmethod
endstruct

private function DamageCond takes nothing returns boolean
    set bj_lastReplacedUnit = GetFilterUnit()
    return UnitAlive(bj_lastReplacedUnit) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit))
endfunction

private function Damage takes nothing returns nothing
    call UnitDamageTarget(bj_lastCreatedUnit,GetEnumUnit(),100,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
endfunction

// рывок
private function Dash takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys1 A = LoadInteger(H,GetHandleId(t),0)
    local real x = GetUnitX(A.caster)+20*Cos(A.angle)
    local real y = GetUnitY(A.caster)+20*Sin(A.angle)
    local real x1
    local real y1
    
    set A.dist = A.dist-20
    call SetUnitPositionEx(A.caster,x,y)
    call SetItemPosition(TempItem,x,y)
    call SetItemVisible(TempItem,false)
    set x = GetUnitX(A.caster)
    set y = GetUnitY(A.caster)
    set x1 = GetItemX(TempItem)
    set y1 = GetItemY(TempItem)
    
    call CreateUnitEx(GetOwningPlayer(A.caster),'u003',x,y,A.angle)
    call SetUnitVertexColor(CUEX,255,255,255,75)
    call UnitApplyTimedLife(CUEX,'BTLF',.1)
    
    if DBC(x1,y1,x,y) > 0 or A.dist <= 0 or not UnitAlive(A.caster) then
        set bj_lastCreatedUnit = A.caster
        call KillUnit(CreateUnitEx(Player(15),'u002',x,y,GetRandomReal(0,360)))
        
        call GroupEnumUnitsInRange(TempG,x,y,250,Condition(function DamageCond))
        call ForGroup(TempG,function Damage)
        call GroupClear(TempG)
        
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        set A.caster = null
        call A.destroy()
    endif
    
    set t = null
endfunction

// отдать приказ стоп после того, как кастующий выбрал направление
private function stop takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local mys2 A = LoadInteger(H,GetHandleId(LoadUnitHandle(H,i,0)),0)
    call IssueImmediateOrder(LoadUnitHandle(H,i,0),"stop")
    set A.b1 = true // сохранить булевую о возможности юзануть рывок для функции MoveAndDash
    call DestroyTimer(t)
    call FlushChildHashtable(H,i)
    set t = null
endfunction

// движение кастера
private function MoveCaster takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local mys2 A1 = LoadInteger(H,GetHandleId(A.caster),0)
    local real x = GetUnitX(A.dummy)+A.dist*Cos(A.angle)
    local real y = GetUnitY(A.dummy)+A.dist*Sin(A.angle)
    local real x1
    local real y1
    local unit u
    
    if not A1.b then
        set A.angle = A.angle+A.a
        set A.time = A.time-.01
        
        if A.target != null then
            call SetUnitPositionEx(A.dummy,GetUnitX(A.target)+A.tdist*Cos(A.ta),GetUnitY(A.target)+A.tdist*Sin(A.ta))
        endif
        
        call SetUnitPositionEx(A.caster,x,y)
        call SetItemPosition(TempItem,x,y)
        call SetItemVisible(TempItem,false)
        
        set x = GetUnitX(A.caster)
        set y = GetUnitY(A.caster)
        set x1 = GetItemX(TempItem)
        set y1 = GetItemY(TempItem)
        call MoveLightningEx(A.l,true,x,y,GetLocZ(x,y)+GetUnitFlyHeight(A.caster)+50,GetUnitX(A.dummy),GetUnitY(A.dummy),GetLocZ(GetUnitX(A.dummy),GetUnitY(A.dummy))+A.fly)
    endif
    
    if A.time <= 0. or not UnitAlive(A.caster) or A1.b or DBC(x,y,x1,y1) > 10 then
        if not A1.b then // не создавать взрыв если кастуется рывок
            set bj_lastCreatedUnit = A.caster
            set x = GetUnitX(A.caster)
            set y = GetUnitY(A.caster)
            
            set u = CreateUnit(GetOwningPlayer(A.caster),'u002',x,y,GetRandomReal(0,360))
            call SetUnitPositionEx(u,x,y)
            call KillUnit(u)
            set u = null
            
            call GroupEnumUnitsInRange(TempG,x,y,250,Condition(function DamageCond))
            call ForGroup(TempG,function Damage)
            call GroupClear(TempG)
        endif
        
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.Destroy()
        call A1.Destroy()
    endif
    
    set t = null
endfunction

// направление и рывок
private function AngleAndDash takes nothing returns boolean
    local timer t
    local mys A
    local mys1 A1
    local mys2 A2
    local real a
    
    set bj_lastReplacedUnit = GetTriggerUnit()
    set A2 = LoadInteger(H,GetHandleId(bj_lastReplacedUnit),0)
    if A2 > 0 and OrderId2String(GetIssuedOrderId()) != "stop" then
        if A2.b1 then // рывок
            set A2.b = true // сохранить булевую о прекращении полёта для функции MoveCaster
            set A2.b1 = false
            set t = CreateTimer()
            set A1 = mys1.create()
            
            set A1.caster = bj_lastReplacedUnit
            set A1.angle = Atan2(GetOrderPointY()-GetUnitY(bj_lastReplacedUnit),GetOrderPointX()-GetUnitX(bj_lastReplacedUnit))
            set A1.dist = DBC(GetOrderPointX(),GetOrderPointY(),GetUnitX(bj_lastReplacedUnit),GetUnitY(bj_lastReplacedUnit))
            if A1.dist > 300 then
                set A1.dist = 300
            endif
            
            call SaveInteger(H,GetHandleId(t),0,A1)
            call TimerStart(t,.01,true,function Dash)
            set t = null
        endif
        
        if A2.b2 then // в какую сторону начать лететь
            set A2.b2 = false
            set t = CreateTimer()
            set A = LoadInteger(H,GetHandleId(bj_lastReplacedUnit),1)
            set a = bj_RADTODEG*Atan2(GetOrderPointY()-GetUnitY(A.dummy),GetOrderPointX()-GetUnitX(A.dummy))
            set A.b = false
            set A.fly = GetUnitFlyHeight(A.dummy)
            
            call RemoveSavedInteger(H,GetHandleId(A.caster),1)
            
            if A.angle < 0 then
                set A.angle = A.angle+360.
            endif
            if a < 0 then
                set a = a+360.
            endif
            
            if (A.angle < 180. and not (a > A.angle and a < A.angle + 180.)) or (A.angle > 180. and a > A.angle - 180. and a < A.angle) then 
                set A.a = 700*bj_DEGTORAD/A.dist
            else
                set A.a = -700*bj_DEGTORAD/A.dist
            endif
            
            set A.angle = Atan2(GetUnitY(A.caster)-GetUnitY(A.dummy),GetUnitX(A.caster)-GetUnitX(A.dummy))+A.a
            call SaveInteger(H,GetHandleId(t),0,A)
            call UnitAddAbility(A.caster,'A002')
            
            call TimerStart(t,.01,true,function MoveCaster)
            
            // отдать приказ стоп
            set t = CreateTimer()
            call SaveUnitHandle(H,GetHandleId(t),0,A.caster)
            call TimerStart(t,0.,false,function stop)
            set t = null
        endif
        
        set A2.b3 = true
        set A2.x = GetOrderPointX()
        set A2.y = GetOrderPointY()
    endif
    return false
endfunction

// удаление крюка если не полететь
private function DestroyHook takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local mys2 A1 = LoadInteger(H,GetHandleId(A.caster),0)
    local real x
    local real y
    local real x1
    local real y1
    
    if A.target != null then
        set x = GetUnitX(A.target)+A.tdist*Cos(A.ta)
        set y = GetUnitY(A.target)+A.tdist*Sin(A.ta)
        set x1 = GetUnitX(A.caster)
        set y1 = GetUnitY(A.caster)
        set A.dist = DBC(x,y,x1,y1)
        call SetUnitPositionEx(A.dummy,x,y)
        call MoveLightningEx(A.l,true,x1,y1,GetLocZ(x1,y1)+GetUnitFlyHeight(A.caster)+50,x,y,GetLocZ(x,y)+GetUnitFlyHeight(A.dummy))
    endif
    
    if A.b then
        set A.time1 = A.time1-.01
        if A.time1 <= 0. then
            call FlushChildHashtable(H,GetHandleId(t))
            call PauseTimer(t)
            call DestroyTimer(t)
            call A.Destroy()
            call A1.Destroy()
        endif
    else
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    set t = null
endfunction

// движение зацепного крюка
private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer t1
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local mys2 A1
    local real x = GetUnitX(A.dummy)+15*Cos(A.angle)
    local real y = GetUnitY(A.dummy)+15*Sin(A.angle)
    local real x1
    local real y1
    local real a
    
    set A.dist = A.dist-15
    call SetUnitPositionEx(A.dummy,x,y)
    
    call SetItemPosition(TempItem,x,y)
    call SetItemVisible(TempItem,false)
    
    set x = GetUnitX(A.dummy)
    set y = GetUnitY(A.dummy)
    set x1 = GetItemX(TempItem)
    set y1 = GetItemY(TempItem)
    call MoveLightningEx(A.l,true,GetUnitX(A.caster),GetUnitY(A.caster),GetLocZ(GetUnitX(A.caster),GetUnitY(A.caster))+GetUnitFlyHeight(A.caster)+50,x,y,GetLocZ(x,y)+GetUnitFlyHeight(A.dummy))
    set bj_lastCreatedUnit = A.caster
    call GroupEnumUnitsInRange(TempG,x,y,100,Condition(function DamageCond))
    
    if A.dist <= 0 or DBC(x1,y1,x,y) > 0 or not UnitAlive(A.caster) or FirstOfGroup(TempG) != null then
        call PauseTimer(t)
        set bj_lastCreatedUnit = FirstOfGroup(TempG)
        call UnitDamageTarget(A.caster,bj_lastCreatedUnit,50,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
        if (DBC(x1,y1,x,y) > 0 and UnitAlive(A.caster)) or bj_lastCreatedUnit != null then
            call IssueImmediateOrder(A.caster,"stop")
            call UnitAddAbility(A.caster,'Abun')
            call SetUnitTimeScale(A.dummy,0.)
            
            set A.dist = 700.-A.dist
            set A.time = 3.
            set A.angle = A.angle*bj_RADTODEG
            set A.target = bj_lastCreatedUnit
            
            if A.target != null then
                set A.tdist = DBC(x,y,GetUnitX(A.target),GetUnitY(A.target))
                set A.ta = Atan2(y-GetUnitY(A.target),x-GetUnitX(A.target))
            endif
            
            // ради звука удара об стену
            set bj_lastCreatedUnit = CreateUnit(Player(15),'u000',x,y,0)
            call SetUnitVertexColor(bj_lastCreatedUnit,0,0,0,0)
            call KillUnit(bj_lastCreatedUnit)
            set bj_lastCreatedUnit = null
            
            set A1 = LoadInteger(H,GetHandleId(A.caster),0)
            
            if A1.b3 then
                set A.b = false
                set A1.b1 = true
                set A1.b2 = false
                set A1.b3 = false
                
                set a = bj_RADTODEG*Atan2(A1.y-y,A1.x-x)
                set A.fly = GetUnitFlyHeight(A.dummy)
                
                call RemoveSavedInteger(H,GetHandleId(A.caster),1)
                
                if A.angle < 0 then
                    set A.angle = A.angle+360.
                endif
                if a < 0 then
                    set a = a+360.
                endif
                
                if (A.angle < 180. and not (a > A.angle and a < A.angle + 180.)) or (A.angle > 180. and a > A.angle - 180. and a < A.angle) then 
                    set A.a = 700*bj_DEGTORAD/A.dist
                else
                    set A.a = -700*bj_DEGTORAD/A.dist
                endif
                
                set A.angle = Atan2(GetUnitY(A.caster)-y,GetUnitX(A.caster)-x)+A.a
                call UnitAddAbility(A.caster,'A002')
                
                set t1 = CreateTimer()
                call SaveInteger(H,GetHandleId(t1),0,A)
                call TimerStart(t1,.01,true,function MoveCaster)
                set t1 = null
            else
                set A1 = LoadInteger(H,GetHandleId(A.caster),0)
                set A1.b2 = true // сохраняем, что кастер может выбрать куда полететь, для функции AngleAndDash
                set A.b = true
                set A.time1 = 2.
                call SaveInteger(H,GetHandleId(A.caster),1,A)
                call TimerStart(t,.01,true,function DestroyHook) // если в течении 2 секунд не полететь - уничтожить
            endif
        else
            call FlushChildHashtable(H,GetHandleId(t))
            call DestroyTimer(t)
            call A.Destroy()
        endif
        call GroupClear(TempG)
    endif
    
    set t = null
endfunction

// создание зацепного крюка
private function Trig_AkshanE_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local mys A = mys.create()
    local mys2 A1
    local real x
    local real y
    local real x1 = GetSpellTargetX()
    local real y1 = GetSpellTargetY()

    set A.dist = 700.
    set A.caster = GetTriggerUnit()
    set x = GetUnitX(A.caster)
    set y = GetUnitY(A.caster)
    set A.angle = Atan2(y1-y,x1-x)
    set x1 = x+50*Cos(A.angle)
    set y1 = y+50*Sin(A.angle)
    set A.dummy = CreateUnitEx(GetOwningPlayer(A.caster),'u000',x1,y1,A.angle)
    set A.l = AddLightningEx("MFPB",true,x,y,GetLocZ(x,y)+GetUnitFlyHeight(A.caster)+50,x1,y1,GetLocZ(x1,y1)+50)

    call SetUnitFlyHeight(A.dummy,50,0)

    call SaveInteger(H,GetHandleId(t),0,A)
    call TimerStart(t,.01,true,function move)
    
    set A1 = LoadInteger(H,GetHandleId(A.caster),0)
    if A1 == 0 then
        set A1 = mys2.create()
        call SaveInteger(H,GetHandleId(A.caster),0,A1)
    endif
    set A1.b3 = false
    
    set t = null
endfunction

function Trig_AkshanE_Conditions takes nothing returns boolean
    if GetSpellAbilityId() == 'A001' then
        call Trig_AkshanE_Actions()
    endif
    return false
endfunction
//===========================================================================
function InitTrig_AkshanE takes nothing returns nothing
    local trigger t = CreateTrigger()
    local trigger t1 = CreateTrigger()
    set gg_trg_AkshanE = CreateTrigger(  )
    
    set TempItem = CreateItem('spsh',0,0)
    call SetItemVisible(TempItem,false)
    
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)

    call TriggerRegisterPlayerUnitEvent(gg_trg_AkshanE, Player(0x00), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    
    call TriggerAddCondition( gg_trg_AkshanE, Condition(function Trig_AkshanE_Conditions) )
    call TriggerAddCondition(t,Condition(function AngleAndDash))
    
    set MaxX = GetRectMaxX(GetWorldBounds())
    set MaxY = GetRectMaxY(GetWorldBounds())
    set MinX = GetRectMinX(GetWorldBounds())
    set MinY = GetRectMinY(GetWorldBounds())

    set t = null
    set t1 = null
endfunction

endlibrary
Загруженные файлы
28
раскрыть
globals
    location LFZ = Location(0,0)
endglobals

native UnitAlive takes unit id returns boolean

library functions

function GetLocZ takes real x, real y returns real
    call MoveLocation(LFZ,x,y)
    return GetLocationZ(LFZ)
endfunction

function DBC takes real x, real y, real x1, real y1 returns real
   return SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1)) 
endfunction

endlibrary

library mylib1 requires functions
globals
    private group TempG = CreateGroup()
    private item TempItem
endglobals

private function SetUnitPositionEx takes unit u, real x, real y returns nothing
    call SetItemPosition(TempItem,x,y)
    call SetItemVisible(TempItem,false)
    call SetUnitX(u,GetItemX(TempItem))
    call SetUnitY(u,GetItemY(TempItem))
endfunction

private struct mys1
    unit caster
    real angle
    real dist
endstruct

private struct mys
    unit caster
    unit dummy
    real angle
    real dist
    real time
    real time1
    real fly
    real a
    boolean b
    lightning l
    
    method Destroy takes nothing returns nothing
        call KillUnit(this.dummy)
        call DestroyLightning(this.l)
        call RemoveSavedBoolean(H,GetHandleId(this.caster),0)
        call RemoveSavedBoolean(H,GetHandleId(this.caster),2)
        call UnitRemoveAbility(this.caster,'A002')
        call UnitRemoveAbility(this.caster,'Abun')
        
        set this.caster = null
        set this.dummy = null
        set this.l = null
        call this.destroy()
    endmethod
endstruct


private function mycond takes nothing returns boolean
    set bj_lastReplacedUnit = GetFilterUnit()
    return UnitAlive(bj_lastReplacedUnit) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit))
endfunction

private function myfunc7 takes nothing returns nothing
    call UnitDamageTarget(bj_lastCreatedUnit,GetEnumUnit(),100,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
endfunction

private function move1 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local real x = GetUnitX(A.dummy)+A.dist*Cos(A.angle)
    local real y = GetUnitY(A.dummy)+A.dist*Sin(A.angle)
    local unit u
    set A.angle = A.angle+A.a
    set A.time = A.time-.01
    
    call SetUnitPositionEx(A.caster,x,y)
    call MoveLightningEx(A.l,true,GetUnitX(A.caster),GetUnitY(A.caster),A.fly+GetUnitFlyHeight(A.caster),GetUnitX(A.dummy),GetUnitY(A.dummy),GetLocZ(GetUnitX(A.dummy),GetUnitY(A.dummy))+GetUnitFlyHeight(A.dummy))

    if A.time <= 0. or not UnitAlive(A.caster) or LoadBoolean(H,GetHandleId(A.caster),0) or DBC(GetUnitX(A.caster),GetUnitY(A.caster),x,y) > 10 then
        if not LoadBoolean(H,GetHandleId(A.caster),0) then
            set bj_lastCreatedUnit = A.caster
            set x = GetUnitX(A.caster)
            set y = GetUnitY(A.caster)
            
            set u = CreateUnit(GetOwningPlayer(A.caster),'u002',x,y,GetRandomReal(0,360))
            call SetUnitX(u,x)
            call SetUnitY(u,y)
            call KillUnit(u)
            set u = null
            
            call GroupEnumUnitsInRange(TempG,x,y,200,Condition(function mycond))
            call ForGroup(TempG,function myfunc7)
            call GroupClear(TempG)
        endif
        
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.Destroy()
    endif
    
    set t = null
endfunction

private function myfunc5 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    
    if A.b then
        set A.time1 = A.time1-.01
    else
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    
    if A.time1 <= 0. then
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.Destroy()
    endif
    
    set t = null
endfunction

private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local real x = GetUnitX(A.dummy)+15*Cos(A.angle)
    local real y = GetUnitY(A.dummy)+15*Sin(A.angle)
    local real x1
    local real y1
    
    set A.dist = A.dist-15
    call SetUnitPositionEx(A.dummy,x,y)
    
    set x1 = GetUnitX(A.dummy)
    set y1 = GetUnitY(A.dummy)
    call MoveLightningEx(A.l,true,GetUnitX(A.caster),GetUnitY(A.caster),A.fly+GetUnitFlyHeight(A.caster),x1,y1,GetLocZ(x1,y1)+GetUnitFlyHeight(A.dummy))
    
    if A.dist <= 0 or DBC(x1,y1,x,y) > 0 or not UnitAlive(A.caster) then
        call PauseTimer(t)
        if DBC(x1,y1,x,y) > 0 and UnitAlive(A.caster) then
            call UnitAddAbility(A.caster,'Abun')
            call IssueImmediateOrder(A.caster,"stop")
            call SaveBoolean(H,GetHandleId(A.caster),0,false)
            call SaveBoolean(H,GetHandleId(A.caster),2,false)
            call SaveBoolean(H,GetHandleId(A.caster),3,true)
            call SetUnitTimeScale(A.dummy,0.)
            
            // ради звука удара об стену
            set bj_lastCreatedUnit = CreateUnit(Player(15),'u000',x1,y1,0)
            call SetUnitVertexColor(bj_lastCreatedUnit,0,0,0,0)
            call KillUnit(bj_lastCreatedUnit)
            set bj_lastCreatedUnit = null
            
            set A.dist = 700.-A.dist
            set A.time = 3.
            set A.time1 = 2.
            set A.angle = A.angle*bj_RADTODEG
            set A.b = true
            
            call SaveInteger(H,GetHandleId(A.caster),1,A)
            call TimerStart(t,.01,true,function myfunc5) // если в течении 2 секунд не полететь - уничтожить
        else
            call FlushChildHashtable(H,GetHandleId(t))
            call DestroyTimer(t)
            call A.Destroy()
        endif
    endif
    
    set t = null
endfunction

private function myfunc takes nothing returns nothing
    local timer t = CreateTimer()
    local mys A = mys.create()
    local real x
    local real y
    
    set A.caster = GetTriggerUnit()
    set x = GetUnitX(A.caster)
    set y = GetUnitY(A.caster)
    set A.angle = Atan2(GetSpellTargetY()-y,GetSpellTargetX()-x)
    set A.dummy = CreateUnit(GetOwningPlayer(A.caster),'u000',x,y,A.angle*bj_RADTODEG)
    set A.dist = 700.
    set A.fly = GetLocZ(x,y)+50
    set A.l = AddLightningEx("MFPB",true,x,y,A.fly+GetUnitFlyHeight(A.caster),x,y,GetLocZ(x,y)+50)
    
    call UnitAddAbility(A.dummy,'Arav')
    call SetUnitFlyHeight(A.dummy,50,0)
    call SetUnitPathing(A.dummy,false)
    call SetUnitX(A.dummy,x)
    call SetUnitY(A.dummy,y)
    
    call SaveInteger(H,GetHandleId(t),0,A)
    call TimerStart(t,.01,true,function move)
    
    set t = null
endfunction

function Trig_AkshanE_Actions takes nothing returns boolean
    if GetSpellAbilityId() == 'A001' then
        call myfunc()
    endif
    return false
endfunction

private function myfunc3 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    call IssueImmediateOrder(LoadUnitHandle(H,i,0),"stop")
    call SaveBoolean(H,GetHandleId(LoadUnitHandle(H,i,0)),2,true)
    call DestroyTimer(t)
    call FlushChildHashtable(H,i)
    set t = null
endfunction

private function myfunc2 takes nothing returns boolean
    local timer t
    local mys A
    local real a
    if LoadBoolean(H,GetHandleId(GetTriggerUnit()),3) then
        call RemoveSavedBoolean(H,GetHandleId(GetTriggerUnit()),3)
        set t = CreateTimer()
        set A = LoadInteger(H,GetHandleId(GetTriggerUnit()),1)
        set a = bj_RADTODEG * Atan2(GetOrderPointY()-GetUnitY(A.dummy), GetOrderPointX()-GetUnitX(A.dummy))
        set A.b = false
        
        if A.angle < 0 then
            set A.angle = 360.+A.angle
        endif
        if a < 0 then
            set a = a+360.
        endif
        
        if (A.angle < 180. and not(a > A.angle and a < A.angle + 180.)) or (A.angle > 180. and a > A.angle - 180. and a < A.angle) then 
            set A.a = 700*bj_DEGTORAD/A.dist
        else
            set A.a = -700*bj_DEGTORAD/A.dist
        endif
        
        set A.angle = Atan2(GetUnitY(A.caster)-GetUnitY(A.dummy),GetUnitX(A.caster)-GetUnitX(A.dummy))+A.a
        call SaveInteger(H,GetHandleId(t),0,A)
        call RemoveSavedInteger(H,GetHandleId(A.caster),1)
        call TimerStart(t,.01,true,function move1)

        call UnitAddAbility(A.caster,'A002')
        
        set t = CreateTimer()
        call SaveUnitHandle(H,GetHandleId(t),0,A.caster)
        call TimerStart(t,0.,false,function myfunc3)
        set t = null
    endif
    return false
endfunction

private function myfunc6 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys1 A = LoadInteger(H,GetHandleId(t),0)
    local real x = GetUnitX(A.caster)+20*Cos(A.angle)
    local real y = GetUnitY(A.caster)+20*Sin(A.angle)
    
    set A.dist = A.dist-20
    call SetUnitPositionEx(A.caster,x,y)
    
    set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(A.caster),'u003',GetUnitX(A.caster),GetUnitY(A.caster),A.angle*bj_RADTODEG)
    call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,75)
    call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',.1)
    
    if DBC(x,y,GetUnitX(A.caster),GetUnitY(A.caster)) > 10 or A.dist <= 0 or not UnitAlive(A.caster) then
        set bj_lastCreatedUnit = A.caster
        set x = GetUnitX(A.caster)
        set y = GetUnitY(A.caster)
        
        set A.caster = CreateUnit(GetOwningPlayer(bj_lastCreatedUnit),'u002',x,y,GetRandomReal(0,360))
        call SetUnitX(A.caster,x)
        call SetUnitY(A.caster,y)
        call KillUnit(A.caster)
        set A.caster = null
        
        call GroupEnumUnitsInRange(TempG,x,y,200,Condition(function mycond))
        call ForGroup(TempG,function myfunc7)
        call GroupClear(TempG)
        
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        
        call A.destroy()
    endif
    
    set t = null
endfunction

private function myfunc1 takes nothing returns boolean
    local timer t
    local mys1 A
    set bj_lastReplacedUnit = GetTriggerUnit()
    if LoadBoolean(H,GetHandleId(bj_lastReplacedUnit),2) then
        call SaveBoolean(H,GetHandleId(bj_lastReplacedUnit),0,true)
        call RemoveSavedBoolean(H,GetHandleId(bj_lastReplacedUnit),2)
        set t = CreateTimer()
        set A = mys1.create()
        
        set A.caster = bj_lastReplacedUnit
        set A.angle = Atan2(GetOrderPointY()-GetUnitY(bj_lastReplacedUnit),GetOrderPointX()-GetUnitX(bj_lastReplacedUnit))
        set A.dist = DBC(GetOrderPointX(),GetOrderPointY(),GetUnitX(bj_lastReplacedUnit),GetUnitY(bj_lastReplacedUnit))
        if A.dist > 300 then
            set A.dist = 300
        endif
        
        call SaveInteger(H,GetHandleId(t),0,A)
        call TimerStart(t,.01,true,function myfunc6)
        set t = null
    endif
    return false
endfunction
//===========================================================================
function InitTrig_AkshanE takes nothing returns nothing
    local trigger t = CreateTrigger()
    local trigger t1 = CreateTrigger()
    set gg_trg_AkshanE = CreateTrigger(  )
    
    set TempItem = CreateItem('spsh',0,0)
    call SetItemVisible(TempItem,false)
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t1, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t1, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t1, Player(0x00), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_AkshanE, Player(0x00), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerAddCondition( gg_trg_AkshanE, Condition(function Trig_AkshanE_Actions) )
    call TriggerAddCondition(t,Condition(function myfunc1))
    call TriggerAddCondition(t1,Condition(function myfunc2))
endfunction

endlibrary
Загруженные файлы