• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Why is the spell not working?

Status
Not open for further replies.
Level 3
Joined
Nov 18, 2013
Messages
21
can someone please explain me why isn't this spell working...

JASS:
function Turmoil_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A003'
endfunction

function Group takes nothing returns boolean
    return IsUnitAlive(GetFilterUnit())
endfunction

function Timer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit caster = GetHandleUnit(t, "caster")
    local real x = GetHandleReal(t, "x")
    local real y = GetHandleReal(t, "y")
    local group target = CreateGroup()
    local unit temp
    local real dmg = 55
    call GroupEnumUnitsInRange(target, x, y, 500., Condition(function Group))
    set temp = GroupPickRandomUnit(target)
    if (IsUnitEnemy(temp, GetOwningPlayer(caster))) and (not IsUnitType(temp, UNIT_TYPE_STRUCTURE)) then
        call UnitDamageTarget(caster, temp, dmg, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\Devour\\DevourEffectArt.mdl", temp, "chest"))
    endif
    loop
        set temp = FirstOfGroup(target)
        call GroupRemoveUnit(target, temp)
        exitwhen temp == null
    endloop
    call DestroyGroup(target)
    set temp = null
    set target = null
endfunction

function Turmoil_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit caster = GetTriggerUnit()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    call SetHandleHandle(t, "caster", caster)
    call SetHandleReal(t, "x", x)
    call SetHandleReal(t, "y", y)
    call ShowUnit(caster, false)
    call TimerStart(t, 0.2, true, function Timer)
    call TriggerSleepAction(2.)
    call FlushHandleLocals(t)
    call DestroyTimer(t)
    call ShowUnit(caster, true)
    call SetUnitPosition(caster, x, y)
    set t = null
    set caster = null
endfunction

function InitTrig_Turmoil takes nothing returns nothing
    set gg_trg_Turmoil = CreateTrigger()
    call TriggerAddCondition( gg_trg_Turmoil, Condition(function Turmoil_Conditions))
    call TriggerAddAction(gg_trg_Turmoil, function Turmoil_Actions)
endfunction

custom text functions (yes, I already created the Hashtable on the variable editor)

JASS:
 function LocalVars takes nothing returns hashtable
    return udg_Hashtable
endfunction

function XGWait takes real time returns nothing
    local timer t=CreateTimer()
    call TimerStart(t,time,false,null)
    loop
        if TimerGetRemaining(t)==0.0 then
            call DestroyTimer(t)
            set t=null
            return
        else
            call TriggerSleepAction(TimerGetRemaining(t)/2.)
        endif
    endloop
endfunction

function SetHandleHandle takes handle subject,string name,agent value returns nothing
    call SaveAgentHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name),value)
endfunction

function SetHandleInt takes handle subject,string name,integer value returns nothing
    call SaveInteger(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name),value)
endfunction

function SetHandleBoolean takes handle subject,string name,boolean value returns nothing
    call SaveBoolean(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name),value)
endfunction

function SetHandleReal takes handle subject,string name,real value returns nothing
    call SaveReal(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name),value)
endfunction

function SetHandleString takes handle subject,string name,string value returns nothing
    call SaveStr(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name),value)
endfunction

function FlushHandleLocals takes handle subject returns nothing
    call FlushChildHashtable(LocalVars(),GetHandleIdBJ(subject))
endfunction

