- Blood: separated actor spawning from map loading.

This commit is contained in:
Christoph Oelckers 2021-12-03 22:19:28 +01:00
parent e543c70439
commit ec888c097c
4 changed files with 91 additions and 86 deletions

View file

@ -79,6 +79,71 @@ void EndLevel(void)
seqKillAll();
}
TArray<DBloodActor*> SpawnActors(SpawnSpriteDef& sprites)
{
TArray<DBloodActor*> spawns(sprites.sprites.Size(), true);
initspritelists();
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
{
RemoveSpriteStat(i);
auto actor = &bloodActors[i];
spawns[i] = actor;
actor->Clear();
actor->s() = sprites.sprites[i];
if (sprites.sprites[i].extra > 0)
{
actor->addX();
actor->x() = sprites.xspr[i];
}
InsertSpriteSect(i, actor->s().sectnum);
InsertSpriteStat(i, actor->s().statnum);
}
Numsprites = spawns.Size();
return spawns;
}
void PropagateMarkerReferences(void)
{
BloodStatIterator it(kStatMarker);
while (auto actor = it.Next())
{
switch (actor->s().type)
{
case kMarkerOff:
case kMarkerAxis:
case kMarkerWarpDest:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker0 = actor;
continue;
}
}
}
break;
case kMarkerOn:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker1 = actor;
continue;
}
}
}
break;
}
DeleteSprite(actor);
}
}
void StartLevel(MapRecord* level, bool newgame)
{
if (!level) return;
@ -111,7 +176,8 @@ void StartLevel(MapRecord* level, bool newgame)
}
}
//drawLoadingScreen();
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsector, nullptr);
SpawnSpriteDef sprites;
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsector, nullptr, sprites);
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
STAT_NewLevel(currentLevel->fileName);
wsrand(dbReadMapCRC(currentLevel->LabelName()));
@ -119,23 +185,13 @@ void StartLevel(MapRecord* level, bool newgame)
gSecretMgr.Clear();
automapping = 1;
// Here is where later the actors must be spawned.
// get a sorted list of all actors as we need to run some init code in spawn order. (iterating bloodActors would actually do, but that won't last forever)
TArray<DBloodActor*> actorlist;
BloodSpriteIterator sit;
while (auto act = sit.Next())
{
actorlist.Push(act);
}
std::sort(actorlist.begin(), actorlist.end(), [](DBloodActor* a, DBloodActor* b) { return a->GetIndex() < b->GetIndex(); });
auto actorlist = SpawnActors(sprites);
PropagateMarkerReferences();
int modernTypesErased = 0;
for(unsigned i = 0; i < actorlist.Size(); i++)
for (auto actor : actorlist)
{
auto actor = actorlist[i];
spritetype* pSprite = &actor->s();
if (actor->exists() && actor->hasX())
{

View file

@ -171,7 +171,6 @@ extern HitInfo gHitInfo;
using BloodStatIterator = TStatIterator<DBloodActor>;
using BloodSectIterator = TSectIterator<DBloodActor>;
using BloodSpriteIterator = TSpriteIterator<DBloodActor>;
using BloodLinearSpriteIterator = TLinearSpriteIterator<DBloodActor>;
inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
{

View file

@ -244,47 +244,6 @@ void dbInit(void)
}
}
void PropagateMarkerReferences(void)
{
BloodStatIterator it(kStatMarker);
while (auto actor = it.Next())
{
switch (actor->s().type)
{
case kMarkerOff:
case kMarkerAxis:
case kMarkerWarpDest:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker0 = actor;
continue;
}
}
}
break;
case kMarkerOn:
{
int nOwner = actor->s().owner;
if (nOwner >= 0 && nOwner < numsectors)
{
if (sector[nOwner].hasX())
{
sector[nOwner].xs().marker1 = actor;
continue;
}
}
}
break;
}
DeleteSprite(actor);
}
}
bool drawtile2048, encrypted;
MAPHEADER2 byte_19AE44;
@ -384,8 +343,7 @@ struct walltypedisk
#pragma pack(pop)
void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC)
void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, SpawnSpriteDef& sprites)
{
int16_t tpskyoff[256];
ClearAutomap();
@ -728,21 +686,19 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
}
}
initspritelists();
leveltimer = mapHeader.numsprites;
sprites.sprites.Resize(mapHeader.numsprites);
sprites.xspr.Resize(mapHeader.numsprites);
for (int i = 0; i < mapHeader.numsprites; i++)
{
RemoveSpriteStat(i);
spritetypedisk load;
auto actor = &bloodActors[i];
actor->Clear();
spritetype* pSprite = &actor->s();
fr.Read(&load, sizeof(spritetypedisk)); // load into an intermediate buffer so that spritetype is no longer bound by file formats.
if (encrypted) // What were these people thinking? :(
{
dbCrypt((char*)&load, sizeof(spritetypedisk), (gMapRev * sizeof(spritetypedisk)) | 0x7474614d);
}
auto pSprite = &sprites.sprites[i];
pSprite->clear();
pSprite->x = LittleLong(load.x);
pSprite->y = LittleLong(load.y);
pSprite->z = LittleLong(load.z);
@ -770,14 +726,11 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
pSprite->time = i;
ValidateSprite(*pSprite);
InsertSpriteSect(i, pSprite->sectnum);
InsertSpriteStat(i, pSprite->statnum);
Numsprites++;
if (pSprite->extra > 0)
{
char pBuffer[nXSpriteSize];
actor->addX();
XSPRITE* pXSprite = &actor->x();
XSPRITE* pXSprite = &sprites.xspr[i];
*pXSprite = {};
int nCount;
if (!encrypted)
{
@ -863,10 +816,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
gModernMap = true;
#endif
}
if ((sprite[i].cstat & 0x30) == 0x30)
{
sprite[i].cstat &= ~0x30;
}
}
unsigned int nCRC = fr.ReadUInt32();
@ -874,7 +823,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
auto buffer = fr.Read();
uint8_t md4[16];
md4once(buffer.Data(), buffer.Size(), md4);
G_LoadMapHack(mapname, md4, sprite, mapHeader.numsprites);
G_LoadMapHack(mapname, md4, sprites.sprites.Data(), mapHeader.numsprites);
if (CalcCRC32(buffer.Data(), buffer.Size() - 4) != nCRC)
{
@ -882,7 +831,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
}
if (pCRC)
*pCRC = nCRC;
PropagateMarkerReferences();
if (encrypted)
{
if (gMattId == 0x7474614d || gMattId == 0x4d617474)
@ -908,9 +856,9 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
switch (header.version & 0xff)
{
case 0:
for (int i = 0; i < numsectors; i++)
for (auto& sect : sectors())
{
sectortype* pSector = &sector[i];
sectortype* pSector = &sect;
if (pSector->hasX())
{
XSECTOR* pXSector = &pSector->xs();
@ -932,9 +880,9 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
}
[[fallthrough]];
case 1:
for (int i = 0; i < numsectors; i++)
for (auto& sect : sectors())
{
sectortype* pSector = &sector[i];
sectortype* pSector = &sect;
if (pSector->hasX())
{
XSECTOR* pXSector = &pSector->xs();
@ -943,9 +891,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
}
[[fallthrough]];
case 2:
for (int i = 0; i < kMaxSprites; i++)
{
}
break;
}
@ -964,8 +909,9 @@ END_BLD_NS
// only used by the backup loader.
void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang)
{
Blood::SpawnSpriteDef sprites;
sectortype* sp;
Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, NULL);
Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, nullptr, sprites);
Blood::dbInit(); // clean up immediately.
}

View file

@ -74,7 +74,11 @@ struct MAPHEADER2 {
#pragma pack(pop)
extern unsigned int gStatCount[kMaxStatus + 1];;
struct SpawnSpriteDef
{
TArray<spritetype> sprites;
TArray<XSPRITE> xspr;
};
extern bool drawtile2048, encrypted;
extern MAPHEADER2 byte_19AE44;
@ -125,7 +129,7 @@ int ChangeSpriteStat(int nSprite, int nStatus);
void dbInit(void);
void PropagateMarkerReferences(void);
unsigned int dbReadMapCRC(const char *pPath);
void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC);
void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sectortype** pSector, unsigned int* pCRC, SpawnSpriteDef& sprites);
END_BLD_NS