2006-04-13 20:47:06 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
2016-02-07 02:38:03 +00:00
|
|
|
Copyright (C) 2016 EDuke32 developers and contributors
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-05-25 10:56:00 +00:00
|
|
|
This file is part of EDuke32.
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
EDuke32 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
|
2014-07-20 08:55:56 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2006-04-13 20:47:06 +00:00
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
2019-09-21 18:59:54 +00:00
|
|
|
#include "ns.h" // Must come before everything else!
|
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
#include "anim.h"
|
2018-11-18 19:03:40 +00:00
|
|
|
#include "cmdline.h"
|
2010-08-02 08:19:28 +00:00
|
|
|
#include "demo.h"
|
2018-11-18 19:03:40 +00:00
|
|
|
#include "duke3d.h"
|
|
|
|
#include "menus.h"
|
2017-12-18 11:24:53 +00:00
|
|
|
#include "savegame.h"
|
2019-12-09 16:17:15 +00:00
|
|
|
#include "statistics.h"
|
2019-11-23 22:05:24 +00:00
|
|
|
#include "menu/menu.h"
|
2019-12-09 23:01:45 +00:00
|
|
|
#include "mapinfo.h"
|
|
|
|
#include "cmdlib.h"
|
2019-12-31 18:25:49 +00:00
|
|
|
#include "v_2ddrawer.h"
|
2019-12-12 17:43:27 +00:00
|
|
|
|
2019-09-21 20:53:00 +00:00
|
|
|
BEGIN_DUKE_NS
|
|
|
|
|
2019-07-19 01:49:19 +00:00
|
|
|
static uint8_t precachehightile[2][(MAXTILES+7)>>3];
|
2018-10-16 06:08:50 +00:00
|
|
|
static int32_t g_precacheCount;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2008-07-22 09:05:34 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
static int32_t NET_75_CHECK = 0;
|
|
|
|
|
|
|
|
static void flag_precache(int32_t tile, int32_t type)
|
2012-11-17 19:46:37 +00:00
|
|
|
{
|
|
|
|
if (!(gotpic[tile>>3] & pow2char[tile&7]))
|
|
|
|
g_precacheCount++;
|
2018-11-18 18:08:08 +00:00
|
|
|
|
2012-11-17 19:46:37 +00:00
|
|
|
gotpic[tile>>3] |= pow2char[tile&7];
|
|
|
|
precachehightile[type][tile>>3] |= pow2char[tile&7];
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
static void tloadtile(int tilenume, int type)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
int firstTile, lastTile;
|
2012-11-17 19:46:37 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if ((picanm[tilenume].sf & PICANM_ANIMTYPE_MASK) == PICANM_ANIMTYPE_BACK)
|
2006-12-17 21:20:35 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
firstTile = tilenume - picanm[tilenume].num;
|
|
|
|
lastTile = tilenume;
|
2006-12-17 21:20:35 +00:00
|
|
|
}
|
2012-11-17 19:46:37 +00:00
|
|
|
else
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
firstTile = tilenume;
|
|
|
|
lastTile = tilenume + picanm[tilenume].num;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2012-11-17 19:46:37 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
for (; firstTile <= lastTile; firstTile++)
|
|
|
|
flag_precache(firstTile, type);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
static void cacheTilesForSprite(int spriteNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:08:14 +00:00
|
|
|
if (ud.monsters_off && A_CheckEnemySprite(&sprite[spriteNum])) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
int const picnum = sprite[spriteNum].picnum;
|
|
|
|
int extraTiles = 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j = picnum; j <= g_tile[picnum].cacherange; j++)
|
|
|
|
tloadtile(j, 1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-10-25 23:33:09 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-11-18 18:08:14 +00:00
|
|
|
switch (DYNAMICTILEMAP(picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-16 03:02:42 +00:00
|
|
|
case HYDRENT__STATIC:
|
|
|
|
tloadtile(BROKEFIREHYDRENT,1);
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case TOILET__STATIC:
|
|
|
|
tloadtile(TOILETBROKE,1);
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case STALL__STATIC:
|
|
|
|
tloadtile(STALLBROKE,1);
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case RUBBERCAN__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 2;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case TOILETWATER__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 4;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case FEMPIC1__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 44;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case LIZTROOP__STATIC:
|
|
|
|
case LIZTROOPRUNNING__STATIC:
|
|
|
|
case LIZTROOPSHOOT__STATIC:
|
|
|
|
case LIZTROOPJETPACK__STATIC:
|
|
|
|
case LIZTROOPONTOILET__STATIC:
|
|
|
|
case LIZTROOPDUCKING__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j = LIZTROOP; j < (LIZTROOP+72); j++) tloadtile(j,1);
|
|
|
|
for (int j=HEADJIB1; j<LEGJIB1+3; j++) tloadtile(j,1);
|
|
|
|
extraTiles = 0;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case WOODENHORSE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 5;
|
|
|
|
for (int j = HORSEONSIDE; j < (HORSEONSIDE+4); j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case NEWBEAST__STATIC:
|
|
|
|
case NEWBEASTSTAYPUT__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 90;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case BOSS1__STATIC:
|
|
|
|
case BOSS2__STATIC:
|
|
|
|
case BOSS3__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 30;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case OCTABRAIN__STATIC:
|
|
|
|
case OCTABRAINSTAYPUT__STATIC:
|
|
|
|
case COMMANDER__STATIC:
|
|
|
|
case COMMANDERSTAYPUT__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 38;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case RECON__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 13;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case PIGCOP__STATIC:
|
|
|
|
case PIGCOPDIVE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 61;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case SHARK__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 30;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case LIZMAN__STATIC:
|
|
|
|
case LIZMANSPITTING__STATIC:
|
|
|
|
case LIZMANFEEDING__STATIC:
|
|
|
|
case LIZMANJUMP__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=LIZMANHEAD1; j<LIZMANLEG1+3; j++) tloadtile(j,1);
|
|
|
|
extraTiles = 80;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case APLAYER__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 0;
|
2010-01-16 23:08:17 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 5;
|
|
|
|
for (int j = 1420; j < 1420+106; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ATOMICHEALTH__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 14;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case DRONE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 10;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case EXPLODINGBARREL__STATIC:
|
|
|
|
case SEENINE__STATIC:
|
|
|
|
case OOZFILTER__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 3;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case NUKEBARREL__STATIC:
|
|
|
|
case CAMERA1__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
extraTiles = 5;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
// caching of HUD sprites for weapons that may be in the level
|
|
|
|
case CHAINGUNSPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=CHAINGUN; j<=CHAINGUN+7; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case RPGSPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=RPGGUN; j<=RPGGUN+2; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case FREEZESPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=FREEZE; j<=FREEZE+5; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case GROWSPRITEICON__STATIC:
|
|
|
|
case SHRINKERSPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=SHRINKER-2; j<=SHRINKER+5; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case HBOMBAMMO__STATIC:
|
|
|
|
case HEAVYHBOMB__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=HANDREMOTE; j<=HANDREMOTE+5; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case TRIPBOMBSPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=HANDHOLDINGLASER; j<=HANDHOLDINGLASER+4; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case SHOTGUNSPRITE__STATIC:
|
|
|
|
tloadtile(SHOTGUNSHELL,1);
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=SHOTGUN; j<=SHOTGUN+6; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case DEVISTATORSPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j=DEVISTATOR; j<=DEVISTATOR+1; j++) tloadtile(j,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2018-10-25 23:33:09 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int j = picnum; j < (picnum + extraTiles); j++)
|
|
|
|
tloadtile(j, 1);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-11-18 18:08:14 +00:00
|
|
|
static void cacheDukeTiles(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
tloadtile(BOTTOMSTATUSBAR, 1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1))
|
|
|
|
tloadtile(FRAGBAR, 1);
|
|
|
|
|
|
|
|
tloadtile(VIEWSCREEN, 1);
|
|
|
|
|
|
|
|
for (int i = STARTALPHANUM; i < ENDALPHANUM+1; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = BIGALPHANUM-11; i < BIGALPHANUM+82; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = MINIFONT; i < MINIFONT+93; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = FOOTPRINTS; i < FOOTPRINTS+3; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = BURNING; i < BURNING+14; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = BURNING2; i < BURNING2+14; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = CRACKKNUCKLES; i < CRACKKNUCKLES+4; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = FIRSTGUN; i < FIRSTGUN+3; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = FIRSTGUNRELOAD; i < FIRSTGUNRELOAD+8; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = EXPLOSION2; i < EXPLOSION2+21; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = COOLEXPLOSION1; i < COOLEXPLOSION1+21; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
tloadtile(BULLETHOLE, 1);
|
|
|
|
tloadtile(BLOODPOOL, 1);
|
|
|
|
|
|
|
|
for (int i = TRANSPORTERBEAM; i < (TRANSPORTERBEAM+6); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = SMALLSMOKE; i < (SMALLSMOKE+4); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = SHOTSPARK1; i < (SHOTSPARK1+4); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = BLOOD; i < (BLOOD+4); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = JIBS1; i < (JIBS5+5); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = JIBS6; i < (JIBS6+8); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = SCRAP1; i < (SCRAP1+29); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
tloadtile(FIRELASER, 1);
|
|
|
|
|
|
|
|
for (int i = TRANSPORTERSTAR; i < TRANSPORTERSTAR+6; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = FORCERIPPLE; i < (FORCERIPPLE+9); i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = MENUSCREEN; i < DUKECAR; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
|
|
|
|
for (int i = RPG; i < RPG+7; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = FREEZEBLAST; i < FREEZEBLAST+3; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = SHRINKSPARK; i < SHRINKSPARK+4; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = GROWSPARK; i < GROWSPARK+4; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = SHRINKEREXPLOSION; i < SHRINKEREXPLOSION+4; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = MORTER; i < MORTER+4; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
for (int i = 0; i <= 60; i++)
|
|
|
|
tloadtile(i, 1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
static void cacheFlaggedTiles(void)
|
2018-11-18 18:08:08 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < MAXTILES; i++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2014-02-22 19:38:52 +00:00
|
|
|
if (g_tile[i].flags & SFLAG_PROJECTILE)
|
2018-11-18 18:08:08 +00:00
|
|
|
tloadtile(i, 1);
|
2012-10-30 15:54:35 +00:00
|
|
|
|
2014-02-22 19:38:52 +00:00
|
|
|
if (A_CheckSpriteTileFlags(i, SFLAG_CACHE))
|
2018-11-18 18:08:08 +00:00
|
|
|
for (int j = i; j <= g_tile[i].cacherange; j++)
|
|
|
|
tloadtile(j, 1);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-11-18 18:08:14 +00:00
|
|
|
cacheDukeTiles();
|
2018-11-18 18:08:08 +00:00
|
|
|
#endif
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
static void G_DemoLoadScreen(const char *statustext, int const loadScreenTile, int percent)
|
|
|
|
{
|
|
|
|
if (statustext == NULL)
|
|
|
|
{
|
|
|
|
videoClearScreen(0L);
|
|
|
|
// g_player[myconnectindex].ps->palette = palette;
|
|
|
|
// G_FadePalette(0,0,0,0);
|
|
|
|
P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0); // JBF 20040308
|
|
|
|
}
|
2008-04-25 01:46:19 +00:00
|
|
|
|
2018-12-15 22:33:09 +00:00
|
|
|
if ((unsigned)loadScreenTile < (MAXTILES<<1))
|
2018-11-18 18:08:08 +00:00
|
|
|
{
|
2018-12-15 22:33:09 +00:00
|
|
|
rotatesprite_fs(320<<15, 200<<15, 65536L, 0, loadScreenTile, 0, 0, 2+8+64+BGSTRETCH);
|
2018-11-18 18:08:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
videoNextPage();
|
|
|
|
return;
|
|
|
|
}
|
2007-03-01 00:50:59 +00:00
|
|
|
|
2019-12-07 13:53:13 +00:00
|
|
|
FStringf msg("%s...", GStrings("TXT_LOADING"));
|
|
|
|
menutext_center(105, msg);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (statustext)
|
|
|
|
gametext_center_number(180, statustext);
|
2007-03-11 00:47:32 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
VM_OnEventWithReturn(EVENT_DISPLAYLOADINGSCREEN, g_player[screenpeek].ps->i, screenpeek, percent);
|
|
|
|
videoNextPage();
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
static void G_DoLoadScreen(const char *statustext, int percent)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
int const loadScreenTile = VM_OnEventWithReturn(EVENT_GETLOADTILE, g_player[screenpeek].ps->i, screenpeek, LOADSCREEN);
|
|
|
|
|
|
|
|
if (ud.recstat == 2)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
G_DemoLoadScreen(statustext, loadScreenTile, percent);
|
|
|
|
return;
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
int const screenSize = ud.screen_size;
|
2011-12-28 20:35:23 +00:00
|
|
|
|
2020-01-26 09:58:00 +00:00
|
|
|
P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0);
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (statustext == NULL)
|
|
|
|
{
|
|
|
|
ud.screen_size = 0;
|
|
|
|
G_UpdateScreenArea();
|
|
|
|
videoClearScreen(0L);
|
|
|
|
}
|
2012-08-16 21:48:52 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if ((unsigned)loadScreenTile < (MAXTILES<<1))
|
|
|
|
{
|
|
|
|
videoClearScreen(0);
|
2018-12-15 22:33:09 +00:00
|
|
|
rotatesprite_fs(320<<15, 200<<15, 65536L, 0, loadScreenTile, 0, 0, 2+8+64+BGSTRETCH);
|
2018-11-18 18:08:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
videoNextPage();
|
|
|
|
return;
|
|
|
|
}
|
2011-08-17 18:52:54 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0)
|
|
|
|
{
|
2019-12-07 13:53:13 +00:00
|
|
|
menutext_center(90, GStrings("TXT_LOADUM"));
|
2018-11-18 18:08:08 +00:00
|
|
|
gametext_center_shade_pal(90+10, boardfilename, 14, 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-07 13:53:13 +00:00
|
|
|
menutext_center(90, GStrings("TXT_LOADING"));
|
2019-12-09 23:01:45 +00:00
|
|
|
menutext_center(90+16+8, mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName());
|
2018-11-18 18:08:08 +00:00
|
|
|
}
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2015-02-11 05:22:55 +00:00
|
|
|
#ifndef EDUKE32_TOUCH_DEVICES
|
2018-11-18 18:08:08 +00:00
|
|
|
if (statustext)
|
|
|
|
gametext_center_number(180, statustext);
|
2015-02-11 05:22:55 +00:00
|
|
|
#endif
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (percent != -1)
|
|
|
|
{
|
|
|
|
int const width = scale(scale(xdim-1, 288, 320), percent, 100);
|
|
|
|
int constexpr tile = 929;
|
|
|
|
int constexpr bits = 2+8+16;
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
rotatesprite(31<<16 , 145<<16, 65536, 0, tile, 15, 0, bits, 0, 0, width, ydim-1);
|
|
|
|
rotatesprite(159<<16, 145<<16, 65536, 0, tile, 15, 0, bits, 0, 0, width, ydim-1);
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
rotatesprite(30<<16 , 144<<16, 65536, 0, tile, 0, 0, bits, 0, 0, width, ydim-1);
|
|
|
|
rotatesprite(158<<16, 144<<16, 65536, 0, tile, 0, 0, bits, 0, 0, width, ydim-1);
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
2011-08-17 18:52:54 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
VM_OnEventWithReturn(EVENT_DISPLAYLOADINGSCREEN, g_player[screenpeek].ps->i, screenpeek, percent);
|
|
|
|
videoNextPage();
|
2011-08-17 18:52:54 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (!statustext)
|
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.keyFlushChars();
|
2018-11-18 18:08:08 +00:00
|
|
|
ud.screen_size = screenSize;
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
|
2018-10-16 06:08:50 +00:00
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
void G_CacheMapData(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-13 23:12:47 +00:00
|
|
|
if (ud.recstat == 2)
|
2006-04-16 03:42:36 +00:00
|
|
|
return;
|
|
|
|
|
2019-12-10 23:57:53 +00:00
|
|
|
//S_TryPlaySpecialMusic(MUS_LOADING);
|
2008-03-16 06:37:47 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
uint32_t const cacheStartTime = timerGetTicks();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
cacheFlaggedTiles();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
for (int i=0; i<numwalls; i++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
|
|
|
tloadtile(wall[i].picnum, 0);
|
|
|
|
|
2006-11-15 01:16:55 +00:00
|
|
|
if (wall[i].overpicnum >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
tloadtile(wall[i].overpicnum, 0);
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
for (int i=0; i<numsectors; i++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-14 21:35:50 +00:00
|
|
|
tloadtile(sector[i].floorpicnum, 0);
|
|
|
|
tloadtile(sector[i].ceilingpicnum, 0);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
for (int SPRITES_OF_SECT(i, j))
|
|
|
|
{
|
|
|
|
if (sprite[j].xrepeat != 0 && sprite[j].yrepeat != 0 && (sprite[j].cstat & CSTAT_SPRITE_INVISIBLE) == 0)
|
2018-11-18 18:08:14 +00:00
|
|
|
cacheTilesForSprite(j);
|
2018-11-18 18:08:08 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 13:39:54 +00:00
|
|
|
int clock = (int) totalclock;
|
2018-11-18 18:08:08 +00:00
|
|
|
int cnt = 0;
|
|
|
|
int percentDisplayed = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
for (int i=0; i<MAXTILES && !inputState.GetKeyStatus(sc_Space); i++)
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
|
|
|
if (!(i&7) && !gotpic[i>>3])
|
|
|
|
{
|
2006-04-16 03:42:36 +00:00
|
|
|
i+=7;
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-18 18:08:14 +00:00
|
|
|
else if ((gotpic[i>>3] & pow2char[i&7]) != pow2char[i&7])
|
|
|
|
continue;
|
2011-09-28 20:30:24 +00:00
|
|
|
|
2019-10-14 22:54:14 +00:00
|
|
|
// For the hardware renderer precaching the raw pixel data is pointless.
|
|
|
|
if (videoGetRenderMode() < REND_POLYMOST)
|
|
|
|
tileLoad(i);
|
2018-11-18 18:08:08 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
#ifdef USE_OPENGL
|
2019-10-23 12:39:33 +00:00
|
|
|
if (r_precache) PrecacheHardwareTextures(i);
|
2006-08-07 19:57:53 +00:00
|
|
|
#endif
|
2006-04-16 03:42:36 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
if ((++cnt & 7) == 0)
|
2019-10-19 23:41:40 +00:00
|
|
|
gameHandleEvents();
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2014-01-12 14:54:36 +00:00
|
|
|
Bmemset(gotpic, 0, sizeof(gotpic));
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
OSD_Printf("Cache time: %dms\n", timerGetTicks() - cacheStartTime);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
int fragbarheight(void)
|
2018-01-26 04:34:51 +00:00
|
|
|
{
|
|
|
|
if (ud.screen_size > 0 && !(ud.statusbarflags & STATUSBAR_NOFRAGBAR)
|
|
|
|
#ifdef SPLITSCREEN_MOD_HACKS
|
|
|
|
&& !g_fakeMultiMode
|
|
|
|
#endif
|
|
|
|
&& (g_netServer || ud.multimode > 1) && GTFLAGS(GAMETYPE_FRAGBAR))
|
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
int j = 0;
|
2018-01-26 04:34:51 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
for (int TRAVERSE_CONNECT(i))
|
2018-01-26 04:34:51 +00:00
|
|
|
if (i > j)
|
|
|
|
j = i;
|
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
return ((j + 3) >> 2) * tilesiz[FRAGBAR].y;
|
2018-01-26 04:34:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
void G_UpdateScreenArea(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2013-05-30 09:13:32 +00:00
|
|
|
if (!in3dmode())
|
2013-01-17 21:59:11 +00:00
|
|
|
return;
|
2009-04-29 19:43:51 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if ((ud.screen_size = clamp(ud.screen_size, 0, 64)) == 0)
|
2018-04-12 21:04:00 +00:00
|
|
|
renderFlushPerms();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
int const screenSize = max(ud.screen_size - 8, 0);
|
|
|
|
int const bottomStatusY = tilesiz[BOTTOMSTATUSBAR].y;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
vec2_t v1 = { scale(screenSize, xdim, 160),
|
|
|
|
scale(screenSize, (200 * 100) - (bottomStatusY * ud.statusbarscale), 200 - bottomStatusY) };
|
|
|
|
vec2_t v2 = { xdim - v1.x, 200 * 100 - v1.y };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
v1.y += fragbarheight() * 100;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (ud.screen_size >= 8 && ud.statusbarmode == 0)
|
|
|
|
v2.y -= bottomStatusY * ud.statusbarscale;
|
2017-11-29 07:29:44 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
v1.y = scale(v1.y, ydim, 200 * 100);
|
|
|
|
v2.y = scale(v2.y, ydim, 200 * 100);
|
2013-01-20 21:17:31 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
if (VM_HaveEvent(EVENT_UPDATESCREENAREA))
|
|
|
|
{
|
|
|
|
ud.returnvar[0] = v1.y;
|
|
|
|
ud.returnvar[1] = v2.x;
|
|
|
|
ud.returnvar[2] = v2.y;
|
|
|
|
v1.x = VM_OnEventWithReturn(EVENT_UPDATESCREENAREA, g_player[screenpeek].ps->i, screenpeek, v1.x);
|
|
|
|
v1.y = ud.returnvar[0];
|
|
|
|
v2.x = ud.returnvar[1];
|
|
|
|
v2.y = ud.returnvar[2];
|
2013-01-17 21:59:11 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
videoSetViewableArea(v1.x, v1.y, v2.x-1, v2.y-1);
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
pub = NUMPAGES;
|
|
|
|
pus = NUMPAGES;
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
void P_MoveToRandomSpawnPoint(int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &p = *g_player[playerNum].ps;
|
|
|
|
int i = playerNum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1) && !(g_gametypeFlags[ud.coop] & GAMETYPE_FIXEDRESPAWN))
|
2006-08-18 23:52:26 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
i = krand() % g_playerSpawnCnt;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_gametypeFlags[ud.coop] & GAMETYPE_TDMSPAWN)
|
2006-08-18 23:52:26 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
uint32_t pdist = INT_MAX;
|
|
|
|
|
|
|
|
for (int TRAVERSE_CONNECT(j))
|
2006-08-18 23:52:26 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
if (j == playerNum)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto const &op = *g_player[j].ps;
|
|
|
|
|
|
|
|
// pick a spawn near a living teammate
|
|
|
|
if (op.team == p.team && sprite[op.i].extra > 0)
|
2006-08-18 23:52:26 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int k = 0; k < g_playerSpawnCnt; k++)
|
2006-08-18 23:52:26 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
uint32_t const dist = FindDistance2D(op.pos.x - g_playerSpawnPoints[k].pos.x,
|
|
|
|
op.pos.y - g_playerSpawnPoints[k].pos.y);
|
2006-11-13 23:12:47 +00:00
|
|
|
if (dist < pdist)
|
2006-08-18 23:52:26 +00:00
|
|
|
i = k, pdist = dist;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-08-18 23:52:26 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
p.opos = p.pos = g_playerSpawnPoints[i].pos;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2019-08-07 22:43:48 +00:00
|
|
|
p.bobpos = p.pos.vec2;
|
2018-11-18 18:07:51 +00:00
|
|
|
p.cursectnum = g_playerSpawnPoints[i].sect;
|
|
|
|
p.q16ang = fix16_from_int(g_playerSpawnPoints[i].ang);
|
|
|
|
|
|
|
|
sprite[p.i].cstat = CSTAT_SPRITE_BLOCK + CSTAT_SPRITE_BLOCK_HITSCAN;
|
2009-12-12 11:07:59 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
static inline void P_ResetTintFade(DukePlayer_t *const pPlayer)
|
2013-06-20 18:31:50 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pPlayer->pals.f = 0;
|
2013-06-20 18:31:50 +00:00
|
|
|
#ifdef LUNATIC
|
2016-08-27 01:40:56 +00:00
|
|
|
pPlayer->palsfadeprio = 0;
|
2013-06-20 18:31:50 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
void P_ResetMultiPlayer(int playerNum)
|
2009-12-12 11:07:59 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &p = *g_player[playerNum].ps;
|
|
|
|
|
|
|
|
Bassert((unsigned)p.i < MAXSPRITES);
|
|
|
|
|
|
|
|
auto &s = sprite[p.i];
|
|
|
|
auto &a = actor[p.i];
|
|
|
|
|
|
|
|
vec3_t tmpvect = p.pos;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
tmpvect.z += PHEIGHT;
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
P_MoveToRandomSpawnPoint(playerNum);
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
a.bpos = p.opos = p.pos;
|
2019-08-07 22:43:48 +00:00
|
|
|
p.bobpos = p.pos.vec2;
|
2018-11-18 18:07:51 +00:00
|
|
|
|
2019-08-13 14:44:00 +00:00
|
|
|
s.pos = p.pos;
|
2018-11-18 18:07:51 +00:00
|
|
|
|
|
|
|
updatesector(p.pos.x, p.pos.y, &p.cursectnum);
|
|
|
|
setsprite(p.i, &tmpvect);
|
|
|
|
|
|
|
|
s.clipdist = 64;
|
|
|
|
s.cstat = 257;
|
|
|
|
s.owner = p.i;
|
|
|
|
s.pal = p.palookup;
|
|
|
|
s.shade = -12; // ???
|
|
|
|
s.xoffset = 0;
|
|
|
|
s.xrepeat = 42;
|
|
|
|
s.yrepeat = 36;
|
|
|
|
|
|
|
|
p.last_extra = s.extra = p.max_player_health;
|
|
|
|
p.inv_amount[GET_SHIELD] = g_startArmorAmount;
|
|
|
|
|
|
|
|
p.dead_flag = 0;
|
|
|
|
p.falling_counter = 0;
|
|
|
|
p.footprintcount = 0;
|
|
|
|
p.frag_ps = playerNum;
|
|
|
|
p.fta = 0;
|
|
|
|
p.ftq = 0;
|
|
|
|
p.on_crane = -1;
|
|
|
|
p.opyoff = 0;
|
|
|
|
p.q16horiz = F16(100);
|
|
|
|
p.q16horizoff = 0;
|
|
|
|
p.rotscrnang = 0;
|
|
|
|
p.runspeed = g_playerFriction;
|
|
|
|
p.vel = { 0, 0, 0 };
|
|
|
|
p.wackedbyactor = -1;
|
|
|
|
p.wantweaponfire = -1;
|
|
|
|
p.weapreccnt = 0;
|
|
|
|
|
|
|
|
P_ResetTintFade(&p);
|
|
|
|
|
|
|
|
a.cgg = 0;
|
|
|
|
a.dispicnum = 0;
|
|
|
|
a.extra = -1;
|
|
|
|
a.movflag = 0;
|
|
|
|
a.owner = p.i;
|
|
|
|
a.stayput = -1;
|
|
|
|
a.t_data[4] = 0;
|
|
|
|
a.tempang = 0;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
P_ResetInventory(playerNum);
|
|
|
|
P_ResetWeapons(playerNum);
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
p.reloading = 0;
|
|
|
|
p.movement_lock = 0;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
VM_OnEvent(EVENT_RESETPLAYER, p.i, playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
void P_ResetPlayer(int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &p = *g_player[playerNum].ps;
|
|
|
|
|
|
|
|
ud.showallmap = 0;
|
|
|
|
|
|
|
|
p.access_spritenum = -1;
|
|
|
|
p.actorsqu = -1;
|
|
|
|
p.airleft = 15 * GAMETICSPERSEC;
|
|
|
|
p.autostep = (20L << 8);
|
|
|
|
p.autostep_sbw = (4L << 8);
|
|
|
|
p.bobcounter = 0;
|
|
|
|
p.buttonpalette = 0;
|
|
|
|
p.cheat_phase = 0;
|
|
|
|
p.clipdist = 164;
|
|
|
|
p.crack_time = 0;
|
|
|
|
p.dead_flag = 0;
|
|
|
|
p.dummyplayersprite = -1;
|
|
|
|
p.extra_extra8 = 0;
|
|
|
|
p.falling_counter = 0;
|
|
|
|
p.fist_incs = 0;
|
|
|
|
p.footprintcount = 0;
|
|
|
|
p.footprintpal = 0;
|
|
|
|
p.footprintshade = 0;
|
2018-11-18 18:07:57 +00:00
|
|
|
p.frag = 0;
|
2018-11-18 18:07:51 +00:00
|
|
|
p.frag_ps = playerNum;
|
2018-11-18 18:07:57 +00:00
|
|
|
p.fraggedself = 0;
|
2018-11-18 18:07:51 +00:00
|
|
|
p.fric = { 0, 0 };
|
|
|
|
p.fta = 0;
|
|
|
|
p.ftq = 0;
|
|
|
|
p.got_access = ((g_netServer || ud.multimode > 1) && (g_gametypeFlags[ud.coop] & GAMETYPE_ACCESSATSTART)) ? 7 : 0;
|
|
|
|
p.hard_landing = 0;
|
|
|
|
p.hbomb_hold_delay = 0;
|
|
|
|
p.heat_on = 0;
|
|
|
|
p.holoduke_on = -1;
|
|
|
|
p.holster_weapon = 0;
|
|
|
|
p.hurt_delay = 0;
|
|
|
|
p.invdisptime = 0;
|
|
|
|
p.jetpack_on = 0;
|
|
|
|
p.jumping_counter = 0;
|
|
|
|
p.jumping_toggle = 0;
|
|
|
|
p.knee_incs = 0;
|
|
|
|
p.knuckle_incs = 1;
|
|
|
|
p.last_full_weapon = 0;
|
|
|
|
p.last_pissed_time = 0;
|
|
|
|
p.loogcnt = 0;
|
|
|
|
p.look_ang = 512 - ((ud.level_number&1)<<10);
|
|
|
|
p.movement_lock = 0;
|
|
|
|
p.newowner = -1;
|
|
|
|
p.on_crane = -1;
|
|
|
|
p.on_ground = 0;
|
|
|
|
p.on_warping_sector = 0;
|
|
|
|
p.one_eighty_count = 0;
|
|
|
|
p.opyoff = 0;
|
|
|
|
p.oq16horiz = F16(140);
|
|
|
|
p.orotscrnang = 1; // JBF 20031220
|
2018-11-18 18:07:57 +00:00
|
|
|
p.over_shoulder_on = 0;
|
2018-11-18 18:07:51 +00:00
|
|
|
p.palette = BASEPAL;
|
|
|
|
p.player_par = 0;
|
|
|
|
p.pycount = 0;
|
|
|
|
p.pyoff = 0;
|
|
|
|
p.q16angvel = 0;
|
|
|
|
p.q16horiz = F16(140);
|
|
|
|
p.q16horizoff = 0;
|
|
|
|
p.quick_kick = 0;
|
|
|
|
p.random_club_frame = 0;
|
|
|
|
p.rapid_fire_hold = 0;
|
|
|
|
p.reloading = 0;
|
|
|
|
p.return_to_center = 9;
|
|
|
|
p.rotscrnang = 0;
|
|
|
|
p.sbs = 0;
|
|
|
|
p.show_empty_weapon = 0;
|
|
|
|
p.somethingonplayer = -1;
|
|
|
|
p.spritebridge = 0;
|
|
|
|
p.subweapon = 0;
|
|
|
|
p.tipincs = 0;
|
|
|
|
p.toggle_key_flag = 0;
|
|
|
|
p.transporter_hold = 0;
|
|
|
|
p.vel.x = 0;
|
|
|
|
p.vel.y = 0;
|
|
|
|
p.vel.z = 0;
|
|
|
|
p.wackedbyactor = -1;
|
|
|
|
p.walking_snd_toggle = 0;
|
|
|
|
p.wantweaponfire = -1;
|
|
|
|
p.weapon_ang = 0;
|
|
|
|
p.weapon_pos = WEAPON_POS_START;
|
|
|
|
p.weapon_sway = 0;
|
|
|
|
|
|
|
|
pus = 1;
|
|
|
|
|
|
|
|
if (p.inv_amount[GET_STEROIDS] < 400)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
p.inv_amount[GET_STEROIDS] = 0;
|
|
|
|
p.inven_icon = ICON_NONE;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
p.kickback_pic = ((PWEAPON(playerNum, p.curr_weapon, WorksLike) == PISTOL_WEAPON)
|
|
|
|
&& (PWEAPON(playerNum, p.curr_weapon, Reload) > PWEAPON(playerNum, p.curr_weapon, TotalTime)))
|
|
|
|
? PWEAPON(playerNum, p.curr_weapon, TotalTime)
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
P_UpdateScreenPal(&p);
|
|
|
|
VM_OnEvent(EVENT_RESETPLAYER, p.i, playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
void P_ResetWeapons(int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &p = *g_player[playerNum].ps;
|
|
|
|
|
|
|
|
for (short & ammo : p.ammo_amount)
|
|
|
|
ammo = 0;
|
|
|
|
|
|
|
|
p.curr_weapon = PISTOL_WEAPON;
|
|
|
|
p.gotweapon = ((1 << PISTOL_WEAPON) | (1 << KNEE_WEAPON) | (1 << HANDREMOTE_WEAPON));
|
|
|
|
p.holster_weapon = 0;
|
|
|
|
p.kickback_pic = PWEAPON(playerNum, p.curr_weapon, TotalTime);
|
|
|
|
p.last_pissed_time = 0;
|
|
|
|
p.last_used_weapon = -1;
|
|
|
|
p.last_weapon = -1;
|
|
|
|
p.show_empty_weapon = 0;
|
|
|
|
p.weapon_pos = WEAPON_POS_START;
|
|
|
|
|
|
|
|
p.ammo_amount[PISTOL_WEAPON] = min<int16_t>(p.max_ammo_amount[PISTOL_WEAPON], 48);
|
|
|
|
|
|
|
|
VM_OnEvent(EVENT_RESETWEAPONS, p.i, playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
void P_ResetInventory(int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &p = *g_player[playerNum].ps;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
Bmemset(p.inv_amount, 0, sizeof(p.inv_amount));
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
p.heat_on = 0;
|
|
|
|
p.holoduke_on = -1;
|
|
|
|
p.inven_icon = ICON_NONE;
|
|
|
|
p.jetpack_on = 0;
|
|
|
|
p.scuba_on = 0;
|
2009-12-15 05:53:15 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
p.inv_amount[GET_SHIELD] = g_startArmorAmount;
|
|
|
|
|
|
|
|
VM_OnEvent(EVENT_RESETINVENTORY, p.i, playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
static void P_PrepForNewLevel(int playerNum, int gameMode)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &p = *g_player[playerNum].ps;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
g_spriteDeleteQueuePos = 0;
|
2018-11-18 18:07:51 +00:00
|
|
|
|
|
|
|
for (short &i : SpriteDeletionQueue)
|
|
|
|
i = -1;
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
g_animWallCnt = 0;
|
|
|
|
g_animateCnt = 0;
|
|
|
|
g_curViewscreen = -1;
|
2018-11-18 18:07:51 +00:00
|
|
|
g_cyclerCnt = 0;
|
2016-08-27 01:42:01 +00:00
|
|
|
g_earthquakeTime = 0;
|
|
|
|
g_interpolationCnt = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
randomseed = 1996;
|
|
|
|
screenpeek = myconnectindex;
|
|
|
|
tempwallptr = 0;
|
|
|
|
|
|
|
|
p.actors_killed = 0;
|
|
|
|
p.cheat_phase = 0;
|
|
|
|
p.customexitsound = 0;
|
|
|
|
p.hbomb_on = 0;
|
|
|
|
p.holster_weapon = 0;
|
|
|
|
p.interface_toggle = 0;
|
|
|
|
p.last_pissed_time = 0;
|
|
|
|
p.last_weapon = -1;
|
|
|
|
p.max_actors_killed = 0;
|
|
|
|
p.max_secret_rooms = 0;
|
|
|
|
p.parallax_sectnum = -1;
|
|
|
|
p.secret_rooms = 0;
|
|
|
|
p.show_empty_weapon = 0;
|
|
|
|
p.timebeforeexit = 0;
|
|
|
|
p.toggle_key_flag = 0;
|
|
|
|
p.visibility = ud.const_visibility;
|
|
|
|
p.weapon_pos = WEAPON_POS_START;
|
|
|
|
p.weapreccnt = 0;
|
|
|
|
|
|
|
|
p.kickback_pic = ((PWEAPON(playerNum, p.curr_weapon, WorksLike) == PISTOL_WEAPON)
|
|
|
|
&& (PWEAPON(playerNum, p.curr_weapon, Reload) > PWEAPON(playerNum, p.curr_weapon, TotalTime)))
|
|
|
|
? PWEAPON(playerNum, p.curr_weapon, TotalTime)
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
ud.camerasprite = -1;
|
|
|
|
ud.eog = 0;
|
|
|
|
ud.pause_on = 0;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (((gameMode & MODE_EOL) != MODE_EOL && numplayers < 2 && !g_netServer)
|
2016-08-27 01:42:01 +00:00
|
|
|
|| (!(g_gametypeFlags[ud.coop] & GAMETYPE_PRESERVEINVENTORYDEATH) && numplayers > 1))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
P_ResetWeapons(playerNum);
|
|
|
|
P_ResetInventory(playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2018-11-18 18:07:51 +00:00
|
|
|
else if (PWEAPON(playerNum, p.curr_weapon, WorksLike) == HANDREMOTE_WEAPON)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
p.ammo_amount[HANDBOMB_WEAPON]++;
|
|
|
|
p.curr_weapon = HANDBOMB_WEAPON;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
P_ResetTintFade(&p);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:38:54 +00:00
|
|
|
// Tweak sprites contained in moving sectors with these SE lotags.
|
2016-08-27 01:40:56 +00:00
|
|
|
#define FIXSPR_SELOTAGP(k) ((k) == SE_0_ROTATING_SECTOR || (k) == SE_6_SUBWAY || (k) == SE_14_SUBWAY_CAR)
|
2011-06-22 19:12:47 +00:00
|
|
|
|
2012-12-28 17:17:53 +00:00
|
|
|
// Set up sprites in moving sectors that are to be fixed wrt a certain pivot
|
2011-06-22 19:12:47 +00:00
|
|
|
// position and should not diverge from it due to roundoff error in the future.
|
2012-12-28 17:17:53 +00:00
|
|
|
// Has to be after the spawning stuff.
|
|
|
|
static void G_SetupRotfixedSprites(void)
|
2011-06-22 19:12:47 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int spriteNum, nextSpriteNum;
|
2011-06-22 19:12:47 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
for (SPRITES_OF_STAT_SAFE(STAT_EFFECTOR, spriteNum, nextSpriteNum))
|
2011-06-22 19:12:47 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto const &s = sprite[spriteNum];
|
|
|
|
|
|
|
|
if (FIXSPR_SELOTAGP(s.lotag))
|
2011-06-22 19:12:47 +00:00
|
|
|
{
|
2011-06-29 19:57:05 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2016-08-27 01:40:56 +00:00
|
|
|
int firstrun = 1;
|
2011-06-29 19:57:05 +00:00
|
|
|
#endif
|
2018-11-18 18:07:51 +00:00
|
|
|
int sectSprite = headspritesect[s.sectnum];
|
2014-02-22 19:38:54 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
do
|
2011-06-22 19:12:47 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto const &ss = sprite[sectSprite];
|
|
|
|
auto &a = actor[sectSprite];
|
2014-02-22 19:38:54 +00:00
|
|
|
|
2011-06-22 19:12:47 +00:00
|
|
|
// TRIPBOMB uses t_data[7] for its own purposes. Wouldn't be
|
|
|
|
// too useful with moving sectors anyway
|
2018-11-18 18:07:51 +00:00
|
|
|
if ((ROTFIXSPR_STATNUMP(ss.statnum) && ss.picnum != TRIPBOMB)
|
|
|
|
|| ((ss.statnum == STAT_ACTOR || ss.statnum == STAT_ZOMBIEACTOR) && A_CheckSpriteFlags(sectSprite, SFLAG_ROTFIXED)))
|
2011-06-22 19:12:47 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
int const pivotSprite = (s.lotag == 0) ? s.owner : spriteNum;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
if (sectSprite != spriteNum && sectSprite != pivotSprite && pivotSprite >= 0 && pivotSprite < MAXSPRITES)
|
2011-06-29 19:57:05 +00:00
|
|
|
{
|
|
|
|
// let's hope we don't step on anyone's toes here
|
2018-11-18 18:07:51 +00:00
|
|
|
a.t_data[7] = ROTFIXSPR_MAGIC | pivotSprite; // 'rs' magic + pivot SE sprite index
|
|
|
|
a.t_data[8] = ss.x - sprite[pivotSprite].x;
|
|
|
|
a.t_data[9] = ss.y - sprite[pivotSprite].y;
|
2011-06-29 19:57:05 +00:00
|
|
|
}
|
2011-06-22 19:12:47 +00:00
|
|
|
}
|
2011-06-29 19:57:05 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
sectSprite = nextspritesect[sectSprite];
|
2011-06-29 19:57:05 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2018-11-18 18:07:51 +00:00
|
|
|
if ((sectSprite < 0 && firstrun) && (s.lotag == SE_6_SUBWAY || s.lotag == SE_14_SUBWAY_CAR))
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
|
|
|
firstrun = 0;
|
|
|
|
sectSprite = actor[spriteNum].t_data[9];
|
|
|
|
|
|
|
|
if (sectSprite >= 0)
|
|
|
|
sectSprite = headspritesect[sectSprite];
|
|
|
|
}
|
2011-06-29 19:57:05 +00:00
|
|
|
#endif
|
2018-11-18 18:07:51 +00:00
|
|
|
}
|
|
|
|
while (sectSprite >= 0);
|
2011-06-22 19:12:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
static void G_SetupLightSwitches()
|
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto tagbitmap = (uint8_t *)Xcalloc(65536 >> 3, 1);
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int nextSprite, SPRITES_OF_STAT_SAFE(STAT_DEFAULT, spriteNum, nextSprite))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:08:14 +00:00
|
|
|
auto &s = sprite[spriteNum];
|
|
|
|
|
|
|
|
if (s.picnum <= 0) // oob safety for switch below
|
2011-12-11 13:26:39 +00:00
|
|
|
continue;
|
|
|
|
|
2018-11-18 18:08:14 +00:00
|
|
|
for (int i = 0; i < 2; i++)
|
2016-08-27 01:42:01 +00:00
|
|
|
{
|
2018-11-18 18:08:14 +00:00
|
|
|
switch (DYNAMICTILEMAP(s.picnum-1+i))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
case DIPSWITCH__STATIC:
|
|
|
|
case DIPSWITCH2__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
case FRANKENSTINESWITCH__STATIC:
|
2018-11-18 18:07:57 +00:00
|
|
|
case HANDSWITCH__STATIC:
|
|
|
|
case LIGHTSWITCH__STATIC:
|
|
|
|
case LIGHTSWITCH2__STATIC:
|
|
|
|
case LOCKSWITCH1__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
case POWERSWITCH1__STATIC:
|
2018-11-18 18:07:57 +00:00
|
|
|
case POWERSWITCH2__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
case PULLSWITCH__STATIC:
|
|
|
|
case SLOTDOOR__STATIC:
|
|
|
|
case SPACEDOORSWITCH__STATIC:
|
|
|
|
case SPACELIGHTSWITCH__STATIC:
|
2018-11-18 18:07:57 +00:00
|
|
|
// the lower code only for the 'on' state (*)
|
2018-11-18 18:08:14 +00:00
|
|
|
if (i == 0)
|
2018-11-18 18:07:57 +00:00
|
|
|
{
|
2018-11-18 18:08:14 +00:00
|
|
|
uint16_t const tag = s.lotag;
|
2018-11-18 18:07:57 +00:00
|
|
|
tagbitmap[tag >> 3] |= 1 << (tag & 7);
|
|
|
|
}
|
2011-08-17 18:52:54 +00:00
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
2011-08-17 18:52:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// initially 'on' SE 12 light (*)
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int nextSprite, SPRITES_OF_STAT_SAFE(STAT_EFFECTOR, j, nextSprite))
|
2011-08-17 18:52:54 +00:00
|
|
|
{
|
2018-02-11 05:03:50 +00:00
|
|
|
uint16_t const tag = sprite[j].hitag;
|
2011-08-17 18:52:16 +00:00
|
|
|
|
2019-08-04 02:51:50 +00:00
|
|
|
if (sprite[j].lotag == SE_12_LIGHT_SWITCH && tagbitmap[tag>>3] & pow2char[tag&7])
|
2011-08-17 18:52:54 +00:00
|
|
|
actor[j].t_data[0] = 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
DO_FREE_AND_NULL(tagbitmap);
|
2018-11-18 18:07:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void G_SetupSpecialWalls(void)
|
|
|
|
{
|
2008-11-20 14:06:36 +00:00
|
|
|
g_mirrorCount = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int i = 0; i < numwalls; i++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &w = wall[i];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
if (w.overpicnum == MIRROR && (w.cstat & 32) != 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
int const nextSectnum = w.nextsector;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((nextSectnum >= 0) && sector[nextSectnum].ceilingpicnum != MIRROR)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-01-05 20:48:05 +00:00
|
|
|
if (g_mirrorCount > 63)
|
2016-08-27 01:42:01 +00:00
|
|
|
{
|
2012-01-05 20:48:05 +00:00
|
|
|
G_GameExit("\nToo many mirrors (64 max.)");
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
2012-01-05 20:48:05 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
sector[nextSectnum].ceilingpicnum = MIRROR;
|
|
|
|
sector[nextSectnum].floorpicnum = MIRROR;
|
|
|
|
g_mirrorWall[g_mirrorCount] = i;
|
|
|
|
g_mirrorSector[g_mirrorCount] = nextSectnum;
|
2008-11-20 14:06:36 +00:00
|
|
|
g_mirrorCount++;
|
2006-04-13 20:47:06 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_animWallCnt >= MAXANIMWALLS)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
Bsprintf(tempbuf, "\nToo many 'anim' walls (%d max).", MAXANIMWALLS);
|
2008-11-20 14:06:36 +00:00
|
|
|
G_GameExit(tempbuf);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &aw = animwall[g_animWallCnt];
|
2012-09-12 09:45:14 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
aw.tag = 0;
|
|
|
|
aw.wallnum = 0;
|
2011-12-09 19:12:15 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
switch (DYNAMICTILEMAP(G_GetForcefieldPicnum(i)))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
case FANSHADOW__STATIC:
|
|
|
|
case FANSPRITE__STATIC:
|
2018-11-18 18:08:14 +00:00
|
|
|
// w.cstat |= 65;
|
2018-11-18 18:07:51 +00:00
|
|
|
aw.wallnum = i;
|
|
|
|
g_animWallCnt++;
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
case W_FORCEFIELD__STATIC:
|
|
|
|
if (w.overpicnum == W_FORCEFIELD__STATIC)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 3; j++)
|
|
|
|
tloadtile(W_FORCEFIELD + j, 0);
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (w.shade > 31)
|
|
|
|
w.cstat = 0;
|
|
|
|
else
|
|
|
|
w.cstat |= FORCEFIELD_CSTAT | CSTAT_WALL_BLOCK;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (w.lotag && w.nextwall >= 0)
|
|
|
|
wall[w.nextwall].lotag = w.lotag;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
fallthrough__;
|
|
|
|
case BIGFORCE__STATIC:
|
|
|
|
aw.wallnum = i;
|
|
|
|
g_animWallCnt++;
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
w.extra = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
switch (DYNAMICTILEMAP(w.picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-09-28 04:27:23 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
case FEMPIC1__STATIC:
|
|
|
|
case FEMPIC2__STATIC:
|
|
|
|
case FEMPIC3__STATIC:
|
2018-11-18 18:07:51 +00:00
|
|
|
w.extra = w.picnum;
|
2018-09-28 04:27:23 +00:00
|
|
|
|
2019-10-27 12:40:24 +00:00
|
|
|
if (adult_lockout)
|
2018-11-18 18:07:51 +00:00
|
|
|
w.picnum = (w.picnum == FEMPIC1) ? BLANKSCREEN : SCREENBREAK6;
|
2018-09-28 04:27:23 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
aw.tag = w.picnum;
|
|
|
|
aw.wallnum = i;
|
2018-09-28 04:27:23 +00:00
|
|
|
g_animWallCnt++;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
case W_TECHWALL1__STATIC:
|
|
|
|
case W_TECHWALL2__STATIC:
|
|
|
|
case W_TECHWALL3__STATIC:
|
|
|
|
case W_TECHWALL4__STATIC:
|
2018-11-18 18:07:51 +00:00
|
|
|
aw.wallnum = i;
|
2016-08-27 01:42:01 +00:00
|
|
|
g_animWallCnt++;
|
|
|
|
break;
|
|
|
|
case SCREENBREAK6__STATIC:
|
|
|
|
case SCREENBREAK7__STATIC:
|
|
|
|
case SCREENBREAK8__STATIC:
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int j = SCREENBREAK6; j < SCREENBREAK9; j++)
|
2016-08-27 01:42:01 +00:00
|
|
|
tloadtile(j, 0);
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
aw.tag = -1;
|
|
|
|
aw.wallnum = i;
|
2016-08-27 01:42:01 +00:00
|
|
|
g_animWallCnt++;
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
case SCREENBREAK1__STATIC:
|
|
|
|
case SCREENBREAK2__STATIC:
|
|
|
|
case SCREENBREAK3__STATIC:
|
|
|
|
case SCREENBREAK4__STATIC:
|
|
|
|
case SCREENBREAK5__STATIC:
|
2012-09-12 09:45:14 +00:00
|
|
|
//
|
2016-08-27 01:42:01 +00:00
|
|
|
case SCREENBREAK9__STATIC:
|
|
|
|
case SCREENBREAK10__STATIC:
|
|
|
|
case SCREENBREAK11__STATIC:
|
|
|
|
case SCREENBREAK12__STATIC:
|
|
|
|
case SCREENBREAK13__STATIC:
|
|
|
|
case SCREENBREAK14__STATIC:
|
|
|
|
case SCREENBREAK15__STATIC:
|
|
|
|
case SCREENBREAK16__STATIC:
|
|
|
|
case SCREENBREAK17__STATIC:
|
|
|
|
case SCREENBREAK18__STATIC:
|
|
|
|
case SCREENBREAK19__STATIC:
|
2018-11-18 18:07:51 +00:00
|
|
|
aw.tag = w.picnum;
|
|
|
|
aw.wallnum = i;
|
2016-08-27 01:42:01 +00:00
|
|
|
g_animWallCnt++;
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
// Invalidate textures in sector behind mirror
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int i = 0; i < g_mirrorCount; i++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const startWall = sector[g_mirrorSector[i]].wallptr;
|
|
|
|
int const endWall = startWall + sector[g_mirrorSector[i]].wallnum;
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int j = startWall; j < endWall; j++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
wall[j].picnum = wall[j].overpicnum = MIRROR;
|
2016-08-27 01:42:01 +00:00
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
if (wall[g_mirrorWall[i]].pal == 4)
|
2008-10-11 11:50:02 +00:00
|
|
|
wall[j].pal = 4;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
static void A_MaybeProcessEffector(int spriteNum)
|
|
|
|
{
|
|
|
|
switch (DYNAMICTILEMAP(PN(spriteNum)))
|
|
|
|
{
|
2018-11-18 18:08:14 +00:00
|
|
|
case ACTIVATOR__STATIC:
|
|
|
|
case ACTIVATORLOCKED__STATIC:
|
|
|
|
case LOCATORS__STATIC:
|
|
|
|
case MASTERSWITCH__STATIC:
|
|
|
|
case MUSICANDSFX__STATIC:
|
|
|
|
case RESPAWN__STATIC:
|
|
|
|
case SECTOREFFECTOR__STATIC:
|
|
|
|
case TOUCHPLATE__STATIC:
|
|
|
|
sprite[spriteNum].cstat &= ~(CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_ALIGNMENT_MASK);
|
|
|
|
break;
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
case GPSPEED__STATIC:
|
|
|
|
// DELETE_AFTER_LOADACTOR. Must not change statnum.
|
|
|
|
sector[SECT(spriteNum)].extra = SLT(spriteNum);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CYCLER__STATIC:
|
|
|
|
{
|
|
|
|
// DELETE_AFTER_LOADACTOR. Must not change statnum.
|
|
|
|
if (g_cyclerCnt >= MAXCYCLERS)
|
|
|
|
{
|
|
|
|
Bsprintf(tempbuf, "\nToo many cycling sectors (%d max).", MAXCYCLERS);
|
|
|
|
G_GameExit(tempbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto &cycler = g_cyclers[g_cyclerCnt];
|
|
|
|
|
|
|
|
cycler[0] = SECT(spriteNum);
|
|
|
|
cycler[1] = SLT(spriteNum);
|
|
|
|
cycler[2] = SS(spriteNum);
|
|
|
|
cycler[3] = sector[SECT(spriteNum)].floorshade;
|
|
|
|
cycler[4] = SHT(spriteNum);
|
|
|
|
cycler[5] = (SA(spriteNum) == 1536);
|
|
|
|
|
|
|
|
g_cyclerCnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void G_SpawnAllSprites()
|
|
|
|
{
|
|
|
|
// I don't know why this is separated, but I have better things to do than combine them and see what happens
|
|
|
|
for (int i = 0; i < MAXSPRITES; i++)
|
|
|
|
{
|
|
|
|
if (sprite[i].statnum < MAXSTATUS && (PN(i) != SECTOREFFECTOR || SLT(i) != SE_14_SUBWAY_CAR))
|
|
|
|
A_Spawn(-1, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < MAXSPRITES; i++)
|
|
|
|
{
|
|
|
|
if (sprite[i].statnum < MAXSTATUS && PN(i) == SECTOREFFECTOR && SLT(i) == SE_14_SUBWAY_CAR)
|
|
|
|
A_Spawn(-1, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void G_DeleteTempEffectors()
|
|
|
|
{
|
|
|
|
for (int nextSprite, SPRITES_OF_STAT_SAFE(STAT_DEFAULT, i, nextSprite))
|
|
|
|
{
|
2018-11-18 18:08:26 +00:00
|
|
|
switch (DYNAMICTILEMAP(PN(i)))
|
2018-11-18 18:07:57 +00:00
|
|
|
{
|
2018-11-18 18:08:26 +00:00
|
|
|
case GPSPEED__STATIC:
|
|
|
|
case CYCLER__STATIC: A_DeleteSprite(i); break;
|
2018-11-18 18:07:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prelevel(int g)
|
|
|
|
{
|
|
|
|
Bmemset(show2dsector, 0, sizeof(show2dsector));
|
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
Bmemset(ror_protectedsectors, 0, MAXSECTORS);
|
|
|
|
#endif
|
|
|
|
g_cloudCnt = 0;
|
|
|
|
|
|
|
|
P_PrepForNewLevel(0, g);
|
|
|
|
G_SetupGlobalPsky();
|
|
|
|
|
2019-06-25 11:30:17 +00:00
|
|
|
VM_OnEvent(EVENT_PRELEVEL);
|
2018-11-18 18:07:57 +00:00
|
|
|
|
|
|
|
int missedCloudSectors = 0;
|
|
|
|
|
|
|
|
auto &p0 = *g_player[0].ps;
|
|
|
|
|
|
|
|
for (int i = 0; i < numsectors; i++)
|
|
|
|
{
|
|
|
|
auto &s = sector[i];
|
|
|
|
|
|
|
|
s.extra = 256;
|
|
|
|
|
|
|
|
switch (s.lotag)
|
|
|
|
{
|
|
|
|
case ST_20_CEILING_DOOR:
|
|
|
|
case ST_22_SPLITTING_DOOR:
|
|
|
|
if (s.floorz > s.ceilingz)
|
|
|
|
s.lotag |= 32768u;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s.ceilingstat&1)
|
|
|
|
{
|
|
|
|
if (s.ceilingpicnum == CLOUDYSKIES)
|
|
|
|
{
|
|
|
|
if (g_cloudCnt < ARRAY_SSIZE(g_cloudSect))
|
|
|
|
g_cloudSect[g_cloudCnt++] = i;
|
|
|
|
else
|
|
|
|
missedCloudSectors++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p0.parallax_sectnum == -1)
|
|
|
|
p0.parallax_sectnum = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s.lotag == 32767) //Found a secret room
|
|
|
|
{
|
|
|
|
p0.max_secret_rooms++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (missedCloudSectors > 0)
|
|
|
|
OSD_Printf(OSDTEXT_RED "Map warning: have %d unhandled CLOUDYSKIES ceilings.\n", missedCloudSectors);
|
|
|
|
|
|
|
|
// NOTE: must be safe loop because callbacks could delete sprites.
|
|
|
|
for (int nextSprite, SPRITES_OF_STAT_SAFE(STAT_DEFAULT, i, nextSprite))
|
|
|
|
{
|
|
|
|
A_ResetVars(i);
|
|
|
|
#if !defined LUNATIC
|
|
|
|
A_LoadActor(i);
|
|
|
|
#endif
|
2019-06-25 11:30:17 +00:00
|
|
|
VM_OnEvent(EVENT_LOADACTOR, i);
|
2018-11-18 18:07:57 +00:00
|
|
|
|
|
|
|
A_MaybeProcessEffector(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete some effector / effector modifier sprites AFTER the loop running
|
|
|
|
// the LOADACTOR events. DELETE_AFTER_LOADACTOR.
|
|
|
|
G_DeleteTempEffectors();
|
|
|
|
|
|
|
|
G_SpawnAllSprites();
|
|
|
|
G_SetupRotfixedSprites();
|
|
|
|
G_SetupLightSwitches();
|
|
|
|
G_SetupSpecialWalls();
|
|
|
|
}
|
|
|
|
|
2009-10-25 23:25:38 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
void G_PlayE4Cutscene(void)
|
|
|
|
{
|
|
|
|
S_PlaySpecialMusicOrNothing(MUS_BRIEFING);
|
|
|
|
|
|
|
|
renderFlushPerms();
|
|
|
|
videoSetViewableArea(0, 0, xdim-1, ydim-1);
|
2020-01-05 09:48:44 +00:00
|
|
|
twod->ClearScreen();
|
2018-11-18 18:08:08 +00:00
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
if (Anim_Play("vol41a.anm"))
|
|
|
|
goto end_vol4a;
|
|
|
|
|
2020-01-05 09:48:44 +00:00
|
|
|
twod->ClearScreen();
|
2018-11-18 18:08:08 +00:00
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
if (Anim_Play("vol42a.anm"))
|
|
|
|
goto end_vol4a;
|
|
|
|
|
2020-01-05 09:48:44 +00:00
|
|
|
twod->ClearScreen();
|
2018-11-18 18:08:08 +00:00
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
Anim_Play("vol43a.anm");
|
|
|
|
|
|
|
|
end_vol4a:
|
2020-01-05 09:48:44 +00:00
|
|
|
twod->ClearScreen();
|
2018-11-18 18:08:08 +00:00
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
FX_StopAllSounds();
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
void G_NewGame(int volumeNum, int levelNum, int skillNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
auto &p0 = *g_player[0].ps;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-10-19 23:41:40 +00:00
|
|
|
gameHandleEvents();
|
2006-12-17 21:20:35 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
ready2send = 0;
|
|
|
|
|
2019-11-09 18:15:03 +00:00
|
|
|
if (m_recstat != 2 && ud.last_level != -1 && !VM_OnEventWithReturn(EVENT_EXITGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0)
|
2018-11-18 18:07:51 +00:00
|
|
|
&& (g_netServer || ud.multimode > 1) && (ud.coop & GAMETYPE_SCORESHEET))
|
2008-11-20 14:06:36 +00:00
|
|
|
G_BonusScreen(1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-26 04:34:38 +00:00
|
|
|
g_showShareware = GAMETICSPERSEC*34;
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
ud.from_bonus = 0;
|
|
|
|
ud.last_level = -1;
|
|
|
|
ud.level_number = levelNum;
|
|
|
|
ud.player_skill = skillNum;
|
|
|
|
ud.secretlevel = 0;
|
2018-01-26 04:34:38 +00:00
|
|
|
ud.volume_number = volumeNum;
|
|
|
|
|
|
|
|
// we don't want the intro to play after the multiplayer setup screen
|
2018-11-18 18:07:51 +00:00
|
|
|
if ((!g_netServer && ud.multimode < 2) && !Menu_HaveUserMap()
|
|
|
|
&& !VM_OnEventWithReturn(EVENT_NEWGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0)
|
2019-10-27 12:40:24 +00:00
|
|
|
&& !levelNum && volumeNum == 3 && !adult_lockout && !(G_GetLogoFlags() & LOGO_NOE4CUTSCENE))
|
2018-11-18 18:08:08 +00:00
|
|
|
G_PlayE4Cutscene();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-12-27 18:36:14 +00:00
|
|
|
#ifdef EDUKE32_TOUCH_DEVICES
|
2018-11-18 18:08:08 +00:00
|
|
|
p0.zoom = 360;
|
2014-10-29 17:07:47 +00:00
|
|
|
#else
|
2018-11-18 18:08:08 +00:00
|
|
|
p0.zoom = 768;
|
2014-10-29 17:07:47 +00:00
|
|
|
#endif
|
2018-11-18 18:08:08 +00:00
|
|
|
p0.gm = 0;
|
2018-11-18 18:07:51 +00:00
|
|
|
|
2019-11-23 22:05:24 +00:00
|
|
|
M_ClearMenus();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-01-19 18:29:00 +00:00
|
|
|
#if !defined LUNATIC
|
2008-12-13 07:23:13 +00:00
|
|
|
Gv_ResetVars();
|
2008-11-20 14:06:36 +00:00
|
|
|
Gv_InitWeaponPointers();
|
2012-01-03 19:55:38 +00:00
|
|
|
Gv_RefreshPointers();
|
2013-01-01 15:24:18 +00:00
|
|
|
#endif
|
2013-02-07 21:00:48 +00:00
|
|
|
Gv_ResetSystemDefaults();
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int i=0; i < (MAXVOLUMES*MAXLEVELS); i++)
|
2017-12-02 08:45:09 +00:00
|
|
|
G_FreeMapState(i);
|
2008-07-18 02:46:24 +00:00
|
|
|
|
2019-11-09 18:15:03 +00:00
|
|
|
if (m_coop != 1)
|
2006-12-17 21:20:35 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int weaponNum = 0; weaponNum < MAX_WEAPONS; weaponNum++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (PWEAPON(0, weaponNum, WorksLike) == PISTOL_WEAPON)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:08:08 +00:00
|
|
|
p0.curr_weapon = weaponNum;
|
|
|
|
p0.gotweapon |= (1 << weaponNum);
|
|
|
|
p0.ammo_amount[weaponNum] = min<int16_t>(p0.max_ammo_amount[weaponNum], 48);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (PWEAPON(0, weaponNum, WorksLike) == KNEE_WEAPON || PWEAPON(0, weaponNum, WorksLike) == HANDREMOTE_WEAPON)
|
2018-11-18 18:08:08 +00:00
|
|
|
p0.gotweapon |= (1 << weaponNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2018-11-18 18:07:51 +00:00
|
|
|
|
2018-11-18 18:08:08 +00:00
|
|
|
p0.last_weapon = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2013-07-13 21:04:52 +00:00
|
|
|
display_mirror = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-07-13 21:04:53 +00:00
|
|
|
#ifdef LUNATIC
|
|
|
|
// NOTE: Lunatic state creation is relatively early. No map has yet been loaded.
|
|
|
|
// XXX: What about the cases where G_EnterLevel() is called without a preceding G_NewGame()?
|
|
|
|
El_CreateGameState();
|
|
|
|
G_PostCreateGameState();
|
|
|
|
#endif
|
2018-11-18 18:07:51 +00:00
|
|
|
|
2017-12-02 09:24:55 +00:00
|
|
|
VM_OnEvent(EVENT_NEWGAME, g_player[screenpeek].ps->i, screenpeek);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
static void G_CollectSpawnPoints(int gameMode)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
g_playerSpawnCnt = 0;
|
2018-11-18 18:07:57 +00:00
|
|
|
// circ = 2048/ud.multimode;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int pindex = 0, pal = 9, nexti, SPRITES_OF_STAT_SAFE(STAT_PLAYER, i, nexti))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_playerSpawnCnt == MAXPLAYERS)
|
2008-11-20 14:06:36 +00:00
|
|
|
G_GameExit("\nToo many player sprites (max 16.)");
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
auto &s = sprite[i];
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &spawn = g_playerSpawnPoints[g_playerSpawnCnt];
|
|
|
|
|
2019-06-25 11:28:25 +00:00
|
|
|
spawn.pos = s.pos;
|
2018-11-18 18:07:51 +00:00
|
|
|
spawn.ang = s.ang;
|
|
|
|
spawn.sect = s.sectnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
g_playerSpawnCnt++;
|
2009-12-05 09:22:43 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (pindex >= MAXPLAYERS)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
A_DeleteSprite(i);
|
|
|
|
i = nexti;
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
s.clipdist = 64;
|
|
|
|
s.owner = i;
|
|
|
|
s.shade = 0;
|
|
|
|
s.xoffset = 0;
|
|
|
|
s.xrepeat = 42;
|
|
|
|
s.yrepeat = 36;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
s.cstat
|
|
|
|
= (pindex < (!g_fakeMultiMode ? numplayers : ud.multimode)) ? CSTAT_SPRITE_BLOCK + CSTAT_SPRITE_BLOCK_HITSCAN : CSTAT_SPRITE_INVISIBLE;
|
2009-12-05 09:22:43 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &plr = g_player[pindex];
|
|
|
|
auto &p = *plr.ps;
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
if ((gameMode & MODE_EOL) != MODE_EOL || p.last_extra == 0)
|
2018-11-18 18:07:51 +00:00
|
|
|
{
|
|
|
|
p.runspeed = g_playerFriction;
|
|
|
|
p.last_extra = p.max_player_health;
|
|
|
|
s.extra = p.max_player_health;
|
|
|
|
}
|
2018-11-18 18:07:57 +00:00
|
|
|
else
|
|
|
|
s.extra = p.last_extra;
|
2018-11-18 18:07:51 +00:00
|
|
|
|
|
|
|
s.yvel = pindex;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (!plr.pcolor && (g_netServer || ud.multimode > 1) && !(g_gametypeFlags[ud.coop] & GAMETYPE_TDM))
|
|
|
|
{
|
|
|
|
if (s.pal == 0)
|
|
|
|
{
|
|
|
|
for (int TRAVERSE_CONNECT(k))
|
|
|
|
{
|
|
|
|
if (pal == g_player[k].ps->palookup)
|
2009-12-05 09:22:43 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
if (++pal > 16)
|
|
|
|
pal = 9;
|
|
|
|
k = 0;
|
2009-12-05 09:22:43 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
plr.pcolor = s.pal = p.palookup = pal++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (pal > 16)
|
|
|
|
pal = 9;
|
|
|
|
}
|
2018-11-18 18:07:57 +00:00
|
|
|
else
|
|
|
|
plr.pcolor = p.palookup = s.pal;
|
2018-11-18 18:07:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int k = plr.pcolor;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (g_gametypeFlags[ud.coop] & GAMETYPE_TDM)
|
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
k = G_GetTeamPalette(plr.pteam);
|
2018-11-18 18:07:51 +00:00
|
|
|
p.team = plr.pteam;
|
2009-12-05 09:22:43 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
s.pal = p.palookup = k;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2018-11-18 18:07:51 +00:00
|
|
|
|
|
|
|
p.frag_ps = pindex;
|
|
|
|
|
|
|
|
actor[i].owner = p.i = i;
|
2019-06-25 11:28:25 +00:00
|
|
|
actor[i].bpos = p.opos = p.pos = s.pos;
|
2019-08-07 22:43:48 +00:00
|
|
|
p.bobpos = s.pos.vec2;
|
2018-11-18 18:07:51 +00:00
|
|
|
|
|
|
|
p.oq16ang = p.q16ang = fix16_from_int(s.ang);
|
|
|
|
|
|
|
|
updatesector(s.x, s.y, &p.cursectnum);
|
|
|
|
|
|
|
|
pindex++;
|
2012-08-16 21:48:13 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
i = nexti;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
static void G_ResetAllPlayers(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
uint8_t aimmode[MAXPLAYERS], autoaim[MAXPLAYERS], wswitch[MAXPLAYERS];
|
|
|
|
DukeStatus_t tsbar[MAXPLAYERS];
|
|
|
|
|
|
|
|
if (g_player[0].ps->cursectnum >= 0) // < 0 may happen if we start a map in void space (e.g. testing it)
|
|
|
|
{
|
|
|
|
A_InsertSprite(g_player[0].ps->cursectnum,g_player[0].ps->pos.x,g_player[0].ps->pos.y,g_player[0].ps->pos.z,
|
|
|
|
APLAYER,0,0,0,fix16_to_int(g_player[0].ps->q16ang),0,0,0,10);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ud.recstat != 2)
|
|
|
|
{
|
|
|
|
for (int TRAVERSE_CONNECT(i))
|
|
|
|
{
|
|
|
|
auto &p = *g_player[i].ps;
|
|
|
|
|
|
|
|
aimmode[i] = p.aim_mode;
|
|
|
|
autoaim[i] = p.auto_aim;
|
|
|
|
wswitch[i] = p.weaponswitch;
|
|
|
|
|
|
|
|
if ((g_netServer || ud.multimode > 1) && (g_gametypeFlags[ud.coop] & GAMETYPE_PRESERVEINVENTORYDEATH) && ud.last_level >= 0)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < MAX_WEAPONS; j++)
|
|
|
|
tsbar[i].ammo_amount[j] = p.ammo_amount[j];
|
|
|
|
|
|
|
|
tsbar[i].gotweapon = p.gotweapon;
|
|
|
|
tsbar[i].curr_weapon = p.curr_weapon;
|
|
|
|
tsbar[i].inven_icon = p.inven_icon;
|
|
|
|
Bmemcpy(tsbar[i].inv_amount, p.inv_amount, sizeof(tsbar[i].inv_amount));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
P_ResetPlayer(0);
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int TRAVERSE_CONNECT(i))
|
2007-08-27 06:46:31 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &plr = g_player[i];
|
2018-11-18 18:07:57 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
Bmemset(plr.frags, 0, sizeof(plr.frags));
|
2018-11-18 18:07:57 +00:00
|
|
|
|
|
|
|
if (i != 0)
|
|
|
|
Bmemcpy(plr.ps, g_player[0].ps, sizeof(DukePlayer_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ud.recstat != 2)
|
|
|
|
{
|
|
|
|
for (int TRAVERSE_CONNECT(i))
|
|
|
|
{
|
|
|
|
auto &p = *g_player[i].ps;
|
|
|
|
|
|
|
|
p.aim_mode = aimmode[i];
|
|
|
|
p.auto_aim = autoaim[i];
|
|
|
|
p.weaponswitch = wswitch[i];
|
|
|
|
|
|
|
|
if ((g_netServer || ud.multimode > 1) && (g_gametypeFlags[ud.coop] & GAMETYPE_PRESERVEINVENTORYDEATH) && ud.last_level >= 0)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < MAX_WEAPONS; j++)
|
|
|
|
p.ammo_amount[j] = tsbar[i].ammo_amount[j];
|
|
|
|
|
|
|
|
p.gotweapon = tsbar[i].gotweapon;
|
|
|
|
p.curr_weapon = tsbar[i].curr_weapon;
|
|
|
|
p.inven_icon = tsbar[i].inven_icon;
|
|
|
|
Bmemcpy(p.inv_amount, tsbar[i].inv_amount, sizeof(tsbar[i].inv_amount));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// take away the pistol if the player spawns on any of these textures
|
|
|
|
for (int TRAVERSE_CONNECT(i))
|
|
|
|
{
|
|
|
|
auto &p = *g_player[i].ps;
|
2018-12-15 21:34:57 +00:00
|
|
|
|
|
|
|
if (p.cursectnum >= 0)
|
2018-11-18 18:07:57 +00:00
|
|
|
{
|
2018-12-15 21:34:57 +00:00
|
|
|
switch (DYNAMICTILEMAP(sector[p.cursectnum].floorpicnum))
|
|
|
|
{
|
|
|
|
case HURTRAIL__STATIC:
|
|
|
|
case FLOORSLIME__STATIC:
|
|
|
|
case FLOORPLASMA__STATIC:
|
|
|
|
P_ResetWeapons(i);
|
|
|
|
P_ResetInventory(i);
|
2018-11-18 18:07:57 +00:00
|
|
|
|
2018-12-15 21:34:57 +00:00
|
|
|
p.ammo_amount[PISTOL_WEAPON] = 0;
|
|
|
|
p.gotweapon &= ~(1 << PISTOL_WEAPON);
|
|
|
|
p.curr_weapon = KNEE_WEAPON;
|
|
|
|
p.kickback_pic = 0;
|
2018-11-18 18:07:57 +00:00
|
|
|
|
2018-12-15 21:34:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-11-18 18:07:57 +00:00
|
|
|
}
|
2007-08-27 06:46:31 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
void G_ResetTimers(bool saveMoveCnt)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
totalclock = g_cloudClock = ototalclock = lockclock = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
ready2send = 1;
|
2008-11-20 14:06:36 +00:00
|
|
|
g_levelTextTime = 85;
|
2014-12-21 15:51:48 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (!saveMoveCnt)
|
2013-07-04 19:38:46 +00:00
|
|
|
g_moveThingsCount = 0;
|
2014-12-21 15:51:48 +00:00
|
|
|
|
2014-10-25 03:27:13 +00:00
|
|
|
if (g_curViewscreen >= 0)
|
|
|
|
actor[g_curViewscreen].t_data[0] = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2011-02-25 21:50:19 +00:00
|
|
|
void G_ClearFIFO(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2019-05-19 03:52:47 +00:00
|
|
|
localInput = {};
|
|
|
|
Bmemset(&inputfifo, 0, sizeof(input_t) * MOVEFIFOSIZ * MAXPLAYERS);
|
2008-11-20 14:06:36 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int p = 0; p < MAXPLAYERS; ++p)
|
2007-08-27 06:46:31 +00:00
|
|
|
{
|
2019-07-08 00:41:17 +00:00
|
|
|
if (g_player[p].input != NULL)
|
|
|
|
Bmemset(g_player[p].input, 0, sizeof(input_t));
|
2016-08-27 01:42:01 +00:00
|
|
|
g_player[p].vote = g_player[p].gotvote = 0;
|
2007-08-27 06:46:31 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int G_FindLevelByFile(const char *fileName)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
int i = 0;
|
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
for (auto &levelNum : mapList)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
i++;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
if (levelNum.fileName.CompareNoCase(fileName) == 0)
|
2018-11-18 18:08:08 +00:00
|
|
|
return i-1;
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
Clean up some player code a bit... make bobposx/bobposy a vec2_t, make fricxv/fricyv a per-player vec2_t (TODO: CON access), promote angvel in input_t to int16_t and allow for player angle changes that result in odd numbered angles (we were effectively artificially limiting the angle to 1024 values before), fix some HUD model ID stuff that should help with the weapons in the HRP, clean up a bunch of random functions (P_FireWeapon(), P_DisplayTip(), P_DisplayAccess(), P_DisplayWeapon(), P_GetInput(), etc). Also clean up G_SetupFilenameBasedMusic() to loop through flac/ogg/mid when searching for usermap music replacements. Some of this really needs a BYTEVERSION bump, but these commits aren't for synthesis to build so we're not doing it yet. DONT_BUILD.
git-svn-id: https://svn.eduke32.com/eduke32@4703 1a8010ca-5511-0410-912e-c29ae57300e0
2014-10-29 17:07:11 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
return -1;
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
|
|
|
|
2017-06-17 11:41:49 +00:00
|
|
|
#if 0
|
2015-02-09 05:50:47 +00:00
|
|
|
static void G_FadeLoad(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step, int32_t ticwait, int32_t tc)
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2011-08-17 18:52:54 +00:00
|
|
|
int32_t m = (step < 0) ? -1 : 1;
|
|
|
|
|
|
|
|
int32_t nexttic = totalclock;
|
|
|
|
|
|
|
|
for (; m*start <= m*end; start += step)
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2011-08-17 18:52:54 +00:00
|
|
|
while (totalclock < nexttic)
|
|
|
|
sampletimer();
|
|
|
|
nexttic += ticwait;
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.GetKeyStatus(sc_Space))
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(sc_Space);
|
2011-08-17 18:52:54 +00:00
|
|
|
return;
|
2010-05-02 23:27:30 +00:00
|
|
|
}
|
2011-08-17 18:52:54 +00:00
|
|
|
|
2015-09-23 17:55:11 +00:00
|
|
|
setpalettefade(r,g,b,start);
|
2011-08-17 18:52:54 +00:00
|
|
|
flushperms();
|
2015-02-09 05:50:47 +00:00
|
|
|
G_DoLoadScreen(" ", tc);
|
2011-08-17 18:52:54 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
}
|
2017-06-17 11:41:49 +00:00
|
|
|
#endif
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
static int G_TryMapHack(const char *mhkfile)
|
2015-01-08 15:14:00 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
int const failure = engineLoadMHK(mhkfile);
|
2015-01-08 15:14:00 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!failure)
|
2015-01-08 15:14:00 +00:00
|
|
|
initprintf("Loaded map hack file \"%s\"\n", mhkfile);
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
return failure;
|
2015-01-08 15:14:00 +00:00
|
|
|
}
|
2011-01-09 18:53:06 +00:00
|
|
|
|
|
|
|
static void G_LoadMapHack(char *outbuf, const char *filename)
|
|
|
|
{
|
|
|
|
if (filename != NULL)
|
|
|
|
Bstrcpy(outbuf, filename);
|
2011-02-25 21:50:19 +00:00
|
|
|
|
2013-05-06 19:43:38 +00:00
|
|
|
append_ext_UNSAFE(outbuf, ".mhk");
|
2011-02-25 21:50:19 +00:00
|
|
|
|
2016-09-16 21:55:39 +00:00
|
|
|
if (G_TryMapHack(outbuf) && usermaphacks != NULL)
|
2015-01-08 15:14:00 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto pMapInfo = (usermaphack_t *)bsearch(&g_loadedMapHack, usermaphacks, num_usermaphacks,
|
|
|
|
sizeof(usermaphack_t), compare_usermaphacks);
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pMapInfo)
|
|
|
|
G_TryMapHack(pMapInfo->mhkfile);
|
2015-01-08 15:14:00 +00:00
|
|
|
}
|
2011-01-09 18:53:06 +00:00
|
|
|
}
|
|
|
|
|
2019-07-19 09:49:18 +00:00
|
|
|
static void G_CheckIfStateless()
|
|
|
|
{
|
|
|
|
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
|
|
|
|
{
|
|
|
|
map_t *const pMapInfo = &g_mapInfo[i];
|
|
|
|
if (pMapInfo->savedstate != nullptr)
|
|
|
|
{
|
|
|
|
// buildprint("G_CheckIfStateless: no ", ud.volume_number, " ", ud.level_number, "\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildprint("G_CheckIfStateless: yes ", ud.volume_number, " ", ud.level_number, "\n");
|
|
|
|
ud.last_stateless_volume = ud.volume_number;
|
|
|
|
ud.last_stateless_level = ud.level_number;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int G_EnterLevel(int gameMode)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2007-08-27 06:46:31 +00:00
|
|
|
vote_map = vote_episode = voting = -1;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
ud.respawn_monsters = ud.m_respawn_monsters;
|
|
|
|
ud.respawn_items = ud.m_respawn_items;
|
|
|
|
ud.respawn_inventory = ud.m_respawn_inventory;
|
|
|
|
ud.monsters_off = ud.m_monsters_off;
|
2019-11-09 18:15:03 +00:00
|
|
|
ud.coop = m_coop;
|
|
|
|
ud.marker = m_marker;
|
|
|
|
ud.ffire = m_ffire;
|
|
|
|
ud.noexits = m_noexits;
|
2006-05-04 03:14:49 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((gameMode & MODE_DEMO) != MODE_DEMO)
|
2019-11-09 18:15:03 +00:00
|
|
|
ud.recstat = m_recstat;
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((gameMode & MODE_DEMO) == 0 && ud.recstat == 2)
|
2006-04-13 20:47:06 +00:00
|
|
|
ud.recstat = 0;
|
|
|
|
|
2011-02-25 21:50:19 +00:00
|
|
|
if (g_networkMode != NET_DEDICATED_SERVER)
|
|
|
|
{
|
2018-10-25 23:32:29 +00:00
|
|
|
S_PauseSounds(false);
|
2011-02-25 21:50:19 +00:00
|
|
|
FX_StopAllSounds();
|
|
|
|
S_ClearSoundLocks();
|
|
|
|
FX_SetReverb(0);
|
2016-06-05 04:46:28 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-29 11:13:21 +00:00
|
|
|
if (Menu_HaveUserMap())
|
2006-12-09 23:41:43 +00:00
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
Bcorrectfilename(boardfilename, 0);
|
2006-12-12 07:25:01 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int levelNum = G_FindLevelByFile(boardfilename);
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (levelNum != -1)
|
2006-12-09 23:41:43 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int volumeNum = levelNum;
|
|
|
|
|
|
|
|
levelNum &= MAXLEVELS-1;
|
|
|
|
volumeNum = (volumeNum - levelNum) / MAXLEVELS;
|
|
|
|
|
2019-11-09 18:15:03 +00:00
|
|
|
ud.level_number = m_level_number = levelNum;
|
2016-08-27 01:40:56 +00:00
|
|
|
ud.volume_number = ud.m_volume_number = volumeNum;
|
2009-06-28 20:23:12 +00:00
|
|
|
|
2006-12-09 23:41:43 +00:00
|
|
|
boardfilename[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
2019-08-15 04:39:46 +00:00
|
|
|
else
|
|
|
|
boardfilename[0] = '\0';
|
2006-12-09 23:41:43 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
int const mapidx = (ud.volume_number * MAXLEVELS) + ud.level_number;
|
2012-05-25 18:39:22 +00:00
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
Bassert((unsigned)mapidx < ARRAY_SIZE(mapList));
|
2018-11-18 18:07:51 +00:00
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
auto& mm = mapList[mapidx];
|
2018-11-18 18:07:51 +00:00
|
|
|
|
2019-08-15 04:39:46 +00:00
|
|
|
if (VOLUMEONE || !Menu_HaveUserMap())
|
2006-12-04 22:22:07 +00:00
|
|
|
{
|
2019-12-10 16:35:28 +00:00
|
|
|
if (mm.fileName.IsEmpty())
|
2006-12-05 21:22:19 +00:00
|
|
|
{
|
2012-05-25 18:39:22 +00:00
|
|
|
OSD_Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1);
|
2006-12-05 21:22:19 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2006-12-04 22:22:07 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
int const ssize = ud.screen_size;
|
2010-01-24 23:33:17 +00:00
|
|
|
ud.screen_size = 0;
|
2009-10-25 23:25:38 +00:00
|
|
|
|
2019-12-07 13:53:13 +00:00
|
|
|
FStringf msg("%s . . .", GStrings("TXT_LOADMAP"));
|
|
|
|
G_DoLoadScreen(msg, -1);
|
2010-01-24 23:33:17 +00:00
|
|
|
G_UpdateScreenArea();
|
2011-01-09 18:53:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
ud.screen_size = ssize;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
auto &p0 = *g_player[0].ps;
|
2018-11-18 18:07:51 +00:00
|
|
|
int16_t playerAngle;
|
|
|
|
|
|
|
|
char levelName[BMAX_PATH];
|
2018-12-08 00:40:39 +00:00
|
|
|
NET_75_CHECK++; // a major problem with how STAT_NETALLOC works, is that loadboard loads sprites directly into the arrays and does not take from
|
|
|
|
// STAT_NETALLOC, even though the loaded sprites are very, very likely to be relevant to the netcode.
|
2013-12-24 09:44:25 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
if (!VOLUMEONE && G_HaveUserMap())
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
if (engineLoadBoard(boardfilename, 0, &p0.pos, &playerAngle, &p0.cursectnum) < 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", boardfilename);
|
2006-04-13 20:47:06 +00:00
|
|
|
return 1;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2019-12-10 21:22:59 +00:00
|
|
|
userMapRecord.name = "";
|
|
|
|
userMapRecord.SetFileName(boardfilename);
|
|
|
|
currentLevel = &userMapRecord;
|
|
|
|
STAT_NewLevel(boardfilename);
|
2016-08-27 01:40:56 +00:00
|
|
|
G_LoadMapHack(levelName, boardfilename);
|
2020-01-27 19:53:41 +00:00
|
|
|
|
|
|
|
userMapRecord.music = G_SetupFilenameBasedMusic(boardfilename, mapList[MUS_USERMAP].music.IsNotEmpty()? mapList[MUS_USERMAP].music.GetChars() :(!FURY? mapList[7].music.GetChars() : nullptr));
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
2019-12-09 23:01:45 +00:00
|
|
|
else if (engineLoadBoard(mm.fileName, VOLUMEONE, &p0.pos, &playerAngle, &p0.cursectnum) < 0)
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
2019-12-09 23:01:45 +00:00
|
|
|
OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", mm.fileName.GetChars());
|
2016-08-27 01:40:56 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-10 21:22:59 +00:00
|
|
|
currentLevel = &mm;
|
2019-12-09 23:01:45 +00:00
|
|
|
STAT_NewLevel(mm.fileName);
|
|
|
|
G_LoadMapHack(levelName, mm.fileName);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:57 +00:00
|
|
|
p0.q16ang = fix16_from_int(playerAngle);
|
2018-03-07 04:21:18 +00:00
|
|
|
|
2010-01-24 23:33:17 +00:00
|
|
|
g_precacheCount = 0;
|
2011-08-17 18:52:54 +00:00
|
|
|
Bmemset(gotpic, 0, sizeof(gotpic));
|
|
|
|
Bmemset(precachehightile, 0, sizeof(precachehightile));
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
NET_75_CHECK++; // resetpspritevars attempts to insert player 0's sprite, which isn't going to work because we don't have
|
|
|
|
// the STAT_NETALLOC sprites allocated yet.
|
|
|
|
|
|
|
|
Net_NotifyNewGame();
|
|
|
|
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
prelevel(gameMode);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-12 09:45:14 +00:00
|
|
|
G_AlignWarpElevators();
|
2018-11-18 18:07:57 +00:00
|
|
|
G_ResetAllPlayers();
|
|
|
|
G_CollectSpawnPoints(gameMode);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
ud.playerbest = CONFIG_GetMapBestTime(Menu_HaveUserMap() ? boardfilename : mm.fileName.GetChars(), g_loadedMapHack.md4);
|
2015-02-08 08:03:30 +00:00
|
|
|
|
2017-06-17 11:41:49 +00:00
|
|
|
// G_FadeLoad(0,0,0, 252,0, -28, 4, -1);
|
2010-01-24 23:33:17 +00:00
|
|
|
G_CacheMapData();
|
2017-06-17 11:41:49 +00:00
|
|
|
// G_FadeLoad(0,0,0, 0,252, 28, 4, -2);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-13 23:12:47 +00:00
|
|
|
if (ud.recstat != 2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2019-08-15 04:39:46 +00:00
|
|
|
if (Menu_HaveUserMap())
|
|
|
|
{
|
|
|
|
S_PlayLevelMusicOrNothing(USERMAPMUSICFAKESLOT);
|
|
|
|
}
|
2019-12-10 21:22:59 +00:00
|
|
|
else S_PlayLevelMusicOrNothing(mapidx);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-23 22:05:24 +00:00
|
|
|
M_ClearMenus();
|
2016-08-27 01:40:56 +00:00
|
|
|
if (gameMode & (MODE_GAME|MODE_EOL))
|
2009-06-24 08:20:10 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int TRAVERSE_CONNECT(i))
|
2014-11-29 03:43:11 +00:00
|
|
|
{
|
2012-02-21 19:33:33 +00:00
|
|
|
g_player[i].ps->gm = MODE_GAME;
|
2014-11-29 03:43:11 +00:00
|
|
|
}
|
2009-06-24 08:20:10 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (gameMode & MODE_RESTART)
|
2018-11-18 18:07:51 +00:00
|
|
|
g_player[myconnectindex].ps->gm = (ud.recstat == 2) ? MODE_DEMO : MODE_GAME;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((ud.recstat == 1) && (gameMode&MODE_RESTART) != MODE_RESTART)
|
2008-11-20 14:06:36 +00:00
|
|
|
G_OpenDemoWrite();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-12-27 18:36:14 +00:00
|
|
|
#ifndef EDUKE32_TOUCH_DEVICES
|
2010-07-22 20:29:09 +00:00
|
|
|
if (VOLUMEONE && ud.level_number == 0 && ud.recstat != 2)
|
2011-02-25 21:50:19 +00:00
|
|
|
P_DoQuote(QUOTE_F1HELP,g_player[myconnectindex].ps);
|
2014-09-30 04:08:10 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
//Net_NotifyNewGame();
|
2008-11-20 14:06:36 +00:00
|
|
|
Net_ResetPrediction();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2007-08-27 06:46:31 +00:00
|
|
|
//g_player[myconnectindex].ps->palette = palette;
|
2008-11-20 14:06:36 +00:00
|
|
|
//G_FadePalette(0,0,0,0);
|
2011-01-17 03:49:34 +00:00
|
|
|
P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0); // JBF 20040308
|
2010-01-24 23:33:17 +00:00
|
|
|
P_UpdateScreenPal(g_player[myconnectindex].ps);
|
2018-04-12 21:04:00 +00:00
|
|
|
renderFlushPerms();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
everyothertime = 0;
|
2008-11-20 14:06:36 +00:00
|
|
|
g_globalRandom = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
ud.last_level = ud.level_number+1;
|
|
|
|
|
2011-02-25 21:50:19 +00:00
|
|
|
G_ClearFIFO();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int i=g_interpolationCnt-1; i>=0; i--) bakipos[i] = *curipos[i];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-07-04 19:38:46 +00:00
|
|
|
G_ResetTimers(0); // Here we go
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-07-19 09:49:18 +00:00
|
|
|
G_CheckIfStateless();
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int TRAVERSE_CONNECT(i))
|
2015-05-25 12:57:50 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
if (!VM_OnEventWithReturn(EVENT_ENTERLEVEL, g_player[i].ps->i, i, 0))
|
2015-05-25 12:57:50 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-01-29 11:13:37 +00:00
|
|
|
if (G_HaveUserMap())
|
2019-12-07 13:53:13 +00:00
|
|
|
OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename);
|
2019-08-07 22:36:20 +00:00
|
|
|
else if (FURY)
|
2019-12-09 23:01:45 +00:00
|
|
|
OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_ENTERING"), mm.DisplayName());
|
2018-01-29 11:13:37 +00:00
|
|
|
else
|
2019-12-09 23:01:45 +00:00
|
|
|
OSD_Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number + 1, ud.level_number + 1, mm.DisplayName());
|
2011-04-07 01:16:29 +00:00
|
|
|
|
2015-12-23 04:06:13 +00:00
|
|
|
g_restorePalette = -1;
|
|
|
|
|
|
|
|
G_UpdateScreenArea();
|
2018-04-12 21:02:51 +00:00
|
|
|
videoClearViewableArea(0L);
|
2015-12-23 04:06:13 +00:00
|
|
|
G_DrawBackground();
|
|
|
|
G_DrawRooms(myconnectindex,65536);
|
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
if (g_netClient || g_netServer) // [75] : Initialize map states after map load
|
|
|
|
{
|
|
|
|
Net_InitMapStateHistory();
|
2018-12-15 21:34:57 +00:00
|
|
|
Net_AddWorldToInitialSnapshot();
|
2018-12-08 00:40:39 +00:00
|
|
|
}
|
|
|
|
|
2011-04-07 01:16:29 +00:00
|
|
|
Net_WaitForServer();
|
2006-04-13 20:47:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-07-18 02:46:24 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
void G_FreeMapState(int levelNum)
|
2008-07-18 02:46:24 +00:00
|
|
|
{
|
2018-11-18 18:07:51 +00:00
|
|
|
auto &board = g_mapInfo[levelNum];
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
if (board.savedstate == NULL)
|
2013-05-19 19:29:23 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
#if !defined LUNATIC
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int j=0; j<g_gameVarCount; j++)
|
2008-07-18 02:46:24 +00:00
|
|
|
{
|
2017-10-31 02:09:25 +00:00
|
|
|
if (aGameVars[j].flags & GAMEVAR_NORESET)
|
|
|
|
continue;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[j].flags & (GAMEVAR_PERPLAYER|GAMEVAR_PERACTOR))
|
2018-11-18 18:07:51 +00:00
|
|
|
ALIGNED_FREE_AND_NULL(board.savedstate->vars[j]);
|
2017-10-31 02:09:25 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
for (int j=0; j<g_gameArrayCount; j++)
|
2017-10-31 02:09:25 +00:00
|
|
|
{
|
|
|
|
if (aGameArrays[j].flags & GAMEARRAY_RESTORE)
|
2018-11-18 18:07:51 +00:00
|
|
|
ALIGNED_FREE_AND_NULL(board.savedstate->arrays[j]);
|
2008-07-18 02:46:24 +00:00
|
|
|
}
|
2013-10-27 21:12:20 +00:00
|
|
|
#else
|
2019-06-25 11:29:08 +00:00
|
|
|
Xfree(board.savedstate->savecode);
|
2013-01-20 21:17:06 +00:00
|
|
|
#endif
|
2017-10-31 02:09:25 +00:00
|
|
|
|
2018-11-18 18:07:51 +00:00
|
|
|
ALIGNED_FREE_AND_NULL(board.savedstate);
|
2008-08-09 19:59:41 +00:00
|
|
|
}
|
2019-09-21 20:53:00 +00:00
|
|
|
END_DUKE_NS
|