The m4nfo User manual and Technical Report

Functions for industries

Using functions for industries

Content

Introduction

In m4nfo, industries are using five types of functions:

Functions for tile layout definition

For industries, the tile layout defines what industry tiles should be displayed, and where they are to be displayed inside the industry.

Format

The industry's tile layout is loosely based on that of stations, at least on the tile level, since industries don't have graphics' sprites themselves.

layout_table(<Industry-ID>,
  {<layout>(
    {<tile>(<xy>, <tile-id> | <oldtile> | <check>)}
  )}
)

<xy> ::= xy(<xoff>, <yoff>)
<oldtile> ::= ttdtile(<tile-id>)
<ID>, <xoff>, <yoff>, <tile-id> ::= Byte
<check> ::=

Description

Offsets are counted from the northernmost tile of the industry (see picture on the left), specifying the position of the current tile. Both values are taken as a signed Byte, but cannot go negative except the special case mentioned below (<check>).

<tile-id> is the ID of an already defined new industry tile. Function ttdtile() takes an original TTD industry tile as its parameter.

<check> is an empty parameter. In this special case, the given tile is checked for clearance, but nothing will be placed on it. This is useful to ensure some free space around the industry. This is the only case where <xoff> and/or <yoff> can be negative. If <xoff> is negative, <yoff> must be one lower than the wanted value.

Examples

Example 1 (single layout for salt works, see above):
layout_table(_SALTER,
   layout(
	tile(xy(0,0), 0) // shed
	tile(xy(0,1), 1) // depot

	tile(xy(1,0), 0) // shed
	tile(xy(1,1), 2) // track top
	tile(xy(1,2), 0)
	tile(xy(1,3), 0)
	tile(xy(1,4), 0)
	
	tile(xy(2,0), 0) // shed
	tile(xy(2,1), 3) // track bottom
	tile(xy(2,2), 0)
	tile(xy(2,3), 0)
	tile(xy(2,4), 0)
   )
)

Example 2 (4-tile industry (brewery) with 2 layouts:
layout_table(_BREWERY,
   layout(
	tile(xy(0,0), 0)
	tile(xy(0,1), 1)
	tile(xy(1,0), 2)
	tile(xy(1,1), 3)
   )
   layout(
	tile(xy(0,0), 4)
	tile(xy(0,1), 3)
	tile(xy(1,0), 1)
	tile(xy(1,1), 2)
   )
)

Functions for industries performance

These functions are used to evaluate game-intrinsic variables, and make them accessible to the industry's activation function. A typical application would use a multitude of these functions linked together to form a "chain", connecting the graphics' sprites of an industry tile with its activation function. See here for an example.

Function Description
anim_frame(<Coordinate>, <block>)Get current animation frame
callback(<block>)Check incidence (and type) of callback
cargodate(<block>)Date when cargo accepted
cargosubtext(<block>)Associate cargo subtext for cargo type
cargosubtextdisplay(<block>)Set display window for cargo subtext
cargowaiting([1 .. 3], <block>)Waiting cargo
cargoproduced(1 | 2, THISMONTH | LASTMONTH, <block>)Amounts of cargo produced
cargotransported(1 | 2, THISMONTH | LASTMONTH, <block>)Amounts of cargo transported
cargofraction(1 | 2, <block>)Fractions of cargo transported
colour(<block>)Colour of industry buildings that support variable colouring scheme
daysbuilt(<block>)Date when industry was built in days since 1920
distindustry(<Industry-ID>, <block>)Distance of nearest industry with given type
distland(<block>)Manhattan distance of closest dry/land tile
disttown(<block>)Manhattan distance of closest town
elseThis is really a void statement
effect(<block>)Special effect when in CB_EFFECTS
height(<Coordinate>, <block>)Get height of lowest corner of tile
history(<block>)Construction history
industrycount(<Industry-ID>, <block>)Count of industry
lastproductionyear(<block>)Last year anything was produced (base +1920)
layoutnum(<block>)Layout number
lclass(<Coordinate>, <block>)Get landscape class of tile
owner(<block>)Industry owner information
playerinfo(<block>)Player info
prodcallback(<version>, subtractin(<Word>, <Word>, <Word>), addout(<Word>, <Word>), <Boolean>)Production callback
prodcallback_info(EVENT | NUMBER | REPEAT, <block>)Production callback info
prodcounter(<block>)Production counter, decremented on every tick, used for timing of primary industry production
randombits([<Coordinate>,] <block>)Get random bits at specified tile when in callback
slope(<Coordinate>, <block>)Get slope info of given tile
status(<block>)Status when trying to build industry
terrain(<Coordinate>, <block>)Get terrain type
tileid(<block>)Get industry tile ID at offset
townzone(<block>)Get town zone of closest town
water(<Coordinate>, <block>)Returns 1 if flat water, else 0
waterclass(<Coordinate>, <block>)Returns "class" of water
yearbuilt(<block>)Date when industry was built in days since year 0
Auxiliary functions
nibble(<Coordinate>)Get position information from x/y coordinates
pos(<Coordinate>)Construct position information from x/y coordinate

Description

anim_frame(<Coordinate>, <block>)

The coordinate parameter of this function is an offset from the northernmost tile of the industry. Coordinates must be given by the auxiliary function pos(<x>, <y>,)

This function returns the same values as function anim_frame() for industry tiles.

callback(<block>)

This function checks for a callback incidence, and if so, returns the type of the incurred callback. See example above.

cargodate(<block>)

This function returns the date when cargo was last accepted in days since 1920.

cargosubtext(<block>)

This function assigns cargo subtexts from input/output cargo types. See CB_CARGOSUBTEXT for return values.

cargosubtextdisplay(<block>)

This function assigns the window to display a cargo subtext in. See CB_CARGOSUBTEXT for return values.

cargowaiting([1 .. 3], <block>)

If a production callback (CB_ARRIVE or CB_PERIODIC) is set in property function callbacks(), this function returns the amount of incoming cargo, set by first parameter, waiting to be processed. Return values are capped at 0xFFFF (65535).

cargoproduced(1 | 2, THISMONTH | LASTMONTH, <block>)

This function returns the amount of cargo produced either for the first or second cargo, and either for this month or the last month.

cargotransported(1 | 2, THISMONTH | LASTMONTH, <block>)

This function returns the amount of cargo transported either for the first or second cargo, and either for this month or the last month.

cargofraction(1 | 2, <block>)

This function returns the fractions of cargo transported last month, either for the first or second cargo. A return value of 0xff means 100% of the produced cargo has been transported.

daysbuilt(<block>)

This function retuens the date when this industry was built in days since 1920. In TTDPatch, industry age is limited to 65535 days (approximately 180 years), i.e., the build date is never more than 65535 days ago.

distindustry(<Industry-ID>, <block>)

The parameter of this function is an industry-ID same as for industry property function conflicting(): either the ID of a new type with bit 7 set, or the ID of an old type. The returned value is 0xFFFFFFFF if there are no industries with the given type (not counting the current one, if it has the given type); otherwise, the returned value is the Manhattan distance of the closest industry with the given type.

distland(<block>)

This function works the same way as function xxx() does during callback CB_LOCATION: if your industry is built on water, it gives the distance of the closest dry land tile, otherwise it gives the distance of the closest water tile. However, you can't use this function during callback CB_LOCATION; you must always use xxx().

Note:

This function is rather expensive because, in the worst case, it has to check all tiles on the map before it gives up looking for a good tile. Try to avoid it in frequent callbacks such as the production callbacks, animation callbacks (unless the animation is slow, around 1 frame per game day or slower). It is, however, OK to use it during the production change callbacks (CB_MONTHLYPROD or CB_RANDOMPROD).

disttown(<Coordinate>, <block>)

This function returns the Manhattan distance of the closest town. The coordinate parameter means the offset from the northernmost tile of the industry.

As usual, coordinates must be given by the auxiliary function pos(<x>, <y>,)

event(<block>)

This function returns the event resulting in building an industry when in a CB_LOCATION callback, see there.

height(<Coordinate>, <block>)

This function returns the height of the lowest corner of the tile at the given coordinate. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)

