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

[vJASS] What's a smart way of dealing with this without using waits?

Status
Not open for further replies.
Level 19
Joined
Oct 12, 2007
Messages
1,821
Hey there.

Today I worked on a system, and it's nearly done apart from one feature.
I quickly try to explain how the system should work:

In a GUI trigger I queue a few Camera, Transmission and other things. Then after queuing them I start the system that will run all the queued actions for the player resulting in a transmission with camera movement. If the transmission is done, or if the player presses ESC during the transmission it should continue with the remaining commands in the GUI trigger.

So what the GUI should do in short:
1) Queue actions
2) Start the cinematic
3) Wait till it's over or ESC is pressed
4) continue with some other actions

I noticed that I can only 'pause' the GUI trigger by using waits. (Or is there a better solution) That's why I created a small function that basically loops a few waits after eachother to keep checking if in the meanwhile ESC has been pressed or not.

Here are my triggers:

JASS:
library QuestInteraction initializer init

globals

    ///Overall Globals///
    boolean array QI_InProgress[8]
    boolean array QI_EscPressed[8]
    integer array QI_id[8]
    string array QI_Type[8][99]
    real array QI_Duration[8]
    real array QI_Timing[8][99]

    ///Transmission Globals///
    unit array QI_Speaker[8][99]
    string array QI_SpeakerName[8][99]
    string array QI_Text[8][99]
    real array QI_TextDur[8][99]
    ///Camera Globals///
    camerasetup array QI_Cam[8][99]
    real array QI_CamMoveTime[8][99]
    real array QI_CamDur[8][99]
    ///Unit Order Globals///
    unit array QI_OrderUnit[8][99]
    widget array QI_OrderTarget[8][99]
    real array QI_OrderX[8][99]
    real array QI_OrderY[8][99]
    string array QI_OrderType[8][99]

endglobals

private struct Data
player p
integer id
real time


static integer array Ar
static integer Total = 0
static group g = CreateGroup()
static timer Time = CreateTimer()
static force Force = CreateForce()

    static method create takes player p returns Data
        local Data Dat = Data.allocate()
        local integer i = 0
        
        set Dat.p = p
        set Dat.id = GetPlayerId(p)
        set Dat.time = 0.
        
        call ForceAddPlayer(Dat.Force, Dat.p)
        
        call ShowInterfaceForceOff(Dat.Force, QI_Duration[Dat.id])
        call CinematicModeExBJ(true, Dat.Force, 0.1)
        set QI_InProgress[Dat.id] = true
        set QI_EscPressed[Dat.id] = false
        call HideBar(p)
        
        call PauseUnit(PlayerHero[Dat.id], true)
        loop
            exitwhen i > 8
            if GetPlayerAlliance(p, Player(i), ALLIANCE_PASSIVE) == true then
                call SetPlayerAlliance(p, Player(i), ALLIANCE_SHARED_VISION, false)
                call SetPlayerAlliance(Player(i), p, ALLIANCE_SHARED_VISION, false)
            endif
            set i = i + 1
        endloop
        
        if Dat.Total == 0 then
            call TimerStart(Dat.Time,.05,true,function Data.Loop)
        endif
        
        set Dat.Ar[Dat.Total] = Dat
        set Dat.Total = Dat.Total + 1
        
        return Dat
    endmethod

    static method Loop takes nothing returns nothing
        local Data Dat
        local integer i = 0
        local integer id
        
        loop
            exitwhen i >= Dat.Total
            set Dat = Dat.Ar[i]
            
            set id = 0
            loop
                exitwhen id > QI_id[Dat.id]
                if QI_Timing[Dat.id][id] == Dat.time then
                    if QI_Type[Dat.id][id] == "Trans" then
                        call TransmissionFromUnitWithNameBJ(Dat.Force, QI_Speaker[Dat.id][id], QI_SpeakerName[Dat.id][id], null, QI_Text[Dat.id][id], bj_TIMETYPE_SET, QI_TextDur[Dat.id][id], false)
                        set QI_Speaker[Dat.id][id] = null
                        set QI_SpeakerName[Dat.id][id] = ""
                        set QI_Text[Dat.id][id] = ""
                        set QI_TextDur[Dat.id][id] = 0.
                    elseif QI_Type[Dat.id][id] == "Camera" then
                        call CameraSetupApplyForPlayer(true, QI_Cam[Dat.id][id], Dat.p, QI_CamMoveTime[Dat.id][id])
                        set QI_Cam[Dat.id][id] = null
                        set QI_CamMoveTime[Dat.id][id] = 0.
                    elseif QI_Type[Dat.id][id] == "Order" and QI_OrderTarget[Dat.id][id] == null and QI_OrderX[Dat.id][id] == 0. and QI_OrderY[Dat.id][id] == 0. then
                        call IssueImmediateOrder(QI_OrderUnit[Dat.id][id], QI_OrderType[Dat.id][id])
                        set QI_OrderUnit[Dat.id][id] = null
                        set QI_OrderType[Dat.id][id] = ""
                    elseif QI_Type[Dat.id][id] == "Order" and QI_OrderTarget[Dat.id][id] == null then
                        call IssuePointOrder(QI_OrderUnit[Dat.id][id], QI_OrderType[Dat.id][id], QI_OrderX[Dat.id][id], QI_OrderY[Dat.id][id])
                        set QI_OrderUnit[Dat.id][id] = null
                        set QI_OrderType[Dat.id][id] = ""
                        set QI_OrderX[Dat.id][id] = 0.
                        set QI_OrderY[Dat.id][id] = 0.
                    elseif QI_Type[Dat.id][id] == "Order" then
                        call IssueTargetOrder(QI_OrderUnit[Dat.id][id], QI_OrderType[Dat.id][id], QI_OrderTarget[Dat.id][id])
                        set QI_OrderUnit[Dat.id][id] = null
                        set QI_OrderType[Dat.id][id] = ""
                        set QI_OrderTarget[Dat.id][id] = null
                    endif
                endif
                set id = id + 1
            endloop
            
            set Dat.time = Dat.time + .05
            
            
            if Dat.time >= QI_Duration[Dat.id] or QI_EscPressed[Dat.id] == true then
            
                set QI_id[Dat.id] = 0
                
                call ShowInterfaceForceOn(Dat.Force, 1.)
                call CinematicModeExBJ(false, Dat.Force, 0.1)
                set QI_Duration[Dat.id] = 0.
                call LockCameraUnit(Dat.p,PlayerHero[Dat.id])
                call ShowBar(Dat.p)
                set id = 0
                loop
                    exitwhen id > 8
                    if GetPlayerAlliance(Dat.p, Player(id), ALLIANCE_PASSIVE) == true then
                        call SetPlayerAlliance(Dat.p, Player(id), ALLIANCE_SHARED_VISION, true)
                        call SetPlayerAlliance(Player(id), Dat.p, ALLIANCE_SHARED_VISION, true)
                    endif
                    set id = id + 1
                endloop
                call ForceRemovePlayer(Dat.Force, Dat.p)
                
                call PauseUnit(PlayerHero[Dat.id], false)
                set QI_InProgress[Dat.id] = false
                set QI_EscPressed[Dat.id] = false
                
                ///end///
                set Dat.Total = Dat.Total - 1
                set Dat.Ar[i] = Dat.Ar[Dat.Total]
                set i = i - 1
                call Dat.destroy()
            endif
            
            set i = i + 1
        endloop
    endmethod
    
    method onDestroy takes nothing returns nothing
        set .p = null
    endmethod
    
endstruct

function AddUnitOrder takes player p, unit u, string order, widget t, real x, real y, real timing returns nothing
    local integer id = GetPlayerId(p)
    
    set QI_OrderUnit[id][QI_id[id]] = u
    set QI_OrderType[id][QI_id[id]] = order
    set QI_OrderX[id][QI_id[id]] = x
    set QI_OrderY[id][QI_id[id]] = y
    set QI_OrderTarget[id][QI_id[id]] = t
    set QI_Timing[id][QI_id[id]] = timing

    set QI_Type[id][QI_id[id]] = "Order"
    set QI_id[id] = QI_id[id] + 1
endfunction

function AddTransmission takes player p, unit u, string name, string text, real duration, real timing returns nothing
    local integer id = GetPlayerId(p)
    
    set QI_Speaker[id][QI_id[id]] = u
    set QI_SpeakerName[id][QI_id[id]] = name
    set QI_Text[id][QI_id[id]] = text
    set QI_TextDur[id][QI_id[id]] = duration
    set QI_Timing[id][QI_id[id]] = timing
    
    set QI_Type[id][QI_id[id]] = "Trans"
    set QI_id[id] = QI_id[id] + 1
endfunction

function AddCamera takes player p, camerasetup cam, real movetime, real duration, real timing returns nothing
    local integer id = GetPlayerId(p)
    
    set QI_Cam[id][QI_id[id]] = cam
    set QI_CamDur[id][QI_id[id]] = duration
    set QI_CamMoveTime[id][QI_id[id]] = movetime
    set QI_Timing[id][QI_id[id]] = timing

    set QI_Type[id][QI_id[id]] = "Camera"
    set QI_Duration[id] = QI_Duration[id] + duration
    set QI_id[id] = QI_id[id] + 1
endfunction

function AddAdvancedWait takes player p, real time returns nothing
    local real timeleft = time
    local integer id = GetPlayerId(p)
    
    loop
        exitwhen timeleft <= 0.
        if QI_EscPressed[id] == true then
            set timeleft = 0.
        else
            set timeleft = timeleft - 0.50
            call TriggerSleepAction(0.50)
        endif
    endloop
endfunction

/// This makes the entire interaction event roll ///        
function QIStart takes player p returns nothing
    local Data Dat

    call UnlockCamera(p)
    set Dat = Data.create(p)
endfunction

private function ESC takes nothing returns boolean
    local integer id = GetPlayerId(GetTriggerPlayer())
    
    if QI_InProgress[id] == true then
        set QI_EscPressed[id] = true
    endif
    
    return false
endfunction

private function init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local integer index = 0
    
    loop
        exitwhen index >= bj_MAX_PLAYER_SLOTS
        call TriggerRegisterPlayerEvent(trig, Player(index), EVENT_PLAYER_END_CINEMATIC)
        set index = index + 1
    endloop
    
    call TriggerAddCondition(trig, Condition(function ESC))
    
    set trig = null
endfunction
endlibrary

  • Anna 5 Fleshy Constructs
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Issued order) Equal to (Order(attack))
      • ((Triggering unit) is A Hero) Equal to True
      • (Owner of (Triggering unit)) Not equal to Player 10 (Light Blue)
      • ((Triggering unit) belongs to an ally of Player 10 (Light Blue)) Equal to True
      • (Target unit of issued order) Equal to Anna Skysong 0365 <gen>
    • Actions
      • Custom script: local player p = GetOwningPlayer(GetTriggerUnit())
      • Custom script: local unit u = GetTriggerUnit()
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is in (Units within 200.00 of (Position of (Target unit of issued order)))) Equal to False
        • Then - Actions
          • Unit - Order (Triggering unit) to Move To (Position of (Target unit of issued order))
          • Skip remaining actions
        • Else - Actions
      • Unit - Order (Triggering unit) to Stop
      • Custom script: call SetUnitFacingTimed(GetTriggerUnit(), ABPXY(GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), GetUnitX(GetOrderTargetUnit()), GetUnitY(GetOrderTargetUnit())), 0.5)
      • Custom script: call SetUnitFacingTimed(GetTriggerUnit(), ABPXY(GetUnitX(GetOrderTargetUnit()), GetUnitY(GetOrderTargetUnit()), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit())), 0.5)
      • Custom script: set udg_QuestGiver[GetPlayerId(p)] = GetOrderTargetUnit()
      • -------- ------------------- --------
      • -------- Start Quest! --------
      • -------- ------------------- --------
      • -------- if GetQuestState(u,5)==0 and IsQuestReqComplete(u,7,2) == true and udg_MissionStatus[GetPlayerId(p)] == 0 then --------
      • Custom script: if GetQuestState(u,5)==0 and udg_MissionStatus[GetPlayerId(p)] == 0 then
      • -------- Transmission Queue --------
      • Set TempString = Welcome back friend.
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 2.00, 0.00)
      • Set TempString = As of late, a necromancer has moved in on us toward the east. We have no clue of his intentions or whether he serves the Defilers; but we do know that he poses a great threat.
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 11.00, 2.00)
      • Set TempString = Captain Harius isn't even doing anything against it which makes me sick! Look at the amount of Skeletal Beasts crawling around in this area! It has to stop!
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 8.00, 13.00)
      • Set TempString = However... The necromancer's latest works, dubbed as Rotten Horrors, are beastly masses of flesh and steel. They are even more dangerous then the Skeletal Beasts.
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 9.00, 21.00)
      • Set TempString = In order to keep this place secure, I need you to slaughter 7 of those Rotten Horrors for me.|nStrike quickly my friend!
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 5.00, 30.00)
      • -------- Camera Queue --------
      • Custom script: call AddCamera(p, gg_cam_AnnaSkysong, 1., 3., 0.)
      • Custom script: call AddCamera(p, gg_cam_SkeletalBeast, 3., 5., 3.)
      • Custom script: call AddCamera(p, gg_cam_Scorchfield_Camp, 3., 5., 8.)
      • Custom script: call AddCamera(p, gg_cam_Scorchfield_Camp2, 3., 5., 13.)
      • Custom script: call AddCamera(p, gg_cam_RottenHorror, 8., 10., 18.)
      • Custom script: call AddCamera(p, gg_cam_SkeletalBeast, 3., 4., 28.)
      • Custom script: call AddCamera(p, gg_cam_MayaOathCam, 2., 3., 32.)
      • -------- EndofQueue --------
      • Custom script: call QIStart(p)
      • -------- ------------------- --------
      • -------- After the Quest Interaction --------
      • -------- ------------------- --------
      • Custom script: call AddAdvancedWait(p, 35.)
      • Custom script: call StartQuest(u, 5)
      • Custom script: call CreateQuestEffect(Player(GetPlayerId(p)), 15)
      • -------- ------------------- --------
      • -------- Quest Done? --------
      • -------- ------------------- --------
      • Custom script: elseif GetQuestState(u,5) ==2 then
      • -------- Transmission Queue --------
      • Set TempString = Thanks again.
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 2.00, 0.00)
      • Set TempString = Today you've proven Gryphonwing a great favor. Take this as your reward.
      • Set TempUnit = Anna Skysong 0365 <gen>
      • Custom script: call AddTransmission(p, udg_TempUnit, "Anna Skysong", udg_TempString, 4.00, 2.00)
      • -------- Camera Queue --------
      • Custom script: call AddCamera(p, gg_cam_MayaOathCam, 2., 6., 0.)
      • -------- EndofQueue --------
      • Custom script: call QIStart(p)
      • -------- ------------------- --------
      • -------- After the Quest Interaction --------
      • -------- ------------------- --------
      • Custom script: call AddAdvancedWait(p, 6.)
      • Custom script: call CompleteReq(u, 5, 2)
      • Custom script: call FinishQuest(u, 5)
      • Custom script: if GetQuestState(u,16)==0 and IsQuestReqComplete(u,15,2) == true and IsQuestReqComplete(u,5,2) == true then
      • Custom script: call CreateQuestEffect(Player(GetPlayerId(p)), 16)
      • Custom script: endif
      • -------- Rewards! --------
      • Custom script: call CreateXPReward(u, 167)
      • Custom script: call CreateReward(u, 180., 'I003', 'I00L', 'I026', 0, 0, 0)
      • Custom script: endif
      • -------- ------------------ --------
      • -------- UNPAUSE --------
      • -------- ------------------ --------
      • Custom script: set p = null
      • Custom script: set u = null
