Help with jass auto ability trigger

superkar

New Member
Reaction score
0
Hello everyone! I am decent at programming but I'm pretty new to jass so I might just have done something stupid! I'm trying to create an auto cast ability, like cold arrow, that deals a scaling dmg, let's say 5 per each level multoplied by the times the target has remained the same, meaning that for example the 4th hit on the same target will deal 20 dmg. I've taken the script from this tutorial and modified it for my cause:
http://world-editor-tutorials.thehelper.net/cat_usersubmit.php?view=41266
I have two main problems:
First, the trigger needs to detect the auto ability either it was auto cast or cast by the user. The code for the second "trigger" in the int_trigger was wrong in the page, I have tried to fix it but it doesn't seem to work.
Second, the script doesn't work as I would like it to. If the target is changed and the ability is used, it works, the counter is reset, but if the target is changed and the ability is not used, the counter on the previous unit, the one hit by the ability, the counter would not reset and start from the number it stopped. I really can't figure out why. I think the problem is somehow in the Auto Attack Detect trigger. If the conditions are not met, meaning that the ability has not been cast, the counter should be reset. Somehow it doesn't! This is weird because the Auto Attack Detect should run every time a unit is hit, if I'm not mistaken! Here is the code:

function Auto_Attack_Detect takes nothing returns boolean
if GetTriggerEventId()==EVENT_PLAYER_UNIT_ATTACKED then
if (GetAttacker() == udg_Emanation) then
set udg_EtherStrikeNextTarget= GetTriggerUnit()
endif
if GetUnitAbilityLevel(GetAttacker(),'A000')>0 then
return true
endif
endif
if GetTriggerEventId()==EVENT_UNIT_SPELL_EFFECT and GetSpellAbilityId()=='A000' then
return true
endif
set udg_EtherStrikeCount = 0
return false
endfunction

function Auto_Attack_Effects takes nothing returns nothing
local real dam
local unit targ = GetTriggerUnit()
local unit cast = GetEventDamageSource()
local texttag t

if GetUnitAbilityLevel(targ,'B000')>0 and GetUnitAbilityLevel(cast,'A000')>0 then
call DisableTrigger(GetTriggeringTrigger())
if (udg_EtherStrikePreviousTarget==udg_EtherStrikeNextTarget) then
set udg_EtherStrikeCount = udg_EtherStrikeCount +1
else
set udg_EtherStrikeCount = 0
endif
set udg_EtherStrikePreviousTarget=udg_EtherStrikeNextTarget
set dam = (GetUnitAbilityLevel(cast,'A000')*5)*(1+(udg_EtherStrikeCount))
set t = CreateTextTag()
call SetTextTagText(t,"+"+I2S(R2I(dam)),.023)
call SetTextTagPosUnit(t,targ,15)
call SetTextTagColor(t,0,0,255,50)
call SetTextTagVelocity(t,.0355 * Cos(90 * bj_DEGTORAD),.0355 * Sin(90 * bj_DEGTORAD))
call SetTextTagLifespan(t,1.)
call UnitDamageTarget(cast,targ,dam,false,false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_COLD,null)
call PolledWait(1.)
call DestroyTextTag(t)
set t = null
endif

set targ = null
set cast = null
endfunction

function Auto_Attack_Detect_Actions takes nothing returns nothing
local trigger trig = CreateTrigger()
local triggeraction ta
local unit u

if GetTriggerEventId()==EVENT_UNIT_SPELL_EFFECT then
set u = GetSpellTargetUnit()
else
set u = GetTriggerUnit()
endif
call TriggerRegisterUnitEvent(trig,u, EVENT_UNIT_DAMAGED)
set ta = TriggerAddAction(trig, function Auto_Attack_Effects)
call PolledWait(2)

call DisableTrigger(trig)
call TriggerRemoveAction(trig,ta)
call DestroyTrigger(trig)

set ta = null
set u = null
set trig = null
endfunction

function InitTrig_Ether_Strike takes nothing returns nothing
set gg_trg_Ether_Strike = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(gg_trg_Ether_Strike, EVENT_PLAYER_UNIT_ATTACKED)
//call TriggerRegisterAnyUnitEventBJ(gg_trg_Ether_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerRegisterUnitEvent(gg_trg_Ether_Strike,udg_u, EVENT_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_Ether_Strike, Condition(function Auto_Attack_Detect))
call TriggerAddAction(gg_trg_Ether_Strike, function Auto_Attack_Detect_Actions)
endfunction

Emanation is the caster of the ability, A000 the ability and B000 the effect
In the init trigger you can see my poor attempts to make the trigger work for the ability being cast by the user :D
Thanks in advance!
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Could you please put all the code in JASS tags.

And I see a PolledWait in there, these are inaccurate, and a Timer should be used instead.
 

Dameon

"All the power in the world resides in the eyes"
Reaction score
127
Incinerate with the death damage removed?
 

Imp Midna

Active Member
Reaction score
52
And I see a PolledWait in there, these are inaccurate, and a Timer should be used instead.
Thumbs up for this insiginificant side commentary, containing information that could not be less usefull for the whole script :)

From what i see, your counter will be reset when either any unit uses any spell that is not A000, or when any unit is attacked (note, attacked is not the actual act of getting damage, but far before, and the execution of the attack may still be interrupted at this point) by someone that does not have the ability A000. It does not ask for which unit did this in general, so any other unit on the whole map may reset your counter as it feels like. Somehow odd in my opinion, i doubt that this is what you wanted. I wonder why its not reset all the time in your test. Also note that you Auto_Attack_Effect function triggers every time the attacked unit takes damage, no matter from which sorce.
General fix tip i like to give is the DisplayTextToForce(GetPlayersAll(), "TEXT HERE"). Just insert it every time you modify your counter so you can track down the situation when it happens. Sort of a cheap replacement for the missing debugger ;)
 

superkar

New Member
Reaction score
0
wow thanks for the multiple answers!
Oh my GOD! I can u believe I didn't know that incinerate did basically what I needed? Jesus!
Anyway, I need it to be autocast, also because, if I'll be able to, I'd like to add a cumulative mana cost as well! So incinerate would not be good for it. Plus I'd like to show the extra dmg.
To imp midna: thanks for understanding what I need :D you are right, i did something really silly with the counter reset!
And now, after 1 hour of tests, I understand why u said that auto attack effect triggers everytime.. The condition that checks if the damage source is the auto ability is inside auto-effect :D i'm so stupid! So i tried to move the counter and Previous/NextTarget setting to the Effect part, while i left the detect exactly as it was in the link. This is how i thought it would be fixed:
Code:
function Auto_Attack_Effects takes nothing returns nothing
    local real dam
    local unit targ = GetTriggerUnit()
    local unit cast = GetEventDamageSource()
    local texttag t
    if GetUnitAbilityLevel(targ,'B000')>0 and GetUnitAbilityLevel(cast,'A000')>0 then
        call DisplayTextToForce(GetPlayersAll(), "auto-used")
        call DisableTrigger(GetTriggeringTrigger())       
        if (udg_EtherStrikePreviousTarget==udg_EtherStrikeNextTarget) then
            set udg_EtherStrikeCount = udg_EtherStrikeCount +1
        else
            set udg_EtherStrikeCount = 0
        endif
        set udg_EtherStrikePreviousTarget=udg_EtherStrikeNextTarget
        set dam = (GetUnitAbilityLevel(cast,'A000')*5)*(1+(udg_EtherStrikeCount))       
        BLABLABLA text tag settings
        call UnitDamageTarget(cast,targ,dam,false,false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_COLD,null)               
        call PolledWait(1.)
        call DestroyTextTag(t)
        set t = null
    elseif (cast==udg_Emanation) then
        set udg_EtherStrikePreviousTarget = udg_Emanation
        set udg_EtherStrikeCount = 0
        call DisplayTextToForce(GetPlayersAll(), "not ether strike")
    endif
 
    set targ = null
    set cast = null     
endfunction

