pressure above a certain value. Once a condition has completed its value is saved and any further checks will return this saved value.
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 Call, scenario 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 )