Currently the wait is taking too long and when I press ESC my cinematic immediatelly stops (so that's good) but for some reason the waits still keep running because the functions that are supposed to come after the wait (in the GUI trigger) are still taking some time to trigger.
So the waits are very inaccurate.

There might be more (minor) flaws with the way I made the system. But you have to know that I'm not a very experienced coder or anything. I just want it to work and be leakless. I do know there's (quite some) red text, but for now I want to keep that here because I want to make the system perfect some other time. For now I just want it to work the way I want and I don't really care much about the beauty/speed flaws.

So is there anyone that has an idea how to get what I want?
 
Last edited:
Level 19
Joined
Oct 12, 2007
Messages
1,821
I tried that, but for some reason it didn't work.
I used something like TriggerExecute(<name of the GUI trigger>) but that didn't work.
Or could you give me a small basic example of what you mean?
 
Level 14
Joined
Nov 18, 2007
Messages
816
JASS:
function Quest_1_Start_Callback takes nothing returns nothing
    // whatever
endfunction

function Quest_1_Start takes nothing returns nothing
    // set up the cinematic
    StartCinematic(blah, Quest_1_Start_Callback)
    // something else
endfunction

function interface CinematicCallback takes nothing returns nothing

struct Cinematic
    // ...
    CinematicCallback callbackFunc
    // ...
    method run takes nothing returns nothing
        // play the cinematic
        callbackFunc.execute() // start a new thread
    endmethod
endstruct

function StartCinematic takes blah, CinematicCallback func returns nothing
    someCinematic.callbackFunc=func
    someCinematic.run.execute() // start a new thread
endfunction
 
Status
Not open for further replies.
Top