Actor pointer

From ZDoom Wiki
Jump to navigation Jump to search

Actor pointers are used to keep track of an actor's relationships with others, such as which one spawned them, or which ones they spawned.

There are three actor pointers that are generally used:

  • target
  • tracer
  • master

Some additional pointers also exist, such as lastenemy, but are not normally exposed to modders.

Depending on the type of actor, different pointers are used.

Projectiles

  • target: A projectile's target is not the actor that it will seek after. Instead, this is the actor who fired the projectile (though a little counter-intuitive at that).
  • tracer: This is used only if the projectile has the +SEEKERMISSILE flag. It will lock onto an enemy and seek towards whoever is in this field.
  • master: Unused.

Monsters

  • master: Unused by default. Can be set if the monster was spawned using A_SpawnItemEx with the SXF_SETMASTER flag, or is transferred over with the SXF_TRANSFERPOINTERS flag.
  • target: This refers to whom the monster is chasing and will attack when called upon with A_Chase.
  • tracer: Unused.

Special cases

Many special actors have different handling for these pointers which do not fit in the generic categories above. They include:

  • Anything that explodes will use its target as the source responsible for damage inflicted by the explosion.
  • SpawnShot (A_SpawnFly and A_SpawnSound will move it towards its target, not its tracer as with other projectiles).
  • Archvile (A_VileTarget assigns its tracer to the spawned ArchvileFire, and A_VileAttack detonates the fire)
  • MinotaurFriend uses the tracer pointer to keep track of the player who summoned it.
  • HolyTail (A_CHolyTail uses the tracer pointer to manage its trail).
  • Lightning and derived classes use the tracer, target and lastenemy pointers to manage cohesion between the various components of the lightning column.
  • Dragon (its dedicated movement functions use the tracer fields as path nodes for its navigation)
  • TeleportFog uses the actor who teleported as the target.

This list is not exhaustive.

Custom scripting

ZScript

ZScript can utilize all of the above mentioned DECORATE pointers (target, master and tracer), but also features a wide range of unique pointers. In addition, custom pointers can be declared.

Some of the most commonly existing pointers in ZScript are:

  • self
Can be used by any ZScript class and points to the class itself.
  • owner
Used by inventory items and anything that inherits from them. This pointer refers to the actor that is holding the item.
  • invoker
Appears in the context of classes based on StateProvider, of which currently there are only two: Weapon and CustomInventory. This pointer is used in the states of those classes (outside of the Spawn state, which is used while the Weapon/CustomInventory is simply a pickup in the world) and action functions defined in those classes (such as A_FireBullets). In the context of these functions, self becomes the PlayerPawn owner of the Weapon/CustomInventory, while invoker points to the Weapon/CustomInventory itself.
The reason why the invoker/self pointers interact in such an unorthodox manner in Weapon and CustomInventory states is, their behavior has to simultaneously interact with multiple classes: it interacts with the PlayerPawn and PlayerInfo of the player owner (to modify its states when attacking, check its inventory for ammo, etc.), with the Weapon/CustomInventory itself, and with the PSprite class which is responsible for performing sprite animations. In all other actors these behaviors would be limited to the actor itself, so only Weapon and CustomInventory need special handling
  • player
Used by the PlayerPawn class and poitns to the related PlayerInfo struct. PlayerInfo itself features a lot of unique pointers.

Pointers in ZScript can (and often need to) be stringed together. For example, to access the currently selected weapon from an inventory item, owner.player.readyweapon is needed.

When killed, this version of Imp will spawn another Imp which has 500 health, is twice as slow and appears twice as big:

class DoomImpEnhanced : DoomImp replaces DoomImp
{
	States 
	{
	Death:
		#### # 0 
		{
			A_NoBlocking();
			let foo = Spawn("DoomImp",pos);
			if (foo) //it's important to null-check the spawned actor, just in case
			{
				foo.health = 500;
				foo.scale *= 2;
				foo.speed *= 0.5;
			}
		}
		#### # 1 A_FadeOut(0.01);
		wait;
	}
}

