Re-added sector damage for non-players. (#2773)

* Re-add non-player sector damage.

Reimplements SECMF_HURTMONSTERS and SECMF_HARMINAIR.

* Fixed 3D floor handling for sector damage.

Fixes sector damage to either monsters or players not working on (non-)solid 3D floors.
This commit is contained in:
inkoalawetrust 2024-10-20 14:51:36 +03:00 committed by GitHub
parent 12c6d1361a
commit 34dc204517
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 102 additions and 59 deletions

View file

@ -307,6 +307,8 @@ Note: All <bool> fields default to false unless mentioned otherwise.
leakiness = <int>; // Probability of leaking through radiation suit (0 = never, 256 = always), default = 0. leakiness = <int>; // Probability of leaking through radiation suit (0 = never, 256 = always), default = 0.
damageterraineffect = <bool>; // Will spawn a terrain splash when damage is inflicted. Default = false. damageterraineffect = <bool>; // Will spawn a terrain splash when damage is inflicted. Default = false.
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false. damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
hurtmonsters = <bool>; // Non-players like monsters and decorations are hurt by this sector in the same manner as player. Doesn't work with damagehazard.
harminair = <bool>; // Actors in this sector are harmed by the damage effects of the floor even if they aren't touching it.
floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.' floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.'
ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.' ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.'
floor_reflect = <float>; // reflectiveness of floor (OpenGL only, not functional on sloped sectors) floor_reflect = <float>; // reflectiveness of floor (OpenGL only, not functional on sloped sectors)

View file

@ -504,6 +504,8 @@ enum
SECMF_OVERLAPPING = 512, // floor and ceiling overlap and require special renderer action. SECMF_OVERLAPPING = 512, // floor and ceiling overlap and require special renderer action.
SECMF_NOSKYWALLS = 1024, // Do not draw "sky walls" SECMF_NOSKYWALLS = 1024, // Do not draw "sky walls"
SECMF_LIFT = 2048, // For MBF monster AI SECMF_LIFT = 2048, // For MBF monster AI
SECMF_HURTMONSTERS = 4096, // Monsters in this sector are hurt like players.
SECMF_HARMINAIR = 8192, // Actors in this sector are also hurt mid-air.
}; };
enum enum

View file

@ -1979,6 +1979,14 @@ public:
Flag(sec->Flags, SECF_HAZARD, key); Flag(sec->Flags, SECF_HAZARD, key);
break; break;
case NAME_hurtmonsters:
Flag(sec->MoreFlags, SECMF_HURTMONSTERS, key);
break;
case NAME_harminair:
Flag(sec->MoreFlags, SECMF_HARMINAIR, key);
break;
case NAME_floorterrain: case NAME_floorterrain:
sec->terrainnum[sector_t::floor] = P_FindTerrain(CheckString(key)); sec->terrainnum[sector_t::floor] = P_FindTerrain(CheckString(key));
break; break;

View file

@ -810,6 +810,8 @@ xx(damageinterval)
xx(leakiness) xx(leakiness)
xx(damageterraineffect) xx(damageterraineffect)
xx(damagehazard) xx(damagehazard)
xx(hurtmonsters)
xx(harminair)
xx(floorterrain) xx(floorterrain)
xx(ceilingterrain) xx(ceilingterrain)
xx(floor_reflect) xx(floor_reflect)

View file

