это я делал для друга, мы хотели посмотреть как подобное взаимодействие в варе смотреться будет, код я писал на коленке и никак соответственно не оформлял, так что если хочется блевануть, вы по адресу
это не точная копия само собой (над выстрелами я вообще поленился и взял пламя феникса) но мне в принципе…
Тема
3 405
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
Загруженные файлы
Делал для другого чела простой гуи-спелл чтобы показать, что можно делать с хэш-таблицей
да и сам впервые юзал хэш-таблицу на гуи
Тема
1 269
Я пам'ятаю своє рідне село! Де я лопатою черпав гівно...
Тема
7 574
28
собираюсь очень сильно преобразить волны, добавить больше вариативности действий, убрать сджасс, а так же сделать более дружелюбным к гуи пользователям
Решил изучить сферические координаты, результатом более менее доволен, но код как всегда говно, карта с видосом в комментах
Тема
2 588
28
говнокод

library mylib
globals
private location LFZ = Location(0,0)
private constant hashtable H = InitHashtable()
private constant real UnitHeight = 80.
private constant integer AbilityWeight = 'A001' // прочность
private constant integer AbilityWeight1 = 'A003' // вес
private constant integer WeaponNumberNot = 0 // Неиспользуемый номер оружия
private group TempG = CreateGroup()
private group TempG1 = null
private real TempR = 0.
private real TempR1 = 0.
private real TempR2 = 0.
private real TempR3 = 0.
private real TempR4 = 0.
private integer TempI = 0
private integer TempI1 = 0
private integer TempI2 = 0
endglobals
private function GetLocZ takes real x, real y returns real
    call MoveLocation(LFZ,x,y)
    return GetLocationZ(LFZ)
endfunction

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

private function SetUnitPositionEx takes unit u, real x, real y returns nothing
    local item i = CreateItem('spsh',x,y)
    local real x1 = GetItemX(i)
    local real y1 = GetItemY(i)
    if DBC(x,y,x1,y1) > 10 then
        set x = x1
        set y = y1
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
    call RemoveItem(i)
    set i = null
endfunction
//==========================================
private struct Bullet
    unit caster
    unit bullet
    real angle
    
    real damage
    integer AttackType
    integer DamageType
    integer bulletArmCount
    integer WeaponNum
    
    real speed
    real speedz
    real distance
    
    real radius
    real radiusZ
    
    real discarding
    real tmDiscarding
    real dsPeriodic
    
    effect Effect
    group Group
endstruct
private struct BulletInfo
    unit caster
    real angle
    real dist
    real z

    real mindamage
    real maxdamage
    integer AttackType
    integer DamageType
    integer bulletCount
    integer bulletArmCount
    integer WeaponNum
    
    real speed
    real distance
    real tmPeriodic
    
    real spreading
    real spreadingZ
    
    real radius
    real radiusZ
    
    real blsPeriodic
    
    real atkOffset
    real atkOffsetZ
    real atkOffsetDist
    
    real discarding
    real tmDiscarding
    real dsPeriodic
    
    string Effect
endstruct

private function DmgCond takes nothing returns boolean
    local real fly
    local real fl
    local boolean b
    local boolean b1
    set bj_lastReplacedUnit = GetFilterUnit()
    set b1 = not IsUnitInGroup(bj_lastReplacedUnit,TempG1) and not (IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_DEAD) or GetUnitTypeId(bj_lastReplacedUnit) < 1) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit)) and TempI2 > 0
    if b1 then
        set fly = GetUnitFlyHeight(bj_lastReplacedUnit)+UnitHeight
        set fl = GetLocZ(GetUnitX(bj_lastReplacedUnit),GetUnitY(bj_lastReplacedUnit))
        if fl < 0 and IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_FLYING) then
            set fly = fly-UnitHeight+(RAbsBJ(fl)*2)
        endif
        if IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_FLYING) then
            set fly = fly-UnitHeight
        endif
        //BJDebugMsg(R2S(fly))
        //BJDebugMsg(R2S(TempR))
        set b = TempR <= fly+TempR1 and TempR >= fly-TempR1
        if b then
            set TempI2 = TempI2-GetUnitAbilityLevel(bj_lastReplacedUnit,AbilityWeight)
        endif
    endif
    return b1 and b
endfunction
private function Discarding takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local unit u = LoadUnitHandle(H,i,0)
    local real a = LoadReal(H,i,4)
    local real sp = LoadReal(H,i,1)
    local real tm = LoadReal(H,i,2)-LoadReal(H,i,3)
    
    call SetUnitPositionEx(u,GetUnitX(u)+sp*Cos(a),GetUnitY(u)+sp*Sin(a))
    
    if tm <= 0. then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
    else
        call SaveReal(H,i,2,tm)
    endif
    
    set t = null
    set u = null
endfunction
private function Dmg takes nothing returns nothing
    local timer t
    local integer i
    local unit u = GetEnumUnit()
    call GroupAddUnit(TempG1,u)
    call UnitDamageTarget(bj_lastCreatedUnit,u,TempR,false,false,ConvertAttackType(TempI),ConvertDamageType(TempI1),null)
    if not IsUnitType(u,UNIT_TYPE_DEAD) and TempR1 > 0. and GetUnitAbilityLevel(u,AbilityWeight1) > 0 then
        set t = CreateTimer()
        set i = GetHandleId(t)
        call SaveUnitHandle(H,i,0,u)
        call SaveReal(H,i,1,TempR1*(GetUnitAbilityLevel(u,AbilityWeight1)*.1))
        call SaveReal(H,i,2,TempR2)
        call SaveReal(H,i,3,TempR3)
        call SaveReal(H,i,4,TempR4)
        call TimerStart(t,TempR3,true,function Discarding)
        set t = null
    endif
    set u = null
endfunction

