From f357a36c5cef92dd39ce7d389cdb9fcd8c33cb57 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 5 Nov 2015 13:01:44 -0600 Subject: [PATCH 1/3] - New A_Chase flags. - CHF_NORANDOMTURN: Actor will not randomly turn during chasing to pursue its target. It will only turn if it cannot keep moving forward. - CHF_DONTANGLE: Actor does not adjust its angle to match the movement direction. - CHF_NOPOSTATTACKTURN: Actor will not make its first turn after exiting its attacks. --- src/p_enemy.cpp | 43 +++++++++++++++++------------- wadsrc/static/actors/constants.txt | 3 +++ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 5291101a5..669a9fbb6 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2163,7 +2163,19 @@ nosee: //============================================================================= #define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT -void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove) +enum ChaseFlags +{ + CHF_FASTCHASE = 1, + CHF_NOPLAYACTIVE = 2, + CHF_NIGHTMAREFAST = 4, + CHF_RESURRECT = 8, + CHF_DONTMOVE = 16, + CHF_NORANDOMTURN = 32, + CHF_DONTANGLE = 64, + CHF_NOPOSTATTACKTURN = 128, +}; + +void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags) { int delta; @@ -2225,7 +2237,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi { A_FaceTarget(actor); } - else if (actor->movedir < 8) + else if (!(flags & CHF_DONTANGLE) && actor->movedir < 8) { actor->angle &= (angle_t)(7<<29); delta = actor->angle - (actor->movedir << 29); @@ -2315,7 +2327,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi if (actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if (!actor->isFast() && !dontmove) + if (!actor->isFast() && !dontmove && !(flags & CHF_NOPOSTATTACKTURN)) { P_NewChaseDir (actor); } @@ -2485,7 +2497,9 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi FTextureID oldFloor = actor->floorpic; // chase towards player - if (--actor->movecount < 0 || !P_Move (actor)) + if (actor->movecount >= 0) + actor->movecount--; + if (((!(flags & CHF_NORANDOMTURN)) && (actor->movecount < 0)) || !P_Move(actor)) { P_NewChaseDir (actor); } @@ -2662,15 +2676,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) { ACTION_PARAM_START(3); @@ -2683,23 +2688,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase) if (flags & CHF_RESURRECT && P_CheckForResurrection(self, false)) return; A_DoChase(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 { - A_DoChase (self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false); + A_DoChase (self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, flags); } } DEFINE_ACTION_FUNCTION(AActor, A_FastChase) { - A_DoChase (self, true, self->MeleeState, self->MissileState, true, true, false); + A_DoChase (self, true, self->MeleeState, self->MissileState, true, true, false, 0); } DEFINE_ACTION_FUNCTION(AActor, A_VileChase) { if (!P_CheckForResurrection(self, true)) - A_DoChase (self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false); + A_DoChase(self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0); } DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase) @@ -2713,13 +2718,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase) // Now that A_Chase can handle state label parameters, this function has become rather useless... A_DoChase(self, false, domelee ? self->MeleeState:NULL, domissile ? self->MissileState:NULL, - playactive, nightmarefast, false); + playactive, nightmarefast, false, 0); } // for internal use void A_Chase(AActor *self) { - A_DoChase (self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false); + A_DoChase(self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0); } //============================================================================= diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 213e2109d..01d92c103 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -84,6 +84,9 @@ const int CHF_NOPLAYACTIVE = 2; const int CHF_NIGHTMAREFAST = 4; const int CHF_RESURRECT = 8; const int CHF_DONTMOVE = 16; +const int CHF_NORANDOMTURN = 32; +const int CHF_DONTANGLE = 64; +const int CHF_NOPOSTATTACKTURN = 128; // Flags for A_LookEx const int LOF_NOSIGHTCHECK = 1; From da9c3ff9d2301f35862b5a743f1f50bf512c85f7 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 5 Nov 2015 15:33:56 -0600 Subject: [PATCH 2/3] Added A_Wander Flags. - WF_NORANDOMTURN and WF_DONTANGLE do the same as their CHF_ counterparts for A_Wander. --- src/p_enemy.cpp | 44 ++++++++++++++++++++++-------- src/p_enemy.h | 2 +- wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/constants.txt | 7 +++++ 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 669a9fbb6..68de283da 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1799,7 +1799,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look) } else { - CALL_ACTION(A_Wander, self); + A_Wander(self); } } else @@ -1957,7 +1957,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) } else { - CALL_ACTION(A_Wander, self); + A_Wander(self); } } } @@ -2054,7 +2054,27 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ClearLastHeard) // A_Wander // //========================================================================== -DEFINE_ACTION_FUNCTION(AActor, A_Wander) +enum WFFlags +{ + WF_NORANDOMTURN = 1, + WF_DONTANGLE = 2, +}; + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Wander) +{ + ACTION_PARAM_START(1); + ACTION_PARAM_INT(flags, 0); + + A_Wander(self, flags); +} + +// [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. // This seems as good a place as any. @@ -2073,28 +2093,30 @@ DEFINE_ACTION_FUNCTION(AActor, A_Wander) } // turn towards movement direction if not there yet - if (self->movedir < DI_NODIR) + if (!(flags & WF_DONTANGLE) && (self->movedir < DI_NODIR)) { - self->angle &= (angle_t)(7<<29); + self->angle &= (angle_t)(7 << 29); int delta = self->angle - (self->movedir << 29); if (delta > 0) { - self->angle -= ANG90/2; + self->angle -= ANG90 / 2; } else if (delta < 0) { - self->angle += ANG90/2; + self->angle += ANG90 / 2; } } - if (--self->movecount < 0 || !P_Move (self)) + if (self->movecount >= 0) + self->movecount--; + + if ((!(flags & WF_NORANDOMTURN) && self->movecount < 0) || !P_Move(self)) { - P_RandomChaseDir (self); + P_RandomChaseDir(self); self->movecount += 5; } } - //========================================================================== // // A_Look2 @@ -2309,7 +2331,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi //CALL_ACTION(A_Look, actor); if (actor->target == NULL) { - if (!dontmove) CALL_ACTION(A_Wander, actor); + if (!dontmove) A_Wander(actor); actor->flags &= ~MF_INCHASE; return; } diff --git a/src/p_enemy.h b/src/p_enemy.h index 799b4c0ff..15ac335e0 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -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); DECLARE_ACTION(A_Look) -DECLARE_ACTION(A_Wander) DECLARE_ACTION(A_BossDeath) DECLARE_ACTION(A_Pain) DECLARE_ACTION(A_MonsterRail) @@ -72,6 +71,7 @@ DECLARE_ACTION(A_FreezeDeathChunks) DECLARE_ACTION(A_BossDeath) void A_Chase(AActor *self); +void A_Wander(AActor *self, int flags = 0); void A_FaceTarget(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 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); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 5158aa7b5..6c0fe6944 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -176,7 +176,7 @@ ACTOR Actor native //: Thinker action native A_SkullPop(class skulltype = "BloodySkull"); action native A_CheckPlayerDone(); - action native A_Wander(); + action native A_Wander(int flags = 0); action native A_Look2(); action native A_TossGib(); action native A_SentinelBob(); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 01d92c103..143477bac 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -513,6 +513,13 @@ enum CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self. }; +// Wander Flags +enum +{ + WF_NORANDOMTURN = 1, + WF_DONTANGLE = 2, +}; + // This is only here to provide one global variable for testing. native int testglobalvar; From bfd9e2bc1c18dbc5e9ea998135dea2be2deb5820 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 7 Jan 2016 19:20:02 -0600 Subject: [PATCH 3/3] - Added CHF_STOPIFBLOCKED and CHF_DONTTURN macro. - CHF_STOPIFBLOCKED simply prevents the actor from changing directions for movement. - CHF_DONTTURN implies NORANDOMTURN, NOPOSTATTACKTURN and STOPIFBLOCKED. --- src/p_enemy.cpp | 19 ++++++++++++++----- wadsrc/static/actors/constants.txt | 22 ++++++++++++++-------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 68de283da..8ace645d2 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2195,6 +2195,7 @@ enum ChaseFlags CHF_NORANDOMTURN = 32, CHF_DONTANGLE = 64, CHF_NOPOSTATTACKTURN = 128, + CHF_STOPIFBLOCKED = 256, }; void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags) @@ -2349,10 +2350,15 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi if (actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if (!actor->isFast() && !dontmove && !(flags & CHF_NOPOSTATTACKTURN)) + if (!actor->isFast() && !dontmove && !(flags & CHF_NOPOSTATTACKTURN) && !(flags & CHF_STOPIFBLOCKED)) { 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; return; } @@ -2510,6 +2516,8 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi if (actor->strafecount) actor->strafecount--; + bool movecheck = P_Move(actor); + // class bosses don't do this when strafing if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove) { @@ -2521,24 +2529,25 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi // chase towards player if (actor->movecount >= 0) actor->movecount--; - if (((!(flags & CHF_NORANDOMTURN)) && (actor->movecount < 0)) || !P_Move(actor)) + if (!(flags & CHF_STOPIFBLOCKED)) { - P_NewChaseDir (actor); + if ((!(flags & CHF_NORANDOMTURN) && (actor->movecount < 0)) || !movecheck) + P_NewChaseDir(actor); } // if the move was illegal, reset it // (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!) if (actor->flags2&MF2_CANTLEAVEFLOORPIC && actor->floorpic != oldFloor ) { - if (P_TryMove (actor, oldX, oldY, false)) + if (!(flags & CHF_STOPIFBLOCKED) && P_TryMove(actor, oldX, oldY, false)) { if (nomonsterinterpolation) { actor->PrevX = oldX; actor->PrevY = oldY; } + P_NewChaseDir(actor); } - P_NewChaseDir (actor); } } else if (dontmove && actor->movecount > 0) actor->movecount--; diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 143477bac..0b8833806 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -79,14 +79,20 @@ const int SXF_ISMASTER = 1 << 27; const int SXF_ISTRACER = 1 << 28; // Flags for A_Chase -const int CHF_FASTCHASE = 1; -const int CHF_NOPLAYACTIVE = 2; -const int CHF_NIGHTMAREFAST = 4; -const int CHF_RESURRECT = 8; -const int CHF_DONTMOVE = 16; -const int CHF_NORANDOMTURN = 32; -const int CHF_DONTANGLE = 64; -const int CHF_NOPOSTATTACKTURN = 128; +enum +{ + CHF_FASTCHASE = 1, + CHF_NOPLAYACTIVE = 2, + CHF_NIGHTMAREFAST = 4, + CHF_RESURRECT = 8, + CHF_DONTMOVE = 16, + CHF_NORANDOMTURN = 32, + CHF_DONTANGLE = 64, + CHF_NOPOSTATTACKTURN = 128, + CHF_STOPIFBLOCKED = 256, + + CHF_DONTTURN = CHF_NORANDOMTURN|CHF_NOPOSTATTACKTURN|CHF_STOPIFBLOCKED, +}; // Flags for A_LookEx const int LOF_NOSIGHTCHECK = 1;