<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://www.tt-wiki.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hirundo</id>
	<title>TTWiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://www.tt-wiki.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hirundo"/>
	<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/wiki/Special:Contributions/Hirundo"/>
	<updated>2026-05-02T02:16:38Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_recolour&amp;diff=7831</id>
		<title>NMLTutorial/Train recolour</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_recolour&amp;diff=7831"/>
		<updated>2011-09-04T14:33:01Z</updated>

		<summary type="html">&lt;p&gt;Hirundo: /* Total code so far */ Again icm-&amp;gt;item_icm&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues and concludes the [[NMLTutorial/Train four part refit|fourth part]] of the train example. A parameter setting will be added (with a GUI for OpenTTD) to allow choosing between 1cc, 2cc or real life colours for our train. And we&#039;ll do some further visual improvements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== GRF Parameter setting ==&lt;br /&gt;
The GRF parameter setting will allow choosing between 1cc, 2cc or real life colours. This is done by adding a param block to the grf block. In this param block one (named) parameter will be defined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
    param {&lt;br /&gt;
        /* There is one parameter, which can be used to alter the colour scheme */&lt;br /&gt;
        param_colour_scheme {&lt;br /&gt;
            type: int;&lt;br /&gt;
            name: string(STR_PARAM_COLOUR_SCHEME_NAME);&lt;br /&gt;
            desc: string(STR_PARAM_COLOUR_SCHEME_DESC);&lt;br /&gt;
            /* There are currently three possible values:&lt;br /&gt;
             * - 1cc&lt;br /&gt;
             * - 2cc (default)&lt;br /&gt;
             * - real-world&lt;br /&gt;
             */&lt;br /&gt;
            min_value: 0;&lt;br /&gt;
            max_value: 2;&lt;br /&gt;
            def_value: 1;&lt;br /&gt;
            names: {&lt;br /&gt;
                0: string(STR_PARAM_COLOUR_SCHEME_1CC);&lt;br /&gt;
                1: string(STR_PARAM_COLOUR_SCHEME_2CC);&lt;br /&gt;
                2: string(STR_PARAM_COLOUR_SCHEME_REAL);&lt;br /&gt;
            };&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The GRF parameter is named &amp;lt;code&amp;gt;param_colour_scheme&amp;lt;/code&amp;gt;. This identifier needs to be unique and can be used elsewhere in the code to make decisions upon. Because we want three possible values, the GRF parameter needs to be of the integer type. The boolean type wouldn&#039;t work, as that only allows two possible values (on and off). The minimum value will be 0, the maximum 2 (resulting in three possible values 0, 1 and 2) and the default (in OpenTTD, TTDPatch always defaults to 0) will be 1. Strings are defined for the GRF parameter name and description. Each GRF parameter value will also get custom strings to display the settings rather than just numbers.&lt;br /&gt;
&lt;br /&gt;
This means we have to add these strings to the language file as well:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_NAME :Colour scheme&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_DESC :Select the type of colour scheme to use&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_1CC  :One company colour&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_2CC  :Two company colours&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_REAL :Real-world colours&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Colour mapping callback ==&lt;br /&gt;
This only added the parameter setting, but it doesn&#039;t do anything yet. We&#039;ll use the &amp;lt;code&amp;gt;colour_mapping&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback]. This callback allows recolouring a sprite using, well errr, recolour sprites. This is a slightly complicated callback, but the first step is easy. Reference a switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
        colour_mapping:               sw_icm_colour_mapping;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself we&#039;ll just give to you, attempting to explain what it does afterwards. If you don&#039;t understand how this switch block works, just copy it or ignore the callback altogether. Try yourself at some more easy NewGRFs first to get the hang of NML and come back to this later.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_colour_mapping, param_colour_scheme) {&lt;br /&gt;
    /* Emulate 1cc by making the first colour always yellow, this looks much better (and more realistic) */&lt;br /&gt;
    0: return palette_2cc(COLOUR_YELLOW, company_colour1);&lt;br /&gt;
    /* Use realistic colours, i.e. yellow + dark blue */&lt;br /&gt;
    2: return palette_2cc(COLOUR_YELLOW, COLOUR_DARK_BLUE);&lt;br /&gt;
    /* Use the default, i.e. 2 company colours */&lt;br /&gt;
    return base_sprite_2cc + CB_RESULT_COLOUR_MAPPING_ADD_CC;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The decision of this switch block is made on the &amp;lt;code&amp;gt;param_colour_scheme&amp;lt;/code&amp;gt;. The name of this variable is what we gave to it when defining the param block, so that&#039;s how you use a predefined GRF parameter. The values this GRF parameter can have are those defined in the same param block, so these values can be used as range in the switch block. It&#039;s useful to consider one value as default here, in case a user manages to make a setting outside the range of the minimum and maximum GRF parameter setting.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;colour_mapping&amp;lt;/code&amp;gt; needs to return the sprite number of a recolour sprite. We&#039;ll be using the default recolour sprites for this and NML has some functions and variables to retrieve these sprite numbers for you. You can find more about that in the [http://newgrf-specs.tt-wiki.net/wiki/NML:List_of_default_colour_translation_palettes NML Documentation].&lt;br /&gt;
; 1cc (&amp;lt;code&amp;gt;param_colour_scheme&amp;lt;/code&amp;gt; == 0)&lt;br /&gt;
: Here we use the &amp;lt;code&amp;gt;palette_2cc&amp;lt;/code&amp;gt; function even though we only want 1cc. To make the train look better we make one of the two company colours yellow rather than keeping the normal company colour range, using the &amp;lt;code&amp;gt;COLOUR_YELLOW&amp;lt;/code&amp;gt; from the default [http://newgrf-specs.tt-wiki.net/wiki/NML:List_of_default_colour_translation_palettes#Company_colour_helper_functions colour constants]. The other company colour will depend on what first company colour the user has selected, which we&#039;ll get from the &amp;lt;code&amp;gt;company_colour1&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables vehicle variable].&lt;br /&gt;
; real life colours (&amp;lt;code&amp;gt;param_colour_scheme&amp;lt;/code&amp;gt; == 2)&lt;br /&gt;
: The real life colours of this Dutch NS train are blue and yellow. We can force the train to be recoloured in these colours regardless of the company colours selected by the user. This is similar to the 1cc recolour from above, but now we return two specific colours rather than depend on the company colour variable.&lt;br /&gt;
; 2cc (default)&lt;br /&gt;
: This is what will be used as default if the GRF parameter setting is not equal to 0 or 2. Here a different way of returning the recolour sprite is used. The sprite number of the first 2cc recolour sprite can be found with the &amp;lt;code&amp;gt;base_sprite_2cc&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:General#General_variables variable]. Add &amp;lt;code&amp;gt;CB_RESULT_COLOUR_MAPPING_ADD_CC&amp;lt;/code&amp;gt; to this (see the [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback description]) to find the company colours used.&lt;br /&gt;
&lt;br /&gt;
With that the GRF parameter setting to choose the vehicle colours is done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Visual effect ==&lt;br /&gt;
The train currently has a visual effect (electric spark) on all parts of the vehicle, but only the first part has a pantograph. We can limit the effect to only this first part by using the &amp;lt;code&amp;gt;visual_effect_and_powered&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback]. Making a decision only on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] we can do this using a conditional assignment directly from the graphics block without the need for a switch block:&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
        visual_effect_and_powered:    return (position_in_consist % 4 == 0) ?&lt;br /&gt;
                                          visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER) :&lt;br /&gt;
                                          visual_effect_and_powered(VISUAL_EFFECT_DISABLE, 0, DISABLE_WAGON_POWER);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the first part of the vehicle we return the electric spark [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Train_properties visual effect] with an offset of 2 and not making this a powered wagon. For all other parts we disable the visual effect (offset doesn&#039;t matter now) and also not make this a powered wagon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lights out ==&lt;br /&gt;
There&#039;s one more thing that can be improved about this train. We still have not used the sprites that show no lights at the front and rear of the train. It would be nice if two EMUs are coupled that there are no lights on where the coupling is, only at the front and back.&lt;br /&gt;
&lt;br /&gt;
For this we have to change the graphics switch block, not referencing the spritesets for back and front directly, but using an intermediate switch block to decide if we want lights or not.&lt;br /&gt;
&lt;br /&gt;
Change the current switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      sw_icm_graphics_front;&lt;br /&gt;
    3:      sw_icm_graphics_rear;&lt;br /&gt;
    sw_icm_graphics_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This now links to two additional switch blocks, one for the front and one for the rear:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example&amp;quot;&amp;gt;&lt;br /&gt;
/* Only the frontmost vehicle should have its lights on */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_front, position_in_consist) {&lt;br /&gt;
    0: set_icm_front_lighted;&lt;br /&gt;
    set_icm_front;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Only the rearmost vehicle should have red lights */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_rear, position_in_consist_from_end) {&lt;br /&gt;
    0: set_icm_rear_lighted;&lt;br /&gt;
    set_icm_rear;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In case of the front part, we make a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. If it&#039;s the very first of the consist, show front lights, otherwise show no front lights for further connected EMUs.&lt;br /&gt;
&lt;br /&gt;
In case of the last part, we make a decision based on the &amp;lt;code&amp;gt;position_in_consist_from_end&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. This counts exactly opposite than &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt;, now starting from the back. If it&#039;s the very last of the consist, show rear lights, otherwise show no rear lights for further connected EMUs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example small&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
&lt;br /&gt;
    /* Define user-configurable parameters */&lt;br /&gt;
    param {&lt;br /&gt;
        /* There is one parameter, which can be used to alter the colour scheme */&lt;br /&gt;
        param_colour_scheme {&lt;br /&gt;
            type: int;&lt;br /&gt;
            name: string(STR_PARAM_COLOUR_SCHEME_NAME);&lt;br /&gt;
            desc: string(STR_PARAM_COLOUR_SCHEME_DESC);&lt;br /&gt;
            /* There are currently three possible values:&lt;br /&gt;
             * - 1cc&lt;br /&gt;
             * - 2cc (default)&lt;br /&gt;
             * - real-world&lt;br /&gt;
             */&lt;br /&gt;
            min_value: 0;&lt;br /&gt;
            max_value: 2;&lt;br /&gt;
            def_value: 1;&lt;br /&gt;
            names: {&lt;br /&gt;
                0: string(STR_PARAM_COLOUR_SCHEME_1CC);&lt;br /&gt;
                1: string(STR_PARAM_COLOUR_SCHEME_2CC);&lt;br /&gt;
                2: string(STR_PARAM_COLOUR_SCHEME_REAL);&lt;br /&gt;
            };&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    ELRL&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* --- Graphics callback  --- */&lt;br /&gt;
&lt;br /&gt;
/* Only the frontmost vehicle should have its lights on */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_front, position_in_consist) {&lt;br /&gt;
    0: set_icm_front_lighted;&lt;br /&gt;
    set_icm_front;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Only the rearmost vehicle should have red lights */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_rear, position_in_consist_from_end) {&lt;br /&gt;
    0: set_icm_rear_lighted;&lt;br /&gt;
    set_icm_rear;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* In the 3-part version, the 3rd car is invisible */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      sw_icm_graphics_front;&lt;br /&gt;
    3:      sw_icm_graphics_rear;&lt;br /&gt;
    sw_icm_graphics_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Cargo subtype text --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Colour mapping callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_colour_mapping, param_colour_scheme) {&lt;br /&gt;
    /* Emulate 1cc by making the first colour always yellow, this looks much better (and more realistic) */&lt;br /&gt;
    0: return palette_2cc(COLOUR_YELLOW, company_colour1);&lt;br /&gt;
    /* Use realistic colours, i.e. yellow + dark blue */&lt;br /&gt;
    2: return palette_2cc(COLOUR_YELLOW, COLOUR_DARK_BLUE);&lt;br /&gt;
    /* Use the default, i.e. 2 company colours */&lt;br /&gt;
    return base_sprite_2cc + CB_RESULT_COLOUR_MAPPING_ADD_CC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return item_icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Power, weight and TE are all applied to the front vehicle only */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
        colour_mapping:               sw_icm_colour_mapping;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
        /* Capacity is per part */&lt;br /&gt;
        cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
        /* In the purchase menu, we want to show the capacity for the three-part version,&lt;br /&gt;
         * i.e. divide the capacity of three cars across four */&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
        /* Only the front vehicle has a visual effect */&lt;br /&gt;
        visual_effect_and_powered:    return (position_in_consist % 4 == 0) ?&lt;br /&gt;
                                          visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER) :&lt;br /&gt;
                                          visual_effect_and_powered(VISUAL_EFFECT_DISABLE, 0, DISABLE_WAGON_POWER);&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
        /* Only the front vehicle has power */&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
        //purchase_power:               return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
        /* Only the front vehicle has weight */&lt;br /&gt;
        weight:                       sw_icm_weight;&lt;br /&gt;
        /* Only the front vehicle has TE */&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
        /* Only 1/3 of the weight is on the driving weels. */&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The complete language file ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;example small&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_NAME :Colour scheme&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_DESC :Select the type of colour scheme to use&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_1CC  :One company colour&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_2CC  :Two company colours&lt;br /&gt;
STR_PARAM_COLOUR_SCHEME_REAL :Real-world colours&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now our train is really completed and that makes this the end of the train example.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Parameters|Object}}&lt;/div&gt;</summary>
		<author><name>Hirundo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_four_part_refit&amp;diff=7830</id>
		<title>NMLTutorial/Train four part refit</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_four_part_refit&amp;diff=7830"/>
		<updated>2011-09-04T14:31:06Z</updated>

		<summary type="html">&lt;p&gt;Hirundo: Some more icm-&amp;gt;item_icm fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Train three part articulated|third part]] of the train example. The three part EMU will be made refittable to a four part EMU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What&#039;s going to happen ==&lt;br /&gt;