private function Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local Bullet A = LoadInteger(H,GetHandleId(t),0)
    local real x  = GetUnitX(A.bullet)
    local real y  = GetUnitY(A.bullet)
    local real z  = GetUnitFlyHeight(A.bullet)+GetLocZ(x,y)
    local real zun
    local boolexpr b = Condition(function DmgCond)
    
    set x = x+Cos(A.angle)*Cos(A.speedz)*A.speed
    set y = y+Sin(A.angle)*Cos(A.speedz)*A.speed
    set zun = (z+A.speed*Sin(A.speedz))-GetLocZ(x,y)
    
    call SetUnitX(A.bullet,x)
    call SetUnitY(A.bullet,y)
    call SetUnitFlyHeight(A.bullet,zun,0.)

    set TempR = zun
    set bj_lastCreatedUnit = A.caster
    set TempR1 = A.radiusZ
    set TempI2 = A.bulletArmCount
    set TempG1 = A.Group
    call GroupEnumUnitsInRange(TempG,x,y,A.radius,b)
    if FirstOfGroup(TempG) != null then
        set TempR = A.damage
        set TempR1 = A.discarding
        set TempR2 = A.tmDiscarding
        set TempR3 = A.dsPeriodic
        set TempR4 = A.angle
        set TempI = A.AttackType
        set TempI1 = A.DamageType
        set udg_TF = A.WeaponNum
        call ForGroup(TempG,function Dmg)
        set udg_TF = WeaponNumberNot
        call GroupClear(TempG)
    endif

    set A.distance = A.distance-A.speed
    set A.bulletArmCount = TempI2
    
    if zun <= 0.00 or A.distance <= 0. or A.bulletArmCount <= 0 or (x+A.speed >= GetRectMaxX(bj_mapInitialPlayableArea) or x-A.speed <= GetRectMinX(bj_mapInitialPlayableArea) or y+A.speed >= GetRectMaxY(bj_mapInitialPlayableArea) or y-A.speed <= GetRectMinY(bj_mapInitialPlayableArea)) then
        
        call KillUnit(A.bullet)
        call DestroyEffect(A.Effect)
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        
        call A.destroy()
        
        set A.caster = null
        set A.bullet = null
        set A.angle = 0.
    
        set A.damage = 0.
        set A.AttackType = 0
        set A.DamageType = 0
        set A.bulletArmCount = 0
        set A.WeaponNum = 0
        
        set A.speed = 0.
        set A.speedz = 0.
        set A.distance = 0.
        
        set A.radius = 0.
        set A.radiusZ = 0.
        
        set A.discarding = 0.
        set A.tmDiscarding = 0.
        set A.dsPeriodic = 0.
        
        call GroupClear(A.Group)
        call DestroyGroup(A.Group)
        set A.Group = null
    endif
    
    set t = null
    set TempG1 = null
endfunction

private function Create takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer t1 = CreateTimer()
    local integer i = GetHandleId(t1)
    local BulletInfo A = LoadInteger(H,GetHandleId(t),0)
    local Bullet A1 = Bullet.create()
    
    local real xu = GetUnitX(A.caster)
    local real yu = GetUnitY(A.caster)
    local real zu = GetLocZ(xu,yu)+GetUnitFlyHeight(A.caster)
   
    local real a  = A.angle+(GetRandomReal(-(A.spreading/2),A.spreading/2)*bj_DEGTORAD)
    local real xr = xu+A.atkOffsetDist*Cos(a+(A.atkOffset*bj_DEGTORAD))
    local real yr = yu+A.atkOffsetDist*Sin(a+(A.atkOffset*bj_DEGTORAD))
    local real zr = ((zu-GetLocZ(xr,yr))+A.atkOffsetZ)+GetLocZ(xr,yr)
    local real zs = Atan2(A.z-zr,A.dist)+(GetRandomReal(-(A.spreadingZ/2),A.spreadingZ/2)*bj_DEGTORAD)
    local unit r  = CreateUnit(GetOwningPlayer(A.caster),'u000',xr,yr,a*bj_RADTODEG)
    
    if zs*bj_RADTODEG > 90. then
        set zs = 90.*bj_DEGTORAD
    elseif zs*bj_RADTODEG < -90. then
        set zs = -90.*bj_DEGTORAD
    endif
    
    call SetUnitX(r,xr)
    call SetUnitY(r,yr)
    call UnitAddAbility(r,'Arav')
    call SetUnitFlyHeight(r,zr-GetLocZ(xr,yr),0.00)
    call SetUnitAnimationByIndex(r,R2I(zs*bj_RADTODEG)+90)
    
    set A1.caster = A.caster
    set A1.bullet = r
    set A1.angle = a
    
    set A1.damage = GetRandomReal(A.mindamage,A.maxdamage)
    set A1.AttackType = A.AttackType
    set A1.DamageType = A.DamageType
    set A1.bulletArmCount = A.bulletArmCount
    set A1.WeaponNum = A.WeaponNum
    
    set A1.speed = A.speed
    set A1.speedz = zs
    set A1.distance = A.distance
    
    set A1.radius = A.radius
    set A1.radiusZ = A.radiusZ
    
    set A1.discarding = A.discarding
    set A1.tmDiscarding = A.tmDiscarding
    set A1.dsPeriodic = A.dsPeriodic
    
    set A1.Effect = AddSpecialEffectTarget(A.Effect,r,"head")
    set A1.Group = CreateGroup()
    
    call SaveInteger(H,i,0,A1)
    call TimerStart(t1,A.tmPeriodic,true,function Move)
    //===================================
    set A.bulletCount = A.bulletCount-1
    
    if A.bulletCount <= 0 then
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.destroy()
        
        set A.caster = null
        set A.angle = 0.
        set A.dist = 0.
        set A.z = 0.
    
        set A.mindamage = 0.
        set A.maxdamage = 0.
        set A.AttackType = 0
        set A.DamageType = 0
        set A.bulletCount = 0
        set A.bulletArmCount = 0
        set A.WeaponNum = 0
    
        set A.speed = 0.
        set A.distance = 0.
        set A.tmPeriodic = 0.
    
        set A.spreading = 0.
        set A.spreadingZ = 0.
    
        set A.radius = 0.
        set A.radiusZ = 0.
    
        set A.blsPeriodic = 0.
    
        set A.atkOffset = 0.
        set A.atkOffsetZ = 0.
        set A.atkOffsetDist = 0.
    
        set A.discarding = 0.
        set A.tmDiscarding = 0.
        set A.dsPeriodic = 0.
        
        set A.Effect = ""
    endif
    
    set r = null
    set t = null
    set t1 = null
