TTDPatch allows for 127 parameters (of 4 bytes) per newGRF. These parameters can be set by the user, and/or they can be used for math calculations, internal to the newGRF in question.
Hence, m4nfo provides a number of functions and macros to read, write and do math calculations on parameters:
Be aware that following examples don't result into 100% complete newGRFs, but instead concentrate on the most important code features.
Parameters in TTDPatch are defined in file newgrf(w).cfg, by adding the parameters as numbers after the filename, separated by spaces:
This sets the first parameter to "15" and the second parameter to "3". What the parameters do depends on the newGRF set, so be sure to read the documentation that it provides.
In OpenTTD, parameters can be set by the user in-game, and have to be defined inside m4nfos's grfinit() function:
... grfsetting( settype(ENUM,1,0,8) setlimits(1,4) setdefault(1) setname( ALL, "Capacity factor", D, UTF8 "Kapazitätsfaktor", F, UTF8 "Facteur de capacité", E, "Factor de capacidad", I, UTF8 "Fattore di capacità", NL, "Capaciteitsfactor", RUS, UTF8 "Коэффициент вместимости" ) ...
Here, 8 bits of parameter 1 are defined to be used as a capacity factor, with a range of 1 .. 4, the default value being set to "1".
This example shows how to set ship properties capacity and load amount depending on the value of said parameter 1. This is done by overwriting those two properties after the ships's definition with its default values.
defineship(_KVAERNER,{"'Kværner' Bulk freighter"},
intro(1961)
climate(TEMPERATE, ARCTIC, TROPIC)
newgraphics()
refittable(YES)
price(160)
speed(37 km/h)
cargotype(MENU)
capacity(420) // tons
loadamount(70)
runningcost(180)
soundeffect(4)
callbacks(CB_RCOL, CB_RCAP, CB_LOAD, CB_TSFX)
refitcost(3 %)
canalspeed(40 %)
cargoclasses(+BULK, +COVERED, -LIQUID, -PGOODS, -REEF, -HAZARD)
)
Now, to overwrite these default values with the new values for capacity and load amount, based on the capacity factor (supplied by parameter 1), we have to use m4nfo's functions skipif() and skip() to keep control of property assignment:
// Test parameter 1 being [1 .. 4]
skipif(2,getowngrfparameter(1),!=,2)
defineship(_KVAERNER,{""},
capacity(840)
loadamount(140)
)
skip(5)
skipif(2,getowngrfparameter(1),!=,3)
defineship(_KVAERNER,{""},
capacity(1260)
loadamount(210)
)
skip(2)
skipif(1,getowngrfparameter(1),!=,4)
defineship(_KVAERNER,{""},
capacity(1680)
loadamount(250)
)
Hence, capacity would be changed to 1680 if parameter 1 is set to "4", to 1260 for a value of "3", to 840 for a parameter value of "2".
It is of course possible to use values given by parameter to change properties dynamically by use of callbacks. In the example below, we do this by use of CB_RCAP (refitted capacity callback), and by calculating the refit capacity from the value of parameter 1. This is done with help from function calculate(), and will result into different loading weights, depending on stowage factors for the cargo type in question:
// all heavy cargo:
// IORE, AORE, SAND, GRVL, CLAY, LIME, BDMT (cement), SCMT => 420 tons
def(0x60, __W420) calculate({getparameter(1,) * 420},
cbfail() else
)
// COAL, GRAI => 402 tons
def(0x61, __W402) calculate({getparameter(1,) * 402},
cbfail() else
)
// OLSD => 384 tons
def(0x62, __W384) calculate({getparameter(1,) * 384},
cbfail() else
)
// FERT => 350 tons
def(0x63, __W350) calculate({getparameter(1,) * 350},
cbfail() else
)
// WDPR, SGBT => 280 tons
def(0x64, __W280) calculate({getparameter(1,) * 280},
cbfail() else
)
What we do here, is to set up a number of labeled def()s, each returning the result of a different capacity value multiplicated by the capacity factor set via parameter 1.
Note that results are returned as callback results, since the function blocks do not return any ordinary result, except the ubiquitous default value (that cbfail() in the "else" branch) which will never be taken, only if the callback would fail at all. This is a special behaviour of the underlying nfo layer.
Now, only part missing, would be to link the cargo types to be refitted to those capacity results by use of CB_RCAP. In the same go, we're addressing the required colour of the bulk cargoes as well, by use of CB_RCOL:
...
def(0) spriteset(move(0,1),load(2,3,4,5)) // ship graphics
// IORE, SCMT
def(1) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__IORE) if(CB_RCOL) // recolour: iron ore
ref(0) else
)
// CORE
def(2) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__CORE) if(CB_RCOL) // recolour: copper ore
ref(0) else
)
// LIME, BDMT, CLAY, GRVL
def(3) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__LIME) if(CB_RCOL) // recolour: lime stone
ref(0) else
)
// SAND
def(4) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__SAND) if(CB_RCOL) // recolour sand
ref(0) else
)
// AORE
def(5) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__AORE) if(CB_RCOL) // recolour: bauxite
ref(0) else
)
// POTA
def(6) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__POTA) if(CB_RCOL) // recolour: potash
ref(0) else
)
// SULP
def(7) callback(
ref(__W420) if(CB_RCAP) // 420t
ref(__SULP) if(CB_RCOL) // recolour: sulphur
ref(0) else
)
// GRAI
def(8) callback(
ref(__W402) if(CB_RCAP) // 402t
ref(__GRAI) if(CB_RCOL) // recolour: grain, cereals, wheat, maize
ref(0) else
)
// OLSD
def(9) callback(
ref(__W384) if(CB_RCAP) // 384t
ref(__OLSD) if(CB_RCOL) // recolour: oil seeds
ref(0) else
)
// FERT
def(10) callback(
ref(__W350) if(CB_RCAP) // 350t
ref(__SAND) if(CB_RCOL) // recolour: sand
ref(0) else
)
// SGBT
def(11) callback(
ref(__W280) if(CB_RCAP) // 280t
ref(__CORE) if(CB_RCOL) // recolour: copper ore
ref(0) else
)
// 402t (menu)
def(12) property(
ref(__W402) if(capacity())
cbfail() else
)
// default & menu
def(13) callback(
ref(__W402) if(CB_RCAP) // 402t
ref(12) if(CB_PROP)
ref(__COAL) if(CB_RCOL) // recolour: coal
ref(0) else
)
makeship(_KVAERNER,
link(ref(13), MENU) // default cargo is COAL, show 402t as well, use CB_PROP!
link(ref(13), COAL) // 402t, needs CB_PROP!
link(ref(1),IORE, SCMT) // FIRS
link(ref(2),CORE)
link(ref(3),LIME, BDMT, CLAY, GRVL)
link(ref(4),SAND)
link(ref(5),AORE)
link(ref(6),POTA)
link(ref(7),SULP)
link(ref(8),CERE, GRAI, WHEA, MAIZ)
link(ref(9),OLSD)
link(ref(10),FERT)
link(ref(11),SGBT)
default(ref(11))
)
Please note def(13), which is somewhat special. Point is that COAL should be the default cargo for that ship, but the appropriate capacity (402 tons) could only be set by CB_RCAP through a manual refit operation, so it must be set by CB_PROP to be shown properly in the purchase menu and as the default.