• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] Spell Combo

Status
Not open for further replies.
Level 4
Joined
Sep 12, 2008
Messages
111
JASS:
struct Punch extends array

private static constant string EFFECT = "Environment\\UndeadBuildingFire\\UndeadLargeBuildingFire1.mdl"
private static constant integer SPELL_ID = 'A000'
private static constant integer SPELL_ID1 = 'A001'
private static constant string EFFECT_ID = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
private static unit array u
private static unit array t
private static real time = .3
private static real combo = 1.
private static timer array timezz
private static timer timez = CreateTimer()
private static integer array swag
private static integer Count = 0
private static integer array rn
private static integer ic = 0
private static integer array next
private static integer array prev

private static method Damage takes integer i, integer stat returns real
    return i * 50 + stat * (i * 0.5) // i(50) + stat(i(.5))
endmethod

private static method radius takes integer i returns real
    return 200. + i * 50.
endmethod

private static method Lulz takes nothing returns nothing
    local thistype this = next[0]
    local unit Unit
    local group g = CreateGroup()
    local real x
    local real y
    local real angle
    local real face
    local real lol
    loop
    exitwhen this == 0
        set x = GetUnitX(u[this])
        set y = GetUnitY(u[this])
        //call DestroyEffect(AddSpecialEffect(EFFECT_ID, x, y))
        set face = GetUnitFacing(u[this])*bj_DEGTORAD
        call GroupEnumUnitsInRange(g, x, y, radius(1), null)
        loop
        set Unit = FirstOfGroup(g)
        exitwhen Unit == null
            call BJDebugMsg(GetUnitName(Unit))
            call GroupRemoveUnit(g, Unit)
            set angle = Atan2(GetUnitY(Unit)-GetUnitY(u[this]), GetUnitX(Unit)-GetUnitX(u[this]))
            set lol = Cos(face-angle)
            if not /*Libs_IsUnitDead(Unit) and*/ IsUnitAlly(Unit, GetOwningPlayer(u[this]))/*
            */ and not IsUnitType(Unit, UNIT_TYPE_STRUCTURE) and lol>0. then
                //call TextTag_Unit(Unit, I2S(R2I(Damage(lvl[this], GetHeroStr(u[this], true)))), "|c00ff0000")
                set angle = Atan2((GetUnitY(Unit)-GetUnitY(u[this])), GetUnitX(Unit)-GetUnitX(u[this])) * bj_RADTODEG
                //set kb = Knockback.create(u[this], Unit, distance(lvl[this], GetHeroStr(u[this], true)), 1.5, angle, Slam)
                //call kb.addSpecialEffect(EFFECT, "origin")
                /*call UnitDamageTarget(u[this], Unit, Damage(lvl[this], GetHeroStr(u[this], true)), true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_AXE_MEDIUM_CHOP)*/
                if swag[this] == SPELL_ID1 then
                    call BJDebugMsg(R2S(TimerGetRemaining(timezz[this])))
                    call UnitDamageTarget(u[this], Unit, 50., true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
                else
                    call UnitDamageTarget(u[this], Unit, 5., true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
                endif
            endif
        endloop
        call BJDebugMsg(R2S(TimerGetRemaining(timezz[this])))
        call DestroyGroup(g)
        call SetUnitTimeScale(u[this], 1)
        call PauseUnit(u[this], false)
        //set u[this] = null
        set t[this] = null
        set Unit = null
        set g = null
        set Count = Count - 1
        set rn[this] = rn[0]
        set rn[0] = this
        set prev[next[this]] = prev[this]
        set next[prev[this]] = next[this]
        if Count == 0 then
            call PauseTimer(timez)
        endif
    set this = next[this]
    endloop
endmethod

private static method run takes nothing returns thistype
    local thistype this = rn[0]
    local unit u = GetTriggerUnit()
    //local integer level = GetUnitAbilityLevel(u, SPELL_ID)
        if this == 0 then
            set ic = ic + 1
            set this = ic
        else
            set rn[0] = rn[this]
        endif
        set .u[this] = u
        set Count = Count + 1
        set next[this] = 0
        set prev[this] = prev[0]
        set next[prev[0]] = this
        set prev[0] = this
        if GetSpellAbilityId() == SPELL_ID then    //normal punch
            set swag[this] = SPELL_ID
            call UnitRemoveAbility(u, SPELL_ID)
            call UnitAddAbility(u, SPELL_ID1)
        else
            set swag[this] = SPELL_ID1
            call UnitRemoveAbility(u, SPELL_ID1)
            call UnitAddAbility(u, SPELL_ID)
        endif
        call PauseUnit(u, true)
        call SetUnitTimeScale(u, 1.)
        call SetUnitAnimation(u, "attack")
        if Count == 1 then
            call TimerStart(timez, time, true, function thistype.Lulz)
            call TimerStart(timezz[this], combo, false, null)
        endif
    set u = null
    return this
endmethod

private static method huez0r takes nothing returns nothing
    local integer i = 0
    loop
    exitwhen i > Count
        if TimerGetRemaining(timezz[i]) <= 0. then
            call UnitRemoveAbility(u[i], SPELL_ID1)
            call UnitAddAbility(u[i], SPELL_ID)
        endif
    set i = i + 1
    endloop
endmethod

private static method onInit takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterTimerEvent(t, .5, true)
    call TriggerAddAction(t, function thistype.huez0r)
    call RegisterSpellEffectEvent(SPELL_ID, function thistype.run)
    call RegisterSpellEffectEvent(SPELL_ID1, function thistype.run)
endmethod

endstruct

How do I remove SPELL_ID1 after [combo]?
 
Well, first things first. You should initialize timezz[this] with a value (CreateTimer()) before using it. Then you would put a method callback:
JASS:
static method Remove takes nothing returns nothing 
    local timer t = GetExpiredTimer()
    local thistype this = next[0]
    loop
         exitwhen this == 0
         if timezz[this] == t then
             call UnitRemoveAbility(...) // remove SPELL_ID1
             // cleanup
             call PauseTimer(t)
             call DestroyTimer(t)
         endif
         set this = next[this]
    endloop
    set t = null
endmethod

// ... start the timer in the setup/spell cast method
call TimerStart(timezz[this], combo, false, function thistype.Remove)

You can also use a hashtable instead of searching through the list (which is O(n)), but I chose to show that method above for simplicity's sake. Also, you should start that timer for all instances (I assume), not just for the first instance.
 
Level 4
Joined
Sep 12, 2008
Messages
111
Swag

JASS:
static method Remove takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local thistype this = next[0]
    loop
         exitwhen this == 0
         call BJDebugMsg(I2S(this) + GetUnitName(u[this]))
         if timezz[this] == t then
            call BJDebugMsg("Swagger")
            call UnitRemoveAbility(u[this], SPELL_ID1)
            call UnitAddAbility(u[this], SPELL_ID)
             //call UnitRemoveAbility() // remove SPELL_ID1
             // cleanup
             call PauseTimer(t)
             call DestroyTimer(t)
             set rn[this] = rn[0]
             set rn[0] = this
             set prev[next[this]] = prev[this]
             set next[prev[this]] = next[this]
         endif
         set this = next[this]
    endloop
    set t = null
endmethod

The unit will get paused after casting the spell within 1 second because of
JASS:
set rn[this] = rn[0]
set rn[0] = this
set prev[next[this]] = prev[this]
set next[prev[this]] = next[this]
How do I fix this?
 
Status
Not open for further replies.
Top