Skip to content

Commit

Permalink
- implemented MBF's monsters_avoid_hazards feature.
Browse files Browse the repository at this point in the history
Both as a map flag for MBF21 support and as an actor flag for better control.
  • Loading branch information
coelckers committed Aug 21, 2021
1 parent 5382e7c commit d15f450
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/gamedata/g_mapinfo.cpp
Expand Up @@ -1663,6 +1663,7 @@ MapFlagHandlers[] =
{ "enableskyboxao", MITYPE_SETFLAG3, LEVEL3_SKYBOXAO, 0 },
{ "disableskyboxao", MITYPE_CLRFLAG3, LEVEL3_SKYBOXAO, 0 },
{ "avoidmelee", MITYPE_SETFLAG3, LEVEL3_AVOIDMELEE, 0 },
{ "avoidhazards", MITYPE_SETFLAG3, LEVEL3_AVOID_HAZARDS, 0 },
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 },
{ "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 },
Expand Down
1 change: 1 addition & 0 deletions src/gamedata/g_mapinfo.h
Expand Up @@ -260,6 +260,7 @@ enum ELevelFlags : unsigned int
LEVEL3_NOSHADOWMAP = 0x00010000, // disables shadowmaps for a given level.
LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support.
LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag.
LEVEL3_AVOID_HAZARDS = 0x00080000, // another MBF thing.
};


Expand Down
1 change: 1 addition & 0 deletions src/playsim/actor.h
Expand Up @@ -421,6 +421,7 @@ enum ActorFlag8
MF8_E4M6BOSS = 0x00200000, // MBF21 boss death.
MF8_MAP07BOSS1 = 0x00400000, // MBF21 boss death.
MF8_MAP07BOSS2 = 0x00800000, // MBF21 boss death.
MF8_AVOIDHAZARDS = 0x01000000, // MBF AI enhancement.
};

// --- mobj.renderflags ---
Expand Down
3 changes: 3 additions & 0 deletions src/playsim/mapthinkers/a_ceiling.h
Expand Up @@ -54,6 +54,9 @@ class DCeiling : public DMovingCeiling
void Serialize(FSerializer &arc);
void Tick ();

int getCrush() const { return m_Crush; }
int getDirection() const { return m_Direction; }

protected:
ECeiling m_Type;
double m_BottomHeight;
Expand Down
79 changes: 75 additions & 4 deletions src/playsim/p_enemy.cpp
Expand Up @@ -49,6 +49,7 @@
#include "g_levellocals.h"
#include "vm.h"
#include "actorinlines.h"
#include "a_ceiling.h"

#include "gi.h"

Expand All @@ -67,6 +68,7 @@ static FRandom pr_look3 ("IGotHooky");
static FRandom pr_slook ("SlooK");
static FRandom pr_dropoff ("Dropoff");
static FRandom pr_defect ("Defect");
static FRandom pr_avoidcrush("AvoidCrush");

static FRandom pr_skiptarget("SkipTarget");
static FRandom pr_enemystrafe("EnemyStrafe");
Expand Down Expand Up @@ -414,13 +416,41 @@ int P_HitFriend(AActor * self)
return false;
}

/*
* P_IsUnderDamage
*
* killough 9/9/98:
*
* Returns nonzero if the object is under damage based on
* their current position. Returns 1 if the damage is moderate,
* -1 if it is serious. Used for AI.
*/

static int P_IsUnderDamage(AActor* actor)
{
msecnode_t* seclist;
int dir = 0;
for (seclist = actor->touching_sectorlist; seclist; seclist = seclist->m_tnext)
{
DSectorEffect* e = seclist->m_sector->ceilingdata;
if (e && e->IsKindOf(RUNTIME_CLASS(DCeiling)))
{
auto cl = (DCeiling*)e;
if (cl->getCrush() > 0) // unlike MBF we need to consider non-crushing ceiling movers here.
dir |= cl->getDirection();
}
// Q: consider crushing 3D floors too?
}
return dir;
}

//
// P_Move
// Move in the current direction,
// returns false if the move is blocked.
//

int P_Move (AActor *actor)
static int P_Move (AActor *actor)
{

double tryx, tryy, deltax, deltay, origx, origy;
Expand Down Expand Up @@ -653,6 +683,47 @@ int P_Move (AActor *actor)
return true;
}

