The m4nfo User manual and Technical Report

Technical Report

Train properties, functions and callbacks


Content

Train property functions

m4nfo train properties are based on plain nfo's action0 properties. Most of them are mapped in a straightforward way, but some of m4nfo's train property functions are based on custom calculations, or based on using more than one nfo property.

m4nfo function nfo property custom
airdrag0x20 
aiusage0x18 + 0x08yes
callbacks0x1Eyes
capacity0x14 
cargoaging0x2B
cargoclasses0x28 + 0x29yes
cargolist0x2C 
cargomask0x1D
cargotype0x15
climate0x06
effort0x1Fyes
enginetype0x19 + 0x0Eyes
flags0x27 
intro0x00 + 0x2Ayes
loadamount0x07 
modlife0x04
newgraphics0x12
power0x0Byes
price0x17 
refitcost0x1Cyes
reliability0x02 
retire0x26
runningcost0x0D
seteffect0x22
shortening0x21
sortbefore0x1A
speed0x09yes
railtype0x05 
userdata0x25
vehlife0x03
weight0x16 + 0x24yes

Flag label Bit Value
TILTING00x01
2CC10x02
DEMU20x04
FLIPPING30x08
AUTOREFITTING40x10
CARGOMULTIPLIER50x20
NOBRKEFFECT60x40
STACKEDSPRITES70x80

aiusage(<Byte>[, PASS])

m4nfo combines two different nfo properties for AI handling: the AI 'engine rank' (0x18) and the AI special flag (0x08), which is set if the vehicle is 'optimized' for passenger service, i.e. the AI won't use it for other cargo.

callbacks(<List::Callbacks>)

Enabling callbacks in plain nfo means to set bits in property (0x1E). Unfortunately, these bits have no numerical relation to the corresponding callback values returned by nfo's variable (0x0C). In m4nfo, both property function callbacks() and performance function callback() are using the same callback labels.

cargoclasses(<List::(+|-)CargoClass>)

This m4nfo property function combines the two nfo properties for cargo class inclusion (0x28) and exclusion (0x29).

effort(<Unit-term>)

Plain nfo handles tractive effort as a coefficient. It sets what fraction of the vehicle weight is equal to the maximum tractive effort. The default value of 0x4C represents a friction coefficient of ยต = 0.3.

m4nfo property function effort() takes a real tractive effort value, given either in [kn, KN, kp, KP, lbf, LBF], and re-calculates the nfo coefficient by taking into account the engine's weight.

If the engine's weight has not been specified at the time of this function's call, error message ERR_NOWEIGHT is shown.

enginetype(<EngineType>)

This m4nfo property function combines the two nfo properties for engine traction type (0x19), either steam, diesel, electric, monorail or maglev, and an appropriate running cost base (0x0E).

Each traction type is combined with its appropriate cost base table, i.e. traction type 'steam' is combined with the cost base table for steam engines (0x4C30), etc.

intro(<Date>)

Unline nfo, which again uses two properties for the introduction date (0x00 and 0x2A), this m4nfo function takes an introduction date in different formats and re-formats it for the appropriate nfo properties, i.e. if the given year is after 1920, only nfo property 0x00 will be used.

power(<Unit-term>)

Plain nfo allows to specify the power of an engine in 'hp' only, but m4nfo allows to use either [hp, HP, ps, PS, kw, KW].

refitcost(<Byte> | <Unit-term>)

In m4nfo, the refit cost can be given either as a Byte value, with its maximum value "255" correlating to 50% of the vehicle's purchase price cost base (this is the original nfo behaviour), or directly as a percent value.

speed(<Unit-term>)

Plain nfo allows to specify the speed of an engine in units of mph*1.6, i.e. approximately km/h only, but m4nfo allows to use either [km/h, KM/H, mph, MPH].

weight(<Unit-term>)

Again, plain nfo uses two properties for a vehicle's weight: (0x16) as a Byte value may only represent a vehicle's weight up to 255 tons. And only by using property 0x24, which represents the 'high byte' of the vehicle's weight, larger weights can be specified.

m4nfo's function makes this limitation obsolete and, in addition, makes available the weight value for internal tractive effort calculations.

