- cleaned up Duke's spawn code.

The paths for initializing a map placed sprite and spawning a new actor at run time are now fully separate aside from the actual initialization of the actor.
This commit is contained in:
Christoph Oelckers 2021-11-19 10:41:50 +01:00
parent 4c7662b4ea
commit d5a6be3d96
10 changed files with 2653 additions and 2638 deletions

View file

@ -155,7 +155,11 @@ EXTERN int leveltimer;
inline sectortype* spritetype::sector() const
{
#ifdef _DEBUG
return sectnum < 0? nullptr : &::sector[sectnum];
#else
return &::sector[sectnum];
#endif
}
inline sectortype* walltype::nextSector() const

View file

@ -124,6 +124,7 @@ void SetDispatcher()
checkhitceiling_d,
checkhitsprite_d,
checksectors_d,
spawninit_d,
ceilingspace_d,
floorspace_d,
@ -167,6 +168,7 @@ void SetDispatcher()
checkhitceiling_r,
checkhitsprite_r,
checksectors_r,
spawninit_r,
ceilingspace_r,
floorspace_r,

View file

@ -88,6 +88,7 @@ struct Dispatcher
bool (*checkhitceiling)(sectortype* sn);
void (*checkhitsprite)(DDukeActor* i, DDukeActor* sn);
void (*checksectors)(int low);
DDukeActor* (*spawninit)(DDukeActor* actj, DDukeActor* act);
bool (*ceilingspace)(sectortype* sectp);
bool (*floorspace)(sectortype* sectp);

View file

@ -138,14 +138,7 @@ inline DDukeActor* ScriptIndexToActor(int index)
return &hittype[index];
}
int spawn_d(int j, int pn);
int spawn_r(int j, int pn);
inline DDukeActor* spawn(DDukeActor* spawner, int type)
{
int i = (isRR()? spawn_r : spawn_d)(spawner ? spawner->GetSpriteIndex() : -1, type);
return i == -1 ? nullptr : &hittype[i];
}
DDukeActor* spawn(DDukeActor* spawner, int type);
inline int ldist(DDukeActor* s1, DDukeActor* s2)
{

View file

@ -178,13 +178,19 @@ void lotsofcolourglass(DDukeActor* snum, walltype* wallNum, int cnt);
void lotsofglass(DDukeActor* snum, walltype* wallnum, int cnt);
void checkplayerhurt_d(struct player_struct* p, const Collision& coll);
void checkplayerhurt_r(struct player_struct* p, const Collision& coll);
DDukeActor* dospawnsprite(DDukeActor* actj, int pn);
void spriteinit_d(int);
void spriteinit_r(int);
DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act);
DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act);
void addspritetodelete(int spnum=0);
void checkavailinven(struct player_struct* p);
int initspriteforspawn(DDukeActor* j, int pn, const std::initializer_list<int> &excludes);
int initspriteforspawn(int spn, const std::initializer_list<int> &excludes);
void spawninitdefault(DDukeActor* actj, DDukeActor* act);
void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam);
int spawnbloodpoolpart1(DDukeActor* actj, DDukeActor* acti);
int spawnbloodpoolpart1(DDukeActor* acti);
void initfootprint(DDukeActor* actj, DDukeActor* acti);
void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell);
void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE);

View file

@ -269,6 +269,11 @@ void cacheit_d(void)
//
//
//---------------------------------------------------------------------------
void spriteinit_d(int i)
{
i = initspriteforspawn(i, { CRACK1, CRACK2, CRACK3, CRACK4, SPEAKER, LETTER, DUCK, TARGET, TRIPBOMB, VIEWSCREEN, VIEWSCREEN2 });
if ((i & 0x1000000)) spawninit_d(nullptr, &hittype[i&0xffffff]);
}
void prelevel_d(int g)
{
@ -318,7 +323,7 @@ void prelevel_d(int g)
{
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
continue;
spawn(nullptr, i);
spriteinit_d(i);
}
}
@ -328,7 +333,7 @@ void prelevel_d(int g)
if (spr->statnum < MAXSTATUS)
{
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
spawn(nullptr, i);
spriteinit_d(i);
}
}
lotaglist = 0;

View file

@ -407,6 +407,12 @@ void cacheit_r(void)
//
//---------------------------------------------------------------------------
void spriteinit_r(int i)
{
i = initspriteforspawn(i, { CRACK1, CRACK2, CRACK3, CRACK4 });
if ((i & 0x1000000)) spawninit_r(nullptr, &hittype[i & 0xffffff]);
}
void prelevel_r(int g)
{
struct player_struct* p;
@ -635,9 +641,9 @@ void prelevel_r(int g)
auto spr = &sprite[i];
if (spr->statnum < MAXSTATUS)
{
if (spr->picnum == SECTOREFFECTOR && spr->lotag == 14)
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
continue;
spawn(nullptr, i);
spriteinit_r(i);
}
}
@ -646,8 +652,8 @@ void prelevel_r(int g)
auto spr = &sprite[i];
if (spr->statnum < MAXSTATUS)
{
if (spr->picnum == SECTOREFFECTOR && spr->lotag == 14)
spawn(nullptr, i);
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
spriteinit_r(i);
}
if (spr->picnum == RRTILE19)
deletesprite(i);

View file

