User Tools

Site Tools


mtr_addon:nte:js:train

Train Related

NTE supports full control of train rendering via JavaScript. You can either fully control the rendering of all elements using JavaScript, or overlay JavaScript-driven displays or objects on an existing train model.

Adding a Train

You can add a model that uses JavaScript to control rendering by writing something like this in the mtr_custom_resources.json file:

mtr_custom_resources.json
{
  "custom_trains": {
    "s_train_suspend": {
      "name": "JS Test Train",
      "base_type": "train_9_2",
      "color": "2AF0AD",
      "script_files": [ "mtr:js_train/main.js" ],
      "bve_sound_base_id": "optonix1500"
    }
  }
}

In general, the parameters are the same as those required for regular resourcepacks for MTR, except for the script_files parameter.

If the base_type parameter is not specified, the train appearance specified by the other parameters will be displayed as is, and then JavaScript-driven elements will be overlaid on top of it. Otherwise, if the base_type parameter is specified, the appearance will be controlled solely by JavaScript.

Parameter Description
base_type Train type, length and width. For example, train_19_2. If this attribute is specified, the appearance of the train will be controlled solely by JavaScript, i.e. without taking base_train_type, model and other parameters into account. Otherwise, the appearance of the train will be based on base_train_type, model and others, and then JavaScript-driven elements will be overlaid on top of it.
script_files An array containing the locations of .js scripts. Multiple scripts can be specified.
script_texts Optional parameter. An array containing the JavaScript text to be executed before script_files. Can be used when the same script is used for different trains, but you need to set variables that are different for each train.
has_gangway_connection Is it possible to pass between cars? Without this parameter the base_train_type setting is taken.
is_jacobs_bogie Whether the Jacobs bogie is used. Only affects sounds when using the BVE format.
bogie_position The distance between the normal bogie and the center of the car. Only affects sounds when using the BVE format.

Global Environment

All trains of the same type use the same working environment (global variables and etc).

Code written in top-level space outside of functions will run when a resource package is loaded, and can be used to load resources such as models and textures. It is recommended to store resources (such as models, fonts and textures) in global variables, which do not need to be different for each train, to avoid excessive memory usage caused by loading a copy of the same content for each train.

Called Functions

Your script should include the following functions that the NTE will call as needed:

function create(ctx, state, train) { ... }
function render(ctx, state, train) { ... }
function dispose(ctx, state, train) { ... }
Functions Description
create It is called when the train is loaded at the client and can be used to perform some initialization operations, for example, to create dynamic textures.
render It is called approximately once per frame. It is used for basic display logic. In practice however, the code is executed in a separate thread so as not to slow down FPS. If it takes too long to execute the code, it can be called once every few frames instead of every frame.
dispose Called when a train goes out of sight. Can be used for things like releasing the dynamic textures to free up memory.

The NTE calls these functions with three parameters, each of which is described below.

Parameter Description
First (ctx) Used to pass train rendering actions to the NTE. Type — TrainScriptContext.
Second (state) A JavaScript object associated with a train. The initial value is {}, and its content can be set arbitrarily to store what should be different for each train.
Third (train) Used to get the status of the train. Type — Train.

The following lists all the rendering control operations that can be performed and all the information that can be obtained about the train.

TrainScriptContext

