Merge branch 'ChaseDontTurnScript' of https://github.com/MajorCooke/zdoom

This commit is contained in:
Christoph Oelckers 2016-02-10 22:47:41 +01:00
commit 646f7a1f90
4 changed files with 83 additions and 54 deletions

View file

@ -1792,7 +1792,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
} }
else else
{ {
CALL_ACTION(A_Wander, self); A_Wander(self);
} }
} }
else else
@ -1952,7 +1952,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx)
} }
else else
{ {
CALL_ACTION(A_Wander, self); A_Wander(self);
} }
} }
} }
@ -2051,50 +2051,74 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearLastHeard)
// A_Wander // A_Wander
// //
//========================================================================== //==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_Wander) enum ChaseFlags
{
CHF_FASTCHASE = 1,
CHF_NOPLAYACTIVE = 2,
CHF_NIGHTMAREFAST = 4,
CHF_RESURRECT = 8,
CHF_DONTMOVE = 16,
CHF_NORANDOMTURN = 32,
CHF_NODIRECTIONTURN = 64,
CHF_NOPOSTATTACKTURN = 128,
CHF_STOPIFBLOCKED = 256,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Wander)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
PARAM_INT_OPT(flags) { flags = 0; }
A_Wander(self, flags);
return 0;
}
// [MC] I had to move this out from within A_Wander in order to allow flags to
// pass into it. That meant replacing the CALL_ACTION(A_Wander) functions with
// just straight up defining A_Wander in order to compile. Looking around though,
// actors from the games themselves just do a straight A_Chase call itself so
// I saw no harm in it.
void A_Wander(AActor *self, int flags)
{
// [RH] Strife probably clears this flag somewhere, but I couldn't find where. // [RH] Strife probably clears this flag somewhere, but I couldn't find where.
// This seems as good a place as any. // This seems as good a place as any.
self->flags4 &= ~MF4_INCOMBAT; self->flags4 &= ~MF4_INCOMBAT;
if (self->flags5 & MF5_INCONVERSATION) if (self->flags5 & MF5_INCONVERSATION)
return 0; return;
if (self->flags4 & MF4_STANDSTILL) if (self->flags4 & MF4_STANDSTILL)
return 0; return;
if (self->reactiontime != 0) if (self->reactiontime != 0)
{ {
self->reactiontime--; self->reactiontime--;
return 0; return;
} }
// turn towards movement direction if not there yet // turn towards movement direction if not there yet
if (self->movedir < DI_NODIR) if (!(flags & CHF_NODIRECTIONTURN) && (self->movedir < DI_NODIR))
{ {
self->angle &= (angle_t)(7<<29); self->angle &= (angle_t)(7 << 29);
int delta = self->angle - (self->movedir << 29); int delta = self->angle - (self->movedir << 29);
if (delta > 0) if (delta > 0)
{ {
self->angle -= ANG90/2; self->angle -= ANG90 / 2;
} }
else if (delta < 0) else if (delta < 0)
{ {
self->angle += ANG90/2; self->angle += ANG90 / 2;
} }
} }
if (--self->movecount < 0 || !P_Move (self)) if ((--self->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_Move(self) && !(flags & CHF_STOPIFBLOCKED)))
{ {
P_RandomChaseDir (self); P_RandomChaseDir(self);
self->movecount += 5; self->movecount += 5;
} }
return 0; return;
} }
//========================================================================== //==========================================================================
// //
// A_Look2 // A_Look2
@ -2165,8 +2189,8 @@ nosee:
// //
//============================================================================= //=============================================================================
#define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT #define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT
void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove) void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags)
{ {
int delta; int delta;
@ -2228,7 +2252,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
{ {
A_FaceTarget(actor); A_FaceTarget(actor);
} }
else if (actor->movedir < 8) else if (!(flags & CHF_NODIRECTIONTURN) && actor->movedir < 8)
{ {
actor->angle &= (angle_t)(7<<29); actor->angle &= (angle_t)(7<<29);
delta = actor->angle - (actor->movedir << 29); delta = actor->angle - (actor->movedir << 29);
@ -2300,7 +2324,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
//CALL_ACTION(A_Look, actor); //CALL_ACTION(A_Look, actor);
if (actor->target == NULL) if (actor->target == NULL)
{ {
if (!dontmove) CALL_ACTION(A_Wander, actor); if (!dontmove) A_Wander(actor);
actor->flags &= ~MF_INCHASE; actor->flags &= ~MF_INCHASE;
return; return;
} }
@ -2318,10 +2342,15 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
if (actor->flags & MF_JUSTATTACKED) if (actor->flags & MF_JUSTATTACKED)
{ {
actor->flags &= ~MF_JUSTATTACKED; actor->flags &= ~MF_JUSTATTACKED;
if (!actor->isFast() && !dontmove) if (!actor->isFast() && !dontmove && !(flags & CHF_NOPOSTATTACKTURN) && !(flags & CHF_STOPIFBLOCKED))
{ {
P_NewChaseDir (actor); P_NewChaseDir (actor);
} }
//Because P_TryWalk would never be reached if the actor is stopped by a blocking object,
//need to make sure the movecount is reset, otherwise they will just keep attacking
//over and over again.
if (flags & CHF_STOPIFBLOCKED)
actor->movecount = pr_trywalk() & 15;
actor->flags &= ~MF_INCHASE; actor->flags &= ~MF_INCHASE;
return; return;
} }
@ -2478,7 +2507,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
if (actor->strafecount) if (actor->strafecount)
actor->strafecount--; actor->strafecount--;
// class bosses don't do this when strafing // class bosses don't do this when strafing
if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove) if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove)
{ {
@ -2488,16 +2517,15 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
FTextureID oldFloor = actor->floorpic; FTextureID oldFloor = actor->floorpic;
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move (actor)) if ((--actor->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_Move(actor) && !(flags & CHF_STOPIFBLOCKED)))
{ {
P_NewChaseDir (actor); P_NewChaseDir(actor);
} }
// if the move was illegal, reset it // if the move was illegal, reset it
// (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!) // (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!)
if (actor->flags2&MF2_CANTLEAVEFLOORPIC && actor->floorpic != oldFloor ) if (actor->flags2&MF2_CANTLEAVEFLOORPIC && actor->floorpic != oldFloor )
{ {
if (P_TryMove (actor, oldX, oldY, false)) if (P_TryMove(actor, oldX, oldY, false))
{ {
if (nomonsterinterpolation) if (nomonsterinterpolation)
{ {
@ -2505,7 +2533,8 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
actor->PrevY = oldY; actor->PrevY = oldY;
} }
} }
P_NewChaseDir (actor); if (!(flags & CHF_STOPIFBLOCKED))
P_NewChaseDir(actor);
} }
} }
else if (dontmove && actor->movecount > 0) actor->movecount--; else if (dontmove && actor->movecount > 0) actor->movecount--;
@ -2666,15 +2695,6 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
// //
//========================================================================== //==========================================================================
enum ChaseFlags
{
CHF_FASTCHASE = 1,
CHF_NOPLAYACTIVE = 2,
CHF_NIGHTMAREFAST = 4,
CHF_RESURRECT = 8,
CHF_DONTMOVE = 16,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
@ -2686,22 +2706,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase)
{ {
if ((flags & CHF_RESURRECT) && P_CheckForResurrection(self, false)) if ((flags & CHF_RESURRECT) && P_CheckForResurrection(self, false))
return 0; return 0;
A_DoChase(stack, self, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE), A_DoChase(stack, self, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE),
!!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE)); !!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE), flags);
} }
else // this is the old default A_Chase else // this is the old default A_Chase
{ {
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false); A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, flags);
} }
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_FastChase) DEFINE_ACTION_FUNCTION(AActor, A_FastChase)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
A_DoChase(stack, self, true, self->MeleeState, self->MissileState, true, true, false); A_DoChase(stack, self, true, self->MeleeState, self->MissileState, true, true, false, 0);
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(AActor, A_VileChase) DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
@ -2709,9 +2729,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
if (!P_CheckForResurrection(self, true)) if (!P_CheckForResurrection(self, true))
{ {
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false); A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0);
} }
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
@ -2725,14 +2745,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
// Now that A_Chase can handle state label parameters, this function has become rather useless... // Now that A_Chase can handle state label parameters, this function has become rather useless...
A_DoChase(stack, self, false, A_DoChase(stack, self, false,
domelee ? self->MeleeState : NULL, domissile ? self->MissileState : NULL, domelee ? self->MeleeState : NULL, domissile ? self->MissileState : NULL,
playactive, nightmarefast, false); playactive, nightmarefast, false, 0);
return 0; return 0;
} }
// for internal use // for internal use
void A_Chase(VMFrameStack *stack, AActor *self) void A_Chase(VMFrameStack *stack, AActor *self)
{ {
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false); A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0);
} }
//============================================================================= //=============================================================================

View file

@ -61,7 +61,6 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis
void A_Unblock(AActor *self, bool drop); void A_Unblock(AActor *self, bool drop);
DECLARE_ACTION(A_Look) DECLARE_ACTION(A_Look)
DECLARE_ACTION(A_Wander)
DECLARE_ACTION(A_BossDeath) DECLARE_ACTION(A_BossDeath)
DECLARE_ACTION(A_Pain) DECLARE_ACTION(A_Pain)
DECLARE_ACTION(A_MonsterRail) DECLARE_ACTION(A_MonsterRail)
@ -70,10 +69,11 @@ DECLARE_ACTION(A_Scream)
DECLARE_ACTION(A_FreezeDeath) DECLARE_ACTION(A_FreezeDeath)
DECLARE_ACTION(A_FreezeDeathChunks) DECLARE_ACTION(A_FreezeDeathChunks)
void A_BossDeath(AActor *self); void A_BossDeath(AActor *self);
void A_Wander(AActor *self, int flags = 0);
void A_Chase(VMFrameStack *stack, AActor *self); void A_Chase(VMFrameStack *stack, AActor *self);
void A_FaceTarget(AActor *actor); void A_FaceTarget(AActor *actor);
void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0); void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0);
bool A_RaiseMobj (AActor *, fixed_t speed); bool A_RaiseMobj (AActor *, fixed_t speed);
bool A_SinkMobj (AActor *, fixed_t speed); bool A_SinkMobj (AActor *, fixed_t speed);

View file

@ -149,7 +149,7 @@ ACTOR Actor native //: Thinker
action native A_SkullPop(class<PlayerChunk> skulltype = "BloodySkull"); action native A_SkullPop(class<PlayerChunk> skulltype = "BloodySkull");
action native A_CheckPlayerDone(); action native A_CheckPlayerDone();
action native A_Wander(); action native A_Wander(int flags = 0);
action native A_Look2(); action native A_Look2();
action native A_TossGib(); action native A_TossGib();
action native A_SentinelBob(); action native A_SentinelBob();

View file

@ -79,11 +79,20 @@ const int SXF_ISMASTER = 1 << 27;
const int SXF_ISTRACER = 1 << 28; const int SXF_ISTRACER = 1 << 28;
// Flags for A_Chase // Flags for A_Chase
const int CHF_FASTCHASE = 1; enum
const int CHF_NOPLAYACTIVE = 2; {
const int CHF_NIGHTMAREFAST = 4; CHF_FASTCHASE = 1,
const int CHF_RESURRECT = 8; CHF_NOPLAYACTIVE = 2,
const int CHF_DONTMOVE = 16; CHF_NIGHTMAREFAST = 4,
CHF_RESURRECT = 8,
CHF_DONTMOVE = 16,
CHF_NORANDOMTURN = 32,
CHF_NODIRECTIONTURN = 64,
CHF_NOPOSTATTACKTURN = 128,
CHF_STOPIFBLOCKED = 256,
CHF_DONTTURN = CHF_NORANDOMTURN | CHF_NOPOSTATTACKTURN | CHF_STOPIFBLOCKED
};
// Flags for A_LookEx // Flags for A_LookEx
const int LOF_NOSIGHTCHECK = 1; const int LOF_NOSIGHTCHECK = 1;