• 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.

[Solved] How to detect which event fired/triggered?

Status
Not open for further replies.
Level 12
Joined
Nov 3, 2013
Messages
989
  • Recall Start
    • Events
      • Unit - A unit Starts the effect of an ability
      • Unit - A unit Stops casting an ability
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Recall
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Current order of (Triggering unit)) Equal to (Order(channel))
        • Then - Actions
          • Game - Display to (All players) the text: Channeling recall.
          • Special Effect - Create a special effect at (Position of (Triggering unit)) using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
          • Set recall_specialEffect[0] = (Last created special effect)
        • Else - Actions
          • Game - Display to (All players) the text: Not channeling reca...
          • Special Effect - Destroy recall_specialEffect[0]
Here I managed to separate EVENT_PLAYER_UNIT_SPELL_EFFECT & EVENT_PLAYER_UNIT_SPELL_FINISH by checking whether the unit's current order is still to channel (It's a dummy ability based of channel.) However, EVENT_PLAYER_UNIT_SPELL_ENDCAST (the event that happens if the unit is interrupted, moves, etc.) still show that the unit is channeling.


Now, I think that "stop casting"/_ENDCAST event happens before "finishes casting"/_FINISH, so that might affect how I'll make the actions. (edit: Actually, it doesn't. so I don't have to care about that part. As long as 'finish' happens, 'endcast' won't occur.)


Anyway, I want to be able to tell whether the casting begun or ended, and I want to be able to tell whether the channel was successful or not.
 
Last edited:
Level 12
Joined
Mar 24, 2011
Messages
1,082
I think you are better to split off into different triggers.
In GUI you could have 3 different triggers like:
  • SpellStrt
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • Stuff
  • Actions
    • More stuff
  • SpellStopCast
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
    • Stuff
  • Actions
    • More stuff
  • SpellFinishCast
  • Events
    • Unit - A unit Finishes casting an ability
  • Conditions
    • Stuff
  • Actions
    • More stuff
But this is ugly as all hell. Other option is to have 4 triggers in total and use 3 with events as kind of enum... kinda... It is still ugly as hell, but I guess there would be less repetition of code, depending on what you are doing.
  • SpellStrt
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
  • Actions
    • Set Stage = 0
  • SpellStopCast
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
  • Actions
    • Set Stage = 1
  • SpellFinishCast
  • Events
    • Unit - A unit Finishes casting an ability
  • Conditions
  • Actions
    • Set Stage = 2
  • SpellCore
  • Events
  • Conditions
  • Actions
    • If Stage equals to 0 do
      • Stuff
    • If Stage equals to 1 do
      • Other Stuff
    • If Stage equals to 2 do
      • Totally different stuff

In JASS, you may be able to do that within the Event, now again I am not especially versed in JASS events and would rather not give any more ideas on this, I am thinking you may be able to do something during the event registration.

Hope this helps!

regards
-Ned
 
Level 12
Joined
Nov 3, 2013
Messages
989
I think you are better to split off into different triggers.
In GUI you could have 3 different triggers like:
  • SpellStrt
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • Stuff
  • Actions
    • More stuff
  • SpellStopCast
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
    • Stuff
  • Actions
    • More stuff
  • SpellFinishCast
  • Events
    • Unit - A unit Finishes casting an ability
  • Conditions
    • Stuff
  • Actions
    • More stuff
But this is ugly as all hell. Other option is to have 4 triggers in total and use 3 with events as kind of enum... kinda... It is still ugly as hell, but I guess there would be less repetition of code, depending on what you are doing.
  • SpellStrt
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
  • Actions
    • Set Stage = 0
  • SpellStopCast
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
  • Actions
    • Set Stage = 1
  • SpellFinishCast
  • Events
    • Unit - A unit Finishes casting an ability
  • Conditions
  • Actions
    • Set Stage = 2
  • SpellCore
  • Events
  • Conditions
  • Actions
    • If Stage equals to 0 do
      • Stuff
    • If Stage equals to 1 do
      • Other Stuff
    • If Stage equals to 2 do
      • Totally different stuff

In JASS, you may be able to do that within the Event, now again I am not especially versed in JASS events and would rather not give any more ideas on this, I am thinking you may be able to do something during the event registration.

Hope this helps!

regards
-Ned
I'd rather not split it up into multiple triggers, if it can be helped, because it will get messy with other stuff.

And honestly this part is kinda like practice, in the first place I don't even need to really trigger a Recall spell, since I could just use Mass Teleport with dummy etc.

But I need something to work with for other channel spells later, so I wanted to do something simple first to figure out some of the things I need to do.
 
Now, I think that "stop casting"/
_ENDCAST
event happens before "finishes casting"/
For such questions I use the cool image from this tutorial: Casting Events Guide , here it shows "stop casting" comes at end.

There's a native function to retrieve the firing event (id) which let the trigger run, for GUI some custom script can be used for getting event and making checks with if-statements, example:

  • SomeTrigger
    • Events
      • Unit - A unit Starts the effect of an ability
      • Unit - A unit Finishes casting an ability
      • Unit - A unit Stops casting an ability
    • Conditions
    • Actions
      • Custom script: local eventid event = GetTriggerEventId()
      • Custom script: if event == EVENT_PLAYER_UNIT_SPELL_EFFECT then
      • -------- ---------------------------- --------
      • -------- // Starts Effect --------
      • -------- ---------------------------- --------
      • Custom script: elseif event = EVENT_PLAYER_UNIT_SPELL_FINISH
      • -------- ---------------------------- --------
      • -------- Finishes Casting --------
      • -------- ---------------------------- --------
      • Custom script: elseif event = EVENT_PLAYER_UNIT_SPELL_ENDCAST
      • -------- ---------------------------- --------
      • -------- // Stops Casting --------
      • -------- ---------------------------- --------
      • Custom script: endif
^It would do the wanted effect, I guess, with using ifs.

==

I persoanlly would usually prefer seperating it into triggers with each one event. (if it messes with other triggers, maybe something else would need to be changed, or not sure If I understand correctly)
But for only little info, without too much spell logics, it doesn't maybe hurt very much, too, keeping them in one, if you prefer.
 
Level 12
Joined
Nov 3, 2013
Messages
989
For such questions I use the cool image from this tutorial: Casting Events Guide , here it shows "stop casting" comes at end.

There's a native function to retrieve the firing event (id) which let the trigger run, for GUI some custom script can be used for getting event and making checks with if-statements, example:

  • SomeTrigger
    • Events
      • Unit - A unit Starts the effect of an ability
      • Unit - A unit Finishes casting an ability
      • Unit - A unit Stops casting an ability
    • Conditions
    • Actions
      • Custom script: local eventid event = GetTriggerEventId()
      • Custom script: if event == EVENT_PLAYER_UNIT_SPELL_EFFECT then
      • -------- ---------------------------- --------
      • -------- // Starts Effect --------
      • -------- ---------------------------- --------
      • Custom script: elseif event = EVENT_PLAYER_UNIT_SPELL_FINISH
      • -------- ---------------------------- --------
      • -------- Finishes Casting --------
      • -------- ---------------------------- --------
      • Custom script: elseif event = EVENT_PLAYER_UNIT_SPELL_ENDCAST
      • -------- ---------------------------- --------
      • -------- // Stops Casting --------
      • -------- ---------------------------- --------
      • Custom script: endif
^It would do the wanted effect, I guess, with using ifs.

==

I persoanlly would usually prefer seperating it into triggers with each one event. (if it messes with other triggers, maybe something else would need to be changed, or not sure If I understand correctly)
But for only little info, without too much spell logics, it doesn't maybe hurt very much, too, keeping them in one, if you prefer.
Thanks, that's exactly what I was looking for. I converted the GUI trigger to jass and simply did this:

if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT ) then... and repeat for the rest. I don't think there's any reason to use the local eventid event = GetTriggerEventId() part, no? Besides it always being there in the beginning I guess. (Just for good habit/practice.)


Anyway, what I ended up with was this, if it matters/is interesting:

JASS:
//function Trig_Recall_Start_Copy_Conditions takes nothing returns boolean
//    if ( not ( GetSpellAbilityId() == 'A04Z' ) ) then
//        return false
//    endif
//    return true
//endfunction

function Trig_Recall_Start_Copy_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    if ( GetSpellAbilityId() == 'A04Z' ) then
        if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT ) then
            call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_2100" )
            call AddSpecialEffectLocBJ( GetUnitLoc(GetTriggerUnit()), "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTo.mdl" )
            set udg_recall_specialEffect[0] = GetLastCreatedEffectBJ()
        else
            call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_2099" )
            call DestroyEffectBJ( udg_recall_specialEffect[0] )
            if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_FINISH ) then
                call DisplayTextToForce( GetPlayersAll(), "Channel completed." ) //proceed to teleport units
                call DestroyEffect( AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl", x, y) )
                call SetUnitPositionLoc( u, udg_revive_point[0] )
                call DestroyEffect( AddSpecialEffectLoc( "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl", udg_revive_point[0] ) )
            else
                if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST ) then
                    call DisplayTextToForce( GetPlayersAll(), "Channel was interupted." )
                endif
            endif
        endif
    endif
endfunction

//===========================================================================
function InitTrig_Recall_Start_Copy takes nothing returns nothing
    set gg_trg_Recall_Start_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Recall_Start_Copy, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Recall_Start_Copy, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Recall_Start_Copy, EVENT_PLAYER_UNIT_SPELL_FINISH )
    //call TriggerAddCondition( gg_trg_Recall_Start_Copy, Condition( function Trig_Recall_Start_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_Recall_Start_Copy, function Trig_Recall_Start_Copy_Actions )
endfunction

By the way, somewhat offtopic, but is there any reason to use TriggerAddCondition? I simply commented it out just in case, and well it works in game, but maybe it's bad?

JASS:
if ( not ( GetSpellAbilityId() == 'A04Z' ) ) then
        return false
    endif
    return true
^ Looks real bad though, and I remember people joking about how it's convoluted/redundant as well...
 
Level 16
Joined
Mar 25, 2016
Messages
1,327
Thanks, that's exactly what I was looking for. I converted the GUI trigger to jass and simply did this:

if ( GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT ) then...
and repeat for the rest. I don't think there's any reason to use the
local eventid event = GetTriggerEventId()
part, no? Besides it always being there in the beginning I guess. (Just for good habit/practice.)

It's a bit faster. This way GetTriggerEventId() is only executed once.

By the way, somewhat offtopic, but is there any reason to use TriggerAddCondition? I simply commented it out just in case, and well it works in game, but maybe it's bad?
If you do not have a condition, then you don't need to add one. It is also fine to put conditions into the actions, like you did here.
In your trigger the locals are initialized before your conditions are checked. This means GetTriggerUnit(), GetUnitX() and GetUnitY() will always be executed when the trigger runs. Even if a different spell is casted. If you initialize their values only after the condition it is a bit faster.

Conditions are a bit faster than actions. You could put all your actions into the conditions and don't have actions at all. One downside is that you cannot use waits in a condition, but you usually don't use them in JASS anyway.

^ Looks real bad though, and I remember people joking about how it's convoluted/redundant as well...
This is how every GUI condition looks like in JASS. It's a bit slower than if you would write it normally in JASS. This is usually not a big problem though.
It just looks horrible in JASS and can be very confusing.

Most of these things are very minor and will only improve performance by a bit. You usually won't notice it at all.
 
Status
Not open for further replies.
Top