====== 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:
{
"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 [[https://en.wikipedia.org/wiki/Jacobs_bogie|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'' | 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
* 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
* 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 [[https://github.com/jonafanho/Minecraft-Transit-Railway/blob/3.3.0/common/src/main/java/mtr/data/Rail.java|Rail.java]] source code from MTR. |
| ''PathData.rail.railType: RailType'' | Rail type (wood, stone, iron...) See the [[https://github.com/jonafanho/Minecraft-Transit-Railway/blob/3.3.0/common/src/main/java/mtr/data/RailType.java|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 [[https://github.com/jonafanho/Minecraft-Transit-Railway/blob/3.3.0/common/src/main/java/mtr/data/Route.java|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 [[https://github.com/jonafanho/Minecraft-Transit-Railway/blob/3.3.0/common/src/main/java/mtr/data/Station.java|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 [[https://github.com/jonafanho/Minecraft-Transit-Railway/blob/3.3.0/common/src/main/java/mtr/data/Platform.java|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 [[https://github.com/jonafanho/Minecraft-Transit-Railway/blob/3.3.0/common/src/main/java/mtr/data/Station.java|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 =====
* [[https://www.zbx1425.cn/nautilus/mtr-nte/#/js-train]]