raze/source/games/duke/src/actors_lava.cpp
Christoph Oelckers ddcee4ecbf - split up g_visibility into two variables.
This is preparation for experimenting with the weapon flashes that can be quite annoying with how they brighten distant parts of the level far more than nearby parts.
2022-01-11 00:12:32 +01:00

640 lines
14 KiB
C++

//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT
Copyright (C) 2020 - Christoph Oelckers
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
aint 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 "names_r.h"
#include "serializer.h"
#include "savegamehelp.h"
#include "dukeactor.h"
#include "interpolate.h"
BEGIN_DUKE_NS
static int torchcnt;
static int jaildoorcnt;
static int minecartcnt;
static int lightnincnt;
static sectortype* torchsector[64];
static short torchsectorshade[64];
static short torchtype[64];
static short jaildoorsound[32];
static int jaildoordrag[32];
static int jaildoorspeed[32];
static short jaildoorsecthtag[32];
static int jaildoordist[32];
static short jaildoordir[32];
static short jaildooropen[32];
static sectortype* jaildoorsect[32];
static short minecartdir[16];
static int minecartspeed[16];
static sectortype* minecartchildsect[16];
static short minecartsound[16];
static int minecartdist[16];
static int minecartdrag[16];
static short minecartopen[16];
static sectortype* minecartsect[16];
static sectortype* lightninsector[64];
static short lightninsectorshade[64];
static uint8_t brightness;
static int thunderflash;
static int thundertime;
static int winderflash;
static int windertime;
void lava_cleararrays()
{
jaildoorcnt = 0;
minecartcnt = 0;
torchcnt = 0;
lightnincnt = 0;
}
void lava_serialize(FSerializer& arc)
{
arc("torchcnt", torchcnt)
("jaildoorcnt", jaildoorcnt)
("minecartcnt", minecartcnt)
("lightnincnt", lightnincnt);
if (torchcnt)
arc.Array("torchsector", torchsector, torchcnt)
.Array("torchsectorshade", torchsectorshade, torchcnt)
.Array("torchtype", torchtype, torchcnt);
if (jaildoorcnt)
arc.Array("jaildoorsound", jaildoorsound, jaildoorcnt)
.Array("jaildoordrag", jaildoordrag, jaildoorcnt)
.Array("jaildoorspeed", jaildoorspeed, jaildoorcnt)
.Array("jaildoorsecthtag", jaildoorsecthtag, jaildoorcnt)
.Array("jaildoordist", jaildoordist, jaildoorcnt)
.Array("jaildoordir", jaildoordir, jaildoorcnt)
.Array("jaildooropen", jaildooropen, jaildoorcnt)
.Array("jaildoorsect", jaildoorsect, jaildoorcnt);
if (minecartcnt)
arc.Array("minecartdir", minecartdir, minecartcnt)
.Array("minecartspeed", minecartspeed, minecartcnt)
.Array("minecartchildsect", minecartchildsect, minecartcnt)
.Array("minecartsound", minecartsound, minecartcnt)
.Array("minecartdist", minecartdist, minecartcnt)
.Array("minecartdrag", minecartdrag, minecartcnt)
.Array("minecartopen", minecartopen, minecartcnt)
.Array("minecartsect", minecartsect, minecartcnt);
if (lightnincnt)
arc.Array("lightninsector", lightninsector, lightnincnt)
.Array("lightninsectorshade", lightninsectorshade, lightnincnt);
arc("brightness", brightness)
("thunderflash", thunderflash)
("thundertime", thundertime)
("winderflash", winderflash)
("windertime", windertime);
}
void addtorch(DDukeActor* actor)
{
if (torchcnt >= 64)
I_Error("Too many torch effects");
torchsector[torchcnt] = actor->sector();
torchsectorshade[torchcnt] = actor->sector()->floorshade;
torchtype[torchcnt] = actor->spr.lotag;
torchcnt++;
}
void addlightning(DDukeActor* actor)
{
if (lightnincnt >= 64)
I_Error("Too many lightnin effects");
lightninsector[lightnincnt] = actor->sector();
lightninsectorshade[lightnincnt] = actor->sector()->floorshade;
lightnincnt++;
}
void addjaildoor(int p1, int p2, int iht, int jlt, int p3, sectortype* j)
{
if (jaildoorcnt >= 32)
I_Error("Too many jaildoor sectors");
if (jlt != 10 && jlt != 20 && jlt != 30 && jlt != 40)
{
Printf(PRINT_HIGH, "Bad direction %d for jail door with tag %d\n", jlt, iht);
return; // wouldn't work so let's skip it.
}
jaildoordist[jaildoorcnt] = p1;
jaildoorspeed[jaildoorcnt] = p2;
jaildoorsecthtag[jaildoorcnt] = iht;
jaildoorsect[jaildoorcnt] = j;
jaildoordrag[jaildoorcnt] = 0;
jaildooropen[jaildoorcnt] = 0;
jaildoordir[jaildoorcnt] = jlt;
jaildoorsound[jaildoorcnt] = p3;
setsectinterpolate(j);
jaildoorcnt++;
}
void addminecart(int p1, int p2, sectortype* i, int iht, int p3, sectortype* childsectnum)
{
if (minecartcnt >= 16)
I_Error("Too many minecart sectors");
minecartdist[minecartcnt] = p1;
minecartspeed[minecartcnt] = p2;
minecartsect[minecartcnt] = i;
minecartdir[minecartcnt] = i->hitag;
minecartdrag[minecartcnt] = p1;
minecartopen[minecartcnt] = 1;
minecartsound[minecartcnt] = p3;
minecartchildsect[minecartcnt] = childsectnum;
setsectinterpolate(i);
minecartcnt++;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void dotorch(void)
{
int ds;
uint8_t shade;
ds = krand()&8;
for (int i = 0; i < torchcnt; i++)
{
auto sect = torchsector[i];
shade = torchsectorshade[i] - ds;
switch (torchtype[i])
{
case 0:
sect->floorshade = shade;
sect->ceilingshade = shade;
break;
case 1:
sect->ceilingshade = shade;
break;
case 2:
sect->floorshade = shade;
break;
case 4:
sect->ceilingshade = shade;
break;
case 5:
sect->floorshade = shade;
break;
}
for (auto& wal : wallsofsector(sect))
{
if (wal.lotag != 1)
{
switch (torchtype[i])
{
case 0:
wal.shade = shade;
break;
case 1:
wal.shade = shade;
break;
case 2:
wal.shade = shade;
break;
case 3:
wal.shade = shade;
break;
}
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void dojaildoor(void)
{
for (int i = 0; i < jaildoorcnt; i++)
{
int speed;
auto sectp = jaildoorsect[i];
if (numplayers > 2)
speed = jaildoorspeed[i];
else
speed = jaildoorspeed[i];
if (speed < 2)
speed = 2;
if (jaildooropen[i] == 1)
{
jaildoordrag[i] -= speed;
if (jaildoordrag[i] <= 0)
{
jaildoordrag[i] = 0;
jaildooropen[i] = 2;
switch (jaildoordir[i])
{
case 10:
jaildoordir[i] = 30;
break;
case 20:
jaildoordir[i] = 40;
break;
case 30:
jaildoordir[i] = 10;
break;
case 40:
jaildoordir[i] = 20;
break;
}
}
else
{
for (auto& wal : wallsofsector(sectp))
{
int x = wal.pos.X;
int y = wal.pos.Y;
switch (jaildoordir[i])
{
case 10:
y += speed;
break;
case 20:
x -= speed;
break;
case 30:
y -= speed;
break;
case 40:
x += speed;
break;
}
dragpoint(&wal, x, y);
}
}
}
if (jaildooropen[i] == 3)
{
jaildoordrag[i] -= speed;
if (jaildoordrag[i] <= 0)
{
jaildoordrag[i] = 0;
jaildooropen[i] = 0;
switch (jaildoordir[i])
{
case 10:
jaildoordir[i] = 30;
break;
case 20:
jaildoordir[i] = 40;
break;
case 30:
jaildoordir[i] = 10;
break;
case 40:
jaildoordir[i] = 20;
break;
}
}
else
{
for (auto& wal : wallsofsector(sectp))
{
int x, y;
switch (jaildoordir[i])
{
default: // make case of bad parameters well defined.
x = wal.pos.X;
y = wal.pos.Y;
break;
case 10:
x = wal.pos.X;
y = wal.pos.Y + speed;
break;
case 20:
x = wal.pos.X - speed;
y = wal.pos.Y;
break;
case 30:
x = wal.pos.X;
y = wal.pos.Y - speed;
break;
case 40:
x = wal.pos.X + speed;
y = wal.pos.Y;
break;
}
dragpoint(&wal, x, y);
}
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void moveminecart(void)
{
int i;
int speed;
int y;
int x;
int cx;
int cy;
int max_x;
int min_y;
int max_y;
int min_x;
for (i = 0; i < minecartcnt; i++)
{
auto sectp = minecartsect[i];
speed = minecartspeed[i];
if (speed < 2)
speed = 2;
if (minecartopen[i] == 1)
{
minecartdrag[i] -= speed;
if (minecartdrag[i] <= 0)
{
minecartdrag[i] = minecartdist[i];
minecartopen[i] = 2;
switch (minecartdir[i])
{
case 10:
minecartdir[i] = 30;
break;
case 20:
minecartdir[i] = 40;
break;
case 30:
minecartdir[i] = 10;
break;
case 40:
minecartdir[i] = 20;
break;
}
}
else
{
for (auto& wal : wallsofsector(sectp))
{
switch (minecartdir[i])
{
default: // make case of bad parameters well defined.
x = wal.pos.X;
y = wal.pos.Y;
break;
case 10:
x = wal.pos.X;
y = wal.pos.Y + speed;
break;
case 20:
x = wal.pos.X - speed;
y = wal.pos.Y;
break;
case 30:
x = wal.pos.X;
y = wal.pos.Y - speed;
break;
case 40:
x = wal.pos.X + speed;
y = wal.pos.Y;
break;
}
dragpoint(&wal, x, y);
}
}
}
if (minecartopen[i] == 2)
{
minecartdrag[i] -= speed;
if (minecartdrag[i] <= 0)
{
minecartdrag[i] = minecartdist[i];
minecartopen[i] = 1;
switch (minecartdir[i])
{
case 10:
minecartdir[i] = 30;
break;
case 20:
minecartdir[i] = 40;
break;
case 30:
minecartdir[i] = 10;
break;
case 40:
minecartdir[i] = 20;
break;
}
}
else
{
for (auto& wal : wallsofsector(sectp))
{
switch (minecartdir[i])
{
default: // make case of bad parameters well defined.
x = wal.pos.X;
y = wal.pos.Y;
break;
case 10:
x = wal.pos.X;
y = wal.pos.Y + speed;
break;
case 20:
x = wal.pos.X - speed;
y = wal.pos.Y;
break;
case 30:
x = wal.pos.X;
y = wal.pos.Y - speed;
break;
case 40:
x = wal.pos.X + speed;
y = wal.pos.Y;
break;
}
dragpoint(&wal, x, y);
}
}
}
auto csect = minecartchildsect[i];
max_x = max_y = -0x20000;
min_x = min_y = 0x20000;
for (auto& wal : wallsofsector(csect))
{
x = wal.pos.X;
y = wal.pos.Y;
if (x > max_x)
max_x = x;
if (y > max_y)
max_y = y;
if (x < min_x)
min_x = x;
if (y < min_y)
min_y = y;
}
cx = (max_x + min_x) >> 1;
cy = (max_y + min_y) >> 1;
DukeSectIterator it(csect);
while (auto a2 = it.Next())
{
if (badguy(a2))
SetActor(a2, { cx, cy, a2->spr.pos.Z });
}
}
}
void operatejaildoors(int hitag)
{
for (int i = 0; i < jaildoorcnt; i++)
{
if (jaildoorsecthtag[i] == hitag)
{
if (jaildooropen[i] == 0)
{
jaildooropen[i] = 1;
jaildoordrag[i] = jaildoordist[i];
if (!isRRRA() || jaildoorsound[i] != 0)
S_PlayActorSound(jaildoorsound[i], ps[screenpeek].GetActor());
}
if (jaildooropen[i] == 2)
{
jaildooropen[i] = 3;
jaildoordrag[i] = jaildoordist[i];
if (!isRRRA() || jaildoorsound[i] != 0)
S_PlayActorSound(jaildoorsound[i], ps[screenpeek].GetActor());
}
}
}
}
void thunder(void)
{
struct player_struct* p;
int r1, r2;
int i = 0;
uint8_t shade;
p = &ps[screenpeek];
if (!thunderflash)
{
if (testgotpic(RRTILE2577, true))
{
g_relvisibility = 0;
if (krand() > 65000)
{
thunderflash = 1;
thundertime = 256;
S_PlaySound(351 + (rand() % 3));
}
}
else
{
brightness = ud.brightness >> 2;
}
}
else
{
thundertime -= 4;
if (thundertime < 0)
{
thunderflash = 0;
brightness = ud.brightness >> 2;
thunder_brightness = brightness;
}
}
if (!winderflash)
{
if (testgotpic(RRTILE2562, true))
{
if (krand() > 65000)
{
winderflash = 1;
windertime = 128;
S_PlaySound(351 + (rand() % 3));
}
}
}
else
{
windertime -= 4;
if (windertime < 0)
{
winderflash = 0;
for (i = 0; i < lightnincnt; i++)
{
auto sectp = lightninsector[i];
sectp->floorshade = (int8_t)lightninsectorshade[i];
sectp->ceilingshade = (int8_t)lightninsectorshade[i];
for (auto& wal : wallsofsector(sectp))
wal.shade = (int8_t)lightninsectorshade[i];
}
}
}
if (thunderflash == 1)
{
r1 = krand() & 4;
brightness += r1;
if (brightness > 8)
brightness = 0;
thunder_brightness = brightness;
}
if (winderflash == 1)
{
r2 = krand() & 8;
shade = torchsectorshade[i] + r2;
for (i = 0; i < lightnincnt; i++)
{
auto sectp = lightninsector[i];
sectp->floorshade = lightninsectorshade[i] - shade;
sectp->ceilingshade = lightninsectorshade[i] - shade;
for (auto& wal : wallsofsector(sectp))
wal.shade = lightninsectorshade[i] - shade;
}
}
}
END_DUKE_NS