The m4nfo User manual and Technical Report

Train vehicles

Defining properties for and performance of train vehicles

Introduction

The code for train vehicles consists of three parts:

The definition sets the properties of the train vehicle like introduction date, top speed, wagon capacity, etc. Please note that a vehicle definition may only occur after the prior grfinit() function call for the newGRF file.

The train performance functions are used to group sets of graphics sprites from a previous spriteblock() (layout functions), or to evaluate game-intrinsic variables, and make both of them accessible to the vehicle's activation function (performance functions).

The vehicle activation instantiates the vehicle by finally assigning graphics sets and/or callback or other variable-referencing functions to this particular vehicle. This is done by supplying a block of special functions handling references and cargo types to the vehicle's activation. See below.

Functions

FunctionMeaning
definevehicle(<Veh-ID>, List::(<Language-ID>, <String>) | <String>,<block>)Train vehicle definition
namevehicle(<Veh-ID>, List::(<Language-ID>, <String>))Definition of train name(s)
makevehicle(<Veh-ID>,<block>)Train vehicle activation
sortvehicles(List:: <Veh-ID>)Sorting the purchase list

Description

definevehicle(<Veh-ID>, List::(<Language-ID>, <String>) | <String>,<block>)

This function defines a train vehicle. Its parameters are the train vehicle's ID, a text string giving the default name of the vehicle (or a namevehicle block, s.b.), and a block of property-defining functions, where the relative position of the property functions is irrelevant.

Example 1 (vehicle definition):
setcurrency(DEM)

...

definevehicle(_BR75, "BR 75 (ex wü. T5)",
	newgraphics()
	lifecycle(1-1-1912, 1932, 1963)
	climate(TEMPERATE, ARCTIC)
	reliability(7)    // reliability decrease
	enginetype(STEAM) // traction type & cost base
	railtype(RAIL)
	speed(75 km/h)
	power(880 PS)
	dualhead(NO)	
	capacity(0)
	weight(71 t)
	price(68'750) // DEM == RM
	runningcost(7'563) // DEM == RM
	aiusage(2)
	callbacks(CB_RCOL, CB_SOUND)
	effort(101 kN) // tractive effort
	vehlen(7/8)
	flags(FLIPPING)
)

definevehicle(_MSP,{
	ALL,"Passenger coach",
	US,"Passenger car",
	D,"Passagierwagen",
	F,"Voiture voyageur",
	E,UTF8 "Vagón de pasajeros",
	I,"Carrozza viaggiatori"},
	newgraphics()
	lifecycle(1-1-1916, 1952, 1960)
	climate(TEMPERATE, ARCTIC)
	...
)

namevehicle(<Veh-ID>, List::(<Language-ID>, <String>))

This function defines more names for a train vehicle than the default one given by definevehicle(). It should be used if a vehicle needs names in more than one language. The function's parameters are the vehicle's ID and a block consisting of language IDs and associated names.

Example 2 (setting vehicle names):
definevehicle(_MSP,"Passenger coach",
	newgraphics()
	lifecycle(1-1-1916, 1952, 1960)
	climate(TEMPERATE, ARCTIC)
	loadamount(6) // {1; 2; 3; 6; 9; 18}
	speed(140 km/h)
	...
)

namevehicle(_MSP,
	US,"Passenger car",
	D,"Passagierwagen",
	F,"Voiture voyageur",
	E,UTF8 "Vagón de pasajeros",
	I,"Carrozza viaggiatori"
)

Alternatively, you may use a namevehicle block as the second parameter for function definevehicle() as a template. This might be beneficial in situations where a vehicle's name would be different in a number of languages, and those would be stored in an extra file, to keep them together, see example:

Example 3 (using templates for vehicle names):
// file "strings.nfx"
define(STR_LOW,{
	ALL, "Low side wagon",
	D, "Niederbordwagen",
	F, "Wagon ouvert",
	E, UTF8 "Vagón de bordes bajos",
	I, "Carro aperto a sponde basse",
	NL, "Lageboordwagen"}
)
define(STR_BOX,{
	ALL,"Goods van",
	D,"geschlossener Wagen",
	F,"Wagon couvert",
	E,UTF8 "Vagón cerrado",
	I,"Carro chiuso",
	NL,"Gesloten wagen"}
)

// file defining freight wagons
include(strings.nfx)
definevehicle(_SLOW, {STR_LOW},
	newgraphics()
	intro(1911)
	climate(TEMPERATE, ARCTIC)
	vehlife(40)
	...
)

definevehicle(_SBOX, {STR_BOX},
	newgraphics()
	intro(1900)
	climate(TEMPERATE, ARCTIC)
	vehlife(30)
	...
)

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

This function activates a previously defined train vehicle. Its parameters are the train vehicle's ID and a block of special cargo-associated functions:

FunctionMeaning
link(<ref()>{,<CargoType>})Linking a cargo-dependent chain of graphics or variable dependencies to this vehicle
default(<ref()>)Default chain to use with this vehicle
override(<Veh-ID>, <ref()>)An engine-override for this vehicle

For special purposes, the vehicle ID may be omitted to create a "generic callback" (CB_AISELECT).

link(<ref()>{, <CargoType>})

This function links a reference to a chain of functions describing graphics and/or variable evaluations with particular cargo types. Its parameters are the reference to the chain of functions and appropriate cargo types.

The given cargo types determine the set of graphics or the variable chain to be used with a particular type of cargo. If the newGRF file has installed a cargo translation table, the cargo types refer to cargoes with those particular labels in the translation table.

The special cargo type MENU is used for graphics shown in the purchase or construction window.

default(<ref()>)

This function is used if no entry from the link() function(s) matches, or if there are no special cargo types listed at all in a link() function.

override(<Veh-ID>,<ref()>)

This is a special type of a link() function. It changes the graphics of train wagons when attached to a certain train engine. E.g., this makes it possible to have train sets where the look of certain wagons matches that of the engine (informally, this is called a 'livery override'). As its first parameter, it takes the vehicle ID of the wagon to use overrides for, and for its second parameter, it needs a reference to a chain of functions ending in the graphics to use for the override. Keep in mind that the wagon needs to use the newgraphics() property function in its definition to show new graphics for the override to work.

The override() function needs to follow special considerations:

Example 4 (activating a vehicle)::
makevehicle(_BR38,
	link(ref(4),MENU)
	default(ref(5))
	override(_TENDER,ref(TENDER2)) // Tender
	override(_PLOCAL,ref(0))       // local coaches
	override(_PDIST,ref(XSPW_))    // long-distance coaches
)

sortvehicles(List:: <Veh-ID>)

By default, vehicles are arranged in the purchase list by their IDs, from the lowest ID upwards. This function allows to sort vehicles differently, by directly specifying the sorting order from top to bottom.

Example 5 (sorting vehicles)::
define(_BR91, 0x06)
define(_BR38, 0xC6)
define(_BR57, 0x11)
define(_BR75, 0x73)
define(_BR18, 0x52)
define(_BR44, 0x51)
define(_BR86, 0x22)
define(_BR64, 0x1F)
define(_BR01, 0x03)

...

definevehicle(_BR01, {"01 (DRG / DB)"},
	...
)

...

definevehicle(_BR91, {"pr. T 9.2 / 91.0-1 (DRG)"},
	...
)

...

definevehicle(_BR57, {"pr. G 10 / 57.10-35 (DRG / DB)"},
	...
)

...

sortvehicles(_BR91, _BR38, _BR57, _BR75, _BR18, _BR44, _BR86, _BR64, _BR01, _BR85)

References