• 🏆 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!

Problem with add/remove ability

Status
Not open for further replies.
Level 6
Joined
Oct 1, 2012
Messages
166
Heloes Hive Workshop
I encountered a weird problem with my code. There is a skill, which gives a unit a dummy skill, slow poison, to be precise. Then, after the unit hits the enemy once, the skill is removed. To this point, it all works. But, when the ability is cast again, triggers don't give casting unit the ability.

Here's the code (two triggers):

First trigger (giving the skill)

JASS:
function SWK_cond takes nothing returns boolean
    if (GetSpellAbilityId() == 'A01Z') then
     return true
    endif
    return false
endfunction

function Trig_Strzal_w_kolano_ON_Actions takes nothing returns nothing
    local integer nr = GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))
    set udg_Strzal[nr] = 1
    call UnitAddAbility(GetTriggerUnit(), 'A020')
endfunction

//===========================================================================
function InitTrig_Strzal_w_kolano_ON takes nothing returns nothing
    set gg_trg_Strzal_w_kolano_ON = CreateTrigger(  )
    call TriggerAddCondition(gg_trg_Strzal_w_kolano_ON, Condition(function SWK_cond))
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Strzal_w_kolano_ON, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Strzal_w_kolano_ON, function Trig_Strzal_w_kolano_ON_Actions )
endfunction

It's in polish, but only the names, guess it's nothing wrong.

Second trigger (removing the skill after the target is damaged)

JASS:
function S_cond takes nothing returns boolean
    if (udg_Strzal[GetConvertedPlayerId(GetOwningPlayer(GetAttacker()))] == 0) then
     return false
    endif
    return true
endfunction

function dostal_f takes nothing returns nothing
    local unit cel = GetTriggerUnit()
    local unit atak = GetEventDamageSource()
    local integer nr = GetConvertedPlayerId(GetOwningPlayer(atak))
    if (udg_Strzal[nr] == 1) then
     call UnitRemoveAbility(atak, 'A020')
    endif
    set udg_Strzal[nr] = 0
    set cel = null
    set atak = null
endfunction

function Trig_Strzal_Actions takes nothing returns nothing
    local trigger dostal = CreateTrigger()
    local unit cel = GetTriggerUnit()
    call TriggerRegisterUnitEvent(dostal, cel, EVENT_UNIT_DAMAGED)
    call TriggerAddAction(dostal, function dostal_f)
    set cel = null
    set dostal = null
endfunction

//===========================================================================
function InitTrig_Strzal takes nothing returns nothing
    set gg_trg_Strzal = CreateTrigger(  )
    call TriggerAddCondition(gg_trg_Strzal, Condition(function S_cond))
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Strzal, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_Strzal, function Trig_Strzal_Actions )
endfunction

Any solutions?
 
Level 7
Joined
Nov 15, 2009
Messages
225
JASS:
function dostal_f takes nothing returns nothing
    local unit cel = GetTriggerUnit()
    local unit atak = GetEventDamageSource()
    local integer nr = GetConvertedPlayerId(GetOwningPlayer(atak))
    if (udg_Strzal[nr] == 1) then
     call UnitRemoveAbility(atak, 'A020')
    endif
    set udg_Strzal[nr] = 0
    set cel = null
    set atak = null
endfunction

Hey,
there's one problem I see so far.
All units can attack the unit and set udg_Strzal[whatever] to 0.
There's no condition about it.
You could try to add the condition if damage source got the A01Z ability.
So removing the ability and setting it to 0 should be in the same condition.

If it does not help you, add some debugging messages to see to which point your spells runs.
call BJDebugMsg("test")
 
Level 6
Joined
Oct 1, 2012
Messages
166
Why, that is true, but only for that player's units (as nr is player's number and udg_Strzal[nr] changes only for the given skill).
Still, that is not it, that's just the case of triggering the skill removement by other units.
 
Level 6
Joined
Oct 1, 2012
Messages
166
Thank you for this one, didn't notice that, actually.
But still, the bug remains unsolved, the skill won't re-add itself to the unit :D
 
Level 6
Joined
Oct 1, 2012
Messages
166
No, the spell has 20 sec cd, and poison lasts for up to 18, this one isn't it. It's just that the hero doesn't get the skill again. Only for the first time.
 
Level 7
Joined
Nov 15, 2009
Messages
225
Strange strange..
I remade your functions and the only thing that removed the poison was the poison damage itself.
Anything else worked fine and still I can't find your problem.. -,-'

Anyway.. maybe this will help you..
Copy and paste it, you only need to change the first 2 THIS values
JASS:
scope Poison initializer Init

    globals
        private constant integer CastingSpell = 'THIS' // ability beeing cast to get poison
        private constant integer PoisonSpell = 'THIS' // poison ID
        integer array Strzal
        private trigger Damage = CreateTrigger()
    endglobals

    private function AddPoison takes nothing returns nothing
        if GetSpellAbilityId() == CastingSpell then
            set Strzal[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] = 1
            call UnitAddAbility(GetTriggerUnit(), PoisonSpell)
        endif
    endfunction
    
    private function RemovePoison takes nothing returns nothing
        if Strzal[GetPlayerId(GetOwningPlayer(GetEventDamageSource()))] == 1 and GetUnitAbilityLevel(GetEventDamageSource(), CastingSpell) > 0 then
            call UnitRemoveAbility(GetEventDamageSource(), PoisonSpell)
            set Strzal[GetPlayerId(GetOwningPlayer(GetEventDamageSource()))] = 0
        endif
    endfunction
    
    private function AddUnitToTrigger takes nothing returns nothing
        call TriggerRegisterUnitEvent(Damage, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
    endfunction

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local trigger t2 = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(t, function AddPoison)
        call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_ATTACKED)
        call TriggerAddAction(t2, function AddUnitToTrigger)
        call TriggerAddAction(Damage, function RemovePoison)
    endfunction

endscope
 
Level 6
Joined
Oct 1, 2012
Messages
166
But all this is basically my function, but made in a different way. What sould be the difference?
 
Level 7
Joined
Nov 15, 2009
Messages
225
But all this is basically my function, but made in a different way. What sould be the difference?

The only things I changed are the condition (dostal_f function) and moved the TriggerAddAction (Trig_Strzal_Actions function) into the trigger init.

I wanted to test it, so I copied and pasted your trigger + changed a little bit of the coding.
But I had no problems with it when I was finished.
 
Level 6
Joined
Oct 1, 2012
Messages
166
Ah, okay then, I'll test it as soon as I'll have a computer capable of doing so, thank you :)
 
Status
Not open for further replies.
Top