A lot of things need to be added to make this train refittable between three and four parts.&lt;br /&gt;
&lt;br /&gt;
The method used to do this is actually the other way round than the user will think from the behaviour ingame. The train will be changed to a four part EMU. For the (default) three part refit one of these four parts will be hidden. A lot of switches will be used to make the train look right, make it have the correct capacity, power, weight, running costs and tractive effort.&lt;br /&gt;
&lt;br /&gt;
There are some drawbacks to this method. There&#039;s no way to charge the user for puchasing the extra vehicle part. Also autoreplacing will be difficult, as there&#039;s now way for the user to select which vehicle length they want. For that reason the author of this tutorial thinks making two different vehicles and having both available from the purchase menu is a better solution, but this method is a good illustration for some of the more advanced features of NML. It&#039;s up to you to decide which implementation you think is best for your vehicles.&lt;br /&gt;
&lt;br /&gt;
What we&#039;ll be doing:&lt;br /&gt;
* Add the refit option;&lt;br /&gt;
* Make the graphics work;&lt;br /&gt;
* Add callbacks to supply the correct vehicle properties;&lt;br /&gt;
* Make the purchase menu display the correct values.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Refit option ==&lt;br /&gt;
The refit option will be added by means of the &amp;quot;cargo subtype&amp;quot;. This allows to split each cargo into multiple entities which can be assigned different properties by means of other callbacks.&lt;br /&gt;
&lt;br /&gt;
The first step towards this is defining names for these separate entries using the &amp;lt;code&amp;gt;cargo_subtype_text&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback]. This callback requires the use of a switch, so reference a switch from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch itself will use the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. This variable starts at 0 and will be increased by 1 until the callback returns &amp;lt;code&amp;gt;0xFF&amp;lt;/code&amp;gt;. Return strings to use as cargo subtype. Each returned string will be a separate cargo subtype:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds two cargo subtypes. Also add these strings to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
The graphics defined previously were for a three part vehicle. Now we have to make this into a four part vehicle and hide one wagon for the three part refit.&lt;br /&gt;
&lt;br /&gt;
=== Four part articulated vehicle ===&lt;br /&gt;
In order to make the vehicle four parts, the articulated vehicle callback switch needs to be changed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return item_icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is done by changing the value range from &amp;lt;code&amp;gt;1 .. 2&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;1 .. 3&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Start/stop callback ===&lt;br /&gt;
The start/stop callback checking the vehicle length needs to be changed as well. If we still want a maximum of four EMUs, the maximum length will now be 4 * 4 instead of 4 * 3. This means changing the switch for this callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is done by changing the value range from &amp;lt;code&amp;gt;1 .. 12&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;1 .. 16&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
Now that the vehicle is four parts, the default graphics switch needs to be changed as well to allow for two middle parts instead of one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    3:      set_icm_rear_lighted;&lt;br /&gt;
    sw_icm_graphics_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of modulo 3 we&#039;re now taking modulo 4. And the value for the rear vehicle part was changed from 2 to 3. For the middle parts, we also need to hide the one of the wagons for the three part EMU. Therefore we can&#039;t directly reference the spriteset but need an extra intermediate switch block.&lt;br /&gt;
&lt;br /&gt;
The extra switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even an expression this advanced can be used for switch block decision. Here we again check the position of the vehicle part, but also which cargo subtype is used for this vehicle. If it is the three part EMU (cargo subtype 0) AND it is the third vehicle part (position 2 counting from 0), we hide this vehicle part by displaying no graphics for it. In all other cases we display the regular middle part.&lt;br /&gt;
&lt;br /&gt;
=== Vehicle length ===&lt;br /&gt;
If you were to encode the result so far as a NewGRF, you end up with a three part train that has a big gap between the second and last part. This is because it&#039;s essentially still a four part vehicle, just with no graphics for the third part. This can be solved by changing the length of the two middle parts. If we make the second part (7/8) long and the third part (1/8), both together are a full wagon length, completely hiding the invisible third part.&lt;br /&gt;
&lt;br /&gt;
This is done by means of the &amp;lt;code&amp;gt;shorten_vehicle&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback], referencing a switch block as we first need to differentiate between the two cargo subtypes and then by the position in consist. Reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we get the two switch blocks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second of these switch blocks (called first from the graphics block) differentiates between the two cargo subtypes. For subtype 0 (three part vehicle) we need to do the shortenings and reference the first switch block. For the four part vehicle we need no shortening, so directly return to &amp;quot;shorten&amp;quot; to full length.&lt;br /&gt;
&lt;br /&gt;
The first switch again makes a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] we&#039;ve seen several times now. As said, the second part will be shortened to (7/8), the third part to (1/8) and the front and back part are kept full length (8/8).&lt;br /&gt;
&lt;br /&gt;
Now the vehicle looks good in both refits.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Vehicle properties ==&lt;br /&gt;
Both refits still have identical properties. Surely the four part EMU has a higher capacity. We&#039;ll also change the running costs, power, weight and tractive effort depending on the refit chosen. This is all done by callbacks. You can find the available vehicle callbacks [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks here], with the second table especially on callbacks that change certain properties.&lt;br /&gt;
&lt;br /&gt;
=== Running cost factor ===&lt;br /&gt;
You can easily imagine that the longer vehicle will be more expensive to run. The three part has a running cost factor of 100, the four part will get a factor of 150. This requires adding the &amp;lt;code&amp;gt;running_cost_factor&amp;lt;/code&amp;gt; callback to the graphics block. From there we can link to a switch block and base the decision on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. A different method as shown below is not to use a switch block but to make the decision directly from the graphics block using a conditional assignment. We&#039;ve used a conditional assignment [[Train_single_engine#Templates|before]] in one of the template blocks.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In case the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; is 1 (the four part vehicle), a running cost factor of 150 is used. Otherwise, a factor of 100 is used. If you&#039;d rather used a switch block then that&#039;s up to you. Just reference one from the graphics block instead of the conditional assignment and use the switch block to make the decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity ===&lt;br /&gt;
The cargo capacity is 36 passengers per unit. Now the three part EMU will have a capacity that is too high, because it technically is a four part EMU with one part hidden. We need to give this hidden part 0 capacity.&lt;br /&gt;
&lt;br /&gt;
This is done by the &amp;lt;code&amp;gt;cargo_capacity&amp;lt;/code&amp;gt; callback. If the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; is 0 and the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; is the third part, we give it 0 capacity. Else it will get 36 capacity. Also this can be done directly from the graphics block, using a slightly more advanced conditional assignment. Of course you could again have used a switch block here, but there&#039;s no need for that in this case.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Power ===&lt;br /&gt;
The power of the four part vehicle will be higher. Let&#039;s use a switch block this time. Of course a conditional assignment could be used here, but compare this example with the running cost factor yourself. The callback used here is called &amp;lt;code&amp;gt;power&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will again make a decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable. The callback must return the vehicle power in horsepower (imperial) and this must be an integer value. Because we know the power in kW, a little calculation is needed which NML can do for you. Returning the integer is done by the &amp;lt;code&amp;gt;int()&amp;lt;/code&amp;gt; function that turns a (decimal) number into an integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Weight ===&lt;br /&gt;
Of course you could have done the calculation yourself and put the rounded values in the switch block. That we&#039;ll do for the weight of the vehicle. The callback used here is called &amp;lt;code&amp;gt;weight&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Again, reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
weight:                       sw_icm_weight;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will again make a decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable. The weight here must be specified in tons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tractive effort coefficient===&lt;br /&gt;
The last property to sort out is the tractive effort. The callback used here is called &amp;lt;code&amp;gt;tractive_effort_coefficient&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Again, reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the switch block we&#039;ll actually calculate the tractive effort coefficient:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;The technical background of the tractive effort coefficient is that it must be supplied as value between 0 and 255, with 255 equal to 100%. The tractive effort coefficient itself is calculated by multiplying the friction coefficient (see [http://en.wikipedia.org/wiki/Rail_adhesion Wikipedia] for it&#039;s meaning) with the percentage of weight that is on driven wheels. I this case we use a friction of 30%. In real life the three part vehicle has 12 axles of which 4 powered. The four part vehicle has 16 axles of which 6 powered. Assuming an equal distribution of weight along the length of the vehicle, the three part vehicle has 33.3% of it&#039;s weight on powered wheels. The four part vehicle has 37.5% of it&#039;s weight on powered wheels. Multiply both by the friction coefficient and the factor of 255 and you have the tractive effort coefficient.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;If you don&#039;t provide a tractive effort coefficient, the game will assume a friction coefficient of 0.3 and all axles powered. A tractive effort coefficient of 100% you&#039;ll only get with 100% friction and and all axles powered. This is unrealistic for railroads but can be used for maglev when there actually is no contact between vehicle and guideway.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu ==&lt;br /&gt;
With all these callbacks we&#039;ve sort of broken the display of properties in the purchase menu. This is because the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] is not available in the purchase menu and &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable is always 0 in the purchase menu. The latter can be to our advantage if we want to display the properties of the shorter refit, but the other needs some fixing.&lt;br /&gt;
&lt;br /&gt;
=== Running cost factor ===&lt;br /&gt;
This callback was only based on &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt;, so no fixing needed here.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity ===&lt;br /&gt;
The capacity used both variables, so some fixing is in order here. We want to display 36*3 as capacity. Because capacity is defined per unit and our vehicle is technically four units, we need to divide this over four units: 36*3/4. Add the &amp;lt;code&amp;gt;purchase_cargo_capacity&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback] to the graphics block and return this value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Power, weight and tractive effort coefficient ===&lt;br /&gt;
Luckily, these are also only based on the cargo subtype variable, so no fixing needed. If you wanted a different value to be displayed in the purchase menu, you&#039;d use the &amp;lt;code&amp;gt;purchase_power&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;purchase_weight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;purchase_tractive_effort_coefficient&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callbacks] to do this. And if you want to know, the running cost factor would logically use the &amp;lt;code&amp;gt;purchase_running_cost_factor&amp;lt;/code&amp;gt; callback.&lt;br /&gt;
&lt;br /&gt;
=== Additional text ===&lt;br /&gt;
We want to inform the user that this train has an option to refit it into a four part version and that the properties shown are for the three part version. For this we&#039;ll use the &amp;lt;code&amp;gt;additional_text&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback] which we also used in the tram example. It can directly return a string from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also don&#039;t forget to add this string to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This means our vehicle now works like it should with the two refits. Encode it into a NewGRF if you like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    ELRL&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* --- Graphics callback  --- */&lt;br /&gt;
&lt;br /&gt;
/* In the 3-part version, the 3rd car is invisible */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    3:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Cargo subtype text --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return item_icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Power, weight and TE are all applied to the front vehicle only */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
        /* Capacity is per part */&lt;br /&gt;
        cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
        /* In the purchase menu, we want to show the capacity for the three-part version,&lt;br /&gt;
         * i.e. divide the capacity of three cars across four */&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
        /* Only the front vehicle has a visual effect */&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
        /* Only the front vehicle has power */&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
        /* Only the front vehicle has weight */&lt;br /&gt;
        weight:                       sw_icm_weight;&lt;br /&gt;
        /* Only the front vehicle has TE */&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
        /* Only 1/3 of the weight is on the driving weels. */&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language file so far ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you like, this train is done. If you like to continue, you can learn about GRF parameters and then we&#039;ll add a parameter setting to display this train in either 1cc, 2cc or real life colours.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train three part articulated|Parameters}}&lt;/div&gt;</summary>
		<author><name>Hirundo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_three_part_articulated&amp;diff=7829</id>
		<title>NMLTutorial/Train three part articulated</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_three_part_articulated&amp;diff=7829"/>
		<updated>2011-09-04T14:27:37Z</updated>

		<summary type="html">&lt;p&gt;Hirundo: Fix callbacks (icm-&amp;gt;item_icm) and final comment&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Train single engine|second part]] of the train example. The train will be made into an articulated EMU that can be purchased all at once.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Callbacks ==&lt;br /&gt;
