• 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.
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!
  • ✅ The POLL for Hive's Texturing Contest #34 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!
  • ✅ The POLL for Hive's Techtree Contest #20 is OPEN! Vote for the TOP 3 FACTIONS! 🔗Click here to cast your vote!

[JASS] Custom-Spell's effects doesn't work properly

Status
Not open for further replies.
Level 2
Joined
May 1, 2010
Messages
13
Hi, i've got a problem with a triggers and timers created effects.
The trigger is a custom spell based on abitily: ANcl. It simply creates a signal-effect and a chaos-comet effect, starts a non-periodic timer for 3 secs. After that, the comet hits and another effect is created and damage is dealt.

Here the JASS:


JASS:
function Trig_ChaosComet_IsEnemy takes nothing returns boolean
    return (( IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(udg_ChaosCometCaster)) == true ) )
endfunction

function Trig_ChaosComet_Damage takes nothing returns nothing
    local integer level = GetUnitAbilityLevelSwapped('A0DJ', udg_ChaosCometCaster)
    local real damage = (level * 75.00)
    call UnitDamageTargetBJ( udg_ChaosCometCaster, GetEnumUnit(), damage, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNIVERSAL )
    call AddSpecialEffectTargetUnitBJ( "chest", GetEnumUnit(), "Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl" )
    call DestroyEffect( bj_lastCreatedEffect )
endfunction

function Trig_ChaosComet_Wait takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local group damageGroup
    local effect tempEffect 
    
    set damageGroup = GetUnitsInRangeOfLocMatching( 200, udg_ChaosCometTarget, Condition(function Trig_ChaosComet_IsEnemy) )
    call ForGroup(damageGroup, function Trig_ChaosComet_Damage)

    set tempEffect = AddSpecialEffectLoc( "Units\\NightElf\\Wisp\\WispExplode.mdl", udg_ChaosCometTarget )
    call DestroyEffect( tempEffect )
    set tempEffect = AddSpecialEffectLoc( "Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl", udg_ChaosCometTarget )
    call DestroyEffect( tempEffect )
    set tempEffect = null
    
    call DestroyEffect(udg_ChaosCometIndicator)
    set udg_ChaosCometIndicator = null
    set udg_ChaosCometCaster = null
    call RemoveLocation(udg_ChaosCometTarget)
    set udg_ChaosCometTarget = null
    call DestroyGroup(damageGroup)
    set damageGroup = null
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function Trig_ChaosComet_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local effect tempEffect 
    
    set udg_ChaosCometCaster = GetTriggerUnit()
    set udg_ChaosCometTarget = GetSpellTargetLoc()
    
    set tempEffect = AddSpecialEffectLoc( "Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", udg_ChaosCometTarget )
    call DestroyEffect( tempEffect )
    set tempEffect = null
    
    set udg_ChaosCometIndicator = AddSpecialEffectLoc( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", udg_ChaosCometTarget )

    call TimerStart(t, 2.7, false, function Trig_ChaosComet_Wait)
    set t = null
    
endfunction

function Trig_ChaosComet_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A0DJ' ) ) then
        return false
    endif
    return true
endfunction

//===========================================================================
function InitTrig_ChaosComet takes nothing returns nothing
    set gg_trg_ChaosComet = CreateTrigger(  )
    
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ChaosComet, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ChaosComet, Condition( function Trig_ChaosComet_Conditions ) )
    
    call TriggerAddAction( gg_trg_ChaosComet, function Trig_ChaosComet_Actions )
endfunction

Now, the problem is that some of the created effects won't display! The ChaosCometIndicator-Effect:
JASS:
set udg_ChaosCometIndicator = AddSpecialEffectLoc( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", udg_ChaosCometTarget )
works, and the others won't show up...

I have to mention, that it worked! I'm using newgen and just switched my wc3 to 1.26a.

Does anybod has an idea, what caused the error??? i'm totaly confused...:vw_wtf:
 
Try this instead of creating effects and then destroying them:

JASS:
call DestroyEffect(AddSpecialEffectTarget("Units\\NightElf\\Wisp\\WispExplode.mdl", udg_ChaosCometTarget, "origin"))
I'm no expert with JASS but, you seem to be using AddSpecialEffectLoc without including a location.
 
Yes, i'll try it! but it worked for the global effect-var
JASS:
udg_ChaosCometIndicator
but not for the local
JASS:
tempEffect
in this lines:
JASS:
    set tempEffect = AddSpecialEffectLoc( "Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", udg_ChaosCometTarget )
    call DestroyEffect( tempEffect )
    set tempEffect = null
    
    set udg_ChaosCometIndicator = AddSpecialEffectLoc( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", udg_ChaosCometTarget )

Edit:
You meant that udg_ChaosCometTarget is not assigned in the call of the timer-function? it is assigned before the timer is started in the function: Trig_ChaosComet_Actions
here:
JASS:
function Trig_ChaosComet_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local effect tempEffect 
    
    set udg_ChaosCometCaster = GetTriggerUnit()
    set udg_ChaosCometTarget = GetSpellTargetLoc()
    
    set tempEffect = AddSpecialEffectLoc( "Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", udg_ChaosCometTarget )
    call DestroyEffect( tempEffect )
    set tempEffect = null
    
    set udg_ChaosCometIndicator = AddSpecialEffectLoc( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", udg_ChaosCometTarget )

    call TimerStart(t, 2.7, false, function Trig_ChaosComet_Wait)
    set t = null
    
endfunction
 
Is "udg_ChaosCometTarget" a location variable?
Try putting the destroy and add special effect into one line - this may solve the problem. This way you don't need to create a local variable.

JASS:
call DestroyEffect(AddSpecialEffectLoc("Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", udg_ChaosCometTarget))
 
I will add destription in sec. Fixed trigger:
~MUI version
JASS:
function Trig_ChaosComet_IsEnemy takes nothing returns boolean
    local integer level
    local real damage
    local unit u = GetFilterUnit()

    if IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(udg_ChaosCometCaster)) == true then
        set level = GetUnitAbilityLevel(udg_ChaosCometCaster, 'A0DJ')
        set damage = (level * 75.00)
        call UnitDamageTarget(udg_ChaosCometCaster, u, damage, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNIVERSAL, null)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl", u, "chest"))
    endif

    set u = null
    return false
endfunction

function Trig_ChaosComet_Wait takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local real x = LoadReal(udg_Hash, id, 2)
    local real y = LoadReal(udg_Hash, id, 3)

    set udg_ChaosCometCaster = LoadUnitHandle(udg_Hash, id, 1)
    call GroupEnumUnitsInRange (bj_lastCreatedGroup, x, y, 200, Condition(function Trig_ChaosComet_IsEnemy))
    call DestroyEffect(AddSpecialEffect( "Units\\NightElf\\Wisp\\WispExplode.mdl", x, y))
    call DestroyEffect(AddSpecialEffect( "Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl", x, y))
    call DestroyEffect(LoadEffectHandle(udg_Hash, id, 4))
    call FlushChildHashtable(udg_Hash, id)
    call PauseTimer(t)
    call DestroyTimer(t)

    set t = null
endfunction

function Trig_ChaosComet_Conditions takes nothing returns boolean
    local timer t
    local integer id
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local unit u = GetTriggerUnit()

    if GetSpellAbilityId() == 'A0DJ' then
        set t = CreateTimer()
        set id = GetHandleId(t)
        call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", x, y))
        call SaveUnitHandle(udg_Hash, id, 1, u)
        call SaveReal(udg_Hash, id, 2, x)
        call SaveReal(udg_Hash, id, 3, y)
        call SaveEffectHandle(udg_Hash, id, 4, AddSpecialEffect( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", x, y))
        call TimerStart(t, 2.7, false, function Trig_ChaosComet_Wait)
    endif
    set t = null
    set u = null
    return false
endfunction

//===========================================================================
function InitTrig_ChaosComet takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition( function Trig_ChaosComet_Conditions ))
    set udg_Hash = InitHashtable()
    set t = null
endfunction
 
Last edited:
No, it is a global variable.

i changed it that no more local variables are needed, but the problem remains :(

here the code:

JASS:
function Trig_ChaosComet_IsEnemy takes nothing returns boolean
    return (( IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(udg_ChaosCometCaster)) == true ) )
endfunction

function Trig_ChaosComet_Damage takes nothing returns nothing
    local integer level = GetUnitAbilityLevelSwapped('A0DJ', udg_ChaosCometCaster)
    local real damage = (level * 75.00)
    call UnitDamageTargetBJ( udg_ChaosCometCaster, GetEnumUnit(), damage, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNIVERSAL )
    call DestroyEffect( AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl", GetEnumUnit(), "chest") )
endfunction

function Trig_ChaosComet_Wait takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local group damageGroup
    
    set damageGroup = GetUnitsInRangeOfLocMatching( 200, udg_ChaosCometTarget, Condition(function Trig_ChaosComet_IsEnemy) )
    call ForGroup(damageGroup, function Trig_ChaosComet_Damage)

    call DestroyEffect( AddSpecialEffectLoc( "Units\\NightElf\\Wisp\\WispExplode.mdl", udg_ChaosCometTarget ) )
    call DestroyEffect( AddSpecialEffectLoc( "Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl", udg_ChaosCometTarget ) )
    
    call DestroyEffect(udg_ChaosCometIndicator)
    set udg_ChaosCometIndicator = null
    set udg_ChaosCometCaster = null
    call RemoveLocation(udg_ChaosCometTarget)
    set udg_ChaosCometTarget = null
    call DestroyGroup(damageGroup)
    set damageGroup = null
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function Trig_ChaosComet_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    
    set udg_ChaosCometCaster = GetTriggerUnit()
    set udg_ChaosCometTarget = GetSpellTargetLoc()
    
    call DestroyEffect( AddSpecialEffectLoc( "Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", udg_ChaosCometTarget ) )
    
    set udg_ChaosCometIndicator = AddSpecialEffectLoc( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", udg_ChaosCometTarget )

    call TimerStart(t, 2.7, false, function Trig_ChaosComet_Wait)
    set t = null
endfunction

function Trig_ChaosComet_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A0DJ' ) ) then
        return false
    endif
    return true
endfunction

//===========================================================================
function InitTrig_ChaosComet takes nothing returns nothing
    set gg_trg_ChaosComet = CreateTrigger(  )
    
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ChaosComet, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ChaosComet, Condition( function Trig_ChaosComet_Conditions ) )
    
    call TriggerAddAction( gg_trg_ChaosComet, function Trig_ChaosComet_Actions )
endfunction
 
Fixed syntax errors. Now, a bit of explanation:

- Merge Conditions and Actions into one function
- You need only two globals variables: hashtable and unit one (hashtable 'Hash' is here for making your spell MUI)
- to get rid of ForGroup() just add actions immidiately in Filter function
- use natives instead of Switch/Sample/BJ
- coordinates proves to be much more effective than locations
- get rid of leaks
- first destroy handles before nulling them (you're actually nulling them before destroying, so functions Destroy/Removing will actually refer to null - nothing will get removed)
 
Thanks Spinnaker, now it is optimized ;) But the error is still the same, only the manadrain-effect is displayed...as before :(

here how it looks now:

JASS:
function Trig_ChaosComet_IsEnemy takes nothing returns boolean
    local integer level
    local real damage
    local unit u = GetFilterUnit()
    if IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(udg_ChaosCometCaster)) == true then
        set level = GetUnitAbilityLevel(udg_ChaosCometCaster, 'A0DJ')
        set damage = (level * 75.00)
        call UnitDamageTarget(udg_ChaosCometCaster, u, damage, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNIVERSAL, null)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl", u, "chest"))
    endif
    set u = null
    return true
endfunction

function Trig_ChaosComet_Wait takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local real x = LoadReal(udg_ChaosCometHash, id, 2)
    local real y = LoadReal(udg_ChaosCometHash, id, 3)
    local effect tempEffect 
    set udg_ChaosCometCaster = LoadUnitHandle(udg_ChaosCometHash, id, 1)
    call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, 200, Condition(function Trig_ChaosComet_IsEnemy))

    call DestroyEffect(AddSpecialEffect( "Units\\NightElf\\Wisp\\WispExplode.mdl", x, y))
    call DestroyEffect(AddSpecialEffect( "Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl", x, y))
    
    call DestroyEffect(LoadEffectHandle(udg_ChaosCometHash, id, 4))
    call FlushChildHashtable(udg_ChaosCometHash, id)
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function Trig_ChaosComet_Conditions takes nothing returns boolean
    local timer t
    local integer id
    local effect tempEffect 
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local unit u = GetTriggerUnit()
    if GetSpellAbilityId() == 'A0DJ' then
        set t = CreateTimer()
        set id = GetHandleId(t)
        call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Demon\\InfernalMeteor\\InfernalMeteor3.mdl", x, y))
        call SaveEffectHandle(udg_ChaosCometHash, id, 4, AddSpecialEffect( "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl", x, y))
        call TimerStart(t, 2.7, false, function Trig_ChaosComet_Wait)
    endif
    set t = null
    return true
endfunction

//===========================================================================
function InitTrig_ChaosComet takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition( function Trig_ChaosComet_Conditions ))
    set udg_ChaosCometHash = InitHashtable()
    set t = null
endfunction

i still think that the error could have been caused by changing form v1.24d to 1.26 :eekani:
 
Fixed syntax errors. Now, a bit of explanation:

- Merge Conditions and Actions into one function
- You need only two globals variables: hashtable and unit one (hashtable 'Hash' is here for making your spell MUI)
- to get rid of ForGroup() just add actions immidiately in Filter function
- use natives instead of Switch/Sample/BJ
- coordinates proves to be much more effective than locations
- get rid of leaks
- first destroy handles before nulling them (you're actually nulling them before destroying, so functions Destroy/Removing will actually refer to null - nothing will get removed)

Thanks for that! It isn't needed MUI now, but maybe later. I've never considered doing it in the conditions, clever :)
Im still writing it fast with BJs and stuff and optimize it afterwards...stupid, i know -.-

Well, problem remains sadly....i could explode...
 
Done, but it is still that the drain is on the ground and nothing happens.
Im gonna make a extra map for that and post it! Than it is better to compare :)

Edit: map for testing included! please take a look at this. Does every effect display?
 

Attachments

Last edited:
What is the diffrence if you use Hash and i ChaosCometHash? If i replace it, the results are the same...or not?

And for me i see only the mana-drain effect, nothing else! same for you or do you see the comet and the impact effects?
 
Thanks you two,

so it isn't the spell which was wrong (okay, it was leaking and so on, but it did what i intended). So my wc3 could be the problem:

i used this tool: Warcraft 1.26 Version Switcher to switch form 1.24d to 1.26 as said before. Does anybody know such errors??

@Spinnaker I refered to udg_ChaosCometHash not to udg_Hash.

@watermelon_1234 thanks, i will take another one. That was only to test if that effect appears or isn't displayed like the rest. So this was a bad testing-sample^^

Edit: Okay i think i got the error: this program is used to patch from 1.25b to 1.26 -.-
I will try to patch it the right way...

Edit2: Thaaanks to all! now it works, was that nasty version-error :thumbs_up:
 
Last edited:
Status
Not open for further replies.
Back
Top