- fixed some issues with the bodyque and moved this variable into FLevelLocals

* it was never saved in savegames, leaving the state of dead bodies undefined
* it shouldn't be subjected to pointer substitution because all it contains is old dead bodies, not live ones.
This commit is contained in:
Christoph Oelckers 2018-11-19 18:13:23 +01:00
parent 02de10f657
commit ad04001135
12 changed files with 47 additions and 45 deletions

View file

@ -38,7 +38,6 @@
#include "actor.h" #include "actor.h"
#include "doomstat.h" // Ideally, DObjects can be used independant of Doom. #include "doomstat.h" // Ideally, DObjects can be used independant of Doom.
#include "d_player.h" // See p_user.cpp to find out why this doesn't work. #include "d_player.h" // See p_user.cpp to find out why this doesn't work.
#include "g_game.h" // Needed for bodyque.
#include "c_dispatch.h" #include "c_dispatch.h"
#include "dsectoreffect.h" #include "dsectoreffect.h"
#include "serializer.h" #include "serializer.h"
@ -500,16 +499,6 @@ size_t DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
last = probe; last = probe;
} }
// Go through the bodyque.
for (i = 0; i < BODYQUESIZE; ++i)
{
if (bodyque[i] == old)
{
bodyque[i] = notOld;
changed++;
}
}
// Go through players. // Go through players.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {

View file

@ -325,15 +325,8 @@ static void MarkRoot()
FCanvasTextureInfo::Mark(); FCanvasTextureInfo::Mark();
Mark(E_FirstEventHandler); Mark(E_FirstEventHandler);
Mark(E_LastEventHandler); Mark(E_LastEventHandler);
for (auto &s : level.sectorPortals) level.Mark();
{
Mark(s.mSkybox);
}
// Mark dead bodies.
for (i = 0; i < BODYQUESIZE; ++i)
{
Mark(bodyque[i]);
}
// Mark players. // Mark players.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {

View file

@ -224,7 +224,10 @@ template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
return static_cast<T>(static_cast<U>(o)); return static_cast<T>(static_cast<U>(o));
} }
template<class T> inline void GC::Mark(TObjPtr<T> &obj) namespace GC
{ {
GC::Mark(&obj.o); template<class T> inline void Mark(TObjPtr<T> &obj)
{
GC::Mark(&obj.o);
}
} }

View file

@ -197,8 +197,6 @@ EXTERN_CVAR (Float, mouse_sensitivity)
// debug flag to cancel adaptiveness // debug flag to cancel adaptiveness
extern bool singletics; extern bool singletics;
extern int bodyqueslot;
// Needed to store the number of the dummy sky flat. // Needed to store the number of the dummy sky flat.

View file

@ -70,6 +70,7 @@
#include "p_spec.h" #include "p_spec.h"
#include "serializer.h" #include "serializer.h"
#include "vm.h" #include "vm.h"
#include "dobjgc.h"
#include "g_hub.h" #include "g_hub.h"
#include "g_levellocals.h" #include "g_levellocals.h"
@ -211,9 +212,6 @@ FString savedescription;
// [RH] Name of screenshot file to generate (usually NULL) // [RH] Name of screenshot file to generate (usually NULL)
FString shotfile; FString shotfile;
AActor* bodyque[BODYQUESIZE];
int bodyqueslot;
FString savename; FString savename;
FString BackupSaveName; FString BackupSaveName;
@ -1676,13 +1674,14 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart)
static void G_QueueBody (AActor *body) static void G_QueueBody (AActor *body)
{ {
// flush an old corpse if needed // flush an old corpse if needed
int modslot = bodyqueslot%BODYQUESIZE; int modslot = level.bodyqueslot%level.BODYQUESIZE;
level.bodyqueslot = modslot + 1;
if (bodyqueslot >= BODYQUESIZE && bodyque[modslot] != NULL) if (level.bodyqueslot >= level.BODYQUESIZE && level.bodyque[modslot] != NULL)
{ {
bodyque[modslot]->Destroy (); level.bodyque[modslot]->Destroy ();
} }
bodyque[modslot] = body; level.bodyque[modslot] = body;
// Copy the player's translation, so that if they change their color later, only // Copy the player's translation, so that if they change their color later, only
// their current body will change and not all their old corpses. // their current body will change and not all their old corpses.
@ -1706,7 +1705,6 @@ static void G_QueueBody (AActor *body)
body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y; body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y;
} }
bodyqueslot++;
} }
// //

View file