Except the articulated vehicle callback, we&#039;ll add two more callbacks to only allow attaching more of these multiple units (and not other trains/wagons) and to give the train a maximum length.&lt;br /&gt;
&lt;br /&gt;
The callbacks and switch blocks that are needed for this will be discussed below. What callbacks are available for vehicles can be found in the [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks NML Documentation]. From here you can decide what callbacks suit your needs and find their names to be used in the graphics block.&lt;br /&gt;
&lt;br /&gt;
=== Articulated part callback ===&lt;br /&gt;
We have seen this one before in the tram example. Returning a single value is not enough for this callback, so we need to reference a switch block to handle the callback.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The callback needs to return the identifier of a vehicle for as long as you want to keep adding parts and return &amp;lt;code&amp;gt;0xFF&amp;lt;/code&amp;gt; to stop the process. During the callback the game will continuously call the callback, each time increasing the &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:General variable] by one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add two articulated parts, for a total of three */&lt;br /&gt;
    1 .. 2: return item_icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This causes the callback to be called three times, adding two extra parts to the &amp;lt;code&amp;gt;item_icm&amp;lt;/code&amp;gt; vehicle. For an extended explanation of this, see the tram example.&lt;br /&gt;
&lt;br /&gt;
=== Start/stop callback ===&lt;br /&gt;
The start/stop callback is called whenever a vehicle is started in the depot and decides if the vehicle may leave the depot. The callback must return &amp;lt;code&amp;gt;0xFF&amp;lt;/code&amp;gt; to allow the vehicle to leave the depot. If you want to prevent the vehicle from leaving the depot, the callback must return a string containing an error message.&lt;br /&gt;
&lt;br /&gt;
We want to use this callback to check the vehicle length. As such it makes sense to base the decision on the length of the train, which can be found using the &amp;lt;code&amp;gt;num_vehs_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. Because we need to base a decision on some variable, we&#039;ll use a switch block to do that.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We want to limit our train length to a maximum of four coupled EMUs. As each EMU has a length of three, the total possible train length is twelve. So for train lengths 1 to 12 we want to return &amp;lt;code&amp;gt;0xFF&amp;lt;/code&amp;gt; (and allow the train to leave the depot). For any other train length we return a string to disallow starting the train and informing the user why that is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12 cars) */&lt;br /&gt;
    1 .. 12: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we added a new string, define it in the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wagon attach callback ===&lt;br /&gt;