@ -443,7 +443,9 @@ enum ActorFlag9
MF9_SHADOWBLOCK = 0x00000004, // [inkoalawetrust] Actors in the line of fire with this flag trigger the MF_SHADOW aiming penalty. MF9_SHADOWBLOCK = 0x00000004, // [inkoalawetrust] Actors in the line of fire with this flag trigger the MF_SHADOW aiming penalty.
MF9_SHADOWAIMVERT = 0x00000008, // [inkoalawetrust] Monster aim is also offset vertically when aiming at shadow actors. MF9_SHADOWAIMVERT = 0x00000008, // [inkoalawetrust] Monster aim is also offset vertically when aiming at shadow actors.
MF9_DECOUPLEDANIMATIONS = 0x00000010, // [RL0] Decouple model animations from states MF9_DECOUPLEDANIMATIONS = 0x00000010, // [RL0] Decouple model animations from states
MF9_NOSECTORDAMAGE = 0x00000020, // [inkoalawetrust] Actor ignores any sector-based damage (i.e damaging floors, NOT crushers)
MF9_ISPUFF = 0x00000040, // [AA] Set on actors by P_SpawnPuff MF9_ISPUFF = 0x00000040, // [AA] Set on actors by P_SpawnPuff
MF9_FORCESECTORDAMAGE = 0x00000080, // [inkoalawetrust] Actor ALWAYS takes hurt floor damage if there's any. Even if the floor doesn't have SECMF_HURTMONSTERS.
}; };
// --- mobj.renderflags --- // --- mobj.renderflags ---

View file

@ -198,39 +198,40 @@ void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flags, int
//========================================================================== //==========================================================================
// //
// P_PlayerOnSpecial3DFloor // P_ActorOnSpecial3DFloor
// Checks to see if a player is standing on or is inside a 3D floor (water) // Checks to see if an actor is standing on or is inside a 3D floor (water)
// and applies any specials.. // and applies any specials..
// //
//========================================================================== //==========================================================================
void P_PlayerOnSpecial3DFloor(player_t* player) void P_ActorOnSpecial3DFloor(AActor* victim)
{ {
for(auto rover : player->mo->Sector->e->XFloor.ffloors) for(auto rover : victim->Sector->e->XFloor.ffloors)
{ {
if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_EXISTS)) continue;
if (rover->flags & FF_FIX) continue; if (rover->flags & FF_FIX) continue;
if (!checkForSpecialSector(victim, rover->model)) continue;
// Check the 3D floor's type... // Check the 3D floor's type...
if(rover->flags & FF_SOLID) if(rover->flags & FF_SOLID)
{ {
// Player must be on top of the floor to be affected... // Player must be on top of the floor to be affected...
if(player->mo->Z() != rover->top.plane->ZatPoint(player->mo)) continue; if (victim->Z() != rover->top.plane->ZatPoint(victim)) continue;
} }
else else
{ {
//Water and DEATH FOG!!! heh //Water and DEATH FOG!!! heh
if ((rover->flags & FF_NODAMAGE) || if ((rover->flags & FF_NODAMAGE) ||
player->mo->Z() > rover->top.plane->ZatPoint(player->mo) || victim->Z() > rover->top.plane->ZatPoint(victim) ||
player->mo->Top() < rover->bottom.plane->ZatPoint(player->mo)) victim->Top() < rover->bottom.plane->ZatPoint(victim))
continue; continue;
} }
// Apply sector specials // Apply sector specials
P_PlayerInSpecialSector(player, rover->model); P_ActorInSpecialSector(victim, rover->model,rover);
// Apply flat specials (using the ceiling!) // Apply flat specials (using the ceiling!)
P_PlayerOnSpecialFlat(player, rover->model->GetTerrain(rover->top.isceiling)); P_ActorOnSpecialFlat(victim, rover->model->GetTerrain(rover->top.isceiling));
break; break;
} }

View file

@ -113,8 +113,7 @@ struct lightlist_t
class player_t; void P_ActorOnSpecial3DFloor(AActor* victim);
void P_PlayerOnSpecial3DFloor(player_t* player);
bool P_CheckFor3DFloorHit(AActor * mo, double z, bool trigger); bool P_CheckFor3DFloorHit(AActor * mo, double z, bool trigger);
bool P_CheckFor3DCeilingHit(AActor * mo, double z, bool trigger); bool P_CheckFor3DCeilingHit(AActor * mo, double z, bool trigger);

View file

