mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-12 21:01:00 +00:00
Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2 into fix-fixedrem
This commit is contained in:
commit
ac7db85149
23 changed files with 418 additions and 263 deletions
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
||||||
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
|
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
|
||||||
# Version change is fine.
|
# Version change is fine.
|
||||||
project(SRB2
|
project(SRB2
|
||||||
VERSION 2.1.24
|
VERSION 2.1.25
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2.1.24.{branch}-{build}
|
version: 2.1.25.{branch}-{build}
|
||||||
os: MinGW
|
os: MinGW
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
|
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
|
||||||
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"
|
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
#define ASSET_HASH_PATCH_DTA "b04fd9624bfd94dc96dcf4f400f7deb4"
|
#define ASSET_HASH_PATCH_DTA "636BD1C9269629AEAC2C3C184754D471"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "lzf.h"
|
#include "lzf.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
#ifdef CLIENT_LOADINGSCREEN
|
#ifdef CLIENT_LOADINGSCREEN
|
||||||
// cl loading screen
|
// cl loading screen
|
||||||
|
@ -116,6 +117,9 @@ static UINT8 resynch_local_inprogress = false; // WE are desynched and getting p
|
||||||
static UINT8 player_joining = false;
|
static UINT8 player_joining = false;
|
||||||
UINT8 hu_resynching = 0;
|
UINT8 hu_resynching = 0;
|
||||||
|
|
||||||
|
UINT8 adminpassmd5[16];
|
||||||
|
boolean adminpasswordset = false;
|
||||||
|
|
||||||
// Client specific
|
// Client specific
|
||||||
static ticcmd_t localcmds;
|
static ticcmd_t localcmds;
|
||||||
static ticcmd_t localcmds2;
|
static ticcmd_t localcmds2;
|
||||||
|
@ -3760,6 +3764,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
XBOXSTATIC INT32 netconsole;
|
XBOXSTATIC INT32 netconsole;
|
||||||
XBOXSTATIC tic_t realend, realstart;
|
XBOXSTATIC tic_t realend, realstart;
|
||||||
XBOXSTATIC UINT8 *pak, *txtpak, numtxtpak;
|
XBOXSTATIC UINT8 *pak, *txtpak, numtxtpak;
|
||||||
|
XBOXSTATIC UINT8 finalmd5[16];/* Well, it's the cool thing to do? */
|
||||||
FILESTAMP
|
FILESTAMP
|
||||||
|
|
||||||
txtpak = NULL;
|
txtpak = NULL;
|
||||||
|
@ -3958,6 +3963,32 @@ FILESTAMP
|
||||||
textcmd[0] += (UINT8)netbuffer->u.textcmd[0];
|
textcmd[0] += (UINT8)netbuffer->u.textcmd[0];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PT_LOGIN:
|
||||||
|
if (client)
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef NOMD5
|
||||||
|
if (doomcom->datalength < 16)/* ignore partial sends */
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!adminpasswordset)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the final pass to compare with the sent md5
|
||||||
|
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5);
|
||||||
|
|
||||||
|
if (!memcmp(netbuffer->u.md5sum, finalmd5, 16))
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]);
|
||||||
|
COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case PT_NODETIMEOUT:
|
case PT_NODETIMEOUT:
|
||||||
case PT_CLIENTQUIT:
|
case PT_CLIENTQUIT:
|
||||||
if (client)
|
if (client)
|
||||||
|
@ -4841,3 +4872,29 @@ tic_t GetLag(INT32 node)
|
||||||
{
|
{
|
||||||
return gametic - nettics[node];
|
return gametic - nettics[node];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest)
|
||||||
|
{
|
||||||
|
#ifdef NOMD5
|
||||||
|
(void)buffer;
|
||||||
|
(void)len;
|
||||||
|
(void)salt;
|
||||||
|
memset(dest, 0, 16);
|
||||||
|
#else
|
||||||
|
XBOXSTATIC char tmpbuf[256];
|
||||||
|
const size_t sl = strlen(salt);
|
||||||
|
|
||||||
|
if (len > 256-sl)
|
||||||
|
len = 256-sl;
|
||||||
|
|
||||||
|
memcpy(tmpbuf, buffer, len);
|
||||||
|
memmove(&tmpbuf[len], salt, sl);
|
||||||
|
//strcpy(&tmpbuf[len], salt);
|
||||||
|
len += strlen(salt);
|
||||||
|
if (len < 256)
|
||||||
|
memset(&tmpbuf[len],0,256-len);
|
||||||
|
|
||||||
|
// Yes, we intentionally md5 the ENTIRE buffer regardless of size...
|
||||||
|
md5_buffer(tmpbuf, 256, dest);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -70,6 +70,9 @@ typedef enum
|
||||||
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
|
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
|
||||||
PT_RESYNCHING, // Packet sent to resync players.
|
PT_RESYNCHING, // Packet sent to resync players.
|
||||||
// Blocks game advance until synched.
|
// Blocks game advance until synched.
|
||||||
|
|
||||||
|
PT_LOGIN, // Login attempt from the client.
|
||||||
|
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||||
#endif
|
#endif
|
||||||
|
@ -398,6 +401,7 @@ typedef struct
|
||||||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
||||||
filetx_pak filetxpak; // 139 bytes
|
filetx_pak filetxpak; // 139 bytes
|
||||||
clientconfig_pak clientcfg; // 136 bytes
|
clientconfig_pak clientcfg; // 136 bytes
|
||||||
|
UINT8 md5sum[16];
|
||||||
serverinfo_pak serverinfo; // 1024 bytes
|
serverinfo_pak serverinfo; // 1024 bytes
|
||||||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
||||||
askinfo_pak askinfo; // 61 bytes
|
askinfo_pak askinfo; // 61 bytes
|
||||||
|
@ -526,5 +530,10 @@ void D_ResetTiccmds(void);
|
||||||
tic_t GetLag(INT32 node);
|
tic_t GetLag(INT32 node);
|
||||||
UINT8 GetFreeXCmdSize(void);
|
UINT8 GetFreeXCmdSize(void);
|
||||||
|
|
||||||
|
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
||||||
|
|
||||||
extern UINT8 hu_resynching;
|
extern UINT8 hu_resynching;
|
||||||
|
|
||||||
|
extern UINT8 adminpassmd5[16];
|
||||||
|
extern boolean adminpasswordset;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,18 +34,19 @@
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
|
#include "d_net.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "filesrch.h"
|
#include "filesrch.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "md5.h"
|
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
#include "m_cond.h"
|
#include "m_cond.h"
|
||||||
#include "m_anigif.h"
|
#include "m_anigif.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
#ifdef NETGAME_DEVMODE
|
#ifdef NETGAME_DEVMODE
|
||||||
#define CV_RESTRICT CV_NETVAR
|
#define CV_RESTRICT CV_NETVAR
|
||||||
|
@ -143,7 +144,6 @@ static void Command_Clearscores_f(void);
|
||||||
// Remote Administration
|
// Remote Administration
|
||||||
static void Command_Changepassword_f(void);
|
static void Command_Changepassword_f(void);
|
||||||
static void Command_Login_f(void);
|
static void Command_Login_f(void);
|
||||||
static void Got_Login(UINT8 **cp, INT32 playernum);
|
|
||||||
static void Got_Verification(UINT8 **cp, INT32 playernum);
|
static void Got_Verification(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_Removal(UINT8 **cp, INT32 playernum);
|
static void Got_Removal(UINT8 **cp, INT32 playernum);
|
||||||
static void Command_Verify_f(void);
|
static void Command_Verify_f(void);
|
||||||
|
@ -437,7 +437,6 @@ void D_RegisterServerCommands(void)
|
||||||
|
|
||||||
// Remote Administration
|
// Remote Administration
|
||||||
COM_AddCommand("password", Command_Changepassword_f);
|
COM_AddCommand("password", Command_Changepassword_f);
|
||||||
RegisterNetXCmd(XD_LOGIN, Got_Login);
|
|
||||||
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
||||||
COM_AddCommand("promote", Command_Verify_f);
|
COM_AddCommand("promote", Command_Verify_f);
|
||||||
RegisterNetXCmd(XD_VERIFIED, Got_Verification);
|
RegisterNetXCmd(XD_VERIFIED, Got_Verification);
|
||||||
|
@ -2652,35 +2651,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
// Attempts to make password system a little sane without
|
// Attempts to make password system a little sane without
|
||||||
// rewriting the entire goddamn XD_file system
|
// rewriting the entire goddamn XD_file system
|
||||||
//
|
//
|
||||||
#include "md5.h"
|
|
||||||
static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest)
|
|
||||||
{
|
|
||||||
#ifdef NOMD5
|
|
||||||
(void)buffer;
|
|
||||||
(void)len;
|
|
||||||
(void)salt;
|
|
||||||
memset(dest, 0, 16);
|
|
||||||
#else
|
|
||||||
XBOXSTATIC char tmpbuf[256];
|
|
||||||
const size_t sl = strlen(salt);
|
|
||||||
|
|
||||||
if (len > 256-sl)
|
|
||||||
len = 256-sl;
|
|
||||||
memcpy(tmpbuf, buffer, len);
|
|
||||||
memmove(&tmpbuf[len], salt, sl);
|
|
||||||
//strcpy(&tmpbuf[len], salt);
|
|
||||||
len += strlen(salt);
|
|
||||||
if (len < 256)
|
|
||||||
memset(&tmpbuf[len],0,256-len);
|
|
||||||
|
|
||||||
// Yes, we intentionally md5 the ENTIRE buffer regardless of size...
|
|
||||||
md5_buffer(tmpbuf, 256, dest);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BASESALT "basepasswordstorage"
|
#define BASESALT "basepasswordstorage"
|
||||||
static UINT8 adminpassmd5[16];
|
|
||||||
static boolean adminpasswordset = false;
|
|
||||||
|
|
||||||
void D_SetPassword(const char *pw)
|
void D_SetPassword(const char *pw)
|
||||||
{
|
{
|
||||||
|
@ -2718,7 +2689,6 @@ static void Command_Login_f(void)
|
||||||
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
|
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
|
||||||
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
|
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
|
||||||
#else
|
#else
|
||||||
XBOXSTATIC UINT8 finalmd5[16];
|
|
||||||
const char *pw;
|
const char *pw;
|
||||||
|
|
||||||
if (!netgame)
|
if (!netgame)
|
||||||
|
@ -2738,47 +2708,15 @@ static void Command_Login_f(void)
|
||||||
pw = COM_Argv(1);
|
pw = COM_Argv(1);
|
||||||
|
|
||||||
// Do the base pass to get what the server has (or should?)
|
// Do the base pass to get what the server has (or should?)
|
||||||
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &finalmd5);
|
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &netbuffer->u.md5sum);
|
||||||
|
|
||||||
// Do the final pass to get the comparison the server will come up with
|
// Do the final pass to get the comparison the server will come up with
|
||||||
D_MD5PasswordPass(finalmd5, 16, va("PNUM%02d", consoleplayer), &finalmd5);
|
D_MD5PasswordPass(netbuffer->u.md5sum, 16, va("PNUM%02d", consoleplayer), &netbuffer->u.md5sum);
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Sending login... (Notice only given if password is correct.)\n"));
|
CONS_Printf(M_GetText("Sending login... (Notice only given if password is correct.)\n"));
|
||||||
|
|
||||||
SendNetXCmd(XD_LOGIN, finalmd5, 16);
|
netbuffer->packettype = PT_LOGIN;
|
||||||
#endif
|
HSendPacket(servernode, true, 0, 16);
|
||||||
}
|
|
||||||
|
|
||||||
static void Got_Login(UINT8 **cp, INT32 playernum)
|
|
||||||
{
|
|
||||||
#ifdef NOMD5
|
|
||||||
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
|
|
||||||
(void)cp;
|
|
||||||
(void)playernum;
|
|
||||||
#else
|
|
||||||
UINT8 sentmd5[16], finalmd5[16];
|
|
||||||
|
|
||||||
READMEM(*cp, sentmd5, 16);
|
|
||||||
|
|
||||||
if (client)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!adminpasswordset)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[playernum]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the final pass to compare with the sent md5
|
|
||||||
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", playernum), &finalmd5);
|
|
||||||
|
|
||||||
if (!memcmp(sentmd5, finalmd5, 16))
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
|
|
||||||
COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4000,7 +3938,7 @@ static void Command_ExitLevel_f(void)
|
||||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
else if (!(server || (IsPlayerAdmin(consoleplayer))))
|
else if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
else if (gamestate != GS_LEVEL || demoplayback)
|
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
|
||||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||||
else
|
else
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||||
|
|
|
@ -125,8 +125,8 @@ typedef enum
|
||||||
XD_ADDPLAYER, // 10
|
XD_ADDPLAYER, // 10
|
||||||
XD_TEAMCHANGE, // 11
|
XD_TEAMCHANGE, // 11
|
||||||
XD_CLEARSCORES, // 12
|
XD_CLEARSCORES, // 12
|
||||||
XD_LOGIN, // 13
|
// UNUSED 13 (Because I don't want to change these comments)
|
||||||
XD_VERIFIED, // 14
|
XD_VERIFIED = 14,//14
|
||||||
XD_RANDOMSEED, // 15
|
XD_RANDOMSEED, // 15
|
||||||
XD_RUNSOC, // 16
|
XD_RUNSOC, // 16
|
||||||
XD_REQADDFILE, // 17
|
XD_REQADDFILE, // 17
|
||||||
|
|
|
@ -150,9 +150,9 @@ extern FILE *logstream;
|
||||||
// we use comprevision and compbranch instead.
|
// we use comprevision and compbranch instead.
|
||||||
#else
|
#else
|
||||||
#define VERSION 201 // Game version
|
#define VERSION 201 // Game version
|
||||||
#define SUBVERSION 24 // more precise version number
|
#define SUBVERSION 25 // more precise version number
|
||||||
#define VERSIONSTRING "v2.1.24"
|
#define VERSIONSTRING "v2.1.25"
|
||||||
#define VERSIONSTRINGW L"v2.1.24"
|
#define VERSIONSTRINGW L"v2.1.25"
|
||||||
// Hey! If you change this, add 1 to the MODVERSION below!
|
// Hey! If you change this, add 1 to the MODVERSION below!
|
||||||
// Otherwise we can't force updates!
|
// Otherwise we can't force updates!
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,7 +217,7 @@ extern FILE *logstream;
|
||||||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||||
// Only set it higher, not lower, obviously.
|
// Only set it higher, not lower, obviously.
|
||||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||||
#define MODVERSION 29
|
#define MODVERSION 30
|
||||||
|
|
||||||
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
|
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
|
||||||
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
|
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
|
||||||
|
|
|
@ -131,6 +131,7 @@ extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor
|
||||||
|
|
||||||
extern tic_t countdowntimer;
|
extern tic_t countdowntimer;
|
||||||
extern boolean countdowntimeup;
|
extern boolean countdowntimeup;
|
||||||
|
extern boolean exitfadestarted;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
12
src/g_game.c
12
src/g_game.c
|
@ -15,6 +15,7 @@
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
|
@ -130,6 +131,7 @@ UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE;
|
||||||
|
|
||||||
tic_t countdowntimer = 0;
|
tic_t countdowntimer = 0;
|
||||||
boolean countdowntimeup = false;
|
boolean countdowntimeup = false;
|
||||||
|
boolean exitfadestarted = false;
|
||||||
|
|
||||||
cutscene_t *cutscenes[128];
|
cutscene_t *cutscenes[128];
|
||||||
|
|
||||||
|
@ -1874,7 +1876,9 @@ boolean G_Responder(event_t *ev)
|
||||||
|
|
||||||
if (F_CreditResponder(ev))
|
if (F_CreditResponder(ev))
|
||||||
{
|
{
|
||||||
F_StartGameEvaluation();
|
// Skip credits for everyone
|
||||||
|
if (!netgame || server || IsPlayerAdmin(consoleplayer))
|
||||||
|
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2696,6 +2700,10 @@ void G_ExitLevel(void)
|
||||||
// Remove CEcho text on round end.
|
// Remove CEcho text on round end.
|
||||||
HU_ClearCEcho();
|
HU_ClearCEcho();
|
||||||
}
|
}
|
||||||
|
else if (gamestate == GS_CREDITS)
|
||||||
|
{
|
||||||
|
F_StartGameEvaluation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See also the enum GameType in doomstat.h
|
// See also the enum GameType in doomstat.h
|
||||||
|
@ -3694,7 +3702,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
{
|
{
|
||||||
// Clear a bunch of variables
|
// Clear a bunch of variables
|
||||||
tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
|
tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
|
||||||
countdown = countdown2 = 0;
|
countdown = countdown2 = exitfadestarted = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
|
97
src/p_map.c
97
src/p_map.c
|
@ -3345,6 +3345,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
||||||
boolean P_CheckSector(sector_t *sector, boolean crunch)
|
boolean P_CheckSector(sector_t *sector, boolean crunch)
|
||||||
{
|
{
|
||||||
msecnode_t *n;
|
msecnode_t *n;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
nofit = false;
|
nofit = false;
|
||||||
crushchange = crunch;
|
crushchange = crunch;
|
||||||
|
@ -3359,9 +3360,57 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
|
||||||
|
|
||||||
|
|
||||||
// First, let's see if anything will keep it from crushing.
|
// First, let's see if anything will keep it from crushing.
|
||||||
|
|
||||||
|
// Sal: This stupid function chain is required to fix polyobjects not being able to crush.
|
||||||
|
// Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead
|
||||||
|
validcount++;
|
||||||
|
|
||||||
|
for (i = 0; i < sector->linecount; i++)
|
||||||
|
{
|
||||||
|
if (sector->lines[i]->polyobj)
|
||||||
|
{
|
||||||
|
polyobj_t *po = sector->lines[i]->polyobj;
|
||||||
|
if (po->validcount == validcount)
|
||||||
|
continue; // skip if already checked
|
||||||
|
if (!(po->flags & POF_SOLID))
|
||||||
|
continue;
|
||||||
|
if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector
|
||||||
|
{
|
||||||
|
INT32 x, y;
|
||||||
|
po->validcount = validcount;
|
||||||
|
|
||||||
|
for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y)
|
||||||
|
{
|
||||||
|
for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x)
|
||||||
|
{
|
||||||
|
mobj_t *mo;
|
||||||
|
|
||||||
|
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mo = blocklinks[y * bmapwidth + x];
|
||||||
|
|
||||||
|
for (; mo; mo = mo->bnext)
|
||||||
|
{
|
||||||
|
// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
|
||||||
|
|
||||||
|
if (!P_MobjInsidePolyobj(po, mo))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!PIT_ChangeSector(mo, false))
|
||||||
|
{
|
||||||
|
nofit = true;
|
||||||
|
return nofit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sector->numattached)
|
if (sector->numattached)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
sector_t *sec;
|
sector_t *sec;
|
||||||
for (i = 0; i < sector->numattached; i++)
|
for (i = 0; i < sector->numattached; i++)
|
||||||
{
|
{
|
||||||
|
@ -3421,9 +3470,53 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
|
||||||
} while (n); // repeat from scratch until all things left are marked valid
|
} while (n); // repeat from scratch until all things left are marked valid
|
||||||
|
|
||||||
// Nothing blocked us, so lets crush for real!
|
// Nothing blocked us, so lets crush for real!
|
||||||
|
|
||||||
|
// Sal: This stupid function chain is required to fix polyobjects not being able to crush.
|
||||||
|
// Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead
|
||||||
|
validcount++;
|
||||||
|
|
||||||
|
for (i = 0; i < sector->linecount; i++)
|
||||||
|
{
|
||||||
|
if (sector->lines[i]->polyobj)
|
||||||
|
{
|
||||||
|
polyobj_t *po = sector->lines[i]->polyobj;
|
||||||
|
if (po->validcount == validcount)
|
||||||
|
continue; // skip if already checked
|
||||||
|
if (!(po->flags & POF_SOLID))
|
||||||
|
continue;
|
||||||
|
if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector
|
||||||
|
{
|
||||||
|
INT32 x, y;
|
||||||
|
po->validcount = validcount;
|
||||||
|
|
||||||
|
for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y)
|
||||||
|
{
|
||||||
|
for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x)
|
||||||
|
{
|
||||||
|
mobj_t *mo;
|
||||||
|
|
||||||
|
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mo = blocklinks[y * bmapwidth + x];
|
||||||
|
|
||||||
|
for (; mo; mo = mo->bnext)
|
||||||
|
{
|
||||||
|
// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
|
||||||
|
|
||||||
|
if (!P_MobjInsidePolyobj(po, mo))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PIT_ChangeSector(mo, true);
|
||||||
|
return nofit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (sector->numattached)
|
if (sector->numattached)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
sector_t *sec;
|
sector_t *sec;
|
||||||
for (i = 0; i < sector->numattached; i++)
|
for (i = 0; i < sector->numattached; i++)
|
||||||
{
|
{
|
||||||
|
|
212
src/p_maputl.c
212
src/p_maputl.c
|
@ -418,10 +418,6 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
if (front->ffloors || back->ffloors)
|
if (front->ffloors || back->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
fixed_t highestceiling = highceiling;
|
|
||||||
fixed_t lowestceiling = opentop;
|
|
||||||
fixed_t highestfloor = openbottom;
|
|
||||||
fixed_t lowestfloor = lowfloor;
|
|
||||||
fixed_t delta1, delta2;
|
fixed_t delta1, delta2;
|
||||||
|
|
||||||
// Check for frontsector's fake floors
|
// Check for frontsector's fake floors
|
||||||
|
@ -437,15 +433,15 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
|
|
||||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
if (bottomheight < lowestceiling && delta1 >= delta2)
|
if (bottomheight < opentop && delta1 >= delta2)
|
||||||
lowestceiling = bottomheight;
|
opentop = bottomheight;
|
||||||
else if (bottomheight < highestceiling && delta1 >= delta2)
|
else if (bottomheight < highceiling && delta1 >= delta2)
|
||||||
highestceiling = bottomheight;
|
highceiling = bottomheight;
|
||||||
|
|
||||||
if (topheight > highestfloor && delta1 < delta2)
|
if (topheight > openbottom && delta1 < delta2)
|
||||||
highestfloor = topheight;
|
openbottom = topheight;
|
||||||
else if (topheight > lowestfloor && delta1 < delta2)
|
else if (topheight > lowfloor && delta1 < delta2)
|
||||||
lowestfloor = topheight;
|
lowfloor = topheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for backsectors fake floors
|
// Check for backsectors fake floors
|
||||||
|
@ -461,28 +457,16 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
|
|
||||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
if (bottomheight < lowestceiling && delta1 >= delta2)
|
if (bottomheight < opentop && delta1 >= delta2)
|
||||||
lowestceiling = bottomheight;
|
opentop = bottomheight;
|
||||||
else if (bottomheight < highestceiling && delta1 >= delta2)
|
else if (bottomheight < highceiling && delta1 >= delta2)
|
||||||
highestceiling = bottomheight;
|
highceiling = bottomheight;
|
||||||
|
|
||||||
if (topheight > highestfloor && delta1 < delta2)
|
if (topheight > openbottom && delta1 < delta2)
|
||||||
highestfloor = topheight;
|
openbottom = topheight;
|
||||||
else if (topheight > lowestfloor && delta1 < delta2)
|
else if (topheight > lowfloor && delta1 < delta2)
|
||||||
lowestfloor = topheight;
|
lowfloor = topheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highestceiling < highceiling)
|
|
||||||
highceiling = highestceiling;
|
|
||||||
|
|
||||||
if (highestfloor > openbottom)
|
|
||||||
openbottom = highestfloor;
|
|
||||||
|
|
||||||
if (lowestceiling < opentop)
|
|
||||||
opentop = lowestceiling;
|
|
||||||
|
|
||||||
if (lowestfloor > lowfloor)
|
|
||||||
lowfloor = lowestfloor;
|
|
||||||
}
|
}
|
||||||
openrange = opentop - openbottom;
|
openrange = opentop - openbottom;
|
||||||
return;
|
return;
|
||||||
|
@ -500,23 +484,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Treat polyobjects kind of like 3D Floors
|
|
||||||
#ifdef POLYOBJECTS
|
|
||||||
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
|
|
||||||
{
|
|
||||||
front = linedef->frontsector;
|
|
||||||
back = linedef->frontsector;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
front = linedef->frontsector;
|
front = linedef->frontsector;
|
||||||
back = linedef->backsector;
|
back = linedef->backsector;
|
||||||
}
|
|
||||||
|
|
||||||
I_Assert(front != NULL);
|
I_Assert(front != NULL);
|
||||||
I_Assert(back != NULL);
|
I_Assert(back != NULL);
|
||||||
|
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
if (linedef->polyobj)
|
||||||
|
{
|
||||||
|
// set these defaults so that polyobjects don't interfere with collision above or below them
|
||||||
|
opentop = INT32_MAX;
|
||||||
|
openbottom = INT32_MIN;
|
||||||
|
highceiling = INT32_MIN;
|
||||||
|
lowfloor = INT32_MAX;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
opentopslope = openbottomslope = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
{ // Set open and high/low values here
|
{ // Set open and high/low values here
|
||||||
fixed_t frontheight, backheight;
|
fixed_t frontheight, backheight;
|
||||||
|
|
||||||
|
@ -622,25 +609,49 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for fake floors in the sector.
|
|
||||||
if (front->ffloors || back->ffloors
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|| linedef->polyobj
|
if (linedef->polyobj)
|
||||||
|
{
|
||||||
|
// Treat polyobj's backsector like a 3D Floor
|
||||||
|
if (linedef->polyobj->flags & POF_TESTHEIGHT)
|
||||||
|
{
|
||||||
|
const sector_t *polysec = linedef->backsector;
|
||||||
|
fixed_t polytop, polybottom;
|
||||||
|
fixed_t delta1, delta2;
|
||||||
|
|
||||||
|
if (linedef->polyobj->flags & POF_CLIPPLANES)
|
||||||
|
{
|
||||||
|
polytop = polysec->ceilingheight;
|
||||||
|
polybottom = polysec->floorheight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
polytop = INT32_MAX;
|
||||||
|
polybottom = INT32_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
delta1 = abs(mobj->z - (polybottom + ((polytop - polybottom)/2)));
|
||||||
|
delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2)));
|
||||||
|
|
||||||
|
if (polybottom < opentop && delta1 >= delta2)
|
||||||
|
opentop = polybottom;
|
||||||
|
else if (polybottom < highceiling && delta1 >= delta2)
|
||||||
|
highceiling = polybottom;
|
||||||
|
|
||||||
|
if (polytop > openbottom && delta1 < delta2)
|
||||||
|
openbottom = polytop;
|
||||||
|
else if (polytop > lowfloor && delta1 < delta2)
|
||||||
|
lowfloor = polytop;
|
||||||
|
}
|
||||||
|
// otherwise don't do anything special, pretend there's nothing else there
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
)
|
// Check for fake floors in the sector.
|
||||||
|
if (front->ffloors || back->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
|
||||||
fixed_t highestceiling = highceiling;
|
|
||||||
fixed_t lowestceiling = opentop;
|
|
||||||
fixed_t highestfloor = openbottom;
|
|
||||||
fixed_t lowestfloor = lowfloor;
|
|
||||||
fixed_t delta1, delta2;
|
fixed_t delta1, delta2;
|
||||||
#ifdef ESLOPE
|
|
||||||
pslope_t *ceilingslope = opentopslope;
|
|
||||||
pslope_t *floorslope = openbottomslope;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check for frontsector's fake floors
|
// Check for frontsector's fake floors
|
||||||
for (rover = front->ffloors; rover; rover = rover->next)
|
for (rover = front->ffloors; rover; rover = rover->next)
|
||||||
|
@ -663,26 +674,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
|
|
||||||
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
||||||
{
|
{
|
||||||
if (bottomheight < lowestceiling) {
|
if (bottomheight < opentop) {
|
||||||
lowestceiling = bottomheight;
|
opentop = bottomheight;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
ceilingslope = *rover->b_slope;
|
opentopslope = *rover->b_slope;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (bottomheight < highestceiling)
|
else if (bottomheight < highceiling)
|
||||||
highestceiling = bottomheight;
|
highceiling = bottomheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
||||||
{
|
{
|
||||||
if (topheight > highestfloor) {
|
if (topheight > openbottom) {
|
||||||
highestfloor = topheight;
|
openbottom = topheight;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
floorslope = *rover->t_slope;
|
openbottomslope = *rover->t_slope;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (topheight > lowestfloor)
|
else if (topheight > lowfloor)
|
||||||
lowestfloor = topheight;
|
lowfloor = topheight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,75 +718,28 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
|
|
||||||
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
||||||
{
|
{
|
||||||
if (bottomheight < lowestceiling) {
|
if (bottomheight < opentop) {
|
||||||
lowestceiling = bottomheight;
|
opentop = bottomheight;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
ceilingslope = *rover->b_slope;
|
opentopslope = *rover->b_slope;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (bottomheight < highestceiling)
|
else if (bottomheight < highceiling)
|
||||||
highestceiling = bottomheight;
|
highceiling = bottomheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
||||||
{
|
{
|
||||||
if (topheight > highestfloor) {
|
if (topheight > openbottom) {
|
||||||
highestfloor = topheight;
|
openbottom = topheight;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
floorslope = *rover->t_slope;
|
openbottomslope = *rover->t_slope;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (topheight > lowestfloor)
|
else if (topheight > lowfloor)
|
||||||
lowestfloor = topheight;
|
lowfloor = topheight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
|
||||||
// Treat polyobj's backsector like a 3D Floor
|
|
||||||
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
|
|
||||||
{
|
|
||||||
const sector_t *polysec = linedef->backsector;
|
|
||||||
|
|
||||||
delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
|
|
||||||
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
|
|
||||||
if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
|
|
||||||
lowestceiling = polysec->floorheight;
|
|
||||||
#ifdef ESLOPE
|
|
||||||
ceilingslope = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (polysec->floorheight < highestceiling && delta1 >= delta2)
|
|
||||||
highestceiling = polysec->floorheight;
|
|
||||||
|
|
||||||
if (polysec->ceilingheight > highestfloor && delta1 < delta2) {
|
|
||||||
highestfloor = polysec->ceilingheight;
|
|
||||||
#ifdef ESLOPE
|
|
||||||
floorslope = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
|
|
||||||
lowestfloor = polysec->ceilingheight;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (highestceiling < highceiling)
|
|
||||||
highceiling = highestceiling;
|
|
||||||
|
|
||||||
if (highestfloor > openbottom) {
|
|
||||||
openbottom = highestfloor;
|
|
||||||
#ifdef ESLOPE
|
|
||||||
openbottomslope = floorslope;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowestceiling < opentop) {
|
|
||||||
opentop = lowestceiling;
|
|
||||||
#ifdef ESLOPE
|
|
||||||
opentopslope = ceilingslope;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowestfloor > lowfloor)
|
|
||||||
lowfloor = lowestfloor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6033,7 +6033,7 @@ void P_RunOverlays(void)
|
||||||
{
|
{
|
||||||
angle_t viewingangle;
|
angle_t viewingangle;
|
||||||
|
|
||||||
if (players[displayplayer].awayviewtics)
|
if (players[displayplayer].awayviewtics && players[displayplayer].awayviewmobj != NULL && !P_MobjWasRemoved(players[displayplayer].awayviewmobj))
|
||||||
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
|
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
|
||||||
else if (!camera.chase && players[displayplayer].mo)
|
else if (!camera.chase && players[displayplayer].mo)
|
||||||
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
|
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
|
||||||
|
|
|
@ -1860,7 +1860,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
po->lines[0]->backsector->floorheight = target->z - amtz;
|
po->lines[0]->backsector->floorheight = target->z - amtz;
|
||||||
po->lines[0]->backsector->ceilingheight = target->z + amtz;
|
po->lines[0]->backsector->ceilingheight = target->z + amtz;
|
||||||
// Sal: Remember to check your sectors!
|
// Sal: Remember to check your sectors!
|
||||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
|
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||||
|
// updating objects in the front one too just added teleporting to ground bugs
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||||
// Apply action to mirroring polyobjects as well
|
// Apply action to mirroring polyobjects as well
|
||||||
start = 0;
|
start = 0;
|
||||||
|
@ -1874,7 +1875,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
|
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
|
||||||
po->lines[0]->backsector->ceilingheight += diffz;
|
po->lines[0]->backsector->ceilingheight += diffz;
|
||||||
// Sal: Remember to check your sectors!
|
// Sal: Remember to check your sectors!
|
||||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
|
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||||
|
// updating objects in the front one too just added teleporting to ground bugs
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2037,8 +2039,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
po->lines[0]->backsector->floorheight += momz;
|
po->lines[0]->backsector->floorheight += momz;
|
||||||
po->lines[0]->backsector->ceilingheight += momz;
|
po->lines[0]->backsector->ceilingheight += momz;
|
||||||
// Sal: Remember to check your sectors!
|
// Sal: Remember to check your sectors!
|
||||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); // frontsector is NEEDED for crushing
|
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // backsector may not be necessary, but just in case
|
// updating objects in the front one too just added teleporting to ground bugs
|
||||||
|
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||||
|
|
||||||
// Apply action to mirroring polyobjects as well
|
// Apply action to mirroring polyobjects as well
|
||||||
start = 0;
|
start = 0;
|
||||||
|
@ -2052,7 +2055,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
po->lines[0]->backsector->floorheight += momz;
|
po->lines[0]->backsector->floorheight += momz;
|
||||||
po->lines[0]->backsector->ceilingheight += momz;
|
po->lines[0]->backsector->ceilingheight += momz;
|
||||||
// Sal: Remember to check your sectors!
|
// Sal: Remember to check your sectors!
|
||||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
|
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||||
|
// updating objects in the front one too just added teleporting to ground bugs
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2311,7 +2311,7 @@ static void P_LevelInitStuff(void)
|
||||||
players[i].lives = cv_startinglives.value;
|
players[i].lives = cv_startinglives.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
players[i].realtime = countdown = countdown2 = 0;
|
players[i].realtime = countdown = countdown2 = exitfadestarted = 0;
|
||||||
|
|
||||||
players[i].gotcontinue = false;
|
players[i].gotcontinue = false;
|
||||||
|
|
||||||
|
|
|
@ -600,6 +600,11 @@ void P_CopySectorSlope(line_t *line)
|
||||||
|
|
||||||
fsec->hasslope = true;
|
fsec->hasslope = true;
|
||||||
|
|
||||||
|
// if this is an FOF control sector, make sure any target sectors also are marked as having slopes
|
||||||
|
if (fsec->numattached)
|
||||||
|
for (i = 0; i < (int)fsec->numattached; i++)
|
||||||
|
sectors[fsec->attached[i]].hasslope = true;
|
||||||
|
|
||||||
line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef
|
line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4973,6 +4973,10 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
||||||
// Add slopes
|
// Add slopes
|
||||||
ffloor->t_slope = &sec2->c_slope;
|
ffloor->t_slope = &sec2->c_slope;
|
||||||
ffloor->b_slope = &sec2->f_slope;
|
ffloor->b_slope = &sec2->f_slope;
|
||||||
|
// mark the target sector as having slopes, if the FOF has any of its own
|
||||||
|
// (this fixes FOF slopes glitching initially at level load in software mode)
|
||||||
|
if (sec2->hasslope)
|
||||||
|
sec->hasslope = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only
|
if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only
|
||||||
|
|
53
src/p_user.c
53
src/p_user.c
|
@ -8741,14 +8741,8 @@ void P_PlayerThink(player_t *player)
|
||||||
if (player->flashcount)
|
if (player->flashcount)
|
||||||
player->flashcount--;
|
player->flashcount--;
|
||||||
|
|
||||||
// Re-fixed by Jimita (11-12-2018)
|
if (player->awayviewtics && player->awayviewtics != -1)
|
||||||
if (player->awayviewtics)
|
|
||||||
{
|
|
||||||
player->awayviewtics--;
|
player->awayviewtics--;
|
||||||
if (!player->awayviewtics)
|
|
||||||
player->awayviewtics = -1;
|
|
||||||
// The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \note do this in the cheat code
|
/// \note do this in the cheat code
|
||||||
if (player->pflags & PF_NOCLIP)
|
if (player->pflags & PF_NOCLIP)
|
||||||
|
@ -8824,6 +8818,48 @@ void P_PlayerThink(player_t *player)
|
||||||
if (player->exiting && countdown2)
|
if (player->exiting && countdown2)
|
||||||
player->exiting = 5;
|
player->exiting = 5;
|
||||||
|
|
||||||
|
// The following code is disabled for now as this causes the game to freeze sometimes
|
||||||
|
// Monster Iestyn -- 16/08/19
|
||||||
|
#if 0
|
||||||
|
// Same check as below, just at 1 second before
|
||||||
|
// so we can fade music
|
||||||
|
if (!exitfadestarted &&
|
||||||
|
player->exiting > 0 && player->exiting <= 1*TICRATE &&
|
||||||
|
(!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) &&
|
||||||
|
// don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop
|
||||||
|
(gametype == GT_RACE || gametype == GT_COMPETITION ? countdown2 == 0 : true) && // don't fade on timeout
|
||||||
|
player->lives > 0 && // don't fade on game over (competition)
|
||||||
|
P_IsLocalPlayer(player))
|
||||||
|
{
|
||||||
|
if (cv_playersforexit.value)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
||||||
|
continue;
|
||||||
|
if (players[i].lives <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!players[i].exiting || players[i].exiting > 1*TICRATE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == MAXPLAYERS)
|
||||||
|
{
|
||||||
|
exitfadestarted = true;
|
||||||
|
S_FadeOutStopMusic(1*MUSICRATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exitfadestarted = true;
|
||||||
|
S_FadeOutStopMusic(1*MUSICRATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (player->exiting == 2 || countdown2 == 2)
|
if (player->exiting == 2 || countdown2 == 2)
|
||||||
{
|
{
|
||||||
if (cv_playersforexit.value) // Count to be sure everyone's exited
|
if (cv_playersforexit.value) // Count to be sure everyone's exited
|
||||||
|
@ -9526,9 +9562,6 @@ void P_PlayerAfterThink(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->awayviewtics < 0)
|
|
||||||
player->awayviewtics = 0;
|
|
||||||
|
|
||||||
// spectator invisibility and nogravity.
|
// spectator invisibility and nogravity.
|
||||||
if ((netgame || multiplayer) && player->spectator)
|
if ((netgame || multiplayer) && player->spectator)
|
||||||
{
|
{
|
||||||
|
|
60
src/r_data.c
60
src/r_data.c
|
@ -404,16 +404,7 @@ void R_LoadTextures(void)
|
||||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||||
{
|
{
|
||||||
if (wadfiles[w]->type == RET_PK3)
|
// Count the textures from TEXTURES lumps
|
||||||
{
|
|
||||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
|
||||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
|
||||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||||
while (texturesLumpPos != INT16_MAX)
|
while (texturesLumpPos != INT16_MAX)
|
||||||
|
@ -422,18 +413,42 @@ void R_LoadTextures(void)
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the textures between TX_START and TX_END
|
// Count single-patch textures
|
||||||
if (texstart != INT16_MAX && texend != INT16_MAX)
|
|
||||||
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||||
|
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
|
||||||
|
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
texstart++; // Do not count the first marker
|
||||||
|
|
||||||
|
// PK3s have subfolders, so we can't just make a simple sum
|
||||||
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
for (j = texstart; j < texend; j++)
|
||||||
|
{
|
||||||
|
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||||
|
numtextures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Add all the textures between TX_START and TX_END
|
||||||
{
|
{
|
||||||
numtextures += (UINT32)(texend - texstart);
|
numtextures += (UINT32)(texend - texstart);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If no textures found by this point, bomb out
|
// If no textures found by this point, bomb out
|
||||||
if (!numtextures && w == (numwadfiles - 1))
|
if (!numtextures)
|
||||||
{
|
|
||||||
I_Error("No textures detected in any WADs!\n");
|
I_Error("No textures detected in any WADs!\n");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||||
// There are actually 5 buffers allocated in one for convenience.
|
// There are actually 5 buffers allocated in one for convenience.
|
||||||
|
@ -469,7 +484,7 @@ void R_LoadTextures(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
|
||||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||||
if (texturesLumpPos != INT16_MAX)
|
if (texturesLumpPos != INT16_MAX)
|
||||||
|
@ -479,9 +494,16 @@ void R_LoadTextures(void)
|
||||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
texstart++; // Do not count the first marker
|
||||||
|
|
||||||
// Work through each lump between the markers in the WAD.
|
// Work through each lump between the markers in the WAD.
|
||||||
for (j = 0; j < (texend - texstart); i++, j++)
|
for (j = 0; j < (texend - texstart); j++)
|
||||||
{
|
{
|
||||||
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
if (W_IsLumpFolder((UINT16)w, texstart + j)) // Check if lump is a folder
|
||||||
|
continue; // If it is then SKIP IT
|
||||||
|
}
|
||||||
patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE);
|
patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE);
|
||||||
|
|
||||||
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height);
|
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height);
|
||||||
|
@ -506,9 +528,9 @@ void R_LoadTextures(void)
|
||||||
k = 1;
|
k = 1;
|
||||||
while (k << 1 <= texture->width)
|
while (k << 1 <= texture->width)
|
||||||
k <<= 1;
|
k <<= 1;
|
||||||
|
|
||||||
texturewidthmask[i] = k - 1;
|
texturewidthmask[i] = k - 1;
|
||||||
textureheight[i] = texture->height << FRACBITS;
|
textureheight[i] = texture->height << FRACBITS;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1219,7 +1219,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.24;
|
CURRENT_PROJECT_VERSION = 2.1.25;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1231,7 +1231,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.24;
|
CURRENT_PROJECT_VERSION = 2.1.25;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -1219,7 +1219,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.24;
|
CURRENT_PROJECT_VERSION = 2.1.25;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1231,7 +1231,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.24;
|
CURRENT_PROJECT_VERSION = 2.1.25;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
16
src/w_wad.c
16
src/w_wad.c
|
@ -1159,6 +1159,22 @@ boolean W_IsLumpWad(lumpnum_t lumpnum)
|
||||||
return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned
|
return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// W_IsLumpFolder
|
||||||
|
// Is the lump a folder? (in a PK3 obviously)
|
||||||
|
//
|
||||||
|
boolean W_IsLumpFolder(UINT16 wad, UINT16 lump)
|
||||||
|
{
|
||||||
|
if (wadfiles[wad]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
const char *name = wadfiles[wad]->lumpinfo[lump].name2;
|
||||||
|
|
||||||
|
return (name[strlen(name)-1] == '/'); // folders end in '/'
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // non-PK3s don't have folders
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
/* report a zlib or i/o error */
|
/* report a zlib or i/o error */
|
||||||
void zerr(int ret)
|
void zerr(int ret)
|
||||||
|
|
|
@ -154,6 +154,7 @@ size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
|
||||||
size_t W_LumpLength(lumpnum_t lumpnum);
|
size_t W_LumpLength(lumpnum_t lumpnum);
|
||||||
|
|
||||||
boolean W_IsLumpWad(lumpnum_t lumpnum); // for loading maps from WADs in PK3s
|
boolean W_IsLumpWad(lumpnum_t lumpnum); // for loading maps from WADs in PK3s
|
||||||
|
boolean W_IsLumpFolder(UINT16 wad, UINT16 lump); // for detecting folder "lumps"
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
void zerr(int ret); // zlib error checking
|
void zerr(int ret); // zlib error checking
|
||||||
|
|
Loading…
Reference in a new issue