Log in

Targeting system

The targeting system consists of three functions:

  • target_available() at 0x47D940, 19 parameters
  • select_target() at 0x47E9D0, 20 parameters
  • validate_target() at 0x47DB90, 20 parameters

Interrupts call only validate_target() because under pre-6th rules there is always exactly one possible target available for them. This target is available from variables at 0x739194 and 0x739190 (note backwards order).

Spells and abilities that can target players usually don't bother calling target_available(), because they assume players can always be targeted.

In addition to targeting, these functions can also be used to select non-targeted cards, for example sacrifices (Ravenous Baloth) or cards of specific type discarded as a cost (Seismic Assault).

Of the parameters, 17 are common to all three functions (remember that in asm they are pushed in reverse order):

  1. Player who selects the target.
  2. Allowed controller of the target. 0/1, or 2 for both.
  3. Preferred controller of the target (for the AI). 0/1, or 2 for both.
  4. Zone where the target must be in. 0x100 is hand, 0x200 in play, 0x1000 allows targeting players. Cards in graveyard or library cannot be targeted with this system, because they don't have card instance structure associated with them.
  5. Required card types.
  6. Illegal card types.
  7. Required keyword abilities.
  8. Illegal keyword abilities. Function at 0x401E20 fills in appropriate protections. Shroud appears to be handled elsewhere.
  9. Required color.
  10. Illegal color.
  11. Extra field. Cards that target specific basic land type (Volcanic Eruption) put that type here. Healers set this to 0x7904F8, which seems to be address of some damage-related global variable. -1 for none.
  12. Required subtype. -1 for none.
  13. Power requirement. Low byte is power value, 0x1000 = it is minumum value, 0x2000 = it is maximum value, otherwise it is exact value (Pendelhaven). -1 for no requirement.
  14. Toughness requirement. Same system as with power.
  15. Special requirement. This is used to handle cards like King Suleiman and Elephant Graveyard. 0x1 is Wall (but we should use the subtype param instead for that). 0x80 is non-Wall, and counters use 0x2.
  16. Required state. 0x1 = tapped, 0x2 = attacking, 0x10 = bloccking, 0x20 = attacking or blocking, 0x40 = enchanted by one or more auras, 0x1000 = summoning sick, 0x4000 being destroyed (for regeneration effects).
  17. Illegal state. Same values as for required state.

target_available() has two extra parameters before the common ones:

  1. Pointer to return location for number of available targets. May be NULL if the number does not matter.
  2. Unknown, ususally set to 0. Valid values appear to be 0, 1, 2.

select_target() has three extra parameters after the common ones:

  1. Pointer to prompt shown to player ("Select target creature" or something similar).
  2. Allow cancelling target selection 0/1.
  3. Pointer to return location (player/card pair) for selected target.

validate_target() has three extra parameters before the common ones:

  1. Target player or controller of target card.
  2. Target card. -1 when targeting a player.
  3. Unknown, set to 0.

In card_instance_t:

  • Byte at 0x36 is the number of targets
  • Starting at 0x74 there is an array of player/card pairs (4+4 bytes) for storing targets.
  • Spells with multiple targets set state (0x8) bits 0x200000 and some also 0x100000. Probably former displays the "already targeted" image and latter prevents targeting same card again. These bits are cleared after all targets are chosen.

There is also player/card pair (0x4D7000 and 0x4D7004) that is used to store current target for validate_target(). Some cards use this, but it appears to not always contain valid data.

TODO:

  • What the unknown parameters and unknown bits for state parameter are?
  • How it is handled if same targeted ability is activated multiple times? Are there such cards in the game currently?
  • What is the maximum number of targets (size of the array in card_instance_t)? 0x11C is used for other things, so it cannot be more than 21.
  • How to target cards in a graveyard?