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

[vJASS] Simple passive ability help part 2:)

Status
Not open for further replies.
Level 8
Joined
Feb 3, 2013
Messages
277
JASS:
scope ASStrike initializer init

    globals
        private constant string FX = "war3mapImported\\BlinkCaster.mdx"
        private constant integer ID = 'A000'
    endglobals

    private function AS_Actions takes nothing returns nothing
        local unit target = GetTriggerUnit()
        local unit attacker = GetEventDamageSource()
        local location blinkpoint = GetUnitLoc(attacker)
        local location targetpoint = GetUnitLoc(target)
        local location newpoint = PolarProjectionBJ(targetpoint, 100, GetRandomReal(0,360))
        if GetUnitAbilityLevel(attacker, ID) > 0 then
            call DestroyEffect(AddSpecialEffectLoc(FX, blinkpoint))
            call SetUnitX(attacker, GetLocationX(newpoint))
            call SetUnitY(attacker, GetLocationY(newpoint))
        endif
        set target = null
        set attacker = null
        call RemoveLocation(blinkpoint)
        call RemoveLocation(targetpoint)
        call RemoveLocation(newpoint)
    endfunction
    
    private function Register takes nothing returns nothing
        local trigger t2 = CreateTrigger()
        call TriggerRegisterUnitEvent(t2, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
        call TriggerAddAction(t2, function AS_Actions)
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_ATTACKED)
        call TriggerAddAction(t1, function Register)
    endfunction
    
endscope

This time I got it to work for all units being attacked and receiving damage, but for some reason - the blink effect is created multiple times :/ Why?
2mot3ew.png

Once again thanks in advance:) - SOLVED

EDIT1:
JASS:
scope GiantSwing initializer init

    globals
        private constant unit attacker = udg_DamageEventSource
        private constant unit target = udg_DamageEventTarget
        private constant integer ID = 'A000'
        private constant string  FX = "Abilities\\Spells\\Orc\\Disenchant\\DisenchantSpecialArt.mdl"
        private constant string WFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
        private constant string  AP = "right, hand"
        private constant real damage = udg_DamageEventAmount
        private integer i
    endglobals
    
    private function GS_Cond takes nothing returns boolean
        return IsPlayerEnemy(GetOwningPlayer(attacker),GetOwningPlayer(target))
    endfunction
    
    private function GS_Damage takes nothing returns nothing
        call UnitDamageTargetBJ(attacker, GetEnumUnit(), 2 * damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
    endfunction
    
    private function GS_Effect takes nothing returns nothing
        call AddSpecialEffectTarget(FX, GetEnumUnit(), "chest")
    endfunction
    
    private function GS_Actions takes nothing returns nothing
        local location target_point = GetUnitLoc(target)
        local group g = CreateGroup()
        local effect Last_FX
        if GetUnitAbilityLevel(attacker, ID) > 0 then
            if i < 2 then
                set i = i + 1
            elseif i == 2 then
                call AddSpecialEffectTarget(WFX, attacker, AP)
                set Last_FX = GetLastCreatedEffectBJ()
                set i = i + 1
            elseif i == 3 then
                call DestroyEffect(Last_FX)
                call GroupEnumUnitsInRangeOfLoc(g, target_point, 285, Filter(function GS_Cond))
                call ForGroup(g, function GS_Damage)
                call ForGroup(g, function GS_Effect)
                set i = 0
            endif
        endif
        call DestroyGroup(g)
        call RemoveLocation(target_point)
    endfunction
            
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterVariableEvent(t, "udg_DamageEvent", EQUAL, 1.00)
        call TriggerAddAction(t, function GS_Actions)
        set i = 0
    endfunction
    
endscope
I didn't want to create another thread just to ask for more help so I'll post another question here.
i'm using bribe's damage detectino system; on every x hits, the unit is supposed to deal a splash damage with an effect
once again saves fine, but can't get it to work :/ - absolutely nothing shows in game


thanks to all that helped me out + REP and much love <333

edit2: SOLVED :)
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
as WaterKnight said,
that will spam your trigger to death

when I attack your unit 2 times it will run the trigger 2 times

you should destroy the trigger in AS_Actions

also you should change AS_Actions from TriggerAddAction to TriggerAddCondition
 
Level 8
Joined
Feb 3, 2013
Messages
277
as WaterKnight said,
that will spam your trigger to death

when I attack your unit 2 times it will run the trigger 2 times

you should destroy the trigger in AS_Actions

also you should change AS_Actions from TriggerAddAction to TriggerAddCondition
okay i used DestroyTrigger(GetTriggeringTrigger()) in my AS_Actions function, but it still seems to make a couple of effects

also what od you mean 'change AS_Actions from TriggerAddAction to TriggerAddCondition)'?

Thanks again for your responses
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
okay i used DestroyTrigger(GetTriggeringTrigger()) in my AS_Actions function and that seems to work much better

also what od you mean 'change AS_Actions from TriggerAddAction to TriggerAddCondition)'?

Thanks again for your responses

Conditions run faster than actions and usually they have no problems. That is because conditions are checked locally.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Try it out. This should simply work faster in multiplayer, as actions are synchronized and conditions are not.
This makes no sense at all...
All triggers, both actions and conditions, execute synchronusly.

EDIT: wow it worked, lol I was shocked - but it doesn't change that there are still multiple effects occuring on damage taken.
That is because you create a new trigger every time the unit is attacked that responds to the unit taking damage. This means that if you attack the unit 100 times, there will be 100 different triggers that run 100 times the same action code in responde to the unit taking damage as each trigger has subscribed to that event.

If you attack 1000 times then it will run the actions 1000 times and probably hang the game for a couple of frames.

To solve, stop creating a new trigger every time the unit is attacked.
 
Level 8
Joined
Feb 3, 2013
Messages
277
This makes no sense at all...
All triggers, both actions and conditions, execute synchronusly.


That is because you create a new trigger every time the unit is attacked that responds to the unit taking damage. This means that if you attack the unit 100 times, there will be 100 different triggers that run 100 times the same action code in responde to the unit taking damage as each trigger has subscribed to that event.

If you attack 1000 times then it will run the actions 1000 times and probably hang the game for a couple of frames.

To solve, stop creating a new trigger every time the unit is attacked.

JASS:
scope ASStrike initializer init

    globals
        private constant string FX = "war3mapImported\\BlinkCaster.mdx"
        private constant integer ID = 'A000'
    endglobals

    private function AS_Actions takes nothing returns boolean
        local unit target = GetTriggerUnit()
        local unit attacker = GetEventDamageSource()
        local location blinkpoint = GetUnitLoc(attacker)
        local location targetpoint = GetUnitLoc(target)
        local location newpoint = PolarProjectionBJ(targetpoint, 100, GetRandomReal(0,360))
        if GetUnitAbilityLevel(attacker, ID) > 0 then
            call DestroyEffect(AddSpecialEffectLoc(FX, blinkpoint))
            call SetUnitX(attacker, GetLocationX(newpoint))
            call SetUnitY(attacker, GetLocationY(newpoint))
        endif
        set target = null
        set attacker = null
        call RemoveLocation(blinkpoint)
        call RemoveLocation(targetpoint)
        call RemoveLocation(newpoint)
        call DestroyTrigger(GetTriggeringTrigger())
        return true
    endfunction
    
    private function Register takes nothing returns nothing
        local trigger t2 = CreateTrigger()
        call TriggerRegisterUnitEvent(t2, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
        call TriggerAddCondition(t2,Condition(function AS_Actions))
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_ATTACKED)
        call TriggerAddAction(t1, function Register)
    endfunction
    
endscope
This is the current code; sorry for being so stupid - but can you spoonfeed me a bit, I'm a litle lost.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
I would not destroy the trigger. First, it's said that the DestroyTrigger function is buggy, second you might still fire your attack event multiple times before the damage event occurs, third it may not even occur. Use a single trigger instead you add the damage events to and check if a unit is already registered. You can store the units in a group for example to make use of its IsUnitInGroup function. Note that even without an attack a unit can suffer damage and the damage from EVENT_UNIT_DAMAGED can be any damage, not only from the normal attack.