@ -30,6 +30,7 @@
struct event_t; struct event_t;
#include "dobjgc.h"
// //
// GAME // GAME
@ -94,10 +95,6 @@ void G_AddViewPitch (int look, bool mouse = false);
// Adds to consoleplayer's viewangle if allowed // Adds to consoleplayer's viewangle if allowed
void G_AddViewAngle (int yaw, bool mouse = false); void G_AddViewAngle (int yaw, bool mouse = false);
#define BODYQUESIZE 32
class AActor;
extern AActor *bodyque[BODYQUESIZE];
extern int bodyqueslot;
class AInventory; class AInventory;
extern const AInventory *SendItemUse, *SendItemDrop; extern const AInventory *SendItemUse, *SendItemDrop;
extern int SendItemDropAmount; extern int SendItemDropAmount;

View file

@ -1956,6 +1956,24 @@ void FLevelLocals::Tick ()
// //
//========================================================================== //==========================================================================
void FLevelLocals::Mark()
{
for (auto &s : sectorPortals)
{
GC::Mark(s.mSkybox);
}
// Mark dead bodies.
for (auto &p : bodyque)
{
GC::Mark(p);
}
}
//==========================================================================
//
//
//==========================================================================
void FLevelLocals::AddScroller (int secnum) void FLevelLocals::AddScroller (int secnum)
{ {
if (secnum < 0) if (secnum < 0)

View file

@ -47,6 +47,7 @@
struct FLevelLocals struct FLevelLocals
{ {
void Tick (); void Tick ();
void Mark();
void AddScroller (int secnum); void AddScroller (int secnum);
void SetInterMusic(const char *nextmap); void SetInterMusic(const char *nextmap);
void SetMusicVolume(float v); void SetMusicVolume(float v);
@ -85,6 +86,11 @@ struct FLevelLocals
TArray<node_t> gamenodes; TArray<node_t> gamenodes;
node_t *headgamenode; node_t *headgamenode;
TArray<uint8_t> rejectmatrix; TArray<uint8_t> rejectmatrix;
static const int BODYQUESIZE = 32;
TObjPtr<AActor*> bodyque[BODYQUESIZE];
int bodyqueslot;
TArray<FSectorPortal> sectorPortals; TArray<FSectorPortal> sectorPortals;
TArray<FLinePortal> linePortals; TArray<FLinePortal> linePortals;

View file

@ -5772,10 +5772,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
} }
DObject::StaticPointerSubstitution (oldactor, p->mo); DObject::StaticPointerSubstitution (oldactor, p->mo);
// PointerSubstitution() will also affect the bodyque, so undo that now.
for (int ii=0; ii < BODYQUESIZE; ++ii)
if (bodyque[ii] == p->mo)
bodyque[ii] = oldactor;
E_PlayerRespawned(int(p - players)); E_PlayerRespawned(int(p - players));
FBehavior::StaticStartTypedScripts (SCRIPT_Respawn, p->mo, true); FBehavior::StaticStartTypedScripts (SCRIPT_Respawn, p->mo, true);
} }

View file

@ -971,7 +971,9 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
("level.skytexture2", level.skytexture2) ("level.skytexture2", level.skytexture2)
("level.fogdensity", level.fogdensity) ("level.fogdensity", level.fogdensity)
("level.outsidefogdensity", level.outsidefogdensity) ("level.outsidefogdensity", level.outsidefogdensity)
("level.skyfog", level.skyfog); ("level.skyfog", level.skyfog)
("level.bodyqueslot", level.bodyqueslot)
.Array("level.bodyque", level.bodyque, level.BODYQUESIZE);
// Hub transitions must keep the current total time // Hub transitions must keep the current total time
if (!hubload) if (!hubload)

View file

@ -4048,12 +4048,12 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
FixHoles(); FixHoles();
} }
bodyqueslot = 0; level.bodyqueslot = 0;
// phares 8/10/98: Clear body queue so the corpses from previous games are // phares 8/10/98: Clear body queue so the corpses from previous games are
// not assumed to be from this one. // not assumed to be from this one.
for (i = 0; i < BODYQUESIZE; i++) for(auto & p : level.bodyque)
bodyque[i] = NULL; p = nullptr;
CreateSections(level.sections); CreateSections(level.sections);

View file

@ -49,6 +49,7 @@
#include "vm.h" #include "vm.h"
#include "v_text.h" #include "v_text.h"
#include "m_crc32.h" #include "m_crc32.h"
#include "g_levellocals.h"
#include "gi.h" #include "gi.h"
@ -926,7 +927,7 @@ void R_InitTranslationTables ()
// Each player corpse has its own translation so they won't change // Each player corpse has its own translation so they won't change
// color if the player who created them changes theirs. // color if the player who created them changes theirs.
for (i = 0; i < BODYQUESIZE; ++i) for (i = 0; i < level.BODYQUESIZE; ++i)
{ {
PushIdentityTable(TRANSLATION_PlayerCorpses); PushIdentityTable(TRANSLATION_PlayerCorpses);
} }