ActionE

From GRFSpecs
Revision as of 19:22, 12 June 2011 by Orudge (talk | contribs) (7 revisions)
Jump to navigationJump to search

Deactivate other graphics files or force activation of current file

Action E

Deactivate other graphics files or force activation of current file.

-=Introduction=-

Normally, graphics files should use Action7 to deactivate themselves, if they find that other incompatible graphics have been loaded.

However, when new sets come out, it is often not feasible to change all existing sets so that they can detect the new set. This action therefore allows the new graphics set to deactivate older sets with which it is incompatible.

-=Format=-

The data looks as follows:

 -+<Sprite-number> * <Length> 0E <num> <grfids...>+-

||Element|Size|Description

<Sprite-number>|dec|A sequential sprite number

<length>|dec|The total number of bytes used in this action.

0E|B|Defines action 0E

<num>|B|Number of sets which should be deactivated

<grfids...>|4*B|GRF IDs of the sets to deactivate||

-=Filling in the terms=-

Sprite-number

This is just the number you are at.

Length

Count the number of bytes in this action.

num

This is the number of sets you want to deactivate.

grfids

Here you give the list of GRF IDs, in the same format as in Action8, which should be deactivated.

-=Notes=-

Note that it is invalid to attempt the deactivation of already active graphics files.  You can only prevent files lower down the newgrf(w).cfg from becoming active later.  Therefore, you must check that none of the GRF IDs in this list are active already using the appropriate action 7.  If the deactivation of an already active set is attempted, the current set is considered invalid and will be disabled.

If you attempt to deactivate a set that isn't loaded, nothing happens.

To handle the cases of incompatible sets being loaded and activated earlier, you can either attempt to overwrite all their settings and graphics, or simply deactivate this set in turn.

If the given GRFID is identical to the GRFID of the file currently being processed, the current file is force-activated.  This is most useful for making changes to the title screen menu, which would otherwise not be possible.  It is strongly recommended not to use this feature in any way other than in combination with an action 7 that checks variable 92 (game mode) so that the activation only happens in the title screen.  Otherwise the GRF Status Windows (de)activation is bypassed entirely.

It is best to limit this forced activation to as few actions as possible for maximum compatibility.

In principle, there can be four cases and your .grf file must be able to handle all of them properly:

  • The .grf file is active and can not be deactivated.

+ You cannot use action E in this case.

  • The .grf file is inactive but will be activated.

+ This is the only case in which action E is useful, the .grf file coming below the current one in newgrf(w).cfg but being set to be activated. Action E will set it to not be activated when it is processed.

  • The .grf file is inactive and will not be activated.

+ This can happen because it has been processed already (it comes earlier in newgrf(w).cfg) and was deactivated, either by default or manually. Another possibility is that the file is disabled either by default or manually.

-=Example=-

The following is an example to deactivate GRFID 54570105 if possible, and deactivate the current file instead if not.

-+ 47 * 9 07 88 04 06 54 57 01 05 02+-

-+ 48 * 9 07 88 04 08 54 57 01 05 03+-

-+ 49 * 6 07 83 01 03 7F 04+-

-+ 50 * x 0B 01 1F FF +-... (e.g. "This file is deactivated because incompatible graphics are active.")

-+ 51 * 6 07 83 01 03 7F 00+-

-+ 52 * x 0B 01 1F FF +-... (e.g. "Deactivating GRFID 54570105.")

-+ 53 * 6 0E 01 54 57 01 05+-

This carries out the following instructions:

47: if (GRFID 54570105 is active) goto 50

48: if (GRFID 54570105 is inactive but will be activated) goto 52

49: goto 54

50: showmessage("This file is deactivated because incompatible graphics are active.")

51: deactivate_current_file

52: showmessage("Deactivating GRFID 54570105.")

53: deactivate(54570105);

continue_with_current_file;

The reason for this particular order of pseudo-sprites is that action 7 will not take a branch if the queried GRFID is not present at all.  In that case, both sprites 47 and 48 fall through, which means the jump in 49 is carried out and the file resumes processing.  The unconditional gotos in 49 and 51 are actually conditional on the climate not being 7F, which it never can be.

Conceptually, without goto-logic, the code could be described by

if (GRFID 54570105 is active) {

   showerror("This file is deactivated because incompatible graphics are active.")

deactivate_current_file

} else if (GRFID 54570105 is inactive but will be activated) {

showmessage("Deactivating GRFID 54570105.")

deactivate(54570105);

}