@ -137,96 +137,99 @@ DDukeActor* EGS(sectortype* whatsectp, int s_x, int s_y, int s_z, int s_pn, int8
//
//---------------------------------------------------------------------------
int initspriteforspawn(DDukeActor* actj, int pn, const std::initializer_list<int> &excludes)
int initspriteforspawn(int i, const std::initializer_list<int> &excludes)
{
spritetype* sp;
int* t;
int i = -1;
auto act = &hittype[i];
auto sp = act->s;
auto t = act->temp_data;
act->picnum = sp->picnum;
act->timetosleep = 0;
act->extra = -1;
sp->backuppos();
act->SetOwner(act);
act->SetHitOwner(act);
act->cgg = 0;
act->movflag = 0;
act->tempang = 0;
act->dispicnum = 0;
act->floorz = sp->sector()->floorz;
act->ceilingz = sp->sector()->ceilingz;
act->lastvx = 0;
act->lastvy = 0;
act->actorstayput = nullptr;
t[0] = t[1] = t[2] = t[3] = t[4] = t[5] = 0;
act->temp_actor = nullptr;
if (sp->cstat & 48)
if (!isIn(sp->picnum, excludes) && (sp->cstat & 48))
{
if (sp->shade == 127) return i;
if (wallswitchcheck(act) && (sp->cstat & 16))
{
if (sp->picnum != TILE_ACCESSSWITCH && sp->picnum != TILE_ACCESSSWITCH2 && sp->pal)
{
if ((ud.multimode < 2) || (ud.multimode > 1 && ud.coop == 1))
{
sp->xrepeat = sp->yrepeat = 0;
sp->cstat = sp->lotag = sp->hitag = 0;
return i;
}
}
sp->cstat |= 257;
if (sp->pal && sp->picnum != TILE_ACCESSSWITCH && sp->picnum != TILE_ACCESSSWITCH2)
sp->pal = 0;
return i;
}
if (sp->hitag)
{
changespritestat(i, 12);
sp->cstat |= 257;
sp->extra = gs.impact_damage;
return i;
}
}
int s = sp->picnum;
if (sp->cstat & 1) sp->cstat |= 256;
if (gs.actorinfo[s].scriptaddress)
{
sp->extra = ScriptCode[gs.actorinfo[s].scriptaddress];
t[4] = ScriptCode[gs.actorinfo[s].scriptaddress+1];
t[1] = ScriptCode[gs.actorinfo[s].scriptaddress+2];
int s3 = ScriptCode[gs.actorinfo[s].scriptaddress+3];
if (s3 && sp->hitag == 0)
sp->hitag = s3;
}
else t[1] = t[4] = 0;
return i | 0x1000000;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
DDukeActor* spawn(DDukeActor* actj, int pn)
{
if (actj)
{
auto spawned = EGS(actj->s->sector(), actj->s->x, actj->s->y, actj->s->z, pn, 0, 0, 0, 0, 0, 0, actj, 0);
if (spawned)
{
spawned->picnum = actj->s->picnum;
i = spawned->GetSpriteIndex();
return fi.spawninit(actj, spawned);
}
}
else
{
i = pn;
auto act = &hittype[i];
sp = act->s;
t = act->temp_data;
act->picnum = sp->picnum;
act->timetosleep = 0;
act->extra = -1;
sp->backuppos();
act->SetOwner(act);
act->SetHitOwner(act);
act->cgg = 0;
act->movflag = 0;
act->tempang = 0;
act->dispicnum = 0;
act->floorz = sp->sector()->floorz;
act->ceilingz = sp->sector()->ceilingz;
act->lastvx = 0;
act->lastvy = 0;
act->actorstayput = nullptr;
t[0] = t[1] = t[2] = t[3] = t[4] = t[5] = 0;
act->temp_actor = nullptr;
if (sp->cstat & 48)
if (!isIn(sp->picnum, excludes) && (sp->cstat & 48))
{
if (sp->shade == 127) return i;
if (wallswitchcheck(act) && (sp->cstat & 16))
{
if (sp->picnum != TILE_ACCESSSWITCH && sp->picnum != TILE_ACCESSSWITCH2 && sp->pal)
{
if ((ud.multimode < 2) || (ud.multimode > 1 && ud.coop == 1))
{
sp->xrepeat = sp->yrepeat = 0;
sp->cstat = sp->lotag = sp->hitag = 0;
return i;
}
}
sp->cstat |= 257;
if (sp->pal && sp->picnum != TILE_ACCESSSWITCH && sp->picnum != TILE_ACCESSSWITCH2)
sp->pal = 0;
return i;
}
if (sp->hitag)
{
changespritestat(i, 12);
sp->cstat |= 257;
sp->extra = gs.impact_damage;
return i;
}
}
int s = sp->picnum;
if (sp->cstat & 1) sp->cstat |= 256;
if (gs.actorinfo[s].scriptaddress)
{
sp->extra = ScriptCode[gs.actorinfo[s].scriptaddress];
t[4] = ScriptCode[gs.actorinfo[s].scriptaddress+1];
t[1] = ScriptCode[gs.actorinfo[s].scriptaddress+2];
int s3 = ScriptCode[gs.actorinfo[s].scriptaddress+3];
if (s3 && sp->hitag == 0)
sp->hitag = s3;
}
else t[1] = t[4] = 0;
}
return i | 0x1000000;
return nullptr;
}
//---------------------------------------------------------------------------
@ -342,7 +345,7 @@ void spawntransporter(DDukeActor *actj, DDukeActor* acti, bool beam)
//
//---------------------------------------------------------------------------
int spawnbloodpoolpart1(DDukeActor *actj, DDukeActor* acti)
int spawnbloodpoolpart1(DDukeActor* acti)
{
auto sp = acti->s;
auto s1 = sp->sector();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff