• 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.
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!
  • ✅ The POLL for Hive's Texturing Contest #34 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!
  • ✅ The POLL for Hive's Techtree Contest #20 is OPEN! Vote for the TOP 3 FACTIONS! 🔗Click here to cast your vote!

[Trigger] Tips Text Help

Status
Not open for further replies.
  • setup
    • Events
      • Map Initialization
    • Conditions
    • Actions
      • Set Tip[0] = "Don't be a fool, stay in school."
      • Set Tip[1] = "Don't do drugs, idiot."
  • Looping Trig
    • Events
      • Elapsed Time - Every 15.00 seconds of game time
    • Conditions
      • ShowTips Equal To True
    • Actions
      • Game - Text Message to All Players: Tip[Math - Random Integer Number between 0 and 1]
  • Off/on trig
    • Events
      • -------- Put what event you want to disable/enable it --------
    • Conditions
    • Actions
      • Set ShowTips = False/True
 
you could slightly improve Bribe's system by turning off the periodic trigger when you toggle off, and turn on the trigger when toggle on. But this could make it spam if you spam the toggle.
 
You can improve it, by writing it in vJass

JASS:
scope text initializer i
    globals
        private constant real TIMEOUT=15
        private constant integer HIGHBOUND=2
        private string array message
        private boolean bool=false
    endglobals
    
    private function p takes nothing returns nothing
        if bool then
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,message[GetRandomInt(0,HIGHBOUND)])
        else
            call PauseTimer(time)
        endif
    endfunction
    
    private function c takes nothing returns boolean
        if bool then
            set bool=false
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Tips turned off")
        else
            set bool=true
            call TimerStart(time,TIMEOUT,true,function p)
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Tips turned on")
        endif
        return false
    endfunction
    
    private function i takes nothing returns nothing
        local trigger t=CreateTrigger()
        set message[0]="first message"
        set message[1]="another message"
        set message[2]="yet a third message."
        call TriggerRegisterPlayerChatEvent(t,Player(0),"-tips",true)
        call TriggerAddCondition(t,Condition(function c))
    endfunction
endscope
 
You can improve your JASS, by using actions instead of conditions, like this:

JASS:
    private function c takes nothing returns nothing
        if bool then
            set bool = false
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Tips turned off")
        else
            set bool = true
            call TimerStart(time,TIMEOUT,true,function p)
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Tips turned on")
        endif
    endfunction
    
    private function i takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterPlayerChatEvent(t,Player(0),"-tips",true)
        call TriggerAddAction(t,function c)
        set message[0] = "first message"
        set message[1] = "another message"
        set message[2] = "yet a third message."
    endfunction
 
Actually no, that's terrible and not an improvement at all.

Edit: let me explain why since I'm sure you're not the only person that doesn't know.

Conditions are handled just like actions in this sense, except they have a few distinct advantages and disadvantages from actions.

First, Conditions CANNOT have TSA within them--it breaks the thread.
Second, Conditions can be destroyed within a dynamic trigger while actions cannot (the result is a non-leaking dynamic trigger if you choose to create one)
Third, because the majority of triggers have both a condition and an action, it's wiser to put the action within the condition than the condition within the action for speed purposes.
 
Actually, yes, that's a great idea and a great improvement over your method.

Actions don't need two handles to be assigned to them. And if you're using both conditions and actions in the same trigger, you've used 3 handles instead of just 1. Conditions take 2? Yes:

JASS:
call TriggerAddCondition(t,Condition(function SomeCondition))
                          //^--- Here it generates a handle.
native TriggerAddCondition takes trigger whichTrigger, boolexpr condition returns triggercondition
                                                    //here it generates another handle --^

Also, unless you are somehow able to track both generated handles created by making a triggercondition, you've just leaked more than the triggeraction would have.

TriggerSleepAction - how about you just avoid using it altogether. That's absolutely no reason to needlessly allocate extra handles just because of useless TSA.

Using Condition as an action allows you to quickly pass parameters to that action. Passing parameters is faster than declaring/nulling local handles:

JASS:
function Action takes unit TrigUnit,unit Target,unit dummy returns nothing
 
if (condition) then
    call Action(GetTriggerUnit(),GetSpellTargetUnit(),null)
endif
 
What you say makes sense, but I think you're misunderstanding what I meant with TSA. I agree it's useless.

I have a question, if TriggerAddCondition() makes 2 handles, then why shouldn't you use TriggerAddAction() the same way I did, ignoring conditions entirely?

Edit: to clarify, I put the actions within my condition function, but if action functions are better, why shouldn't people put conditions within an actions function?
 
All I changed is made function c return nothing instead of a boolean and swap TriggerAddCondition for TriggerAddAction.

What I wrote should, in terms of syntax, look like this:

JASS:
function Action takes unit TrigUnit,unit Target,unit dummy returns nothing
    //actions
endfunction
 
function Conditions takes nothing returns nothing
    if (GetSpellAbilityId() == 'A000') then
        call Action(GetTriggerUnit(),GetSpellTargetUnit(),null)
    endif
endfunction
 
function InitTrig takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction(t,function Conditions)
endfunction
 
Think of a condition like call foo() while an action is like call ExecuteFunc("foo").

Not a perfect analogy but it should hint at why conditions are generally better if all you care about is efficiency.

I don't see how creating an entire boolean expression is an efficient thing to do when 99% of triggers would do better to replace conditions for actions. Unless native event-triggered triggers execute conditions faster than they execute actions, the best plan is to allocate less RAM by generating Actions instead.
 
When the RAM difference is a few bytes, your code looking good is more important than either.

Also, believe it or not, all these little optimizations add up. While they don't matter for anything static, when you are using dynamic triggers as function pointers (and stuff like that) in complicated systems it can matter to actually use conditions, hence why .evaluate() is used much more often than .execute() in vJass.
 
Then it's a matter of preference for you as it is for me. I like doing a "call actions" from within my condition trigger so that I can just pass some parameters right there because parameters don't need null. I'd rather add a little horizontal space than make a lot of vertical space, plus parameters are faster than declaring/nulling locals in scripting time.
 
Status
Not open for further replies.
Back
Top