endfunction

function Shoot takes nothing returns nothing
    local timer t = CreateTimer()
    local BulletInfo A = BulletInfo.create()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real z = GetLocZ(x,y)
    local real zu = GetLocZ(GetUnitX(udg_Unit[0]),GetUnitY(udg_Unit[0]))+GetUnitFlyHeight(udg_Unit[0])
    if udg_Unit[1] != null then
        set x = GetUnitX(udg_Unit[1])
        set y = GetUnitY(udg_Unit[1])
        if IsUnitType(udg_Unit[1],UNIT_TYPE_FLYING) then
            set z = GetLocZ(x,y)
            if z < 0 then
                set z = RAbsBJ(z)-UnitHeight
            else
                set z = z+UnitHeight
            endif
        else
            if z+udg_Real[9] >= zu-udg_Real[9] then
                set z = z+udg_Real[9]
            endif
        endif
        set z = z+GetUnitFlyHeight(udg_Unit[1])
    else
        if z+udg_Real[9] >= zu-udg_Real[9] then
            set z = z+udg_Real[9]
        endif
    endif
    
    set A.caster = udg_Unit[0]
    set A.angle = Atan2(y-GetUnitY(udg_Unit[0]),x-GetUnitX(udg_Unit[0]))
    set A.dist = DBC(GetUnitX(udg_Unit[0]),GetUnitY(udg_Unit[0]),x,y)
    set A.z = z
    
    set A.mindamage = udg_Real[0]
    set A.maxdamage = udg_Real[15]
    set A.AttackType = GetHandleId(udg_AttackType)
    set A.DamageType = GetHandleId(udg_DamageType)
    set A.bulletCount = udg_Int
    set A.bulletArmCount = udg_BulletArm
    set A.WeaponNum = udg_TF
    
    set A.speed = udg_Real[2]
    set A.distance = udg_Real[1]
    set A.tmPeriodic = udg_Real[5]
    
    set A.spreading = udg_Real[3]
    set A.spreadingZ = udg_Real[4]
    
    set A.radius = udg_Real[6]
    set A.radiusZ = udg_Real[7]
    
    set A.blsPeriodic = udg_Real[8]
    
    set A.atkOffset = udg_Real[11]
    set A.atkOffsetZ = udg_Real[9]
    set A.atkOffsetDist = udg_Real[10]
    
    set A.discarding = udg_Real[12]
    set A.tmDiscarding = udg_Real[13]
    set A.dsPeriodic = udg_Real[14]
    
    set A.Effect = udg_Effect
    
    call SaveInteger(H,GetHandleId(t),0,A)
    call TimerStart(t,udg_Real[8],true,function Create)
endfunction

endlibrary





library AINativesLib

native GetPlayerUnitTypeCount takes player p, integer unitid            returns integer

native GetUnitGoldCost      takes integer unitid                        returns integer
native GetUnitWoodCost      takes integer unitid                        returns integer
native GetUnitBuildTime     takes integer unitid                        returns integer

native UnitAlive            takes unit id                               returns boolean

endlibrary

library NegateDamageLib
globals
    private constant group Group = CreateGroup()
    private constant timer Timer = CreateTimer()
    
    // MUST BE SPECIFIED
    public constant integer MaxLifeBonusAbility = 'A002'
    public constant integer MaxLifeBonus = 1000000
endglobals

private function ProcessUnits takes nothing returns nothing
    local unit u
    local real life2set
    
    loop
        set u = FirstOfGroup(Group)
        exitwhen u == null
        call GroupRemoveUnit(Group, u)
        
        if UnitAlive(u) then
            set life2set = GetWidgetLife(u)
            call UnitRemoveAbility(u, MaxLifeBonusAbility)
            call SetWidgetLife(u, life2set)
        else
            call UnitRemoveAbility(u, MaxLifeBonusAbility)
        endif
    endloop
endfunction

function NegateDamage takes unit u, real negated returns nothing
    local real life = GetWidgetLife(u)
    call GroupAddUnit(Group, u)
    call UnitAddAbility(u, MaxLifeBonusAbility)
    call SetWidgetLife(u, life + negated)
    
    call TimerStart(Timer, 0., false, function ProcessUnits)
endfunction

function GetUnitMaxHealth takes unit u returns real
    return GetUnitState(u, UNIT_STATE_MAX_LIFE) - MaxLifeBonus * GetUnitAbilityLevel(u, MaxLifeBonusAbility)
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 450
28
Эль_Кин, ахаха, спасибо))
На самом деле на этот прогресс ушло куда больше времени и недоскиллов, но я всё равно не доволен результатом. Типо всё что в этой карте - банальщина, видели миллион раз, так оно ещё и криво написано)
Думаю мне просто нужна конструктивная критика с предложениями как можно сделать лучше
11
Ого, хороший спеллпак получился, я смотрю твой скилл вырос после тех двух-трёх скиллов, которые ты мне помогал делать.)
28
Готово. Можно было бы ещё добавить деформацию ланда для ульты, но на больших картах оно лагает. Повторюсь, это не для импорта, ибо никаких настроек по использованию и разбора кода я не оставлял. Просто посмотреть на возможности джасса если кому интересно. Мотивация так сказать
хотя кого это говнище мотивировать будет, лол)
upd в видео музыка
Код

