- Changed action function definition so that they have to be defined with a
DEFINE_ACTION_FUNCTION macro. This should make it easier to improve the whole system. SVN r1148 (trunk)
This commit is contained in:
parent
3dbebcb794
commit
1983b5c586
93 changed files with 2378 additions and 2350 deletions
256
src/p_enemy.cpp
256
src/p_enemy.cpp
|
|
@ -1536,31 +1536,31 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround)
|
|||
// Stay in state until a player is sighted.
|
||||
// [RH] Will also leave state to move to goal.
|
||||
//
|
||||
void A_Look (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Look)
|
||||
{
|
||||
AActor *targ;
|
||||
|
||||
// [RH] Set goal now if appropriate
|
||||
if (actor->special == Thing_SetGoal && actor->args[0] == 0)
|
||||
if (self->special == Thing_SetGoal && self->args[0] == 0)
|
||||
{
|
||||
NActorIterator iterator (NAME_PatrolPoint, actor->args[1]);
|
||||
actor->special = 0;
|
||||
actor->goal = iterator.Next ();
|
||||
actor->reactiontime = actor->args[2] * TICRATE + level.maptime;
|
||||
if (actor->args[3] == 0) actor->flags5 &=~ MF5_CHASEGOAL;
|
||||
else actor->flags5 |= MF5_CHASEGOAL;
|
||||
NActorIterator iterator (NAME_PatrolPoint, self->args[1]);
|
||||
self->special = 0;
|
||||
self->goal = iterator.Next ();
|
||||
self->reactiontime = self->args[2] * TICRATE + level.maptime;
|
||||
if (self->args[3] == 0) self->flags5 &=~ MF5_CHASEGOAL;
|
||||
else self->flags5 |= MF5_CHASEGOAL;
|
||||
}
|
||||
|
||||
actor->threshold = 0; // any shot will wake up
|
||||
self->threshold = 0; // any shot will wake up
|
||||
|
||||
if (actor->TIDtoHate != 0)
|
||||
if (self->TIDtoHate != 0)
|
||||
{
|
||||
targ = actor->target;
|
||||
targ = self->target;
|
||||
}
|
||||
else
|
||||
{
|
||||
targ = (i_compatflags & COMPATF_SOUNDTARGET || actor->flags & MF_NOSECTOR)?
|
||||
actor->Sector->SoundTarget : actor->LastHeard;
|
||||
targ = (i_compatflags & COMPATF_SOUNDTARGET || self->flags & MF_NOSECTOR)?
|
||||
self->Sector->SoundTarget : self->LastHeard;
|
||||
|
||||
// [RH] If the soundtarget is dead, don't chase it
|
||||
if (targ != NULL && targ->health <= 0)
|
||||
|
|
@ -1575,40 +1575,40 @@ void A_Look (AActor *actor)
|
|||
}
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (actor->flags & MF_STEALTH)
|
||||
if (self->flags & MF_STEALTH)
|
||||
{
|
||||
actor->visdir = -1;
|
||||
self->visdir = -1;
|
||||
}
|
||||
|
||||
if (targ && (targ->flags & MF_SHOOTABLE))
|
||||
{
|
||||
if (actor->IsFriend (targ)) // be a little more precise!
|
||||
if (self->IsFriend (targ)) // be a little more precise!
|
||||
{
|
||||
// If we find a valid target here, the wandering logic should *not*
|
||||
// be activated! If would cause the seestate to be set twice.
|
||||
if (P_LookForPlayers (actor, actor->flags4 & MF4_LOOKALLAROUND))
|
||||
if (P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND))
|
||||
goto seeyou;
|
||||
|
||||
// Let the actor wander around aimlessly looking for a fight
|
||||
if (actor->SeeState != NULL)
|
||||
// Let the self wander around aimlessly looking for a fight
|
||||
if (self->SeeState != NULL)
|
||||
{
|
||||
if (!(actor->flags & MF_INCHASE))
|
||||
if (!(self->flags & MF_INCHASE))
|
||||
{
|
||||
actor->SetState (actor->SeeState);
|
||||
self->SetState (self->SeeState);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
A_Wander (actor);
|
||||
A_Wander (self);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->target = targ;
|
||||
self->target = targ;
|
||||
|
||||
if (actor->flags & MF_AMBUSH)
|
||||
if (self->flags & MF_AMBUSH)
|
||||
{
|
||||
if (P_CheckSight (actor, actor->target, 2))
|
||||
if (P_CheckSight (self, self->target, 2))
|
||||
goto seeyou;
|
||||
}
|
||||
else
|
||||
|
|
@ -1617,32 +1617,32 @@ void A_Look (AActor *actor)
|
|||
}
|
||||
|
||||
|
||||
if (!P_LookForPlayers (actor, actor->flags4 & MF4_LOOKALLAROUND))
|
||||
if (!P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND))
|
||||
return;
|
||||
|
||||
// go into chase state
|
||||
seeyou:
|
||||
// [RH] Don't start chasing after a goal if it isn't time yet.
|
||||
if (actor->target == actor->goal)
|
||||
if (self->target == self->goal)
|
||||
{
|
||||
if (actor->reactiontime > level.maptime)
|
||||
actor->target = NULL;
|
||||
if (self->reactiontime > level.maptime)
|
||||
self->target = NULL;
|
||||
}
|
||||
else if (actor->SeeSound)
|
||||
else if (self->SeeSound)
|
||||
{
|
||||
if (actor->flags2 & MF2_BOSS)
|
||||
if (self->flags2 & MF2_BOSS)
|
||||
{ // full volume
|
||||
S_Sound (actor, CHAN_VOICE, actor->SeeSound, 1, ATTN_NONE);
|
||||
S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_Sound (actor, CHAN_VOICE, actor->SeeSound, 1, ATTN_NORM);
|
||||
S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->target && !(actor->flags & MF_INCHASE))
|
||||
if (self->target && !(self->flags & MF_INCHASE))
|
||||
{
|
||||
actor->SetState (actor->SeeState);
|
||||
self->SetState (self->SeeState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1652,7 +1652,7 @@ void A_Look (AActor *actor)
|
|||
// A_Wander
|
||||
//
|
||||
//==========================================================================
|
||||
void A_Wander (AActor *self)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Wander)
|
||||
{
|
||||
// [RH] Strife probably clears this flag somewhere, but I couldn't find where.
|
||||
// This seems as good a place as any.
|
||||
|
|
@ -1695,7 +1695,7 @@ void A_Wander (AActor *self)
|
|||
// A_Look2
|
||||
//
|
||||
//==========================================================================
|
||||
void A_Look2 (AActor *self)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Look2)
|
||||
{
|
||||
AActor *targ;
|
||||
|
||||
|
|
@ -2231,38 +2231,38 @@ enum ChaseFlags
|
|||
CHF_DONTMOVE = 16,
|
||||
};
|
||||
|
||||
void A_Chase (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Chase)
|
||||
{
|
||||
int index=CheckIndex(3, &CallingState);
|
||||
if (index>=0)
|
||||
{
|
||||
int flags = EvalExpressionI (StateParameters[index+2], actor);
|
||||
if (flags & CHF_RESURRECT && P_CheckForResurrection(actor, false)) return;
|
||||
int flags = EvalExpressionI (StateParameters[index+2], self);
|
||||
if (flags & CHF_RESURRECT && P_CheckForResurrection(self, false)) return;
|
||||
|
||||
FState *melee = P_GetState(actor, CallingState, StateParameters[index]);
|
||||
FState *missile = P_GetState(actor, CallingState, StateParameters[index+1]);
|
||||
FState *melee = P_GetState(self, CallingState, StateParameters[index]);
|
||||
FState *missile = P_GetState(self, CallingState, StateParameters[index+1]);
|
||||
|
||||
A_DoChase(actor, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE),
|
||||
A_DoChase(self, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE),
|
||||
!!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE));
|
||||
}
|
||||
else // this is the old default A_Chase
|
||||
{
|
||||
A_DoChase (actor, false, actor->MeleeState, actor->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
|
||||
A_DoChase (self, false, self->MeleeState, self->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
|
||||
}
|
||||
}
|
||||
|
||||
void A_FastChase (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FastChase)
|
||||
{
|
||||
A_DoChase (actor, true, actor->MeleeState, actor->MissileState, true, true, false);
|
||||
A_DoChase (self, true, self->MeleeState, self->MissileState, true, true, false);
|
||||
}
|
||||
|
||||
void A_VileChase (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
|
||||
{
|
||||
if (!P_CheckForResurrection(actor, true))
|
||||
A_DoChase (actor, false, actor->MeleeState, actor->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
|
||||
if (!P_CheckForResurrection(self, true))
|
||||
A_DoChase (self, false, self->MeleeState, self->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
|
||||
}
|
||||
|
||||
void A_ExtChase(AActor * self)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ExtChase)
|
||||
{
|
||||
// Now that A_Chase can handle state label parameters, this function has become rather useless...
|
||||
int index=CheckIndex(4, &CallingState);
|
||||
|
|
@ -2280,24 +2280,24 @@ void A_ExtChase(AActor * self)
|
|||
// A_FaceTarget
|
||||
//
|
||||
//=============================================================================
|
||||
void A_FaceTarget (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FaceTarget)
|
||||
{
|
||||
if (!actor->target)
|
||||
if (!self->target)
|
||||
return;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (actor->flags & MF_STEALTH)
|
||||
if (self->flags & MF_STEALTH)
|
||||
{
|
||||
actor->visdir = 1;
|
||||
self->visdir = 1;
|
||||
}
|
||||
|
||||
actor->flags &= ~MF_AMBUSH;
|
||||
actor->angle = R_PointToAngle2 (actor->x, actor->y,
|
||||
actor->target->x, actor->target->y);
|
||||
self->flags &= ~MF_AMBUSH;
|
||||
self->angle = R_PointToAngle2 (self->x, self->y,
|
||||
self->target->x, self->target->y);
|
||||
|
||||
if (actor->target->flags & MF_SHADOW)
|
||||
if (self->target->flags & MF_SHADOW)
|
||||
{
|
||||
actor->angle += pr_facetarget.Random2() << 21;
|
||||
self->angle += pr_facetarget.Random2() << 21;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2309,76 +2309,63 @@ void A_FaceTarget (AActor *actor)
|
|||
// New function to let monsters shoot a railgun
|
||||
//
|
||||
//===========================================================================
|
||||
void A_MonsterRail (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail)
|
||||
{
|
||||
if (!actor->target)
|
||||
if (!self->target)
|
||||
return;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (actor->flags & MF_STEALTH)
|
||||
if (self->flags & MF_STEALTH)
|
||||
{
|
||||
actor->visdir = 1;
|
||||
self->visdir = 1;
|
||||
}
|
||||
|
||||
actor->flags &= ~MF_AMBUSH;
|
||||
self->flags &= ~MF_AMBUSH;
|
||||
|
||||
actor->angle = R_PointToAngle2 (actor->x,
|
||||
actor->y,
|
||||
actor->target->x,
|
||||
actor->target->y);
|
||||
self->angle = R_PointToAngle2 (self->x,
|
||||
self->y,
|
||||
self->target->x,
|
||||
self->target->y);
|
||||
|
||||
actor->pitch = P_AimLineAttack (actor, actor->angle, MISSILERANGE);
|
||||
self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
|
||||
|
||||
// Let the aim trail behind the player
|
||||
actor->angle = R_PointToAngle2 (actor->x,
|
||||
actor->y,
|
||||
actor->target->x - actor->target->momx * 3,
|
||||
actor->target->y - actor->target->momy * 3);
|
||||
self->angle = R_PointToAngle2 (self->x,
|
||||
self->y,
|
||||
self->target->x - self->target->momx * 3,
|
||||
self->target->y - self->target->momy * 3);
|
||||
|
||||
if (actor->target->flags & MF_SHADOW)
|
||||
if (self->target->flags & MF_SHADOW)
|
||||
{
|
||||
actor->angle += pr_railface.Random2() << 21;
|
||||
self->angle += pr_railface.Random2() << 21;
|
||||
}
|
||||
|
||||
P_RailAttack (actor, actor->GetMissileDamage (0, 1), 0);
|
||||
P_RailAttack (self, self->GetMissileDamage (0, 1), 0);
|
||||
}
|
||||
|
||||
void A_Scream (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Scream)
|
||||
{
|
||||
if (actor->DeathSound)
|
||||
if (self->DeathSound)
|
||||
{
|
||||
// Check for bosses.
|
||||
if (actor->flags2 & MF2_BOSS)
|
||||
if (self->flags2 & MF2_BOSS)
|
||||
{
|
||||
// full volume
|
||||
S_Sound (actor, CHAN_VOICE, actor->DeathSound, 1, ATTN_NONE);
|
||||
S_Sound (self, CHAN_VOICE, self->DeathSound, 1, ATTN_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_Sound (actor, CHAN_VOICE, actor->DeathSound, 1, ATTN_NORM);
|
||||
S_Sound (self, CHAN_VOICE, self->DeathSound, 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void A_XScream (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_XScream)
|
||||
{
|
||||
if (actor->player)
|
||||
S_Sound (actor, CHAN_VOICE, "*gibbed", 1, ATTN_NORM);
|
||||
if (self->player)
|
||||
S_Sound (self, CHAN_VOICE, "*gibbed", 1, ATTN_NORM);
|
||||
else
|
||||
S_Sound (actor, CHAN_VOICE, "misc/gibbed", 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
// Strife's version of A_XScrem
|
||||
void A_XXScream (AActor *actor)
|
||||
{
|
||||
if (!(actor->flags & MF_NOBLOOD) || actor->DeathSound == 0)
|
||||
{
|
||||
A_XScream (actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_Sound (actor, CHAN_VOICE, actor->DeathSound, 1, ATTN_NORM);
|
||||
}
|
||||
S_Sound (self, CHAN_VOICE, "misc/gibbed", 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -2506,35 +2493,35 @@ void P_TossItem (AActor *item)
|
|||
}
|
||||
}
|
||||
|
||||
void A_Pain (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Pain)
|
||||
{
|
||||
// [RH] Vary player pain sounds depending on health (ala Quake2)
|
||||
if (actor->player && actor->player->morphTics == 0)
|
||||
if (self->player && self->player->morphTics == 0)
|
||||
{
|
||||
const char *pain_amount;
|
||||
FSoundID sfx_id;
|
||||
|
||||
if (actor->health < 25)
|
||||
if (self->health < 25)
|
||||
pain_amount = "*pain25";
|
||||
else if (actor->health < 50)
|
||||
else if (self->health < 50)
|
||||
pain_amount = "*pain50";
|
||||
else if (actor->health < 75)
|
||||
else if (self->health < 75)
|
||||
pain_amount = "*pain75";
|
||||
else
|
||||
pain_amount = "*pain100";
|
||||
|
||||
// Try for damage-specific sounds first.
|
||||
if (actor->player->LastDamageType != NAME_None)
|
||||
if (self->player->LastDamageType != NAME_None)
|
||||
{
|
||||
FString pain_sound = pain_amount;
|
||||
pain_sound += '-';
|
||||
pain_sound += actor->player->LastDamageType;
|
||||
pain_sound += self->player->LastDamageType;
|
||||
sfx_id = pain_sound;
|
||||
if (sfx_id == 0)
|
||||
{
|
||||
// Try again without a specific pain amount.
|
||||
pain_sound = "*pain-";
|
||||
pain_sound += actor->player->LastDamageType;
|
||||
pain_sound += self->player->LastDamageType;
|
||||
sfx_id = pain_sound;
|
||||
}
|
||||
}
|
||||
|
|
@ -2543,16 +2530,16 @@ void A_Pain (AActor *actor)
|
|||
sfx_id = pain_amount;
|
||||
}
|
||||
|
||||
S_Sound (actor, CHAN_VOICE, sfx_id, 1, ATTN_NORM);
|
||||
S_Sound (self, CHAN_VOICE, sfx_id, 1, ATTN_NORM);
|
||||
}
|
||||
else if (actor->PainSound)
|
||||
else if (self->PainSound)
|
||||
{
|
||||
S_Sound (actor, CHAN_VOICE, actor->PainSound, 1, ATTN_NORM);
|
||||
S_Sound (self, CHAN_VOICE, self->PainSound, 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
// killough 11/98: kill an object
|
||||
void A_Die (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Die)
|
||||
{
|
||||
ENamedName name;
|
||||
|
||||
|
|
@ -2566,7 +2553,7 @@ void A_Die (AActor *actor)
|
|||
name = ENamedName(StateParameters[index]);
|
||||
}
|
||||
|
||||
P_DamageMobj (actor, NULL, NULL, actor->health, name);
|
||||
P_DamageMobj (self, NULL, NULL, self->health, name);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -2574,30 +2561,13 @@ void A_Die (AActor *actor)
|
|||
// killough 8/9/98: same as A_Explode, except that the damage is variable
|
||||
//
|
||||
|
||||
void A_Detonate (AActor *mo)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_Detonate)
|
||||
{
|
||||
int damage = mo->GetMissileDamage (0, 1);
|
||||
P_RadiusAttack (mo, mo->target, damage, damage, mo->DamageType, true);
|
||||
if (mo->z <= mo->floorz + (damage << FRACBITS))
|
||||
int damage = self->GetMissileDamage (0, 1);
|
||||
P_RadiusAttack (self, self->target, damage, damage, self->DamageType, true);
|
||||
if (self->z <= self->floorz + (damage << FRACBITS))
|
||||
{
|
||||
P_HitFloor (mo);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// A_Explode
|
||||
//
|
||||
void A_Explode (AActor *thing)
|
||||
{
|
||||
int damage = 128;
|
||||
int distance = 128;
|
||||
bool hurtSource = true;
|
||||
|
||||
thing->GetExplodeParms (damage, distance, hurtSource);
|
||||
P_RadiusAttack (thing, thing->target, damage, distance, thing->DamageType, hurtSource);
|
||||
if (thing->z <= thing->floorz + (distance<<FRACBITS))
|
||||
{
|
||||
P_HitFloor (thing);
|
||||
P_HitFloor (self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2635,12 +2605,12 @@ bool CheckBossDeath (AActor *actor)
|
|||
// A_BossDeath
|
||||
// Possibly trigger special effects if on a boss level
|
||||
//
|
||||
void A_BossDeath (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_BossDeath)
|
||||
{
|
||||
FName mytype = actor->GetClass()->TypeName;
|
||||
FName mytype = self->GetClass()->TypeName;
|
||||
|
||||
// Ugh...
|
||||
FName type = actor->GetClass()->ActorInfo->GetReplacee()->Class->TypeName;
|
||||
FName type = self->GetClass()->ActorInfo->GetReplacee()->Class->TypeName;
|
||||
|
||||
// Do generic special death actions first
|
||||
bool checked = false;
|
||||
|
|
@ -2649,13 +2619,13 @@ void A_BossDeath (AActor *actor)
|
|||
{
|
||||
if (type == sa->Type || mytype == sa->Type)
|
||||
{
|
||||
if (!checked && !CheckBossDeath(actor))
|
||||
if (!checked && !CheckBossDeath(self))
|
||||
{
|
||||
return;
|
||||
}
|
||||
checked = true;
|
||||
|
||||
LineSpecials[sa->Action](NULL, actor, false,
|
||||
LineSpecials[sa->Action](NULL, self, false,
|
||||
sa->Args[0], sa->Args[1], sa->Args[2], sa->Args[3], sa->Args[4]);
|
||||
}
|
||||
sa = sa->Next;
|
||||
|
|
@ -2686,7 +2656,7 @@ void A_BossDeath (AActor *actor)
|
|||
else
|
||||
return;
|
||||
|
||||
if (!CheckBossDeath (actor))
|
||||
if (!CheckBossDeath (self))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -2802,14 +2772,14 @@ bool A_RaiseMobj (AActor *actor, fixed_t speed)
|
|||
return done; // Reached target height
|
||||
}
|
||||
|
||||
void A_ClassBossHealth (AActor *actor)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ClassBossHealth)
|
||||
{
|
||||
if (multiplayer && !deathmatch) // co-op only
|
||||
{
|
||||
if (!actor->special1)
|
||||
if (!self->special1)
|
||||
{
|
||||
actor->health *= 5;
|
||||
actor->special1 = true; // has been initialized
|
||||
self->health *= 5;
|
||||
self->special1 = true; // has been initialized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue