mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +00:00
- implemented MBF's monsters_avoid_hazards feature.
Both as a map flag for MBF21 support and as an actor flag for better control.
This commit is contained in:
parent
5382e7c17b
commit
d15f450fef
8 changed files with 85 additions and 7 deletions
|
@ -1663,6 +1663,7 @@ MapFlagHandlers[] =
|
||||||
{ "enableskyboxao", MITYPE_SETFLAG3, LEVEL3_SKYBOXAO, 0 },
|
{ "enableskyboxao", MITYPE_SETFLAG3, LEVEL3_SKYBOXAO, 0 },
|
||||||
{ "disableskyboxao", MITYPE_CLRFLAG3, LEVEL3_SKYBOXAO, 0 },
|
{ "disableskyboxao", MITYPE_CLRFLAG3, LEVEL3_SKYBOXAO, 0 },
|
||||||
{ "avoidmelee", MITYPE_SETFLAG3, LEVEL3_AVOIDMELEE, 0 },
|
{ "avoidmelee", MITYPE_SETFLAG3, LEVEL3_AVOIDMELEE, 0 },
|
||||||
|
{ "avoidhazards", MITYPE_SETFLAG3, LEVEL3_AVOID_HAZARDS, 0 },
|
||||||
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
|
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
|
||||||
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 },
|
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 },
|
||||||
{ "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 },
|
{ "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 },
|
||||||
|
|
|
@ -260,6 +260,7 @@ enum ELevelFlags : unsigned int
|
||||||
LEVEL3_NOSHADOWMAP = 0x00010000, // disables shadowmaps for a given level.
|
LEVEL3_NOSHADOWMAP = 0x00010000, // disables shadowmaps for a given level.
|
||||||
LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support.
|
LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support.
|
||||||
LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag.
|
LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag.
|
||||||
|
LEVEL3_AVOID_HAZARDS = 0x00080000, // another MBF thing.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -421,6 +421,7 @@ enum ActorFlag8
|
||||||
MF8_E4M6BOSS = 0x00200000, // MBF21 boss death.
|
MF8_E4M6BOSS = 0x00200000, // MBF21 boss death.
|
||||||
MF8_MAP07BOSS1 = 0x00400000, // MBF21 boss death.
|
MF8_MAP07BOSS1 = 0x00400000, // MBF21 boss death.
|
||||||
MF8_MAP07BOSS2 = 0x00800000, // MBF21 boss death.
|
MF8_MAP07BOSS2 = 0x00800000, // MBF21 boss death.
|
||||||
|
MF8_AVOIDHAZARDS = 0x01000000, // MBF AI enhancement.
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- mobj.renderflags ---
|
// --- mobj.renderflags ---
|
||||||
|
|
|
@ -54,6 +54,9 @@ public:
|
||||||
void Serialize(FSerializer &arc);
|
void Serialize(FSerializer &arc);
|
||||||
void Tick ();
|
void Tick ();
|
||||||
|
|
||||||
|
int getCrush() const { return m_Crush; }
|
||||||
|
int getDirection() const { return m_Direction; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ECeiling m_Type;
|
ECeiling m_Type;
|
||||||
double m_BottomHeight;
|
double m_BottomHeight;
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "actorinlines.h"
|
#include "actorinlines.h"
|
||||||
|
#include "a_ceiling.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ static FRandom pr_look3 ("IGotHooky");
|
||||||
static FRandom pr_slook ("SlooK");
|
static FRandom pr_slook ("SlooK");
|
||||||
static FRandom pr_dropoff ("Dropoff");
|
static FRandom pr_dropoff ("Dropoff");
|
||||||
static FRandom pr_defect ("Defect");
|
static FRandom pr_defect ("Defect");
|
||||||
|
static FRandom pr_avoidcrush("AvoidCrush");
|
||||||
|
|
||||||
static FRandom pr_skiptarget("SkipTarget");
|
static FRandom pr_skiptarget("SkipTarget");
|
||||||
static FRandom pr_enemystrafe("EnemyStrafe");
|
static FRandom pr_enemystrafe("EnemyStrafe");
|
||||||
|
@ -414,13 +416,41 @@ int P_HitFriend(AActor * self)
|
||||||
return false;
|
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
|
// P_Move
|
||||||
// Move in the current direction,
|
// Move in the current direction,
|
||||||
// returns false if the move is blocked.
|
// 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;
|
double tryx, tryy, deltax, deltay, origx, origy;
|
||||||
|
@ -653,6 +683,47 @@ int P_Move (AActor *actor)
|
||||||
return true;
|
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
|
// TryWalk
|
||||||
|
@ -669,7 +740,7 @@ int P_Move (AActor *actor)
|
||||||
|
|
||||||
bool P_TryWalk (AActor *actor)
|
bool P_TryWalk (AActor *actor)
|
||||||
{
|
{
|
||||||
if (!P_Move (actor))
|
if (!P_SmartMove (actor))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
P_RandomChaseDir(self);
|
||||||
self->movecount += 5;
|
self->movecount += 5;
|
||||||
|
@ -2525,7 +2596,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
|
||||||
FTextureID oldFloor = actor->floorpic;
|
FTextureID oldFloor = actor->floorpic;
|
||||||
|
|
||||||
// chase towards player
|
// 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);
|
P_NewChaseDir(actor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ int P_HitFriend (AActor *self);
|
||||||
void P_NoiseAlert (AActor *emmiter, AActor *target, bool splash=false, double maxdist=0);
|
void P_NoiseAlert (AActor *emmiter, AActor *target, bool splash=false, double maxdist=0);
|
||||||
|
|
||||||
bool P_CheckMeleeRange2 (AActor *actor);
|
bool P_CheckMeleeRange2 (AActor *actor);
|
||||||
int P_Move (AActor *actor);
|
int P_SmartMove (AActor *actor);
|
||||||
bool P_TryWalk (AActor *actor);
|
bool P_TryWalk (AActor *actor);
|
||||||
void P_NewChaseDir (AActor *actor);
|
void P_NewChaseDir (AActor *actor);
|
||||||
void P_RandomChaseDir(AActor *actor);;
|
void P_RandomChaseDir(AActor *actor);;
|
||||||
|
|
|
@ -336,6 +336,7 @@ static FFlagDef ActorFlagDefs[]=
|
||||||
DEFINE_FLAG(MF8, E4M6BOSS, AActor, flags8),
|
DEFINE_FLAG(MF8, E4M6BOSS, AActor, flags8),
|
||||||
DEFINE_FLAG(MF8, MAP07BOSS1, AActor, flags8),
|
DEFINE_FLAG(MF8, MAP07BOSS1, AActor, flags8),
|
||||||
DEFINE_FLAG(MF8, MAP07BOSS2, AActor, flags8),
|
DEFINE_FLAG(MF8, MAP07BOSS2, AActor, flags8),
|
||||||
|
DEFINE_FLAG(MF8, AVOIDHAZARDS, AActor, flags8),
|
||||||
|
|
||||||
// Effect flags
|
// Effect flags
|
||||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||||
|
|
|
@ -1443,10 +1443,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, HitFriend, P_HitFriend)
|
||||||
ACTION_RETURN_BOOL(P_HitFriend(self));
|
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);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
ACTION_RETURN_BOOL(P_Move(self));
|
ACTION_RETURN_BOOL(P_SmartMove(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, NewChaseDir, P_NewChaseDir)
|
DEFINE_ACTION_FUNCTION_NATIVE(AActor, NewChaseDir, P_NewChaseDir)
|
||||||
|
|
Loading…
Reference in a new issue