@ -464,6 +464,12 @@ static int P_IsUnderDamage(AActor* actor)
dir |= cl->getDirection(); dir |= cl->getDirection();
} }
// Q: consider crushing 3D floors too? // Q: consider crushing 3D floors too?
// [inkoalawetrust] Check for sectors that can harm the actor.
if (!(actor->flags9 & MF9_NOSECTORDAMAGE) && seclist->m_sector->damageamount > 0)
{
if (seclist->m_sector->MoreFlags & SECMF_HARMINAIR || actor->isAtZ(seclist->m_sector->LowestFloorAt(actor)) || actor->waterlevel)
return (actor->player || (actor->player == nullptr && seclist->m_sector->MoreFlags & SECMF_HURTMONSTERS)) ? -1 : 0;
}
} }
return dir; return dir;
} }

View file

@ -4435,6 +4435,14 @@ void AActor::Tick ()
// must have been removed // must have been removed
if (ObjectFlags & OF_EuthanizeMe) return; if (ObjectFlags & OF_EuthanizeMe) return;
} }
//[inkoalawetrust] Genericized level damage handling that makes sector, 3D floor, and TERRAIN flat damage affect monsters and other NPCs too.
P_ActorOnSpecial3DFloor(this); //3D floors must be checked separately to see if their control sector allows non-player damage
if (checkForSpecialSector(this,Sector))
{
P_ActorInSpecialSector(this,Sector);
if (!isAbove(Sector->floorplane.ZatPoint(this)) || waterlevel) // Actor must be touching the floor for TERRAIN flats.
P_ActorOnSpecialFlat(this, P_GetThingFloorType(this));
}
if (tics != -1) if (tics != -1)
{ {

View file

@ -100,7 +100,7 @@
#include "c_console.h" #include "c_console.h"
#include "p_spec_thinkers.h" #include "p_spec_thinkers.h"
static FRandom pr_playerinspecialsector ("PlayerInSpecialSector"); static FRandom pr_actorinspecialsector ("ActorInSpecialSector");
EXTERN_CVAR(Bool, cl_predict_specials) EXTERN_CVAR(Bool, cl_predict_specials)
EXTERN_CVAR(Bool, forcewater) EXTERN_CVAR(Bool, forcewater)
@ -419,21 +419,25 @@ bool P_PredictLine(line_t *line, AActor *mo, int side, int activationType)
} }
// //
// P_PlayerInSpecialSector // P_ActorInSpecialSector
// Called every tic frame // Called every tic frame
// that the player origin is in a special sector // that the actor origin is in a special sector
// //
void P_PlayerInSpecialSector (player_t *player, sector_t * sector) void P_ActorInSpecialSector (AActor *victim, sector_t * sector, F3DFloor* Ffloor)
{ {
if (sector == NULL) if (sector == NULL)
sector = victim->Sector;
// Falling, not all the way down yet?
if (Ffloor != nullptr && !(Ffloor->flags & FF_SOLID)) Printf("this 3d floor is not solid\n");
bool evilAir = (sector->MoreFlags & SECMF_HARMINAIR);
bool SolidFfloor = Ffloor != nullptr && (Ffloor->flags & FF_SOLID);
if ((!evilAir && !(Ffloor != nullptr && !SolidFfloor)) && !victim->waterlevel)
{ {
// Falling, not all the way down yet? // [inkoalawetrust] Check for 3D floors differently, because non-FF_INVERTSECTOR ffloors have their floor plane as the 3D floor BOTTOM.
sector = player->mo->Sector; double theZ = Ffloor == nullptr ? sector->LowestFloorAt(victim) : Ffloor->top.plane->ZatPoint(victim);
if (!player->mo->isAtZ(sector->LowestFloorAt(player->mo)) if (!victim->isAtZ(theZ))
&& !player->mo->waterlevel)
{
return; return;
}
} }
// Has hit ground. // Has hit ground.
@ -445,7 +449,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
if (sector->damageinterval <= 0) if (sector->damageinterval <= 0)
sector->damageinterval = 32; // repair invalid damageinterval values sector->damageinterval = 32; // repair invalid damageinterval values
if (sector->Flags & (SECF_EXIT1 | SECF_EXIT2)) if (victim->player && sector->Flags & (SECF_EXIT1 | SECF_EXIT2))
{ {
for (int i = 0; i < MAXPLAYERS; i++) for (int i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i])
@ -464,7 +468,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
// different damage types yet, so that's not happening for now. // different damage types yet, so that's not happening for now.
// [MK] account for subclasses that may have "Full" protection (i.e.: prevent leaky damage) // [MK] account for subclasses that may have "Full" protection (i.e.: prevent leaky damage)
int ironfeet = 0; int ironfeet = 0;
for (auto i = player->mo->Inventory; i != NULL; i = i->Inventory) for (auto i = victim->Inventory; i != NULL; i = i->Inventory)
{ {
if (i->IsKindOf(NAME_PowerIronFeet)) if (i->IsKindOf(NAME_PowerIronFeet))
{ {
@ -476,28 +480,28 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
} }
} }
if (sector->Flags & SECF_ENDGODMODE) player->cheats &= ~CF_GODMODE; if (victim->player && sector->Flags & SECF_ENDGODMODE) victim->player->cheats &= ~CF_GODMODE;
if ((ironfeet == 0 || (ironfeet < 2 && pr_playerinspecialsector() < sector->leakydamage))) if ((ironfeet == 0 || (ironfeet < 2 && pr_actorinspecialsector() < sector->leakydamage)))
{ {
if (sector->Flags & SECF_HAZARD) if (victim->player && sector->Flags & SECF_HAZARD)
{ {
player->hazardcount += sector->damageamount; victim->player->hazardcount += sector->damageamount;
player->hazardtype = sector->damagetype; victim->player->hazardtype = sector->damagetype;
player->hazardinterval = sector->damageinterval; victim->player->hazardinterval = sector->damageinterval;
} }
else if (Level->time % sector->damageinterval == 0) else if (Level->time % sector->damageinterval == 0)
{ {
if (!(player->cheats & (CF_GODMODE | CF_GODMODE2))) if (!(victim->player && victim->player->cheats & (CF_GODMODE | CF_GODMODE2)))
{ {
P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); P_DamageMobj(victim, NULL, NULL, sector->damageamount, sector->damagetype);
} }
if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT))) if (victim->player && (sector->Flags & SECF_ENDLEVEL) && victim->player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT)))
{ {
Level->ExitLevel(0, false); Level->ExitLevel(0, false);
} }
if (sector->Flags & SECF_DMGTERRAINFX) if (sector->Flags & SECF_DMGTERRAINFX)
{ {
P_HitWater(player->mo, player->mo->Sector, player->mo->Pos(), false, true, true); P_HitWater(victim, victim->Sector, victim->Pos(), false, true, true);
} }
} }
} }
@ -506,14 +510,14 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
{ {
if (Level->time % sector->damageinterval == 0) if (Level->time % sector->damageinterval == 0)
{ {
P_GiveBody(player->mo, -sector->damageamount, 100); P_GiveBody(victim, -sector->damageamount, 100);
} }
} }
if (sector->isSecret()) if (victim->player && sector->isSecret())
{ {
sector->ClearSecret(); sector->ClearSecret();
P_GiveSecret(Level, player->mo, true, true, sector->Index()); P_GiveSecret(Level, victim, true, true, sector->Index());
} }
} }
@ -652,13 +656,13 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret)
//============================================================================ //============================================================================
// //
// P_PlayerOnSpecialFlat // P_ActorOnSpecialFlat
// //
//============================================================================ //============================================================================
void P_PlayerOnSpecialFlat (player_t *player, int floorType) void P_ActorOnSpecialFlat (AActor *victim, int floorType)
{ {
auto Level = player->mo->Level; auto Level = victim->Level;
if (Terrains[floorType].DamageAmount && if (Terrains[floorType].DamageAmount &&
!(Level->time % (Terrains[floorType].DamageTimeMask+1))) !(Level->time % (Terrains[floorType].DamageTimeMask+1)))
@ -668,7 +672,7 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType)
if (Terrains[floorType].AllowProtection) if (Terrains[floorType].AllowProtection)
{ {
auto pitype = PClass::FindActor(NAME_PowerIronFeet); auto pitype = PClass::FindActor(NAME_PowerIronFeet);
for (ironfeet = player->mo->Inventory; ironfeet != NULL; ironfeet = ironfeet->Inventory) for (ironfeet = victim->Inventory; ironfeet != NULL; ironfeet = ironfeet->Inventory)
{ {
if (ironfeet->IsKindOf (pitype)) if (ironfeet->IsKindOf (pitype))
break; break;
@ -678,20 +682,18 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType)
int damage = 0; int damage = 0;
if (ironfeet == NULL) if (ironfeet == NULL)
{ {
damage = P_DamageMobj (player->mo, NULL, NULL, Terrains[floorType].DamageAmount, damage = P_DamageMobj (victim, NULL, NULL, Terrains[floorType].DamageAmount,
Terrains[floorType].DamageMOD); Terrains[floorType].DamageMOD);
} }
if (damage > 0 && Terrains[floorType].Splash != -1) if (damage > 0 && Terrains[floorType].Splash != -1)
{ {
S_Sound (player->mo, CHAN_AUTO, 0, S_Sound (victim, CHAN_AUTO, 0,
Splashes[Terrains[floorType].Splash].NormalSplashSound, 1, Splashes[Terrains[floorType].Splash].NormalSplashSound, 1,
ATTN_IDLE); ATTN_IDLE);
} }
} }
} }
// //
// P_UpdateSpecials // P_UpdateSpecials
// Animate planes, scroll walls, etc. // Animate planes, scroll walls, etc.

View file

@ -35,6 +35,7 @@
#include "dsectoreffect.h" #include "dsectoreffect.h"
#include "doomdata.h" #include "doomdata.h"
#include "r_state.h" #include "r_state.h"
#include "d_player.h"
class FScanner; class FScanner;
struct level_info_t; struct level_info_t;
@ -90,13 +91,22 @@ bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVect
bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVector3 *optpos = NULL); bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVector3 *optpos = NULL);
bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType); bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType);
void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL); void P_ActorInSpecialSector (AActor *victim, sector_t * sector = NULL, F3DFloor* Ffloor = NULL);
void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_ActorOnSpecialFlat (AActor *victim, int floorType);
void P_SectorDamage(FLevelLocals *Level, int tag, int amount, FName type, PClassActor *protectClass, int flags); void P_SectorDamage(FLevelLocals *Level, int tag, int amount, FName type, PClassActor *protectClass, int flags);
void P_SetSectorFriction (FLevelLocals *level, int tag, int amount, bool alterFlag); void P_SetSectorFriction (FLevelLocals *level, int tag, int amount, bool alterFlag);
double FrictionToMoveFactor(double friction); double FrictionToMoveFactor(double friction);
void P_GiveSecret(FLevelLocals *Level, AActor *actor, bool printmessage, bool playsound, int sectornum); void P_GiveSecret(FLevelLocals *Level, AActor *actor, bool printmessage, bool playsound, int sectornum);
inline bool checkForSpecialSector(AActor* mo, sector_t* sec)
{
bool afsdnope = !!(mo->flags9 & MF9_NOSECTORDAMAGE);
bool afsdforce = !!(mo->flags9 & MF9_FORCESECTORDAMAGE);
bool sfhurtmonsters = !!(sec->MoreFlags & SECMF_HURTMONSTERS);
bool isplayer = (mo->player != nullptr) && (mo == mo->player->mo);
return ((!afsdnope || afsdforce) && (isplayer || sfhurtmonsters || afsdforce));
}
// //
// getNextSector() // getNextSector()
// Return sector_t * of sector next to current. // Return sector_t * of sector next to current.

View file

@ -1204,15 +1204,6 @@ DEFINE_ACTION_FUNCTION(APlayerPawn, CheckMusicChange)
void P_CheckEnvironment(player_t *player) void P_CheckEnvironment(player_t *player)
{ {
P_PlayerOnSpecial3DFloor(player);
P_PlayerInSpecialSector(player);
if (!player->mo->isAbove(player->mo->Sector->floorplane.ZatPoint(player->mo)) ||
player->mo->waterlevel)
{
// Player must be touching the floor
P_PlayerOnSpecialFlat(player, P_GetThingFloorType(player->mo));
}
if (player->mo->Vel.Z <= -player->mo->FloatVar(NAME_FallingScreamMinSpeed) && if (player->mo->Vel.Z <= -player->mo->FloatVar(NAME_FallingScreamMinSpeed) &&
player->mo->Vel.Z >= -player->mo->FloatVar(NAME_FallingScreamMaxSpeed) && player->mo->alternative == nullptr && player->mo->Vel.Z >= -player->mo->FloatVar(NAME_FallingScreamMaxSpeed) && player->mo->alternative == nullptr &&
player->mo->waterlevel == 0) player->mo->waterlevel == 0)

View file

@ -351,7 +351,9 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF9, SHADOWBLOCK, AActor, flags9), DEFINE_FLAG(MF9, SHADOWBLOCK, AActor, flags9),
DEFINE_FLAG(MF9, SHADOWAIMVERT, AActor, flags9), DEFINE_FLAG(MF9, SHADOWAIMVERT, AActor, flags9),
DEFINE_FLAG(MF9, DECOUPLEDANIMATIONS, AActor, flags9), DEFINE_FLAG(MF9, DECOUPLEDANIMATIONS, AActor, flags9),
DEFINE_FLAG(MF9, NOSECTORDAMAGE, AActor, flags9),
DEFINE_PROTECTED_FLAG(MF9, ISPUFF, AActor, flags9), //[AA] was spawned by SpawnPuff DEFINE_PROTECTED_FLAG(MF9, ISPUFF, AActor, flags9), //[AA] was spawned by SpawnPuff
DEFINE_FLAG(MF9, FORCESECTORDAMAGE, AActor, flags9),
// Effect flags // Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View file

@ -435,6 +435,11 @@ struct Sector native play
SECMF_UNDERWATERMASK = 32+64, SECMF_UNDERWATERMASK = 32+64,
SECMF_DRAWN = 128, // sector has been drawn at least once SECMF_DRAWN = 128, // sector has been drawn at least once
SECMF_HIDDEN = 256, // Do not draw on textured automap 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
SECMF_HURTMONSTERS = 4096, // Monsters in this sector are hurt like players.
SECMF_HARMINAIR = 8192, // Actors in this sector are also hurt mid-air.
} }
native uint16 MoreFlags; native uint16 MoreFlags;
@ -452,6 +457,9 @@ struct Sector native play
SECF_ENDLEVEL = 512, // ends level when health goes below 10 SECF_ENDLEVEL = 512, // ends level when health goes below 10
SECF_HAZARD = 1024, // Change to Strife's delayed damage handling. SECF_HAZARD = 1024, // Change to Strife's delayed damage handling.
SECF_NOATTACK = 2048, // monsters cannot start attacks in this sector. SECF_NOATTACK = 2048, // monsters cannot start attacks in this sector.
SECF_EXIT1 = 4096,
SECF_EXIT2 = 8192,
SECF_KILLMONSTERS = 16384,// Monsters in this sector are instantly killed.
SECF_WASSECRET = 1 << 30, // a secret that was discovered SECF_WASSECRET = 1 << 30, // a secret that was discovered
SECF_SECRET = 1 << 31, // a secret sector SECF_SECRET = 1 << 31, // a secret sector