Train performance functions

m4nfo train performance functions are based on plain nfo's Variational Action2 variables. Again, most of them are mapped in a straightforward way, but some of m4nfo's train performance functions are based on custom calculations, or based on use of more than one nfo variable.

Please note that functions return either Byte, Word or Dword values, depending on the context they're used in.

m4nfo function nfo var Byte Word/Dword
ageindays0xC0 85/86 C0 00 FF FF
ageinyears0x24/0x49 89/8A (custom)
animation0x4682 46 08 03 (*) 
articulated0x1081 10 00 FF
autoreplace81 10 00 FF
callback0x0C81 0C 00 FF85 0C 00 FF FF
cargo0xB981 B9 00 FF 
clrubit0x42(custom)
cnst_cargo81/82 42 08 FF 
cnst_cargoclasses81/82 42 00 FF (*)
cnst_refit81/82 42 10 FF
current_capacity0xBA 85 BA 00 FF FF
current_load0xBC85 BC 00 FF FF
current_speed0xB485 B4 00 FF FF
curvature_front0x4581 45 00 0F 
curvature_back81 45 08 0F
curvature_triplet81 45 10 0F
daycounter0xC981 C9 00 FF
daysintravel0xF0 85 F0 00 FF FF
dayspastservice0x23/0x4B(custom)
direction0x9F81 9F 00 FF 
displaymode0x1081 10 00 FF
elsen/a 
flipped0xC881/82 C8 00 FF
getubits0x42(custom)
getubyte(custom)
idcount0x6081/82 60 <par> 00 FF (*) 
incline0x9E(custom)
indepot0xE282 E2 00 FF 
islast0xDA81 DA 00 FF
lastmaintenance0x92 85/86 92 00 FF FF
lastservicedate0x4B 89/8A 4B 00 FF FF FF FF
lastserviceyear(custom)
loadtime0x90 85 90 00 FF FF
maxspeed0x9885 98 00 FF FF
property0x1081 10 00 FF 
randombits0x5F81/82 5F 08 FF (*)
randomtriggers81/82 5F 00 FF (*)
rcost_cargotype0x1081 10 00 FF
rcost_cargosubtype81 10 08 FF
rcost_cargoclass81 10 10 FF (*)
refitted0xF281/82 F2 00 FF
reliabilitystate0xCE 85 CE 00 FF FF
reversed0xFF82 FF 00 01 
servint0x94 85 94 00 FF FF
setubit0x42(custom)
setubyte(custom)
shorter0xF381 F3 00 FF 
soundevent0x1081 10 00 FF
speedlimit0xF4 86 F4 00 FF FF
spritelayer0x1081 10 08 FF 
spritestack (custom)
veh_cargoclass0x4781 47 10 FF (*) 
veh_cargotype81/82 47 00 FF
veh_cargoweight81 47 08 FF
veh_getinfo0x61(custom) (*)
veh_getinfoabs(custom) (*)
veh_id0xC681/82 C6 00 FF 
veh_ispowered0xFE81 FE 00 05
veh_marketinfo0x4881/82 48 00 07
veh_maypowered0xFE81 FE 00 06
veh_num0x4081/82 40 10 FF
veh_posabs0x4081/82 40
veh_posart0x4D81/82 4D
veh_posrel0x4181/82 41
veh_railtype0x4A81 4A 00 FF
veh_status0xB281 B2 00 FF
veh_zpos0x9E81/82 9E 00 FF
yearbuilt0x49 85/86 49 00 FF FF

(*) - may be adjusted by use of auxiliary function shiftmask().
(custom) - these functions are using more than one TTD variable and/or make use of auxiliary functions shiftmask() and/or engine().

clrubit([0 .. 7]), setubit([0 .. 7]), getubits[<shiftmask>,] <block>), getubyte(<block>), setubyte(<block>)

These functions allow manipulation of plain nfo's vehicle 'user bits' (property 0x25) in a most handy way, by splitting the user data area into a range used for bit setting and checking, and a second part for writing and reading numerical values. Both are handled independently, and need initialisation by auxiliary function allocuserdata()

idcount(<Veh-ID>, <block>)

incline(<block>)

veh_getinfo([-]<Byte>, <function>, <block>), veh_getinfoabs(FRONT | BACK, <Byte>, <function>, <block>>)

veh_posrel/veh_posabs(FRONT | BACK | MOD2 | MOD3 | MOD4 | MOD6, <block>)

yearbuilt(<block>)

Train callbacks

m4nfo train callbacks are based on plain nfo's callbacks. They're all mapped in a straightforward way. Callbacks from the first section of the table below have to be enabled by property function callbacks(), but those from the second section do not need to be: they're always active and will be used automatically if needed.

m4nfo callback nfo callback
CB_ARTI0x16
CB_WLEN0x11
CB_LOAD0x12
CB_POWR0x10
CB_RCAP0x15
CB_RCOL0x2D
CB_SOUND0x33
CB_TSFX0x19
CB_ARVS0x34
CB_ATAC0x1D
CB_PROP0x36
CB_RCOST0x15E
CB_STOP0x31
CB_TEXT0x23
CB_32DAY0x32

Callback helper functions

Callback helper functions are based on m4nfo's function cbr() which returns a parameter as a callback return value.

m4nfo function definition
addvehcbr($1)
addvehrevcbr($1+0x80)
attachcbr($1)
effectcbr($1)
seteffort(custom)
autorefitcbr(eval($1 | 16384))
refsndcbr(_S_$1)
grftextcbr($1)
reftxtcb(custom)

Random functions

In nfo, randomized Action2s are used to either randomize the vehicle (0x80) based on itself, based on the first vehicle of its consist (0x83), or based on any vehicle in the consist (0x84).

m4nfo function nfo random Action2 type
randomrel0x80
randomabs0x83
randomcount0x84

m4nfo trigger nfo trigger
bit value
CONSTRUCTn/a0
LOAD01
SERVICE12
UNLOAD24
ANYLOAD38
CB32416
ALLTRIGGERS7128

Global functions

m4nfo function nfo var Byte Word
anim_counter0x0A81 0A85 0A
cargotranslationtableGeneral Action000 09 
checkparameter0x7F81 7F85 7F
incrbasecostGeneral Action000 08 
grf_overrideGeneral Action000 11
setpropertiesAction000 xx

cargotranslationtable(<List::Label>)

Each entry of a cargo translation table represents a corresponding cargo which is meant when using its ID in various cargo-related functions. E.g., given this cargo translation table:

Example (set Cargo Translation Table):
cargotranslationtable( 
	{"PASS"}, {"COAL"}, {"MAIL"}, {"OIL_"},
	{"LVST"}, {"GOOD"}, {"GRAI"}, {"WOOD"},
	{"IORE"}, {"STEL"}, {"VALU"}, {"FOOD"}, 
	{"PAPR"}, {"FRUT"}, "FISH", "WOOL,
	"LIME", "SAND", "GLAS", "WDPR",
	"DYES", "FERT", "OLSD", "RFPR",
	"VEHI", "PETR", "AORE", {"WATR"},
	"BDMT", "FICR", "TOUR", "CERE",
	"MILK", "SGBT", "CLAY", "MNSP",
	"SCMT", "POTA", "SULP", "FMSP",
	"ENSP", "GRVL", "BEER", "RCYC"
)

the cargo defined by cargo label "WDPR" is given cargo-ID WDPR (19).

To support distributed source code, the list of thus defined cargo-IDs is written to an intermediary file named "m4_ctt":

define({PASS},0)
define({COAL},1)
define({MAIL},2)
define({OIL_},3)
define({LVST},4)
define({GOOD},5)
define({GRAI},6)
define({WOOD},7)
define({IORE},8)
define({STEL},9)
define({VALU},10)
define({FOOD},11)
define({PAPR},12)
define({FRUT},13)
define({FISH},14)
define({WOOL},15)
define({LIME},16)
define({SAND},17)
define({GLAS},18)
define({WDPR},19)

...

This file needs to be included into other source files referencing any of those newly declared cargo types, by using function import_ctt(). When using a dependency-tracking build utility ("Make"), you might set up a dependency for file "m4_ctt" to assure consistency.