- 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 inline sectortype* spritetype::sector() const
{ {
#ifdef _DEBUG
return sectnum < 0? nullptr : &::sector[sectnum];
#else
return &::sector[sectnum]; return &::sector[sectnum];
#endif
} }
inline sectortype* walltype::nextSector() const inline sectortype* walltype::nextSector() const

View file

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

View file

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

View file

@ -138,14 +138,7 @@ inline DDukeActor* ScriptIndexToActor(int index)
return &hittype[index]; return &hittype[index];
} }
int spawn_d(int j, int pn); DDukeActor* spawn(DDukeActor* spawner, int type);
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];
}
inline int ldist(DDukeActor* s1, DDukeActor* s2) 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 lotsofglass(DDukeActor* snum, walltype* wallnum, int cnt);
void checkplayerhurt_d(struct player_struct* p, const Collision& coll); void checkplayerhurt_d(struct player_struct* p, const Collision& coll);
void checkplayerhurt_r(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 addspritetodelete(int spnum=0);
void checkavailinven(struct player_struct* p); 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 spawninitdefault(DDukeActor* actj, DDukeActor* act);
void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam); 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 initfootprint(DDukeActor* actj, DDukeActor* acti);
void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell); void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell);
void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE); 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) void prelevel_d(int g)
{ {
@ -318,7 +323,7 @@ void prelevel_d(int g)
{ {
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR) if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
continue; continue;
spawn(nullptr, i); spriteinit_d(i);
} }
} }
@ -328,7 +333,7 @@ void prelevel_d(int g)
if (spr->statnum < MAXSTATUS) if (spr->statnum < MAXSTATUS)
{ {
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR) if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
spawn(nullptr, i); spriteinit_d(i);
} }
} }
lotaglist = 0; 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) void prelevel_r(int g)
{ {
struct player_struct* p; struct player_struct* p;
@ -635,9 +641,9 @@ void prelevel_r(int g)
auto spr = &sprite[i]; auto spr = &sprite[i];
if (spr->statnum < MAXSTATUS) if (spr->statnum < MAXSTATUS)
{ {
if (spr->picnum == SECTOREFFECTOR && spr->lotag == 14) if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
continue; continue;
spawn(nullptr, i); spriteinit_r(i);
} }
} }
@ -646,8 +652,8 @@ void prelevel_r(int g)
auto spr = &sprite[i]; auto spr = &sprite[i];
if (spr->statnum < MAXSTATUS) if (spr->statnum < MAXSTATUS)
{ {
if (spr->picnum == SECTOREFFECTOR && spr->lotag == 14) if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
spawn(nullptr, i); spriteinit_r(i);
} }
if (spr->picnum == RRTILE19) if (spr->picnum == RRTILE19)
deletesprite(i); 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; auto act = &hittype[i];
int* t; auto sp = act->s;
int i = -1; 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) 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); 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) if (spawned)
{ {
spawned->picnum = actj->s->picnum; spawned->picnum = actj->s->picnum;
i = spawned->GetSpriteIndex(); return fi.spawninit(actj, spawned);
} }
} }
else return nullptr;
{
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;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -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 sp = acti->s;
auto s1 = sp->sector(); auto s1 = sp->sector();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff