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

903 lines
25 KiB
C++
Raw Normal View History

//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT
This file is part of 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
*/
//-------------------------------------------------------------------------
#include "ns.h"
#include "global.h"
#include "sounds_common.h"
#include "names_rr.h"
// PRIMITIVE
BEGIN_DUKE_NS
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
bool isadoorwall_r(int dapic)
{
switch(dapic)
{
case DOORTILE1:
case DOORTILE2:
case DOORTILE3:
case DOORTILE4:
case DOORTILE5:
case DOORTILE6:
case DOORTILE7:
case DOORTILE8:
case DOORTILE9:
case DOORTILE10:
case DOORTILE11:
case DOORTILE12:
case DOORTILE14:
case DOORTILE15:
case DOORTILE16:
case DOORTILE17:
case DOORTILE18:
case DOORTILE19:
case DOORTILE20:
case DOORTILE21:
case DOORTILE22:
case RRTILE1856:
case RRTILE1877:
return 1;
}
return 0;
}
bool isablockdoor(int dapic)
{
switch (dapic)
{
case RRTILE1792:
case RRTILE1801:
case RRTILE1805:
case RRTILE1807:
case RRTILE1808:
case RRTILE1812:
case RRTILE1821:
case RRTILE1826:
case RRTILE1850:
case RRTILE1851:
case RRTILE1856:
case RRTILE1877:
case RRTILE1938:
case RRTILE1942:
case RRTILE1944:
case RRTILE1945:
case RRTILE1951:
case RRTILE1961:
case RRTILE1964:
case RRTILE1985:
case RRTILE1995:
case RRTILE2022:
case RRTILE2052:
case RRTILE2053:
case RRTILE2060:
case RRTILE2074:
case RRTILE2132:
case RRTILE2136:
case RRTILE2139:
case RRTILE2150:
case RRTILE2178:
case RRTILE2186:
case RRTILE2319:
case RRTILE2321:
case RRTILE2326:
case RRTILE2329:
case RRTILE2578:
case RRTILE2581:
case RRTILE2610:
case RRTILE2613:
case RRTILE2621:
case RRTILE2622:
case RRTILE2676:
case RRTILE2732:
case RRTILE2831:
case RRTILE2832:
case RRTILE2842:
case RRTILE2940:
case RRTILE2970:
case RRTILE3083:
case RRTILE3100:
case RRTILE3155:
case RRTILE3195:
case RRTILE3232:
case RRTILE3600:
case RRTILE3631:
case RRTILE3635:
case RRTILE3637:
case RRTILE3643+2:
case RRTILE3643+3:
case RRTILE3647:
case RRTILE3652:
case RRTILE3653:
case RRTILE3671:
case RRTILE3673:
case RRTILE3684:
case RRTILE3708:
case RRTILE3714:
case RRTILE3716:
case RRTILE3723:
case RRTILE3725:
case RRTILE3737:
case RRTILE3754:
case RRTILE3762:
case RRTILE3763:
case RRTILE3764:
case RRTILE3765:
case RRTILE3767:
case RRTILE3793:
case RRTILE3814:
case RRTILE3815:
case RRTILE3819:
case RRTILE3827:
case RRTILE3837:
return true;
case RRTILE1996:
case RRTILE2382:
case RRTILE2961:
case RRTILE3804:
case RRTILE7430:
case RRTILE7467:
case RRTILE7469:
case RRTILE7470:
case RRTILE7475:
case RRTILE7566:
case RRTILE7576:
case RRTILE7716:
case RRTILE8063:
case RRTILE8067:
case RRTILE8076:
case RRTILE8106:
case RRTILE8379:
case RRTILE8380:
case RRTILE8565:
case RRTILE8605:
return isRRRA();
}
return false;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void animatewalls_r(void)
{
int i, j, p, t;
if (isRRRA() &&ps[screenpeek].sea_sick_stat == 1)
{
for (i = 0; i < MAXWALLS; i++)
{
if (wall[i].picnum == RRTILE7873)
wall[i].xpanning += 6;
else if (wall[i].picnum == RRTILE7870)
wall[i].xpanning += 6;
}
}
for (p = 0; p < numanimwalls; p++)
{
i = animwall[p].wallnum;
j = wall[i].picnum;
switch (j)
{
case SCREENBREAK1:
case SCREENBREAK2:
case SCREENBREAK3:
case SCREENBREAK4:
case SCREENBREAK5:
case SCREENBREAK9:
case SCREENBREAK10:
case SCREENBREAK11:
case SCREENBREAK12:
case SCREENBREAK13:
if ((krand() & 255) < 16)
{
animwall[p].tag = wall[i].picnum;
wall[i].picnum = SCREENBREAK6;
}
continue;
case SCREENBREAK6:
case SCREENBREAK7:
case SCREENBREAK8:
if (animwall[p].tag >= 0)
wall[i].picnum = animwall[p].tag;
else
{
wall[i].picnum++;
if (wall[i].picnum == (SCREENBREAK6 + 3))
wall[i].picnum = SCREENBREAK6;
}
continue;
}
if (wall[i].cstat & 16)
switch (wall[i].overpicnum)
{
case W_FORCEFIELD:
case W_FORCEFIELD + 1:
case W_FORCEFIELD + 2:
t = animwall[p].tag;
if (wall[i].cstat & 254)
{
wall[i].xpanning -= t >> 10; // sintable[(t+512)&2047]>>12;
wall[i].ypanning -= t >> 10; // sintable[t&2047]>>12;
if (wall[i].extra == 1)
{
wall[i].extra = 0;
animwall[p].tag = 0;
}
else
animwall[p].tag += 128;
if (animwall[p].tag < (128 << 4))
{
if (animwall[p].tag & 128)
wall[i].overpicnum = W_FORCEFIELD;
else wall[i].overpicnum = W_FORCEFIELD + 1;
}
else
{
if ((krand() & 255) < 32)
animwall[p].tag = 128 << (krand() & 3);
else wall[i].overpicnum = W_FORCEFIELD + 1;
}
}
break;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void operaterespawns_r(int low)
{
short i, j, nexti;
i = headspritestat[11];
while (i >= 0)
{
nexti = nextspritestat[i];
if (sprite[i].lotag == low) switch (sprite[i].picnum)
{
case RESPAWN:
if (badguypic(sprite[i].hitag) && ud.monsters_off) break;
j = spawn(i, TRANSPORTERSTAR);
sprite[j].z -= (32 << 8);
sprite[i].extra = 66 - 12; // Just a way to killit
break;
case RRTILE7424:
if (isRRRA() && !ud.monsters_off)
changespritestat(i, 119);
break;
}
i = nexti;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void operateforcefields_r(int s, int low)
{
operateforcefields_common(s, low, { BIGFORCE });
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
bool checkhitswitch_r(int snum, int w, int switchtype)
{
char switchpal;
short i, x, lotag, hitag, picnum, correctdips, numdips;
int sx, sy;
if (w < 0) return 0;
correctdips = 1;
numdips = 0;
if (switchtype == 1) // A wall sprite
{
lotag = sprite[w].lotag; if (lotag == 0) return 0;
hitag = sprite[w].hitag;
sx = sprite[w].x;
sy = sprite[w].y;
picnum = sprite[w].picnum;
switchpal = sprite[w].pal;
}
else
{
lotag = wall[w].lotag; if (lotag == 0) return 0;
hitag = wall[w].hitag;
sx = wall[w].x;
sy = wall[w].y;
picnum = wall[w].picnum;
switchpal = wall[w].pal;
}
switch (picnum)
{
case DIPSWITCH:
case DIPSWITCH + 1:
case TECHSWITCH:
case TECHSWITCH + 1:
case ALIENSWITCH:
case ALIENSWITCH + 1:
break;
case ACCESSSWITCH:
case ACCESSSWITCH2:
if (ps[snum].access_incs == 0)
{
if (switchpal == 0)
{
if (ps[snum].keys[1])
ps[snum].access_incs = 1;
else
{
FTA(70, &ps[snum]);
if (isRRRA()) spritesound(99, w);
}
}
else if (switchpal == 21)
{
if (ps[snum].keys[2])
ps[snum].access_incs = 1;
else
{
FTA(71, &ps[snum]);
if (isRRRA()) spritesound(99, w);
}
}
else if (switchpal == 23)
{
if (ps[snum].keys[3])
ps[snum].access_incs = 1;
else
{
FTA(72, &ps[snum]);
if (isRRRA()) spritesound(99, w);
}
}
if (ps[snum].access_incs == 1)
{
if (switchtype == 0)
ps[snum].access_wallnum = w;
else
ps[snum].access_spritenum = w;
}
return 0;
}
case MULTISWITCH2:
case MULTISWITCH2 + 1:
case MULTISWITCH2 + 2:
case MULTISWITCH2 + 3:
case RRTILE8464:
case RRTILE8660:
if (isRRRA()) break;
case DIPSWITCH2:
case DIPSWITCH2 + 1:
case DIPSWITCH3:
case DIPSWITCH3 + 1:
case MULTISWITCH:
case MULTISWITCH + 1:
case MULTISWITCH + 2:
case MULTISWITCH + 3:
case PULLSWITCH:
case PULLSWITCH + 1:
case HANDSWITCH:
case HANDSWITCH + 1:
case SLOTDOOR:
case SLOTDOOR + 1:
case LIGHTSWITCH:
case LIGHTSWITCH + 1:
case SPACELIGHTSWITCH:
case SPACELIGHTSWITCH + 1:
case SPACEDOORSWITCH:
case SPACEDOORSWITCH + 1:
case FRANKENSTINESWITCH:
case FRANKENSTINESWITCH + 1:
case LIGHTSWITCH2:
case LIGHTSWITCH2 + 1:
case POWERSWITCH1:
case POWERSWITCH1 + 1:
case LOCKSWITCH1:
case LOCKSWITCH1 + 1:
case POWERSWITCH2:
case POWERSWITCH2 + 1:
case NUKEBUTTON:
case NUKEBUTTON + 1:
case RRTILE2214:
case RRTILE2697:
case RRTILE2697 + 1:
case RRTILE2707:
case RRTILE2707 + 1:
if (check_activator_motion(lotag)) return 0;
break;
default:
if (isadoorwall(picnum) == 0) return 0;
break;
}
i = headspritestat[0];
while (i >= 0)
{
if (lotag == sprite[i].lotag) switch (sprite[i].picnum)
{
case DIPSWITCH:
case TECHSWITCH:
case ALIENSWITCH:
if (switchtype == 1 && w == i) sprite[i].picnum++;
else if (sprite[i].hitag == 0) correctdips++;
numdips++;
break;
case TECHSWITCH + 1:
case DIPSWITCH + 1:
case ALIENSWITCH + 1:
if (switchtype == 1 && w == i) sprite[i].picnum--;
else if (sprite[i].hitag == 1) correctdips++;
numdips++;
break;
case MULTISWITCH:
case MULTISWITCH + 1:
case MULTISWITCH + 2:
case MULTISWITCH + 3:
sprite[i].picnum++;
if (sprite[i].picnum > (MULTISWITCH + 3))
sprite[i].picnum = MULTISWITCH;
break;
case MULTISWITCH2:
case MULTISWITCH2 + 1:
case MULTISWITCH2 + 2:
case MULTISWITCH2 + 3:
if (!isRRRA()) break;
sprite[i].picnum++;
if (sprite[i].picnum > (MULTISWITCH2 + 3))
sprite[i].picnum = MULTISWITCH2;
break;
case RRTILE2214:
if (ud.level_number > 6)
ud.level_number = 0;
sprite[i].picnum++;
break;
case RRTILE8660:
if (!isRRRA()) break;
case ACCESSSWITCH:
case ACCESSSWITCH2:
case SLOTDOOR:
case LIGHTSWITCH:
case SPACELIGHTSWITCH:
case SPACEDOORSWITCH:
case FRANKENSTINESWITCH:
case LIGHTSWITCH2:
case POWERSWITCH1:
case LOCKSWITCH1:
case POWERSWITCH2:
case HANDSWITCH:
case PULLSWITCH:
case DIPSWITCH2:
case DIPSWITCH3:
case NUKEBUTTON:
case RRTILE2697:
case RRTILE2707:
if (sprite[i].picnum == DIPSWITCH3)
if (sprite[i].hitag == 999)
{
short j, nextj;
j = headspritestat[107];
while (j >= 0)
{
nextj = nextspritestat[j];
if (sprite[j].picnum == RRTILE3410)
{
sprite[j].picnum++;
sprite[j].hitag = 100;
sprite[j].extra = 0;
spritesound(474, j);
}
else if (sprite[j].picnum == RRTILE295)
deletesprite(j);
j = nextj;
}
sprite[i].picnum++;
break;
}
if (sprite[i].picnum == NUKEBUTTON)
chickenplant = 0;
if (sprite[i].picnum == RRTILE8660)
{
BellTime = 132;
word_119BE0 = i;
}
sprite[i].picnum++;
break;
case PULLSWITCH + 1:
case HANDSWITCH + 1:
case LIGHTSWITCH2 + 1:
case POWERSWITCH1 + 1:
case LOCKSWITCH1 + 1:
case POWERSWITCH2 + 1:
case SLOTDOOR + 1:
case LIGHTSWITCH + 1:
case SPACELIGHTSWITCH + 1:
case SPACEDOORSWITCH + 1:
case FRANKENSTINESWITCH + 1:
case DIPSWITCH2 + 1:
case DIPSWITCH3 + 1:
case NUKEBUTTON + 1:
case RRTILE2697 + 1:
case RRTILE2707 + 1:
if (sprite[i].picnum == NUKEBUTTON + 1)
chickenplant = 1;
if (sprite[i].hitag != 999)
sprite[i].picnum--;
break;
}
i = nextspritestat[i];
}
for (i = 0; i < numwalls; i++)
{
x = i;
if (lotag == wall[x].lotag)
switch (wall[x].picnum)
{
case DIPSWITCH:
case TECHSWITCH:
case ALIENSWITCH:
if (switchtype == 0 && i == w) wall[x].picnum++;
else if (wall[x].hitag == 0) correctdips++;
numdips++;
break;
case DIPSWITCH + 1:
case TECHSWITCH + 1:
case ALIENSWITCH + 1:
if (switchtype == 0 && i == w) wall[x].picnum--;
else if (wall[x].hitag == 1) correctdips++;
numdips++;
break;
case MULTISWITCH:
case MULTISWITCH + 1:
case MULTISWITCH + 2:
case MULTISWITCH + 3:
wall[x].picnum++;
if (wall[x].picnum > (MULTISWITCH + 3))
wall[x].picnum = MULTISWITCH;
break;
case MULTISWITCH2:
case MULTISWITCH2 + 1:
case MULTISWITCH2 + 2:
case MULTISWITCH2 + 3:
if (!isRRRA()) break;
wall[x].picnum++;
if (wall[x].picnum > (MULTISWITCH2 + 3))
wall[x].picnum = MULTISWITCH2;
break;
case RRTILE8660:
if (!isRRRA()) break;
case ACCESSSWITCH:
case ACCESSSWITCH2:
case SLOTDOOR:
case LIGHTSWITCH:
case SPACELIGHTSWITCH:
case SPACEDOORSWITCH:
case LIGHTSWITCH2:
case POWERSWITCH1:
case LOCKSWITCH1:
case POWERSWITCH2:
case PULLSWITCH:
case HANDSWITCH:
case DIPSWITCH2:
case DIPSWITCH3:
case RRTILE2697:
case RRTILE2707:
wall[x].picnum++;
break;
case HANDSWITCH + 1:
case PULLSWITCH + 1:
case LIGHTSWITCH2 + 1:
case POWERSWITCH1 + 1:
case LOCKSWITCH1 + 1:
case POWERSWITCH2 + 1:
case SLOTDOOR + 1:
case LIGHTSWITCH + 1:
case SPACELIGHTSWITCH + 1:
case SPACEDOORSWITCH + 1:
case DIPSWITCH2 + 1:
case DIPSWITCH3 + 1:
case RRTILE2697 + 1:
case RRTILE2707 + 1:
wall[x].picnum--;
break;
}
}
if (lotag == (short)65535)
{
ps[myconnectindex].gm = MODE_EOL;
if (ud.from_bonus)
{
ud.level_number = ud.from_bonus;
ud.m_level_number = ud.level_number;
ud.from_bonus = 0;
}
else
{
// fixme: This needs to be taken from the level definitions.
if (isRRRA() && ud.level_number == 6 && ud.volume_number == 0)
g_RAendEpisode = 1; // hack to force advancing to episode 2.
ud.level_number = (++ud.level_number < MAXLEVELS) ? ud.level_number : 0;
ud.m_level_number = ud.level_number;
}
}
vec3_t v = { sx, sy, ps[snum].posz };
switch (picnum)
{
default:
if (isadoorwall(picnum) == 0) break;
case DIPSWITCH:
case DIPSWITCH + 1:
case TECHSWITCH:
case TECHSWITCH + 1:
case ALIENSWITCH:
case ALIENSWITCH + 1:
if (picnum == DIPSWITCH || picnum == DIPSWITCH + 1 ||
picnum == ALIENSWITCH || picnum == ALIENSWITCH + 1 ||
picnum == TECHSWITCH || picnum == TECHSWITCH + 1)
{
if (picnum == ALIENSWITCH || picnum == ALIENSWITCH + 1)
{
if (switchtype == SWITCH_SPRITE)
S_PlaySound3D(ALIEN_SWITCH1, w, &v);
else S_PlaySound3D(ALIEN_SWITCH1, ps[snum].i, &v);
}
else
{
if (switchtype == SWITCH_SPRITE)
S_PlaySound3D(SWITCH_ON, w, &v);
else S_PlaySound3D(SWITCH_ON, ps[snum].i, &v);
}
if (numdips != correctdips) break;
S_PlaySound3D(END_OF_LEVEL_WARN, ps[snum].i, &v);
}
case MULTISWITCH2:
case MULTISWITCH2 + 1:
case MULTISWITCH2 + 2:
case MULTISWITCH2 + 3:
case RRTILE8464:
case RRTILE8660:
if (!isRRRA()) break;
case DIPSWITCH2:
case DIPSWITCH2 + 1:
case DIPSWITCH3:
case DIPSWITCH3 + 1:
case MULTISWITCH:
case MULTISWITCH + 1:
case MULTISWITCH + 2:
case MULTISWITCH + 3:
case ACCESSSWITCH:
case ACCESSSWITCH2:
case SLOTDOOR:
case SLOTDOOR + 1:
case LIGHTSWITCH:
case LIGHTSWITCH + 1:
case SPACELIGHTSWITCH:
case SPACELIGHTSWITCH + 1:
case SPACEDOORSWITCH:
case SPACEDOORSWITCH + 1:
case FRANKENSTINESWITCH:
case FRANKENSTINESWITCH + 1:
case LIGHTSWITCH2:
case LIGHTSWITCH2 + 1:
case POWERSWITCH1:
case POWERSWITCH1 + 1:
case LOCKSWITCH1:
case LOCKSWITCH1 + 1:
case POWERSWITCH2:
case POWERSWITCH2 + 1:
case HANDSWITCH:
case HANDSWITCH + 1:
case PULLSWITCH:
case PULLSWITCH + 1:
case RRTILE2697:
case RRTILE2697 + 1:
case RRTILE2707:
case RRTILE2707 + 1:
if (isRRRA())
{
if (picnum == RRTILE8660)
{
BellTime = 132;
word_119BE0 = w;
sprite[w].picnum++;
}
else if (picnum == RRTILE8464)
{
sprite[w].picnum = sprite[w].picnum + 1;
if (hitag == 10001)
{
if (ps[snum].SeaSick == 0)
ps[snum].SeaSick = 350;
operateactivators(668, ps[snum].i);
operatemasterswitches(668);
spritesound(328, ps[snum].i);
return 1;
}
}
else if (hitag == 10000)
{
if (picnum == MULTISWITCH || picnum == (MULTISWITCH + 1) ||
picnum == (MULTISWITCH + 2) || picnum == (MULTISWITCH + 3) ||
picnum == MULTISWITCH2 || picnum == (MULTISWITCH2 + 1) ||
picnum == (MULTISWITCH2 + 2) || picnum == (MULTISWITCH2 + 3))
{
int var6c[3], var54, j;
short jpn, jht;
var54 = 0;
S_PlaySound3D(SWITCH_ON, w, &v);
for (j = 0; j < MAXSPRITES; j++)
{
jpn = sprite[j].picnum;
jht = sprite[j].hitag;
if ((jpn == MULTISWITCH || jpn == MULTISWITCH2) && jht == 10000)
{
if (var54 < 3)
{
var6c[var54] = j;
var54++;
}
}
}
if (var54 == 3)
{
S_PlaySound3D(78, w, &v);
for (j = 0; j < var54; j++)
{
sprite[var6c[j]].hitag = 0;
if (picnum >= MULTISWITCH2)
sprite[var6c[j]].picnum = MULTISWITCH2 + 3;
else
sprite[var6c[j]].picnum = MULTISWITCH + 3;
checkhitswitch_r(snum, var6c[j], 1);
}
}
return 1;
}
}
}
if (picnum == MULTISWITCH || picnum == (MULTISWITCH + 1) ||
picnum == (MULTISWITCH + 2) || picnum == (MULTISWITCH + 3))
lotag += picnum - MULTISWITCH;
if (isRRRA())
{
if (picnum == MULTISWITCH2 || picnum == (MULTISWITCH2 + 1) ||
picnum == (MULTISWITCH2 + 2) || picnum == (MULTISWITCH2 + 3))
lotag += picnum - MULTISWITCH2;
}
x = headspritestat[3];
while (x >= 0)
{
if (((sprite[x].hitag) == lotag))
{
switch (sprite[x].lotag)
{
case 46:
case 47:
case 48:
if (!isRRRA()) break;
case 12:
sector[sprite[x].sectnum].floorpal = 0;
hittype[x].temp_data[0]++;
if (hittype[x].temp_data[0] == 2)
hittype[x].temp_data[0]++;
break;
case 24:
case 34:
case 25:
hittype[x].temp_data[4] = !hittype[x].temp_data[4];
if (hittype[x].temp_data[4])
FTA(15, &ps[snum]);
else FTA(2, &ps[snum]);
break;
case 21:
FTA(2, &ps[screenpeek]);
break;
}
}
x = nextspritestat[x];
}
operateactivators(lotag, snum);
operateforcefields(ps[snum].i, lotag);
operatemasterswitches(lotag);
if (picnum == DIPSWITCH || picnum == DIPSWITCH + 1 ||
picnum == ALIENSWITCH || picnum == ALIENSWITCH + 1 ||
picnum == TECHSWITCH || picnum == TECHSWITCH + 1) return 1;
if (hitag == 0 && isadoorwall(picnum) == 0)
{
if (switchtype == SWITCH_SPRITE)
S_PlaySound3D(SWITCH_ON, w, &v);
else S_PlaySound3D(SWITCH_ON, ps[snum].i, &v);
}
else if (hitag != 0)
{
auto flags = S_GetUserFlags(hitag);
if (switchtype == SWITCH_SPRITE && (flags & SF_TALK) == 0)
S_PlaySound3D(hitag, w, &v);
else
A_PlaySound(hitag, ps[snum].i);
}
return 1;
}
return 0;
}
END_DUKE_NS