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 "aistuff.h"
|
|
|
|
#include "player.h"
|
|
|
|
#include "view.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "exhumed.h"
|
|
|
|
#include "menu.h"
|
2019-11-24 09:03:19 +00:00
|
|
|
#include "ps_input.h"
|
2019-12-27 09:52:40 +00:00
|
|
|
#include "mapinfo.h"
|
2019-12-25 23:21:04 +00:00
|
|
|
#include "gamecontrol.h"
|
2020-04-28 21:11:33 +00:00
|
|
|
#include "v_video.h"
|
2020-08-23 06:22:59 +00:00
|
|
|
#include "status.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 };
|
|
|
|
|
|
|
|
|
2020-08-18 08:28:19 +00:00
|
|
|
uint8_t bIsVersion6 = true;
|
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
|
|
|
{
|
2020-08-23 06:22:59 +00:00
|
|
|
if (nMap == kMap20)
|
|
|
|
{
|
|
|
|
lCountDown = 81000;
|
|
|
|
nAlarmTicks = 30;
|
|
|
|
nRedTicks = 0;
|
|
|
|
nClockVal = 0;
|
|
|
|
nEnergyTowers = 0;
|
|
|
|
}
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
initspritelists();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-12-27 09:52:40 +00:00
|
|
|
currentLevel = &mapList[nMap];
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
// 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) {
|
2020-08-18 08:28:19 +00:00
|
|
|
return false;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-27 06:08:18 +00:00
|
|
|
vec3_t startPos;
|
2019-12-27 09:52:40 +00:00
|
|
|
int status = engineLoadBoard(currentLevel->fileName, 0, &startPos, &inita, &initsect);
|
2019-08-31 10:58:30 +00:00
|
|
|
if (status == -2)
|
2019-12-27 09:52:40 +00:00
|
|
|
status = engineLoadBoardV5V6(currentLevel->fileName, 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 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
|
|
|
|
2020-07-14 22:06:19 +00:00
|
|
|
psky_t* pSky = tileSetupSky(DEFAULTPSKY);
|
2019-08-27 06:08:18 +00:00
|
|
|
|
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
|
|
|
|
2020-08-18 08:28:19 +00:00
|
|
|
return true;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2020-08-23 06:22:59 +00:00
|
|
|
void InitLevel(int level)
|
|
|
|
{
|
2020-08-23 10:26:52 +00:00
|
|
|
levelnum = level;
|
2020-08-23 06:22:59 +00:00
|
|
|
StopCD();
|
|
|
|
if (!LoadLevel(level)) {
|
|
|
|
I_Error("Can't load level %d...\n", level);
|
|
|
|
}
|
2020-08-23 10:59:01 +00:00
|
|
|
currentLevel = FindMapByLevelNum(level);
|
2020-08-23 06:22:59 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < nTotalPlayers; i++)
|
|
|
|
{
|
|
|
|
SetSavePoint(i, initx, inity, initz, initsect, inita);
|
|
|
|
RestartPlayer(i);
|
|
|
|
InitPlayerKeys(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
fps = 0;
|
|
|
|
lastfps = 0;
|
|
|
|
InitStatus();
|
|
|
|
ResetView();
|
|
|
|
ResetEngine();
|
|
|
|
totalmoves = 0;
|
|
|
|
GrabPalette();
|
|
|
|
ResetMoveFifo();
|
|
|
|
moveframes = 0;
|
|
|
|
bInMove = false;
|
|
|
|
nPlayerDAng = 0;
|
|
|
|
lPlayerXVel = 0;
|
|
|
|
lPlayerYVel = 0;
|
|
|
|
movefifopos = movefifoend;
|
|
|
|
|
|
|
|
RefreshStatus();
|
2020-08-23 07:11:32 +00:00
|
|
|
|
|
|
|
int nTrack = level;
|
|
|
|
if (nTrack != 0) nTrack--;
|
|
|
|
|
|
|
|
playCDtrack((nTrack % 8) + 11, true);
|
|
|
|
|
2020-08-23 06:22:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InitNewGame()
|
|
|
|
{
|
|
|
|
bCamera = false;
|
2020-08-23 10:26:52 +00:00
|
|
|
nCinemaSeen = 0;
|
2020-08-23 06:22:59 +00:00
|
|
|
PlayerCount = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < nTotalPlayers; i++)
|
|
|
|
{
|
|
|
|
int nPlayer = GrabPlayer();
|
|
|
|
if (nPlayer < 0) {
|
|
|
|
I_Error("Can't create local player\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
InitPlayerInventory(nPlayer);
|
|
|
|
}
|
|
|
|
|
|
|
|
nNetMoves = 0;
|
|
|
|
|
|
|
|
// PINK SECTION
|
|
|
|
UpdateInputs();
|
|
|
|
nNetMoves = 1;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
void ProcessSpriteTag(short nSprite, short nLotag, short nHitag)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
int nChannel = runlist_AllocChannel(nHitag % 1000);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
int nSpeed = nLotag / 1000;
|
|
|
|
if (!nSpeed) {
|
|
|
|
nSpeed = 1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
int nVal = nHitag;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
if (nLotag >= 900 && nLotag <= 949)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
ProcessTrailSprite(nSprite, nLotag, nHitag);
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle tags 6 to 60
|
2020-02-04 21:45:10 +00:00
|
|
|
switch (nLotag)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
case 8: // M-60 ammo belt
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
nVal = 3 * (nHitag / 3);
|
2019-08-31 07:47:15 +00:00
|
|
|
// 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;
|
2020-02-04 21:45:10 +00:00
|
|
|
changespritestat(nSprite, nLotag + 900);
|
2019-08-31 07:47:15 +00:00
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 12: // berry twig
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = 40;
|
2020-02-04 21:45:10 +00:00
|
|
|
changespritestat(nSprite, nLotag + 900);
|
2019-08-31 07:47:15 +00:00
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 13: // blood bowl
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = 160;
|
2020-02-04 21:45:10 +00:00
|
|
|
changespritestat(nSprite, nLotag + 900);
|
2019-08-31 07:47:15 +00:00
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 14: // venom bowl
|
|
|
|
{
|
|
|
|
sprite[nSprite].hitag = -200;
|
2020-02-04 21:45:10 +00:00
|
|
|
changespritestat(nSprite, nLotag + 900);
|
2019-08-31 07:47:15 +00:00
|
|
|
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;
|
2020-02-04 21:45:10 +00:00
|
|
|
changespritestat(nSprite, nLotag + 900);
|
2019-08-31 07:47:15 +00:00
|
|
|
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;
|
2020-02-04 21:45:10 +00:00
|
|
|
changespritestat(nSprite, nLotag + 900);
|
2019-08-31 07:47:15 +00:00
|
|
|
sprite[nSprite].cstat &= 0xFEFE;
|
|
|
|
BuildItemAnim(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
int v6 = nLotag % 1000;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-08-22 18:14:00 +00:00
|
|
|
if (!userConfig.nomonsters || v6 < 100 || v6 > 118)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
if (v6 > 999) {
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (v6)
|
|
|
|
{
|
|
|
|
case 999:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
AddFlicker(sprite[nSprite].sectnum, nSpeed);
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 998:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
AddGlow(sprite[nSprite].sectnum, nSpeed);
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 118: // Anubis with drum
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildAnubis(nSprite, 0, 0, 0, 0, 0, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 117:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
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:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildSet(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 108:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildLava(nSprite, 0, 0, 0, 0, 0, nChannel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 107:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
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
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildFish(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 105:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildSpider(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 104:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildRoach(1, nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 103:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildRoach(0, nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 102:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildLion(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 101:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildMummy(nSprite, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 100:
|
|
|
|
{
|
2020-08-22 18:14:00 +00:00
|
|
|
if (userConfig.nomonsters) {
|
2019-08-31 07:47:15 +00:00
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildAnubis(nSprite, 0, 0, 0, 0, 0, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 99: // underwater type 2
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
2020-02-04 21:45:10 +00:00
|
|
|
SetAbove(nSector, nHitag);
|
2019-08-31 07:47:15 +00:00
|
|
|
SectFlag[nSector] |= kSectUnderwater;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 98:
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
2020-02-04 21:45:10 +00:00
|
|
|
SetBelow(nSector, nHitag);
|
|
|
|
SnapSectors(nSector, nHitag, 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 97:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
AddSectorBob(sprite[nSprite].sectnum, nHitag, 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 96: // Lava sector
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
int nDamage = nHitag / 4;
|
|
|
|
if (!nDamage) {
|
|
|
|
nDamage = 1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
SectDamage[nSector] = nDamage;
|
2019-08-31 07:47:15 +00:00
|
|
|
SectFlag[nSector] |= kSectLava;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 95:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
AddSectorBob(sprite[nSprite].sectnum, nHitag, 0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 94: // water
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
2020-02-04 21:45:10 +00:00
|
|
|
SectDepth[nSector] = nHitag << 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:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
BuildObject(nSprite, 3, nHitag);
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 79:
|
|
|
|
case 89:
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
|
2020-02-04 21:45:10 +00:00
|
|
|
SectSpeed[nSector] = nSpeed;
|
2019-08-31 07:47:15 +00:00
|
|
|
SectFlag[nSector] |= sprite[nSprite].ang;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 88:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
AddFlow(nSprite, nSpeed, 0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 80: // underwater
|
|
|
|
{
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SectFlag[nSector] |= kSectUnderwater;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 78:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
AddFlow(nSprite, nSpeed, 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
short nSector = sprite[nSprite].sectnum;
|
|
|
|
SectFlag[nSector] |= 0x8000;
|
|
|
|
|
|
|
|
mydeletesprite(nSprite);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 77:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
int nArrow = BuildArrow(nSprite, nSpeed);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
runlist_AddRunRec(sRunChannels[nChannel].a, nArrow);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 76: // Explosion Trigger (Exploding Fire Cauldron)
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
BuildObject(nSprite, 0, nHitag);
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 75: // Explosion Target (Cauldrons, fireballs and grenades will destroy nearby 75 sprites)
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
BuildObject(nSprite, 1, nHitag);
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
case 71:
|
|
|
|
{
|
2020-02-04 21:45:10 +00:00
|
|
|
int nFireball = BuildFireBall(nSprite, nHitag, nSpeed);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
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();
|
|
|
|
|
2020-01-03 21:56:02 +00:00
|
|
|
for (int nChannel = 0; nChannel < kMaxChannels; nChannel++)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2020-01-03 21:56:02 +00:00
|
|
|
runlist_ChangeChannel(nChannel, 0);
|
|
|
|
runlist_ReadyChannel(nChannel);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nCamerax = initx;
|
|
|
|
nCameray = inity;
|
|
|
|
nCameraz = initz;
|
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
|