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!
|
|
|
|
|
2016-01-08 01:33:35 +00:00
|
|
|
#define game_c_
|
|
|
|
|
2019-12-29 16:04:38 +00:00
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
2006-04-25 01:56:24 +00:00
|
|
|
#include "duke3d.h"
|
2016-02-07 02:38:03 +00:00
|
|
|
#include "compat.h"
|
2019-12-29 16:04:38 +00:00
|
|
|
#include "baselayer.h"
|
2006-04-13 20:47:06 +00:00
|
|
|
#include "osdcmds.h"
|
2019-03-21 02:24:19 +00:00
|
|
|
#include "network.h"
|
2010-08-02 08:13:51 +00:00
|
|
|
#include "menus.h"
|
|
|
|
#include "savegame.h"
|
|
|
|
#include "anim.h"
|
|
|
|
#include "demo.h"
|
2019-12-24 12:21:36 +00:00
|
|
|
|
2016-02-07 02:38:03 +00:00
|
|
|
#include "cheats.h"
|
2016-02-07 02:38:16 +00:00
|
|
|
#include "sbar.h"
|
2016-02-13 21:05:57 +00:00
|
|
|
#include "screens.h"
|
|
|
|
#include "cmdline.h"
|
2016-06-21 00:33:06 +00:00
|
|
|
#include "palette.h"
|
2019-10-21 21:29:48 +00:00
|
|
|
#include "gamecvars.h"
|
2019-10-26 18:47:37 +00:00
|
|
|
#include "gameconfigfile.h"
|
2019-11-01 07:24:10 +00:00
|
|
|
#include "printf.h"
|
2019-11-01 18:25:42 +00:00
|
|
|
#include "m_argv.h"
|
2019-11-23 22:05:24 +00:00
|
|
|
#include "c_dispatch.h"
|
2020-04-11 21:54:33 +00:00
|
|
|
#include "filesystem.h"
|
2019-11-12 21:45:11 +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"
|
2019-12-23 18:37:40 +00:00
|
|
|
#include "rendering/v_video.h"
|
2016-02-07 02:38:23 +00:00
|
|
|
|
2013-05-04 16:36:12 +00:00
|
|
|
// Uncomment to prevent anything except mirrors from drawing. It is sensible to
|
2015-01-04 18:45:00 +00:00
|
|
|
// also uncomment ENGINE_CLEAR_SCREEN in build/src/engine_priv.h.
|
2013-05-04 16:36:12 +00:00
|
|
|
//#define DEBUG_MIRRORS_ONLY
|
|
|
|
|
2010-01-24 23:33:17 +00:00
|
|
|
#if KRANDDEBUG
|
|
|
|
# define GAME_INLINE
|
|
|
|
# define GAME_STATIC
|
|
|
|
#else
|
|
|
|
# define GAME_INLINE inline
|
|
|
|
# define GAME_STATIC static
|
|
|
|
#endif
|
|
|
|
|
2019-09-21 20:53:00 +00:00
|
|
|
BEGIN_DUKE_NS
|
|
|
|
|
2010-01-16 23:08:17 +00:00
|
|
|
int32_t g_quitDeadline = 0;
|
2006-12-14 08:50:18 +00:00
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t g_cameraDistance = 0, g_cameraClock = 0;
|
2010-01-16 23:08:17 +00:00
|
|
|
static int32_t g_quickExit;
|
2013-07-13 21:04:47 +00:00
|
|
|
|
2019-12-11 17:40:42 +00:00
|
|
|
char boardfilename[BMAX_PATH];
|
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t voting = -1;
|
|
|
|
int32_t vote_map = -1, vote_episode = -1;
|
2006-05-04 03:14:49 +00:00
|
|
|
|
2016-02-07 02:38:03 +00:00
|
|
|
int32_t g_Debug = 0;
|
2006-07-26 01:10:33 +00:00
|
|
|
|
2020-03-18 07:15:45 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
static const char *defaultrtsfilename[GAMECOUNT] = { "DUKE.RTS", "NAM.RTS", "NAPALM.RTS", "WW2GI.RTS" };
|
|
|
|
#endif
|
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t g_Shareware = 0;
|
2006-07-26 01:10:33 +00:00
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t tempwallptr;
|
2006-07-26 01:10:33 +00:00
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
static int32_t nonsharedtimer;
|
2006-07-26 01:10:33 +00:00
|
|
|
|
2009-12-05 09:22:43 +00:00
|
|
|
int32_t ticrandomseed;
|
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t g_levelTextTime = 0;
|
2008-08-07 11:45:28 +00:00
|
|
|
|
2008-12-04 00:31:16 +00:00
|
|
|
#if defined(RENDERTYPEWIN) && defined(USE_OPENGL)
|
2008-10-31 10:08:51 +00:00
|
|
|
extern char forcegl;
|
|
|
|
#endif
|
|
|
|
|
2020-03-18 07:15:45 +00:00
|
|
|
const char *G_DefaultRtsFile(void)
|
|
|
|
{
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
if (DUKE)
|
|
|
|
return defaultrtsfilename[GAME_DUKE];
|
|
|
|
else if (WW2GI)
|
|
|
|
return defaultrtsfilename[GAME_WW2GI];
|
|
|
|
else if (NAPALM)
|
|
|
|
{
|
|
|
|
if (!fileSystem.FileExists(defaultrtsfilename[GAME_NAPALM]) && fileSystem.FileExists(defaultrtsfilename[GAME_NAM]))
|
|
|
|
return defaultrtsfilename[GAME_NAM]; // NAM/NAPALM Sharing
|
|
|
|
else
|
|
|
|
return defaultrtsfilename[GAME_NAPALM];
|
|
|
|
}
|
|
|
|
else if (NAM)
|
|
|
|
{
|
|
|
|
if (!fileSystem.FileExists(defaultrtsfilename[GAME_NAM]) && fileSystem.FileExists(defaultrtsfilename[GAME_NAPALM]))
|
|
|
|
return defaultrtsfilename[GAME_NAPALM]; // NAM/NAPALM Sharing
|
|
|
|
else
|
|
|
|
return defaultrtsfilename[GAME_NAM];
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
enum gametokens
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2007-02-18 22:16:01 +00:00
|
|
|
T_INCLUDE = 0,
|
2006-07-26 01:10:33 +00:00
|
|
|
T_INTERFACE = 0,
|
2007-02-18 22:16:01 +00:00
|
|
|
T_LOADGRP = 1,
|
2006-07-26 01:10:33 +00:00
|
|
|
T_MODE = 1,
|
2007-02-18 22:16:01 +00:00
|
|
|
T_CACHESIZE = 2,
|
2008-02-21 05:11:41 +00:00
|
|
|
T_ALLOW = 2,
|
|
|
|
T_NOAUTOLOAD,
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
T_INCLUDEDEFAULT,
|
2008-03-08 05:23:15 +00:00
|
|
|
T_MUSIC,
|
|
|
|
T_SOUND,
|
|
|
|
T_FILE,
|
2015-02-11 05:22:07 +00:00
|
|
|
T_CUTSCENE,
|
Possibility of specifying sounds for a VPX anim-replacement via DEF.
The syntax is as follows:
animsounds <anim> { frame1 sound1 frame2 sound2 ... }
<anim> has to be one of the tokens: cineov2, cineov3, RADLOGO, DUKETEAM,
logo, vol41a, vol42a, vol4e1, vol43a, vol4e2, or vol4e3, corresponding
to hard-coded Duke3D anims.
The frameN's (1-based frame numbers) have to be in ascending order (but not
necessarily strictly ascending, so that a frame may have more than one sound).
Example: for Duke3D's XBLA nuke logo animation (IVF extracted from nuke.webm),
the following definition overlays the video with a sound sequence similar
(identical save for timing) to the original nuke animation:
// frame 1: FLY_BY, frame 64: PIPEBOMB_EXPLODE
animsounds logo { 1 244 64 14 }
git-svn-id: https://svn.eduke32.com/eduke32@2242 1a8010ca-5511-0410-912e-c29ae57300e0
2012-01-10 23:43:54 +00:00
|
|
|
T_ANIMSOUNDS,
|
2012-03-22 22:47:29 +00:00
|
|
|
T_NOFLOORPALRANGE,
|
2015-02-11 05:22:07 +00:00
|
|
|
T_ID,
|
2018-10-25 23:32:05 +00:00
|
|
|
T_MINPITCH,
|
|
|
|
T_MAXPITCH,
|
|
|
|
T_PRIORITY,
|
|
|
|
T_TYPE,
|
|
|
|
T_DISTANCE,
|
|
|
|
T_VOLUME,
|
2015-04-12 08:07:45 +00:00
|
|
|
T_DELAY,
|
|
|
|
T_RENAMEFILE,
|
2015-04-24 00:08:46 +00:00
|
|
|
T_GLOBALGAMEFLAGS,
|
2017-12-12 05:13:32 +00:00
|
|
|
T_ASPECT,
|
2017-12-12 05:13:38 +00:00
|
|
|
T_FORCEFILTER,
|
|
|
|
T_FORCENOFILTER,
|
|
|
|
T_TEXTUREFILTER,
|
2019-08-09 08:21:19 +00:00
|
|
|
T_NEWGAMECHOICES,
|
|
|
|
T_CHOICE,
|
|
|
|
T_NAME,
|
|
|
|
T_LOCKED,
|
|
|
|
T_HIDDEN,
|
2019-08-14 09:02:07 +00:00
|
|
|
T_USERCONTENT,
|
2006-07-26 01:10:33 +00:00
|
|
|
};
|
|
|
|
|
2019-10-19 23:41:35 +00:00
|
|
|
static void gameTimerHandler(void)
|
|
|
|
{
|
2019-12-16 07:19:57 +00:00
|
|
|
S_Update();
|
2019-10-19 23:41:35 +00:00
|
|
|
G_HandleSpecialKeys();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
void G_HandleSpecialKeys(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:12:16 +00:00
|
|
|
auto &myplayer = *g_player[myconnectindex].ps;
|
|
|
|
|
2009-12-05 09:22:43 +00:00
|
|
|
// we need CONTROL_GetInput in order to pick up joystick button presses
|
2019-10-28 06:10:56 +00:00
|
|
|
if ((!(myplayer.gm & MODE_GAME) || (myplayer.gm & MODE_MENU)))
|
2009-12-05 09:22:43 +00:00
|
|
|
{
|
|
|
|
ControlInfo noshareinfo;
|
|
|
|
CONTROL_GetInput(&noshareinfo);
|
|
|
|
}
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
// only dispatch commands here when not in a game
|
2018-11-18 18:12:16 +00:00
|
|
|
if ((myplayer.gm & MODE_GAME) != MODE_GAME)
|
2006-11-15 01:16:55 +00:00
|
|
|
OSD_DispatchQueued();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
}
|
|
|
|
|
2009-12-14 20:14:12 +00:00
|
|
|
void G_GameQuit(void)
|
2009-12-05 09:22:43 +00:00
|
|
|
{
|
2009-12-30 23:07:00 +00:00
|
|
|
if (numplayers < 2)
|
|
|
|
G_GameExit(" ");
|
|
|
|
|
|
|
|
if (g_gameQuit == 0)
|
2009-12-05 09:22:43 +00:00
|
|
|
{
|
2010-01-23 22:12:02 +00:00
|
|
|
g_gameQuit = 1;
|
2019-08-27 13:39:54 +00:00
|
|
|
g_quitDeadline = (int32_t) totalclock+120;
|
2010-01-23 22:12:02 +00:00
|
|
|
g_netDisconnect = 1;
|
2009-12-05 09:22:43 +00:00
|
|
|
}
|
|
|
|
|
2010-01-16 23:08:17 +00:00
|
|
|
if ((totalclock > g_quitDeadline) && (g_gameQuit == 1))
|
2009-12-05 09:22:43 +00:00
|
|
|
G_GameExit("Timed out.");
|
|
|
|
}
|
|
|
|
|
2009-12-17 11:17:48 +00:00
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
int32_t A_CheckInventorySprite(spritetype *s)
|
|
|
|
{
|
2012-01-28 14:38:23 +00:00
|
|
|
switch (DYNAMICTILEMAP(s->picnum))
|
2009-12-17 11:17:48 +00:00
|
|
|
{
|
2010-08-02 08:13:51 +00:00
|
|
|
case FIRSTAID__STATIC:
|
|
|
|
case STEROIDS__STATIC:
|
|
|
|
case HEATSENSOR__STATIC:
|
|
|
|
case BOOTS__STATIC:
|
|
|
|
case JETPACK__STATIC:
|
|
|
|
case HOLODUKE__STATIC:
|
|
|
|
case AIRTANK__STATIC:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return 0;
|
2009-12-17 11:17:48 +00:00
|
|
|
}
|
2009-12-05 09:22:43 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 06:08:50 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-06-03 15:46:05 +00:00
|
|
|
void G_GameExit(const char *msg)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-11-18 18:06:58 +00:00
|
|
|
if (*msg != 0 && g_player[myconnectindex].ps != NULL)
|
|
|
|
g_player[myconnectindex].ps->palette = BASEPAL;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-05 17:25:31 +00:00
|
|
|
if (ud.recstat == 1)
|
|
|
|
G_CloseDemoWrite();
|
2019-11-07 23:26:14 +00:00
|
|
|
else if (ud.recstat == 2)
|
|
|
|
{
|
|
|
|
delete g_demo_filePtr;
|
|
|
|
g_demo_filePtr = nullptr;
|
|
|
|
}
|
2012-09-05 17:25:31 +00:00
|
|
|
// JBF: fixes crash on demo playback
|
|
|
|
// PK: modified from original
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
if (!g_quickExit)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-01-26 04:34:38 +00:00
|
|
|
if (VM_OnEventWithReturn(EVENT_EXITGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0) == 0 &&
|
2018-11-18 18:12:16 +00:00
|
|
|
g_mostConcurrentPlayers > 1 && g_player[myconnectindex].ps->gm & MODE_GAME && GTFLAGS(GAMETYPE_SCORESHEET) && *msg == ' ')
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2010-08-02 08:13:51 +00:00
|
|
|
G_BonusScreen(1);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-01-26 04:34:38 +00:00
|
|
|
// shareware and TEN screens
|
|
|
|
if (VM_OnEventWithReturn(EVENT_EXITPROGRAMSCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0) == 0 &&
|
|
|
|
*msg != 0 && *(msg+1) != 'V' && *(msg+1) != 'Y')
|
2010-08-02 08:13:51 +00:00
|
|
|
G_DisplayExtraScreens();
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2012-06-03 15:46:05 +00:00
|
|
|
if (*msg != 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-06-03 15:46:05 +00:00
|
|
|
if (!(msg[0] == ' ' && msg[1] == 0))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2019-12-26 13:04:53 +00:00
|
|
|
I_FatalError("%s", msg);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2020-04-11 21:50:43 +00:00
|
|
|
throw CExitEvent(0);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2008-08-07 07:52:36 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
static int32_t G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vsectnum, int16_t ang, int16_t horiz)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const sp = &sprite[pp->i];
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t i, hx, hy;
|
|
|
|
int32_t bakcstat = sp->cstat;
|
|
|
|
hitdata_t hit;
|
2018-03-07 04:21:18 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
vec3_t n = {
|
|
|
|
sintable[(ang+1536)&2047]>>4,
|
|
|
|
sintable[(ang+1024)&2047]>>4,
|
2018-03-07 04:21:18 +00:00
|
|
|
(horiz-100) * 128
|
2016-02-13 21:05:57 +00:00
|
|
|
};
|
2008-08-07 07:52:36 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
updatesectorz(vect->x,vect->y,vect->z,vsectnum);
|
2011-10-17 18:41:38 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
sp->cstat &= ~0x101;
|
|
|
|
hitscan(vect, *vsectnum, n.x,n.y,n.z, &hit, CLIPMASK1);
|
|
|
|
sp->cstat = bakcstat;
|
2010-06-22 21:50:01 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (*vsectnum < 0)
|
|
|
|
return -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
hx = hit.pos.x-(vect->x);
|
|
|
|
hy = hit.pos.y-(vect->y);
|
2013-01-26 17:07:58 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (klabs(n.x)+klabs(n.y) > klabs(hx)+klabs(hy))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
*vsectnum = hit.sect;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (hit.wall >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-03-07 04:21:18 +00:00
|
|
|
int32_t daang = getangle(wall[wall[hit.wall].point2].x-wall[hit.wall].x,
|
2016-02-13 21:05:57 +00:00
|
|
|
wall[wall[hit.wall].point2].y-wall[hit.wall].y);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
i = n.x*sintable[daang] + n.y*sintable[(daang+1536)&2047];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (klabs(n.x) > klabs(n.y))
|
|
|
|
hx -= mulscale28(n.x,i);
|
|
|
|
else hy -= mulscale28(n.y,i);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else if (hit.sprite < 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
if (klabs(n.x) > klabs(n.y))
|
|
|
|
hx -= (n.x>>5);
|
|
|
|
else hy -= (n.y>>5);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (klabs(n.x) > klabs(n.y))
|
|
|
|
i = divscale16(hx,n.x);
|
|
|
|
else i = divscale16(hy,n.y);
|
2013-01-26 17:07:58 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (i < CAMERADIST)
|
|
|
|
CAMERADIST = i;
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
vect->x += mulscale16(n.x,CAMERADIST);
|
|
|
|
vect->y += mulscale16(n.y,CAMERADIST);
|
|
|
|
vect->z += mulscale16(n.z,CAMERADIST);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2019-08-27 13:39:54 +00:00
|
|
|
CAMERADIST = min(CAMERADIST+(((int32_t) totalclock-CAMERACLOCK)<<10),65536);
|
|
|
|
CAMERACLOCK = (int32_t) totalclock;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
updatesectorz(vect->x,vect->y,vect->z,vsectnum);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
char ror_protectedsectors[MAXSECTORS];
|
|
|
|
static int32_t drawing_ror = 0;
|
|
|
|
static int32_t ror_sprite = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-07-08 00:41:25 +00:00
|
|
|
static void G_OROR_DupeSprites(spritetype const *sp)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
// dupe the sprites touching the portal to the other sector
|
|
|
|
int32_t k;
|
2019-07-08 00:41:25 +00:00
|
|
|
spritetype const *refsp;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((unsigned)sp->yvel >= (unsigned)g_mostConcurrentPlayers)
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
2013-01-26 17:07:58 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
refsp = &sprite[sp->yvel];
|
2008-07-31 10:35:23 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (SPRITES_OF_SECT(sp->sectnum, k))
|
2008-10-31 10:08:51 +00:00
|
|
|
{
|
2017-07-08 19:42:11 +00:00
|
|
|
if (spritesortcnt >= maxspritesonscreen)
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2008-09-11 09:24:45 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (sprite[k].picnum != SECTOREFFECTOR && sprite[k].z >= sp->z)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2019-12-26 06:27:58 +00:00
|
|
|
tspriteptr_t tsp = renderAddTSpriteFromSprite(k);
|
2019-12-26 06:28:08 +00:00
|
|
|
Duke_ApplySpritePropertiesToTSprite(tsp, (uspriteptr_t)&sprite[k]);
|
2009-12-14 20:14:12 +00:00
|
|
|
|
2019-12-26 06:27:58 +00:00
|
|
|
tsp->x += (refsp->x - sp->x);
|
|
|
|
tsp->y += (refsp->y - sp->y);
|
|
|
|
tsp->z += -sp->z + actor[sp->yvel].ceilingz;
|
|
|
|
tsp->sectnum = refsp->sectnum;
|
2008-09-11 09:24:45 +00:00
|
|
|
|
2020-04-11 21:45:45 +00:00
|
|
|
// Printf("duped sprite of pic %d at %d %d %d\n",tsp->picnum,tsp->x,tsp->y,tsp->z);
|
2006-06-19 19:28:49 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-07 05:20:00 +00:00
|
|
|
static int16_t SE40backupStat[MAXSECTORS];
|
|
|
|
static int32_t SE40backupZ[MAXSECTORS];
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static void G_SE40(int32_t smoothratio)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
if ((unsigned)ror_sprite < MAXSPRITES)
|
|
|
|
{
|
|
|
|
int32_t x, y, z;
|
|
|
|
int16_t sect;
|
|
|
|
int32_t level = 0;
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const sp = &sprite[ror_sprite];
|
2016-02-13 21:05:57 +00:00
|
|
|
const int32_t sprite2 = sp->yvel;
|
2008-08-28 05:57:46 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if ((unsigned)sprite2 >= MAXSPRITES)
|
|
|
|
return;
|
2008-08-28 05:57:46 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (klabs(sector[sp->sectnum].floorz - sp->z) < klabs(sector[sprite[sprite2].sectnum].floorz - sprite[sprite2].z))
|
|
|
|
level = 1;
|
2008-08-28 05:57:46 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
x = CAMERA(pos.x) - sp->x;
|
|
|
|
y = CAMERA(pos.y) - sp->y;
|
|
|
|
z = CAMERA(pos.z) - (level ? sector[sp->sectnum].floorz : sector[sp->sectnum].ceilingz);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
sect = sprite[sprite2].sectnum;
|
|
|
|
updatesector(sprite[sprite2].x + x, sprite[sprite2].y + y, §);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (sect != -1)
|
2006-04-22 00:17:55 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t renderz, picnum;
|
|
|
|
// XXX: PK: too large stack allocation for my taste
|
|
|
|
int32_t i;
|
|
|
|
int32_t pix_diff, newz;
|
2020-04-11 21:45:45 +00:00
|
|
|
// Printf("drawing ror\n");
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (level)
|
|
|
|
{
|
|
|
|
// renderz = sector[sprite[sprite2].sectnum].ceilingz;
|
|
|
|
renderz = sprite[sprite2].z - (sprite[sprite2].yrepeat * tilesiz[sprite[sprite2].picnum].y<<1);
|
|
|
|
picnum = sector[sprite[sprite2].sectnum].ceilingpicnum;
|
|
|
|
sector[sprite[sprite2].sectnum].ceilingpicnum = 562;
|
2019-10-11 19:04:31 +00:00
|
|
|
tileDelete(562);
|
2006-04-22 02:33:36 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
pix_diff = klabs(z) >> 8;
|
|
|
|
newz = - ((pix_diff / 128) + 1) * (128<<8);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i = 0; i < numsectors; i++)
|
|
|
|
{
|
2018-10-07 05:20:00 +00:00
|
|
|
SE40backupStat[i] = sector[i].ceilingstat;
|
|
|
|
SE40backupZ[i] = sector[i].ceilingz;
|
2018-10-07 05:23:48 +00:00
|
|
|
if (!ror_protectedsectors[i] || sp->lotag == 41)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
sector[i].ceilingstat = 1;
|
|
|
|
sector[i].ceilingz += newz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// renderz = sector[sprite[sprite2].sectnum].floorz;
|
|
|
|
renderz = sprite[sprite2].z;
|
|
|
|
picnum = sector[sprite[sprite2].sectnum].floorpicnum;
|
|
|
|
sector[sprite[sprite2].sectnum].floorpicnum = 562;
|
2019-10-11 19:04:31 +00:00
|
|
|
tileDelete(562);
|
2015-10-20 07:15:01 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
pix_diff = klabs(z) >> 8;
|
|
|
|
newz = ((pix_diff / 128) + 1) * (128<<8);
|
2006-12-23 02:38:47 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i = 0; i < numsectors; i++)
|
|
|
|
{
|
2018-10-07 05:20:00 +00:00
|
|
|
SE40backupStat[i] = sector[i].floorstat;
|
|
|
|
SE40backupZ[i] = sector[i].floorz;
|
2018-10-07 05:23:48 +00:00
|
|
|
if (!ror_protectedsectors[i] || sp->lotag == 41)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
sector[i].floorstat = 1;
|
|
|
|
sector[i].floorz = +newz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-08-28 05:57:46 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef POLYMER
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_POLYMER)
|
2019-06-29 17:48:05 +00:00
|
|
|
polymer_setanimatesprites(G_DoSpriteAnimations, CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), fix16_to_int(CAMERA(q16ang)), smoothratio);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawRoomsQ16(sprite[sprite2].x + x, sprite[sprite2].y + y,
|
2018-03-07 04:21:18 +00:00
|
|
|
z + renderz, CAMERA(q16ang), CAMERA(q16horiz), sect);
|
2016-02-13 21:05:57 +00:00
|
|
|
drawing_ror = 1 + level;
|
2015-10-20 07:15:01 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (drawing_ror == 2) // viewing from top
|
|
|
|
G_OROR_DupeSprites(sp);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-06-29 17:48:05 +00:00
|
|
|
G_DoSpriteAnimations(CAMERA(pos.x),CAMERA(pos.y),CAMERA(pos.z),fix16_to_int(CAMERA(q16ang)),smoothratio);
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawMasks();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (level)
|
|
|
|
{
|
|
|
|
sector[sprite[sprite2].sectnum].ceilingpicnum = picnum;
|
|
|
|
for (i = 0; i < numsectors; i++)
|
|
|
|
{
|
2018-10-07 05:20:00 +00:00
|
|
|
sector[i].ceilingstat = SE40backupStat[i];
|
|
|
|
sector[i].ceilingz = SE40backupZ[i];
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sector[sprite[sprite2].sectnum].floorpicnum = picnum;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i = 0; i < numsectors; i++)
|
|
|
|
{
|
2018-10-07 05:20:00 +00:00
|
|
|
sector[i].floorstat = SE40backupStat[i];
|
|
|
|
sector[i].floorz = SE40backupZ[i];
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-09-15 02:47:02 +00:00
|
|
|
}
|
2015-02-08 08:03:30 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
2015-02-08 08:03:30 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
void G_HandleMirror(int32_t x, int32_t y, int32_t z, fix16_t a, fix16_t q16horiz, int32_t smoothratio)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2019-08-04 02:51:50 +00:00
|
|
|
if ((gotpic[MIRROR>>3]&pow2char[MIRROR&7])
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef POLYMER
|
2018-04-12 21:03:12 +00:00
|
|
|
&& (videoGetRenderMode() != REND_POLYMER)
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
)
|
2008-07-19 04:13:53 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_mirrorCount == 0)
|
|
|
|
{
|
|
|
|
// NOTE: We can have g_mirrorCount==0 but gotpic'd MIRROR,
|
|
|
|
// for example in LNGA2.
|
2019-08-04 02:51:50 +00:00
|
|
|
gotpic[MIRROR>>3] &= ~pow2char[MIRROR&7];
|
2019-06-25 18:35:08 +00:00
|
|
|
|
|
|
|
//give scripts the chance to reset gotpics for effects that run in EVENT_DISPLAYROOMS
|
|
|
|
//EVENT_RESETGOTPICS must be called after the last call to EVENT_DISPLAYROOMS in a frame, but before any engine-side renderDrawRoomsQ16
|
|
|
|
VM_OnEvent(EVENT_RESETGOTPICS, -1, -1);
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
|
|
|
}
|
2008-07-19 04:13:53 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t i = 0, dst = INT32_MAX;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t k=g_mirrorCount-1; k>=0; k--)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-05-17 00:35:26 +00:00
|
|
|
if (!wallvisible(x, y, g_mirrorWall[k]))
|
|
|
|
continue;
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
const int32_t j =
|
|
|
|
klabs(wall[g_mirrorWall[k]].x - x) +
|
|
|
|
klabs(wall[g_mirrorWall[k]].y - y);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (j < dst)
|
|
|
|
dst = j, i = k;
|
|
|
|
}
|
2006-12-09 23:41:43 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (wall[g_mirrorWall[i]].overpicnum != MIRROR)
|
|
|
|
{
|
|
|
|
// Try to find a new mirror wall in case the original one was broken.
|
2006-12-23 02:38:47 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t startwall = sector[g_mirrorSector[i]].wallptr;
|
|
|
|
int32_t endwall = startwall + sector[g_mirrorSector[i]].wallnum;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t k=startwall; k<endwall; k++)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
int32_t j = wall[k].nextwall;
|
|
|
|
if (j >= 0 && (wall[j].cstat&32) && wall[j].overpicnum==MIRROR) // cmp. premap.c
|
|
|
|
{
|
|
|
|
g_mirrorWall[i] = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (wall[g_mirrorWall[i]].overpicnum == MIRROR)
|
|
|
|
{
|
|
|
|
int32_t tposx, tposy;
|
2018-03-07 04:21:18 +00:00
|
|
|
fix16_t tang;
|
2011-05-22 21:52:22 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
//prepare to render any scripted EVENT_DISPLAYROOMS extras as mirrored
|
2019-06-25 18:35:16 +00:00
|
|
|
renderPrepareMirror(x, y, z, a, q16horiz, g_mirrorWall[i], &tposx, &tposy, &tang);
|
2011-05-22 21:52:22 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t j = g_visibility;
|
|
|
|
g_visibility = (j>>1) + (j>>2);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
//backup original camera position
|
2019-08-16 04:58:47 +00:00
|
|
|
auto origCam = CAMERA(pos);
|
|
|
|
fix16_t origCamq16ang = CAMERA(q16ang);
|
2019-06-25 18:35:05 +00:00
|
|
|
fix16_t origCamq16horiz = CAMERA(q16horiz);
|
2019-08-16 04:58:47 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
//set the camera inside the mirror facing out
|
2019-08-16 04:58:47 +00:00
|
|
|
CAMERA(pos) = { tposx, tposy, z };
|
|
|
|
CAMERA(q16ang) = tang;
|
2019-06-25 18:35:05 +00:00
|
|
|
CAMERA(q16horiz) = q16horiz;
|
2019-08-16 04:58:47 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
display_mirror = 1;
|
|
|
|
VM_OnEventWithReturn(EVENT_DISPLAYROOMS, g_player[0].ps->i, 0, 0);
|
|
|
|
display_mirror = 0;
|
2019-08-16 04:58:47 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
//reset the camera position
|
2019-08-16 04:58:47 +00:00
|
|
|
CAMERA(pos) = origCam;
|
|
|
|
CAMERA(q16ang) = origCamq16ang;
|
2019-06-25 18:35:05 +00:00
|
|
|
CAMERA(q16horiz) = origCamq16horiz;
|
|
|
|
|
2019-06-25 18:35:08 +00:00
|
|
|
//give scripts the chance to reset gotpics for effects that run in EVENT_DISPLAYROOMS
|
|
|
|
//EVENT_RESETGOTPICS must be called after the last call to EVENT_DISPLAYROOMS in a frame, but before any engine-side renderDrawRoomsQ16
|
|
|
|
VM_OnEvent(EVENT_RESETGOTPICS, -1, -1);
|
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
//prepare to render the mirror
|
2019-06-25 18:35:16 +00:00
|
|
|
renderPrepareMirror(x, y, z, a, q16horiz, g_mirrorWall[i], &tposx, &tposy, &tang);
|
2019-06-25 18:35:05 +00:00
|
|
|
|
2019-04-07 20:56:38 +00:00
|
|
|
if (videoGetRenderMode() != REND_POLYMER)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
int32_t didmirror;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
yax_preparedrawrooms();
|
2018-04-12 21:03:47 +00:00
|
|
|
didmirror = renderDrawRoomsQ16(tposx,tposy,z,tang,q16horiz,g_mirrorSector[i]+MAXSECTORS);
|
2019-06-25 18:35:05 +00:00
|
|
|
//POGO: if didmirror == 0, we may simply wish to abort instead of rendering with yax_drawrooms (which may require cleaning yax state)
|
2019-07-18 01:33:32 +00:00
|
|
|
if (videoGetRenderMode() != REND_CLASSIC || didmirror)
|
|
|
|
yax_drawrooms(G_DoSpriteAnimations, g_mirrorSector[i], didmirror, smoothratio);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2011-03-04 08:50:58 +00:00
|
|
|
#ifdef USE_OPENGL
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawRoomsQ16(tposx,tposy,z,tang,q16horiz,g_mirrorSector[i]+MAXSECTORS);
|
2016-02-13 21:05:57 +00:00
|
|
|
// XXX: Sprites don't get drawn with TROR/Polymost
|
2014-01-12 14:04:51 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
display_mirror = 1;
|
2019-06-29 17:48:05 +00:00
|
|
|
G_DoSpriteAnimations(tposx,tposy,z,fix16_to_int(tang),smoothratio);
|
2016-02-13 21:05:57 +00:00
|
|
|
display_mirror = 0;
|
2012-08-22 22:49:27 +00:00
|
|
|
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
renderCompleteMirror(); //Reverse screen x-wise in this function
|
2016-02-13 21:05:57 +00:00
|
|
|
g_visibility = j;
|
|
|
|
}
|
2019-06-25 18:35:05 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-22 22:49:27 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
static void G_ClearGotMirror()
|
|
|
|
{
|
2014-01-12 14:04:51 +00:00
|
|
|
#ifdef SPLITSCREEN_MOD_HACKS
|
2019-06-25 18:35:05 +00:00
|
|
|
if (!g_fakeMultiMode)
|
2014-01-12 14:04:51 +00:00
|
|
|
#endif
|
2019-06-25 18:35:05 +00:00
|
|
|
{
|
|
|
|
// HACK for splitscreen mod: this is so that mirrors will be drawn
|
|
|
|
// from showview commands. Ugly, because we'll attempt do draw mirrors
|
|
|
|
// each frame then. But it's better than not drawing them, I guess.
|
|
|
|
// XXX: fix the sequence of setting/clearing this bit. Right now,
|
|
|
|
// we always draw one frame without drawing the mirror, after which
|
|
|
|
// the bit gets set and drawn subsequently.
|
2019-08-04 02:51:50 +00:00
|
|
|
gotpic[MIRROR>>3] &= ~pow2char[MIRROR&7];
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2012-01-30 21:18:59 +00:00
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2017-01-01 13:23:29 +00:00
|
|
|
void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const pPlayer = g_player[playerNum].ps;
|
2012-09-08 22:18:40 +00:00
|
|
|
|
2019-02-22 18:35:33 +00:00
|
|
|
int const viewingRange = viewingrange;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_networkMode == NET_DEDICATED_SERVER) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
totalclocklock = totalclock;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2018-04-12 21:03:12 +00:00
|
|
|
if (pub > 0 || videoGetRenderMode() >= REND_POLYMOST) // JBF 20040101: redraw background always
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-01-26 09:58:00 +00:00
|
|
|
videoClearScreen(0);
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifndef EDUKE32_TOUCH_DEVICES
|
|
|
|
if (ud.screen_size >= 8)
|
|
|
|
#endif
|
|
|
|
G_DrawBackground();
|
|
|
|
pub = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
VM_OnEvent(EVENT_DISPLAYSTART, pPlayer->i, playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
if ((ud.overhead_on == 2 && !automapping) || (pPlayer->cursectnum == -1 && videoGetRenderMode() != REND_CLASSIC))
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (r_usenewaspect)
|
2012-08-20 21:32:11 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
newaspect_enable = 1;
|
2018-04-12 21:02:51 +00:00
|
|
|
videoSetCorrectedAspect();
|
2012-08-20 21:32:11 +00:00
|
|
|
}
|
2012-08-16 21:48:26 +00:00
|
|
|
|
2019-08-27 13:39:54 +00:00
|
|
|
if (pPlayer->on_crane > -1)
|
2016-08-27 01:41:04 +00:00
|
|
|
smoothRatio = 65536;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
int const playerVis = pPlayer->visibility;
|
|
|
|
g_visibility = (playerVis <= 0) ? 0 : (int32_t)(playerVis * (numplayers > 1 ? 1.f : r_ambientlightrecip));
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
CAMERA(sect) = pPlayer->cursectnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
G_DoInterpolations(smoothRatio);
|
|
|
|
G_AnimateCamSprite(smoothRatio);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.camerasprite >= 0)
|
2012-12-10 18:17:53 +00:00
|
|
|
{
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const pSprite = &sprite[ud.camerasprite];
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2019-06-25 18:34:49 +00:00
|
|
|
pSprite->yvel = clamp(TrackerCast(pSprite->yvel), -100, 300);
|
2013-01-17 21:59:11 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
CAMERA(q16ang) = fix16_from_int(actor[ud.camerasprite].tempang
|
|
|
|
+ mulscale16(((pSprite->ang + 1024 - actor[ud.camerasprite].tempang) & 2047) - 1024, smoothRatio));
|
2012-07-05 17:55:15 +00:00
|
|
|
|
2019-09-08 01:01:22 +00:00
|
|
|
#ifdef USE_OPENGL
|
2019-06-25 18:35:01 +00:00
|
|
|
renderSetRollAngle(0);
|
2019-09-08 01:01:22 +00:00
|
|
|
#endif
|
2019-06-25 18:35:01 +00:00
|
|
|
|
2019-01-22 17:56:34 +00:00
|
|
|
int const noDraw = VM_OnEventWithReturn(EVENT_DISPLAYROOMSCAMERA, ud.camerasprite, playerNum, 0);
|
2015-02-11 05:22:07 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (noDraw != 1) // event return values other than 0 and 1 are reserved
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-01-22 17:56:34 +00:00
|
|
|
#ifdef DEBUGGINGAIDS
|
2016-08-27 01:41:04 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(noDraw != 0))
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "ERROR: EVENT_DISPLAYROOMSCAMERA return value must be 0 or 1, "
|
2016-02-13 21:05:57 +00:00
|
|
|
"other values are reserved.\n");
|
2019-01-22 17:56:34 +00:00
|
|
|
#endif
|
2014-12-17 13:00:54 +00:00
|
|
|
|
2020-01-12 19:28:07 +00:00
|
|
|
screen->BeginScene();
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LEGACY_ROR
|
2016-08-27 01:41:04 +00:00
|
|
|
G_SE40(smoothRatio);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
#ifdef POLYMER
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_POLYMER)
|
2019-09-21 11:02:17 +00:00
|
|
|
polymer_setanimatesprites(G_DoSpriteAnimations, pSprite->x, pSprite->y, pSprite->z - ZOFFSET6, fix16_to_int(CAMERA(q16ang)), smoothRatio);
|
2014-12-17 13:00:54 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
yax_preparedrawrooms();
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawRoomsQ16(pSprite->x, pSprite->y, pSprite->z - ZOFFSET6, CAMERA(q16ang), fix16_from_int(pSprite->yvel), pSprite->sectnum);
|
2016-08-27 01:41:04 +00:00
|
|
|
yax_drawrooms(G_DoSpriteAnimations, pSprite->sectnum, 0, smoothRatio);
|
2019-09-21 11:02:17 +00:00
|
|
|
G_DoSpriteAnimations(pSprite->x, pSprite->y, pSprite->z - ZOFFSET6, fix16_to_int(CAMERA(q16ang)), smoothRatio);
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawMasks();
|
2020-01-12 19:28:07 +00:00
|
|
|
screen->FinishScene();
|
2012-05-01 12:39:02 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
int32_t floorZ, ceilZ;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2019-02-22 18:35:33 +00:00
|
|
|
int vr = divscale22(1, sprite[pPlayer->i].yrepeat + 28);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-01-25 10:56:13 +00:00
|
|
|
vr = Blrintf(double(vr) * tan(r_fov * (PI/360.)));
|
2019-02-18 22:02:33 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!r_usenewaspect)
|
2019-02-22 18:35:33 +00:00
|
|
|
renderSetAspect(vr, yxaspect);
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2019-02-22 18:35:33 +00:00
|
|
|
renderSetAspect(mulscale16(vr, viewingrange), yxaspect);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-29 06:36:39 +00:00
|
|
|
if (videoGetRenderMode() >= REND_POLYMOST)
|
2019-06-25 18:35:01 +00:00
|
|
|
{
|
2020-01-12 22:16:21 +00:00
|
|
|
if (ud.screen_tilting)
|
2019-06-25 18:35:01 +00:00
|
|
|
{
|
|
|
|
renderSetRollAngle(pPlayer->orotscrnang + mulscale16(((pPlayer->rotscrnang - pPlayer->orotscrnang + 1024)&2047)-1024, smoothRatio));
|
|
|
|
pPlayer->orotscrnang = pPlayer->rotscrnang;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
renderSetRollAngle(0);
|
|
|
|
}
|
2012-08-20 21:22:41 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (pPlayer->newowner < 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
vec3_t const camVect = { pPlayer->opos.x + mulscale16(pPlayer->pos.x - pPlayer->opos.x, smoothRatio),
|
|
|
|
pPlayer->opos.y + mulscale16(pPlayer->pos.y - pPlayer->opos.y, smoothRatio),
|
|
|
|
pPlayer->opos.z + mulscale16(pPlayer->pos.z - pPlayer->opos.z, smoothRatio) };
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-04-02 21:59:59 +00:00
|
|
|
CAMERA(pos) = camVect;
|
2020-01-29 11:36:45 +00:00
|
|
|
CAMERA(q16ang) = pPlayer->q16ang + fix16_from_int(pPlayer->look_ang);
|
|
|
|
CAMERA(q16horiz) = pPlayer->q16horiz + pPlayer->q16horizoff;
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2019-10-21 23:00:22 +00:00
|
|
|
if (cl_viewbob)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
int zAdd = (pPlayer->opyoff + mulscale16(pPlayer->pyoff-pPlayer->opyoff, smoothRatio));
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (pPlayer->over_shoulder_on)
|
|
|
|
zAdd >>= 3;
|
|
|
|
|
|
|
|
CAMERA(pos.z) += zAdd;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (pPlayer->over_shoulder_on)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
CAMERA(pos.z) -= 3072;
|
2016-08-27 01:41:04 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
if (G_DoThirdPerson(pPlayer, &CAMERA(pos), &CAMERA(sect), fix16_to_int(CAMERA(q16ang)), fix16_to_int(CAMERA(q16horiz))) < 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
CAMERA(pos.z) += 3072;
|
2018-03-07 04:21:18 +00:00
|
|
|
G_DoThirdPerson(pPlayer, &CAMERA(pos), &CAMERA(sect), fix16_to_int(CAMERA(q16ang)), fix16_to_int(CAMERA(q16horiz)));
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
vec3_t const camVect = G_GetCameraPosition(pPlayer->newowner, smoothRatio);
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// looking through viewscreen
|
2018-04-02 21:59:59 +00:00
|
|
|
CAMERA(pos) = camVect;
|
2018-03-07 04:21:18 +00:00
|
|
|
CAMERA(q16ang) = pPlayer->q16ang + fix16_from_int(pPlayer->look_ang);
|
|
|
|
CAMERA(q16horiz) = fix16_from_int(100 + sprite[pPlayer->newowner].shade);
|
2018-04-02 21:59:59 +00:00
|
|
|
CAMERA(sect) = sprite[pPlayer->newowner].sectnum;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
ceilZ = actor[pPlayer->i].ceilingz;
|
|
|
|
floorZ = actor[pPlayer->i].floorz;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (g_earthquakeTime > 0 && pPlayer->on_ground == 1)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
CAMERA(pos.z) += 256 - (((g_earthquakeTime)&1) << 9);
|
2018-03-07 04:21:18 +00:00
|
|
|
CAMERA(q16ang) += fix16_from_int((2 - ((g_earthquakeTime)&2)) << 2);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (sprite[pPlayer->i].pal == 1)
|
2016-02-13 21:05:57 +00:00
|
|
|
CAMERA(pos.z) -= (18<<8);
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (pPlayer->newowner < 0 && pPlayer->spritebridge == 0)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
// NOTE: when shrunk, p->pos.z can be below the floor. This puts the
|
|
|
|
// camera into the sector again then.
|
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (CAMERA(pos.z) < (pPlayer->truecz + ZOFFSET6))
|
|
|
|
CAMERA(pos.z) = ceilZ + ZOFFSET6;
|
|
|
|
else if (CAMERA(pos.z) > (pPlayer->truefz - ZOFFSET6))
|
|
|
|
CAMERA(pos.z) = floorZ - ZOFFSET6;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
while (CAMERA(sect) >= 0) // if, really
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
getzsofslope(CAMERA(sect),CAMERA(pos.x),CAMERA(pos.y),&ceilZ,&floorZ);
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
if (yax_getbunch(CAMERA(sect), YAX_CEILING) >= 0)
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
if (CAMERA(pos.z) < ceilZ)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
updatesectorz(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), &CAMERA(sect));
|
|
|
|
break; // since CAMERA(sect) might have been updated to -1
|
|
|
|
// NOTE: fist discovered in WGR2 SVN r134, til' death level 1
|
|
|
|
// (Lochwood Hollow). A problem REMAINS with Polymost, maybe classic!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2016-08-27 01:41:04 +00:00
|
|
|
if (CAMERA(pos.z) < ceilZ+ZOFFSET6)
|
|
|
|
CAMERA(pos.z) = ceilZ+ZOFFSET6;
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
if (yax_getbunch(CAMERA(sect), YAX_FLOOR) >= 0)
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
if (CAMERA(pos.z) > floorZ)
|
2016-02-13 21:05:57 +00:00
|
|
|
updatesectorz(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), &CAMERA(sect));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2016-08-27 01:41:04 +00:00
|
|
|
if (CAMERA(pos.z) > floorZ-ZOFFSET6)
|
|
|
|
CAMERA(pos.z) = floorZ-ZOFFSET6;
|
2014-03-15 14:10:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// NOTE: might be rendering off-screen here, so CON commands that draw stuff
|
|
|
|
// like showview must cope with that situation or bail out!
|
2016-08-27 01:41:04 +00:00
|
|
|
int const noDraw = VM_OnEventWithReturn(EVENT_DISPLAYROOMS, pPlayer->i, playerNum, 0);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
CAMERA(q16horiz) = fix16_clamp(CAMERA(q16horiz), F16(HORIZ_MIN), F16(HORIZ_MAX));
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (noDraw != 1) // event return values other than 0 and 1 are reserved
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-01-22 17:56:34 +00:00
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
if (EDUKE32_PREDICT_FALSE(noDraw != 0))
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "ERROR: EVENT_DISPLAYROOMS return value must be 0 or 1, "
|
2016-02-13 21:05:57 +00:00
|
|
|
"other values are reserved.\n");
|
2019-01-22 17:56:34 +00:00
|
|
|
#endif
|
2020-01-12 19:28:07 +00:00
|
|
|
screen->BeginScene();
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
G_HandleMirror(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), CAMERA(q16ang), CAMERA(q16horiz), smoothRatio);
|
2019-06-25 18:35:05 +00:00
|
|
|
G_ClearGotMirror();
|
2013-12-28 17:04:34 +00:00
|
|
|
#ifdef LEGACY_ROR
|
2016-08-27 01:41:04 +00:00
|
|
|
G_SE40(smoothRatio);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
#ifdef POLYMER
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_POLYMER)
|
2019-06-29 17:48:05 +00:00
|
|
|
polymer_setanimatesprites(G_DoSpriteAnimations, CAMERA(pos.x),CAMERA(pos.y),CAMERA(pos.z),fix16_to_int(CAMERA(q16ang)),smoothRatio);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
// for G_PrintCoords
|
|
|
|
dr_viewingrange = viewingrange;
|
|
|
|
dr_yxaspect = yxaspect;
|
|
|
|
#ifdef DEBUG_MIRRORS_ONLY
|
2019-08-04 02:51:50 +00:00
|
|
|
gotpic[MIRROR>>3] |= pow2char[MIRROR&7];
|
2016-02-13 21:05:57 +00:00
|
|
|
#else
|
|
|
|
yax_preparedrawrooms();
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawRoomsQ16(CAMERA(pos.x),CAMERA(pos.y),CAMERA(pos.z),CAMERA(q16ang),CAMERA(q16horiz),CAMERA(sect));
|
2016-08-27 01:41:04 +00:00
|
|
|
yax_drawrooms(G_DoSpriteAnimations, CAMERA(sect), 0, smoothRatio);
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
if ((unsigned)ror_sprite < MAXSPRITES && drawing_ror == 1) // viewing from bottom
|
|
|
|
G_OROR_DupeSprites(&sprite[ror_sprite]);
|
|
|
|
#endif
|
2019-06-29 17:48:05 +00:00
|
|
|
G_DoSpriteAnimations(CAMERA(pos.x),CAMERA(pos.y),CAMERA(pos.z),fix16_to_int(CAMERA(q16ang)),smoothRatio);
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
drawing_ror = 0;
|
|
|
|
#endif
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawMasks();
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
2020-01-12 19:28:07 +00:00
|
|
|
screen->FinishScene();
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_RestoreInterpolations();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
// Totalclock count of last step of p->visibility converging towards
|
|
|
|
// ud.const_visibility.
|
|
|
|
static int32_t lastvist;
|
2016-08-27 01:41:04 +00:00
|
|
|
const int32_t visdif = ud.const_visibility-pPlayer->visibility;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Check if totalclock was cleared (e.g. restarted game).
|
|
|
|
if (totalclock < lastvist)
|
|
|
|
lastvist = 0;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Every 2nd totalclock increment (each 1/60th second), ...
|
|
|
|
while (totalclock >= lastvist+2)
|
|
|
|
{
|
|
|
|
// ... approximately three-quarter the difference between
|
|
|
|
// p->visibility and ud.const_visibility.
|
|
|
|
const int32_t visinc = visdif>>2;
|
|
|
|
|
|
|
|
if (klabs(visinc) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
pPlayer->visibility = ud.const_visibility;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
pPlayer->visibility += visinc;
|
2019-08-27 13:39:54 +00:00
|
|
|
lastvist = (int32_t) totalclock;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (r_usenewaspect)
|
2011-12-28 20:33:40 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
newaspect_enable = 0;
|
2019-02-22 18:35:33 +00:00
|
|
|
renderSetAspect(viewingRange, tabledivide32_noinline(65536 * ydim * 8, xdim * 5));
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2017-11-29 07:29:23 +00:00
|
|
|
|
|
|
|
VM_OnEvent(EVENT_DISPLAYROOMSEND, g_player[screenpeek].ps->i, screenpeek);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2015-01-05 21:54:31 +00:00
|
|
|
|
2020-01-12 22:16:21 +00:00
|
|
|
|
|
|
|
bool GameInterface::GenerateSavePic()
|
|
|
|
{
|
|
|
|
G_DrawRooms(myconnectindex, 65536);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void G_DumpDebugInfo(void)
|
|
|
|
{
|
2017-06-05 10:05:12 +00:00
|
|
|
static char const s_WEAPON[] = "WEAPON";
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t i,j,x;
|
2011-12-28 20:33:40 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
VM_ScriptInfo(insptr, 64);
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("\nCurrent gamevar values:\n");
|
2011-12-28 20:33:40 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i=0; i<MAX_WEAPONS; i++)
|
|
|
|
{
|
|
|
|
for (j=0; j<numplayers; j++)
|
2012-02-25 15:59:44 +00:00
|
|
|
{
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("Player ", j, "\n\n");
|
|
|
|
buildprint(s_WEAPON, i, "_CLIP ", PWEAPON(j, i, Clip), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_RELOAD ", PWEAPON(j, i, Reload), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_FIREDELAY ", PWEAPON(j, i, FireDelay), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_TOTALTIME ", PWEAPON(j, i, TotalTime), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_HOLDDELAY ", PWEAPON(j, i, HoldDelay), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_FLAGS ", PWEAPON(j, i, Flags), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SHOOTS ", PWEAPON(j, i, Shoots), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SPAWNTIME ", PWEAPON(j, i, SpawnTime), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SPAWN ", PWEAPON(j, i, Spawn), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SHOTSPERBURST ", PWEAPON(j, i, ShotsPerBurst), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_WORKSLIKE ", PWEAPON(j, i, WorksLike), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_INITIALSOUND ", PWEAPON(j, i, InitialSound), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_FIRESOUND ", PWEAPON(j, i, FireSound), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SOUND2TIME ", PWEAPON(j, i, Sound2Time), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SOUND2SOUND ", PWEAPON(j, i, Sound2Sound), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_RELOADSOUND1 ", PWEAPON(j, i, ReloadSound1), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_RELOADSOUND2 ", PWEAPON(j, i, ReloadSound2), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_SELECTSOUND ", PWEAPON(j, i, SelectSound), "\n");
|
|
|
|
buildprint(s_WEAPON, i, "_FLASHCOLOR ", PWEAPON(j, i, FlashColor), "\n");
|
2012-02-25 15:59:44 +00:00
|
|
|
}
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("\n");
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2012-02-25 15:59:44 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (x=0; x<MAXSTATUS; x++)
|
|
|
|
{
|
|
|
|
j = headspritestat[x];
|
|
|
|
while (j >= 0)
|
2011-12-28 20:33:40 +00:00
|
|
|
{
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("Sprite ", j, " (", TrackerCast(sprite[j].x), ",", TrackerCast(sprite[j].y), ",", TrackerCast(sprite[j].z),
|
|
|
|
") (picnum: ", TrackerCast(sprite[j].picnum), ")\n");
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i=0; i<g_gameVarCount; i++)
|
2011-12-28 20:33:40 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[i].flags & (GAMEVAR_PERACTOR))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[i].pValues[j] != aGameVars[i].defaultValue)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("gamevar ", aGameVars[i].szLabel, " ", aGameVars[i].pValues[j], " GAMEVAR_PERACTOR");
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[i].flags != GAMEVAR_PERACTOR)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint(" // ");
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[i].flags & (GAMEVAR_SYSTEM))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint(" (system)");
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("\n");
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-28 20:33:40 +00:00
|
|
|
}
|
2017-06-05 10:05:12 +00:00
|
|
|
buildprint("\n");
|
2016-02-13 21:05:57 +00:00
|
|
|
j = nextspritestat[j];
|
2012-08-13 18:26:08 +00:00
|
|
|
}
|
2011-12-28 20:33:40 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
Gv_DumpValues();
|
2011-12-28 20:33:40 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// if <set_movflag_uncond> is true, set the moveflag unconditionally,
|
|
|
|
// else only if it equals 0.
|
|
|
|
static int32_t G_InitActor(int32_t i, int32_t tilenum, int32_t set_movflag_uncond)
|
2013-01-20 21:17:28 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_tile[tilenum].execPtr)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
SH(i) = *(g_tile[tilenum].execPtr);
|
2016-02-13 21:05:57 +00:00
|
|
|
AC_ACTION_ID(actor[i].t_data) = *(g_tile[tilenum].execPtr+1);
|
|
|
|
AC_MOVE_ID(actor[i].t_data) = *(g_tile[tilenum].execPtr+2);
|
2013-01-20 21:17:28 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (set_movflag_uncond || SHT(i) == 0) // AC_MOVFLAGS
|
|
|
|
SHT(i) = *(g_tile[tilenum].execPtr+3);
|
2014-11-30 04:23:22 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return 1;
|
2013-08-06 23:51:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2010-10-17 14:49:39 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t A_InsertSprite(int16_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int16_t s_pn,int8_t s_s,
|
|
|
|
uint8_t s_xr,uint8_t s_yr,int16_t s_a,int16_t s_ve,int16_t s_zv,int16_t s_ow,int16_t s_ss)
|
|
|
|
{
|
2018-12-08 00:40:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
int32_t newSprite;
|
2019-01-12 00:21:53 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
#ifdef NETCODE_DISABLE
|
|
|
|
newSprite = insertsprite(whatsect, s_ss);
|
|
|
|
#else
|
|
|
|
newSprite = Net_InsertSprite(whatsect, s_ss);
|
|
|
|
|
|
|
|
#endif
|
2015-02-19 22:19:05 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)newSprite >= MAXSPRITES))
|
2008-09-15 02:47:02 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
G_DumpDebugInfo();
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Failed spawning pic %d spr from pic %d spr %d at x:%d,y:%d,z:%d,sect:%d\n",
|
2016-02-13 21:05:57 +00:00
|
|
|
s_pn,s_ow < 0 ? -1 : TrackerCast(sprite[s_ow].picnum),s_ow,s_x,s_y,s_z,whatsect);
|
|
|
|
G_GameExit("Too many sprites spawned.");
|
2008-09-15 02:47:02 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
g_spriteStat.numins++;
|
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
sprite[newSprite] = { s_x, s_y, s_z, 0, s_pn, s_s, 0, 0, 0, s_xr, s_yr, 0, 0, whatsect, s_ss, s_a, s_ow, s_ve, 0, s_zv, 0, 0, 0 };
|
|
|
|
|
|
|
|
auto &a = actor[newSprite];
|
|
|
|
a = {};
|
|
|
|
a.bpos = { s_x, s_y, s_z };
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if ((unsigned)s_ow < MAXSPRITES)
|
2010-10-17 14:49:39 +00:00
|
|
|
{
|
2018-11-18 18:14:33 +00:00
|
|
|
a.picnum = sprite[s_ow].picnum;
|
|
|
|
a.floorz = actor[s_ow].floorz;
|
|
|
|
a.ceilingz = actor[s_ow].ceilingz;
|
2010-10-17 14:49:39 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
a.stayput = -1;
|
|
|
|
a.extra = -1;
|
2017-06-23 03:59:39 +00:00
|
|
|
#ifdef POLYMER
|
2018-11-18 18:14:33 +00:00
|
|
|
a.lightId = -1;
|
2017-06-23 03:59:39 +00:00
|
|
|
#endif
|
2018-11-18 18:14:33 +00:00
|
|
|
a.owner = s_ow;
|
2012-11-10 14:11:10 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
G_InitActor(newSprite, s_pn, 1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
spriteext[newSprite] = {};
|
|
|
|
spritesmooth[newSprite] = {};
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#if defined LUNATIC
|
|
|
|
if (!g_noResetVars)
|
|
|
|
#endif
|
2018-11-18 18:14:33 +00:00
|
|
|
A_ResetVars(newSprite);
|
2016-02-13 21:05:57 +00:00
|
|
|
#if defined LUNATIC
|
|
|
|
g_noResetVars = 0;
|
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (VM_HaveEvent(EVENT_EGS))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:14:33 +00:00
|
|
|
int32_t p, pl = A_FindPlayer(&sprite[newSprite], &p);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
block_deletesprite++;
|
2019-05-19 03:53:25 +00:00
|
|
|
VM_ExecuteEvent(EVENT_EGS, newSprite, pl, p);
|
2016-02-13 21:05:57 +00:00
|
|
|
block_deletesprite--;
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
return newSprite;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2015-03-08 07:58:24 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
void Yax_SetBunchZs(int32_t sectnum, int32_t cf, int32_t daz)
|
|
|
|
{
|
|
|
|
int32_t i, bunchnum = yax_getbunch(sectnum, cf);
|
2015-03-08 07:58:24 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (bunchnum < 0 || bunchnum >= numyaxbunches)
|
|
|
|
return;
|
2015-03-08 07:58:24 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (SECTORS_OF_BUNCH(bunchnum, YAX_CEILING, i))
|
|
|
|
SECTORFLD(i,z, YAX_CEILING) = daz;
|
|
|
|
for (SECTORS_OF_BUNCH(bunchnum, YAX_FLOOR, i))
|
|
|
|
SECTORFLD(i,z, YAX_FLOOR) = daz;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Yax_SetBunchInterpolation(int32_t sectnum, int32_t cf)
|
|
|
|
{
|
|
|
|
int32_t i, bunchnum = yax_getbunch(sectnum, cf);
|
|
|
|
|
|
|
|
if (bunchnum < 0 || bunchnum >= numyaxbunches)
|
|
|
|
return;
|
2016-06-05 04:46:28 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (SECTORS_OF_BUNCH(bunchnum, YAX_CEILING, i))
|
|
|
|
G_SetInterpolation(§or[i].ceilingz);
|
|
|
|
for (SECTORS_OF_BUNCH(bunchnum, YAX_FLOOR, i))
|
|
|
|
G_SetInterpolation(§or[i].floorz);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
# define Yax_SetBunchInterpolation(sectnum, cf)
|
2010-08-02 08:13:51 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
// A_Spawn has two forms with arguments having different meaning:
|
|
|
|
//
|
2017-11-22 05:23:28 +00:00
|
|
|
// 1. spriteNum>=0: Spawn from parent sprite <spriteNum> with picnum <tileNum>
|
|
|
|
// 2. spriteNum<0: Spawn from already *existing* sprite <tileNum>
|
2016-08-27 01:40:56 +00:00
|
|
|
int A_Spawn(int spriteNum, int tileNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int newSprite;
|
|
|
|
spritetype *pSprite;
|
2017-11-22 05:23:33 +00:00
|
|
|
actor_t * pActor;
|
|
|
|
int sectNum;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
// spawn from parent sprite <j>
|
2016-08-27 01:40:56 +00:00
|
|
|
newSprite = A_InsertSprite(sprite[spriteNum].sectnum,sprite[spriteNum].x,sprite[spriteNum].y,sprite[spriteNum].z,
|
|
|
|
tileNum,0,0,0,0,0,0,spriteNum,0);
|
|
|
|
actor[newSprite].picnum = sprite[spriteNum].picnum;
|
2006-05-06 05:28:28 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
else
|
2006-08-20 22:17:12 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
// spawn from already existing sprite <pn>
|
2018-11-18 18:14:33 +00:00
|
|
|
newSprite = tileNum;
|
|
|
|
auto &s = sprite[newSprite];
|
|
|
|
auto &a = actor[newSprite];
|
2012-05-26 21:58:21 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
a = { };
|
|
|
|
a.bpos = { s.x, s.y, s.z };
|
2010-10-17 14:49:39 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
a.picnum = s.picnum;
|
2011-08-10 11:47:23 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if (s.picnum == SECTOREFFECTOR && s.lotag == 50)
|
|
|
|
a.picnum = s.owner;
|
2006-12-09 23:41:43 +00:00
|
|
|
|
2019-06-29 18:45:44 +00:00
|
|
|
if (s.picnum == LOCATORS && s.owner != -1)
|
2019-06-25 18:35:22 +00:00
|
|
|
a.owner = s.owner;
|
2019-06-29 18:45:44 +00:00
|
|
|
else
|
|
|
|
s.owner = a.owner = newSprite;
|
2012-03-29 21:16:20 +00:00
|
|
|
|
2019-08-14 15:28:53 +00:00
|
|
|
a.floorz = sector[s.sectnum].floorz;
|
|
|
|
a.ceilingz = sector[s.sectnum].ceilingz;
|
|
|
|
a.stayput = a.extra = -1;
|
2006-12-09 23:41:43 +00:00
|
|
|
|
2017-06-23 03:59:39 +00:00
|
|
|
#ifdef POLYMER
|
2018-11-18 18:14:33 +00:00
|
|
|
a.lightId = -1;
|
2017-06-23 03:59:39 +00:00
|
|
|
#endif
|
2015-01-18 23:16:37 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if ((s.cstat & 48)
|
2018-04-04 20:47:48 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-11-18 18:14:33 +00:00
|
|
|
&& s.picnum != SPEAKER && s.picnum != LETTER && s.picnum != DUCK && s.picnum != TARGET && s.picnum != TRIPBOMB
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2018-11-18 18:14:33 +00:00
|
|
|
&& s.picnum != VIEWSCREEN && s.picnum != VIEWSCREEN2 && (!(s.picnum >= CRACK1 && s.picnum <= CRACK4)))
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
2018-11-18 18:14:33 +00:00
|
|
|
if (s.shade == 127)
|
2016-08-27 01:40:56 +00:00
|
|
|
goto SPAWN_END;
|
2006-06-19 19:28:49 +00:00
|
|
|
|
2018-04-04 20:47:48 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-11-18 18:14:33 +00:00
|
|
|
if (A_CheckSwitchTile(newSprite) && (s.cstat & 16))
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
2018-11-18 18:14:33 +00:00
|
|
|
if (s.pal && s.picnum != ACCESSSWITCH && s.picnum != ACCESSSWITCH2)
|
2014-03-05 21:12:59 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (((!g_netServer && ud.multimode < 2)) || ((g_netServer || ud.multimode > 1) && !GTFLAGS(GAMETYPE_DMSWITCHES)))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-11-18 18:14:33 +00:00
|
|
|
s.xrepeat = s.yrepeat = 0;
|
|
|
|
s.lotag = s.hitag = 0;
|
|
|
|
s.cstat = 32768;
|
2016-08-27 01:40:56 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
2012-05-26 21:58:29 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
s.cstat |= 257;
|
2017-11-22 05:23:33 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if (s.pal && s.picnum != ACCESSSWITCH && s.picnum != ACCESSSWITCH2)
|
|
|
|
s.pal = 0;
|
2012-05-26 21:58:29 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
goto SPAWN_END;
|
|
|
|
}
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2012-05-26 21:58:29 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if (s.hitag)
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
|
|
|
changespritestat(newSprite, STAT_FALLER);
|
2018-11-18 18:14:33 +00:00
|
|
|
s.cstat |= 257;
|
|
|
|
s.extra = g_impactDamage;
|
2016-08-27 01:40:56 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
2007-03-11 00:47:32 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if (s.cstat & 1)
|
|
|
|
s.cstat |= 256;
|
2012-05-26 21:58:21 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
if (!G_InitActor(newSprite, s.picnum, 0))
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = T5(newSprite) = 0; // AC_MOVE_ID, AC_ACTION_ID
|
2019-08-29 05:14:59 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
A_GetZLimits(newSprite);
|
|
|
|
actor[newSprite].bpos = sprite[newSprite].pos;
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-10-17 14:49:39 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite = &sprite[newSprite];
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor = &actor[newSprite];
|
2016-08-27 01:40:56 +00:00
|
|
|
sectNum = pSprite->sectnum;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
//some special cases that can't be handled through the dynamictostatic system.
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-04-06 01:42:33 +00:00
|
|
|
if (pSprite->picnum >= CAMERA1 && pSprite->picnum <= CAMERA1 + 4)
|
|
|
|
pSprite->picnum = CAMERA1;
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
else if (pSprite->picnum >= BOLT1 && pSprite->picnum <= BOLT1 + 3)
|
|
|
|
pSprite->picnum = BOLT1;
|
|
|
|
else if (pSprite->picnum >= SIDEBOLT1 && pSprite->picnum <= SIDEBOLT1 + 3)
|
|
|
|
pSprite->picnum = SIDEBOLT1;
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (DYNAMICTILEMAP(pSprite->picnum))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
case FOF__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-06 01:42:33 +00:00
|
|
|
case CAMERA1__STATIC:
|
|
|
|
pSprite->extra = 1;
|
|
|
|
pSprite->cstat &= 32768;
|
|
|
|
|
|
|
|
if (g_damageCameras)
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
|
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal != 0)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->pal = 0;
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
|
|
|
}
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-04-06 01:42:33 +00:00
|
|
|
case CAMERAPOLE__STATIC:
|
|
|
|
pSprite->extra = 1;
|
|
|
|
pSprite->cstat &= 32768;
|
|
|
|
|
|
|
|
if (g_damageCameras)
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
fallthrough__;
|
|
|
|
case GENERICPOLE__STATIC:
|
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal != 0)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pSprite->pal = 0;
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-06 01:42:33 +00:00
|
|
|
|
|
|
|
case BOLT1__STATIC:
|
|
|
|
case SIDEBOLT1__STATIC:
|
|
|
|
T1(newSprite) = pSprite->xrepeat;
|
|
|
|
T2(newSprite) = pSprite->yrepeat;
|
|
|
|
pSprite->yvel = 0;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-06 01:42:33 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case WATERSPLASH2__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2011-05-12 23:31:13 +00:00
|
|
|
{
|
2019-08-13 14:44:00 +00:00
|
|
|
setsprite(newSprite, &sprite[spriteNum].pos);
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 8+(krand()&7);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else pSprite->xrepeat = pSprite->yrepeat = 16+(krand()&15);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->shade = -16;
|
|
|
|
pSprite->cstat |= 128;
|
|
|
|
|
|
|
|
if (spriteNum >= 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[sprite[spriteNum].sectnum].lotag == ST_2_UNDERWATER)
|
2012-01-19 23:17:03 +00:00
|
|
|
{
|
2017-11-22 05:23:33 +00:00
|
|
|
pSprite->z = getceilzofslope(sectNum, pSprite->x, pSprite->y) + (16 << 8);
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= 8;
|
2012-01-19 23:17:03 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (sector[sprite[spriteNum].sectnum].lotag == ST_1_ABOVE_WATER)
|
2017-11-22 05:23:33 +00:00
|
|
|
pSprite->z = getflorzofslope(sectNum, pSprite->x, pSprite->y);
|
2011-05-12 23:31:13 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[sectNum].floorpicnum == FLOORSLIME || sector[sectNum].ceilingpicnum == FLOORSLIME)
|
|
|
|
pSprite->pal = 7;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case DOMELITE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->picnum == DOMELITE)
|
|
|
|
pSprite->cstat |= 257;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case NEON1__STATIC:
|
|
|
|
case NEON2__STATIC:
|
|
|
|
case NEON3__STATIC:
|
|
|
|
case NEON4__STATIC:
|
|
|
|
case NEON5__STATIC:
|
|
|
|
case NEON6__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->picnum != WATERSPLASH2)
|
|
|
|
pSprite->cstat |= 257;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case NUKEBUTTON__STATIC:
|
|
|
|
case JIBS1__STATIC:
|
|
|
|
case JIBS2__STATIC:
|
|
|
|
case JIBS3__STATIC:
|
|
|
|
case JIBS4__STATIC:
|
|
|
|
case JIBS5__STATIC:
|
|
|
|
case JIBS6__STATIC:
|
|
|
|
case HEADJIB1__STATIC:
|
|
|
|
case ARMJIB1__STATIC:
|
|
|
|
case LEGJIB1__STATIC:
|
|
|
|
case LIZMANHEAD1__STATIC:
|
|
|
|
case LIZMANARM1__STATIC:
|
|
|
|
case LIZMANLEG1__STATIC:
|
|
|
|
case DUKETORSO__STATIC:
|
|
|
|
case DUKEGUN__STATIC:
|
|
|
|
case DUKELEG__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case TONGUE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
|
|
|
pSprite->z -= 38<<8;
|
|
|
|
pSprite->zvel = 256-(krand()&511);
|
|
|
|
pSprite->xvel = 64-(krand()&127);
|
|
|
|
changespritestat(newSprite, STAT_PROJECTILE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case NATURALLIGHTNING__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat &= ~257;
|
|
|
|
pSprite->cstat |= 32768;
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case TRANSPORTERSTAR__STATIC:
|
|
|
|
case TRANSPORTERBEAM__STATIC:
|
2020-03-29 08:41:03 +00:00
|
|
|
if (spriteNum == -1)
|
|
|
|
goto SPAWN_END;
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->picnum == TRANSPORTERBEAM)
|
2011-05-12 23:31:13 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = 31;
|
|
|
|
pSprite->yrepeat = 1;
|
|
|
|
pSprite->z = sector[sprite[spriteNum].sectnum].floorz-PHEIGHT;
|
2011-05-12 23:31:13 +00:00
|
|
|
}
|
|
|
|
else
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sprite[spriteNum].statnum == STAT_PROJECTILE)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 8;
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = 48;
|
|
|
|
pSprite->yrepeat = 64;
|
|
|
|
if (sprite[spriteNum].statnum == STAT_PLAYER || A_CheckEnemySprite(&sprite[spriteNum]))
|
|
|
|
pSprite->z -= ZOFFSET5;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->shade = -127;
|
|
|
|
pSprite->cstat = 128|2;
|
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
2012-01-19 23:17:03 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xvel = 128;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
A_SetSprite(newSprite,CLIPMASK0);
|
2019-06-25 11:28:25 +00:00
|
|
|
setsprite(newSprite,&pSprite->pos);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
case FEMMAG1__STATIC:
|
|
|
|
case FEMMAG2__STATIC:
|
|
|
|
pSprite->cstat &= ~257;
|
|
|
|
changespritestat(newSprite, STAT_DEFAULT);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
case DUKETAG__STATIC:
|
|
|
|
case SIGN1__STATIC:
|
|
|
|
case SIGN2__STATIC:
|
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
}
|
|
|
|
else pSprite->pal = 0;
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case MASKWALL1__STATIC:
|
|
|
|
case MASKWALL2__STATIC:
|
|
|
|
case MASKWALL3__STATIC:
|
|
|
|
case MASKWALL4__STATIC:
|
|
|
|
case MASKWALL5__STATIC:
|
|
|
|
case MASKWALL6__STATIC:
|
|
|
|
case MASKWALL7__STATIC:
|
|
|
|
case MASKWALL8__STATIC:
|
|
|
|
case MASKWALL9__STATIC:
|
|
|
|
case MASKWALL10__STATIC:
|
|
|
|
case MASKWALL11__STATIC:
|
|
|
|
case MASKWALL12__STATIC:
|
|
|
|
case MASKWALL13__STATIC:
|
|
|
|
case MASKWALL14__STATIC:
|
|
|
|
case MASKWALL15__STATIC:
|
|
|
|
{
|
|
|
|
int const j = pSprite->cstat & SPAWN_PROTECT_CSTAT_MASK;
|
|
|
|
pSprite->cstat = j | CSTAT_SPRITE_BLOCK;
|
|
|
|
changespritestat(newSprite, STAT_DEFAULT);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case PODFEM1__STATIC:
|
|
|
|
pSprite->extra <<= 1;
|
|
|
|
fallthrough__;
|
|
|
|
case FEM1__STATIC:
|
|
|
|
case FEM2__STATIC:
|
|
|
|
case FEM3__STATIC:
|
|
|
|
case FEM4__STATIC:
|
|
|
|
case FEM5__STATIC:
|
|
|
|
case FEM6__STATIC:
|
|
|
|
case FEM7__STATIC:
|
|
|
|
case FEM8__STATIC:
|
|
|
|
case FEM9__STATIC:
|
|
|
|
case FEM10__STATIC:
|
|
|
|
case NAKED1__STATIC:
|
|
|
|
case STATUE__STATIC:
|
|
|
|
case TOUGHGAL__STATIC:
|
|
|
|
pSprite->yvel = pSprite->hitag;
|
|
|
|
pSprite->hitag = -1;
|
|
|
|
fallthrough__;
|
|
|
|
case BLOODYPOLE__STATIC:
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
pSprite->clipdist = 32;
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case QUEBALL__STATIC:
|
|
|
|
case STRIPEBALL__STATIC:
|
|
|
|
pSprite->cstat = 256;
|
|
|
|
pSprite->clipdist = 8;
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case DUKELYINGDEAD__STATIC:
|
|
|
|
if (spriteNum >= 0 && sprite[spriteNum].picnum == APLAYER)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = sprite[spriteNum].xrepeat;
|
|
|
|
pSprite->yrepeat = sprite[spriteNum].yrepeat;
|
|
|
|
pSprite->shade = sprite[spriteNum].shade;
|
|
|
|
pSprite->pal = g_player[P_Get(spriteNum)].ps->palookup;
|
|
|
|
}
|
|
|
|
fallthrough__;
|
|
|
|
case DUKECAR__STATIC:
|
|
|
|
case HELECOPT__STATIC:
|
|
|
|
// if(sp->picnum == HELECOPT || sp->picnum == DUKECAR) sp->xvel = 1024;
|
|
|
|
pSprite->cstat = 0;
|
|
|
|
pSprite->extra = 1;
|
|
|
|
pSprite->xvel = 292;
|
|
|
|
pSprite->zvel = 360;
|
|
|
|
fallthrough__;
|
|
|
|
case BLIMP__STATIC:
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
pSprite->clipdist = 128;
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case RESPAWNMARKERRED__STATIC:
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 24;
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->z = actor[spriteNum].floorz; // -(1<<4);
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case MIKE__STATIC:
|
|
|
|
pSprite->yvel = pSprite->hitag;
|
|
|
|
pSprite->hitag = 0;
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
case WEATHERWARN__STATIC:
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case SPOTLITE__STATIC:
|
|
|
|
T1(newSprite) = pSprite->x;
|
|
|
|
T2(newSprite) = pSprite->y;
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
case BULLETHOLE__STATIC:
|
|
|
|
pSprite->xrepeat = 3;
|
|
|
|
pSprite->yrepeat = 3;
|
|
|
|
pSprite->cstat = 16 + (krand() & 12);
|
|
|
|
|
|
|
|
A_AddToDeleteQueue(newSprite);
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case MONEY__STATIC:
|
|
|
|
case MAIL__STATIC:
|
|
|
|
case PAPER__STATIC:
|
|
|
|
pActor->t_data[0] = krand() & 2047;
|
|
|
|
|
|
|
|
pSprite->cstat = krand() & 12;
|
|
|
|
pSprite->xrepeat = 8;
|
|
|
|
pSprite->yrepeat = 8;
|
|
|
|
pSprite->ang = krand() & 2047;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case SHELL__STATIC: //From the player
|
|
|
|
case SHOTGUNSHELL__STATIC:
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
int shellAng;
|
|
|
|
|
|
|
|
if (sprite[spriteNum].picnum == APLAYER)
|
|
|
|
{
|
2019-07-08 00:41:25 +00:00
|
|
|
int const playerNum = P_Get(spriteNum);
|
|
|
|
auto const pPlayer = g_player[playerNum].ps;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
shellAng = fix16_to_int(pPlayer->q16ang) - (krand() & 63) + 8; // Fine tune
|
|
|
|
|
|
|
|
T1(newSprite) = krand() & 1;
|
|
|
|
|
|
|
|
pSprite->z = (3 << 8) + pPlayer->pyoff + pPlayer->pos.z - (fix16_to_int((pPlayer->q16horizoff + pPlayer->q16horiz - F16(100))) << 4);
|
|
|
|
|
|
|
|
if (pSprite->picnum == SHOTGUNSHELL)
|
|
|
|
pSprite->z += (3 << 8);
|
|
|
|
|
|
|
|
pSprite->zvel = -(krand() & 255);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
shellAng = pSprite->ang;
|
|
|
|
pSprite->z = sprite[spriteNum].z - PHEIGHT + (3 << 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
pSprite->x = sprite[spriteNum].x + (sintable[(shellAng + 512) & 2047] >> 7);
|
|
|
|
pSprite->y = sprite[spriteNum].y + (sintable[shellAng & 2047] >> 7);
|
|
|
|
pSprite->shade = -8;
|
|
|
|
|
|
|
|
if (pSprite->yvel == 1 || NAM_WW2GI)
|
|
|
|
{
|
|
|
|
pSprite->ang = shellAng + 512;
|
|
|
|
pSprite->xvel = 30;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->ang = shellAng - 512;
|
|
|
|
pSprite->xvel = 20;
|
|
|
|
}
|
|
|
|
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 4;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
}
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case WATERBUBBLE__STATIC:
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].picnum == APLAYER)
|
|
|
|
pSprite->z -= (16 << 8);
|
|
|
|
|
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
|
|
|
}
|
|
|
|
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 4;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case CRANE__STATIC:
|
|
|
|
|
|
|
|
pSprite->cstat |= 64|257;
|
|
|
|
|
|
|
|
pSprite->picnum += 2;
|
|
|
|
pSprite->z = sector[sectNum].ceilingz+(48<<8);
|
|
|
|
T5(newSprite) = tempwallptr;
|
|
|
|
|
2019-08-07 22:43:48 +00:00
|
|
|
g_origins[tempwallptr] = pSprite->pos.vec2;
|
2018-04-04 20:47:55 +00:00
|
|
|
g_origins[tempwallptr+2].x = pSprite->z;
|
|
|
|
|
|
|
|
|
|
|
|
if (headspritestat[STAT_DEFAULT] != -1)
|
|
|
|
{
|
|
|
|
int findSprite = headspritestat[STAT_DEFAULT];
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (sprite[findSprite].picnum == CRANEPOLE && pSprite->hitag == (sprite[findSprite].hitag))
|
|
|
|
{
|
|
|
|
g_origins[tempwallptr + 2].y = findSprite;
|
|
|
|
|
|
|
|
T2(newSprite) = sprite[findSprite].sectnum;
|
|
|
|
|
|
|
|
sprite[findSprite].xrepeat = 48;
|
|
|
|
sprite[findSprite].yrepeat = 128;
|
|
|
|
|
2019-08-07 22:43:48 +00:00
|
|
|
g_origins[tempwallptr + 1] = sprite[findSprite].pos.vec2;
|
2019-06-25 11:28:25 +00:00
|
|
|
sprite[findSprite].pos = pSprite->pos;
|
|
|
|
sprite[findSprite].shade = pSprite->shade;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
2019-08-13 14:44:00 +00:00
|
|
|
setsprite(findSprite, &sprite[findSprite].pos);
|
2018-04-04 20:47:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
findSprite = nextspritestat[findSprite];
|
|
|
|
} while (findSprite >= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
tempwallptr += 3;
|
|
|
|
pSprite->owner = -1;
|
|
|
|
pSprite->extra = 8;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case TRASH__STATIC:
|
|
|
|
pSprite->ang = krand()&2047;
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 24;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case WATERDRIP__STATIC:
|
|
|
|
if (spriteNum >= 0 && (sprite[spriteNum].statnum == STAT_PLAYER || sprite[spriteNum].statnum == STAT_ACTOR))
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].pal != 1)
|
|
|
|
{
|
|
|
|
pSprite->pal = 2;
|
|
|
|
pSprite->z -= (18<<8);
|
|
|
|
}
|
|
|
|
else pSprite->z -= (13<<8);
|
|
|
|
|
|
|
|
pSprite->shade = 32;
|
|
|
|
pSprite->ang = getangle(g_player[0].ps->pos.x - pSprite->x, g_player[0].ps->pos.y - pSprite->y);
|
|
|
|
pSprite->xvel = 48 - (krand() & 31);
|
|
|
|
|
|
|
|
A_SetSprite(newSprite, CLIPMASK0);
|
|
|
|
}
|
|
|
|
else if (spriteNum == -1)
|
|
|
|
{
|
|
|
|
pSprite->z += ZOFFSET6;
|
|
|
|
T1(newSprite) = pSprite->z;
|
|
|
|
T2(newSprite) = krand()&127;
|
|
|
|
}
|
|
|
|
fallthrough__;
|
|
|
|
case WATERDRIPSPLASH__STATIC:
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 24;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case PLUG__STATIC:
|
|
|
|
pSprite->lotag = 9999;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
case TARGET__STATIC:
|
|
|
|
case DUCK__STATIC:
|
|
|
|
case LETTER__STATIC:
|
|
|
|
pSprite->extra = 1;
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
2020-03-29 08:41:12 +00:00
|
|
|
case BOSS2STAYPUT__STATIC:
|
|
|
|
case BOSS3STAYPUT__STATIC:
|
|
|
|
case BOSS5STAYPUT__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
fallthrough__;
|
2018-04-04 20:47:55 +00:00
|
|
|
case OCTABRAINSTAYPUT__STATIC:
|
|
|
|
case LIZTROOPSTAYPUT__STATIC:
|
|
|
|
case PIGCOPSTAYPUT__STATIC:
|
|
|
|
case LIZMANSTAYPUT__STATIC:
|
|
|
|
case BOSS1STAYPUT__STATIC:
|
|
|
|
case PIGCOPDIVE__STATIC:
|
|
|
|
case COMMANDERSTAYPUT__STATIC:
|
|
|
|
case BOSS4STAYPUT__STATIC:
|
2018-11-18 18:07:38 +00:00
|
|
|
pActor->stayput = pSprite->sectnum;
|
2018-04-04 20:47:55 +00:00
|
|
|
fallthrough__;
|
2020-03-29 08:41:12 +00:00
|
|
|
case GREENSLIME__STATIC:
|
|
|
|
if (pSprite->picnum == GREENSLIME)
|
|
|
|
pSprite->extra = 1;
|
|
|
|
fallthrough__;
|
|
|
|
case BOSS5__STATIC:
|
|
|
|
case FIREFLY__STATIC:
|
|
|
|
if (!WORLDTOUR && (pSprite->picnum == BOSS5 || pSprite->picnum == FIREFLY))
|
|
|
|
break;
|
|
|
|
fallthrough__;
|
2018-04-04 20:47:55 +00:00
|
|
|
case BOSS1__STATIC:
|
|
|
|
case BOSS2__STATIC:
|
|
|
|
case BOSS3__STATIC:
|
|
|
|
case BOSS4__STATIC:
|
|
|
|
case ROTATEGUN__STATIC:
|
|
|
|
case DRONE__STATIC:
|
|
|
|
case LIZTROOPONTOILET__STATIC:
|
|
|
|
case LIZTROOPJUSTSIT__STATIC:
|
|
|
|
case LIZTROOPSHOOT__STATIC:
|
|
|
|
case LIZTROOPJETPACK__STATIC:
|
|
|
|
case LIZTROOPDUCKING__STATIC:
|
|
|
|
case LIZTROOPRUNNING__STATIC:
|
|
|
|
case LIZTROOP__STATIC:
|
|
|
|
case OCTABRAIN__STATIC:
|
|
|
|
case COMMANDER__STATIC:
|
|
|
|
case PIGCOP__STATIC:
|
|
|
|
case LIZMAN__STATIC:
|
|
|
|
case LIZMANSPITTING__STATIC:
|
|
|
|
case LIZMANFEEDING__STATIC:
|
|
|
|
case LIZMANJUMP__STATIC:
|
|
|
|
case ORGANTIC__STATIC:
|
|
|
|
case RAT__STATIC:
|
|
|
|
case SHARK__STATIC:
|
|
|
|
|
|
|
|
if (pSprite->pal == 0)
|
|
|
|
{
|
|
|
|
switch (DYNAMICTILEMAP(pSprite->picnum))
|
|
|
|
{
|
|
|
|
case LIZTROOPONTOILET__STATIC:
|
|
|
|
case LIZTROOPSHOOT__STATIC:
|
|
|
|
case LIZTROOPJETPACK__STATIC:
|
|
|
|
case LIZTROOPDUCKING__STATIC:
|
|
|
|
case LIZTROOPRUNNING__STATIC:
|
|
|
|
case LIZTROOPSTAYPUT__STATIC:
|
|
|
|
case LIZTROOPJUSTSIT__STATIC:
|
|
|
|
case LIZTROOP__STATIC: pSprite->pal = 22; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!PLUTOPAK)
|
|
|
|
pSprite->extra <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pSprite->picnum == BOSS4STAYPUT || pSprite->picnum == BOSS1 || pSprite->picnum == BOSS2 ||
|
2020-03-29 08:41:12 +00:00
|
|
|
pSprite->picnum == BOSS1STAYPUT || pSprite->picnum == BOSS3 || pSprite->picnum == BOSS4 ||
|
|
|
|
(WORLDTOUR && (pSprite->picnum == BOSS2STAYPUT || pSprite->picnum == BOSS3STAYPUT ||
|
|
|
|
pSprite->picnum == BOSS5STAYPUT || pSprite->picnum == BOSS5)))
|
2018-04-04 20:47:55 +00:00
|
|
|
{
|
|
|
|
if (spriteNum >= 0 && sprite[spriteNum].picnum == RESPAWN)
|
|
|
|
pSprite->pal = sprite[spriteNum].pal;
|
|
|
|
|
2020-03-29 08:41:12 +00:00
|
|
|
if (pSprite->pal && (!WORLDTOUR || pSprite->pal != 22))
|
2018-04-04 20:47:55 +00:00
|
|
|
{
|
|
|
|
pSprite->clipdist = 80;
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 40;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 80;
|
|
|
|
pSprite->clipdist = 164;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pSprite->picnum != SHARK)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 40;
|
|
|
|
pSprite->clipdist = 80;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 60;
|
|
|
|
pSprite->clipdist = 40;
|
|
|
|
}
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-04-04 20:47:55 +00:00
|
|
|
// If spawned from parent sprite (as opposed to 'from premap'),
|
|
|
|
// ignore skill.
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->lotag = 0;
|
|
|
|
|
|
|
|
if ((pSprite->lotag > ud.player_skill) || ud.monsters_off == 1)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat=pSprite->yrepeat=0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
A_Fall(newSprite);
|
|
|
|
|
|
|
|
if (pSprite->picnum == RAT)
|
|
|
|
{
|
|
|
|
pSprite->ang = krand()&2047;
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 48;
|
|
|
|
pSprite->cstat = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
|
|
|
|
if (pSprite->picnum != SHARK)
|
|
|
|
g_player[myconnectindex].ps->max_actors_killed++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pSprite->picnum == ORGANTIC) pSprite->cstat |= 128;
|
|
|
|
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
pActor->timetosleep = 0;
|
|
|
|
A_PlayAlertSound(newSprite);
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
|
|
|
}
|
|
|
|
else changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pSprite->picnum == ROTATEGUN)
|
|
|
|
pSprite->zvel = 0;
|
|
|
|
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case REACTOR2__STATIC:
|
|
|
|
case REACTOR__STATIC:
|
|
|
|
pSprite->extra = g_impactDamage;
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal != 0)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pSprite->pal = 0;
|
|
|
|
pSprite->shade = -17;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case HEAVYHBOMB__STATIC:
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->owner = spriteNum;
|
|
|
|
else pSprite->owner = newSprite;
|
|
|
|
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 9;
|
|
|
|
pSprite->yvel = 4;
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
|
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal != 0)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
pSprite->pal = 0;
|
|
|
|
pSprite->shade = -17;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case RECON__STATIC:
|
|
|
|
if (pSprite->lotag > ud.player_skill)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
goto SPAWN_END;
|
|
|
|
}
|
|
|
|
g_player[myconnectindex].ps->max_actors_killed++;
|
|
|
|
pActor->t_data[5] = 0;
|
|
|
|
if (ud.monsters_off == 1)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
pSprite->extra = 130;
|
|
|
|
pSprite->cstat |= 256; // Make it hitable
|
|
|
|
|
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal != 0)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
pSprite->pal = 0;
|
|
|
|
pSprite->shade = -17;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
2020-03-29 08:41:12 +00:00
|
|
|
case FLAMETHROWERSPRITE__STATIC:
|
|
|
|
case FLAMETHROWERAMMO__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
fallthrough__;
|
|
|
|
|
2018-04-04 20:47:55 +00:00
|
|
|
case ATOMICHEALTH__STATIC:
|
|
|
|
case STEROIDS__STATIC:
|
|
|
|
case HEATSENSOR__STATIC:
|
|
|
|
case SHIELD__STATIC:
|
|
|
|
case AIRTANK__STATIC:
|
|
|
|
case TRIPBOMBSPRITE__STATIC:
|
|
|
|
case JETPACK__STATIC:
|
|
|
|
case HOLODUKE__STATIC:
|
|
|
|
|
|
|
|
case FIRSTGUNSPRITE__STATIC:
|
|
|
|
case CHAINGUNSPRITE__STATIC:
|
|
|
|
case SHOTGUNSPRITE__STATIC:
|
|
|
|
case RPGSPRITE__STATIC:
|
|
|
|
case SHRINKERSPRITE__STATIC:
|
|
|
|
case FREEZESPRITE__STATIC:
|
|
|
|
case DEVISTATORSPRITE__STATIC:
|
|
|
|
|
|
|
|
case SHOTGUNAMMO__STATIC:
|
|
|
|
case FREEZEAMMO__STATIC:
|
|
|
|
case HBOMBAMMO__STATIC:
|
|
|
|
case CRYSTALAMMO__STATIC:
|
|
|
|
case GROWAMMO__STATIC:
|
|
|
|
case BATTERYAMMO__STATIC:
|
|
|
|
case DEVISTATORAMMO__STATIC:
|
|
|
|
case RPGAMMO__STATIC:
|
|
|
|
case BOOTS__STATIC:
|
|
|
|
case AMMO__STATIC:
|
|
|
|
case AMMOLOTS__STATIC:
|
|
|
|
case COLA__STATIC:
|
|
|
|
case FIRSTAID__STATIC:
|
|
|
|
case SIXPAK__STATIC:
|
|
|
|
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
pSprite->lotag = 0;
|
|
|
|
pSprite->z -= ZOFFSET5;
|
|
|
|
pSprite->zvel = -1024;
|
|
|
|
A_SetSprite(newSprite, CLIPMASK0);
|
|
|
|
pSprite->cstat = krand()&4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->owner = newSprite;
|
|
|
|
pSprite->cstat = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((!g_netServer && ud.multimode < 2) && pSprite->pal != 0) || (pSprite->lotag > ud.player_skill))
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pSprite->pal = 0;
|
|
|
|
|
|
|
|
if (pSprite->picnum == ATOMICHEALTH)
|
|
|
|
pSprite->cstat |= 128;
|
|
|
|
|
|
|
|
fallthrough__;
|
|
|
|
case ACCESSCARD__STATIC:
|
|
|
|
if ((g_netServer || ud.multimode > 1) && !GTFLAGS(GAMETYPE_ACCESSCARDSPRITES) && pSprite->picnum == ACCESSCARD)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pSprite->picnum == AMMO)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 16;
|
|
|
|
else pSprite->xrepeat = pSprite->yrepeat = 32;
|
|
|
|
}
|
|
|
|
|
|
|
|
pSprite->shade = -17;
|
|
|
|
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
|
|
|
A_Fall(newSprite);
|
|
|
|
}
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case WATERFOUNTAIN__STATIC:
|
|
|
|
SLT(newSprite) = 1;
|
|
|
|
fallthrough__;
|
|
|
|
case TREE1__STATIC:
|
|
|
|
case TREE2__STATIC:
|
|
|
|
case TIRE__STATIC:
|
|
|
|
case CONE__STATIC:
|
|
|
|
case BOX__STATIC:
|
|
|
|
pSprite->cstat = 257; // Make it hitable
|
|
|
|
sprite[newSprite].extra = 1;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case FLOORFLAME__STATIC:
|
|
|
|
pSprite->shade = -127;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case BOUNCEMINE__STATIC:
|
|
|
|
pSprite->owner = newSprite;
|
|
|
|
pSprite->cstat |= 1+256; //Make it hitable
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 24;
|
|
|
|
pSprite->shade = -127;
|
|
|
|
pSprite->extra = g_impactDamage<<2;
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case STEAM__STATIC:
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
|
|
|
pSprite->cstat = 16+128+2;
|
|
|
|
pSprite->xrepeat=pSprite->yrepeat=1;
|
|
|
|
pSprite->xvel = -8;
|
|
|
|
A_SetSprite(newSprite, CLIPMASK0);
|
|
|
|
}
|
|
|
|
fallthrough__;
|
|
|
|
case CEILINGSTEAM__STATIC:
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case TOILET__STATIC:
|
|
|
|
case STALL__STATIC:
|
|
|
|
pSprite->lotag = 1;
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
pSprite->clipdist = 8;
|
|
|
|
pSprite->owner = newSprite;
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case CANWITHSOMETHING__STATIC:
|
|
|
|
case CANWITHSOMETHING2__STATIC:
|
|
|
|
case CANWITHSOMETHING3__STATIC:
|
|
|
|
case CANWITHSOMETHING4__STATIC:
|
|
|
|
case RUBBERCAN__STATIC:
|
|
|
|
pSprite->extra = 0;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2018-04-04 20:47:55 +00:00
|
|
|
case EXPLODINGBARREL__STATIC:
|
|
|
|
case HORSEONSIDE__STATIC:
|
|
|
|
case FIREBARREL__STATIC:
|
|
|
|
case NUKEBARREL__STATIC:
|
|
|
|
case FIREVASE__STATIC:
|
|
|
|
case NUKEBARRELDENTED__STATIC:
|
|
|
|
case NUKEBARRELLEAKED__STATIC:
|
|
|
|
case WOODENHORSE__STATIC:
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 32;
|
|
|
|
pSprite->clipdist = 72;
|
|
|
|
A_Fall(newSprite);
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2018-04-04 20:47:55 +00:00
|
|
|
pSprite->owner = spriteNum;
|
|
|
|
else pSprite->owner = newSprite;
|
|
|
|
fallthrough__;
|
|
|
|
case EGG__STATIC:
|
|
|
|
if (ud.monsters_off == 1 && pSprite->picnum == EGG)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-04-04 20:47:55 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2018-04-04 20:47:55 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pSprite->picnum == EGG)
|
|
|
|
pSprite->clipdist = 24;
|
|
|
|
pSprite->cstat = 257|(krand()&4);
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
|
|
|
}
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2012-03-04 20:13:47 +00:00
|
|
|
|
2018-04-04 20:47:55 +00:00
|
|
|
case TOILETWATER__STATIC:
|
|
|
|
pSprite->shade = -16;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case LASERLINE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->yrepeat = 6;
|
|
|
|
pSprite->xrepeat = 32;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_tripbombLaserMode == 1)
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 16 + 2;
|
2016-02-13 21:05:57 +00:00
|
|
|
else if (g_tripbombLaserMode == 0 || g_tripbombLaserMode == 2)
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 16;
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = 0;
|
|
|
|
pSprite->yrepeat = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2012-03-29 21:16:20 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0) pSprite->ang = actor[spriteNum].t_data[5]+512;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
case FORCESPHERE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum == -1)
|
2012-03-29 21:16:20 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 32768;
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2012-03-29 21:16:20 +00:00
|
|
|
}
|
|
|
|
else
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 1;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
case BLOOD__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 16;
|
|
|
|
pSprite->z -= (26<<8);
|
|
|
|
if (spriteNum >= 0 && sprite[spriteNum].pal == 6)
|
|
|
|
pSprite->pal = 6;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
|
|
|
|
2020-03-29 08:41:12 +00:00
|
|
|
case LAVAPOOL__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case BLOODPOOL__STATIC:
|
|
|
|
case PUKE__STATIC:
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int16_t pukeSect = pSprite->sectnum;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x + 108, pSprite->y + 108, &pukeSect);
|
|
|
|
if (pukeSect >= 0 && sector[pukeSect].floorz == sector[pSprite->sectnum].floorz)
|
2014-03-05 21:12:59 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x - 108, pSprite->y - 108, &pukeSect);
|
|
|
|
if (pukeSect >= 0 && sector[pukeSect].floorz == sector[pSprite->sectnum].floorz)
|
2014-03-05 21:12:59 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x + 108, pSprite->y - 108, &pukeSect);
|
|
|
|
if (pukeSect >= 0 && sector[pukeSect].floorz == sector[pSprite->sectnum].floorz)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x - 108, pSprite->y + 108, &pukeSect);
|
|
|
|
if (pukeSect >= 0 && sector[pukeSect].floorz != sector[pSprite->sectnum].floorz)
|
2017-11-22 05:23:28 +00:00
|
|
|
goto zero_puke;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2017-11-22 05:23:28 +00:00
|
|
|
else goto zero_puke;
|
2014-03-05 21:12:59 +00:00
|
|
|
}
|
2017-11-22 05:23:28 +00:00
|
|
|
else goto zero_puke;
|
2014-03-05 21:12:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-22 05:23:28 +00:00
|
|
|
zero_puke:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2014-03-05 21:12:59 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2017-11-22 05:23:33 +00:00
|
|
|
if (sector[sectNum].lotag == ST_1_ABOVE_WATER)
|
2013-01-20 21:17:31 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2013-01-20 21:17:31 +00:00
|
|
|
}
|
2013-07-18 18:08:11 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0 && pSprite->picnum != PUKE)
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].pal == 1)
|
|
|
|
pSprite->pal = 1;
|
|
|
|
else if (sprite[spriteNum].pal != 6 && sprite[spriteNum].picnum != NUKEBARREL && sprite[spriteNum].picnum != TIRE)
|
|
|
|
pSprite->pal = (sprite[spriteNum].picnum == FECES) ? 7 : 2; // Brown or red
|
|
|
|
else
|
|
|
|
pSprite->pal = 0; // green
|
|
|
|
|
|
|
|
if (sprite[spriteNum].picnum == TIRE)
|
|
|
|
pSprite->shade = 127;
|
|
|
|
}
|
|
|
|
pSprite->cstat |= 32;
|
2020-03-29 08:41:12 +00:00
|
|
|
if (pSprite->picnum == LAVAPOOL)
|
|
|
|
pSprite->z = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y) - 200;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
case FECES__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 1;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2013-07-18 18:08:11 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case BLOODSPLAT1__STATIC:
|
|
|
|
case BLOODSPLAT2__STATIC:
|
|
|
|
case BLOODSPLAT3__STATIC:
|
|
|
|
case BLOODSPLAT4__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= 16;
|
|
|
|
pSprite->xrepeat = 7 + (krand() & 7);
|
|
|
|
pSprite->yrepeat = 7 + (krand() & 7);
|
|
|
|
pSprite->z += (tilesiz[pSprite->picnum].y * pSprite->yrepeat) >> 2;
|
|
|
|
|
|
|
|
if (spriteNum >= 0 && sprite[spriteNum].pal == 6)
|
|
|
|
pSprite->pal = 6;
|
|
|
|
|
|
|
|
A_AddToDeleteQueue(newSprite);
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2013-07-18 18:08:11 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case TRIPBOMB__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->lotag > ud.player_skill)
|
2014-03-29 21:48:40 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2014-03-29 21:48:40 +00:00
|
|
|
}
|
2013-07-18 18:08:11 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = 4;
|
|
|
|
pSprite->yrepeat = 5;
|
|
|
|
pSprite->hitag = newSprite;
|
|
|
|
pSprite->owner = pSprite->hitag;
|
|
|
|
pSprite->xvel = 16;
|
|
|
|
|
2018-04-04 20:47:55 +00:00
|
|
|
A_SetSprite(newSprite, CLIPMASK0);
|
2010-10-17 14:49:39 +00:00
|
|
|
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor->t_data[0] = 17;
|
|
|
|
pActor->t_data[2] = 0;
|
|
|
|
pActor->t_data[5] = pSprite->ang;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SPACEMARINE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->extra = 20;
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
case DOORSHOCK__STATIC:
|
|
|
|
pSprite->cstat |= 1+256;
|
|
|
|
pSprite->shade = -12;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case HYDRENT__STATIC:
|
|
|
|
case PANNEL1__STATIC:
|
|
|
|
case PANNEL2__STATIC:
|
|
|
|
case SATELITE__STATIC:
|
|
|
|
case FUELPOD__STATIC:
|
|
|
|
case SOLARPANNEL__STATIC:
|
|
|
|
case ANTENNA__STATIC:
|
|
|
|
case CHAIR1__STATIC:
|
|
|
|
case CHAIR2__STATIC:
|
|
|
|
case CHAIR3__STATIC:
|
|
|
|
case BOTTLE1__STATIC:
|
|
|
|
case BOTTLE2__STATIC:
|
|
|
|
case BOTTLE3__STATIC:
|
|
|
|
case BOTTLE4__STATIC:
|
|
|
|
case BOTTLE5__STATIC:
|
|
|
|
case BOTTLE6__STATIC:
|
|
|
|
case BOTTLE7__STATIC:
|
|
|
|
case BOTTLE8__STATIC:
|
|
|
|
case BOTTLE10__STATIC:
|
|
|
|
case BOTTLE11__STATIC:
|
|
|
|
case BOTTLE12__STATIC:
|
|
|
|
case BOTTLE13__STATIC:
|
|
|
|
case BOTTLE14__STATIC:
|
|
|
|
case BOTTLE15__STATIC:
|
|
|
|
case BOTTLE16__STATIC:
|
|
|
|
case BOTTLE17__STATIC:
|
|
|
|
case BOTTLE18__STATIC:
|
|
|
|
case BOTTLE19__STATIC:
|
|
|
|
case OCEANSPRITE1__STATIC:
|
|
|
|
case OCEANSPRITE2__STATIC:
|
|
|
|
case OCEANSPRITE3__STATIC:
|
|
|
|
case OCEANSPRITE5__STATIC:
|
|
|
|
case MONK__STATIC:
|
|
|
|
case INDY__STATIC:
|
|
|
|
case LUKE__STATIC:
|
|
|
|
case JURYGUY__STATIC:
|
|
|
|
case SCALE__STATIC:
|
|
|
|
case VACUUM__STATIC:
|
|
|
|
case CACTUS__STATIC:
|
|
|
|
case CACTUSBROKE__STATIC:
|
|
|
|
case HANGLIGHT__STATIC:
|
|
|
|
case FETUS__STATIC:
|
|
|
|
case FETUSBROKE__STATIC:
|
|
|
|
case CAMERALIGHT__STATIC:
|
|
|
|
case MOVIECAMERA__STATIC:
|
|
|
|
case IVUNIT__STATIC:
|
|
|
|
case POT1__STATIC:
|
|
|
|
case POT2__STATIC:
|
|
|
|
case POT3__STATIC:
|
|
|
|
case TRIPODCAMERA__STATIC:
|
|
|
|
case SUSHIPLATE1__STATIC:
|
|
|
|
case SUSHIPLATE2__STATIC:
|
|
|
|
case SUSHIPLATE3__STATIC:
|
|
|
|
case SUSHIPLATE4__STATIC:
|
|
|
|
case SUSHIPLATE5__STATIC:
|
|
|
|
case WAITTOBESEATED__STATIC:
|
|
|
|
case VASE__STATIC:
|
|
|
|
case PIPE1__STATIC:
|
|
|
|
case PIPE2__STATIC:
|
|
|
|
case PIPE3__STATIC:
|
|
|
|
case PIPE4__STATIC:
|
|
|
|
case PIPE5__STATIC:
|
|
|
|
case PIPE6__STATIC:
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
|
|
|
case GRATE1__STATIC:
|
|
|
|
case FANSPRITE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->clipdist = 32;
|
|
|
|
pSprite->cstat |= 257;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case OCEANSPRITE4__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_DEFAULT);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case FRAMEEFFECT1_13__STATIC:
|
2020-03-29 08:41:03 +00:00
|
|
|
if (PLUTOPAK)
|
|
|
|
break;
|
2018-04-04 20:47:55 +00:00
|
|
|
fallthrough__;
|
|
|
|
case FRAMEEFFECT1__STATIC:
|
|
|
|
if (spriteNum >= 0)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-04-04 20:47:55 +00:00
|
|
|
pSprite->xrepeat = sprite[spriteNum].xrepeat;
|
|
|
|
pSprite->yrepeat = sprite[spriteNum].yrepeat;
|
|
|
|
T2(newSprite) = sprite[spriteNum].picnum;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2018-04-04 20:47:55 +00:00
|
|
|
else pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case FOOTPRINTS__STATIC:
|
|
|
|
case FOOTPRINTS2__STATIC:
|
|
|
|
case FOOTPRINTS3__STATIC:
|
|
|
|
case FOOTPRINTS4__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int16_t footSect = pSprite->sectnum;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x + 84, pSprite->y + 84, &footSect);
|
|
|
|
if (footSect >= 0 && sector[footSect].floorz == sector[pSprite->sectnum].floorz)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x - 84, pSprite->y - 84, &footSect);
|
|
|
|
if (footSect >= 0 && sector[footSect].floorz == sector[pSprite->sectnum].floorz)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x + 84, pSprite->y - 84, &footSect);
|
|
|
|
if (footSect >= 0 && sector[footSect].floorz == sector[pSprite->sectnum].floorz)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
updatesector(pSprite->x - 84, pSprite->y + 84, &footSect);
|
|
|
|
if (footSect >= 0 && sector[footSect].floorz != sector[pSprite->sectnum].floorz)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-22 05:23:28 +00:00
|
|
|
else goto zero_footprint;
|
2018-04-04 20:47:55 +00:00
|
|
|
}
|
|
|
|
else goto zero_footprint;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-04 20:47:55 +00:00
|
|
|
zero_footprint:
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2013-05-30 18:10:59 +00:00
|
|
|
|
2018-04-04 20:47:55 +00:00
|
|
|
pSprite->cstat = 32 + ((g_player[P_Get(spriteNum)].ps->footprintcount & 1) << 2);
|
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
pSprite->z = sector[sectNum].floorz;
|
|
|
|
|
|
|
|
if (sector[sectNum].lotag != ST_1_ABOVE_WATER && sector[sectNum].lotag != ST_2_UNDERWATER)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 32;
|
|
|
|
|
|
|
|
A_AddToDeleteQueue(newSprite);
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2018-04-04 20:47:55 +00:00
|
|
|
|
|
|
|
case VIEWSCREEN__STATIC:
|
|
|
|
case VIEWSCREEN2__STATIC:
|
|
|
|
pSprite->owner = newSprite;
|
|
|
|
pSprite->lotag = pSprite->extra = 1;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case RESPAWN__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->extra = 66-13;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case MUSICANDSFX__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal == 1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 32768;
|
|
|
|
changespritestat(newSprite, STAT_FX);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case EXPLOSION2__STATIC:
|
2017-06-23 03:59:39 +00:00
|
|
|
#ifdef POLYMER
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->yrepeat > 32)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
G_AddGameLight(0, newSprite, ((pSprite->yrepeat*tilesiz[pSprite->picnum].y)<<1), 32768, 255+(95<<8),PR_LIGHT_PRIO_MAX_GAME);
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor->lightcount = 2;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2017-06-23 03:59:39 +00:00
|
|
|
#endif
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2020-03-29 08:41:12 +00:00
|
|
|
case ONFIRE__STATIC:
|
|
|
|
if (!WORLDTOUR && pSprite->picnum == ONFIRE)
|
|
|
|
break;
|
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case EXPLOSION2BOT__STATIC:
|
|
|
|
case BURNING__STATIC:
|
|
|
|
case BURNING2__STATIC:
|
|
|
|
case SMALLSMOKE__STATIC:
|
|
|
|
case SHRINKEREXPLOSION__STATIC:
|
|
|
|
case COOLEXPLOSION1__STATIC:
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
|
|
|
pSprite->shade = -64;
|
|
|
|
pSprite->cstat = 128|(krand()&4);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2011-06-29 19:57:05 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->picnum == EXPLOSION2 || pSprite->picnum == EXPLOSION2BOT)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 48;
|
|
|
|
pSprite->shade = -127;
|
|
|
|
pSprite->cstat |= 128;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (pSprite->picnum == SHRINKEREXPLOSION)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 32;
|
2020-03-29 08:41:12 +00:00
|
|
|
else if (pSprite->picnum == SMALLSMOKE || pSprite->picnum == ONFIRE)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
// 64 "money"
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 24;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (pSprite->picnum == BURNING || pSprite->picnum == BURNING2)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 4;
|
2011-06-29 19:57:05 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= 8192;
|
2011-06-29 19:57:05 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const floorZ = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
|
|
|
|
|
|
|
if (pSprite->z > floorZ-ZOFFSET4)
|
|
|
|
pSprite->z = floorZ-ZOFFSET4;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2011-06-29 19:57:05 +00:00
|
|
|
|
2020-03-29 08:41:12 +00:00
|
|
|
if (pSprite->picnum == ONFIRE)
|
|
|
|
{
|
|
|
|
pActor->bpos.x = pSprite->x += (krand()%256)-128;
|
|
|
|
pActor->bpos.y = pSprite->y += (krand()%256)-128;
|
|
|
|
pActor->bpos.z = pSprite->z -= krand()%10240;
|
|
|
|
pSprite->cstat |= 128;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2011-06-29 19:57:05 +00:00
|
|
|
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case PLAYERONWATER__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = sprite[spriteNum].xrepeat;
|
|
|
|
pSprite->yrepeat = sprite[spriteNum].yrepeat;
|
|
|
|
pSprite->zvel = 128;
|
|
|
|
if (sector[pSprite->sectnum].lotag != ST_2_UNDERWATER)
|
|
|
|
pSprite->cstat |= 32768;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_DUMMYPLAYER);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case APLAYER__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = 0;
|
|
|
|
pSprite->yrepeat = 0;
|
|
|
|
pSprite->cstat = 32768;
|
|
|
|
|
|
|
|
changespritestat(newSprite, ((!g_netServer && ud.multimode < 2)
|
2016-08-27 01:42:01 +00:00
|
|
|
|| ((g_gametypeFlags[ud.coop] & GAMETYPE_COOPSPAWN) / GAMETYPE_COOPSPAWN) != pSprite->lotag)
|
2016-08-27 01:40:56 +00:00
|
|
|
? STAT_MISC
|
|
|
|
: STAT_PLAYER);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case TOUCHPLATE__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
T3(newSprite) = sector[sectNum].floorz;
|
|
|
|
|
|
|
|
if (sector[sectNum].lotag != ST_1_ABOVE_WATER && sector[sectNum].lotag != ST_2_UNDERWATER)
|
|
|
|
sector[sectNum].floorz = pSprite->z;
|
|
|
|
|
|
|
|
if (pSprite->pal && (g_netServer || ud.multimode > 1))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat=pSprite->yrepeat=0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2018-04-04 20:47:48 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case WATERBUBBLEMAKER__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(pSprite->hitag && pSprite->picnum == WATERBUBBLEMAKER))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
// JBF 20030913: Pisses off X_Move(), eg. in bobsp2
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "WARNING: WATERBUBBLEMAKER %d @ %d,%d with hitag!=0. Applying fixup.\n",
|
2016-08-27 01:40:56 +00:00
|
|
|
newSprite,TrackerCast(pSprite->x),TrackerCast(pSprite->y));
|
|
|
|
pSprite->hitag = 0;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= 32768;
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case MASTERSWITCH__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->picnum == MASTERSWITCH)
|
|
|
|
pSprite->cstat |= 32768;
|
|
|
|
pSprite->yvel = 0;
|
2018-04-04 20:47:55 +00:00
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
case LOCATORS__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= 32768;
|
|
|
|
changespritestat(newSprite, STAT_LOCATOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case ACTIVATORLOCKED__STATIC:
|
|
|
|
case ACTIVATOR__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 32768;
|
|
|
|
if (pSprite->picnum == ACTIVATORLOCKED)
|
|
|
|
sector[pSprite->sectnum].lotag |= 16384;
|
|
|
|
changespritestat(newSprite, STAT_ACTIVATOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case OOZ__STATIC:
|
|
|
|
case OOZ2__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
|
|
|
pSprite->shade = -12;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sprite[spriteNum].picnum == NUKEBARREL)
|
|
|
|
pSprite->pal = 8;
|
|
|
|
A_AddToDeleteQueue(newSprite);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
A_GetZLimits(newSprite);
|
2010-05-16 22:53:08 +00:00
|
|
|
|
2017-11-22 05:23:33 +00:00
|
|
|
int const oozSize = (pActor->floorz-pActor->ceilingz)>>9;
|
2009-07-04 09:28:21 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->yrepeat = oozSize;
|
2017-11-22 05:23:33 +00:00
|
|
|
pSprite->xrepeat = 25 - (oozSize >> 1);
|
|
|
|
pSprite->cstat |= (krand() & 4);
|
2009-07-04 09:28:21 +00:00
|
|
|
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SECTOREFFECTOR__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= 32768;
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (pSprite->lotag)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
case 40:
|
|
|
|
case 41:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 32;
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 64;
|
|
|
|
changespritestat(newSprite, STAT_EFFECTOR);
|
|
|
|
for (spriteNum=0; spriteNum < MAXSPRITES; spriteNum++)
|
|
|
|
if (sprite[spriteNum].picnum == SECTOREFFECTOR && (sprite[spriteNum].lotag == 40 || sprite[spriteNum].lotag == 41) &&
|
|
|
|
sprite[spriteNum].hitag == pSprite->hitag && newSprite != spriteNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
// Printf("found ror match\n");
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->yvel = spriteNum;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
goto SPAWN_END;
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
2016-02-13 21:05:57 +00:00
|
|
|
case 46:
|
2016-08-27 01:40:56 +00:00
|
|
|
ror_protectedsectors[pSprite->sectnum] = 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
/* XXX: fall-through intended? */
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
case SE_49_POINT_LIGHT:
|
|
|
|
case SE_50_SPOT_LIGHT:
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t j, nextj;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
for (TRAVERSE_SPRITE_SECT(headspritesect[pSprite->sectnum], j, nextj))
|
2016-02-13 21:05:57 +00:00
|
|
|
if (sprite[j].picnum == ACTIVATOR || sprite[j].picnum == ACTIVATORLOCKED)
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor->flags |= SFLAG_USEACTIVATOR;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, pSprite->lotag==46 ? STAT_EFFECTOR : STAT_LIGHT);
|
2016-02-13 21:05:57 +00:00
|
|
|
goto SPAWN_END;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->yvel = sector[sectNum].extra;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (pSprite->lotag)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_28_LIGHTNING:
|
2016-08-27 01:40:56 +00:00
|
|
|
T6(newSprite) = 65;// Delay for lightning
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SE_7_TELEPORT: // Transporters!!!!
|
|
|
|
case SE_23_ONE_WAY_TELEPORT:// XPTR END
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->lotag != SE_23_ONE_WAY_TELEPORT)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
for (spriteNum=0; spriteNum<MAXSPRITES; spriteNum++)
|
|
|
|
if (sprite[spriteNum].statnum < MAXSTATUS && sprite[spriteNum].picnum == SECTOREFFECTOR &&
|
|
|
|
(sprite[spriteNum].lotag == SE_7_TELEPORT || sprite[spriteNum].lotag == SE_23_ONE_WAY_TELEPORT) && newSprite != spriteNum && sprite[spriteNum].hitag == SHT(newSprite))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
OW(newSprite) = spriteNum;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else OW(newSprite) = newSprite;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T5(newSprite) = (sector[sectNum].floorz == SZ(newSprite)); // ONFLOORZ
|
|
|
|
pSprite->cstat = 0;
|
|
|
|
changespritestat(newSprite, STAT_TRANSPORT);
|
2016-02-13 21:05:57 +00:00
|
|
|
goto SPAWN_END;
|
|
|
|
case SE_1_PIVOT:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->owner = -1;
|
|
|
|
T1(newSprite) = 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SE_18_INCREMENTAL_SECTOR_RISE_FALL:
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->ang == 512)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = sector[sectNum].ceilingz;
|
|
|
|
if (pSprite->pal)
|
|
|
|
sector[sectNum].ceilingz = pSprite->z;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = sector[sectNum].floorz;
|
|
|
|
if (pSprite->pal)
|
|
|
|
sector[sectNum].floorz = pSprite->z;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->hitag <<= 2;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SE_19_EXPLOSION_LOWERS_CEILING:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->owner = -1;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SE_25_PISTON: // Pistons
|
2016-08-27 01:40:56 +00:00
|
|
|
T4(newSprite) = sector[sectNum].ceilingz;
|
|
|
|
T5(newSprite) = 1;
|
|
|
|
sector[sectNum].ceilingz = pSprite->z;
|
|
|
|
G_SetInterpolation(§or[sectNum].ceilingz);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SE_35:
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingz = pSprite->z;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SE_27_DEMO_CAM:
|
2019-06-25 18:35:24 +00:00
|
|
|
T1(newSprite) = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.recstat == 1)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat=pSprite->yrepeat=64;
|
|
|
|
pSprite->cstat &= 32768;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SE_12_LIGHT_SWITCH:
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = sector[sectNum].floorshade;
|
|
|
|
T3(newSprite) = sector[sectNum].ceilingshade;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SE_13_EXPLOSIVE:
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T1(newSprite) = sector[sectNum].ceilingz;
|
|
|
|
T2(newSprite) = sector[sectNum].floorz;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (klabs(T1(newSprite)-pSprite->z) < klabs(T2(newSprite)-pSprite->z))
|
|
|
|
pSprite->owner = 1;
|
|
|
|
else pSprite->owner = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->ang == 512)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->owner)
|
|
|
|
sector[sectNum].ceilingz = pSprite->z;
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].floorz = pSprite->z;
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int16_t cf=!pSprite->owner, bn=yax_getbunch(sectNum, cf);
|
|
|
|
int32_t jj, daz=SECTORFLD(sectNum,z, cf);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (bn >= 0)
|
|
|
|
{
|
|
|
|
for (SECTORS_OF_BUNCH(bn, cf, jj))
|
|
|
|
{
|
|
|
|
SECTORFLD(jj,z, cf) = daz;
|
|
|
|
SECTORFLD(jj,stat, cf) &= ~256;
|
|
|
|
SECTORFLD(jj,stat, cf) |= 128 + 512+2048;
|
|
|
|
}
|
|
|
|
for (SECTORS_OF_BUNCH(bn, !cf, jj))
|
|
|
|
{
|
|
|
|
SECTORFLD(jj,z, !cf) = daz;
|
|
|
|
SECTORFLD(jj,stat, !cf) &= ~256;
|
|
|
|
SECTORFLD(jj,stat, !cf) |= 128 + 512+2048;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingz = sector[sectNum].floorz = pSprite->z;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[sectNum].ceilingstat&1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingstat ^= 1;
|
|
|
|
T4(newSprite) = 1;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!pSprite->owner && pSprite->ang==512)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingstat ^= 1;
|
|
|
|
T4(newSprite) = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingshade =
|
|
|
|
sector[sectNum].floorshade;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->ang==512)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startwall = sector[sectNum].wallptr;
|
|
|
|
int const endwall = startwall + sector[sectNum].wallnum;
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j = startwall; j < endwall; j++)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const nextSect = wall[j].nextsector;
|
|
|
|
|
|
|
|
if (nextSect >= 0)
|
|
|
|
{
|
|
|
|
if (!(sector[nextSect].ceilingstat & 1))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingpicnum = sector[nextSect].ceilingpicnum;
|
|
|
|
sector[sectNum].ceilingshade = sector[nextSect].ceilingshade;
|
|
|
|
break; // Leave earily
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SE_17_WARP_ELEVATOR:
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
|
|
|
T3(newSprite) = sector[sectNum].floorz; // Stopping loc
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int nextSectNum = nextsectorneighborz(sectNum, sector[sectNum].floorz, -1, -1);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (EDUKE32_PREDICT_TRUE(nextSectNum >= 0))
|
|
|
|
T4(newSprite) = sector[nextSectNum].ceilingz;
|
2006-11-15 01:16:55 +00:00
|
|
|
else
|
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
// use elevator sector's ceiling as heuristic
|
2016-08-27 01:40:56 +00:00
|
|
|
T4(newSprite) = sector[sectNum].ceilingz;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "WARNING: SE17 sprite %d using own sector's ceilingz to "
|
2016-08-27 01:40:56 +00:00
|
|
|
"determine when to warp. Sector %d adjacent to a door?\n",
|
|
|
|
newSprite, sectNum);
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
nextSectNum = nextsectorneighborz(sectNum, sector[sectNum].ceilingz, 1, 1);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (EDUKE32_PREDICT_TRUE(nextSectNum >= 0))
|
|
|
|
T5(newSprite) = sector[nextSectNum].floorz;
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-01-18 04:28:55 +00:00
|
|
|
// heuristic
|
|
|
|
T5(newSprite) = sector[sectNum].floorz;
|
|
|
|
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "WARNING: SE17 sprite %d using own sector %d's floorz.\n",
|
2018-01-18 04:28:55 +00:00
|
|
|
newSprite, sectNum);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (numplayers < 2 && !g_netServer)
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
G_SetInterpolation(§or[sectNum].floorz);
|
|
|
|
G_SetInterpolation(§or[sectNum].ceilingz);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_24_CONVEYOR:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->yvel <<= 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_36_PROJ_SHOOTER:
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_20_STRETCH_BRIDGE:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int closestDist = INT32_MAX;
|
|
|
|
int closestWall = 0;
|
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall + sector[sectNum].wallnum;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t findWall=startWall; findWall<endWall; findWall++)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const x = wall[findWall].x;
|
|
|
|
int const y = wall[findWall].y;
|
|
|
|
int const d = FindDistance2D(pSprite->x - x, pSprite->y - y);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (d < closestDist)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
closestDist = d;
|
|
|
|
closestWall = findWall;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = closestWall;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
closestDist = INT32_MAX;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t findWall=startWall; findWall<endWall; findWall++)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const x = wall[findWall].x;
|
|
|
|
int const y = wall[findWall].y;
|
|
|
|
int const d = FindDistance2D(pSprite->x - x, pSprite->y - y);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (d < closestDist && findWall != T2(newSprite))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
closestDist = d;
|
|
|
|
closestWall = findWall;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T3(newSprite) = closestWall;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-05-02 23:27:30 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT:
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T4(newSprite)=sector[sectNum].floorshade;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].floorshade = pSprite->shade;
|
|
|
|
sector[sectNum].ceilingshade = pSprite->shade;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->owner = sector[sectNum].ceilingpal << 8;
|
|
|
|
pSprite->owner |= sector[sectNum].floorpal;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
//fix all the walls;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall+sector[sectNum].wallnum;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t w=startWall; w<endWall; ++w)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!(wall[w].hitag & 1))
|
|
|
|
wall[w].shade = pSprite->shade;
|
|
|
|
|
|
|
|
if ((wall[w].cstat & 2) && wall[w].nextwall >= 0)
|
|
|
|
wall[wall[w].nextwall].shade = pSprite->shade;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
2016-08-27 01:40:56 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_31_FLOOR_RISE_FALL:
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = sector[sectNum].floorz;
|
|
|
|
|
|
|
|
if (pSprite->ang != 1536)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].floorz = pSprite->z;
|
|
|
|
Yax_SetBunchZs(sectNum, YAX_FLOOR, pSprite->z);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall + sector[sectNum].wallnum;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t w = startWall; w < endWall; ++w)
|
2016-08-27 01:40:56 +00:00
|
|
|
if (wall[w].hitag == 0)
|
|
|
|
wall[w].hitag = 9999;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
G_SetInterpolation(§or[sectNum].floorz);
|
|
|
|
Yax_SetBunchInterpolation(sectNum, YAX_FLOOR);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_32_CEILING_RISE_FALL:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = sector[sectNum].ceilingz;
|
|
|
|
T3(newSprite) = pSprite->hitag;
|
|
|
|
|
|
|
|
if (pSprite->ang != 1536)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].ceilingz = pSprite->z;
|
|
|
|
Yax_SetBunchZs(sectNum, YAX_CEILING, pSprite->z);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall + sector[sectNum].wallnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t w = startWall; w < endWall; ++w)
|
2016-08-27 01:40:56 +00:00
|
|
|
if (wall[w].hitag == 0)
|
|
|
|
wall[w].hitag = 9999;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
G_SetInterpolation(§or[sectNum].ceilingz);
|
|
|
|
Yax_SetBunchInterpolation(sectNum, YAX_CEILING);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_4_RANDOM_LIGHTS: //Flashing lights
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
|
|
|
T3(newSprite) = sector[sectNum].floorshade;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall + sector[sectNum].wallnum;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->owner = sector[sectNum].ceilingpal << 8;
|
|
|
|
pSprite->owner |= sector[sectNum].floorpal;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t w = startWall; w < endWall; ++w)
|
2016-08-27 01:40:56 +00:00
|
|
|
if (wall[w].shade > T4(newSprite))
|
|
|
|
T4(newSprite) = wall[w].shade;
|
|
|
|
}
|
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_9_DOWN_OPEN_DOOR_LIGHTS:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[sectNum].lotag &&
|
|
|
|
labs(sector[sectNum].ceilingz-pSprite->z) > 1024)
|
2018-01-28 04:30:34 +00:00
|
|
|
sector[sectNum].lotag |= 32768u; //If its open
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_8_UP_OPEN_DOOR_LIGHTS:
|
|
|
|
//First, get the ceiling-floor shade
|
2016-08-27 01:40:56 +00:00
|
|
|
{
|
|
|
|
T1(newSprite) = sector[sectNum].floorshade;
|
|
|
|
T2(newSprite) = sector[sectNum].ceilingshade;
|
2009-10-01 05:05:19 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall + sector[sectNum].wallnum;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t w = startWall; w < endWall; ++w)
|
2016-08-27 01:40:56 +00:00
|
|
|
if (wall[w].shade > T3(newSprite))
|
|
|
|
T3(newSprite) = wall[w].shade;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T4(newSprite) = 1; // Take Out;
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
case SE_11_SWINGING_DOOR: // Pivitor rotater
|
|
|
|
T4(newSprite) = (pSprite->ang > 1024) ? 2 : -2;
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case SE_0_ROTATING_SECTOR:
|
2016-08-27 01:40:56 +00:00
|
|
|
case SE_2_EARTHQUAKE: // Earthquakemakers
|
|
|
|
case SE_5: // Boss Creature
|
|
|
|
case SE_6_SUBWAY: // Subway
|
|
|
|
case SE_14_SUBWAY_CAR: // Caboos
|
|
|
|
case SE_15_SLIDING_DOOR: // Subwaytype sliding door
|
|
|
|
case SE_16_REACTOR: // That rotating blocker reactor thing
|
|
|
|
case SE_26: // ESCELATOR
|
|
|
|
case SE_30_TWO_WAY_TRAIN: // No rotational subways
|
|
|
|
if (pSprite->lotag == SE_0_ROTATING_SECTOR)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[sectNum].lotag == ST_30_ROTATE_RISE_BRIDGE)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
sprite[newSprite].clipdist = (pSprite->pal) ? 1 : 0;
|
|
|
|
T4(newSprite) = sector[sectNum].floorz;
|
|
|
|
sector[sectNum].hitag = newSprite;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
for (spriteNum = MAXSPRITES-1; spriteNum>=0; spriteNum--)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sprite[spriteNum].statnum < MAXSTATUS)
|
|
|
|
if (sprite[spriteNum].picnum == SECTOREFFECTOR &&
|
|
|
|
sprite[spriteNum].lotag == SE_1_PIVOT &&
|
|
|
|
sprite[spriteNum].hitag == pSprite->hitag)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->ang == 512)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->x = sprite[spriteNum].x;
|
|
|
|
pSprite->y = sprite[spriteNum].y;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(spriteNum == -1))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "Found lonely Sector Effector (lotag 0) at (%d,%d)\n",
|
2016-08-27 01:40:56 +00:00
|
|
|
TrackerCast(pSprite->x),TrackerCast(pSprite->y));
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
2016-02-13 21:05:57 +00:00
|
|
|
goto SPAWN_END;
|
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->owner = spriteNum;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall+sector[sectNum].wallnum;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
T2(newSprite) = tempwallptr;
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t w = startWall; w < endWall; ++w)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
g_origins[tempwallptr].x = wall[w].x - pSprite->x;
|
|
|
|
g_origins[tempwallptr].y = wall[w].y - pSprite->y;
|
|
|
|
|
|
|
|
tempwallptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE(tempwallptr >= MAXANIMPOINTS))
|
|
|
|
{
|
|
|
|
Bsprintf(tempbuf, "Too many moving sectors at (%d,%d).\n",
|
|
|
|
TrackerCast(wall[w].x), TrackerCast(wall[w].y));
|
|
|
|
G_GameExit(tempbuf);
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->lotag == SE_5 || pSprite->lotag == SE_30_TWO_WAY_TRAIN ||
|
|
|
|
pSprite->lotag == SE_6_SUBWAY || pSprite->lotag == SE_14_SUBWAY_CAR)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
#ifdef YAX_ENABLE
|
2016-08-27 01:40:56 +00:00
|
|
|
int outerWall = -1;
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
2016-08-27 01:40:56 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall + sector[sectNum].wallnum;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2019-09-19 12:18:44 +00:00
|
|
|
pSprite->extra = (uint16_t)((uint16_t)sector[sectNum].hitag != UINT16_MAX);
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// TRAIN_SECTOR_TO_SE_INDEX
|
2016-08-27 01:40:56 +00:00
|
|
|
sector[sectNum].hitag = newSprite;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
spriteNum = 0;
|
|
|
|
|
|
|
|
int foundWall = startWall;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
for (; foundWall<endWall; foundWall++)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (wall[ foundWall ].nextsector >= 0 &&
|
|
|
|
sector[ wall[ foundWall ].nextsector].hitag == 0 &&
|
|
|
|
(int16_t)sector[ wall[ foundWall ].nextsector].lotag < 3)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
#ifdef YAX_ENABLE
|
2016-08-27 01:40:56 +00:00
|
|
|
outerWall = wall[foundWall].nextwall;
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
2016-08-27 01:40:56 +00:00
|
|
|
foundWall = wall[foundWall].nextsector;
|
|
|
|
spriteNum = 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-06-10 18:23:15 +00:00
|
|
|
|
2011-06-26 21:59:42 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor->t_data[9] = -1;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (outerWall >= 0)
|
2011-06-26 21:59:42 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int upperSect = yax_vnextsec(outerWall, YAX_CEILING);
|
2011-06-26 21:59:42 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (upperSect >= 0)
|
2011-06-26 21:59:42 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int foundEffector = headspritesect[upperSect];
|
|
|
|
|
|
|
|
for (; foundEffector >= 0; foundEffector = nextspritesect[foundEffector])
|
|
|
|
if (sprite[foundEffector].picnum == SECTOREFFECTOR && sprite[foundEffector].lotag == pSprite->lotag)
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
if (foundEffector < 0)
|
2011-06-26 21:59:42 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
Sect_SetInterpolation(upperSect);
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor->t_data[9] = upperSect;
|
2011-06-26 21:59:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2016-08-27 01:40:56 +00:00
|
|
|
if (spriteNum == 0)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
Bsprintf(tempbuf,"Subway found no zero'd sectors with locators\nat (%d,%d).\n",
|
2016-08-27 01:40:56 +00:00
|
|
|
TrackerCast(pSprite->x),TrackerCast(pSprite->y));
|
2016-02-13 21:05:57 +00:00
|
|
|
G_GameExit(tempbuf);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->owner = -1;
|
|
|
|
T1(newSprite) = foundWall;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->lotag != SE_30_TWO_WAY_TRAIN)
|
|
|
|
T4(newSprite) = pSprite->hitag;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (pSprite->lotag == SE_16_REACTOR)
|
|
|
|
T4(newSprite) = sector[sectNum].ceilingz;
|
|
|
|
else if (pSprite->lotag == SE_26)
|
2012-08-26 22:17:14 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
T4(newSprite) = pSprite->x;
|
|
|
|
T5(newSprite) = pSprite->y;
|
|
|
|
pSprite->zvel = (pSprite->shade == sector[sectNum].floorshade) ? -256 : 256; // UP
|
|
|
|
pSprite->shade = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else if (pSprite->lotag == SE_2_EARTHQUAKE)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
T6(newSprite) = sector[pSprite->sectnum].floorheinum;
|
|
|
|
sector[pSprite->sectnum].floorheinum = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (pSprite->lotag)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
case SE_6_SUBWAY:
|
|
|
|
case SE_14_SUBWAY_CAR:
|
|
|
|
S_FindMusicSFX(sectNum, &spriteNum);
|
|
|
|
// XXX: uh.. what?
|
|
|
|
if (spriteNum == -1)
|
|
|
|
spriteNum = SUBWAY;
|
2017-11-22 05:23:33 +00:00
|
|
|
pActor->lastv.x = spriteNum;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-08-27 01:40:56 +00:00
|
|
|
case SE_30_TWO_WAY_TRAIN:
|
|
|
|
if (g_netServer || numplayers > 1)
|
|
|
|
break;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-08-27 01:40:56 +00:00
|
|
|
case SE_0_ROTATING_SECTOR:
|
|
|
|
case SE_1_PIVOT:
|
|
|
|
case SE_5:
|
|
|
|
case SE_11_SWINGING_DOOR:
|
|
|
|
case SE_15_SLIDING_DOOR:
|
|
|
|
case SE_16_REACTOR:
|
|
|
|
case SE_26: Sect_SetInterpolation(sprite[newSprite].sectnum); break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
changespritestat(newSprite, STAT_EFFECTOR);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case SEENINE__STATIC:
|
|
|
|
case OOZFILTER__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->shade = -16;
|
|
|
|
if (pSprite->xrepeat <= 8)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 32768;
|
|
|
|
pSprite->xrepeat = 0;
|
|
|
|
pSprite->yrepeat = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
else pSprite->cstat = 1+256;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->extra = g_impactDamage << 2;
|
|
|
|
pSprite->owner = newSprite;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case CRACK1__STATIC:
|
|
|
|
case CRACK2__STATIC:
|
|
|
|
case CRACK3__STATIC:
|
|
|
|
case CRACK4__STATIC:
|
|
|
|
case FIREEXT__STATIC:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pSprite->picnum == FIREEXT)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat = 257;
|
|
|
|
pSprite->extra = g_impactDamage<<2;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->cstat |= (pSprite->cstat & 48) ? 1 : 17;
|
|
|
|
pSprite->extra = 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((!g_netServer && ud.multimode < 2) && pSprite->pal != 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->pal = 0;
|
|
|
|
pSprite->owner = newSprite;
|
|
|
|
pSprite->xvel = 8;
|
|
|
|
|
|
|
|
changespritestat(newSprite, STAT_STANDABLE);
|
|
|
|
A_SetSprite(newSprite,CLIPMASK0);
|
2020-03-29 08:41:03 +00:00
|
|
|
goto SPAWN_END;
|
|
|
|
|
2020-03-29 08:41:12 +00:00
|
|
|
case LAVAPOOLBUBBLE__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
if (sprite[spriteNum].xrepeat >= 30)
|
|
|
|
{
|
|
|
|
pSprite->owner = spriteNum;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 1;
|
|
|
|
pSprite->x += (krand()%512)-256;
|
|
|
|
pSprite->y += (krand()%512)-256;
|
|
|
|
}
|
|
|
|
goto SPAWN_END;
|
|
|
|
case WHISPYSMOKE__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
pActor->bpos.x = pSprite->x += (krand()%256)-128;
|
|
|
|
pActor->bpos.y = pSprite->y += (krand()%256)-128;
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 20;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
goto SPAWN_END;
|
|
|
|
case FIREFLYFLYINGEFFECT__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
pSprite->owner = spriteNum;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 1;
|
|
|
|
goto SPAWN_END;
|
|
|
|
case E32_TILE5846__STATIC:
|
|
|
|
if (!WORLDTOUR)
|
|
|
|
break;
|
|
|
|
pSprite->extra = 150;
|
|
|
|
pSprite->cstat |= 257;
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
|
|
|
goto SPAWN_END;
|
|
|
|
|
2020-03-29 08:41:03 +00:00
|
|
|
default:
|
|
|
|
break; // NOT goto
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation of the default case
|
2020-04-05 06:40:38 +00:00
|
|
|
if (G_TileHasActor(pSprite->picnum))
|
2020-03-29 08:41:03 +00:00
|
|
|
{
|
|
|
|
if (spriteNum == -1 && pSprite->lotag > ud.player_skill)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
goto SPAWN_END;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-29 08:41:03 +00:00
|
|
|
// Init the size
|
|
|
|
if (pSprite->xrepeat == 0 || pSprite->yrepeat == 0)
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 1;
|
|
|
|
|
|
|
|
if (A_CheckSpriteFlags(newSprite, SFLAG_BADGUY))
|
|
|
|
{
|
|
|
|
if (ud.monsters_off == 1)
|
|
|
|
{
|
|
|
|
pSprite->xrepeat = pSprite->yrepeat = 0;
|
|
|
|
changespritestat(newSprite, STAT_MISC);
|
|
|
|
goto SPAWN_END;
|
|
|
|
}
|
|
|
|
|
|
|
|
A_Fall(newSprite);
|
|
|
|
|
|
|
|
if (A_CheckSpriteFlags(newSprite, SFLAG_BADGUYSTAYPUT))
|
|
|
|
pActor->stayput = pSprite->sectnum;
|
|
|
|
|
|
|
|
g_player[myconnectindex].ps->max_actors_killed++;
|
|
|
|
pSprite->clipdist = 80;
|
|
|
|
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].picnum == RESPAWN)
|
|
|
|
pActor->tempang = sprite[newSprite].pal = sprite[spriteNum].pal;
|
|
|
|
|
|
|
|
A_PlayAlertSound(newSprite);
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
changespritestat(newSprite, STAT_ZOMBIEACTOR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSprite->clipdist = 40;
|
|
|
|
pSprite->owner = newSprite;
|
|
|
|
changespritestat(newSprite, STAT_ACTOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
pActor->timetosleep = 0;
|
|
|
|
|
|
|
|
if (spriteNum >= 0)
|
|
|
|
pSprite->ang = sprite[spriteNum].ang;
|
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
SPAWN_END:
|
|
|
|
if (VM_HaveEvent(EVENT_SPAWN))
|
|
|
|
{
|
|
|
|
int32_t p;
|
2016-08-27 01:40:56 +00:00
|
|
|
int32_t pl=A_FindPlayer(&sprite[newSprite],&p);
|
2019-05-19 03:53:25 +00:00
|
|
|
VM_ExecuteEvent(EVENT_SPAWN,newSprite, pl, p);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
return newSprite;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-04-18 17:25:24 +00:00
|
|
|
static int G_MaybeTakeOnFloorPal(tspriteptr_t pSprite, int sectNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const floorPal = sector[sectNum].floorpal;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (floorPal && !g_noFloorPal[floorPal] && !A_CheckSpriteFlags(pSprite->owner, SFLAG_NOPAL))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
pSprite->pal = floorPal;
|
2016-02-13 21:05:57 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-27 11:01:30 +00:00
|
|
|
template <int rotations>
|
|
|
|
static int getofs_viewtype(int angDiff)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2017-07-05 05:37:39 +00:00
|
|
|
return ((((angDiff + 3072) & 2047) * rotations + 1024) >> 11) % rotations;
|
2017-06-27 11:01:30 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-27 11:01:30 +00:00
|
|
|
template <int rotations>
|
|
|
|
static int viewtype_mirror(uint16_t & cstat, int frameOffset)
|
|
|
|
{
|
|
|
|
if (frameOffset > rotations / 2)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2017-07-05 05:37:39 +00:00
|
|
|
cstat |= 4;
|
2017-06-27 11:01:30 +00:00
|
|
|
return rotations - frameOffset;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-27 11:01:30 +00:00
|
|
|
cstat &= ~4;
|
2016-08-27 01:40:56 +00:00
|
|
|
return frameOffset;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-27 11:01:30 +00:00
|
|
|
template <int mirrored_rotations>
|
|
|
|
static int getofs_viewtype_mirrored(uint16_t & cstat, int angDiff)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2017-06-27 11:01:30 +00:00
|
|
|
return viewtype_mirror<mirrored_rotations*2-2>(cstat, getofs_viewtype<mirrored_rotations*2-2>(angDiff));
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-06-26 08:51:42 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
// XXX: this fucking sucks and needs to be replaced with a SFLAG
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:56 +00:00
|
|
|
static int G_CheckAdultTile(int tileNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-04-04 20:47:55 +00:00
|
|
|
UNREFERENCED_PARAMETER(tileNum);
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (tileNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
case FEM1__STATIC:
|
|
|
|
case FEM2__STATIC:
|
|
|
|
case FEM3__STATIC:
|
|
|
|
case FEM4__STATIC:
|
|
|
|
case FEM5__STATIC:
|
|
|
|
case FEM6__STATIC:
|
|
|
|
case FEM7__STATIC:
|
|
|
|
case FEM8__STATIC:
|
|
|
|
case FEM9__STATIC:
|
|
|
|
case FEM10__STATIC:
|
|
|
|
case MAN__STATIC:
|
|
|
|
case MAN2__STATIC:
|
|
|
|
case WOMAN__STATIC:
|
|
|
|
case NAKED1__STATIC:
|
|
|
|
case PODFEM1__STATIC:
|
|
|
|
case FEMMAG1__STATIC:
|
|
|
|
case FEMMAG2__STATIC:
|
|
|
|
case FEMPIC1__STATIC:
|
|
|
|
case FEMPIC2__STATIC:
|
|
|
|
case FEMPIC3__STATIC:
|
|
|
|
case FEMPIC4__STATIC:
|
|
|
|
case FEMPIC5__STATIC:
|
|
|
|
case FEMPIC6__STATIC:
|
|
|
|
case FEMPIC7__STATIC:
|
|
|
|
case BLOODYPOLE__STATIC:
|
|
|
|
case FEM6PAD__STATIC:
|
|
|
|
case STATUE__STATIC:
|
|
|
|
case STATUEFLASH__STATIC:
|
|
|
|
case OOZ__STATIC:
|
|
|
|
case OOZ2__STATIC:
|
|
|
|
case WALLBLOOD1__STATIC:
|
|
|
|
case WALLBLOOD2__STATIC:
|
|
|
|
case WALLBLOOD3__STATIC:
|
|
|
|
case WALLBLOOD4__STATIC:
|
|
|
|
case WALLBLOOD5__STATIC:
|
|
|
|
case WALLBLOOD7__STATIC:
|
|
|
|
case WALLBLOOD8__STATIC:
|
|
|
|
case SUSHIPLATE1__STATIC:
|
|
|
|
case SUSHIPLATE2__STATIC:
|
|
|
|
case SUSHIPLATE3__STATIC:
|
|
|
|
case SUSHIPLATE4__STATIC:
|
|
|
|
case FETUS__STATIC:
|
|
|
|
case FETUSJIB__STATIC:
|
|
|
|
case FETUSBROKE__STATIC:
|
|
|
|
case HOTMEAT__STATIC:
|
|
|
|
case FOODOBJECT16__STATIC:
|
|
|
|
case DOLPHIN1__STATIC:
|
|
|
|
case DOLPHIN2__STATIC:
|
|
|
|
case TOUGHGAL__STATIC:
|
|
|
|
case TAMPON__STATIC:
|
|
|
|
case XXXSTACY__STATIC:
|
|
|
|
case 4946:
|
|
|
|
case 4947:
|
|
|
|
case 693:
|
|
|
|
case 2254:
|
|
|
|
case 4560:
|
|
|
|
case 4561:
|
|
|
|
case 4562:
|
|
|
|
case 4498:
|
|
|
|
case 4957:
|
|
|
|
return 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
static inline void G_DoEventAnimSprites(int tspriteNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const tsprOwner = tsprite[tspriteNum].owner;
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((((unsigned)tsprOwner >= MAXSPRITES || (spriteext[tsprOwner].flags & SPREXT_TSPRACCESS) != SPREXT_TSPRACCESS))
|
|
|
|
&& tsprite[tspriteNum].statnum != TSPR_TEMP)
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
spriteext[tsprOwner].tspr = &tsprite[tspriteNum];
|
2019-05-19 03:53:25 +00:00
|
|
|
VM_ExecuteEvent(EVENT_ANIMATESPRITES, tsprOwner, screenpeek);
|
2016-08-27 01:40:56 +00:00
|
|
|
spriteext[tsprOwner].tspr = NULL;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2019-06-29 17:48:05 +00:00
|
|
|
void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura, int32_t smoothratio)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-06-29 17:48:05 +00:00
|
|
|
UNREFERENCED_PARAMETER(ourz);
|
2016-08-27 01:40:56 +00:00
|
|
|
int32_t j, frameOffset, playerNum;
|
2016-02-13 21:05:57 +00:00
|
|
|
intptr_t l;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (spritesortcnt == 0)
|
|
|
|
{
|
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
g_spriteStat.numonscreen = 0;
|
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
ror_sprite = -1;
|
|
|
|
#endif
|
|
|
|
for (j=spritesortcnt-1; j>=0; j--)
|
|
|
|
{
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const t = &tsprite[j];
|
2016-02-13 21:05:57 +00:00
|
|
|
const int32_t i = t->owner;
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const s = &sprite[i];
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2019-12-26 06:28:08 +00:00
|
|
|
Duke_ApplySpritePropertiesToTSprite(t, (uspriteptr_t)s);
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
switch (DYNAMICTILEMAP(s->picnum))
|
|
|
|
{
|
|
|
|
case SECTOREFFECTOR__STATIC:
|
|
|
|
if (s->lotag == 40 || s->lotag == 41)
|
|
|
|
{
|
|
|
|
t->cstat = 32768;
|
|
|
|
#ifdef LEGACY_ROR
|
|
|
|
if (ror_sprite == -1)
|
|
|
|
ror_sprite = i;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (t->lotag == SE_27_DEMO_CAM && ud.recstat == 1)
|
|
|
|
{
|
2019-08-27 13:39:54 +00:00
|
|
|
t->picnum = 11+(((int) totalclock>>3)&1);
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat |= 128;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j=spritesortcnt-1; j>=0; j--)
|
|
|
|
{
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const t = &tsprite[j];
|
2016-02-13 21:05:57 +00:00
|
|
|
const int32_t i = t->owner;
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const s = (uspriteptr_t)&sprite[i];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (t->picnum < GREENSLIME || t->picnum > GREENSLIME+7)
|
|
|
|
switch (DYNAMICTILEMAP(t->picnum))
|
|
|
|
{
|
|
|
|
case BLOODPOOL__STATIC:
|
|
|
|
case PUKE__STATIC:
|
|
|
|
case FOOTPRINTS__STATIC:
|
|
|
|
case FOOTPRINTS2__STATIC:
|
|
|
|
case FOOTPRINTS3__STATIC:
|
|
|
|
case FOOTPRINTS4__STATIC:
|
|
|
|
if (t->shade == 127) continue;
|
|
|
|
break;
|
|
|
|
case RESPAWNMARKERRED__STATIC:
|
|
|
|
case RESPAWNMARKERYELLOW__STATIC:
|
|
|
|
case RESPAWNMARKERGREEN__STATIC:
|
|
|
|
if (ud.marker == 0)
|
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
continue;
|
|
|
|
case CHAIR3__STATIC:
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(t->picnum,t->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->cstat &= ~4;
|
|
|
|
break;
|
|
|
|
}
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<5>(t->cstat, t->ang - oura);
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum = s->picnum+frameOffset;
|
2006-11-15 01:16:55 +00:00
|
|
|
break;
|
2016-02-13 21:05:57 +00:00
|
|
|
case BLOODSPLAT1__STATIC:
|
|
|
|
case BLOODSPLAT2__STATIC:
|
|
|
|
case BLOODSPLAT3__STATIC:
|
|
|
|
case BLOODSPLAT4__STATIC:
|
2019-10-27 12:40:24 +00:00
|
|
|
if (adult_lockout) t->xrepeat = t->yrepeat = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
else if (t->pal == 6)
|
|
|
|
{
|
|
|
|
t->shade = -127;
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case BULLETHOLE__STATIC:
|
|
|
|
case CRACK1__STATIC:
|
|
|
|
case CRACK2__STATIC:
|
|
|
|
case CRACK3__STATIC:
|
|
|
|
case CRACK4__STATIC:
|
|
|
|
t->shade = 16;
|
|
|
|
continue;
|
|
|
|
case NEON1__STATIC:
|
|
|
|
case NEON2__STATIC:
|
|
|
|
case NEON3__STATIC:
|
|
|
|
case NEON4__STATIC:
|
|
|
|
case NEON5__STATIC:
|
|
|
|
case NEON6__STATIC:
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
// NOTE: wall-aligned sprites will never take on ceiling/floor shade...
|
2016-08-27 01:40:06 +00:00
|
|
|
if ((t->cstat&16) || (A_CheckEnemySprite(t) &&
|
2016-02-13 21:05:57 +00:00
|
|
|
(unsigned)t->owner < MAXSPRITES && sprite[t->owner].extra > 0) || t->statnum == STAT_PLAYER)
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// ... since this is not reached:
|
|
|
|
if (A_CheckSpriteFlags(t->owner, SFLAG_NOSHADE) || (t->cstat&CSTAT_SPRITE_NOSHADE))
|
|
|
|
l = sprite[t->owner].shade;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (sector[t->sectnum].ceilingstat&1)
|
|
|
|
l = sector[t->sectnum].ceilingshade;
|
|
|
|
else
|
|
|
|
l = sector[t->sectnum].floorshade;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (l < -127)
|
|
|
|
l = -127;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
t->shade = l;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (j=spritesortcnt-1; j>=0; j--) //Between drawrooms() and drawmasks()
|
|
|
|
{
|
|
|
|
int32_t switchpic;
|
|
|
|
int32_t curframe;
|
|
|
|
#if !defined LUNATIC
|
|
|
|
int32_t scrofs_action;
|
|
|
|
#else
|
|
|
|
int32_t startframe, viewtype;
|
|
|
|
#endif
|
|
|
|
//is the perfect time to animate sprites
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const t = &tsprite[j];
|
2016-02-13 21:05:57 +00:00
|
|
|
const int32_t i = t->owner;
|
|
|
|
// XXX: what's up with the (i < 0) check?
|
|
|
|
// NOTE: not const spritetype because set at SET_SPRITE_NOT_TSPRITE (see below).
|
2019-12-26 06:27:48 +00:00
|
|
|
EDUKE32_STATIC_ASSERT(sizeof(uspritetype) == sizeof(tspritetype)); // see TSPRITE_SIZE
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const pSprite = (i < 0) ? (uspriteptr_t)&tsprite[j] : (uspriteptr_t)&sprite[i];
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2019-10-27 12:40:24 +00:00
|
|
|
if (adult_lockout && G_CheckAdultTile(DYNAMICTILEMAP(pSprite->picnum)))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
continue;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (pSprite->picnum == NATURALLIGHTNING)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->shade = -127;
|
2019-12-26 06:28:08 +00:00
|
|
|
t->clipdist |= TSPR_FLAGS_NO_SHADOW;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
if (t->statnum == TSPR_TEMP)
|
|
|
|
continue;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Bassert(i >= 0);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const ps = (pSprite->statnum != STAT_ACTOR && pSprite->picnum == APLAYER && pSprite->owner >= 0) ? g_player[P_GetP(pSprite)].ps : NULL;
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ps && ps->newowner == -1)
|
|
|
|
{
|
|
|
|
t->x -= mulscale16(65536-smoothratio,ps->pos.x-ps->opos.x);
|
|
|
|
t->y -= mulscale16(65536-smoothratio,ps->pos.y-ps->opos.y);
|
|
|
|
// dirty hack
|
|
|
|
if (ps->dead_flag) t->z = ps->opos.z;
|
|
|
|
t->z += mulscale16(smoothratio,ps->pos.z-ps->opos.z) -
|
|
|
|
(ps->dead_flag ? 0 : PHEIGHT) + PHEIGHT;
|
|
|
|
}
|
2020-03-12 00:58:32 +00:00
|
|
|
else if (pSprite->picnum != CRANEPOLE)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
t->x -= mulscale16(65536-smoothratio,pSprite->x-actor[i].bpos.x);
|
|
|
|
t->y -= mulscale16(65536-smoothratio,pSprite->y-actor[i].bpos.y);
|
|
|
|
t->z -= mulscale16(65536-smoothratio,pSprite->z-actor[i].bpos.z);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
const int32_t sect = pSprite->sectnum;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
curframe = AC_CURFRAME(actor[i].t_data);
|
|
|
|
#if !defined LUNATIC
|
|
|
|
scrofs_action = AC_ACTION_ID(actor[i].t_data);
|
|
|
|
#else
|
|
|
|
startframe = actor[i].ac.startframe;
|
|
|
|
viewtype = actor[i].ac.viewtype;
|
2011-06-26 21:59:42 +00:00
|
|
|
#endif
|
2016-08-27 01:40:46 +00:00
|
|
|
switchpic = pSprite->picnum;
|
2016-02-13 21:05:57 +00:00
|
|
|
// Some special cases because dynamictostatic system can't handle
|
|
|
|
// addition to constants.
|
2016-08-27 01:40:46 +00:00
|
|
|
if ((pSprite->picnum >= SCRAP6) && (pSprite->picnum<=SCRAP6+7))
|
2016-02-13 21:05:57 +00:00
|
|
|
switchpic = SCRAP5;
|
2016-08-27 01:40:46 +00:00
|
|
|
else if ((pSprite->picnum==MONEY+1) || (pSprite->picnum==MAIL+1) || (pSprite->picnum==PAPER+1))
|
2016-02-13 21:05:57 +00:00
|
|
|
switchpic--;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
switch (DYNAMICTILEMAP(switchpic))
|
|
|
|
{
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-02-13 21:05:57 +00:00
|
|
|
case DUKELYINGDEAD__STATIC:
|
|
|
|
t->z += (24<<8);
|
|
|
|
break;
|
|
|
|
case BLOODPOOL__STATIC:
|
|
|
|
case FOOTPRINTS__STATIC:
|
|
|
|
case FOOTPRINTS2__STATIC:
|
|
|
|
case FOOTPRINTS3__STATIC:
|
|
|
|
case FOOTPRINTS4__STATIC:
|
|
|
|
if (t->pal == 6)
|
|
|
|
t->shade = -127;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case PUKE__STATIC:
|
|
|
|
case MONEY__STATIC:
|
|
|
|
//case MONEY+1__STATIC:
|
|
|
|
case MAIL__STATIC:
|
|
|
|
//case MAIL+1__STATIC:
|
|
|
|
case PAPER__STATIC:
|
|
|
|
//case PAPER+1__STATIC:
|
2019-10-27 12:40:24 +00:00
|
|
|
if (adult_lockout && pSprite->pal == 2)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TRIPBOMB__STATIC:
|
|
|
|
continue;
|
|
|
|
case FORCESPHERE__STATIC:
|
|
|
|
if (t->statnum == STAT_MISC)
|
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
int16_t const sqa = getangle(sprite[pSprite->owner].x - g_player[screenpeek].ps->pos.x,
|
|
|
|
sprite[pSprite->owner].y - g_player[screenpeek].ps->pos.y);
|
|
|
|
int16_t const sqb = getangle(sprite[pSprite->owner].x - t->x, sprite[pSprite->owner].y - t->y);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (klabs(G_GetAngleDelta(sqa,sqb)) > 512)
|
2019-07-08 00:41:25 +00:00
|
|
|
if (ldist(&sprite[pSprite->owner],(spritetype const *)t) < ldist(&sprite[g_player[screenpeek].ps->i],&sprite[pSprite->owner]))
|
2016-02-13 21:05:57 +00:00
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
case BURNING__STATIC:
|
|
|
|
case BURNING2__STATIC:
|
2016-08-27 01:40:46 +00:00
|
|
|
if (sprite[pSprite->owner].statnum == STAT_PLAYER)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
int const playerNum = P_Get(pSprite->owner);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (display_mirror == 0 && playerNum == screenpeek && g_player[playerNum].ps->over_shoulder_on == 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
t->xrepeat = 0;
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
t->ang = getangle(ourx - t->x, oury - t->y);
|
|
|
|
t->x = sprite[pSprite->owner].x + (sintable[(t->ang + 512) & 2047] >> 10);
|
|
|
|
t->y = sprite[pSprite->owner].y + (sintable[t->ang & 2047] >> 10);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case ATOMICHEALTH__STATIC:
|
2016-08-27 01:41:04 +00:00
|
|
|
t->z -= ZOFFSET6;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case CRYSTALAMMO__STATIC:
|
2019-08-27 13:39:54 +00:00
|
|
|
t->shade = (sintable[((int32_t) totalclock<<4)&2047]>>10);
|
2016-02-13 21:05:57 +00:00
|
|
|
continue;
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
case VIEWSCREEN__STATIC:
|
|
|
|
case VIEWSCREEN2__STATIC:
|
|
|
|
{
|
2020-03-29 12:01:46 +00:00
|
|
|
int const viewscrTile = TILE_VIEWSCR;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (g_curViewscreen >= 0 && actor[OW(i)].t_data[0] == 1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->picnum = STATIC;
|
|
|
|
t->cstat |= (rand()&12);
|
|
|
|
t->xrepeat += 10;
|
|
|
|
t->yrepeat += 9;
|
|
|
|
}
|
2019-10-11 21:31:59 +00:00
|
|
|
else if (g_curViewscreen == i && display_mirror != 3 && tileData(viewscrTile))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->picnum = viewscrTile;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-02-13 21:05:57 +00:00
|
|
|
case SHRINKSPARK__STATIC:
|
2019-08-27 13:39:54 +00:00
|
|
|
t->picnum = SHRINKSPARK+(((int32_t) totalclock>>4)&3);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case GROWSPARK__STATIC:
|
2019-08-27 13:39:54 +00:00
|
|
|
t->picnum = GROWSPARK+(((int32_t) totalclock>>4)&3);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case RPG__STATIC:
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(t->picnum,t->pal) && !(spriteext[i].flags & SPREXT_NOTMD))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t v = getangle(t->xvel, t->zvel>>4);
|
|
|
|
|
|
|
|
spriteext[i].pitch = (v > 1023 ? v-2048 : v);
|
|
|
|
t->cstat &= ~4;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2017-06-28 10:55:41 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<7>(t->cstat, pSprite->ang - getangle(pSprite->x-ourx, pSprite->y-oury));
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum = RPG+frameOffset;
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case RECON__STATIC:
|
2019-07-06 19:04:50 +00:00
|
|
|
if (tilehasmodelorvoxel(t->picnum,t->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2017-06-28 10:55:41 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<7>(t->cstat, pSprite->ang - getangle(pSprite->x-ourx, pSprite->y-oury));
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
// RECON_T4
|
|
|
|
if (klabs(curframe) > 64)
|
2016-08-27 01:40:56 +00:00
|
|
|
frameOffset += 7; // tilted recon car
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum = RECON+frameOffset;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
case APLAYER__STATIC:
|
2016-08-27 01:40:46 +00:00
|
|
|
playerNum = P_GetP(pSprite);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (t->pal == 1) t->z -= (18<<8);
|
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (g_player[playerNum].ps->over_shoulder_on > 0 && g_player[playerNum].ps->newowner < 0)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-03-07 04:21:18 +00:00
|
|
|
t->ang = fix16_to_int(
|
|
|
|
g_player[playerNum].ps->q16ang
|
|
|
|
+ mulscale16((((g_player[playerNum].ps->q16ang + 1024 - g_player[playerNum].ps->oq16ang) & 2047) - 1024), smoothratio));
|
2019-07-06 17:57:46 +00:00
|
|
|
if (tilehasmodelorvoxel(t->picnum, t->pal))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
static int32_t targetang = 0;
|
|
|
|
|
2019-07-08 00:41:17 +00:00
|
|
|
if (g_player[playerNum].input->extbits&(1<<1))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-07-08 00:41:17 +00:00
|
|
|
if (g_player[playerNum].input->extbits&(1<<2))targetang += 16;
|
|
|
|
else if (g_player[playerNum].input->extbits&(1<<3)) targetang -= 16;
|
2016-02-13 21:05:57 +00:00
|
|
|
else if (targetang > 0) targetang -= targetang>>2;
|
|
|
|
else if (targetang < 0) targetang += (-targetang)>>2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-08 00:41:17 +00:00
|
|
|
if (g_player[playerNum].input->extbits&(1<<2))targetang -= 16;
|
|
|
|
else if (g_player[playerNum].input->extbits&(1<<3)) targetang += 16;
|
2016-02-13 21:05:57 +00:00
|
|
|
else if (targetang > 0) targetang -= targetang>>2;
|
|
|
|
else if (targetang < 0) targetang += (-targetang)>>2;
|
|
|
|
}
|
|
|
|
|
|
|
|
targetang = clamp(targetang, -128, 128);
|
|
|
|
t->ang += targetang;
|
|
|
|
}
|
2019-08-07 22:44:25 +00:00
|
|
|
else if (!display_mirror)
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat |= 2;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1) && (display_mirror || screenpeek != playerNum || pSprite->owner == -1))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
if (ud.showweapons && sprite[g_player[playerNum].ps->i].extra > 0 && g_player[playerNum].ps->curr_weapon > 0
|
2017-07-08 19:42:11 +00:00
|
|
|
&& spritesortcnt < maxspritesonscreen)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const newTspr = &tsprite[spritesortcnt];
|
|
|
|
int const currentWeapon = g_player[playerNum].ps->curr_weapon;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
*newTspr = *t;
|
|
|
|
newTspr->statnum = TSPR_TEMP;
|
|
|
|
newTspr->cstat = 0;
|
|
|
|
newTspr->pal = 0;
|
|
|
|
newTspr->picnum = (currentWeapon == GROW_WEAPON ? GROWSPRITEICON : WeaponPickupSprites[currentWeapon]);
|
|
|
|
newTspr->z = (pSprite->owner >= 0) ? g_player[playerNum].ps->pos.z - ZOFFSET4 : pSprite->z - (51 << 8);
|
|
|
|
newTspr->xrepeat = (newTspr->picnum == HEAVYHBOMB) ? 10 : 16;
|
|
|
|
newTspr->yrepeat = newTspr->xrepeat;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
spritesortcnt++;
|
|
|
|
}
|
2012-03-22 22:47:29 +00:00
|
|
|
|
2019-07-08 00:41:17 +00:00
|
|
|
if (g_player[playerNum].input->extbits & (1 << 7) && !ud.pause_on && spritesortcnt < maxspritesonscreen)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-04-18 17:25:24 +00:00
|
|
|
auto const playerTyping = t;
|
2012-03-22 22:47:29 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
playerTyping->statnum = TSPR_TEMP;
|
|
|
|
playerTyping->cstat = 0;
|
|
|
|
playerTyping->picnum = RESPAWNMARKERGREEN;
|
|
|
|
playerTyping->z = (pSprite->owner >= 0) ? (g_player[playerNum].ps->pos.z - (20 << 8)) : (pSprite->z - (96 << 8));
|
|
|
|
playerTyping->xrepeat = 32;
|
|
|
|
playerTyping->yrepeat = 32;
|
|
|
|
playerTyping->pal = 20;
|
2012-08-06 20:00:31 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
spritesortcnt++;
|
|
|
|
}
|
|
|
|
}
|
2012-08-06 20:00:31 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (pSprite->owner == -1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(pSprite->picnum,t->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
frameOffset = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
}
|
|
|
|
else
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<5>(t->cstat, pSprite->ang - oura);
|
2012-08-06 20:00:31 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[pSprite->sectnum].lotag == ST_2_UNDERWATER) frameOffset += 1795-1405;
|
|
|
|
else if ((actor[i].floorz-pSprite->z) > (64<<8)) frameOffset += 60;
|
2012-08-06 20:00:31 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum += frameOffset;
|
2016-08-27 01:40:46 +00:00
|
|
|
t->pal = g_player[playerNum].ps->palookup;
|
2013-02-01 13:05:08 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
goto PALONLY;
|
|
|
|
}
|
2014-10-25 03:36:34 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (g_player[playerNum].ps->on_crane == -1 && (sector[pSprite->sectnum].lotag&0x7ff) != 1) // ST_1_ABOVE_WATER ?
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
l = pSprite->z-actor[g_player[playerNum].ps->i].floorz+(3<<8);
|
2016-02-13 21:05:57 +00:00
|
|
|
// SET_SPRITE_NOT_TSPRITE
|
2016-08-27 01:40:46 +00:00
|
|
|
if (l > 1024 && pSprite->yrepeat > 32 && pSprite->extra > 0)
|
2019-04-18 17:25:24 +00:00
|
|
|
t->yoffset = (int8_t)tabledivide32_noinline(l, pSprite->yrepeat<<2);
|
|
|
|
else t->yoffset=0;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2012-08-13 18:26:11 +00:00
|
|
|
|
2019-06-25 11:29:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2019-07-19 01:49:29 +00:00
|
|
|
if (!FURY && g_player[playerNum].ps->newowner > -1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
// Display APLAYER sprites with action PSTAND when viewed through
|
|
|
|
// a camera. Not implemented for Lunatic.
|
|
|
|
#if !defined LUNATIC
|
|
|
|
const intptr_t *aplayer_scr = g_tile[APLAYER].execPtr;
|
|
|
|
// [0]=strength, [1]=actionofs, [2]=moveofs
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
scrofs_action = aplayer_scr[1];
|
2013-05-26 18:42:56 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
curframe = 0;
|
|
|
|
}
|
2019-06-25 11:29:31 +00:00
|
|
|
#endif
|
2016-08-27 01:40:46 +00:00
|
|
|
if (ud.camerasprite == -1 && g_player[playerNum].ps->newowner == -1)
|
|
|
|
{
|
|
|
|
if (pSprite->owner >= 0 && display_mirror == 0 && g_player[playerNum].ps->over_shoulder_on == 0)
|
|
|
|
{
|
|
|
|
if ((!g_netServer && ud.multimode < 2) || ((g_netServer || ud.multimode > 1) && playerNum == screenpeek))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_POLYMER)
|
2019-12-26 06:28:08 +00:00
|
|
|
t->clipdist |= TSPR_FLAGS_INVISIBLE_WITH_SHADOW;
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
t->owner = -1;
|
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(pSprite->picnum, t->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
frameOffset = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
}
|
|
|
|
else
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<5>(t->cstat, pSprite->ang - oura);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (sector[t->sectnum].lotag == ST_2_UNDERWATER) frameOffset += 1795-1405;
|
|
|
|
else if ((actor[i].floorz-pSprite->z) > (64<<8)) frameOffset += 60;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum += frameOffset;
|
2016-08-27 01:40:46 +00:00
|
|
|
t->pal = g_player[playerNum].ps->palookup;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:40:46 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
PALONLY:
|
|
|
|
G_MaybeTakeOnFloorPal(t, sect);
|
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (pSprite->owner == -1) continue;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (t->z > actor[i].floorz && t->xrepeat < 32)
|
|
|
|
t->z = actor[i].floorz;
|
|
|
|
|
|
|
|
break;
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-02-13 21:05:57 +00:00
|
|
|
case JIBS1__STATIC:
|
|
|
|
case JIBS2__STATIC:
|
|
|
|
case JIBS3__STATIC:
|
|
|
|
case JIBS4__STATIC:
|
|
|
|
case JIBS5__STATIC:
|
|
|
|
case JIBS6__STATIC:
|
|
|
|
case HEADJIB1__STATIC:
|
|
|
|
case LEGJIB1__STATIC:
|
|
|
|
case ARMJIB1__STATIC:
|
|
|
|
case LIZMANHEAD1__STATIC:
|
|
|
|
case LIZMANARM1__STATIC:
|
|
|
|
case LIZMANLEG1__STATIC:
|
|
|
|
case DUKELEG__STATIC:
|
|
|
|
case DUKEGUN__STATIC:
|
|
|
|
case DUKETORSO__STATIC:
|
2019-10-27 12:40:24 +00:00
|
|
|
if (adult_lockout)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
continue;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
if (t->pal == 6)
|
|
|
|
t->shade = -120;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case SCRAP1__STATIC:
|
|
|
|
case SCRAP2__STATIC:
|
|
|
|
case SCRAP3__STATIC:
|
|
|
|
case SCRAP4__STATIC:
|
|
|
|
case SCRAP5__STATIC:
|
2016-08-27 01:40:46 +00:00
|
|
|
if (actor[i].picnum == BLIMP && t->picnum == SCRAP1 && pSprite->yvel >= 0)
|
|
|
|
t->picnum = pSprite->yvel < MAXUSERTILES ? pSprite->yvel : 0;
|
2016-08-27 01:40:35 +00:00
|
|
|
else t->picnum += T1(i);
|
2018-01-31 05:23:39 +00:00
|
|
|
t->shade = -128+6 < t->shade ? t->shade-6 : -128; // effectively max(t->shade-6, -128) while avoiding (signed!) underflow
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_MaybeTakeOnFloorPal(t, sect);
|
|
|
|
break;
|
|
|
|
case WATERBUBBLE__STATIC:
|
|
|
|
if (sector[t->sectnum].floorpicnum == FLOORSLIME)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
t->pal = 7;
|
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
default:
|
|
|
|
G_MaybeTakeOnFloorPal(t, sect);
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2020-04-05 06:40:38 +00:00
|
|
|
if (G_TileHasActor(pSprite->picnum))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
#if !defined LUNATIC
|
2019-05-19 19:57:10 +00:00
|
|
|
if ((unsigned)scrofs_action + ACTION_PARAM_COUNT > (unsigned)g_scriptSize)
|
2016-02-13 21:05:57 +00:00
|
|
|
goto skip;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-29 08:41:07 +00:00
|
|
|
int32_t viewtype = apScript[scrofs_action + ACTION_VIEWTYPE];
|
2016-09-06 02:15:31 +00:00
|
|
|
uint16_t const action_flags = apScript[scrofs_action + ACTION_FLAGS];
|
2016-02-13 21:05:57 +00:00
|
|
|
#else
|
2016-09-06 02:15:31 +00:00
|
|
|
uint16_t const action_flags = actor[i].ac.flags;
|
2010-08-02 08:13:51 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-29 08:41:07 +00:00
|
|
|
int const invertp = viewtype < 0;
|
|
|
|
l = klabs(viewtype);
|
2017-06-27 11:01:30 +00:00
|
|
|
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(pSprite->picnum,t->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
frameOffset = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
else
|
2017-06-27 11:01:30 +00:00
|
|
|
{
|
|
|
|
int const viewAng = ((l > 4 && l != 8) || action_flags & AF_VIEWPOINT) ? getangle(pSprite->x-ourx, pSprite->y-oury) : oura;
|
|
|
|
int const angDiff = invertp ? viewAng - pSprite->ang : pSprite->ang - viewAng;
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
switch (l)
|
|
|
|
{
|
|
|
|
case 2:
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype<8>(angDiff) & 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2014-05-30 19:39:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case 3:
|
|
|
|
case 4:
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = viewtype_mirror<7>(t->cstat, getofs_viewtype<16>(angDiff) & 7);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2014-05-30 19:39:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case 5:
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<5>(t->cstat, angDiff);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case 7:
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<7>(t->cstat, angDiff);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype<8>(angDiff);
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
break;
|
2017-06-27 11:01:34 +00:00
|
|
|
case 9:
|
|
|
|
frameOffset = getofs_viewtype_mirrored<9>(t->cstat, angDiff);
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
frameOffset = getofs_viewtype<12>(angDiff);
|
|
|
|
t->cstat &= ~4;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
frameOffset = getofs_viewtype<16>(angDiff);
|
|
|
|
t->cstat &= ~4;
|
|
|
|
break;
|
2016-02-13 21:05:57 +00:00
|
|
|
default:
|
2016-08-27 01:40:56 +00:00
|
|
|
frameOffset = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-06-27 11:01:30 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-06-30 20:38:48 +00:00
|
|
|
#if !defined LUNATIC
|
2020-03-29 08:41:07 +00:00
|
|
|
t->picnum += frameOffset + apScript[scrofs_action + ACTION_STARTFRAME] + viewtype*curframe;
|
2012-06-03 15:46:08 +00:00
|
|
|
#else
|
2020-03-29 08:41:07 +00:00
|
|
|
t->picnum += frameOffset + startframe + viewtype*curframe;
|
2012-05-18 12:46:10 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
// XXX: t->picnum can be out-of-bounds by bad user code.
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-29 08:41:07 +00:00
|
|
|
if (viewtype > 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
while (tilesiz[t->picnum].x == 0 && t->picnum > 0)
|
|
|
|
t->picnum -= l; //Hack, for actors
|
|
|
|
|
|
|
|
if (actor[i].dispicnum >= 0)
|
|
|
|
actor[i].dispicnum = t->picnum;
|
2012-08-06 20:00:31 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
// else if (display_mirror == 1)
|
|
|
|
// t->cstat |= 4;
|
|
|
|
/* completemirror() already reverses the drawn frame, so the above isn't necessary.
|
|
|
|
* Even Polymost's and Polymer's mirror seems to function correctly this way. */
|
2012-08-06 20:00:31 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#if !defined LUNATIC
|
|
|
|
skip:
|
|
|
|
#endif
|
|
|
|
// Night vision goggles tsprite tinting.
|
|
|
|
// XXX: Currently, for the splitscreen mod, sprites will be pal6-colored iff the first
|
|
|
|
// player has nightvision on. We should pass stuff like "from which player is this view
|
|
|
|
// supposed to be" as parameters ("drawing context") instead of relying on globals.
|
|
|
|
if (g_player[screenpeek].ps->inv_amount[GET_HEATS] > 0 && g_player[screenpeek].ps->heat_on &&
|
2016-08-27 01:40:46 +00:00
|
|
|
(A_CheckEnemySprite(pSprite) || A_CheckSpriteFlags(t->owner,SFLAG_NVG) || pSprite->picnum == APLAYER || pSprite->statnum == STAT_DUMMYPLAYER))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
t->pal = 6;
|
|
|
|
t->shade = 0;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Fake floor shadow, implemented by inserting a new tsprite.
|
2016-08-27 01:40:46 +00:00
|
|
|
if (pSprite->statnum == STAT_DUMMYPLAYER || A_CheckEnemySprite(pSprite) || A_CheckSpriteFlags(t->owner,SFLAG_SHADOW) || (pSprite->picnum == APLAYER && pSprite->owner >= 0))
|
|
|
|
if (t->statnum != TSPR_TEMP && pSprite->picnum != EXPLOSION2 && pSprite->picnum != HANGLIGHT && pSprite->picnum != DOMELITE && pSprite->picnum != HOTMEAT)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
if (actor[i].dispicnum < 0)
|
|
|
|
{
|
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
// A negative actor[i].dispicnum used to mean 'no floor shadow please', but
|
|
|
|
// that was a bad hack since the value could propagate to sprite[].picnum.
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf(OSD_ERROR "actor[%d].dispicnum = %d\n", i, actor[i].dispicnum);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
actor[i].dispicnum=0;
|
|
|
|
continue;
|
|
|
|
}
|
2012-08-06 20:00:31 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (actor[i].flags & SFLAG_NOFLOORSHADOW)
|
|
|
|
continue;
|
2014-12-26 17:30:00 +00:00
|
|
|
|
2019-10-22 23:30:43 +00:00
|
|
|
if (r_shadows && spritesortcnt < (maxspritesonscreen-2)
|
2018-01-26 04:35:29 +00:00
|
|
|
#ifdef POLYMER
|
2018-04-12 21:03:12 +00:00
|
|
|
&& !(videoGetRenderMode() == REND_POLYMER && pr_lighting != 0)
|
2018-01-26 04:35:29 +00:00
|
|
|
#endif
|
|
|
|
)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int const shadowZ = ((sector[sect].lotag & 0xff) > 2 || pSprite->statnum == STAT_PROJECTILE ||
|
2016-08-27 01:40:46 +00:00
|
|
|
pSprite->statnum == STAT_MISC || pSprite->picnum == DRONE || pSprite->picnum == COMMANDER)
|
|
|
|
? sector[sect].floorz
|
2016-08-27 01:40:56 +00:00
|
|
|
: actor[i].floorz;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if ((pSprite->z-shadowZ) < ZOFFSET3 && g_player[screenpeek].ps->pos.z < shadowZ)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-04-18 17:25:24 +00:00
|
|
|
tspriteptr_t tsprShadow = &tsprite[spritesortcnt];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
*tsprShadow = *t;
|
|
|
|
tsprShadow->statnum = TSPR_TEMP;
|
|
|
|
tsprShadow->yrepeat = (t->yrepeat >> 3);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (t->yrepeat < 4)
|
|
|
|
t->yrepeat = 4;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
tsprShadow->shade = 127;
|
|
|
|
tsprShadow->cstat |= 2;
|
|
|
|
tsprShadow->z = shadowZ;
|
2018-01-29 11:14:17 +00:00
|
|
|
tsprShadow->pal = ud.shadow_pal;
|
2013-12-28 17:04:27 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef USE_OPENGL
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() >= REND_POLYMOST)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(t->picnum,t->pal))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
tsprShadow->yrepeat = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
// 512:trans reverse
|
|
|
|
//1024:tell MD2SPRITE.C to use Z-buffer hacks to hide overdraw issues
|
2019-12-26 06:28:03 +00:00
|
|
|
tsprShadow->clipdist |= TSPR_FLAGS_MDHACK;
|
2016-08-27 01:40:56 +00:00
|
|
|
tsprShadow->cstat |= 512;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-13 03:20:21 +00:00
|
|
|
int const camang = display_mirror ? ((2048 - fix16_to_int(CAMERA(q16ang))) & 2047) : fix16_to_int(CAMERA(q16ang));
|
|
|
|
vec2_t const ofs = { sintable[(camang+512)&2047]>>11, sintable[(camang)&2047]>>11};
|
2014-10-25 03:35:21 +00:00
|
|
|
|
2019-07-13 03:20:21 +00:00
|
|
|
tsprShadow->x += ofs.x;
|
|
|
|
tsprShadow->y += ofs.y;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2015-02-11 05:22:19 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
spritesortcnt++;
|
|
|
|
}
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2014-10-25 03:35:21 +00:00
|
|
|
|
2019-05-19 19:57:10 +00:00
|
|
|
#ifdef LUNATIC
|
|
|
|
bool const haveAction = false; // FIXME!
|
|
|
|
#else
|
2019-05-19 20:02:05 +00:00
|
|
|
bool const haveAction = scrofs_action != 0 && (unsigned)scrofs_action + ACTION_PARAM_COUNT <= (unsigned)g_scriptSize;
|
2019-05-19 19:57:10 +00:00
|
|
|
#endif
|
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
switch (DYNAMICTILEMAP(pSprite->picnum))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-02-13 21:05:57 +00:00
|
|
|
case LASERLINE__STATIC:
|
|
|
|
if (sector[t->sectnum].lotag == ST_2_UNDERWATER) t->pal = 8;
|
2016-08-27 01:40:46 +00:00
|
|
|
t->z = sprite[pSprite->owner].z-(3<<8);
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_tripbombLaserMode == 2 && g_player[screenpeek].ps->heat_on == 0)
|
|
|
|
t->yrepeat = 0;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case EXPLOSION2BOT__STATIC:
|
|
|
|
case FREEZEBLAST__STATIC:
|
|
|
|
case ATOMICHEALTH__STATIC:
|
|
|
|
case FIRELASER__STATIC:
|
2010-08-02 08:13:51 +00:00
|
|
|
case SHRINKSPARK__STATIC:
|
|
|
|
case GROWSPARK__STATIC:
|
2016-02-13 21:05:57 +00:00
|
|
|
case CHAINGUN__STATIC:
|
|
|
|
case SHRINKEREXPLOSION__STATIC:
|
2010-08-02 08:13:51 +00:00
|
|
|
case RPG__STATIC:
|
2016-02-13 21:05:57 +00:00
|
|
|
case FLOORFLAME__STATIC:
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
|
|
|
case EXPLOSION2__STATIC:
|
2016-02-13 21:05:57 +00:00
|
|
|
if (t->picnum == EXPLOSION2)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[screenpeek].ps->visibility = -127;
|
|
|
|
//g_restorePalette = 1; // JBF 20040101: why?
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
t->shade = -127;
|
2019-12-26 06:28:08 +00:00
|
|
|
t->clipdist |= TSPR_FLAGS_DRAW_LAST | TSPR_FLAGS_NO_SHADOW;
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
2018-07-21 00:18:03 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-02-13 21:05:57 +00:00
|
|
|
case FIRE__STATIC:
|
|
|
|
case FIRE2__STATIC:
|
|
|
|
t->cstat |= 128;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case BURNING__STATIC:
|
|
|
|
case BURNING2__STATIC:
|
2016-08-27 01:40:46 +00:00
|
|
|
if (sprite[pSprite->owner].picnum != TREE1 && sprite[pSprite->owner].picnum != TREE2)
|
2016-02-13 21:05:57 +00:00
|
|
|
t->z = actor[t->owner].floorz;
|
|
|
|
t->shade = -127;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case SMALLSMOKE__STATIC:
|
2019-12-26 06:28:08 +00:00
|
|
|
t->clipdist |= TSPR_FLAGS_DRAW_LAST | TSPR_FLAGS_NO_SHADOW;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case COOLEXPLOSION1__STATIC:
|
|
|
|
t->shade = -127;
|
2019-12-26 06:28:08 +00:00
|
|
|
t->clipdist |= TSPR_FLAGS_DRAW_LAST | TSPR_FLAGS_NO_SHADOW;
|
2016-08-27 01:40:46 +00:00
|
|
|
t->picnum += (pSprite->shade>>1);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case PLAYERONWATER__STATIC:
|
2019-05-19 19:57:10 +00:00
|
|
|
t->shade = sprite[pSprite->owner].shade;
|
|
|
|
if (haveAction)
|
|
|
|
break;
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(pSprite->picnum,pSprite->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
frameOffset = 0;
|
2010-08-02 08:13:51 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<5>(t->cstat, t->ang - oura);
|
2012-08-06 20:00:29 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum = pSprite->picnum+frameOffset+((T1(i)<4)*5);
|
2010-08-02 08:13:51 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case WATERSPLASH2__STATIC:
|
|
|
|
// WATERSPLASH_T2
|
2016-08-27 01:40:35 +00:00
|
|
|
t->picnum = WATERSPLASH2+T2(i);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case SHELL__STATIC:
|
2016-08-27 01:40:46 +00:00
|
|
|
t->picnum = pSprite->picnum+(T1(i)&1);
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2016-02-13 21:05:57 +00:00
|
|
|
case SHOTGUNSHELL__STATIC:
|
|
|
|
t->cstat |= 12;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (T1(i) > 2) t->cstat &= ~16;
|
|
|
|
else if (T1(i) > 1) t->cstat &= ~4;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case FRAMEEFFECT1_13__STATIC:
|
|
|
|
if (PLUTOPAK) break;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2018-07-21 00:18:03 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
case FRAMEEFFECT1__STATIC:
|
2016-08-27 01:40:46 +00:00
|
|
|
if (pSprite->owner >= 0 && sprite[pSprite->owner].statnum < MAXSTATUS)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
if (sprite[pSprite->owner].picnum == APLAYER)
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.camerasprite == -1)
|
2016-08-27 01:40:46 +00:00
|
|
|
if (screenpeek == P_Get(pSprite->owner) && display_mirror == 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
t->owner = -1;
|
|
|
|
break;
|
|
|
|
}
|
2016-08-27 01:40:46 +00:00
|
|
|
if ((sprite[pSprite->owner].cstat&32768) == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
if (!actor[pSprite->owner].dispicnum)
|
2016-02-13 21:05:57 +00:00
|
|
|
t->picnum = actor[i].t_data[1];
|
2016-08-27 01:40:46 +00:00
|
|
|
else t->picnum = actor[pSprite->owner].dispicnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!G_MaybeTakeOnFloorPal(t, sect))
|
2016-08-27 01:40:46 +00:00
|
|
|
t->pal = sprite[pSprite->owner].pal;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
t->shade = sprite[pSprite->owner].shade;
|
|
|
|
t->ang = sprite[pSprite->owner].ang;
|
|
|
|
t->cstat = 2|sprite[pSprite->owner].cstat;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case CAMERA1__STATIC:
|
|
|
|
case RAT__STATIC:
|
2019-05-19 19:57:10 +00:00
|
|
|
if (haveAction)
|
|
|
|
break;
|
2019-07-06 17:54:43 +00:00
|
|
|
if (tilehasmodelorvoxel(pSprite->picnum,pSprite->pal) && !(spriteext[i].flags&SPREXT_NOTMD))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
t->cstat &= ~4;
|
|
|
|
break;
|
|
|
|
}
|
2017-06-27 11:01:30 +00:00
|
|
|
frameOffset = getofs_viewtype_mirrored<5>(t->cstat, t->ang - oura);
|
2016-08-27 01:40:56 +00:00
|
|
|
t->picnum = pSprite->picnum+frameOffset;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
actor[i].dispicnum = t->picnum;
|
|
|
|
#if 0
|
|
|
|
// why?
|
|
|
|
if (sector[t->sectnum].floorpicnum == MIRROR)
|
|
|
|
t->xrepeat = t->yrepeat = 0;
|
|
|
|
#endif
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (VM_HaveEvent(EVENT_ANIMATESPRITES))
|
|
|
|
{
|
|
|
|
for (j = spritesortcnt-1; j>=0; j--)
|
|
|
|
G_DoEventAnimSprites(j);
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LUNATIC
|
2019-06-25 11:30:17 +00:00
|
|
|
VM_OnEvent(EVENT_ANIMATEALLSPRITES);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
g_spriteStat.numonscreen = spritesortcnt;
|
|
|
|
#endif
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void G_InitTimer(int32_t ticspersec)
|
|
|
|
{
|
|
|
|
if (g_timerTicsPerSecond != ticspersec)
|
|
|
|
{
|
2018-04-12 21:02:51 +00:00
|
|
|
timerUninit();
|
|
|
|
timerInit(ticspersec);
|
2016-02-13 21:05:57 +00:00
|
|
|
g_timerTicsPerSecond = ticspersec;
|
|
|
|
}
|
|
|
|
}
|
2012-06-03 15:46:08 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static int32_t g_RTSPlaying;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Returns: started playing?
|
2019-12-16 18:18:03 +00:00
|
|
|
int G_StartRTS(int lumpNum, int localPlayer)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-10-28 21:19:50 +00:00
|
|
|
if (!adult_lockout && SoundEnabled() &&
|
2019-10-22 00:01:05 +00:00
|
|
|
RTS_IsInitialized() && g_RTSPlaying == 0 && (snd_speech & (localPlayer ? 1 : 4)))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-12-16 18:18:03 +00:00
|
|
|
auto sid = RTS_GetSoundID(lumpNum - 1);
|
|
|
|
if (sid != -1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-12-16 23:29:38 +00:00
|
|
|
S_PlaySound(sid, CHAN_AUTO, CHANF_UI);
|
2016-02-13 21:05:57 +00:00
|
|
|
g_RTSPlaying = 7;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2009-12-14 20:14:12 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2009-07-04 09:28:21 +00:00
|
|
|
|
2019-10-22 21:31:46 +00:00
|
|
|
// Trying to sanitize the mess of options and the mess of variables the mess was stored in. (Did I say this was a total mess before...? >) )
|
|
|
|
// Hopefully this is more comprehensible, at least it neatly stores everything useful in a single linear value...
|
2019-11-03 11:32:58 +00:00
|
|
|
bool GameInterface::validate_hud(int layout)
|
2019-10-22 21:31:46 +00:00
|
|
|
{
|
|
|
|
if (layout <= 6) // Status bar with border
|
|
|
|
{
|
|
|
|
return !(ud.statusbarflags & STATUSBAR_NOSHRINK);
|
|
|
|
}
|
|
|
|
else if (layout == 7) // Status bar fullscreen
|
|
|
|
{
|
|
|
|
return (!(ud.statusbarflags & STATUSBAR_NOFULL) || !(ud.statusbarflags & STATUSBAR_NOOVERLAY));
|
|
|
|
}
|
|
|
|
else if (layout == 8) // Status bar overlay
|
|
|
|
{
|
|
|
|
return !(ud.statusbarflags & STATUSBAR_NOOVERLAY);
|
|
|
|
}
|
|
|
|
else if (layout == 9) // Fullscreen HUD
|
|
|
|
{
|
|
|
|
return (!(ud.statusbarflags & STATUSBAR_NOMINI) || !(ud.statusbarflags & STATUSBAR_NOMODERN));
|
|
|
|
}
|
|
|
|
else if (layout == 10)
|
|
|
|
{
|
|
|
|
return !(ud.statusbarflags & STATUSBAR_NOMODERN);
|
|
|
|
}
|
|
|
|
else if (layout == 11)
|
|
|
|
{
|
|
|
|
return !(ud.statusbarflags & STATUSBAR_NONONE);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-11-03 11:32:58 +00:00
|
|
|
void GameInterface::set_hud_layout(int layout)
|
2019-10-22 21:31:46 +00:00
|
|
|
{
|
|
|
|
static const uint8_t screen_size_vals[] = { 60, 54, 48, 40, 32, 24, 16, 8, 8, 4, 4, 0 };
|
|
|
|
if (validate_hud(layout))
|
|
|
|
{
|
|
|
|
ud.screen_size = screen_size_vals[layout];
|
|
|
|
ud.statusbarmode = layout >= 8;
|
|
|
|
ud.althud = layout >= 10;
|
|
|
|
G_UpdateScreenArea();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-03 11:32:58 +00:00
|
|
|
void GameInterface::set_hud_scale(int scale)
|
2019-10-22 21:31:46 +00:00
|
|
|
{
|
2020-02-05 18:06:36 +00:00
|
|
|
ud.statusbarscale = clamp(scale, 36, 100);
|
|
|
|
G_UpdateScreenArea();
|
2019-10-22 21:31:46 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void G_HandleLocalKeys(void)
|
|
|
|
{
|
|
|
|
// CONTROL_ProcessBinds();
|
2018-11-18 18:12:16 +00:00
|
|
|
auto &myplayer = *g_player[myconnectindex].ps;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.recstat == 2)
|
|
|
|
{
|
|
|
|
ControlInfo noshareinfo;
|
|
|
|
CONTROL_GetInput(&noshareinfo);
|
|
|
|
}
|
2007-03-08 21:07:10 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
|
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.UnboundKeyPressed(sc_F1) || inputState.UnboundKeyPressed(sc_F2) || cl_autovote)
|
2009-12-14 20:14:12 +00:00
|
|
|
{
|
2019-12-07 13:53:13 +00:00
|
|
|
G_AddUserQuote(GStrings("VoteCast"));
|
2019-11-03 23:53:55 +00:00
|
|
|
Net_SendMapVote(inputState.UnboundKeyPressed(sc_F1) || cl_autovote ? cl_autovote-1 : 0);
|
|
|
|
inputState.ClearKeyStatus(sc_F1);
|
|
|
|
inputState.ClearKeyStatus(sc_F2);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
if (!ALT_IS_PRESSED && ud.overhead_on == 0 && (myplayer.gm & MODE_TYPE) == 0)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Enlarge_Screen);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (!SHIFTS_IS_PRESSED)
|
|
|
|
{
|
2019-10-22 21:31:46 +00:00
|
|
|
if (G_ChangeHudLayout(1))
|
|
|
|
{
|
2019-12-16 23:29:38 +00:00
|
|
|
S_PlaySound(THUD, CHAN_AUTO, CHANF_UI);
|
2019-10-22 21:31:46 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2008-07-07 22:03:11 +00:00
|
|
|
else
|
|
|
|
{
|
2020-02-05 18:06:36 +00:00
|
|
|
hud_scale = hud_scale + 5;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
G_UpdateScreenArea();
|
|
|
|
}
|
2012-04-04 18:58:33 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Shrink_Screen))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Shrink_Screen);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (!SHIFTS_IS_PRESSED)
|
|
|
|
{
|
2019-10-22 21:31:46 +00:00
|
|
|
if (G_ChangeHudLayout(-1))
|
|
|
|
{
|
2019-12-16 23:29:38 +00:00
|
|
|
S_PlaySound(THUD, CHAN_AUTO, CHANF_UI);
|
2019-10-22 21:31:46 +00:00
|
|
|
}
|
2008-08-20 08:39:07 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
2020-02-05 18:06:36 +00:00
|
|
|
hud_scale = hud_scale - 5;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
Clear up handling of g_*NamePtr in the game.
The primary change is that things have been made memory-clean. Some of these
pointers may point to wildly different places during the course of the program
such as statically or dynamically allocated storage, the buffer returned by
getenv() (which must not be modified according to the docs), or an element of
argv[]. Consequently, we need to strdup, or better, dup_filename them if they
are ever to be passed to a function that modifies their pointed-to data.
Specifically:
- added statics or consts according to usage
- 3 new functions clear{Grp,Def,Script}NamePtr, only 'Def' one extern for now
- in G_CheckCommandLine, don't strip 'const'; use Bstrncpyz where appropriate
- remove multiple declarations
Also, warn if an application parameter has been ignored (not matched).
git-svn-id: https://svn.eduke32.com/eduke32@2561 1a8010ca-5511-0410-912e-c29ae57300e0
2012-03-28 19:44:00 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_UpdateScreenArea();
|
2008-08-20 08:39:07 +00:00
|
|
|
}
|
|
|
|
}
|
2006-12-12 08:46:32 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
if (myplayer.cheat_phase == 1 || (myplayer.gm & (MODE_MENU|MODE_TYPE)))
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_See_Coop_View) && (GTFLAGS(GAMETYPE_COOPVIEW) || ud.recstat == 2))
|
2014-06-16 23:17:11 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_See_Coop_View);
|
2016-02-13 21:05:57 +00:00
|
|
|
screenpeek = connectpoint2[screenpeek];
|
|
|
|
if (screenpeek == -1) screenpeek = 0;
|
|
|
|
g_restorePalette = -1;
|
2014-06-16 23:17:11 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1) && buttonMap.ButtonDown(gamefunc_Show_Opponents_Weapon))
|
2014-06-16 23:17:11 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Show_Opponents_Weapon);
|
2018-11-18 18:08:44 +00:00
|
|
|
ud.config.ShowWeapons = ud.showweapons = 1-ud.showweapons;
|
2018-11-18 18:12:16 +00:00
|
|
|
P_DoQuote(QUOTE_WEAPON_MODE_OFF-ud.showweapons, &myplayer);
|
2014-06-16 23:17:11 +00:00
|
|
|
}
|
2006-08-18 23:52:26 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Toggle_Crosshair))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Toggle_Crosshair);
|
2019-10-21 21:29:48 +00:00
|
|
|
cl_crosshair = !cl_crosshair;
|
|
|
|
P_DoQuote(QUOTE_CROSSHAIR_OFF-cl_crosshair, &myplayer);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2009-01-13 04:40:56 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (ud.overhead_on && buttonMap.ButtonDown(gamefunc_Map_Follow_Mode))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Map_Follow_Mode);
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.scrollmode = 1-ud.scrollmode;
|
|
|
|
if (ud.scrollmode)
|
|
|
|
{
|
|
|
|
ud.folx = g_player[screenpeek].ps->opos.x;
|
|
|
|
ud.foly = g_player[screenpeek].ps->opos.y;
|
2018-03-07 04:21:18 +00:00
|
|
|
ud.fola = fix16_to_int(g_player[screenpeek].ps->oq16ang);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2018-11-18 18:12:16 +00:00
|
|
|
P_DoQuote(QUOTE_MAP_FOLLOW_OFF+ud.scrollmode, &myplayer);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-08-18 23:52:26 +00:00
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.UnboundKeyPressed(sc_ScrollLock))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(sc_ScrollLock);
|
2006-04-18 19:23:53 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
switch (ud.recstat)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
if (SHIFTS_IS_PRESSED)
|
|
|
|
G_OpenDemoWrite();
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
G_CloseDemoWrite();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.recstat == 2)
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.GetKeyStatus(sc_Space))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(sc_Space);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_demo_paused = !g_demo_paused;
|
|
|
|
g_demo_rewind = 0;
|
2012-11-24 09:11:50 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_demo_paused)
|
2013-03-04 01:24:17 +00:00
|
|
|
FX_StopAllSounds();
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.GetKeyStatus(sc_Tab))
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(sc_Tab);
|
2016-02-13 21:05:57 +00:00
|
|
|
g_demo_showStats = !g_demo_showStats;
|
2010-05-02 23:27:30 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#if 0
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.GetKeyStatus(sc_kpad_Plus))
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
G_InitTimer(240);
|
|
|
|
}
|
2019-11-03 23:53:55 +00:00
|
|
|
else if (inputState.GetKeyStatus(sc_kpad_Minus))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
G_InitTimer(60);
|
|
|
|
}
|
|
|
|
else if (g_timerTicsPerSecond != 120)
|
|
|
|
{
|
|
|
|
G_InitTimer(120);
|
|
|
|
}
|
|
|
|
#endif
|
2014-09-30 04:05:07 +00:00
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.GetKeyStatus(sc_kpad_6))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(sc_kpad_6);
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
int const fwdTics = (15 << (int)ALT_IS_PRESSED) << (2 * (int)SHIFTS_IS_PRESSED);
|
|
|
|
g_demo_goalCnt = g_demo_paused ? g_demo_cnt + 1 : g_demo_cnt + REALGAMETICSPERSEC * fwdTics;
|
|
|
|
g_demo_rewind = 0;
|
2014-09-30 04:05:07 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_demo_goalCnt > g_demo_totalCnt)
|
|
|
|
g_demo_goalCnt = 0;
|
|
|
|
else
|
|
|
|
Demo_PrepareWarp();
|
|
|
|
}
|
2019-11-03 23:53:55 +00:00
|
|
|
else if (inputState.GetKeyStatus(sc_kpad_4))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(sc_kpad_4);
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
int const rewindTics = (15 << (int)ALT_IS_PRESSED) << (2 * (int)SHIFTS_IS_PRESSED);
|
|
|
|
g_demo_goalCnt = g_demo_paused ? g_demo_cnt - 1 : g_demo_cnt - REALGAMETICSPERSEC * rewindTics;
|
|
|
|
g_demo_rewind = 1;
|
2014-09-30 04:05:07 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_demo_goalCnt <= 0)
|
|
|
|
g_demo_goalCnt = 1;
|
2014-09-30 04:05:07 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Demo_PrepareWarp();
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2012-04-04 18:57:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (SHIFTS_IS_PRESSED || ALT_IS_PRESSED || WIN_IS_PRESSED)
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int ridiculeNum = 0;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// NOTE: sc_F1 .. sc_F10 are contiguous. sc_F11 is not sc_F10+1.
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j=sc_F1; j<=sc_F10; j++)
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.UnboundKeyPressed(j))
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.ClearKeyStatus(j);
|
2016-08-27 01:40:56 +00:00
|
|
|
ridiculeNum = j - sc_F1 + 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (ridiculeNum)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
if (SHIFTS_IS_PRESSED)
|
|
|
|
{
|
2019-10-27 07:14:58 +00:00
|
|
|
G_AddUserQuote(*CombatMacros[ridiculeNum-1]);
|
2019-11-01 06:26:49 +00:00
|
|
|
Net_SendTaunt(ridiculeNum);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
pus = NUMPAGES;
|
|
|
|
pub = NUMPAGES;
|
2007-02-05 01:33:08 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-05-19 19:29:23 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Not SHIFT -- that is, either some ALT or WIN.
|
2016-08-27 01:40:56 +00:00
|
|
|
if (G_StartRTS(ridiculeNum, 1))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-01 06:26:49 +00:00
|
|
|
Net_SendRTS(ridiculeNum);
|
2016-02-13 21:05:57 +00:00
|
|
|
pus = NUMPAGES;
|
|
|
|
pub = NUMPAGES;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2019-12-24 11:59:26 +00:00
|
|
|
else
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Third_Person_View))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
myplayer.over_shoulder_on = !myplayer.over_shoulder_on;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
CAMERADIST = 0;
|
2019-08-27 13:39:54 +00:00
|
|
|
CAMERACLOCK = (int32_t) totalclock;
|
2016-08-27 01:40:56 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
P_DoQuote(QUOTE_VIEW_MODE_OFF + myplayer.over_shoulder_on, &myplayer);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2014-03-22 09:23:55 +00:00
|
|
|
|
2006-12-14 04:13:19 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.overhead_on != 0)
|
|
|
|
{
|
2019-08-27 13:39:54 +00:00
|
|
|
int const timerOffset = ((int) totalclock - nonsharedtimer);
|
2016-08-27 01:40:56 +00:00
|
|
|
nonsharedtimer += timerOffset;
|
2009-03-14 02:55:39 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen))
|
2018-11-18 18:12:16 +00:00
|
|
|
myplayer.zoom += mulscale6(timerOffset, max<int>(myplayer.zoom, 256));
|
2009-03-14 02:55:39 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Shrink_Screen))
|
2018-11-18 18:12:16 +00:00
|
|
|
myplayer.zoom -= mulscale6(timerOffset, max<int>(myplayer.zoom, 256));
|
2011-06-25 16:37:10 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
myplayer.zoom = clamp(myplayer.zoom, 48, 2048);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2006-07-07 18:41:05 +00:00
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
#if 0 // fixme: We should not query Esc here, this needs to be done differently
|
2018-11-18 18:12:16 +00:00
|
|
|
if (I_EscapeTrigger() && ud.overhead_on && myplayer.newowner == -1)
|
2013-02-25 15:31:24 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
I_EscapeTriggerClear();
|
|
|
|
ud.last_overhead = ud.overhead_on;
|
2016-08-27 01:40:56 +00:00
|
|
|
ud.overhead_on = 0;
|
|
|
|
ud.scrollmode = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
G_UpdateScreenArea();
|
2013-02-25 15:31:24 +00:00
|
|
|
}
|
2019-12-24 11:59:26 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Map))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Map);
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.last_overhead != ud.overhead_on && ud.last_overhead)
|
2013-02-25 15:31:24 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.overhead_on = ud.last_overhead;
|
|
|
|
ud.last_overhead = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ud.overhead_on++;
|
|
|
|
if (ud.overhead_on == 3) ud.overhead_on = 0;
|
|
|
|
ud.last_overhead = ud.overhead_on;
|
2013-02-25 15:31:24 +00:00
|
|
|
}
|
2013-05-24 13:54:39 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_restorePalette = 1;
|
|
|
|
G_UpdateScreenArea();
|
|
|
|
}
|
2013-05-20 19:31:37 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Returns:
|
|
|
|
// 0: all OK
|
|
|
|
// -1: ID declaration was invalid:
|
|
|
|
static int32_t S_DefineMusic(const char *ID, const char *name)
|
2013-05-19 19:29:13 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
int32_t sel = MUS_FIRST_SPECIAL;
|
2013-05-19 19:29:13 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Bassert(ID != NULL);
|
2013-05-19 19:29:13 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!Bstrcmp(ID,"intro"))
|
|
|
|
{
|
|
|
|
// nothing
|
|
|
|
}
|
|
|
|
else if (!Bstrcmp(ID,"briefing"))
|
|
|
|
{
|
|
|
|
sel++;
|
|
|
|
}
|
|
|
|
else if (!Bstrcmp(ID,"loading"))
|
|
|
|
{
|
|
|
|
sel += 2;
|
|
|
|
}
|
2019-07-18 01:25:33 +00:00
|
|
|
else if (!Bstrcmp(ID,"usermap"))
|
|
|
|
{
|
|
|
|
sel += 3;
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
sel = G_GetMusicIdx(ID);
|
|
|
|
if (sel < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
2013-05-19 19:29:13 +00:00
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
mapList[sel].music = name;
|
|
|
|
return 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2013-05-19 19:29:13 +00:00
|
|
|
|
2017-01-01 13:23:29 +00:00
|
|
|
static int parsedefinitions_game(scriptfile *, int);
|
2013-02-25 15:31:24 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
static void parsedefinitions_game_include(const char *fileName, scriptfile *pScript, const char *cmdtokptr, int const firstPass)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
scriptfile *included = scriptfile_fromfile(fileName);
|
2013-06-02 14:07:56 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!included)
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
if (!Bstrcasecmp(cmdtokptr,"null") || pScript == NULL) // this is a bit overboard to prevent unused parameter warnings
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
// Printf("Warning: Failed including %s as module\n", fn);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
else
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Warning: Failed including %s on line %s:%d\n",
|
2016-02-13 21:05:57 +00:00
|
|
|
fn, script->filename,scriptfile_getlinum(script,cmdtokptr));
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
parsedefinitions_game(included, firstPass);
|
2016-02-13 21:05:57 +00:00
|
|
|
scriptfile_close(included);
|
|
|
|
}
|
|
|
|
}
|
2006-07-22 05:20:25 +00:00
|
|
|
|
2018-10-16 06:08:50 +00:00
|
|
|
static void parsedefinitions_game_animsounds(scriptfile *pScript, const char * blockEnd, char const * fileName, dukeanim_t * animPtr)
|
2017-06-25 11:24:23 +00:00
|
|
|
{
|
2019-12-25 08:51:44 +00:00
|
|
|
size_t numPairs = 0;
|
2017-06-25 11:24:23 +00:00
|
|
|
|
2019-12-25 08:51:44 +00:00
|
|
|
animPtr->Sounds.Clear();
|
2017-06-25 11:24:23 +00:00
|
|
|
|
|
|
|
int defError = 1;
|
|
|
|
uint16_t lastFrameNum = 1;
|
|
|
|
|
|
|
|
while (pScript->textptr < blockEnd)
|
|
|
|
{
|
|
|
|
int32_t frameNum;
|
|
|
|
int32_t soundNum;
|
|
|
|
|
|
|
|
// HACK: we've reached the end of the list
|
|
|
|
// (hack because it relies on knowledge of
|
|
|
|
// how scriptfile_* preprocesses the text)
|
|
|
|
if (blockEnd - pScript->textptr == 1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// would produce error when it encounters the closing '}'
|
|
|
|
// without the above hack
|
|
|
|
if (scriptfile_getnumber(pScript, &frameNum))
|
|
|
|
break;
|
|
|
|
|
|
|
|
defError = 1;
|
|
|
|
|
|
|
|
if (scriptfile_getsymbol(pScript, &soundNum))
|
|
|
|
break;
|
|
|
|
|
|
|
|
// frame numbers start at 1 for us
|
|
|
|
if (frameNum <= 0)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: frame number must be greater zero on line %s:%d\n", pScript->filename,
|
2017-06-25 11:24:23 +00:00
|
|
|
scriptfile_getlinum(pScript, pScript->ltextptr));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (frameNum < lastFrameNum)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: frame numbers must be in (not necessarily strictly)"
|
2017-06-25 11:24:23 +00:00
|
|
|
" ascending order (line %s:%d)\n",
|
|
|
|
pScript->filename, scriptfile_getlinum(pScript, pScript->ltextptr));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastFrameNum = frameNum;
|
|
|
|
|
2017-06-25 11:24:27 +00:00
|
|
|
if ((unsigned)soundNum >= MAXSOUNDS && soundNum != -1)
|
2017-06-25 11:24:23 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: sound number #%d invalid on line %s:%d\n", soundNum, pScript->filename,
|
2017-06-25 11:24:23 +00:00
|
|
|
scriptfile_getlinum(pScript, pScript->ltextptr));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
defError = 0;
|
|
|
|
|
2019-12-25 08:51:44 +00:00
|
|
|
animsound_t sound;
|
2017-06-25 11:24:23 +00:00
|
|
|
sound.frame = frameNum;
|
|
|
|
sound.sound = soundNum;
|
2019-12-25 08:51:44 +00:00
|
|
|
animPtr->Sounds.Push(sound);
|
2017-06-25 11:24:23 +00:00
|
|
|
|
|
|
|
++numPairs;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!defError)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
// Printf("Defined sound sequence for hi-anim \"%s\" with %d frame/sound pairs\n",
|
2017-06-25 11:24:23 +00:00
|
|
|
// hardcoded_anim_tokens[animnum].text, numpairs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Failed defining sound sequence for anim \"%s\".\n", fileName);
|
2017-06-25 11:24:23 +00:00
|
|
|
}
|
2019-12-25 08:51:44 +00:00
|
|
|
animPtr->Sounds.ShrinkToFit();
|
2017-06-25 11:24:23 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
static int parsedefinitions_game(scriptfile *pScript, int firstPass)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int token;
|
|
|
|
char *pToken;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static const tokenlist tokens[] =
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
{ "include", T_INCLUDE },
|
|
|
|
{ "#include", T_INCLUDE },
|
|
|
|
{ "includedefault", T_INCLUDEDEFAULT },
|
|
|
|
{ "#includedefault", T_INCLUDEDEFAULT },
|
|
|
|
{ "loadgrp", T_LOADGRP },
|
|
|
|
{ "cachesize", T_CACHESIZE },
|
|
|
|
{ "noautoload", T_NOAUTOLOAD },
|
|
|
|
{ "music", T_MUSIC },
|
|
|
|
{ "sound", T_SOUND },
|
|
|
|
{ "cutscene", T_CUTSCENE },
|
|
|
|
{ "animsounds", T_ANIMSOUNDS },
|
|
|
|
{ "renamefile", T_RENAMEFILE },
|
|
|
|
{ "globalgameflags", T_GLOBALGAMEFLAGS },
|
2019-08-09 08:21:19 +00:00
|
|
|
{ "newgamechoices", T_NEWGAMECHOICES },
|
2016-02-13 21:05:57 +00:00
|
|
|
};
|
2006-07-07 18:41:05 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
static const tokenlist soundTokens[] =
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-10-25 23:32:05 +00:00
|
|
|
{ "id", T_ID },
|
|
|
|
{ "file", T_FILE },
|
|
|
|
{ "minpitch", T_MINPITCH },
|
|
|
|
{ "maxpitch", T_MAXPITCH },
|
|
|
|
{ "priority", T_PRIORITY },
|
|
|
|
{ "type", T_TYPE },
|
|
|
|
{ "distance", T_DISTANCE },
|
|
|
|
{ "volume", T_VOLUME },
|
2016-02-13 21:05:57 +00:00
|
|
|
};
|
2006-07-22 00:53:20 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
static const tokenlist animTokens [] =
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-10-25 23:32:05 +00:00
|
|
|
{ "delay", T_DELAY },
|
|
|
|
{ "aspect", T_ASPECT },
|
|
|
|
{ "sounds", T_SOUND },
|
|
|
|
{ "forcefilter", T_FORCEFILTER },
|
2017-12-12 05:13:38 +00:00
|
|
|
{ "forcenofilter", T_FORCENOFILTER },
|
|
|
|
{ "texturefilter", T_TEXTUREFILTER },
|
2016-02-13 21:05:57 +00:00
|
|
|
};
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2019-08-09 08:21:19 +00:00
|
|
|
static const tokenlist newGameTokens[] =
|
|
|
|
{
|
|
|
|
{ "choice", T_CHOICE },
|
|
|
|
};
|
|
|
|
static const tokenlist newGameChoiceTokens[] =
|
|
|
|
{
|
|
|
|
{ "name", T_NAME },
|
|
|
|
{ "locked", T_LOCKED },
|
|
|
|
{ "hidden", T_HIDDEN },
|
|
|
|
{ "choice", T_CHOICE },
|
2019-08-14 09:02:07 +00:00
|
|
|
{ "usercontent", T_USERCONTENT },
|
2019-08-09 08:21:19 +00:00
|
|
|
};
|
|
|
|
static const tokenlist newGameSubchoiceTokens[] =
|
|
|
|
{
|
|
|
|
{ "name", T_NAME },
|
|
|
|
{ "locked", T_LOCKED },
|
|
|
|
{ "hidden", T_HIDDEN },
|
|
|
|
};
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
do
|
2006-11-16 23:06:16 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
token = getatoken(pScript, tokens, ARRAY_SIZE(tokens));
|
|
|
|
pToken = pScript->ltextptr;
|
|
|
|
|
|
|
|
switch (token)
|
2008-12-13 07:23:13 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
case T_LOADGRP:
|
2008-12-13 07:23:13 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
char *fileName;
|
2008-12-13 07:23:13 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!scriptfile_getstring(pScript,&fileName) && firstPass)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-11-01 08:30:28 +00:00
|
|
|
fileSystem.AddAdditionalFile(fileName);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case T_CACHESIZE:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
int32_t cacheSize;
|
|
|
|
|
|
|
|
if (scriptfile_getnumber(pScript, &cacheSize) || !firstPass)
|
|
|
|
break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case T_INCLUDE:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
char *fileName;
|
|
|
|
|
|
|
|
if (!scriptfile_getstring(pScript, &fileName))
|
|
|
|
parsedefinitions_game_include(fileName, pScript, pToken, firstPass);
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_INCLUDEDEFAULT:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
parsedefinitions_game_include(G_DefaultDefFile(), pScript, pToken, firstPass);
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_NOAUTOLOAD:
|
2016-08-27 01:40:56 +00:00
|
|
|
if (firstPass)
|
2019-10-27 08:38:55 +00:00
|
|
|
gNoAutoLoad = 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
case T_MUSIC:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
char *tokenPtr = pScript->ltextptr;
|
|
|
|
char *musicID = NULL;
|
|
|
|
char *fileName = NULL;
|
|
|
|
char *musicEnd;
|
|
|
|
|
|
|
|
if (scriptfile_getbraces(pScript, &musicEnd))
|
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
while (pScript->textptr < musicEnd)
|
2009-06-24 08:20:10 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (getatoken(pScript, soundTokens, ARRAY_SIZE(soundTokens)))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
case T_ID: scriptfile_getstring(pScript, &musicID); break;
|
|
|
|
case T_FILE: scriptfile_getstring(pScript, &fileName); break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2009-06-24 08:20:10 +00:00
|
|
|
}
|
2007-02-26 01:46:38 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!firstPass)
|
|
|
|
{
|
|
|
|
if (musicID==NULL)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: missing ID for music definition near line %s:%d\n",
|
2016-08-27 01:40:56 +00:00
|
|
|
pScript->filename, scriptfile_getlinum(pScript,tokenPtr));
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2008-12-13 07:23:13 +00:00
|
|
|
|
2019-12-07 09:31:27 +00:00
|
|
|
if (fileName == NULL || fileSystem.FileExists(fileName))
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (S_DefineMusic(musicID, fileName) == -1)
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: invalid music ID on line %s:%d\n", pScript->filename, scriptfile_getlinum(pScript, tokenPtr));
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case T_CUTSCENE:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
char *fileName = NULL;
|
|
|
|
|
|
|
|
scriptfile_getstring(pScript, &fileName);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
char *animEnd;
|
2013-06-13 21:17:03 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (scriptfile_getbraces(pScript, &animEnd))
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!firstPass)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
dukeanim_t *animPtr = Anim_Find(fileName);
|
2007-03-24 23:17:56 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (!animPtr)
|
2017-06-25 11:24:10 +00:00
|
|
|
{
|
|
|
|
animPtr = Anim_Create(fileName);
|
|
|
|
animPtr->framedelay = 10;
|
2017-12-12 05:13:38 +00:00
|
|
|
animPtr->frameflags = 0;
|
2017-06-25 11:24:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int32_t temp;
|
|
|
|
|
|
|
|
while (pScript->textptr < animEnd)
|
|
|
|
{
|
|
|
|
switch (getatoken(pScript, animTokens, ARRAY_SIZE(animTokens)))
|
|
|
|
{
|
|
|
|
case T_DELAY:
|
|
|
|
scriptfile_getnumber(pScript, &temp);
|
|
|
|
animPtr->framedelay = temp;
|
|
|
|
break;
|
2017-12-12 05:13:32 +00:00
|
|
|
case T_ASPECT:
|
|
|
|
{
|
|
|
|
double dtemp, dtemp2;
|
|
|
|
scriptfile_getdouble(pScript, &dtemp);
|
|
|
|
scriptfile_getdouble(pScript, &dtemp2);
|
|
|
|
animPtr->frameaspect1 = dtemp;
|
|
|
|
animPtr->frameaspect2 = dtemp2;
|
|
|
|
break;
|
|
|
|
}
|
2017-06-25 11:24:23 +00:00
|
|
|
case T_SOUND:
|
|
|
|
{
|
|
|
|
char *animSoundsEnd = NULL;
|
|
|
|
if (scriptfile_getbraces(pScript, &animSoundsEnd))
|
|
|
|
break;
|
|
|
|
parsedefinitions_game_animsounds(pScript, animSoundsEnd, fileName, animPtr);
|
|
|
|
break;
|
|
|
|
}
|
2017-12-12 05:13:38 +00:00
|
|
|
case T_FORCEFILTER:
|
|
|
|
animPtr->frameflags |= CUTSCENE_FORCEFILTER;
|
|
|
|
break;
|
|
|
|
case T_FORCENOFILTER:
|
|
|
|
animPtr->frameflags |= CUTSCENE_FORCENOFILTER;
|
|
|
|
break;
|
|
|
|
case T_TEXTUREFILTER:
|
|
|
|
animPtr->frameflags |= CUTSCENE_TEXTUREFILTER;
|
|
|
|
break;
|
2017-06-25 11:24:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2017-06-25 11:24:10 +00:00
|
|
|
else
|
2019-08-09 09:41:05 +00:00
|
|
|
pScript->textptr = animEnd+1;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case T_ANIMSOUNDS:
|
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
char *tokenPtr = pScript->ltextptr;
|
|
|
|
char *fileName = NULL;
|
2016-02-14 03:49:38 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
scriptfile_getstring(pScript, &fileName);
|
2017-06-25 11:24:23 +00:00
|
|
|
if (!fileName)
|
|
|
|
break;
|
2016-02-14 03:49:38 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
char *animSoundsEnd = NULL;
|
2016-02-13 21:06:31 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (scriptfile_getbraces(pScript, &animSoundsEnd))
|
2016-02-13 21:06:31 +00:00
|
|
|
break;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (firstPass)
|
2016-02-13 21:06:31 +00:00
|
|
|
{
|
2019-08-09 09:41:05 +00:00
|
|
|
pScript->textptr = animSoundsEnd+1;
|
2016-02-13 21:06:31 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-06-25 11:24:23 +00:00
|
|
|
dukeanim_t *animPtr = Anim_Find(fileName);
|
2008-12-13 07:23:13 +00:00
|
|
|
|
2017-06-25 11:24:23 +00:00
|
|
|
if (!animPtr)
|
2008-12-13 07:23:13 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: expected animation filename on line %s:%d\n",
|
2017-06-25 11:24:23 +00:00
|
|
|
pScript->filename, scriptfile_getlinum(pScript, tokenPtr));
|
2017-06-25 11:24:19 +00:00
|
|
|
break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2017-06-25 11:24:23 +00:00
|
|
|
parsedefinitions_game_animsounds(pScript, animSoundsEnd, fileName, animPtr);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2014-01-12 14:54:36 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
case T_SOUND:
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-10-25 23:32:05 +00:00
|
|
|
char *tokenPtr = pScript->ltextptr;
|
|
|
|
char *fileName = NULL;
|
|
|
|
char *musicEnd;
|
|
|
|
|
|
|
|
double volume = 1.0;
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int32_t soundNum = -1;
|
2018-10-25 23:32:05 +00:00
|
|
|
int32_t maxpitch = 0;
|
|
|
|
int32_t minpitch = 0;
|
|
|
|
int32_t priority = 0;
|
|
|
|
int32_t type = 0;
|
|
|
|
int32_t distance = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (scriptfile_getbraces(pScript, &musicEnd))
|
|
|
|
break;
|
|
|
|
|
|
|
|
while (pScript->textptr < musicEnd)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
switch (getatoken(pScript, soundTokens, ARRAY_SIZE(soundTokens)))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-10-25 23:32:05 +00:00
|
|
|
case T_ID: scriptfile_getsymbol(pScript, &soundNum); break;
|
|
|
|
case T_FILE: scriptfile_getstring(pScript, &fileName); break;
|
|
|
|
case T_MINPITCH: scriptfile_getsymbol(pScript, &minpitch); break;
|
|
|
|
case T_MAXPITCH: scriptfile_getsymbol(pScript, &maxpitch); break;
|
|
|
|
case T_PRIORITY: scriptfile_getsymbol(pScript, &priority); break;
|
|
|
|
case T_TYPE: scriptfile_getsymbol(pScript, &type); break;
|
|
|
|
case T_DISTANCE: scriptfile_getsymbol(pScript, &distance); break;
|
|
|
|
case T_VOLUME: scriptfile_getdouble(pScript, &volume); break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
|
|
|
|
if (!firstPass)
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
if (soundNum==-1)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: missing ID for sound definition near line %s:%d\n", pScript->filename, scriptfile_getlinum(pScript,tokenPtr));
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-12-07 09:31:27 +00:00
|
|
|
if (fileName == NULL || fileSystem.FileExists(fileName))
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
|
|
|
|
2018-10-25 23:32:05 +00:00
|
|
|
// maybe I should have just packed this into a sound_t and passed a reference...
|
|
|
|
if (S_DefineSound(soundNum, fileName, minpitch, maxpitch, priority, type, distance, volume) == -1)
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: invalid sound ID on line %s:%d\n", pScript->filename, scriptfile_getlinum(pScript,tokenPtr));
|
2006-09-10 17:40:34 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
break;
|
2016-08-27 01:40:56 +00:00
|
|
|
case T_GLOBALGAMEFLAGS: scriptfile_getnumber(pScript, &duke3d_globalflags); break;
|
2019-08-09 08:21:19 +00:00
|
|
|
case T_NEWGAMECHOICES:
|
|
|
|
{
|
|
|
|
char * newGameChoicesEnd;
|
|
|
|
if (scriptfile_getbraces(pScript,&newGameChoicesEnd))
|
|
|
|
break;
|
|
|
|
if (firstPass)
|
|
|
|
{
|
2019-08-09 09:41:05 +00:00
|
|
|
pScript->textptr = newGameChoicesEnd+1;
|
2019-08-09 08:21:19 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (pScript->textptr < newGameChoicesEnd)
|
|
|
|
{
|
|
|
|
switch (getatoken(pScript, newGameTokens, ARRAY_SIZE(newGameTokens)))
|
|
|
|
{
|
|
|
|
case T_CHOICE:
|
|
|
|
{
|
|
|
|
char * choicePtr = pScript->ltextptr;
|
|
|
|
char * choiceEnd;
|
|
|
|
int32_t choiceID;
|
|
|
|
if (scriptfile_getsymbol(pScript,&choiceID))
|
|
|
|
break;
|
|
|
|
if (scriptfile_getbraces(pScript,&choiceEnd))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ((unsigned)choiceID >= MAXMENUGAMEPLAYENTRIES)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: Maximum choices exceeded near line %s:%d\n",
|
2019-08-09 08:21:19 +00:00
|
|
|
pScript->filename, scriptfile_getlinum(pScript, choicePtr));
|
2019-08-09 09:41:05 +00:00
|
|
|
pScript->textptr = choiceEnd+1;
|
2019-08-09 08:21:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MenuGameplayStemEntry & stem = g_MenuGameplayEntries[choiceID];
|
|
|
|
stem = MenuGameplayStemEntry{};
|
|
|
|
MenuGameplayEntry & entry = stem.entry;
|
|
|
|
|
|
|
|
while (pScript->textptr < choiceEnd)
|
|
|
|
{
|
|
|
|
switch (getatoken(pScript, newGameChoiceTokens, ARRAY_SIZE(newGameChoiceTokens)))
|
|
|
|
{
|
|
|
|
case T_CHOICE:
|
|
|
|
{
|
|
|
|
char * subChoicePtr = pScript->ltextptr;
|
|
|
|
char * subChoiceEnd;
|
|
|
|
int32_t subChoiceID;
|
|
|
|
if (scriptfile_getsymbol(pScript,&subChoiceID))
|
|
|
|
break;
|
|
|
|
if (scriptfile_getbraces(pScript,&subChoiceEnd))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ((unsigned)subChoiceID >= MAXMENUGAMEPLAYENTRIES)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Error: Maximum subchoices exceeded near line %s:%d\n",
|
2019-08-09 08:21:19 +00:00
|
|
|
pScript->filename, scriptfile_getlinum(pScript, subChoicePtr));
|
2019-08-09 09:41:05 +00:00
|
|
|
pScript->textptr = subChoiceEnd+1;
|
2019-08-09 08:21:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MenuGameplayEntry & subentry = stem.subentries[subChoiceID];
|
|
|
|
subentry = MenuGameplayEntry{};
|
|
|
|
|
|
|
|
while (pScript->textptr < subChoiceEnd)
|
|
|
|
{
|
|
|
|
switch (getatoken(pScript, newGameSubchoiceTokens, ARRAY_SIZE(newGameSubchoiceTokens)))
|
|
|
|
{
|
|
|
|
case T_NAME:
|
|
|
|
{
|
|
|
|
char *name = NULL;
|
|
|
|
if (scriptfile_getstring(pScript, &name))
|
|
|
|
break;
|
|
|
|
|
|
|
|
memset(subentry.name, 0, ARRAY_SIZE(subentry.name));
|
|
|
|
strncpy(subentry.name, name, ARRAY_SIZE(subentry.name)-1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_LOCKED:
|
|
|
|
{
|
|
|
|
subentry.flags |= MGE_Locked;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_HIDDEN:
|
|
|
|
{
|
|
|
|
subentry.flags |= MGE_Hidden;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_NAME:
|
|
|
|
{
|
|
|
|
char *name = NULL;
|
|
|
|
if (scriptfile_getstring(pScript, &name))
|
|
|
|
break;
|
|
|
|
|
|
|
|
memset(entry.name, 0, ARRAY_SIZE(entry.name));
|
|
|
|
strncpy(entry.name, name, ARRAY_SIZE(entry.name)-1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_LOCKED:
|
|
|
|
{
|
|
|
|
entry.flags |= MGE_Locked;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case T_HIDDEN:
|
|
|
|
{
|
|
|
|
entry.flags |= MGE_Hidden;
|
|
|
|
break;
|
|
|
|
}
|
2019-08-14 09:02:07 +00:00
|
|
|
case T_USERCONTENT:
|
|
|
|
{
|
|
|
|
entry.flags |= MGE_UserContent;
|
|
|
|
break;
|
|
|
|
}
|
2019-08-09 08:21:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
case T_EOF: return 0;
|
|
|
|
default: break;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2007-01-30 09:03:51 +00:00
|
|
|
}
|
2016-08-27 01:40:56 +00:00
|
|
|
while (1);
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2013-07-13 21:04:52 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int loaddefinitions_game(const char *fileName, int32_t firstPass)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2016-08-27 01:40:56 +00:00
|
|
|
scriptfile *pScript = scriptfile_fromfile(fileName);
|
2013-07-13 21:04:52 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pScript)
|
|
|
|
parsedefinitions_game(pScript, firstPass);
|
2013-07-13 21:04:52 +00:00
|
|
|
|
2019-12-17 19:08:59 +00:00
|
|
|
if (userConfig.AddDefs) for (auto& m : *userConfig.AddDefs)
|
2018-02-17 22:30:39 +00:00
|
|
|
parsedefinitions_game_include(m, NULL, "null", firstPass);
|
2007-01-30 09:03:51 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (pScript)
|
|
|
|
scriptfile_close(pScript);
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
scriptfile_clearsymbols();
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
return 0;
|
2012-05-28 18:15:19 +00:00
|
|
|
}
|
|
|
|
|
2013-02-10 16:24:44 +00:00
|
|
|
|
2012-06-26 19:49:59 +00:00
|
|
|
|
2018-10-16 06:08:50 +00:00
|
|
|
static void G_FreeHashAnim(const char * /*string*/, intptr_t key)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2019-06-25 11:29:08 +00:00
|
|
|
Xfree((void *)key);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2012-05-01 12:40:08 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static void G_Cleanup(void)
|
|
|
|
{
|
|
|
|
int32_t i;
|
2013-09-10 22:41:19 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i=(MAXLEVELS*(MAXVOLUMES+1))-1; i>=0; i--) // +1 volume for "intro", "briefing" music
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
G_FreeMapState(i);
|
|
|
|
}
|
2008-07-22 09:05:34 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i=MAXPLAYERS-1; i>=0; i--)
|
2013-04-17 20:34:39 +00:00
|
|
|
{
|
2019-06-25 11:29:08 +00:00
|
|
|
Xfree(g_player[i].ps);
|
2019-07-08 00:41:17 +00:00
|
|
|
Xfree(g_player[i].input);
|
2013-04-17 20:34:39 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#if !defined LUNATIC
|
2019-06-25 11:29:08 +00:00
|
|
|
if (label != (char *)&sprite[0]) Xfree(label);
|
|
|
|
if (labelcode != (int32_t *)§or[0]) Xfree(labelcode);
|
2020-04-07 22:40:02 +00:00
|
|
|
if (labeltype != (uint8_t*)&wall[0]) Xfree(labeltype);
|
2019-06-25 11:29:08 +00:00
|
|
|
Xfree(apScript);
|
|
|
|
Xfree(bitptr);
|
2010-07-22 20:29:09 +00:00
|
|
|
|
2019-06-25 11:29:08 +00:00
|
|
|
// Xfree(MusicPtr);
|
2009-12-05 09:22:43 +00:00
|
|
|
|
2017-10-16 21:17:47 +00:00
|
|
|
Gv_Clear();
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
hash_free(&h_gamevars);
|
|
|
|
hash_free(&h_arrays);
|
|
|
|
hash_free(&h_labels);
|
2014-04-14 16:30:23 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2009-12-05 09:22:43 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
/*
|
|
|
|
===================
|
|
|
|
=
|
|
|
|
= ShutDown
|
|
|
|
=
|
|
|
|
===================
|
|
|
|
*/
|
2007-08-27 06:46:31 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void G_Shutdown(void)
|
|
|
|
{
|
|
|
|
}
|
2014-08-08 20:02:56 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
/*
|
|
|
|
===================
|
|
|
|
=
|
|
|
|
= G_Startup
|
|
|
|
=
|
|
|
|
===================
|
|
|
|
*/
|
2010-07-22 20:29:09 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static void G_CompileScripts(void)
|
|
|
|
{
|
|
|
|
#if !defined LUNATIC
|
|
|
|
label = (char *)&sprite[0]; // V8: 16384*44/64 = 11264 V7: 4096*44/64 = 2816
|
2020-04-05 06:40:11 +00:00
|
|
|
labelcode = (int32_t *)§or[0]; // V8: 4096*40/4 = 40960 V7: 1024*40/4 = 10240
|
|
|
|
labeltype = (uint8_t *)&wall[0]; // V8: 16384*32 = 524288 V7: 8192*32/4 = 262144
|
2010-08-02 08:13:51 +00:00
|
|
|
#endif
|
2008-10-18 12:37:26 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#if defined LUNATIC
|
|
|
|
Gv_Init();
|
|
|
|
C_InitProjectiles();
|
|
|
|
#else
|
|
|
|
C_Compile(G_ConFile());
|
2009-04-29 19:43:51 +00:00
|
|
|
|
2019-11-01 08:30:28 +00:00
|
|
|
if ((uint32_t)g_labelCnt > MAXSPRITES*sizeof(spritetype)/64) // see the arithmetic above for why
|
2016-02-13 21:05:57 +00:00
|
|
|
G_GameExit("Error: too many labels defined!");
|
2013-08-06 23:52:49 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
auto newlabel = (char *)Xmalloc(g_labelCnt << 6);
|
|
|
|
auto newlabelcode = (int32_t *)Xmalloc(g_labelCnt * sizeof(int32_t));
|
2020-04-05 06:40:11 +00:00
|
|
|
auto newlabeltype = (uint8_t *)Xmalloc(g_labelCnt * sizeof(uint8_t));
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
Bmemcpy(newlabel, label, g_labelCnt * 64);
|
|
|
|
Bmemcpy(newlabelcode, labelcode, g_labelCnt * sizeof(int32_t));
|
2020-04-05 06:40:11 +00:00
|
|
|
Bmemcpy(newlabeltype, labeltype, g_labelCnt * sizeof(uint8_t));
|
2010-08-02 08:13:51 +00:00
|
|
|
|
2018-11-18 18:14:33 +00:00
|
|
|
label = newlabel;
|
|
|
|
labelcode = newlabelcode;
|
|
|
|
labeltype = newlabeltype;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Bmemset(sprite, 0, MAXSPRITES*sizeof(spritetype));
|
|
|
|
Bmemset(sector, 0, MAXSECTORS*sizeof(sectortype));
|
|
|
|
Bmemset(wall, 0, MAXWALLS*sizeof(walltype));
|
|
|
|
|
2019-06-25 11:30:17 +00:00
|
|
|
VM_OnEvent(EVENT_INIT);
|
2010-08-02 08:13:51 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static inline void G_CheckGametype(void)
|
|
|
|
{
|
2019-11-09 18:15:03 +00:00
|
|
|
m_coop = clamp(*m_coop, 0, g_gametypeCnt-1);
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("%s\n",g_gametypeNames[m_coop]);
|
2019-11-09 18:15:03 +00:00
|
|
|
if (g_gametypeFlags[m_coop] & GAMETYPE_ITEMRESPAWN)
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.m_respawn_items = ud.m_respawn_inventory = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void G_PostLoadPalette(void)
|
|
|
|
{
|
|
|
|
if (!(duke3d_globalflags & DUKE3D_NO_PALETTE_CHANGES))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
// Make color index 255 of default/water/slime palette black.
|
|
|
|
if (basepaltable[BASEPAL] != NULL)
|
|
|
|
Bmemset(&basepaltable[BASEPAL][255*3], 0, 3);
|
|
|
|
if (basepaltable[WATERPAL] != NULL)
|
|
|
|
Bmemset(&basepaltable[WATERPAL][255*3], 0, 3);
|
|
|
|
if (basepaltable[SLIMEPAL] != NULL)
|
|
|
|
Bmemset(&basepaltable[SLIMEPAL][255*3], 0, 3);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!(duke3d_globalflags & DUKE3D_NO_HARDCODED_FOGPALS))
|
2018-04-12 21:03:12 +00:00
|
|
|
paletteSetupDefaultFog();
|
2006-12-04 02:10:18 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!(duke3d_globalflags & DUKE3D_NO_PALETTE_CHANGES))
|
2018-04-12 21:03:12 +00:00
|
|
|
paletteFixTranslucencyMask();
|
2015-03-27 12:30:35 +00:00
|
|
|
|
2018-04-12 21:03:12 +00:00
|
|
|
palettePostLoadLookups();
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2015-11-25 12:08:28 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#define SETFLAG(Tilenum, Flag) g_tile[Tilenum].flags |= Flag
|
2013-04-08 18:30:39 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Has to be after setting the dynamic names (e.g. SHARK).
|
|
|
|
static void A_InitEnemyFlags(void)
|
|
|
|
{
|
2018-04-04 20:47:48 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:56 +00:00
|
|
|
int DukeEnemies[] = {
|
2016-02-13 21:05:57 +00:00
|
|
|
SHARK, RECON, DRONE,
|
|
|
|
LIZTROOPONTOILET, LIZTROOPJUSTSIT, LIZTROOPSTAYPUT, LIZTROOPSHOOT,
|
|
|
|
LIZTROOPJETPACK, LIZTROOPSHOOT, LIZTROOPDUCKING, LIZTROOPRUNNING, LIZTROOP,
|
|
|
|
OCTABRAIN, COMMANDER, COMMANDERSTAYPUT, PIGCOP, PIGCOPSTAYPUT, PIGCOPDIVE, EGG,
|
|
|
|
LIZMAN, LIZMANSPITTING, LIZMANJUMP, ORGANTIC,
|
|
|
|
BOSS1, BOSS2, BOSS3, BOSS4, RAT, ROTATEGUN };
|
2013-05-23 18:28:04 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
int SolidEnemies[] = { TANK, BOSS1, BOSS2, BOSS3, BOSS4, RECON, ROTATEGUN };
|
|
|
|
int NoWaterDipEnemies[] = { OCTABRAIN, COMMANDER, DRONE };
|
|
|
|
int GreenSlimeFoodEnemies[] = { LIZTROOP, LIZMAN, PIGCOP, NEWBEAST };
|
2006-04-17 07:53:31 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=GREENSLIME; i<=GREENSLIME+7; i++)
|
2016-02-13 21:05:57 +00:00
|
|
|
SETFLAG(i, SFLAG_HARDCODED_BADGUY);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=ARRAY_SIZE(DukeEnemies)-1; i>=0; i--)
|
2016-02-13 21:05:57 +00:00
|
|
|
SETFLAG(DukeEnemies[i], SFLAG_HARDCODED_BADGUY);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=ARRAY_SIZE(SolidEnemies)-1; i>=0; i--)
|
2016-02-13 21:05:57 +00:00
|
|
|
SETFLAG(SolidEnemies[i], SFLAG_NODAMAGEPUSH);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=ARRAY_SIZE(NoWaterDipEnemies)-1; i>=0; i--)
|
2016-02-13 21:05:57 +00:00
|
|
|
SETFLAG(NoWaterDipEnemies[i], SFLAG_NOWATERDIP);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=ARRAY_SIZE(GreenSlimeFoodEnemies)-1; i>=0; i--)
|
2016-02-13 21:05:57 +00:00
|
|
|
SETFLAG(GreenSlimeFoodEnemies[i], SFLAG_GREENSLIMEFOOD);
|
2020-03-29 08:41:12 +00:00
|
|
|
|
|
|
|
if (WORLDTOUR)
|
|
|
|
{
|
|
|
|
SETFLAG(FIREFLY, SFLAG_HARDCODED_BADGUY);
|
|
|
|
SETFLAG(BOSS5, SFLAG_NODAMAGEPUSH|SFLAG_HARDCODED_BADGUY);
|
|
|
|
SETFLAG(BOSS1STAYPUT, SFLAG_NODAMAGEPUSH|SFLAG_HARDCODED_BADGUY);
|
|
|
|
SETFLAG(BOSS2STAYPUT, SFLAG_NODAMAGEPUSH|SFLAG_HARDCODED_BADGUY);
|
|
|
|
SETFLAG(BOSS3STAYPUT, SFLAG_NODAMAGEPUSH|SFLAG_HARDCODED_BADGUY);
|
|
|
|
SETFLAG(BOSS4STAYPUT, SFLAG_NODAMAGEPUSH|SFLAG_HARDCODED_BADGUY);
|
|
|
|
SETFLAG(BOSS5STAYPUT, SFLAG_NODAMAGEPUSH|SFLAG_HARDCODED_BADGUY);
|
|
|
|
}
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
#undef SETFLAG
|
2012-08-13 18:25:32 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LUNATIC
|
|
|
|
// Will be used to store CON code translated to Lua.
|
|
|
|
int32_t g_elCONSize;
|
|
|
|
char *g_elCON; // NOT 0-terminated!
|
2007-02-11 00:49:03 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
LUNATIC_EXTERN void El_SetCON(const char *conluacode)
|
|
|
|
{
|
|
|
|
int32_t slen = Bstrlen(conluacode);
|
2007-10-24 06:48:13 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_elCON = (char *)Xmalloc(slen);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_elCONSize = slen;
|
|
|
|
Bmemcpy(g_elCON, conluacode, slen);
|
|
|
|
}
|
2013-01-19 18:28:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void El_CreateGameState(void)
|
|
|
|
{
|
|
|
|
int32_t i;
|
2013-01-19 18:28:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
El_DestroyState(&g_ElState);
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if ((i = El_CreateState(&g_ElState, "game")))
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Lunatic: Error initializing global ELua state (code %d)\n", i);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2010-01-24 23:33:17 +00:00
|
|
|
{
|
2017-02-01 10:20:54 +00:00
|
|
|
extern const char luaJIT_BC__defs_game[];
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2017-02-01 10:20:54 +00:00
|
|
|
if ((i = L_RunString(&g_ElState, luaJIT_BC__defs_game,
|
|
|
|
LUNATIC_DEFS_BC_SIZE, "_defs_game.lua")))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Lunatic: Error preparing global ELua state (code %d)\n", i);
|
2016-02-13 21:05:57 +00:00
|
|
|
El_DestroyState(&g_ElState);
|
|
|
|
}
|
2010-01-24 23:33:17 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (i)
|
|
|
|
G_GameExit("Failure setting up Lunatic!");
|
2011-07-21 22:39:29 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
# if !defined DEBUGGINGAIDS
|
|
|
|
El_ClearErrors();
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
#endif
|
2015-09-23 17:54:42 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Throw in everything here that needs to be called after a Lua game state
|
|
|
|
// recreation (or on initial startup in a non-Lunatic build.)
|
|
|
|
void G_PostCreateGameState(void)
|
|
|
|
{
|
|
|
|
Net_SendClientInfo();
|
|
|
|
A_InitEnemyFlags();
|
|
|
|
}
|
2015-09-23 17:54:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static void G_Startup(void)
|
|
|
|
{
|
|
|
|
int32_t i;
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2018-04-12 21:02:51 +00:00
|
|
|
timerInit(TICRATE);
|
2019-10-19 23:41:35 +00:00
|
|
|
timerSetCallback(gameTimerHandler);
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_CompileScripts();
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2018-04-12 21:03:47 +00:00
|
|
|
if (engineInit())
|
2016-02-13 21:05:57 +00:00
|
|
|
G_FatalEngineError();
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef LUNATIC
|
|
|
|
El_CreateGameState();
|
|
|
|
C_InitQuotes();
|
|
|
|
#endif
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_InitDynamicTiles();
|
|
|
|
G_InitDynamicSounds();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// These depend on having the dynamic tile and/or sound mappings set up:
|
|
|
|
G_InitMultiPsky(CLOUDYOCEAN, MOONSKY1, BIGORBIT1, LA);
|
|
|
|
Gv_FinalizeWeaponDefaults();
|
|
|
|
G_PostCreateGameState();
|
|
|
|
#ifdef LUNATIC
|
|
|
|
// NOTE: This is only effective for CON-defined EVENT_INIT. See EVENT_INIT
|
2017-02-01 10:20:54 +00:00
|
|
|
// not in _defs_game.lua.
|
2019-06-25 11:30:17 +00:00
|
|
|
VM_OnEvent(EVENT_INIT);
|
2016-02-13 21:05:57 +00:00
|
|
|
#endif
|
|
|
|
if (g_netServer || ud.multimode > 1) G_CheckGametype();
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2019-10-28 21:19:50 +00:00
|
|
|
if (userConfig.CommandMap.IsNotEmpty())
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-12-11 00:11:35 +00:00
|
|
|
FString startupMap;
|
2016-02-13 21:05:57 +00:00
|
|
|
if (VOLUMEONE)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("The -map option is available in the registered version only!\n");
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-11 00:11:35 +00:00
|
|
|
startupMap = userConfig.CommandMap;
|
|
|
|
if (startupMap.IndexOfAny("/\\") < 0) startupMap.Insert(0, "/");
|
|
|
|
DefaultExtension(startupMap, ".map");
|
|
|
|
startupMap.Substitute("\\", "/");
|
|
|
|
NormalizeFileName(startupMap);
|
2010-10-28 20:17:22 +00:00
|
|
|
|
2019-12-11 00:11:35 +00:00
|
|
|
if (fileSystem.FileExists(startupMap))
|
2019-10-20 21:37:07 +00:00
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Using level: \"%s\".\n",startupMap.GetChars());
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Level \"%s\" not found.\n",startupMap.GetChars());
|
2016-02-13 21:05:57 +00:00
|
|
|
boardfilename[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
2019-12-11 00:11:35 +00:00
|
|
|
strncpy(boardfilename, startupMap, BMAX_PATH);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-01-08 01:32:50 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
for (i=0; i<MAXPLAYERS; i++)
|
|
|
|
g_player[i].pingcnt = 0;
|
2014-05-31 12:26:41 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Net_GetPackets();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (numplayers > 1)
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Multiplayer initialized.\n");
|
2015-03-08 07:58:36 +00:00
|
|
|
|
2019-10-15 18:02:37 +00:00
|
|
|
if (TileFiles.artLoadFiles("tiles%03i.art") < 0)
|
2018-11-18 18:09:04 +00:00
|
|
|
G_GameExit("Failed loading art.");
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Make the fullscreen nuke logo background non-fullbright. Has to be
|
|
|
|
// after dynamic tile remapping (from C_Compile) and loading tiles.
|
|
|
|
picanm[LOADSCREEN].sf |= PICANM_NOFULLBRIGHT_BIT;
|
|
|
|
|
2020-04-11 21:45:45 +00:00
|
|
|
// Printf("Loading palette/lookups...\n");
|
2016-02-13 21:05:57 +00:00
|
|
|
G_LoadLookups();
|
|
|
|
|
|
|
|
screenpeek = myconnectindex;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
static void P_SetupMiscInputSettings(void)
|
|
|
|
{
|
2019-07-08 00:41:25 +00:00
|
|
|
auto ps = g_player[myconnectindex].ps;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-12-05 00:08:35 +00:00
|
|
|
ps->aim_mode = in_mousemode;
|
2019-10-21 22:05:21 +00:00
|
|
|
ps->auto_aim = cl_autoaim;
|
2019-10-22 00:31:14 +00:00
|
|
|
ps->weaponswitch = cl_weaponswitch;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void G_UpdatePlayerFromMenu(void)
|
|
|
|
{
|
|
|
|
if (ud.recstat != 0)
|
|
|
|
return;
|
|
|
|
|
2018-11-18 18:09:09 +00:00
|
|
|
auto &p = *g_player[myconnectindex].ps;
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (numplayers > 1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
Net_SendClientInfo();
|
2018-11-18 18:09:09 +00:00
|
|
|
if (sprite[p.i].picnum == APLAYER && sprite[p.i].pal != 1)
|
|
|
|
sprite[p.i].pal = g_player[myconnectindex].pcolor;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
2018-11-18 18:09:09 +00:00
|
|
|
/*int32_t j = p.team;*/
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
P_SetupMiscInputSettings();
|
2019-12-04 00:38:51 +00:00
|
|
|
p.palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-11-09 18:15:03 +00:00
|
|
|
g_player[myconnectindex].pteam = playerteam;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:09:09 +00:00
|
|
|
if (sprite[p.i].picnum == APLAYER && sprite[p.i].pal != 1)
|
|
|
|
sprite[p.i].pal = g_player[myconnectindex].pcolor;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2009-11-01 20:30:09 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void G_BackToMenu(void)
|
|
|
|
{
|
|
|
|
boardfilename[0] = 0;
|
|
|
|
if (ud.recstat == 1) G_CloseDemoWrite();
|
2010-08-02 08:13:51 +00:00
|
|
|
ud.warp_on = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[myconnectindex].ps->gm = 0;
|
2019-11-23 22:05:24 +00:00
|
|
|
M_StartControlPanel(false);
|
2020-04-11 22:02:48 +00:00
|
|
|
M_SetMenu(NAME_Mainmenu);
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.keyFlushChars();
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
static int G_EndOfLevel(void)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2018-11-18 18:09:09 +00:00
|
|
|
auto &p = *g_player[myconnectindex].ps;
|
|
|
|
|
2019-12-10 21:22:59 +00:00
|
|
|
if ((currentLevel->flags & MI_FORCEEOG)) ud.eog = 1; // if the finished level says to end the game, end it!
|
|
|
|
STAT_Update(ud.eog);
|
2018-11-18 18:09:09 +00:00
|
|
|
P_SetGamePalette(&p, BASEPAL, 0);
|
|
|
|
P_UpdateScreenPal(&p);
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2018-11-18 18:09:09 +00:00
|
|
|
if (p.gm & MODE_EOL)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
G_CloseDemoWrite();
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
ready2send = 0;
|
|
|
|
|
2018-11-18 18:09:09 +00:00
|
|
|
if (p.player_par > 0 && (p.player_par < ud.playerbest || ud.playerbest < 0) && ud.display_bonus_screen == 1)
|
|
|
|
CONFIG_SetMapBestTime(g_loadedMapHack.md4, p.player_par);
|
2018-02-25 01:18:36 +00:00
|
|
|
|
2018-11-18 18:09:09 +00:00
|
|
|
if ((VM_OnEventWithReturn(EVENT_ENDLEVELSCREEN, p.i, myconnectindex, 0)) == 0 && ud.display_bonus_screen == 1)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2018-11-18 18:09:09 +00:00
|
|
|
int const ssize = ud.screen_size;
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.screen_size = 0;
|
|
|
|
G_UpdateScreenArea();
|
2018-11-18 18:09:09 +00:00
|
|
|
ud.screen_size = ssize;
|
2016-02-13 21:05:57 +00:00
|
|
|
G_BonusScreen(0);
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Clear potentially loaded per-map ART only after the bonus screens.
|
2018-04-12 21:03:30 +00:00
|
|
|
artClearMapArt();
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2019-12-10 21:22:59 +00:00
|
|
|
if (ud.eog || G_HaveUserMap() || (currentLevel->flags & MI_FORCEEOG))
|
2011-02-25 21:50:19 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.eog = 0;
|
|
|
|
if ((!g_netServer && ud.multimode < 2))
|
2011-02-25 21:50:19 +00:00
|
|
|
{
|
2017-06-24 21:18:06 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!VOLUMEALL)
|
|
|
|
G_DoOrderScreen();
|
2017-06-24 21:18:06 +00:00
|
|
|
#endif
|
2018-11-18 18:09:09 +00:00
|
|
|
p.gm = 0;
|
2019-11-23 22:05:24 +00:00
|
|
|
return 2;
|
2011-02-25 21:50:19 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
2011-02-25 21:50:19 +00:00
|
|
|
{
|
2019-11-09 18:15:03 +00:00
|
|
|
m_level_number = 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.level_number = 0;
|
2011-02-25 21:50:19 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.display_bonus_screen = 1;
|
|
|
|
ready2send = 0;
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (numplayers > 1)
|
2018-11-18 18:09:09 +00:00
|
|
|
p.gm = MODE_GAME;
|
2011-03-03 06:57:42 +00:00
|
|
|
|
2018-11-18 18:09:09 +00:00
|
|
|
if (G_EnterLevel(p.gm))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
return 2;
|
|
|
|
}
|
2010-01-24 23:33:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Net_WaitForServer();
|
|
|
|
return 1;
|
|
|
|
}
|
2009-10-25 23:25:38 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
void G_MaybeAllocPlayer(int32_t pnum)
|
|
|
|
{
|
|
|
|
if (g_player[pnum].ps == NULL)
|
|
|
|
g_player[pnum].ps = (DukePlayer_t *)Xcalloc(1, sizeof(DukePlayer_t));
|
2019-07-08 00:41:17 +00:00
|
|
|
if (g_player[pnum].input == NULL)
|
|
|
|
g_player[pnum].input = (input_t *)Xcalloc(1, sizeof(input_t));
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-23 03:59:26 +00:00
|
|
|
|
2019-12-24 17:53:29 +00:00
|
|
|
|
2017-01-05 05:29:51 +00:00
|
|
|
// TODO: reorder (net)actor_t to eliminate slop and update assertion
|
2017-06-23 03:59:39 +00:00
|
|
|
EDUKE32_STATIC_ASSERT(sizeof(actor_t)%4 == 0);
|
2016-02-13 21:05:57 +00:00
|
|
|
EDUKE32_STATIC_ASSERT(sizeof(DukePlayer_t)%4 == 0);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-11-06 13:12:50 +00:00
|
|
|
void app_loop();
|
|
|
|
|
2020-04-11 22:10:39 +00:00
|
|
|
static const char* actions[] = {
|
|
|
|
"Move_Forward",
|
|
|
|
"Move_Backward",
|
|
|
|
"Turn_Left",
|
|
|
|
"Turn_Right",
|
|
|
|
"Strafe",
|
|
|
|
"Fire",
|
|
|
|
"Open",
|
|
|
|
"Run",
|
|
|
|
"Alt_Fire", // Duke3D", Blood
|
|
|
|
"Jump",
|
|
|
|
"Crouch",
|
|
|
|
"Look_Up",
|
|
|
|
"Look_Down",
|
|
|
|
"Look_Left",
|
|
|
|
"Look_Right",
|
|
|
|
"Strafe_Left",
|
|
|
|
"Strafe_Right",
|
|
|
|
"Aim_Up",
|
|
|
|
"Aim_Down",
|
|
|
|
"Weapon_1",
|
|
|
|
"Weapon_2",
|
|
|
|
"Weapon_3",
|
|
|
|
"Weapon_4",
|
|
|
|
"Weapon_5",
|
|
|
|
"Weapon_6",
|
|
|
|
"Weapon_7",
|
|
|
|
"Weapon_8",
|
|
|
|
"Weapon_9",
|
|
|
|
"Weapon_10",
|
|
|
|
"Inventory",
|
|
|
|
"Inventory_Left",
|
|
|
|
"Inventory_Right",
|
|
|
|
"Holo_Duke", // Duke3D", RR
|
|
|
|
"Jetpack",
|
|
|
|
"NightVision",
|
|
|
|
"MedKit",
|
|
|
|
"TurnAround",
|
|
|
|
"SendMessage",
|
|
|
|
"Map",
|
|
|
|
"Shrink_Screen",
|
|
|
|
"Enlarge_Screen",
|
|
|
|
"Center_View",
|
|
|
|
"Holster_Weapon",
|
|
|
|
"Show_Opponents_Weapon",
|
|
|
|
"Map_Follow_Mode",
|
|
|
|
"See_Coop_View",
|
|
|
|
"Mouse_Aiming",
|
|
|
|
"Toggle_Crosshair",
|
|
|
|
"Steroids",
|
|
|
|
"Quick_Kick",
|
|
|
|
"Next_Weapon",
|
|
|
|
"Previous_Weapon",
|
|
|
|
"Dpad_Select",
|
|
|
|
"Dpad_Aiming",
|
|
|
|
"Last_Weapon",
|
|
|
|
"Alt_Weapon",
|
|
|
|
"Third_Person_View",
|
|
|
|
"Show_DukeMatch_Scores",
|
|
|
|
"Toggle_Crouch", // This is the last one used by EDuke32.
|
|
|
|
};
|
2019-11-03 11:32:58 +00:00
|
|
|
int GameInterface::app_main()
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-04-11 22:10:39 +00:00
|
|
|
buttonMap.SetButtons(actions, NUM_ACTIONS);
|
2016-08-27 01:42:01 +00:00
|
|
|
g_skillCnt = 4;
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.multimode = 1;
|
2019-10-28 21:19:50 +00:00
|
|
|
ud.m_monsters_off = userConfig.nomonsters;
|
2006-05-09 04:24:44 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// This needs to happen before G_CheckCommandLine() because G_GameExit()
|
|
|
|
// accesses g_player[0].
|
|
|
|
G_MaybeAllocPlayer(0);
|
2006-05-09 04:24:44 +00:00
|
|
|
|
2019-10-31 23:32:56 +00:00
|
|
|
G_CheckCommandLine();
|
2006-05-09 04:24:44 +00:00
|
|
|
|
2016-11-28 04:35:21 +00:00
|
|
|
CONFIG_ReadSetup();
|
2009-12-05 09:22:43 +00:00
|
|
|
|
2019-12-19 08:31:39 +00:00
|
|
|
hud_size.Callback();
|
2020-03-22 09:20:59 +00:00
|
|
|
hud_scale.Callback();
|
2019-12-15 16:16:11 +00:00
|
|
|
S_InitSound();
|
2006-08-31 19:05:23 +00:00
|
|
|
|
2019-10-31 22:25:21 +00:00
|
|
|
|
2017-01-18 22:21:08 +00:00
|
|
|
G_SetupCheats();
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (SHAREWARE)
|
|
|
|
g_Shareware = 1;
|
|
|
|
else
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2019-12-07 09:31:27 +00:00
|
|
|
if (fileSystem.FileExists("DUKESW.BIN")) // JBF 20030810
|
2019-10-20 21:37:07 +00:00
|
|
|
{
|
|
|
|
g_Shareware = 1;
|
|
|
|
}
|
|
|
|
}
|
2010-01-05 21:53:14 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// gotta set the proper title after we compile the CONs if this is the full version
|
2012-04-13 10:45:49 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_scriptDebug)
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("CON debugging activated (level %d).\n",g_scriptDebug);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifndef NETCODE_DISABLE
|
|
|
|
if (g_networkMode == NET_SERVER || g_networkMode == NET_DEDICATED_SERVER)
|
2012-04-13 10:45:49 +00:00
|
|
|
{
|
2020-02-03 20:06:03 +00:00
|
|
|
Net_InitNetwork();
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
numplayers = 1;
|
2016-08-27 01:42:01 +00:00
|
|
|
g_mostConcurrentPlayers = ud.multimode; // Lunatic needs this (player[] bound)
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!g_fakeMultiMode)
|
2007-08-25 01:05:00 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
connectpoint2[0] = -1;
|
|
|
|
}
|
|
|
|
else
|
2010-06-22 21:50:01 +00:00
|
|
|
{
|
2018-11-18 18:12:16 +00:00
|
|
|
for (int i=0; i<ud.multimode-1; i++)
|
2016-02-13 21:05:57 +00:00
|
|
|
connectpoint2[i] = i+1;
|
|
|
|
connectpoint2[ud.multimode-1] = -1;
|
2014-06-16 23:16:37 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
for (int i=1; i<ud.multimode; i++)
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[i].playerquitflag = 1;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Net_GetPackets();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// NOTE: Allocating the DukePlayer_t structs has to be before compiling scripts,
|
|
|
|
// because in Lunatic, the {pipe,trip}bomb* members are initialized.
|
2018-11-18 18:12:16 +00:00
|
|
|
for (int i=0; i<MAXPLAYERS; i++)
|
2016-02-13 21:05:57 +00:00
|
|
|
G_MaybeAllocPlayer(i);
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_Startup(); // a bunch of stuff including compiling cons
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[0].playerquitflag = 1;
|
2013-04-05 17:53:25 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
auto &myplayer = *g_player[myconnectindex].ps;
|
|
|
|
|
|
|
|
myplayer.palette = BASEPAL;
|
2012-04-04 18:56:16 +00:00
|
|
|
|
2016-08-29 19:11:47 +00:00
|
|
|
for (int i=1, j=numplayers; j<ud.multimode; j++)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-12-07 13:53:13 +00:00
|
|
|
Bsprintf(g_player[j].user_name,"%s %d", GStrings("PLAYER"),j+1);
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[j].ps->team = g_player[j].pteam = i;
|
|
|
|
g_player[j].ps->weaponswitch = 3;
|
|
|
|
g_player[j].ps->auto_aim = 0;
|
|
|
|
i = 1-i;
|
|
|
|
}
|
2012-04-04 18:56:16 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Anim_Init();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
const char *defsfile = G_DefFile();
|
2018-04-12 21:02:51 +00:00
|
|
|
uint32_t stime = timerGetTicks();
|
2016-02-13 21:05:57 +00:00
|
|
|
if (!loaddefinitionsfile(defsfile))
|
|
|
|
{
|
2018-04-12 21:02:51 +00:00
|
|
|
uint32_t etime = timerGetTicks();
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Definitions file \"%s\" loaded in %d ms.\n", defsfile, etime-stime);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2017-06-25 11:24:02 +00:00
|
|
|
loaddefinitions_game(defsfile, FALSE);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-11-01 18:25:42 +00:00
|
|
|
userConfig.AddDefs.reset();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-12-07 23:52:40 +00:00
|
|
|
cacheAllSounds();
|
|
|
|
|
2020-02-01 22:05:43 +00:00
|
|
|
enginePostInit();
|
2014-06-16 23:16:37 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_PostLoadPalette();
|
2012-04-04 18:56:16 +00:00
|
|
|
|
2018-04-12 21:03:30 +00:00
|
|
|
tileDelete(MIRROR);
|
2016-10-24 21:30:39 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
Gv_ResetSystemDefaults(); // called here to populate our fake tilesizx and tilesizy arrays presented to CON with sizes generated by dummytiles
|
2014-06-16 23:16:37 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (numplayers == 1 && boardfilename[0] != 0)
|
|
|
|
{
|
2019-11-09 18:15:03 +00:00
|
|
|
m_level_number = 7;
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.m_volume_number = 0;
|
2016-08-27 01:41:33 +00:00
|
|
|
ud.warp_on = 1;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2014-06-16 23:16:37 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// getnames();
|
2013-04-05 17:53:25 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_netServer || ud.multimode > 1)
|
|
|
|
{
|
|
|
|
if (ud.warp_on == 0)
|
2013-04-05 17:53:25 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.m_monsters_off = 1;
|
|
|
|
ud.m_player_skill = 0;
|
2013-04-05 17:53:25 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
g_mostConcurrentPlayers = ud.multimode; // XXX: redundant?
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.last_level = -1;
|
2014-06-16 23:16:37 +00:00
|
|
|
|
2019-11-01 08:30:28 +00:00
|
|
|
VM_OnEvent(EVENT_SETDEFAULTS, g_player[myconnectindex].ps->i, myconnectindex);
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
registerosdcommands();
|
2014-01-12 14:02:30 +00:00
|
|
|
|
2018-04-12 21:03:47 +00:00
|
|
|
int const clipMapError = engineLoadClipMaps();
|
2016-08-27 01:41:04 +00:00
|
|
|
if (clipMapError > 0)
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("There was an error loading the sprite clipping map (status %d).\n", clipMapError);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2019-12-24 15:09:43 +00:00
|
|
|
g_clipMapFiles.Reset();
|
2013-04-05 17:53:25 +00:00
|
|
|
|
2019-12-23 18:37:40 +00:00
|
|
|
if (g_networkMode != NET_DEDICATED_SERVER)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-12-23 18:37:40 +00:00
|
|
|
V_Init2();
|
2019-10-27 12:40:24 +00:00
|
|
|
videoSetPalette(0, myplayer.palette, 0);
|
2018-03-21 20:41:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check if the minifont will support lowercase letters (3136-3161)
|
|
|
|
// there is room for them in tiles012.art between "[\]^_." and "{|}~"
|
|
|
|
minitext_lowercase = 1;
|
2018-04-12 21:03:30 +00:00
|
|
|
|
2018-11-18 18:13:14 +00:00
|
|
|
for (int i = MINIFONT + ('a'-'!'); minitext_lowercase && i < MINIFONT + ('z'-'!') + 1; ++i)
|
2019-10-15 21:18:52 +00:00
|
|
|
minitext_lowercase &= (int)tileCheck(i);
|
2018-03-21 20:41:26 +00:00
|
|
|
|
|
|
|
if (g_networkMode != NET_DEDICATED_SERVER)
|
|
|
|
{
|
2017-11-22 05:23:23 +00:00
|
|
|
Menu_Init();
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
FX_StopAllSounds();
|
|
|
|
S_ClearSoundLocks();
|
2012-06-03 16:11:22 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// getpackets();
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
VM_OnEvent(EVENT_INITCOMPLETE);
|
2019-11-06 13:12:50 +00:00
|
|
|
|
|
|
|
app_loop();
|
2019-11-06 18:22:14 +00:00
|
|
|
return 0;
|
2019-11-06 13:12:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void app_loop()
|
|
|
|
{
|
|
|
|
auto &myplayer = *g_player[myconnectindex].ps;
|
2019-09-21 11:02:17 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
MAIN_LOOP_RESTART:
|
|
|
|
totalclock = 0;
|
|
|
|
ototalclock = 0;
|
|
|
|
lockclock = 0;
|
2014-01-12 14:05:23 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
myplayer.fta = 0;
|
2019-03-19 17:08:19 +00:00
|
|
|
for (int32_t & q : user_quote_time)
|
2018-10-25 23:33:40 +00:00
|
|
|
q = 0;
|
2014-01-12 14:05:23 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
if(g_netClient)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("Waiting for initial snapshot...");
|
2018-12-08 00:40:39 +00:00
|
|
|
Net_WaitForInitialSnapshot();
|
2019-01-12 00:21:53 +00:00
|
|
|
|
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
}
|
|
|
|
|
2017-10-16 03:32:26 +00:00
|
|
|
if (ud.warp_on == 1)
|
|
|
|
{
|
|
|
|
G_NewGame_EnterLevel();
|
|
|
|
// may change ud.warp_on in an error condition
|
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.warp_on == 0)
|
2014-01-12 14:05:23 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1) && boardfilename[0] != 0)
|
|
|
|
{
|
2019-11-09 18:15:03 +00:00
|
|
|
m_level_number = 7;
|
2018-11-18 18:12:16 +00:00
|
|
|
ud.m_volume_number = 0;
|
|
|
|
ud.m_respawn_monsters = !!(ud.m_player_skill == 4);
|
2014-01-12 14:05:23 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
for (int TRAVERSE_CONNECT(i))
|
2014-01-12 14:05:23 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
P_ResetWeapons(i);
|
|
|
|
P_ResetInventory(i);
|
2014-01-12 14:05:23 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
G_NewGame_EnterLevel();
|
|
|
|
|
|
|
|
Net_WaitForServer();
|
|
|
|
}
|
|
|
|
else if (g_networkMode != NET_DEDICATED_SERVER)
|
|
|
|
G_DisplayLogo();
|
|
|
|
|
|
|
|
if (g_networkMode != NET_DEDICATED_SERVER)
|
|
|
|
{
|
2019-11-23 22:05:24 +00:00
|
|
|
M_StartControlPanel(false);
|
2020-04-11 22:02:48 +00:00
|
|
|
M_SetMenu(NAME_Mainmenu);
|
2019-11-23 22:05:24 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (G_PlaybackDemo())
|
2014-01-12 14:05:23 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
FX_StopAllSounds();
|
|
|
|
g_noLogoAnim = 1;
|
|
|
|
goto MAIN_LOOP_RESTART;
|
2014-01-12 14:05:23 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
else G_UpdateScreenArea();
|
|
|
|
|
2019-11-23 22:05:24 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// G_GameExit(" "); ///
|
2014-01-12 14:05:23 +00:00
|
|
|
|
2018-11-18 18:08:44 +00:00
|
|
|
ud.showweapons = ud.config.ShowWeapons;
|
2016-02-13 21:05:57 +00:00
|
|
|
P_SetupMiscInputSettings();
|
2019-11-09 18:15:03 +00:00
|
|
|
g_player[myconnectindex].pteam = playerteam;
|
2014-01-12 14:05:23 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_gametypeFlags[ud.coop] & GAMETYPE_TDM)
|
2018-11-18 18:12:16 +00:00
|
|
|
myplayer.palookup = g_player[myconnectindex].pcolor = G_GetTeamPalette(g_player[myconnectindex].pteam);
|
2016-02-13 21:05:57 +00:00
|
|
|
else
|
|
|
|
{
|
2019-12-04 00:38:51 +00:00
|
|
|
if (playercolor) myplayer.palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor);
|
2018-11-18 18:12:16 +00:00
|
|
|
else myplayer.palookup = g_player[myconnectindex].pcolor;
|
2014-01-12 14:05:23 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
ud.warp_on = 0;
|
2019-10-28 00:12:31 +00:00
|
|
|
inputState.ClearKeyStatus(sc_Pause); // JBF: I hate the pause key
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
if(g_netClient)
|
|
|
|
{
|
|
|
|
ready2send = 1; // TESTING
|
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
do //main loop
|
2014-01-12 14:05:23 +00:00
|
|
|
{
|
2019-12-01 08:02:17 +00:00
|
|
|
gameHandleEvents();
|
2019-12-06 17:36:49 +00:00
|
|
|
if (myplayer.gm == MODE_DEMO)
|
|
|
|
{
|
|
|
|
M_ClearMenus();
|
|
|
|
goto MAIN_LOOP_RESTART;
|
|
|
|
}
|
2014-01-12 14:05:23 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// only allow binds to function if the player is actually in a game (not in a menu, typing, et cetera) or demo
|
2019-10-28 06:10:56 +00:00
|
|
|
inputState.SetBindsEnabled(!!(myplayer.gm & (MODE_GAME|MODE_DEMO)));
|
2015-02-08 08:03:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2019-11-05 19:07:16 +00:00
|
|
|
if (g_networkMode != NET_DEDICATED_SERVER)
|
2016-02-13 21:05:57 +00:00
|
|
|
G_HandleLocalKeys();
|
2015-02-08 08:03:30 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
OSD_DispatchQueued();
|
2015-02-08 08:03:30 +00:00
|
|
|
|
2019-10-19 23:45:49 +00:00
|
|
|
bool gameUpdate = false;
|
|
|
|
double gameUpdateStartTime = timerGetHiTicks();
|
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
while (((g_netClient || g_netServer) || (myplayer.gm & (MODE_MENU | MODE_DEMO)) == 0) && (int)(totalclock - ototalclock) >= TICSPERFRAME)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2020-03-27 11:17:01 +00:00
|
|
|
ototalclock += TICSPERFRAME;
|
2020-01-29 11:36:45 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
P_GetInput(myconnectindex);
|
2020-01-29 11:37:16 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
// this is where we fill the input_t struct that is actually processed by P_ProcessInput()
|
|
|
|
auto const pPlayer = g_player[myconnectindex].ps;
|
|
|
|
auto const q16ang = fix16_to_int(pPlayer->q16ang);
|
|
|
|
auto & input = inputfifo[0][myconnectindex];
|
2020-01-29 11:37:16 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
input = localInput;
|
|
|
|
input.fvel = mulscale9(localInput.fvel, sintable[(q16ang + 2560) & 2047]) +
|
|
|
|
mulscale9(localInput.svel, sintable[(q16ang + 2048) & 2047]);
|
|
|
|
input.svel = mulscale9(localInput.fvel, sintable[(q16ang + 2048) & 2047]) +
|
|
|
|
mulscale9(localInput.svel, sintable[(q16ang + 1536) & 2047]);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
if (!FURY)
|
|
|
|
{
|
|
|
|
input.fvel += pPlayer->fric.x;
|
|
|
|
input.svel += pPlayer->fric.y;
|
|
|
|
}
|
2019-10-19 23:45:49 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
localInput = {};
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
if (((!GUICapture && (myplayer.gm & MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1))
|
|
|
|
&& (myplayer.gm & MODE_GAME))
|
|
|
|
{
|
|
|
|
Net_GetPackets();
|
|
|
|
G_DoMoveThings();
|
2020-03-25 09:38:44 +00:00
|
|
|
}
|
2020-03-27 11:17:01 +00:00
|
|
|
}
|
2019-10-19 23:45:49 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
gameUpdate = true;
|
|
|
|
g_gameUpdateTime = timerGetHiTicks() - gameUpdateStartTime;
|
2019-10-19 23:45:49 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
if (g_gameUpdateAvgTime <= 0.0)
|
|
|
|
g_gameUpdateAvgTime = g_gameUpdateTime;
|
2018-05-08 17:32:11 +00:00
|
|
|
|
2020-03-27 11:17:01 +00:00
|
|
|
g_gameUpdateAvgTime
|
|
|
|
= ((GAMEUPDATEAVGTIMENUMSAMPLES - 1.f) * g_gameUpdateAvgTime + g_gameUpdateTime) / ((float)GAMEUPDATEAVGTIMENUMSAMPLES);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_DoCheats();
|
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
if (myplayer.gm & (MODE_EOL|MODE_RESTART))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
switch (G_EndOfLevel())
|
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
case 1: continue;
|
|
|
|
case 2: goto MAIN_LOOP_RESTART;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_networkMode == NET_DEDICATED_SERVER)
|
|
|
|
{
|
2019-12-29 16:04:38 +00:00
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2018-03-06 10:25:11 +00:00
|
|
|
else if (G_FPSLimit() || g_saveRequested)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2020-01-29 11:36:45 +00:00
|
|
|
if (!g_saveRequested)
|
|
|
|
{
|
|
|
|
P_GetInput(myconnectindex);
|
|
|
|
}
|
|
|
|
|
2019-08-27 13:39:54 +00:00
|
|
|
int const smoothRatio = calc_smoothratio(totalclock, ototalclock);
|
2008-11-14 19:55:48 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
G_DrawRooms(screenpeek, smoothRatio);
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() >= REND_POLYMOST)
|
2016-02-13 21:05:57 +00:00
|
|
|
G_DrawBackground();
|
2016-08-27 01:41:04 +00:00
|
|
|
G_DisplayRest(smoothRatio);
|
2019-06-25 18:34:56 +00:00
|
|
|
videoNextPage();
|
2018-05-08 17:32:11 +00:00
|
|
|
|
|
|
|
if (gameUpdate)
|
2019-11-10 10:42:25 +00:00
|
|
|
g_gameUpdateAndDrawTime = g_beforeSwapTime/* timerGetHiTicks()*/ - gameUpdateStartTime;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-03-06 10:25:11 +00:00
|
|
|
// handle CON_SAVE and CON_SAVENN
|
|
|
|
if (g_saveRequested)
|
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
inputState.keyFlushChars();
|
2018-04-12 21:02:51 +00:00
|
|
|
videoNextPage();
|
2018-03-06 10:25:11 +00:00
|
|
|
|
2019-11-30 18:23:54 +00:00
|
|
|
M_Autosave();
|
2018-03-06 10:25:11 +00:00
|
|
|
|
|
|
|
g_saveRequested = false;
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
if (myplayer.gm & MODE_DEMO)
|
2016-02-13 21:05:57 +00:00
|
|
|
goto MAIN_LOOP_RESTART;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
while (1);
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
int G_DoMoveThings(void)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
ud.camerasprite = -1;
|
|
|
|
lockclock += TICSPERFRAME;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Moved lower so it is restored correctly by demo diffs:
|
|
|
|
//if (g_earthquakeTime > 0) g_earthquakeTime--;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_RTSPlaying > 0)
|
|
|
|
g_RTSPlaying--;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-03-19 17:08:19 +00:00
|
|
|
for (int32_t & i : user_quote_time)
|
2016-08-27 01:41:21 +00:00
|
|
|
{
|
2018-10-25 23:33:40 +00:00
|
|
|
if (i)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-10-23 23:30:33 +00:00
|
|
|
if (--i > hud_messagetime)
|
|
|
|
i = hud_messagetime;
|
2018-10-25 23:33:40 +00:00
|
|
|
if (!i) pub = NUMPAGES;
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
2016-08-27 01:41:21 +00:00
|
|
|
}
|
2020-02-06 22:00:39 +00:00
|
|
|
#ifndef NETCODE_DISABLE
|
2016-02-13 21:05:57 +00:00
|
|
|
// Name display when aiming at opponents
|
2019-10-21 23:00:22 +00:00
|
|
|
if (cl_idplayers && (g_netServer || ud.multimode > 1)
|
2016-02-13 21:05:57 +00:00
|
|
|
#ifdef SPLITSCREEN_MOD_HACKS
|
|
|
|
&& !g_fakeMultiMode
|
|
|
|
#endif
|
|
|
|
)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
hitdata_t hitData;
|
2019-07-08 00:41:25 +00:00
|
|
|
auto const pPlayer = g_player[screenpeek].ps;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t TRAVERSE_CONNECT(i))
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_player[i].ps->holoduke_on != -1)
|
|
|
|
sprite[g_player[i].ps->holoduke_on].cstat ^= 256;
|
2006-10-23 21:47:28 +00:00
|
|
|
|
2019-06-25 11:28:25 +00:00
|
|
|
hitscan(&pPlayer->pos, pPlayer->cursectnum, sintable[(fix16_to_int(pPlayer->q16ang) + 512) & 2047],
|
2018-03-07 04:21:18 +00:00
|
|
|
sintable[fix16_to_int(pPlayer->q16ang) & 2047], fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) << 11, &hitData,
|
|
|
|
0xffff0030);
|
2012-04-04 18:56:31 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t TRAVERSE_CONNECT(i))
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_player[i].ps->holoduke_on != -1)
|
|
|
|
sprite[g_player[i].ps->holoduke_on].cstat ^= 256;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:12:16 +00:00
|
|
|
if ((hitData.sprite >= 0) && (g_player[myconnectindex].ps->gm & MODE_MENU) == 0 &&
|
2016-08-27 01:41:04 +00:00
|
|
|
sprite[hitData.sprite].picnum == APLAYER)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
int const playerNum = P_Get(hitData.sprite);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
if (playerNum != screenpeek && g_player[playerNum].ps->dead_flag == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
if (pPlayer->fta == 0 || pPlayer->ftq == QUOTE_RESERVED3)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
if (ldist(&sprite[pPlayer->i], &sprite[hitData.sprite]) < 9216)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2019-12-03 23:28:28 +00:00
|
|
|
quoteMgr.InitializeQuote(QUOTE_RESERVED3, "%s", &g_player[playerNum].user_name[0]);
|
2016-08-27 01:41:04 +00:00
|
|
|
pPlayer->fta = 12, pPlayer->ftq = QUOTE_RESERVED3;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:41:04 +00:00
|
|
|
else if (pPlayer->fta > 2) pPlayer->fta -= 3;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-06 22:00:39 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_showShareware > 0)
|
|
|
|
{
|
|
|
|
g_showShareware--;
|
|
|
|
if (g_showShareware == 0)
|
|
|
|
{
|
|
|
|
pus = NUMPAGES;
|
|
|
|
pub = NUMPAGES;
|
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Moved lower so it is restored correctly by diffs:
|
|
|
|
// everyothertime++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-09-27 02:30:28 +00:00
|
|
|
if (g_netClient) // [75] The server should not overwrite its own randomseed
|
2016-02-13 21:05:57 +00:00
|
|
|
randomseed = ticrandomseed;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t TRAVERSE_CONNECT(i))
|
2019-07-08 00:41:17 +00:00
|
|
|
Bmemcpy(g_player[i].input, &inputfifo[(g_netServer && myconnectindex == i)][i], sizeof(input_t));
|
2006-10-23 21:47:28 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_UpdateInterpolations();
|
2006-10-23 21:47:28 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
/*
|
|
|
|
j = -1;
|
|
|
|
for (TRAVERSE_CONNECT(i))
|
|
|
|
{
|
|
|
|
if (g_player[i].playerquitflag == 0 || TEST_SYNC_KEY(g_player[i].sync->bits,SK_GAMEQUIT) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
j = i;
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
G_CloseDemoWrite();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[i].playerquitflag = 0;
|
|
|
|
}
|
|
|
|
*/
|
2006-10-23 21:47:28 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
g_moveThingsCount++;
|
2006-10-23 21:47:28 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.recstat == 1) G_DemoRecord();
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
everyothertime++;
|
|
|
|
if (g_earthquakeTime > 0) g_earthquakeTime--;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.pause_on == 0)
|
|
|
|
{
|
|
|
|
g_globalRandom = krand();
|
|
|
|
A_MoveDummyPlayers();//ST 13
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t TRAVERSE_CONNECT(i))
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
2019-07-06 16:30:43 +00:00
|
|
|
if (g_player[i].ps->team != g_player[i].pteam && g_gametypeFlags[ud.coop] & GAMETYPE_TDM)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
g_player[i].ps->team = g_player[i].pteam;
|
2019-07-06 16:30:43 +00:00
|
|
|
actor[g_player[i].ps->i].picnum = APLAYERTOP;
|
|
|
|
P_QuickKill(g_player[i].ps);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2019-07-06 16:30:43 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_gametypeFlags[ud.coop] & GAMETYPE_TDM)
|
2016-02-13 21:05:57 +00:00
|
|
|
g_player[i].ps->palookup = g_player[i].pcolor = G_GetTeamPalette(g_player[i].ps->team);
|
2010-11-23 22:30:27 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (sprite[g_player[i].ps->i].pal != 1)
|
|
|
|
sprite[g_player[i].ps->i].pal = g_player[i].pcolor;
|
|
|
|
|
|
|
|
P_HandleSharedKeys(i);
|
|
|
|
|
|
|
|
if (ud.pause_on == 0)
|
|
|
|
{
|
|
|
|
P_ProcessInput(i);
|
|
|
|
P_CheckSectors(i);
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (ud.pause_on == 0)
|
|
|
|
G_MoveWorld();
|
2015-03-08 07:58:06 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
// Net_CorrectPrediction();
|
2014-12-26 18:05:41 +00:00
|
|
|
|
2016-02-13 21:05:57 +00:00
|
|
|
if (g_netServer)
|
|
|
|
Net_SendServerUpdates();
|
|
|
|
|
|
|
|
if ((everyothertime&1) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-02-13 21:05:57 +00:00
|
|
|
G_AnimateWalls();
|
|
|
|
A_MoveCyclers();
|
2014-12-26 18:05:41 +00:00
|
|
|
|
2018-12-08 00:40:39 +00:00
|
|
|
if ((everyothertime % 10) == 0)
|
2017-07-05 05:42:37 +00:00
|
|
|
{
|
2018-12-08 00:40:39 +00:00
|
|
|
if(g_netServer)
|
|
|
|
{
|
|
|
|
Net_SendMapUpdate();
|
|
|
|
}
|
|
|
|
else if(g_netClient)
|
|
|
|
{
|
|
|
|
Net_StoreClientState();
|
|
|
|
}
|
2017-07-05 05:42:37 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (g_netClient) //Slave
|
|
|
|
Net_SendClientUpdate();
|
|
|
|
|
|
|
|
return 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:41:33 +00:00
|
|
|
void A_SpawnWallGlass(int spriteNum, int wallNum, int glassCnt)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
if (wallNum < 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j = glassCnt - 1; j >= 0; --j)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:04 +00:00
|
|
|
int const a = SA(spriteNum) - 256 + (krand() & 511) + 1024;
|
|
|
|
A_InsertSprite(SECT(spriteNum), SX(spriteNum), SY(spriteNum), SZ(spriteNum), GLASSPIECES + (j % 3), -32, 36, 36, a,
|
|
|
|
32 + (krand() & 63), 1024 - (krand() & 1023), spriteNum, 5);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
vec2_t v1 = { wall[wallNum].x, wall[wallNum].y };
|
|
|
|
vec2_t v = { wall[wall[wallNum].point2].x - v1.x, wall[wall[wallNum].point2].y - v1.y };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
v1.x -= ksgn(v.y);
|
|
|
|
v1.y += ksgn(v.x);
|
2016-08-27 01:41:04 +00:00
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
v.x = tabledivide32_noinline(v.x, glassCnt+1);
|
|
|
|
v.y = tabledivide32_noinline(v.y, glassCnt+1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:04 +00:00
|
|
|
int16_t sect = -1;
|
|
|
|
|
2019-05-19 03:56:13 +00:00
|
|
|
for (int j = glassCnt; j > 0; --j)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
v1.x += v.x;
|
|
|
|
v1.y += v.y;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
updatesector(v1.x,v1.y,§);
|
2006-11-13 23:12:47 +00:00
|
|
|
if (sect >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
int z = sector[sect].floorz - (krand() & (klabs(sector[sect].ceilingz - sector[sect].floorz)));
|
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (z < -ZOFFSET5 || z > ZOFFSET5)
|
2016-08-27 01:41:33 +00:00
|
|
|
z = SZ(spriteNum) - ZOFFSET5 + (krand() & ((64 << 8) - 1));
|
|
|
|
|
|
|
|
A_InsertSprite(SECT(spriteNum), v1.x, v1.y, z, GLASSPIECES + (j % 3), -32, 36, 36, SA(spriteNum) - 1024, 32 + (krand() & 63),
|
|
|
|
-(krand() & 1023), spriteNum, 5);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
void A_SpawnGlass(int spriteNum, int glassCnt)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
for (; glassCnt>0; glassCnt--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
int const k
|
|
|
|
= A_InsertSprite(SECT(spriteNum), SX(spriteNum), SY(spriteNum), SZ(spriteNum) - ((krand() & 16) << 8), GLASSPIECES + (glassCnt % 3),
|
|
|
|
krand() & 15, 36, 36, krand() & 2047, 32 + (krand() & 63), -512 - (krand() & 2047), spriteNum, 5);
|
|
|
|
sprite[k].pal = sprite[spriteNum].pal;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
void A_SpawnCeilingGlass(int spriteNum, int sectNum, int glassCnt)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
int const startWall = sector[sectNum].wallptr;
|
|
|
|
int const endWall = startWall+sector[sectNum].wallnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
for (bssize_t wallNum = startWall; wallNum < (endWall - 1); wallNum++)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
vec2_t v1 = { wall[wallNum].x, wall[wallNum].y };
|
|
|
|
vec2_t v = { tabledivide32_noinline(wall[wallNum + 1].x - v1.x, glassCnt + 1),
|
|
|
|
tabledivide32_noinline(wall[wallNum + 1].y - v1.y, glassCnt + 1) };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-05-19 03:56:13 +00:00
|
|
|
for (int j = glassCnt; j > 0; j--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
v1.x += v.x;
|
|
|
|
v1.y += v.y;
|
|
|
|
A_InsertSprite(sectNum, v1.x, v1.y, sector[sectNum].ceilingz + ((krand() & 15) << 8), GLASSPIECES + (j % 3), -32, 36, 36,
|
|
|
|
krand() & 2047, (krand() & 31), 0, spriteNum, 5);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
void A_SpawnRandomGlass(int spriteNum, int wallNum, int glassCnt)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
if (wallNum < 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
for (bssize_t j = glassCnt - 1; j >= 0; j--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
int const k
|
|
|
|
= A_InsertSprite(SECT(spriteNum), SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (krand() & (63 << 8)), GLASSPIECES + (j % 3),
|
|
|
|
-32, 36, 36, krand() & 2047, 32 + (krand() & 63), 1024 - (krand() & 2047), spriteNum, 5);
|
|
|
|
sprite[k].pal = krand() & 15;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
vec2_t v1 = { wall[wallNum].x, wall[wallNum].y };
|
|
|
|
vec2_t v = { tabledivide32_noinline(wall[wall[wallNum].point2].x - wall[wallNum].x, glassCnt + 1),
|
|
|
|
tabledivide32_noinline(wall[wall[wallNum].point2].y - wall[wallNum].y, glassCnt + 1) };
|
|
|
|
int16_t sectNum = sprite[spriteNum].sectnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-05-19 03:56:13 +00:00
|
|
|
for (int j = glassCnt; j > 0; j--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
v1.x += v.x;
|
|
|
|
v1.y += v.y;
|
|
|
|
|
|
|
|
updatesector(v1.x, v1.y, §Num);
|
|
|
|
|
|
|
|
int z = sector[sectNum].floorz - (krand() & (klabs(sector[sectNum].ceilingz - sector[sectNum].floorz)));
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:56 +00:00
|
|
|
if (z < -ZOFFSET5 || z > ZOFFSET5)
|
2016-08-27 01:41:33 +00:00
|
|
|
z = SZ(spriteNum) - ZOFFSET5 + (krand() & ((64 << 8) - 1));
|
|
|
|
|
|
|
|
int const k = A_InsertSprite(SECT(spriteNum), v1.x, v1.y, z, GLASSPIECES + (j % 3), -32, 36, 36, SA(spriteNum) - 1024,
|
|
|
|
32 + (krand() & 63), -(krand() & 2047), spriteNum, 5);
|
|
|
|
sprite[k].pal = krand() & 7;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-12-24 12:21:36 +00:00
|
|
|
#if 0
|
|
|
|
void GameInterface::SendMessage(const char* msg)
|
|
|
|
{
|
|
|
|
if ((g_netServer || ud.multimode > 1) && buttonMap.ButtonDown(gamefunc_SendMessage))
|
|
|
|
{
|
|
|
|
inputState.keyFlushChars();
|
|
|
|
buttonMap.ClearButton(gamefunc_SendMessage);
|
|
|
|
myplayer.gm |= MODE_TYPE;
|
|
|
|
typebuf[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
2019-12-24 17:53:29 +00:00
|
|
|
|
|
|
|
void nix()
|
2019-12-24 12:21:36 +00:00
|
|
|
{
|
|
|
|
int32_t const hitstate = I_EnterText(typebuf, 120, 0);
|
|
|
|
|
|
|
|
int32_t const y = ud.screen_size > 1 ? (200 - 58) << 16 : (200 - 35) << 16;
|
|
|
|
|
|
|
|
int32_t const width = mpgametextsize(typebuf, TEXT_LITERALESCAPE).x;
|
|
|
|
int32_t const fullwidth = width + textsc((tilesiz[SPINNINGNUKEICON].x << 15) + (2 << 16));
|
|
|
|
int32_t const text_x = fullwidth >= (320 << 16) ? (320 << 16) - fullwidth : mpgametext_x;
|
|
|
|
mpgametext(text_x, y, typebuf, 1, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, TEXT_YCENTER | TEXT_LITERALESCAPE);
|
|
|
|
int32_t const cursor_x = text_x + width + textsc((tilesiz[SPINNINGNUKEICON].x << 14) + (1 << 16));
|
|
|
|
rotatesprite_fs(cursor_x, y, textsc(32768), 0, SPINNINGNUKEICON + (((int32_t)totalclock >> 3) % 7),
|
|
|
|
4 - (sintable[((int32_t)totalclock << 4) & 2047] >> 11), 0, 2 | 8);
|
|
|
|
|
|
|
|
if (hitstate == 1)
|
|
|
|
{
|
|
|
|
inputState.ClearKeyStatus(sc_Enter);
|
|
|
|
if (Bstrlen(typebuf) == 0)
|
|
|
|
{
|
|
|
|
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE | MODE_SENDTOWHOM);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (cl_automsg)
|
|
|
|
{
|
|
|
|
if (SHIFTS_IS_PRESSED)
|
|
|
|
g_chatPlayer = -1;
|
|
|
|
else
|
|
|
|
g_chatPlayer = ud.multimode;
|
|
|
|
}
|
|
|
|
g_player[myconnectindex].ps->gm |= MODE_SENDTOWHOM;
|
|
|
|
}
|
|
|
|
else if (hitstate == -1)
|
|
|
|
g_player[myconnectindex].ps->gm &= ~(MODE_TYPE | MODE_SENDTOWHOM);
|
|
|
|
else
|
|
|
|
pub = NUMPAGES;
|
|
|
|
}
|
2019-12-24 17:53:29 +00:00
|
|
|
}
|
2019-12-24 12:21:36 +00:00
|
|
|
#endif
|
|
|
|
|
2019-12-24 17:53:29 +00:00
|
|
|
void GameInterface::FreeGameData()
|
|
|
|
{
|
|
|
|
G_Cleanup();
|
|
|
|
}
|
|
|
|
|
2020-01-01 08:49:06 +00:00
|
|
|
void GameInterface::UpdateScreenSize()
|
|
|
|
{
|
|
|
|
G_UpdateScreenArea();
|
|
|
|
}
|
|
|
|
|
2019-11-03 11:32:58 +00:00
|
|
|
::GameInterface* CreateInterface()
|
|
|
|
{
|
|
|
|
return new GameInterface;
|
|
|
|
}
|
2019-09-21 20:53:00 +00:00
|
|
|
|
|
|
|
END_DUKE_NS
|