library mylib initializer init
    private hashtable H = InitHashtable()
    private trigger trg = CreateTrigger()
    private group TempG = CreateGroup()
    private group TempG1 = CreateGroup()
    private unit CUEX = null
    private real TempR
    private real TempR1
    private real TempR2
    private real TempR3
    private real TempX
    private real TempY
    private integer TF = 0
    private integer TF1 = 0
    private boolean FireID
    private damagetype DamageType
    // Переменные быстрого доступа управления полётом апокалиптического дождя
    private constant real RainFly = 600
    private constant real RainFlyD = 100
    // Воспомогательные функции
    private function Kill takes nothing returns nothing
        call KillUnit(GetEnumUnit())
    endfunction
    
    private function IsUnitDead takes unit u returns boolean
        return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) < 1
    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 SetUnitX(CUEX,x)
        call SetUnitY(CUEX,y)
        return CUEX
    endfunction
    
    private function li takes nothing returns boolean
        return not IsUnitDead(GetFilterUnit()) and GetUnitTypeId(GetFilterUnit()) != 'u000'
    endfunction
    
    private function DBC takes real x, real y, real x1, real y1 returns real
        return SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1)) 
    endfunction 
    
    private function IsPointInSector takes real x1, real y1, real x2, real y2, real orientation, real width, real radius returns boolean
        local real lenght = DBC(x1,y1,x2,y2)
        local real angle = Acos(Cos(orientation*bj_DEGTORAD)*(x1-x2)/lenght+Sin(orientation*bj_DEGTORAD)*(y1-y2)/lenght )*bj_RADTODEG
        return angle<=width and lenght<=radius
    endfunction
    
    private function SetUnitPositionEx takes unit u, real x, real y returns nothing
        local item i = CreateItem('spsh',x,y)
        set TempX = GetItemX(i)
        set TempY = GetItemY(i)
        set TempR = DBC(x,y,TempX,TempY)
        if TempR > 10 then
            call SetUnitX(u,TempX)
            call SetUnitY(u,TempY)
        else
            call SetUnitX(u,x)
            call SetUnitY(u,y)
        endif
        call RemoveItem(i)
        set i = null
    endfunction
    
    //===================================================
        // Пламя преисподней
    private function UnderworldFlamesDMG takes nothing returns nothing
        local timer t=GetExpiredTimer()
        local integer timerH=GetHandleId(t)
        local unit caster=LoadUnitHandle(H,timerH,1)
        local unit target=LoadUnitHandle(H,timerH,2)
        local integer casterH=GetHandleId(caster)
        local integer targetH=GetHandleId(target)
        local integer level=LoadInteger(H,timerH,3)
        local integer counter=LoadInteger(H,targetH,casterH)
        local real dmg = LoadReal(H,timerH,0)

        call SaveInteger(H,targetH,casterH,counter-1)
        set TF = 1
        call UnitDamageTarget(caster,target,dmg,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_FIRE,null)
        set TF = 0
        if counter == 1 or IsUnitDead(target) or GetUnitAbilityLevel(target,'B000') < 1 then
            call UnitRemoveAbility(target,'A000')
            call UnitRemoveAbility(target,'B000')
            call RemoveSavedInteger(H,targetH,casterH)
            call FlushChildHashtable(H,timerH)
            call PauseTimer(t)
            call DestroyTimer(t)
        endif
        
        set t=null
        set caster=null
        set target=null
    endfunction
    
    private function UnderworldFlames takes unit u, unit u1 returns nothing
        local integer casterH=GetHandleId(u)
        local integer targetH=GetHandleId(u1)
        local integer lvl=GetUnitAbilityLevel(u,'A005')
        local integer timerH
        local integer counter=LoadInteger(H,targetH,casterH)
        local integer tm
        local timer t
        local real dmg
        
        if lvl == 1 then
            set dmg = 5.
            set tm = 3
        elseif lvl == 2 then
            set dmg = 15.
            set tm = 5
        elseif lvl == 3 then
            set dmg = 20.
            set tm = 6
        endif
        set dmg = dmg+(GetHeroInt(u,true)*.1)
        if counter == 0 then
            call UnitAddAbility(u1,'A000')
            set t = CreateTimer()
            set timerH = GetHandleId(t)
            call SaveReal(H,timerH,0,dmg)
            call SaveUnitHandle(H,timerH,1,u)
            call SaveUnitHandle(H,timerH,2,u1)
            call SaveInteger(H,timerH,3,lvl)
            call TimerStart(t,1.,true,function UnderworldFlamesDMG)
            set t=null
        endif
        
        call SaveInteger(H,targetH,casterH,tm)
    endfunction
    // Планетарное разрушение
    private function PlanetaryDestructionCond takes nothing returns boolean
        set bj_lastReplacedUnit = GetFilterUnit()
        return not IsUnitDead(bj_lastReplacedUnit) and not IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit)) and not IsUnitInGroup(bj_lastReplacedUnit,TempG1)
    endfunction
    private function PlanetaryDiscarding takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        local unit u = LoadUnitHandle(H,i,0)
        local real a = LoadReal(H,i,2)
        local real s = LoadReal(H,i,6)
        local real tm = LoadReal(H,i,4)+.02
        
        call SetUnitPositionEx(u,GetUnitX(u)+s*Cos(a),GetUnitY(u)+s*Sin(a))
        
        if TempR > 10 and not IsUnitDead(u) then
            call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl",GetUnitX(u),GetUnitY(u)))
            set TF = 1
            call UnitDamageTarget(LoadUnitHandle(H,i,3),u,LoadReal(H,i,1),false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_SONIC,null)
            set TF = 0
            if not IsUnitDead(u) then
                call CreateUnitEx(Player(15),'u007',GetUnitX(u),GetUnitY(u),0)
                call UnitAddAbility(CUEX,'A008')
                call IssueTargetOrder(CUEX,"thunderbolt",u)
                call UnitApplyTimedLife(CUEX,'BTLF',1)
            endif
        endif
        if TempR > 10 or tm > LoadReal(H,i,5) or GetUnitTypeId(u) < 1 then
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushChildHashtable(H,i)
        else
            call SaveReal(H,i,4,tm)
        endif
        
        set t = null
        set u = null
    endfunction
    private function PlanetaryDestructionDmg takes nothing returns nothing
        local unit u = GetEnumUnit()
        local timer t
        local integer i
        local real x
        local real y
        local real dc
        local real tm
        
        call UnitDamageTarget(bj_lastCreatedUnit,u,TempR1,false,false,ATTACK_TYPE_MAGIC,DamageType,null)
        if not IsUnitDead(u) then
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            call CreateUnitEx(Player(15),'u007',x,y,0)
            if TF1 == 0 then
                call UnitAddAbility(CUEX,'A008')
                call IssueTargetOrder(CUEX,"thunderbolt",u)
                call UnitApplyTimedLife(CUEX,'BTLF',1)
            else
                call UnitAddAbility(CUEX,'A009')
                call IssueTargetOrder(CUEX,"slow",u)
                call UnitApplyTimedLife(CUEX,'BTLF',1)
                set t = CreateTimer()
                set i = GetHandleId(t)
                call SaveUnitHandle(H,i,0,u)
                call SaveReal(H,i,1,TempR1*.5)
                call SaveReal(H,i,2,Atan2(y-TempR3,x-TempR2))
                call SaveUnitHandle(H,i,3,bj_lastCreatedUnit)
                if GetUnitAbilityLevel(u,'A002') > 0 then
                    set tm = .1
                    set dc = 7.5
                elseif GetUnitAbilityLevel(u,'A003') > 0 then
                    set tm = .5
                    set dc = 10.
                else
                    set tm = .5
                    set dc = 15.
                endif
                call SaveReal(H,i,5,tm)
                call SaveReal(H,i,6,dc)
                call TimerStart(t,.02,true,function PlanetaryDiscarding)
                set t = null
            endif
            if FireID then
                call UnderworldFlames(bj_lastCreatedUnit,u)
            endif
            call GroupAddUnit(TempG1,u)
        endif
        
        set u = null
    endfunction
    private function PlanetaryDestructionAct takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        local unit u = LoadUnitHandle(H,i,1)
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        local real dmg = LoadReal(H,i,4)
        set FireID = LoadBoolean(H,i,3)
        if FireID then
            call KillUnit(CreateUnitEx(Player(15),'u00A',x,y,GetRandomReal(0,360)))
        endif
        set TempR1 = dmg*2
        set TempR2 = x
        set TempR3 = y
        set TF = 1
        
        set DamageType = DAMAGE_TYPE_DEMOLITION
        set bj_lastCreatedUnit = LoadUnitHandle(H,i,0)
        call GroupEnumUnitsInRange(TempG,x,y,200,Condition(function PlanetaryDestructionCond))
        call ForGroup(TempG,function PlanetaryDestructionDmg)
        call GroupClear(TempG)
        
        set TempR1 = dmg
        set TF1 = 1
        set DamageType = DAMAGE_TYPE_SONIC
        call GroupEnumUnitsInRange(TempG,x,y,500,Condition(function PlanetaryDestructionCond))
        call ForGroup(TempG,function PlanetaryDestructionDmg)
        call GroupClear(TempG)
        call GroupClear(TempG1)
        set TF = 0
        set TF1 = 0
        
        call KillUnit(CreateUnitEx(Player(15),'u003',x,y,GetRandomReal(0,360)))
        call KillUnit(CreateUnitEx(Player(15),'u00C',x,y,GetRandomReal(0,360)))
        call KillUnit(CreateUnitEx(Player(15),'u00B',x,y,GetRandomReal(0,360)))
        call KillUnit(CreateUnitEx(Player(15),'u009',x,y,GetRandomReal(0,360)))
        call KillUnit(CreateUnitEx(Player(15),'u008',x,y,GetRandomReal(0,360)))
        call KillUnit(u)
        call KillUnit(LoadUnitHandle(H,i,2))
        
        call DestroyFogModifier(LoadFogModifierHandle(H,i,5))
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
        
        set bj_lastCreatedUnit = null
        set t = null
        set u = null
    endfunction
    private function PlanetaryDestruction takes nothing returns nothing
        local timer t = CreateTimer()
        local integer i = GetHandleId(t)
        local unit u = GetTriggerUnit()
        local real x = GetSpellTargetX()
        local real y = GetSpellTargetY()
        local real dmg = 300+(GetHeroInt(u,true))
        
        set FireID = GetUnitAbilityLevel(u,'B001') > 0
        if FireID then
            set dmg = dmg+(dmg*(.05*GetUnitAbilityLevel(u,'A005')))
        endif
        
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        set bj_lastCreatedFogModifier = CreateFogModifierRadius(bj_groupEnumOwningPlayer,FOG_OF_WAR_VISIBLE,x,y,1000, true, false)
        call FogModifierStart(bj_lastCreatedFogModifier)
        
        call SaveUnitHandle(H,i,0,u)
        call SaveUnitHandle(H,i,1,CreateUnitEx(bj_groupEnumOwningPlayer,'u006',x,y,bj_RADTODEG*Atan2(y-GetUnitY(u),x-GetUnitX(u))))
        call SaveUnitHandle(H,i,2,CreateUnitEx(bj_groupEnumOwningPlayer,'u006',x,y,bj_RADTODEG*Atan2(y-GetUnitY(u),x-GetUnitX(u))))
        call SaveBoolean(H,i,3,FireID)
        call SaveReal(H,i,4,dmg)
        call SaveFogModifierHandle(H,i,5,bj_lastCreatedFogModifier)
        call TimerStart(t,.9,false,function PlanetaryDestructionAct)
        
        
        set u = null
        set t = null
    endfunction
    
    // Огненный дождь
    private function FieryRainDmgCond takes nothing returns boolean
        set bj_lastReplacedUnit = GetFilterUnit()
        return not IsUnitDead(bj_lastReplacedUnit) and not IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit))
    endfunction
    private function FieryRainDmg1 takes nothing returns nothing
        call UnitDamageTarget(bj_lastCreatedUnit,GetEnumUnit(),TempR,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_FIRE,null)
        if FireID then
            call UnderworldFlames(bj_lastCreatedUnit,GetEnumUnit())
        endif
    endfunction
    private function FieryRainDmg takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        local unit u = LoadUnitHandle(H,i,0)
        set bj_lastCreatedUnit = LoadUnitHandle(H,i,1)
        
        if GetUnitTypeId(bj_lastCreatedUnit) > 0 then
            call GroupEnumUnitsInRange(TempG,GetUnitX(u),GetUnitY(u),LoadReal(H,i,3),Condition(function FieryRainDmgCond))
            set FireID = GetUnitTypeId(u) == 'u004'
            set TempR = LoadReal(H,i,2)
            set TF = 1
            call ForGroup(TempG,function FieryRainDmg1)
            set TF = 0
            call GroupClear(TempG)
        endif
        
        call KillUnit(u)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
        
        set u = null
        set t = null
    endfunction
    
    private function FieryRainAct takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local timer t1
        local integer i = GetHandleId(t)
        local unit u = LoadUnitHandle(H,i,0)
        local integer count = LoadInteger(H,i,4)
        local integer count1 = LoadInteger(H,i,5)-1
        local integer count2 = count
        local integer id = LoadInteger(H,i,1)
        local integer i1
        local real a = GetRandomReal(0,360)
        local real x = LoadReal(H,i,7)
        local real y = LoadReal(H,i,8)
        local real sc = LoadReal(H,i,9)
        local real maxr = LoadReal(H,i,3)
        local real minr
        local real ranr
        local real fly
        local real dmg = LoadReal(H,i,2)
        local real rad = LoadReal(H,i,10)
        
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        
        loop
            exitwhen count <= 0
            set minr = GetRandomReal(0,maxr*.2)
            set ranr = GetRandomReal(minr,maxr)
            call CreateUnitEx(bj_groupEnumOwningPlayer,id,x+ranr*Cos(a*bj_DEGTORAD),y+ranr*Sin(a*bj_DEGTORAD),GetRandomReal(0,360))
            set fly = GetRandomReal(RainFly-RainFlyD,RainFly+RainFlyD)
            call UnitAddAbility(CUEX,'Arav')
            call SetUnitFlyHeight(CUEX,fly,0)
            call SetUnitFlyHeight(CUEX,0,RainFly)
            call SetUnitScale(CUEX,sc,sc,sc)
            set t1 = CreateTimer()
            set i1 = GetHandleId(t1)
            call SaveUnitHandle(H,i1,0,CUEX)
            call SaveUnitHandle(H,i1,1,u)
            call SaveReal(H,i1,2,dmg)
            call SaveReal(H,i1,3,rad)
            call TimerStart(t1,fly/RainFly,false,function FieryRainDmg)
            set a = a+(360/count2)
            set count = count-1
        endloop
        set t1 = null
        if count1 <= 0 or GetUnitTypeId(u) < 1 then
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushChildHashtable(H,i)
        else
            call SaveInteger(H,i,5,count1)
            call TimerStart(t,LoadReal(H,i,6),false,function FieryRainAct)
        endif
        
        set u = null
        set t = null
    endfunction
    
    private function FieryRain takes nothing returns nothing
        local timer t = CreateTimer()
        local integer i = GetHandleId(t)
        local unit u = GetTriggerUnit()
        local integer lvl = GetUnitAbilityLevel(u,GetSpellAbilityId())
        local integer id
        local integer count
        local integer count1
        local real dmg
        local real scale
        local real radius
        local real radius1
        local real periodic
        set FireID = GetUnitAbilityLevel(u,'B001') > 0
        if FireID then
            set id = 'u004'
        else
            set id = 'u005'
        endif
        
        if     lvl == 1 then
            set dmg = 25.
            set scale = 1.
            set radius = 400.
            set radius1 = 80.
            set count = 15
            set count1 = 5
            set periodic = 1.
        elseif lvl == 2 then
            set dmg = 40.
            set scale = 1.25
            set radius = 600.
            set radius1 = 100.
            set count = 20
            set count1 = 7
            set periodic = 1.
        elseif lvl == 3 then
            set dmg = 70.
            set scale = 1.5
            set radius = 1000.
            set radius1 = 120.
            set count = 30
            set count1 = 10
            set periodic = 1.
        endif
        set dmg = dmg+(GetHeroInt(u,true)*.4)
        if FireID then
            set dmg = dmg+(dmg*(.05*GetUnitAbilityLevel(u,'A005')))
        endif
        call SaveUnitHandle(H,i,0,u)
        call SaveInteger(H,i,1,id)
        call SaveReal(H,i,2,dmg)
        call SaveReal(H,i,3,radius)
        call SaveInteger(H,i,4,count)
        call SaveInteger(H,i,5,count1)
        call SaveReal(H,i,6,periodic)
        call SaveReal(H,i,7,GetSpellTargetX())
        call SaveReal(H,i,8,GetSpellTargetY())
        call SaveReal(H,i,9,scale)
        call SaveReal(H,i,10,radius1)
        call TimerStart(t,0.,false,function FieryRainAct)
        
        set u = null
        set t = null
    endfunction
    // Огненная стена
    private function FireWallCond takes nothing returns boolean
        set bj_lastReplacedUnit = GetFilterUnit()
        return not IsUnitDead(bj_lastReplacedUnit) and not IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitInGroup(bj_lastReplacedUnit,TempG1) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit))
    endfunction
    private function FireWallDamageEx takes nothing returns nothing
        local unit u = GetEnumUnit()
        call UnitDamageTarget(bj_lastCreatedUnit,u,TempR,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_FIRE,null)
        if not IsUnitDead(u) and FireID then
            call UnderworldFlames(bj_lastCreatedUnit,u)
        endif
        call GroupAddUnit(TempG1,u)
        set u = null
    endfunction
    private function FireWallDamage takes nothing returns nothing
        local unit u = GetEnumUnit()
        call GroupEnumUnitsInRange(TempG,GetUnitX(u),GetUnitY(u),TempR1,Condition(function FireWallCond))
        call ForGroup(TempG,function FireWallDamageEx)
        call GroupClear(TempG)
        set u = null
    endfunction
    private function FireWallDmg takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        local group g = LoadGroupHandle(H,i,1)
        local real tm = LoadReal(H,i,2)-.25
        
        set bj_lastCreatedUnit = LoadUnitHandle(H,i,0)
        set TempR = LoadReal(H,i,3)
        set FireID = LoadBoolean(H,i,4)
        set TempR1 = 100.
        set TF = 1
        call ForGroup(g,function FireWallDamage)
        call GroupClear(TempG1)
        set TF = 0
        
        if tm <= 0. then
            call ForGroup(g,function Kill)
            call GroupClear(g)
            call DestroyGroup(g)
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushChildHashtable(H,i)
        else
            call SaveReal(H,i,2,tm)
        endif
        
        set bj_lastCreatedUnit = null
        set g = null
        set t = null
    endfunction
    
    private function FireWall takes nothing returns nothing
        local timer t = CreateTimer()
        local integer i = GetHandleId(t)
        local unit u = GetTriggerUnit()
        local integer lvl = GetUnitAbilityLevel(u,GetSpellAbilityId())
        local integer id
        local boolean b = GetUnitAbilityLevel(u,'B001') > 0
        local group g = CreateGroup()
        local real x = GetSpellTargetX()
        local real y = GetSpellTargetY()
        local real a = bj_RADTODEG*Atan2(y-GetUnitY(u),x-GetUnitX(u))
        local real d
        local real d1
        local real dmg
        local real dmg1
        local real sc
        local real tm
        
        if     lvl == 1 then
            set dmg1 = 80.
            set dmg = 25.
            set d = 300.
            set tm = 5.
            set sc = .5
        elseif lvl == 2 then
            set dmg1 = 150.
            set dmg = 40.
            set d = 400.
            set tm = 7.
            set sc = .75
        elseif lvl == 3 then
            set dmg1 = 225.
            set dmg = 70.
            set d = 500.
            set tm = 10.
            set sc = 1.
        endif
        set dmg = dmg+(GetHeroInt(u,true)*.5)
        set dmg1 = dmg1+(GetHeroInt(u,true)*.65)
        if b then
            set id = 'u002'
            set dmg = dmg+(dmg*(.05*GetUnitAbilityLevel(u,'A005')))
            set dmg1 = dmg1+(dmg1*(.05*GetUnitAbilityLevel(u,'A005')))
        else
            set id = 'u001'
        endif
        set d1 = d/2
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupAddUnit(g,CreateUnitEx(bj_groupEnumOwningPlayer,id,x,y,GetRandomReal(0,360)))
        call KillUnit(CreateUnitEx(bj_groupEnumOwningPlayer,'u000',x,y,GetRandomReal(0,360)))
        call SetUnitScale(CUEX,sc,sc,sc)
        if b then
            call SetUnitVertexColor(CUEX,0,255,255,100)
        endif
        call KillUnit(CreateUnitEx(bj_groupEnumOwningPlayer,'u000',x+d1*Cos((a-90)*bj_DEGTORAD),y+d1*Sin((a-90)*bj_DEGTORAD),GetRandomReal(0,360)))
        call SetUnitScale(CUEX,sc,sc,sc)
        if b then
            call SetUnitVertexColor(CUEX,0,255,255,100)
        endif
        call KillUnit(CreateUnitEx(bj_groupEnumOwningPlayer,'u000',x+d1*Cos((a+90)*bj_DEGTORAD),y+d1*Sin((a+90)*bj_DEGTORAD),GetRandomReal(0,360)))
        call SetUnitScale(CUEX,sc,sc,sc)
        if b then
            call SetUnitVertexColor(CUEX,0,255,255,100)
        endif
        loop
            exitwhen d1 <= 0.
            call GroupAddUnit(g,CreateUnitEx(bj_groupEnumOwningPlayer,id,x+d1*Cos((a-90)*bj_DEGTORAD),y+d1*Sin((a-90)*bj_DEGTORAD),GetRandomReal(0,360)))
            set d1 = d1-20.
        endloop
        set d1 = d/2
        loop
            exitwhen d1 <= 0.
            call GroupAddUnit(g,CreateUnitEx(bj_groupEnumOwningPlayer,id,x+d1*Cos((a+90)*bj_DEGTORAD),y+d1*Sin((a+90)*bj_DEGTORAD),GetRandomReal(0,360)))
            set d1 = d1-20.
        endloop
        
        set bj_lastCreatedUnit = u
        set TempR = dmg1
        set FireID = b
        set TempR1 = 200.
        set TF = 1
        call ForGroup(g,function FireWallDamage)
        call GroupClear(TempG1)
        set TF = 0
        
        call SaveUnitHandle(H,i,0,u)
        call SaveGroupHandle(H,i,1,g)
        call SaveReal(H,i,2,tm)
        call SaveReal(H,i,3,dmg)
        call SaveBoolean(H,i,4,b)
        call TimerStart(t,.25,true,function FireWallDmg)
        
        set g = null
        set t = null
        set u = null
    endfunction
    
    // Отталкивание юнитов с руки
    private function PassiveCond takes nothing returns boolean
        set bj_lastReplacedUnit = GetFilterUnit()
        return IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit)) and not IsUnitDead(bj_lastReplacedUnit) and IsPointInSector(GetUnitX(bj_lastReplacedUnit),GetUnitY(bj_lastReplacedUnit),GetUnitX(bj_lastCreatedUnit),GetUnitY(bj_lastCreatedUnit),TempR3,80,300.)
    endfunction
    
    private function PassiveMove takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer i = GetHandleId(t)
        local unit u = LoadUnitHandle(H,i,0)
        local real tm = LoadReal(H,i,4)+.02
        local real dc = LoadReal(H,i,1)
        local real a = LoadReal(H,i,2)
        
        call SetUnitPositionEx(u,GetUnitX(u)+dc*Cos(a),GetUnitY(u)+dc*Sin(a))
        call IssueImmediateOrder(u,"stop")
        
        if GetUnitTypeId(u) < 1 or tm >= LoadReal(H,i,3) or TempR > 10 then
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushChildHashtable(H,i)
        else
            call SaveReal(H,i,4,tm)
        endif
        
        set t = null
        set u = null
    endfunction
    
    private function PassiveAct takes nothing returns nothing
        local unit u = GetEnumUnit()
        local timer t
        local integer i
        local real tm1
        local real dc
        
        if u != bj_lastLoadedUnit then
            call UnitDamageTarget(bj_lastCreatedUnit,u,TempR2,false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,null)
        endif
        
        if not IsUnitDead(u) then
            set t = CreateTimer()
            if GetUnitAbilityLevel(bj_lastCreatedUnit,'B001') > 0 and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)then
                call UnderworldFlames(bj_lastCreatedUnit,u)
            endif
        
            if GetUnitAbilityLevel(u,'A002') > 0 then
                call DestroyTimer(t)
                set t = null
            elseif GetUnitAbilityLevel(u,'A003') > 0 then
                set tm1 = .05
                set dc = 5.
            else
                set tm1 = .1
                set dc = 10.
            endif
        
            if t != null then
                set i = GetHandleId(t)
                call SaveUnitHandle(H,i,0,u)
                call SaveReal(H,i,1,dc)
                call SaveReal(H,i,2,Atan2(GetUnitY(u)-TempR1,GetUnitX(u)-TempR))
                call SaveReal(H,i,3,tm1)
                call TimerStart(t,.02,true,function PassiveMove)
                set t = null
            endif
        endif
        set u = null
    endfunction
    
    private function Passive takes nothing returns nothing
        set bj_lastLoadedUnit = GetTriggerUnit()
        set bj_lastCreatedUnit = GetEventDamageSource()
        set TempR = GetUnitX(bj_lastCreatedUnit)
        set TempR1 = GetUnitY(bj_lastCreatedUnit)
        set TempR2 = GetEventDamage()
        set TempR3 = Atan2(GetUnitY(bj_lastLoadedUnit)-TempR1,GetUnitX(bj_lastLoadedUnit)-TempR)*bj_RADTODEG
        
        call GroupEnumUnitsInRange(TempG,TempR,TempR1,300.,Condition(function PassiveCond))
        set TF = 1
        call ForGroup(TempG,function PassiveAct)
        set TF = 0
        call GroupClear(TempG)
        
        set bj_lastReplacedUnit = null
        set bj_lastLoadedUnit = null
    endfunction
    
    //=== Каст спеллов ===
    private function SpellsCond takes nothing returns boolean
        local integer i = GetSpellAbilityId()
        if i == 'A001' then
            call ExecuteFunc(SCOPE_PRIVATE+"FireWall")
        elseif i == 'A006' then
            call ExecuteFunc(SCOPE_PRIVATE+"FieryRain")
        elseif i == 'A007' then
            call ExecuteFunc(SCOPE_PRIVATE+"PlanetaryDestruction")
        endif
        return false
    endfunction
    
    //Показ урона + взаимодействие с уроном
    private function trgact takes nothing returns nothing
        local unit u = GetEventDamageSource()
        local unit u1 = GetTriggerUnit()
        local texttag tt = CreateTextTag()
        call SetTextTagText(tt,I2S(R2I(GetEventDamage())),.0276)
        call SetTextTagPosUnit(tt,GetTriggerUnit(),0)
        call SetTextTagColor(tt,255,0,255,0)
        call SetTextTagVelocity(tt,.05325*Cos(1.570788),.05325*Sin(1.570788))
        call SetTextTagPermanent(tt,false)
        call SetTextTagLifespan(tt,.5)
        call SetTextTagFadepoint(tt,.0)
        set tt = null
        
        if TF == 0 and GetUnitAbilityLevel(u,'A004') > 0 then
            call ExecuteFunc(SCOPE_PRIVATE+"Passive")
        endif
        
        set u = null
        set u1 = null
    endfunction
    
    //===================================================
    //---Регистрация события получения урона---
    private function trgcond takes nothing returns boolean
        return GetEventDamage() > 1.
    endfunction

    private function eve takes nothing returns nothing
        call TriggerRegisterUnitEvent(trg,GetEnumUnit(),EVENT_UNIT_DAMAGED)
    endfunction
    
    private function initcond takes nothing returns boolean
        local integer i = GetUnitTypeId(GetTriggerUnit())
        
        if i != 'u000' and i != 'u001' and i != 'u002' and i != 'u004' and i != 'u005' and i != 'u00C'/*
        */ and i != 'u003' and i != 'u00B' and i != 'u009' and i != 'u008' and i != 'u00A' and i != 'u006' and i != 'u007' then
            call TriggerRegisterUnitEvent(trg,GetTriggerUnit(),EVENT_UNIT_DAMAGED)
        endif
        return false
    endfunction
    //Пересборка триггера
    private function reset takes nothing returns nothing
        call DestroyTrigger(trg)
        set trg = CreateTrigger()
        call TriggerAddCondition(trg,Condition(function trgcond))
        call TriggerAddAction(trg,function trgact)
        call GroupEnumUnitsInRect(TempG,bj_mapInitialPlayableArea,Condition(function li))
        call ForGroup(TempG,function eve)
        call GroupClear(TempG)
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local region r = CreateRegion()
        local integer i = 0
        //Preload
        call RemoveUnit(CreateUnit(Player(15),'u00C',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u003',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u00B',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u009',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u008',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u00A',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u006',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u000',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u001',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u002',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u004',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u005',0,0,0))
        call RemoveUnit(CreateUnit(Player(15),'u007',0,0,0))
        
        call RegionAddRect(r,bj_mapInitialPlayableArea)
        call TriggerRegisterEnterRegion(t,r,null)
        call TriggerAddCondition(t,Condition(function initcond))
        set t = null
        set r = null
        
        call reset()
        
        set t = CreateTrigger()
        loop
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
            set i = i+1
            exitwhen i == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddCondition(t,Condition(function SpellsCond))
        set t = null
        
        call TimerStart(CreateTimer(),600.,true,function reset)
    endfunction

endlibrary

//Счётчик
library HC initializer init
    private leaderboard HB
    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
Загруженные файлы
Счётчик хэндлов
Тема
1 382
28
library HC initializer init
    private leaderboard HB
    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
Да-да, я лох, атстань)