Skip to content

Commit

Permalink
- added a modified version of MBF's stay-on-lift feature.
Browse files Browse the repository at this point in the history
The reason this was never added was the hard dependency on the line trigger types. This implements some modified logic that does not try to find all potential lifts in the map.
Also moving the MBF flags to compatflags so that they are easier to control by the user as these must be part of compatibility presets.
  • Loading branch information
coelckers committed Aug 24, 2021
1 parent 4bd6171 commit 196a4c0
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 14 deletions.
6 changes: 4 additions & 2 deletions src/d_main.cpp
Expand Up @@ -703,7 +703,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
case 5: // MBF compat mode
v = COMPATF_TRACE | COMPATF_SOUNDTARGET | COMPATF_BOOMSCROLL | COMPATF_MISSILECLIP | COMPATF_MUSHROOM |
COMPATF_MBFMONSTERMOVE | COMPATF_NOBLOCKFRIENDS | COMPATF_MASKEDMIDTEX;
w = COMPATF2_EXPLODE1;
w = COMPATF2_EXPLODE1 | COMPATF2_AVOID_HAZARDS | COMPATF2_STAYONLIFT;
break;

case 6: // Boom with some added settings to reenable some 'broken' behavior
Expand All @@ -716,7 +716,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
v = COMPATF_CORPSEGIBS | COMPATF_NOBLOCKFRIENDS | COMPATF_MBFMONSTERMOVE | COMPATF_INVISIBILITY |
COMPATF_NOTOSSDROPS | COMPATF_MUSHROOM | COMPATF_NO_PASSMOBJ | COMPATF_BOOMSCROLL | COMPATF_WALLRUN |
COMPATF_TRACE | COMPATF_HITSCAN | COMPATF_MISSILECLIP | COMPATF_MASKEDMIDTEX | COMPATF_SOUNDTARGET;
w = COMPATF2_POINTONLINE | COMPATF2_EXPLODE1 | COMPATF2_EXPLODE2;
w = COMPATF2_POINTONLINE | COMPATF2_EXPLODE1 | COMPATF2_EXPLODE2 | COMPATF2_AVOID_HAZARDS | COMPATF2_STAYONLIFT;
break;
}
compatflags = v;
Expand Down Expand Up @@ -766,6 +766,8 @@ CVAR (Flag, compat_checkswitchrange, compatflags2, COMPATF2_CHECKSWITCHRANGE);
CVAR (Flag, compat_explode1, compatflags2, COMPATF2_EXPLODE1);
CVAR (Flag, compat_explode2, compatflags2, COMPATF2_EXPLODE2);
CVAR (Flag, compat_railing, compatflags2, COMPATF2_RAILING);
CVAR (Flag, compat_avoidhazard, compatflags2, COMPATF2_AVOID_HAZARDS);
CVAR (Flag, compat_stayonlift, compatflags2, COMPATF2_STAYONLIFT);

CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)

Expand Down
3 changes: 3 additions & 0 deletions src/doomdef.h
Expand Up @@ -222,6 +222,9 @@ enum : unsigned int
COMPATF2_EXPLODE2 = 1 << 9, // Use original explosion code throughout.
COMPATF2_RAILING = 1 << 10, // Bugged Strife railings.
COMPATF2_SCRIPTWAIT = 1 << 11, // Use old scriptwait implementation where it doesn't wait on a non-running script.
COMPATF2_AVOID_HAZARDS = 1 << 12, // another MBF thing.
COMPATF2_STAYONLIFT = 1 << 13, // yet another MBF thing.

};

// Emulate old bugs for select maps. These are not exposed by a cvar
Expand Down
3 changes: 2 additions & 1 deletion src/gamedata/g_mapinfo.cpp
Expand Up @@ -1663,7 +1663,6 @@ 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 Expand Up @@ -1705,6 +1704,8 @@ MapFlagHandlers[] =
{ "compat_explode2", MITYPE_COMPATFLAG, 0, COMPATF2_EXPLODE2 },
{ "compat_railing", MITYPE_COMPATFLAG, 0, COMPATF2_RAILING },
{ "compat_scriptwait", MITYPE_COMPATFLAG, 0, COMPATF2_SCRIPTWAIT },
{ "compat_avoidhazards", MITYPE_COMPATFLAG, 0, COMPATF2_AVOID_HAZARDS },
{ "compat_stayonlift", MITYPE_COMPATFLAG, 0, COMPATF2_STAYONLIFT },
{ "cd_start_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end1_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end2_track", MITYPE_EATNEXT, 0, 0 },
Expand Down
1 change: 0 additions & 1 deletion src/gamedata/g_mapinfo.h
Expand Up @@ -260,7 +260,6 @@ 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/gamedata/r_defs.h
Expand Up @@ -485,6 +485,7 @@ enum
SECMF_HIDDEN = 256, // Do not draw on textured automap
SECMF_OVERLAPPING = 512, // floor and ceiling overlap and require special renderer action.
SECMF_NOSKYWALLS = 1024, // Do not draw "sky walls"
SECMF_LIFT = 2048, // For MBF monster AI
};

enum
Expand Down
21 changes: 21 additions & 0 deletions src/maploader/specials.cpp
Expand Up @@ -787,6 +787,27 @@ void MapLoader::SpawnSpecials ()
SpawnLinePortal(&line);
break;

// partial support for MBF's stay-on-lift feature.
// Unlike MBF we cannot scan all lines for a proper special each time because it'd take too long.
// So instead, set the info here, but only for repeatable lifts to keep things simple.
// This also cannot consider lifts triggered by scripts etc.
case Generic_Lift:
if (line.args[3] != 1) continue;
case Plat_DownWaitUpStay:
case Plat_DownWaitUpStayLip:
case Plat_UpWaitDownStay:
case Plat_UpNearestWaitDownStay:
if (line.flags & ML_REPEAT_SPECIAL)
{
auto it = Level->GetSectorTagIterator(line.args[0], &line);
int secno;
while ((secno = it.Next()) != -1)
{
Level->sectors[secno].MoreFlags |= SECMF_LIFT;
}
}
break;

// [RH] ZDoom Static_Init settings
case Static_Init:
switch (line.args[1])
Expand Down
1 change: 1 addition & 0 deletions src/playsim/actor.h
Expand Up @@ -422,6 +422,7 @@ enum ActorFlag8
MF8_MAP07BOSS1 = 0x00400000, // MBF21 boss death.
MF8_MAP07BOSS2 = 0x00800000, // MBF21 boss death.
MF8_AVOIDHAZARDS = 0x01000000, // MBF AI enhancement.
MF8_STAYONLIFT = 0x02000000, // MBF AI enhancement.
};

// --- mobj.renderflags ---
Expand Down
57 changes: 47 additions & 10 deletions src/playsim/p_enemy.cpp
Expand Up @@ -69,6 +69,7 @@ static FRandom pr_slook ("SlooK");
static FRandom pr_dropoff ("Dropoff");
static FRandom pr_defect ("Defect");
static FRandom pr_avoidcrush("AvoidCrush");
static FRandom pr_stayonlift("StayOnLift");

static FRandom pr_skiptarget("SkipTarget");
static FRandom pr_enemystrafe("EnemyStrafe");
Expand Down Expand Up @@ -409,6 +410,33 @@ int P_HitFriend(AActor * self)
return false;
}

/*
* P_IsOnLift
*
* killough 9/9/98:
*
* Returns true if the object is on a lift. Used for AI,
* since it may indicate the need for crowded conditions,
* or that a monster should stay on the lift for a while
* while it goes up or down.
*/

static bool P_IsOnLift(const AActor* actor)
{
sector_t* sec = actor->Sector;

// Short-circuit: it's on a lift which is active.
DSectorEffect* e = sec->floordata;
if (e && e->IsKindOf(RUNTIME_CLASS(DPlat)))
return true;

// Check to see if it's in a sector which can be activated as a lift.
// This is a bit more restrictive than MBF as it only considers repeatable lifts moving from A->B->A and stop.
// Other types of movement are not easy to detect with the more complex map setup
// and also do not really make sense in this context unless they are actually active
return !!(sec->MoreFlags & SECMF_LIFT);
}

/*
* P_IsUnderDamage
*
Expand Down Expand Up @@ -437,6 +465,20 @@ static int P_IsUnderDamage(AActor* actor)
return dir;
}

//
// P_CheckTags
// Checks if 2 sectors share the same primary activation tag
//

bool P_CheckTags(sector_t* sec1, sector_t* sec2)
{
auto Level = sec1->Level;
if (!Level->SectorHasTags(sec1) || !Level->SectorHasTags(sec2)) return sec1 == sec2;
if (Level->GetFirstSectorTag(sec1) == Level->GetFirstSectorTag(sec2)) return true;
// todo: check secondary tags as well.
return false;
}

//
// P_Move
// Move in the current direction,
Expand Down Expand Up @@ -686,15 +728,12 @@ 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);
bool monster_avoid_hazards = (actor->Level->i_compatflags2 & COMPATF2_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
on_lift = ((actor->flags8 & MF8_STAYONLIFT) || (actor->Level->i_compatflags2 & COMPATF2_STAYONLIFT))
&& target && target->health > 0 && P_IsOnLift(actor)
&& P_CheckTags(target->Sector, actor->Sector);

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

Expand All @@ -703,11 +742,9 @@ int P_SmartMove(AActor* actor)

// killough 9/9/98: avoid crushing ceilings or other damaging areas
if (
#if 0
(on_lift && P_Random(pr_stayonlift) < 230 && // Stay on lift
(on_lift && 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))
Expand Down

0 comments on commit 196a4c0

Please sign in to comment.