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

[JASS] I'm not programming this quest correctly :(

Status
Not open for further replies.
Level 14
Joined
Jul 26, 2008
Messages
1,009
Alright I decided to do quests for players in a nifty way using trigger arrays. I figured it'd be good cause it'd allow me to control how quests flow and condense them to a single struct.

However I must not have done it correctly because when I try to do it, it gives me the quest twice when I enter the rect. I'm not sure why either, I cant figure it out :\

I've also set up an effect array so player A sees a little boy at location A and after completing the quest he'll see the little boy at location B, but only he will see it.

Advice on the FXPath and if I'm doing it right would be great. Also help with the double-Trigger thing would do wonders, thanks :)

JASS:
scope LightHouseQuest initializer Init

globals
    public trigger array Quest1
    public trigger array Quest2
    public trigger array Quest3
    private effect array FX1
    private effect array FX2
endglobals

private function Actions3 takes nothing returns nothing
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffffd700LIGHTHOUSE KEEPER|r: You Found Him! Here are the keys! Its all yours!" )
    if GetOwningPlayer(gg_unit_nC48_0523) == Player(PLAYER_NEUTRAL_PASSIVE) then
        call SetUnitOwner( gg_unit_nC48_0523, GetOwningPlayer(GetTriggerUnit()), true )
        call SetUnitInvulnerable( gg_unit_nC48_0523, false )
    else
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'nC06', 10735, 5739, 270)
        call IssuePointOrder(bj_lastCreatedUnit, "move", GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()))
    endif
 call DestroyTrigger( Quest3[id] )
 set Quest3[id] = null
endfunction

private function Actions2 takes nothing returns nothing
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
 local string boy = "none.mdl"
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(GetOwningPlayer(GetTriggerUnit())) == MAP_CONTROL_USER then
        call DisableTrigger( Quest1[id] )
        call DestroyTrigger( Quest1[id] )
        set Quest1[id] = null
        call DestroyTrigger( Quest2[id] )
        set Quest2[id] = null
        call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0,"|cffffd700KEEPERS SON|r: My dad sent you? oh... I come here to play with my friends sometimes... I guess I stayed out too long. You look weird, Oh well, I better go" )
        set Quest3[id] = CreateTrigger()
            call TriggerRegisterEnterRectSimple( Quest3[id], gg_rct_QuestLightHouse )
            call TriggerAddAction( Quest3[id], function Actions3 )
        call TriggerSleepAction( 2.00 )
        call IssuePointOrderLoc( gg_unit_nvlk_0611, "move", GetRandomLocInRect(gg_rct_QuestLHouseSon) )
        call IssuePointOrderLoc( gg_unit_nvlk_0612, "move", GetRandomLocInRect(gg_rct_QuestLHouseSon) )
        call TriggerSleepAction( 10.00 )
        call DestroyEffect(FX1[id])
        if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
            set boy = "units\\critters\\VillagerKid1\\VillagerKid1.mdl"
        endif
        set FX2[id] = AddSpecialEffect(boy, 10818, 5357 )
    endif
endfunction

private function Actions1 takes nothing returns nothing
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(GetOwningPlayer(GetTriggerUnit())) == MAP_CONTROL_USER then
        if Quest2[id] == null then
            call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffffd700LIGHTHOUSE KEEPER|r: Please..... I don't know what you are, but find my boy and bring him back... I don't have much, but you can have my Armoured Car if you find him. Its not as fast as other cars, but it has Weaponry and formidable armour. I last saw my son to the southeast of Bob's Guns, near the cities walls." )
             set Quest2[id] = CreateTrigger()
                call TriggerRegisterEnterRectSimple( Quest2[id], gg_rct_QuestLHouseSon )
                call TriggerAddAction( Quest2[id], function Actions2 )
        else
            call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffffd700LIGHTHOUSE KEEPER|r: My son, I saw him just southeast of Bobs. Find him, please." )
        endif
        call DisableTrigger(GetTriggeringTrigger())
    endif
endfunction

//===========================================================================
public function Init takes nothing returns nothing
local integer i = 0
local string boy = "none.mdl"
    loop
    exitwhen i > 11
        if i != 3 and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
            if GetLocalPlayer() == Player(i) then
                set boy = "units\\critters\\VillagerKid1\\VillagerKid1.mdl"
            endif
            set Quest1[i] = CreateTrigger()
            set FX1[i] = AddSpecialEffect(boy, 1320, 4358 )
            call TriggerRegisterEnterRectSimple( Quest1[i], gg_rct_QuestLightHouse )
            call TriggerAddAction( Quest1[i], function Actions1 )
        endif
        set i = i + 1
    endloop
endfunction

endscope
 
Level 3
Joined
Apr 17, 2008
Messages
41
There's only one thing I can see that would give you the starting message twice. You're creating a new trigger with the same event and action for every player that's playing (including computers, but excluding Player 4). When one unit enters that region, all the triggers with that event are going to run.

You could just use one trigger and add a boolean array for each player:
JASS:
globals
    private boolean array IsStarted
    private boolean array KidIsSafe
    private boolean array IsFinished
endglobals

Just use as many as you need in order to mark the progress for each player. You can also use a hashtable for this.

Edit: One trigger for each part of the quest, unless you actually feel like putting all of that into one trigger.
Edit2: Idk if you intended to remove the leaks eventually, but you do leak a triggeraction each time you destroy a trigger and two locations every time Actions2 runs through its If-Then.
 
TriggerActions do leak, I recommend using conditions, which do not leak, and use timers instead of waits. Are you too lasy to do timers instead of waits? It is ALWAYS possible, it is just a matter of you have to learn how to make it happen. If you want to do a triggersleepaction, you need to create it in a new thread, which can be achieved via ExecuteFunc("FuncName") or, since you are using vJass, FuncName.execute().
 
It has to be in two functions. It is actually clean when you get used to the idea that functions are extremely useful features in programming.

JASS:
function two takes nothing returns nothing
    call ExecuteFunc("one")
endfunction
function one takes nothing returns nothing
    call two()
endfunction

Wrap your head around this one, it should spark some ideas.
 
Level 14
Joined
Jul 26, 2008
Messages
1,009
I still don't feel like I understand. I'm having problems.

Calling ExecuteFunc("name") doesn't cause the triggers to wait.
However, if I don't do it then the triggers freeze up and fail to execute past their wait.

Also, doing Timers leaves a lot of problems, like transfering variables easily through to the timer. (I have to create a struct or create globals? That's pretty hugely inconvienent.)

An example of two different Quest triggers. One where I Execute and one where i use timers.

JASS:
scope TynanQuest initializer Init

globals
    public trigger array Quest
endglobals

private function Actions4 takes nothing returns boolean
 local integer i = 0
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(GetOwningPlayer(GetTriggerUnit())) == MAP_CONTROL_USER then
        if not IsUnitType(Tynan, UNIT_TYPE_DEAD) then
            call UnitRemoveAbility( Tynan, 'Ashm' )
            call TriggerSleepAction( 2 )
            call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffff0000TYNAN|r: You have freed me... As a reward I shall not destroy you as I had been contemplating... Instead take my beast here.. He will serve you well, and here is a Blood Rite. Use it well.. At Last.. Freedom...Vengeance is at hand..." )
            call SetUnitOwner( Beast, GetOwningPlayer(GetTriggerUnit()), false )
            call UnitRemoveAbility( Beast, 'ARal')
            call UnitAddItemById( GetTriggerUnit(), 'IC76' )
            call Return_Data.create( GetTriggerUnit(), Beast )
            call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl", GetUnitX(Tynan), GetUnitY(Tynan)))
            call RemoveUnit( Tynan )
            loop
            exitwhen i > 4
                call DisableTrigger(Quest[i])
                call DestroyTrigger(Quest[i])
                set Quest[i] = null
                set i = i + 1
            endloop
        endif
    endif
 return false
endfunction

private function Actions3 takes nothing returns boolean
 local integer id = GetPlayerId(GetOwningPlayer(GetKillingUnit()))
    call CreateItem( 'IC62', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()) )
        set Quest[3] = CreateTrigger()
            call TriggerRegisterEnterRectSimple( Quest[3], gg_rct_ConfrontTynan )
            call TriggerAddCondition(Quest[3], function Actions4)
 return false
endfunction

private function Timer2 takes nothing returns nothing
    call SetUnitInvulnerable( Woman, false )
    call SetUnitOwner( Woman, Player(8), true )
    set Quest[2] = CreateTrigger()
        call TriggerRegisterUnitEvent(Quest[2], Woman, EVENT_UNIT_DEATH)
        call TriggerAddCondition(Quest[2], function Actions3)
    call DisableTrigger( Quest[0] )
    call DestroyTrigger( Quest[0] )
    set Quest[0] = null
    call ReleaseTimer(GetExpiredTimer())
endfunction

private function Actions2 takes nothing returns boolean
 local timer tim
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(Player(id)) == MAP_CONTROL_USER then
        set tim = NewTimer()
        call DisplayTextToPlayer( Player(id), 0, 0, "SELENA: What does a Vampire want with my key... Unless it can free the first Mortal Vampire... Listen to me spawn of Caine.. If you succeed in destroying me and taking this key, the being imprisoned beyond those walls will destroy you and drain you for your power.. He will then be unleashed upon this us all and man and mortal will all suffer. For that reason I must stop you." )
        call TimerStart(tim, 2.5, false, function Timer2)
    endif
 return false
endfunction

private function Actions1 takes nothing returns boolean
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(GetOwningPlayer(GetTriggerUnit())) == MAP_CONTROL_USER then
        if GetOwningPlayer(Tynan) == Player(PLAYER_NEUTRAL_PASSIVE) then
            if not(IsUnitType(Tynan, UNIT_TYPE_DEAD) or IsUnitType(Woman, UNIT_TYPE_DEAD)) then
                if RectContainsCoords(gg_rct_TynanTurnArea, GetUnitX(Tynan), GetUnitY(Tynan)) then
                    call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0, 0, "|cffff0000RASPING VOICE|r: Release me.. There is a being... On the northern beach.. She has created a key... She does not know its power... bring it here and open this door... GO.. NOW..." )
                    if Quest[1] == null then
                        set Quest[1] = CreateTrigger()
                            call TriggerRegisterEnterRectSimple( Quest[1], gg_rct_SelenaVampQuest )
                            call TriggerAddCondition(Quest[1], function Actions2 )
                    endif
                endif
            endif
        endif
    endif
 return false
endfunction

//===========================================================================
public function Init takes nothing returns nothing
local integer i = 0
    loop
    exitwhen i > 11
     set i = i + 1
    endloop
    set Quest[0] = CreateTrigger()
        call TriggerRegisterEnterRectSimple( Quest[0], gg_rct_TynanTurnArea )
        call TriggerAddCondition( Quest[0], function Actions1 )
    set Tynan = gg_unit_UC63_0634
    set Woman = gg_unit_HC67_0642
    set Beast = gg_unit_oC66_0635
    call UnitModifyMaxLife(Beast, 150)
    call UnitModifyMaxMana(Beast, 75)
    call UnitModifyDamage(Beast, 10)
    call UnitModifyArmor(Beast, 3)
    call SetUnitInvulnerable( Woman, true )
endfunction

endscope
JASS:
scope QueenQuest initializer Init

globals
    public trigger array Quest
    public trigger array QuestInfo
    private boolean array MetQueen
endglobals

private function Pause takes real dur returns nothing
    call TriggerSleepAction(2)
endfunction

private function Actions4 takes nothing returns boolean
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(Player(id)) == MAP_CONTROL_USER then
        if not(IsUnitType(QueenN, UNIT_TYPE_DEAD)) and RectContainsCoords(gg_rct_SpawnPalace1, GetUnitX(QueenN), GetUnitY(QueenN) ) then
            call DisplayTextToPlayer( Player(id), 0, 0, "|cffaca899CHARNIS|r: So... You've come for the ring and your revenge... I thought you would... Guards! Attack! Die Vampire filth!" )
            call DisableTrigger( Quest[3] )
            call DestroyTrigger( Quest[3] )
            set Quest[3] = null
            call TriggerSleepAction( 5.00 )
            call SetUnitOwner( gg_unit_EC53_0419, Player(8), false )
            call SetUnitOwner( gg_unit_hC54_0614, Player(8), false )
            call SetUnitOwner( gg_unit_hC54_0615, Player(8), false )
        endif
    endif
 return false
endfunction

private function Actions3 takes nothing returns boolean//Queen Dies function
 local integer id = GetPlayerId(GetOwningPlayer(GetKillingUnit()))
    if IsUnitType(GetKillingUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetKillingUnit(), UNIT_TYPE_HERO) and GetPlayerController(Player(id)) == MAP_CONTROL_USER then
        call CreateItem( 'IC09', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()) )
        call CreateItem( 'IC16', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()) )
        call DisplayTextToPlayer( Player(id), 0, 0, "You have done it! You have slain Charnis, the Queen of Prague! The lying bitch didn't even have the ring, but her Staff and Crown are yours.... Too bad the guards won't obey a Vampire, but hey, thats life.... err... undeath." )
        call DisableTrigger( Quest[2] )
        call DestroyTrigger( Quest[2] )
        set Quest[2] = null
    endif
 return false
endfunction

private function Actions2 takes nothing returns boolean
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
 local integer i = 0
 local real ang = GetRandomReal(0,2*bj_PI)
 local real x = GetUnitX(GetTriggerUnit())+GetRandomReal(300,500)*Cos(ang)
 local real y = GetUnitY(GetTriggerUnit())+GetRandomReal(300,500)*Sin(ang)
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(Player(id)) == MAP_CONTROL_USER then
        if GetOwningPlayer(QueenN) == Player(PLAYER_NEUTRAL_PASSIVE) and GetOwningPlayer(QueenS) == Player(PLAYER_NEUTRAL_PASSIVE) then
            if UnitHasItem(GetTriggerUnit(), GetItemOfTypeFromUnitBJ(GetTriggerUnit(), 'IC16')) then
                call RemoveItem( GetItemOfTypeFromUnitBJ(GetTriggerUnit(), 'IC16') )
                call DisplayTextToPlayer( Player(id), 0, 0, "|cffaca899CHARNIS|r: Excellent! The Crown! Now, for my end of the bargain.  Guards, sieze this Vampire! I will never deal with Vampires, if you want your ring, come and get it!" )
                call ExecuteFunc("Pause")
                debug call BJDebugMsg("Queen goes after Pause")
                call SetUnitAnimation( QueenN, "spell" )
                call SetUnitAnimation( QueenS, "spell" )
                call DisableTrigger( Quest[0] )
                call DestroyTrigger( Quest[0] )
                set Quest[0] = null
                call DisableTrigger( Quest[1] )
                call DestroyTrigger( Quest[1] )
                set Quest[1] = null

                if Quest[2] == null then //Queen Dies
                    set Quest[2] = CreateTrigger()
                        call TriggerRegisterUnitEvent( Quest[2], QueenN, EVENT_UNIT_DEATH )
                        call TriggerAddCondition( Quest[2], function Actions3 )
                endif

                if Quest[3] == null then //Queen Speech
                    set Quest[3] = CreateTrigger()
                        call TriggerRegisterEnterRectSimple( Quest[3], gg_rct_QuestQueenSpeech )
                        call TriggerAddCondition( Quest[3], function Actions4 )
                endif

                loop
                    call CreateUnit(Player(8), 'hfoo', x, y, ang)
                exitwhen i == 3
                    set ang = GetRandomReal(0,2*bj_PI)
                    set x = GetUnitX(GetTriggerUnit())+GetRandomReal(300,500)*Cos(ang)
                    set y = GetUnitY(GetTriggerUnit())+GetRandomReal(300,500)*Sin(ang)
                    set i = i + 1
                endloop

                call ExecuteFunc("Pause")
                call RemoveUnit( gg_unit_hC14_0367 )
                call RemoveUnit( QueenS )
                call RemoveUnit( gg_unit_hmpr_0190 )
                call RemoveUnit( gg_unit_hmpr_0293 )
                call RemoveUnit( gg_unit_hmpr_0191 )
                call SetUnitPosition( QueenN, 12383, 5395 )
                call SetUnitFacing( QueenN, 90 )
                call SetUnitInvulnerable( QueenN, false )
                call SetUnitPosition( gg_unit_hC54_0614, 12404, 6181 )
                call SetUnitPosition( gg_unit_hC54_0615, 12851, 6211 )

                call DisableTrigger( gg_trg_GeneralQueenArrive )
                call DisableTrigger( gg_trg_Charnis1 )
                call DisableTrigger( gg_trg_Charnis2 )
                call DisableTrigger( gg_trg_QueenGrandFinale )
                call DisableTrigger( gg_trg_InitialReward )
            endif
        endif
    endif
 return false
