Добавлен , опубликован
делал для друга спелл, феникс летит по параболе, задумывается о жизни и его маленький куриный мозг взрывается, нанося урон окружающим и вызывая огненную стенку вдоль крыльев, если шарите за код то можете спокойно (или беспокойно) импортировать, карта с видосом в комментах
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
27
3 года назад
1
раскрыть
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




Загруженные файлы
0
27
2 года назад
0
этот спелл задумывался для карты Crusader, мы хотели таким образом выкашивать дальников, но его негде было пихнуть
2
4
2 года назад
2
С такими спеллами можно новую доту делать хДД , а так идея хороша было бы лучше если бы был не чисто линия , а Овал какой нибудь. Ну это субьективно)
2
11
2 года назад
2
Красота
Чтобы оставить комментарий, пожалуйста, войдите на сайт.