Action2/Industries

From GRFSpecs
< Action2
Revision as of 15:24, 15 August 2011 by Frosch (talk | contribs) (version tags)
Jump to navigationJump to search

Industry Production Callback

Industries don't have graphics directly associated with them (they have graphics through their tiles), so they can't have a traditional action 2. However, they still can use action 2 for a special purpose: production callbacks. A production callback can define exactly how an industry is producing cargo, but this needs more than the 15 bits a normal callback can return.

When an industry has bits 1 or 2 set in property 21, its production is changed. Instead of processing the incoming cargo instantly, it remembers how many units are waiting, and uses the production callback mechanism to decide how much cargo must be produced.

The production callback is handled in an action 2 chain.  Typically there will be a sub-chain of multiple varaction 2s for logic before the final varaction 2 handling the production cb.  The ID of the first varaction 2 in the subchain should be handled explicitly by a check for production cb using var 0C.  Do not rely on handling production cb sub-chain as default ID for the varaction 2 checking 0C, this can have unexpected results.  However the ID of the varaction 2 handling the production cb itself should be the default ID for the 0C check.  Makes sense?

Format

For the production callback, the action 2 data looks as follows:

Format version 00

 <Sprite-number> * <Length> 02 0A <set-id> <version> <subtract-in-1> <subtract-in-2> <subtract-in-3> <add-out-1> <add-out-2> <again> 
Element Size Description
<Sprite-number> dec A sequential sprite number
<length> dec The total number of bytes used in this action
02 B Defines action 02
0A B feature 0A=industries
<set-id> B ID for this definition
<version> B version of the production-callback format, 00
<subtract-in-1..3> W Amounts to be subtracted from the incoming cargoes waiting to be processed. (Signed)
<add-out-1/2> W Amounts to be added to the produced cargoes. (Unsigned)
<again> B Repeat callback if nonzero, do not repeat if 00. [1]
  1. Before TTDPatch 2.0.1 alpha 73 the only valid values were 01 and 00.

Format version 01

Supported by OpenTTD 0.60.6 Supported by TTDPatch 2.6 (r1307)2.6

 <Sprite-number> * <Length> 02 0A <set-id> <version> <subtract-in-1> <subtract-in-2> <subtract-in-3> <add-out-1> <add-out-2> <again> 


Element Size Description
<Sprite-number> dec A sequential sprite number
<length> dec The total number of bytes used in this action
02 B Defines action 02
0A B feature 0A=industries
<set-id> B ID for this definition
<version> B version of the production-callback format, 01
<subtract-in-1..3> B Numbers of registers that contain the amounts to be subtracted from the incoming cargoes waiting to be processed.
<add-out-1/2> B Numbers of registers that hold the amounts to be added to the produced cargoes.
<again> B Number of <again> register. Repeat callback if the value of the register  isn't zero, do not repeat otherwise

Details

Subtract-in-1..3

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 subtract-in values to increase the amount of cargo waiting.

During this callback, the lowest byte of variable 18 contains the reason the callback is called: 0 if it was called because of incoming cargo, 1 if it was called in the periodic processing. Bits 8-23 contain how many times the callback was already called in this loop, i.e. 0 for the first call, 1 for the second etc.)

Supported by OpenTTD 0.60.6 Supported by TTDPatch 2.5 (2.0.1 alpha 73)2.5 For TTDPatch 2.0.1 alpha 73 and above, bits 24-31 of variable 18 contain the <again> value of the previous call (the lowest byte only in case of version 1), 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.

Supported by OpenTTD 0.60.6 Supported by TTDPatch 2.5 (2.5 beta 5)2.5 Since TTDPatch 2.5 beta 5, you can request some random bits in variable 10 by setting bit 15 of property 1A. These bits won't be re-randomized when you call the callback again by setting a non-zero "again" value; they're randomized only for the first call.

Supported by OpenTTD 0.60.6 Supported by TTDPatch 2.6 (r1307)2.6 Using the version 1 format, available since TTDPatch 2.6 r1307, you can decide the instructions dynamically. Instead of constants, you give register numbers that contain the needed values; you can compute these values earlier in the action2 chain. 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).