endfunction

//===========================================================================

private function Conditions1 takes nothing returns boolean
    call DisplayTextToPlayer( GetTriggerPlayer(), 0, 0, "The Vault is to the Southeast of the town centre, and is located between the two separated sections of the river fork. It is lightly guarded, but the Royal Crown has a guardian within the Vault..." )
 return false
endfunction

private function Conditions2 takes nothing returns boolean
    call DisplayTextToPlayer( GetTriggerPlayer(), 0, 0, "The Bishop is located in the Cathedral Grounds,  just to the south of the center of town. He has a light retinue of guards, but is a powerful magic wielder." )
 return false
endfunction

private function Conditions3 takes nothing returns boolean
    call DisplayTextToPlayer( GetTriggerPlayer(), 0, 0, "Queen Alexis is located in the Palace, which is at the very bottom of the map, dead center. She is guarded at all entrances to the palace, and has a retinue of Priests guarding her." )
 return false
endfunction

private function Conditions4 takes nothing returns boolean
    call DisplayTextToPlayer( GetTriggerPlayer(), 0, 0, "General Cassidy is located in the Central Barracks, where he is heavily guarded. The barracks is almost at the very center of the map. General Cassidy is a trained Paladin, and quite capable of defending himself." )
 return false
endfunction
//===========================================================================

private function Actions1 takes nothing returns boolean
 local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_UNDEAD) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) and GetPlayerController(Player(id)) == MAP_CONTROL_USER then
        if RectContainsCoords(gg_rct_QuestQueenReturn, GetUnitX(QueenN), GetUnitY(QueenN)) or RectContainsCoords(gg_rct_QuestQueenReturn2, GetUnitX(QueenS), GetUnitY(QueenS)) then
            if GetOwningPlayer(QueenN) == Player(PLAYER_NEUTRAL_PASSIVE) and GetOwningPlayer(QueenS) == Player(PLAYER_NEUTRAL_PASSIVE) and MetQueen[id] == false then
                call DisplayTextToPlayer( Player(id), 0, 0, "|cffaca899CHARNIS|r: Bow to the true Queen of this land.... Exiled to live with those few loyal, which you have slain. I will strike a bargain with you Vampire... My crown resides in the royal vault, and |c0000ff00three have they key - General Cassidy, Archbishop Aldric and my accursed half-sister Alexis.|r If you secure my crown, no guard will lay a finger on you, and you will recieve my sigil ring as proof. Now go, dog, and fetch me my crown!" )
                if Quest[1] == null then
                    set Quest[1] = CreateTrigger() //Return Crown
                        call TriggerRegisterEnterRectSimple( Quest[1], gg_rct_QuestQueen )
                        call TriggerRegisterEnterRectSimple( Quest[1], gg_rct_QuestQueen2 )
                        call TriggerAddCondition(Quest[1], function Actions2 )
                endif
                set MetQueen[id] = true
                call TriggerSleepAction( 25.00 )
                call DisplayTextToPlayer( Player(id), 0, 0, "Type any of the following for their location, and additional info. 
            |cffffcc00-general     -bishop     -alexis     -vault" )
                if QuestInfo[0] == null then
                    set QuestInfo[0] = CreateTrigger()
                    call TriggerAddCondition(QuestInfo[0], function Conditions1)
                    set QuestInfo[1] = CreateTrigger()
                    call TriggerAddCondition(QuestInfo[1], function Conditions2)
                    set QuestInfo[2] = CreateTrigger()
                    call TriggerAddCondition(QuestInfo[2], function Conditions3)
                    set QuestInfo[3] = CreateTrigger()
                    call TriggerAddCondition(QuestInfo[3], function Conditions4)
                endif
                call TriggerRegisterPlayerChatEvent( QuestInfo[0], Player(id), "-vault", true )
                call TriggerRegisterPlayerChatEvent( QuestInfo[1], Player(id), "-bishop", true )
                call TriggerRegisterPlayerChatEvent( QuestInfo[2], Player(id), "-alexis", true )
                call TriggerRegisterPlayerChatEvent( QuestInfo[3], Player(id), "-general", true )
            endif
        endif
    endif
 return false
endfunction

//===========================================================================
public function Init takes nothing returns nothing
set Quest[0] = CreateTrigger() //Enter Queen Area to Start Quest
    call TriggerRegisterEnterRectSimple( Quest[0], gg_rct_QuestQueen )
    call TriggerRegisterEnterRectSimple( Quest[0], gg_rct_QuestQueen2 )
    call TriggerAddCondition( Quest[0], function Actions1 )
    set QueenN = gg_unit_EC53_0419
    set QueenS = gg_unit_EC53_0422
endfunction

endscope
 
If you are going to use TriggerSleepAction (which is fine for decently long waits > 1 or 2 seconds), then you should use actions instead of conditions. Use actions when you need to use waits (such as triggersleepaction) because conditions go on the same thread instead of starting a new one, and waits cause it to freeze the function. :)

So, yeah, you'll have to revert back to actions. Sorry. :( Unless you want to use timers, but they are not too necessary when you have long enough waits.

... Otherwise you can use executefunc, but might as well use actions if you are going to use that.
 
Level 14
Joined
Jul 26, 2008
Messages
1,009
Ahhh thank you purge. That explains a lot. The triggers really started bugging when I switched them to conditions.

As of now the ExecuteFunc I'm using doesn't do a wait on the trigger. Perhaps it's because I have to divide the function between the two, one after the wait and one before the wait? I assume I can't just store a TriggerSleepAction in an ExecuteFunc.

As for timers, yea it seems like a real hassle to use them for waits. It'd be safer but at the same time it seems to require an unnecessary amount of work.
 
Make sure that the functions you are using after the wait go in the separate executefunc function. (that was confusing to right, and probably confusing to understand, so let me show an example)
JASS:
function Cond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then //just an example
        call ExecuteFunc("lala")
    endif
    return false
endfunction

function lala takes nothing returns nothing
    call TriggerSleepAction(5)
    //do your actions here
endfunction

Yeah, it looks a little weird, and may seem identical to timers in that you need to pass data, but it actually isn't. If you want to pass data, just have temporary globals, set data to them, and then retrieve them as locals before the wait. Ex:
JASS:
globals
    unit tempCaster
    unit tempTarget
endglobals

function Cond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then //just an example
        set tempCaster = GetTriggerUnit()
        set tempTarget = GetSpellTargetUnit()
        call ExecuteFunc("lala")
    endif
    return false
endfunction

function lala takes nothing returns nothing
    local unit cast = tempCaster
    local unit targ = tempTarget
    call TriggerSleepAction(5)
    //do your actions here
    
    //...
    set cast = null
    set targ = null
endfunction

That way, it can stay MUI. Although, I am not sure if it is necessary whether or not to save the trigger data, but I think it is necessary since it is starting a new thread. I am too lazy to check. :p
 
GetTriggerUnit() has the same response from ExecuteFunc as it would from the trigger which executed the new thread. It's easy enough to do:

JASS:
function Cond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then //just an example
        call ExecuteFunc("lala")
    endif
    return false
endfunction

function lala takes nothing returns nothing
    local unit cast = GetTriggerUnit()
    local unit targ = GetSpellTargetUnit()
    call TriggerSleepAction(5)
    //do your actions here
    
    //...
    set cast = null
    set targ = null
endfunction
 
It's a hidden thing called threading. Actions (execute) create a new thread, while Conditions (evaluate) retain the same thread. Because of the nature of the "evaulate" process, a wait crashes the thread.

A simple "call" keeps things in one thread. Keep in mind that call GetTriggerUnit() is the same principle as set u = GetTriggerUnit(), and that you will find the "call" keyword used less and less unless it's for natives.
 
Status
Not open for further replies.
Top