Spell Falcon Punch

Discussion in 'Spells' started by Dinowc, Jan 15, 2011.

  1. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    yeah ofc the idea isn't mine :p
    I've made this spell since HeX.16 requested it
    and I thought I could share it here

    Falcon Punch



    [​IMG]

    [​IMG]

    JASS:
    scope punch initializer init // requires Timer Utils, AIDS, Knockback System (Kenny's), Group Utils
    
    // CONFIGURABLE:
    globals
        private constant integer SPELL_ID = 'A000'
        private constant integer PHOENIX_DUMMY = 'h000'
        private constant integer STORM_CROW = 'Arav'
        
        private constant real INTERVAL = 0.03125
        private constant real MAX_SPEED = 1300.
        private constant real START_SPEED = 100.
        private constant real ACCELERATION = 800. // speed increase after 1 second
        private constant real FLY_SPEED = 900.
        private constant boolean INVULNERABLE = false // unit is invulnerable while sliding
        private constant real MINIMUM_CAST_RANGE = 0.
        private constant boolean COUNTER_PUNCH_DISABLED = false // setting this to true will cause the faster sliding unit to punch the target if both are sliding and targeting each other
        
        private constant boolean CHECK_PATHING = true // for going over cliffs
        private constant boolean DESTROYS_TREES = true // if it's set to false, it will stop charging if he hits a tree (or any other destructible)
        private constant real TREE_CUT_AOE = 100.
        
        private constant string CAST_SFX = "Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl"
        private constant string STRIKE_SFX = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
        private constant string STRIKE_SFX_ATTACH = "chest"
        private constant string IMPACT_SFX = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
        
        private constant real BASE_PRIMARY_DAMAGE = 120.
        private constant real PRIMARY_DAMAGE_PER_LVL = 50.
        private constant real BASE_SECONDARY_DAMAGE = 50.
        private constant real SECONDARY_DAMAGE_PER_LVL = 25.
        
        private constant real BASE_PRIMARY_AOE = 250.
        private constant real PRIMARY_AOE_PER_LVL = 25.
        private constant real BASE_SECONDARY_AOE = 200.
        private constant real SECONDARY_AOE_PER_LVL = 25.
        
        private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
        private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
        
        private constant real BASE_BURN_DAMAGE = 10.
        private constant real BURN_DAMAGE_PER_LVL = 5.
        private constant real BURN_INTERVAL = 0.50
        private constant real BASE_BURN_DURATION = 7.
        private constant real BURN_DURATION_PER_LVL = 0.
        private constant string BURN_SFX = "Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl"
        private constant string BURN_SFX_ATTACH = "chest"
        
        private constant attacktype BURN_ATTACK_TYPE = ATTACK_TYPE_MAGIC
        private constant damagetype BURN_DAMAGE_TYPE = DAMAGE_TYPE_FIRE
        
        private constant real MAX_HEIGHT = 200.
        private constant real FLY_DISTANCE = 700.
        private constant real FLY_RATE = 800.
        private constant real SLIDE_DISTANCE = 300. // distance of the additional sliding once unit falls to the ground
        private constant real SLIDE_DURATION = 1.
        private constant boolean FLY_OVER_CLIFFS = true
        private constant boolean FLIER_INVULNERABLE = false // unit is invulnerable while flying
        
        private constant real KNOCK_SPEED = 750. // speed at which are units being knocked; this is not the speed of knocked units, but of the sliding caster
        private constant real KNOCK_DISTANCE = 250.
        private constant real KNOCK_DURATION = 0.6
        private constant real KNOCK_AOE = 100. // AoE at which are nearby enemies knocked back
        private constant real KNOCK_OFFSET = 50. // distance between the center of enumeration rect and the caster
        
        private constant real PHOENIX_OFFSET = -10. // distance between the caster and the phoenix dummy
        private constant integer PHOENIX_TRANSPARENCY = 75
        private constant real PHOENIX_ANIMATION_SPEED = 1.5
        private constant real IMPACT_RANGE = 125. // distance between the caster and the target before the target is hit
        private constant integer ANIMATION_ID = 5
        private constant real PAUSE_ANIMATION = 0.25 // pauses animation after this many seconds
    endglobals
    
    // NOT SO MUCH CONFIGURABLE:
    globals
        private group G = CreateGroup()
        private unit Caster
        private unit Target
        private player Owner
        private integer Lvl
        private rect R
        private real Slide_Speed = MAX_SPEED * INTERVAL
        private real Fly_Speed = FLY_SPEED * INTERVAL
        private real X
        private real Y
        private real Acc = ACCELERATION * INTERVAL * INTERVAL
        private real MaxX
        private real MaxY
        private real MinX
        private real MinY
        private real Damage
        private integer Index
        private group Sliders = CreateGroup()
    endglobals
    
    private function PolarX takes real dist, real angle returns real
        return dist * Cos(angle * bj_DEGTORAD)
    endfunction
    
    private function PolarY takes real dist, real angle returns real
        return dist * Sin(angle * bj_DEGTORAD)
    endfunction
    
    private function GetDistance takes real x1, real y1, real x2, real y2 returns real
        local real dx = x2 - x1
        local real dy = y2 - y1
        return SquareRoot(dx * dx + dy * dy)
    endfunction
    
    private function GetAngle takes real x1, real y1, real x2, real y2 returns real
        return bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
    endfunction
    
    private function GetParabolaZ takes real x returns real
        return 4 * MAX_HEIGHT * x * (FLY_DISTANCE - x) / (FLY_DISTANCE * FLY_DISTANCE)
    endfunction
    
    private function PrimaryDamage takes integer lvl returns real
        return BASE_PRIMARY_DAMAGE + (lvl - 1) * PRIMARY_DAMAGE_PER_LVL
    endfunction
    
    private function SecondaryDamage takes integer lvl returns real
        return BASE_SECONDARY_DAMAGE + (lvl - 1) * SECONDARY_DAMAGE_PER_LVL
    endfunction
    
    private function BurnDamage takes integer lvl returns real
        return BASE_BURN_DAMAGE + (lvl - 1) * BURN_DAMAGE_PER_LVL
    endfunction
    
    private function PrimaryAoe takes integer lvl returns real
        return BASE_PRIMARY_AOE + (lvl - 1) * PRIMARY_AOE_PER_LVL
    endfunction
    
    private function SecondaryAoe takes integer lvl returns real
        return BASE_SECONDARY_AOE + (lvl - 1) * SECONDARY_AOE_PER_LVL
    endfunction
    
    private function BurnDuration takes integer lvl returns real
        return BASE_BURN_DURATION + (lvl - 1) * BURN_DURATION_PER_LVL
    endfunction
    
    private function SafeX takes real x returns real
        if x > MaxX then
            return MaxX
        endif
        
        if x < MinX then
            return MinX
        endif
        
        return x
    endfunction
    
    private function SafeY takes real y returns real
        if y > MaxY then
            return MaxY
        endif
        
        if y < MinY then
            return MinY
        endif
        
        return y
    endfunction
    
    private struct dot
        unit caster
        group g
        real dmg
        timer t
        real ticks
        real duration
        
        private method onDestroy takes nothing returns nothing
            call ReleaseTimer(this.t)
            call ReleaseGroup(this.g)
        endmethod
    endstruct
    
    private struct slide
        unit caster
        unit target
        unit phoenix
        real dmg1
        real dmg2
        real ticks
        real dist
        real cos
        real sin
        real acc
        real angle
        boolean paused
        boolean sliding
        timer t
        
        static method create takes unit caster, unit target returns thistype
            local thistype d = thistype.allocate()
            local real angle = GetUnitFacing(caster)
            local integer lvl = GetUnitAbilityLevel(caster, SPELL_ID)
            
            set d.caster = caster
            set d.target = target
            set d.phoenix = CreateUnit(GetOwningPlayer(d.caster), PHOENIX_DUMMY, GetUnitX(d.caster) + PolarX(PHOENIX_OFFSET, angle), GetUnitY(d.caster) + PolarY(PHOENIX_OFFSET, angle), angle)
            call SetUnitVertexColor(d.phoenix, 255, 255, 255, PHOENIX_TRANSPARENCY)
            call SetUnitTimeScale(d.phoenix, PHOENIX_ANIMATION_SPEED)
            set d.t = NewTimer()
            set d.dmg1 = PrimaryDamage(lvl)
            set d.dmg2 = SecondaryDamage(lvl)
            set d.ticks = 0.
            set d.dist = 0.
            set d.acc = START_SPEED * INTERVAL
            set d.paused = false
            set d.sliding = true
            call GroupAddUnit(Sliders, caster)
            
            return d
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call ReleaseTimer(this.t)
            set this.caster = null
            set this.target = null
            set this.phoenix = null
        endmethod
    endstruct
    
    globals
        private slide array D
    endglobals
    
    private function PrimaryStrike takes nothing returns boolean
        local unit picked = GetFilterUnit()
        if IsUnitEnemy(picked, Owner) and GetWidgetLife(picked) > 0. then
            call UnitDamageTarget(Caster, picked, Damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
            set picked = null
            return true
        endif
        set picked = null
        return false
    endfunction
    
    private function SecondaryStrike takes nothing returns boolean
        local unit picked = GetFilterUnit()
        if IsUnitEnemy(picked, Owner) and GetWidgetLife(picked) > 0. then
            call UnitDamageTarget(Caster, picked, Damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
        endif
        set picked = null
        return false
    endfunction
    
    private function KnockUnits takes nothing returns boolean
        local unit picked = GetFilterUnit()
        if IsUnitEnemy(picked, Owner) and GetWidgetLife(picked) > 0. and picked != Target and KBS_IsUnitSliding(picked) == false then
            call KBS_BeginCommon(picked, KNOCK_DISTANCE, KNOCK_DURATION, GetAngle(X, Y, GetUnitX(picked), GetUnitY(picked)))
        endif
        set picked = null
        return false
    endfunction
    
    private function EndSlide takes nothing returns nothing
        call PauseUnit(D[Index].caster, false)
        call SetUnitPathing(D[Index].caster, true)
        call SetUnitTimeScale(D[Index].caster, 1.)
        call SetUnitAnimation(D[Index].caster, "stand")
        call KillUnit(D[Index].phoenix)
        call SetUnitInvulnerable(D[Index].target, false)
        call SetUnitInvulnerable(D[Index].caster, false)
        call GroupRemoveUnit(Sliders, D[Index].caster)
        call PauseTimer(D[Index].t)
        call D[Index].destroy()
    endfunction
    
    private function DestructibleFilter takes nothing returns nothing
        local destructable d = GetEnumDestructable()
        static if DESTROYS_TREES then
            call KillDestructable(d)
        else
            call EndSlide()
        endif
        set d = null
    endfunction
    
    private function DoT takes nothing returns nothing
        local unit picked = GetEnumUnit()
        if GetWidgetLife(picked) > 0. then
            call UnitDamageTarget(Caster, picked, Damage, false, false, BURN_ATTACK_TYPE, BURN_DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
            call DestroyEffect(AddSpecialEffectTarget(BURN_SFX, picked, BURN_SFX_ATTACH))
        endif
        set picked = null
    endfunction
    
    private function DamageOverTime takes nothing returns nothing
        local dot d = GetTimerData(GetExpiredTimer())
        set Caster = d.caster
        set Damage = d.dmg
        call ForGroup(d.g, function DoT)
        set d.ticks = d.ticks + BURN_INTERVAL
        if d.ticks > d.duration then
            call PauseTimer(d.t)
            call d.destroy()
        endif
    endfunction
    
    private function callback takes nothing returns nothing
        local slide d = GetTimerData(GetExpiredTimer())
        local real x1 = GetUnitX(d.caster)
        local real y1 = GetUnitY(d.caster)
        local real x2 = GetUnitX(d.target)
        local real y2 = GetUnitY(d.target)
        local real angle = GetAngle(x1, y1, x2, y2)
        local real cos
        local real sin
        local real dist
        local dot a
        local real speed
        local boolean b = true
        
        set Owner = GetOwningPlayer(d.caster)
        set Index = GetUnitIndex(d.caster)
    
        if d.sliding then
        
        if d.acc < Slide_Speed then
            set d.acc = d.acc + Acc
        else
            set d.acc = Slide_Speed
        endif
        
        set cos = PolarX(d.acc, angle)
        set sin = PolarY(d.acc, angle)
        set dist = GetDistance(x1, y1, x2, y2)
        call SetUnitX(d.caster, x1 + cos)
        call SetUnitY(d.caster, y1 + sin)
        call SetUnitX(d.phoenix, GetUnitX(d.phoenix) + cos)
        call SetUnitY(d.phoenix, GetUnitY(d.phoenix) + sin)
        
        set X = x1
        set Y = y1
        set cos = cos + PolarX(KNOCK_OFFSET, angle)
        set sin = sin + PolarY(KNOCK_OFFSET, angle)
        call MoveRectTo(R, X, Y)
        
        static if CHECK_PATHING then
            if IsTerrainPathable(x1 + cos, y1 + sin, PATHING_TYPE_WALKABILITY) == true then
                call EndSlide()
            endif
        endif
        
        call EnumDestructablesInRect(R, null, function DestructibleFilter)
        
        set Target = d.target
        
        if d.acc / INTERVAL > KNOCK_SPEED then
            call GroupEnumUnitsInRange(G, x1 + cos, y1 + sin, KNOCK_AOE, Filter(function KnockUnits))
        endif
        
        call SetUnitFacingTimed(d.caster, angle, 0.01)
        call SetUnitFacingTimed(d.phoenix, angle, 0.01)
        
        if dist <= IMPACT_RANGE + (Slide_Speed * 2.5) then
            call SetUnitTimeScale(d.caster, 0.8)
        endif
        
        if GetWidgetLife(d.target) <= 0. and IsUnitInGroup(d.caster, Sliders) == true then
            call EndSlide()
        endif
        
        if dist <= IMPACT_RANGE then
            
            set Index = GetUnitIndex(d.target)
            static if COUNTER_PUNCH_DISABLED then
                if D[Index].target == d.caster and D[Index].acc > d.acc then
                    set b = false
                endif
            endif
            
            if b == true then
                call DestroyEffect(AddSpecialEffectTarget(STRIKE_SFX, d.target, STRIKE_SFX_ATTACH))
                set Caster = d.caster
                set Lvl = GetUnitAbilityLevel(d.caster, SPELL_ID)
            
                set a = dot.create()
                set a.caster = d.caster
                set a.g = NewGroup()
                set a.t = NewTimer()
                set a.ticks = 0.
                set a.dmg = BurnDamage(Lvl) * BURN_INTERVAL
                set a.duration = BurnDuration(Lvl)
                set Damage = d.dmg1
            
                call GroupEnumUnitsInRange(a.g, x2, y2, PrimaryAoe(Lvl), Filter(function PrimaryStrike))
                call SetTimerData(a.t, a)
                call TimerStart(a.t, BURN_INTERVAL, true, function DamageOverTime)
            
                call SetUnitTimeScale(d.caster, 1.)
                
                if COUNTER_PUNCH_DISABLED or D[Index].target != d.caster then
                
                if IsUnitInGroup(d.target, Sliders) then
                    call EndSlide()
                endif
                
                endif
                
                call KillUnit(d.phoenix)
                call PauseUnit(d.caster, false)
                call PauseUnit(d.target, true)
                call SetUnitAnimation(D[Index].caster, "stand")
                call IssueImmediateOrder(d.caster, "holdposition")
            
                static if FLIER_INVULNERABLE then
                    call SetUnitInvulnerable(d.target, true)
                endif
                
                call UnitAddAbility(d.target, STORM_CROW)
                call UnitRemoveAbility(d.target, STORM_CROW)
                call SetUnitPathing(d.target, false)
                call SetUnitPathing(d.caster, true)
                
                call GroupRemoveUnit(Sliders, d.caster)
                set d.angle = angle
                set d.sliding = false
            endif
        endif
        
        set d.ticks = d.ticks + INTERVAL
        if d.ticks > PAUSE_ANIMATION and d.paused == false then
            call SetUnitTimeScale(d.caster, 0.)
            set d.paused = true
        endif
        
        else
            set d.cos = PolarX(Fly_Speed, d.angle)
            set d.sin = PolarY(Fly_Speed, d.angle)
            if d.dist <= FLY_DISTANCE then
                set X = x2 + d.cos
                set Y = y2 + d.sin
                if FLY_OVER_CLIFFS then
                    call SetUnitX(d.target, SafeX(X))
                    call SetUnitY(d.target, SafeY(Y))
                elseif IsTerrainPathable(X, Y, PATHING_TYPE_WALKABILITY) == false then
                    call SetUnitX(d.target, SafeX(X))
                    call SetUnitY(d.target, SafeY(Y))
                endif
                call SetUnitFlyHeight(d.target, GetParabolaZ(d.dist), FLY_RATE)
            elseif KBS_IsUnitSliding(d.target) == false and d.dist < SLIDE_DISTANCE + FLY_DISTANCE then
                call SetUnitFlyHeight(d.target, 0., FLY_RATE)
                call SetUnitInvulnerable(d.target, false)
                call SetUnitInvulnerable(d.caster, false)
                call DestroyEffect(AddSpecialEffectTarget(IMPACT_SFX, d.target, "origin"))
                call SetUnitPathing(d.target, true)
                call KBS_BeginCommon(d.target, SLIDE_DISTANCE, SLIDE_DURATION, d.angle)
                set Lvl = GetUnitAbilityLevel(d.caster, SPELL_ID)
                set Damage = d.dmg2
                call GroupEnumUnitsInRange(G, x2 + d.cos, y2 + d.sin, SecondaryAoe(Lvl), Filter(function SecondaryStrike))
            else
                call PauseUnit(d.target, false)
                call PauseTimer(d.t)
                call d.destroy()
            endif
            set d.dist = d.dist + Fly_Speed
        endif
        
    endfunction
    
    private function actions takes nothing returns boolean
        local unit caster
        local unit target
        local slide d
        local real angle
        if GetSpellAbilityId() == SPELL_ID then
            set caster = GetTriggerUnit()
            set target = GetSpellTargetUnit()
            set d = slide.create(caster, target)
            call IssueImmediateOrder(caster, "stop")
            call PauseUnit(caster, true)
            static if INVULNERABLE then
                call SetUnitInvulnerable(caster, true)
            endif
            call SetUnitPathing(caster, false)
            call SetUnitAnimationByIndex(caster, ANIMATION_ID)
            set D[GetUnitIndex(caster)] = d
            call SetTimerData(d.t, d)
            call TimerStart(d.t, INTERVAL, true, function callback)
        endif
        set caster = null
        set target = null
        return false
    endfunction
    
    private function actions2 takes nothing returns boolean
        local unit caster
        local real x
        local real y
        if GetSpellAbilityId() == SPELL_ID then
            set caster = GetTriggerUnit()
            set x = GetUnitX(caster)
            set y = GetUnitY(caster)
            if GetDistance(x, y, GetSpellTargetX(), GetSpellTargetY()) >= MINIMUM_CAST_RANGE then
                call DestroyEffect(AddSpecialEffect(CAST_SFX, GetUnitX(caster), GetUnitY(caster)))
            else
                call IssueImmediateOrder(caster, "stop")
            endif
        endif
        set caster = null
        return false
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function actions))
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
        call TriggerAddCondition(t, Condition(function actions2))
        
        set R = Rect(-TREE_CUT_AOE, -TREE_CUT_AOE, TREE_CUT_AOE, TREE_CUT_AOE)
        
        set MaxX = GetRectMaxX(bj_mapInitialPlayableArea)
        set MaxY = GetRectMaxY(bj_mapInitialPlayableArea)
        set MinX = GetRectMinX(bj_mapInitialPlayableArea)
        set MinY = GetRectMinY(bj_mapInitialPlayableArea)
    endfunction
    
    endscope


    any feedback appreciated

    fixed some bugs and added counter punching :D
     

    Attached Files:

    • Like Like x 3
  2. HeX.16

    HeX.16 Isn't Trollin You Right Now

    Ratings:
    +131 / 0 / -0
    Pretty epic. Just one thing is that it has no cliff detection.
     
    • Like Like x 1
  3. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    fixed.
     
  4. jrhetf4xb

    jrhetf4xb Member

    Ratings:
    +12 / 0 / -0
    Fun spell but the charging is quite slow... :/
     
  5. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    you mean the casting time is too long? (when he jumps and growls)
    I did that on purpose, but it can be faster by lowering the cast time/backswing thingies

    if you mean that he accelerates too slow, there's a configuration for that (you can even set the initial speed, so you don't need to accelerate at all)

    EDIT: reuploaded the version with lower casting time

    EDIT2: updated with a FLYING_OVER_CLIFFS boolean (since HeX.16 requested it)
     
  6. HeX.16

    HeX.16 Isn't Trollin You Right Now

    Ratings:
    +131 / 0 / -0
    Perfect with my request now.

    Thank you again Dinowc

    Ill let you know if i find any bugs/places for improvement.

    E:Units that die from the fire damage(burned) dont give the caster a bounty.
     
  7. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    yeah about that... I based the DoT effect on Inner Fire with negative effects
    it doesn't damage them, but causes them to have reduced health regen instead

    that way they actually kill themselves and you don't gain bounty (probably exp as well)
    I couldn't find any other spell to base the DoT from (didn't want to trigger that too, was too bored xd)

    I'll try to do it in v1.2
     
  8. HeX.16

    HeX.16 Isn't Trollin You Right Now

    Ratings:
    +131 / 0 / -0
    I would attach pheonix fire to the pheonix dummy and set its level.
    Works imo
     
  9. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    wont work since I'm using only 1 global dummy for every instance of the spell
    no problem I'm fixing the DoT problem right now...

    EDIT: fixed
     
  10. DrEvil

    DrEvil FCRI Associate!

    Ratings:
    +111 / 0 / -0
    pretty awesome spell :)
    but I was probably the only person to be so impatient trying to download it while you were updating to version 1.2 I was so fired up...
    but more to my point,
    I used it on a shaman at an angle where he got flung into a little enclosure between cliffs and is invulnerable.. maybe a possible fix? somehow.
    [​IMG]
     
  11. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    =0

    I've been testing the spell for like a half an hour and haven't noticed that one yet xd
    I'll see what I can do...
     
  12. HeX.16

    HeX.16 Isn't Trollin You Right Now

    Ratings:
    +131 / 0 / -0
    Very nice now. All working 110% customisable

    @DrEvil try set
    JASS:
        private constant boolean FLY_OVER_CLIFFS = true

    to
    JASS:
        private constant boolean FLY_OVER_CLIFFS = false
     
  13. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    @DrEvil
    w8
    was he permanently invulnerable or just while flying? because he is supposed to be invulnerable while flying
     
  14. DrEvil

    DrEvil FCRI Associate!

    Ratings:
    +111 / 0 / -0
    ahh yeah -.-'
    didn't realise it was on by default :D ( because in the code here it's set false.. xD )
    +rep for a meaningless but devastating spell ( by meaningless I mean you just can't falcon punch random strangers )

    @Dinowc
    yeah permanent invulnerability ( no spazzing on the ground )
     
  15. Laiev

    Laiev Hey Listen!!

    Ratings:
    +187 / 0 / -0
    if you're still searching for a spell dps, incinerate :p or use the best way, timer with damage function

    fast edit: and why you use this function not private?

    JASS:
    function GetParabolaZ takes real x returns real
     
  16. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    I'm afraid I don't know how to fix that one :(

    as I said, it never happened to me so I don't know the reason why he stays invulnerable

    added an option to make caster/target invulnerable while sliding/flying
    thanks
    I already did it with a timer
    I was just copy/pasting that Acehart's magical function xd
    wasn't even looking, nice find though
     
  17. kingkingyyk3

    kingkingyyk3 Visitor (Welcome to the Jungle, Baby!)

    Ratings:
    +216 / 0 / -0
    Unit leaking for GetFilterUnit().
     
    • Like Like x 1
  18. Weep

    Weep Godspeed to the sound of the pounding

    Ratings:
    +400 / 0 / -0
    Falcom paunch!

    Yes!

    At maximum level, it should explode the galaxy. :p (Warning: spoilers :rolleyes:)
     
  19. Laiev

    Laiev Hey Listen!!

    Ratings:
    +187 / 0 / -0
    Weep exaggerated :x
     
  20. Dinowc

    Dinowc don't expect anything, prepare for everything

    Ratings:
    +223 / 0 / -0
    where? I must be blind...
     

Share This Page