The following functions are called to control rendering. The functions for rendering models should be called each time render is called.

  • TrainScriptContext.drawCarModel(model: ModelCluster, carIndex: int, poseStack: Matrices): void
    • Requests NTE to render the car model.
    • carIndex: defines the car whose origin point will be used for rendering (0 — first car in front, train.trainCars() - 1 — last). The origin point is in the middle of the car, 1 block above ground level.
    • poseStack: transformation of model placement. If passed null, the model will be placed in the center without transformation.
  • TrainScriptContext.drawConnModel(model: ModelCluster, carIndex: int, poseStack: Matrices): void
    • Requests the NTE to render a model of the wagon coupling.
    • carIndex: defines the car connection whose origin point will be used for rendering (0 — between the 1st and 2nd car in front, train.trainCars() - 2 — last). The origin point is in the middle of the connection, 1 block above ground level.
    • poseStack: transformation of model placement. If passed null, the model will be placed in the center without transformation.
  • TrainScriptContext.drawConnStretchTexture(location: ResourceLocation, carIndex: int): void
    • Requests NTE to render the same stretching coupling between cars as in the original MTR. To improve performance, the provided textures are four images from the original MTR combined into one. Top left is the outside, top right is the inside, bottom left is the top, bottom right is the bottom. [Translator's note: these couplings have a fixed size.]

Call the following functions to play sounds. Call only when you need to start playback, repeated calls will cause multiple sounds to stack.

  • TrainScriptContext.playCarSound(sound: ResourceLocation, carIndex: int, x: float, y: float, z: float, volume: float, pitch: float): void
    • Play sound. The sound source position can be set so that it can be heard by all nearby players.
  • TrainScriptContext.playAnnSound(sound: ResourceLocation, volume: float, pitch: float): void
    • Play announcer sound. Can only be heard by the players currently in the train.

In addition, there is a set of functions to aid development and debugging.

  • TrainScriptContext.setDebugInfo(key: String, value: Object)
    • Output debugging information in the upper left corner of the screen. You need to enable “Show JS debug info” in NTE Settings to display it. key is the name of the value, value is the content (GraphicsTexture type will be displayed, others will be converted to string).
Functions And Objects Description
train.shouldRender(): boolean Whether this train should be shown now. When the setting to hide the train the player is on is enabled, the script will run as normal in order for features such as broadcasting to still work. This function will return false to disable features such as particle effects. Note that this function is not needed to stop drawCarModel, NTE will automatically call it.
train.shouldRenderDetail(): boolean Whether the train is within the detailed drawing radius (32 blocks). To save resources, it is recommended to stop processing things like broadcasts, displays, detailed models, etc. when the value is false.
train.trainTypeId(): String Train Type ID.
train.baseTrainType(): String Based on the model ID.
train.id(): long The unique number of the vehicle inside the MTR. It's a random 64-bit integer. [Nemo's note: Maybe in JavaScript the last few bits become 0 because there are not enough valid digits?]
train.transportMode(): TransportMode Mode of transportation.
train.spacing(): int Length of each car + 1.
train.width(): int Width. Since the player also has a width [what?], a wagon that is 3 blocks wide has a value of 2 for this attribute.
train.trainCars(): int Number of cars.
train.accelerationConstant(): float Acceleration. The unit of measurement is m/tick/tick, which is 1/400 m/s2
train.manualAllowed(): boolean Whether manual operation is allowed.
train.maxManualSpeed(): int The maximum speed at manual control. It corresponds to the ordering of track types from low to high. [what?]
train.manualToAutomaticTime(): int Time to switch back to automatic control after being unmanned.
train.path(): List<PathData> A travel path representing a list of each section of the path to be traveled. Each element represents one PathData.
train.railProgress(): double Distance from the siding.
train.speed(): float Speed, is measured in m/tick, which is equal to 1/20 m/s.
train.doorValue(): float Door status. 0 - fully closed, 1 - fully open. Values between - smooth transition between states.
train.isDoorOpening(): boolean Are doors opening?
train.doorLeftOpen[carIndex: int]: boolean Whether left doors of a particular car can be opened.
train.doorRightOpen[carIndex: int]: boolean Whether right doors of a particular car can be opened.
train.isCurrentlyManual(): boolean Is it manually operated right now?
train.isReversed(): boolean Is the train reversed? That is, is the first car on the rear?
train.isOnRoute(): boolean Is the train on the route?
  • train.getRailProgress(car: int): double
    • Distance traveled by the car car from the moment of leaving the depot. Car counting starts from 0, the starting point is considered to be their front when leaving the depot. For example, getRailProgress(1) will return the distance to the coupling between cars 1 and 2
  • train.getRailIndex(railProgress: double, roundDown: boolean): int
    • Calculates which track a particular railProgress is on at the first entry in path(). If this position is at the junction of two tracks, roundDown is true to return the one further to the rear, otherwise it returns the one further to the front.
  • train.getRailSpeed(railIndex: int): float
    • The maximum speed at which this track can be traveled, as indicated by the railIndex entry in path(). It correctly handles the case where a train should not enter a station and accelerate when this section of track is a platform. The unit is m/tick, which is 1/20 m/s.
  • train.getAllPlatforms(): List<PlatformInfo>
    • A list of all platforms through which the train passes according to the instruction. Each element is a PlatformInfo. A turn on a platform counts as one element.
  • train.getAllPlatformsNextIndex(): int
    • Returns the number of the next station in the getAllPlatforms() list at which the train will stop (this value is updated when the train departs, so when it stops at a platform, it is the same station). A value of 0 means the train has just left the depot and is traveling to the first platform, and a value equal to getAllPlatforms().size() means it is returning to the depot. Note that it is therefore not necessarily within the index range of `getAllPlatforms()`, which needs to be determined.
  • train.getThisRoutePlatforms(): List<PlatformInfo>
    • A list of all platforms of the current route. Each element is a PlatformInfo.
  • train.getThisRoutePlatformsNextIndex(): int
    • Returns the number of the next station in the getThisRoutePlatforms() list where the train will stop. A value of 0 means that the train is going to the first platform, and a value equal to getThisRoutePlatforms().size() means that it is leaving for the next route or returning to the depot. Note that it is therefore not necessarily within the index range of `getThisRoutePlatforms()`, which needs to be determined.

PathData

Functions And Objects Description
PathData.rail: Rail Rail. For more details, see the Rail.java source code from MTR.
PathData.rail.railType: RailType Rail type (wood, stone, iron…) See the RailType.java source code from MTR.
PathData.rail.getModelKey(): String The NTE path model used for this section.This will return an empty string if no NTE path model are assigned, and “null” if the model in use are the (Hidden) track model.
PathData.dwellTime: int The amount of time a train has to stop if this section of track is a platform. 0 if it is not a platform, in *0.5s.

PlatformInfo

Functions And Objects Description
platformInfo.route: Route The route to which this platform belongs. If the reverse happens at the platform — the route after reversal is returned. See Route.java source code from MTR.
PlatformInfo.route.name: String The name of the route to which this platform belongs.
PlatformInfo.station: Station The station to which the platform belongs. See the Station.java source code from the MTR.
PlatformInfo.station.name: String The name of the station to which the platform belongs.
PlatformInfo.platform: Platform This platform. See the Platform.java source code from the MTR.
PlatformInfo.platform.name: String Platform Name.
PlatformInfo.platform.dwellTime: int Train dwell time, indicated in ticks (1/20 s).
PlatformInfo.destinationStation: Station The end station of the route to which this platform belongs. See the Station.java source code from the MTR.
PlatformInfo.destinationStation.name: String The name of the terminus of the route to which the platform belongs.
PlatformInfo.destinationName: String Name of the final station (including the possibility of customizing the text).
PlatformInfo.distance: double The distance from the depot to the platform, can be compared with railProgress.
PlatformInfo.reverseAtPlatform: boolean Does the train reverse on the platform?

Source

mtr_addon/nte/js/train.txt · Last modified: 2024/04/09 17:45 by weryskok