function GetHandleBoolean takes handle subject,string name returns boolean
    return LoadBoolean(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleInt takes handle subject,string name returns integer
    return LoadInteger(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleReal takes handle subject,string name returns real
    return LoadReal(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleString takes handle subject,string name returns string
    return LoadStringBJ(StringHashBJ(name),GetHandleIdBJ(subject),LocalVars())
endfunction

function GetHandleUnit takes handle subject,string name returns unit
    return LoadUnitHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleEffect takes handle subject,string name returns effect
    return LoadEffectHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleTimer takes handle subject,string name returns timer
    return LoadTimerHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleTrigger takes handle subject,string name returns trigger
    return LoadTriggerHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleGroup takes handle subject,string name returns group
    return LoadGroupHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleItem takes handle subject,string name returns item
    return LoadItemHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandlePlayer takes handle subject,string name returns player
    return LoadPlayerHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleLocation takes handle subject,string name returns location
    return LoadLocationHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleLightning takes handle subject,string name returns lightning
    return LoadLightningHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function GetHandleTextTag takes handle subject,string name returns texttag
    return LoadTextTagHandle(LocalVars(),GetHandleIdBJ(subject),StringHashBJ(name))
endfunction

function IsUnitDead takes unit u returns boolean
    return IsUnitType(u,UNIT_TYPE_DEAD)or GetUnitTypeId(u)==0
endfunction

function IsUnitAlive takes unit u returns boolean
    return not IsUnitDead(u)
endfunction[/jas]
 
Last edited by a moderator:
Level 39
Joined
Feb 27, 2007
Messages
5,010
Probably TriggerSleepAction(2.) is slightly shorter than 2 seconds (it's not very precise) do DestroyTimer(t)and FlushHandleLocals() happen before the random unit is damaged. You shouldn't be destroying the timer or flushing its variables in the main onSpell function-- that's for the timer callback to do. In fact, everything after hiding the caster and starting the timer is! Your onSpell should basically end there.

Why are you clearing target unit-by-unit before destroying it? Also there is ClearGroup(). If the randomly picked unit isn't an enemy non-structure it will fail the if/else block and then no unit is damaged; the spell just ends thinking it worked.
 
Level 3
Joined
Nov 18, 2013
Messages
21
Probably TriggerSleepAction(2.) is slightly shorter than 2 seconds (it's not very precise) do DestroyTimer(t)and FlushHandleLocals() happen before the random unit is damaged. You shouldn't be destroying the timer or flushing its variables in the main onSpell function-- that's for the timer callback to do. In fact, everything after hiding the caster and starting the timer is! Your onSpell should basically end there.

Why are you clearing target unit-by-unit before destroying it? Also there is ClearGroup(). If the randomly picked unit isn't an enemy non-structure it will fail the if/else block and then no unit is damaged; the spell just ends thinking it worked.

I can't use ClearGroup() since I'm not using vJASS. The main problem appears to be that the handles are not beeing loaded in the Timer function. In the code I posted, I also forgot the
Code:
call TriggerRegisterAnyUnitEventBJ(gg_trg_Turmoil, EVENT_PLAYER_UNIT_SPELL_EFFECT)
function, but still after I fixed that, the trigger just hides and then shows the caster after 2 seconds. Any idea why isn't the values beeing loaded in the Timer function?
 
Level 3
Joined
Nov 18, 2013
Messages
21
Sorry, it's GroupClear(), definitely a vanilla JASS function. Did you try with a TSA longer than 2 seconds to see if it's not just getting destroyed prematurely like I suggested?

I didn't know that, that function doesn't show up in my JassCraft, so I assumed that it was a vJASS function. Actually the problem was that I didn't created the initialization trigger to create the hashtable. The spell works fine now, but I'm still implementing it. Here's the code:
Code:
function Turmoil_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A003'
endfunction

function Timer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit caster = GetHandleUnit(t, "caster")
    local real x = GetHandleReal(t, "x")
    local real y = GetHandleReal(t, "y")
    local group target = CreateGroup()
    local unit temp
    local real dmg = 35+20*GetUnitAbilityLevel(caster, 'A003')
    local unit dummy
    call GroupEnumUnitsInRange(target, x, y, 500., null)
    set temp = GroupPickRandomUnit(target)
    if (IsUnitEnemy(temp, GetOwningPlayer(caster))) and (not IsUnitType(temp, UNIT_TYPE_STRUCTURE)) and (IsUnitAlive(temp)) then
        set dummy = CreateUnit(GetOwningPlayer(caster), 'h005', x, y, GetUnitFacing(temp)+180)
        call UnitApplyTimedLife(dummy, 'BTFL', 0.2)
        call SetUnitTimeScalePercent(dummy, 400.00)
        call SetUnitVertexColor(dummy, 255, 255, 255, PercentToInt(60, 255))
        call SetUnitAnimationByIndex(dummy, 7)
    endif
        call UnitDamageTarget(caster, temp, dmg, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\MakuraMissile\\MakuraMissile.mdl", temp, "chest"))
    loop
        set temp = FirstOfGroup(target)
        call GroupRemoveUnit(target, temp)
        exitwhen temp == null
    endloop
    call DestroyGroup(target)
    set temp = null
    set target = null
    set t = null
    set caster = null
endfunction

function Turmoil_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit caster = GetTriggerUnit()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    call SetHandleHandle(t, "caster", caster)
    call SetHandleReal(t, "x", x)
    call SetHandleReal(t, "y", y)
    call ShowUnit(caster, false)
    call TimerStart(t, 0.2, true, function Timer)
    call TriggerSleepAction(2.)
    call FlushHandleLocals(t)
    call PauseTimer(t)
    call DestroyTimer(t)
    call ShowUnit(caster, true)
    call SetUnitPosition(caster, x, y)
    set t = null
    set caster = null
endfunction

function InitTrig_Turmoil takes nothing returns nothing
    set gg_trg_Turmoil = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Turmoil, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition( gg_trg_Turmoil, Condition(function Turmoil_Conditions))
    call TriggerAddAction(gg_trg_Turmoil, function Turmoil_Actions)
endfunction
 
Status
Not open for further replies.
Top