From a5a069a4b0835191652bb211dfa2a57a6f641042 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 5 Jan 2016 14:06:07 +0100 Subject: [PATCH 01/17] - use DMENUPIC as titlepic in doom2bfg. --- wadsrc/static/mapinfo/doom2bfg.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/mapinfo/doom2bfg.txt b/wadsrc/static/mapinfo/doom2bfg.txt index cc82c4e19..28bea129d 100644 --- a/wadsrc/static/mapinfo/doom2bfg.txt +++ b/wadsrc/static/mapinfo/doom2bfg.txt @@ -3,7 +3,7 @@ include "mapinfo/doom2.txt" gameinfo { - titlepage = "INTERPIC" + titlepage = "DMENUPIC" } clearepisodes From 8ded18a96c79f69211d80bce532bc283e4e16758 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 5 Jan 2016 14:09:34 +0100 Subject: [PATCH 02/17] - changed default frequency for Timidity++ to 44100kHz. --- src/sound/music_midi_timidity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 9f50b4155..667de8842 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -58,7 +58,7 @@ CUSTOM_CVAR (Int, timidity_pipe, 90, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } } -CUSTOM_CVAR (Int, timidity_frequency, 22050, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { // Clamp frequency to Timidity's limits if (self < 4000) self = 4000; From 006d3022ca60e1f8048a682668ee41a649695bba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 5 Jan 2016 17:10:47 +0100 Subject: [PATCH 03/17] - changed the BFG decal for Freedoom to blue. With the software renderer this will be displayed as gray due to lack of blue in the palette. (Itz's still better than green, though.) --- wadsrc/static/filter/doom.freedoom/decaldef.z | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 wadsrc/static/filter/doom.freedoom/decaldef.z diff --git a/wadsrc/static/filter/doom.freedoom/decaldef.z b/wadsrc/static/filter/doom.freedoom/decaldef.z new file mode 100644 index 000000000..68b85a848 --- /dev/null +++ b/wadsrc/static/filter/doom.freedoom/decaldef.z @@ -0,0 +1,29 @@ + +/***** BFG Scorches ********************************************************/ + +decal BFGLightning1 +{ + pic BFGLITE1 + shade "80 80 ff" + fullbright + randomflipx + animator GoAway2 + lowerdecal BFGScorch +} + +decal BFGLightning2 +{ + pic BFGLITE2 + shade "80 80 ff" + fullbright + randomflipy + animator GoAway2 + lowerdecal BFGScorch +} + +decalgroup BFGLightning +{ + BFGLightning1 1 + BFGLightning2 1 +} + From 1c6a00059f9ede7d913d06bae7f8c4994964649b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 5 Jan 2016 20:41:59 +0100 Subject: [PATCH 04/17] - fixed: MAPINFO option fs_nocheckposition parsed the '=' twice. --- src/fragglescript/t_load.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index eedb68f7c..cd40d809a 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -87,7 +87,6 @@ DEFINE_MAP_OPTION(fs_nocheckposition, false) { FFsOptions *opt = info->GetOptData("fragglescript"); - parse.ParseAssign(); if (parse.CheckAssign()) { parse.sc.MustGetNumber(); From 6a63effa1fbcdb8619383c565394317869ab7ac1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 01:50:45 +0100 Subject: [PATCH 05/17] - fixed: A_CheckTerrain did not use the proper damage type for processing an instant death sector. - moved sector secret information from sector_t::special and secretsector to two flag bits in sector_t::Flags. This is to get rid of the bit masking madness in the floor/ceiling thinkers which need to preserve this bit when they change a sector's type. --- src/am_map.cpp | 8 ++++---- src/c_cmds.cpp | 7 ++----- src/g_strife/a_strifestuff.cpp | 2 +- src/p_3dfloors.cpp | 3 +-- src/p_floor.cpp | 16 ++++++++-------- src/p_lnspec.cpp | 3 +++ src/p_lnspec.h | 2 ++ src/p_plats.cpp | 4 ++-- src/p_saveg.cpp | 18 ++++++++++++++---- src/p_setup.cpp | 1 - src/p_spec.cpp | 10 +++++++--- src/p_udmf.cpp | 2 -- src/p_user.cpp | 6 ++---- src/r_defs.h | 21 ++++++++++++++++++++- src/version.h | 2 +- 15 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 81e45c685..606a65ae8 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2071,17 +2071,17 @@ static bool AM_CheckSecret(line_t *line) { if (line->frontsector != NULL) { - if (line->frontsector->secretsector) + if (line->frontsector->wasSecret()) { - if (am_map_secrets!=0 && !(line->frontsector->special&SECRET_MASK)) return true; + if (am_map_secrets!=0 && !line->frontsector->isSecret()) return true; if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true; } } if (line->backsector != NULL) { - if (line->backsector->secretsector) + if (line->backsector->wasSecret()) { - if (am_map_secrets!=0 && !(line->backsector->special&SECRET_MASK)) return true; + if (am_map_secrets!=0 && !line->backsector->isSecret()) return true; if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true; } } diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 0a9e4f0e3..57290a98a 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -1106,11 +1106,8 @@ static void PrintSecretString(const char *string, bool thislevel) if (*string == ';') string++; if (thislevel && secnum >= 0 && secnum < numsectors) { - if (sectors[secnum].secretsector) - { - if ((sectors[secnum].special & SECRET_MASK)) colstr = TEXTCOLOR_RED; - else colstr = TEXTCOLOR_GREEN; - } + if (sectors[secnum].isSecret()) colstr = TEXTCOLOR_RED; + else if (sectors[secnum].wasSecret()) colstr = TEXTCOLOR_GREEN; else colstr = TEXTCOLOR_ORANGE; } } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 1edea19fa..7e9330990 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -632,7 +632,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) { if ((sec->special & 0xFF) == Damage_InstantDeath) { - P_DamageMobj (self, NULL, NULL, 999, NAME_None); + P_DamageMobj (self, NULL, NULL, 999, NAME_InstantDeath); } else if ((sec->special & 0xFF) == Scroll_StrifeCurrent) { diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 6af26652f..3fbbfeab7 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -342,8 +342,7 @@ void P_PlayerOnSpecial3DFloor(player_t* player) } // Apply sector specials - if (rover->model->special || rover->model->damageamount) - P_PlayerInSpecialSector(player, rover->model); + P_PlayerInSpecialSector(player, rover->model); // Apply flat specials (using the ceiling!) P_PlayerOnSpecialFlat( diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 9e7806039..42372888b 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -159,7 +159,7 @@ void DFloor::Tick () case donutRaise: case genFloorChgT: case genFloorChg0: - m_Sector->special = (m_Sector->special & SECRET_MASK) | m_NewSpecial; + m_Sector->special = m_Sector->special | m_NewSpecial; //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -175,7 +175,7 @@ void DFloor::Tick () case floorLowerAndChange: case genFloorChgT: case genFloorChg0: - m_Sector->special = (m_Sector->special & SECRET_MASK) | m_NewSpecial; + m_Sector->special = m_Sector->special | m_NewSpecial; //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -240,7 +240,7 @@ void DFloor::SetFloorChangeType (sector_t *sec, int change) m_Type = DFloor::genFloorChg; break; case 3: - m_NewSpecial = sec->special & ~SECRET_MASK; + m_NewSpecial = sec->special; m_Type = DFloor::genFloorChgT; break; } @@ -438,11 +438,11 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, { FTextureID oldpic = sec->GetTexture(sector_t::floor); sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->special = (sec->special & SECRET_MASK) | (line->frontsector->special & ~SECRET_MASK); + sec->special = line->frontsector->special; } else { - sec->special &= SECRET_MASK; + sec->special = 0; } break; @@ -454,7 +454,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, // jff 1/24/98 make sure floor->m_NewSpecial gets initialized // in case no surrounding sector is at floordestheight // --> should not affect compatibility <-- - floor->m_NewSpecial = sec->special & ~SECRET_MASK; + floor->m_NewSpecial = sec->special; //jff 5/23/98 use model subroutine to unify fixes and handling sector_t *modelsec; @@ -462,7 +462,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, if (modelsec != NULL) { floor->m_Texture = modelsec->GetTexture(sector_t::floor); - floor->m_NewSpecial = modelsec->special & ~SECRET_MASK; + floor->m_NewSpecial = modelsec->special; } break; @@ -1091,7 +1091,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) if (line) { // [RH] if no line, no change sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->special = (sec->special & SECRET_MASK) | (line->frontsector->special & ~SECRET_MASK); + sec->special = line->frontsector->special; } break; case numChangeOnly: diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 8fa8691b2..53090ef18 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1945,6 +1945,9 @@ FUNC(LS_Sector_ChangeFlags) rtn = false; FSectorTagIterator itr(arg0); + // exclude protected flags + arg1 &= ~SECF_NOMODIFY; + arg2 &= ~SECF_NOMODIFY; while ((secNum = itr.Next()) >= 0) { sectors[secNum].Flags = (sectors[secNum].Flags | arg1) & ~arg2; diff --git a/src/p_lnspec.h b/src/p_lnspec.h index 9fb4c17b3..cb3f6bf85 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -176,10 +176,12 @@ typedef enum { // [RH] Equivalents for BOOM's generalized sector types +#ifndef SECRET_MASK #define DAMAGE_MASK 0x0300 #define SECRET_MASK 0x0400 #define FRICTION_MASK 0x0800 #define PUSH_MASK 0x1000 +#endif struct line_t; class AActor; diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 7600637b2..eecf521ee 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -281,7 +281,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, if (line) sec->SetTexture(sector_t::floor, line->sidedef[0]->sector->GetTexture(sector_t::floor)); if (change == 1) - sec->special &= SECRET_MASK; // Stop damage and other stuff, if any + sec->special = 0; // Stop damage and other stuff, if any } switch (type) @@ -293,7 +293,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, plat->m_Low = sec->floorplane.d; plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); - sec->special &= SECRET_MASK; // NO MORE DAMAGE, IF APPLICABLE + sec->special = 0; // NO MORE DAMAGE, IF APPLICABLE break; case DPlat::platUpByValue: diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index fdf57ddb0..fa1f395cf 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -398,15 +398,25 @@ void P_SerializeWorld (FArchive &arc) } } - arc << sec->SoundTarget + arc << sec->SoundTarget << sec->SecActTarget << sec->sky << sec->MoreFlags << sec->Flags << sec->FloorSkyBox << sec->CeilingSkyBox - << sec->ZoneNumber - << sec->secretsector - << sec->interpolations[0] + << sec->ZoneNumber; + if (SaveVersion < 4529) + { + short secretsector; + arc << secretsector; + if (secretsector) sec->Flags |= SECF_WASSECRET; + if (sec->special & SECRET_MASK) + { + sec->Flags |= SECF_SECRET; + sec->special &= ~SECRET_MASK; + } + } + arc << sec->interpolations[0] << sec->interpolations[1] << sec->interpolations[2] << sec->interpolations[3] diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 50e7f41d6..dbd0954cc 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1512,7 +1512,6 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->special = LittleShort(ms->special); else // [RH] Translate to new sector special ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); - ss->secretsector = !!(ss->special&SECRET_MASK); tagManager.AddSectorTag(i, LittleShort(ms->tag)); ss->thinglist = NULL; ss->touching_thinglist = NULL; // phares 3/14/98 diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c439ac50e..d94d91ac5 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -437,7 +437,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) } } - int special = sector->special & ~SECRET_MASK; + int special = sector->special; // Has hit ground. AInventory *ironfeet; @@ -574,9 +574,9 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) } } - if (sector->special & SECRET_MASK) + if (sector->isSecret()) { - sector->special &= ~SECRET_MASK; + sector->ClearSecret(); P_GiveSecret(player->mo, true, true, int(sector - sectors)); } } @@ -1189,7 +1189,11 @@ void P_SpawnSpecials (void) // [RH] All secret sectors are marked with a BOOM-ish bitfield if (sector->special & SECRET_MASK) + { + sector->Flags |= SECF_SECRET | SECF_WASSECRET; + sector->special &= ~SECRET_MASK; level.total_secrets++; + } switch (sector->special & 0xff) { diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 2169da49f..128225e4a 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1567,8 +1567,6 @@ public: if (sc.Number != 0) tagManager.AddSectorTag(index, sc.Number); } } - - sec->secretsector = !!(sec->special&SECRET_MASK); // Reset the planes to their defaults if not all of the plane equation's parameters were found. if (fplaneflags != 15) diff --git a/src/p_user.cpp b/src/p_user.cpp index 8f8a93fdb..922cc2a1c 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2538,10 +2538,8 @@ void P_PlayerThink (player_t *player) if (!(player->cheats & CF_PREDICTING)) { P_PlayerOnSpecial3DFloor (player); - if (player->mo->Sector->special || player->mo->Sector->damageamount != 0) - { - P_PlayerInSpecialSector (player); - } + P_PlayerInSpecialSector (player); + if (player->mo->z <= player->mo->Sector->floorplane.ZatPoint( player->mo->x, player->mo->y) || player->mo->waterlevel) diff --git a/src/r_defs.h b/src/r_defs.h index 89449f446..0c873beeb 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -355,6 +355,12 @@ enum SECF_NOFALLINGDAMAGE= 2, // No falling damage in this sector SECF_FLOORDROP = 4, // all actors standing on this floor will remain on it when it lowers very fast. SECF_NORESPAWN = 8, // players can not respawn in this sector + + + SECF_WASSECRET = 1 << 30, // a secret that was discovered + SECF_SECRET = 1 << 31, // a secret sector + + SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET // not modifiable by Sector_ChangeFlags }; enum @@ -642,6 +648,20 @@ struct sector_t return pos == floor? floorplane:ceilingplane; } + bool isSecret() const + { + return !!(Flags & SECF_SECRET); + } + + bool wasSecret() const + { + return !!(Flags & SECF_WASSECRET); + } + + void ClearSecret() + { + Flags &= ~SECF_SECRET; + } bool PlaneMoving(int pos); @@ -729,7 +749,6 @@ struct sector_t // regular sky. TObjPtr FloorSkyBox, CeilingSkyBox; - short secretsector; //jff 2/16/98 remembers if sector WAS secret (automap) int sectornum; // for comparing sector copies extsector_t * e; // This stores data that requires construction/destruction. Such data must not be copied by R_FakeFlat. diff --git a/src/version.h b/src/version.h index d7026786e..b10074f41 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4528 +#define SAVEVER 4529 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 3ffcec3eb3446eda1615d277104b6822fd0af69d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 02:01:59 +0100 Subject: [PATCH 06/17] - moved friction flag from special to Flags as well. --- src/p_map.cpp | 2 +- src/p_saveg.cpp | 6 +++++- src/p_spec.cpp | 12 ++++++++---- src/r_defs.h | 1 + 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 5dd0967b9..f409dafa4 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -630,7 +630,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) } } - if (!(sec->special & FRICTION_MASK) && + if (!(sec->Flags & SECF_FRICTION) && Terrains[TerrainTypes[sec->GetTexture(sector_t::floor)]].Friction == 0) { continue; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index fa1f395cf..16109891b 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -413,8 +413,12 @@ void P_SerializeWorld (FArchive &arc) if (sec->special & SECRET_MASK) { sec->Flags |= SECF_SECRET; - sec->special &= ~SECRET_MASK; } + if (sec->special & FRICTION_MASK) + { + sec->Flags |= SECF_FRICTION; + } + sec->special &= ~(SECRET_MASK|FRICTION_MASK); } arc << sec->interpolations[0] << sec->interpolations[1] diff --git a/src/p_spec.cpp b/src/p_spec.cpp index d94d91ac5..a5bdfffd4 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1191,9 +1191,13 @@ void P_SpawnSpecials (void) if (sector->special & SECRET_MASK) { sector->Flags |= SECF_SECRET | SECF_WASSECRET; - sector->special &= ~SECRET_MASK; level.total_secrets++; } + if (sector->special & FRICTION_MASK) + { + sector->Flags |= SECF_FRICTION; + } + sector->special &= ~(SECRET_MASK|FRICTION_MASK); switch (sector->special & 0xff) { @@ -1262,7 +1266,7 @@ void P_SpawnSpecials (void) sector->friction = FRICTION_LOW; sector->movefactor = 0x269; sector->special &= 0xff00; - sector->special |= FRICTION_MASK; + sector->Flags |= SECF_FRICTION; break; // [RH] Hexen-like phased lighting @@ -2060,11 +2064,11 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) // can be enabled and disabled at will. if (friction == ORIG_FRICTION) { - sectors[s].special &= ~FRICTION_MASK; + sectors[s].Flags &= ~SECF_FRICTION; } else { - sectors[s].special |= FRICTION_MASK; + sectors[s].Flags |= SECF_FRICTION; } } } diff --git a/src/r_defs.h b/src/r_defs.h index 0c873beeb..014fa1b32 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -355,6 +355,7 @@ enum SECF_NOFALLINGDAMAGE= 2, // No falling damage in this sector SECF_FLOORDROP = 4, // all actors standing on this floor will remain on it when it lowers very fast. SECF_NORESPAWN = 8, // players can not respawn in this sector + SECF_FRICTION = 16, // sector has friction enabled SECF_WASSECRET = 1 << 30, // a secret that was discovered From d34077a3ba50b0953c02ec67c30257fb6ca664a3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 02:05:39 +0100 Subject: [PATCH 07/17] - ... and finally the push flag. --- src/p_lnspec.h | 2 -- src/p_saveg.cpp | 6 +++++- src/p_spec.cpp | 8 ++++++-- src/r_defs.h | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/p_lnspec.h b/src/p_lnspec.h index cb3f6bf85..9fb4c17b3 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -176,12 +176,10 @@ typedef enum { // [RH] Equivalents for BOOM's generalized sector types -#ifndef SECRET_MASK #define DAMAGE_MASK 0x0300 #define SECRET_MASK 0x0400 #define FRICTION_MASK 0x0800 #define PUSH_MASK 0x1000 -#endif struct line_t; class AActor; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 16109891b..2547933bc 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -418,7 +418,11 @@ void P_SerializeWorld (FArchive &arc) { sec->Flags |= SECF_FRICTION; } - sec->special &= ~(SECRET_MASK|FRICTION_MASK); + if (sec->special & PUSH_MASK) + { + sec->Flags |= SECF_PUSH; + } + sec->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK); } arc << sec->interpolations[0] << sec->interpolations[1] diff --git a/src/p_spec.cpp b/src/p_spec.cpp index a5bdfffd4..493e3e157 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1197,7 +1197,11 @@ void P_SpawnSpecials (void) { sector->Flags |= SECF_FRICTION; } - sector->special &= ~(SECRET_MASK|FRICTION_MASK); + if (sector->special & PUSH_MASK) + { + sector->Flags |= SECF_PUSH; + } + sector->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK); switch (sector->special & 0xff) { @@ -2184,7 +2188,7 @@ void DPusher::Tick () // Be sure the special sector type is still turned on. If so, proceed. // Else, bail out; the sector type has been changed on us. - if (!(sec->special & PUSH_MASK)) + if (!(sec->Flags & SECF_PUSH)) return; // For constant pushers (wind/current) there are 3 situations: diff --git a/src/r_defs.h b/src/r_defs.h index 014fa1b32..d5321a0c3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -356,6 +356,7 @@ enum SECF_FLOORDROP = 4, // all actors standing on this floor will remain on it when it lowers very fast. SECF_NORESPAWN = 8, // players can not respawn in this sector SECF_FRICTION = 16, // sector has friction enabled + SECF_PUSH = 32, // pushers enabled SECF_WASSECRET = 1 << 30, // a secret that was discovered From b0db5d9b169b858a7b0a5ef265474c36a29afd00 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 02:16:33 +0100 Subject: [PATCH 08/17] - added a SECF_SILENTMOVE flag. Since Eternity got this it's a good candidate for a potential Super-Boom standard, and it's also useful for silencing a sector temporarily without removing the sound sequence. --- src/p_ceiling.cpp | 1 + src/p_doors.cpp | 2 ++ src/p_floor.cpp | 2 ++ src/p_pillar.cpp | 23 +++++++++++++---------- src/p_plats.cpp | 2 ++ src/r_defs.h | 1 + 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 7efef80a5..37cf91b47 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -90,6 +90,7 @@ void DCeiling::Serialize (FArchive &arc) void DCeiling::PlayCeilingSound () { + if (m_Sector->Flags & SECF_SILENTMOVE) return; if (m_Sector->seqType >= 0) { SN_StartSequence (m_Sector, CHAN_CEILING, m_Sector->seqType, SEQ_PLATFORM, 0, false); diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 49ed20f46..f01f2beeb 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -250,6 +250,8 @@ void DDoor::DoorSound(bool raise, DSeqNode *curseq) const choice = !raise; + if (m_Sector->Flags & SECF_SILENTMOVE) return; + if (m_Speed >= FRACUNIT*8) { choice += 2; diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 42372888b..e9febae66 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -55,6 +55,8 @@ inline FArchive &operator<< (FArchive &arc, DFloor::EFloor &type) static void StartFloorSound (sector_t *sec) { + if (sec->Flags & SECF_SILENTMOVE) return; + if (sec->seqType >= 0) { SN_StartSequence (sec, CHAN_FLOOR, sec->seqType, SEQ_PLATFORM, 0); diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index 884218bee..b1cae3af9 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -198,17 +198,20 @@ DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed, m_FloorSpeed = Scale (speed, floordist, ceilingdist); } - if (sector->seqType >= 0) + if (!(m_Sector->Flags & SECF_SILENTMOVE)) { - SN_StartSequence (sector, CHAN_FLOOR, sector->seqType, SEQ_PLATFORM, 0); - } - else if (sector->SeqName != NAME_None) - { - SN_StartSequence (sector, CHAN_FLOOR, sector->SeqName, 0); - } - else - { - SN_StartSequence (sector, CHAN_FLOOR, "Floor", 0); + if (sector->seqType >= 0) + { + SN_StartSequence(sector, CHAN_FLOOR, sector->seqType, SEQ_PLATFORM, 0); + } + else if (sector->SeqName != NAME_None) + { + SN_StartSequence(sector, CHAN_FLOOR, sector->SeqName, 0); + } + else + { + SN_StartSequence(sector, CHAN_FLOOR, "Floor", 0); + } } } diff --git a/src/p_plats.cpp b/src/p_plats.cpp index eecf521ee..280eb415c 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -72,6 +72,8 @@ void DPlat::Serialize (FArchive &arc) void DPlat::PlayPlatSound (const char *sound) { + if (m_Sector->Flags & SECF_SILENTMOVE) return; + if (m_Sector->seqType >= 0) { SN_StartSequence (m_Sector, CHAN_FLOOR, m_Sector->seqType, SEQ_PLATFORM, 0); diff --git a/src/r_defs.h b/src/r_defs.h index d5321a0c3..3a024831c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -357,6 +357,7 @@ enum SECF_NORESPAWN = 8, // players can not respawn in this sector SECF_FRICTION = 16, // sector has friction 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_WASSECRET = 1 << 30, // a secret that was discovered From 5474e01de8c1153c25c7d9968e4d435c54933ad9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 12:12:47 +0100 Subject: [PATCH 09/17] - 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. --- specs/udmf_zdoom.txt | 7 +- src/b_move.cpp | 18 +- src/fragglescript/t_func.cpp | 34 +-- src/namedef.h | 2 + src/p_doors.cpp | 3 - src/p_interaction.cpp | 3 +- src/p_spec.cpp | 514 +++++++++++++++++------------------ src/p_udmf.cpp | 18 ++ src/r_defs.h | 6 +- 9 files changed, 282 insertions(+), 323 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index f20525d13..74d5fb4f7 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -204,10 +204,15 @@ Note: All fields default to false unless mentioned otherwise. hidden = ; // if true this sector will not be drawn on the textured automap. waterzone = ; // Sector is under water and swimmable moreids = ; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505") - damageamount = ; // Amount of damage inflicted by this sector, default = 0 + damageamount = ; // 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 = ; // Damage type for sector damage, Default = "None". (generic damage) damageinterval = ; // Interval in tics between damage application, default = 32. leakiness = ; // Probability of leaking through radiation suit (0 = never, 256 = always), default = 0. + damageterraineffect = ; // Will spawn a terrain splash when damage is inflicted. Default = false. + damagehazard = ; // Changes damage model to Strife's delayed damage for the given sector. Default = false. + * Note about dropactors diff --git a/src/b_move.cpp b/src/b_move.cpp index 2a76f1925..4759f22d9 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -354,21 +354,5 @@ void DBot::Pitch (AActor *target) //Checks if a sector is dangerous. bool FCajunMaster::IsDangerous (sector_t *sec) { - int special; - - 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; + return sec->damageamount > 0; } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 7e05be8da..fdf904764 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -4323,44 +4323,12 @@ void FParser::SF_KillInSector() //========================================================================== // // 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) { - int tagnum, secnum; - 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; - } + // I don't think this was ever used publicly so I'm not going to bother fixing it. } //========================================================================== diff --git a/src/namedef.h b/src/namedef.h index cad58bfa3..9ca8cb8ed 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -510,6 +510,8 @@ xx(damageamount) xx(damagetype) xx(damageinterval) xx(leakiness) +xx(damageterraineffect) +xx(damagehazard) // USDF keywords xx(Amount) diff --git a/src/p_doors.cpp b/src/p_doors.cpp index f01f2beeb..bce324902 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -513,8 +513,6 @@ void P_SpawnDoorCloseIn30 (sector_t *sec) fixed_t height; DDoor *door = new DDoor (sec); - sec->special = 0; - door->m_Sector = sec; door->m_Direction = 0; door->m_Type = DDoor::doorRaise; @@ -535,7 +533,6 @@ void P_SpawnDoorCloseIn30 (sector_t *sec) void P_SpawnDoorRaiseIn5Mins (sector_t *sec) { - sec->special = 0; new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0); } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 203d1688d..b2e27adc8 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1255,8 +1255,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } // end of game hell hack - if ((target->Sector->special & 255) == dDamage_End - && damage >= target->health) + if ((target->Sector->Flags & SECF_ENDLEVEL) && damage >= target->health) { damage = target->health - 1; } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 493e3e157..807e6e64b 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -442,135 +442,40 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) // Has hit ground. 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 - 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)) { - 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 // @@ -1187,147 +1309,7 @@ void P_SpawnSpecials (void) if (sector->special == 0) continue; - // [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; - } - 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; - } + P_InitSectorSpecial(sector, sector->special); } // Init other misc stuff diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 128225e4a..64536fff4 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1542,6 +1542,14 @@ public: sec->leakydamage = CheckInt(key); break; + case NAME_damageterraineffect: + Flag(sec->Flags, SECF_DMGTERRAINFX, key); + break; + + case NAME_damagehazard: + Flag(sec->Flags, SECF_HAZARD, key); + break; + case NAME_MoreIds: // 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. @@ -1567,6 +1575,16 @@ public: 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. if (fplaneflags != 15) diff --git a/src/r_defs.h b/src/r_defs.h index 3a024831c..e4b404687 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -358,11 +358,15 @@ enum SECF_FRICTION = 16, // sector has friction 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_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_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 }; From 73f4e013f18116010a85f7c2c44c62098e9ae123 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 6 Jan 2016 13:26:05 +0200 Subject: [PATCH 10/17] Font kerning is no longer ignored in intermission screen See http://forum.zdoom.org/viewtopic.php?t=50304 --- src/intermission/intermission.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 2a52df58a..a19d0a479 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -329,6 +329,7 @@ void DIntermissionScreenText::Drawer () int c; const FRemapTable *range; const char *ch = mText; + const int kerning = SmallFont->GetDefaultKerning(); // Count number of rows in this text. Since it does not word-wrap, we just count // line feed characters. @@ -380,6 +381,7 @@ void DIntermissionScreenText::Drawer () } pic = SmallFont->GetChar (c, &w); + w += kerning; w *= CleanXfac; if (cx + w > SCREENWIDTH) continue; From 1ee441412a7c8b30d616324a31d490c279e230f2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 12:31:27 +0100 Subject: [PATCH 11/17] - add savegame compatibility handling for damage related changes: When loading an old savegame the sector specials must be reinitialized to set the damage properties. --- src/p_lights.cpp | 3 +-- src/p_saveg.cpp | 13 +------------ src/p_spec.cpp | 40 ++++++++++++++++++++++------------------ src/p_spec.h | 1 + 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/p_lights.cpp b/src/p_lights.cpp index 49ef130e8..7d56bce95 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -791,7 +791,7 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev index + 1, l->m_BaseLevel, sector); l->m_Phase = ((numsteps - index - 1) * 64) / numsteps; - sector->special &= 0xff00; + sector->special = 0; return numsteps; } @@ -820,7 +820,6 @@ DPhased::DPhased (sector_t *sector, int baselevel, int phase) { m_BaseLevel = baselevel; m_Phase = phase; - sector->special &= 0xff00; } //============================================================================ diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 2547933bc..21e6605b9 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -410,19 +410,8 @@ void P_SerializeWorld (FArchive &arc) short secretsector; arc << secretsector; if (secretsector) sec->Flags |= SECF_WASSECRET; - if (sec->special & SECRET_MASK) - { - sec->Flags |= SECF_SECRET; - } - if (sec->special & FRICTION_MASK) - { - sec->Flags |= SECF_FRICTION; - } - if (sec->special & PUSH_MASK) - { - sec->Flags |= SECF_PUSH; - } sec->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK); + P_InitSectorSpecial(sec, sec->special, true); } arc << sec->interpolations[0] << sec->interpolations[1] diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 807e6e64b..789e44a27 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1098,7 +1098,7 @@ static void P_SetupSectorDamage(sector_t *sector, int damage, int interval, int // ('fromload' is necessary to allow conversion upon savegame load.) // -void P_InitSectorSpecial(sector_t *sector, int special) +void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) { // [RH] All secret sectors are marked with a BOOM-ish bitfield if (sector->special & SECRET_MASK) @@ -1133,28 +1133,28 @@ void P_InitSectorSpecial(sector_t *sector, int special) switch (sector->special) { case Light_Phased: - new DPhased (sector, 48, 63 - (sector->lightlevel & 63)); + if (!nothinkers) new DPhased (sector, 48, 63 - (sector->lightlevel & 63)); break; // [RH] Hexen-like phased lighting case LightSequenceStart: - new DPhased (sector); + if (!nothinkers) new DPhased (sector); break; case dLight_Flicker: - new DLightFlash (sector); + if (!nothinkers) new DLightFlash (sector); break; case dLight_StrobeFast: - new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); + if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); break; case dLight_StrobeSlow: - new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false); + if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false); break; case dLight_Strobe_Hurt: - new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); + if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0); break; @@ -1167,7 +1167,7 @@ void P_InitSectorSpecial(sector_t *sector, int special) break; case dLight_Glow: - new DGlow (sector); + if (!nothinkers) new DGlow (sector); break; case dSector_DoorCloseIn30: @@ -1179,11 +1179,11 @@ void P_InitSectorSpecial(sector_t *sector, int special) break; case dLight_StrobeSlowSync: - new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true); + if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true); break; case dLight_StrobeFastSync: - new DStrobe (sector, STROBEBRIGHT, FASTDARK, true); + if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, true); break; case dSector_DoorRaiseIn5Mins: @@ -1201,7 +1201,7 @@ void P_InitSectorSpecial(sector_t *sector, int special) break; case dLight_FireFlicker: - new DFireFlicker (sector); + if (!nothinkers) new DFireFlicker (sector); break; case dDamage_LavaWimpy: @@ -1214,9 +1214,12 @@ void P_InitSectorSpecial(sector_t *sector, int special) 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); + if (!nothinkers) + { + new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); + new DScroller(DScroller::sc_floor, (-FRACUNIT / 2) << 3, + 0, -1, int(sector - sectors), 0); + } break; case hDamage_Sludge: @@ -1225,7 +1228,7 @@ void P_InitSectorSpecial(sector_t *sector, int special) case sLight_Strobe_Hurt: P_SetupSectorDamage(sector, 5, 32, 0, NAME_Slime, 0); - new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); + if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); break; case sDamage_Hellslime: @@ -1270,16 +1273,17 @@ void P_InitSectorSpecial(sector_t *sector, int special) { 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); + if (!nothinkers) 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, + if (!nothinkers) new DScroller (DScroller::sc_floor, (-FRACUNIT/2)<<((sector->special & 0xff) - Carry_East5), 0, -1, int(sector-sectors), 0); } @@ -1309,7 +1313,7 @@ void P_SpawnSpecials (void) if (sector->special == 0) continue; - P_InitSectorSpecial(sector, sector->special); + P_InitSectorSpecial(sector, sector->special, false); } // Init other misc stuff diff --git a/src/p_spec.h b/src/p_spec.h index 0c3ee8745..da508fda1 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -158,6 +158,7 @@ bool PIT_PushThing (AActor *thing); bool CheckIfExitIsGood (AActor *self, level_info_t *info); // at map load +void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers); void P_SpawnSpecials (void); // every tic From bd8513c063e2451e7d075e803efd10aae9ec8f09 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 12:56:35 +0100 Subject: [PATCH 12/17] - made sector_t::damageamount an int so that it can hold TELEFRAG_DAMAGE. - marked all places where sector_t::special needs to be addressed for the damage overhaul. NOTE: This commit will not compile! --- src/g_shared/a_lightning.cpp | 2 +- src/g_strife/a_strifestuff.cpp | 4 ++-- src/p_ceiling.cpp | 8 ++++---- src/p_floor.cpp | 20 ++++++++++---------- src/p_lights.cpp | 2 +- src/p_mobj.cpp | 4 ++-- src/p_plats.cpp | 4 ++-- src/p_saveg.cpp | 13 +++++++++++-- src/p_sectors.cpp | 2 +- src/p_setup.cpp | 2 +- src/p_spec.cpp | 9 ++++----- src/p_udmf.cpp | 8 ++++---- src/r_defs.h | 2 +- 13 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/g_shared/a_lightning.cpp b/src/g_shared/a_lightning.cpp index e7c598d3e..33d51c02d 100644 --- a/src/g_shared/a_lightning.cpp +++ b/src/g_shared/a_lightning.cpp @@ -139,7 +139,7 @@ void DLightningThinker::LightningFlash () for (i = numsectors, j = 0; i > 0; --i, ++j, ++tempSec) { // allow combination of the lightning sector specials with bit masks - int special = tempSec->special & 0xff; + int special = tempSec->special; if (tempSec->GetTexture(sector_t::ceiling) == skyflatnum || special == Light_IndoorLightning1 || special == Light_IndoorLightning2 diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 7e9330990..05f6367dc 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -630,11 +630,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) if (self->z == sec->floorplane.ZatPoint (self->x, self->y)) { - if ((sec->special & 0xFF) == Damage_InstantDeath) + if (sec->special == Damage_InstantDeath) { P_DamageMobj (self, NULL, NULL, 999, NAME_InstantDeath); } - else if ((sec->special & 0xFF) == Scroll_StrifeCurrent) + else if (sec->special == Scroll_StrifeCurrent) { int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; fixed_t speed = (anglespeed % 10) << (FRACBITS - 4); diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 37cf91b47..b8a3ead7b 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -143,7 +143,7 @@ void DCeiling::Tick () // movers with texture change, change the texture then get removed case genCeilingChgT: case genCeilingChg0: - m_Sector->special = m_NewSpecial; + m_Sector->xspecial = m_NewSpecial; // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); @@ -176,7 +176,7 @@ void DCeiling::Tick () // then remove the active ceiling case genCeilingChgT: case genCeilingChg0: - m_Sector->special = m_NewSpecial; + m_Sector->xspecial = m_NewSpecial; // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); @@ -440,7 +440,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, ceiling->m_Type = genCeilingChg0; break; case 2: // type is copied - ceiling->m_NewSpecial = sec->special; + ceiling->m_NewSpecial = sec->xspecial; ceiling->m_Type = genCeilingChgT; break; case 3: // type is left alone @@ -459,7 +459,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, ceiling->m_Type = genCeilingChg0; break; case 2: // type is copied - ceiling->m_NewSpecial = line->frontsector->special; + ceiling->m_NewSpecial = line->frontsector->xspecial; ceiling->m_Type = genCeilingChgT; break; case 3: // type is left alone diff --git a/src/p_floor.cpp b/src/p_floor.cpp index e9febae66..c570bff4a 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -161,7 +161,7 @@ void DFloor::Tick () case donutRaise: case genFloorChgT: case genFloorChg0: - m_Sector->special = m_Sector->special | m_NewSpecial; + m_Sector->xspecial = m_Sector->xspecial | m_NewSpecial; //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -177,7 +177,7 @@ void DFloor::Tick () case floorLowerAndChange: case genFloorChgT: case genFloorChg0: - m_Sector->special = m_Sector->special | m_NewSpecial; + m_Sector->xspecial = m_Sector->xspecial | m_NewSpecial; //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -242,7 +242,7 @@ void DFloor::SetFloorChangeType (sector_t *sec, int change) m_Type = DFloor::genFloorChg; break; case 3: - m_NewSpecial = sec->special; + m_NewSpecial = sec->xspecial; m_Type = DFloor::genFloorChgT; break; } @@ -440,11 +440,11 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, { FTextureID oldpic = sec->GetTexture(sector_t::floor); sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->special = line->frontsector->special; + sec->xspecial = line->frontsector->xspecial; } else { - sec->special = 0; + sec->xspecial = 0; } break; @@ -456,7 +456,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, // jff 1/24/98 make sure floor->m_NewSpecial gets initialized // in case no surrounding sector is at floordestheight // --> should not affect compatibility <-- - floor->m_NewSpecial = sec->special; + floor->m_NewSpecial = sec->xspecial; //jff 5/23/98 use model subroutine to unify fixes and handling sector_t *modelsec; @@ -464,7 +464,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, if (modelsec != NULL) { floor->m_Texture = modelsec->GetTexture(sector_t::floor); - floor->m_NewSpecial = modelsec->special; + floor->m_NewSpecial = modelsec->xspecial; } break; @@ -637,7 +637,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, { // [RH] Find the next sector by scanning for Stairs_Special? tsec = sec->NextSpecialSector ( - (sec->special & 0xff) == Stairs_Special1 ? + sec->special == Stairs_Special1 ? Stairs_Special2 : Stairs_Special1, prev); if ( (ok = (tsec != NULL)) ) @@ -1093,7 +1093,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) if (line) { // [RH] if no line, no change sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->special = line->frontsector->special; + sec->xspecial = line->frontsector->xspecial; } break; case numChangeOnly: @@ -1101,7 +1101,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) if (secm) { // if no model, no change sec->SetTexture(sector_t::floor, secm->GetTexture(sector_t::floor)); - sec->special = secm->special; + sec->xspecial = secm->xspecial; } break; default: diff --git a/src/p_lights.cpp b/src/p_lights.cpp index 7d56bce95..656b86112 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -786,7 +786,7 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev l = new DPhased (sector, baselevel); int numsteps = PhaseHelper (sector->NextSpecialSector ( - (sector->special & 0x00ff) == LightSequenceSpecial1 ? + sector->special == LightSequenceSpecial1 ? LightSequenceSpecial2 : LightSequenceSpecial1, prev), index + 1, l->m_BaseLevel, sector); l->m_Phase = ((numsteps - index - 1) * 64) / numsteps; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index bc314dc0e..2ded3daf2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3452,7 +3452,7 @@ void AActor::Tick () if (player != NULL) { - int scrolltype = sec->special & 0xff; + int scrolltype = sec->special; if (scrolltype >= Scroll_North_Slow && scrolltype <= Scroll_SouthWest_Fast) @@ -4424,7 +4424,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) ( gameaction != ga_worlddone ) && ( p->mo != NULL ) && ( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) && - ( (p->mo->Sector->special & 255) != Damage_InstantDeath )) + ( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) { spawn_x = p->mo->x; spawn_y = p->mo->y; diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 280eb415c..467559e63 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -283,7 +283,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, if (line) sec->SetTexture(sector_t::floor, line->sidedef[0]->sector->GetTexture(sector_t::floor)); if (change == 1) - sec->special = 0; // Stop damage and other stuff, if any + sec->xspecial = 0; // Stop damage and other stuff, if any } switch (type) @@ -295,7 +295,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, plat->m_Low = sec->floorplane.d; plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); - sec->special = 0; // NO MORE DAMAGE, IF APPLICABLE + sec->xspecial = 0; // NO MORE DAMAGE, IF APPLICABLE break; case DPlat::platUpByValue: diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 21e6605b9..8e2f7e9d9 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -368,8 +368,17 @@ void P_SerializeWorld (FArchive &arc) << sec->planes[sector_t::ceiling] << sec->heightsec << sec->bottommap << sec->midmap << sec->topmap - << sec->gravity - << sec->damageamount; + << sec->gravity; + if (SaveVersion >= 4529) + { + arc << sec->damageamount; + } + else + { + short dmg; + arc << dmg; + sec->damageamount = dmg; + } if (SaveVersion >= 4528) { arc << sec->damageinterval diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 361b220a7..0b6f032e5 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -49,7 +49,7 @@ sector_t *sector_t::NextSpecialSector (int type, sector_t *nogood) const if (NULL != (tsec = getNextSector (ln, this)) && tsec != nogood && - (tsec->special & 0x00ff) == type) + tsec->special == type) { return tsec; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index dbd0954cc..772679269 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4048,7 +4048,7 @@ void P_SetupLevel (const char *lumpname, int position) { if (mo->flags & MF_COUNTKILL) { - if (mo->Sector->special == dDamage_End) + if (mo->Sector->damageamount > 0 && (mo->Sector->Flags & (SECF_ENDGODMODE|SECF_ENDLEVEL)) == (SECF_ENDGODMODE|SECF_ENDLEVEL)) { mo->ClearCounters(); } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 789e44a27..58679e3e6 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -437,8 +437,6 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) } } - int special = sector->special; - // Has hit ground. AInventory *ironfeet; @@ -1220,6 +1218,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) new DScroller(DScroller::sc_floor, (-FRACUNIT / 2) << 3, 0, -1, int(sector - sectors), 0); } + keepspecial = true; break; case hDamage_Sludge: @@ -1274,7 +1273,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) }; - int i = (sector->special & 0xff) - Scroll_North_Slow; + int i = sector->special - Scroll_North_Slow; fixed_t dx = hexenScrollies[i][0] * (FRACUNIT/2); fixed_t dy = hexenScrollies[i][1] * (FRACUNIT/2); if (!nothinkers) new DScroller (DScroller::sc_floor, dx, dy, -1, int(sector-sectors), 0); @@ -1284,10 +1283,10 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) { // Heretic scroll special // Only east scrollers also scroll the texture if (!nothinkers) new DScroller (DScroller::sc_floor, - (-FRACUNIT/2)<<((sector->special & 0xff) - Carry_East5), + (-FRACUNIT/2)<<(sector->special - Carry_East5), 0, -1, int(sector-sectors), 0); } - else keepspecial = true; + keepspecial = true; break; } if (!keepspecial) sector->special = 0; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 64536fff4..e95193860 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1628,10 +1628,10 @@ public: { // [RH] Sectors default to white light with the default fade. // If they are outside (have a sky ceiling), they use the outside fog. - if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special&0xff) == Sector_Outside)) + if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside)) { if (fogMap == NULL) - fogMap = GetSpecialLights (PalEntry (255,255,255), level.outsidefog, 0); + fogMap = GetSpecialLights(PalEntry(255, 255, 255), level.outsidefog, 0); sec->ColorMap = fogMap; } else @@ -1644,9 +1644,9 @@ public: else { if (lightcolor == -1) lightcolor = PalEntry(255,255,255); - if (fadecolor == -1) + if (fadecolor == -1) { - if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special&0xff) == Sector_Outside)) + if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside)) fadecolor = level.outsidefog; else fadecolor = level.fadeto; diff --git a/src/r_defs.h b/src/r_defs.h index e4b404687..92b95699f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -738,7 +738,7 @@ struct sector_t float gravity; // [RH] Sector gravity (1.0 is normal) FNameNoInit damagetype; // [RH] Means-of-death for applied damage - short damageamount; // [RH] Damage to do while standing on floor + int damageamount; // [RH] Damage to do while standing on floor short damageinterval; // Interval for damage application short leakydamage; // chance of leaking through radiation suit From eb6c855a95993fd031ef2f0160b40d7b0b915a23 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 13:30:28 +0100 Subject: [PATCH 13/17] - handle intermediate special values in thinkers. They also need to take care of the related damage variables and flags. --- src/p_ceiling.cpp | 12 +++++------ src/p_floor.cpp | 23 ++++++++++---------- src/p_mobj.cpp | 2 +- src/p_plats.cpp | 5 ++--- src/p_sectors.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_spec.h | 4 ++-- src/r_defs.h | 34 ++++++++++++++++++++++++++++- 7 files changed, 109 insertions(+), 25 deletions(-) diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index b8a3ead7b..3203cf777 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -143,7 +143,7 @@ void DCeiling::Tick () // movers with texture change, change the texture then get removed case genCeilingChgT: case genCeilingChg0: - m_Sector->xspecial = m_NewSpecial; + m_Sector->SetSpecial(&m_NewSpecial); // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); @@ -176,7 +176,7 @@ void DCeiling::Tick () // then remove the active ceiling case genCeilingChgT: case genCeilingChg0: - m_Sector->xspecial = m_NewSpecial; + m_Sector->SetSpecial(&m_NewSpecial); // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); @@ -436,11 +436,11 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, switch (change & 3) { case 1: // type is zeroed - ceiling->m_NewSpecial = 0; + ceiling->m_NewSpecial.Clear(); ceiling->m_Type = genCeilingChg0; break; case 2: // type is copied - ceiling->m_NewSpecial = sec->xspecial; + sec->GetSpecial(&ceiling->m_NewSpecial); ceiling->m_Type = genCeilingChgT; break; case 3: // type is left alone @@ -455,11 +455,11 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, switch (change & 3) { case 1: // type is zeroed - ceiling->m_NewSpecial = 0; + ceiling->m_NewSpecial.Clear(); ceiling->m_Type = genCeilingChg0; break; case 2: // type is copied - ceiling->m_NewSpecial = line->frontsector->xspecial; + line->frontsector->GetSpecial(&ceiling->m_NewSpecial); ceiling->m_Type = genCeilingChgT; break; case 3: // type is left alone diff --git a/src/p_floor.cpp b/src/p_floor.cpp index c570bff4a..780bd5d9d 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -161,7 +161,7 @@ void DFloor::Tick () case donutRaise: case genFloorChgT: case genFloorChg0: - m_Sector->xspecial = m_Sector->xspecial | m_NewSpecial; + m_Sector->GetSpecial(&m_NewSpecial); //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -177,7 +177,7 @@ void DFloor::Tick () case floorLowerAndChange: case genFloorChgT: case genFloorChg0: - m_Sector->xspecial = m_Sector->xspecial | m_NewSpecial; + m_Sector->GetSpecial(&m_NewSpecial); //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -235,14 +235,14 @@ void DFloor::SetFloorChangeType (sector_t *sec, int change) switch (change & 3) { case 1: - m_NewSpecial = 0; + m_NewSpecial.Clear(); m_Type = DFloor::genFloorChg0; break; case 2: m_Type = DFloor::genFloorChg; break; case 3: - m_NewSpecial = sec->xspecial; + sec->GetSpecial(&m_NewSpecial); m_Type = DFloor::genFloorChgT; break; } @@ -440,11 +440,11 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, { FTextureID oldpic = sec->GetTexture(sector_t::floor); sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->xspecial = line->frontsector->xspecial; + sec->TransferSpecial(line->frontsector); } else { - sec->xspecial = 0; + sec->ClearSpecial(); } break; @@ -455,8 +455,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, floor->m_Texture = sec->GetTexture(sector_t::floor); // jff 1/24/98 make sure floor->m_NewSpecial gets initialized // in case no surrounding sector is at floordestheight - // --> should not affect compatibility <-- - floor->m_NewSpecial = sec->xspecial; + sec->GetSpecial(&floor->m_NewSpecial); //jff 5/23/98 use model subroutine to unify fixes and handling sector_t *modelsec; @@ -464,7 +463,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, if (modelsec != NULL) { floor->m_Texture = modelsec->GetTexture(sector_t::floor); - floor->m_NewSpecial = modelsec->xspecial; + modelsec->GetSpecial(&floor->m_NewSpecial); } break; @@ -794,7 +793,7 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed) floor->m_Sector = s2; floor->m_Speed = slimespeed; floor->m_Texture = s3->GetTexture(sector_t::floor); - floor->m_NewSpecial = 0; + floor->m_NewSpecial.Clear(); height = s3->FindHighestFloorPoint (&spot); floor->m_FloorDestDist = s2->floorplane.PointToDist (spot, height); floor->StartFloorSound (); @@ -1093,7 +1092,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) if (line) { // [RH] if no line, no change sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->xspecial = line->frontsector->xspecial; + sec->TransferSpecial(line->frontsector); } break; case numChangeOnly: @@ -1101,7 +1100,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) if (secm) { // if no model, no change sec->SetTexture(sector_t::floor, secm->GetTexture(sector_t::floor)); - sec->xspecial = secm->xspecial; + sec->TransferSpecial(secm); } break; default: diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2ded3daf2..e78307949 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4424,7 +4424,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) ( gameaction != ga_worlddone ) && ( p->mo != NULL ) && ( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) && - ( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) + ( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter... { spawn_x = p->mo->x; spawn_y = p->mo->y; diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 467559e63..b0697fc34 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -282,8 +282,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, { if (line) sec->SetTexture(sector_t::floor, line->sidedef[0]->sector->GetTexture(sector_t::floor)); - if (change == 1) - sec->xspecial = 0; // Stop damage and other stuff, if any + if (change == 1) sec->ClearSpecial(); } switch (type) @@ -295,7 +294,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, plat->m_Low = sec->floorplane.d; plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); - sec->xspecial = 0; // NO MORE DAMAGE, IF APPLICABLE + sec->ClearSpecial(); break; case DPlat::platUpByValue: diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 0b6f032e5..321ecdd37 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -843,6 +843,60 @@ sector_t *sector_t::GetHeightSec() const } +void sector_t::GetSpecial(secspecial_t *spec) +{ + spec->special = special; + spec->damageamount = damageamount; + spec->damagetype = damagetype; + spec->damageinterval = damageinterval; + spec->leakydamage = leakydamage; + spec->Flags = Flags & SECF_SPECIALFLAGS; +} + +void sector_t::SetSpecial(const secspecial_t *spec) +{ + special = spec->special; + damageamount = spec->damageamount; + damagetype = spec->damagetype; + damageinterval = spec->damageinterval; + leakydamage = spec->leakydamage; + Flags = (Flags & ~SECF_SPECIALFLAGS) | (spec->Flags & SECF_SPECIALFLAGS); +} + +void sector_t::TransferSpecial(sector_t *model) +{ + special = model->special; + damageamount = model->damageamount; + damagetype = model->damagetype; + damageinterval = model->damageinterval; + leakydamage = model->leakydamage; + Flags = (Flags&~SECF_SPECIALFLAGS) | (model->Flags & SECF_SPECIALFLAGS); +} + +FArchive &operator<< (FArchive &arc, secspecial_t &p) +{ + if (SaveVersion < 4529) + { + short special; + arc << special; + sector_t sec; + P_InitSectorSpecial(&sec, special, true); + sec.GetSpecial(&p); + } + else + { + arc << p.special + << p.damageamount + << p.damagetype + << p.damageinterval + << p.leakydamage + << p.Flags; + } + return arc; +} + + + bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const { bool copy = false; diff --git a/src/p_spec.h b/src/p_spec.h index da508fda1..a95e07ce8 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -674,7 +674,7 @@ protected: // [RH] Need these for BOOM-ish transferring ceilings FTextureID m_Texture; - int m_NewSpecial; + secspecial_t m_NewSpecial; // ID int m_Tag; @@ -761,7 +761,7 @@ protected: int m_Crush; bool m_Hexencrush; int m_Direction; - int m_NewSpecial; + secspecial_t m_NewSpecial; FTextureID m_Texture; fixed_t m_FloorDestDist; fixed_t m_Speed; diff --git a/src/r_defs.h b/src/r_defs.h index 92b95699f..536376b63 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -367,7 +367,8 @@ enum 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 + SECF_SPECIALFLAGS = SECF_DAMAGEFLAGS|SECF_FRICTION|SECF_PUSH, // these flags originate from 'special and must be transferrable by floor thinkers }; enum @@ -440,6 +441,23 @@ struct FTransform fixed_t base_angle, base_yoffs; }; +struct secspecial_t +{ + FNameNoInit damagetype; // [RH] Means-of-death for applied damage + int damageamount; // [RH] Damage to do while standing on floor + short special; + short damageinterval; // Interval for damage application + short leakydamage; // chance of leaking through radiation suit + int Flags; + + void Clear() + { + memset(this, 0, sizeof(*this)); + } +}; + +FArchive &operator<< (FArchive &arc, secspecial_t &p); + struct sector_t { // Member functions @@ -670,6 +688,20 @@ struct sector_t Flags &= ~SECF_SECRET; } + void ClearSpecial() + { + // clears all variables that originate from 'special'. Used for sector type transferring thinkers + special = 0; + damageamount = 0; + damageinterval = 0; + damagetype = NAME_None; + leakydamage = 0; + Flags &= ~SECF_SPECIALFLAGS; + } + + void TransferSpecial(sector_t *model); + void GetSpecial(secspecial_t *spec); + void SetSpecial(const secspecial_t *spec); bool PlaneMoving(int pos); From 6afd76e5dbeaaf1caba244de6d735a6b5710334c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 13:36:22 +0100 Subject: [PATCH 14/17] - enable damage types for Strife's delayed damage. It will always use the type of damage that was last encountered. --- src/d_player.h | 1 + src/p_spec.cpp | 5 +++-- src/p_user.cpp | 9 +++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 11611cded..dc5b27a2b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -422,6 +422,7 @@ public: int killcount, itemcount, secretcount; // for intermission int damagecount, bonuscount;// for screen flashing int hazardcount; // for delayed Strife damage + FName hazardtype; // Damage type of last hazardous damage encounter. int poisoncount; // screen flash for poison damage FName poisontype; // type of poison damage to apply FName poisonpaintype; // type of Pain state to enter for poison damage diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 58679e3e6..aa6e0235b 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -458,6 +458,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) if (sector->Flags & SECF_HAZARD) { player->hazardcount += sector->damageamount; + player->hazardtype = sector->damagetype; } else { @@ -1231,7 +1232,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case sDamage_Hellslime: - P_SetupSectorDamage(sector, 2, 1, 0, NAME_None, SECF_HAZARD); + P_SetupSectorDamage(sector, 2, 1, 0, NAME_Slime, SECF_HAZARD); break; case Damage_InstantDeath: @@ -1240,7 +1241,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case sDamage_SuperHellslime: - P_SetupSectorDamage(sector, 4, 1, 0, NAME_None, SECF_HAZARD); + P_SetupSectorDamage(sector, 4, 1, 0, NAME_Slime, SECF_HAZARD); break; case Sector_Hidden: diff --git a/src/p_user.cpp b/src/p_user.cpp index 922cc2a1c..e60b82039 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -362,6 +362,7 @@ player_t &player_t::operator=(const player_t &p) damagecount = p.damagecount; bonuscount = p.bonuscount; hazardcount = p.hazardcount; + hazardtype = p.hazardtype; poisoncount = p.poisoncount; poisontype = p.poisontype; poisonpaintype = p.poisonpaintype; @@ -2599,7 +2600,7 @@ void P_PlayerThink (player_t *player) { player->hazardcount--; if (!(level.time & 31) && player->hazardcount > 16*TICRATE) - P_DamageMobj (player->mo, NULL, NULL, 5, NAME_Slime); + P_DamageMobj (player->mo, NULL, NULL, 5, player->hazardtype); } if (player->poisoncount && !(level.time & 15)) @@ -3012,7 +3013,11 @@ void player_t::Serialize (FArchive &arc) << air_finished << turnticks << oldbuttons; - bool IsBot; + if (SaveVersion >= 4929) + { + arc << hazardtype; + } + bool IsBot = false; if (SaveVersion >= 4514) { arc << Bot; From 154e1063150be76ab337436b568cffabf774c0a6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 14:16:42 +0100 Subject: [PATCH 15/17] - make better use of the damageinterval value for Strife's delayed damage. --- src/d_player.h | 1 + src/p_spec.cpp | 9 +++++---- src/p_user.cpp | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index dc5b27a2b..38879a63a 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -422,6 +422,7 @@ public: int killcount, itemcount, secretcount; // for intermission int damagecount, bonuscount;// for screen flashing int hazardcount; // for delayed Strife damage + int hazardinterval; // Frequency of damage infliction FName hazardtype; // Damage type of last hazardous damage encounter. int poisoncount; // screen flash for poison damage FName poisontype; // type of poison damage to apply diff --git a/src/p_spec.cpp b/src/p_spec.cpp index aa6e0235b..101309651 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -453,14 +453,15 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) } if (sector->Flags & SECF_ENDGODMODE) player->cheats &= ~CF_GODMODE; - if (level.time % sector->damageinterval == 0 && (ironfeet == NULL || pr_playerinspecialsector() < sector->leakydamage)) + if ((ironfeet == NULL || pr_playerinspecialsector() < sector->leakydamage)) { if (sector->Flags & SECF_HAZARD) { player->hazardcount += sector->damageamount; player->hazardtype = sector->damagetype; + player->hazardinterval = sector->damageinterval; } - else + else if (level.time % sector->damageinterval == 0) { P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT))) @@ -1232,7 +1233,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case sDamage_Hellslime: - P_SetupSectorDamage(sector, 2, 1, 0, NAME_Slime, SECF_HAZARD); + P_SetupSectorDamage(sector, 2, 32, 0, NAME_Slime, SECF_HAZARD); break; case Damage_InstantDeath: @@ -1241,7 +1242,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case sDamage_SuperHellslime: - P_SetupSectorDamage(sector, 4, 1, 0, NAME_Slime, SECF_HAZARD); + P_SetupSectorDamage(sector, 4, 32, 0, NAME_Slime, SECF_HAZARD); break; case Sector_Hidden: diff --git a/src/p_user.cpp b/src/p_user.cpp index e60b82039..ba987d393 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -363,6 +363,7 @@ player_t &player_t::operator=(const player_t &p) bonuscount = p.bonuscount; hazardcount = p.hazardcount; hazardtype = p.hazardtype; + hazardinterval = p.hazardinterval; poisoncount = p.poisoncount; poisontype = p.poisontype; poisonpaintype = p.poisonpaintype; @@ -2599,7 +2600,7 @@ void P_PlayerThink (player_t *player) if (player->hazardcount) { player->hazardcount--; - if (!(level.time & 31) && player->hazardcount > 16*TICRATE) + if (!(level.time % player->hazardinterval) && player->hazardcount > 16*TICRATE) P_DamageMobj (player->mo, NULL, NULL, 5, player->hazardtype); } @@ -3015,7 +3016,8 @@ void player_t::Serialize (FArchive &arc) << oldbuttons; if (SaveVersion >= 4929) { - arc << hazardtype; + arc << hazardtype + << hazardinterval; } bool IsBot = false; if (SaveVersion >= 4514) From f8b2b4558f8ccd3cdd49a309a1218308d770fa2b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 15:47:56 +0100 Subject: [PATCH 16/17] - fixed a few typos (Get instead of Set...) --- src/p_floor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 780bd5d9d..e3763e677 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -161,7 +161,7 @@ void DFloor::Tick () case donutRaise: case genFloorChgT: case genFloorChg0: - m_Sector->GetSpecial(&m_NewSpecial); + m_Sector->SetSpecial(&m_NewSpecial); //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); @@ -177,7 +177,7 @@ void DFloor::Tick () case floorLowerAndChange: case genFloorChgT: case genFloorChg0: - m_Sector->GetSpecial(&m_NewSpecial); + m_Sector->SetSpecial(&m_NewSpecial); //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); From eafa394af4abeffb86e4cb2f582d8c4873f55bd0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Jan 2016 16:42:21 +0100 Subject: [PATCH 17/17] - re-added and fixed terrain splashes for damaging sectors. Turned out that P_HitWater wasn't even able to spawn the splashes, even after the call was re-added. --- src/p_local.h | 1288 ++++++++++++++++++++++++------------------------ src/p_mobj.cpp | 31 +- src/p_spec.cpp | 4 + 3 files changed, 665 insertions(+), 658 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 11e6678c1..63ee4c1b1 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -1,647 +1,647 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// DESCRIPTION: -// Play functions, animation, global header. -// -//----------------------------------------------------------------------------- - - -#ifndef __P_LOCAL__ -#define __P_LOCAL__ - -#include "doomtype.h" -#include "doomdef.h" -#include "tables.h" -#include "r_state.h" -#include "r_utility.h" -#include "d_player.h" - -#include "a_morph.h" - -#include - -#define STEEPSLOPE 46342 // [RH] Minimum floorplane.c value for walking - -#define BONUSADD 6 - -// mapblocks are used to check movement -// against lines and things -#define MAPBLOCKUNITS 128 -#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT) -#define MAPBLOCKSHIFT (FRACBITS+7) -#define MAPBMASK (MAPBLOCKSIZE-1) -#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS) - -// Inspired by Maes -extern int bmapnegx; -extern int bmapnegy; - -inline int GetSafeBlockX(int blockx) -{ - blockx >>= MAPBLOCKSHIFT; - return (blockx <= bmapnegx) ? blockx & 0x1FF : blockx; -} -inline int GetSafeBlockX(long long blockx) -{ - blockx >>= MAPBLOCKSHIFT; - return int((blockx <= bmapnegx) ? blockx & 0x1FF : blockx); -} - -inline int GetSafeBlockY(int blocky) -{ - blocky >>= MAPBLOCKSHIFT; - return (blocky <= bmapnegy) ? blocky & 0x1FF: blocky; -} -inline int GetSafeBlockY(long long blocky) -{ - blocky >>= MAPBLOCKSHIFT; - return int((blocky <= bmapnegy) ? blocky & 0x1FF: blocky); -} - -// MAXRADIUS is for precalculated sector block boxes -// the spider demon is larger, -// but we do not have any moving sectors nearby -#define MAXRADIUS 0/*32*FRACUNIT*/ - -//#define GRAVITY FRACUNIT -#define MAXMOVE (30*FRACUNIT) - -#define TALKRANGE (128*FRACUNIT) -#define USERANGE (64*FRACUNIT) -#define MELEERANGE (64*FRACUNIT) -#define MISSILERANGE (32*64*FRACUNIT) -#define PLAYERMISSILERANGE (8192*FRACUNIT) // [RH] New MISSILERANGE for players - -// follow a player exlusively for 3 seconds -#define BASETHRESHOLD 100 - - -// -// P_PSPR -// -void P_SetupPsprites (player_t* curplayer, bool startweaponup); -void P_MovePsprites (player_t* curplayer); -void P_DropWeapon (player_t* player); - - -// -// P_USER -// -void P_FallingDamage (AActor *ent); -void P_PlayerThink (player_t *player); -void P_PredictPlayer (player_t *player); -void P_UnPredictPlayer (); -void P_PredictionLerpReset(); - -// -// P_MOBJ -// - -#define ONFLOORZ FIXED_MIN -#define ONCEILINGZ FIXED_MAX -#define FLOATRANDZ (FIXED_MAX-1) - -#define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player -#define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised - -APlayerPawn *P_SpawnPlayer (struct FPlayerStart *mthing, int playernum, int flags=0); - -void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); -int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false); - -enum EPuffFlags -{ - PF_HITTHING = 1, - PF_MELEERANGE = 2, - PF_TEMPORARY = 4, - PF_HITTHINGBLEED = 8, - PF_NORANDOMZ = 16 -}; - -AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL); -void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); -void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator); -void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator); -void P_RipperBlood (AActor *mo, AActor *bleeder); -int P_GetThingFloorType (AActor *thing); -void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target); - -AActor *P_SpawnMissile (AActor* source, AActor* dest, const PClass *type, AActor* owner = NULL); -AActor *P_SpawnMissileZ (AActor* source, fixed_t z, AActor* dest, const PClass *type); -AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, const PClass *type, bool checkspawn = true, AActor *owner = NULL); -AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, angle_t angle, fixed_t velz); -AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed); -AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz); -AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); -AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PClass *type); - -AActor *P_SpawnPlayerMissile (AActor* source, const PClass *type); -AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle); -AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, - AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false); - -void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); - -// -// [RH] P_THINGS -// -extern FClassMap SpawnableThings; -extern FClassMap StrifeTypes; - -bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid); -bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle, - fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid, - bool leadTarget); -bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog); -bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog); -int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type); -void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob); -void P_RemoveThing(AActor * actor); -bool P_Thing_Raise(AActor *thing, AActor *raiser); -bool P_Thing_CanRaise(AActor *thing); -const PClass *P_GetSpawnableType(int spawnnum); -void InitSpawnablesFromMapinfo(); -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch); - -enum WARPF +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// DESCRIPTION: +// Play functions, animation, global header. +// +//----------------------------------------------------------------------------- + + +#ifndef __P_LOCAL__ +#define __P_LOCAL__ + +#include "doomtype.h" +#include "doomdef.h" +#include "tables.h" +#include "r_state.h" +#include "r_utility.h" +#include "d_player.h" + +#include "a_morph.h" + +#include + +#define STEEPSLOPE 46342 // [RH] Minimum floorplane.c value for walking + +#define BONUSADD 6 + +// mapblocks are used to check movement +// against lines and things +#define MAPBLOCKUNITS 128 +#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT) +#define MAPBLOCKSHIFT (FRACBITS+7) +#define MAPBMASK (MAPBLOCKSIZE-1) +#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS) + +// Inspired by Maes +extern int bmapnegx; +extern int bmapnegy; + +inline int GetSafeBlockX(int blockx) { - WARPF_ABSOLUTEOFFSET = 0x1, - WARPF_ABSOLUTEANGLE = 0x2, - WARPF_USECALLERANGLE = 0x4, - - WARPF_NOCHECKPOSITION = 0x8, - - WARPF_INTERPOLATE = 0x10, - WARPF_WARPINTERPOLATION = 0x20, - WARPF_COPYINTERPOLATION = 0x40, - - WARPF_STOP = 0x80, - WARPF_TOFLOOR = 0x100, - WARPF_TESTONLY = 0x200, - WARPF_ABSOLUTEPOSITION = 0x400, - WARPF_BOB = 0x800, - WARPF_MOVEPTR = 0x1000, - WARPF_USEPTR = 0x2000, - WARPF_USETID = 0x2000, - WARPF_COPYVELOCITY = 0x4000, - WARPF_COPYPITCH = 0x8000, + blockx >>= MAPBLOCKSHIFT; + return (blockx <= bmapnegx) ? blockx & 0x1FF : blockx; +} +inline int GetSafeBlockX(long long blockx) +{ + blockx >>= MAPBLOCKSHIFT; + return int((blockx <= bmapnegx) ? blockx & 0x1FF : blockx); +} + +inline int GetSafeBlockY(int blocky) +{ + blocky >>= MAPBLOCKSHIFT; + return (blocky <= bmapnegy) ? blocky & 0x1FF: blocky; +} +inline int GetSafeBlockY(long long blocky) +{ + blocky >>= MAPBLOCKSHIFT; + return int((blocky <= bmapnegy) ? blocky & 0x1FF: blocky); +} + +// MAXRADIUS is for precalculated sector block boxes +// the spider demon is larger, +// but we do not have any moving sectors nearby +#define MAXRADIUS 0/*32*FRACUNIT*/ + +//#define GRAVITY FRACUNIT +#define MAXMOVE (30*FRACUNIT) + +#define TALKRANGE (128*FRACUNIT) +#define USERANGE (64*FRACUNIT) +#define MELEERANGE (64*FRACUNIT) +#define MISSILERANGE (32*64*FRACUNIT) +#define PLAYERMISSILERANGE (8192*FRACUNIT) // [RH] New MISSILERANGE for players + +// follow a player exlusively for 3 seconds +#define BASETHRESHOLD 100 + + +// +// P_PSPR +// +void P_SetupPsprites (player_t* curplayer, bool startweaponup); +void P_MovePsprites (player_t* curplayer); +void P_DropWeapon (player_t* player); + + +// +// P_USER +// +void P_FallingDamage (AActor *ent); +void P_PlayerThink (player_t *player); +void P_PredictPlayer (player_t *player); +void P_UnPredictPlayer (); +void P_PredictionLerpReset(); + +// +// P_MOBJ +// + +#define ONFLOORZ FIXED_MIN +#define ONCEILINGZ FIXED_MAX +#define FLOATRANDZ (FIXED_MAX-1) + +#define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player +#define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised + +APlayerPawn *P_SpawnPlayer (struct FPlayerStart *mthing, int playernum, int flags=0); + +void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); +int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); +bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false); + +enum EPuffFlags +{ + PF_HITTHING = 1, + PF_MELEERANGE = 2, + PF_TEMPORARY = 4, + PF_HITTHINGBLEED = 8, + PF_NORANDOMZ = 16 }; - - -// -// P_MAPUTL -// -struct divline_t -{ - fixed_t x; - fixed_t y; - fixed_t dx; - fixed_t dy; - -}; - -struct intercept_t -{ - fixed_t frac; // along trace line - bool isaline; - bool done; - union { - AActor *thing; - line_t *line; - } d; -}; - -typedef bool (*traverser_t) (intercept_t *in); - -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); - -//========================================================================== -// -// P_PointOnLineSide -// -// Returns 0 (front/on) or 1 (back) -// [RH] inlined, stripped down, and made more precise -// -//========================================================================== - -inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) -{ - extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); - - return i_compatflags2 & COMPATF2_POINTONLINE - ? P_VanillaPointOnLineSide(x, y, line) - : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; -} - -//========================================================================== -// -// P_PointOnDivlineSide -// -// Same as P_PointOnLineSide except it uses divlines -// [RH] inlined, stripped down, and made more precise -// -//========================================================================== - -inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) -{ - extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); - - return (i_compatflags2 & COMPATF2_POINTONLINE) - ? P_VanillaPointOnDivlineSide(x, y, line) - : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); -} - -//========================================================================== -// -// P_MakeDivline -// -//========================================================================== - -inline void P_MakeDivline (const line_t *li, divline_t *dl) -{ - dl->x = li->v1->x; - dl->y = li->v1->y; - dl->dx = li->dx; - dl->dy = li->dy; -} - -fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1); - -struct FLineOpening -{ - fixed_t top; - fixed_t bottom; - fixed_t range; - fixed_t lowfloor; - sector_t *bottomsec; - sector_t *topsec; - FTextureID ceilingpic; - FTextureID floorpic; - bool touchmidtex; - bool abovemidtex; -}; - -void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, int flags=0); - -class FBoundingBox; -struct polyblock_t; - -class FBlockLinesIterator -{ - int minx, maxx; - int miny, maxy; - - int curx, cury; - polyblock_t *polyLink; - int polyIndex; - int *list; - - void StartBlock(int x, int y); - -public: - FBlockLinesIterator(int minx, int miny, int maxx, int maxy, bool keepvalidcount = false); - FBlockLinesIterator(const FBoundingBox &box); - line_t *Next(); - void Reset() { StartBlock(minx, miny); } -}; - -class FBlockThingsIterator -{ - int minx, maxx; - int miny, maxy; - - int curx, cury; - - FBlockNode *block; - - int Buckets[32]; - - struct HashEntry - { - AActor *Actor; - int Next; - }; - HashEntry FixedHash[10]; - int NumFixedHash; - TArray DynHash; - - HashEntry *GetHashEntry(int i) { return i < (int)countof(FixedHash) ? &FixedHash[i] : &DynHash[i - countof(FixedHash)]; } - - void StartBlock(int x, int y); - void SwitchBlock(int x, int y); - void ClearHash(); - - // The following is only for use in the path traverser - // and therefore declared private. - FBlockThingsIterator(); - - friend class FPathTraverse; - -public: - FBlockThingsIterator(int minx, int miny, int maxx, int maxy); - FBlockThingsIterator(const FBoundingBox &box); - AActor *Next(bool centeronly = false); - void Reset() { StartBlock(minx, miny); } -}; - -class FPathTraverse -{ - static TArray intercepts; - - divline_t trace; - unsigned int intercept_index; - unsigned int intercept_count; - fixed_t maxfrac; - unsigned int count; - - void AddLineIntercepts(int bx, int by); - void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it, bool compatible); -public: - - intercept_t *Next(); - - FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags); - ~FPathTraverse(); - const divline_t &Trace() const { return trace; } -}; - - -#define PT_ADDLINES 1 -#define PT_ADDTHINGS 2 -#define PT_COMPATIBLE 4 -#define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint - -AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL); -AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false); - -// -// P_MAP -// - -struct FCheckPosition -{ - // in - AActor *thing; - fixed_t x; - fixed_t y; - fixed_t z; - - // out - sector_t *sector; - fixed_t floorz; - fixed_t ceilingz; - fixed_t dropoffz; - FTextureID floorpic; - sector_t *floorsector; - FTextureID ceilingpic; - sector_t *ceilingsector; - bool touchmidtex; - bool abovemidtex; - bool floatok; - bool FromPMove; - line_t *ceilingline; - AActor *stepthing; - // [RH] These are used by PIT_CheckThing and P_XYMovement to apply - // ripping damage once per tic instead of once per move. - bool DoRipping; - AActor *LastRipped; - int PushTime; - - FCheckPosition(bool rip=false) - { - DoRipping = rip; - LastRipped = NULL; - PushTime = 0; - FromPMove = false; - } -}; - - - -// If "floatok" true, move would be ok -// if within "tmfloorz - tmceilingz". -extern msecnode_t *sector_list; // phares 3/16/98 - -extern TArray spechit; - - -bool P_TestMobjLocation (AActor *mobj); -bool P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL); -bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly=false); -bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly=false); -AActor *P_CheckOnmobj (AActor *thing); -void P_FakeZMovement (AActor *mo); -bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); -bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL); -bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y); -void P_ApplyTorque(AActor *mo); -bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag); // [RH] Added z and telefrag parameters -void P_PlayerStartStomp (AActor *actor); // [RH] Stomp on things for a newly spawned player -void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); -bool P_BounceWall (AActor *mo); -bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop); -bool P_CheckSight (const AActor *t1, const AActor *t2, int flags=0); - -enum ESightFlags -{ - SF_IGNOREVISIBILITY=1, - SF_SEEPASTSHOOTABLELINES=2, - SF_SEEPASTBLOCKEVERYTHING=4, - SF_IGNOREWATERBOUNDARY=8 -}; - -void P_ResetSightCounters (bool full); -bool P_TalkFacing (AActor *player); -void P_UseLines (player_t* player); -bool P_UsePuzzleItem (AActor *actor, int itemType); - -enum -{ - FFCF_ONLYSPAWNPOS = 1, - FFCF_SAMESECTOR = 2, - FFCF_ONLY3DFLOORS = 4, // includes 3D midtexes - FFCF_3DRESTRICT = 8, // ignore 3D midtexes and floors whose floorz are above thing's z -}; -void P_FindFloorCeiling (AActor *actor, int flags=0); - -bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); - -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL, AActor *friender=NULL); - -enum // P_AimLineAttack flags -{ - ALF_FORCENOSMART = 1, - ALF_CHECK3D = 2, - ALF_CHECKNONSHOOTABLE = 4, - ALF_CHECKCONVERSATION = 8, - ALF_NOFRIENDS = 16, -}; - -enum // P_LineAttack flags -{ - LAF_ISMELEEATTACK = 1, - LAF_NORANDOMPUFFZ = 2, - LAF_NOIMPACTDECAL = 4 -}; - -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); -AActor *P_LinePickActor (AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); -void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); -void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); -void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version -void P_TraceBleed (int damage, AActor *target); // random direction version -bool P_HitFloor (AActor *thing); -bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true); -void P_CheckSplash(AActor *self, fixed_t distance); -void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, const PClass *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, const PClass *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun - -enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags -{ - RAF_SILENT = 1, - RAF_NOPIERCE = 2, - RAF_EXPLICITANGLE = 4, - RAF_FULLBRIGHT = 8, - RAF_CENTERZ = 16, -}; - - -bool P_CheckMissileSpawn (AActor *missile, fixed_t maxdist); -void P_PlaySpawnSound(AActor *missile, AActor *spawner); - -// [RH] Position the chasecam -void P_AimCamera (AActor *t1, fixed_t &x, fixed_t &y, fixed_t &z, sector_t *&sec); - -// [RH] Means of death -enum -{ - RADF_HURTSOURCE = 1, - RADF_NOIMPACTDAMAGE = 2, - RADF_SOURCEISSPOT = 4, - RADF_NODAMAGE = 8, -}; -void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, - FName damageType, int flags, int fulldamagedistance=0); - -void P_DelSector_List(); -void P_DelSeclist(msecnode_t *); // phares 3/16/98 -msecnode_t* P_DelSecnode(msecnode_t *); -void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98 -int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98 -int P_GetFriction(const AActor *mo, int *frictionfactor); -bool Check_Sides(AActor *, int, int); // phares - -// [RH] -const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove); - -//---------------------------------------------------------------------------------- -// -// Added so that in the source there's a clear distinction between -// game engine and renderer specific calls. -// (For ZDoom itself this doesn't make any difference here but for GZDoom it does.) -// -//---------------------------------------------------------------------------------- -subsector_t *P_PointInSubsector (fixed_t x, fixed_t y); -inline sector_t *P_PointInSector(fixed_t x, fixed_t y) -{ - return P_PointInSubsector(x,y)->sector; -} - -// -// P_SETUP -// -extern BYTE* rejectmatrix; // for fast sight rejection -extern int* blockmaplump; // offsets in blockmap are from here - -extern int* blockmap; -extern int bmapwidth; -extern int bmapheight; // in mapblocks -extern fixed_t bmaporgx; -extern fixed_t bmaporgy; // origin of block map -extern FBlockNode** blocklinks; // for thing chains - - - -// -// P_INTER -// -void P_TouchSpecialThing (AActor *special, AActor *toucher); -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0); -void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type); -bool P_GiveBody (AActor *actor, int num, int max=0); -bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); -void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound); - -enum EDmgFlags -{ - DMG_NO_ARMOR = 1, - DMG_INFLICTOR_IS_PUFF = 2, - DMG_THRUSTLESS = 4, - DMG_FORCED = 8, - DMG_NO_FACTOR = 16, - DMG_PLAYERATTACK = 32, - DMG_FOILINVUL = 64, - DMG_FOILBUDDHA = 128, - DMG_NO_PROTECT = 256, -}; - - -// ===== PO_MAN ===== - -typedef enum -{ - PODOOR_NONE, - PODOOR_SLIDE, - PODOOR_SWING, -} podoortype_t; - -bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide); -bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide); -bool EV_MovePolyTo (line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide); -bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type); -bool EV_StopPoly (int polyNum); - - -// [RH] Data structure for P_SpawnMapThing() to keep track -// of polyobject-related things. -struct polyspawns_t -{ - polyspawns_t *next; - fixed_t x; - fixed_t y; - short angle; - short type; -}; - -extern int po_NumPolyobjs; -extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn - - -void PO_Init (); -bool PO_Busy (int polyobj); -FPolyObj *PO_GetPolyobj(int polyNum); - -// -// P_SPEC -// -#include "p_spec.h" - -bool P_AlignFlat (int linenum, int side, int fc); - -#endif // __P_LOCAL__ +AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL); +void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); +void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator); +void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator); +void P_RipperBlood (AActor *mo, AActor *bleeder); +int P_GetThingFloorType (AActor *thing); +void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target); + +AActor *P_SpawnMissile (AActor* source, AActor* dest, const PClass *type, AActor* owner = NULL); +AActor *P_SpawnMissileZ (AActor* source, fixed_t z, AActor* dest, const PClass *type); +AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, const PClass *type, bool checkspawn = true, AActor *owner = NULL); +AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, angle_t angle, fixed_t velz); +AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed); +AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz); +AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); +AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PClass *type); + +AActor *P_SpawnPlayerMissile (AActor* source, const PClass *type); +AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle); +AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, + AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false); + +void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); + +// +// [RH] P_THINGS +// +extern FClassMap SpawnableThings; +extern FClassMap StrifeTypes; + +bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid); +bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle, + fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid, + bool leadTarget); +bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog); +bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog); +int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type); +void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob); +void P_RemoveThing(AActor * actor); +bool P_Thing_Raise(AActor *thing, AActor *raiser); +bool P_Thing_CanRaise(AActor *thing); +const PClass *P_GetSpawnableType(int spawnnum); +void InitSpawnablesFromMapinfo(); +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch); + +enum WARPF +{ + WARPF_ABSOLUTEOFFSET = 0x1, + WARPF_ABSOLUTEANGLE = 0x2, + WARPF_USECALLERANGLE = 0x4, + + WARPF_NOCHECKPOSITION = 0x8, + + WARPF_INTERPOLATE = 0x10, + WARPF_WARPINTERPOLATION = 0x20, + WARPF_COPYINTERPOLATION = 0x40, + + WARPF_STOP = 0x80, + WARPF_TOFLOOR = 0x100, + WARPF_TESTONLY = 0x200, + WARPF_ABSOLUTEPOSITION = 0x400, + WARPF_BOB = 0x800, + WARPF_MOVEPTR = 0x1000, + WARPF_USEPTR = 0x2000, + WARPF_USETID = 0x2000, + WARPF_COPYVELOCITY = 0x4000, + WARPF_COPYPITCH = 0x8000, +}; + + + +// +// P_MAPUTL +// +struct divline_t +{ + fixed_t x; + fixed_t y; + fixed_t dx; + fixed_t dy; + +}; + +struct intercept_t +{ + fixed_t frac; // along trace line + bool isaline; + bool done; + union { + AActor *thing; + line_t *line; + } d; +}; + +typedef bool (*traverser_t) (intercept_t *in); + +fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); + +//========================================================================== +// +// P_PointOnLineSide +// +// Returns 0 (front/on) or 1 (back) +// [RH] inlined, stripped down, and made more precise +// +//========================================================================== + +inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) +{ + extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); + + return i_compatflags2 & COMPATF2_POINTONLINE + ? P_VanillaPointOnLineSide(x, y, line) + : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; +} + +//========================================================================== +// +// P_PointOnDivlineSide +// +// Same as P_PointOnLineSide except it uses divlines +// [RH] inlined, stripped down, and made more precise +// +//========================================================================== + +inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) +{ + extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); + + return (i_compatflags2 & COMPATF2_POINTONLINE) + ? P_VanillaPointOnDivlineSide(x, y, line) + : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); +} + +//========================================================================== +// +// P_MakeDivline +// +//========================================================================== + +inline void P_MakeDivline (const line_t *li, divline_t *dl) +{ + dl->x = li->v1->x; + dl->y = li->v1->y; + dl->dx = li->dx; + dl->dy = li->dy; +} + +fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1); + +struct FLineOpening +{ + fixed_t top; + fixed_t bottom; + fixed_t range; + fixed_t lowfloor; + sector_t *bottomsec; + sector_t *topsec; + FTextureID ceilingpic; + FTextureID floorpic; + bool touchmidtex; + bool abovemidtex; +}; + +void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, int flags=0); + +class FBoundingBox; +struct polyblock_t; + +class FBlockLinesIterator +{ + int minx, maxx; + int miny, maxy; + + int curx, cury; + polyblock_t *polyLink; + int polyIndex; + int *list; + + void StartBlock(int x, int y); + +public: + FBlockLinesIterator(int minx, int miny, int maxx, int maxy, bool keepvalidcount = false); + FBlockLinesIterator(const FBoundingBox &box); + line_t *Next(); + void Reset() { StartBlock(minx, miny); } +}; + +class FBlockThingsIterator +{ + int minx, maxx; + int miny, maxy; + + int curx, cury; + + FBlockNode *block; + + int Buckets[32]; + + struct HashEntry + { + AActor *Actor; + int Next; + }; + HashEntry FixedHash[10]; + int NumFixedHash; + TArray DynHash; + + HashEntry *GetHashEntry(int i) { return i < (int)countof(FixedHash) ? &FixedHash[i] : &DynHash[i - countof(FixedHash)]; } + + void StartBlock(int x, int y); + void SwitchBlock(int x, int y); + void ClearHash(); + + // The following is only for use in the path traverser + // and therefore declared private. + FBlockThingsIterator(); + + friend class FPathTraverse; + +public: + FBlockThingsIterator(int minx, int miny, int maxx, int maxy); + FBlockThingsIterator(const FBoundingBox &box); + AActor *Next(bool centeronly = false); + void Reset() { StartBlock(minx, miny); } +}; + +class FPathTraverse +{ + static TArray intercepts; + + divline_t trace; + unsigned int intercept_index; + unsigned int intercept_count; + fixed_t maxfrac; + unsigned int count; + + void AddLineIntercepts(int bx, int by); + void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it, bool compatible); +public: + + intercept_t *Next(); + + FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags); + ~FPathTraverse(); + const divline_t &Trace() const { return trace; } +}; + + +#define PT_ADDLINES 1 +#define PT_ADDTHINGS 2 +#define PT_COMPATIBLE 4 +#define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint + +AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL); +AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false); + +// +// P_MAP +// + +struct FCheckPosition +{ + // in + AActor *thing; + fixed_t x; + fixed_t y; + fixed_t z; + + // out + sector_t *sector; + fixed_t floorz; + fixed_t ceilingz; + fixed_t dropoffz; + FTextureID floorpic; + sector_t *floorsector; + FTextureID ceilingpic; + sector_t *ceilingsector; + bool touchmidtex; + bool abovemidtex; + bool floatok; + bool FromPMove; + line_t *ceilingline; + AActor *stepthing; + // [RH] These are used by PIT_CheckThing and P_XYMovement to apply + // ripping damage once per tic instead of once per move. + bool DoRipping; + AActor *LastRipped; + int PushTime; + + FCheckPosition(bool rip=false) + { + DoRipping = rip; + LastRipped = NULL; + PushTime = 0; + FromPMove = false; + } +}; + + + +// If "floatok" true, move would be ok +// if within "tmfloorz - tmceilingz". +extern msecnode_t *sector_list; // phares 3/16/98 + +extern TArray spechit; + + +bool P_TestMobjLocation (AActor *mobj); +bool P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL); +bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly=false); +bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly=false); +AActor *P_CheckOnmobj (AActor *thing); +void P_FakeZMovement (AActor *mo); +bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); +bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL); +bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y); +void P_ApplyTorque(AActor *mo); +bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag); // [RH] Added z and telefrag parameters +void P_PlayerStartStomp (AActor *actor); // [RH] Stomp on things for a newly spawned player +void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); +bool P_BounceWall (AActor *mo); +bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop); +bool P_CheckSight (const AActor *t1, const AActor *t2, int flags=0); + +enum ESightFlags +{ + SF_IGNOREVISIBILITY=1, + SF_SEEPASTSHOOTABLELINES=2, + SF_SEEPASTBLOCKEVERYTHING=4, + SF_IGNOREWATERBOUNDARY=8 +}; + +void P_ResetSightCounters (bool full); +bool P_TalkFacing (AActor *player); +void P_UseLines (player_t* player); +bool P_UsePuzzleItem (AActor *actor, int itemType); + +enum +{ + FFCF_ONLYSPAWNPOS = 1, + FFCF_SAMESECTOR = 2, + FFCF_ONLY3DFLOORS = 4, // includes 3D midtexes + FFCF_3DRESTRICT = 8, // ignore 3D midtexes and floors whose floorz are above thing's z +}; +void P_FindFloorCeiling (AActor *actor, int flags=0); + +bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); + +fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL, AActor *friender=NULL); + +enum // P_AimLineAttack flags +{ + ALF_FORCENOSMART = 1, + ALF_CHECK3D = 2, + ALF_CHECKNONSHOOTABLE = 4, + ALF_CHECKCONVERSATION = 8, + ALF_NOFRIENDS = 16, +}; + +enum // P_LineAttack flags +{ + LAF_ISMELEEATTACK = 1, + LAF_NORANDOMPUFFZ = 2, + LAF_NOIMPACTDECAL = 4 +}; + +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); +AActor *P_LinePickActor (AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); +void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); +void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); +void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version +void P_TraceBleed (int damage, AActor *target); // random direction version +bool P_HitFloor (AActor *thing); +bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false); +void P_CheckSplash(AActor *self, fixed_t distance); +void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, const PClass *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, const PClass *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun + +enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags +{ + RAF_SILENT = 1, + RAF_NOPIERCE = 2, + RAF_EXPLICITANGLE = 4, + RAF_FULLBRIGHT = 8, + RAF_CENTERZ = 16, +}; + + +bool P_CheckMissileSpawn (AActor *missile, fixed_t maxdist); +void P_PlaySpawnSound(AActor *missile, AActor *spawner); + +// [RH] Position the chasecam +void P_AimCamera (AActor *t1, fixed_t &x, fixed_t &y, fixed_t &z, sector_t *&sec); + +// [RH] Means of death +enum +{ + RADF_HURTSOURCE = 1, + RADF_NOIMPACTDAMAGE = 2, + RADF_SOURCEISSPOT = 4, + RADF_NODAMAGE = 8, +}; +void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, + FName damageType, int flags, int fulldamagedistance=0); + +void P_DelSector_List(); +void P_DelSeclist(msecnode_t *); // phares 3/16/98 +msecnode_t* P_DelSecnode(msecnode_t *); +void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98 +int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98 +int P_GetFriction(const AActor *mo, int *frictionfactor); +bool Check_Sides(AActor *, int, int); // phares + +// [RH] +const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove); + +//---------------------------------------------------------------------------------- +// +// Added so that in the source there's a clear distinction between +// game engine and renderer specific calls. +// (For ZDoom itself this doesn't make any difference here but for GZDoom it does.) +// +//---------------------------------------------------------------------------------- +subsector_t *P_PointInSubsector (fixed_t x, fixed_t y); +inline sector_t *P_PointInSector(fixed_t x, fixed_t y) +{ + return P_PointInSubsector(x,y)->sector; +} + +// +// P_SETUP +// +extern BYTE* rejectmatrix; // for fast sight rejection +extern int* blockmaplump; // offsets in blockmap are from here + +extern int* blockmap; +extern int bmapwidth; +extern int bmapheight; // in mapblocks +extern fixed_t bmaporgx; +extern fixed_t bmaporgy; // origin of block map +extern FBlockNode** blocklinks; // for thing chains + + + +// +// P_INTER +// +void P_TouchSpecialThing (AActor *special, AActor *toucher); +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0); +void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type); +bool P_GiveBody (AActor *actor, int num, int max=0); +bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); +void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound); + +enum EDmgFlags +{ + DMG_NO_ARMOR = 1, + DMG_INFLICTOR_IS_PUFF = 2, + DMG_THRUSTLESS = 4, + DMG_FORCED = 8, + DMG_NO_FACTOR = 16, + DMG_PLAYERATTACK = 32, + DMG_FOILINVUL = 64, + DMG_FOILBUDDHA = 128, + DMG_NO_PROTECT = 256, +}; + + +// ===== PO_MAN ===== + +typedef enum +{ + PODOOR_NONE, + PODOOR_SLIDE, + PODOOR_SWING, +} podoortype_t; + +bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide); +bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide); +bool EV_MovePolyTo (line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide); +bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type); +bool EV_StopPoly (int polyNum); + + +// [RH] Data structure for P_SpawnMapThing() to keep track +// of polyobject-related things. +struct polyspawns_t +{ + polyspawns_t *next; + fixed_t x; + fixed_t y; + short angle; + short type; +}; + +extern int po_NumPolyobjs; +extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn + + +void PO_Init (); +bool PO_Busy (int polyobj); +FPolyObj *PO_GetPolyobj(int polyNum); + +// +// P_SPEC +// +#include "p_spec.h" + +bool P_AlignFlat (int linenum, int side, int fc); + +#endif // __P_LOCAL__ diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e78307949..48f16ba0e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5320,7 +5320,7 @@ int P_GetThingFloorType (AActor *thing) // Returns true if hit liquid and splashed, false if not. //--------------------------------------------------------------------------- -bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool checkabove, bool alert) +bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool checkabove, bool alert, bool force) { if (thing->flags3 & MF3_DONTSPLASH) return false; @@ -5362,24 +5362,27 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z } #endif - for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) - { - F3DFloor * rover = sec->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; - fixed_t planez = rover->top.plane->ZatPoint(x, y); - if (z > planez - FRACUNIT/2 && z < planez + FRACUNIT/2) // allow minor imprecisions + if (!force) + { + for (unsigned int i = 0; ie->XFloor.ffloors.Size(); i++) { - if (rover->flags & (FF_SOLID|FF_SWIMMABLE) ) + F3DFloor * rover = sec->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_EXISTS)) continue; + fixed_t planez = rover->top.plane->ZatPoint(x, y); + if (z > planez - FRACUNIT / 2 && z < planez + FRACUNIT / 2) // allow minor imprecisions { - terrainnum = TerrainTypes[*rover->top.texture]; - goto foundone; + if (rover->flags & (FF_SOLID | FF_SWIMMABLE)) + { + terrainnum = TerrainTypes[*rover->top.texture]; + goto foundone; + } } + planez = rover->bottom.plane->ZatPoint(x, y); + if (planez < z && !(planez < thing->floorz)) return false; } - planez = rover->bottom.plane->ZatPoint(x, y); - if (planez < z && !(planez < thing->floorz)) return false; } hsec = sec->GetHeightSec(); - if (hsec == NULL || !(hsec->MoreFlags & SECF_CLIPFAKEPLANES)) + if (force || hsec == NULL || !(hsec->MoreFlags & SECF_CLIPFAKEPLANES)) { terrainnum = TerrainTypes[sec->GetTexture(sector_t::floor)]; } @@ -5403,7 +5406,7 @@ foundone: // Don't splash for living things with small vertical velocities. // There are levels where the constant splashing from the monsters gets extremely annoying - if ((thing->flags3&MF3_ISMONSTER || thing->player) && thing->velz >= -6*FRACUNIT) + if (((thing->flags3&MF3_ISMONSTER || thing->player) && thing->velz >= -6*FRACUNIT) && !force) return Terrains[terrainnum].IsLiquid; splash = &Splashes[splashnum]; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 101309651..918d07ed2 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -468,6 +468,10 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) { G_ExitLevel(0, false); } + if (sector->Flags & SECF_DMGTERRAINFX) + { + P_HitWater(player->mo, sector, INT_MIN, INT_MIN, INT_MIN, false, true, true); + } } } }