Or just take one of those damage detection systems. You do not need to register all the units for each and every spell of this kind then.
 
Level 8
Joined
Feb 3, 2013
Messages
277
I decided to go ahead and use Bribe's amazing damage detection system and now it works flawlessly. Thank you for your responsese again

EDIT: I've been thread spamming, so instead I just decided to keep another question here

JASS:
Jass:  
scope GiantSwing initializer init

    globals
        private constant unit attacker = udg_DamageEventSource
        private constant unit target = udg_DamageEventTarget
        private constant integer ID = 'A000'
        private constant string  FX = "Abilities\\Spells\\Orc\\Disenchant\\DisenchantSpecialArt.mdl"
        private constant string WFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
        private constant string  AP = "right, hand"
        private constant real damage = udg_DamageEventAmount
        private integer i
    endglobals
    
    private function GS_Cond takes nothing returns boolean
        return IsPlayerEnemy(GetOwningPlayer(attacker),GetOwningPlayer(target))
    endfunction
    
    private function GS_Damage takes nothing returns nothing
        call UnitDamageTargetBJ(attacker, GetEnumUnit(), 2 * damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
    endfunction
    
    private function GS_Effect takes nothing returns nothing
        call AddSpecialEffectTarget(FX, GetEnumUnit(), "chest")
    endfunction
    
    private function GS_Actions takes nothing returns nothing
        local location target_point = GetUnitLoc(target)
        local group g = CreateGroup()
        local effect Last_FX
        if GetUnitAbilityLevel(attacker, ID) > 0 then
            if i < 2 then
                set i = i + 1
            elseif i == 2 then
                call AddSpecialEffectTarget(WFX, attacker, AP)
                set Last_FX = GetLastCreatedEffectBJ()
                set i = i + 1
            elseif i == 3 then
                call DestroyEffect(Last_FX)
                call GroupEnumUnitsInRangeOfLoc(g, target_point, 285, Filter(function GS_Cond))
                call ForGroup(g, function GS_Damage)
                call ForGroup(g, function GS_Effect)
                set i = 0
            endif
        endif
        call DestroyGroup(g)
        call RemoveLocation(target_point)
    endfunction
            
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterVariableEvent(t, "udg_DamageEvent", EQUAL, 1.00)
        call TriggerAddAction(t, function GS_Actions)
        set i = 0
    endfunction
    
endscope
i'm using bribe's damage detectino system; on every x hits, the unit is supposed to deal a splash damage with an effect
once again saves fine, but can't get it to work :/ - absolutely nothing shows in game

once again thanks to all that helped me out + REP and much loves <333
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
variables are not bound to each other, they only copy the value stored in them before, so your
JASS:
        private constant unit attacker = udg_DamageEventSource
        private constant unit target = udg_DamageEventTarget
        private constant real damage = udg_DamageEventAmount

will get null, null and 0.00

you should set the variables to those values in the GS_Action trigger instead

also i can be initialized to 0 in the global block

also
JASS:
call AddSpecialEffectTarget(WFX, attacker, AP)
set Last_FX = GetLastCreatedEffectBJ()

will not work, because GetLastCreatedEffectBJ() returns bj_lastCreatedEffect but when you call AddSpecialEffectTarget, the value is still null, you can do:
JASS:
set Last_FX = AddSpecialEffectTarget(WFX, attacker, AP)

also:

JASS:
    private function GS_Effect takes nothing returns nothing
        call AddSpecialEffectTarget(FX, GetEnumUnit(), "chest")
    endfunction

->

JASS:
    private function GS_Effect takes nothing returns effect
        return AddSpecialEffectTarget(FX, GetEnumUnit(), "chest")
    endfunction
 
Status
Not open for further replies.
Top