In addition to the official OpenTTD implementation ("trunk") there exist a couple of "patchpacks" implementing non-standard game additions and even non-standard newgrf features, namely the JGR Patch Pack (JGRPP), or the New Map Features (NMF). The first one provides an interface for seamless inclusion of non-standard newgrf additions which are supported in this very patch pack.
For this to work, JGRPP introduces a "feature test" mechanism to be used also on implementations which do not use either this test mechanism nor any of its newgrf additions. It also provides a "property mapping" mechanism, to define non-standard property functions and include them into the set of existing "trunk" properties.
As of today, JGR's patchpack provides some more custom features (special real sprites, nfo action5) than implemented in the current m4nfo release.
These will be implemented in m4nfo at a later date.
Supported custom features
At the time being, following custom features for JGRPP are handled in m4nfo:
| Custom feature | Description | Custom property | PROP_MAPPING | defines a property mapping | no |
| STAT_TRACKTYPE | considers track type in station building menu | no | STAT_BRIDGES | sets minimum height for bridges over stations | yes | STAT_PILLARS | disallows specified bridge pillars on stations |
| BRDG_MORE | allows for more bridges (16 instead of 13) | no | BRDG_ICONS | sets menu icons for (extra) bridges | yes | BRDG_PILLARS | disallows specified bridge pillars | BRDG_AVAIL | makes bridges unavailable for towns or AIs |
| RAIL_PROGRAM | Railtype custom signal sprites (programmable) | yes | RAIL_RESTRICT | Railtype custom signal sprites (restricted) |
| ROAD_EXTRAFLAGS | Extra road/tram type flags | yes |
By using PROP_MAPPING, additional properties, e.g. for stations and bridges can be included. This is done by defining them inside m4nfo's grfinit() function by user-defined functions (see examples). Prior to that, a test should be carried out to assure that the property mapping process is available at all, using function feature_test().
This custom feature allows to check the track type for a yet to be build station tile. Thus, it can be used to decide whether to allow building of certain station tiles, depending on the given track type. Use function tinfo_tracktype() for querying the track type.
The user-supplied function for this custom feature defines minimum clearances required for a bridge for each of the eight tile types of this station (or zero to not allow any bridge). Values are given in "height level" units (1 level == 8px), and need not to be the same for the tile types in question for both x- and y-direction.
The user-supplied function for this custom feature decribes which pillars are not allowed on each of the eight tile types of this orstation. Values are given as flag bits in each of the 8 parameter bytes:
| Bit | Value | Description |
| 0 | WEST | pillar on west corner |
| 1 | SOUTH | pillar on south corner |
| 2 | EAST | pillar on east corner |
| 3 | NORTH | pillar on north corner |
| 4 | NORTHEAST | pillar on north-east edge |
| 5 | SOUTHEAST | pillar on south-east edge |
| 6 | SOUTHWEST | pillar on south-west edge |
| 7 | NORTHWEST | pillar on north-west edge |
| STAT_NOPILLARS | pillars/nopillars on all corners/edges | |
| BRDG_ALLPILLARS | ||
The user-supplied function for this custom feature property allows to set the menu icon for a bridge type, being displayed when constructing a bridge. Parameters are of type Word, first one for the bridge menu graphics sprite and the second one for its recolour sprite.
The user-supplied function for this custom feature property allows to define pillars present for each bridge sprite table. It consists of 6 pairs of pillar flags, for bridge tables 0 .. 5. Each pair consists of x-direction and y-direction flags, with each set of flags being one Byte, see table of STAT_PILLARS above.
This user supplied property function enables performance and activation functions for railtype custom signal sprites for programmable pre-signals. Associated signaltype value is 06. Parameter is "1" to enable, and "0" to disable the feature.
This user supplied property function applies to performance and activation functions for custom signal sprites. When enabled by supplying "1" as its parameter, function signalrestricted() will return "1" as well, if the signal is restricted., i.e. has a routing restriction mechanism attached. In addition, the "show electric signals using default graphics" client setting and signal post recolouring is not applied. This custom feature should only be enabled if performance and activation functions actually supply a different sprite when signalrestricted() returns the correct result.
This user supplied property function sets extra flags for this road/tram type by the given parameter. The format is:
| Value | Description |
| 1 | AI/GS may not build this road/tram type |
| 2 | Towns may not modify tiles of this road/tram type in any way |
| 3 | Both limitations as above |
<feature> ::= [STAT_BRIDGES | STAT_PILLARS | STAT_TRACKTYPE | BRDG_ICONS | BRDG_PILLARS | BRDG_MORE ...]
<feature_version> ::= [1 .. n]
<feature_test> ::= {<feature> <feature_version>}
<mapping> ::= {<feature> <user_func>}
<property_mapping> ::= {<feature> <user_func>}
<fallback> ::= [0,1,2]
<feature_propertymapping> ::= {<mapping> <fallback>
| Function | Description | feature | set feature to test for (see table above) | feature_version | set version of feature to test for | feature_test | install test for feature availability | mapping | map user-defined function to newly available feature property | property_mapping | mapping function for distributed source files (w/o grfinit()) | feature_propertymapping | mapping wrapper function to be used in grfinit() | fallback | set fallback mode |
Sets min (and max) version of feature, with <min> ≥ 1, and <max> ≤ 65535. Custom feature version numbers are defined by the current JGRPP implementation. At the time being, the min version number is 1.
feature_test()
Installs test for availability of given feature. The test itself must be done by function skipif(), using variable FEATURE:
skipif(1, FEATURE, !=, STAT_BRIDGES) setproperties(WAYP0, bridge_height(3,3,3,3,3,3,3,3) )
skipif(4, FEATURE, !=, STAT_BRIDGES)
forloop(X,{setproperties(WAYP{}X,
bridge_height(3,3,3,3,3,3,3,3)
)},0 .. 3)
This function links a user-defined function to the custom feature property given. I.e., for custom feature 'bridge height' (STAT_BRIDGES) a freely chosen name like "bridge_height" might be specified, which will be used later to define the max bridge's height for station tiles. See examples above.
Be aware that custom feature property functions need different type and numbers for their parameters:
| Custom feature | Function parameter | STAT_BRIDGES | 8 Bytes | STAT_PILLARS | 8 Bytes |
| BRDG_ICONS | 2 Words | BRDG_PILLARS | 12 Bytes | BRDG_AVAIL | 1 Byte (values 0,1,2) |
Function mapping() is used as a parameter to function feature_propertymapping(), together with function fallback(). Apart from binding user-defined functions to allocated custom feature properties, it does all the other internal assignments needed. As such, function feature_propertymapping() should be part of grfinit(), i.e. only once present in a grf file.
Successful outcome of a mapping is checked by function skipif(), very much like the custom feature availability check above, but using variable MAPPING:
skipif(1, MAPPING, !=, STAT_BRIDGES) setproperties(ROOFS, bridge_height(2,2,2,2,2,2,2,2) ) skipif(1, MAPPING, !=, STAT_PILLARS) setproperties(ROOFS, bridge_pillars(0,0,NORTH+EAST+SOUTH+WEST,NORTH+EAST+SOUTH+WEST, STAT_NOPILLARS,STAT_NOPILLARS,STAT_NOPILLARS,STAT_NOPILLARS) )
The feature mapping process also works for distributed source files. In this case, source files without the grfinit() function, making use of user-defined custom feature mapping functions, should use function propertymapping(), which other than function mapping() is lacking internal variable setup, but only instantiates the property mapping process..
The fallback function specifies following modes:
| Value | Description |
| 0 | default. Attempts to map an unknown custom feature property name are ignored. Use of the mapped property is ignored. |
| 1 | attempts to map an unknown custom feature property name are ignored. Use of the mapped property is an error. |
| 2 | attempts to map an unknown custom feature property name is an error. |
grfinit(GRF_NEWSTATIONS,
grfname(ALL, "NewStations v0.7 05.05.2020")
...
grfparameter(
grfsetting(
settype(BOOL,0,0,1)
setname(STR_PARAMETER)
setdescription(STR_DESCRIPTION)
)
)
feature_test(
feature(PROP_MAPPING)
feature_version(1)
)
feature_propertymapping(
mapping(STAT_BRIDGES, {bridge_height})
fallback(0)
)
feature_propertymapping(
mapping(STAT_PILLARS, {bridge_pillars})
fallback(0)
)
)
...
// prepare for custom feature "bridge_height"
property_mapping(STAT_BRIDGES,{bridge_height}) // set up user-supplied function
skipif(2, MAPPING, !=, STAT_BRIDGES)
forloop(X,{setproperties(X,
bridge_height(1,1,1,1,1,1,1,1)
)},VOIDZ .. VOIDZ+1)
...