//
// P_SmartMove
//
// killough 9/12/98: Same as P_Move, except smarter
//

int P_SmartMove(AActor* actor)
{
AActor* target = actor->target;
int on_lift = false, dropoff = false, under_damage;
bool monster_avoid_hazards = (actor->Level->flags3 & LEVEL3_AVOID_HAZARDS) || (actor->flags8 & MF8_AVOIDHAZARDS);

#if 0
/* killough 9/12/98: Stay on a lift if target is on one */
on_lift = !comp[comp_staylift]
&& target && target->health > 0
&& target->subsector->sector->tag == actor->subsector->sector->tag &&
P_IsOnLift(actor);
#endif

under_damage = monster_avoid_hazards && P_IsUnderDamage(actor) != 0;//e6y

if (!P_Move(actor))
return false;

// killough 9/9/98: avoid crushing ceilings or other damaging areas
if (
#if 0
(on_lift && P_Random(pr_stayonlift) < 230 && // Stay on lift
!P_IsOnLift(actor))
||
#endif
(monster_avoid_hazards && !under_damage && //e6y // Get away from damage
(under_damage = P_IsUnderDamage(actor)) &&
(under_damage < 0 || pr_avoidcrush() < 200))
)
actor->movedir = DI_NODIR; // avoid the area (most of the time anyway)

return true;
}

//=============================================================================
//
// TryWalk
Expand All @@ -669,7 +740,7 @@ int P_Move (AActor *actor)

bool P_TryWalk (AActor *actor)
{
if (!P_Move (actor))
if (!P_SmartMove (actor))
{
return false;
}
Expand Down Expand Up @@ -2123,7 +2194,7 @@ void A_Wander(AActor *self, int flags)
}
}

if ((--self->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_Move(self) && !(flags & CHF_STOPIFBLOCKED)))
if ((--self->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_SmartMove(self) && !(flags & CHF_STOPIFBLOCKED)))
{
P_RandomChaseDir(self);
self->movecount += 5;
Expand Down Expand Up @@ -2525,7 +2596,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
FTextureID oldFloor = actor->floorpic;

// chase towards player
if ((--actor->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_Move(actor) && !(flags & CHF_STOPIFBLOCKED)))
if ((--actor->movecount < 0 && !(flags & CHF_NORANDOMTURN)) || (!P_SmartMove(actor) && !(flags & CHF_STOPIFBLOCKED)))
{
P_NewChaseDir(actor);
}
Expand Down
2 changes: 1 addition & 1 deletion src/playsim/p_enemy.h
Expand Up @@ -50,7 +50,7 @@ int P_HitFriend (AActor *self);
void P_NoiseAlert (AActor *emmiter, AActor *target, bool splash=false, double maxdist=0);

bool P_CheckMeleeRange2 (AActor *actor);
int P_Move (AActor *actor);
int P_SmartMove (AActor *actor);
bool P_TryWalk (AActor *actor);
void P_NewChaseDir (AActor *actor);
void P_RandomChaseDir(AActor *actor);;
Expand Down
1 change: 1 addition & 0 deletions src/scripting/thingdef_data.cpp
Expand Up @@ -336,6 +336,7 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF8, E4M6BOSS, AActor, flags8),
DEFINE_FLAG(MF8, MAP07BOSS1, AActor, flags8),
DEFINE_FLAG(MF8, MAP07BOSS2, AActor, flags8),
DEFINE_FLAG(MF8, AVOIDHAZARDS, AActor, flags8),

// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
Expand Down
4 changes: 2 additions & 2 deletions src/scripting/vmthunks_actors.cpp
Expand Up @@ -1443,10 +1443,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, HitFriend, P_HitFriend)
ACTION_RETURN_BOOL(P_HitFriend(self));
}

DEFINE_ACTION_FUNCTION_NATIVE(AActor, MonsterMove, P_Move)
DEFINE_ACTION_FUNCTION_NATIVE(AActor, MonsterMove, P_SmartMove)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_BOOL(P_Move(self));
ACTION_RETURN_BOOL(P_SmartMove(self));
}

DEFINE_ACTION_FUNCTION_NATIVE(AActor, NewChaseDir, P_NewChaseDir)
Expand Down

0 comments on commit d15f450

Please sign in to comment.