2019-11-20 16:21:32 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
|
|
Copyright (C) 2019 sirlemonhead, Nuke.YKT
|
|
|
|
This file is part of PCExhumed.
|
|
|
|
PCExhumed is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License version 2
|
|
|
|
as published by the Free Software Foundation.
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-11-22 23:11:37 +00:00
|
|
|
#include "ns.h"
|
2019-08-31 09:08:38 +00:00
|
|
|
#include "compat.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "init.h"
|
|
|
|
#include "runlist.h"
|
|
|
|
#include "switch.h"
|
|
|
|
#include "object.h"
|
|
|
|
#include "aistuff.h"
|
|
|
|
#include "player.h"
|
|
|
|
#include "mummy.h"
|
|
|
|
#include "move.h"
|
|
|
|
#include "ra.h"
|
|
|
|
#include "view.h"
|
|
|
|
#include "runlist.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "exhumed.h"
|
|
|
|
#include "items.h"
|
|
|
|
#include "light.h"
|
|
|
|
#include "map.h"
|
|
|
|
#include "menu.h"
|
|
|
|
#include "lighting.h"
|
|
|
|
#include "anims.h"
|
2019-11-24 09:03:19 +00:00
|
|
|
#include "ps_input.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "util.h"
|
2019-12-25 23:21:04 +00:00
|
|
|
#include "gamecontrol.h"
|
|
|
|
#include "rendering/v_video.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2019-11-22 23:11:37 +00:00
|
|
|
BEGIN_PS_NS
|
|
|
|
|
2019-08-26 03:59:14 +00:00
|
|
|
enum
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
kTagRamses = 61,
|
2019-08-26 03:59:14 +00:00
|
|
|
};
|
|
|
|
|
2019-11-13 18:26:29 +00:00
|
|
|
ClockTicks ototalclock = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
int initx, inity, initz;
|
|
|
|
short inita, initsect;
|
|
|
|
|
|
|
|
short nCurChunkNum = 0;
|
|
|
|
|
|
|
|
short nBodyGunSprite[50];
|
|
|
|
int movefifoend;
|
|
|
|
int movefifopos;
|
|
|
|
|
|
|
|
short nCurBodyGunNum;
|
|
|
|
|
|
|
|
short SectSoundSect[kMaxSectors] = { 0 };
|
|
|
|
short SectSound[kMaxSectors] = { 0 };
|
|
|
|
short SectFlag[kMaxSectors] = { 0 };
|
|
|
|
int SectDepth[kMaxSectors] = { 0 };
|
|
|
|
int SectAbove[kMaxSectors] = { 0 };
|
|
|
|
short SectDamage[kMaxSectors] = { 0 };
|
|
|
|
short SectSpeed[kMaxSectors] = { 0 };
|
|
|
|
int SectBelow[kMaxSectors] = { 0 };
|
|
|
|
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t bIsVersion6 = kTrue;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t LoadLevel(int nMap)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
char fileName_1[80];
|
|
|
|
char fileName_2[32];
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
initspritelists();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
// nMap = 1;
|
|
|
|
|
|
|
|
// sprintf(fileName_2, "queen");
|
2019-08-31 07:47:15 +00:00
|
|
|
sprintf(fileName_2, "lev%d", nMap);
|
2019-08-26 03:59:14 +00:00
|
|
|
// sprintf(fileName_2, "sentry");
|
|
|
|
// sprintf(fileName_2, "bjd");
|
|
|
|
// sprintf(fileName_2, "door");
|
|
|
|
// sprintf(fileName_2, "ceil");
|
|
|
|
// sprintf(fileName_2, "scarab");
|
|
|
|
// sprintf(fileName_2, "guns");
|
|
|
|
// sprintf(fileName_2, "wasp");
|
|
|
|
// sprintf(fileName_2, "items");
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
fileName_1[0] = '\0';
|
|
|
|
strcat(fileName_1, fileName_2);
|
|
|
|
strcat(fileName_1, ".map");
|
|
|
|
|
|
|
|
// init stuff
|
|
|
|
{
|
|
|
|
StopAllSounds();
|
|
|
|
nCreaturesLeft = 0;
|
|
|
|
nFreeze = 0;
|
|
|
|
nSpiritSprite = -1;
|
|
|
|
|
|
|
|
InitLion();
|
|
|
|
InitRexs();
|
|
|
|
InitSets();
|
|
|
|
InitQueens();
|
|
|
|
InitRoachs();
|
|
|
|
InitWasps();
|
|
|
|
InitRats();
|
|
|
|
InitBullets();
|
|
|
|
InitWeapons();
|
|
|
|
InitGrenades();
|
|
|
|
InitAnims();
|
|
|
|
InitSnakes();
|
|
|
|
InitFishes();
|
|
|
|
InitLights();
|
|
|
|
InitMap();
|
|
|
|
InitBubbles();
|
|
|
|
InitObjects();
|
|
|
|
InitLava();
|
|
|
|
InitPushBlocks();
|
|
|
|
InitAnubis();
|
|
|
|
InitSpider();
|
|
|
|
InitMummy();
|
|
|
|
InitScorp();
|
|
|
|
InitPlayer();
|
|
|
|
InitItems();
|
|
|
|
InitInput();
|
|
|
|
|
|
|
|
if (nMap == kMap20) {
|
|
|
|
InitEnergyTile();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nMap > 15)
|
|
|
|
{
|
|
|
|
nSwitchSound = 35;
|
|
|
|
nStoneSound = 23;
|
|
|
|
nElevSound = 51;
|
|
|
|
nStopSound = 35;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nSwitchSound = 33;
|
|
|
|
nStoneSound = 23;
|
|
|
|
nElevSound = 23;
|
|
|
|
nStopSound = 66;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nMap < 0) {
|
|
|
|
return kFalse;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-27 06:08:18 +00:00
|
|
|
vec3_t startPos;
|
2019-08-31 10:58:30 +00:00
|
|
|
int status = engineLoadBoard(fileName_1, 0, &startPos, &inita, &initsect);
|
|
|
|
if (status == -2)
|
|
|
|
status = engineLoadBoardV5V6(fileName_1, 0, &startPos, &inita, &initsect);
|
2019-08-27 06:08:18 +00:00
|
|
|
initx = startPos.x;
|
|
|
|
inity = startPos.y;
|
|
|
|
initz = startPos.z;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 10:58:30 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
yax_update(1);
|
|
|
|
#endif
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int i;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (i = 0; i < kMaxPlayers; i++)
|
|
|
|
{
|
|
|
|
PlayerList[i].nSprite = -1;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-27 06:08:18 +00:00
|
|
|
psky_t* pSky = tileSetupSky(0);
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
pSky->tileofs[0] = 0;
|
|
|
|
pSky->tileofs[1] = 0;
|
|
|
|
pSky->tileofs[2] = 0;
|
|
|
|
pSky->tileofs[3] = 0;
|
2019-08-27 06:08:18 +00:00
|
|
|
pSky->yoffs = 256;
|
|
|
|
pSky->lognumtiles = 2;
|
2019-08-31 19:20:01 +00:00
|
|
|
pSky->horizfrac = 65536;
|
|
|
|
pSky->yscale = 65536;
|
|
|
|
parallaxtype = 2;
|
|
|
|
g_visibility = 2048;
|
|
|
|
flash = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
precache();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
LoadObjects();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
levelnum = nMap;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return kTrue;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ResetEngine()
|
|
|
|
{
|
2019-10-12 21:09:55 +00:00
|
|
|
SetOverscan(BASEPAL);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
EraseScreen(-1);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
resettiming();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
totalclock = 0;
|
2019-11-13 18:26:29 +00:00
|
|
|
ototalclock = totalclock;
|
2019-09-06 05:18:12 +00:00
|
|
|
localclock = (int)totalclock;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
numframes = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InstallEngine()
|
|
|
|
{
|
2019-10-31 17:22:12 +00:00
|
|
|
// initgroupfile("stuff.dat");
|
2019-11-24 12:59:36 +00:00
|
|
|
TileFiles.LoadArtSet("tiles%03d.art");
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-11-24 12:59:36 +00:00
|
|
|
// TEMP
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
//nScreenWidth *= 2;
|
|
|
|
//nScreenHeight *= 2;
|
|
|
|
bHiRes = kTrue;
|
|
|
|
// TEMP
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-27 06:08:18 +00:00
|
|
|
if (engineInit())
|
|
|
|
{
|
2019-12-25 23:21:04 +00:00
|
|
|
G_FatalEngineError();
|
2019-08-27 06:08:18 +00:00
|
|
|
}
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
LoadPaletteLookups();
|
2019-12-25 23:54:21 +00:00
|
|
|
V_Init2();
|
2019-09-22 19:09:50 +00:00
|
|
|
|
2019-11-08 16:18:44 +00:00
|
|
|
enginecompatibility_mode = ENGINECOMPATIBILITY_19950829;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RemoveEngine()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
engineUnInit();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetBelow(short nCurSector, short nBelowSector)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
SectBelow[nCurSector] = nBelowSector;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetAbove(short nCurSector, short nAboveSector)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
SectAbove[nCurSector] = nAboveSector;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SnapSectors(short nSectorA, short nSectorB, short b)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
// edx - nSectorA
|
|
|
|
// eax - nSectorB
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
short nWallA = sector[nSectorA].wallptr;
|
|
|
|
short nWallB = sector[nSectorB].wallptr;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
short num1 = sector[nSectorA].wallnum;
|
|
|
|
short num2 = sector[nSectorB].wallnum;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int nCount = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (num1 > nCount)
|
|
|
|
{
|
|
|
|
short dx = nWallB;
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int esi = 0x7FFFFFF;
|
|
|
|
int edi = esi;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int x = wall[nWallA].x;
|
|
|
|
int y = wall[nWallA].y;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_14 = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-11-20 16:21:32 +00:00
|
|
|
int nCount2 = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (nCount2 < num2)
|
|
|
|
{
|
|
|
|
int eax = x - wall[dx].x;
|
|
|
|
int ebx = y - wall[dx].y;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_38 = eax;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (ebx < 0) {
|
|
|
|
ebx = -ebx;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_3C = ebx;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
var_38 += var_3C;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
eax = esi;
|
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
var_3C = eax;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
eax = edi;
|
2019-08-26 03:59:14 +00:00
|
|
|
// int var_34 = edi;
|
2019-08-31 07:47:15 +00:00
|
|
|
if (eax < 0) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_34 = eax;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
var_34 += var_3C;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-11-20 16:21:32 +00:00
|
|
|
if (var_38 < var_34)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
esi = x - wall[dx].x;
|
|
|
|
edi = y - wall[dx].y;
|
|
|
|
var_14 = dx;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
dx++;
|
|
|
|
nCount2++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
dragpoint(var_14, wall[var_14].x + esi, wall[var_14].y + edi, 0);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nCount++;
|
|
|
|
nWallA++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (b) {
|
|
|
|
sector[nSectorB].ceilingz = sector[nSectorA].floorz;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (SectFlag[nSectorA] & 0x1000) {
|
|
|
|
SnapBobs(nSectorA, nSectorB);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InitSectFlag()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int i = 0; i < kMaxSectors; i++)
|
|
|
|
{
|
|
|
|
SectSoundSect[i] = -1;
|
|
|
|
SectSound[i] = -1;
|
|
|
|
SectAbove[i] = -1;
|
|
|
|
SectBelow[i] = -1;
|
|
|
|
SectDepth[i] = 0;
|
|
|
|
SectFlag[i] = 0;
|
|
|
|
SectSpeed[i] = 0;
|
|
|
|
SectDamage[i] = 0;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProcessSpriteTag(short nSprite, short lotag, short hitag)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int nChannel = runlist_AllocChannel(hitag % 1000);
|
2019-08-26 03:59:14 +00:00
|
|
|
// int ebp = nChannel;
|
|
|
|
|
2019-12-02 16:34:59 +00:00
|
|
|
// int nHitag2 = hitag / 1000;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int nLotag2 = lotag / 1000;
|
|
|
|
if (nLotag2 == 0) {
|
|
|
|
nLotag2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// this value can change in the below code but we also need to retain the original hitag value
|
|
|
|
int nVal = hitag;
|
|
|
|
|
|
|
|
if (lotag >= 900 && lotag <= 949)
|
|
|
|
{
|
|
|
|
ProcessTrailSprite(nSprite, lotag, hitag);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle tags 6 to 60
|
|
|
|
switch (lotag)
|
|
|
|
{
|
|
|
|
case 8: // M-60 ammo belt
|
|
|
|
{
|
|
|
|
nVal = 3 * (hitag / 3);
|
|
|
|
// fall through to 6,7 etc
|
2019-12-02 14:56:24 +00:00
|
|
|
fallthrough__;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
case 9:
|
|
|
|
case 10:
|
|
|
|
case 11:
|
|
|
|
case 15:
|
|
|
|
case 17:
|
|
|
|
case 18:
|
|
|
|
case 19:
|
|
|
|
case 20:
|
|
|
|
case 21:
|
|
|
|
case 22:
|
|
|
|
case 23:
|
|
|
|
case 24:
|
|
|
|
case 26:
|
|
|
|
case 28:
|
|
|
|
case 29:
|
|
|
|
case 30:
|
|
|
|
case 31:
|
|
|
|
case 32:
|
|
|
|
case 33:
|
|
|
|
case 34:
|
|
|
|
case 35:
|
|
|
|
case 36:
|
|
|
|
case 37:
|
|
|
|
case 39:
|
|
|
|
case 40:
|
|
|
|
case 41:
|
|
|
|
case 42:
|
|
|
|
case 43:
|
|
|
|
case 44:
|
|
|
|
case 45:
|
|
|
|
case 46:
|
|
|
|
case 47:
|
|
|
|
case 48:
|
|
|
|
case 49:
|
|
|
|
case 50:
|
|
|
|
case 51:
|
|
|
|
case 52:
|
|
|
|
case 53:
|
|
|
|
case 54:
|
|
|
|
case 55:
|
|
|
|
case 56:
|
|
|
|
case 57:
|
|
|
|
case 58:
|
|
|
|
case 60:
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = nVal;
|
|
|
|
changespritestat(nSprite, lotag + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 12: // berry twig
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = 40;
|
|
|
|
changespritestat(nSprite, lotag + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 13: // blood bowl
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = 160;
|
|
|
|
changespritestat(nSprite, lotag + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 14: // venom bowl
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = -200;
|
|
|
|
changespritestat(nSprite, lotag + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
// reserved
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 25:
|
|
|
|
case 59:
|
|
|
|
{
|
|
|
|
// extra life or checkpoint scarab. Delete for multiplayer
|
|
|
|
if (nNetPlayerCount != 0)
|
|
|
|
{
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = nVal;
|
|
|
|
changespritestat(nSprite, lotag + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 27:
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = 1;
|
|
|
|
changespritestat(nSprite, 9 + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 38: // raw energy
|
|
|
|
{
|
|
|
|
nVal++;
|
|
|
|
nVal--; // CHECKME ??
|
|
|
|
sprite[nSprite].hitag = nVal;
|
|
|
|
changespritestat(nSprite, lotag + 900);
|
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int v6 = lotag % 1000;
|
|
|
|
|
|
|
|
if (!bNoCreatures || v6 < 100 || v6 > 118)
|
|
|
|
{
|
|
|
|
if (v6 > 999) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (v6)
|
|
|
|
{
|
|
|
|
case 999:
|
|
|
|
{
|
|
|
|
AddFlicker(sprite[nSprite].sectnum, nLotag2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 998:
|
|
|
|
{
|
|
|
|
AddGlow(sprite[nSprite].sectnum, nLotag2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 118: // Anubis with drum
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildAnubis(nSprite, 0, 0, 0, 0, 0, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 117:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildWasp(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 116:
|
|
|
|
{
|
|
|
|
BuildRat(nSprite, 0, 0, 0, 0, -1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 115: // Rat (eating)
|
|
|
|
{
|
|
|
|
BuildRat(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 113:
|
|
|
|
{
|
|
|
|
BuildQueen(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 112:
|
|
|
|
{
|
|
|
|
BuildScorp(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 111:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildSet(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 108:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildLava(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 107:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildRex(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
2019-11-20 16:21:32 +00:00
|
|
|
case 106:
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildFish(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 105:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildSpider(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 104:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildRoach(1, nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 103:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildRoach(0, nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 102:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildLion(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 101:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildMummy(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 100:
|
|
|
|
{
|
|
|
|
if (bNoCreatures) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildAnubis(nSprite, 0, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 99: // underwater type 2
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SetAbove(nSector, hitag);
|
|
|
|
SectFlag[nSector] |= kSectUnderwater;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 98:
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SetBelow(nSector, hitag);
|
|
|
|
SnapSectors(nSector, hitag, 1);
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 97:
|
|
|
|
{
|
|
|
|
AddSectorBob(sprite[nSprite].sectnum, hitag, 1);
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 96: // Lava sector
|
|
|
|
{
|
|
|
|
hitag /= 4; // hitag is damage level?
|
|
|
|
if (hitag == 0) {
|
|
|
|
hitag = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
|
|
|
|
SectDamage[nSector] = hitag;
|
|
|
|
SectFlag[nSector] |= kSectLava;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 95:
|
|
|
|
{
|
|
|
|
AddSectorBob(sprite[nSprite].sectnum, hitag, 0);
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 94: // water
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SectDepth[nSector] = hitag << 8;
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 93:
|
|
|
|
{
|
|
|
|
BuildBubbleMachine(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 90:
|
|
|
|
{
|
|
|
|
BuildObject(nSprite, 3, hitag);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 79:
|
|
|
|
case 89:
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
|
|
|
|
SectSpeed[nSector] = nLotag2;
|
|
|
|
SectFlag[nSector] |= sprite[nSprite].ang;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 88:
|
|
|
|
{
|
|
|
|
AddFlow(nSprite, nLotag2, 0);
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 80: // underwater
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SectFlag[nSector] |= kSectUnderwater;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 78:
|
|
|
|
{
|
|
|
|
AddFlow(nSprite, nLotag2, 1);
|
|
|
|
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SectFlag[nSector] |= 0x8000;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 77:
|
|
|
|
{
|
|
|
|
int nArrow = BuildArrow(nSprite, nLotag2);
|
|
|
|
|
|
|
|
runlist_AddRunRec(sRunChannels[nChannel].a, nArrow);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 76: // Explosion Trigger (Exploding Fire Cauldron)
|
|
|
|
{
|
|
|
|
BuildObject(nSprite, 0, hitag);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 75: // Explosion Target (Cauldrons, fireballs and grenades will destroy nearby 75 sprites)
|
|
|
|
{
|
|
|
|
BuildObject(nSprite, 1, hitag);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 71:
|
|
|
|
{
|
|
|
|
int nFireball = BuildFireBall(nSprite, hitag, nLotag2);
|
|
|
|
|
|
|
|
runlist_AddRunRec(sRunChannels[nChannel].a, nFireball);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 70:
|
|
|
|
{
|
|
|
|
BuildDrip(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 63:
|
|
|
|
{
|
|
|
|
changespritestat(nSprite, 405);
|
|
|
|
sprite[nSprite].cstat = 0x8000;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 62:
|
|
|
|
{
|
|
|
|
nNetStartSprite[nNetStartSprites] = nSprite;
|
|
|
|
sprite[nSprite].cstat = 0x8000;
|
|
|
|
|
|
|
|
nNetStartSprites++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case kTagRamses: // Ramses head
|
|
|
|
{
|
|
|
|
nSpiritSprite = nSprite;
|
|
|
|
sprite[nSprite].cstat |= 0x8000;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
default: // TODO - checkme!
|
|
|
|
{
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ExamineSprites()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nNetStartSprites = 0;
|
|
|
|
nCurStartSprite = 0;
|
|
|
|
|
|
|
|
for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
|
|
|
|
{
|
|
|
|
int nStatus = sprite[nSprite].statnum;
|
|
|
|
if (!nStatus)
|
|
|
|
{
|
|
|
|
short lotag = sprite[nSprite].lotag;
|
|
|
|
short hitag = sprite[nSprite].hitag;
|
|
|
|
|
|
|
|
if ((nStatus < kMaxStatus) && lotag)
|
|
|
|
{
|
|
|
|
sprite[nSprite].lotag = 0;
|
|
|
|
sprite[nSprite].hitag = 0;
|
|
|
|
|
|
|
|
ProcessSpriteTag(nSprite, lotag, hitag);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
changespritestat(nSprite, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nNetPlayerCount)
|
|
|
|
{
|
|
|
|
int nSprite = insertsprite(initsect, 0);
|
|
|
|
sprite[nSprite].x = initx;
|
|
|
|
sprite[nSprite].y = inity;
|
|
|
|
sprite[nSprite].z = initz;
|
|
|
|
sprite[nSprite].cstat = 0x8000;
|
|
|
|
nNetStartSprite[nNetStartSprites] = nSprite;
|
|
|
|
nNetStartSprites++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LoadObjects()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
runlist_InitRun();
|
|
|
|
runlist_InitChan();
|
|
|
|
InitLink();
|
|
|
|
InitPoint();
|
|
|
|
InitSlide();
|
|
|
|
InitSwitch();
|
|
|
|
InitElev();
|
|
|
|
InitWallFace();
|
|
|
|
InitTimeSlot();
|
|
|
|
InitSectFlag();
|
|
|
|
|
|
|
|
for (int nSector = 0; nSector < numsectors; nSector++)
|
|
|
|
{
|
|
|
|
short hitag = sector[nSector].hitag;
|
|
|
|
short lotag = sector[nSector].lotag;
|
|
|
|
|
|
|
|
sector[nSector].hitag = 0;
|
|
|
|
sector[nSector].lotag = 0;
|
|
|
|
sector[nSector].extra = -1;
|
|
|
|
|
|
|
|
if (hitag || lotag)
|
|
|
|
{
|
|
|
|
sector[nSector].lotag = runlist_HeadRun() + 1;
|
|
|
|
sector[nSector].hitag = lotag;
|
|
|
|
|
|
|
|
runlist_ProcessSectorTag(nSector, lotag, hitag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int nWall = 0; nWall < numwalls; nWall++)
|
|
|
|
{
|
|
|
|
wall[nWall].extra = -1;
|
|
|
|
|
|
|
|
short lotag = wall[nWall].lotag;
|
|
|
|
short hitag = wall[nWall].hitag;
|
|
|
|
|
|
|
|
wall[nWall].lotag = 0;
|
|
|
|
|
|
|
|
if (hitag || lotag)
|
|
|
|
{
|
|
|
|
wall[nWall].lotag = runlist_HeadRun() + 1;
|
|
|
|
runlist_ProcessWallTag(nWall, lotag, hitag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ExamineSprites();
|
|
|
|
PostProcess();
|
|
|
|
InitRa();
|
|
|
|
InitChunks();
|
|
|
|
|
|
|
|
for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
|
|
|
|
{
|
|
|
|
runlist_ChangeChannel(nSprite, 0);
|
|
|
|
runlist_ReadyChannel(nSprite);
|
|
|
|
}
|
|
|
|
|
|
|
|
nCamerax = initx;
|
|
|
|
nCameray = inity;
|
|
|
|
nCameraz = initz;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int myloadconfig()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
return 1;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int mysaveconfig()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return 1;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
2019-12-26 21:00:04 +00:00
|
|
|
|
|
|
|
static SavegameHelper sgh("init",
|
|
|
|
SV(initx),
|
|
|
|
SV(inity),
|
|
|
|
SV(initz),
|
|
|
|
SV(inita),
|
|
|
|
SV(initsect),
|
|
|
|
SV(nCurChunkNum),
|
|
|
|
SA(nBodyGunSprite),
|
|
|
|
SV(nCurBodyGunNum),
|
|
|
|
SA(SectSoundSect),
|
|
|
|
SA(SectSound),
|
|
|
|
SA(SectFlag),
|
|
|
|
SA(SectDepth),
|
|
|
|
SA(SectAbove),
|
|
|
|
SA(SectDamage),
|
|
|
|
SA(SectSpeed),
|
|
|
|
SA(SectBelow),
|
|
|
|
nullptr);
|
|
|
|
|
|
|
|
|
2019-11-22 23:11:37 +00:00
|
|
|
END_PS_NS
|