The m4nfo User manual and Technical Report

Properties for new objects

Defining properties of new objects

Introduction

Unlike vehicles or new stations, new objects have no real equivalent in TTD.

The IDs are therefore free to be chosen and will in fact be allocated automatically by TTDPatch. In the object's definition, you only specify IDs relative to the set, i.e. the ID of the first object type is 0, the second object type is 1 and so on. In total, each game can have 255 object IDs for all active grf files.

The property you must set for each object ID is the class label. Also, all object IDs must get their classes in the right order, starting from ID 0 onwards.

Properties are defined inside the defineobject() function. Depending on the type of object and its specification, different properties have to be used. See the example. All properties are given by the property functions below.

Properties

Property function Description
anim_info(<Byte> [,LOOP])Animation information
anim_speed(<Byte>)Animation speed
anim_triggers(<List::trigger>)Animation triggers
buildingheight(<Byte>)Height of the building
callbacks(<List::Callback>)List of callbacks, see below
classlabel(<Label>)Class label, see below
classname(<String>)Text ID for class
climate(<List::Climate>)Climate availability
flags(<List>)Object flags
mapcreate(<Byte>)Number of this object type placed upon map creation (OTTD only, since r25878)
numviews(1 | 2 | 4)Number of object views
objectname(<String>)Text ID for this object
price(<Byte>)Object build cost factor (sets object removal cost factor as well)
removalcost(<Byte>)Object removal cost factor (set after object build cost factor)
size(<Nibble>, <Nibble>)Object size in x and y
timeframe(<Date> .. <Date>)Introduction date and end of life dates, see below

The specifications of Objects are available in OpenTTD only since r20670.

Description

anim_info(<Byte> [,LOOP])

The parameter specifies the number of animation frames to use. Maximum number of frames is 255, although you can have some problems if your animation exceeds 253 frames. The optional second parameter LOOP may be added for looping animations.

Since you can't have properties for individual object tiles, this property applies for every tile of the object. If you don't want to animate some tiles, you should check the current position during callback CB_ACONTROL and return a value of "253" if the current tile doesn't need to be animated. If you also need animations of different length per tile, you'll have to use callback CB_AFRAME for that.

anim_speed(<Byte>)

The meaning is the same as for house animation speed, but the lower limit is 0 instead of 2, so the fastest possible animation changes frames every game tick (27 ms). The default value is 0.

anim_triggers(<List::trigger>)

Parameter is a list of events that should trigger callback CB_ACONTROL, allowing to change the animation state:

TriggerMeaningHappens on
BUILTObject is builtall tiles
PERIODICPeriodic tile loopsingle tile
SYNCHRONSynchronised periodic tile loopall tiles

The synchronised periodic tile loop is called directly after the (unsynchronised) periodic tile loop of the northern tile.

buildingheight(<Byte>)

This function sets the height of the building in 'height levels' (8 pixels). For example, if the structure is 16 pixels high, you'd set this property to 2.

In OpenTTD this property is used to determine the height of the build object window; the height for the object preview is set to 32 + buildingheight() * 8. The property is also used to determine how high a bridge must be if it is allowed by setting ALLOWBRIDGE in function flags().

callbacks(<List::Callback>)

For objects, the following callbacks can be defined by setting the corresponding parameter list:

CallbackMeaning
CB_AFRAMEDecide next animation frame
CB_ASPEEDDecide animation speed
CB_AUTOSLOPEAllow/disallow autosloping
CB_COLOURDecide colour of building
CB_SLOPECustom slope check
CB_TEXTShow additional text in the build object window

Callback CB_ACONTROL (sets frame the animation should jump to) does not need to be activated in this property function, because it is always active and will be used automatically if needed. Same is true for CB_SLOPE

classlabel(<Label>)

Class labels are unique identifiers composed of the letters A-Z and/or the numbers 0-9. Their main use is to combine objects into classes and make them available by the top dropdown list in the object construction window.

Unlike for stations, there is no default class for objects. Set authors have to specify their own labels, although it is strongly recommended to follow a general scheme to try to avoid confusion.

Please note that class labels must be set before any other property.

classname(<String>)

The textual description for this class. This should be either a TTD textid or a text set via deftxt(). When specifying an object, you don't need to set a class name again if you already did for another one with the same class.

flags(<List>)

The parameter is a list of flags, controlling this object's behaviour. Please note that changing flags for already constructed objects will have no effect.

FlagMeaning
INEDITOROnly available in the scenario editor (1)
NOTREMOVABLENot removable (2)
REMOVABLERemovable (owned land behaviour, e.g. can be overbuilt)
BUILDONWATERAllow object's construction on water
REMOVALINCOMERemoval cost is actually income (owned land behaviour)
NOFOUNDATIONDo not display foundations if on a slope
HASANIMATIONObject has animation (3)
INGAMEOnly available during game play (1)
TWOCCAllows 2cc mapping for objects instead of the default 1cc
NOBUILDONLANDDisallows construction on land (also has BUILDONWATER behaviour)
DRAWWATERDraws the water under the object (4)
ALLOWBRIDGEAllow bridge over the object taking the building height into account (5)
RANDOMBITSRandom bits in callback CB_AFRAME
SCALEAMOUNTScale amount of objects placed on map generation not by map area, but (roughly) by the length of the coastline (6)

(1) - Note that INEDITOR and INGAME are incompatible and setting both will make an object completely unavailable.
(2) - Object cannot be removed through normal dynamite, control must be held and the removal cost will be multiplied by 25 (this is the usual behaviour for most class A objects in TTDPatch).
(3) - Setting this flag will allow the object's animation counter to be increased, must be set if you plan to make use of animations. Like stations you must enable animation on a per tile basis by means of the "built tile" trigger and callback CB_ACONTROL.
(4) - Only applies when built on top of a water tile, also replaces the ground tile of the object completely. (Does not work when object built on sloped water tiles).
(5) - Only applies to OpenTTD. TTDPatch does not support bridges over objects yet.
(6) - OpenTTD only (since r25859).

numviews(1 | 2 | 4)

Since TTDPatch nightly r2360 and OpenTTD r21455 objects may have "views", i.e. different graphical representations, e.g. used to show rotated views or other variants of an objects. Number of views/variants may be 1, 2, or 4. Default value is 1.

For non-square objects, x and y sizes are swapped for odd views. I.e., giving an object size of 1*2 (x = 1, y = 2), it will be displayed as 1*2 for num = [0,2] (x-direction) but as 2*1 for num = [1,3] (y-direction).

Use function getviews() to access particular views of an object.

objectname(<String>)

The textual description for this object for query and selection. Same requirements as for the object class label.

price(<Byte>)

The build cost multiplier. This is multiplied by the number of tiles for evaluation of construction and removal costs of an object.

removalcost(<Byte>)

Cost factor for the removal of an object. This must be set after the object build cost factor property as that overwrites this value.

size(<Nibble>,<Nibble>)

The object size up to 15x15 tiles. The first parameter defines the size in x direction and the second defines the size in y.

Note that any value lower than "1" will be rejected.

timeframe(<Date> .. <Date>)

The timeframe of an object is specified by giving its first date and the last date it can be built. In TTDPatch, anything before 1920 is considered to be always available, and it should allow for objects to work past 2044, the introduction date is also the very first date you can build the object. Please note that the timeframe must be a minimum of a year (365 days).