Scenario Function Reference

Overview

Train Simulator features scripting functionality for scenario events and conditions. This can be used to play an animation or trigger a camera change when an instruction or trigger is completed.

Events and Conditions

Events are triggered by the success or failure of an Instruction or by the completion of a Trigger and can be added in the timetable view editor to the fields labelled 'Trigger Event', 'Trigger Event Success' and 'Trigger Event Failure'. Events can also be triggered by a script call to the function TriggerDeferredEvent. Deferred events are just events that are deferred to trigger after a fixed interval and are the mechanism for doing all timing as they are saved with a game save.

Conditions are tests for additional requirements on the player and are tested when an instruction would otherwise succeed. E.g. for a 'Go Via' instruction the condition would be begin being tested as the train enters the marker and the condition would cease to be tested once the train leaves again. Conditions may be added to an instruction in the 'Success Condition' field. Conditions may also be tested by a call to the script function BeginConditonCheckChecked conditions are a way of testing that a condition is maintained over a period. E.g. keeping the steam
pressure above a certain value. Once a condition has completed its value is saved and any further checks will return this saved value.

Scenario Script

To give a scenario a script a ScenarioScript.lua must be placed in the root of the scenario, this should define two functions.

function OnEvent ( event )

This is the event handler function it handles any event calls from the scenario system. It should return TRUE(1) if the event is handled or FALSE(0) if the event is unknown, event is the name of the event as defined in the instruction, trigger or TriggerDeferredEvent call.

function TestCondition ( condition )

This is the condition checker function, it is used to test whether the player has met additional conditions for an instruction. It should return one of CONDITION_NOT_YET_MET(0), CONDITION_SUCCEEDED(1) or CONDITION_FAILED(2), condition is the name of the condition as defined in the instruction or BeginConditonCheck call.

Scenario scripts have a slightly different calling convention to other scripts in the game. Rather than use Callscenario scripts use SysCall

SysCall has access to a number of global functions as well as to the normal script functions of any named objects. SysCall uses the same colon notation to describe the object or global module for which the function call is required. E.g.:

SysCall ( "ScenarioManager:ShowMessage", "Title", "Message" )
speed = SysCall ( "PlayerEngine:GetSpeed" )

A second colon can be used to get a child object, e.g.:

SysCall ( "PlayerEngine:Main Smoke Stack:GetEmitRate" )

Any object placed in a scenario can be named from the properties flyout in the 'Object Name' field. PlayerEngine is a special value and always pertains to the player's engine, any numbered rail vehicle can also be used.

Important Note: Since scripts are not persisted by a save the scenario script should be stateless. The state can be affected by the use of Checked Conditions and Deferred Events which are persisted by a save.

Function Reference

The list of functions available, defined by module.

ScenarioManager

The core scenario scripting module.

TriggerScenarioFailure

Syntax: TriggerScenarioFailure ( message )
Function: Triggers the failure of the scenario
Arguments: message The message to show indicating why the scenario failed
Return: N/A

TriggerScenarioComplete

Syntax: TriggerScenarioComplete ( message )
Function: Triggers the successful completion of the scenario
Arguments: message The message to show indicating why the scenario succeeded
Return: N/A

TriggerDeferredEvent

Syntax: TriggerDeferredEvent ( event, time )
Function: Triggers a deferred event
Arguments: event The name of the event

time The time in seconds until the event should trigger
Return: false if the event was already scheduled
Note: Only one event per update may be triggered, two events with the same expiry time will be triggered in successive frames.

CancelDeferredEvent

Syntax: CancelDeferredEvent ( event )
Function: Cancels a deferred event
Arguments: event The name of the event
Return: false if the event was no longer scheduled

BeginConditionCheck

Syntax: BeginConditionCheck ( condition )
Function: Begins testing of a condition
Arguments: condition The name of the condition
Return: false if the condition was already scheduled
Note: As soon as the condition is completed as either CONDITION_SUCCEEDED(1) or CONDITION_FAILED(2), the condition will cease to be tested. If the condition was already complete at hte time of the call, no CheckCondition will be generated.

EndConditionCheck

Syntax: EndConditionCheck ( condition )
Function: Removes a condition from checking per frame
Arguments: condition The name of the condition
Return: false if the condition was no longer scheduled
Note: Cannot be called from within TestCondition

GetConditionStatus

Syntax: GetConditionStatus ( condition )
Function: Get the status of a script condition
Arguments: condition The name of the condition
Return: CONDITION_NOT_YET_MET(0), CONDITION_SUCCEEDED(1) or CONDITION_FAILED(2)
Note: The call only tests the saved status of a condition, it does not generate a call to CheckCondition

ShowMessage

Syntax: ShowMessage ( title, message, type )
Function: Shows a dialogue box with a message
Arguments: title The title for the message box

message The text for the message

type The type of message box INFO(0) or ALERT(1)
Return: N/A
Note: If title or message are in UUID format, then they are used as keys into the language table

ShowInfoMessageExt

Syntax: ShowInfoMessageExt ( title, message, time, pos, size, pause )
Function: Shows an info dialogue box with a message and extended attributes
Arguments: title The title for the message box

message The text for the message

time The time to show the message, 0.0 for indefinite

pos The position of the message box (MSG_TOP(1), MSG_VCENTRE(2), MSG_BOTTOM(4), MSG_LEFT(8), MSG_CENTRE(16), MSG_RIGHT(32))

size The size of the message box (MSG_SMALL(0), MSG_REG(1), MSG_LRG(2))

pause If true pause the game while the message is shown
Return: N/A
Note: If title or message are in UUID format, then they are used as keys into the language table

ShowAlertMessageExt

Syntax: ShowAlertMessageExt ( title, message, time, event )
Function: Shows an info dialogue box with a message and extended attributes
Arguments: title The title for the message box

message The text for the message

time The time to show the message, 0.0 for indefinite

event Event name triggered on click of message
Return: N/A
Note: If title or message are in UUID format, then they are used as keys into the language table

IsAtDestination

Syntax: IsAtDestination ( service, dest )
Function: Triggers a deferred event
Arguments: service The name of the event

dest The time in seconds until the event should trigger
Return: false if the event was already scheduled
Note: Only one event per update may be triggered, two events with the same expiry time will be triggered in successive frames.

GetScenarioTime

Syntax: GetScenarioTime ()
Function: Gets the time since the scenario start in seconds
Arguments: N/A
Return: The time since the scenario start in seconds

GetTimeOfDay

Syntax: GetTimeOfDay ()
Function: Gets the time since midnight in seconds
Arguments: N/A
Return: The time since midnight in seconds

LockControls

Syntax: LockControls ()
Function: Locks out controls and keyboard
Arguments: N/A
Return: N/A

UnlockControls

Syntax: UnlockControls ()
Function: Unlocks controls and keyboard
Arguments: N/A
Return: N/A

GetSeason

Syntax: GetSeason ()
Function: Gets the season
Arguments: N/A
Return: SEASON_SPRING = 0, SEASON_SUMMER = 1, SEASON_AUTUMN = 2, SEASON_WINTER = 3

WeatherController

The weather control module.

GetCurrentPrecipitationType

Syntax: GetCurrentPrecipitationType ()
Function: Gets the current type of precipitation
Arguments: N/A
Return: 0 = rain, 1 = sleet, 2 = hail, 3 = snow

GetPrecipitationDensity

Syntax: GetPrecipitationDensity ()
Function: Gets the density of the precipitation
Arguments: N/A
Return: A value between 0 and 1 for the density of precipitation

GetPrecipitationSpeed

Syntax: GetPrecipitationSpeed ()
Function: Gets the speed of the precipitation
Arguments: N/A
Return: The vertical fall speed of precipitation in metres per second

CameraManager

The camera control module.

ActivateCamera

Syntax: ActivateCamera ( name, time )
Function: Switch to a named camera
Arguments: name The name of the camera

time The time in seconds before reverting back to previous camera. Use 0 for no revert
Return: N/A
Note: The camera can be any of hte standard cameras or a user-defined camera.

CabCamera - the cab interior camera (as assigned to Key 1)
ExternalCamera - the exterior train tracking camera (as assigned to Key 2)
HeadOutCamera - the head out camera (as assigned to Shift + Key 2)
TrackSideCamrea - the trackside camera (as assigned to Key 4)
CarriageCamera - the carriage interior camera (as assigned to Key 5)
CouplingCamera - the coupling camera (as assigned to Key 6)
YardCamera - the top-down camera view (as assigned to Key 7)
FreeCamera - the free camera (as mapped to Key 8)

LookAt

Syntax: LookAt ( name )
Function: Have the camera look at an objection
Arguments: name The name of the object to look at
Return: True if the named object was found
Note: If name is a rail vehicle number, then the camera will look at that rail vehicle. If the name is that of a named object, then only the free camera will look at the object

JumpTo

Syntax: JumpTo ( longitude, latitude, height )
Function: Move the camera to a location
Arguments: longitude The longitude of the position

latitude The latitude of the position

height The height above sea level
Return: True if the camera could move to the location
Note: Only available for the free camera

Example Script


------------------------------------------------
-- ScenarioScript.lua
-- Sample Scenario Script
------------------------------------------------


-- true/false defn
FALSE = 0
TRUE = 1

-- condition return values
CONDITION_NOT_YET_MET = 0
CONDITION_SUCCEEDED = 1
CONDITION_FAILED = 2

-- Message types
MT_INFO = 0 -- large centre screen pop up
MT_ALERT = 1 -- top right alert message

------------------------------------------------
-- Fn OnEvent
-- event - name of the event
-- return - TRUE/FALSE if event handled


function OnEvent ( event )


    if event == "Event1" then

        SysCall ( "AnimObject1:PlayAnim", "Anim1", 0, 1.0 ); -- Play anim once non looping at normal(1.0x) speed
        SysCall ( "CameraManager:ActivateCamera", "CabCamera", 0 ); -- Switch to cab view
        return TRUE;

    end -- if event == "Event1" then


    if event == "Event2" then

        SysCall ( "ScenarioManager:ShowMessage", "Title", "Message", MT_INFO ); -- Show message
        return TRUE;

    end -- if event == "Event2" then


    if event == "Event3" then

        SysCall ( "ScenarioManager:BeginConditionCheck", "TestCondition1" ); --
        Start continual testing of a condition
        SysCall ( "ScenarioManager:TriggerDeferredEvent", "DeferredEvent1", 300.0 );--Trigger a deferred event in 300s

        return TRUE;

    end -- if event == "Event3" then

    if event == "DeferredEvent1" then

        SysCall ( "ScenarioManager:EndConditionCheck", "TestCondition1" );

        if SysCall ( "ScenarioManager:GetConditionStatus", "TestCondition1" ) ~= CONDITION_SUCCEEDED then

            SysCall ( "ScenarioManager:ShowMessage", "Failed", "TestCondition1", MT_ALERT ); -- Show message

        end -- if SysCall ( "ScenarioManager:GetConditionStatus", "TestCondition1" ) == CONDITION_FAILED then

        return TRUE;

    end -- if event == "DeferredEvent1" then

    return FALSE;

end -- function OnEvent ( event )

------------------------------------------------
-- Fn TestCondition
-- condition - name of the condition
-- return state of the condition

function TestCondition ( condition )

    if condition == "Condition1" then -- consist weight > 100000 kg

        mass = SysCall ( "PlayerEngine:GetConsistTotalMass" );

        if mass > 100000 then

            return CONDITION_SUCCEEDED;

        else

            return CONDITION_FAILED;

        end

    end -- if condition == "Condition1" then
 
    if condition == "Condition2" then -- using whistle

        controlValue = SysCall( "PlayerEngine:GetControlValue", "Horn", 0 );

        if controlValue > 0.5 then

            return CONDITION_SUCCEEDED;

        else

            return CONDITION_FAILED;

        end

    end -- if condition == "Condition2" then

    if condition == "Condition3" then -- engaged low gear

        gear = SysCall( "PlayerEngine:GetControlValue", "Gear", 0 );

        if gear < 3 then

            return CONDITION_SUCCEEDED;

        else

            return CONDITION_FAILED;

        end

    end -- if condition == "Condition2" then 

    if condition == "TestCondition1" then -- reached 100mph (44.704 m/s)

        speed = SysCall ( "PlayerEngine:GetSpeed" );

        if speed > 44.704 then

            return CONDITION_SUCCEEDED;

        end -- if speed > 44.704 then

    end -- if condition == "TestCondition1" then

    -- default to not met
    return CONDITION_NOT_YET_MET;

end -- function TestCondition ( condition )

Example Notes

The sample script is a very basic example of a scenario script which demonstrates some key features of the system.

In the related scenario, Event1 is triggered from an instruction 5 seconds after the scenario starts. Event2 and Event3 are to be triggered from 'Stop At Destination' instructions. 

Condition1, Condition2 and Condition3 are all tested on 'Stop At Destination' instructions.

Event1 plays an animation once at 1x speed and places the camera in the cab view.
Event2 shows a message.
Event3 starts a test condition and triggers a deferred event for 5 minutes (300 seconds) time.

Condition1 checks the player train is at least 100,000 kg in weight.
Condition2 checks the player is using the horn/whistle.
Condition3 checks the player is in a low gear.

The deferred event and it associated test condition is an example of testing a requirement on the player in a fixed time span. In this case - testing the player reaches 100mph in the next 5 minutes.

Note: The DeferredEvent1 cancels the testing of TestCondition1 otherwise TestCondition1 would continue until the scenario is completed or the player reaches 100mph.