We only want to allow attaching more of the same EMUs to this train. Amongst others, the callback can return a custom string to disallow or return &amp;lt;code&amp;gt;CB_RESULT_ATTACH_ALLOW&amp;lt;/code&amp;gt; to allow attaching. The decision must be made on the basis of the identifier of the wagon that is being attached. We can use the &amp;lt;code&amp;gt;vehicle_type_id&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] to make that decision, using a switch block.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will be the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the attached wagon is of the type &#039;&#039;item_icm&#039;&#039;, it is allowed. Otherwise, a custom error message is displayed. This obviously means that we have to add this message to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
The final step in making this work is adding the graphics for the second and third part of the train. This is the same as in the tram example: point to a switch from the graphics block, make a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] and point to the spritesets from there.&lt;br /&gt;
&lt;br /&gt;
We already have the graphics and spritesets defined, so that&#039;s no problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 3) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    2:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular switch block actually first does a calculation on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; variable before making a decision on the result of that calculation. Here the modulo 3 of the value of &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; is calculated (&amp;lt;code&amp;gt;%&amp;lt;/code&amp;gt; is the modulo operator, see [http://en.wikipedia.org/wiki/Modulo_operation Wikipedia] for more details on modulo but basically it&#039;s the remainder after devision (by three in this case)).&lt;br /&gt;
&lt;br /&gt;
So for the first three vehicle parts the expression will yield 0, 1 and 2. For part four through six, it will again yield 0, 1 and 2, etc. The callback decision is then made on these three values alone: for part 0 use graphics for the train front, for part 2 use graphics for the train end and for all other parts use graphics for the middle.&lt;br /&gt;
&lt;br /&gt;
Also don&#039;t forget to reference this switch instead of the spriteset directly from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu sprite ==&lt;br /&gt;
The spriteset for the purchase menu sprite is already there. We only need to reference it from the graphics block&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    RAIL, ELRL, MONO, MGLV,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 3) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    2:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 2: return item_icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12 cars) */&lt;br /&gt;
    1 .. 12: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language file so far ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is now a working 3-part EMU. In real life, the EMU is also available as a 4-part variant. In the next part of the tutorial, we will add the option to choose between a 3- and 4 part EMU via a refit.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train single engine|Train four part refit}}&lt;/div&gt;</summary>
		<author><name>Hirundo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_four_part_refit&amp;diff=7828</id>
		<title>NMLTutorial/Train four part refit</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_four_part_refit&amp;diff=7828"/>
		<updated>2011-09-04T14:13:58Z</updated>

		<summary type="html">&lt;p&gt;Hirundo: /* Total code so far */ Some fixes to the code; needs more review.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Train three part articulated|third part]] of the train example. The three part EMU will be made refittable to a four part EMU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What&#039;s going to happen ==&lt;br /&gt;
A lot of things need to be added to make this train refittable between three and four parts.&lt;br /&gt;
&lt;br /&gt;
The method used to do this is actually the other way round than the user will think from the behaviour ingame. The train will be changed to a four part EMU. For the (default) three part refit one of these four parts will be hidden. A lot of switches will be used to make the train look right, make it have the correct capacity, power, weight, running costs and tractive effort.&lt;br /&gt;
&lt;br /&gt;
There are some drawbacks to this method. There&#039;s no way to charge the user for puchasing the extra vehicle part. Also autoreplacing will be difficult, as there&#039;s now way for the user to select which vehicle length they want. For that reason the author of this tutorial thinks making two different vehicles and having both available from the purchase menu is a better solution, but this method is a good illustration for some of the more advanced features of NML. It&#039;s up to you to decide which implementation you think is best for your vehicles.&lt;br /&gt;
&lt;br /&gt;
What we&#039;ll be doing:&lt;br /&gt;
* Add the refit option;&lt;br /&gt;
* Make the graphics work;&lt;br /&gt;
* Add callbacks to supply the correct vehicle properties;&lt;br /&gt;
* Make the purchase menu display the correct values.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Refit option ==&lt;br /&gt;
The refit option will be added by means of the &amp;quot;cargo subtype&amp;quot;. This allows to split each cargo into multiple entities which can be assigned different properties by means of other callbacks.&lt;br /&gt;
&lt;br /&gt;
The first step towards this is defining names for these separate entries using the &amp;lt;code&amp;gt;cargo_subtype_text&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback]. This callback requires the use of a switch, so reference a switch from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch itself will use the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. This variable starts at 0 and will be increased by 1 until the callback returns &amp;lt;code&amp;gt;0xFF&amp;lt;/code&amp;gt;. Return strings to use as cargo subtype. Each returned string will be a separate cargo subtype:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds two cargo subtypes. Also add these strings to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
The graphics defined previously were for a three part vehicle. Now we have to make this into a four part vehicle and hide one wagon for the three part refit.&lt;br /&gt;
&lt;br /&gt;
=== Four part articulated vehicle ===&lt;br /&gt;
In order to make the vehicle four parts, the articulated vehicle callback switch needs to be changed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is done by changing the value range from &amp;lt;code&amp;gt;1 .. 2&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;1 .. 3&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Start/stop callback ===&lt;br /&gt;
The start/stop callback checking the vehicle length needs to be changed as well. If we still want a maximum of four EMUs, the maximum length will now be 4 * 4 instead of 4 * 3. This means changing the switch for this callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is done by changing the value range from &amp;lt;code&amp;gt;1 .. 12&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;1 .. 16&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
Now that the vehicle is four parts, the default graphics switch needs to be changed as well to allow for two middle parts instead of one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    3:      set_icm_rear_lighted;&lt;br /&gt;
    sw_icm_graphics_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of modulo 3 we&#039;re now taking modulo 4. And the value for the rear vehicle part was changed from 2 to 3. For the middle parts, we also need to hide the one of the wagons for the three part EMU. Therefore we can&#039;t directly reference the spriteset but need an extra intermediate switch block.&lt;br /&gt;
