mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
- removed FraggleScript's 'sectortype' function. This was GZDoom exclusive and never documented so it got no public exposure. Since this is incompatible with the damage related changes, it has no more use.
- major overhaul of the static sector damage system: * consolidated special based damage, Sector_SetDamage and UDMF properties into one set of damage properties. The parallel handling that could lead to double damage infliction was removed. This also means that damage through sector specials can be retroactively changed through Sector_SetDamage. * all special cases were turned into flags. The new system can switch between Strife's delayed damage and regular damage, and it can also set whether terrain splashes are used or not. It also has access to the special properties of the end-level type (i.e. switching off god mode and ending the level.) * the damage related flags are accessible through Sector_ChangeFlags, not the damage functions themselves.
This commit is contained in:
parent
b0db5d9b16
commit
5474e01de8
9 changed files with 282 additions and 323 deletions
|
@ -204,10 +204,15 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
||||||
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
|
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
|
||||||
waterzone = <bool>; // Sector is under water and swimmable
|
waterzone = <bool>; // Sector is under water and swimmable
|
||||||
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||||
damageamount = <int>; // Amount of damage inflicted by this sector, default = 0
|
damageamount = <int>; // Amount of damage inflicted by this sector, default = 0. If this is 0, all other damage properties will be ignored.
|
||||||
|
// Setting damage through these properties will override any damage set through 'special'.
|
||||||
|
// Setting damageamount to a negative value will create a healing sector.
|
||||||
damagetype = <string>; // Damage type for sector damage, Default = "None". (generic damage)
|
damagetype = <string>; // Damage type for sector damage, Default = "None". (generic damage)
|
||||||
damageinterval = <int>; // Interval in tics between damage application, default = 32.
|
damageinterval = <int>; // Interval in tics between damage application, default = 32.
|
||||||
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.
|
||||||
|
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
|
||||||
|
|
||||||
|
|
||||||
* Note about dropactors
|
* Note about dropactors
|
||||||
|
|
||||||
|
|
|
@ -354,21 +354,5 @@ void DBot::Pitch (AActor *target)
|
||||||
//Checks if a sector is dangerous.
|
//Checks if a sector is dangerous.
|
||||||
bool FCajunMaster::IsDangerous (sector_t *sec)
|
bool FCajunMaster::IsDangerous (sector_t *sec)
|
||||||
{
|
{
|
||||||
int special;
|
return sec->damageamount > 0;
|
||||||
|
|
||||||
return
|
|
||||||
sec->damageamount
|
|
||||||
|| sec->special & DAMAGE_MASK
|
|
||||||
|| (special = sec->special & 0xff, special == dLight_Strobe_Hurt)
|
|
||||||
|| special == dDamage_Hellslime
|
|
||||||
|| special == dDamage_Nukage
|
|
||||||
|| special == dDamage_End
|
|
||||||
|| special == dDamage_SuperHellslime
|
|
||||||
|| special == dDamage_LavaWimpy
|
|
||||||
|| special == dDamage_LavaHefty
|
|
||||||
|| special == dScroll_EastLavaDamage
|
|
||||||
|| special == hDamage_Sludge
|
|
||||||
|| special == sLight_Strobe_Hurt
|
|
||||||
|| special == Damage_InstantDeath
|
|
||||||
|| special == sDamage_SuperHellslime;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4323,44 +4323,12 @@ void FParser::SF_KillInSector()
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// new for GZDoom: Sets a sector's type
|
// new for GZDoom: Sets a sector's type
|
||||||
// (Sure, this is not particularly useful. But having it made it possible
|
|
||||||
// to fix a few annoying bugs in some old maps ;) )
|
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FParser::SF_SectorType(void)
|
void FParser::SF_SectorType(void)
|
||||||
{
|
{
|
||||||
int tagnum, secnum;
|
// I don't think this was ever used publicly so I'm not going to bother fixing it.
|
||||||
sector_t *sector;
|
|
||||||
|
|
||||||
if (CheckArgs(1))
|
|
||||||
{
|
|
||||||
tagnum = intvalue(t_argv[0]);
|
|
||||||
|
|
||||||
// argv is sector tag
|
|
||||||
secnum = T_FindFirstSectorFromTag(tagnum);
|
|
||||||
|
|
||||||
if(secnum < 0)
|
|
||||||
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
|
|
||||||
|
|
||||||
sector = §ors[secnum];
|
|
||||||
|
|
||||||
if(t_argc > 1)
|
|
||||||
{
|
|
||||||
int i = -1;
|
|
||||||
int spec = intvalue(t_argv[1]);
|
|
||||||
|
|
||||||
// set all sectors with tag
|
|
||||||
FSSectorTagIterator itr(tagnum);
|
|
||||||
while ((i = itr.Next()) >= 0)
|
|
||||||
{
|
|
||||||
sectors[i].special = spec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t_return.type = svt_int;
|
|
||||||
t_return.value.i = sector->special;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -510,6 +510,8 @@ xx(damageamount)
|
||||||
xx(damagetype)
|
xx(damagetype)
|
||||||
xx(damageinterval)
|
xx(damageinterval)
|
||||||
xx(leakiness)
|
xx(leakiness)
|
||||||
|
xx(damageterraineffect)
|
||||||
|
xx(damagehazard)
|
||||||
|
|
||||||
// USDF keywords
|
// USDF keywords
|
||||||
xx(Amount)
|
xx(Amount)
|
||||||
|
|
|
@ -513,8 +513,6 @@ void P_SpawnDoorCloseIn30 (sector_t *sec)
|
||||||
fixed_t height;
|
fixed_t height;
|
||||||
DDoor *door = new DDoor (sec);
|
DDoor *door = new DDoor (sec);
|
||||||
|
|
||||||
sec->special = 0;
|
|
||||||
|
|
||||||
door->m_Sector = sec;
|
door->m_Sector = sec;
|
||||||
door->m_Direction = 0;
|
door->m_Direction = 0;
|
||||||
door->m_Type = DDoor::doorRaise;
|
door->m_Type = DDoor::doorRaise;
|
||||||
|
@ -535,7 +533,6 @@ void P_SpawnDoorCloseIn30 (sector_t *sec)
|
||||||
|
|
||||||
void P_SpawnDoorRaiseIn5Mins (sector_t *sec)
|
void P_SpawnDoorRaiseIn5Mins (sector_t *sec)
|
||||||
{
|
{
|
||||||
sec->special = 0;
|
|
||||||
new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0);
|
new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1255,8 +1255,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of game hell hack
|
// end of game hell hack
|
||||||
if ((target->Sector->special & 255) == dDamage_End
|
if ((target->Sector->Flags & SECF_ENDLEVEL) && damage >= target->health)
|
||||||
&& damage >= target->health)
|
|
||||||
{
|
{
|
||||||
damage = target->health - 1;
|
damage = target->health - 1;
|
||||||
}
|
}
|
||||||
|
|
514
src/p_spec.cpp
514
src/p_spec.cpp
|
@ -442,135 +442,40 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
|
||||||
// Has hit ground.
|
// Has hit ground.
|
||||||
AInventory *ironfeet;
|
AInventory *ironfeet;
|
||||||
|
|
||||||
// Allow subclasses. Better would be to implement it as armor and let that reduce
|
|
||||||
// the damage as part of the normal damage procedure. Unfortunately, I don't have
|
|
||||||
// different damage types yet, so that's not happening for now.
|
|
||||||
for (ironfeet = player->mo->Inventory; ironfeet != NULL; ironfeet = ironfeet->Inventory)
|
|
||||||
{
|
|
||||||
if (ironfeet->IsKindOf (RUNTIME_CLASS(APowerIronFeet)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RH] Normal DOOM special or BOOM specialized?
|
|
||||||
if (special >= dLight_Flicker && special <= 255)
|
|
||||||
{
|
|
||||||
switch (special)
|
|
||||||
{
|
|
||||||
case Sector_Heal:
|
|
||||||
// CoD's healing sector
|
|
||||||
if (!(level.time & 0x1f))
|
|
||||||
P_GiveBody (player->mo, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Damage_InstantDeath:
|
|
||||||
// Strife's instant death sector
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 999, NAME_InstantDeath);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dDamage_Hellslime:
|
|
||||||
// HELLSLIME DAMAGE
|
|
||||||
if (ironfeet == NULL && !(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 10, NAME_Slime);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dDamage_Nukage:
|
|
||||||
// NUKAGE DAMAGE
|
|
||||||
case sLight_Strobe_Hurt:
|
|
||||||
if (ironfeet == NULL && !(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 5, NAME_Slime);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case hDamage_Sludge:
|
|
||||||
if (ironfeet == NULL && !(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 4, NAME_Slime);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dDamage_SuperHellslime:
|
|
||||||
// SUPER HELLSLIME DAMAGE
|
|
||||||
case dLight_Strobe_Hurt:
|
|
||||||
// STROBE HURT
|
|
||||||
if (ironfeet == NULL || pr_playerinspecialsector() < 5)
|
|
||||||
{
|
|
||||||
if (!(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 20, NAME_Slime);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case sDamage_Hellslime:
|
|
||||||
if (ironfeet == NULL)
|
|
||||||
player->hazardcount += 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case sDamage_SuperHellslime:
|
|
||||||
if (ironfeet == NULL)
|
|
||||||
player->hazardcount += 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dDamage_End:
|
|
||||||
// EXIT SUPER DAMAGE! (for E1M8 finale)
|
|
||||||
player->cheats &= ~CF_GODMODE;
|
|
||||||
|
|
||||||
if (!(level.time & 0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 20, NAME_None);
|
|
||||||
|
|
||||||
if (player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT)))
|
|
||||||
G_ExitLevel(0, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dDamage_LavaWimpy:
|
|
||||||
case dScroll_EastLavaDamage:
|
|
||||||
if (!(level.time & 15))
|
|
||||||
{
|
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 5, NAME_Fire);
|
|
||||||
P_HitFloor(player->mo);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dDamage_LavaHefty:
|
|
||||||
if(!(level.time & 15))
|
|
||||||
{
|
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 8, NAME_Fire);
|
|
||||||
P_HitFloor(player->mo);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// [RH] Ignore unknown specials
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//jff 3/14/98 handle extended sector types for secrets and damage
|
|
||||||
switch (special & DAMAGE_MASK)
|
|
||||||
{
|
|
||||||
case 0x000: // no damage
|
|
||||||
break;
|
|
||||||
case 0x100: // 2/5 damage per 31 ticks
|
|
||||||
if (ironfeet == NULL && !(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 5, NAME_Fire);
|
|
||||||
break;
|
|
||||||
case 0x200: // 5/10 damage per 31 ticks
|
|
||||||
if (ironfeet == NULL && !(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 10, NAME_Slime);
|
|
||||||
break;
|
|
||||||
case 0x300: // 10/20 damage per 31 ticks
|
|
||||||
if (ironfeet == NULL
|
|
||||||
|| pr_playerinspecialsector() < 5) // take damage even with suit
|
|
||||||
{
|
|
||||||
if (!(level.time&0x1f))
|
|
||||||
P_DamageMobj (player->mo, NULL, NULL, 20, NAME_Slime);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RH] Apply any customizable damage
|
// [RH] Apply any customizable damage
|
||||||
if (sector->damageamount != 0)
|
if (sector->damageamount > 0)
|
||||||
{
|
{
|
||||||
|
// Allow subclasses. Better would be to implement it as armor and let that reduce
|
||||||
|
// the damage as part of the normal damage procedure. Unfortunately, I don't have
|
||||||
|
// different damage types yet, so that's not happening for now.
|
||||||
|
for (ironfeet = player->mo->Inventory; ironfeet != NULL; ironfeet = ironfeet->Inventory)
|
||||||
|
{
|
||||||
|
if (ironfeet->IsKindOf (RUNTIME_CLASS(APowerIronFeet)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sector->Flags & SECF_ENDGODMODE) player->cheats &= ~CF_GODMODE;
|
||||||
if (level.time % sector->damageinterval == 0 && (ironfeet == NULL || pr_playerinspecialsector() < sector->leakydamage))
|
if (level.time % sector->damageinterval == 0 && (ironfeet == NULL || pr_playerinspecialsector() < sector->leakydamage))
|
||||||
{
|
{
|
||||||
P_DamageMobj (player->mo, NULL, NULL, sector->damageamount, sector->damagetype);
|
if (sector->Flags & SECF_HAZARD)
|
||||||
|
{
|
||||||
|
player->hazardcount += sector->damageamount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype);
|
||||||
|
if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT)))
|
||||||
|
{
|
||||||
|
G_ExitLevel(0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sector->damageamount < 0)
|
||||||
|
{
|
||||||
|
if (level.time % sector->damageinterval == 0)
|
||||||
|
{
|
||||||
|
P_GiveBody(player->mo, -sector->damageamount, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1167,6 +1072,223 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_SetSectorDamage
|
||||||
|
//
|
||||||
|
// Sets damage properties for one sector. Allows combination of original specials with explicit use of the damage properties
|
||||||
|
//
|
||||||
|
|
||||||
|
static void P_SetupSectorDamage(sector_t *sector, int damage, int interval, int leakchance, FName type, int flags)
|
||||||
|
{
|
||||||
|
// Only set if damage is not yet initialized. This ensures that UDMF takes precedence over sector specials.
|
||||||
|
if (sector->damageamount == 0)
|
||||||
|
{
|
||||||
|
sector->damageamount = damage;
|
||||||
|
sector->damageinterval = MAX(1, interval);
|
||||||
|
sector->leakydamage = leakchance;
|
||||||
|
sector->damagetype = type;
|
||||||
|
sector->Flags = (sector->Flags & ~SECF_DAMAGEFLAGS) | (flags & SECF_DAMAGEFLAGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_InitSectorSpecial
|
||||||
|
//
|
||||||
|
// Sets up everything derived from 'sector->special' for one sector
|
||||||
|
// ('fromload' is necessary to allow conversion upon savegame load.)
|
||||||
|
//
|
||||||
|
|
||||||
|
void P_InitSectorSpecial(sector_t *sector, int special)
|
||||||
|
{
|
||||||
|
// [RH] All secret sectors are marked with a BOOM-ish bitfield
|
||||||
|
if (sector->special & SECRET_MASK)
|
||||||
|
{
|
||||||
|
sector->Flags |= SECF_SECRET | SECF_WASSECRET;
|
||||||
|
level.total_secrets++;
|
||||||
|
}
|
||||||
|
if (sector->special & FRICTION_MASK)
|
||||||
|
{
|
||||||
|
sector->Flags |= SECF_FRICTION;
|
||||||
|
}
|
||||||
|
if (sector->special & PUSH_MASK)
|
||||||
|
{
|
||||||
|
sector->Flags |= SECF_PUSH;
|
||||||
|
}
|
||||||
|
if ((sector->special & DAMAGE_MASK) == 0x100)
|
||||||
|
{
|
||||||
|
P_SetupSectorDamage(sector, 5, 32, 0, NAME_Fire, 0);
|
||||||
|
}
|
||||||
|
else if ((sector->special & DAMAGE_MASK) == 0x200)
|
||||||
|
{
|
||||||
|
P_SetupSectorDamage(sector, 10, 32, 0, NAME_Slime, 0);
|
||||||
|
}
|
||||||
|
else if ((sector->special & DAMAGE_MASK) == 0x300)
|
||||||
|
{
|
||||||
|
P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0);
|
||||||
|
}
|
||||||
|
sector->special &= 0xff;
|
||||||
|
|
||||||
|
// [RH] Normal DOOM special or BOOM specialized?
|
||||||
|
bool keepspecial = false;
|
||||||
|
switch (sector->special)
|
||||||
|
{
|
||||||
|
case Light_Phased:
|
||||||
|
new DPhased (sector, 48, 63 - (sector->lightlevel & 63));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// [RH] Hexen-like phased lighting
|
||||||
|
case LightSequenceStart:
|
||||||
|
new DPhased (sector);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_Flicker:
|
||||||
|
new DLightFlash (sector);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_StrobeFast:
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_StrobeSlow:
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_Strobe_Hurt:
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
||||||
|
P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dDamage_Hellslime:
|
||||||
|
P_SetupSectorDamage(sector, 10, 32, 0, NAME_Slime, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dDamage_Nukage:
|
||||||
|
P_SetupSectorDamage(sector, 5, 32, 0, NAME_Slime, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_Glow:
|
||||||
|
new DGlow (sector);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dSector_DoorCloseIn30:
|
||||||
|
P_SpawnDoorCloseIn30 (sector);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dDamage_End:
|
||||||
|
P_SetupSectorDamage(sector, 20, 32, 256, NAME_None, SECF_ENDGODMODE|SECF_ENDLEVEL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_StrobeSlowSync:
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_StrobeFastSync:
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, FASTDARK, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dSector_DoorRaiseIn5Mins:
|
||||||
|
P_SpawnDoorRaiseIn5Mins (sector);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dFriction_Low:
|
||||||
|
sector->friction = FRICTION_LOW;
|
||||||
|
sector->movefactor = 0x269;
|
||||||
|
sector->Flags |= SECF_FRICTION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dDamage_SuperHellslime:
|
||||||
|
P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dLight_FireFlicker:
|
||||||
|
new DFireFlicker (sector);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dDamage_LavaWimpy:
|
||||||
|
P_SetupSectorDamage(sector, 5, 32, 256, NAME_Fire, SECF_DMGTERRAINFX);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dDamage_LavaHefty:
|
||||||
|
P_SetupSectorDamage(sector, 8, 32, 256, NAME_Fire, SECF_DMGTERRAINFX);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dScroll_EastLavaDamage:
|
||||||
|
P_SetupSectorDamage(sector, 5, 32, 256, NAME_Fire, SECF_DMGTERRAINFX);
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
||||||
|
new DScroller (DScroller::sc_floor, (-FRACUNIT/2)<<3,
|
||||||
|
0, -1, int(sector-sectors), 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case hDamage_Sludge:
|
||||||
|
P_SetupSectorDamage(sector, 4, 32, 0, NAME_Slime, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sLight_Strobe_Hurt:
|
||||||
|
P_SetupSectorDamage(sector, 5, 32, 0, NAME_Slime, 0);
|
||||||
|
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sDamage_Hellslime:
|
||||||
|
P_SetupSectorDamage(sector, 2, 1, 0, NAME_None, SECF_HAZARD);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Damage_InstantDeath:
|
||||||
|
// Strife's instant death sector
|
||||||
|
P_SetupSectorDamage(sector, TELEFRAG_DAMAGE, 1, 256, NAME_InstantDeath, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sDamage_SuperHellslime:
|
||||||
|
P_SetupSectorDamage(sector, 4, 1, 0, NAME_None, SECF_HAZARD);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Sector_Hidden:
|
||||||
|
sector->MoreFlags |= SECF_HIDDEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Sector_Heal:
|
||||||
|
// CoD's healing sector
|
||||||
|
P_SetupSectorDamage(sector, -1, 32, 0, NAME_None, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Sky2:
|
||||||
|
sector->sky = PL_SKYFLAT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (sector->special >= Scroll_North_Slow &&
|
||||||
|
sector->special <= Scroll_SouthWest_Fast)
|
||||||
|
{ // Hexen scroll special
|
||||||
|
static const char hexenScrollies[24][2] =
|
||||||
|
{
|
||||||
|
{ 0, 1 }, { 0, 2 }, { 0, 4 },
|
||||||
|
{ -1, 0 }, { -2, 0 }, { -4, 0 },
|
||||||
|
{ 0, -1 }, { 0, -2 }, { 0, -4 },
|
||||||
|
{ 1, 0 }, { 2, 0 }, { 4, 0 },
|
||||||
|
{ 1, 1 }, { 2, 2 }, { 4, 4 },
|
||||||
|
{ -1, 1 }, { -2, 2 }, { -4, 4 },
|
||||||
|
{ -1, -1 }, { -2, -2 }, { -4, -4 },
|
||||||
|
{ 1, -1 }, { 2, -2 }, { 4, -4 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int i = (sector->special & 0xff) - Scroll_North_Slow;
|
||||||
|
fixed_t dx = hexenScrollies[i][0] * (FRACUNIT/2);
|
||||||
|
fixed_t dy = hexenScrollies[i][1] * (FRACUNIT/2);
|
||||||
|
new DScroller (DScroller::sc_floor, dx, dy, -1, int(sector-sectors), 0);
|
||||||
|
}
|
||||||
|
else if (sector->special >= Carry_East5 &&
|
||||||
|
sector->special <= Carry_East35)
|
||||||
|
{ // Heretic scroll special
|
||||||
|
// Only east scrollers also scroll the texture
|
||||||
|
new DScroller (DScroller::sc_floor,
|
||||||
|
(-FRACUNIT/2)<<((sector->special & 0xff) - Carry_East5),
|
||||||
|
0, -1, int(sector-sectors), 0);
|
||||||
|
}
|
||||||
|
else keepspecial = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!keepspecial) sector->special = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_SpawnSpecials
|
// P_SpawnSpecials
|
||||||
//
|
//
|
||||||
|
@ -1187,147 +1309,7 @@ void P_SpawnSpecials (void)
|
||||||
if (sector->special == 0)
|
if (sector->special == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// [RH] All secret sectors are marked with a BOOM-ish bitfield
|
P_InitSectorSpecial(sector, sector->special);
|
||||||
if (sector->special & SECRET_MASK)
|
|
||||||
{
|
|
||||||
sector->Flags |= SECF_SECRET | SECF_WASSECRET;
|
|
||||||
level.total_secrets++;
|
|
||||||
}
|
|
||||||
if (sector->special & FRICTION_MASK)
|
|
||||||
{
|
|
||||||
sector->Flags |= SECF_FRICTION;
|
|
||||||
}
|
|
||||||
if (sector->special & PUSH_MASK)
|
|
||||||
{
|
|
||||||
sector->Flags |= SECF_PUSH;
|
|
||||||
}
|
|
||||||
sector->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK);
|
|
||||||
|
|
||||||
switch (sector->special & 0xff)
|
|
||||||
{
|
|
||||||
// [RH] Normal DOOM/Hexen specials. We clear off the special for lights
|
|
||||||
// here instead of inside the spawners.
|
|
||||||
|
|
||||||
case dLight_Flicker:
|
|
||||||
// FLICKERING LIGHTS
|
|
||||||
new DLightFlash (sector);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_StrobeFast:
|
|
||||||
// STROBE FAST
|
|
||||||
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_StrobeSlow:
|
|
||||||
// STROBE SLOW
|
|
||||||
new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_Strobe_Hurt:
|
|
||||||
case sLight_Strobe_Hurt:
|
|
||||||
// STROBE FAST/DEATH SLIME
|
|
||||||
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_Glow:
|
|
||||||
// GLOWING LIGHT
|
|
||||||
new DGlow (sector);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dSector_DoorCloseIn30:
|
|
||||||
// DOOR CLOSE IN 30 SECONDS
|
|
||||||
P_SpawnDoorCloseIn30 (sector);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_StrobeSlowSync:
|
|
||||||
// SYNC STROBE SLOW
|
|
||||||
new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_StrobeFastSync:
|
|
||||||
// SYNC STROBE FAST
|
|
||||||
new DStrobe (sector, STROBEBRIGHT, FASTDARK, true);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dSector_DoorRaiseIn5Mins:
|
|
||||||
// DOOR RAISE IN 5 MINUTES
|
|
||||||
P_SpawnDoorRaiseIn5Mins (sector);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dLight_FireFlicker:
|
|
||||||
// fire flickering
|
|
||||||
new DFireFlicker (sector);
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dFriction_Low:
|
|
||||||
sector->friction = FRICTION_LOW;
|
|
||||||
sector->movefactor = 0x269;
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
sector->Flags |= SECF_FRICTION;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// [RH] Hexen-like phased lighting
|
|
||||||
case LightSequenceStart:
|
|
||||||
new DPhased (sector);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Light_Phased:
|
|
||||||
new DPhased (sector, 48, 63 - (sector->lightlevel & 63));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Sky2:
|
|
||||||
sector->sky = PL_SKYFLAT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dScroll_EastLavaDamage:
|
|
||||||
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
|
||||||
new DScroller (DScroller::sc_floor, (-FRACUNIT/2)<<3,
|
|
||||||
0, -1, int(sector-sectors), 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Sector_Hidden:
|
|
||||||
sector->MoreFlags |= SECF_HIDDEN;
|
|
||||||
sector->special &= 0xff00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if ((sector->special & 0xff) >= Scroll_North_Slow &&
|
|
||||||
(sector->special & 0xff) <= Scroll_SouthWest_Fast)
|
|
||||||
{ // Hexen scroll special
|
|
||||||
static const char hexenScrollies[24][2] =
|
|
||||||
{
|
|
||||||
{ 0, 1 }, { 0, 2 }, { 0, 4 },
|
|
||||||
{ -1, 0 }, { -2, 0 }, { -4, 0 },
|
|
||||||
{ 0, -1 }, { 0, -2 }, { 0, -4 },
|
|
||||||
{ 1, 0 }, { 2, 0 }, { 4, 0 },
|
|
||||||
{ 1, 1 }, { 2, 2 }, { 4, 4 },
|
|
||||||
{ -1, 1 }, { -2, 2 }, { -4, 4 },
|
|
||||||
{ -1, -1 }, { -2, -2 }, { -4, -4 },
|
|
||||||
{ 1, -1 }, { 2, -2 }, { 4, -4 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int i = (sector->special & 0xff) - Scroll_North_Slow;
|
|
||||||
fixed_t dx = hexenScrollies[i][0] * (FRACUNIT/2);
|
|
||||||
fixed_t dy = hexenScrollies[i][1] * (FRACUNIT/2);
|
|
||||||
new DScroller (DScroller::sc_floor, dx, dy, -1, int(sector-sectors), 0);
|
|
||||||
}
|
|
||||||
else if ((sector->special & 0xff) >= Carry_East5 &&
|
|
||||||
(sector->special & 0xff) <= Carry_East35)
|
|
||||||
{ // Heretic scroll special
|
|
||||||
// Only east scrollers also scroll the texture
|
|
||||||
new DScroller (DScroller::sc_floor,
|
|
||||||
(-FRACUNIT/2)<<((sector->special & 0xff) - Carry_East5),
|
|
||||||
0, -1, int(sector-sectors), 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init other misc stuff
|
// Init other misc stuff
|
||||||
|
|
|
@ -1542,6 +1542,14 @@ public:
|
||||||
sec->leakydamage = CheckInt(key);
|
sec->leakydamage = CheckInt(key);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NAME_damageterraineffect:
|
||||||
|
Flag(sec->Flags, SECF_DMGTERRAINFX, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_damagehazard:
|
||||||
|
Flag(sec->Flags, SECF_HAZARD, key);
|
||||||
|
break;
|
||||||
|
|
||||||
case NAME_MoreIds:
|
case NAME_MoreIds:
|
||||||
// delay parsing of the tag string until parsing of the sector is complete
|
// delay parsing of the tag string until parsing of the sector is complete
|
||||||
// This ensures that the ID is always the first tag in the list.
|
// This ensures that the ID is always the first tag in the list.
|
||||||
|
@ -1567,6 +1575,16 @@ public:
|
||||||
if (sc.Number != 0) tagManager.AddSectorTag(index, sc.Number);
|
if (sc.Number != 0) tagManager.AddSectorTag(index, sc.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sec->damageamount == 0)
|
||||||
|
{
|
||||||
|
// If no damage is set, clear all other related properties so that they do not interfere
|
||||||
|
// with other means of setting them.
|
||||||
|
sec->damagetype = NAME_None;
|
||||||
|
sec->damageinterval = 0;
|
||||||
|
sec->leakydamage = 0;
|
||||||
|
sec->Flags &= ~SECF_DAMAGEFLAGS;
|
||||||
|
}
|
||||||
|
|
||||||
// Reset the planes to their defaults if not all of the plane equation's parameters were found.
|
// Reset the planes to their defaults if not all of the plane equation's parameters were found.
|
||||||
if (fplaneflags != 15)
|
if (fplaneflags != 15)
|
||||||
|
|
|
@ -358,11 +358,15 @@ enum
|
||||||
SECF_FRICTION = 16, // sector has friction enabled
|
SECF_FRICTION = 16, // sector has friction enabled
|
||||||
SECF_PUSH = 32, // pushers enabled
|
SECF_PUSH = 32, // pushers enabled
|
||||||
SECF_SILENTMOVE = 64, // Sector movement makes mo sound (Eternity got this so this may be useful for an extended cross-port standard.)
|
SECF_SILENTMOVE = 64, // Sector movement makes mo sound (Eternity got this so this may be useful for an extended cross-port standard.)
|
||||||
|
SECF_DMGTERRAINFX = 128, // spawns terrain splash when inflicting damage
|
||||||
|
SECF_ENDGODMODE = 256, // getting damaged by this sector ends god mode
|
||||||
|
SECF_ENDLEVEL = 512, // ends level when health goes below 10
|
||||||
|
SECF_HAZARD = 1024, // Change to Strife's delayed damage handling.
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
SECF_DAMAGEFLAGS = SECF_ENDGODMODE|SECF_ENDLEVEL|SECF_DMGTERRAINFX|SECF_HAZARD,
|
||||||
SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET // not modifiable by Sector_ChangeFlags
|
SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET // not modifiable by Sector_ChangeFlags
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue