mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +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/mdsprite.cpp
|
||||||
build/src/polymost.cpp
|
build/src/polymost.cpp
|
||||||
|
|
||||||
|
core/actorlist.cpp
|
||||||
core/automap.cpp
|
core/automap.cpp
|
||||||
core/cheats.cpp
|
core/cheats.cpp
|
||||||
core/cheathandler.cpp
|
core/cheathandler.cpp
|
||||||
|
|
|
@ -238,10 +238,6 @@ extern int16_t pskybits_override;
|
||||||
// (or -1 if freelist is empty):
|
// (or -1 if freelist is empty):
|
||||||
EXTERN int16_t tailspritefree;
|
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 uint8_t gotpic[(MAXTILES+7)>>3];
|
||||||
extern FixedBitArray<MAXSECTORS> gotsector;
|
extern FixedBitArray<MAXSECTORS> gotsector;
|
||||||
|
|
||||||
|
@ -321,7 +317,6 @@ typedef struct artheader_t {
|
||||||
|
|
||||||
int32_t engineInit(void);
|
int32_t engineInit(void);
|
||||||
void engineUnInit(void);
|
void engineUnInit(void);
|
||||||
void initspritelists(void);
|
|
||||||
|
|
||||||
struct SpawnSpriteDef
|
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 lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY,
|
||||||
int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ);
|
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);
|
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();
|
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;
|
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,
|
extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
|
||||||
int32_t vx_, int32_t vy_, int32_t vz,
|
int32_t vx_, int32_t vy_, int32_t vz,
|
||||||
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
|
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
|
||||||
int32_t *intx, int32_t *inty, int32_t *intz);
|
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();
|
void updateModelInterpolation();
|
||||||
|
@ -704,7 +679,4 @@ inline walltype* sectortype::lastWall() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "iterators.h"
|
|
||||||
|
|
||||||
#endif // build_h_
|
#endif // build_h_
|
||||||
|
|
|
@ -59,8 +59,12 @@ END_BLD_NS
|
||||||
//40 bytes
|
//40 bytes
|
||||||
class DCoreActor;
|
class DCoreActor;
|
||||||
struct walltype;
|
struct walltype;
|
||||||
|
|
||||||
|
|
||||||
struct sectortype
|
struct sectortype
|
||||||
{
|
{
|
||||||
|
DCoreActor* firstEntry, * lastEntry;
|
||||||
|
|
||||||
int16_t wallptr, wallnum;
|
int16_t wallptr, wallnum;
|
||||||
int32_t ceilingz, floorz;
|
int32_t ceilingz, floorz;
|
||||||
uint16_t ceilingstat, floorstat;
|
uint16_t ceilingstat, floorstat;
|
||||||
|
|
|
@ -223,195 +223,6 @@ static int32_t engineLoadTables(void)
|
||||||
return 0;
|
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)
|
// lintersect (internal)
|
||||||
//
|
//
|
||||||
|
@ -629,60 +440,6 @@ int32_t engineInit(void)
|
||||||
return 0;
|
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
|
// 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)
|
CCMD(updatesectordebug)
|
||||||
{
|
{
|
||||||
int sect = 319;
|
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 <stdint.h>
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "iterators.h"
|
|
||||||
|
|
||||||
class DCoreActor
|
class DCoreActor
|
||||||
{
|
{
|
||||||
|
@ -12,6 +11,12 @@ protected:
|
||||||
|
|
||||||
public:
|
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
|
bool exists() const
|
||||||
{
|
{
|
||||||
return (unsigned)s().statnum < MAXSTATUS;
|
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.
|
// Iterator wrappers that return an actor pointer, not an index.
|
||||||
template<class TActor>
|
template<class TActor>
|
||||||
class TStatIterator : public StatIterator
|
class TStatIterator
|
||||||
{
|
{
|
||||||
|
DCoreActor* next;
|
||||||
public:
|
public:
|
||||||
TStatIterator(int stat) : StatIterator(stat)
|
TStatIterator(int stat)
|
||||||
{
|
{
|
||||||
|
next = statList[stat].firstEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset(int stat)
|
||||||
|
{
|
||||||
|
next = statList[stat].firstEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
TActor* Next()
|
TActor* Next()
|
||||||
{
|
{
|
||||||
int n = NextIndex();
|
auto n = next;
|
||||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
if (next) next = next->nextStat;
|
||||||
|
return static_cast<TActor*>(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
TActor* Peek()
|
TActor* Peek()
|
||||||
{
|
{
|
||||||
int n = PeekIndex();
|
return static_cast<TActor*>(next);
|
||||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class TActor>
|
template<class TActor>
|
||||||
class TSectIterator : public SectIterator
|
class TSectIterator
|
||||||
{
|
{
|
||||||
|
DCoreActor* next;
|
||||||
public:
|
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()
|
TActor* Next()
|
||||||
{
|
{
|
||||||
int n = NextIndex();
|
auto n = next;
|
||||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
if (next) next = next->nextSect;
|
||||||
|
return static_cast<TActor*>(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
TActor* Peek()
|
TActor* Peek()
|
||||||
{
|
{
|
||||||
int n = PeekIndex();
|
return static_cast<TActor*>(next);
|
||||||
return n >= 0 ? static_cast<TActor*>(actorArray[n]) : nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -288,16 +322,15 @@ public:
|
||||||
|
|
||||||
using CoreSectIterator = TSectIterator<DCoreActor>;
|
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)
|
DCoreActor* InsertActor(sectortype* sector, int stat, bool forcetail = false);
|
||||||
{
|
int DeleteActor(DCoreActor* actor);
|
||||||
changespritestat(actor->GetSpriteIndex(), stat);
|
void ChangeActorSect(DCoreActor* actor, sectortype* sector, bool forcetail = false);
|
||||||
}
|
int ChangeActorStat(DCoreActor* actor, int nStatus, bool forcetail = false);
|
||||||
|
void InitSpriteLists();
|
||||||
inline void ChangeActorSect(DCoreActor* actor, sectortype* sect)
|
|
||||||
{
|
|
||||||
changespritesect(actor->GetSpriteIndex(), sector.IndexOf(sect));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SetActorZ(DCoreActor* actor, const vec3_t* newpos);
|
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_voxels.h"
|
||||||
#include "hw_palmanager.h"
|
#include "hw_palmanager.h"
|
||||||
#include "razefont.h"
|
#include "razefont.h"
|
||||||
|
#include "coreactor.h"
|
||||||
|
|
||||||
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
@ -1376,7 +1377,7 @@ void GameInterface::loadPalette()
|
||||||
void GameInterface::FreeLevelData()
|
void GameInterface::FreeLevelData()
|
||||||
{
|
{
|
||||||
// Make sure that there is no more level to toy around with.
|
// Make sure that there is no more level to toy around with.
|
||||||
initspritelists();
|
InitSpriteLists();
|
||||||
numsectors = numwalls = 0;
|
numsectors = numwalls = 0;
|
||||||
currentLevel = nullptr;
|
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;
|
removeit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
insertsprite(spr.sectnum, spr.statnum, true);
|
//insertsprite(spr.sectnum, spr.statnum, true);
|
||||||
|
|
||||||
if (removeit)
|
if (removeit)
|
||||||
{
|
{
|
||||||
|
@ -407,7 +407,7 @@ void insertAllSprites(SpawnSpriteDef& sprites)
|
||||||
{
|
{
|
||||||
// Now remove it for real!
|
// Now remove it for real!
|
||||||
spr.statnum = 0;
|
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.
|
// Now that we know the map's size, set up the globals.
|
||||||
allocateMapArrays(numsprites);
|
allocateMapArrays(numsprites);
|
||||||
initspritelists(); // may not be used in Blood!
|
|
||||||
sprites.sprites.Resize(numsprites);
|
sprites.sprites.Resize(numsprites);
|
||||||
memset(sprites.sprites.Data(), 0, numsprites * sizeof(spritetype));
|
memset(sprites.sprites.Data(), 0, numsprites * sizeof(spritetype));
|
||||||
|
|
||||||
|
@ -549,7 +548,6 @@ void loadMapBackup(const char* filename)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
engineLoadBoard(filename, 0, &pos, &scratch, &scratch2, scratch3);
|
engineLoadBoard(filename, 0, &pos, &scratch, &scratch2, scratch3);
|
||||||
initspritelists();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -666,20 +666,11 @@ void SerializeMap(FSerializer& arc)
|
||||||
activeSprites.Set(i);
|
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
|
else
|
||||||
{
|
{
|
||||||
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
|
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
|
||||||
initspritelists();
|
InitSpriteLists();
|
||||||
zsp = sprite[0];
|
zsp = sprite[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,12 +683,6 @@ void SerializeMap(FSerializer& arc)
|
||||||
("sectors", sector, sectorbackup)
|
("sectors", sector, sectorbackup)
|
||||||
("numwalls", numwalls)
|
("numwalls", numwalls)
|
||||||
("walls", wall, wallbackup)
|
("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)
|
("tailspritefree", tailspritefree)
|
||||||
("myconnectindex", myconnectindex)
|
("myconnectindex", myconnectindex)
|
||||||
|
@ -729,15 +714,6 @@ void SerializeMap(FSerializer& arc)
|
||||||
arc.EndObject();
|
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())
|
if (arc.isReading())
|
||||||
{
|
{
|
||||||
setWallSectors();
|
setWallSectors();
|
||||||
|
|
|
@ -82,12 +82,18 @@ void EndLevel(void)
|
||||||
TArray<DBloodActor*> SpawnActors(BloodSpawnSpriteDef& sprites)
|
TArray<DBloodActor*> SpawnActors(BloodSpawnSpriteDef& sprites)
|
||||||
{
|
{
|
||||||
TArray<DBloodActor*> spawns(sprites.sprites.Size(), true);
|
TArray<DBloodActor*> spawns(sprites.sprites.Size(), true);
|
||||||
initspritelists();
|
InitSpriteLists();
|
||||||
|
int j = 0;
|
||||||
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
|
for (unsigned i = 0; i < sprites.sprites.Size(); i++)
|
||||||
{
|
{
|
||||||
RemoveSpriteStat(i);
|
if (sprites.sprites[i].statnum == MAXSTATUS)
|
||||||
auto actor = &bloodActors[i];
|
{
|
||||||
spawns[i] = actor;
|
spawns.Pop();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto sprt = &sprites.sprites[i];
|
||||||
|
auto actor = InsertSprite(sprt->sector(), sprt->statnum);
|
||||||
|
spawns[j++] = actor;
|
||||||
actor->Clear();
|
actor->Clear();
|
||||||
actor->s() = sprites.sprites[i];
|
actor->s() = sprites.sprites[i];
|
||||||
if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i];
|
if (sprites.sprext.Size()) actor->sx() = sprites.sprext[i];
|
||||||
|
@ -99,11 +105,7 @@ TArray<DBloodActor*> SpawnActors(BloodSpawnSpriteDef& sprites)
|
||||||
actor->addX();
|
actor->addX();
|
||||||
actor->x() = sprites.xspr[i];
|
actor->x() = sprites.xspr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertSpriteSect(i, actor->s().sectnum);
|
|
||||||
InsertSpriteStat(i, actor->s().statnum);
|
|
||||||
}
|
}
|
||||||
Numsprites = spawns.Size();
|
|
||||||
return spawns;
|
return spawns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,8 +509,6 @@ void GameInterface::app_init()
|
||||||
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
||||||
ReadAllRFS();
|
ReadAllRFS();
|
||||||
|
|
||||||
HookReplaceFunctions();
|
|
||||||
|
|
||||||
levelLoadDefaults();
|
levelLoadDefaults();
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
|
|
|
@ -177,14 +177,4 @@ inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)
|
||||||
GetSpriteExtents(&actor->s(), top, 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
|
END_BLD_NS
|
||||||
|
|
|
@ -41,6 +41,31 @@ BEGIN_BLD_NS
|
||||||
DBloodActor bloodActors[kMaxSprites];
|
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;
|
bool gModernMap = false;
|
||||||
unsigned int gStatCount[kMaxStatus + 1];
|
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;
|
bool drawtile2048, encrypted;
|
||||||
|
|
||||||
MAPHEADER2 byte_19AE44;
|
MAPHEADER2 byte_19AE44;
|
||||||
|
@ -436,7 +276,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
|
||||||
#endif
|
#endif
|
||||||
* pSector = §or[mapHeader.sect];
|
* pSector = §or[mapHeader.sect];
|
||||||
|
|
||||||
dbInit();
|
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
{
|
{
|
||||||
fr.Read(&byte_19AE44, 128);
|
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;
|
Blood::BloodSpawnSpriteDef sprites;
|
||||||
sectortype* sp;
|
sectortype* sp;
|
||||||
Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, daang, &sp, nullptr, sprites);
|
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
|
#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);
|
DBloodActor* InsertSprite(sectortype* pSector, int nStat);
|
||||||
int DeleteSprite(DBloodActor* actor);
|
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);
|
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);
|
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 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);
|
void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer);
|
||||||
int qanimateoffs(int a1, int a2);
|
int qanimateoffs(int a1, int a2);
|
||||||
void HookReplaceFunctions();
|
|
||||||
|
|
||||||
struct PLAYER;
|
struct PLAYER;
|
||||||
|
|
||||||
|
|
|
@ -61,13 +61,4 @@ int qanimateoffs(int a1, int a2)
|
||||||
return offset;
|
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
|
END_BLD_NS
|
||||||
|
|
|
@ -78,7 +78,7 @@ void deletesprite(DDukeActor *const actor)
|
||||||
S_StopSound(actor->s->lotag, actor);
|
S_StopSound(actor->s->lotag, actor);
|
||||||
else
|
else
|
||||||
S_RelinkActorSound(actor, nullptr);
|
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
|
// 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_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);
|
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*> spawns(sprites.sprites.Size(), true);
|
||||||
TArray<DDukeActor*> actorlist;
|
InitSpriteLists();
|
||||||
for(unsigned i = 0; i < spawns.sprites.Size(); i++)
|
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;
|
||||||
}
|
}
|
||||||
return actorlist;
|
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 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.
|
// sector pointer must be strictly validated here or the engine will crash.
|
||||||
if (whatsectp == nullptr || !validSectorIndex(sectnum(whatsectp))) return nullptr;
|
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)
|
if (act == nullptr) return nullptr;
|
||||||
I_Error(" Too many sprites spawned.");
|
|
||||||
|
|
||||||
auto act = &hittype[i];
|
|
||||||
auto s = act->s;
|
auto s = act->s;
|
||||||
|
|
||||||
s->x = s_x;
|
s->x = s_x;
|
||||||
|
|
|
@ -220,11 +220,7 @@ Collision MoveCreature(DExhumedActor* nSprite);
|
||||||
Collision MoveCreatureWithCaution(DExhumedActor* actor);
|
Collision MoveCreatureWithCaution(DExhumedActor* actor);
|
||||||
void WheresMyMouth(int nPlayer, vec3_t* pos, sectortype** sectnum);
|
void WheresMyMouth(int nPlayer, vec3_t* pos, sectortype** sectnum);
|
||||||
int GetActorHeight(DExhumedActor* nSprite);
|
int GetActorHeight(DExhumedActor* nSprite);
|
||||||
DExhumedActor* insertActor(int, int);
|
DExhumedActor* insertActor(sectortype* s, int st);
|
||||||
inline DExhumedActor* insertActor(sectortype* s, int st)
|
|
||||||
{
|
|
||||||
return insertActor(sector.IndexOf(s), st);
|
|
||||||
}
|
|
||||||
DExhumedActor* GrabBody();
|
DExhumedActor* GrabBody();
|
||||||
DExhumedActor* GrabBodyGunSprite();
|
DExhumedActor* GrabBodyGunSprite();
|
||||||
void FuncCreatureChunk(int a, int, int nRun);
|
void FuncCreatureChunk(int a, int, int nRun);
|
||||||
|
|
|
@ -503,12 +503,11 @@ void DeleteActor(DExhumedActor* actor)
|
||||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
FVector3 pos = GetSoundPos(&actor->s().pos);
|
||||||
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
||||||
|
|
||||||
deletesprite(actor->GetSpriteIndex());
|
|
||||||
actor->s().ox = 0x80000000;
|
|
||||||
|
|
||||||
if (actor == bestTarget) {
|
if (actor == bestTarget) {
|
||||||
bestTarget = nullptr;
|
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*> spawns(sprites.sprites.Size(), true);
|
||||||
TArray<DExhumedActor*> actorlist;
|
InitSpriteLists();
|
||||||
for (unsigned i = 0; i < spawns.sprites.Size(); i++)
|
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;
|
||||||
}
|
}
|
||||||
return actorlist;
|
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 spawns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t LoadLevel(MapRecord* map)
|
uint8_t LoadLevel(MapRecord* map)
|
||||||
{
|
{
|
||||||
if (map->gameflags & LEVEL_EX_COUNTDOWN)
|
if (map->gameflags & LEVEL_EX_COUNTDOWN)
|
||||||
|
@ -87,9 +99,6 @@ uint8_t LoadLevel(MapRecord* map)
|
||||||
nEnergyTowers = 0;
|
nEnergyTowers = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
initspritelists();
|
|
||||||
|
|
||||||
|
|
||||||
// init stuff
|
// init stuff
|
||||||
{
|
{
|
||||||
StopAllSounds();
|
StopAllSounds();
|
||||||
|
|
|
@ -469,10 +469,9 @@ int GetActorHeight(DExhumedActor* actor)
|
||||||
return tileHeight(actor->s().picnum) * actor->s().yrepeat * 4;
|
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 static_cast<DExhumedActor*>(::InsertActor(s, st));
|
||||||
return ndx >= 0 ? &exhumedActors[ndx] : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
vec3_t hit_pos = { hit_x, hit_y, hit_z };
|
||||||
// need correct location for spawning shrap
|
// need correct location for spawning shrap
|
||||||
auto breakActor = InsertActor(0, STAT_DEFAULT);
|
auto breakActor = insertActor(0, STAT_DEFAULT);
|
||||||
auto bsp = &breakActor->s();
|
auto bsp = &breakActor->s();
|
||||||
bsp->cstat = 0;
|
bsp->cstat = 0;
|
||||||
bsp->extra = 0;
|
bsp->extra = 0;
|
||||||
|
|
|
@ -1155,7 +1155,7 @@ void BunnyHatch(DSWActor* actor)
|
||||||
|
|
||||||
for (int i = 0; i < MAX_BUNNYS; i++)
|
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 = &actorNew->s();
|
||||||
np->clear();
|
np->clear();
|
||||||
np->x = sp->x;
|
np->x = sp->x;
|
||||||
|
@ -1218,7 +1218,7 @@ DSWActor* BunnyHatch2(DSWActor* actor)
|
||||||
SPRITEp wp = &actor->s();
|
SPRITEp wp = &actor->s();
|
||||||
|
|
||||||
|
|
||||||
auto actorNew = InsertActor(wp->sector(), STAT_DEFAULT);
|
auto actorNew = insertActor(wp->sector(), STAT_DEFAULT);
|
||||||
auto np = &actorNew->s();
|
auto np = &actorNew->s();
|
||||||
np->clear();
|
np->clear();
|
||||||
np->x = wp->x;
|
np->x = wp->x;
|
||||||
|
|
|
@ -547,7 +547,7 @@ DSWActor* CopySprite(sprt const* tsp, sectortype* newsector)
|
||||||
{
|
{
|
||||||
SPRITEp sp;
|
SPRITEp sp;
|
||||||
|
|
||||||
auto actorNew = InsertActor(newsector, STAT_FAF_COPY);
|
auto actorNew = insertActor(newsector, STAT_FAF_COPY);
|
||||||
sp = &actorNew->s();
|
sp = &actorNew->s();
|
||||||
|
|
||||||
sp->x = tsp->x;
|
sp->x = tsp->x;
|
||||||
|
@ -1277,7 +1277,7 @@ PostDraw(void)
|
||||||
while (auto actor = it.Next())
|
while (auto actor = it.Next())
|
||||||
{
|
{
|
||||||
actor->clearUser();
|
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)
|
void InitLevel(MapRecord *maprec)
|
||||||
{
|
{
|
||||||
Terminate3DSounds();
|
Terminate3DSounds();
|
||||||
|
@ -330,7 +350,7 @@ void InitLevel(MapRecord *maprec)
|
||||||
int cursect;
|
int cursect;
|
||||||
SpawnSpriteDef sprites;
|
SpawnSpriteDef sprites;
|
||||||
engineLoadBoard(maprec->fileName, SW_SHAREWARE ? 1 : 0, &Player[0].pos, &ang, &cursect, sprites);
|
engineLoadBoard(maprec->fileName, SW_SHAREWARE ? 1 : 0, &Player[0].pos, &ang, &cursect, sprites);
|
||||||
insertAllSprites(sprites);
|
spawnactors(sprites);
|
||||||
Player[0].cursector = §or[cursect];
|
Player[0].cursector = §or[cursect];
|
||||||
|
|
||||||
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
||||||
|
|
|
@ -2103,11 +2103,7 @@ void SetSpikeActive(DSWActor*); // spike.c
|
||||||
#define NTAG_SEARCH_HI 2
|
#define NTAG_SEARCH_HI 2
|
||||||
#define NTAG_SEARCH_LO_HI 3
|
#define NTAG_SEARCH_LO_HI 3
|
||||||
|
|
||||||
DSWActor* InsertActor(int sectnum, int statnum);
|
DSWActor* insertActor(sectortype* sect, int statnum);
|
||||||
inline DSWActor* InsertActor(sectortype* sect, int statnum)
|
|
||||||
{
|
|
||||||
return InsertActor(sectnum(sect), statnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioUpdate(void); // stupid
|
void AudioUpdate(void); // stupid
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ BEGIN_SW_NS
|
||||||
|
|
||||||
void CopyQuakeSpotToOn(SPRITEp sp)
|
void CopyQuakeSpotToOn(SPRITEp sp)
|
||||||
{
|
{
|
||||||
auto actorNew = InsertActor(sp->sector(), STAT_QUAKE_SPOT);
|
auto actorNew = insertActor(sp->sector(), STAT_QUAKE_SPOT);
|
||||||
auto np = &actorNew->s();
|
auto np = &actorNew->s();
|
||||||
|
|
||||||
memcpy(np, sp, sizeof(SPRITE));
|
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)
|
short tics, short amt, int radius)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto actorNew = InsertActor(sect, STAT_QUAKE_ON);
|
auto actorNew = insertActor(sect, STAT_QUAKE_ON);
|
||||||
auto sp = &actorNew->s();
|
auto sp = &actorNew->s();
|
||||||
|
|
||||||
sp->x = x;
|
sp->x = x;
|
||||||
|
|
|
@ -1216,7 +1216,7 @@ void RipperHatch(DSWActor* actor)
|
||||||
|
|
||||||
for (int i = 0; i < MAX_RIPPERS; i++)
|
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 = &actorNew->s();
|
||||||
np->clear();
|
np->clear();
|
||||||
ClearOwner(actorNew);
|
ClearOwner(actorNew);
|
||||||
|
|
|
@ -1234,7 +1234,7 @@ void Ripper2Hatch(DSWActor* actor)
|
||||||
|
|
||||||
for (int i = 0; i < MAX_RIPPER2S; i++)
|
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 = &actorNew->s();
|
||||||
np->clear();
|
np->clear();
|
||||||
ClearOwner(actorNew);
|
ClearOwner(actorNew);
|
||||||
|
|
|
@ -54,15 +54,11 @@ SAVE save;
|
||||||
|
|
||||||
bool FAF_DebugView = false;
|
bool FAF_DebugView = false;
|
||||||
|
|
||||||
DSWActor* InsertActor(int sectnum, int stat)
|
DSWActor* insertActor(sectortype* sect, int statnum)
|
||||||
{
|
{
|
||||||
short spnum;
|
auto pActor = static_cast<DSWActor*>(::InsertActor(sect, statnum));
|
||||||
spnum = insertsprite(sectnum, stat);
|
|
||||||
auto pActor = &swActors[spnum];
|
|
||||||
auto pSprite = &pActor->s();
|
auto pSprite = &pActor->s();
|
||||||
|
|
||||||
PRODUCTION_ASSERT(spnum >= 0);
|
|
||||||
|
|
||||||
pSprite->x = pSprite->y = pSprite->z = 0;
|
pSprite->x = pSprite->y = pSprite->z = 0;
|
||||||
pSprite->cstat = 0;
|
pSprite->cstat = 0;
|
||||||
pSprite->picnum = 0;
|
pSprite->picnum = 0;
|
||||||
|
|
|
@ -774,7 +774,7 @@ void KillActor(DSWActor* actor)
|
||||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
FVector3 pos = GetSoundPos(&actor->s().pos);
|
||||||
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
||||||
|
|
||||||
deletesprite(actor->GetSpriteIndex());
|
::DeleteActor(actor);
|
||||||
// shred your garbage
|
// shred your garbage
|
||||||
sp->clear();
|
sp->clear();
|
||||||
|
|
||||||
|
@ -918,7 +918,7 @@ DSWActor* SpawnActor(int stat, int id, STATEp state, sectortype* sect, int x, in
|
||||||
|
|
||||||
ASSERT(!Prediction);
|
ASSERT(!Prediction);
|
||||||
|
|
||||||
auto spawnedActor = InsertActor(sect, stat);
|
auto spawnedActor = insertActor(sect, stat);
|
||||||
|
|
||||||
sp = &spawnedActor->s();
|
sp = &spawnedActor->s();
|
||||||
|
|
||||||
|
@ -983,7 +983,7 @@ bool ActorTestSpawn(DSWActor* actor)
|
||||||
auto sp = &actor->s();
|
auto sp = &actor->s();
|
||||||
if (sp->statnum == STAT_DEFAULT && sp->lotag == TAG_SPAWN_ACTOR)
|
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!
|
int t = actorNew->s().time; // must be preserved!
|
||||||
actorNew->s() = *sp;
|
actorNew->s() = *sp;
|
||||||
actorNew->s().time = t;
|
actorNew->s().time = t;
|
||||||
|
@ -2570,7 +2570,7 @@ void SpriteSetup(void)
|
||||||
change_actor_stat(actor, STAT_CLIMB_MARKER);
|
change_actor_stat(actor, STAT_CLIMB_MARKER);
|
||||||
|
|
||||||
// make a QUICK_LADDER sprite automatically
|
// 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();
|
auto np = &ns->s();
|
||||||
|
|
||||||
np->cstat = 0;
|
np->cstat = 0;
|
||||||
|
@ -3618,7 +3618,7 @@ int ActorCoughItem(DSWActor* actor)
|
||||||
{
|
{
|
||||||
case SAILORGIRL_R0:
|
case SAILORGIRL_R0:
|
||||||
ASSERT(sp->insector());
|
ASSERT(sp->insector());
|
||||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||||
np = &actorNew->s();
|
np = &actorNew->s();
|
||||||
np->cstat = np->extra = 0;
|
np->cstat = np->extra = 0;
|
||||||
np->x = sp->x;
|
np->x = sp->x;
|
||||||
|
@ -3659,7 +3659,7 @@ int ActorCoughItem(DSWActor* actor)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ASSERT(sp->insector());
|
ASSERT(sp->insector());
|
||||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||||
np = &actorNew->s();
|
np = &actorNew->s();
|
||||||
np->cstat = np->extra = 0;
|
np->cstat = np->extra = 0;
|
||||||
np->x = sp->x;
|
np->x = sp->x;
|
||||||
|
@ -3687,7 +3687,7 @@ int ActorCoughItem(DSWActor* actor)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ASSERT(sp->insector());
|
ASSERT(sp->insector());
|
||||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||||
np = &actorNew->s();
|
np = &actorNew->s();
|
||||||
np->cstat = np->extra = 0;
|
np->cstat = np->extra = 0;
|
||||||
np->x = sp->x;
|
np->x = sp->x;
|
||||||
|
@ -3718,7 +3718,7 @@ int ActorCoughItem(DSWActor* actor)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ASSERT(sp->insector());
|
ASSERT(sp->insector());
|
||||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||||
np = &actorNew->s();
|
np = &actorNew->s();
|
||||||
np->cstat = 0;
|
np->cstat = 0;
|
||||||
np->extra = 0;
|
np->extra = 0;
|
||||||
|
@ -3781,7 +3781,7 @@ int ActorCoughItem(DSWActor* actor)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ASSERT(sp->insector());
|
ASSERT(sp->insector());
|
||||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||||
np = &actorNew->s();
|
np = &actorNew->s();
|
||||||
np->cstat = np->extra = 0;
|
np->cstat = np->extra = 0;
|
||||||
np->x = sp->x;
|
np->x = sp->x;
|
||||||
|
@ -3839,7 +3839,7 @@ int ActorCoughItem(DSWActor* actor)
|
||||||
case PACHINKO4:
|
case PACHINKO4:
|
||||||
|
|
||||||
ASSERT(sp->insector());
|
ASSERT(sp->insector());
|
||||||
actorNew = InsertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
actorNew = insertActor(sp->sector(), STAT_SPAWN_ITEMS);
|
||||||
np = &actorNew->s();
|
np = &actorNew->s();
|
||||||
np->cstat = np->extra = 0;
|
np->cstat = np->extra = 0;
|
||||||
np->x = sp->x;
|
np->x = sp->x;
|
||||||
|
|
|
@ -313,7 +313,7 @@ DSWActor* TrackClonePoint(DSWActor* actor)
|
||||||
{
|
{
|
||||||
SPRITEp sp = &actor->s(), np;
|
SPRITEp sp = &actor->s(), np;
|
||||||
|
|
||||||
auto actorNew = InsertActor(sp->sector(), sp->statnum);
|
auto actorNew = insertActor(sp->sector(), sp->statnum);
|
||||||
|
|
||||||
np = &actorNew->s();
|
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();
|
sp = &actorNew->s();
|
||||||
SetOwner(parentActor, actorNew);
|
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)
|
if (sect->floorpal == PALETTE_FOG)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto actorNew = InsertActor(sect, STAT_VIS_ON);
|
auto actorNew = insertActor(sect, STAT_VIS_ON);
|
||||||
sp = &actorNew->s();
|
sp = &actorNew->s();
|
||||||
|
|
||||||
sp->x = x;
|
sp->x = x;
|
||||||
|
|
|
@ -16069,7 +16069,7 @@ DSWActor* SpawnWallHole(sectortype* hit_sect, walltype* hit_wall, int hit_x, int
|
||||||
short w,nw,wall_ang;
|
short w,nw,wall_ang;
|
||||||
SPRITEp sp;
|
SPRITEp sp;
|
||||||
|
|
||||||
auto actor = InsertActor(hit_sect, STAT_DEFAULT);
|
auto actor = insertActor(hit_sect, STAT_DEFAULT);
|
||||||
sp = &actor->s();
|
sp = &actor->s();
|
||||||
sp->xrepeat = sp->yrepeat = 16;
|
sp->xrepeat = sp->yrepeat = 16;
|
||||||
sp->cstat = 0;
|
sp->cstat = 0;
|
||||||
|
@ -18602,7 +18602,7 @@ void QueueHole(sectortype* hit_sect, walltype* hit_wall, int hit_x, int hit_y, i
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HoleQueue[HoleQueueHead] == nullptr)
|
if (HoleQueue[HoleQueueHead] == nullptr)
|
||||||
HoleQueue[HoleQueueHead] = spawnedActor = InsertActor(hit_sect, STAT_HOLE_QUEUE);
|
HoleQueue[HoleQueueHead] = spawnedActor = insertActor(hit_sect, STAT_HOLE_QUEUE);
|
||||||
else
|
else
|
||||||
spawnedActor = HoleQueue[HoleQueueHead];
|
spawnedActor = HoleQueue[HoleQueueHead];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue