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

Is there a way to get what event actually triggered the Action?

Status
Not open for further replies.
Level 2
Joined
Feb 1, 2014
Messages
5
So im doing some quest triggers and i would like to have all the quest actions in one trigger (Quest pickup, Quest progressing and completion) and since that would require several events im just curious in how i would aproach that.

i noticed that we have "GetTriggerEventId()" but i didnt really understand what it does, or what Id's different events have or how to find that out. after doing alot of searching i have finally given up and i now turn to you guys <3

edit: found my own solution through converting "GetTriggerEventId()" With "GetHandleId()"
 
Last edited:
Level 30
Joined
Nov 29, 2012
Messages
6,637
As far as I know you could try using If Then Else. For example, in a trigger when the unit picks up the quest, make an If Then Else statement like If Demon_Killed Greater than or equal to 5 Then Display Qeest Update text. After that, in the same If Then Else, create another If Then Else that when your unit entered a region (possibly make the region near the NPC), start a cinematic then quest complete and give rewards BUT I cannot assure if this will work for this is just my assumption or a wild guess if I may say.

It's always better and much more accurate if you are just to stay on the original ways of creating quests where it composes of triggers: Pickup, Update and Completion for it is much easier to play with the triggers rather than limiting yourself in one trigger.
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
If you're using JASS/vJASS you can actually put everything you want in a library/scope quests.
In GUI it is possible with this trick :
  • Custom script - call ExecuteFunc("Quest_1_Start")
  • Custom script - call ExecuteFunc("Quest_2_Start")
  • Custom script - endfunction
  • Custom script - function Quest_1_Start takes nothing returns nothing
  • Custom script - ....
  • Custom script - endfunction
  • Custom script - function Quest_2_Start takes nothing returns nothing
  • Custom script - ...
  • Custom script - endfunction
And on the .... you can freely put GUI/Custom script :)
But you will be able to use only one event and one condition with this form.
But as I just showed you can freely put all your quest_starting in the same trigger for example.
 
Level 2
Joined
Feb 1, 2014
Messages
5
Yes it is actually very easy. Are you familiar with JASS/vJass or are you using GUI(triggers)?

Yes i am using VJass

If you're using JASS/vJASS you can actually put everything you want in a library/scope quests.
In GUI it is possible with this trick :
  • Custom script - call ExecuteFunc("Quest_1_Start")
  • Custom script - call ExecuteFunc("Quest_2_Start")
  • Custom script - endfunction
  • Custom script - function Quest_1_Start takes nothing returns nothing
  • Custom script - ....
  • Custom script - endfunction
  • Custom script - function Quest_2_Start takes nothing returns nothing
  • Custom script - ...
  • Custom script - endfunction
And on the .... you can freely put GUI/Custom script :)
But you will be able to use only one event and one condition with this form.
But as I just showed you can freely put all your quest_starting in the same trigger for example.

how you mean using a library/scope?
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
JASS:
scope AllQuests initializer init
    globals
        private constant string NAME_QUEST_1 = "Name"
        private constant string NAME_QUEST_2 = "Name"
    endglobals

    private function Q1Init takes nothing returns boolean
        //Create your quest
        return false
    endfunction

    private function init takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        local trigger t2 = CreateTrigger()
        local trigger t3 = CreateTrigger()
        local trigger t4 = CreateTrigger()
        call TriggerRegisterTimerEvent(t1, 0., false)
        call TriggerAddCondition(t, Condition(function Q1Init))
        ....
        set t1 = null
        set t2 = null
        set t3 = null
        set t4 = null
    endfunction
endscope
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
It is very possible to narrow down what event triggered your action.

Suppose (oddly enough) you give the same action to a trigger that detects when a player kills a unit. But you also gave the same action to a different trigger that detects when a player clicks a dialog button.

Clearly these are two different events, but it's possible to detect what trigger they originating from if they have the same action.

This is because things like "GetTriggerPlayer()" or "GetClickedButton()" always return null values UNLESS the event subcategorizes for them. For example, every Dialog Event subcategorizes for: the player who clicked it, the dialog that was clicked, and the button that was clicked. It does NOT subcategorize for a unit (because there's no unit involved) or really anything else.

So what you can do is this:

JASS:
private function main takes nothing returns nothing
  //if it's a unit event
  if GetTriggerUnit() != null then:
    //your code here
  elseif GetClickedDialog() != null then:
    //your code here
  …
  endif
endfunction

The problem is some events may subcategorize for the same exact handles, or a superset of them. For example, take the events "DialogClickedEvent" and "ButtonClickedEvent." These subcategorize for:

DialogClicked: GetClickedDialog(), GetClickedButton(), GetTriggerPlayer()
ButtonClicked: GetClickedButton() (<-- this might not even work), GetTriggerPlayer()

Now if your test was just "GetClickedButton() != null", you would still fail to distinguish between a button click event and a dialog click event.


I don't encourage this kind of coding. Because events have much different sub categorizations (i.e. the entities which semantically belong in those events), every event should have its own separate action. What would happen is you'll end up with one super long action that will be a pain to debug, versus dealing with say three much smaller actions where any bugs become immediately obvious.

In my own quest API, I actually give players an array of quests, pre-made. I then arbitrarily decide when a quest is available (e.g. a player beats a boss) and simple do this:

JASS:
  //somehow we're ready to activate this specific quest
  call currentPlayerQuests[NEW_QUEST].enable()

Of course I have an actually custom QuestStruct (quests don't have an enable() method).

Updating a quest is more tricky, but really it's the same exact thing as completing it. So you can put those two together. You'll need to do your own magic here as it will depend on what kind of subparts your quests have. My quests are simple in many respects, so I can write a general API for creating quests with arbitrary stages, but you might have some difficult parts that can't be easily done so.
 
Level 2
Joined
Feb 1, 2014
Messages
5
While im at it, is there a way to dynamically tell a function what variable to alter? i was thinking about making a quest library or something like that

For Example
JASS:
function Quest takes player TrigPlayer, string Questname, string Questlore

  set udg_"Questname"Active[GetPlayerId(TrigPlayer)] = 1
  ...
  set udg_"QuestName"Quest[GetPlayerId(TrigPlayer)] = GetLastCreatedQuestBJ()

endfunction
 
Level 2
Joined
Feb 1, 2014
Messages
5
JASS:
globals
    private unit u
endglobals

//So you don't need to use the variable editor anymore :)

//GetLastCreatedQuest() is a non-native that return a variable which is bj_lastCreatedQuest.

//For your last question it is very specific though :/

ah, i didnt use the var editor, but i thought you needed to name them udg_ even in VJass

how you mean its very specific? should i take that as if its not possible? :/
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
It makes little sense to use different events in the same trigger unless what they run is very similar, in which case that should outsource to a function still. Each event can be looked at as an action with the script it runs as the action handler. Unless you want the action to be handled in exactly the same way, you will want different triggers as that represents a different mapping between action and action handler. It just makes more sense like this.

The trick is to keep cohesion by grouping such triggers together. WC3 GUI kind of sucks as it does not have nested folders like SC2 but in SC2 the solution is simply to put all the triggers inside a folder and name them uniquely (such as folder name as a prefix). In WC3 you will have to tolerate using just the prefix as the cohesion between the triggers. If you use vJASS you can bundle all the trigger script into a single scope (or library if you prefer but I think scope is more meaningful for this) which acts as another level of containment inside a single element.
 
Status
Not open for further replies.
Top