So everytime some1 is attacked, it will check if the attacked one has the effect of the auto-ability and that the attacker has used the ability itself. At that point, the ability works fine (it did before and I didn't change this part), recognising also a target switch while still using the ability. Instead, basically, if the attacker is not using the autoability and is the emanation(this is the elseif part close to the end), the counter is reset and the previous target is set to be the emanation, so the next check between Previous-Next target will be for sure negative.
Well something really disturbing happens. Both the if and the elseif are executed, meaning that 5 dmg will be dealt forever, no matter what, and both "auto-used" and "not ether strike" are displayed. Funnily enough, "not ether strike" is displayed before "auto-used".
Am i missing something big about JASS? in this language both ifs and elseifs are executed?
I am pretty sure this is the last problem for this script. Can anybody help?
Plus, how do I make the INIT trigger recognise the "user-cast" version of the auto-attack??
 

Dameon

"All the power in the world resides in the eyes"
Reaction score
127
Make 5 abilitys.
Channel Based
Dummy On
Dummy Off
Engineering Upgrade
Set 1 to D on, D off
Set 2 to D off, D on
incinerate
Set how u want it.
SpellBook
Put Incinerate inside it then disable it in the scenario options.

Then use this trigger

Trigger:
  • Untitled Trigger 001
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Dummy On
        • Then - Actions
          • Unit - Set level of EU for (Casting unit) to 2
          • Player - Enable incinerate for (Owner of (Casting unit))
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Ability being cast) Equal to Dummy Off
            • Then - Actions
              • Unit - Set level of EU for (Casting unit) to 1
              • Player - Disable incinerate for (Owner of (Casting unit))
            • Else - Actions
 

superkar

New Member
Reaction score
0
Well thank you, this would work but not as i'd like it to. I want it to be a clean autocast that resets totally when the target changes! I just need some1 to tell me why both the if and elseif are executed!
 

Imp Midna

Active Member
Reaction score
52
Am i missing something big about JASS? in this language both ifs and elseifs are executed?

Would be extremly weird and sort of kill the purpose of the elseif. The only thing that i can see happening is that the trigger triggers twice, which may only happen when your caster deals damage twice. Maybe he has some spell or orb-effect that deals damage? Try to find out where the other damage came from (GetEventDamage() may be a hint).

Plus, how do I make the INIT trigger recognise the "user-cast" version of the auto-attack??

Thought the EVENT_UNIT_SPELL_EFFECT is the one that triggers when you manually use the ability, isnt it?
 

superkar

New Member
Reaction score
0
You are right about the trigger firing twice, if I auto-use the ability on a unit and then attack it without the ability, and then auto-use the ability again the trigger is fired twice, the tags are like +5, no tag because of notmal attack, +10 and +15 together on top of each other when I eactivate the autocast. It might be significant to you the fact that the next +20 tag destroys the +15 one.. I really have no idea what to say :D the more I check it the more I think it should not trigger more then once! I did what u said (btw your tips till now has proven to be incredibly helpful, thank you :) ) it says that both the damages that trigger the triggers are from the "emanation".. This just came to my mind, is it that may be it is triggered by the normal attack plus the autoability itself, as they both deal damage and do it in the same instant??? This sounds reasonable! Omg how can i avoid this? I've set the dummy ability to deal 0 dmg but i guess it still counts as damage for the compiler! How can i make the script not consider the 0 dmg from the dummy ability? The ability of orb of corruption doesn't deal damg and leaves an effect, so it might work, but it is not "autocastable"! What can i do? :(
Just for good measure, i deleted the EVENT_UNIT_SPELL_EFFECT, which yes was the one supposed to trigger the manual usage. Of course nothing changed.
 

superkar

New Member
Reaction score
0
OMG it works! IT WORKS!! I've simply put a GetEventDamage()!=0 condition and it works!
Imp Midna i would have NEVER done this without your help! THANK YOU very muchhh!!
I'll put your name in the "thanks to" part of my map. It's worth nothing but sadly it's the best I can do :D
Actually this 0 dmg from a dummy ability can be used for a lot of stuff!
Now I just need to make the trigger work for the manual use of the ability, any idea?? :D
 

superkar

New Member
Reaction score
0
It still had problems, fixed it changing the duration of the polled wait! This time it looks like it really works as intended! Still hasn't fixed the manual trigger though!
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top