NML:Random switch
Vehicles, Stations, Canals, Bridges, Towns, Houses, Industries (Tiles), Cargos, Airports+Tiles, Objects, Railtypes, Roadtypes, Tramtypes, Terrain
While a switch-block allows making a predictable decision, a random_switch allows a randomised choice between several options.
random_switch (<feature>, <type>, <ID>[, <triggers>]) { (independent: <other_random>;)* (dependent: <other_random>;)* (<probability>: <return_value>;)+ }
The first parameter <feature>
specifies the feature to use. <type>
, the second parameter, is used to define what random data is used. The supported combinations are listed in the following table. The amount of random data is given in the third column. The maximum number of possible combinations is equal to 2^x, with x being the number of random bits. Not all combinations support re-randomizing via triggers, this is indicated in the fourth column. The last column specifies the object of which the random data is used.
Feature | Type | # of random bits | Triggers possible? | Random data used |
---|---|---|---|---|
Vehicles | SELF | 8 | Yes | Vehicle itself |
Vehicles | PARENT | 8 | No | Leading engine |
Vehicles | BACKWARD_SELF(x) | 8 | No | Count x vehicles backward (away from the engine), starting at the vehicle itself [1] |
Vehicles | FORWARD_SELF(x) | 8 | No | Count x vehicles forward (towards the engine), starting at the vehicle itself [1] |
Vehicles | BACKWARD_ENGINE(x) | 8 | No | Count x vehicles backward, starting at the leading engine [1] |
Vehicles | BACKWARD_SAMEID(x) | 8 | No | Count x vehicles backward, starting at the first vehicle in the chain with the same ID [1] |
Stations / airport tiles | SELF | 16 | Stations only | Station |
Stations / airport tiles | TILE | 4 | Stations only | Specific station tile |
Canals | SELF | 8 | No | Canal tile |
Houses | SELF | 8 | Yes | House tile [2] |
Industry tiles | SELF | 8 | Yes | Industry tile |
Industry tiles | PARENT | 16 | Yes | Industry as a whole |
Industries | SELF | 16 | No | Industry (same as above) |
Objects | SELF | 8 | No | Object tile (different per tile) |
Rail types | SELF | 2 | No | Rail tile (pseudo-random, based on location) |
- ↑ 1.0 1.1 1.2 1.3 x can be any expression. It may access parameters, registers, or variables of the vehicle itself. if x is an expression, its result gets stored in register 0x100. if x is 0, the value of register 0x100 is read
- ↑ The random bits are initially the same for all tiles of a multi-tile house.
The third parameter <ID>
can be used to refer to this block from other (random-)switch-blocks. The last parameter <triggers>
is optional and allows re-randomizing when certain conditions occur. The events and accompanying trigger names are given in the following tables. To re-randomize graphics when any of a set of events occurs, use bitmask(TRIGGER_A, TRIGGER_B, .. , TRIGGER_Z)
To re-randomize only when all of the events have occured, add TRIGGER_ALL_NEEDED
to the list of used triggers, e.g. use bitmask(TRIGGER_ALL_NEEDED, TRIGGER_A, ...)
Trigger | Event |
---|---|
TRIGGER_VEHICLE_NEW_LOAD | Vehicle gets new load of cargo (only after it was empty) |
TRIGGER_VEHICLE_SERVICE | Vehicle enters a depot and is serviced |
TRIGGER_VEHICLE_UNLOAD_ALL | The consist has unloaded all cargo (use with type 'SELF') |
TRIGGER_VEHICLE_ANY_LOAD | Any vehicle of the consist receives cargo (use with type 'SELF') |
TRIGGER_VEHICLE_32_CALLBACK | 32-day callback returned 1 |
To re-randomize when the consist has been emptied and then receives new cargo, use bitmask(TRIGGER_VEHICLE_UNLOAD_ALL, TRIGGER_VEHICLE_ANY_LOAD, TRIGGER_ALL_NEEDED)
Trigger | Event | Triggered on |
---|---|---|
TRIGGER_STATION_NEW_CARGO | New cargo waiting | Entire station |
TRIGGER_STATION_NO_MORE_CARGO | No more cargo waiting | Entire station |
TRIGGER_STATION_TRAIN_ARRIVES | Train arrives (starts loading/unloading) | Platform the train is on |
TRIGGER_STATION_TRAIN_LEAVES | Train leaves (done loading/unloading) | Platform the train is on |
TRIGGER_STATION_TRAIN_LOADS_UNLOADS | Train loads/unloads cargo | Platform the train is on |
TRIGGER_STATION_TRAIN_RESERVES | Train reserves platform using PBS | Platform the train is on |
The last four triggers in the table only trigger on the platform on which they occur. Note that triggers are only saved per-station, not per-tile, so using TRIGGER_ALL_NEEDED
doesn't make a lot of sense for per-platform triggers
Trigger | Event |
---|---|
TRIGGER_HOUSE_TILELOOP | The house tile is processed in the periodic tile-processing loop |
TRIGGER_HOUSE_TOP_TILELOOP | The top tile of the house is processed in the periodic tile-processing loop |
Using TRIGGER_HOUSE_TOP_TILELOOP
, it is possible to re-randomize the whole building as one unit. All tiles of a multi-tile house will get the same new random data.
Trigger | Event |
---|---|
TRIGGER_INDUSTRYTILE_TILELOOP | The industry tile is processed in the periodic tile-processing loop |
TRIGGER_INDUSTRYTILE_256_TICKS | Triggers simultaneously for all tiles of the industry every 256 ticks. If the industry is a primary one, output cargo is generated at the same time. |
TRIGGER_INDUSTRYTILE_CARGO_DELIVERY | Cargo is delivered to the industry. If the industry is a processing one, output cargo is generated at the same time. |
Industry tiles can rerandomise both their own random bits as well as the random bits of the industry (via type PARENT
). The triggers for rerandomisation are in both cases shared per tile (when using TRIGGER_ALL_NEEDED
), i.e. the triggers are in all cases independent for different tiles. Industries have random bits. However, they can only be rerandomised by their tiles.
<independent>: <other_random>;
makes sure that this random_switch block and <other_random>
use different (non-intersecting) random data. This allows making multiple randomized decisions that are independent of each other.
<dependent>: <other_random>;
, on the other hand, lets this random_switch block and <other_random>
use the same random data. To make this possible, it should not require more random data (i.e. have a higher sum of probabilities) than the block it is dependent on.
Both of these options require enough random data to be available. Also, the combination must make sense. For example, if A is dependent on B and B is dependent on C, then A cannot be independent of C.
Following this, there is a list of options, one of which will be chosen randomly. The syntax is <probability>: <return_value>;
. The relative probability that this option will be chosen is given by <probability>
. The chance is equal to the probability divided by the sum of all probabilities. If this sum is not equal to a power of two (2, 4, 8, 16, ...), then rounding is done and the probabilities may be inexact. For information about <return_value>
, see the switch-block. Note that accessed variables in the return value are always in the scope of the item itself (i.e. SELF
)
Note that re-randomizing is done only during a special callback, random_trigger
. This callback is called whenever a trigger event occurs. As a consequence, it's absolutely necessary for the random_switch block to be in executed during this callback, or trigger-based re-randomizing won't take place. Also, the callback may not fail (end with CB_FAILED), so return an arbitrary value or even a sprite set instead. This return value is not used anywhere.
Let's conclude with an example:
random_switch (FEAT_TRAINS, SELF, random_42, bitmask(TRIGGER_VEHICLE_UNLOAD_ALL, TRIGGER_VEHICLE_ANY_LOAD, TRIGGER_ALL_NEEDED)) { /* re-randomize when vehicle has been emptied and then received new cargo */ independent: random_43; // decision should be independent from random_43, which is defined elsewhere 6: group_open; // 6/11 chance to display open wagon 3: group_closed; // 3/11 chance to display closed wagon (with cover) 2: group_halfopen; // 2/11 chance to display a half-covered wagon }