raze/source/games/duke/src/premap_d.cpp

511 lines
11 KiB
C++
Raw Normal View History

//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements)
2020-06-28 07:03:31 +00:00
Copyright (C) 2020 - Christoph Oelckers
This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
EDuke enhancements integrated: 04/13/2003 - Matt Saettler
Note: EDuke source was in transition. Changes are in-progress in the
source as it is released.
*/
//-------------------------------------------------------------------------
#include "ns.h"
#include "global.h"
#include "build.h"
#include "names_d.h"
#include "dukeactor.h"
#include "precache.h"
BEGIN_DUKE_NS
inline void tloadtile(int tilenum, int palnum = 0)
{
2020-07-20 21:21:27 +00:00
assert(tilenum < MAXTILES);
markTileForPrecache(tilenum, palnum);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-10-28 05:20:29 +00:00
static void cachespritenum(spritetype *spr)
{
2020-07-20 21:21:27 +00:00
int maxc;
int j;
2020-10-28 05:20:29 +00:00
int pal = spr->pal;
2020-10-28 05:20:29 +00:00
if(ud.monsters_off && badguy(spr)) return;
2020-07-20 21:21:27 +00:00
maxc = 1;
2020-10-28 05:20:29 +00:00
switch(spr->picnum)
2020-07-20 21:21:27 +00:00
{
case HYDRENT:
tloadtile(BROKEFIREHYDRENT);
for(j = TOILETWATER; j < (TOILETWATER+4); j++)
tloadtile(j, pal);
break;
case TOILET:
tloadtile(TOILETBROKE);
for(j = TOILETWATER; j < (TOILETWATER+4); j++)
tloadtile(j, pal);
break;
case STALL:
tloadtile(STALLBROKE);
for(j = TOILETWATER; j < (TOILETWATER+4); j++)
tloadtile(j, pal);
break;
case RUBBERCAN:
maxc = 2;
break;
case TOILETWATER:
maxc = 4;
break;
case FEMPIC1:
maxc = 44;
break;
case LIZTROOP:
case LIZTROOPRUNNING:
case LIZTROOPSHOOT:
case LIZTROOPJETPACK:
case LIZTROOPONTOILET:
case LIZTROOPDUCKING:
for(j = LIZTROOP; j < (LIZTROOP+72); j++)
tloadtile(j, pal);
for(j=HEADJIB1;j<LEGJIB1+3;j++)
tloadtile(j, pal);
maxc = 0;
break;
case WOODENHORSE:
maxc = 5;
for(j = HORSEONSIDE; j < (HORSEONSIDE+4); j++)
tloadtile(j, pal);
break;
case NEWBEAST:
case NEWBEASTSTAYPUT:
maxc = 90;
break;
case BOSS1:
case BOSS2:
case BOSS3:
maxc = 30;
break;
case OCTABRAIN:
case OCTABRAINSTAYPUT:
case COMMANDER:
case COMMANDERSTAYPUT:
maxc = 38;
break;
case RECON:
maxc = 13;
break;
case PIGCOP:
case PIGCOPDIVE:
maxc = 61;
break;
case SHARK:
maxc = 30;
break;
case LIZMAN:
case LIZMANSPITTING:
case LIZMANFEEDING:
case LIZMANJUMP:
for(j=LIZMANHEAD1;j<LIZMANLEG1+3;j++)
tloadtile(j, pal);
maxc = 80;
break;
case APLAYER:
maxc = 0;
if(ud.multimode > 1)
{
maxc = 5;
for(j = 1420;j < 1420+106; j++)
tloadtile(j, pal);
}
break;
case ATOMICHEALTH:
maxc = 14;
break;
case DRONE:
maxc = 10;
break;
case EXPLODINGBARREL:
case SEENINE:
case OOZFILTER:
maxc = 3;
break;
case NUKEBARREL:
case CAMERA1:
maxc = 5;
break;
}
2020-10-28 05:20:29 +00:00
for(j = spr->picnum; j < (spr->picnum+maxc); j++)
2020-07-20 21:21:27 +00:00
tloadtile(j, pal);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void cachegoodsprites(void)
{
2020-07-20 21:21:27 +00:00
int i;
2020-07-20 21:21:27 +00:00
tloadtile(BOTTOMSTATUSBAR);
if (ud.multimode > 1)
{
tloadtile(FRAGBAR);
for (i = MINIFONT; i < MINIFONT + 63; i++)
tloadtile(i);
}
2020-07-20 21:21:27 +00:00
tloadtile(VIEWSCREEN);
2020-07-20 21:21:27 +00:00
for(i=FOOTPRINTS;i<FOOTPRINTS+3;i++)
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = BURNING; i < BURNING+14; i++)
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = BURNING2; i < BURNING2+14; i++)
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = CRACKKNUCKLES; i < CRACKKNUCKLES+4; i++)
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = FIRSTGUN; i < FIRSTGUN+3 ; i++ )
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = EXPLOSION2; i < EXPLOSION2+21 ; i++ )
tloadtile(i);
2020-07-20 21:21:27 +00:00
tloadtile(BULLETHOLE);
2020-07-20 21:21:27 +00:00
for( i = FIRSTGUNRELOAD; i < FIRSTGUNRELOAD+8 ; i++ )
tloadtile(i);
2020-07-20 21:21:27 +00:00
tloadtile(FOOTPRINTS);
2020-07-20 21:21:27 +00:00
for( i = JIBS1; i < (JIBS5+5); i++)
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = SCRAP1; i < (SCRAP1+19); i++)
tloadtile(i);
2020-07-20 21:21:27 +00:00
for( i = SMALLSMOKE; i < (SMALLSMOKE+4); i++)
tloadtile(i);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void cacheit_d(void)
{
2021-04-28 20:56:01 +00:00
if (!r_precache) return;
2020-07-20 21:21:27 +00:00
cachegoodsprites();
for (auto& wal : walls())
2020-07-20 21:21:27 +00:00
{
tloadtile(wal.picnum, wal.pal);
if (wal.overpicnum >= 0)
tloadtile(wal.overpicnum, wal.pal);
2020-07-20 21:21:27 +00:00
}
for (auto& sect : sectors())
2020-07-20 21:21:27 +00:00
{
tloadtile(sect.floorpicnum, sect.floorpal);
tloadtile(sect.ceilingpicnum, sect.ceilingpal);
if (sect.ceilingpicnum == LA)
2020-07-20 21:21:27 +00:00
{
tloadtile(LA + 1);
tloadtile(LA + 2);
}
DukeSectIterator it(&sect);
2020-10-28 05:20:29 +00:00
while (auto j = it.Next())
{
if (j->s->xrepeat != 0 && j->s->yrepeat != 0 && (j->s->cstat & 32768) == 0)
cachespritenum(j->s);
2020-10-28 05:20:29 +00:00
}
2020-07-20 21:21:27 +00:00
}
precacheMarkedTiles();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void spriteinit_d(DDukeActor* actor, TArray<DDukeActor*>& actors)
{
bool res = initspriteforspawn(actor, { CRACK1, CRACK2, CRACK3, CRACK4, SPEAKER, LETTER, DUCK, TARGET, TRIPBOMB, VIEWSCREEN, VIEWSCREEN2 });
if (res) spawninit_d(nullptr, actor, &actors);
}
void prelevel_d(int g, TArray<DDukeActor*>& actors)
{
2021-11-17 21:48:05 +00:00
int i, j, lotaglist;
2020-07-20 21:21:27 +00:00
short lotags[65];
prelevel_common(g);
2020-11-02 18:13:58 +00:00
DukeStatIterator it(STAT_DEFAULT);
while (auto ac = it.Next())
2020-07-20 21:21:27 +00:00
{
auto si = ac->s;
2020-10-23 18:27:05 +00:00
LoadActor(ac, -1, -1);
2020-07-20 21:21:27 +00:00
if (si->lotag == -1 && (si->cstat & 16))
2020-07-20 21:21:27 +00:00
{
ps[0].exitx = si->x;
ps[0].exity = si->y;
2020-07-20 21:21:27 +00:00
}
else switch (si->picnum)
2020-07-20 21:21:27 +00:00
{
case GPSPEED:
si->sector()->extra = si->lotag;
2020-11-02 18:13:58 +00:00
deletesprite(ac);
2020-07-20 21:21:27 +00:00
break;
case CYCLER:
if (numcyclers >= MAXCYCLERS)
I_Error("Too many cycling sectors.");
cyclers[numcyclers].sector = si->sector();
cyclers[numcyclers].lotag = si->lotag;
cyclers[numcyclers].shade1 = si->shade;
cyclers[numcyclers].shade2 = si->sector()->floorshade;
cyclers[numcyclers].hitag = si->hitag;
cyclers[numcyclers].state = (si->ang == 1536);
2020-07-20 21:21:27 +00:00
numcyclers++;
2020-11-02 18:13:58 +00:00
deletesprite(ac);
2020-07-20 21:21:27 +00:00
break;
}
}
2020-10-28 05:25:08 +00:00
for (auto actor : actors)
2020-07-20 21:21:27 +00:00
{
if (actor->exists())
2020-07-20 21:21:27 +00:00
{
auto spr = actor->s;
2020-10-28 05:25:08 +00:00
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
2020-07-20 21:21:27 +00:00
continue;
spriteinit_d(actor, actors);
2020-07-20 21:21:27 +00:00
}
}
for (auto actor : actors)
2020-10-28 05:25:08 +00:00
{
if (actor->exists())
2020-07-20 21:21:27 +00:00
{
auto spr = actor->s;
2020-10-28 05:25:08 +00:00
if (spr->picnum == SECTOREFFECTOR && spr->lotag == SE_14_SUBWAY_CAR)
spriteinit_d(actor, actors);
2020-07-20 21:21:27 +00:00
}
2020-10-28 05:25:08 +00:00
}
2020-07-20 21:21:27 +00:00
lotaglist = 0;
it.Reset(STAT_DEFAULT);
while (auto actor = it.Next())
2020-07-20 21:21:27 +00:00
{
auto spr = actor->s;
2020-10-28 05:25:08 +00:00
switch (spr->picnum)
2020-07-20 21:21:27 +00:00
{
case DIPSWITCH + 1:
case DIPSWITCH2 + 1:
case PULLSWITCH + 1:
case HANDSWITCH + 1:
case SLOTDOOR + 1:
case LIGHTSWITCH + 1:
case SPACELIGHTSWITCH + 1:
case SPACEDOORSWITCH + 1:
case FRANKENSTINESWITCH + 1:
case LIGHTSWITCH2 + 1:
case POWERSWITCH1 + 1:
case LOCKSWITCH1 + 1:
case POWERSWITCH2 + 1:
for (j = 0; j < lotaglist; j++)
2020-10-28 05:25:08 +00:00
if (spr->lotag == lotags[j])
2020-07-20 21:21:27 +00:00
break;
if (j == lotaglist)
{
2020-10-28 05:25:08 +00:00
lotags[lotaglist] = spr->lotag;
2020-07-20 21:21:27 +00:00
lotaglist++;
if (lotaglist > 64)
I_Error("Too many switches (64 max).");
2020-11-02 18:13:58 +00:00
DukeStatIterator it1(STAT_EFFECTOR);
while (auto ac = it1.Next())
2020-07-20 21:21:27 +00:00
{
if (ac->s->lotag == 12 && ac->s->hitag == spr->lotag)
2020-11-02 18:13:58 +00:00
ac->temp_data[0] = 1;
2020-07-20 21:21:27 +00:00
}
}
break;
}
}
mirrorcnt = 0;
2021-11-17 21:48:05 +00:00
for (auto& wal : walls())
2020-07-20 21:21:27 +00:00
{
if (wal.overpicnum == MIRROR && (wal.cstat & CSTAT_WALL_1WAY) != 0)
2020-07-20 21:21:27 +00:00
{
2021-11-17 21:48:05 +00:00
auto sectp = wal.nextSector();
2020-07-20 21:21:27 +00:00
if (mirrorcnt > 63)
I_Error("Too many mirrors (64 max.)");
if (sectp && sectp->ceilingpicnum != MIRROR)
2020-07-20 21:21:27 +00:00
{
sectp->ceilingpicnum = MIRROR;
sectp->floorpicnum = MIRROR;
2021-11-17 23:24:17 +00:00
mirrorwall[mirrorcnt] = &wal;
2021-11-17 23:27:03 +00:00
mirrorsector[mirrorcnt] = sectp;
2020-07-20 21:21:27 +00:00
mirrorcnt++;
continue;
}
}
if (numanimwalls >= MAXANIMWALLS)
I_Error("Too many 'anim' walls (max 512.)");
animwall[numanimwalls].tag = 0;
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = nullptr;
2020-07-20 21:21:27 +00:00
2021-11-17 21:48:05 +00:00
switch (wal.overpicnum)
2020-07-20 21:21:27 +00:00
{
case FANSHADOW:
case FANSPRITE:
wal.cstat |= CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN;
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = &wal;
2020-07-20 21:21:27 +00:00
numanimwalls++;
break;
case W_FORCEFIELD:
2021-11-17 21:48:05 +00:00
for (int j = 0; j < 3; j++)
2020-07-20 21:21:27 +00:00
tloadtile(W_FORCEFIELD + j);
[[fallthrough]];
2020-07-20 21:21:27 +00:00
case W_FORCEFIELD + 1:
case W_FORCEFIELD + 2:
2021-11-17 21:48:05 +00:00
if (wal.shade > 31)
wal.cstat = 0;
else wal.cstat |= 85 + 256;
2020-07-20 21:21:27 +00:00
if (wal.lotag && wal.twoSided())
2021-11-17 21:48:05 +00:00
wal.nextWall()->lotag = wal.lotag;
[[fallthrough]];
2020-07-20 21:21:27 +00:00
case BIGFORCE:
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = &wal;
2020-07-20 21:21:27 +00:00
numanimwalls++;
continue;
}
2021-11-17 21:48:05 +00:00
wal.extra = -1;
2020-07-20 21:21:27 +00:00
2021-11-17 21:48:05 +00:00
switch (wal.picnum)
2020-07-20 21:21:27 +00:00
{
case W_TECHWALL1:
case W_TECHWALL2:
case W_TECHWALL3:
case W_TECHWALL4:
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = &wal;
2020-07-20 21:21:27 +00:00
// animwall[numanimwalls].tag = -1;
numanimwalls++;
break;
case SCREENBREAK6:
case SCREENBREAK7:
case SCREENBREAK8:
2021-11-17 21:48:05 +00:00
for (int j = SCREENBREAK6; j < SCREENBREAK9; j++)
2020-07-20 21:21:27 +00:00
tloadtile(j);
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = &wal;
2020-07-20 21:21:27 +00:00
animwall[numanimwalls].tag = -1;
numanimwalls++;
break;
case FEMPIC1:
case FEMPIC2:
case FEMPIC3:
2021-11-17 21:48:05 +00:00
wal.extra = wal.picnum;
2020-07-20 21:21:27 +00:00
animwall[numanimwalls].tag = -1;
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = &wal;
2021-11-17 21:48:05 +00:00
animwall[numanimwalls].tag = wal.picnum;
2020-07-20 21:21:27 +00:00
numanimwalls++;
break;
case SCREENBREAK1:
case SCREENBREAK2:
case SCREENBREAK3:
case SCREENBREAK4:
case SCREENBREAK5:
case SCREENBREAK9:
case SCREENBREAK10:
case SCREENBREAK11:
case SCREENBREAK12:
case SCREENBREAK13:
case SCREENBREAK14:
case SCREENBREAK15:
case SCREENBREAK16:
case SCREENBREAK17:
case SCREENBREAK18:
case SCREENBREAK19:
2021-11-17 23:30:37 +00:00
animwall[numanimwalls].wall = &wal;
2021-11-17 21:48:05 +00:00
animwall[numanimwalls].tag = wal.picnum;
2020-07-20 21:21:27 +00:00
numanimwalls++;
break;
}
}
//Invalidate textures in sector behind mirror
for (i = 0; i < mirrorcnt; i++)
{
2021-11-17 21:48:05 +00:00
for (auto& wal : wallsofsector(mirrorsector[i]))
2020-07-20 21:21:27 +00:00
{
2021-11-17 21:48:05 +00:00
wal.picnum = MIRROR;
wal.overpicnum = MIRROR;
2020-07-20 21:21:27 +00:00
}
}
}
END_DUKE_NS