• 🏆 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] Timer wont work.

Status
Not open for further replies.
Level 3
Joined
Mar 2, 2012
Messages
27
in this skill i wanted to damage per second the whole unit nearby the casting unit however this trigger wont damage them. plss help
JASS:
scope PE initializer init
    globals
        private constant integer SPELL_ID = 'A001'
        private constant string SPELL_EFFECT_INDIVIDUAL = "Abilities\\Weapons\\PoisonSting\\PoisonStingTarget.mdl"
        private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_POISON
        private constant real SPELL_AOE = 550.
        private constant real SPELL_INTERVAL_POISON = 0.5
        private constant real SPELL_DURATION_POISON = 20.
        private constant integer SPELL_BUFF_ID = 'B000'
        private constant attacktype SPELL_TYPE = ATTACK_TYPE_MAGIC 
    endglobals
    
    private function getPoisonDamage takes integer level returns real
        return 1. * level
    endfunction
    
    private function getDamage takes integer level returns real
        return 100. * level
    endfunction
    
    private function groupp1 takes nothing returns boolean
      if 0 != GetUnitAbilityLevel(GetEventTargetUnit(), SPELL_BUFF_ID) then
      return true
      else
      return false
      endif
    endfunction
    
    private function groupp2 takes nothing returns boolean
      if 0 == GetUnitAbilityLevel(GetEventTargetUnit(), SPELL_BUFF_ID) then
      return true
      else
      return false
      endif
    endfunction

    private function group1 takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local widget t = GetEnumUnit()
        local integer level = GetUnitAbilityLevel(u, SPELL_ID)
        call DisplayTimedTextToPlayer(Player(0),0.,0.,20.,"ttttt")
        call UnitDamageTarget(u, t, getPoisonDamage(level), true, false, SPELL_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
        call DestroyEffect(AddSpecialEffectTarget(SPELL_EFFECT_INDIVIDUAL,t,"chest"))
    endfunction
    
    private function poison takes nothing returns nothing
        local group g = CreateGroup()
        call DisplayTimedTextToPlayer(Player(0),0.,0.,20.,"twttt")
        call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Filter(function groupp1))
        call ForGroup(g, function group1)
        call DestroyGroup(g)
        set g = null //Has to be cleaned
    endfunction    
    
    private function group2 takes nothing returns nothing
        local widget targ = GetEnumUnit()
        local unit u = GetTriggerUnit()
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        local timer t = CreateTimer()
        local integer level = GetUnitAbilityLevel(u, SPELL_ID)
        call UnitDamageTarget(u,targ, getDamage(level), true, false, SPELL_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
        call TimerStart(t,SPELL_INTERVAL_POISON, true, function poison)
    endfunction
    
    private function action takes nothing returns nothing
        local group g = CreateGroup()
        call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Filter(function groupp2))
        call ForGroup(g, function group2)
        call DestroyGroup(g)
        set g = null
    endfunction
        
        
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(t, function action)
        call Preload(SPELL_EFFECT_INDIVIDUAL)
    endfunction
endscope
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
what is firing ? and what isnt ?

change the conditions to this
JASS:
 private function groupp1 takes nothing returns boolean
        return 0 != GetUnitAbilityLevel(GetEventTargetUnit(), SPELL_BUFF_ID)
    endfunction
    
    private function groupp2 takes nothing returns boolean
        return 0 == GetUnitAbilityLevel(GetEventTargetUnit(), SPELL_BUFF_ID)
    endfunction
 
Level 3
Joined
Mar 2, 2012
Messages
27
this is an instant spell, when casted all units nearby it will be receiving damage and will be poisoned(damage per second).
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
this is an instant spell, when casted all units nearby it will be receiving damage and will be poisoned(damage per second).

ik tht i want to know what is firing u have the displaytext in there what is showing up when u try to cast it ? also i think u r losing the gettriggeringunit or the geteventtargetunit when u use the timer
 
Level 4
Joined
Jan 27, 2010
Messages
133
You know, a great way to confuse people is to name things so that they almost sound the same. Like group1 and groupp1.

First of all, if you want the trigger to react to a certain spell, you should add that as an explicit trigger condition.

JASS:
private function Conditions takes nothing returns boolean
    return GetSpellAbilityId()==SPELL_ID
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 Conditions))
        call TriggerAddAction(t, function action)
        call Preload(SPELL_EFFECT_INDIVIDUAL)
    endfunction

Secondly: you either do the group loop in the filter OR with a ForGroup. No need to do both.

JASS:
private function SpellTargets takes nothing returns nothing
        local unit targ = GetEnumUnit()
        local unit u = GetTriggerUnit()
        local integer level = GetUnitAbilityLevel(u, SPELL_ID)
        local timer t

        if GetWidgetLife(targ)>.405 and IsUnitEnemy(targ,GetOwningPlayer(u)) then
            call UnitDamageTarget(u,targ, getDamage(level), true, false, SPELL_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
            set t=CreateTimer()
            call TimerStart(t,SPELL_INTERVAL_POISON, true, function poison)
        endif

        set t=null
        set u=null
        set targ=null
endfunction

private function action takes nothing returns nothing
        local group g = CreateGroup()

    // You want enum units in range, not rect
        call GroupEnumUnitsInRange(g, GetSpellTargetX(), GetSpellTargetY(), SPELL_AOE, null)
        call ForGroup(g, function SpellTargets)
        call DestroyGroup(g)
        set g = null
    endfunction

And, finally, like deathismyfriend said. All variables are unknown in a timer-expires function. The only thing you can use is globals and GetExpiredTimer. Read up on structs and TimerUtils/Table if you want to bypass this limitation.

Can there ever be more than 1 instance of this spell running at the same time? (that is, can hero X cast it before hero Y's poison has finished. And is the cooldown less than 20 seconds ? )
 
Level 3
Joined
Mar 2, 2012
Messages
27
Ok reworked it all tnx for the tips! ill be learning structs in some other time otherwise thank you! +rep
 
Status
Not open for further replies.
Top