by FDARI » Wed Apr 06, 2011 2:37 am
I'm not sure what you're asking. If a player fires a seeker missile, the linetarget is automatically put in the tracer field. If you want a missile to acquire its player's linetarget after creation (like a missile that always goes for what you're looking at), you should use
A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0); like this:
A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_PLAYER_GETTARGET|AAPTR_NULL, AAPTR_TRACER)
This will get data from TARGET
It will assign data to DEFAULT (self)
The data it will get from TARGET is a player's linetarget. If TARGET is not a player (will not happen if the projectile is only ever created by a weapon) it will get NULL.
It will assign the data to its own TRACER field.
If you use this function to change an actor's master or target, there are safeguards that can be disabled with a flag in the fifth parameter (to prevent a circular chain of references). These safeguards do not apply to a tracer field, nor do any flags.
Any pointer assignment that would cause an actor to point to itself, assigns null instead. (If you have a missile without NOBLOCKMAP, it could possibly become the player's linetarget. However, if assigning the player's linetarget to its tracer field under these circumstances, it will assign null instead. This behaviour cannot be disabled.)
Also: A_RearrangePointers only works with stored pointers. If you wish to store a linetarget, use A_TransferPointers.
I do not recommend storing pointers in player classes, because I'm not sure what the implications are. It may well be nothing more than unused data, but existing mods may depend on players never having data in their target pointer, to make A_GiveToTarget work only when called from a monster (
highly unlikely scenario, I know), and there may be a future use for these pointers in the engine (
perhaps equally unlikely), or some current use I am not aware of (I doubt it).
Spoiler: Concept: Autolook with FOV
Code: Select all
actor X
{
Projectile
+SEEKERMISSILE
States
{
Spawn:
ABCD A 2
ABCD A 0 A_RearrangePointers(AAPTR_DEFAULT, AAPTR_TARGET, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS) // TARGET = TARGET, MASTER = TARGET, TRACER = TRACER
ABCD A 0 A_CopyFriendliness // FRIEND TO MASTER
ABCD A 0 A_JumpIfTargetInLOS("HasTracer", 0, JLOSF_NOSIGHT|JLOSF_ALLYNOJUMP|JLOSF_PROJECTILE)
// ALLYNOJUMP may require monster type, but I don't think so; JLOSF_PROJECTILE may be the wrong name (I'm on a break, but the firewall remains in effect...)
// We have befriended player to make ALLYNOJUMP work
// If we reach this point, we have no tracer, or an ally of the player
ABCD A 0 A_ClearTarget // Make sure there is absolutely no target info (more thorough than assigning NULL to the target pointer)
ABCD A 0 A_LookEx(...) // No wiki access... Should jump to state "HasTarget". Call it with a narrow FOV, and other sight restrictions; if you find something nearly dead ahead, it's your target
ABCD A 0 A_LookEx(...) // No wiki access... Should jump to state "HasTarget". Call it with fewer restrictions
// If we reach this point, there is no target
ABCD A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_NULL, AAPTR_NULL, PTROP_NOSAFEGUARDS)
HasNoTracer:
ABCD AB 2
loop
HasTracer:
ABCD A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_NULL, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS) // put MASTER back in the TARGET field for missile behaviour
goto Seek
HasTarget:
ABCD A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_NULL, AAPTR_TARGET, PTROP_NOSAFEGUARDS) // put TARGET in TRACER field, and MASTER in TARGET field
Seek:
ABCD AB 2 A_SeekerMissile(...)
loop
}
}
I'm not sure what you're asking. If a player fires a seeker missile, the linetarget is automatically put in the tracer field. If you want a missile to acquire its player's linetarget after creation (like a missile that always goes for what you're looking at), you should use [b]A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);[/b] like this:
A_TransferPointer(AAPTR_TARGET, AAPTR_DEFAULT, AAPTR_PLAYER_GETTARGET|AAPTR_NULL, AAPTR_TRACER)
This will get data from TARGET
It will assign data to DEFAULT (self)
The data it will get from TARGET is a player's linetarget. If TARGET is not a player (will not happen if the projectile is only ever created by a weapon) it will get NULL.
It will assign the data to its own TRACER field.
If you use this function to change an actor's master or target, there are safeguards that can be disabled with a flag in the fifth parameter (to prevent a circular chain of references). These safeguards do not apply to a tracer field, nor do any flags.
Any pointer assignment that would cause an actor to point to itself, assigns null instead. (If you have a missile without NOBLOCKMAP, it could possibly become the player's linetarget. However, if assigning the player's linetarget to its tracer field under these circumstances, it will assign null instead. This behaviour cannot be disabled.)
Also: A_RearrangePointers only works with stored pointers. If you wish to store a linetarget, use A_TransferPointers.
I do not recommend storing pointers in player classes, because I'm not sure what the implications are. It may well be nothing more than unused data, but existing mods may depend on players never having data in their target pointer, to make A_GiveToTarget work only when called from a monster ([i]highly unlikely scenario, I know[/i]), and there may be a future use for these pointers in the engine ([i]perhaps equally unlikely[/i]), or some current use I am not aware of (I doubt it).
[spoiler=Concept: Autolook with FOV][code]actor X
{
Projectile
+SEEKERMISSILE
States
{
Spawn:
ABCD A 2
ABCD A 0 A_RearrangePointers(AAPTR_DEFAULT, AAPTR_TARGET, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS) // TARGET = TARGET, MASTER = TARGET, TRACER = TRACER
ABCD A 0 A_CopyFriendliness // FRIEND TO MASTER
ABCD A 0 A_JumpIfTargetInLOS("HasTracer", 0, JLOSF_NOSIGHT|JLOSF_ALLYNOJUMP|JLOSF_PROJECTILE)
// ALLYNOJUMP may require monster type, but I don't think so; JLOSF_PROJECTILE may be the wrong name (I'm on a break, but the firewall remains in effect...)
// We have befriended player to make ALLYNOJUMP work
// If we reach this point, we have no tracer, or an ally of the player
ABCD A 0 A_ClearTarget // Make sure there is absolutely no target info (more thorough than assigning NULL to the target pointer)
ABCD A 0 A_LookEx(...) // No wiki access... Should jump to state "HasTarget". Call it with a narrow FOV, and other sight restrictions; if you find something nearly dead ahead, it's your target
ABCD A 0 A_LookEx(...) // No wiki access... Should jump to state "HasTarget". Call it with fewer restrictions
// If we reach this point, there is no target
ABCD A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_NULL, AAPTR_NULL, PTROP_NOSAFEGUARDS)
HasNoTracer:
ABCD AB 2
loop
HasTracer:
ABCD A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_NULL, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS) // put MASTER back in the TARGET field for missile behaviour
goto Seek
HasTarget:
ABCD A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_NULL, AAPTR_TARGET, PTROP_NOSAFEGUARDS) // put TARGET in TRACER field, and MASTER in TARGET field
Seek:
ABCD AB 2 A_SeekerMissile(...)
loop
}
}[/code][/spoiler]