history(<block>)

This function returns information about the industry's histoy, i.e. how it got onto the map. The following values are possible:

ValueMeaning
0Unknown - This industry was built with newindustries being off, or in a TTDPatch version prior to 2.0.1 alpha 74
1Created during normal gameplay, either by a player or the in-game random industry generator
2Created during random map generation
3Created in the scenario editor

In case 1, you can use function owner() to find out whether the industry was funded by a player or by the random generator.

industrycount(<industry-type>, <block>)

This function returns the number of instances of the industry type given per parameter

layoutnum(<block>)

This function returns the number of the current layout. The first layout will return "1", the second "2", etc. In other words, this is one larger than what function _layoutnum() returns during callback CB_LOCATION.

If the industry was created using an earlier version of TTDPatch than 2.6 r1594, or while newindustries was off, the result will be zero.

lclass(<Coordinate>, <block>)

This function returns the landscape class of the tile at the given coordinate: The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)

ValueLabelDescription
0LC_TERRAINbare land, grass, rocks, fields
1LC_RAILrailway track, with and w/o signals, fences
2LC_ROADroad, level crossings, depots
3LC_HOUSEtown buildings
4LC_TREESclimate-dependent trees
5LC_STATIONTILErailway station, airport, lorry and bus station, ship dock
6LC_WATERwater, coast, river bank, ship depot
7LC_VOIDinvisible border at bottom edges of map
8LC_INDUSTRYTILEindustry tile types
9LC_TUNNELBRIDGErailway or road tunnel, bridge
10LC_OBJECTtransmitter, lighthouse, statue, company-owned land, headquarter

owner(<block>)

Since TTDPatch 2.0.1 alpha 74, this function returns the ID of the company that funded the industry, or 0x10 if the industry was generated randomly. If the industry was built using an earlier TTDPatch version or with newindustries turned off, the return value will be 0x10 either.

playerinfo(<block>)

[### not implemented yet]

randombits([<Coordinate>,] <block>)

This function returns the random bits for the given industry tile. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)

If there's an industry tile on that offset and it belongs to the current industry, the return value will contain the random bits of that tile. Otherwise, the value will be zero.

slope(<block>)

terrain(<Coordinate>, <block>)

This function returns the terrain type for the current tile. Values are NORMAL, DESERT, RAINFOREST, and SNOW (on or above snowline).

The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)

type(<Coordinate>, <block>)

This function returns the tile-ID of an industry tile at the given coordinate. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)

The return value may be:

townzone(<Coordinate>, <block>)

This function returns the town zone of the selected tile. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)

The return value may be:

ValueMeaning
TZ_CENTREInnermost zone, street lights
TZ_COMMERCIALTrees
TZ_RESIDENTIALPaved roads
TZ_PERIPHERYPlain roads
TZ_OUTSKIRTS

water(<Coordinate>, <block>)

This function returns a value of "1" if the tile given by <coordinate> is built on flat water, else "0" is returned. Again, the coordinate parameter means the offset from the northernmost tile of the industry, and coordinates must be given by auxiliary function pos(<x>, <y>,)

waterclass(<Coordinate>, <block>)

This function returns the "water class" of the tile given by <coordinate>. Water class values are as follows:

ValueMeaning
0WC_LANDUndefined / land
1WC_SEASea, ocean
2WC_CANALCanal
3WC_RIVERRiver

Again, the coordinate parameter needs to be given by the auxiliary function pos(<x>, <y>), and are counted from the northernmost tile of the industry.

yearbuilt(<block>)

Date when industry was built in years since 1920, derived from daysbuilt().

Industry Production Callback

Defining the industry production callback

Introduction

Industries don't have graphics directly associated with them (they have graphics through their tiles), so they don't have functions to define the layout of sprites either. However, unlike other TTD features, they have yet another type of callback for a special purpose: the "production callback", which defines exactly how an industry is producing cargo. Unlike normal callbacks, the latter needs more than the 15 bits a normal callback can return.

When an industry has defined CB_ARRIVE or CB_PERIODIC by property function callbacks(), its way of production is modified. Instead of processing the incoming cargo instantly, it remembers how many units of cargo are waiting, and applies the production callback mechanism to decide how much cargo has to be produced.

The production callback is handled inside the usual chain of control. Typically, there will be a sub-chain of multiple performance functions before the final function handling the production callback. Production callbacks should be handled in the same way as normal callbacks, i.e. using function callback().

Format

prodcallback(<version>, <subtract_in>, <add_out>, <repeat>)

<subtract_in> ::= subtractin(<cargo1>, <cargo2>, <cargo3>)

<add_out> ::= addout(<cargo1>, <cargo2>)

There are two versions of the production callback, version 0 needs WORD-sized cargo amounts both for the input and output parameters, as well as for the repeat parameter; and version 1 needs register numbers for registers that contain the cargo amounts and repeat parameter: this allows dynamic computation of all three parameter types.

Description

prodcallback(<version>, subtractin(<Word>, <Word>, <Word>), addout(<Word>, <Word>), <Boolean>)

First parameter is the production callback version number.

Version 0

If version is 0, cargo amounts to be subtracted and added must be unsigned Words.

The total amount of cargo waiting cannot go negative. If you specify more than the amount actually waiting, the incoming amount will be zeroed instead. You can use negative values to increase the amount of cargo waiting, though.

If <repeat> is 1, the callback will be repeated; if it is 0, it will not.

Version 1

Using the version 1 format, available since TTDPatch 2.6 r1307, you can decide the instructions for cargo amounts and callback repetition dynamically. Instead of constants, you give numbers of registers that contain the needed values; you can compute these values earlier in the chain of control. Registers are 4 bytes long and are considered to be signed. Negative <add_out> values don't make sense and are ignored. The results are clamped to the allowed range, 0 .. 65535 for both incoming and outgoing cargo amounts.

Since TTDPatch 2.5 beta 5, you can request some random bits by function randombits() by setting RANDOMBITS in property function flags(). These bits won't be re-randomized when you call the callback again by setting a non-zero <repeat> value; they're randomized only for the first call.

During this callback, function prodcallback_info() returns additional information about the current production callback:

ParameterMeaning
EVENT The reason the callback is called: "0" if it was called because of incoming cargo (CB_ARRIVE), "1" if it was called in the periodic processing (CB_PROCESSING).
NUMBER How many times the callback was already called in this loop, i.e. "0" for the first call, "1" for the second, etc.
REPEAT The <repeat> value of the previous call, or "0" if this is the first call. This can be used to have state information during the loop since you can pass information to the next iteration. (Since TTDPatch 2.0.1 alpha 73)

Auxiliary functions

This pair of functions is used to evaluate coordinate offsets for some of the houseinfo_*() functions. They work in a somewhat "inverse" way.

nibble(<Coordinate>)

This function is used to check a returned byte-packed coordinate value in the usual form (<x>, <y>). Parameter range is [-8 ... +7], both for x- and y-offsets. For an example see here.

pos(<Coordinate>)

This function supplies the given coordinates in a byte-packed form to another function. Parameter range is [-8 ... +7], both for x- and y-coordinates. Please note that the coordinate (0,0) refers to the current tile itself. For an example see here.