mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 00:42:08 +00:00
- actor lists refactored.
No more shorts, no more static arrays. This was one of the biggest blockers for unlimiting the engine.
This commit is contained in:
parent
87ac9bee44
commit
f855b1020f
37 changed files with 641 additions and 730 deletions
|
@ -1013,6 +1013,7 @@ set (PCH_SOURCES
|
|||
build/src/mdsprite.cpp
|
||||
build/src/polymost.cpp
|
||||
|
||||
core/actorlist.cpp
|
||||
core/automap.cpp
|
||||
core/cheats.cpp
|
||||
core/cheathandler.cpp
|
||||
|
|
|
@ -238,10 +238,6 @@ extern int16_t pskybits_override;
|
|||
// (or -1 if freelist is empty):
|
||||
EXTERN int16_t tailspritefree;
|
||||
|
||||
EXTERN int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
|
||||
EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
|
||||
EXTERN int16_t nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES];
|
||||
|
||||
EXTERN uint8_t gotpic[(MAXTILES+7)>>3];
|
||||
extern FixedBitArray<MAXSECTORS> gotsector;
|
||||
|
||||
|
@ -321,7 +317,6 @@ typedef struct artheader_t {
|
|||
|
||||
int32_t engineInit(void);
|
||||
void engineUnInit(void);
|
||||
void initspritelists(void);
|
||||
|
||||
struct SpawnSpriteDef
|
||||
{
|
||||
|
@ -484,19 +479,7 @@ int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ,
|
|||
int32_t lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY,
|
||||
int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ);
|
||||
|
||||
int32_t insertsprite(int16_t sectnum, int16_t statnum, bool frominit = false);
|
||||
int32_t deletesprite(int16_t spritenum);
|
||||
|
||||
int32_t changespritesect(int16_t spritenum, int16_t newsectnum);
|
||||
int32_t changespritestat(int16_t spritenum, int16_t newstatnum);
|
||||
|
||||
int32_t setspritez(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
|
||||
|
||||
int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyofs);
|
||||
inline int32_t spriteheightofs(int16_t i, int32_t *height, int32_t alsotileyofs)
|
||||
{
|
||||
return spriteheightofsptr((uspriteptr_t)&sprite[i], height, alsotileyofs);
|
||||
}
|
||||
|
||||
int videoCaptureScreen();
|
||||
|
||||
|
@ -593,19 +576,11 @@ static inline int64_t compat_maybe_truncate_to_int32(int64_t val)
|
|||
return enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? (int32_t)val : val;
|
||||
}
|
||||
|
||||
static inline int32_t setspritez_old(int16_t spritenum, int32_t x, int32_t y, int32_t z)
|
||||
{
|
||||
const vec3_t vector = { x, y, z };
|
||||
return setspritez(spritenum, &vector);
|
||||
}
|
||||
|
||||
extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
|
||||
int32_t vx_, int32_t vy_, int32_t vz,
|
||||
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
|
||||
int32_t *intx, int32_t *inty, int32_t *intz);
|
||||
|
||||
extern void(*initspritelists_replace)(void);
|
||||
extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum);
|
||||
|
||||
|
||||
void updateModelInterpolation();
|
||||
|
@ -704,7 +679,4 @@ inline walltype* sectortype::lastWall() const
|
|||
}
|
||||
|
||||
|
||||
|
||||
#include "iterators.h"
|
||||
|
||||
#endif // build_h_
|
||||
|
|
|
@ -59,8 +59,12 @@ END_BLD_NS
|
|||
//40 bytes
|
||||
class DCoreActor;
|
||||
struct walltype;
|
||||
|
||||
|
||||
struct sectortype
|
||||
{
|
||||
DCoreActor* firstEntry, * lastEntry;
|
||||
|
||||
int16_t wallptr, wallnum;
|
||||
int32_t ceilingz, floorz;
|
||||
uint16_t ceilingstat, floorstat;
|
||||
|
|
|
@ -223,195 +223,6 @@ static int32_t engineLoadTables(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////// SPRITE LIST MANIPULATION FUNCTIONS //////////
|
||||
|
||||
///// sector lists of sprites /////
|
||||
|
||||
// insert sprite at the head of sector list, change sectnum
|
||||
static void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum)
|
||||
{
|
||||
int16_t const ohead = headspritesect[sectnum];
|
||||
|
||||
prevspritesect[spritenum] = -1;
|
||||
nextspritesect[spritenum] = ohead;
|
||||
if (ohead >= 0)
|
||||
prevspritesect[ohead] = spritenum;
|
||||
headspritesect[sectnum] = spritenum;
|
||||
|
||||
sprite[spritenum].sectnum = sectnum;
|
||||
}
|
||||
|
||||
// remove sprite 'deleteme' from its sector list
|
||||
static void do_deletespritesect(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].sectnum;
|
||||
int32_t const prev = prevspritesect[deleteme];
|
||||
int32_t const next = nextspritesect[deleteme];
|
||||
|
||||
if (headspritesect[sectnum] == deleteme)
|
||||
headspritesect[sectnum] = next;
|
||||
if (prev >= 0)
|
||||
nextspritesect[prev] = next;
|
||||
if (next >= 0)
|
||||
prevspritesect[next] = prev;
|
||||
}
|
||||
|
||||
///// now, status lists /////
|
||||
|
||||
// insert sprite at head of status list, change .statnum
|
||||
static void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum)
|
||||
{
|
||||
int16_t const ohead = headspritestat[statnum];
|
||||
|
||||
prevspritestat[spritenum] = -1;
|
||||
nextspritestat[spritenum] = ohead;
|
||||
if (ohead >= 0)
|
||||
prevspritestat[ohead] = spritenum;
|
||||
headspritestat[statnum] = spritenum;
|
||||
|
||||
sprite[spritenum].statnum = statnum;
|
||||
}
|
||||
|
||||
// insertspritestat (internal)
|
||||
static int32_t insertspritestat(int16_t statnum)
|
||||
{
|
||||
if ((statnum >= MAXSTATUS) || (headspritestat[MAXSTATUS] == -1))
|
||||
return -1; //list full
|
||||
|
||||
// remove one sprite from the statnum-freelist
|
||||
int16_t const blanktouse = headspritestat[MAXSTATUS];
|
||||
headspritestat[MAXSTATUS] = nextspritestat[blanktouse];
|
||||
|
||||
// make back-link of the new freelist head point to nil
|
||||
if (headspritestat[MAXSTATUS] >= 0)
|
||||
prevspritestat[headspritestat[MAXSTATUS]] = -1;
|
||||
else if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
tailspritefree = -1;
|
||||
|
||||
do_insertsprite_at_headofstat(blanktouse, statnum);
|
||||
|
||||
return blanktouse;
|
||||
}
|
||||
|
||||
// remove sprite 'deleteme' from its status list
|
||||
static void do_deletespritestat(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].statnum;
|
||||
int32_t const prev = prevspritestat[deleteme];
|
||||
int32_t const next = nextspritestat[deleteme];
|
||||
|
||||
if (headspritestat[sectnum] == deleteme)
|
||||
headspritestat[sectnum] = next;
|
||||
if (prev >= 0)
|
||||
nextspritestat[prev] = next;
|
||||
if (next >= 0)
|
||||
prevspritestat[next] = prev;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// insertsprite
|
||||
//
|
||||
int32_t insertsprite(int16_t sectnum, int16_t statnum, bool frominit)
|
||||
{
|
||||
// TODO: guard against bad sectnum?
|
||||
int32_t const newspritenum = insertspritestat(statnum);
|
||||
|
||||
// Build's default init of sprites is insantity².
|
||||
if (newspritenum >= 0)
|
||||
{
|
||||
// Make sure it's clear.
|
||||
if (!frominit) sprite[newspritenum].clear();
|
||||
|
||||
assert(validSectorIndex(sectnum));
|
||||
|
||||
do_insertsprite_at_headofsect(newspritenum, sectnum);
|
||||
Numsprites++;
|
||||
}
|
||||
|
||||
sprite[newspritenum].time = leveltimer++;
|
||||
return newspritenum;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// deletesprite
|
||||
//
|
||||
int32_t deletesprite(int16_t spritenum)
|
||||
{
|
||||
assert((sprite[spritenum].statnum == MAXSTATUS)
|
||||
== (sprite[spritenum].sectnum == MAXSECTORS));
|
||||
|
||||
if (sprite[spritenum].statnum == MAXSTATUS)
|
||||
return -1; // already not in the world
|
||||
|
||||
do_deletespritestat(spritenum);
|
||||
do_deletespritesect(spritenum);
|
||||
|
||||
// (dummy) insert at tail of sector freelist, compat
|
||||
// for code that checks sectnum==MAXSECTOR
|
||||
sprite[spritenum].sectnum = MAXSECTORS;
|
||||
|
||||
// insert at tail of status freelist
|
||||
if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
|
||||
do_insertsprite_at_headofstat(spritenum, MAXSTATUS);
|
||||
else
|
||||
{
|
||||
prevspritestat[spritenum] = tailspritefree;
|
||||
nextspritestat[spritenum] = -1;
|
||||
if (tailspritefree >= 0)
|
||||
nextspritestat[tailspritefree] = spritenum;
|
||||
else
|
||||
headspritestat[MAXSTATUS] = spritenum;
|
||||
sprite[spritenum].statnum = MAXSTATUS;
|
||||
|
||||
tailspritefree = spritenum;
|
||||
}
|
||||
Numsprites--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// changespritesect
|
||||
//
|
||||
int32_t (*changespritesect_replace)(int16_t spritenum, int16_t newsectnum) = NULL;
|
||||
int32_t changespritesect(int16_t spritenum, int16_t newsectnum)
|
||||
{
|
||||
if (changespritesect_replace)
|
||||
return changespritesect_replace(spritenum, newsectnum);
|
||||
// XXX: NOTE: MAXSECTORS is allowed
|
||||
if ((newsectnum < 0 || newsectnum > MAXSECTORS) || (sprite[spritenum].sectnum == MAXSECTORS))
|
||||
return -1;
|
||||
|
||||
if (sprite[spritenum].sectnum == newsectnum)
|
||||
return 0;
|
||||
|
||||
do_deletespritesect(spritenum);
|
||||
do_insertsprite_at_headofsect(spritenum, newsectnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// changespritestat
|
||||
//
|
||||
int32_t changespritestat(int16_t spritenum, int16_t newstatnum)
|
||||
{
|
||||
// XXX: NOTE: MAXSTATUS is allowed
|
||||
if ((newstatnum < 0 || newstatnum > MAXSTATUS) || (sprite[spritenum].statnum == MAXSTATUS))
|
||||
return -1; // can't set the statnum of a sprite not in the world
|
||||
|
||||
if (sprite[spritenum].statnum == newstatnum)
|
||||
return 0; // sprite already has desired statnum
|
||||
|
||||
do_deletespritestat(spritenum);
|
||||
do_insertsprite_at_headofstat(spritenum, newstatnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// lintersect (internal)
|
||||
//
|
||||
|
@ -629,60 +440,6 @@ int32_t engineInit(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// initspritelists
|
||||
//
|
||||
void (*initspritelists_replace)(void) = NULL;
|
||||
void initspritelists(void)
|
||||
{
|
||||
leveltimer = 0;
|
||||
if (initspritelists_replace)
|
||||
{
|
||||
initspritelists_replace();
|
||||
return;
|
||||
}
|
||||
int32_t i;
|
||||
|
||||
// initial list state for statnum lists:
|
||||
//
|
||||
// statnum 0: nil
|
||||
// statnum 1: nil
|
||||
// . . .
|
||||
// statnum MAXSTATUS-1: nil
|
||||
// "statnum MAXSTATUS": nil <- 0 <-> 1 <-> 2 <-> ... <-> MAXSPRITES-1 -> nil
|
||||
//
|
||||
// That is, the dummy MAXSTATUS statnum has all sprites.
|
||||
|
||||
for (i=0; i<MAXSECTORS; i++) //Init doubly-linked sprite sector lists
|
||||
headspritesect[i] = -1;
|
||||
headspritesect[MAXSECTORS] = 0;
|
||||
|
||||
for (i=0; i<MAXSPRITES; i++)
|
||||
{
|
||||
prevspritesect[i] = i-1;
|
||||
nextspritesect[i] = i+1;
|
||||
sprite[i].sectnum = MAXSECTORS;
|
||||
}
|
||||
prevspritesect[0] = -1;
|
||||
nextspritesect[MAXSPRITES-1] = -1;
|
||||
|
||||
|
||||
for (i=0; i<MAXSTATUS; i++) //Init doubly-linked sprite status lists
|
||||
headspritestat[i] = -1;
|
||||
headspritestat[MAXSTATUS] = 0;
|
||||
|
||||
for (i=0; i<MAXSPRITES; i++)
|
||||
{
|
||||
prevspritestat[i] = i-1;
|
||||
nextspritestat[i] = i+1;
|
||||
sprite[i].statnum = MAXSTATUS;
|
||||
}
|
||||
prevspritestat[0] = -1;
|
||||
nextspritestat[MAXSPRITES-1] = -1;
|
||||
|
||||
tailspritefree = MAXSPRITES-1;
|
||||
Numsprites = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// inside
|
||||
|
@ -1396,28 +1153,6 @@ int tilehasmodelorvoxel(int const tilenume, int pal)
|
|||
}
|
||||
|
||||
|
||||
void SetActor(DCoreActor* actor, const vec3_t* newpos)
|
||||
{
|
||||
auto tempsector = actor->sector();
|
||||
actor->s().setpos(*newpos);
|
||||
updatesector(newpos->x, newpos->y, &tempsector);
|
||||
|
||||
if (tempsector && tempsector != actor->sector())
|
||||
ChangeActorSect(actor, tempsector);
|
||||
}
|
||||
|
||||
void SetActorZ(DCoreActor* actor, const vec3_t* newpos)
|
||||
{
|
||||
auto tempsector = actor->sector();
|
||||
actor->s().setpos(*newpos);
|
||||
updatesectorz(newpos->x, newpos->y, newpos->z, &tempsector);
|
||||
|
||||
if (tempsector && tempsector != actor->sector())
|
||||
ChangeActorSect(actor, tempsector);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CCMD(updatesectordebug)
|
||||
{
|
||||
int sect = 319;
|
||||
|
|
446
source/core/actorlist.cpp
Normal file
446
source/core/actorlist.cpp
Normal file
|
@ -0,0 +1,446 @@
|
|||
/*
|
||||
** actorlist.cpp
|
||||
** Implements the linked stat/sector actor lists
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2021 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include <deque>
|
||||
#include "build.h"
|
||||
#include "coreactor.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
// Doubly linked ring list of Actors
|
||||
|
||||
|
||||
std::deque<DCoreActor*> freeList; // only needed until we can get rid of the sprite array.
|
||||
ActorStatList statList[MAXSTATUS];
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR(Bool, safe_spritelist, false, CVAR_ARCHIVE)
|
||||
|
||||
static bool isSafe()
|
||||
{
|
||||
return isBlood() || safe_spritelist;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
TArray<DCoreActor*> checked;
|
||||
|
||||
static bool ValidateStatList(int statnum)
|
||||
{
|
||||
checked.Clear();
|
||||
for (auto entry = statList[statnum].firstEntry; entry; entry = entry->nextStat)
|
||||
{
|
||||
assert(!checked.Contains(entry));
|
||||
checked.Push(entry);
|
||||
assert(entry->prevStat != nullptr || statList[statnum].firstEntry == entry);
|
||||
assert(entry->nextStat != nullptr || statList[statnum].lastEntry == entry);
|
||||
assert(entry->prevStat == nullptr || entry->prevStat->nextStat == entry);
|
||||
assert(entry->nextStat == nullptr || entry->nextStat->prevStat == entry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void AddStatTail(DCoreActor* actor, int statnum)
|
||||
{
|
||||
assert(actor->prevStat == nullptr && actor->nextStat == nullptr);
|
||||
|
||||
auto tail = statList[statnum].lastEntry;
|
||||
assert(tail == nullptr || tail->nextStat == nullptr);
|
||||
assert(ValidateStatList(statnum));
|
||||
actor->prevStat = tail;
|
||||
if (tail) tail->nextStat = actor;
|
||||
else statList[statnum].firstEntry = actor;
|
||||
statList[statnum].lastEntry = actor;
|
||||
assert(ValidateStatList(statnum));
|
||||
actor->s().statnum = statnum;
|
||||
actor->link_stat = statnum;
|
||||
//GC::WriteBarrier(tail);
|
||||
//GC::WriteBarrier(actor);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void AddStatHead(DCoreActor* actor, int statnum)
|
||||
{
|
||||
assert(actor->prevStat == nullptr && actor->nextStat == nullptr);
|
||||
|
||||
auto head = statList[statnum].firstEntry;
|
||||
assert(head == nullptr || head->prevStat == nullptr);
|
||||
assert(ValidateStatList(statnum));
|
||||
actor->nextStat = head;
|
||||
if (head) head->prevStat = actor;
|
||||
else statList[statnum].lastEntry = actor;
|
||||
assert(ValidateStatList(statnum));
|
||||
statList[statnum].firstEntry = actor;
|
||||
actor->s().statnum = statnum;
|
||||
actor->link_stat = statnum;
|
||||
//GC::WriteBarrier(head);
|
||||
//GC::WriteBarrier(actor);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void RemoveActorStat(DCoreActor* actor)
|
||||
{
|
||||
DCoreActor* prev = actor->prevStat;
|
||||
DCoreActor* next = actor->nextStat;
|
||||
auto& firstEntry = statList[actor->link_stat].firstEntry;
|
||||
auto& lastEntry = statList[actor->link_stat].lastEntry;
|
||||
|
||||
auto prevp = prev ? &prev->nextStat : &firstEntry;
|
||||
auto nextp = next ? &next->prevStat : &lastEntry;
|
||||
assert(*prevp == actor);
|
||||
assert(*nextp == actor);
|
||||
|
||||
assert(ValidateStatList(actor->link_stat));
|
||||
*prevp = next;
|
||||
*nextp = prev;
|
||||
assert(ValidateStatList(actor->link_stat));
|
||||
|
||||
actor->nextStat = actor->prevStat = nullptr;
|
||||
actor->s().statnum = MAXSTATUS;
|
||||
actor->link_stat = MAXSTATUS;
|
||||
/*
|
||||
GC::WriteBarrier(prev, next);
|
||||
GC::WriteBarrier(next, prev);
|
||||
*/
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void InsertActorStat(DCoreActor* actor, int stat, bool tail)
|
||||
{
|
||||
assert(actor->prevStat == nullptr && actor->nextStat == nullptr);
|
||||
assert(stat >= 0 && stat <= MAXSTATUS);
|
||||
if (isSafe() || tail) AddStatTail(actor, stat);
|
||||
else AddStatHead(actor, stat);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int ChangeActorStat(DCoreActor* actor, int statnum, bool tail)
|
||||
{
|
||||
int oldstat = actor->link_stat;
|
||||
assert(statnum >= 0 && statnum < MAXSTATUS);
|
||||
assert(actor->s().statnum >= 0 && actor->s().statnum < MAXSTATUS);
|
||||
RemoveActorStat(actor);
|
||||
InsertActorStat(actor, statnum, tail);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr)
|
||||
{
|
||||
assert(sect);
|
||||
checked.Clear();
|
||||
assert(sect->firstEntry == nullptr || sect->firstEntry->prevSect == nullptr);
|
||||
assert(sect->lastEntry == nullptr || sect->lastEntry->nextSect == nullptr);
|
||||
for (auto entry = sect->firstEntry; entry; entry = entry->nextSect)
|
||||
{
|
||||
assert(entry != checkme);
|
||||
assert(!checked.Contains(entry));
|
||||
checked.Push(entry);
|
||||
assert(entry->prevSect != nullptr || sect->firstEntry == entry);
|
||||
assert(entry->nextSect != nullptr || sect->lastEntry == entry);
|
||||
assert(entry->prevSect == nullptr || entry->prevSect->nextSect == entry);
|
||||
assert(entry->nextSect == nullptr || entry->nextSect->prevSect == entry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void AddSectTail(DCoreActor *actor, sectortype* sect)
|
||||
{
|
||||
assert(actor->prevSect == nullptr && actor->nextSect == nullptr);
|
||||
|
||||
auto tail = sect->lastEntry;
|
||||
assert(tail == nullptr || tail->nextSect == nullptr);
|
||||
assert(ValidateSectList(sect));
|
||||
actor->prevSect = tail;
|
||||
if (tail) tail->nextSect = actor;
|
||||
else sect->firstEntry = actor;
|
||||
sect->lastEntry = actor;
|
||||
assert(ValidateSectList(sect));
|
||||
actor->s().setsector(sect);
|
||||
actor->link_sector = sect;
|
||||
//GC::WriteBarrier(tail);
|
||||
//GC::WriteBarrier(actor);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void AddSectHead(DCoreActor *actor, sectortype* sect)
|
||||
{
|
||||
assert(actor->prevSect == nullptr && actor->nextSect == nullptr);
|
||||
|
||||
auto head = sect->firstEntry;
|
||||
assert(head == nullptr || head->prevSect == nullptr);
|
||||
assert(ValidateSectList(sect));
|
||||
actor->nextSect = head;
|
||||
if (head) head->prevSect = actor;
|
||||
else sect->lastEntry = actor;
|
||||
sect->firstEntry = actor;
|
||||
assert(ValidateSectList(sect));
|
||||
actor->s().sectnum = sectnum(sect);
|
||||
actor->link_sector = sect;
|
||||
//GC::WriteBarrier(head);
|
||||
//GC::WriteBarrier(actor);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void RemoveActorSect(DCoreActor* actor)
|
||||
{
|
||||
if (actor->link_sector == nullptr)
|
||||
{
|
||||
assert(actor->prevSect == nullptr && actor->nextSect == nullptr);
|
||||
return;
|
||||
}
|
||||
DCoreActor *prev = actor->prevSect;
|
||||
DCoreActor *next = actor->nextSect;
|
||||
|
||||
auto& firstEntry = actor->link_sector->firstEntry;
|
||||
auto& lastEntry = actor->link_sector->lastEntry;
|
||||
|
||||
auto prevp = prev ? &prev->nextSect : &firstEntry;
|
||||
auto nextp = next ? &next->prevSect : &lastEntry;
|
||||
assert(*prevp == actor);
|
||||
assert(*nextp == actor);
|
||||
|
||||
assert(ValidateSectList(actor->link_sector));
|
||||
*prevp = next;
|
||||
*nextp = prev;
|
||||
assert(ValidateSectList(actor->link_sector, actor));
|
||||
|
||||
actor->nextSect = actor->prevSect = nullptr;
|
||||
actor->s().setsector(nullptr);
|
||||
actor->link_sector = nullptr;
|
||||
/*
|
||||
GC::WriteBarrier(prev, next);
|
||||
GC::WriteBarrier(next, prev);
|
||||
*/
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail)
|
||||
{
|
||||
assert(actor->prevSect == nullptr && actor->nextSect == nullptr);
|
||||
|
||||
if (!sector)
|
||||
{
|
||||
actor->link_sector = nullptr;
|
||||
actor->s().setsector(nullptr);
|
||||
return;
|
||||
}
|
||||
if (isSafe() || tail) AddSectTail(actor, sector);
|
||||
else AddSectHead(actor, sector);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ChangeActorSect(DCoreActor* actor, sectortype* sect, bool tail)
|
||||
{
|
||||
if (sect == nullptr) return;
|
||||
auto old_sect = actor->link_sector;
|
||||
assert(actor->s().insector());
|
||||
RemoveActorSect(actor);
|
||||
InsertActorSect(actor, sect, tail);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DCoreActor* InsertActor(sectortype* sector, int stat, bool tail)
|
||||
{
|
||||
if (freeList.empty())
|
||||
{
|
||||
I_Error("Out of sprites!"); // we cannot deal with this - and most of the calling code never checks...
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto actor = freeList.back();
|
||||
freeList.pop_back();
|
||||
|
||||
spritetype* pSprite = &actor->s();
|
||||
pSprite->clear();
|
||||
|
||||
InsertActorStat(actor, stat, tail);
|
||||
InsertActorSect(actor, sector, tail);
|
||||
|
||||
Numsprites++;
|
||||
actor->s().time = leveltimer++;
|
||||
return actor;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int DeleteActor(DCoreActor* actor)
|
||||
{
|
||||
auto sp = &actor->s();
|
||||
assert(sp->statnum >= 0 && sp->statnum < MAXSTATUS);
|
||||
|
||||
int stat = actor->link_stat;
|
||||
RemoveActorStat(actor);
|
||||
|
||||
auto sect = actor->link_sector;
|
||||
if (sect)
|
||||
{
|
||||
RemoveActorSect(actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(actor->prevSect == nullptr && actor->nextSect == nullptr);
|
||||
}
|
||||
Numsprites--;
|
||||
freeList.push_front(actor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void InitSpriteLists()
|
||||
{
|
||||
for (auto& stat : statList)
|
||||
{
|
||||
stat.firstEntry = stat.lastEntry = nullptr;
|
||||
}
|
||||
for (auto& sect : sectors())
|
||||
{
|
||||
sect.firstEntry = sect.lastEntry = nullptr;
|
||||
}
|
||||
freeList.clear();
|
||||
for(auto& actor : actorArray)
|
||||
{
|
||||
actor->prevSect = actor->prevStat = actor->nextSect = actor->nextStat = nullptr;
|
||||
freeList.push_front(actor);
|
||||
}
|
||||
Numsprites = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SetActor(DCoreActor* actor, const vec3_t* newpos)
|
||||
{
|
||||
auto tempsector = actor->sector();
|
||||
actor->s().setpos(*newpos);
|
||||
updatesector(newpos->x, newpos->y, &tempsector);
|
||||
|
||||
if (tempsector && tempsector != actor->sector())
|
||||
ChangeActorSect(actor, tempsector);
|
||||
}
|
||||
|
||||
void SetActorZ(DCoreActor* actor, const vec3_t* newpos)
|
||||
{
|
||||
auto tempsector = actor->sector();
|
||||
actor->s().setpos(*newpos);
|
||||
updatesectorz(newpos->x, newpos->y, newpos->z, &tempsector);
|
||||
|
||||
if (tempsector && tempsector != actor->sector())
|
||||
ChangeActorSect(actor, tempsector);
|
||||
}
|
||||
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "build.h"
|
||||
#include "iterators.h"
|
||||
|
||||
class DCoreActor
|
||||
{
|
||||
|
@ -12,6 +11,12 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
// These two are needed because we cannot rely on the ones in the sprites for unlinking.
|
||||
int link_stat;
|
||||
sectortype* link_sector;
|
||||
DCoreActor* prevStat, * nextStat;
|
||||
DCoreActor* prevSect, * nextSect;
|
||||
|
||||
bool exists() const
|
||||
{
|
||||
return (unsigned)s().statnum < MAXSTATUS;
|
||||
|
@ -209,51 +214,80 @@ struct TCollision : public CollisionBase
|
|||
};
|
||||
|
||||
|
||||
struct ActorStatList
|
||||
{
|
||||
DCoreActor* firstEntry, * lastEntry;
|
||||
};
|
||||
|
||||
extern ActorStatList statList[MAXSTATUS];
|
||||
|
||||
// Iterator wrappers that return an actor pointer, not an index.
|
||||
template<class TActor>
|
||||
class TStatIterator : public StatIterator
|
||||
class TStatIterator
|
||||
{
|
||||
DCoreActor* next;
|
||||
public:
|
||||
TStatIterator(int stat) : StatIterator(stat)
|
||||
TStatIterator(int stat)
|
||||
{
|
||||
next = statList[stat].firstEntry;
|
||||
}
|
||||
|
||||
void Reset(int stat)
|
||||
{
|
||||
next = statList[stat].firstEntry;
|
||||
}
|
||||
|
||||
TActor* Next()
|
||||
{
|
||||
int n = NextIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
auto n = next;
|
||||
if (next) next = next->nextStat;
|
||||
return static_cast<TActor*>(n);
|
||||
}
|
||||
|
||||
TActor* Peek()
|
||||
{
|
||||
int n = PeekIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
return static_cast<TActor*>(next);
|
||||
}
|
||||
};
|
||||
|
||||
template<class TActor>
|
||||
class TSectIterator : public SectIterator
|
||||
class TSectIterator
|
||||
{
|
||||
DCoreActor* next;
|
||||
public:
|
||||
TSectIterator(int stat) : SectIterator(stat)
|
||||
//[[deprecated]]
|
||||
TSectIterator(int stat)
|
||||
{
|
||||
next = sector[stat].firstEntry;
|
||||
}
|
||||
|
||||
TSectIterator(sectortype* stat) : SectIterator(stat)
|
||||
TSectIterator(sectortype* stat)
|
||||
{
|
||||
next = stat->firstEntry;
|
||||
}
|
||||
|
||||
//[[deprecated]]
|
||||
void Reset(int stat)
|
||||
{
|
||||
next = sector[stat].firstEntry;
|
||||
}
|
||||
|
||||
void Reset(sectortype* stat)
|
||||
{
|
||||
next = stat->firstEntry;
|
||||
}
|
||||
|
||||
|
||||
TActor* Next()
|
||||
{
|
||||
int n = NextIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
auto n = next;
|
||||
if (next) next = next->nextSect;
|
||||
return static_cast<TActor*>(n);
|
||||
}
|
||||
|
||||
TActor* Peek()
|
||||
{
|
||||
int n = PeekIndex();
|
||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
||||
return static_cast<TActor*>(next);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -288,16 +322,15 @@ public:
|
|||
|
||||
using CoreSectIterator = TSectIterator<DCoreActor>;
|
||||
|
||||
// Only to be used by initial actor spawns!
|
||||
void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail = false);
|
||||
void InsertActorStat(DCoreActor* actor, int stat, bool tail = false);
|
||||
|
||||
inline void ChangeActorStat(DCoreActor* actor, int stat)
|
||||
{
|
||||
changespritestat(actor->GetSpriteIndex(), stat);
|
||||
}
|
||||
|
||||
inline void ChangeActorSect(DCoreActor* actor, sectortype* sect)
|
||||
{
|
||||
changespritesect(actor->GetSpriteIndex(), sector.IndexOf(sect));
|
||||
}
|
||||
DCoreActor* InsertActor(sectortype* sector, int stat, bool forcetail = false);
|
||||
int DeleteActor(DCoreActor* actor);
|
||||
void ChangeActorSect(DCoreActor* actor, sectortype* sector, bool forcetail = false);
|
||||
int ChangeActorStat(DCoreActor* actor, int nStatus, bool forcetail = false);
|
||||
void InitSpriteLists();
|
||||
|
||||
|
||||
void SetActorZ(DCoreActor* actor, const vec3_t* newpos);
|
||||
|
|
|
@ -78,6 +78,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "hw_voxels.h"
|
||||
#include "hw_palmanager.h"
|
||||
#include "razefont.h"
|
||||
#include "coreactor.h"
|
||||
|
||||
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
@ -1376,7 +1377,7 @@ void GameInterface::loadPalette()
|
|||
void GameInterface::FreeLevelData()
|
||||
{
|
||||
// Make sure that there is no more level to toy around with.
|
||||
initspritelists();
|
||||
InitSpriteLists();
|
||||
numsectors = numwalls = 0;
|
||||
currentLevel = nullptr;
|
||||
}
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
class StatIterator
|
||||
{
|
||||
int next;
|
||||
public:
|
||||
StatIterator(int stat)
|
||||
{
|
||||
assert(stat >= 0 && stat < MAXSTATUS);
|
||||
next = headspritestat[stat];
|
||||
}
|
||||
|
||||
void Reset(int stat)
|
||||
{
|
||||
assert(stat >= 0 && stat < MAXSTATUS);
|
||||
next = headspritestat[stat];
|
||||
}
|
||||
|
||||
int NextIndex()
|
||||
{
|
||||
int n = next;
|
||||
if (n >= 0) next = nextspritestat[next];
|
||||
return n;
|
||||
}
|
||||
|
||||
int PeekIndex()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
// These are only used by one particularly screwy loop in Blood's nnexts.cpp.
|
||||
static int First(int stat)
|
||||
{
|
||||
return headspritestat[stat];
|
||||
}
|
||||
|
||||
static int NextFor(int spr)
|
||||
{
|
||||
return nextspritestat[spr];
|
||||
}
|
||||
};
|
||||
|
||||
class SectIterator
|
||||
{
|
||||
int next;
|
||||
public:
|
||||
SectIterator(int stat)
|
||||
{
|
||||
assert(validSectorIndex(stat));
|
||||
next = headspritesect[stat];
|
||||
}
|
||||
|
||||
SectIterator(sectortype* sect)
|
||||
{
|
||||
assert(sect);
|
||||
next = headspritesect[sector.IndexOf(sect)];
|
||||
}
|
||||
|
||||
void Reset(int stat)
|
||||
{
|
||||
assert(validSectorIndex(stat));
|
||||
next = headspritesect[stat];
|
||||
}
|
||||
|
||||
void Reset(sectortype* sect)
|
||||
{
|
||||
assert(sect);
|
||||
next = headspritesect[sector.IndexOf(sect)];
|
||||
}
|
||||
|
||||
int NextIndex()
|
||||
{
|
||||
int n = next;
|
||||
if (n >= 0) next = nextspritesect[next];
|
||||
return n;
|
||||
}
|
||||
|
||||
int PeekIndex()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
};
|
|
@ -387,7 +387,7 @@ void insertAllSprites(SpawnSpriteDef& sprites)
|
|||
removeit = true;
|
||||
}
|
||||
|
||||
insertsprite(spr.sectnum, spr.statnum, true);
|
||||
//insertsprite(spr.sectnum, spr.statnum, true);
|
||||
|
||||
if (removeit)
|
||||
{
|
||||
|
@ -407,7 +407,7 @@ void insertAllSprites(SpawnSpriteDef& sprites)
|
|||
{
|
||||
// Now remove it for real!
|
||||
spr.statnum = 0;
|
||||
deletesprite(i);
|
||||
//deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -468,7 +468,6 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
|
|||
|
||||
// Now that we know the map's size, set up the globals.
|
||||
allocateMapArrays(numsprites);
|
||||
initspritelists(); // may not be used in Blood!
|
||||
sprites.sprites.Resize(numsprites);
|
||||
memset(sprites.sprites.Data(), 0, numsprites * sizeof(spritetype));
|
||||
|
||||
|
@ -549,7 +548,6 @@ void loadMapBackup(const char* filename)
|
|||
else
|
||||
{
|
||||
engineLoadBoard(filename, 0, &pos, &scratch, &scratch2, scratch3);
|
||||
initspritelists();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -666,20 +666,11 @@ void SerializeMap(FSerializer& arc)
|
|||
activeSprites.Set(i);
|
||||
}
|
||||
}
|
||||
// simplify the data a bit for better compression.
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
if (nextspritestat[i] == i + 1) nextspritestat[i] = -2;
|
||||
if (nextspritesect[i] == i + 1) nextspritesect[i] = -2;
|
||||
if (prevspritestat[i] == i - 1) prevspritestat[i] = -2;
|
||||
if (prevspritesect[i] == i - 1) prevspritesect[i] = -2;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
|
||||
initspritelists();
|
||||
InitSpriteLists();
|
||||
zsp = sprite[0];
|
||||
}
|
||||
|
||||
|
@ -692,12 +683,6 @@ void SerializeMap(FSerializer& arc)
|
|||
("sectors", sector, sectorbackup)
|
||||
("numwalls", numwalls)
|
||||
("walls", wall, wallbackup)
|
||||
.Array("headspritestat", headspritestat, MAXSTATUS + 1)
|
||||
.Array("nextspritestat", nextspritestat, MAXSPRITES)
|
||||
.Array("prevspritestat", prevspritestat, MAXSPRITES)
|
||||
.Array("headspritesect", headspritesect, MAXSECTORS + 1)
|
||||
.Array("nextspritesect", nextspritesect, MAXSPRITES)
|
||||
.Array("prevspritesect", prevspritesect, MAXSPRITES)
|
||||
|
||||
("tailspritefree", tailspritefree)
|
||||
("myconnectindex", myconnectindex)
|
||||
|
@ -729,15 +714,6 @@ void SerializeMap(FSerializer& arc)
|
|||
arc.EndObject();
|
||||
}
|
||||
|
||||
|
||||
// Undo the simplification.
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
if (nextspritestat[i] == -2) nextspritestat[i] = i + 1;
|
||||
if (nextspritesect[i] == -2) nextspritesect[i] = i + 1;
|
||||
if (prevspritestat[i] == -2) prevspritestat[i] = i - 1;
|
||||
if (prevspritesect[i] == -2) prevspritesect[i] = i - 1;
|
||||
}
|
||||
if (arc.isReading())
|
||||
{
|
||||
setWallSectors();
|
||||
|
|
|
@ -82,12 +82,18 @@ void EndLevel(void)
|
|||
TArray<DBloodActor*> SpawnActors(BloodSpawnSpriteDef& sprites)
|
||||
{
|
||||
TArray<DBloodActor*> spawns(sprites.sprites.Size(), true);
|
||||
initspritelists();
|
||||
InitSpriteLists();
|
||||
int j = 0;
|
||||
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
|
||||
{
|
||||
RemoveSpriteStat(i);
|
||||
auto actor = &bloodActors[i];
|
||||
spawns[i] = actor;
|
||||
if (sprites.sprites[i].statnum == MAXSTATUS)
|
||||
{
|
||||
spawns.Pop();
|
||||
continue;
|
||||
}
|
||||
auto sprt = &sprites.sprites[i];
|
||||
auto actor = InsertSprite(sprt->sector(), sprt->statnum);
|
||||
spawns[j++] = actor;
|
||||
actor->Clear();
|
||||
actor->s() = sprites.sprites[i];
|
||||
if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i];
|
||||
|
@ -99,11 +105,7 @@ TArray<DBloodActor*> SpawnActors(BloodSpawnSpriteDef& sprites)
|
|||
actor->addX();
|
||||
actor->x() = sprites.xspr[i];
|
||||
}
|
||||
|
||||
InsertSpriteSect(i, actor->s().sectnum);
|
||||
InsertSpriteStat(i, actor->s().statnum);
|
||||
}
|
||||
Numsprites = spawns.Size();
|
||||
return spawns;
|
||||
}
|
||||
|
||||
|
@ -507,8 +509,6 @@ void GameInterface::app_init()
|
|||
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
||||
ReadAllRFS();
|
||||
|
||||
HookReplaceFunctions();
|
||||
|
||||
levelLoadDefaults();
|
||||
|
||||
//---------
|
||||
|
|
|
@ -177,14 +177,4 @@ inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
|
|||
GetSpriteExtents(&actor->s(), top, bottom);
|
||||
}
|
||||
|
||||
inline void ChangeActorStat(DBloodActor* actor, int stat)
|
||||
{
|
||||
ChangeSpriteStat(actor->GetSpriteIndex(), stat);
|
||||
}
|
||||
|
||||
inline void ChangeActorSect(DBloodActor* actor, sectortype* stat)
|
||||
{
|
||||
ChangeSpriteSect(actor->GetSpriteIndex(), sectnum(stat));
|
||||
}
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -41,6 +41,31 @@ BEGIN_BLD_NS
|
|||
DBloodActor bloodActors[kMaxSprites];
|
||||
|
||||
|
||||
DBloodActor* InsertSprite(sectortype* pSector, int nStat)
|
||||
{
|
||||
auto act = static_cast<DBloodActor*>(::InsertActor(pSector, nStat));
|
||||
auto pSprite = &act->s();
|
||||
pSprite->cstat = 128;
|
||||
pSprite->clipdist = 32;
|
||||
pSprite->xrepeat = pSprite->yrepeat = 64;
|
||||
return act;
|
||||
}
|
||||
|
||||
int DeleteSprite(DBloodActor* actor)
|
||||
{
|
||||
auto sp = &actor->s();
|
||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
||||
soundEngine->RelinkSound(SOURCE_Actor, actor, nullptr, &pos);
|
||||
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
for (auto& ctrl : gPlayerCtrl) if (ctrl.qavScene.initiator == actor) ctrl.qavScene.initiator = nullptr;
|
||||
#endif
|
||||
|
||||
::DeleteActor(actor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool gModernMap = false;
|
||||
unsigned int gStatCount[kMaxStatus + 1];
|
||||
|
||||
|
@ -55,191 +80,6 @@ void dbCrypt(char *pPtr, int nLength, int nKey)
|
|||
}
|
||||
}
|
||||
|
||||
void InsertSpriteSect(int nSprite, int nSector)
|
||||
{
|
||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
assert(validSectorIndex(nSector));
|
||||
int nOther = headspritesect[nSector];
|
||||
if (nOther >= 0)
|
||||
{
|
||||
prevspritesect[nSprite] = prevspritesect[nOther];
|
||||
nextspritesect[nSprite] = -1;
|
||||
nextspritesect[prevspritesect[nOther]] = nSprite;
|
||||
prevspritesect[nOther] = nSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevspritesect[nSprite] = nSprite;
|
||||
nextspritesect[nSprite] = -1;
|
||||
headspritesect[nSector] = nSprite;
|
||||
}
|
||||
sprite[nSprite].sectnum = nSector;
|
||||
}
|
||||
|
||||
void RemoveSpriteSect(int nSprite)
|
||||
{
|
||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
int nSector = sprite[nSprite].sectnum;
|
||||
assert(validSectorIndex(nSector));
|
||||
int nOther = nextspritesect[nSprite];
|
||||
if (nOther < 0)
|
||||
{
|
||||
nOther = headspritesect[nSector];
|
||||
}
|
||||
prevspritesect[nOther] = prevspritesect[nSprite];
|
||||
if (headspritesect[nSector] != nSprite)
|
||||
{
|
||||
nextspritesect[prevspritesect[nSprite]] = nextspritesect[nSprite];
|
||||
}
|
||||
else
|
||||
{
|
||||
headspritesect[nSector] = nextspritesect[nSprite];
|
||||
}
|
||||
sprite[nSprite].sectnum = MAXSECTORS;
|
||||
}
|
||||
|
||||
void InsertSpriteStat(int nSprite, int nStat)
|
||||
{
|
||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
assert(nStat >= 0 && nStat <= kMaxStatus);
|
||||
int nOther = headspritestat[nStat];
|
||||
if (nOther >= 0)
|
||||
{
|
||||
prevspritestat[nSprite] = prevspritestat[nOther];
|
||||
nextspritestat[nSprite] = -1;
|
||||
nextspritestat[prevspritestat[nOther]] = nSprite;
|
||||
prevspritestat[nOther] = nSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevspritestat[nSprite] = nSprite;
|
||||
nextspritestat[nSprite] = -1;
|
||||
headspritestat[nStat] = nSprite;
|
||||
}
|
||||
sprite[nSprite].statnum = nStat;
|
||||
gStatCount[nStat]++;
|
||||
}
|
||||
|
||||
void RemoveSpriteStat(int nSprite)
|
||||
{
|
||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
int nStat = sprite[nSprite].statnum;
|
||||
assert(nStat >= 0 && nStat <= kMaxStatus);
|
||||
int nOther = nextspritestat[nSprite];
|
||||
if (nOther < 0)
|
||||
{
|
||||
nOther = headspritestat[nStat];
|
||||
}
|
||||
prevspritestat[nOther] = prevspritestat[nSprite];
|
||||
if (headspritestat[nStat] != nSprite)
|
||||
{
|
||||
nextspritestat[prevspritestat[nSprite]] = nextspritestat[nSprite];
|
||||
}
|
||||
else
|
||||
{
|
||||
headspritestat[nStat] = nextspritestat[nSprite];
|
||||
}
|
||||
sprite[nSprite].statnum = MAXSTATUS;
|
||||
gStatCount[nStat]--;
|
||||
}
|
||||
|
||||
void qinitspritelists(void) // Replace
|
||||
{
|
||||
for (int i = 0; i <= MAXSECTORS; i++)
|
||||
{
|
||||
headspritesect[i] = -1;
|
||||
}
|
||||
for (int i = 0; i <= kMaxStatus; i++)
|
||||
{
|
||||
headspritestat[i] = -1;
|
||||
}
|
||||
for (int i = 0; i < kMaxSprites; i++)
|
||||
{
|
||||
sprite[i].sectnum = -1;
|
||||
InsertSpriteStat(i, kMaxStatus);
|
||||
}
|
||||
memset(gStatCount, 0, sizeof(gStatCount));
|
||||
Numsprites = 0;
|
||||
}
|
||||
|
||||
DBloodActor* InsertSprite(sectortype* pSector, int nStat)
|
||||
{
|
||||
int nSprite = headspritestat[kMaxStatus];
|
||||
assert(nSprite < kMaxSprites);
|
||||
if (nSprite < 0)
|
||||
{
|
||||
I_Error("Out of sprites!"); // we cannot deal with this - and most of the calling code never checks...
|
||||
return nullptr;
|
||||
}
|
||||
RemoveSpriteStat(nSprite);
|
||||
DBloodActor* actor = &bloodActors[nSprite];
|
||||
actor->Clear();
|
||||
spritetype *pSprite = &actor->s();
|
||||
memset(pSprite, 0, sizeof(spritetype));
|
||||
InsertSpriteStat(nSprite, nStat);
|
||||
InsertSpriteSect(nSprite, sectnum(pSector));
|
||||
pSprite->cstat = 128;
|
||||
pSprite->clipdist = 32;
|
||||
pSprite->xrepeat = pSprite->yrepeat = 64;
|
||||
actor->SetOwner(nullptr);
|
||||
|
||||
Numsprites++;
|
||||
|
||||
sprite[nSprite].time = leveltimer++;
|
||||
return actor;
|
||||
}
|
||||
|
||||
|
||||
inline int DeleteSprite(DBloodActor* actor)
|
||||
{
|
||||
auto sp = &actor->s();
|
||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
||||
soundEngine->RelinkSound(SOURCE_Actor, actor, nullptr, &pos);
|
||||
|
||||
assert(sp->statnum >= 0 && sp->statnum < kMaxStatus);
|
||||
RemoveSpriteStat(actor->GetSpriteIndex());
|
||||
assert(sp->insector());
|
||||
RemoveSpriteSect(actor->GetSpriteIndex());
|
||||
InsertSpriteStat(actor->GetSpriteIndex(), kMaxStatus);
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
for (auto& ctrl : gPlayerCtrl) if (ctrl.qavScene.initiator == actor) ctrl.qavScene.initiator = nullptr;
|
||||
#endif
|
||||
Numsprites--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ChangeSpriteSect(int nSprite, int nSector)
|
||||
{
|
||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
assert(validSectorIndex(nSector));
|
||||
assert(sprite[nSprite].insector());
|
||||
RemoveSpriteSect(nSprite);
|
||||
InsertSpriteSect(nSprite, nSector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qchangespritesect(short nSprite, short nSector)
|
||||
{
|
||||
return ChangeSpriteSect(nSprite, nSector);
|
||||
}
|
||||
|
||||
int ChangeSpriteStat(int nSprite, int nStatus)
|
||||
{
|
||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
||||
assert(nStatus >= 0 && nStatus < kMaxStatus);
|
||||
assert(sprite[nSprite].statnum >= 0 && sprite[nSprite].statnum < kMaxStatus);
|
||||
assert(sprite[nSprite].insector());
|
||||
RemoveSpriteStat(nSprite);
|
||||
InsertSpriteStat(nSprite, nStatus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dbInit(void)
|
||||
{
|
||||
initspritelists();
|
||||
}
|
||||
|
||||
bool drawtile2048, encrypted;
|
||||
|
||||
MAPHEADER2 byte_19AE44;
|
||||
|
@ -436,7 +276,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
|
|||
#endif
|
||||
* pSector = §or[mapHeader.sect];
|
||||
|
||||
dbInit();
|
||||
if (encrypted)
|
||||
{
|
||||
fr.Read(&byte_19AE44, 128);
|
||||
|
@ -904,6 +743,5 @@ void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang)
|
|||
Blood::BloodSpawnSpriteDef sprites;
|
||||
sectortype* sp;
|
||||
Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, nullptr, sprites);
|
||||
Blood::dbInit(); // clean up immediately.
|
||||
}
|
||||
|
|
@ -115,18 +115,9 @@ void DeleteLight(int32_t s);
|
|||
|
||||
#endif
|
||||
|
||||
void InsertSpriteSect(int nSprite, int nSector);
|
||||
void RemoveSpriteSect(int nSprite);
|
||||
void InsertSpriteStat(int nSprite, int nStat);
|
||||
void RemoveSpriteStat(int nSprite);
|
||||
void qinitspritelists(void);
|
||||
DBloodActor* InsertSprite(sectortype* pSector, int nStat);
|
||||
int DeleteSprite(DBloodActor* actor);
|
||||
int ChangeSpriteSect(int nSprite, int nSector);
|
||||
int qchangespritesect(short nSprite, short nSector);
|
||||
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, BloodSpawnSpriteDef& sprites);
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ void setPortalFlags(int mode);
|
|||
void processSpritesOnOtherSideOfPortal(int x, int y, int interpolation);
|
||||
void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer);
|
||||
int qanimateoffs(int a1, int a2);
|
||||
void HookReplaceFunctions();
|
||||
|
||||
struct PLAYER;
|
||||
|
||||
|
|
|
@ -61,13 +61,4 @@ int qanimateoffs(int a1, int a2)
|
|||
return offset;
|
||||
}
|
||||
|
||||
void qinitspritelists();
|
||||
int32_t qchangespritesect(int16_t nSprite, int16_t nSector);
|
||||
|
||||
void HookReplaceFunctions(void)
|
||||
{
|
||||
initspritelists_replace = qinitspritelists;
|
||||
changespritesect_replace = qchangespritesect;
|
||||
}
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -78,7 +78,7 @@ void deletesprite(DDukeActor *const actor)
|
|||
S_StopSound(actor->s->lotag, actor);
|
||||
else
|
||||
S_RelinkActorSound(actor, nullptr);
|
||||
::deletesprite(actor->GetSpriteIndex());
|
||||
::DeleteActor(actor);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -56,11 +56,6 @@ inline int bossguy(DDukeActor* pSprite)
|
|||
|
||||
// old interface versions of already changed functions
|
||||
|
||||
inline void deletesprite(int num)
|
||||
{
|
||||
deletesprite(&hittype[num]);
|
||||
}
|
||||
|
||||
int movesprite_ex_d(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision& result);
|
||||
int movesprite_ex_r(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision& result);
|
||||
|
||||
|
|
|
@ -935,15 +935,27 @@ static void SpawnPortals()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static TArray<DDukeActor*> spawnactors(SpawnSpriteDef& spawns)
|
||||
static TArray<DDukeActor*> spawnactors(SpawnSpriteDef& sprites)
|
||||
{
|
||||
insertAllSprites(spawns);
|
||||
TArray<DDukeActor*> actorlist;
|
||||
for(unsigned i = 0; i < spawns.sprites.Size(); i++)
|
||||
TArray<DDukeActor*> spawns(sprites.sprites.Size(), true);
|
||||
InitSpriteLists();
|
||||
int j = 0;
|
||||
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
|
||||
{
|
||||
if (hittype[i].exists()) actorlist.Push(&hittype[i]);
|
||||
if (sprites.sprites[i].statnum == MAXSTATUS)
|
||||
{
|
||||
spawns.Pop();
|
||||
continue;
|
||||
}
|
||||
auto sprt = &sprites.sprites[i];
|
||||
auto actor = static_cast<DDukeActor*>(InsertActor(sprt->sector(), sprt->statnum));
|
||||
spawns[j++] = actor;
|
||||
*actor->s = sprites.sprites[i];
|
||||
if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i];
|
||||
else actor->sx() = {};
|
||||
actor->sm() = {};
|
||||
}
|
||||
return actorlist;
|
||||
return spawns;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -53,12 +53,10 @@ DDukeActor* EGS(sectortype* whatsectp, int s_x, int s_y, int s_z, int s_pn, int8
|
|||
{
|
||||
// sector pointer must be strictly validated here or the engine will crash.
|
||||
if (whatsectp == nullptr || !validSectorIndex(sectnum(whatsectp))) return nullptr;
|
||||
int const i = insertsprite(sectnum(whatsectp), s_ss);
|
||||
auto act = static_cast<DDukeActor*>(::InsertActor(whatsectp, s_ss));
|
||||
|
||||
if (i < 0)
|
||||
I_Error(" Too many sprites spawned.");
|
||||
if (act == nullptr) return nullptr;
|
||||
|
||||
auto act = &hittype[i];
|
||||
auto s = act->s;
|
||||
|
||||
s->x = s_x;
|
||||
|
|
|
@ -220,11 +220,7 @@ Collision MoveCreature(DExhumedActor* nSprite);
|
|||
Collision MoveCreatureWithCaution(DExhumedActor* actor);
|
||||
void WheresMyMouth(int nPlayer, vec3_t* pos, sectortype** sectnum);
|
||||
int GetActorHeight(DExhumedActor* nSprite);
|
||||
DExhumedActor* insertActor(int, int);
|
||||
inline DExhumedActor* insertActor(sectortype* s, int st)
|
||||
{
|
||||
return insertActor(sector.IndexOf(s), st);
|
||||
}
|
||||
DExhumedActor* insertActor(sectortype* s, int st);
|
||||
DExhumedActor* GrabBody();
|
||||
DExhumedActor* GrabBodyGunSprite();
|
||||
void FuncCreatureChunk(int a, int, int nRun);
|
||||
|
|
|
@ -503,12 +503,11 @@ void DeleteActor(DExhumedActor* actor)
|
|||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
||||
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
||||
|
||||
deletesprite(actor->GetSpriteIndex());
|
||||
actor->s().ox = 0x80000000;
|
||||
|
||||
if (actor == bestTarget) {
|
||||
bestTarget = nullptr;
|
||||
}
|
||||
|
||||
::DeleteActor(actor);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -63,19 +63,31 @@ uint8_t bIsVersion6 = true;
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static TArray<DExhumedActor*> spawnactors(SpawnSpriteDef& spawns)
|
||||
static TArray<DExhumedActor*> spawnactors(SpawnSpriteDef& sprites)
|
||||
{
|
||||
insertAllSprites(spawns);
|
||||
TArray<DExhumedActor*> actorlist;
|
||||
for (unsigned i = 0; i < spawns.sprites.Size(); i++)
|
||||
TArray<DExhumedActor*> spawns(sprites.sprites.Size(), true);
|
||||
InitSpriteLists();
|
||||
int j = 0;
|
||||
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
|
||||
{
|
||||
if (exhumedActors[i].exists()) actorlist.Push(&exhumedActors[i]);
|
||||
if (sprites.sprites[i].statnum == MAXSTATUS)
|
||||
{
|
||||
spawns.Pop();
|
||||
continue;
|
||||
}
|
||||
auto sprt = &sprites.sprites[i];
|
||||
auto actor = insertActor(sprt->sector(), sprt->statnum);
|
||||
spawns[j++] = actor;
|
||||
actor->Clear();
|
||||
actor->s() = sprites.sprites[i];
|
||||
if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i];
|
||||
else actor->sx() = {};
|
||||
actor->sm() = {};
|
||||
}
|
||||
return actorlist;
|
||||
return spawns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t LoadLevel(MapRecord* map)
|
||||
{
|
||||
if (map->gameflags & LEVEL_EX_COUNTDOWN)
|
||||
|
@ -87,9 +99,6 @@ uint8_t LoadLevel(MapRecord* map)
|
|||
nEnergyTowers = 0;
|
||||
}
|
||||
|
||||
initspritelists();
|
||||
|
||||
|
||||
// init stuff
|
||||
{
|
||||
StopAllSounds();
|
||||
|
|
|
@ -469,10 +469,9 @@ int GetActorHeight(DExhumedActor* actor)
|
|||
return tileHeight(actor->s().picnum) * actor->s().yrepeat * 4;
|
||||
}
|
||||
|
||||
DExhumedActor* insertActor(int sect, int stat)
|
||||
DExhumedActor* insertActor(sectortype* s, int st)
|
||||
{
|
||||
int ndx = insertsprite(sect, stat);
|
||||
return ndx >= 0 ? &exhumedActors[ndx] : nullptr;
|
||||
return static_cast<DExhumedActor*>(::InsertActor(s, st));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -588,7 +588,7 @@ int AutoBreakWall(WALLp wallp, int hit_x, int hit_y, int hit_z, int ang, int typ
|
|||
{
|
||||
vec3_t hit_pos = { hit_x, hit_y, hit_z };
|
||||
// need correct location for spawning shrap
|
||||
auto breakActor = InsertActor(0, STAT_DEFAULT);
|
||||
auto breakActor = insertActor(0, STAT_DEFAULT);
|
||||
auto bsp = &breakActor->s();
|
||||
bsp->cstat = 0;
|
||||
bsp->extra = 0;
|
||||
|
|
|
@ -1155,7 +1155,7 @@ void BunnyHatch(DSWActor* actor)
|
|||
|
||||
for (int i = 0; i < MAX_BUNNYS; i++)
|
||||
{
|
||||
auto actorNew = InsertActor(sp->sector(), STAT_DEFAULT);
|
||||
auto actorNew = insertActor(sp->sector(), STAT_DEFAULT);
|
||||
np = &actorNew->s();
|
||||
np->clear();
|
||||
np->x = sp->x;
|
||||
|
@ -1218,7 +1218,7 @@ DSWActor* BunnyHatch2(DSWActor* actor)
|
|||
SPRITEp wp = &actor->s();
|
||||
|
||||
|
||||
auto actorNew = InsertActor(wp->sector(), STAT_DEFAULT);
|
||||
auto actorNew = insertActor(wp->sector(), STAT_DEFAULT);
|
||||
auto np = &actorNew->s();
|
||||
np->clear();
|
||||
np->x = wp->x;
|
||||
|
|
|
@ -547,7 +547,7 @@ DSWActor* CopySprite(sprt const* tsp, sectortype* newsector)
|
|||
{
|
||||
SPRITEp sp;
|
||||
|
||||
auto actorNew = InsertActor(newsector, STAT_FAF_COPY);
|
||||
auto actorNew = insertActor(newsector, STAT_FAF_COPY);
|
||||
sp = &actorNew->s();
|
||||
|
||||
sp->x = tsp->x;
|
||||
|
@ -1277,7 +1277,7 @@ PostDraw(void)
|
|||
while (auto actor = it.Next())
|
||||
{
|
||||
actor->clearUser();
|
||||
deletesprite(actor->GetSpriteIndex());
|
||||
::DeleteActor(actor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -293,6 +293,26 @@ void InitLevelGlobals2(void)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void spawnactors(SpawnSpriteDef& sprites)
|
||||
{
|
||||
InitSpriteLists();
|
||||
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
|
||||
{
|
||||
if (sprites.sprites[i].statnum == MAXSTATUS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto sprt = &sprites.sprites[i];
|
||||
auto actor = insertActor(sprt->sector(), sprt->statnum);
|
||||
actor->Clear();
|
||||
actor->s() = sprites.sprites[i];
|
||||
if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i];
|
||||
else actor->sx() = {};
|
||||
actor->sm() = {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InitLevel(MapRecord *maprec)
|
||||
{
|
||||
Terminate3DSounds();
|
||||
|
@ -330,7 +350,7 @@ void InitLevel(MapRecord *maprec)
|
|||
int cursect;
|
||||
SpawnSpriteDef sprites;
|
||||
engineLoadBoard(maprec->fileName, SW_SHAREWARE ? 1 : 0, &Player[0].pos, &ang, &cursect, sprites);
|
||||
insertAllSprites(sprites);
|
||||
spawnactors(sprites);
|
||||
Player[0].cursector = §or[cursect];
|
||||
|
||||
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
||||
|
|
|
@ -2103,11 +2103,7 @@ void SetSpikeActive(DSWActor*); // spike.c
|
|||
#define NTAG_SEARCH_HI 2
|
||||
#define NTAG_SEARCH_LO_HI 3
|
||||
|
||||
DSWActor* InsertActor(int sectnum, int statnum);
|
||||
inline DSWActor* InsertActor(sectortype* sect, int statnum)
|
||||
{
|
||||
return InsertActor(sectnum(sect), statnum);
|
||||
}
|
||||
DSWActor* insertActor(sectortype* sect, int statnum);
|
||||
|
||||
void AudioUpdate(void); // stupid
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ BEGIN_SW_NS
|
|||
|
||||
void CopyQuakeSpotToOn(SPRITEp sp)
|
||||
{
|
||||
auto actorNew = InsertActor(sp->sector(), STAT_QUAKE_SPOT);
|
||||
auto actorNew = insertActor(sp->sector(), STAT_QUAKE_SPOT);
|
||||
auto np = &actorNew->s();
|
||||
|
||||
memcpy(np, sp, sizeof(SPRITE));
|
||||
|
@ -237,7 +237,7 @@ void SpawnQuake(sectortype* sect, int x, int y, int z,
|
|||
short tics, short amt, int radius)
|
||||
{
|
||||
|
||||
auto actorNew = InsertActor(sect, STAT_QUAKE_ON);
|
||||
auto actorNew = insertActor(sect, STAT_QUAKE_ON);
|
||||
auto sp = &actorNew->s();
|
||||
|
||||
sp->x = x;
|
||||
|
|
|
@ -1216,7 +1216,7 @@ void RipperHatch(DSWActor* actor)
|
|||
|
||||
for (int i = 0; i < MAX_RIPPERS; i++)
|
||||
{
|
||||
auto actorNew = InsertActor(wp->sector(), STAT_DEFAULT);
|
||||
auto actorNew = insertActor(wp->sector(), STAT_DEFAULT);
|
||||
np = &actorNew->s();
|
||||
np->clear();
|
||||
ClearOwner(actorNew);
|
||||
|
|
|
@ -1234,7 +1234,7 @@ void Ripper2Hatch(DSWActor* actor)
|
|||
|
||||
for (int i = 0; i < MAX_RIPPER2S; i++)
|
||||
{
|
||||
auto actorNew = InsertActor(wp->sector(), STAT_DEFAULT);
|
||||
auto actorNew = insertActor(wp->sector(), STAT_DEFAULT);
|
||||
np = &actorNew->s();
|
||||
np->clear();
|
||||
ClearOwner(actorNew);
|
||||
|
|
|
@ -54,15 +54,11 @@ SAVE save;
|
|||
|
||||
bool FAF_DebugView = false;
|
||||
|
||||
DSWActor* InsertActor(int sectnum, int stat)
|
||||
DSWActor* insertActor(sectortype* sect, int statnum)
|
||||
{
|
||||
short spnum;
|
||||
spnum = insertsprite(sectnum, stat);
|
||||
auto pActor = &swActors[spnum];
|
||||
auto pActor = static_cast<DSWActor*>(::InsertActor(sect, statnum));
|
||||
auto pSprite = &pActor->s();
|
||||
|
||||
PRODUCTION_ASSERT(spnum >= 0);
|
||||
|
||||
pSprite->x = pSprite->y = pSprite->z = 0;
|
||||
pSprite->cstat = 0;
|
||||
pSprite->picnum = 0;
|
||||
|
|
|
@ -774,7 +774,7 @@ void KillActor(DSWActor* actor)
|
|||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
||||
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
||||
|
||||
deletesprite(actor->GetSpriteIndex());
|
||||
::DeleteActor(actor);
|
||||
// shred your garbage
|
||||
sp->clear();
|
||||
|
||||
|
@ -918,7 +918,7 @@ DSWActor* SpawnActor(int stat, int id, STATEp state, sectortype* sect, int x, in
|
|||
|
||||
ASSERT(!Prediction);
|
||||
|
||||
auto spawnedActor = InsertActor(sect, stat);
|
||||
auto spawnedActor = insertActor(sect, stat);
|
||||
|
||||
sp = &spawnedActor->s();
|
||||
|
||||
|
@ -983,7 +983,7 @@ bool ActorTestSpawn(DSWActor* actor)
|
|||
auto sp = &actor->s();
|
||||
if (sp->statnum == STAT_DEFAULT && sp->lotag == TAG_SPAWN_ACTOR)
|
||||
{
|
||||
auto actorNew = InsertActor(sp->sector(), STAT_DEFAULT);
|
||||
auto actorNew = insertActor(sp->sector(), STAT_DEFAULT);
|
||||
int t = actorNew->s().time; // must be preserved!
|
||||
actorNew->s() = *sp;
|
||||
actorNew->s().time = t;
|
||||
|
@ -2570,7 +2570,7 @@ void SpriteSetup(void)
|
|||
change_actor_stat(actor, STAT_CLIMB_MARKER);
|
||||
|
||||
// make a QUICK_LADDER sprite automatically
|
||||
auto ns = InsertActor(sp->sector(), STAT_QUICK_LADDER);
|
||||
auto ns = insertActor(sp->sector(), STAT_QUICK_LADDER);
|
||||
auto np = &ns->s();
|
||||
|
||||
np->cstat = 0;
|
||||
|
@ -3618,7 +3618,7 @@ int ActorCoughItem(DSWActor* actor)
|
|||
{
|
||||
case SAILORGIRL_R0:
|
||||
ASSERT(sp->insector());
|
||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
np = &actorNew->s();
|
||||
np->cstat = np->extra = 0;
|
||||
np->x = sp->x;
|
||||
|
@ -3659,7 +3659,7 @@ int ActorCoughItem(DSWActor* actor)
|
|||
return 0;
|
||||
|
||||
ASSERT(sp->insector());
|
||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
np = &actorNew->s();
|
||||
np->cstat = np->extra = 0;
|
||||
np->x = sp->x;
|
||||
|
@ -3687,7 +3687,7 @@ int ActorCoughItem(DSWActor* actor)
|
|||
return 0;
|
||||
|
||||
ASSERT(sp->insector());
|
||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
np = &actorNew->s();
|
||||
np->cstat = np->extra = 0;
|
||||
np->x = sp->x;
|
||||
|
@ -3718,7 +3718,7 @@ int ActorCoughItem(DSWActor* actor)
|
|||
return 0;
|
||||
|
||||
ASSERT(sp->insector());
|
||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
np = &actorNew->s();
|
||||
np->cstat = 0;
|
||||
np->extra = 0;
|
||||
|
@ -3781,7 +3781,7 @@ int ActorCoughItem(DSWActor* actor)
|
|||
return 0;
|
||||
|
||||
ASSERT(sp->insector());
|
||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
np = &actorNew->s();
|
||||
np->cstat = np->extra = 0;
|
||||
np->x = sp->x;
|
||||
|
@ -3839,7 +3839,7 @@ int ActorCoughItem(DSWActor* actor)
|
|||
case PACHINKO4:
|
||||
|
||||
ASSERT(sp->insector());
|
||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||
np = &actorNew->s();
|
||||
np->cstat = np->extra = 0;
|
||||
np->x = sp->x;
|
||||
|
|
|
@ -313,7 +313,7 @@ DSWActor* TrackClonePoint(DSWActor* actor)
|
|||
{
|
||||
SPRITEp sp = &actor->s(), np;
|
||||
|
||||
auto actorNew = InsertActor(sp->sector(), sp->statnum);
|
||||
auto actorNew = insertActor(sp->sector(), sp->statnum);
|
||||
|
||||
np = &actorNew->s();
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ void SpawnVis(DSWActor* parentActor, sectortype* sect, int x, int y, int z, int
|
|||
}
|
||||
}
|
||||
|
||||
auto actorNew = InsertActor(psp->sector(), STAT_VIS_ON);
|
||||
auto actorNew = insertActor(psp->sector(), STAT_VIS_ON);
|
||||
sp = &actorNew->s();
|
||||
SetOwner(parentActor, actorNew);
|
||||
|
||||
|
@ -170,7 +170,7 @@ void SpawnVis(DSWActor* parentActor, sectortype* sect, int x, int y, int z, int
|
|||
if (sect->floorpal == PALETTE_FOG)
|
||||
return;
|
||||
|
||||
auto actorNew = InsertActor(sect, STAT_VIS_ON);
|
||||
auto actorNew = insertActor(sect, STAT_VIS_ON);
|
||||
sp = &actorNew->s();
|
||||
|
||||
sp->x = x;
|
||||
|
|
|
@ -16069,7 +16069,7 @@ DSWActor* SpawnWallHole(sectortype* hit_sect, walltype* hit_wall, int hit_x, int
|
|||
short w,nw,wall_ang;
|
||||
SPRITEp sp;
|
||||
|
||||
auto actor = InsertActor(hit_sect, STAT_DEFAULT);
|
||||
auto actor = insertActor(hit_sect, STAT_DEFAULT);
|
||||
sp = &actor->s();
|
||||
sp->xrepeat = sp->yrepeat = 16;
|
||||
sp->cstat = 0;
|
||||
|
@ -18602,7 +18602,7 @@ void QueueHole(sectortype* hit_sect, walltype* hit_wall, int hit_x, int hit_y, i
|
|||
return;
|
||||
|
||||
if (HoleQueue[HoleQueueHead] == nullptr)
|
||||
HoleQueue[HoleQueueHead] = spawnedActor = InsertActor(hit_sect, STAT_HOLE_QUEUE);
|
||||
HoleQueue[HoleQueueHead] = spawnedActor = insertActor(hit_sect, STAT_HOLE_QUEUE);
|
||||
else
|
||||
spawnedActor = HoleQueue[HoleQueueHead];
|
||||
|
||||
|
|
Loading…
Reference in a new issue