Note, this doesn't cause recursive spawning of DoomImpEnhanced, because the Spawn function in ZScript by default spawns a specific class forcefully, ignoring Actor replacement rules.

DECORATE & ACS

Several DECORATE and ACS functions support custom retrieval and assignment of pointer values. The data location or method of retrieval is specified using named pointer selectors.

All pointers are automatically supported by all implementing functions, unless the function documentation specifies otherwise.

Selectors

The following set of named values all indicate ways of retrieving an actor pointer from a source actor or a static context. The values are divided into categories, and the first selector applicable to the source actor is used. Selectors from different categories may be combined using BITWISE OR. (SELECTOR_A | SELECTOR_B)


Selector category 1: Player-only selectors

Players will use a pointer in this category if one is specified. Otherwise, a pointer from another applicable category will be used.

  • AAPTR_PLAYER_GETTARGET: Get the actor in the player's line of sight. Most target-specific functions use this approach to determining the player's target. This only works if the actor has the SHOOTABLE and SOLID flags, and also lacks the NOBLOCKMAP flag, much like A_JumpIfTargetInLOS.
  • AAPTR_PLAYER_GETCONVERSATION: Get the actor currently talking to the player. Best used from a Strife dialogue that gives a custom inventory item, or starts a script with ACS_ExecuteWithResult (as it processes immediately).


Selector category 2: Generic context selectors

Any actor (non-null) will use a pointer in this category if one is specified. Otherwise, a pointer from another applicable category will be used.

  • AAPTR_MASTER: Access the actor's MASTER pointer. (Players normally do not have masters.)
  • AAPTR_TARGET: Access the actor's TARGET pointer. (Players normally do not use this.)
  • AAPTR_TRACER: Access the actor's TRACER pointer.
  • AAPTR_FRIENDPLAYER: Access the actor's FRIENDPLAYER pointer.
  • AAPTR_GET_LINETARGET: Get the actor in the line of sight. This is similar to AAPTR_PLAYER_GETTARGET above, except it is used for non-player actors.

Note that AAPTR_GET_LINETARGET is identified as AAPTR_LINETARGET in DECORATE.

Note on retrieving TARGET information: Most functions use a special approach to find the target of a player; checking what they are aiming/looking at. This corresponds to AAPTR_PLAYER_GETTARGET. To make a single function that conforms to this standard, use the selector combination AAPTR_TARGET|AAPTR_PLAYER_GETTARGET. The most applicable method will be used (AAPTR_PLAYER_GETTARGET for any player).


Selector category 3: Static context selectors

Any specified pointer in this category will be used.

  • AAPTR_NULL: Return NULL.
  • AAPTR_PLAYER# (where # is a number in the range 1 - 8):
    • A static pointer to the player of that number. NULL if the player does not exist.

Scripting tip: AAPTR_PLAYER1 points to player 1. AAPTR_PLAYER1<<X (shift bits X up) points to player (1 + X). This fact can be applied in ACS loops if you need to reference each active player in sequence.


Selector category 4: Default

This selection is always implied, and applies if no other selection was made. To fully disable this, specify one static selection (as they always apply when specified), such as AAPTR_NULL.

  • AAPTR_DEFAULT: Returns the source actor itself (null if there is no source actor).


Assignment

The following selectors expose fields for manipulation: AAPTR_MASTER, AAPTR_TARGET and AAPTR_TRACER.

Assignment operations will often, but not necessarily, prevent some assignments from occuring. Examples of such events are:

  • An actor pointing to itself
  • An infinite chain of references (two actors referencing eachother as master or target)

Prevention may involve cancelling the operation, or setting the pointer to NULL. Details on this should be included in the documentation of the individual function.

Revision information - assigning to pointers: Significant changes to this functionality are unlikely. Functions that support a set of selectors different from AAPTR_MASTER, AAPTR_TARGET, AAPTR_TRACER should list the supported features, along with any needed revision information.

See also