&lt;br /&gt;
The extra switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even an expression this advanced can be used for switch block decision. Here we again check the position of the vehicle part, but also which cargo subtype is used for this vehicle. If it is the three part EMU (cargo subtype 0) AND it is the third vehicle part (position 2 counting from 0), we hide this vehicle part by displaying no graphics for it. In all other cases we display the regular middle part.&lt;br /&gt;
&lt;br /&gt;
=== Vehicle length ===&lt;br /&gt;
If you were to encode the result so far as a NewGRF, you end up with a three part train that has a big gap between the second and last part. This is because it&#039;s essentially still a four part vehicle, just with no graphics for the third part. This can be solved by changing the length of the two middle parts. If we make the second part (7/8) long and the third part (1/8), both together are a full wagon length, completely hiding the invisible third part.&lt;br /&gt;
&lt;br /&gt;
This is done by means of the &amp;lt;code&amp;gt;shorten_vehicle&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback], referencing a switch block as we first need to differentiate between the two cargo subtypes and then by the position in consist. Reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we get the two switch blocks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second of these switch blocks (called first from the graphics block) differentiates between the two cargo subtypes. For subtype 0 (three part vehicle) we need to do the shortenings and reference the first switch block. For the four part vehicle we need no shortening, so directly return to &amp;quot;shorten&amp;quot; to full length.&lt;br /&gt;
&lt;br /&gt;
The first switch again makes a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] we&#039;ve seen several times now. As said, the second part will be shortened to (7/8), the third part to (1/8) and the front and back part are kept full length (8/8).&lt;br /&gt;
&lt;br /&gt;
Now the vehicle looks good in both refits.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Vehicle properties ==&lt;br /&gt;
Both refits still have identical properties. Surely the four part EMU has a higher capacity. We&#039;ll also change the running costs, power, weight and tractive effort depending on the refit chosen. This is all done by callbacks. You can find the available vehicle callbacks [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks here], with the second table especially on callbacks that change certain properties.&lt;br /&gt;
&lt;br /&gt;
=== Running cost factor ===&lt;br /&gt;
You can easily imagine that the longer vehicle will be more expensive to run. The three part has a running cost factor of 100, the four part will get a factor of 150. This requires adding the &amp;lt;code&amp;gt;running_cost_factor&amp;lt;/code&amp;gt; callback to the graphics block. From there we can link to a switch block and base the decision on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. A different method as shown below is not to use a switch block but to make the decision directly from the graphics block using a conditional assignment. We&#039;ve used a conditional assignment [[Train_single_engine#Templates|before]] in one of the template blocks.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In case the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; is 1 (the four part vehicle), a running cost factor of 150 is used. Otherwise, a factor of 100 is used. If you&#039;d rather used a switch block then that&#039;s up to you. Just reference one from the graphics block instead of the conditional assignment and use the switch block to make the decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity ===&lt;br /&gt;
The cargo capacity is 36 passengers per unit. Now the three part EMU will have a capacity that is too high, because it technically is a four part EMU with one part hidden. We need to give this hidden part 0 capacity.&lt;br /&gt;
&lt;br /&gt;
This is done by the &amp;lt;code&amp;gt;cargo_capacity&amp;lt;/code&amp;gt; callback. If the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; is 0 and the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; is the third part, we give it 0 capacity. Else it will get 36 capacity. Also this can be done directly from the graphics block, using a slightly more advanced conditional assignment. Of course you could again have used a switch block here, but there&#039;s no need for that in this case.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Power ===&lt;br /&gt;
The power of the four part vehicle will be higher. Let&#039;s use a switch block this time. Of course a conditional assignment could be used here, but compare this example with the running cost factor yourself. The callback used here is called &amp;lt;code&amp;gt;power&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will again make a decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable. The callback must return the vehicle power in horsepower (imperial) and this must be an integer value. Because we know the power in kW, a little calculation is needed which NML can do for you. Returning the integer is done by the &amp;lt;code&amp;gt;int()&amp;lt;/code&amp;gt; function that turns a (decimal) number into an integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Weight ===&lt;br /&gt;
Of course you could have done the calculation yourself and put the rounded values in the switch block. That we&#039;ll do for the weight of the vehicle. The callback used here is called &amp;lt;code&amp;gt;weight&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Again, reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
weight:                       sw_icm_weight;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will again make a decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable. The weight here must be specified in tons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tractive effort coefficient===&lt;br /&gt;
The last property to sort out is the tractive effort. The callback used here is called &amp;lt;code&amp;gt;tractive_effort_coefficient&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Again, reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the switch block we&#039;ll actually calculate the tractive effort coefficient:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;The technical background of the tractive effort coefficient is that it must be supplied as value between 0 and 255, with 255 equal to 100%. The tractive effort coefficient itself is calculated by multiplying the friction coefficient (see [http://en.wikipedia.org/wiki/Rail_adhesion Wikipedia] for it&#039;s meaning) with the percentage of weight that is on driven wheels. I this case we use a friction of 30%. In real life the three part vehicle has 12 axles of which 4 powered. The four part vehicle has 16 axles of which 6 powered. Assuming an equal distribution of weight along the length of the vehicle, the three part vehicle has 33.3% of it&#039;s weight on powered wheels. The four part vehicle has 37.5% of it&#039;s weight on powered wheels. Multiply both by the friction coefficient and the factor of 255 and you have the tractive effort coefficient.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;If you don&#039;t provide a tractive effort coefficient, the game will assume a friction coefficient of 0.3 and all axles powered. A tractive effort coefficient of 100% you&#039;ll only get with 100% friction and and all axles powered. This is unrealistic for railroads but can be used for maglev when there actually is no contact between vehicle and guideway.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu ==&lt;br /&gt;
With all these callbacks we&#039;ve sort of broken the display of properties in the purchase menu. This is because the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] is not available in the purchase menu and &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable is always 0 in the purchase menu. The latter can be to our advantage if we want to display the properties of the shorter refit, but the other needs some fixing.&lt;br /&gt;
&lt;br /&gt;
=== Running cost factor ===&lt;br /&gt;
This callback was only based on &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt;, so no fixing needed here.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity ===&lt;br /&gt;
The capacity used both variables, so some fixing is in order here. We want to display 36*3 as capacity. Because capacity is defined per unit and our vehicle is technically four units, we need to divide this over four units: 36*3/4. Add the &amp;lt;code&amp;gt;purchase_cargo_capacity&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback] to the graphics block and return this value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Power, weight and tractive effort coefficient ===&lt;br /&gt;
Luckily, these are also only based on the cargo subtype variable, so no fixing needed. If you wanted a different value to be displayed in the purchase menu, you&#039;d use the &amp;lt;code&amp;gt;purchase_power&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;purchase_weight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;purchase_tractive_effort_coefficient&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callbacks] to do this. And if you want to know, the running cost factor would logically use the &amp;lt;code&amp;gt;purchase_running_cost_factor&amp;lt;/code&amp;gt; callback.&lt;br /&gt;
&lt;br /&gt;
=== Additional text ===&lt;br /&gt;
We want to inform the user that this train has an option to refit it into a four part version and that the properties shown are for the three part version. For this we&#039;ll use the &amp;lt;code&amp;gt;additional_text&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback] which we also used in the tram example. It can directly return a string from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also don&#039;t forget to add this string to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This means our vehicle now works like it should with the two refits. Encode it into a NewGRF if you like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    ELRL&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* --- Graphics callback  --- */&lt;br /&gt;
&lt;br /&gt;
/* In the 3-part version, the 3rd car is invisible */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    3:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Cargo subtype text --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return item_icm;&lt;br /&gt;
    return 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return 0xFF;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Power, weight and TE are all applied to the front vehicle only */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
        /* Capacity is per part */&lt;br /&gt;
        cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
        /* In the purchase menu, we want to show the capacity for the three-part version,&lt;br /&gt;
         * i.e. divide the capacity of three cars across four */&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
        /* Only the front vehicle has a visual effect */&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
        /* Only the front vehicle has power */&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
        /* Only the front vehicle has weight */&lt;br /&gt;
        weight:                       sw_icm_weight;&lt;br /&gt;
        /* Only the front vehicle has TE */&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
        /* Only 1/3 of the weight is on the driving weels. */&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language file so far ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you like, this train is done. If you like to continue, you can learn about GRF parameters and then we&#039;ll add a parameter setting to display this train in either 1cc, 2cc or real life colours.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train three part articulated|Parameters}}&lt;/div&gt;</summary>
		<author><name>Hirundo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train&amp;diff=7804</id>
		<title>NMLTutorial/Train</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train&amp;diff=7804"/>
		<updated>2011-08-30T20:28:50Z</updated>

		<summary type="html">&lt;p&gt;Hirundo: spelling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This example will show you how to make a train. This particular train is the Dutch ICM that exists as a three and four part multiple unit. In this example we&#039;ll first make a one-part train. If you want to make such a train yourself, you can stop there. Then we&#039;ll continue making this into a three-part multiple unit. This technique can also be used for steam trains with a tender. If that&#039;s all you need, you can stop here. If you want to see some more callback applications, continue where we&#039;ll make this train refittable to a four-part multiple unit. Lastly, a parameter option will be added to select if you want this train in 1cc, 2cc or real colours.&lt;br /&gt;
