From df138fe4f90725894fceee2b54b27a0f296406fb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Sep 2010 00:06:45 +0000 Subject: [PATCH] - added a ClearCounters function to AActor that handles everything necessary to un-count an item that is not supposed to be counted but has some of the COUNT* flags set. - merged all places where secrets are credited into one common function. - added the Doom64 COUNTSECRET actor flag. - fixed: AInventory::CreateCopy did not clear the COUNTITEM flag. - fixed: Dropping an item did not increase the item count but the dropped item could still have the COUNTITEM flag. Now this flag gets cleared when the item gets picked up so that dropped items don't count a second time. SVN r2826 (trunk) --- specs/udmf_zdoom.txt | 6 +++- src/actor.h | 7 ++-- src/d_dehacked.cpp | 6 +--- src/doomdata.h | 2 ++ src/g_heretic/a_dsparil.cpp | 2 +- src/g_hexen/a_heresiarch.cpp | 2 +- src/g_shared/a_pickups.cpp | 5 +++ src/g_shared/a_secrettrigger.cpp | 19 ++--------- src/gameconfigfile.cpp | 2 +- src/m_cheat.cpp | 6 +--- src/namedef.h | 1 + src/p_acs.cpp | 16 ++------- src/p_conversation.cpp | 6 +--- src/p_mobj.cpp | 56 ++++++++++++++++++++++++++----- src/p_spec.cpp | 39 +++++++++++++++++---- src/p_spec.h | 10 ++---- src/p_things.cpp | 23 ++----------- src/p_udmf.cpp | 5 +++ src/thingdef/thingdef_codeptr.cpp | 23 +++++++++---- src/thingdef/thingdef_data.cpp | 1 + 20 files changed, 137 insertions(+), 100 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index fe6897d9f..fef3fa996 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -183,6 +183,7 @@ Note: All fields default to false unless mentioned otherwise. // menu can display. conversation = // Assigns a conversation dialogue to this thing. // Parameter is the conversation ID, 0 meaning none. + countsecret = ; // Picking up this actor counts as a secret. } @@ -269,7 +270,7 @@ Changed node specifications to deprecate compression of node lump. Added 'playeruseback' line trigger flag. 1.11 07.08.2010 -Added 'soundsequnce' sector property. +Added 'soundsequence' sector property. 1.12 22.08.2010 Added 'conversation' thing property. @@ -277,6 +278,9 @@ Added 'conversation' thing property. 1.13 29.08.2010 Added 'hidden' sector property. +1.14 19.09.2010 +Added 'countsecret' actor property. + =============================================================================== EOF =============================================================================== diff --git a/src/actor.h b/src/actor.h index 2a8921b56..7de8a725e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -269,7 +269,7 @@ enum MF5_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on. MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. /* = 0x00000008, */ - /* = 0x00000010, */ + MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage MF5_CHASEGOAL = 0x00000080, // Walks to goal instead of target if a valid goal is set. @@ -289,7 +289,7 @@ enum MF5_NOINTERACTION = 0x00200000, // Thing is completely excluded from any gameplay related checks MF5_NOTIMEFREEZE = 0x00400000, // Actor is not affected by time freezer MF5_PUFFGETSOWNER = 0x00800000, // [BB] Sets the owner of the puff to the player who fired it - MF5_SPECIALFIREDAMAGE=0x01000000, // Special treatment of PhoenixFX1 turned into a flag to removr + MF5_SPECIALFIREDAMAGE=0x01000000, // Special treatment of PhoenixFX1 turned into a flag to remove // dependence of main engine code of specific actor types. MF5_SUMMONEDMONSTER = 0x02000000, // To mark the friendly Minotaur. Hopefully to be generalized later. MF5_NOVERTICALMELEERANGE=0x04000000,// Does not check vertical distance for melee range @@ -832,7 +832,7 @@ public: BYTE MinMissileChance;// [RH] If a random # is > than this, then missile attack. SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0) WORD BounceFlags; // which bouncing type? - WORD SpawnFlags; + DWORD SpawnFlags; // Increased to DWORD because of Doom 64 fixed_t meleerange; // specifies how far a melee attack reaches. fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore // but instead tries to come closer for a melee attack. @@ -937,6 +937,7 @@ public: virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); bool isFast(); void SetIdle(); + void ClearCounters(); FState *FindState (FName label) const { diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 97c8296a4..225f24cab 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2895,11 +2895,7 @@ bool ADehackedPickup::TryPickup (AActor *&toucher) if (RealPickup != NULL) { // The internally spawned item should never count towards statistics. - if (RealPickup->flags & MF_COUNTITEM) - { - RealPickup->flags &= ~MF_COUNTITEM; - level.total_items--; - } + RealPickup->ClearCounters(); if (!(flags & MF_DROPPED)) { RealPickup->flags &= ~MF_DROPPED; diff --git a/src/doomdata.h b/src/doomdata.h index 9c22b22a6..83345a671 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -380,6 +380,8 @@ enum EMapThingFlags MTF_STANDSTILL = 0x4000, MTF_STRIFESOMETHING = 0x8000, + MTF_SECRET = 0x080000, // Secret pickup + MTF_NOINFIGHTING = 0x100000, // BOOM and DOOM compatible versions of some of the above BTF_NOTSINGLE = 0x0010, // (TF_COOPERATIVE|TF_DEATHMATCH) diff --git a/src/g_heretic/a_dsparil.cpp b/src/g_heretic/a_dsparil.cpp index aa0bd46ed..0b25a94de 100644 --- a/src/g_heretic/a_dsparil.cpp +++ b/src/g_heretic/a_dsparil.cpp @@ -258,8 +258,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard) mo->z -= mo->GetDefault()->height/2; if (!P_TestMobjLocation (mo)) { // Didn't fit + mo->ClearCounters(); mo->Destroy (); - level.total_monsters--; } else { // [RH] Make the new wizards inherit D'Sparil's target diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index 2107f2722..ecce5d2a8 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -859,8 +859,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnBishop) { if (!P_TestMobjLocation(mo)) { + mo->ClearCounters(); mo->Destroy (); - level.total_monsters--; } else if (self->target != NULL) { // [RH] Make the new bishops inherit the Heriarch's target diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 30dcd482c..524daee77 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -924,6 +924,11 @@ void AInventory::Touch (AActor *toucher) level.found_items++; } + if (flags5 & MF5_COUNTSECRET) + { + P_GiveSecret(toucher, true, true); + } + //Added by MC: Check if item taken was the roam destination of any bot for (int i = 0; i < MAXPLAYERS; i++) { diff --git a/src/g_shared/a_secrettrigger.cpp b/src/g_shared/a_secrettrigger.cpp index d0996aab8..79f3bcd30 100644 --- a/src/g_shared/a_secrettrigger.cpp +++ b/src/g_shared/a_secrettrigger.cpp @@ -40,6 +40,8 @@ #include "d_player.h" #include "doomstat.h" #include "v_font.h" +#include "r_data.h" +#include "p_spec.h" EXTERN_CVAR(String, secretmessage) @@ -61,22 +63,7 @@ void ASecretTrigger::PostBeginPlay () void ASecretTrigger::Activate (AActor *activator) { - if (activator != NULL) - { - if (activator->CheckLocalView (consoleplayer)) - { - if (args[0] <= 1) - { - C_MidPrint (SmallFont, secretmessage); - } - if (args[0] == 0 || args[0] == 2) - { - S_Sound (activator, CHAN_AUTO, "misc/secret", 1, ATTN_NORM); - } - } - if (activator->player) activator->player->secretcount++; - } - level.found_secrets++; + P_GiveSecret(activator, args[0] <= 1, (args[0] == 0 || args[0] == 2)); Destroy (); } diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index acf2bbad1..64ddaa4b8 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -380,7 +380,7 @@ void FGameConfigFile::DoGameSetup (const char *gamename) ReadCVars (0); } - if (game != Doom && game != Strife && game != Chex) + if (game == Heretic || game == Hexen) { SetRavenDefaults (game == Hexen); } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 9da1b1ff5..95ddf7725 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -590,11 +590,7 @@ void GiveSpawner (player_t *player, const PClass *type, int amount) item->Amount = MIN (amount, item->MaxAmount); } } - if(item->flags & MF_COUNTITEM) // Given items shouldn't count against the map's total, - { // since they aren't added to the player's total. - level.total_items--; - item->flags &= ~MF_COUNTITEM; - } + item->ClearCounters(); if (!item->CallTryPickup (player->mo)) { item->Destroy (); diff --git a/src/namedef.h b/src/namedef.h index 9f7e5a87d..012d85afa 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -359,6 +359,7 @@ xx(Invisible) xx(Friend) xx(Strifeally) xx(Standing) +xx(Countsecret) xx(Blocking) xx(Blockmonsters) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index f7a52987b..e147648e5 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -434,11 +434,7 @@ static void DoGiveInv (AActor *actor, const PClass *info, int amount) AInventory *item = static_cast(Spawn (info, 0,0,0, NO_REPLACE)); // This shouldn't count for the item statistics! - if (item->flags & MF_COUNTITEM) - { - level.total_items--; - item->flags &= ~MF_COUNTITEM; - } + item->ClearCounters(); if (info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup))) { if (static_cast(item)->SaveAmount != 0) @@ -2286,15 +2282,7 @@ int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, i { // If this is a monster, subtract it from the total monster // count, because it already added to it during spawning. - if (actor->CountsAsKill()) - { - level.total_monsters--; - } - // Same, for items - if (actor->flags & MF_COUNTITEM) - { - level.total_items--; - } + actor->ClearCounters(); actor->Destroy (); actor = NULL; } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index a2c287a42..7283c4abd 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1264,11 +1264,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply { AInventory *item = static_cast(Spawn(reply->GiveType, 0, 0, 0, NO_REPLACE)); // Items given here should not count as items! - if (item->flags & MF_COUNTITEM) - { - level.total_items--; - item->flags &= ~MF_COUNTITEM; - } + item->ClearCounters(); if (item->GetClass()->TypeName == NAME_FlameThrower) { // The flame thrower gives less ammo when given in a dialog diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 4d6cdc765..f12127a75 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -258,9 +258,18 @@ void AActor::Serialize (FArchive &arc) << args[0] << args[1] << args[2] << args[3] << args[4] << goal << waterlevel - << MinMissileChance - << SpawnFlags - << Inventory + << MinMissileChance; + if (SaveVersion >= 2826) + { + arc << SpawnFlags; + } + else + { + WORD w; + arc << w; + SpawnFlags = w; + } + arc << Inventory << InventoryID << id << FloatBobPhase @@ -728,6 +737,7 @@ AInventory *AActor::DropInventory (AInventory *item) drop->vely = vely + 5 * finesine[an]; drop->velz = velz + FRACUNIT; drop->flags &= ~MF_NOGRAVITY; // Don't float + drop->ClearCounters(); // do not count for statistics again return drop; } @@ -2458,7 +2468,7 @@ void P_NightmareRespawn (AActor *mobj) if (!P_TestMobjLocation (mo)) { //[GrafZahl] MF_COUNTKILL still needs to be checked here. - if (mo->CountsAsKill()) level.total_monsters--; + mo->ClearCounters(); mo->Destroy (); return; // no respawn } @@ -3626,6 +3636,11 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t { level.total_items++; } + // And for secrets + if (actor->flags5 & MF5_COUNTSECRET) + { + level.total_secrets++; + } if (screen != NULL) { screen->StateChanged(actor); @@ -3695,6 +3710,11 @@ void AActor::HandleSpawnFlags () { RenderStyle = STYLE_None; } + if (SpawnFlags & MTF_SECRET) + { + //Printf("Secret %s in sector %i!\n", GetTag(), Sector->sectornum); + flags5 |= MF5_COUNTSECRET; + } } void AActor::BeginPlay () @@ -4969,11 +4989,7 @@ bool P_CheckMissileSpawn (AActor* th) if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) { // If this is a monster spawned by A_CustomMissile subtract it from the counter. - if (th->CountsAsKill()) - { - th->flags&=~MF_COUNTKILL; - level.total_monsters--; - } + th->ClearCounters(); // [RH] Don't explode missiles that spawn on top of horizon lines if (th->BlockingLine != NULL && th->BlockingLine->special == Line_Horizon) { @@ -5602,6 +5618,28 @@ const char *AActor::GetTag(const char *def) const } +void AActor::ClearCounters() +{ + if (CountsAsKill()) + { + level.total_monsters--; + flags &= ~MF_COUNTKILL; + } + // Same, for items + if (flags & MF_COUNTITEM) + { + level.total_items--; + flags &= ~MF_COUNTITEM; + } + // And finally for secrets + if (flags5 & MF5_COUNTSECRET) + { + level.total_secrets--; + flags5 &= ~MF5_COUNTSECRET; + } +} + + //---------------------------------------------------------------------------- // // DropItem handling diff --git a/src/p_spec.cpp b/src/p_spec.cpp index e37df68b1..2e3f1b6e2 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -256,7 +256,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) // end of changed code if (developer && buttonSuccess) { - Printf ("Line special %d activated\n", special); + Printf ("Line special %d activated on line %i\n", special, line - lines); } return true; } @@ -561,15 +561,33 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) if (sector->special & SECRET_MASK) { - player->secretcount++; - level.found_secrets++; sector->special &= ~SECRET_MASK; - if (player->mo->CheckLocalView (consoleplayer)) + P_GiveSecret(player->mo, true, true); + } +} + + +//============================================================================ +// +// P_GiveSecret +// +//============================================================================ + +void P_GiveSecret(AActor *actor, bool printmessage, bool playsound) +{ + if (actor != NULL) + { + if (actor->player != NULL) { - C_MidPrint (SmallFont, secretmessage); - S_Sound (CHAN_AUTO, "misc/secret", 1, ATTN_NORM); + actor->player->secretcount++; + } + if (actor->CheckLocalView (consoleplayer)) + { + if (printmessage) C_MidPrint (SmallFont, secretmessage); + if (playsound) S_Sound (CHAN_AUTO, "misc/secret", 1, ATTN_NORM); } } + level.found_secrets++; } //============================================================================ @@ -1923,6 +1941,15 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, m_Affectee = affectee; } +int DPusher::CheckForSectorMatch (EPusher type, int tag) +{ + if (m_Type == type && sectors[m_Affectee].tag == tag) + return m_Affectee; + else + return -1; +} + + ///////////////////////////// // // T_Pusher looks for all objects that are inside the radius of diff --git a/src/p_spec.h b/src/p_spec.h index ca3694c09..0171cf796 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -122,13 +122,7 @@ public: DPusher (); DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, int affectee); void Serialize (FArchive &arc); - int CheckForSectorMatch (EPusher type, int tag) - { - if (m_Type == type && sectors[m_Affectee].tag == tag) - return m_Affectee; - else - return -1; - } + int CheckForSectorMatch (EPusher type, int tag); void ChangeValues (int magnitude, int angle) { angle_t ang = ((angle_t)(angle<<24)) >> ANGLETOFINESHIFT; @@ -187,6 +181,8 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_SetSectorFriction (int tag, int amount, bool alterFlag); +void P_GiveSecret(AActor *actor, bool printmessage, bool playsound); + // // getSide() // Will return a side_t* diff --git a/src/p_things.cpp b/src/p_things.cpp index 6622ac0a7..aa48fe18b 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -105,15 +105,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, { // If this is a monster, subtract it from the total monster // count, because it already added to it during spawning. - if (mobj->CountsAsKill()) - { - level.total_monsters--; - } - // Same, for items - if (mobj->flags & MF_COUNTITEM) - { - level.total_items--; - } + mobj->ClearCounters(); mobj->Destroy (); } } @@ -352,15 +344,7 @@ nolead: mobj->angle = R_PointToAngle2 (mobj->x, mobj->y, targ->x, targ->y); { // If this is a monster, subtract it from the total monster // count, because it already added to it during spawning. - if (mobj->CountsAsKill()) - { - level.total_monsters--; - } - // Same, for items - if (mobj->flags & MF_COUNTITEM) - { - level.total_items--; - } + mobj->ClearCounters(); mobj->Destroy (); } else @@ -418,8 +402,7 @@ void P_RemoveThing(AActor * actor) if (actor->player == NULL || actor != actor->player->mo) { // be friendly to the level statistics. ;) - if (actor->CountsAsKill() && actor->health > 0) level.total_monsters--; - if (actor->flags&MF_COUNTITEM) level.total_items--; + actor->ClearCounters(); actor->Destroy (); } } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 5f2fca941..2dd3c770e 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -599,6 +599,11 @@ public: Flag(th->flags, MTF_STANDSTILL, key); break; + case NAME_Countsecret: + CHECK_N(Zd | Zdt | Va) + Flag(th->flags, MTF_SECRET, key); + break; + default: if (!strnicmp("user_", key.GetChars(), 5)) { diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index b304e638f..1ac84d38a 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1402,11 +1402,7 @@ static void DoGiveInventory(AActor * receiver, DECLARE_PARAMINFO) item->Amount = amount; } item->flags |= MF_DROPPED; - if (item->flags & MF_COUNTITEM) - { - item->flags&=~MF_COUNTITEM; - level.total_items--; - } + item->ClearCounters(); if (!item->CallTryPickup (receiver)) { item->Destroy (); @@ -1541,7 +1537,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) if (!(flags&SIXF_NOCHECKPOSITION) && !P_TestMobjLocation(mo)) { // The monster is blocked so don't spawn it at all! - if (mo->CountsAsKill()) level.total_monsters--; + mo->ClearCounters(); mo->Destroy(); return false; } @@ -2925,9 +2921,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag) { bool kill_before, kill_after; INTBOOL item_before, item_after; + INTBOOL secret_before, secret_after; kill_before = self->CountsAsKill(); item_before = self->flags & MF_COUNTITEM; + secret_before = self->flags5 & MF5_COUNTSECRET; if (fd->structoffset == -1) { @@ -2953,6 +2951,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag) } kill_after = self->CountsAsKill(); item_after = self->flags & MF_COUNTITEM; + secret_after = self->flags5 & MF5_COUNTSECRET; // Was this monster previously worth a kill but no longer is? // Or vice versa? if (kill_before != kill_after) @@ -2978,6 +2977,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag) level.total_items--; } } + // and secretd + if (secret_before != secret_after) + { + if (secret_after) + { // It counts as an secret now. + level.total_secrets++; + } + else + { // It no longer counts as an secret + level.total_secrets--; + } + } } else { diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index b08e48719..05e5bc3a7 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -185,6 +185,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF5, FASTER, AActor, flags5), DEFINE_FLAG(MF5, FASTMELEE, AActor, flags5), DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5), + DEFINE_FLAG(MF5, COUNTSECRET, AActor, flags5), DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5), DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5), DEFINE_FLAG(MF5, OLDRADIUSDMG, AActor, flags5),