I'm working a bit on getting newobjects
into OpenTTD but there are a few things that bother me or that I have heard about bothered others. So I'd like some input on what changes to the current specifications are desirable and whether the current specification is actually desirable. As such I won't release/commit anything just yet as it is not finished in any way and the specifications might change in any case.
First of all I've heard that using the same callback ID for multiple features isn't something that is done anywhere else in the specifications, so I'd like to keep it that way. This would mean that callback 149 becomes some other, to be determined, callback. Besides that I propose "callback flags" so you can tell whether you want the callback to be called or not. In that case returning a failed callback would mean "disallow" as I'm not that certain that returning a sprite set would mean "any slopes are fine by me".
Talking about the current callback 149: I would like to pass YX to the low byte of variable 18 as the same format is used for variable 40 and property 0C.
This would furthermore allow objects to be on steep slopes, however allowing objects being on steep slopes means you have to disable drawing of foundations!
To object flags I want to add two flags: "can be built under bridge" (behaviour of owned land in OpenTTD) and "requires flat land, but not on foundations" (the current behaviour of lighthouses and transmitters).
Besides that tile animation seems to be totally neglected. I propose:
- animation frames and speed properties,
- the equivalent of callbacks 1A, 1B and 20 (decide following frame of animation, periodically start/stop animation, decide length of animation frame) plus bits in "callback masks".
Callback 1B equivalent would use triggers instead of a callback mask bit: upon construction, synchronised for all tiles (i.e. tileloop of the northern tile) and unsynchronised (normal tileloop). For these triggers to work the animation bit must be set!
For constructions I could imagine the equivalent of 1E (decide colour of building) plus a callback mask bit.
I'd also suggest some sort of method for NewGRFs providing a bit more of a description than just their name, i.e. callback 23/38 equivalent.
Variable 42 defines the construction year in a word, although theoretically it can be more than 65535 in OpenTTD. So it should be considered for "upgrading" to a dword. OpenTTD furthermore has a "resolution" of one day for the construction, i.e. it can as well return the exact date.
What should var 43 return as "c" when the structure is company owned?
What should be the related object of an object? I'm thinking about the town it is placed in (can change whenever the town is removed though!).
Should object removal costs be related to the build costs? What about specifying a factor for those as well?
Declare TRNS and LIGH default classes, with the default transmitter and lighthouse in there but only in the scenario-editor.
Via Lakie I've heard that the current fixed size rectangular objects are considered too restrictive. Ideas to overcome this issue are to use the system used by stations, i.e. dragging and configurable sizes, or the system used by industries, i.e. multiple tile layouts.
The problem with the station system would be to determine when individually built parts are part of the same object, i.e. when to join and when not to join. For stations this is relatively simply as they have an in-game unique identity (read: name), though objects don't currently have that. It is ofcourse possible to name them and then use the same joining mechanisms as used for stations. Question remains whether bits should be removable tile-by-tile like stations, or whether the whole structure has to go at once. Should pieces be able to overwrite other pieces by overbuilding? The "fixed rectangular objects" still remains, though adjoining will somewhat negate that problem.
The problem with the industry system is that you'd still be limited to the layouts designed by the developer and that dragging e.g. a pipeline remains impossible. It would, however, mean that non-rectangular objects can be constructed in one go and with multiple layouts per object lots of variants can be made.
Any of these suggestions would ofcourse null-ify my current suggestion.
So the question is, which approach is best for the NewGRF/OpenTTD/TTDP developers and for our users and what other properties, variables and callbacks would be needed?
Proposed specs, currently based on the TTDP implementation (will be updated whenever there are new/better ideas)
Action 0 properties:
Nr. Size Description
08 D Class ID
09 W Text ID for class
0A W Text ID for object
0B B Climate availability
0C B Size (yx)
0D B Object build cost factor (sets object removal cost to same value, so has to go before prop 14)
0E D Introduction date
0F D End of life date
10 W Object flags
Bit Value Meaning
0 1 Only available in sceneditor
1 2 Irremovable, except with extra (powerful) dynamite
2 4 Anything can remove (of same company)
3 8 Allow construction on water (does not flood)
4 16 Removal cost is income
5 32 Do not show foundations
6 64 Animation
7 128 Only available during game play
8 256 Allows 2cc colour mapping
9 512 Disallows building on land
10 1024 Draws water under tile
11 2048 Allows bridge overhead taking the height of the building into account
12 4096 Random bits in "next animation frame" callback
11 W Animation information (station property 16)
12 B Animation speed (station property 17)
13 W Animation triggers (like station property 18)
Bit Value Meaning
0 1 Upon construction (whole object)
1 2 Periodic tileloop (per tile)
2 4 Every 256 ticks (whole object)
14 B Object removal cost factor
15 W Callback flags
Bit Value Callback
0 1 Custom slope check
1 2 Decide next animation frame
2 4 Decide animation speed
3 8 Decide colour of building
4 16 Display additional text in the build object window
5 32 Decide autoslope
16 B Height of building (measured from the highest point within a tile on a per tile basis)
Action 2 variables:
Nr. Size Description
40 D Relative position, format 00yxYYXX
41 W Tile information, format ss0t (ss = slope bits, t = terrain type)
42 D Construction date (not year!)
43 W Animation counter, format ccaa; cc = (random) colour, aa = animation state
44 B Object founder information (like varact2industries A7)
45 D Get town zone and Manhattan distance of closest town (like varact2industries 65, distance
from current tile)
46 D Get square of Euclidean distance of closest town (like varact2industries 66, distance from
60 W Get object ID at offset (like varact2industries 60, offset from current tile) without FFxxh
61 B Get random bits at offset (like varact2industries 61, offset from current tile)
62 D Land info of nearby tiles (like varact2industrytiles 60, offset from current tile)
63 W Animation count of nearby tiles (return value of 43, offset from current tile)
64 D Count of object, distance of closest instance (like varact2industries 67)
Nr. Eq. Description
157 149 Land slope check, var 10 offset yx, var 18 slope data
158 1A Next animation frame, var 10 random bits if requested
159 1B Animation control, var 18 reason (bit number from property 13)
15A 20 Length of animation frame
15B 1E Building colour
15C 38 Show addition text in the build object window
15D 3C Allow/disallow autosloping
Related object: towns
8 per tile
Note: colour gets set once; when there's no owner a random colour, otherwise the company colour.
That's passed through the building colour and then stored.
Changes to the current TTDP spec:
- callback 149 -> callback 157, flag to enable it
- varact 42 from year -> date, word -> dword
- add properties 11-16
- add flags 11-12 to property 10
- add varact 44-46, 60-64
- add callback 158-15C
Edit (2010-08-24 20:55 UTC): add act2 vars 44-46,60-64
Edit (2010-08-25 15:45 UTC): add act0 prop 15, remove 2 bits from prop 10
Edit (2010-08-26 08:35 UTC): tweak prop 15, readd "allows bridge" bit, add autosloping