mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-31 21:50:48 +00:00
Merge branch 'next' into knuxtweaks
This commit is contained in:
commit
af7366058d
39 changed files with 809 additions and 563 deletions
15
appveyor.yml
15
appveyor.yml
|
@ -83,7 +83,14 @@ before_build:
|
||||||
- ccache -V
|
- ccache -V
|
||||||
- ccache -s
|
- ccache -s
|
||||||
- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
|
- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
|
||||||
- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX%"
|
- if defined [%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%] ( set "COMMIT=%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%" ) else ( set "COMMIT=%APPVEYOR_REPO_COMMIT%" )
|
||||||
|
- cmd: git rev-parse --short %COMMIT%>%TMP%/gitshort.txt
|
||||||
|
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
||||||
|
# for pull requests, take the owner's name only, if this isn't the same repo of course
|
||||||
|
- set "REPO=%APPVEYOR_REPO_BRANCH%"
|
||||||
|
- if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) )
|
||||||
|
- set "EXENAME=EXENAME=srb2win-%REPO%-%GITSHORT%.exe"
|
||||||
|
- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX% %EXENAME%"
|
||||||
- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
|
- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
|
||||||
- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
|
- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
|
||||||
|
|
||||||
|
@ -99,10 +106,8 @@ after_build:
|
||||||
)
|
)
|
||||||
- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
|
- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
|
||||||
- ccache -s
|
- ccache -s
|
||||||
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
|
- set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z
|
||||||
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
- set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z
|
||||||
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
|
|
||||||
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
|
|
||||||
- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
|
- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
|
||||||
- appveyor PushArtifact %BUILD_ARCHIVE%
|
- appveyor PushArtifact %BUILD_ARCHIVE%
|
||||||
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
|
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
|
||||||
|
|
|
@ -1458,7 +1458,7 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
|
||||||
// not from server or remote admin, must be hacked/buggy client
|
// not from server or remote admin, must be hacked/buggy client
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
netid = READUINT16(*p);
|
netid = READUINT16(*p);
|
||||||
|
|
321
src/d_clisrv.c
321
src/d_clisrv.c
|
@ -21,6 +21,7 @@
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
|
#include "st_stuff.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "g_input.h" // JOY1
|
#include "g_input.h" // JOY1
|
||||||
|
@ -76,6 +77,7 @@ char motd[254], server_context[8]; // Message of the Day, Unique Context (even w
|
||||||
|
|
||||||
// Server specific vars
|
// Server specific vars
|
||||||
UINT8 playernode[MAXPLAYERS];
|
UINT8 playernode[MAXPLAYERS];
|
||||||
|
char playeraddress[MAXPLAYERS][64];
|
||||||
|
|
||||||
// Minimum timeout for sending the savegame
|
// Minimum timeout for sending the savegame
|
||||||
// The actual timeout will be longer depending on the savegame length
|
// The actual timeout will be longer depending on the savegame length
|
||||||
|
@ -391,7 +393,7 @@ static void ExtraDataTicker(void)
|
||||||
{
|
{
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
SendKick(i, KICK_MSG_CON_FAIL);
|
SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
|
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
|
||||||
}
|
}
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
|
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
|
||||||
|
@ -437,6 +439,9 @@ void SendKick(UINT8 playernum, UINT8 msg)
|
||||||
{
|
{
|
||||||
UINT8 buf[2];
|
UINT8 buf[2];
|
||||||
|
|
||||||
|
if (!(server && cv_rejointimeout.value))
|
||||||
|
msg &= ~KICK_MSG_KEEP_BODY;
|
||||||
|
|
||||||
buf[0] = playernum;
|
buf[0] = playernum;
|
||||||
buf[1] = msg;
|
buf[1] = msg;
|
||||||
SendNetXCmd(XD_KICK, &buf, 2);
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
@ -1058,7 +1063,7 @@ static void SV_SendResynch(INT32 node)
|
||||||
|
|
||||||
if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250)
|
if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250)
|
||||||
{
|
{
|
||||||
SendKick(nodetoplayer[node], KICK_MSG_CON_FAIL);
|
SendKick(nodetoplayer[node], KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
resynch_score[node] = 0;
|
resynch_score[node] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2413,6 +2418,7 @@ void CL_ClearPlayer(INT32 playernum)
|
||||||
if (players[playernum].mo)
|
if (players[playernum].mo)
|
||||||
P_RemoveMobj(players[playernum].mo);
|
P_RemoveMobj(players[playernum].mo);
|
||||||
memset(&players[playernum], 0, sizeof (player_t));
|
memset(&players[playernum], 0, sizeof (player_t));
|
||||||
|
memset(playeraddress[playernum], 0, sizeof(*playeraddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2420,7 +2426,7 @@ void CL_ClearPlayer(INT32 playernum)
|
||||||
//
|
//
|
||||||
// Removes a player from the current game
|
// Removes a player from the current game
|
||||||
//
|
//
|
||||||
static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
static void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
|
||||||
{
|
{
|
||||||
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
||||||
// kick commands to be issued for the same player.
|
// kick commands to be issued for the same player.
|
||||||
|
@ -2433,9 +2439,6 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||||
playerpernode[node]--;
|
playerpernode[node]--;
|
||||||
if (playerpernode[node] <= 0)
|
if (playerpernode[node] <= 0)
|
||||||
{
|
{
|
||||||
// If a resynch was in progress, well, it no longer needs to be.
|
|
||||||
SV_InitResynchVars(playernode[playernum]);
|
|
||||||
|
|
||||||
nodeingame[playernode[playernum]] = false;
|
nodeingame[playernode[playernum]] = false;
|
||||||
Net_CloseConnection(playernode[playernum]);
|
Net_CloseConnection(playernode[playernum]);
|
||||||
ResetNode(node);
|
ResetNode(node);
|
||||||
|
@ -2557,6 +2560,7 @@ void CL_Reset(void)
|
||||||
multiplayer = false;
|
multiplayer = false;
|
||||||
servernode = 0;
|
servernode = 0;
|
||||||
server = true;
|
server = true;
|
||||||
|
resynch_local_inprogress = false;
|
||||||
doomcom->numnodes = 1;
|
doomcom->numnodes = 1;
|
||||||
doomcom->numslots = 1;
|
doomcom->numslots = 1;
|
||||||
SV_StopServer();
|
SV_StopServer();
|
||||||
|
@ -2830,9 +2834,12 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
char buf[3 + MAX_REASONLENGTH];
|
char buf[3 + MAX_REASONLENGTH];
|
||||||
char *reason = buf;
|
char *reason = buf;
|
||||||
kickreason_t kickreason = KR_KICK;
|
kickreason_t kickreason = KR_KICK;
|
||||||
|
boolean keepbody;
|
||||||
|
|
||||||
pnum = READUINT8(*p);
|
pnum = READUINT8(*p);
|
||||||
msg = READUINT8(*p);
|
msg = READUINT8(*p);
|
||||||
|
keepbody = (msg & KICK_MSG_KEEP_BODY) != 0;
|
||||||
|
msg &= ~KICK_MSG_KEEP_BODY;
|
||||||
|
|
||||||
if (pnum == serverplayer && IsPlayerAdmin(playernum))
|
if (pnum == serverplayer && IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
|
@ -2892,6 +2899,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
*/
|
*/
|
||||||
pnum = playernum;
|
pnum = playernum;
|
||||||
msg = KICK_MSG_CON_FAIL;
|
msg = KICK_MSG_CON_FAIL;
|
||||||
|
keepbody = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CONS_Printf("\x82%s ", player_names[pnum]);
|
//CONS_Printf("\x82%s ", player_names[pnum]);
|
||||||
|
@ -2911,7 +2919,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case KICK_MSG_GO_AWAY:
|
case KICK_MSG_GO_AWAY:
|
||||||
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
if (!players[pnum].quittime)
|
||||||
|
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
||||||
kickreason = KR_KICK;
|
kickreason = KR_KICK;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_PING_HIGH:
|
case KICK_MSG_PING_HIGH:
|
||||||
|
@ -2960,7 +2969,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
kickreason = KR_TIMEOUT;
|
kickreason = KR_TIMEOUT;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_PLAYER_QUIT:
|
case KICK_MSG_PLAYER_QUIT:
|
||||||
if (netgame) // not splitscreen/bots
|
if (netgame && !players[pnum].quittime) // not splitscreen/bots or soulless body
|
||||||
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
||||||
kickreason = KR_LEAVE;
|
kickreason = KR_LEAVE;
|
||||||
break;
|
break;
|
||||||
|
@ -3001,6 +3010,24 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
else
|
else
|
||||||
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
}
|
}
|
||||||
|
else if (keepbody)
|
||||||
|
{
|
||||||
|
if (server && !demoplayback)
|
||||||
|
{
|
||||||
|
INT32 node = playernode[pnum];
|
||||||
|
playerpernode[node]--;
|
||||||
|
if (playerpernode[node] <= 0)
|
||||||
|
{
|
||||||
|
nodeingame[node] = false;
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
ResetNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playernode[pnum] = UINT8_MAX;
|
||||||
|
|
||||||
|
players[pnum].quittime = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CL_RemovePlayer(pnum, kickreason);
|
CL_RemovePlayer(pnum, kickreason);
|
||||||
}
|
}
|
||||||
|
@ -3009,6 +3036,9 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0,
|
||||||
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
||||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||||
|
consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}};
|
static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}};
|
||||||
consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||||
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||||
|
@ -3078,6 +3108,7 @@ static void ResetNode(INT32 node)
|
||||||
nodewaiting[node] = 0;
|
nodewaiting[node] = 0;
|
||||||
playerpernode[node] = 0;
|
playerpernode[node] = 0;
|
||||||
sendingsavegame[node] = false;
|
sendingsavegame[node] = false;
|
||||||
|
SV_InitResynchVars(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SV_ResetServer(void)
|
void SV_ResetServer(void)
|
||||||
|
@ -3093,13 +3124,8 @@ void SV_ResetServer(void)
|
||||||
tictoclear = maketic;
|
tictoclear = maketic;
|
||||||
|
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (i = 0; i < MAXNETNODES; i++)
|
||||||
{
|
|
||||||
ResetNode(i);
|
ResetNode(i);
|
||||||
|
|
||||||
// Make sure resynch status doesn't get carried over!
|
|
||||||
SV_InitResynchVars(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
|
@ -3107,6 +3133,7 @@ void SV_ResetServer(void)
|
||||||
#endif
|
#endif
|
||||||
playeringame[i] = false;
|
playeringame[i] = false;
|
||||||
playernode[i] = UINT8_MAX;
|
playernode[i] = UINT8_MAX;
|
||||||
|
memset(playeraddress[i], 0, sizeof(*playeraddress));
|
||||||
sprintf(player_names[i], "Player %d", i + 1);
|
sprintf(player_names[i], "Player %d", i + 1);
|
||||||
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
||||||
}
|
}
|
||||||
|
@ -3197,6 +3224,37 @@ void D_QuitNetGame(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INT32 FindRejoinerNum(SINT8 node)
|
||||||
|
{
|
||||||
|
char strippednodeaddress[64];
|
||||||
|
const char *nodeaddress;
|
||||||
|
char *port;
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
// Make sure there is no dead dress before proceeding to the stripping
|
||||||
|
if (!I_GetNodeAddress)
|
||||||
|
return -1;
|
||||||
|
nodeaddress = I_GetNodeAddress(node);
|
||||||
|
if (!nodeaddress)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Strip the address of its port
|
||||||
|
strcpy(strippednodeaddress, nodeaddress);
|
||||||
|
port = strchr(strippednodeaddress, ':');
|
||||||
|
if (port)
|
||||||
|
*port = '\0';
|
||||||
|
|
||||||
|
// Check if any player matches the stripped address
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
|
||||||
|
&& !strcmp(playeraddress[i], strippednodeaddress))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Adds a node to the game (player will follow at map change or at savegame....)
|
// Adds a node to the game (player will follow at map change or at savegame....)
|
||||||
static inline void SV_AddNode(INT32 node)
|
static inline void SV_AddNode(INT32 node)
|
||||||
{
|
{
|
||||||
|
@ -3213,13 +3271,16 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
{
|
{
|
||||||
INT16 node, newplayernum;
|
INT16 node, newplayernum;
|
||||||
boolean splitscreenplayer;
|
boolean splitscreenplayer;
|
||||||
|
boolean rejoined;
|
||||||
|
player_t *newplayer;
|
||||||
|
char *port;
|
||||||
|
|
||||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
// protect against hacked/buggy client
|
// protect against hacked/buggy client
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3228,15 +3289,34 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
splitscreenplayer = newplayernum & 0x80;
|
splitscreenplayer = newplayernum & 0x80;
|
||||||
newplayernum &= ~0x80;
|
newplayernum &= ~0x80;
|
||||||
|
|
||||||
// Clear player before joining, lest some things get set incorrectly
|
rejoined = playeringame[newplayernum];
|
||||||
// HACK: don't do this for splitscreen, it relies on preset values
|
|
||||||
if (!splitscreen && !botingame)
|
if (!rejoined)
|
||||||
CL_ClearPlayer(newplayernum);
|
{
|
||||||
playeringame[newplayernum] = true;
|
// Clear player before joining, lest some things get set incorrectly
|
||||||
|
// HACK: don't do this for splitscreen, it relies on preset values
|
||||||
|
if (!splitscreen && !botingame)
|
||||||
|
CL_ClearPlayer(newplayernum);
|
||||||
|
playeringame[newplayernum] = true;
|
||||||
|
G_AddPlayer(newplayernum);
|
||||||
|
if (newplayernum+1 > doomcom->numslots)
|
||||||
|
doomcom->numslots = (INT16)(newplayernum+1);
|
||||||
|
|
||||||
|
if (server && I_GetNodeAddress)
|
||||||
|
{
|
||||||
|
strcpy(playeraddress[newplayernum], I_GetNodeAddress(node));
|
||||||
|
port = strchr(playeraddress[newplayernum], ':');
|
||||||
|
if (port)
|
||||||
|
*port = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newplayer = &players[newplayernum];
|
||||||
|
|
||||||
|
newplayer->jointime = 0;
|
||||||
|
newplayer->quittime = 0;
|
||||||
|
|
||||||
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
||||||
G_AddPlayer(newplayernum);
|
|
||||||
if (newplayernum+1 > doomcom->numslots)
|
|
||||||
doomcom->numslots = (INT16)(newplayernum+1);
|
|
||||||
|
|
||||||
// the server is creating my player
|
// the server is creating my player
|
||||||
if (node == mynode)
|
if (node == mynode)
|
||||||
|
@ -3254,29 +3334,67 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
secondarydisplayplayer = newplayernum;
|
secondarydisplayplayer = newplayernum;
|
||||||
DEBFILE("spawning my brother\n");
|
DEBFILE("spawning my brother\n");
|
||||||
if (botingame)
|
if (botingame)
|
||||||
players[newplayernum].bot = 1;
|
newplayer->bot = 1;
|
||||||
}
|
}
|
||||||
D_SendPlayerConfig();
|
D_SendPlayerConfig();
|
||||||
addedtogame = true;
|
addedtogame = true;
|
||||||
|
|
||||||
|
if (rejoined)
|
||||||
|
{
|
||||||
|
if (newplayer->mo)
|
||||||
|
{
|
||||||
|
if (!splitscreenplayer)
|
||||||
|
localangle = newplayer->mo->angle;
|
||||||
|
else
|
||||||
|
localangle2 = newplayer->mo->angle;
|
||||||
|
|
||||||
|
newplayer->viewheight = 41*newplayer->height/48;
|
||||||
|
|
||||||
|
if (newplayer->mo->eflags & MFE_VERTICALFLIP)
|
||||||
|
newplayer->viewz = newplayer->mo->z + newplayer->mo->height - newplayer->viewheight;
|
||||||
|
else
|
||||||
|
newplayer->viewz = newplayer->mo->z + newplayer->viewheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wake up the status bar
|
||||||
|
ST_Start();
|
||||||
|
// wake up the heads up text
|
||||||
|
HU_Start();
|
||||||
|
|
||||||
|
if (camera.chase && !splitscreenplayer)
|
||||||
|
P_ResetCamera(newplayer, &camera);
|
||||||
|
if (camera2.chase && splitscreenplayer)
|
||||||
|
P_ResetCamera(newplayer, &camera2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netgame)
|
if (netgame)
|
||||||
{
|
{
|
||||||
if (server && cv_showjoinaddress.value)
|
char joinmsg[256];
|
||||||
{
|
|
||||||
const char *address;
|
if (rejoined)
|
||||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
|
strcpy(joinmsg, M_GetText("\x82*%s has rejoined the game (player %d)"));
|
||||||
HU_AddChatText(va("\x82*%s has joined the game (player %d) (%s)", player_names[newplayernum], newplayernum, address), false); // merge join notification + IP to avoid clogging console/chat.
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
HU_AddChatText(va("\x82*%s has joined the game (player %d)", player_names[newplayernum], newplayernum), false); // if you don't wanna see the join address.
|
strcpy(joinmsg, M_GetText("\x82*%s has joined the game (player %d)"));
|
||||||
|
strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum));
|
||||||
|
|
||||||
|
// Merge join notification + IP to avoid clogging console/chat
|
||||||
|
if (server && cv_showjoinaddress.value && I_GetNodeAddress)
|
||||||
|
{
|
||||||
|
const char *address = I_GetNodeAddress(node);
|
||||||
|
if (address)
|
||||||
|
strcat(joinmsg, va(" (%s)", address));
|
||||||
|
}
|
||||||
|
|
||||||
|
HU_AddChatText(joinmsg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server && multiplayer && motd[0] != '\0')
|
if (server && multiplayer && motd[0] != '\0')
|
||||||
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
|
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
LUAh_PlayerJoin(newplayernum);
|
if (!rejoined)
|
||||||
|
LUAh_PlayerJoin(newplayernum);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3285,11 +3403,7 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
||||||
INT32 node, n, newplayer = false;
|
INT32 node, n, newplayer = false;
|
||||||
UINT8 buf[2 + MAXPLAYERNAME];
|
UINT8 buf[2 + MAXPLAYERNAME];
|
||||||
UINT8 *p;
|
UINT8 *p;
|
||||||
UINT8 newplayernum = 0;
|
INT32 newplayernum;
|
||||||
|
|
||||||
// What is the reason for this? Why can't newplayernum always be 0?
|
|
||||||
if (dedicated)
|
|
||||||
newplayernum = 1;
|
|
||||||
|
|
||||||
for (node = 0; node < MAXNETNODES; node++)
|
for (node = 0; node < MAXNETNODES; node++)
|
||||||
{
|
{
|
||||||
|
@ -3298,68 +3412,22 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
||||||
{
|
{
|
||||||
newplayer = true;
|
newplayer = true;
|
||||||
|
|
||||||
if (netgame)
|
newplayernum = FindRejoinerNum(node);
|
||||||
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
|
if (newplayernum == -1)
|
||||||
//
|
{
|
||||||
// The line just after that comment is an awful, horrible, terrible, TERRIBLE hack.
|
|
||||||
//
|
|
||||||
// Basically, the fix I did in order to fix the download freezes happens
|
|
||||||
// to cause situations in which a player number does not match
|
|
||||||
// the node number associated to that player.
|
|
||||||
// That is totally normal, there is absolutely *nothing* wrong with that.
|
|
||||||
// Really. Player 7 being tied to node 29, for instance, is totally fine.
|
|
||||||
//
|
|
||||||
// HOWEVER. A few (broken) parts of the netcode do the TERRIBLE mistake
|
|
||||||
// of mixing up the concepts of node and player, resulting in
|
|
||||||
// incorrect handling of cases where a player is tied to a node that has
|
|
||||||
// a different number (which is a totally normal case, or at least should be).
|
|
||||||
// This incorrect handling can go as far as literally
|
|
||||||
// anyone from joining your server at all, forever.
|
|
||||||
//
|
|
||||||
// Given those two facts, there are two options available
|
|
||||||
// in order to let this download freeze fix be:
|
|
||||||
// 1) Fix the broken parts that assume a node is a player or similar bullshit.
|
|
||||||
// 2) Change the part this comment is located at, so that any player who joins
|
|
||||||
// is given the same number as their associated node.
|
|
||||||
//
|
|
||||||
// No need to say, 1) is by far the obvious best, whereas 2) is a terrible hack.
|
|
||||||
// Unfortunately, after trying 1), I most likely didn't manage to find all
|
|
||||||
// of those broken parts, and thus 2) has become the only safe option that remains.
|
|
||||||
//
|
|
||||||
// So I did this hack.
|
|
||||||
//
|
|
||||||
// If it isn't clear enough, in order to get rid of this ugly hack,
|
|
||||||
// you will have to fix all parts of the netcode that
|
|
||||||
// make a confusion between nodes and players.
|
|
||||||
//
|
|
||||||
// And if it STILL isn't clear enough, a node and a player
|
|
||||||
// is NOT the same thing. Never. NEVER. *NEVER*.
|
|
||||||
//
|
|
||||||
// And if someday you make the terrible mistake of
|
|
||||||
// daring to have the unforgivable idea to try thinking
|
|
||||||
// that a node might possibly be the same as a player,
|
|
||||||
// or that a player should have the same number as its node,
|
|
||||||
// be sure that I will somehow know about it and
|
|
||||||
// hunt you down tirelessly and make you regret it,
|
|
||||||
// even if you live on the other side of the world.
|
|
||||||
//
|
|
||||||
// TODO: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
||||||
// \todo >>>>>>>>>> Remove this horrible hack as soon as possible <<<<<<<<<<
|
|
||||||
// TODO: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
//
|
|
||||||
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
|
|
||||||
newplayernum = node; // OMFG SAY WELCOME TO TEH NEW HACK FOR FIX FIL DOWNLOAD!!1!
|
|
||||||
else // Don't use the hack if we don't have to
|
|
||||||
// search for a free playernum
|
// search for a free playernum
|
||||||
// we can't use playeringame since it is not updated here
|
// we can't use playeringame since it is not updated here
|
||||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++)
|
||||||
{
|
{
|
||||||
|
if (playeringame[newplayernum])
|
||||||
|
continue;
|
||||||
for (n = 0; n < MAXNETNODES; n++)
|
for (n = 0; n < MAXNETNODES; n++)
|
||||||
if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum)
|
if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum)
|
||||||
break;
|
break;
|
||||||
if (n == MAXNETNODES)
|
if (n == MAXNETNODES)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// should never happen since we check the playernum
|
// should never happen since we check the playernum
|
||||||
// before accepting the join
|
// before accepting the join
|
||||||
|
@ -3386,8 +3454,6 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
||||||
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
||||||
|
|
||||||
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
|
||||||
newplayernum++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3513,8 +3579,11 @@ static size_t TotalTextCmdPerTic(tic_t tic)
|
||||||
static void HandleConnect(SINT8 node)
|
static void HandleConnect(SINT8 node)
|
||||||
{
|
{
|
||||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||||
|
INT32 rejoinernum;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
|
rejoinernum = FindRejoinerNum(node);
|
||||||
|
|
||||||
if (bannednode && bannednode[node])
|
if (bannednode && bannednode[node])
|
||||||
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server"));
|
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server"));
|
||||||
else if (netbuffer->u.clientcfg._255 != 255 ||
|
else if (netbuffer->u.clientcfg._255 != 255 ||
|
||||||
|
@ -3526,9 +3595,9 @@ static void HandleConnect(SINT8 node)
|
||||||
else if (netbuffer->u.clientcfg.version != VERSION
|
else if (netbuffer->u.clientcfg.version != VERSION
|
||||||
|| netbuffer->u.clientcfg.subversion != SUBVERSION)
|
|| netbuffer->u.clientcfg.subversion != SUBVERSION)
|
||||||
SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION));
|
SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION));
|
||||||
else if (!cv_allownewplayer.value && node)
|
else if (!cv_allownewplayer.value && node && rejoinernum == -1)
|
||||||
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment"));
|
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment"));
|
||||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1)
|
||||||
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
|
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
|
||||||
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
|
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
|
||||||
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
|
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
|
||||||
|
@ -3543,7 +3612,7 @@ static void HandleConnect(SINT8 node)
|
||||||
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
||||||
{
|
{
|
||||||
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
||||||
if (!EnsurePlayerNameIsGood(names[i], -1))
|
if (!EnsurePlayerNameIsGood(names[i], rejoinernum))
|
||||||
{
|
{
|
||||||
SV_SendRefuse(node, "Bad player name");
|
SV_SendRefuse(node, "Bad player name");
|
||||||
return;
|
return;
|
||||||
|
@ -3984,7 +4053,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
|
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
|
||||||
netconsole, realstart, consistancy[realstart%BACKUPTICS],
|
netconsole, realstart, consistancy[realstart%BACKUPTICS],
|
||||||
SHORT(netbuffer->u.clientpak.consistancy)));
|
SHORT(netbuffer->u.clientpak.consistancy)));
|
||||||
|
@ -4103,6 +4172,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
kickmsg = KICK_MSG_TIMEOUT;
|
kickmsg = KICK_MSG_TIMEOUT;
|
||||||
else
|
else
|
||||||
kickmsg = KICK_MSG_PLAYER_QUIT;
|
kickmsg = KICK_MSG_PLAYER_QUIT;
|
||||||
|
kickmsg |= KICK_MSG_KEEP_BODY;
|
||||||
|
|
||||||
SendKick(netconsole, kickmsg);
|
SendKick(netconsole, kickmsg);
|
||||||
nodetoplayer[node] = -1;
|
nodetoplayer[node] = -1;
|
||||||
|
@ -4124,7 +4194,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHEND", node);
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHEND", node);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
resynch_local_inprogress = false;
|
resynch_local_inprogress = false;
|
||||||
|
@ -4142,7 +4212,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node);
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4202,7 +4272,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHING", node);
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHING", node);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
resynch_local_inprogress = true;
|
resynch_local_inprogress = true;
|
||||||
|
@ -4214,7 +4284,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node);
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4238,7 +4308,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (client)
|
if (client)
|
||||||
|
@ -4434,7 +4504,7 @@ static void CL_SendClientCmd(void)
|
||||||
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
||||||
HSendPacket(servernode, false, 0, packetsize);
|
HSendPacket(servernode, false, 0, packetsize);
|
||||||
}
|
}
|
||||||
else if (gamestate != GS_NULL)
|
else if (gamestate != GS_NULL && addedtogame)
|
||||||
{
|
{
|
||||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
||||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
||||||
|
@ -4610,6 +4680,11 @@ static void Local_Maketic(INT32 realtics)
|
||||||
localcmds.angleturn |= TICCMD_RECEIVED;
|
localcmds.angleturn |= TICCMD_RECEIVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is utter bullshit and is responsible for
|
||||||
|
// the random desynch that happens when a player spawns.
|
||||||
|
// This is because ticcmds are resent to clients if a packet
|
||||||
|
// was dropped, and thus modifying them can lead to several
|
||||||
|
// clients having their ticcmds set to different values.
|
||||||
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
||||||
{
|
{
|
||||||
tic_t tic;
|
tic_t tic;
|
||||||
|
@ -4643,28 +4718,36 @@ void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
||||||
// create missed tic
|
// create missed tic
|
||||||
static void SV_Maketic(void)
|
static void SV_Maketic(void)
|
||||||
{
|
{
|
||||||
INT32 j;
|
INT32 i;
|
||||||
|
|
||||||
for (j = 0; j < MAXNETNODES; j++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playerpernode[j])
|
{
|
||||||
|
if (!playeringame[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We didn't receive this tic
|
||||||
|
if ((netcmds[maketic % BACKUPTICS][i].angleturn & TICCMD_RECEIVED) == 0)
|
||||||
{
|
{
|
||||||
INT32 player = nodetoplayer[j];
|
ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i];
|
||||||
if ((netcmds[maketic%BACKUPTICS][player].angleturn & TICCMD_RECEIVED) == 0)
|
ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i];
|
||||||
{ // we didn't receive this tic
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
DEBFILE(va("MISS tic%4d for node %d\n", maketic, j));
|
if (players[i].quittime)
|
||||||
#if defined(PARANOIA) && 0
|
{
|
||||||
CONS_Debug(DBG_NETPLAY, "Client Misstic %d\n", maketic);
|
// Copy the angle/aiming from the previous tic
|
||||||
#endif
|
// and empty the other inputs
|
||||||
// copy the old tic
|
memset(ticcmd, 0, sizeof(netcmds[0][0]));
|
||||||
for (i = 0; i < playerpernode[j]; i++, player = nodetoplayer2[j])
|
ticcmd->angleturn = prevticcmd->angleturn | TICCMD_RECEIVED;
|
||||||
{
|
ticcmd->aiming = prevticcmd->aiming;
|
||||||
netcmds[maketic%BACKUPTICS][player] = netcmds[(maketic-1)%BACKUPTICS][player];
|
}
|
||||||
netcmds[maketic%BACKUPTICS][player].angleturn &= ~TICCMD_RECEIVED;
|
else
|
||||||
}
|
{
|
||||||
|
DEBFILE(va("MISS tic%4d for player %d\n", maketic, i));
|
||||||
|
// Copy the input from the previous tic
|
||||||
|
*ticcmd = *prevticcmd;
|
||||||
|
ticcmd->angleturn &= ~TICCMD_RECEIVED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// all tic are now proceed make the next
|
// all tic are now proceed make the next
|
||||||
maketic++;
|
maketic++;
|
||||||
|
@ -4786,7 +4869,7 @@ static inline void PingUpdate(void)
|
||||||
// ok your net has been bad for too long, you deserve to die.
|
// ok your net has been bad for too long, you deserve to die.
|
||||||
{
|
{
|
||||||
pingtimeout[i] = 0;
|
pingtimeout[i] = 0;
|
||||||
SendKick(i, KICK_MSG_PING_HIGH);
|
SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -485,6 +485,7 @@ extern consvar_t cv_playbackspeed;
|
||||||
#define KICK_MSG_PING_HIGH 6
|
#define KICK_MSG_PING_HIGH 6
|
||||||
#define KICK_MSG_CUSTOM_KICK 7
|
#define KICK_MSG_CUSTOM_KICK 7
|
||||||
#define KICK_MSG_CUSTOM_BAN 8
|
#define KICK_MSG_CUSTOM_BAN 8
|
||||||
|
#define KICK_MSG_KEEP_BODY 0x80
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -512,7 +513,9 @@ extern UINT32 realpingtable[MAXPLAYERS];
|
||||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||||
extern tic_t servermaxping;
|
extern tic_t servermaxping;
|
||||||
|
|
||||||
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout;
|
||||||
|
extern consvar_t cv_resynchattempts, cv_blamecfail;
|
||||||
|
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||||
|
|
||||||
// Used in d_net, the only dependence
|
// Used in d_net, the only dependence
|
||||||
tic_t ExpandTics(INT32 low);
|
tic_t ExpandTics(INT32 low);
|
||||||
|
|
|
@ -651,8 +651,14 @@ void D_SRB2Loop(void)
|
||||||
// hack to start on a nice clear console screen.
|
// hack to start on a nice clear console screen.
|
||||||
COM_ImmedExecute("cls;version");
|
COM_ImmedExecute("cls;version");
|
||||||
|
|
||||||
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
|
|
||||||
I_FinishUpdate(); // page flip or blit buffer
|
I_FinishUpdate(); // page flip or blit buffer
|
||||||
|
/*
|
||||||
|
LMFAO this was showing garbage under OpenGL
|
||||||
|
because I_FinishUpdate was called afterward
|
||||||
|
*/
|
||||||
|
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */
|
||||||
|
if (gamestate != GS_TITLESCREEN)
|
||||||
|
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|
|
@ -579,6 +579,7 @@ void D_RegisterServerCommands(void)
|
||||||
|
|
||||||
// d_clisrv
|
// d_clisrv
|
||||||
CV_RegisterVar(&cv_maxplayers);
|
CV_RegisterVar(&cv_maxplayers);
|
||||||
|
CV_RegisterVar(&cv_rejointimeout);
|
||||||
CV_RegisterVar(&cv_resynchattempts);
|
CV_RegisterVar(&cv_resynchattempts);
|
||||||
CV_RegisterVar(&cv_maxsend);
|
CV_RegisterVar(&cv_maxsend);
|
||||||
CV_RegisterVar(&cv_noticedownload);
|
CV_RegisterVar(&cv_noticedownload);
|
||||||
|
@ -1124,7 +1125,7 @@ static void SetPlayerName(INT32 playernum, char *newname)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Player %d sent a bad name change\n"), playernum+1);
|
CONS_Printf(M_GetText("Player %d sent a bad name change\n"), playernum+1);
|
||||||
if (server && netgame)
|
if (server && netgame)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,7 +1483,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
if (kick)
|
if (kick)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor);
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2022,7 +2023,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2133,7 +2134,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2208,7 +2209,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2271,7 +2272,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2618,7 +2619,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
// this should never happen unless the client is hacked/buggy
|
// this should never happen unless the client is hacked/buggy
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetPacket.packet.verification) // Special marker that the server sent the request
|
if (NetPacket.packet.verification) // Special marker that the server sent the request
|
||||||
|
@ -2627,7 +2628,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
playernum = NetPacket.packet.playernum;
|
playernum = NetPacket.packet.playernum;
|
||||||
|
@ -2660,7 +2661,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2719,7 +2720,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
if (server && ((NetPacket.packet.newteam < 0 || NetPacket.packet.newteam > 3) || error))
|
if (server && ((NetPacket.packet.newteam < 0 || NetPacket.packet.newteam > 3) || error))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Safety first!
|
//Safety first!
|
||||||
|
@ -3011,7 +3012,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal verification received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal verification received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3061,7 +3062,7 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3135,7 +3136,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
Z_Free(mymotd);
|
Z_Free(mymotd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3191,7 +3192,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3349,7 +3350,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
|
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3398,7 +3399,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4191,7 +4192,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -510,6 +510,7 @@ typedef struct player_s
|
||||||
UINT8 bot;
|
UINT8 bot;
|
||||||
|
|
||||||
tic_t jointime; // Timer when player joins game to change skin/color
|
tic_t jointime; // Timer when player joins game to change skin/color
|
||||||
|
tic_t quittime; // Time elapsed since user disconnected, zero if connected
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
fixed_t fovadd; // adjust FOV for hw rendering
|
fixed_t fovadd; // adjust FOV for hw rendering
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9143,6 +9143,7 @@ static const char *const HUDITEMS_LIST[] = {
|
||||||
|
|
||||||
"RINGS",
|
"RINGS",
|
||||||
"RINGSNUM",
|
"RINGSNUM",
|
||||||
|
"RINGSNUMTICS",
|
||||||
|
|
||||||
"SCORE",
|
"SCORE",
|
||||||
"SCORENUM",
|
"SCORENUM",
|
||||||
|
@ -9162,8 +9163,7 @@ static const char *const HUDITEMS_LIST[] = {
|
||||||
"TIMELEFTNUM",
|
"TIMELEFTNUM",
|
||||||
"TIMEUP",
|
"TIMEUP",
|
||||||
"HUNTPICS",
|
"HUNTPICS",
|
||||||
"POWERUPS",
|
"POWERUPS"
|
||||||
"LAP"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const MENUTYPES_LIST[] = {
|
static const char *const MENUTYPES_LIST[] = {
|
||||||
|
|
|
@ -1165,6 +1165,7 @@ static const char *credits[] = {
|
||||||
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
||||||
"Wessel \"sphere\" Smit",
|
"Wessel \"sphere\" Smit",
|
||||||
"Ben \"Cue\" Woodford",
|
"Ben \"Cue\" Woodford",
|
||||||
|
"Ikaro \"Tatsuru\" Vinhas",
|
||||||
// Git contributors with 5+ approved merges of substantive quality,
|
// Git contributors with 5+ approved merges of substantive quality,
|
||||||
// or contributors with at least one groundbreaking merge, may be named.
|
// or contributors with at least one groundbreaking merge, may be named.
|
||||||
// Everyone else is acknowledged under "Special Thanks > SRB2 Community Contributors".
|
// Everyone else is acknowledged under "Special Thanks > SRB2 Community Contributors".
|
||||||
|
@ -2694,8 +2695,18 @@ static void F_FigureActiveTtScale(void)
|
||||||
SINT8 newttscale = max(1, min(6, vid.dupx));
|
SINT8 newttscale = max(1, min(6, vid.dupx));
|
||||||
SINT8 oldttscale = activettscale;
|
SINT8 oldttscale = activettscale;
|
||||||
|
|
||||||
if (newttscale == testttscale)
|
if (needpatchrecache)
|
||||||
return;
|
ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (newttscale == testttscale)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We have a new ttscale, so load gfx
|
||||||
|
if(oldttscale > 0)
|
||||||
|
F_UnloadAlacroixGraphics(oldttscale);
|
||||||
|
}
|
||||||
|
|
||||||
testttscale = newttscale;
|
testttscale = newttscale;
|
||||||
|
|
||||||
// If ttscale is unavailable: look for lower scales, then higher scales.
|
// If ttscale is unavailable: look for lower scales, then higher scales.
|
||||||
|
@ -2713,10 +2724,6 @@ static void F_FigureActiveTtScale(void)
|
||||||
|
|
||||||
activettscale = (newttscale >= 1 && newttscale <= 6) ? newttscale : 0;
|
activettscale = (newttscale >= 1 && newttscale <= 6) ? newttscale : 0;
|
||||||
|
|
||||||
// We have a new ttscale, so load gfx
|
|
||||||
if(oldttscale > 0)
|
|
||||||
F_UnloadAlacroixGraphics(oldttscale);
|
|
||||||
|
|
||||||
if(activettscale > 0)
|
if(activettscale > 0)
|
||||||
F_LoadAlacroixGraphics(activettscale);
|
F_LoadAlacroixGraphics(activettscale);
|
||||||
}
|
}
|
||||||
|
@ -2758,12 +2765,6 @@ void F_TitleScreenDrawer(void)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (needpatchrecache && (curttmode == TTMODE_ALACROIX))
|
|
||||||
{
|
|
||||||
ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
|
|
||||||
F_LoadAlacroixGraphics(activettscale);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(curttmode)
|
switch(curttmode)
|
||||||
{
|
{
|
||||||
case TTMODE_OLD:
|
case TTMODE_OLD:
|
||||||
|
@ -3629,7 +3630,6 @@ void F_StartContinue(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
wipestyleflags = WSF_FADEOUT;
|
wipestyleflags = WSF_FADEOUT;
|
||||||
F_TryColormapFade(31);
|
|
||||||
G_SetGamestate(GS_CONTINUING);
|
G_SetGamestate(GS_CONTINUING);
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
|
|
||||||
|
|
144
src/g_game.c
144
src/g_game.c
|
@ -1140,7 +1140,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2);
|
INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2);
|
||||||
|
|
||||||
angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0;
|
angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0;
|
||||||
INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, mousemove;
|
INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, turnmultiplier, mousemove;
|
||||||
controlstyle_e controlstyle = G_ControlStyle(ssplayer);
|
controlstyle_e controlstyle = G_ControlStyle(ssplayer);
|
||||||
INT32 *mx; INT32 *my; INT32 *mly;
|
INT32 *mx; INT32 *my; INT32 *mly;
|
||||||
|
|
||||||
|
@ -1163,6 +1163,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
alwaysfreelook = cv_alwaysfreelook.value;
|
alwaysfreelook = cv_alwaysfreelook.value;
|
||||||
usejoystick = cv_usejoystick.value;
|
usejoystick = cv_usejoystick.value;
|
||||||
invertmouse = cv_invertmouse.value;
|
invertmouse = cv_invertmouse.value;
|
||||||
|
turnmultiplier = cv_cam_turnmultiplier.value;
|
||||||
mousemove = cv_mousemove.value;
|
mousemove = cv_mousemove.value;
|
||||||
mx = &mousex;
|
mx = &mousex;
|
||||||
my = &mousey;
|
my = &mousey;
|
||||||
|
@ -1176,6 +1177,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
alwaysfreelook = cv_alwaysfreelook2.value;
|
alwaysfreelook = cv_alwaysfreelook2.value;
|
||||||
usejoystick = cv_usejoystick2.value;
|
usejoystick = cv_usejoystick2.value;
|
||||||
invertmouse = cv_invertmouse2.value;
|
invertmouse = cv_invertmouse2.value;
|
||||||
|
turnmultiplier = cv_cam2_turnmultiplier.value;
|
||||||
mousemove = cv_mousemove2.value;
|
mousemove = cv_mousemove2.value;
|
||||||
mx = &mouse2x;
|
mx = &mouse2x;
|
||||||
my = &mouse2y;
|
my = &mouse2y;
|
||||||
|
@ -1293,14 +1295,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
{
|
{
|
||||||
if (turnright && turnleft);
|
if (turnright && turnleft);
|
||||||
else if (turnright)
|
else if (turnright)
|
||||||
cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS));
|
cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * turnmultiplier)>>FRACBITS));
|
||||||
else if (turnleft)
|
else if (turnleft)
|
||||||
cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS));
|
cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * turnmultiplier)>>FRACBITS));
|
||||||
|
|
||||||
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
||||||
{
|
{
|
||||||
// JOYAXISRANGE should be 1023 (divide by 1024)
|
// JOYAXISRANGE should be 1023 (divide by 1024)
|
||||||
cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * cv_cam_turnmultiplier.value)>>FRACBITS)); // ANALOG!
|
cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * turnmultiplier)>>FRACBITS)); // ANALOG!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turnright || turnleft || abs(cmd->angleturn) > angleturn[2])
|
if (turnright || turnleft || abs(cmd->angleturn) > angleturn[2])
|
||||||
|
@ -1939,6 +1941,10 @@ boolean G_IsTitleCardAvailable(void)
|
||||||
if (gametyperules & GTR_NOTITLECARD)
|
if (gametyperules & GTR_NOTITLECARD)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// The current level has no name.
|
||||||
|
if (!mapheaderinfo[gamemap-1]->lvlttl[0])
|
||||||
|
return false;
|
||||||
|
|
||||||
// The title card is available.
|
// The title card is available.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2412,6 +2418,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
INT32 skin;
|
INT32 skin;
|
||||||
UINT32 availabilities;
|
UINT32 availabilities;
|
||||||
tic_t jointime;
|
tic_t jointime;
|
||||||
|
tic_t quittime;
|
||||||
boolean spectator;
|
boolean spectator;
|
||||||
boolean outofcoop;
|
boolean outofcoop;
|
||||||
INT16 bot;
|
INT16 bot;
|
||||||
|
@ -2425,6 +2432,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
ctfteam = players[player].ctfteam;
|
ctfteam = players[player].ctfteam;
|
||||||
exiting = players[player].exiting;
|
exiting = players[player].exiting;
|
||||||
jointime = players[player].jointime;
|
jointime = players[player].jointime;
|
||||||
|
quittime = players[player].quittime;
|
||||||
spectator = players[player].spectator;
|
spectator = players[player].spectator;
|
||||||
outofcoop = players[player].outofcoop;
|
outofcoop = players[player].outofcoop;
|
||||||
pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
|
pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
|
||||||
|
@ -2496,6 +2504,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
p->pflags = pflags;
|
p->pflags = pflags;
|
||||||
p->ctfteam = ctfteam;
|
p->ctfteam = ctfteam;
|
||||||
p->jointime = jointime;
|
p->jointime = jointime;
|
||||||
|
p->quittime = quittime;
|
||||||
p->spectator = spectator;
|
p->spectator = spectator;
|
||||||
p->outofcoop = outofcoop;
|
p->outofcoop = outofcoop;
|
||||||
|
|
||||||
|
@ -2649,73 +2658,24 @@ static boolean G_CheckSpot(INT32 playernum, mapthing_t *mthing)
|
||||||
// or a not-so-appropriate spot, if it initially fails
|
// or a not-so-appropriate spot, if it initially fails
|
||||||
// due to a lack of starts open or something.
|
// due to a lack of starts open or something.
|
||||||
//
|
//
|
||||||
void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
void G_SpawnPlayer(INT32 playernum)
|
||||||
{
|
{
|
||||||
mapthing_t *spawnpoint;
|
|
||||||
|
|
||||||
if (!playeringame[playernum])
|
if (!playeringame[playernum])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
P_SpawnPlayer(playernum);
|
P_SpawnPlayer(playernum);
|
||||||
|
G_MovePlayerToSpawnOrStarpost(playernum);
|
||||||
if (starpost) //Don't even bother with looking for a place to spawn.
|
|
||||||
{
|
|
||||||
P_MovePlayerToStarpost(playernum);
|
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- CTF --
|
|
||||||
// Order: CTF->DM->Coop
|
|
||||||
if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
|
|
||||||
{
|
|
||||||
if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start
|
|
||||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
|
||||||
spawnpoint = G_FindCoopStart(playernum); // fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- DM/Tag/CTF-spectator/etc --
|
|
||||||
// Order: DM->CTF->Coop
|
|
||||||
else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT))
|
|
||||||
{
|
|
||||||
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
|
||||||
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
|
|
||||||
spawnpoint = G_FindCoopStart(playernum); // fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Other game modes --
|
|
||||||
// Order: Coop->DM->CTF
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start
|
|
||||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
|
||||||
spawnpoint = G_FindCTFStart(playernum); // fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
//No spawns found. ANYWHERE.
|
|
||||||
if (!spawnpoint)
|
|
||||||
{
|
|
||||||
if (nummapthings)
|
|
||||||
{
|
|
||||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the first mapthing!\n"));
|
|
||||||
spawnpoint = &mapthings[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the origin!\n"));
|
|
||||||
//P_MovePlayerToSpawn handles this fine if the spawnpoint is NULL.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
P_MovePlayerToSpawn(playernum, spawnpoint);
|
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_MovePlayerToSpawnOrStarpost(INT32 playernum)
|
||||||
|
{
|
||||||
|
if (players[playernum].starposttime)
|
||||||
|
P_MovePlayerToStarpost(playernum);
|
||||||
|
else
|
||||||
|
P_MovePlayerToSpawn(playernum, G_FindMapStart(playernum));
|
||||||
}
|
}
|
||||||
|
|
||||||
mapthing_t *G_FindCTFStart(INT32 playernum)
|
mapthing_t *G_FindCTFStart(INT32 playernum)
|
||||||
|
@ -2812,6 +2772,59 @@ mapthing_t *G_FindCoopStart(INT32 playernum)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapthing_t *G_FindMapStart(INT32 playernum)
|
||||||
|
{
|
||||||
|
mapthing_t *spawnpoint;
|
||||||
|
|
||||||
|
if (!playeringame[playernum])
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// -- CTF --
|
||||||
|
// Order: CTF->DM->Coop
|
||||||
|
if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
|
||||||
|
{
|
||||||
|
if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start
|
||||||
|
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||||
|
spawnpoint = G_FindCoopStart(playernum); // fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- DM/Tag/CTF-spectator/etc --
|
||||||
|
// Order: DM->CTF->Coop
|
||||||
|
else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT))
|
||||||
|
{
|
||||||
|
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
||||||
|
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
|
||||||
|
spawnpoint = G_FindCoopStart(playernum); // fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Other game modes --
|
||||||
|
// Order: Coop->DM->CTF
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start
|
||||||
|
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||||
|
spawnpoint = G_FindCTFStart(playernum); // fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
//No spawns found. ANYWHERE.
|
||||||
|
if (!spawnpoint)
|
||||||
|
{
|
||||||
|
if (nummapthings)
|
||||||
|
{
|
||||||
|
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the first mapthing!\n"));
|
||||||
|
spawnpoint = &mapthings[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the origin!\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return spawnpoint;
|
||||||
|
}
|
||||||
|
|
||||||
// Go back through all the projectiles and remove all references to the old
|
// Go back through all the projectiles and remove all references to the old
|
||||||
// player mobj, replacing them with the new one.
|
// player mobj, replacing them with the new one.
|
||||||
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo)
|
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo)
|
||||||
|
@ -2990,7 +3003,7 @@ void G_DoReborn(INT32 playernum)
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (!playeringame[i])
|
||||||
continue;
|
continue;
|
||||||
G_SpawnPlayer(i, (players[i].starposttime));
|
G_SpawnPlayer(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore time in netgame (see also p_setup.c)
|
// restore time in netgame (see also p_setup.c)
|
||||||
|
@ -3036,7 +3049,7 @@ void G_DoReborn(INT32 playernum)
|
||||||
P_RemoveMobj(player->mo);
|
P_RemoveMobj(player->mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_SpawnPlayer(playernum, (player->starposttime));
|
G_SpawnPlayer(playernum);
|
||||||
if (oldmo)
|
if (oldmo)
|
||||||
G_ChangePlayerReferences(oldmo, players[playernum].mo);
|
G_ChangePlayerReferences(oldmo, players[playernum].mo);
|
||||||
}
|
}
|
||||||
|
@ -3078,7 +3091,6 @@ void G_AddPlayer(INT32 playernum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->jointime = 0;
|
|
||||||
p->playerstate = PST_REBORN;
|
p->playerstate = PST_REBORN;
|
||||||
|
|
||||||
p->height = mobjinfo[MT_PLAYER].height;
|
p->height = mobjinfo[MT_PLAYER].height;
|
||||||
|
@ -3101,6 +3113,8 @@ boolean G_EnoughPlayersFinished(void)
|
||||||
{
|
{
|
||||||
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
||||||
continue;
|
continue;
|
||||||
|
if (players[i].quittime > 30 * TICRATE)
|
||||||
|
continue;
|
||||||
if (players[i].lives <= 0)
|
if (players[i].lives <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,9 @@ INT32 G_FindMapByNameOrCode(const char *query, char **foundmapnamep);
|
||||||
mapthing_t *G_FindCTFStart(INT32 playernum);
|
mapthing_t *G_FindCTFStart(INT32 playernum);
|
||||||
mapthing_t *G_FindMatchStart(INT32 playernum);
|
mapthing_t *G_FindMatchStart(INT32 playernum);
|
||||||
mapthing_t *G_FindCoopStart(INT32 playernum);
|
mapthing_t *G_FindCoopStart(INT32 playernum);
|
||||||
void G_SpawnPlayer(INT32 playernum, boolean starpost);
|
mapthing_t *G_FindMapStart(INT32 playernum);
|
||||||
|
void G_MovePlayerToSpawnOrStarpost(INT32 playernum);
|
||||||
|
void G_SpawnPlayer(INT32 playernum);
|
||||||
|
|
||||||
// Can be called by the startup code or M_Responder.
|
// Can be called by the startup code or M_Responder.
|
||||||
// A normal game starts at map 1, but a warp test can start elsewhere
|
// A normal game starts at map 1, but a warp test can start elsewhere
|
||||||
|
|
|
@ -662,7 +662,13 @@ INT32 G_KeyStringtoNum(const char *keystr)
|
||||||
return keystr[0];
|
return keystr[0];
|
||||||
|
|
||||||
if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9')
|
if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9')
|
||||||
return atoi(&keystr[3]);
|
{
|
||||||
|
/* what if we out of range bruh? */
|
||||||
|
j = atoi(&keystr[3]);
|
||||||
|
if (j < NUMINPUTS)
|
||||||
|
return j;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j < NUMKEYNAMES; j++)
|
for (j = 0; j < NUMKEYNAMES; j++)
|
||||||
if (!stricmp(keynames[j].name, keystr))
|
if (!stricmp(keynames[j].name, keystr))
|
||||||
|
|
|
@ -5325,7 +5325,7 @@ static void HWR_AddSprites(sector_t *sec)
|
||||||
#ifdef HWPRECIP
|
#ifdef HWPRECIP
|
||||||
precipmobj_t *precipthing;
|
precipmobj_t *precipthing;
|
||||||
#endif
|
#endif
|
||||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
fixed_t limit_dist, hoop_limit_dist;
|
||||||
|
|
||||||
// BSP is traversed by subsector.
|
// BSP is traversed by subsector.
|
||||||
// A sector might have been split into several
|
// A sector might have been split into several
|
||||||
|
@ -5344,35 +5344,10 @@ static void HWR_AddSprites(sector_t *sec)
|
||||||
// If a limit exists, handle things a tiny bit different.
|
// If a limit exists, handle things a tiny bit different.
|
||||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||||
if (limit_dist || hoop_limit_dist)
|
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||||
{
|
{
|
||||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
|
||||||
{
|
|
||||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
|
||||||
|
|
||||||
if (thing->sprite == SPR_HOOP)
|
|
||||||
{
|
|
||||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (limit_dist && approx_dist > limit_dist)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWR_ProjectSprite(thing);
|
HWR_ProjectSprite(thing);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Draw everything in sector, no checks
|
|
||||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
|
||||||
if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW))
|
|
||||||
HWR_ProjectSprite(thing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HWPRECIP
|
#ifdef HWPRECIP
|
||||||
|
@ -5381,15 +5356,8 @@ static void HWR_AddSprites(sector_t *sec)
|
||||||
{
|
{
|
||||||
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
|
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
|
||||||
{
|
{
|
||||||
if (precipthing->precipflags & PCF_INVISIBLE)
|
if (R_PrecipThingVisible(precipthing, limit_dist))
|
||||||
continue;
|
HWR_ProjectPrecipitationSprite(precipthing);
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
|
||||||
|
|
||||||
if (approx_dist > limit_dist)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
HWR_ProjectPrecipitationSprite(precipthing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -5643,7 +5611,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
||||||
{
|
{
|
||||||
// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
|
// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
|
||||||
if (thing->tracer->sprite == SPR_NULL || thing->tracer->flags2 & MF2_DONTDRAW)
|
if (! R_ThingVisible(thing->tracer))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
|
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
|
||||||
player_names[playernum]);
|
player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,7 +668,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1437,7 +1437,7 @@ static void HU_drawMiniChat(void)
|
||||||
|
|
||||||
for (; i>0; i--)
|
for (; i>0; i--)
|
||||||
{
|
{
|
||||||
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
INT32 linescount = 0;
|
INT32 linescount = 0;
|
||||||
|
|
||||||
|
@ -1479,6 +1479,9 @@ static void HU_drawMiniChat(void)
|
||||||
dy = 0;
|
dy = 0;
|
||||||
dx = 0;
|
dx = 0;
|
||||||
msglines += linescount+1;
|
msglines += linescount+1;
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
Z_Free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
y = chaty - charheight*(msglines+1);
|
y = chaty - charheight*(msglines+1);
|
||||||
|
@ -1501,7 +1504,7 @@ static void HU_drawMiniChat(void)
|
||||||
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
||||||
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||||
UINT8 *colormap = NULL;
|
UINT8 *colormap = NULL;
|
||||||
|
|
||||||
while(msg[j]) // iterate through msg
|
while(msg[j]) // iterate through msg
|
||||||
|
@ -1547,6 +1550,9 @@ static void HU_drawMiniChat(void)
|
||||||
}
|
}
|
||||||
dy += charheight;
|
dy += charheight;
|
||||||
dx = 0;
|
dx = 0;
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
Z_Free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrement addy and make that shit smooth:
|
// decrement addy and make that shit smooth:
|
||||||
|
@ -1598,7 +1604,7 @@ static void HU_drawChatLog(INT32 offset)
|
||||||
{
|
{
|
||||||
INT32 clrflag = 0;
|
INT32 clrflag = 0;
|
||||||
INT32 j = 0;
|
INT32 j = 0;
|
||||||
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||||
UINT8 *colormap = NULL;
|
UINT8 *colormap = NULL;
|
||||||
while(msg[j]) // iterate through msg
|
while(msg[j]) // iterate through msg
|
||||||
{
|
{
|
||||||
|
@ -1638,6 +1644,9 @@ static void HU_drawChatLog(INT32 offset)
|
||||||
}
|
}
|
||||||
dy += charheight;
|
dy += charheight;
|
||||||
dx = 0;
|
dx = 0;
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
Z_Free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2369,7 +2378,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||||
|
|
||||||
if (!splitscreen) // don't draw it on splitscreen,
|
if (!splitscreen) // don't draw it on splitscreen,
|
||||||
{
|
{
|
||||||
if (!(tab[i].num == serverplayer))
|
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||||
HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0);
|
HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0);
|
||||||
//else
|
//else
|
||||||
// V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER");
|
// V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER");
|
||||||
|
@ -2568,7 +2577,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
||||||
V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||||
if (!splitscreen)
|
if (!splitscreen)
|
||||||
{
|
{
|
||||||
if (!(tab[i].num == serverplayer))
|
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||||
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
||||||
//else
|
//else
|
||||||
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
||||||
|
@ -2692,7 +2701,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
||||||
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
|
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
|
||||||
if (!splitscreen)
|
if (!splitscreen)
|
||||||
{
|
{
|
||||||
if (!(tab[i].num == serverplayer))
|
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||||
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
||||||
//else
|
//else
|
||||||
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
||||||
|
@ -2723,7 +2732,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
||||||
supercheck = supercheckdef;
|
supercheck = supercheckdef;
|
||||||
|
|
||||||
strlcpy(name, tab[i].name, 7);
|
strlcpy(name, tab[i].name, 7);
|
||||||
if (!(tab[i].num == serverplayer))
|
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||||
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
||||||
//else
|
//else
|
||||||
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
||||||
|
@ -2831,7 +2840,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
|
||||||
strlcpy(name, tab[i].name, 7);
|
strlcpy(name, tab[i].name, 7);
|
||||||
if (!splitscreen) // don't draw it on splitscreen,
|
if (!splitscreen) // don't draw it on splitscreen,
|
||||||
{
|
{
|
||||||
if (!(tab[i].num == serverplayer))
|
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||||
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
||||||
//else
|
//else
|
||||||
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
||||||
|
|
|
@ -6487,10 +6487,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
24*FRACUNIT, // radius
|
24*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
24*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
0, // mass
|
DMG_FIRE, // mass
|
||||||
1, // damage
|
1, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags
|
MF_NOBLOCKMAP|MF_MISSILE|MF_PAIN|MF_NOGRAVITY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -2193,11 +2193,11 @@ static int lib_rPointInSubsector(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_rIsPointInSubsector(lua_State *L)
|
static int lib_rPointInSubsectorOrNil(lua_State *L)
|
||||||
{
|
{
|
||||||
fixed_t x = luaL_checkfixed(L, 1);
|
fixed_t x = luaL_checkfixed(L, 1);
|
||||||
fixed_t y = luaL_checkfixed(L, 2);
|
fixed_t y = luaL_checkfixed(L, 2);
|
||||||
subsector_t *sub = R_IsPointInSubsector(x, y);
|
subsector_t *sub = R_PointInSubsectorOrNull(x, y);
|
||||||
//HUDSAFE
|
//HUDSAFE
|
||||||
INLEVEL
|
INLEVEL
|
||||||
if (sub)
|
if (sub)
|
||||||
|
@ -3141,7 +3141,7 @@ static luaL_Reg lib[] = {
|
||||||
{"R_PointToDist",lib_rPointToDist},
|
{"R_PointToDist",lib_rPointToDist},
|
||||||
{"R_PointToDist2",lib_rPointToDist2},
|
{"R_PointToDist2",lib_rPointToDist2},
|
||||||
{"R_PointInSubsector",lib_rPointInSubsector},
|
{"R_PointInSubsector",lib_rPointInSubsector},
|
||||||
{"R_IsPointInSubsector",lib_rIsPointInSubsector},
|
{"R_PointInSubsectorOrNil",lib_rPointInSubsectorOrNil},
|
||||||
|
|
||||||
// r_things (sprite)
|
// r_things (sprite)
|
||||||
{"R_Char2Frame",lib_rChar2Frame},
|
{"R_Char2Frame",lib_rChar2Frame},
|
||||||
|
|
|
@ -87,7 +87,7 @@ deny:
|
||||||
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper for COM_AddCommand commands
|
// Wrapper for COM_AddCommand commands
|
||||||
|
|
|
@ -102,7 +102,7 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
||||||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||||
boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following
|
boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following
|
||||||
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
|
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
|
||||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player quitting
|
||||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||||
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
|
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
|
||||||
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
|
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
|
||||||
|
|
|
@ -1439,7 +1439,7 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj)
|
||||||
return shouldCollide;
|
return shouldCollide;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LUAh_PlayerQuit(player_t *plr, int reason)
|
void LUAh_PlayerQuit(player_t *plr, kickreason_t reason)
|
||||||
{
|
{
|
||||||
hook_p hookp;
|
hook_p hookp;
|
||||||
if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8))))
|
if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8))))
|
||||||
|
|
|
@ -362,6 +362,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->bot);
|
lua_pushinteger(L, plr->bot);
|
||||||
else if (fastcmp(field,"jointime"))
|
else if (fastcmp(field,"jointime"))
|
||||||
lua_pushinteger(L, plr->jointime);
|
lua_pushinteger(L, plr->jointime);
|
||||||
|
else if (fastcmp(field,"quittime"))
|
||||||
|
lua_pushinteger(L, plr->quittime);
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
else if (fastcmp(field,"fovadd"))
|
else if (fastcmp(field,"fovadd"))
|
||||||
lua_pushfixed(L, plr->fovadd);
|
lua_pushfixed(L, plr->fovadd);
|
||||||
|
@ -701,6 +703,8 @@ static int player_set(lua_State *L)
|
||||||
return NOSET;
|
return NOSET;
|
||||||
else if (fastcmp(field,"jointime"))
|
else if (fastcmp(field,"jointime"))
|
||||||
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"quittime"))
|
||||||
|
plr->quittime = (tic_t)luaL_checkinteger(L, 3);
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
else if (fastcmp(field,"fovadd"))
|
else if (fastcmp(field,"fovadd"))
|
||||||
plr->fovadd = luaL_checkfixed(L, 3);
|
plr->fovadd = luaL_checkfixed(L, 3);
|
||||||
|
|
|
@ -452,7 +452,7 @@ void Command_RTeleport_f(void)
|
||||||
else
|
else
|
||||||
inty = 0;
|
inty = 0;
|
||||||
|
|
||||||
ss = R_IsPointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
|
ss = R_PointInSubsectorOrNull(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
|
||||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
||||||
|
@ -530,7 +530,7 @@ void Command_Teleport_f(void)
|
||||||
inty = mt->y<<FRACBITS;
|
inty = mt->y<<FRACBITS;
|
||||||
offset = mt->z<<FRACBITS;
|
offset = mt->z<<FRACBITS;
|
||||||
|
|
||||||
ss = R_IsPointInSubsector(intx, inty);
|
ss = R_PointInSubsectorOrNull(intx, inty);
|
||||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Spawnpoint not in a valid location.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Spawnpoint not in a valid location.\n"));
|
||||||
|
@ -597,7 +597,7 @@ void Command_Teleport_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss = R_IsPointInSubsector(mo2->x, mo2->y);
|
ss = R_PointInSubsectorOrNull(mo2->x, mo2->y);
|
||||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Starpost not in a valid location.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Starpost not in a valid location.\n"));
|
||||||
|
@ -653,7 +653,7 @@ void Command_Teleport_f(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ss = R_IsPointInSubsector(intx, inty);
|
ss = R_PointInSubsectorOrNull(intx, inty);
|
||||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
||||||
|
|
15
src/m_menu.c
15
src/m_menu.c
|
@ -3758,6 +3758,12 @@ void M_SetupNextMenu(menu_t *menudef)
|
||||||
hidetitlemap = false;
|
hidetitlemap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Guess I'll put this here, idk
|
||||||
|
boolean M_MouseNeeded(void)
|
||||||
|
{
|
||||||
|
return (currentMenu == &MessageDef && currentMenu->prevMenu == &OP_ChangeControlsDef);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// M_Ticker
|
// M_Ticker
|
||||||
//
|
//
|
||||||
|
@ -5596,7 +5602,8 @@ static void M_DrawNightsAttackMountains(void)
|
||||||
static INT32 bgscrollx;
|
static INT32 bgscrollx;
|
||||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||||
patch_t *background = W_CachePatchName(curbgname, PU_PATCH);
|
patch_t *background = W_CachePatchName(curbgname, PU_PATCH);
|
||||||
INT32 x = FixedInt(bgscrollx) % SHORT(background->width);
|
INT16 w = SHORT(background->width);
|
||||||
|
INT32 x = FixedInt(-bgscrollx) % w;
|
||||||
INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2;
|
INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2;
|
||||||
|
|
||||||
if (vid.height != BASEVIDHEIGHT * dupz)
|
if (vid.height != BASEVIDHEIGHT * dupz)
|
||||||
|
@ -5604,11 +5611,13 @@ static void M_DrawNightsAttackMountains(void)
|
||||||
V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31);
|
V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31);
|
||||||
|
|
||||||
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
||||||
x += SHORT(background->width);
|
x += w;
|
||||||
if (x < BASEVIDWIDTH)
|
if (x < BASEVIDWIDTH)
|
||||||
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
||||||
|
|
||||||
bgscrollx -= (FRACUNIT/2);
|
bgscrollx += (FRACUNIT/2);
|
||||||
|
if (bgscrollx > w<<FRACBITS)
|
||||||
|
bgscrollx &= 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NiGHTS Attack foreground.
|
// NiGHTS Attack foreground.
|
||||||
|
|
|
@ -322,6 +322,9 @@ typedef struct menu_s
|
||||||
void M_SetupNextMenu(menu_t *menudef);
|
void M_SetupNextMenu(menu_t *menudef);
|
||||||
void M_ClearMenus(boolean callexitmenufunc);
|
void M_ClearMenus(boolean callexitmenufunc);
|
||||||
|
|
||||||
|
// Maybe this goes here????? Who knows.
|
||||||
|
boolean M_MouseNeeded(void);
|
||||||
|
|
||||||
extern menu_t *currentMenu;
|
extern menu_t *currentMenu;
|
||||||
|
|
||||||
extern menu_t MainDef;
|
extern menu_t MainDef;
|
||||||
|
|
|
@ -746,6 +746,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
|
||||||
if (player->bot)
|
if (player->bot)
|
||||||
continue; // ignore bots
|
continue; // ignore bots
|
||||||
|
|
||||||
|
if (player->quittime)
|
||||||
|
continue; // Ignore uncontrolled bodies
|
||||||
|
|
||||||
if (dist > 0
|
if (dist > 0
|
||||||
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
|
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
|
||||||
continue; // Too far away
|
continue; // Too far away
|
||||||
|
|
|
@ -2257,9 +2257,9 @@ void P_CheckSurvivors(void)
|
||||||
{
|
{
|
||||||
if (players[i].spectator)
|
if (players[i].spectator)
|
||||||
spectators++;
|
spectators++;
|
||||||
else if (players[i].pflags & PF_TAGIT)
|
else if ((players[i].pflags & PF_TAGIT) && players[i].quittime < 30 * TICRATE)
|
||||||
taggers++;
|
taggers++;
|
||||||
else if (!(players[i].pflags & PF_GAMETYPEOVER))
|
else if (!(players[i].pflags & PF_GAMETYPEOVER) && players[i].quittime < 30 * TICRATE)
|
||||||
{
|
{
|
||||||
survivorarray[survivors] = i;
|
survivorarray[survivors] = i;
|
||||||
survivors++;
|
survivors++;
|
||||||
|
|
|
@ -3396,7 +3396,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
|
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
|
||||||
{
|
{
|
||||||
boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
|
boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
|
||||||
if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER)))
|
if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER) && !(mobj->eflags & MFE_TOUCHLAVA)))
|
||||||
{ // Water removes electric and non-water fire shields...
|
{ // Water removes electric and non-water fire shields...
|
||||||
P_FlashPal(p,
|
P_FlashPal(p,
|
||||||
electric
|
electric
|
||||||
|
@ -11114,7 +11114,7 @@ void P_SpawnPrecipitation(void)
|
||||||
x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
||||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
||||||
|
|
||||||
precipsector = R_IsPointInSubsector(x, y);
|
precipsector = R_PointInSubsectorOrNull(x, y);
|
||||||
|
|
||||||
// No sector? Stop wasting time,
|
// No sector? Stop wasting time,
|
||||||
// move on to the next entry in the blockmap
|
// move on to the next entry in the blockmap
|
||||||
|
|
|
@ -255,6 +255,7 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEINT32(save_p, players[i].onconveyor);
|
WRITEINT32(save_p, players[i].onconveyor);
|
||||||
|
|
||||||
WRITEUINT32(save_p, players[i].jointime);
|
WRITEUINT32(save_p, players[i].jointime);
|
||||||
|
WRITEUINT32(save_p, players[i].quittime);
|
||||||
|
|
||||||
WRITEUINT16(save_p, flags);
|
WRITEUINT16(save_p, flags);
|
||||||
|
|
||||||
|
@ -446,6 +447,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].onconveyor = READINT32(save_p);
|
players[i].onconveyor = READINT32(save_p);
|
||||||
|
|
||||||
players[i].jointime = READUINT32(save_p);
|
players[i].jointime = READUINT32(save_p);
|
||||||
|
players[i].quittime = READUINT32(save_p);
|
||||||
|
|
||||||
flags = READUINT16(save_p);
|
flags = READUINT16(save_p);
|
||||||
|
|
||||||
|
|
|
@ -411,7 +411,7 @@ levelflat refers to an array of level flats,
|
||||||
or NULL if we want to allocate it now.
|
or NULL if we want to allocate it now.
|
||||||
*/
|
*/
|
||||||
static INT32
|
static INT32
|
||||||
Ploadflat (levelflat_t *levelflat, const char *flatname)
|
Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
|
||||||
{
|
{
|
||||||
#ifndef NO_PNG_LUMPS
|
#ifndef NO_PNG_LUMPS
|
||||||
UINT8 buffer[8];
|
UINT8 buffer[8];
|
||||||
|
@ -422,31 +422,26 @@ Ploadflat (levelflat_t *levelflat, const char *flatname)
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (levelflat)
|
// Scan through the already found flats, return if it matches.
|
||||||
|
for (i = 0; i < numlevelflats; i++)
|
||||||
{
|
{
|
||||||
// Scan through the already found flats, return if it matches.
|
if (strnicmp(levelflat[i].name, flatname, 8) == 0)
|
||||||
for (i = 0; i < numlevelflats; i++)
|
return i;
|
||||||
{
|
|
||||||
if (strnicmp(levelflat[i].name, flatname, 8) == 0)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ZDEBUG
|
if (resize)
|
||||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (numlevelflats >= MAXLEVELFLATS)
|
|
||||||
I_Error("Too many flats in level\n");
|
|
||||||
|
|
||||||
if (levelflat)
|
|
||||||
levelflat += numlevelflats;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// allocate new flat memory
|
// allocate new flat memory
|
||||||
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
|
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
|
||||||
levelflat = levelflats + numlevelflats;
|
levelflat = levelflats + numlevelflats;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (numlevelflats >= MAXLEVELFLATS)
|
||||||
|
I_Error("Too many flats in level\n");
|
||||||
|
|
||||||
|
levelflat += numlevelflats;
|
||||||
|
}
|
||||||
|
|
||||||
// Store the name.
|
// Store the name.
|
||||||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||||
|
@ -501,6 +496,10 @@ flatfound:
|
||||||
levelflat->u.flat.baselumpnum = LUMPERROR;
|
levelflat->u.flat.baselumpnum = LUMPERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ZDEBUG
|
||||||
|
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ( numlevelflats++ );
|
return ( numlevelflats++ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +507,7 @@ flatfound:
|
||||||
// allocate an id for it, and set the levelflat (to speedup search)
|
// allocate an id for it, and set the levelflat (to speedup search)
|
||||||
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
||||||
{
|
{
|
||||||
return Ploadflat(levelflat, flatname);
|
return Ploadflat(levelflat, flatname, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// help function for Lua and $$$.sav reading
|
// help function for Lua and $$$.sav reading
|
||||||
|
@ -517,7 +516,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
||||||
//
|
//
|
||||||
INT32 P_AddLevelFlatRuntime(const char *flatname)
|
INT32 P_AddLevelFlatRuntime(const char *flatname)
|
||||||
{
|
{
|
||||||
return Ploadflat(levelflats, flatname);
|
return Ploadflat(levelflats, flatname, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// help function for $$$.sav checking
|
// help function for $$$.sav checking
|
||||||
|
@ -3097,7 +3096,7 @@ static void P_InitTagGametype(void)
|
||||||
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
|
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && !players[i].spectator)
|
if (playeringame[i] && !(players[i].spectator && players[i].quittime))
|
||||||
{
|
{
|
||||||
playersactive[realnumplayers] = i; //stores the player's node in the array.
|
playersactive[realnumplayers] = i; //stores the player's node in the array.
|
||||||
realnumplayers++;
|
realnumplayers++;
|
||||||
|
@ -3119,7 +3118,7 @@ static void P_InitTagGametype(void)
|
||||||
if (players[playersactive[i]].mo)
|
if (players[playersactive[i]].mo)
|
||||||
P_RemoveMobj(players[playersactive[i]].mo);
|
P_RemoveMobj(players[playersactive[i]].mo);
|
||||||
|
|
||||||
G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location.
|
G_SpawnPlayer(playersactive[i]); //respawn the lucky player in his dedicated spawn location.
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_SetupCamera(void)
|
static void P_SetupCamera(void)
|
||||||
|
@ -3297,7 +3296,7 @@ static void P_InitPlayers(void)
|
||||||
G_DoReborn(i);
|
G_DoReborn(i);
|
||||||
else // gametype is GT_COOP or GT_RACE
|
else // gametype is GT_COOP or GT_RACE
|
||||||
{
|
{
|
||||||
G_SpawnPlayer(i, players[i].starposttime);
|
G_SpawnPlayer(i);
|
||||||
if (players[i].starposttime)
|
if (players[i].starposttime)
|
||||||
P_ClearStarPost(players[i].starpostnum);
|
P_ClearStarPost(players[i].starpostnum);
|
||||||
}
|
}
|
||||||
|
@ -3685,8 +3684,7 @@ boolean P_LoadLevel(boolean fromnetsave)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If so...
|
// If so...
|
||||||
if ((!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)) && (*mapheaderinfo[gamemap-1]->lvlttl != '\0'))
|
G_PreLevelTitleCard();
|
||||||
G_PreLevelTitleCard();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
12
src/p_spec.c
12
src/p_spec.c
|
@ -4426,10 +4426,18 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
case 6: // Death Pit (Camera Mod)
|
case 6: // Death Pit (Camera Mod)
|
||||||
case 7: // Death Pit (No Camera Mod)
|
case 7: // Death Pit (No Camera Mod)
|
||||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT);
|
{
|
||||||
|
if (player->quittime)
|
||||||
|
G_MovePlayerToSpawnOrStarpost(player - players);
|
||||||
|
else
|
||||||
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 8: // Instant Kill
|
case 8: // Instant Kill
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
if (player->quittime)
|
||||||
|
G_MovePlayerToSpawnOrStarpost(player - players);
|
||||||
|
else
|
||||||
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||||
break;
|
break;
|
||||||
case 9: // Ring Drainer (Floor Touch)
|
case 9: // Ring Drainer (Floor Touch)
|
||||||
case 10: // Ring Drainer (No Floor Touch)
|
case 10: // Ring Drainer (No Floor Touch)
|
||||||
|
|
18
src/p_tick.c
18
src/p_tick.c
|
@ -590,10 +590,24 @@ void P_Ticker(boolean run)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
//Increment jointime even if paused.
|
// Increment jointime and quittime even if paused
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
++players[i].jointime;
|
{
|
||||||
|
players[i].jointime++;
|
||||||
|
|
||||||
|
if (players[i].quittime)
|
||||||
|
{
|
||||||
|
players[i].quittime++;
|
||||||
|
|
||||||
|
if (players[i].quittime == 30 * TICRATE && G_TagGametype())
|
||||||
|
P_CheckSurvivors();
|
||||||
|
|
||||||
|
if (server && players[i].quittime >= (tic_t)FixedMul(cv_rejointimeout.value, 60 * TICRATE)
|
||||||
|
&& !(players[i].quittime % TICRATE))
|
||||||
|
SendKick(i, KICK_MSG_PLAYER_QUIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (objectplacing)
|
if (objectplacing)
|
||||||
{
|
{
|
||||||
|
|
30
src/p_user.c
30
src/p_user.c
|
@ -3164,7 +3164,7 @@ static void P_DoClimbing(player_t *player)
|
||||||
platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
||||||
platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
||||||
|
|
||||||
glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy);
|
glidesector = R_PointInSubsectorOrNull(player->mo->x + platx, player->mo->y + platy);
|
||||||
|
|
||||||
{
|
{
|
||||||
boolean floorclimb = false;
|
boolean floorclimb = false;
|
||||||
|
@ -10251,7 +10251,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
|
|
||||||
// move camera down to move under lower ceilings
|
// move camera down to move under lower ceilings
|
||||||
newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
|
newsubsec = R_PointInSubsectorOrNull(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
|
||||||
|
|
||||||
if (!newsubsec)
|
if (!newsubsec)
|
||||||
newsubsec = thiscam->subsector;
|
newsubsec = thiscam->subsector;
|
||||||
|
@ -11059,10 +11059,21 @@ static void P_MinecartThink(player_t *player)
|
||||||
|
|
||||||
if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG))
|
if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG))
|
||||||
{
|
{
|
||||||
|
angle_t *ang = NULL;
|
||||||
|
|
||||||
if (player == &players[consoleplayer])
|
if (player == &players[consoleplayer])
|
||||||
localangle = player->mo->angle;
|
ang = &localangle;
|
||||||
else if (player == &players[secondarydisplayplayer])
|
else if (player == &players[secondarydisplayplayer])
|
||||||
localangle2 = player->mo->angle;
|
ang = &localangle2;
|
||||||
|
|
||||||
|
if (ang)
|
||||||
|
{
|
||||||
|
angdiff = *ang - minecart->angle;
|
||||||
|
if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX)
|
||||||
|
*ang = minecart->angle + MINECARTCONEMAX;
|
||||||
|
else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX))
|
||||||
|
*ang = minecart->angle - MINECARTCONEMAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11772,6 +11783,8 @@ void P_PlayerThink(player_t *player)
|
||||||
{
|
{
|
||||||
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
||||||
continue;
|
continue;
|
||||||
|
if (players[i].quittime > 30 * TICRATE)
|
||||||
|
continue;
|
||||||
if (players[i].lives <= 0)
|
if (players[i].lives <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -12224,6 +12237,11 @@ void P_PlayerThink(player_t *player)
|
||||||
player->pflags &= ~PF_USEDOWN;
|
player->pflags &= ~PF_USEDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IF PLAYER NOT HERE THEN FLASH END IF
|
||||||
|
if (player->quittime && player->powers[pw_flashing] < flashingtics - 1
|
||||||
|
&& !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag)
|
||||||
|
player->powers[pw_flashing] = flashingtics - 1;
|
||||||
|
|
||||||
// Counters, time dependent power ups.
|
// Counters, time dependent power ups.
|
||||||
// Time Bonus & Ring Bonus count settings
|
// Time Bonus & Ring Bonus count settings
|
||||||
|
|
||||||
|
@ -12267,12 +12285,12 @@ void P_PlayerThink(player_t *player)
|
||||||
else
|
else
|
||||||
player->powers[pw_underwater] = 0;
|
player->powers[pw_underwater] = 0;
|
||||||
}
|
}
|
||||||
else if (player->powers[pw_underwater] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer
|
else if (player->powers[pw_underwater] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && (player->spectator || player->quittime))) // underwater timer
|
||||||
player->powers[pw_underwater]--;
|
player->powers[pw_underwater]--;
|
||||||
|
|
||||||
if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
||||||
player->powers[pw_spacetime] = 0;
|
player->powers[pw_spacetime] = 0;
|
||||||
else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer
|
else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && (player->spectator || player->quittime))) // underwater timer
|
||||||
player->powers[pw_spacetime]--;
|
player->powers[pw_spacetime]--;
|
||||||
|
|
||||||
if (player->powers[pw_gravityboots] && player->powers[pw_gravityboots] < UINT16_MAX)
|
if (player->powers[pw_gravityboots] && player->powers[pw_gravityboots] < UINT16_MAX)
|
||||||
|
|
59
src/r_main.c
59
src/r_main.c
|
@ -71,6 +71,7 @@ angle_t viewangle, aimingangle;
|
||||||
fixed_t viewcos, viewsin;
|
fixed_t viewcos, viewsin;
|
||||||
sector_t *viewsector;
|
sector_t *viewsector;
|
||||||
player_t *viewplayer;
|
player_t *viewplayer;
|
||||||
|
mobj_t *r_viewmobj;
|
||||||
|
|
||||||
//
|
//
|
||||||
// precalculated math tables
|
// precalculated math tables
|
||||||
|
@ -701,9 +702,9 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_IsPointInSubsector, same as above but returns 0 if not in subsector
|
// R_PointInSubsectorOrNull, same as above but returns 0 if not in subsector
|
||||||
//
|
//
|
||||||
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
|
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
node_t *node;
|
node_t *node;
|
||||||
INT32 side, i;
|
INT32 side, i;
|
||||||
|
@ -742,8 +743,6 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
|
||||||
// R_SetupFrame
|
// R_SetupFrame
|
||||||
//
|
//
|
||||||
|
|
||||||
static mobj_t *viewmobj;
|
|
||||||
|
|
||||||
// WARNING: a should be unsigned but to add with 2048, it isn't!
|
// WARNING: a should be unsigned but to add with 2048, it isn't!
|
||||||
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan)
|
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan)
|
||||||
|
|
||||||
|
@ -800,16 +799,16 @@ void R_SetupFrame(player_t *player)
|
||||||
if (player->awayviewtics)
|
if (player->awayviewtics)
|
||||||
{
|
{
|
||||||
// cut-away view stuff
|
// cut-away view stuff
|
||||||
viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||||
I_Assert(viewmobj != NULL);
|
I_Assert(r_viewmobj != NULL);
|
||||||
viewz = viewmobj->z + 20*FRACUNIT;
|
viewz = r_viewmobj->z + 20*FRACUNIT;
|
||||||
aimingangle = player->awayviewaiming;
|
aimingangle = player->awayviewaiming;
|
||||||
viewangle = viewmobj->angle;
|
viewangle = r_viewmobj->angle;
|
||||||
}
|
}
|
||||||
else if (!player->spectator && chasecam)
|
else if (!player->spectator && chasecam)
|
||||||
// use outside cam view
|
// use outside cam view
|
||||||
{
|
{
|
||||||
viewmobj = NULL;
|
r_viewmobj = NULL;
|
||||||
viewz = thiscam->z + (thiscam->height>>1);
|
viewz = thiscam->z + (thiscam->height>>1);
|
||||||
aimingangle = thiscam->aiming;
|
aimingangle = thiscam->aiming;
|
||||||
viewangle = thiscam->angle;
|
viewangle = thiscam->angle;
|
||||||
|
@ -819,11 +818,11 @@ void R_SetupFrame(player_t *player)
|
||||||
{
|
{
|
||||||
viewz = player->viewz;
|
viewz = player->viewz;
|
||||||
|
|
||||||
viewmobj = player->mo;
|
r_viewmobj = player->mo;
|
||||||
I_Assert(viewmobj != NULL);
|
I_Assert(r_viewmobj != NULL);
|
||||||
|
|
||||||
aimingangle = player->aiming;
|
aimingangle = player->aiming;
|
||||||
viewangle = viewmobj->angle;
|
viewangle = r_viewmobj->angle;
|
||||||
|
|
||||||
if (!demoplayback && player->playerstate != PST_DEAD)
|
if (!demoplayback && player->playerstate != PST_DEAD)
|
||||||
{
|
{
|
||||||
|
@ -857,13 +856,13 @@ void R_SetupFrame(player_t *player)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewx = viewmobj->x;
|
viewx = r_viewmobj->x;
|
||||||
viewy = viewmobj->y;
|
viewy = r_viewmobj->y;
|
||||||
viewx += quake.x;
|
viewx += quake.x;
|
||||||
viewy += quake.y;
|
viewy += quake.y;
|
||||||
|
|
||||||
if (viewmobj->subsector)
|
if (r_viewmobj->subsector)
|
||||||
viewsector = viewmobj->subsector->sector;
|
viewsector = r_viewmobj->subsector->sector;
|
||||||
else
|
else
|
||||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||||
}
|
}
|
||||||
|
@ -885,12 +884,12 @@ void R_SkyboxFrame(player_t *player)
|
||||||
thiscam = &camera;
|
thiscam = &camera;
|
||||||
|
|
||||||
// cut-away view stuff
|
// cut-away view stuff
|
||||||
viewmobj = skyboxmo[0];
|
r_viewmobj = skyboxmo[0];
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
if (!viewmobj)
|
if (!r_viewmobj)
|
||||||
{
|
{
|
||||||
const size_t playeri = (size_t)(player - players);
|
const size_t playeri = (size_t)(player - players);
|
||||||
I_Error("R_SkyboxFrame: viewmobj null (player %s)", sizeu1(playeri));
|
I_Error("R_SkyboxFrame: r_viewmobj null (player %s)", sizeu1(playeri));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (player->awayviewtics)
|
if (player->awayviewtics)
|
||||||
|
@ -921,13 +920,13 @@ void R_SkyboxFrame(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewangle += viewmobj->angle;
|
viewangle += r_viewmobj->angle;
|
||||||
|
|
||||||
viewplayer = player;
|
viewplayer = player;
|
||||||
|
|
||||||
viewx = viewmobj->x;
|
viewx = r_viewmobj->x;
|
||||||
viewy = viewmobj->y;
|
viewy = r_viewmobj->y;
|
||||||
viewz = viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||||
|
|
||||||
if (mapheaderinfo[gamemap-1])
|
if (mapheaderinfo[gamemap-1])
|
||||||
{
|
{
|
||||||
|
@ -967,29 +966,29 @@ void R_SkyboxFrame(player_t *player)
|
||||||
else if (mh->skybox_scaley < 0)
|
else if (mh->skybox_scaley < 0)
|
||||||
y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley;
|
y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley;
|
||||||
|
|
||||||
if (viewmobj->angle == 0)
|
if (r_viewmobj->angle == 0)
|
||||||
{
|
{
|
||||||
viewx += x;
|
viewx += x;
|
||||||
viewy += y;
|
viewy += y;
|
||||||
}
|
}
|
||||||
else if (viewmobj->angle == ANGLE_90)
|
else if (r_viewmobj->angle == ANGLE_90)
|
||||||
{
|
{
|
||||||
viewx -= y;
|
viewx -= y;
|
||||||
viewy += x;
|
viewy += x;
|
||||||
}
|
}
|
||||||
else if (viewmobj->angle == ANGLE_180)
|
else if (r_viewmobj->angle == ANGLE_180)
|
||||||
{
|
{
|
||||||
viewx -= x;
|
viewx -= x;
|
||||||
viewy -= y;
|
viewy -= y;
|
||||||
}
|
}
|
||||||
else if (viewmobj->angle == ANGLE_270)
|
else if (r_viewmobj->angle == ANGLE_270)
|
||||||
{
|
{
|
||||||
viewx += y;
|
viewx += y;
|
||||||
viewy -= x;
|
viewy -= x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
|
angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT;
|
||||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||||
}
|
}
|
||||||
|
@ -1000,8 +999,8 @@ void R_SkyboxFrame(player_t *player)
|
||||||
viewz += campos.z * -mh->skybox_scalez;
|
viewz += campos.z * -mh->skybox_scalez;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewmobj->subsector)
|
if (r_viewmobj->subsector)
|
||||||
viewsector = viewmobj->subsector->sector;
|
viewsector = r_viewmobj->subsector->sector;
|
||||||
else
|
else
|
||||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||||
|
|
||||||
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
|
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
|
||||||
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
|
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
|
||||||
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y);
|
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
||||||
|
|
||||||
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ extern fixed_t viewx, viewy, viewz;
|
||||||
extern angle_t viewangle, aimingangle;
|
extern angle_t viewangle, aimingangle;
|
||||||
extern sector_t *viewsector;
|
extern sector_t *viewsector;
|
||||||
extern player_t *viewplayer;
|
extern player_t *viewplayer;
|
||||||
|
extern mobj_t *r_viewmobj;
|
||||||
|
|
||||||
extern consvar_t cv_allowmlook;
|
extern consvar_t cv_allowmlook;
|
||||||
extern consvar_t cv_maxportals;
|
extern consvar_t cv_maxportals;
|
||||||
|
|
|
@ -1695,7 +1695,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
thing = thing->tracer;
|
thing = thing->tracer;
|
||||||
|
|
||||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
if (! R_ThingVisible(thing))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tr_x = thing->x - viewx;
|
tr_x = thing->x - viewx;
|
||||||
|
@ -2098,7 +2098,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||||
mobj_t *thing;
|
mobj_t *thing;
|
||||||
precipmobj_t *precipthing; // Tails 08-25-2002
|
precipmobj_t *precipthing; // Tails 08-25-2002
|
||||||
INT32 lightnum;
|
INT32 lightnum;
|
||||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
fixed_t limit_dist, hoop_limit_dist;
|
||||||
|
|
||||||
if (rendermode != render_soft)
|
if (rendermode != render_soft)
|
||||||
return;
|
return;
|
||||||
|
@ -2131,35 +2131,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||||
// If a limit exists, handle things a tiny bit different.
|
// If a limit exists, handle things a tiny bit different.
|
||||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||||
if (limit_dist || hoop_limit_dist)
|
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||||
{
|
{
|
||||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
|
||||||
{
|
|
||||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
|
||||||
|
|
||||||
if (thing->sprite == SPR_HOOP)
|
|
||||||
{
|
|
||||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (limit_dist && approx_dist > limit_dist)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_ProjectSprite(thing);
|
R_ProjectSprite(thing);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Draw everything in sector, no checks
|
|
||||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
|
||||||
if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW))
|
|
||||||
R_ProjectSprite(thing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
|
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
|
||||||
|
@ -2167,15 +2142,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||||
{
|
{
|
||||||
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
|
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
|
||||||
{
|
{
|
||||||
if (precipthing->precipflags & PCF_INVISIBLE)
|
if (R_PrecipThingVisible(precipthing, limit_dist))
|
||||||
continue;
|
R_ProjectPrecipitationSprite(precipthing);
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
|
||||||
|
|
||||||
if (approx_dist > limit_dist)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
R_ProjectPrecipitationSprite(precipthing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2877,6 +2845,55 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if thing may be drawn from our current view. */
|
||||||
|
boolean R_ThingVisible (mobj_t *thing)
|
||||||
|
{
|
||||||
|
return (!(
|
||||||
|
thing->sprite == SPR_NULL ||
|
||||||
|
( thing->flags2 & (MF2_DONTDRAW) ) ||
|
||||||
|
thing == r_viewmobj
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
||||||
|
fixed_t limit_dist,
|
||||||
|
fixed_t hoop_limit_dist)
|
||||||
|
{
|
||||||
|
fixed_t approx_dist;
|
||||||
|
|
||||||
|
if (! R_ThingVisible(thing))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||||
|
|
||||||
|
if (thing->sprite == SPR_HOOP)
|
||||||
|
{
|
||||||
|
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (limit_dist && approx_dist > limit_dist)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if precipitation may be drawn from our current view. */
|
||||||
|
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
||||||
|
fixed_t limit_dist)
|
||||||
|
{
|
||||||
|
fixed_t approx_dist;
|
||||||
|
|
||||||
|
if (( precipthing->precipflags & PCF_INVISIBLE ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||||
|
|
||||||
|
return ( approx_dist <= limit_dist );
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_DrawMasked
|
// R_DrawMasked
|
||||||
//
|
//
|
||||||
|
|
|
@ -59,6 +59,15 @@ void R_InitSprites(void);
|
||||||
void R_ClearSprites(void);
|
void R_ClearSprites(void);
|
||||||
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
||||||
|
|
||||||
|
boolean R_ThingVisible (mobj_t *thing);
|
||||||
|
|
||||||
|
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
||||||
|
fixed_t draw_dist,
|
||||||
|
fixed_t nights_draw_dist);
|
||||||
|
|
||||||
|
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
||||||
|
fixed_t precip_draw_dist);
|
||||||
|
|
||||||
/** Used to count the amount of masked elements
|
/** Used to count the amount of masked elements
|
||||||
* per portal to later group them in separate
|
* per portal to later group them in separate
|
||||||
* drawnode lists.
|
* drawnode lists.
|
||||||
|
|
369
src/s_sound.c
369
src/s_sound.c
|
@ -1441,6 +1441,12 @@ static tic_t pause_starttic;
|
||||||
/// Music Definitions
|
/// Music Definitions
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MUSICDEF_220,
|
||||||
|
MUSICDEF_221,
|
||||||
|
};
|
||||||
|
|
||||||
musicdef_t soundtestsfx = {
|
musicdef_t soundtestsfx = {
|
||||||
"_STSFX", // prevents exactly one valid track name from being used on the sound test
|
"_STSFX", // prevents exactly one valid track name from being used on the sound test
|
||||||
"Sound Effects",
|
"Sound Effects",
|
||||||
|
@ -1472,188 +1478,164 @@ static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid)
|
||||||
return INT16_MAX; // not found
|
return INT16_MAX; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_LoadMusicDefs(UINT16 wadnum)
|
static void
|
||||||
|
MusicDefStrcpy (char *p, const char *s, size_t n, int version)
|
||||||
{
|
{
|
||||||
UINT16 lumpnum;
|
strlcpy(p, s, n);
|
||||||
char *lump, *buf;
|
if (version == MUSICDEF_220)
|
||||||
char *musdeftext;
|
{
|
||||||
char *stoken;
|
while (( p = strchr(p, '_') ))
|
||||||
|
*p++ = ' '; // turn _ into spaces.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken,
|
||||||
|
musicdef_t **defp, int *versionp)
|
||||||
|
{
|
||||||
|
musicdef_t *def;
|
||||||
|
int version;
|
||||||
|
|
||||||
char *value;
|
char *value;
|
||||||
char *textline;
|
char *textline;
|
||||||
size_t size;
|
int i;
|
||||||
INT32 i;
|
|
||||||
musicdef_t *def = NULL;
|
|
||||||
UINT16 line = 1; // for better error msgs
|
|
||||||
|
|
||||||
lumpnum = W_CheckForMusicDefInPwad(wadnum);
|
if (!stricmp(stoken, "lump"))
|
||||||
if (lumpnum == INT16_MAX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
|
||||||
size = W_LumpLengthPwad(wadnum, lumpnum);
|
|
||||||
|
|
||||||
// Null-terminated MUSICDEF lump.
|
|
||||||
musdeftext = malloc(size+1);
|
|
||||||
if (!musdeftext)
|
|
||||||
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
|
|
||||||
M_Memcpy(musdeftext, lump, size);
|
|
||||||
musdeftext[size] = '\0';
|
|
||||||
|
|
||||||
// for strtok
|
|
||||||
buf = malloc(size+1);
|
|
||||||
if (!buf)
|
|
||||||
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
|
|
||||||
M_Memcpy(buf, musdeftext, size+1);
|
|
||||||
|
|
||||||
stoken = strtok(buf, "\r\n ");
|
|
||||||
// Find music def
|
|
||||||
while (stoken)
|
|
||||||
{
|
{
|
||||||
/*if ((stoken[0] == '/' && stoken[1] == '/')
|
value = strtok(NULL, " ");
|
||||||
|| (stoken[0] == '#')) // skip comments
|
if (!value)
|
||||||
{
|
{
|
||||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
CONS_Alert(CONS_WARNING,
|
||||||
if (def)
|
"MUSICDEF: Field '%s' is missing name. (file %s, line %d)\n",
|
||||||
stoken = strtok(NULL, "\r\n= ");
|
stoken, wadfiles[wadnum]->filename, line);
|
||||||
else
|
return false;
|
||||||
stoken = strtok(NULL, "\r\n ");
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
else*/ if (!stricmp(stoken, "lump"))
|
|
||||||
{
|
|
||||||
value = strtok(NULL, "\r\n ");
|
|
||||||
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_WARNING, "MUSICDEF: Lump '%s' is missing name. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
|
||||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
|
||||||
goto skip_lump;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No existing musicdefs
|
|
||||||
/*if (!musicdefstart)
|
|
||||||
{
|
|
||||||
musicdefstart = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
|
||||||
STRBUFCPY(musicdefstart->name, value);
|
|
||||||
strlwr(musicdefstart->name);
|
|
||||||
def = musicdefstart;
|
|
||||||
//CONS_Printf("S_LoadMusicDefs: Initialized musicdef w/ song '%s'\n", def->name);
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
|
||||||
musicdef_t *prev = NULL;
|
|
||||||
def = musicdefstart;
|
|
||||||
|
|
||||||
// Search if this is a replacement
|
|
||||||
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
|
|
||||||
while (def)
|
|
||||||
{
|
|
||||||
if (!stricmp(def->name, value))
|
|
||||||
{
|
|
||||||
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = def;
|
|
||||||
def = def->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found, add to the end.
|
|
||||||
if (!def)
|
|
||||||
{
|
|
||||||
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
|
||||||
STRBUFCPY(def->name, value);
|
|
||||||
strlwr(def->name);
|
|
||||||
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
|
|
||||||
if (prev != NULL)
|
|
||||||
prev->next = def;
|
|
||||||
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_lump:
|
|
||||||
stoken = strtok(NULL, "\r\n ");
|
|
||||||
line++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If this is set true, the line was invalid.
|
musicdef_t *prev = NULL;
|
||||||
boolean brokenline = false;
|
def = musicdefstart;
|
||||||
|
|
||||||
// Delimit only by line break.
|
// Search if this is a replacement
|
||||||
value = strtok(NULL, "\r\n");
|
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
|
||||||
|
while (def)
|
||||||
|
{
|
||||||
|
if (!stricmp(def->name, value))
|
||||||
|
{
|
||||||
|
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Find the equals sign.
|
prev = def;
|
||||||
value = strchr(value, '=');
|
def = def->next;
|
||||||
|
}
|
||||||
|
|
||||||
// It's not there?!
|
// Nothing found, add to the end.
|
||||||
|
if (!def)
|
||||||
|
{
|
||||||
|
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
||||||
|
STRBUFCPY(def->name, value);
|
||||||
|
strlwr(def->name);
|
||||||
|
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
|
||||||
|
if (prev != NULL)
|
||||||
|
prev->next = def;
|
||||||
|
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*defp) = def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!stricmp(stoken, "version"))
|
||||||
|
{
|
||||||
|
if (fields)/* is this not the first field? */
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
"MUSICDEF: Field '%s' must come first. (file %s, line %d)\n",
|
||||||
|
stoken, wadfiles[wadnum]->filename, line);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = strtok(NULL, " ");
|
||||||
if (!value)
|
if (!value)
|
||||||
brokenline = true;
|
{
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
"MUSICDEF: Field '%s' is missing version. (file %s, line %d)\n",
|
||||||
|
stoken, wadfiles[wadnum]->filename, line);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (strcasecmp(value, "2.2.0"))
|
||||||
|
(*versionp) = MUSICDEF_221;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
version = (*versionp);
|
||||||
|
|
||||||
|
if (version == MUSICDEF_220)
|
||||||
|
value = strtok(NULL, " =");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = strtok(NULL, "");
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
// Find the equals sign.
|
||||||
|
value = strchr(value, '=');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
"MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n",
|
||||||
|
stoken, wadfiles[wadnum]->filename, line);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
def = (*defp);
|
||||||
|
|
||||||
|
if (!def)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR,
|
||||||
|
"MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n",
|
||||||
|
stoken, wadfiles[wadnum]->filename, line);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != MUSICDEF_220)
|
||||||
{
|
{
|
||||||
// Skip the equals sign.
|
// Skip the equals sign.
|
||||||
value++;
|
value++;
|
||||||
|
|
||||||
// Now skip funny whitespace.
|
// Now skip funny whitespace.
|
||||||
if (value[0] == '\0') // :NOTHING:
|
value += strspn(value, "\t ");
|
||||||
brokenline = true;
|
|
||||||
else
|
|
||||||
value += strspn(value, "\t ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the line is valid, copy the text line from the lump data.
|
textline = value;
|
||||||
if (!brokenline)
|
i = atoi(value);
|
||||||
{
|
|
||||||
// strtok returns memory that already belongs to the input string.
|
|
||||||
value = musdeftext + (value - buf);
|
|
||||||
|
|
||||||
// Find the length of the line.
|
|
||||||
size = strcspn(value, "\r\n");
|
|
||||||
|
|
||||||
// Copy the line.
|
|
||||||
textline = malloc(size+1);
|
|
||||||
if (!textline)
|
|
||||||
I_Error("S_LoadMusicDefs: No more free memory for text line\n");
|
|
||||||
M_Memcpy(textline, value, size);
|
|
||||||
textline[size] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
|
||||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
|
||||||
goto skip_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!def)
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
|
||||||
free(textline);
|
|
||||||
free(buf);
|
|
||||||
free(musdeftext);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = atoi(textline);
|
|
||||||
|
|
||||||
|
/* based ignored lumps */
|
||||||
if (!stricmp(stoken, "usage")) {
|
if (!stricmp(stoken, "usage")) {
|
||||||
#if 0 // Ignore for now
|
#if 0 // Ignore for now
|
||||||
STRBUFCPY(def->usage, textline);
|
STRBUFCPY(def->usage, textline);
|
||||||
//CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage);
|
|
||||||
#endif
|
#endif
|
||||||
} else if (!stricmp(stoken, "source")) {
|
} else if (!stricmp(stoken, "source")) {
|
||||||
#if 0 // Ignore for now
|
#if 0 // Ignore for now
|
||||||
STRBUFCPY(def->source, textline);
|
STRBUFCPY(def->source, textline);
|
||||||
//CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->usage);
|
|
||||||
#endif
|
#endif
|
||||||
} else if (!stricmp(stoken, "title")) {
|
} else if (!stricmp(stoken, "title")) {
|
||||||
STRBUFCPY(def->title, textline);
|
MusicDefStrcpy(def->title, textline,
|
||||||
//CONS_Printf("S_LoadMusicDefs: Set title to '%s'\n", def->source);
|
sizeof def->title, version);
|
||||||
} else if (!stricmp(stoken, "alttitle")) {
|
} else if (!stricmp(stoken, "alttitle")) {
|
||||||
STRBUFCPY(def->alttitle, textline);
|
MusicDefStrcpy(def->alttitle, textline,
|
||||||
//CONS_Printf("S_LoadMusicDefs: Set alttitle to '%s'\n", def->source);
|
sizeof def->alttitle, version);
|
||||||
} else if (!stricmp(stoken, "authors")) {
|
} else if (!stricmp(stoken, "authors")) {
|
||||||
STRBUFCPY(def->authors, textline);
|
MusicDefStrcpy(def->authors, textline,
|
||||||
//CONS_Printf("S_LoadMusicDefs: Set authors to '%s'\n", def->source);
|
sizeof def->authors, version);
|
||||||
} else if (!stricmp(stoken, "soundtestpage")) {
|
} else if (!stricmp(stoken, "soundtestpage")) {
|
||||||
def->soundtestpage = (UINT8)i;
|
def->soundtestpage = (UINT8)i;
|
||||||
} else if (!stricmp(stoken, "soundtestcond")) {
|
} else if (!stricmp(stoken, "soundtestcond")) {
|
||||||
|
@ -1670,21 +1652,90 @@ skip_lump:
|
||||||
if (bpmf > 0)
|
if (bpmf > 0)
|
||||||
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
|
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
|
||||||
} else {
|
} else {
|
||||||
CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
CONS_Alert(CONS_WARNING,
|
||||||
|
"MUSICDEF: Invalid field '%s'. (file %s, line %d)\n",
|
||||||
|
stoken, wadfiles[wadnum]->filename, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the temporary text line from memory.
|
|
||||||
free(textline);
|
|
||||||
|
|
||||||
skip_field:
|
|
||||||
stoken = strtok(NULL, "\r\n= ");
|
|
||||||
line++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_LoadMusicDefs(UINT16 wadnum)
|
||||||
|
{
|
||||||
|
UINT16 lumpnum;
|
||||||
|
char *lump;
|
||||||
|
char *musdeftext;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
char *lf;
|
||||||
|
char *stoken;
|
||||||
|
|
||||||
|
size_t nlf;
|
||||||
|
size_t ncr;
|
||||||
|
|
||||||
|
musicdef_t *def = NULL;
|
||||||
|
int version = MUSICDEF_220;
|
||||||
|
int line = 1; // for better error msgs
|
||||||
|
boolean fields = false;
|
||||||
|
|
||||||
|
lumpnum = W_CheckForMusicDefInPwad(wadnum);
|
||||||
|
if (lumpnum == INT16_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||||
|
size = W_LumpLengthPwad(wadnum, lumpnum);
|
||||||
|
|
||||||
|
// Null-terminated MUSICDEF lump.
|
||||||
|
musdeftext = malloc(size+1);
|
||||||
|
if (!musdeftext)
|
||||||
|
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
|
||||||
|
M_Memcpy(musdeftext, lump, size);
|
||||||
|
musdeftext[size] = '\0';
|
||||||
|
|
||||||
|
// Find music def
|
||||||
|
stoken = musdeftext;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
lf = strpbrk(stoken, "\r\n");
|
||||||
|
if (lf)
|
||||||
|
{
|
||||||
|
if (*lf == '\n')
|
||||||
|
nlf = 1;
|
||||||
|
else
|
||||||
|
nlf = 0;
|
||||||
|
*lf++ = '\0';/* now we can delimit to here */
|
||||||
|
}
|
||||||
|
|
||||||
|
stoken = strtok(stoken, " ");
|
||||||
|
if (stoken)
|
||||||
|
{
|
||||||
|
if (! ReadMusicDefFields(wadnum, line, fields, stoken,
|
||||||
|
&def, &version))
|
||||||
|
break;
|
||||||
|
fields = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lf)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
line += nlf;
|
||||||
|
ncr = strspn(lf, "\r");/* skip CR */
|
||||||
|
lf += ncr;
|
||||||
|
nlf = strspn(lf, "\n");
|
||||||
|
lf += nlf;
|
||||||
|
}
|
||||||
|
while (nlf || ncr) ;
|
||||||
|
|
||||||
|
stoken = lf;/* now the next nonempty line */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;/* EOF */
|
||||||
|
}
|
||||||
|
|
||||||
free(musdeftext);
|
free(musdeftext);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -110,7 +110,6 @@ static SDL_bool disable_fullscreen = SDL_FALSE;
|
||||||
#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value
|
#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value
|
||||||
static SDL_bool disable_mouse = SDL_FALSE;
|
static SDL_bool disable_mouse = SDL_FALSE;
|
||||||
#define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus)
|
#define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus)
|
||||||
#define IGNORE_MOUSE (!cv_alwaysgrabmouse.value && (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL))
|
|
||||||
#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN)
|
#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN)
|
||||||
#define MOUSEBUTTONS_MAX MOUSEBUTTONS
|
#define MOUSEBUTTONS_MAX MOUSEBUTTONS
|
||||||
|
|
||||||
|
@ -362,6 +361,17 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean IgnoreMouse(void)
|
||||||
|
{
|
||||||
|
if (cv_alwaysgrabmouse.value)
|
||||||
|
return false;
|
||||||
|
if (menuactive)
|
||||||
|
return !M_MouseNeeded();
|
||||||
|
if (paused || con_destlines || chat_on || gamestate != GS_LEVEL)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void SDLdoGrabMouse(void)
|
static void SDLdoGrabMouse(void)
|
||||||
{
|
{
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
@ -388,7 +398,7 @@ void I_UpdateMouseGrab(void)
|
||||||
{
|
{
|
||||||
if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL
|
if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL
|
||||||
&& SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window
|
&& SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window
|
||||||
&& USE_MOUSEINPUT && !IGNORE_MOUSE)
|
&& USE_MOUSEINPUT && !IgnoreMouse())
|
||||||
SDLdoGrabMouse();
|
SDLdoGrabMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +606,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
||||||
}
|
}
|
||||||
//else firsttimeonmouse = SDL_FALSE;
|
//else firsttimeonmouse = SDL_FALSE;
|
||||||
|
|
||||||
if (USE_MOUSEINPUT && !IGNORE_MOUSE)
|
if (USE_MOUSEINPUT && !IgnoreMouse())
|
||||||
SDLdoGrabMouse();
|
SDLdoGrabMouse();
|
||||||
}
|
}
|
||||||
else if (!mousefocus && !kbfocus)
|
else if (!mousefocus && !kbfocus)
|
||||||
|
@ -647,7 +657,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
|
||||||
|
|
||||||
if (USE_MOUSEINPUT)
|
if (USE_MOUSEINPUT)
|
||||||
{
|
{
|
||||||
if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IGNORE_MOUSE && !firstmove))
|
if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IgnoreMouse() && !firstmove))
|
||||||
{
|
{
|
||||||
SDLdoUngrabMouse();
|
SDLdoUngrabMouse();
|
||||||
firstmove = false;
|
firstmove = false;
|
||||||
|
@ -700,7 +710,7 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
|
||||||
// this apparently makes a mouse button down event but not a mouse button up event,
|
// this apparently makes a mouse button down event but not a mouse button up event,
|
||||||
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
|
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
|
||||||
// -- Monster Iestyn (28/05/18)
|
// -- Monster Iestyn (28/05/18)
|
||||||
if (SDL_GetMouseFocus() != window || IGNORE_MOUSE)
|
if (SDL_GetMouseFocus() != window || IgnoreMouse())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/// \todo inputEvent.button.which
|
/// \todo inputEvent.button.which
|
||||||
|
@ -1082,7 +1092,7 @@ void I_StartupMouse(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
firsttimeonmouse = SDL_FALSE;
|
firsttimeonmouse = SDL_FALSE;
|
||||||
if (cv_usemouse.value && !IGNORE_MOUSE)
|
if (cv_usemouse.value && !IgnoreMouse())
|
||||||
SDLdoGrabMouse();
|
SDLdoGrabMouse();
|
||||||
else
|
else
|
||||||
SDLdoUngrabMouse();
|
SDLdoUngrabMouse();
|
||||||
|
|
|
@ -1278,13 +1278,15 @@ void ST_preDrawTitleCard(void)
|
||||||
//
|
//
|
||||||
void ST_runTitleCard(void)
|
void ST_runTitleCard(void)
|
||||||
{
|
{
|
||||||
|
boolean run = !(paused || P_AutoPause());
|
||||||
|
|
||||||
if (!G_IsTitleCardAvailable())
|
if (!G_IsTitleCardAvailable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(paused || P_AutoPause()))
|
if (run || (lt_ticker < PRELEVELTIME))
|
||||||
{
|
{
|
||||||
// tick
|
// tick
|
||||||
lt_ticker++;
|
lt_ticker++;
|
||||||
|
|
Loading…
Reference in a new issue