&lt;br /&gt;
Some knowledge from the the previous examples is assumed. The most basic things will not be explained in detailed, you must apply the rule that everything must be defined before it can be referenced yourself and that you know how to link callbacks to switch blocks. If you&#039;re still uncomfortable with those things, go back and try the road vehicle and tram example (again). It&#039;s best if you at least have made one NewGRF in NML yourself (either using the examples or one of your own) before embarking on this train example. This example uses some of the more advanced features of NML, which you may not understand if you don&#039;t understand the basics yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Folder structure ==&lt;br /&gt;
For this example we&#039;ll assume the following folder structure. There will be one language file in the &#039;&#039;lang&#039;&#039; folder, one graphics file in the &#039;&#039;gfx&#039;&#039; folder. These two folders sit together with the main NML file in one project folder. We&#039;ll not be using &#039;&#039;custom_tags.txt&#039;&#039; this time:&lt;br /&gt;
&lt;br /&gt;
 tram_example&lt;br /&gt;
  |- lang&lt;br /&gt;
  |   |- english.lng&lt;br /&gt;
  |- gfx&lt;br /&gt;
  |   |- icm.png&lt;br /&gt;
  |- example_train.nml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Language files ==&lt;br /&gt;
Only English as default language with NewGRF name and description already defined. More things will be added to the language file as we go.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== NML file ==&lt;br /&gt;
Start the NML file by adding a grf block.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When working with trains, a railtypetable is a useful means to have the train on the correct railtype, regardless of track sets loaded by the user.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Tram purchase menu|Railtypetable}}&lt;/div&gt;</summary>
		<author><name>Hirundo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Installation&amp;diff=7673</id>
		<title>NMLTutorial/Installation</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Installation&amp;diff=7673"/>
		<updated>2011-08-25T14:42:33Z</updated>

		<summary type="html">&lt;p&gt;Hirundo: Some minor spelling fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&lt;br /&gt;
NML is written in Python and therefore can be made to run on every operating system that can run Python. This includes the popular operating sytems Linux, MacOS and Windows. Below you&#039;ll find a description on how to install NML and how to use the command-line NML program on your operating system (MacOS description currently missing, as I don&#039;t have that, but please add it).&lt;br /&gt;
&lt;br /&gt;
{{Note|The NML Documentation reflects the latest state of the NML program. Make sure to update your NML regularly, especially if you find something not working that should work according to the documentation.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Linux ==&lt;br /&gt;
NML requires Python, the Python Image Library and PLY (Python Lex-Yacc). These three things are best installed from your package manager. If you&#039;re looking to compiling NML yourself, you also need the Python Setuptools. Note that NML currently only runs on Python 2.5 through 2.7, but not 3.x. Look for the following in your package manager:&lt;br /&gt;
* python (you might already have this)&lt;br /&gt;
* python-imaging (pil)&lt;br /&gt;
* python-ply&lt;br /&gt;
* python-setuptools&lt;br /&gt;
&lt;br /&gt;
=== Installing NML as precompiled binary (recommended) ===&lt;br /&gt;
The latest version of NML is available as RPM package from the #openttdcoop DevZone. You can find it here: http://bundles.openttdcoop.org/nml/nightlies/LATEST/rpms/. This package is known to work on openSUSE and Red Hat (including Fedora and CentOS) distributions.&lt;br /&gt;
&lt;br /&gt;
You can use the terminal to install this package through your package manager (make sure to run it as superuser). For example on Fedora:&lt;br /&gt;
&lt;br /&gt;
 sudo bash&lt;br /&gt;
 yum install &amp;lt;nowiki&amp;gt;http://bundles.openttdcoop.org/nml/nightlies/LATEST/rpms/nml-rXXXX-suseYYYY.noarch.rpm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure to replace XXXX and YYYY in the url with the actual version numbers you found via the link above. Enter &amp;quot;y&amp;quot; when asked and when done don&#039;t forget to &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; sudo again, preventing yourself from doing stupid things from this point.&lt;br /&gt;
&lt;br /&gt;
=== Compiling NML yourself ===&lt;br /&gt;
The other option to get NML is to compile it yourself. First you need to get the source from http://bundles.openttdcoop.org/nml/nightlies/LATEST/ or via Mercurial checkout from http://hg.openttdcoop.org/nml (&amp;lt;code&amp;gt;hg clone &amp;lt;nowiki&amp;gt;http://hg.openttdcoop.org/nml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Also this time you need the terminal as superuser. Then change directory to the (extracted) NML source and run &amp;lt;code&amp;gt;python setup.py install&amp;lt;/code&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 sudo bash&lt;br /&gt;
 cd ~/Downloads/nml-rXXXX&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
=== Using NML ===&lt;br /&gt;
As said before, NML is a command-line program and therefore doesn&#039;t have a GUI; much like GRFCodec in fact. That means you need to run it from a terminal window. The NML program itself is called &amp;lt;code&amp;gt;nmlc&amp;lt;/code&amp;gt; and the general usage is &amp;lt;code&amp;gt;nmlc [options] &amp;lt;filename&amp;gt;&amp;lt;/code&amp;gt;. First change directory to the directory which has your nml file. Then run the nmlc program to compile your grf. For example:&lt;br /&gt;
&lt;br /&gt;
 cd ~/grfs/mygrf&lt;br /&gt;
 nmlc -c --grf mygrf.grf mygrf.nml&lt;br /&gt;
&lt;br /&gt;
This will encode the nml file ~/grfs/mygrf/mygrf.nml into the grf file ~/grfs/mygrf/mygrf.grf. The -c option is not mandatory, but crops extraneous blue from sprites, reducing the filesize of the grf file.&lt;br /&gt;
&lt;br /&gt;
All command-line options available to NML are available via the &amp;lt;code&amp;gt;nmlc -h&amp;lt;/code&amp;gt; command and are also [[#NML Command-line Options|listed]] on this page. Now that you have NML and know how to use it, you can continue this tutorial to learn how to create an actual grf file using NML.&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
NML is available as pre-built (32 bit) Windows executable from the #openttdcoop DevZone, so there is no need to compile it yourself.&lt;br /&gt;
&lt;br /&gt;
=== Installing NML ===&lt;br /&gt;
Go to http://bundles.openttdcoop.org/nml/nightlies/LATEST/ and download nml-rXXXX-windows-win32.zip, replacing XXXX with the actual version number of the package. The zip file contains a number of files that all need to stay together, so extract the zip file entirely into a single folder, for example D:\grfs\nml.&lt;br /&gt;
&lt;br /&gt;
If you leave it at this, you can already start to use NML, but only from that folder. This makes compiling grfs a bit more difficult as you have to write full paths when encoding a grf file. If you want to run NML from any directory, you need to add the directory containing the nmlc.exe executable to your PATH environment variable. As this can break Windows if you don&#039;t do this properly, we&#039;ll not be explaining this here and go for the long route instead. You&#039;re of course free to change your PATH yourself; if you do, you&#039;re probably also smart enough to know how to change the commands as explained in the section below.&lt;br /&gt;
&lt;br /&gt;
=== Using NML ===&lt;br /&gt;
As said before, NML is a command-line program and therefore doesn&#039;t have a GUI; much like GRFCodec in fact. That means you need to run it from a command prompt window. You can start the command prompt from Start &amp;gt; Programs &amp;gt; Accessories &amp;gt; Command Prompt. Or by entering &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; into the Run dialog or the Start menu search bar.&lt;br /&gt;
&lt;br /&gt;
Next, you need to change directory to the folder where you have nmlc.exe in. Then you can run NML from there. For the example below we&#039;ll be assuming the following:&lt;br /&gt;
* nmlc.exe and related files are in D:\grfs\nml&lt;br /&gt;
* The nml file you want to encode is D:\grfs\mygrf\mygrf.nml&lt;br /&gt;
* The grf file to be created needs to go into D:\grfs\mygrf\mygrf.grf&lt;br /&gt;
&lt;br /&gt;
From the command prompt you can now run the following commands, one at a time, confirm with Enter after each line:&lt;br /&gt;
&lt;br /&gt;
 D:&lt;br /&gt;
 cd D:\grfs\nml&lt;br /&gt;
 nmlc -c --grf D:\grfs\mygrf\mygrf.grf D:\grfs\mygrf\mygrf.nml&lt;br /&gt;
&lt;br /&gt;
This will encode the nml file D:\grfs\mygrf\mygrf.nml into the grf file D:\grfs\mygrf\mygrf.grf. The -c option is not mandatory, but crops extraneous blue from sprites, reducing the filesize of the grf file. Note that if you have any spaces in a folder or file name, you need to enclose the complete path in double quotes, e.g.: &amp;lt;code&amp;gt;nmlc -c --grf &amp;quot;D:\grfs\my grf\mygrf.grf&amp;quot; &amp;quot;D:\grfs\mgrf\mygrf.nml&amp;quot;&amp;lt;/code&amp;gt;. It is therefore recommended not to have any spaces.&lt;br /&gt;
&lt;br /&gt;
All command-line options available to NML are available via the &amp;lt;code&amp;gt;nmlc -h&amp;lt;/code&amp;gt; command and are also [[#NML Command-line Options|listed]] on this page. Now that you have NML and know how to use it, you can continue this tutorial to learn how to create an actual grf file using NML.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== NML Command-line Options ==&lt;br /&gt;
&#039;&#039;From the NML readme&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 Usage: nmlc [options] &amp;lt;filename&amp;gt;&lt;br /&gt;
 Where &amp;lt;filename&amp;gt; is the nml file to parse&lt;br /&gt;
 &lt;br /&gt;
 Options:&lt;br /&gt;
  --version             show program&#039;s version number and exit&lt;br /&gt;
  -h, --help            show this help message and exit&lt;br /&gt;
  -d, --debug           write the AST to stdout&lt;br /&gt;
  -s, --stack           Dump stack when an error occurs&lt;br /&gt;
  --grf=&amp;lt;file&amp;gt;          write the resulting grf to &amp;lt;file&amp;gt;&lt;br /&gt;
  --nfo=&amp;lt;file&amp;gt;          write nfo output to &amp;lt;file&amp;gt;&lt;br /&gt;
  -c                    crop extraneous transparent blue from real sprites&lt;br /&gt;
  -u                    save uncompressed data in the grf file&lt;br /&gt;
  --nml=&amp;lt;file&amp;gt;          write optimized nml to &amp;lt;file&amp;gt;&lt;br /&gt;
  -o &amp;lt;file&amp;gt;, --output=&amp;lt;file&amp;gt;&lt;br /&gt;
                        write output(nfo/grf) to &amp;lt;file&amp;gt;&lt;br /&gt;
  -t &amp;lt;file&amp;gt;, --custom-tags=&amp;lt;file&amp;gt;&lt;br /&gt;
                        Load custom tags from &amp;lt;file&amp;gt; [default:&lt;br /&gt;
                        custom_tags.txt]&lt;br /&gt;
  -l &amp;lt;dir&amp;gt;, --lang-dir=&amp;lt;dir&amp;gt;&lt;br /&gt;
                        Load language files from directory &amp;lt;dir&amp;gt; [default:&lt;br /&gt;
                        lang]&lt;br /&gt;
  -a &amp;lt;dir&amp;gt;, --sprites-dir=&amp;lt;dir&amp;gt;&lt;br /&gt;
                        Store 32bpp sprites in directory &amp;lt;dir&amp;gt; [default:&lt;br /&gt;
                        sprites]&lt;br /&gt;
  --default-lang=&amp;lt;file&amp;gt;&lt;br /&gt;
                        The default language is stored in &amp;lt;file&amp;gt; [default:&lt;br /&gt;
                        english.lng]&lt;br /&gt;
  --start-sprite=&amp;lt;num&amp;gt;  Set the first sprite number to write (do not use&lt;br /&gt;
                        except when you output nfo that you want to include in&lt;br /&gt;
                        other files)&lt;br /&gt;
  -p &amp;lt;palette&amp;gt;, --palette=&amp;lt;palette&amp;gt;&lt;br /&gt;
                        Force nml to use the palette &amp;lt;pal&amp;gt; [default: ANY].&lt;br /&gt;
                        Valid values are &#039;DOS&#039;, &#039;WIN&#039;, &#039;ANY&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Text editor ==&lt;br /&gt;
NML files and its language files are plain text files and should be edited in a plain text editor. Your operating system most likely comes with a text editor with limited functionality. As such it is recommended to choose an editor with more functionality:&lt;br /&gt;
; Cross-platform&lt;br /&gt;
* [http://www.geany.org/ Geany]&lt;br /&gt;
; Linux&lt;br /&gt;
* &lt;br /&gt;
; MacOS&lt;br /&gt;
* &lt;br /&gt;
; Windows&lt;br /&gt;
* [http://notepad-plus-plus.org/ Notepad++]&lt;br /&gt;
&lt;br /&gt;
If you use an editor which you think is quite good and not listed here, you&#039;re welcome to add it.&lt;br /&gt;
&lt;br /&gt;
=== Syntax highlighting ===&lt;br /&gt;
Syntax highlighting adds some colour to NML code, which makes it easier to read.&lt;br /&gt;
&lt;br /&gt;
At the #openttdcoop DevZone there are syntax highlighter extensions available for [http://dev.openttdcoop.org/documents/24 Notepad++] and [http://dev.openttdcoop.org/documents/26 Geany]. If you want to create your own syntax highlighter, there&#039;s a [http://dev.openttdcoop.org/documents/25 script] available as well that will help you create the keyword lists.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar||Graphic files}}&lt;/div&gt;</summary>
		<author><name>Hirundo</name></author>
	</entry>
</feed>