Difference between revisions of "HPL3/Scripting/Scripting Guide/Sequences"

From Frictional Wiki
Jump to navigation Jump to search
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{wip}}
 
 
{{Hpl3ScriptingGuideMenuBasic}}
 
{{Hpl3ScriptingGuideMenuBasic}}
 
{{shortPageTitle}}
 
{{shortPageTitle}}
 
+
{| style="border:0px;" cellspacing="0"
 +
|- valign="top"
 +
| style="padding-right:0.2em" |
 
Many of the events that happen inside map script files are triggered sequences. For example: A sound plays, then the player's FoV changes, then a light starts flashing, etc.
 
Many of the events that happen inside map script files are triggered sequences. For example: A sound plays, then the player's FoV changes, then a light starts flashing, etc.
  
Line 9: Line 10:
 
They are very useful when we need to handle a big amount of timers that should occur one after another - or in other words - a sequence.
 
They are very useful when we need to handle a big amount of timers that should occur one after another - or in other words - a sequence.
  
For each sequence you need a map property to store the state - a cSequenceStatesData property e.g.
+
== Workflow ==
 +
For each sequence you need a map property to store the state - a cSequenceStatesData property:
  
 
<pre>cSequenceStatesData mSequenceAlert;</pre>
 
<pre>cSequenceStatesData mSequenceAlert;</pre>
  
Then you create a sequence function. This will be repeatedly called until the whole sequence is over. It looks something like this:
+
Then you create a sequence function. This will be repeatedly called until the whole sequence is over. It looks something like this:<syntaxhighlight lang="c++">
 
+
cSequenceStatesData mSequenceAlert;
*shows sequence example*
+
void Sequence_Alert(const tString& in asName)
 +
{
 +
    Sequence_Begin("Sequence_Alert", mSequenceAlert);
 +
   
 +
    if(Sequence_DoStepAndWait(1.0f))  // Do this step and then wait for 1 second
 +
    {
 +
        MakeALoudNoise();
 +
    }
 +
    else if (Sequence_DoStepAndWait(2.5f)) // Do this and then wait for 2.5 seconds
 +
    {
 +
        FlashABrightLight();
 +
    }
 +
    else if (Sequence_DoStepAndPause()) // Do this and then pause until told otherwise
 +
    {
 +
        SaySomethingAndCallBack("OnSayingSomethingComplete");
 +
    }
 +
    else if (Sequence_DoStepAndWait(10.0f)) // Do this and then wait for 10s
 +
    {
 +
        CrushPlayerLikeAnAnt();
 +
    }
 +
    else if (Sequence_DoStepAndContinue()) // Do this and go on to the next step (in this case there isn't one)
 +
    {
 +
        ApologiseToPlayer();
 +
    }
 +
   
 +
    Sequence_End();
 +
}
  
 +
void OnSayingSomethingComplete()
 +
{
 +
    // Saying something is now complete - poke the sequence to continue processing
 +
    SequenceStates_Resume("Sequence_Alert");
 +
}
 +
</syntaxhighlight>
 +
| style="width:0.1%" |
 +
|}
 
As you can see, <code>Sequence_DoStepAndPause()</code> in there actually pauses the whole sequence until some external event - in this case the callback from the voice playing code - calls <code>SequenceStates_Resume()</code> and asks it to continue.
 
As you can see, <code>Sequence_DoStepAndPause()</code> in there actually pauses the whole sequence until some external event - in this case the callback from the voice playing code - calls <code>SequenceStates_Resume()</code> and asks it to continue.
  
To start the sequence, you just call the sequence function once with an empty argument when you want it to trigger:
+
To start the sequence, you just call the sequence function once with an empty argument when you want it to trigger:<syntaxhighlight lang="c++">
 
 
 
Sequence_Alert("");
 
Sequence_Alert("");
 
+
</syntaxhighlight>No need to call it every frame or anything! Once started, timers will automatically make sure that the sequence steps get followed when they need to be.
No need to call it every frame or anything! Once started, timers will automatically make sure that the sequence steps get followed when they need to be.
 
  
 
{{tip|Since sequences are totally independent of each other, you could run multiple sequences in parallel.}}
 
{{tip|Since sequences are totally independent of each other, you could run multiple sequences in parallel.}}
  
== See Also ==
+
==See Also==
* [[HPL3/Scripting/Sequences_Helper|Sequences Helper]]
 
  
 +
*[[HPL3/SOMA/Scripting/Sequences Helper|Sequences Helper]] - SOMA
 +
*[[HPL3/Amnesia: Rebirth/Scripting/Sequences Helper|Sequences Helper]] - Amnesia: Rebirth
  
{{NavBar|HPL3/Scripting/Timers|Timers|HPL3/Scripting/HPL3 Scripting Guide|HPL3 Scripting Guide|HPL3/Scripting/Local and Global Variables|Local and Global Variables}}
+
{{NavBar|HPL3/Scripting/Scripting_Guide/Timers|Timers|HPL3/Scripting/HPL3 Scripting Guide|HPL3 Scripting Guide|HPL3/Scripting/Scripting_Guide/Local and Global Variables|Local and Global Variables}}
  
 
[[Category:HPL3 Scripting]]
 
[[Category:HPL3 Scripting]]
 
[[Category:English]]
 
[[Category:English]]

Latest revision as of 12:23, 14 August 2020

Many of the events that happen inside map script files are triggered sequences. For example: A sound plays, then the player's FoV changes, then a light starts flashing, etc.

We control all of those through a set of wrappers we call Sequences, which hide a bunch of timers away and make things easier to read.

They are very useful when we need to handle a big amount of timers that should occur one after another - or in other words - a sequence.

Workflow

For each sequence you need a map property to store the state - a cSequenceStatesData property:

cSequenceStatesData mSequenceAlert;
Then you create a sequence function. This will be repeatedly called until the whole sequence is over. It looks something like this:
cSequenceStatesData mSequenceAlert;
void Sequence_Alert(const tString& in asName)
{
    Sequence_Begin("Sequence_Alert", mSequenceAlert);
    
    if(Sequence_DoStepAndWait(1.0f))  // Do this step and then wait for 1 second
    {
        MakeALoudNoise();
    }
    else if (Sequence_DoStepAndWait(2.5f)) // Do this and then wait for 2.5 seconds
    {
        FlashABrightLight();
    }
    else if (Sequence_DoStepAndPause()) // Do this and then pause until told otherwise
    {
        SaySomethingAndCallBack("OnSayingSomethingComplete");
    }
    else if (Sequence_DoStepAndWait(10.0f)) // Do this and then wait for 10s
    {
        CrushPlayerLikeAnAnt();
    }
    else if (Sequence_DoStepAndContinue()) // Do this and go on to the next step (in this case there isn't one)
    {
        ApologiseToPlayer();
    }
    
    Sequence_End();
}

void OnSayingSomethingComplete()
{
    // Saying something is now complete - poke the sequence to continue processing
    SequenceStates_Resume("Sequence_Alert");
}

As you can see, Sequence_DoStepAndPause() in there actually pauses the whole sequence until some external event - in this case the callback from the voice playing code - calls SequenceStates_Resume() and asks it to continue.

To start the sequence, you just call the sequence function once with an empty argument when you want it to trigger:

Sequence_Alert("");

No need to call it every frame or anything! Once started, timers will automatically make sure that the sequence steps get followed when they need to be.

Icon tip.png Tip: Since sequences are totally independent of each other, you could run multiple sequences in parallel.

See Also


Timers