mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 07:22:28 +00:00
Merge branch 'master' into opengl-improvements
This commit is contained in:
commit
18d018b8ff
38 changed files with 1527 additions and 693 deletions
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(SRB2
|
project(SRB2
|
||||||
VERSION 2.1.14
|
VERSION 2.1.17
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2.1.16.{branch}-{build}
|
version: 2.1.17.{branch}-{build}
|
||||||
os: MinGW
|
os: MinGW
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -393,18 +393,25 @@ if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${SRB2_CONFIG_USEASM})
|
if(${SRB2_CONFIG_USEASM})
|
||||||
|
#SRB2_ASM_FLAGS can be used to pass flags to either nasm or yasm.
|
||||||
|
if(${CMAKE_SYSTEM} MATCHES "Linux")
|
||||||
|
set(SRB2_ASM_FLAGS "-DLINUX ${SRB2_ASM_FLAGS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(${SRB2_CONFIG_YASM})
|
if(${SRB2_CONFIG_YASM})
|
||||||
set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS} nas)
|
set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS} nas)
|
||||||
|
set(CMAKE_ASM_YASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.")
|
||||||
enable_language(ASM_YASM)
|
enable_language(ASM_YASM)
|
||||||
else()
|
else()
|
||||||
set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} nas)
|
set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} nas)
|
||||||
|
set(CMAKE_ASM_NASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.")
|
||||||
enable_language(ASM_NASM)
|
enable_language(ASM_NASM)
|
||||||
endif()
|
endif()
|
||||||
set(SRB2_USEASM ON)
|
set(SRB2_USEASM ON)
|
||||||
add_definitions(-DUSEASM)
|
add_definitions(-DUSEASM)
|
||||||
else()
|
else()
|
||||||
set(SRB2_USEASM OFF)
|
set(SRB2_USEASM OFF)
|
||||||
add_definitions(-DNOASM -DNONX86)
|
add_definitions(-DNONX86 -DNORUSEASM)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
|
|
203
src/d_clisrv.c
203
src/d_clisrv.c
|
@ -72,14 +72,21 @@
|
||||||
#define MAX_REASONLENGTH 30
|
#define MAX_REASONLENGTH 30
|
||||||
|
|
||||||
boolean server = true; // true or false but !server == client
|
boolean server = true; // true or false but !server == client
|
||||||
|
#define client (!server)
|
||||||
boolean nodownload = false;
|
boolean nodownload = false;
|
||||||
static boolean serverrunning = false;
|
static boolean serverrunning = false;
|
||||||
INT32 serverplayer = 0;
|
INT32 serverplayer = 0;
|
||||||
char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
|
char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
|
||||||
|
|
||||||
// server specific vars
|
// Server specific vars
|
||||||
UINT8 playernode[MAXPLAYERS];
|
UINT8 playernode[MAXPLAYERS];
|
||||||
|
|
||||||
|
// Minimum timeout for sending the savegame
|
||||||
|
// The actual timeout will be longer depending on the savegame length
|
||||||
|
tic_t jointimeout = (10*TICRATE);
|
||||||
|
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
|
||||||
|
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
|
||||||
|
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
UINT16 pingmeasurecount = 1;
|
UINT16 pingmeasurecount = 1;
|
||||||
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
|
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
|
||||||
|
@ -108,7 +115,7 @@ static UINT8 resynch_local_inprogress = false; // WE are desynched and getting p
|
||||||
static UINT8 player_joining = false;
|
static UINT8 player_joining = false;
|
||||||
UINT8 hu_resynching = 0;
|
UINT8 hu_resynching = 0;
|
||||||
|
|
||||||
// client specific
|
// Client specific
|
||||||
static ticcmd_t localcmds;
|
static ticcmd_t localcmds;
|
||||||
static ticcmd_t localcmds2;
|
static ticcmd_t localcmds2;
|
||||||
static boolean cl_packetmissed;
|
static boolean cl_packetmissed;
|
||||||
|
@ -404,7 +411,7 @@ static void ExtraDataTicker(void)
|
||||||
// If you are a client, you can safely forget the net commands for this tic
|
// If you are a client, you can safely forget the net commands for this tic
|
||||||
// If you are the server, you need to remember them until every client has been aknowledged,
|
// If you are the server, you need to remember them until every client has been aknowledged,
|
||||||
// because if you need to resend a PT_SERVERTICS packet, you need to put the commands in it
|
// because if you need to resend a PT_SERVERTICS packet, you need to put the commands in it
|
||||||
if (!server)
|
if (client)
|
||||||
D_FreeTextcmd(gametic);
|
D_FreeTextcmd(gametic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,7 +919,7 @@ static inline void resynch_read_others(resynchend_pak *p)
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
// We don't care if they're in the game or not, just write all the data.
|
// We don't care if they're in the game or not, just write all the data.
|
||||||
players[i].spectator = !(loc_ingame & i<<i);
|
players[i].spectator = !(loc_ingame & (1<<i));
|
||||||
players[i].ctfteam = (INT32)LONG(p->ctfteam[i]); // no, 0 does not mean spectator, at least not in Match
|
players[i].ctfteam = (INT32)LONG(p->ctfteam[i]); // no, 0 does not mean spectator, at least not in Match
|
||||||
players[i].score = (UINT32)LONG(p->score[i]);
|
players[i].score = (UINT32)LONG(p->score[i]);
|
||||||
players[i].numboxes = SHORT(p->numboxes[i]);
|
players[i].numboxes = SHORT(p->numboxes[i]);
|
||||||
|
@ -1033,6 +1040,9 @@ static void SV_AcknowledgeResynchAck(INT32 node, UINT8 rsg)
|
||||||
resynch_status[node] &= ~(1<<rsg);
|
resynch_status[node] &= ~(1<<rsg);
|
||||||
--resynch_score[node]; // unpenalize
|
--resynch_score[node]; // unpenalize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't let resynch cause a timeout
|
||||||
|
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||||
}
|
}
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
// end resynch
|
// end resynch
|
||||||
|
@ -1126,12 +1136,17 @@ static inline void CL_DrawConnectionStatus(void)
|
||||||
{
|
{
|
||||||
#ifdef JOININGAME
|
#ifdef JOININGAME
|
||||||
case CL_DOWNLOADSAVEGAME:
|
case CL_DOWNLOADSAVEGAME:
|
||||||
cltext = M_GetText("Downloading game state...");
|
if (lastfilenum != -1)
|
||||||
Net_GetNetStat();
|
{
|
||||||
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
cltext = M_GetText("Downloading game state...");
|
||||||
va(" %4uK",fileneeded[lastfilenum].currentsize>>10));
|
Net_GetNetStat();
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
||||||
va("%3.1fK/s ", ((double)getbps)/1024));
|
va(" %4uK",fileneeded[lastfilenum].currentsize>>10));
|
||||||
|
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
||||||
|
va("%3.1fK/s ", ((double)getbps)/1024));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cltext = M_GetText("Waiting to download game state...");
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case CL_ASKJOIN:
|
case CL_ASKJOIN:
|
||||||
|
@ -1146,25 +1161,31 @@ static inline void CL_DrawConnectionStatus(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INT32 dldlength;
|
if (lastfilenum != -1)
|
||||||
static char tempname[32];
|
{
|
||||||
|
INT32 dldlength;
|
||||||
|
static char tempname[32];
|
||||||
|
|
||||||
Net_GetNetStat();
|
Net_GetNetStat();
|
||||||
dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256);
|
dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256);
|
||||||
if (dldlength > 256)
|
if (dldlength > 256)
|
||||||
dldlength = 256;
|
dldlength = 256;
|
||||||
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111);
|
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111);
|
||||||
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96);
|
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96);
|
||||||
|
|
||||||
memset(tempname, 0, sizeof(tempname));
|
memset(tempname, 0, sizeof(tempname));
|
||||||
nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31));
|
nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31));
|
||||||
|
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP,
|
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP,
|
||||||
va(M_GetText("Downloading \"%s\""), tempname));
|
va(M_GetText("Downloading \"%s\""), tempname));
|
||||||
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
||||||
va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,fileneeded[lastfilenum].totalsize>>10));
|
va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,fileneeded[lastfilenum].totalsize>>10));
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
|
||||||
va("%3.1fK/s ", ((double)getbps)/1024));
|
va("%3.1fK/s ", ((double)getbps)/1024));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP,
|
||||||
|
M_GetText("Waiting to download files..."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1453,6 +1474,10 @@ static void SV_SendSaveGame(INT32 node)
|
||||||
|
|
||||||
SV_SendRam(node, buffertosend, length, SF_RAM, 0);
|
SV_SendRam(node, buffertosend, length, SF_RAM, 0);
|
||||||
save_p = NULL;
|
save_p = NULL;
|
||||||
|
|
||||||
|
// Remember when we started sending the savegame so we can handle timeouts
|
||||||
|
sendingsavegame[node] = true;
|
||||||
|
freezetimeout[node] = I_GetTime() + jointimeout + length / 1024; // 1 extra tic for each kilobyte
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DUMPCONSISTENCY
|
#ifdef DUMPCONSISTENCY
|
||||||
|
@ -1745,7 +1770,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server)
|
if (client)
|
||||||
{
|
{
|
||||||
D_ParseFileneeded(serverlist[i].info.fileneedednum,
|
D_ParseFileneeded(serverlist[i].info.fileneedednum,
|
||||||
serverlist[i].info.fileneeded);
|
serverlist[i].info.fileneeded);
|
||||||
|
@ -1919,7 +1944,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
||||||
*oldtic = I_GetTime();
|
*oldtic = I_GetTime();
|
||||||
|
|
||||||
#ifdef CLIENT_LOADINGSCREEN
|
#ifdef CLIENT_LOADINGSCREEN
|
||||||
if (!server && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED)
|
if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED)
|
||||||
{
|
{
|
||||||
F_TitleScreenTicker(true);
|
F_TitleScreenTicker(true);
|
||||||
F_TitleScreenDrawer();
|
F_TitleScreenDrawer();
|
||||||
|
@ -1961,7 +1986,7 @@ static void CL_ConnectToServer(boolean viams)
|
||||||
cl_mode = CL_SEARCHING;
|
cl_mode = CL_SEARCHING;
|
||||||
|
|
||||||
#ifdef CLIENT_LOADINGSCREEN
|
#ifdef CLIENT_LOADINGSCREEN
|
||||||
lastfilenum = 0;
|
lastfilenum = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JOININGAME
|
#ifdef JOININGAME
|
||||||
|
@ -2032,7 +2057,7 @@ static void CL_ConnectToServer(boolean viams)
|
||||||
pnumnodes++;
|
pnumnodes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!(cl_mode == CL_CONNECTED && (!server || (server && nodewaited <= pnumnodes))));
|
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
|
||||||
|
|
||||||
DEBFILE(va("Synchronisation Finished\n"));
|
DEBFILE(va("Synchronisation Finished\n"));
|
||||||
|
|
||||||
|
@ -2569,6 +2594,14 @@ static void Command_Kick(void)
|
||||||
WRITESINT8(p, pn);
|
WRITESINT8(p, pn);
|
||||||
if (pn == -1 || pn == 0)
|
if (pn == -1 || pn == 0)
|
||||||
return;
|
return;
|
||||||
|
// Special case if we are trying to kick a player who is downloading the game state:
|
||||||
|
// trigger a timeout instead of kicking them, because a kick would only
|
||||||
|
// take effect after they have finished downloading
|
||||||
|
if (sendingsavegame[playernode[pn]])
|
||||||
|
{
|
||||||
|
Net_ConnectionTimeout(playernode[pn]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (COM_Argc() == 2)
|
if (COM_Argc() == 2)
|
||||||
{
|
{
|
||||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||||
|
@ -2781,7 +2814,12 @@ consvar_t cv_blamecfail = {"blamecfail", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL
|
||||||
|
|
||||||
// max file size to send to a player (in kilobytes)
|
// max file size to send to a player (in kilobytes)
|
||||||
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_maxsend = {"maxsend", "1024", CV_SAVE, maxsend_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_maxsend = {"maxsend", "4096", CV_SAVE, maxsend_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_noticedownload = {"noticedownload", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// Speed of file downloading (in packets per tic)
|
||||||
|
static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_downloadspeed = {"downloadspeed", "16", CV_SAVE, downloadspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static void Got_AddPlayer(UINT8 **p, INT32 playernum);
|
static void Got_AddPlayer(UINT8 **p, INT32 playernum);
|
||||||
|
|
||||||
|
@ -2804,6 +2842,9 @@ void D_ClientServerInit(void)
|
||||||
COM_AddCommand("drop", Command_Drop);
|
COM_AddCommand("drop", Command_Drop);
|
||||||
COM_AddCommand("droprate", Command_Droprate);
|
COM_AddCommand("droprate", Command_Droprate);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _DEBUG
|
||||||
|
COM_AddCommand("numnodes", Command_Numnodes);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RegisterNetXCmd(XD_KICK, Got_KickCmd);
|
RegisterNetXCmd(XD_KICK, Got_KickCmd);
|
||||||
|
@ -2839,6 +2880,7 @@ static void ResetNode(INT32 node)
|
||||||
supposedtics[node] = gametic;
|
supposedtics[node] = gametic;
|
||||||
nodewaiting[node] = 0;
|
nodewaiting[node] = 0;
|
||||||
playerpernode[node] = 0;
|
playerpernode[node] = 0;
|
||||||
|
sendingsavegame[node] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SV_ResetServer(void)
|
void SV_ResetServer(void)
|
||||||
|
@ -3131,7 +3173,7 @@ void CL_RemoveSplitscreenPlayer(void)
|
||||||
// is there a game running
|
// is there a game running
|
||||||
boolean Playing(void)
|
boolean Playing(void)
|
||||||
{
|
{
|
||||||
return (server && serverrunning) || (!server && cl_mode == CL_CONNECTED);
|
return (server && serverrunning) || (client && cl_mode == CL_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean SV_SpawnServer(void)
|
boolean SV_SpawnServer(void)
|
||||||
|
@ -3394,12 +3436,19 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
}
|
}
|
||||||
if (cl_mode == CL_WAITJOINRESPONSE)
|
if (cl_mode == CL_WAITJOINRESPONSE)
|
||||||
{
|
{
|
||||||
|
// Save the reason so it can be displayed after quitting the netgame
|
||||||
|
char *reason = strdup(netbuffer->u.serverrefuse.reason);
|
||||||
|
if (!reason)
|
||||||
|
I_Error("Out of memory!\n");
|
||||||
|
|
||||||
D_QuitNetGame();
|
D_QuitNetGame();
|
||||||
CL_Reset();
|
CL_Reset();
|
||||||
D_StartTitle();
|
D_StartTitle();
|
||||||
|
|
||||||
M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"),
|
M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"),
|
||||||
netbuffer->u.serverrefuse.reason), NULL, MM_NOTHING);
|
reason), NULL, MM_NOTHING);
|
||||||
|
|
||||||
|
free(reason);
|
||||||
|
|
||||||
// Will be reset by caller. Signals refusal.
|
// Will be reset by caller. Signals refusal.
|
||||||
cl_mode = CL_ABORTED;
|
cl_mode = CL_ABORTED;
|
||||||
|
@ -3420,7 +3469,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
if (cl_mode != CL_WAITJOINRESPONSE)
|
if (cl_mode != CL_WAITJOINRESPONSE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!server)
|
if (client)
|
||||||
{
|
{
|
||||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||||
gametype = netbuffer->u.servercfg.gametype;
|
gametype = netbuffer->u.servercfg.gametype;
|
||||||
|
@ -3548,7 +3597,7 @@ FILESTAMP
|
||||||
case PT_CLIENT2MIS:
|
case PT_CLIENT2MIS:
|
||||||
case PT_NODEKEEPALIVE:
|
case PT_NODEKEEPALIVE:
|
||||||
case PT_NODEKEEPALIVEMIS:
|
case PT_NODEKEEPALIVEMIS:
|
||||||
if (!server)
|
if (client)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Ignore tics from those not synched
|
// Ignore tics from those not synched
|
||||||
|
@ -3581,6 +3630,13 @@ FILESTAMP
|
||||||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// If a client sends a ticcmd it should mean they are done receiving the savegame
|
||||||
|
sendingsavegame[node] = false;
|
||||||
|
|
||||||
|
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
||||||
|
/// \todo Use a separate cvar for that kind of timeout?
|
||||||
|
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||||
|
|
||||||
// Copy ticcmd
|
// Copy ticcmd
|
||||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||||
|
|
||||||
|
@ -3647,7 +3703,7 @@ FILESTAMP
|
||||||
case PT_TEXTCMD2: // splitscreen special
|
case PT_TEXTCMD2: // splitscreen special
|
||||||
netconsole = nodetoplayer2[node];
|
netconsole = nodetoplayer2[node];
|
||||||
case PT_TEXTCMD:
|
case PT_TEXTCMD:
|
||||||
if (!server)
|
if (client)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (netconsole < 0 || netconsole >= MAXPLAYERS)
|
if (netconsole < 0 || netconsole >= MAXPLAYERS)
|
||||||
|
@ -3691,7 +3747,7 @@ FILESTAMP
|
||||||
break;
|
break;
|
||||||
case PT_NODETIMEOUT:
|
case PT_NODETIMEOUT:
|
||||||
case PT_CLIENTQUIT:
|
case PT_CLIENTQUIT:
|
||||||
if (!server)
|
if (client)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// nodeingame will be put false in the execution of kick command
|
// nodeingame will be put false in the execution of kick command
|
||||||
|
@ -3723,7 +3779,7 @@ FILESTAMP
|
||||||
// Only accept PT_RESYNCHEND from the server.
|
// Only accept PT_RESYNCHEND from the server.
|
||||||
if (node != servernode)
|
if (node != servernode)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s recieved 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)
|
||||||
{
|
{
|
||||||
|
@ -3801,13 +3857,20 @@ FILESTAMP
|
||||||
neededtic = realend;
|
neededtic = realend;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
DEBFILE(va("frame not in bound: %u\n", neededtic));
|
DEBFILE(va("frame not in bound: %u\n", neededtic));
|
||||||
|
/*if (realend < neededtic - 2 * TICRATE || neededtic + 2 * TICRATE < realstart)
|
||||||
|
I_Error("Received an out of order PT_SERVERTICS packet!\n"
|
||||||
|
"Got tics %d-%d, needed tic %d\n\n"
|
||||||
|
"Please report this crash on the Master Board,\n"
|
||||||
|
"IRC or Discord so it can be fixed.\n", (INT32)realstart, (INT32)realend, (INT32)neededtic);*/
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PT_RESYNCHING:
|
case PT_RESYNCHING:
|
||||||
// Only accept PT_RESYNCHING from the server.
|
// Only accept PT_RESYNCHING from the server.
|
||||||
if (node != servernode)
|
if (node != servernode)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s recieved 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)
|
||||||
{
|
{
|
||||||
|
@ -3827,7 +3890,7 @@ FILESTAMP
|
||||||
// Only accept PT_PING from the server.
|
// Only accept PT_PING from the server.
|
||||||
if (node != servernode)
|
if (node != servernode)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s recieved 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)
|
||||||
{
|
{
|
||||||
|
@ -3841,7 +3904,7 @@ FILESTAMP
|
||||||
}
|
}
|
||||||
|
|
||||||
//Update client ping table from the server.
|
//Update client ping table from the server.
|
||||||
if (!server)
|
if (client)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (i = 0; i < MAXNETNODES; i++)
|
||||||
|
@ -3854,7 +3917,7 @@ FILESTAMP
|
||||||
case PT_SERVERCFG:
|
case PT_SERVERCFG:
|
||||||
break;
|
break;
|
||||||
case PT_FILEFRAGMENT:
|
case PT_FILEFRAGMENT:
|
||||||
if (!server)
|
if (client)
|
||||||
Got_Filetxpak();
|
Got_Filetxpak();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -3884,17 +3947,18 @@ FILESTAMP
|
||||||
HandleConnect(node);
|
HandleConnect(node);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (netbuffer->packettype == PT_SERVERSHUTDOWN && node == servernode
|
if (node == servernode && client && cl_mode != CL_SEARCHING)
|
||||||
&& !server && cl_mode != CL_SEARCHING)
|
|
||||||
{
|
{
|
||||||
HandleShutdown(node);
|
if (netbuffer->packettype == PT_SERVERSHUTDOWN)
|
||||||
continue;
|
{
|
||||||
}
|
HandleShutdown(node);
|
||||||
if (netbuffer->packettype == PT_NODETIMEOUT && node == servernode
|
continue;
|
||||||
&& !server && cl_mode != CL_SEARCHING)
|
}
|
||||||
{
|
if (netbuffer->packettype == PT_NODETIMEOUT)
|
||||||
HandleTimeout(node);
|
{
|
||||||
continue;
|
HandleTimeout(node);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
|
@ -3911,7 +3975,7 @@ FILESTAMP
|
||||||
// Packet received from someone already playing
|
// Packet received from someone already playing
|
||||||
if (nodeingame[node])
|
if (nodeingame[node])
|
||||||
HandlePacketFromPlayer(node);
|
HandlePacketFromPlayer(node);
|
||||||
// Packet received from someone trying to join
|
// Packet received from someone not playing
|
||||||
else
|
else
|
||||||
HandlePacketFromAwayNode(node);
|
HandlePacketFromAwayNode(node);
|
||||||
}
|
}
|
||||||
|
@ -4042,7 +4106,7 @@ static void CL_SendClientCmd(void)
|
||||||
|
|
||||||
if (gamestate == GS_WAITINGPLAYERS)
|
if (gamestate == GS_WAITINGPLAYERS)
|
||||||
{
|
{
|
||||||
// send NODEKEEPALIVE packet
|
// Send PT_NODEKEEPALIVE packet
|
||||||
netbuffer->packettype += 4;
|
netbuffer->packettype += 4;
|
||||||
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);
|
||||||
|
@ -4052,7 +4116,7 @@ static void CL_SendClientCmd(void)
|
||||||
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]);
|
||||||
|
|
||||||
// send a special packet with 2 cmd for splitscreen
|
// Send a special packet with 2 cmd for splitscreen
|
||||||
if (splitscreen || botingame)
|
if (splitscreen || botingame)
|
||||||
{
|
{
|
||||||
netbuffer->packettype += 2;
|
netbuffer->packettype += 2;
|
||||||
|
@ -4067,23 +4131,23 @@ static void CL_SendClientCmd(void)
|
||||||
|
|
||||||
if (cl_mode == CL_CONNECTED || dedicated)
|
if (cl_mode == CL_CONNECTED || dedicated)
|
||||||
{
|
{
|
||||||
// send extra data if needed
|
// Send extra data if needed
|
||||||
if (localtextcmd[0])
|
if (localtextcmd[0])
|
||||||
{
|
{
|
||||||
netbuffer->packettype = PT_TEXTCMD;
|
netbuffer->packettype = PT_TEXTCMD;
|
||||||
M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1);
|
M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1);
|
||||||
// all extra data have been sended
|
// All extra data have been sent
|
||||||
if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // send can fail...
|
if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail...
|
||||||
localtextcmd[0] = 0;
|
localtextcmd[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send extra data if needed for player 2 (splitscreen)
|
// Send extra data if needed for player 2 (splitscreen)
|
||||||
if (localtextcmd2[0])
|
if (localtextcmd2[0])
|
||||||
{
|
{
|
||||||
netbuffer->packettype = PT_TEXTCMD2;
|
netbuffer->packettype = PT_TEXTCMD2;
|
||||||
M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1);
|
M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1);
|
||||||
// all extra data have been sended
|
// All extra data have been sent
|
||||||
if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // send can fail...
|
if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail...
|
||||||
localtextcmd2[0] = 0;
|
localtextcmd2[0] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4347,7 +4411,7 @@ static inline void PingUpdate(void)
|
||||||
//check for ping limit breakage.
|
//check for ping limit breakage.
|
||||||
if (cv_maxping.value)
|
if (cv_maxping.value)
|
||||||
{
|
{
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
for (i = 1; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
|
if (playeringame[i] && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
|
||||||
{
|
{
|
||||||
|
@ -4361,7 +4425,7 @@ static inline void PingUpdate(void)
|
||||||
//in that case, it is probably the server's fault.
|
//in that case, it is probably the server's fault.
|
||||||
if (numlaggers < D_NumPlayers() - 1)
|
if (numlaggers < D_NumPlayers() - 1)
|
||||||
{
|
{
|
||||||
for (i = 1; i < MAXNETNODES; i++)
|
for (i = 1; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && laggers[i])
|
if (playeringame[i] && laggers[i])
|
||||||
{
|
{
|
||||||
|
@ -4376,7 +4440,7 @@ static inline void PingUpdate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
//make the ping packet and clear server data for next one
|
//make the ping packet and clear server data for next one
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
netbuffer->u.pingtable[i] = realpingtable[i] / pingmeasurecount;
|
netbuffer->u.pingtable[i] = realpingtable[i] / pingmeasurecount;
|
||||||
//server takes a snapshot of the real ping for display.
|
//server takes a snapshot of the real ping for display.
|
||||||
|
@ -4386,7 +4450,7 @@ static inline void PingUpdate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
//send out our ping packets
|
//send out our ping packets
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
||||||
|
|
||||||
|
@ -4435,7 +4499,7 @@ void NetUpdate(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!server)
|
if (client)
|
||||||
maketic = neededtic;
|
maketic = neededtic;
|
||||||
|
|
||||||
Local_Maketic(realtics); // make local tic, and call menu?
|
Local_Maketic(realtics); // make local tic, and call menu?
|
||||||
|
@ -4450,7 +4514,7 @@ FILESTAMP
|
||||||
|
|
||||||
MasterClient_Ticker(); // Acking the Master Server
|
MasterClient_Ticker(); // Acking the Master Server
|
||||||
|
|
||||||
if (!server)
|
if (client)
|
||||||
{
|
{
|
||||||
if (!resynch_local_inprogress)
|
if (!resynch_local_inprogress)
|
||||||
CL_SendClientCmd(); // Send tic cmd
|
CL_SendClientCmd(); // Send tic cmd
|
||||||
|
@ -4500,6 +4564,11 @@ FILESTAMP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Net_AckTicker();
|
Net_AckTicker();
|
||||||
|
// Handle timeouts to prevent definitive freezes from happenning
|
||||||
|
if (server)
|
||||||
|
for (i = 1; i < MAXNETNODES; i++)
|
||||||
|
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
||||||
|
Net_ConnectionTimeout(i);
|
||||||
nowtime /= NEWTICRATERATIO;
|
nowtime /= NEWTICRATERATIO;
|
||||||
if (nowtime > resptime)
|
if (nowtime > resptime)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,9 @@ typedef enum
|
||||||
void Command_Drop(void);
|
void Command_Drop(void);
|
||||||
void Command_Droprate(void);
|
void Command_Droprate(void);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _DEBUG
|
||||||
|
void Command_Numnodes(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
@ -447,6 +450,7 @@ extern consvar_t cv_playbackspeed;
|
||||||
#define KICK_MSG_CUSTOM_BAN 8
|
#define KICK_MSG_CUSTOM_BAN 8
|
||||||
|
|
||||||
extern boolean server;
|
extern boolean server;
|
||||||
|
#define client (!server)
|
||||||
extern boolean dedicated; // For dedicated server
|
extern boolean dedicated; // For dedicated server
|
||||||
extern UINT16 software_MAXPACKETLENGTH;
|
extern UINT16 software_MAXPACKETLENGTH;
|
||||||
extern boolean acceptnewnode;
|
extern boolean acceptnewnode;
|
||||||
|
@ -454,13 +458,14 @@ extern SINT8 servernode;
|
||||||
|
|
||||||
void Command_Ping_f(void);
|
void Command_Ping_f(void);
|
||||||
extern tic_t connectiontimeout;
|
extern tic_t connectiontimeout;
|
||||||
|
extern tic_t jointimeout;
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
extern UINT16 pingmeasurecount;
|
extern UINT16 pingmeasurecount;
|
||||||
extern UINT32 realpingtable[MAXPLAYERS];
|
extern UINT32 realpingtable[MAXPLAYERS];
|
||||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend;
|
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, 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);
|
||||||
|
|
102
src/d_net.c
102
src/d_net.c
|
@ -42,7 +42,7 @@
|
||||||
// Normally maketic >= gametic > 0
|
// Normally maketic >= gametic > 0
|
||||||
|
|
||||||
#define FORCECLOSE 0x8000
|
#define FORCECLOSE 0x8000
|
||||||
tic_t connectiontimeout = (15*TICRATE);
|
tic_t connectiontimeout = (10*TICRATE);
|
||||||
|
|
||||||
/// \brief network packet
|
/// \brief network packet
|
||||||
doomcom_t *doomcom = NULL;
|
doomcom_t *doomcom = NULL;
|
||||||
|
@ -62,7 +62,7 @@ INT32 net_bandwidth;
|
||||||
/// \brief max length per packet
|
/// \brief max length per packet
|
||||||
INT16 hardware_MAXPACKETLENGTH;
|
INT16 hardware_MAXPACKETLENGTH;
|
||||||
|
|
||||||
void (*I_NetGet)(void) = NULL;
|
boolean (*I_NetGet)(void) = NULL;
|
||||||
void (*I_NetSend)(void) = NULL;
|
void (*I_NetSend)(void) = NULL;
|
||||||
boolean (*I_NetCanSend)(void) = NULL;
|
boolean (*I_NetCanSend)(void) = NULL;
|
||||||
boolean (*I_NetCanGet)(void) = NULL;
|
boolean (*I_NetCanGet)(void) = NULL;
|
||||||
|
@ -142,7 +142,7 @@ typedef struct
|
||||||
UINT8 destinationnode; // The node to send the ack to
|
UINT8 destinationnode; // The node to send the ack to
|
||||||
tic_t senttime; // The time when the ack was sent
|
tic_t senttime; // The time when the ack was sent
|
||||||
UINT16 length; // The packet size
|
UINT16 length; // The packet size
|
||||||
UINT16 resentnum; // The number of
|
UINT16 resentnum; // The number of times the ack has been resent
|
||||||
union {
|
union {
|
||||||
SINT8 raw[MAXPACKETLENGTH];
|
SINT8 raw[MAXPACKETLENGTH];
|
||||||
doomdata_t data;
|
doomdata_t data;
|
||||||
|
@ -152,11 +152,12 @@ typedef struct
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CLOSE = 1, // flag is set when connection is closing
|
NF_CLOSE = 1, // Flag is set when connection is closing
|
||||||
|
NF_TIMEOUT = 2, // Flag is set when the node got a timeout
|
||||||
} node_flags_t;
|
} node_flags_t;
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
// table of packet that was not acknowleged can be resend (the sender window)
|
// Table of packets that were not acknowleged can be resent (the sender window)
|
||||||
static ackpak_t ackpak[MAXACKPACKETS];
|
static ackpak_t ackpak[MAXACKPACKETS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -274,6 +275,38 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Counts how many acks are free
|
||||||
|
*
|
||||||
|
* \param urgent True if the type of the packet meant to
|
||||||
|
* use an ack is lower than PT_CANFAIL
|
||||||
|
* If for some reason you don't want use it
|
||||||
|
* for any packet type in particular,
|
||||||
|
* just set to false
|
||||||
|
* \return The number of free acks
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
INT32 Net_GetFreeAcks(boolean urgent)
|
||||||
|
{
|
||||||
|
INT32 i, numfreeslot = 0;
|
||||||
|
INT32 n = 0; // Number of free acks found
|
||||||
|
|
||||||
|
for (i = 0; i < MAXACKPACKETS; i++)
|
||||||
|
if (!ackpak[i].acknum)
|
||||||
|
{
|
||||||
|
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
||||||
|
if (!urgent)
|
||||||
|
{
|
||||||
|
numfreeslot++;
|
||||||
|
if (numfreeslot <= URGENTFREESLOTNUM)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
// Get a ack to send in the queue of this node
|
// Get a ack to send in the queue of this node
|
||||||
static UINT8 GetAcktosend(INT32 node)
|
static UINT8 GetAcktosend(INT32 node)
|
||||||
{
|
{
|
||||||
|
@ -298,7 +331,7 @@ static void RemoveAck(INT32 i)
|
||||||
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
|
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
|
||||||
#endif
|
#endif
|
||||||
ackpak[i].acknum = 0;
|
ackpak[i].acknum = 0;
|
||||||
if (nodes[node].flags & CLOSE)
|
if (nodes[node].flags & NF_CLOSE)
|
||||||
Net_CloseConnection(node);
|
Net_CloseConnection(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,8 +485,13 @@ static void GotAcks(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void Net_ConnectionTimeout(INT32 node)
|
void Net_ConnectionTimeout(INT32 node)
|
||||||
{
|
{
|
||||||
|
// Don't timeout several times
|
||||||
|
if (nodes[node].flags & NF_TIMEOUT)
|
||||||
|
return;
|
||||||
|
nodes[node].flags |= NF_TIMEOUT;
|
||||||
|
|
||||||
// Send a very special packet to self (hack the reboundstore queue)
|
// Send a very special packet to self (hack the reboundstore queue)
|
||||||
// Main code will handle it
|
// Main code will handle it
|
||||||
reboundstore[rebound_head].packettype = PT_NODETIMEOUT;
|
reboundstore[rebound_head].packettype = PT_NODETIMEOUT;
|
||||||
|
@ -484,7 +522,7 @@ void Net_AckTicker(void)
|
||||||
if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime())
|
if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (ackpak[i].resentnum > 10 && (node->flags & CLOSE))
|
if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE))
|
||||||
{
|
{
|
||||||
DEBFILE(va("ack %d sent 10 times so connection is supposed lost: node %d\n",
|
DEBFILE(va("ack %d sent 10 times so connection is supposed lost: node %d\n",
|
||||||
i, nodei));
|
i, nodei));
|
||||||
|
@ -520,7 +558,7 @@ void Net_AckTicker(void)
|
||||||
if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime())
|
if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime())
|
||||||
Net_SendAcks(i);
|
Net_SendAcks(i);
|
||||||
|
|
||||||
if (!(nodes[i].flags & CLOSE)
|
if (!(nodes[i].flags & NF_CLOSE)
|
||||||
&& nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime())
|
&& nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime())
|
||||||
{
|
{
|
||||||
Net_ConnectionTimeout(i);
|
Net_ConnectionTimeout(i);
|
||||||
|
@ -678,7 +716,7 @@ void Net_CloseConnection(INT32 node)
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nodes[node].flags |= CLOSE;
|
nodes[node].flags |= NF_CLOSE;
|
||||||
|
|
||||||
// try to Send ack back (two army problem)
|
// try to Send ack back (two army problem)
|
||||||
if (GetAcktosend(node))
|
if (GetAcktosend(node))
|
||||||
|
@ -813,18 +851,20 @@ static void DebugPrintpacket(const char *header)
|
||||||
case PT_SERVERTICS:
|
case PT_SERVERTICS:
|
||||||
{
|
{
|
||||||
servertics_pak *serverpak = &netbuffer->u.serverpak;
|
servertics_pak *serverpak = &netbuffer->u.serverpak;
|
||||||
ticcmd_t *cmd = &serverpak->cmds[serverpak->numslots * serverpak->numtics];
|
UINT8 *cmd = (UINT8 *)(&serverpak->cmds[serverpak->numslots * serverpak->numtics]);
|
||||||
size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - (UINT8 *)cmd;
|
size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd;
|
||||||
|
|
||||||
fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ",
|
fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ",
|
||||||
(UINT32)ExpandTics(serverpak->starttic), serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd));
|
(UINT32)ExpandTics(serverpak->starttic), serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd));
|
||||||
fprintfstring((char *)cmd, 3);
|
/// \todo Display more readable information about net commands
|
||||||
|
fprintfstringnewline((char *)cmd, ntxtcmd);
|
||||||
|
/*fprintfstring((char *)cmd, 3);
|
||||||
if (ntxtcmd > 4)
|
if (ntxtcmd > 4)
|
||||||
{
|
{
|
||||||
fprintf(debugfile, "[%s]", netxcmdnames[*(((UINT8 *)cmd) + 3) - 1]);
|
fprintf(debugfile, "[%s]", netxcmdnames[*((cmd) + 3) - 1]);
|
||||||
fprintfstring(((char *)cmd) + 4, ntxtcmd - 4);
|
fprintfstring(((char *)cmd) + 4, ntxtcmd - 4);
|
||||||
}
|
}
|
||||||
fprintf(debugfile, "\n");
|
fprintf(debugfile, "\n");*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PT_CLIENTCMD:
|
case PT_CLIENTCMD:
|
||||||
|
@ -891,7 +931,7 @@ void Command_Drop(void)
|
||||||
if (COM_Argc() < 2)
|
if (COM_Argc() < 2)
|
||||||
{
|
{
|
||||||
CONS_Printf("drop <packettype> [quantity]: drop packets\n"
|
CONS_Printf("drop <packettype> [quantity]: drop packets\n"
|
||||||
"drop reset: cancel all packet drops");
|
"drop reset: cancel all packet drops\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,6 +1107,8 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
||||||
//
|
//
|
||||||
boolean HGetPacket(void)
|
boolean HGetPacket(void)
|
||||||
{
|
{
|
||||||
|
//boolean nodejustjoined;
|
||||||
|
|
||||||
// Get a packet from self
|
// Get a packet from self
|
||||||
if (rebound_tail != rebound_head)
|
if (rebound_tail != rebound_head)
|
||||||
{
|
{
|
||||||
|
@ -1092,9 +1134,10 @@ boolean HGetPacket(void)
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
//nodejustjoined = I_NetGet();
|
||||||
I_NetGet();
|
I_NetGet();
|
||||||
|
|
||||||
if (doomcom->remotenode == -1)
|
if (doomcom->remotenode == -1) // No packet received
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
getbytes += packetheaderlength + doomcom->datalength; // For stat
|
getbytes += packetheaderlength + doomcom->datalength; // For stat
|
||||||
|
@ -1110,6 +1153,7 @@ boolean HGetPacket(void)
|
||||||
if (netbuffer->checksum != NetbufferChecksum())
|
if (netbuffer->checksum != NetbufferChecksum())
|
||||||
{
|
{
|
||||||
DEBFILE("Bad packet checksum\n");
|
DEBFILE("Bad packet checksum\n");
|
||||||
|
//Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode);
|
||||||
Net_CloseConnection(doomcom->remotenode);
|
Net_CloseConnection(doomcom->remotenode);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1119,11 +1163,26 @@ boolean HGetPacket(void)
|
||||||
DebugPrintpacket("GET");
|
DebugPrintpacket("GET");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// proceed the ack and ackreturn field
|
/*// If a new node sends an unexpected packet, just ignore it
|
||||||
|
if (nodejustjoined && server
|
||||||
|
&& !(netbuffer->packettype == PT_ASKINFO
|
||||||
|
|| netbuffer->packettype == PT_SERVERINFO
|
||||||
|
|| netbuffer->packettype == PT_PLAYERINFO
|
||||||
|
|| netbuffer->packettype == PT_REQUESTFILE
|
||||||
|
|| netbuffer->packettype == PT_ASKINFOVIAMS
|
||||||
|
|| netbuffer->packettype == PT_CLIENTJOIN))
|
||||||
|
{
|
||||||
|
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
|
||||||
|
//CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
|
||||||
|
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Proceed the ack and ackreturn field
|
||||||
if (!Processackpak())
|
if (!Processackpak())
|
||||||
continue; // discarded (duplicated)
|
continue; // discarded (duplicated)
|
||||||
|
|
||||||
// a packet with just ackreturn
|
// A packet with just ackreturn
|
||||||
if (netbuffer->packettype == PT_NOTHING)
|
if (netbuffer->packettype == PT_NOTHING)
|
||||||
{
|
{
|
||||||
GotAcks();
|
GotAcks();
|
||||||
|
@ -1136,9 +1195,10 @@ boolean HGetPacket(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Internal_Get(void)
|
static boolean Internal_Get(void)
|
||||||
{
|
{
|
||||||
doomcom->remotenode = -1;
|
doomcom->remotenode = -1;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNCNORETURN static ATTRNORETURN void Internal_Send(void)
|
FUNCNORETURN static ATTRNORETURN void Internal_Send(void)
|
||||||
|
@ -1223,7 +1283,7 @@ boolean D_CheckNetGame(void)
|
||||||
|
|
||||||
if (netgame)
|
if (netgame)
|
||||||
ret = true;
|
ret = true;
|
||||||
if (!server && netgame)
|
if (client && netgame)
|
||||||
netgame = false;
|
netgame = false;
|
||||||
server = true; // WTF? server always true???
|
server = true; // WTF? server always true???
|
||||||
// no! The deault mode is server. Client is set elsewhere
|
// no! The deault mode is server. Client is set elsewhere
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern SINT8 nodetoplayer2[MAXNETNODES]; // Say the numplayer for this node if a
|
||||||
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
|
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
|
||||||
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
|
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
|
||||||
|
|
||||||
|
INT32 Net_GetFreeAcks(boolean urgent);
|
||||||
void Net_AckTicker(void);
|
void Net_AckTicker(void);
|
||||||
|
|
||||||
// If reliable return true if packet sent, 0 else
|
// If reliable return true if packet sent, 0 else
|
||||||
|
@ -53,6 +54,7 @@ boolean D_CheckNetGame(void);
|
||||||
void D_CloseConnection(void);
|
void D_CloseConnection(void);
|
||||||
void Net_UnAcknowledgePacket(INT32 node);
|
void Net_UnAcknowledgePacket(INT32 node);
|
||||||
void Net_CloseConnection(INT32 node);
|
void Net_CloseConnection(INT32 node);
|
||||||
|
void Net_ConnectionTimeout(INT32 node);
|
||||||
void Net_AbortPacketType(UINT8 packettype);
|
void Net_AbortPacketType(UINT8 packettype);
|
||||||
void Net_SendAcks(INT32 node);
|
void Net_SendAcks(INT32 node);
|
||||||
void Net_WaitAllAckReceived(UINT32 timeout);
|
void Net_WaitAllAckReceived(UINT32 timeout);
|
||||||
|
|
|
@ -82,6 +82,7 @@ static void AutoBalance_OnChange(void);
|
||||||
static void TeamScramble_OnChange(void);
|
static void TeamScramble_OnChange(void);
|
||||||
|
|
||||||
static void NetTimeout_OnChange(void);
|
static void NetTimeout_OnChange(void);
|
||||||
|
static void JoinTimeout_OnChange(void);
|
||||||
|
|
||||||
static void Ringslinger_OnChange(void);
|
static void Ringslinger_OnChange(void);
|
||||||
static void Gravity_OnChange(void);
|
static void Gravity_OnChange(void);
|
||||||
|
@ -340,7 +341,9 @@ consvar_t cv_killingdead = {"killingdead", "Off", CV_NETVAR, CV_OnOff, NULL, 0,
|
||||||
|
|
||||||
consvar_t cv_netstat = {"netstat", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // show bandwidth statistics
|
consvar_t cv_netstat = {"netstat", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // show bandwidth statistics
|
||||||
static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_nettimeout = {"nettimeout", "525", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
|
@ -546,9 +549,12 @@ void D_RegisterServerCommands(void)
|
||||||
// d_clisrv
|
// d_clisrv
|
||||||
CV_RegisterVar(&cv_maxplayers);
|
CV_RegisterVar(&cv_maxplayers);
|
||||||
CV_RegisterVar(&cv_maxsend);
|
CV_RegisterVar(&cv_maxsend);
|
||||||
|
CV_RegisterVar(&cv_noticedownload);
|
||||||
|
CV_RegisterVar(&cv_downloadspeed);
|
||||||
|
|
||||||
COM_AddCommand("ping", Command_Ping_f);
|
COM_AddCommand("ping", Command_Ping_f);
|
||||||
CV_RegisterVar(&cv_nettimeout);
|
CV_RegisterVar(&cv_nettimeout);
|
||||||
|
CV_RegisterVar(&cv_jointimeout);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_skipmapcheck);
|
CV_RegisterVar(&cv_skipmapcheck);
|
||||||
CV_RegisterVar(&cv_sleep);
|
CV_RegisterVar(&cv_sleep);
|
||||||
|
@ -1005,7 +1011,7 @@ UINT8 CanChangeSkin(INT32 playernum)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Force skin in effect.
|
// Force skin in effect.
|
||||||
if (!server && (cv_forceskin.value != -1) && !(adminplayer == playernum && serverplayer == -1))
|
if (client && (cv_forceskin.value != -1) && !(adminplayer == playernum && serverplayer == -1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can change skin in intermission and whatnot.
|
// Can change skin in intermission and whatnot.
|
||||||
|
@ -1616,7 +1622,7 @@ static void Command_Map_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server && !(adminplayer == consoleplayer))
|
if (client && !(adminplayer == consoleplayer))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -1943,7 +1949,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
|
||||||
// You can't suicide someone else. Nice try, there.
|
// You can't suicide someone else. Nice try, there.
|
||||||
if (suicideplayer != playernum || (!G_PlatformGametype()))
|
if (suicideplayer != playernum || (!G_PlatformGametype()))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command recieved 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)
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[2];
|
XBOXSTATIC UINT8 buf[2];
|
||||||
|
@ -2658,7 +2664,7 @@ static void Command_Changepassword_f(void)
|
||||||
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
|
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
|
||||||
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
|
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
|
||||||
#else
|
#else
|
||||||
if (!server) // cannot change remotely
|
if (client) // cannot change remotely
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -2717,7 +2723,7 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
READMEM(*cp, sentmd5, 16);
|
READMEM(*cp, sentmd5, 16);
|
||||||
|
|
||||||
if (!server)
|
if (client)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Do the final pass to compare with the sent md5
|
// Do the final pass to compare with the sent md5
|
||||||
|
@ -2739,7 +2745,7 @@ static void Command_Verify_f(void)
|
||||||
char *temp;
|
char *temp;
|
||||||
INT32 playernum;
|
INT32 playernum;
|
||||||
|
|
||||||
if (!server)
|
if (client)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -2823,7 +2829,7 @@ static void Command_MotD_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((netgame || multiplayer) && !server)
|
if ((netgame || multiplayer) && client)
|
||||||
SendNetXCmd(XD_SETMOTD, mymotd, sizeof(motd));
|
SendNetXCmd(XD_SETMOTD, mymotd, sizeof(motd));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3080,7 +3086,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
READMEM(*cp, md5sum, 16);
|
READMEM(*cp, md5sum, 16);
|
||||||
|
|
||||||
// Only the server processes this message.
|
// Only the server processes this message.
|
||||||
if (!server)
|
if (client)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Disallow non-printing characters and semicolons.
|
// Disallow non-printing characters and semicolons.
|
||||||
|
@ -3347,6 +3353,11 @@ static void NetTimeout_OnChange(void)
|
||||||
connectiontimeout = (tic_t)cv_nettimeout.value;
|
connectiontimeout = (tic_t)cv_nettimeout.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void JoinTimeout_OnChange(void)
|
||||||
|
{
|
||||||
|
jointimeout = (tic_t)cv_jointimeout.value;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 timelimitintics = 0;
|
UINT32 timelimitintics = 0;
|
||||||
|
|
||||||
/** Deals with a timelimit change by printing the change to the console.
|
/** Deals with a timelimit change by printing the change to the console.
|
||||||
|
|
136
src/d_netfil.c
136
src/d_netfil.c
|
@ -97,7 +97,7 @@ char downloaddir[256] = "DOWNLOAD";
|
||||||
|
|
||||||
#ifdef CLIENT_LOADINGSCREEN
|
#ifdef CLIENT_LOADINGSCREEN
|
||||||
// for cl loading screen
|
// for cl loading screen
|
||||||
INT32 lastfilenum = 0;
|
INT32 lastfilenum = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Fills a serverinfo packet with information about wad files loaded.
|
/** Fills a serverinfo packet with information about wad files loaded.
|
||||||
|
@ -487,6 +487,9 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
char wadfilename[MAX_WADPATH];
|
char wadfilename[MAX_WADPATH];
|
||||||
|
|
||||||
|
if (cv_noticedownload.value)
|
||||||
|
CONS_Printf("Sending file \"%s\" to node %d\n", filename, node);
|
||||||
|
|
||||||
// Find the last file in the list and set a pointer to its "next" field
|
// Find the last file in the list and set a pointer to its "next" field
|
||||||
q = &transfer[node].txlist;
|
q = &transfer[node].txlist;
|
||||||
while (*q)
|
while (*q)
|
||||||
|
@ -609,6 +612,8 @@ static void SV_EndFileSend(INT32 node)
|
||||||
switch (p->ram)
|
switch (p->ram)
|
||||||
{
|
{
|
||||||
case SF_FILE: // It's a file, close it and free its filename
|
case SF_FILE: // It's a file, close it and free its filename
|
||||||
|
if (cv_noticedownload.value)
|
||||||
|
CONS_Printf("Ending file transfer for node %d\n", node);
|
||||||
if (transfer[node].currentfile)
|
if (transfer[node].currentfile)
|
||||||
fclose(transfer[node].currentfile);
|
fclose(transfer[node].currentfile);
|
||||||
free(p->id.filename);
|
free(p->id.filename);
|
||||||
|
@ -636,6 +641,9 @@ static void SV_EndFileSend(INT32 node)
|
||||||
|
|
||||||
/** Handles file transmission
|
/** Handles file transmission
|
||||||
*
|
*
|
||||||
|
* \todo Use an acknowledging method more adapted to file transmission
|
||||||
|
* The current download speed suffers from lack of ack packets,
|
||||||
|
* especially when the one downloading has high latency
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SV_FileSendTicker(void)
|
void SV_FileSendTicker(void)
|
||||||
|
@ -644,17 +652,38 @@ void SV_FileSendTicker(void)
|
||||||
filetx_pak *p;
|
filetx_pak *p;
|
||||||
size_t size;
|
size_t size;
|
||||||
filetx_t *f;
|
filetx_t *f;
|
||||||
INT32 packetsent = PACKETPERTIC, ram, i;
|
INT32 packetsent, ram, i, j;
|
||||||
|
INT32 maxpacketsent;
|
||||||
|
|
||||||
if (!filestosend)
|
if (!filestosend) // No file to send
|
||||||
return;
|
return;
|
||||||
if (!packetsent)
|
|
||||||
packetsent++;
|
if (cv_downloadspeed.value) // New (and experimental) behavior
|
||||||
|
{
|
||||||
|
packetsent = cv_downloadspeed.value;
|
||||||
|
// Don't send more packets than we have free acks
|
||||||
|
#ifndef NONET
|
||||||
|
maxpacketsent = Net_GetFreeAcks(false) - 5; // Let 5 extra acks just in case
|
||||||
|
#else
|
||||||
|
maxpacketsent = 1;
|
||||||
|
#endif
|
||||||
|
if (packetsent > maxpacketsent && maxpacketsent > 0) // Send at least one packet
|
||||||
|
packetsent = maxpacketsent;
|
||||||
|
}
|
||||||
|
else // Old behavior
|
||||||
|
{
|
||||||
|
packetsent = PACKETPERTIC;
|
||||||
|
if (!packetsent)
|
||||||
|
packetsent = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netbuffer->packettype = PT_FILEFRAGMENT;
|
||||||
|
|
||||||
// (((sendbytes-nowsentbyte)*TICRATE)/(I_GetTime()-starttime)<(UINT32)net_bandwidth)
|
// (((sendbytes-nowsentbyte)*TICRATE)/(I_GetTime()-starttime)<(UINT32)net_bandwidth)
|
||||||
while (packetsent-- && filestosend != 0)
|
while (packetsent-- && filestosend != 0)
|
||||||
{
|
{
|
||||||
for (i = currentnode, ram = 0; ram < MAXNETNODES;
|
for (i = currentnode, j = 0; j < MAXNETNODES;
|
||||||
i = (i+1) % MAXNETNODES, ram++)
|
i = (i+1) % MAXNETNODES, j++)
|
||||||
{
|
{
|
||||||
if (transfer[i].txlist)
|
if (transfer[i].txlist)
|
||||||
goto found;
|
goto found;
|
||||||
|
@ -713,7 +742,6 @@ void SV_FileSendTicker(void)
|
||||||
p->position |= LONG(0x80000000);
|
p->position |= LONG(0x80000000);
|
||||||
p->fileid = f->fileid;
|
p->fileid = f->fileid;
|
||||||
p->size = SHORT((UINT16)size);
|
p->size = SHORT((UINT16)size);
|
||||||
netbuffer->packettype = PT_FILEFRAGMENT;
|
|
||||||
|
|
||||||
// Send the packet
|
// Send the packet
|
||||||
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
|
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
|
||||||
|
@ -735,27 +763,40 @@ void SV_FileSendTicker(void)
|
||||||
void Got_Filetxpak(void)
|
void Got_Filetxpak(void)
|
||||||
{
|
{
|
||||||
INT32 filenum = netbuffer->u.filetxpak.fileid;
|
INT32 filenum = netbuffer->u.filetxpak.fileid;
|
||||||
|
fileneeded_t *file = &fileneeded[filenum];
|
||||||
|
char *filename = file->filename;
|
||||||
static INT32 filetime = 0;
|
static INT32 filetime = 0;
|
||||||
|
|
||||||
|
if (!(strcmp(filename, "srb2.srb")
|
||||||
|
&& strcmp(filename, "srb2.wad")
|
||||||
|
&& strcmp(filename, "zones.dta")
|
||||||
|
&& strcmp(filename, "player.dta")
|
||||||
|
&& strcmp(filename, "rings.dta")
|
||||||
|
&& strcmp(filename, "patch.dta")
|
||||||
|
&& strcmp(filename, "music.dta")
|
||||||
|
))
|
||||||
|
I_Error("Tried to download \"%s\"", filename);
|
||||||
|
|
||||||
if (filenum >= fileneedednum)
|
if (filenum >= fileneedednum)
|
||||||
{
|
{
|
||||||
DEBFILE(va("fileframent not needed %d>%d\n", filenum, fileneedednum));
|
DEBFILE(va("fileframent not needed %d>%d\n", filenum, fileneedednum));
|
||||||
|
//I_Error("Received an unneeded file fragment (file id received: %d, file id needed: %d)\n", filenum, fileneedednum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileneeded[filenum].status == FS_REQUESTED)
|
if (file->status == FS_REQUESTED)
|
||||||
{
|
{
|
||||||
if (fileneeded[filenum].file)
|
if (file->file)
|
||||||
I_Error("Got_Filetxpak: already open file\n");
|
I_Error("Got_Filetxpak: already open file\n");
|
||||||
fileneeded[filenum].file = fopen(fileneeded[filenum].filename, "wb");
|
file->file = fopen(filename, "wb");
|
||||||
if (!fileneeded[filenum].file)
|
if (!file->file)
|
||||||
I_Error("Can't create file %s: %s", fileneeded[filenum].filename, strerror(errno));
|
I_Error("Can't create file %s: %s", filename, strerror(errno));
|
||||||
CONS_Printf("\r%s...\n",fileneeded[filenum].filename);
|
CONS_Printf("\r%s...\n",filename);
|
||||||
fileneeded[filenum].currentsize = 0;
|
file->currentsize = 0;
|
||||||
fileneeded[filenum].status = FS_DOWNLOADING;
|
file->status = FS_DOWNLOADING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileneeded[filenum].status == FS_DOWNLOADING)
|
if (file->status == FS_DOWNLOADING)
|
||||||
{
|
{
|
||||||
UINT32 pos = LONG(netbuffer->u.filetxpak.position);
|
UINT32 pos = LONG(netbuffer->u.filetxpak.position);
|
||||||
UINT16 size = SHORT(netbuffer->u.filetxpak.size);
|
UINT16 size = SHORT(netbuffer->u.filetxpak.size);
|
||||||
|
@ -764,27 +805,47 @@ void Got_Filetxpak(void)
|
||||||
if (pos & 0x80000000)
|
if (pos & 0x80000000)
|
||||||
{
|
{
|
||||||
pos &= ~0x80000000;
|
pos &= ~0x80000000;
|
||||||
fileneeded[filenum].totalsize = pos + size;
|
file->totalsize = pos + size;
|
||||||
}
|
}
|
||||||
// We can receive packet in the wrong order, anyway all os support gaped file
|
// We can receive packet in the wrong order, anyway all os support gaped file
|
||||||
fseek(fileneeded[filenum].file, pos, SEEK_SET);
|
fseek(file->file, pos, SEEK_SET);
|
||||||
if (fwrite(netbuffer->u.filetxpak.data,size,1,fileneeded[filenum].file) != 1)
|
if (fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1)
|
||||||
I_Error("Can't write to %s: %s\n",fileneeded[filenum].filename, strerror(ferror(fileneeded[filenum].file)));
|
I_Error("Can't write to %s: %s\n",filename, strerror(ferror(file->file)));
|
||||||
fileneeded[filenum].currentsize += size;
|
file->currentsize += size;
|
||||||
|
|
||||||
// Finished?
|
// Finished?
|
||||||
if (fileneeded[filenum].currentsize == fileneeded[filenum].totalsize)
|
if (file->currentsize == file->totalsize)
|
||||||
{
|
{
|
||||||
fclose(fileneeded[filenum].file);
|
fclose(file->file);
|
||||||
fileneeded[filenum].file = NULL;
|
file->file = NULL;
|
||||||
fileneeded[filenum].status = FS_FOUND;
|
file->status = FS_FOUND;
|
||||||
CONS_Printf(M_GetText("Downloading %s...(done)\n"),
|
CONS_Printf(M_GetText("Downloading %s...(done)\n"),
|
||||||
fileneeded[filenum].filename);
|
filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
I_Error("Received a file not requested\n");
|
{
|
||||||
|
const char *s;
|
||||||
|
switch(file->status)
|
||||||
|
{
|
||||||
|
case FS_NOTFOUND:
|
||||||
|
s = "FS_NOTFOUND";
|
||||||
|
break;
|
||||||
|
case FS_FOUND:
|
||||||
|
s = "FS_FOUND";
|
||||||
|
break;
|
||||||
|
case FS_OPEN:
|
||||||
|
s = "FS_OPEN";
|
||||||
|
break;
|
||||||
|
case FS_MD5SUMBAD:
|
||||||
|
s = "FS_MD5SUMBAD";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = "unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
|
||||||
|
}
|
||||||
// Send ack back quickly
|
// Send ack back quickly
|
||||||
if (++filetime == 3)
|
if (++filetime == 3)
|
||||||
{
|
{
|
||||||
|
@ -797,12 +858,23 @@ void Got_Filetxpak(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cancels all file requests for a node
|
/** \brief Checks if a node is downloading a file
|
||||||
*
|
*
|
||||||
* \param node The destination
|
* \param node The node to check for
|
||||||
* \sa SV_EndFileSend
|
* \return True if the node is downloading a file
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
boolean SV_SendingFile(INT32 node)
|
||||||
|
{
|
||||||
|
return transfer[node].txlist != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Cancels all file requests for a node
|
||||||
|
*
|
||||||
|
* \param node The destination
|
||||||
|
* \sa SV_EndFileSend
|
||||||
|
*
|
||||||
|
*/
|
||||||
void SV_AbortSendFiles(INT32 node)
|
void SV_AbortSendFiles(INT32 node)
|
||||||
{
|
{
|
||||||
while (transfer[node].txlist)
|
while (transfer[node].txlist)
|
||||||
|
|
|
@ -65,6 +65,7 @@ void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod,
|
||||||
|
|
||||||
void SV_FileSendTicker(void);
|
void SV_FileSendTicker(void);
|
||||||
void Got_Filetxpak(void);
|
void Got_Filetxpak(void);
|
||||||
|
boolean SV_SendingFile(INT32 node);
|
||||||
|
|
||||||
boolean CL_CheckDownloadable(void);
|
boolean CL_CheckDownloadable(void);
|
||||||
boolean CL_SendRequestFile(void);
|
boolean CL_SendRequestFile(void);
|
||||||
|
|
|
@ -1961,6 +1961,7 @@ static actionpointer_t actionpointers[] =
|
||||||
{{A_FlickyCheck}, "A_FLICKYCHECK"},
|
{{A_FlickyCheck}, "A_FLICKYCHECK"},
|
||||||
{{A_FlickyHeightCheck}, "A_FLICKYHEIGHTCHECK"},
|
{{A_FlickyHeightCheck}, "A_FLICKYHEIGHTCHECK"},
|
||||||
{{A_FlickyFlutter}, "A_FLICKYFLUTTER"},
|
{{A_FlickyFlutter}, "A_FLICKYFLUTTER"},
|
||||||
|
{{A_FlameParticle}, "A_FLAMEPARTICLE"},
|
||||||
|
|
||||||
{{NULL}, "NONE"},
|
{{NULL}, "NONE"},
|
||||||
|
|
||||||
|
@ -4398,6 +4399,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_GOOP1",
|
"S_GOOP1",
|
||||||
"S_GOOP2",
|
"S_GOOP2",
|
||||||
"S_GOOP3",
|
"S_GOOP3",
|
||||||
|
"S_GOOPTRAIL",
|
||||||
|
|
||||||
// Boss 3
|
// Boss 3
|
||||||
"S_EGGMOBILE3_STND",
|
"S_EGGMOBILE3_STND",
|
||||||
|
@ -4974,7 +4976,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
// Starpost
|
// Starpost
|
||||||
"S_STARPOST_IDLE",
|
"S_STARPOST_IDLE",
|
||||||
"S_STARPOST_FLASH",
|
"S_STARPOST_FLASH",
|
||||||
|
"S_STARPOST_STARTSPIN",
|
||||||
"S_STARPOST_SPIN",
|
"S_STARPOST_SPIN",
|
||||||
|
"S_STARPOST_ENDSPIN",
|
||||||
|
|
||||||
// Big floating mine
|
// Big floating mine
|
||||||
"S_BIGMINE1",
|
"S_BIGMINE1",
|
||||||
|
@ -5156,21 +5160,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_DEMONFIRE6",
|
"S_DEMONFIRE6",
|
||||||
|
|
||||||
"S_GFZFLOWERA",
|
"S_GFZFLOWERA",
|
||||||
"S_GFZFLOWERA2",
|
"S_GFZFLOWERB",
|
||||||
|
"S_GFZFLOWERC",
|
||||||
"S_GFZFLOWERB1",
|
|
||||||
"S_GFZFLOWERB2",
|
|
||||||
|
|
||||||
"S_GFZFLOWERC1",
|
|
||||||
|
|
||||||
"S_BERRYBUSH",
|
"S_BERRYBUSH",
|
||||||
"S_BUSH",
|
"S_BUSH",
|
||||||
|
|
||||||
// THZ Plant
|
// THZ Plant
|
||||||
"S_THZPLANT1",
|
"S_THZFLOWERA",
|
||||||
"S_THZPLANT2",
|
"S_THZFLOWERB",
|
||||||
"S_THZPLANT3",
|
|
||||||
"S_THZPLANT4",
|
|
||||||
|
|
||||||
// THZ Alarm
|
// THZ Alarm
|
||||||
"S_ALARM1",
|
"S_ALARM1",
|
||||||
|
@ -5215,6 +5213,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_FLAME2",
|
"S_FLAME2",
|
||||||
"S_FLAME3",
|
"S_FLAME3",
|
||||||
"S_FLAME4",
|
"S_FLAME4",
|
||||||
|
"S_FLAME5",
|
||||||
|
"S_FLAME6",
|
||||||
|
"S_FLAMEPARTICLE",
|
||||||
|
|
||||||
|
"S_FLAMEREST",
|
||||||
|
|
||||||
// Eggman Statue
|
// Eggman Statue
|
||||||
"S_EGGSTATUE1",
|
"S_EGGSTATUE1",
|
||||||
|
@ -5276,36 +5279,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
// Spinning flame jets
|
// Spinning flame jets
|
||||||
"S_FJSPINAXISA1", // Counter-clockwise
|
"S_FJSPINAXISA1", // Counter-clockwise
|
||||||
"S_FJSPINAXISA2",
|
"S_FJSPINAXISA2",
|
||||||
"S_FJSPINAXISA3",
|
|
||||||
"S_FJSPINAXISA4",
|
|
||||||
"S_FJSPINAXISA5",
|
|
||||||
"S_FJSPINAXISA6",
|
|
||||||
"S_FJSPINAXISA7",
|
|
||||||
"S_FJSPINAXISA8",
|
|
||||||
"S_FJSPINAXISA9",
|
|
||||||
"S_FJSPINHELPERA1",
|
|
||||||
"S_FJSPINHELPERA2",
|
|
||||||
"S_FJSPINHELPERA3",
|
|
||||||
"S_FJSPINAXISB1", // Clockwise
|
"S_FJSPINAXISB1", // Clockwise
|
||||||
"S_FJSPINAXISB2",
|
"S_FJSPINAXISB2",
|
||||||
"S_FJSPINAXISB3",
|
|
||||||
"S_FJSPINAXISB4",
|
|
||||||
"S_FJSPINAXISB5",
|
|
||||||
"S_FJSPINAXISB6",
|
|
||||||
"S_FJSPINAXISB7",
|
|
||||||
"S_FJSPINAXISB8",
|
|
||||||
"S_FJSPINAXISB9",
|
|
||||||
"S_FJSPINHELPERB1",
|
|
||||||
"S_FJSPINHELPERB2",
|
|
||||||
"S_FJSPINHELPERB3",
|
|
||||||
|
|
||||||
// Blade's flame
|
// Blade's flame
|
||||||
"S_FLAMEJETFLAMEB1",
|
"S_FLAMEJETFLAMEB1",
|
||||||
"S_FLAMEJETFLAMEB2",
|
"S_FLAMEJETFLAMEB2",
|
||||||
"S_FLAMEJETFLAMEB3",
|
"S_FLAMEJETFLAMEB3",
|
||||||
"S_FLAMEJETFLAMEB4",
|
|
||||||
"S_FLAMEJETFLAMEB5",
|
|
||||||
"S_FLAMEJETFLAMEB6",
|
|
||||||
|
|
||||||
// Trapgoyles
|
// Trapgoyles
|
||||||
"S_TRAPGOYLE",
|
"S_TRAPGOYLE",
|
||||||
|
@ -5400,8 +5380,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_BSZVINE_ORANGE",
|
"S_BSZVINE_ORANGE",
|
||||||
"S_BSZSHRUB",
|
"S_BSZSHRUB",
|
||||||
"S_BSZCLOVER",
|
"S_BSZCLOVER",
|
||||||
"S_BSZFISH",
|
"S_BIG_PALMTREE_TRUNK",
|
||||||
"S_BSZSUNFLOWER",
|
"S_BIG_PALMTREE_TOP",
|
||||||
|
"S_PALMTREE_TRUNK",
|
||||||
|
"S_PALMTREE_TOP",
|
||||||
|
|
||||||
"S_DBALL1",
|
"S_DBALL1",
|
||||||
"S_DBALL2",
|
"S_DBALL2",
|
||||||
|
@ -6120,20 +6102,19 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_FIREBALLEXP2",
|
"S_FIREBALLEXP2",
|
||||||
"S_FIREBALLEXP3",
|
"S_FIREBALLEXP3",
|
||||||
"S_SHELL",
|
"S_SHELL",
|
||||||
"S_SHELL1",
|
"S_PUMA_START1",
|
||||||
"S_SHELL2",
|
"S_PUMA_START2",
|
||||||
"S_SHELL3",
|
"S_PUMA_UP1",
|
||||||
"S_SHELL4",
|
"S_PUMA_UP2",
|
||||||
"S_PUMA1",
|
"S_PUMA_UP3",
|
||||||
"S_PUMA2",
|
"S_PUMA_DOWN1",
|
||||||
"S_PUMA3",
|
"S_PUMA_DOWN2",
|
||||||
"S_PUMA4",
|
"S_PUMA_DOWN3",
|
||||||
"S_PUMA5",
|
"S_PUMATRAIL1",
|
||||||
"S_PUMA6",
|
"S_PUMATRAIL2",
|
||||||
"S_HAMMER1",
|
"S_PUMATRAIL3",
|
||||||
"S_HAMMER2",
|
"S_PUMATRAIL4",
|
||||||
"S_HAMMER3",
|
"S_HAMMER",
|
||||||
"S_HAMMER4",
|
|
||||||
"S_KOOPA1",
|
"S_KOOPA1",
|
||||||
"S_KOOPA2",
|
"S_KOOPA2",
|
||||||
"S_KOOPAFLAME1",
|
"S_KOOPAFLAME1",
|
||||||
|
@ -6386,6 +6367,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_BOSSTANK2",
|
"MT_BOSSTANK2",
|
||||||
"MT_BOSSSPIGOT",
|
"MT_BOSSSPIGOT",
|
||||||
"MT_GOOP",
|
"MT_GOOP",
|
||||||
|
"MT_GOOPTRAIL",
|
||||||
|
|
||||||
// Boss 3
|
// Boss 3
|
||||||
"MT_EGGMOBILE3",
|
"MT_EGGMOBILE3",
|
||||||
|
@ -6555,7 +6537,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_BUSH",
|
"MT_BUSH",
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
"MT_THZPLANT", // THZ Plant
|
"MT_THZFLOWER1",
|
||||||
|
"MT_THZFLOWER2",
|
||||||
"MT_ALARM",
|
"MT_ALARM",
|
||||||
|
|
||||||
// Deep Sea Scenery
|
// Deep Sea Scenery
|
||||||
|
@ -6571,6 +6554,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
// Castle Eggman Scenery
|
// Castle Eggman Scenery
|
||||||
"MT_CHAIN", // CEZ Chain
|
"MT_CHAIN", // CEZ Chain
|
||||||
"MT_FLAME", // Flame (has corona)
|
"MT_FLAME", // Flame (has corona)
|
||||||
|
"MT_FLAMEPARTICLE",
|
||||||
"MT_EGGSTATUE", // Eggman Statue
|
"MT_EGGSTATUE", // Eggman Statue
|
||||||
"MT_MACEPOINT", // Mace rotation point
|
"MT_MACEPOINT", // Mace rotation point
|
||||||
"MT_SWINGMACEPOINT", // Mace swinging point
|
"MT_SWINGMACEPOINT", // Mace swinging point
|
||||||
|
@ -6597,9 +6581,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_FLAMEJETFLAME",
|
"MT_FLAMEJETFLAME",
|
||||||
|
|
||||||
"MT_FJSPINAXISA", // Counter-clockwise
|
"MT_FJSPINAXISA", // Counter-clockwise
|
||||||
"MT_FJSPINHELPERA",
|
|
||||||
"MT_FJSPINAXISB", // Clockwise
|
"MT_FJSPINAXISB", // Clockwise
|
||||||
"MT_FJSPINHELPERB",
|
|
||||||
|
|
||||||
"MT_FLAMEJETFLAMEB", // Blade's flame
|
"MT_FLAMEJETFLAMEB", // Blade's flame
|
||||||
|
|
||||||
|
@ -6676,8 +6658,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_BSZVINE_ORANGE",
|
"MT_BSZVINE_ORANGE",
|
||||||
"MT_BSZSHRUB",
|
"MT_BSZSHRUB",
|
||||||
"MT_BSZCLOVER",
|
"MT_BSZCLOVER",
|
||||||
"MT_BSZFISH",
|
"MT_BIG_PALMTREE_TRUNK",
|
||||||
"MT_BSZSUNFLOWER",
|
"MT_BIG_PALMTREE_TOP",
|
||||||
|
"MT_PALMTREE_TRUNK",
|
||||||
|
"MT_PALMTREE_TOP",
|
||||||
|
|
||||||
// Misc scenery
|
// Misc scenery
|
||||||
"MT_DBALL",
|
"MT_DBALL",
|
||||||
|
@ -6783,6 +6767,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_FIREBALL",
|
"MT_FIREBALL",
|
||||||
"MT_SHELL",
|
"MT_SHELL",
|
||||||
"MT_PUMA",
|
"MT_PUMA",
|
||||||
|
"MT_PUMATRAIL",
|
||||||
"MT_HAMMER",
|
"MT_HAMMER",
|
||||||
"MT_KOOPA",
|
"MT_KOOPA",
|
||||||
"MT_KOOPAFLAME",
|
"MT_KOOPAFLAME",
|
||||||
|
|
|
@ -214,7 +214,7 @@ extern FILE *logstream;
|
||||||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||||
// Only set it higher, not lower, obviously.
|
// Only set it higher, not lower, obviously.
|
||||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||||
#define MODVERSION 21
|
#define MODVERSION 22
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
|
|
@ -974,7 +974,7 @@ static const char *credits[] = {
|
||||||
"Scott \"Graue\" Feeney",
|
"Scott \"Graue\" Feeney",
|
||||||
"Nathan \"Jazz\" Giroux",
|
"Nathan \"Jazz\" Giroux",
|
||||||
"Thomas \"Shadow Hog\" Igoe",
|
"Thomas \"Shadow Hog\" Igoe",
|
||||||
"\"Monster\" Iestyn Jealous",
|
"Iestyn \"Monster Iestyn\" Jealous",
|
||||||
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
|
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
|
||||||
"John \"JTE\" Muniz",
|
"John \"JTE\" Muniz",
|
||||||
"Ehab \"Wolfy\" Saeed",
|
"Ehab \"Wolfy\" Saeed",
|
||||||
|
@ -986,6 +986,7 @@ static const char *credits[] = {
|
||||||
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
|
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
|
||||||
"Andrew \"orospakr\" Clunis",
|
"Andrew \"orospakr\" Clunis",
|
||||||
"Gregor \"Oogaland\" Dick",
|
"Gregor \"Oogaland\" Dick",
|
||||||
|
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
|
||||||
"Vivian \"toaster\" Grannell",
|
"Vivian \"toaster\" Grannell",
|
||||||
"Julio \"Chaos Zero 64\" Guir",
|
"Julio \"Chaos Zero 64\" Guir",
|
||||||
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
||||||
|
@ -1021,7 +1022,7 @@ static const char *credits[] = {
|
||||||
"Paul \"Boinciel\" Clempson",
|
"Paul \"Boinciel\" Clempson",
|
||||||
"Cyan Helkaraxe",
|
"Cyan Helkaraxe",
|
||||||
"Kepa \"Nev3r\" Iceta",
|
"Kepa \"Nev3r\" Iceta",
|
||||||
"\"Monster\" Iestyn Jealous",
|
"Iestyn \"Monster Iestyn\" Jealous",
|
||||||
"Jarel \"Arrow\" Jones",
|
"Jarel \"Arrow\" Jones",
|
||||||
"Stefan \"Stuf\" Rimalia",
|
"Stefan \"Stuf\" Rimalia",
|
||||||
"Shane Mychal Sexton",
|
"Shane Mychal Sexton",
|
||||||
|
|
|
@ -296,6 +296,7 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
&lspr[NOLIGHT], // SPR_THZP
|
&lspr[NOLIGHT], // SPR_THZP
|
||||||
|
&lspr[NOLIGHT], // SPR_FWR5
|
||||||
&lspr[REDBALL_L], // SPR_ALRM
|
&lspr[REDBALL_L], // SPR_ALRM
|
||||||
|
|
||||||
// Deep Sea Scenery
|
// Deep Sea Scenery
|
||||||
|
|
|
@ -470,7 +470,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
boolean action = false;
|
boolean action = false;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
CONS_Debug(DBG_NETPLAY,"Recieved SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]);
|
CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]);
|
||||||
|
|
||||||
target = READSINT8(*p);
|
target = READSINT8(*p);
|
||||||
flags = READUINT8(*p);
|
flags = READUINT8(*p);
|
||||||
|
@ -1102,7 +1102,19 @@ void HU_Drawer(void)
|
||||||
|
|
||||||
// draw desynch text
|
// draw desynch text
|
||||||
if (hu_resynching)
|
if (hu_resynching)
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP, "Resynching...");
|
{
|
||||||
|
static UINT32 resynch_ticker = 0;
|
||||||
|
char resynch_text[14];
|
||||||
|
UINT32 i;
|
||||||
|
|
||||||
|
// Animate the dots
|
||||||
|
resynch_ticker++;
|
||||||
|
strcpy(resynch_text, "Resynching");
|
||||||
|
for (i = 0; i < (resynch_ticker / 16) % 4; i++)
|
||||||
|
strcat(resynch_text, ".");
|
||||||
|
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
|
@ -85,7 +85,7 @@ extern doomcom_t *doomcom;
|
||||||
|
|
||||||
/** \brief return packet in doomcom struct
|
/** \brief return packet in doomcom struct
|
||||||
*/
|
*/
|
||||||
extern void (*I_NetGet)(void);
|
extern boolean (*I_NetGet)(void);
|
||||||
|
|
||||||
/** \brief ask to driver if there is data waiting
|
/** \brief ask to driver if there is data waiting
|
||||||
*/
|
*/
|
||||||
|
|
97
src/i_tcp.c
97
src/i_tcp.c
|
@ -179,6 +179,7 @@ static UINT8 UPNP_support = TRUE;
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "i_net.h"
|
#include "i_net.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
|
#include "d_netfil.h"
|
||||||
#include "i_tcp.h"
|
#include "i_tcp.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
|
|
||||||
|
@ -482,21 +483,12 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SINT8 getfreenode(void)
|
|
||||||
{
|
|
||||||
SINT8 j;
|
|
||||||
|
|
||||||
for (j = 0; j < MAXNETNODES; j++)
|
|
||||||
if (!nodeconnected[j])
|
|
||||||
{
|
|
||||||
nodeconnected[j] = true;
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a hack. For some reason, nodes aren't being freed properly.
|
// This is a hack. For some reason, nodes aren't being freed properly.
|
||||||
// This goes through and cleans up what nodes were supposed to be freed.
|
// This goes through and cleans up what nodes were supposed to be freed.
|
||||||
|
/** \warning This function causes the file downloading to stop if someone joins.
|
||||||
|
* How? Because it removes nodes that are connected but not in game,
|
||||||
|
* which is exactly what clients downloading a file are.
|
||||||
|
*/
|
||||||
static void cleanupnodes(void)
|
static void cleanupnodes(void)
|
||||||
{
|
{
|
||||||
SINT8 j;
|
SINT8 j;
|
||||||
|
@ -506,13 +498,81 @@ static void cleanupnodes(void)
|
||||||
|
|
||||||
// Why can't I start at zero?
|
// Why can't I start at zero?
|
||||||
for (j = 1; j < MAXNETNODES; j++)
|
for (j = 1; j < MAXNETNODES; j++)
|
||||||
|
//if (!(nodeingame[j] || SV_SendingFile(j)))
|
||||||
if (!nodeingame[j])
|
if (!nodeingame[j])
|
||||||
nodeconnected[j] = false;
|
nodeconnected[j] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SINT8 getfreenode(void)
|
||||||
|
{
|
||||||
|
SINT8 j;
|
||||||
|
|
||||||
|
cleanupnodes();
|
||||||
|
|
||||||
|
for (j = 0; j < MAXNETNODES; j++)
|
||||||
|
if (!nodeconnected[j])
|
||||||
|
{
|
||||||
|
nodeconnected[j] = true;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \warning No free node? Just in case a node might not have been freed properly,
|
||||||
|
* look if there are connected nodes that aren't in game, and forget them.
|
||||||
|
* It's dirty, and might result in a poor guy having to restart
|
||||||
|
* downloading a needed wad, but it's better than not letting anyone join...
|
||||||
|
*/
|
||||||
|
/*I_Error("No more free nodes!!1!11!11!!1111\n");
|
||||||
|
for (j = 1; j < MAXNETNODES; j++)
|
||||||
|
if (!nodeingame[j])
|
||||||
|
return j;*/
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
void Command_Numnodes(void)
|
||||||
|
{
|
||||||
|
INT32 connected = 0;
|
||||||
|
INT32 ingame = 0;
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
for (i = 1; i < MAXNETNODES; i++)
|
||||||
|
{
|
||||||
|
if (!(nodeconnected[i] || nodeingame[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nodeconnected[i])
|
||||||
|
connected++;
|
||||||
|
if (nodeingame[i])
|
||||||
|
ingame++;
|
||||||
|
|
||||||
|
CONS_Printf("%2d - ", i);
|
||||||
|
if (nodetoplayer[i] != -1)
|
||||||
|
CONS_Printf("player %.2d", nodetoplayer[i]);
|
||||||
|
else
|
||||||
|
CONS_Printf(" ");
|
||||||
|
if (nodeconnected[i])
|
||||||
|
CONS_Printf(" - connected");
|
||||||
|
else
|
||||||
|
CONS_Printf(" - ");
|
||||||
|
if (nodeingame[i])
|
||||||
|
CONS_Printf(" - ingame");
|
||||||
|
else
|
||||||
|
CONS_Printf(" - ");
|
||||||
|
CONS_Printf(" - %s\n", I_GetNodeAddress(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
CONS_Printf("\n"
|
||||||
|
"Connected: %d\n"
|
||||||
|
"Ingame: %d\n",
|
||||||
|
connected, ingame);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
static void SOCK_Get(void)
|
// Returns true if a packet was received from a new node, false in all other cases
|
||||||
|
static boolean SOCK_Get(void)
|
||||||
{
|
{
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
int j;
|
int j;
|
||||||
|
@ -535,13 +595,12 @@ static void SOCK_Get(void)
|
||||||
doomcom->remotenode = (INT16)j; // good packet from a game player
|
doomcom->remotenode = (INT16)j; // good packet from a game player
|
||||||
doomcom->datalength = (INT16)c;
|
doomcom->datalength = (INT16)c;
|
||||||
nodesocket[j] = mysockets[n];
|
nodesocket[j] = mysockets[n];
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not found
|
// not found
|
||||||
|
|
||||||
// find a free slot
|
// find a free slot
|
||||||
cleanupnodes();
|
|
||||||
j = getfreenode();
|
j = getfreenode();
|
||||||
if (j > 0)
|
if (j > 0)
|
||||||
{
|
{
|
||||||
|
@ -564,14 +623,15 @@ static void SOCK_Get(void)
|
||||||
}
|
}
|
||||||
if (i == numbans)
|
if (i == numbans)
|
||||||
SOCK_bannednode[j] = false;
|
SOCK_bannednode[j] = false;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DEBFILE("New node detected: No more free slots\n");
|
DEBFILE("New node detected: No more free slots\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doomcom->remotenode = -1; // no packet
|
doomcom->remotenode = -1; // no packet
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1256,7 +1316,6 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||||
gaie = I_getaddrinfo(address, port, &hints, &ai);
|
gaie = I_getaddrinfo(address, port, &hints, &ai);
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
cleanupnodes();
|
|
||||||
newnode = getfreenode();
|
newnode = getfreenode();
|
||||||
}
|
}
|
||||||
if (newnode == -1)
|
if (newnode == -1)
|
||||||
|
|
437
src/info.c
437
src/info.c
|
@ -184,6 +184,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
"THZP", // Techno Hill Zone Plant
|
"THZP", // Techno Hill Zone Plant
|
||||||
|
"FWR5", // Another one
|
||||||
"ALRM", // THZ2 Alarm
|
"ALRM", // THZ2 Alarm
|
||||||
|
|
||||||
// Deep Sea Scenery
|
// Deep Sea Scenery
|
||||||
|
@ -990,9 +991,10 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_SPNK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT
|
{SPR_SPNK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT
|
||||||
|
|
||||||
// Boss 2 Goop
|
// Boss 2 Goop
|
||||||
{SPR_GOOP, 0, 2, {NULL}, 0, 0, S_GOOP2}, // S_GOOP1
|
{SPR_GOOP, 0, 2, {A_SpawnObjectRelative}, 0, MT_GOOPTRAIL, S_GOOP2}, // S_GOOP1
|
||||||
{SPR_GOOP, 1, 2, {NULL}, 0, 0, S_GOOP1}, // S_GOOP2
|
{SPR_GOOP, 1, 2, {A_SpawnObjectRelative}, 0, MT_GOOPTRAIL, S_GOOP1}, // S_GOOP2
|
||||||
{SPR_GOOP, 2,-1, {NULL}, 0, 0, S_NULL}, // S_GOOP3
|
{SPR_GOOP, 2, -1, {NULL}, 0, 0, S_NULL}, // S_GOOP3
|
||||||
|
{SPR_GOOP, FF_ANIMATE|3, 11, {NULL}, 2, 6, S_NULL}, // S_GOOPTRAIL
|
||||||
|
|
||||||
// Boss 3
|
// Boss 3
|
||||||
{SPR_EGGO, 0, 1, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_STND
|
{SPR_EGGO, 0, 1, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_STND
|
||||||
|
@ -1244,12 +1246,12 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_RCKT, 2 + FF_FULLBRIGHT, 6, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (6<<16), 32 + (16<<16), S_CYBRAKDEMONMISSILE_EXPLODE3}, // S_CYBRAKDEMONMISSILE_EXPLODE2
|
{SPR_RCKT, 2 + FF_FULLBRIGHT, 6, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (6<<16), 32 + (16<<16), S_CYBRAKDEMONMISSILE_EXPLODE3}, // S_CYBRAKDEMONMISSILE_EXPLODE2
|
||||||
{SPR_RCKT, 3 + FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_NULL}, // S_CYBRAKDEMONMISSILE_EXPLODE3
|
{SPR_RCKT, 3 + FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_NULL}, // S_CYBRAKDEMONMISSILE_EXPLODE3
|
||||||
|
|
||||||
{SPR_FLME, FF_TRANS50|FF_FULLBRIGHT , 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY2}, // S_CYBRAKDEMONFLAMESHOT_FLY1
|
{SPR_FLME, FF_TRANS20|FF_FULLBRIGHT , 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY2}, // S_CYBRAKDEMONFLAMESHOT_FLY1
|
||||||
{SPR_FLME, FF_TRANS50|FF_FULLBRIGHT|1, 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY2
|
{SPR_FLME, FF_TRANS20|FF_FULLBRIGHT|1, 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY2
|
||||||
{SPR_FLME, FF_TRANS50|FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY3
|
{SPR_FLME, FF_TRANS20|FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY3
|
||||||
{SPR_FLME, FF_TRANS50|FF_FULLBRIGHT|2, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, // S_CYBRAKDEMONFLAMESHOT_DIE
|
{SPR_FLME, FF_TRANS20|FF_FULLBRIGHT|2, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, // S_CYBRAKDEMONFLAMESHOT_DIE
|
||||||
|
|
||||||
{SPR_FLAM, FF_TRANS50|FF_FULLBRIGHT|3, 3, {A_SetFuse}, 10*TICRATE, 0, S_FLAME1}, // S_CYBRAKDEMONFLAMEREST
|
{SPR_FLAM, FF_TRANS20|FF_FULLBRIGHT|5, 3, {A_SetFuse}, 10*TICRATE, 0, S_FLAMEREST}, // S_CYBRAKDEMONFLAMEREST
|
||||||
|
|
||||||
{SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_INIT2}, // S_CYBRAKDEMONELECTRICBARRIER_INIT1
|
{SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_INIT2}, // S_CYBRAKDEMONELECTRICBARRIER_INIT1
|
||||||
{SPR_ELEC, 0 + FF_FULLBRIGHT, 0, {A_RemoteAction}, -1, S_CYBRAKDEMON_INVINCIBLERIZE, S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND}, // S_CYBRAKDEMONELECTRICBARRIER_INIT2
|
{SPR_ELEC, 0 + FF_FULLBRIGHT, 0, {A_RemoteAction}, -1, S_CYBRAKDEMON_INVINCIBLERIZE, S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND}, // S_CYBRAKDEMONELECTRICBARRIER_INIT2
|
||||||
|
@ -1570,9 +1572,11 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2
|
{SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2
|
||||||
|
|
||||||
// Starpost
|
// Starpost
|
||||||
{SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE
|
{SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE
|
||||||
{SPR_STPT, FF_ANIMATE , -1, {NULL}, 1, 2, S_NULL}, // S_STARPOST_FLASH
|
{SPR_STPT, FF_ANIMATE|17, -1, {NULL}, 5, 1, S_NULL}, // S_STARPOST_FLASH
|
||||||
{SPR_STPT, FF_ANIMATE|2, 31, {NULL}, 15, 1, S_STARPOST_FLASH}, // S_STARPOST_SPIN
|
{SPR_STPT, FF_ANIMATE|13, 2, {NULL}, 1, 1, S_STARPOST_SPIN}, // S_STARPOST_STARTSPIN
|
||||||
|
{SPR_STPT, FF_ANIMATE|1 , 23, {NULL}, 11, 1, S_STARPOST_ENDSPIN}, // S_STARPOST_SPIN
|
||||||
|
{SPR_STPT, FF_ANIMATE|15, 2, {NULL}, 1, 1, S_STARPOST_FLASH}, // S_STARPOST_ENDSPIN
|
||||||
|
|
||||||
// Big floating mine
|
// Big floating mine
|
||||||
{SPR_BMNE, 0, 5, {NULL}, 0, 0, S_BIGMINE2}, // S_BIGMINE1
|
{SPR_BMNE, 0, 5, {NULL}, 0, 0, S_BIGMINE2}, // S_BIGMINE1
|
||||||
|
@ -1753,21 +1757,15 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_CFIR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_DEMONFIRE1}, // S_DEMONFIRE6
|
{SPR_CFIR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_DEMONFIRE1}, // S_DEMONFIRE6
|
||||||
|
|
||||||
// GFZ Flower
|
// GFZ Flower
|
||||||
{SPR_FWR1, 0, 14, {NULL}, 0, 0, S_GFZFLOWERA2}, // S_GFZFLOWERA
|
{SPR_FWR1, FF_ANIMATE, -1, {NULL}, 7, 3, S_NULL}, // S_GFZFLOWERA
|
||||||
{SPR_FWR1, 1, 14, {NULL}, 0, 0, S_GFZFLOWERA}, // S_GFZFLOWERA2
|
{SPR_FWR2, FF_ANIMATE, -1, {NULL}, 19, 3, S_NULL}, // S_GFZFLOWERB
|
||||||
|
{SPR_FWR3, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_GFZFLOWERC
|
||||||
{SPR_FWR2, 0, 7, {NULL}, 0, 0, S_GFZFLOWERB2}, // S_GFZFLOWERB1
|
|
||||||
{SPR_FWR2, 1, 7, {NULL}, 0, 0, S_GFZFLOWERB1}, // S_GFZFLOWERB1
|
|
||||||
|
|
||||||
{SPR_FWR3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GFZFLOWERC1
|
|
||||||
|
|
||||||
{SPR_BUS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BERRYBUSH
|
{SPR_BUS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BERRYBUSH
|
||||||
{SPR_BUS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSH
|
{SPR_BUS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSH
|
||||||
|
|
||||||
{SPR_THZP, 0, 4, {NULL}, 0, 0, S_THZPLANT2}, // S_THZPLANT1
|
{SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA
|
||||||
{SPR_THZP, 1, 4, {NULL}, 0, 0, S_THZPLANT3}, // S_THZPLANT1
|
{SPR_FWR5, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERB
|
||||||
{SPR_THZP, 2, 4, {NULL}, 0, 0, S_THZPLANT4}, // S_THZPLANT1
|
|
||||||
{SPR_THZP, 3, 4, {NULL}, 0, 0, S_THZPLANT1}, // S_THZPLANT1
|
|
||||||
|
|
||||||
// THZ Alarm
|
// THZ Alarm
|
||||||
{SPR_ALRM, FF_FULLBRIGHT, 35, {A_Scream}, 0, 0, S_ALARM1}, // S_ALARM1
|
{SPR_ALRM, FF_FULLBRIGHT, 35, {A_Scream}, 0, 0, S_ALARM1}, // S_ALARM1
|
||||||
|
@ -1808,10 +1806,15 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN
|
{SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN
|
||||||
|
|
||||||
// Flame
|
// Flame
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_FLAME2}, // S_FLAME1
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20, 3, {A_FlameParticle}, 3, 0, S_FLAME2}, // S_FLAME1
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50|1, 3, {NULL}, 0, 0, S_FLAME3}, // S_FLAME2
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|1, 3, {NULL}, 0, 0, S_FLAME3}, // S_FLAME2
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50|2, 3, {NULL}, 0, 0, S_FLAME4}, // S_FLAME3
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|2, 3, {A_FlameParticle}, 3, 0, S_FLAME4}, // S_FLAME3
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50|3, 3, {NULL}, 0, 0, S_FLAME1}, // S_FLAME4
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|3, 3, {NULL}, 0, 0, S_FLAME5}, // S_FLAME4
|
||||||
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|4, 3, {A_FlameParticle}, 3, 0, S_FLAME6}, // S_FLAME5
|
||||||
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|5, 3, {NULL}, 0, 0, S_FLAME1}, // S_FLAME6
|
||||||
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS10|6, 24, {NULL}, 0, 0, S_NULL}, // S_FLAMEPARTICLE
|
||||||
|
|
||||||
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|FF_ANIMATE, -1, {NULL}, 5, 3, S_FLAME2}, // S_FLAMEREST
|
||||||
|
|
||||||
// Eggman statue
|
// Eggman statue
|
||||||
{SPR_ESTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGSTATUE1
|
{SPR_ESTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGSTATUE1
|
||||||
|
@ -1867,48 +1870,23 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_NULL, 0, 2*TICRATE, {NULL}, 0, 0, S_FLAMEJETSTART}, // S_FLAMEJETSTND
|
{SPR_NULL, 0, 2*TICRATE, {NULL}, 0, 0, S_FLAMEJETSTART}, // S_FLAMEJETSTND
|
||||||
{SPR_NULL, 0, 3*TICRATE, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTOP}, // S_FLAMEJETSTART
|
{SPR_NULL, 0, 3*TICRATE, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTOP}, // S_FLAMEJETSTART
|
||||||
{SPR_NULL, 0, 1, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTND}, // S_FLAMEJETSTOP
|
{SPR_NULL, 0, 1, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTND}, // S_FLAMEJETSTOP
|
||||||
{SPR_FLME, FF_TRANS50 , 4, {NULL}, 0, 0, S_FLAMEJETFLAME2}, // S_FLAMEJETFLAME1
|
{SPR_FLME, FF_FULLBRIGHT|FF_TRANS50 , 4, {NULL}, 0, 0, S_FLAMEJETFLAME2}, // S_FLAMEJETFLAME1
|
||||||
{SPR_FLME, FF_TRANS60|1, 5, {NULL}, 0, 0, S_FLAMEJETFLAME3}, // S_FLAMEJETFLAME2
|
{SPR_FLME, FF_FULLBRIGHT|FF_TRANS60|1, 5, {NULL}, 0, 0, S_FLAMEJETFLAME3}, // S_FLAMEJETFLAME2
|
||||||
{SPR_FLME, FF_TRANS70|2, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME3
|
{SPR_FLME, FF_FULLBRIGHT|FF_TRANS70|2, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME3
|
||||||
|
|
||||||
// Spinning flame jets
|
// Spinning flame jets
|
||||||
// A: Counter-clockwise
|
// A: Counter-clockwise
|
||||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINAXISA2}, // S_FJSPINAXISA1
|
{SPR_NULL, 0, 1, {A_TrapShot}, MT_FLAMEJETFLAMEB, -(16<<16)|(1<<15)|64, S_FJSPINAXISA2}, // S_FJSPINAXISA1
|
||||||
{SPR_NULL, 0, 1, {A_Thrust}, 10, 1, S_FJSPINAXISA3}, // S_FJSPINAXISA2
|
{SPR_NULL, 0, 2, {A_ChangeAngleRelative}, 6, 6, S_FJSPINAXISA1}, // S_FJSPINAXISA2
|
||||||
{SPR_NULL, 0, 0, {A_Thrust}, 0, 1, S_FJSPINAXISA4}, // S_FJSPINAXISA3
|
|
||||||
{SPR_NULL, 0, 0, {A_SpawnObjectRelative}, 0, MT_FJSPINHELPERA, S_FJSPINAXISA5}, // S_FJSPINAXISA4
|
|
||||||
{SPR_NULL, 0, 2, {A_FindTarget}, MT_FJSPINHELPERA, 0, S_FJSPINAXISA6}, // S_FJSPINAXISA5
|
|
||||||
{SPR_NULL, 0, 1, {A_Thrust}, -10, 1, S_FJSPINAXISA7}, // S_FJSPINAXISA6
|
|
||||||
{SPR_NULL, 0, 1, {A_Thrust}, 0, 1, S_FJSPINAXISA8}, // S_FJSPINAXISA7
|
|
||||||
{SPR_NULL, 0, 0, {A_FireShot}, MT_FLAMEJETFLAMEB, -64, S_FJSPINAXISA9}, // S_FJSPINAXISA8
|
|
||||||
{SPR_NULL, 0, 3, {A_ChangeAngleRelative}, 6, 6, S_FJSPINAXISA8}, // S_FJSPINAXISA9
|
|
||||||
|
|
||||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINHELPERA2}, // S_FJSPINHELPERA1
|
|
||||||
{SPR_NULL, 0, 0, {A_FindTarget}, MT_FJSPINAXISA, 0, S_FJSPINHELPERA3}, // S_FJSPINHELPERA2
|
|
||||||
{SPR_NULL, 0, 1, {A_CapeChase}, 0, (64<<16), S_FJSPINHELPERA3}, // S_FJSPINHELPERA3
|
|
||||||
|
|
||||||
// B: Clockwise
|
// B: Clockwise
|
||||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINAXISB2}, // S_FJSPINAXISB1
|
{SPR_NULL, 0, 1, {A_TrapShot}, MT_FLAMEJETFLAMEB, -(16<<16)|(1<<15)|64, S_FJSPINAXISB2}, // S_FJSPINAXISB1
|
||||||
{SPR_NULL, 0, 1, {A_Thrust}, 10, 1, S_FJSPINAXISB3}, // S_FJSPINAXISB2
|
{SPR_NULL, 0, 2, {A_ChangeAngleRelative}, -6, -6, S_FJSPINAXISB1}, // S_FJSPINAXISB2
|
||||||
{SPR_NULL, 0, 0, {A_Thrust}, 0, 1, S_FJSPINAXISB4}, // S_FJSPINAXISB3
|
|
||||||
{SPR_NULL, 0, 0, {A_SpawnObjectRelative}, 0, MT_FJSPINHELPERB, S_FJSPINAXISB5}, // S_FJSPINAXISB4
|
|
||||||
{SPR_NULL, 0, 2, {A_FindTarget}, MT_FJSPINHELPERB, 0, S_FJSPINAXISB6}, // S_FJSPINAXISB5
|
|
||||||
{SPR_NULL, 0, 1, {A_Thrust}, -10, 1, S_FJSPINAXISB7}, // S_FJSPINAXISB6
|
|
||||||
{SPR_NULL, 0, 1, {A_Thrust}, 0, 1, S_FJSPINAXISB8}, // S_FJSPINAXISB7
|
|
||||||
{SPR_NULL, 0, 0, {A_FireShot}, MT_FLAMEJETFLAMEB, -64, S_FJSPINAXISB9}, // S_FJSPINAXISB8
|
|
||||||
{SPR_NULL, 0, 3, {A_ChangeAngleRelative}, -6, -6, S_FJSPINAXISB8}, // S_FJSPINAXISB9
|
|
||||||
|
|
||||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINHELPERB2}, // S_FJSPINHELPERB1
|
|
||||||
{SPR_NULL, 0, 0, {A_FindTarget}, MT_FJSPINAXISB, 0, S_FJSPINHELPERB3}, // S_FJSPINHELPERB2
|
|
||||||
{SPR_NULL, 0, 1, {A_CapeChase}, 0, (64<<16), S_FJSPINHELPERB3}, // S_FJSPINHELPERB3
|
|
||||||
|
|
||||||
// Blade's flame
|
// Blade's flame
|
||||||
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|1, 1, {A_MoveRelative}, 0, 5, S_FLAMEJETFLAMEB2}, // S_FLAMEJETFLAMEB1
|
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40, 1, {A_MoveRelative}, 0, 5, S_FLAMEJETFLAMEB2}, // S_FLAMEJETFLAMEB1
|
||||||
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|2, 1, {A_MoveRelative}, 0, 7, S_FLAMEJETFLAMEB3}, // S_FLAMEJETFLAMEB2
|
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40, 1, {A_MoveRelative}, 0, 7, S_FLAMEJETFLAMEB3}, // S_FLAMEJETFLAMEB2
|
||||||
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|3,24, {NULL}, 0, 0, S_FLAMEJETFLAMEB4}, // S_FLAMEJETFLAMEB3
|
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|FF_ANIMATE, (12*7), {NULL}, 7, 12, S_NULL}, // S_FLAMEJETFLAMEB3
|
||||||
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|4,24, {NULL}, 0, 0, S_FLAMEJETFLAMEB5}, // S_FLAMEJETFLAMEB4
|
|
||||||
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|5,24, {NULL}, 0, 0, S_FLAMEJETFLAMEB6}, // S_FLAMEJETFLAMEB5
|
|
||||||
{SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|6,12, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAMEB6
|
|
||||||
|
|
||||||
// Trapgoyles
|
// Trapgoyles
|
||||||
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE
|
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE
|
||||||
|
@ -2006,8 +1984,10 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_BSZ7, 5, -1, {NULL}, 0, 0, S_NULL}, // S_BSZVINE_ORANGE
|
{SPR_BSZ7, 5, -1, {NULL}, 0, 0, S_NULL}, // S_BSZVINE_ORANGE
|
||||||
{SPR_BSZ8, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSHRUB
|
{SPR_BSZ8, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSHRUB
|
||||||
{SPR_BSZ8, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BSZCLOVER
|
{SPR_BSZ8, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BSZCLOVER
|
||||||
{SPR_BSZ8, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BSZFISH
|
{SPR_BSZ8, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BIG_PALMTREE_TRUNK
|
||||||
{SPR_BSZ8, 3, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSUNFLOWER
|
{SPR_BSZ8, 3, -1, {NULL}, 0, 0, S_NULL}, // S_BIG_PALMTREE_TOP
|
||||||
|
{SPR_BSZ8, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PALMTREE_TRUNK
|
||||||
|
{SPR_BSZ8, 5, -1, {NULL}, 0, 0, S_NULL}, // S_PALMTREE_TOP
|
||||||
|
|
||||||
// Disco ball
|
// Disco ball
|
||||||
{SPR_DBAL, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_DBALL2}, // S_DBALL1
|
{SPR_DBAL, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_DBALL2}, // S_DBALL1
|
||||||
|
@ -2762,25 +2742,25 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP3
|
{SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP3
|
||||||
|
|
||||||
// Turtle Shell
|
// Turtle Shell
|
||||||
{SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL
|
{SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL
|
||||||
{SPR_SHLL, 0, 2, {NULL}, 0, 0, S_SHELL2}, // S_SHELL1
|
|
||||||
{SPR_SHLL, 1, 2, {NULL}, 0, 0, S_SHELL3}, // S_SHELL2
|
|
||||||
{SPR_SHLL, 2, 2, {NULL}, 0, 0, S_SHELL4}, // S_SHELL3
|
|
||||||
{SPR_SHLL, 3, 2, {NULL}, 0, 0, S_SHELL1}, // S_SHELL4
|
|
||||||
|
|
||||||
// Puma (Mario fireball)
|
// Puma (Mario fireball)
|
||||||
{SPR_PUMA, FF_FULLBRIGHT, 3, {A_FishJump}, 0, 0, S_PUMA2}, // S_PUMA1
|
{SPR_PUMA, FF_FULLBRIGHT|2, 1, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_START2}, // S_PUMA_START1
|
||||||
{SPR_PUMA, FF_FULLBRIGHT|1, 3, {A_FishJump}, 0, 0, S_PUMA3}, // S_PUMA2
|
{SPR_PUMA, FF_FULLBRIGHT|2, 1, {A_PlaySound}, sfx_s3k70, 1, S_PUMA_UP1}, // S_PUMA_START2
|
||||||
{SPR_PUMA, FF_FULLBRIGHT|2, 3, {A_FishJump}, 0, 0, S_PUMA1}, // S_PUMA3
|
{SPR_PUMA, FF_FULLBRIGHT , 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_UP2}, // S_PUMA_UP1
|
||||||
{SPR_PUMA, FF_FULLBRIGHT|3, 3, {A_FishJump}, 0, 0, S_PUMA5}, // S_PUMA4
|
{SPR_PUMA, FF_FULLBRIGHT|1, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_UP3}, // S_PUMA_UP2
|
||||||
{SPR_PUMA, FF_FULLBRIGHT|4, 3, {A_FishJump}, 0, 0, S_PUMA6}, // S_PUMA5
|
{SPR_PUMA, FF_FULLBRIGHT|2, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_UP1}, // S_PUMA_UP3
|
||||||
{SPR_PUMA, FF_FULLBRIGHT|5, 3, {A_FishJump}, 0, 0, S_PUMA4}, // S_PUMA6
|
{SPR_PUMA, FF_FULLBRIGHT|3, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_DOWN2}, // S_PUMA_DOWN1
|
||||||
|
{SPR_PUMA, FF_FULLBRIGHT|4, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_DOWN3}, // S_PUMA_DOWN2
|
||||||
|
{SPR_PUMA, FF_FULLBRIGHT|5, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_DOWN1}, // S_PUMA_DOWN3
|
||||||
|
|
||||||
|
{SPR_PUMA, FF_FULLBRIGHT|FF_TRANS20|6, 4, {NULL}, 0, 0, S_PUMATRAIL2}, // S_PUMATRAIL1
|
||||||
|
{SPR_PUMA, FF_FULLBRIGHT|FF_TRANS40|6, 5, {A_SetScale}, FRACUNIT, 1, S_PUMATRAIL3}, // S_PUMATRAIL2
|
||||||
|
{SPR_PUMA, FF_FULLBRIGHT|FF_TRANS50|7, 4, {NULL}, 0, 0, S_PUMATRAIL4}, // S_PUMATRAIL3
|
||||||
|
{SPR_PUMA, FF_FULLBRIGHT|FF_TRANS60|8, 3, {NULL}, 0, 0, S_NULL}, // S_PUMATRAIL4
|
||||||
|
|
||||||
// Hammer
|
// Hammer
|
||||||
{SPR_HAMM, 0, 3, {NULL}, 0, 0, S_HAMMER2}, // S_HAMMER1
|
{SPR_HAMM, FF_ANIMATE, -1, {NULL}, 4, 3, S_NULL}, // S_HAMMER
|
||||||
{SPR_HAMM, 1, 3, {NULL}, 0, 0, S_HAMMER3}, // S_HAMMER2
|
|
||||||
{SPR_HAMM, 2, 3, {NULL}, 0, 0, S_HAMMER4}, // S_HAMMER3
|
|
||||||
{SPR_HAMM, 3, 3, {NULL}, 0, 0, S_HAMMER1}, // S_HAMMER4
|
|
||||||
|
|
||||||
// Koopa
|
// Koopa
|
||||||
{SPR_KOOP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KOOPA1
|
{SPR_KOOP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KOOPA1
|
||||||
|
@ -3195,8 +3175,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_pop, // deathsound
|
sfx_pop, // deathsound
|
||||||
4*FRACUNIT, // speed
|
4*FRACUNIT, // speed
|
||||||
20*FRACUNIT, // radius
|
28*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
100, // mass
|
100, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -3222,8 +3202,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_pop, // deathsound
|
sfx_pop, // deathsound
|
||||||
8*FRACUNIT, // speed
|
8*FRACUNIT, // speed
|
||||||
20*FRACUNIT, // radius
|
28*FRACUNIT, // radius
|
||||||
24*FRACUNIT, // height
|
40*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
100, // mass
|
100, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -4339,6 +4319,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_GOOPTRAIL
|
||||||
|
-1, // doomednum
|
||||||
|
S_GOOPTRAIL, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
3, // speed
|
||||||
|
4*FRACUNIT, // radius
|
||||||
|
4*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
4, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_EGGMOBILE3
|
{ // MT_EGGMOBILE3
|
||||||
202, // doomednum
|
202, // doomednum
|
||||||
S_EGGMOBILE3_STND, // spawnstate
|
S_EGGMOBILE3_STND, // spawnstate
|
||||||
|
@ -4726,7 +4733,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
8, // reactiontime
|
8, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
S_NULL, // painstate
|
S_NULL, // painstate
|
||||||
0, // painchance
|
MT_NULL, // painchance
|
||||||
sfx_None, // painsound
|
sfx_None, // painsound
|
||||||
S_NULL, // meleestate
|
S_NULL, // meleestate
|
||||||
S_NULL, // missilestate
|
S_NULL, // missilestate
|
||||||
|
@ -5989,7 +5996,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
8, // reactiontime
|
8, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
S_STARPOST_SPIN, // painstate
|
S_STARPOST_STARTSPIN, // painstate
|
||||||
0, // painchance
|
0, // painchance
|
||||||
sfx_strpst, // painsound
|
sfx_strpst, // painsound
|
||||||
S_NULL, // meleestate
|
S_NULL, // meleestate
|
||||||
|
@ -5999,7 +6006,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
8, // speed
|
8, // speed
|
||||||
64*FRACUNIT, // radius
|
64*FRACUNIT, // radius
|
||||||
80*FRACUNIT, // height
|
128*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
4, // mass
|
4, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
|
@ -7927,7 +7934,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_GFZFLOWER2
|
{ // MT_GFZFLOWER2
|
||||||
801, // doomednum
|
801, // doomednum
|
||||||
S_GFZFLOWERB1, // spawnstate
|
S_GFZFLOWERB, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -7954,7 +7961,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_GFZFLOWER3
|
{ // MT_GFZFLOWER3
|
||||||
802, // doomednum
|
802, // doomednum
|
||||||
S_GFZFLOWERC1, // spawnstate
|
S_GFZFLOWERC, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -7975,7 +7982,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
100, // mass
|
100, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8033,9 +8040,36 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_THZPLANT
|
{ // MT_THZFLOWER1
|
||||||
900, // doomednum
|
900, // doomednum
|
||||||
S_THZPLANT1, // spawnstate
|
S_THZFLOWERA, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
8, // speed
|
||||||
|
8*FRACUNIT, // radius
|
||||||
|
32*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
16, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_THZFLOWER2
|
||||||
|
902, // doomednum
|
||||||
|
S_THZFLOWERB, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -8339,7 +8373,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
8, // reactiontime
|
8, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
S_NULL, // painstate
|
S_NULL, // painstate
|
||||||
0, // painchance
|
MT_FLAMEPARTICLE, // painchance
|
||||||
sfx_None, // painsound
|
sfx_None, // painsound
|
||||||
S_NULL, // meleestate
|
S_NULL, // meleestate
|
||||||
S_NULL, // missilestate
|
S_NULL, // missilestate
|
||||||
|
@ -8357,6 +8391,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_FLAMEPARTICLE
|
||||||
|
-1, // doomednum
|
||||||
|
S_FLAMEPARTICLE, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
0, // speed
|
||||||
|
FRACUNIT, // radius
|
||||||
|
FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_EGGSTATUE
|
{ // MT_EGGSTATUE
|
||||||
1102, // doomednum
|
1102, // doomednum
|
||||||
S_EGGSTATUE1, // spawnstate
|
S_EGGSTATUE1, // spawnstate
|
||||||
|
@ -8924,33 +8985,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_FJSPINHELPERA
|
|
||||||
-1, // doomednum
|
|
||||||
S_FJSPINHELPERA1,// spawnstate
|
|
||||||
1000, // spawnhealth
|
|
||||||
S_NULL, // seestate
|
|
||||||
sfx_None, // seesound
|
|
||||||
8, // reactiontime
|
|
||||||
sfx_None, // attacksound
|
|
||||||
S_NULL, // painstate
|
|
||||||
0, // painchance
|
|
||||||
sfx_None, // painsound
|
|
||||||
S_NULL, // meleestate
|
|
||||||
S_NULL, // missilestate
|
|
||||||
S_NULL, // deathstate
|
|
||||||
S_NULL, // xdeathstate
|
|
||||||
sfx_None, // deathsound
|
|
||||||
10*FRACUNIT, // speed
|
|
||||||
16*FRACUNIT, // radius
|
|
||||||
1*FRACUNIT, // height
|
|
||||||
0, // display offset
|
|
||||||
100, // mass
|
|
||||||
1, // damage
|
|
||||||
sfx_None, // activesound
|
|
||||||
MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags
|
|
||||||
S_NULL // raisestate
|
|
||||||
},
|
|
||||||
|
|
||||||
{ // MT_FJSPINAXISB
|
{ // MT_FJSPINAXISB
|
||||||
3576, // doomednum
|
3576, // doomednum
|
||||||
S_FJSPINAXISB1, // spawnstate
|
S_FJSPINAXISB1, // spawnstate
|
||||||
|
@ -8978,33 +9012,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_FJSPINHELPERB
|
|
||||||
-1, // doomednum
|
|
||||||
S_FJSPINHELPERB1,// spawnstate
|
|
||||||
1000, // spawnhealth
|
|
||||||
S_NULL, // seestate
|
|
||||||
sfx_None, // seesound
|
|
||||||
8, // reactiontime
|
|
||||||
sfx_None, // attacksound
|
|
||||||
S_NULL, // painstate
|
|
||||||
0, // painchance
|
|
||||||
sfx_None, // painsound
|
|
||||||
S_NULL, // meleestate
|
|
||||||
S_NULL, // missilestate
|
|
||||||
S_NULL, // deathstate
|
|
||||||
S_NULL, // xdeathstate
|
|
||||||
sfx_None, // deathsound
|
|
||||||
10*FRACUNIT, // speed
|
|
||||||
16*FRACUNIT, // radius
|
|
||||||
1*FRACUNIT, // height
|
|
||||||
0, // display offset
|
|
||||||
100, // mass
|
|
||||||
1, // damage
|
|
||||||
sfx_None, // activesound
|
|
||||||
MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags
|
|
||||||
S_NULL // raisestate
|
|
||||||
},
|
|
||||||
|
|
||||||
{ // MT_FLAMEJETFLAMEB
|
{ // MT_FLAMEJETFLAMEB
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_FLAMEJETFLAMEB1, // spawnstate
|
S_FLAMEJETFLAMEB1, // spawnstate
|
||||||
|
@ -10709,9 +10716,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_BSZFISH
|
{ // MT_BIG_PALMTREE_TRUNK
|
||||||
1472, // doomednum
|
1472, // doomednum
|
||||||
S_BSZFISH, // spawnstate
|
S_BIG_PALMTREE_TRUNK, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -10736,9 +10743,63 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_BSZSUNFLOWER
|
{ // MT_BIG_PALMTREE_TOP
|
||||||
1473, // doomednum
|
1473, // doomednum
|
||||||
S_BSZSUNFLOWER, // spawnstate
|
S_BIG_PALMTREE_TOP, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
0, // speed
|
||||||
|
16*FRACUNIT, // radius
|
||||||
|
32*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_PALMTREE_TRUNK
|
||||||
|
1474, // doomednum
|
||||||
|
S_PALMTREE_TRUNK, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
0, // speed
|
||||||
|
16*FRACUNIT, // radius
|
||||||
|
32*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_PALMTREE_TOP
|
||||||
|
1475, // doomednum
|
||||||
|
S_PALMTREE_TOP, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -13085,9 +13146,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // deathstate
|
S_NULL, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
20*FRACUNIT, // speed
|
16, // speed
|
||||||
8*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
16*FRACUNIT, // height
|
20*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
100, // mass
|
100, // mass
|
||||||
1, // damage
|
1, // damage
|
||||||
|
@ -13098,19 +13159,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_PUMA
|
{ // MT_PUMA
|
||||||
1805, // doomednum
|
1805, // doomednum
|
||||||
S_PUMA1, // spawnstate
|
S_PUMA_START1, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_PUMA1, // seestate
|
S_PUMA_START1, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
8, // reactiontime
|
8, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
S_NULL, // painstate
|
S_NULL, // painstate
|
||||||
0, // painchance
|
0, // painchance
|
||||||
sfx_None, // painsound
|
sfx_None, // painsound
|
||||||
S_PUMA4, // meleestate
|
S_PUMA_DOWN1, // meleestate
|
||||||
S_NULL, // missilestate
|
S_NULL, // missilestate
|
||||||
S_NULL, // deathstate
|
S_NULL, // deathstate
|
||||||
S_PUMA6, // xdeathstate
|
S_PUMA_DOWN3, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
0, // speed
|
0, // speed
|
||||||
8*FRACUNIT, // radius
|
8*FRACUNIT, // radius
|
||||||
|
@ -13119,12 +13180,40 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
100, // mass
|
100, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_PAIN|MF_FIRE, // flags
|
MF_PAIN|MF_FIRE, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_PUMATRAIL
|
||||||
|
-1, // doomednum
|
||||||
|
S_PUMATRAIL1, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
0, // speed
|
||||||
|
2*FRACUNIT, // radius
|
||||||
|
4*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_HAMMER
|
{ // MT_HAMMER
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_HAMMER1, // spawnstate
|
S_HAMMER, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -14335,7 +14424,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14362,7 +14451,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14389,7 +14478,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14416,7 +14505,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14443,7 +14532,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14470,7 +14559,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14497,7 +14586,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14524,7 +14613,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14551,7 +14640,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14578,7 +14667,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14605,7 +14694,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14632,7 +14721,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14659,7 +14748,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14686,7 +14775,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14713,7 +14802,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
@ -14740,7 +14829,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // display offset
|
0, // display offset
|
||||||
1000, // mass
|
1000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_crumbl, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
96
src/info.h
96
src/info.h
|
@ -224,6 +224,7 @@ void A_FlickyFlounder();
|
||||||
void A_FlickyCheck();
|
void A_FlickyCheck();
|
||||||
void A_FlickyHeightCheck();
|
void A_FlickyHeightCheck();
|
||||||
void A_FlickyFlutter();
|
void A_FlickyFlutter();
|
||||||
|
void A_FlameParticle();
|
||||||
|
|
||||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||||
#define NUMMOBJFREESLOTS 256
|
#define NUMMOBJFREESLOTS 256
|
||||||
|
@ -388,7 +389,8 @@ typedef enum sprite
|
||||||
SPR_BUS2, // GFZ Bush w/o berries
|
SPR_BUS2, // GFZ Bush w/o berries
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
SPR_THZP, // Techno Hill Zone Plant
|
SPR_THZP, // THZ1 Flower
|
||||||
|
SPR_FWR5, // Another flower
|
||||||
SPR_ALRM, // THZ2 Alarm
|
SPR_ALRM, // THZ2 Alarm
|
||||||
|
|
||||||
// Deep Sea Scenery
|
// Deep Sea Scenery
|
||||||
|
@ -1200,6 +1202,7 @@ typedef enum state
|
||||||
S_GOOP1,
|
S_GOOP1,
|
||||||
S_GOOP2,
|
S_GOOP2,
|
||||||
S_GOOP3,
|
S_GOOP3,
|
||||||
|
S_GOOPTRAIL,
|
||||||
|
|
||||||
// Boss 3
|
// Boss 3
|
||||||
S_EGGMOBILE3_STND,
|
S_EGGMOBILE3_STND,
|
||||||
|
@ -1776,7 +1779,9 @@ typedef enum state
|
||||||
// Starpost
|
// Starpost
|
||||||
S_STARPOST_IDLE,
|
S_STARPOST_IDLE,
|
||||||
S_STARPOST_FLASH,
|
S_STARPOST_FLASH,
|
||||||
|
S_STARPOST_STARTSPIN,
|
||||||
S_STARPOST_SPIN,
|
S_STARPOST_SPIN,
|
||||||
|
S_STARPOST_ENDSPIN,
|
||||||
|
|
||||||
// Big floating mine
|
// Big floating mine
|
||||||
S_BIGMINE1,
|
S_BIGMINE1,
|
||||||
|
@ -1960,21 +1965,15 @@ typedef enum state
|
||||||
S_DEMONFIRE6,
|
S_DEMONFIRE6,
|
||||||
|
|
||||||
S_GFZFLOWERA,
|
S_GFZFLOWERA,
|
||||||
S_GFZFLOWERA2,
|
S_GFZFLOWERB,
|
||||||
|
S_GFZFLOWERC,
|
||||||
S_GFZFLOWERB1,
|
|
||||||
S_GFZFLOWERB2,
|
|
||||||
|
|
||||||
S_GFZFLOWERC1,
|
|
||||||
|
|
||||||
S_BERRYBUSH,
|
S_BERRYBUSH,
|
||||||
S_BUSH,
|
S_BUSH,
|
||||||
|
|
||||||
// THZ Plant
|
// THZ Plant
|
||||||
S_THZPLANT1,
|
S_THZFLOWERA,
|
||||||
S_THZPLANT2,
|
S_THZFLOWERB,
|
||||||
S_THZPLANT3,
|
|
||||||
S_THZPLANT4,
|
|
||||||
|
|
||||||
// THZ Alarm
|
// THZ Alarm
|
||||||
S_ALARM1,
|
S_ALARM1,
|
||||||
|
@ -2019,6 +2018,11 @@ typedef enum state
|
||||||
S_FLAME2,
|
S_FLAME2,
|
||||||
S_FLAME3,
|
S_FLAME3,
|
||||||
S_FLAME4,
|
S_FLAME4,
|
||||||
|
S_FLAME5,
|
||||||
|
S_FLAME6,
|
||||||
|
S_FLAMEPARTICLE,
|
||||||
|
|
||||||
|
S_FLAMEREST,
|
||||||
|
|
||||||
// Eggman Statue
|
// Eggman Statue
|
||||||
S_EGGSTATUE1,
|
S_EGGSTATUE1,
|
||||||
|
@ -2080,36 +2084,13 @@ typedef enum state
|
||||||
// Spinning flame jets
|
// Spinning flame jets
|
||||||
S_FJSPINAXISA1, // Counter-clockwise
|
S_FJSPINAXISA1, // Counter-clockwise
|
||||||
S_FJSPINAXISA2,
|
S_FJSPINAXISA2,
|
||||||
S_FJSPINAXISA3,
|
|
||||||
S_FJSPINAXISA4,
|
|
||||||
S_FJSPINAXISA5,
|
|
||||||
S_FJSPINAXISA6,
|
|
||||||
S_FJSPINAXISA7,
|
|
||||||
S_FJSPINAXISA8,
|
|
||||||
S_FJSPINAXISA9,
|
|
||||||
S_FJSPINHELPERA1,
|
|
||||||
S_FJSPINHELPERA2,
|
|
||||||
S_FJSPINHELPERA3,
|
|
||||||
S_FJSPINAXISB1, // Clockwise
|
S_FJSPINAXISB1, // Clockwise
|
||||||
S_FJSPINAXISB2,
|
S_FJSPINAXISB2,
|
||||||
S_FJSPINAXISB3,
|
|
||||||
S_FJSPINAXISB4,
|
|
||||||
S_FJSPINAXISB5,
|
|
||||||
S_FJSPINAXISB6,
|
|
||||||
S_FJSPINAXISB7,
|
|
||||||
S_FJSPINAXISB8,
|
|
||||||
S_FJSPINAXISB9,
|
|
||||||
S_FJSPINHELPERB1,
|
|
||||||
S_FJSPINHELPERB2,
|
|
||||||
S_FJSPINHELPERB3,
|
|
||||||
|
|
||||||
// Blade's flame
|
// Blade's flame
|
||||||
S_FLAMEJETFLAMEB1,
|
S_FLAMEJETFLAMEB1,
|
||||||
S_FLAMEJETFLAMEB2,
|
S_FLAMEJETFLAMEB2,
|
||||||
S_FLAMEJETFLAMEB3,
|
S_FLAMEJETFLAMEB3,
|
||||||
S_FLAMEJETFLAMEB4,
|
|
||||||
S_FLAMEJETFLAMEB5,
|
|
||||||
S_FLAMEJETFLAMEB6,
|
|
||||||
|
|
||||||
// Trapgoyles
|
// Trapgoyles
|
||||||
S_TRAPGOYLE,
|
S_TRAPGOYLE,
|
||||||
|
@ -2204,8 +2185,10 @@ typedef enum state
|
||||||
S_BSZVINE_ORANGE,
|
S_BSZVINE_ORANGE,
|
||||||
S_BSZSHRUB,
|
S_BSZSHRUB,
|
||||||
S_BSZCLOVER,
|
S_BSZCLOVER,
|
||||||
S_BSZFISH,
|
S_BIG_PALMTREE_TRUNK,
|
||||||
S_BSZSUNFLOWER,
|
S_BIG_PALMTREE_TOP,
|
||||||
|
S_PALMTREE_TRUNK,
|
||||||
|
S_PALMTREE_TOP,
|
||||||
|
|
||||||
S_DBALL1,
|
S_DBALL1,
|
||||||
S_DBALL2,
|
S_DBALL2,
|
||||||
|
@ -2924,20 +2907,19 @@ typedef enum state
|
||||||
S_FIREBALLEXP2,
|
S_FIREBALLEXP2,
|
||||||
S_FIREBALLEXP3,
|
S_FIREBALLEXP3,
|
||||||
S_SHELL,
|
S_SHELL,
|
||||||
S_SHELL1,
|
S_PUMA_START1,
|
||||||
S_SHELL2,
|
S_PUMA_START2,
|
||||||
S_SHELL3,
|
S_PUMA_UP1,
|
||||||
S_SHELL4,
|
S_PUMA_UP2,
|
||||||
S_PUMA1,
|
S_PUMA_UP3,
|
||||||
S_PUMA2,
|
S_PUMA_DOWN1,
|
||||||
S_PUMA3,
|
S_PUMA_DOWN2,
|
||||||
S_PUMA4,
|
S_PUMA_DOWN3,
|
||||||
S_PUMA5,
|
S_PUMATRAIL1,
|
||||||
S_PUMA6,
|
S_PUMATRAIL2,
|
||||||
S_HAMMER1,
|
S_PUMATRAIL3,
|
||||||
S_HAMMER2,
|
S_PUMATRAIL4,
|
||||||
S_HAMMER3,
|
S_HAMMER,
|
||||||
S_HAMMER4,
|
|
||||||
S_KOOPA1,
|
S_KOOPA1,
|
||||||
S_KOOPA2,
|
S_KOOPA2,
|
||||||
S_KOOPAFLAME1,
|
S_KOOPAFLAME1,
|
||||||
|
@ -3209,6 +3191,7 @@ typedef enum mobj_type
|
||||||
MT_BOSSTANK2,
|
MT_BOSSTANK2,
|
||||||
MT_BOSSSPIGOT,
|
MT_BOSSSPIGOT,
|
||||||
MT_GOOP,
|
MT_GOOP,
|
||||||
|
MT_GOOPTRAIL,
|
||||||
|
|
||||||
// Boss 3
|
// Boss 3
|
||||||
MT_EGGMOBILE3,
|
MT_EGGMOBILE3,
|
||||||
|
@ -3378,7 +3361,8 @@ typedef enum mobj_type
|
||||||
MT_BUSH,
|
MT_BUSH,
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
MT_THZPLANT, // THZ Plant
|
MT_THZFLOWER1,
|
||||||
|
MT_THZFLOWER2,
|
||||||
MT_ALARM,
|
MT_ALARM,
|
||||||
|
|
||||||
// Deep Sea Scenery
|
// Deep Sea Scenery
|
||||||
|
@ -3394,6 +3378,7 @@ typedef enum mobj_type
|
||||||
// Castle Eggman Scenery
|
// Castle Eggman Scenery
|
||||||
MT_CHAIN, // CEZ Chain
|
MT_CHAIN, // CEZ Chain
|
||||||
MT_FLAME, // Flame (has corona)
|
MT_FLAME, // Flame (has corona)
|
||||||
|
MT_FLAMEPARTICLE,
|
||||||
MT_EGGSTATUE, // Eggman Statue
|
MT_EGGSTATUE, // Eggman Statue
|
||||||
MT_MACEPOINT, // Mace rotation point
|
MT_MACEPOINT, // Mace rotation point
|
||||||
MT_SWINGMACEPOINT, // Mace swinging point
|
MT_SWINGMACEPOINT, // Mace swinging point
|
||||||
|
@ -3420,9 +3405,7 @@ typedef enum mobj_type
|
||||||
MT_FLAMEJETFLAME,
|
MT_FLAMEJETFLAME,
|
||||||
|
|
||||||
MT_FJSPINAXISA, // Counter-clockwise
|
MT_FJSPINAXISA, // Counter-clockwise
|
||||||
MT_FJSPINHELPERA,
|
|
||||||
MT_FJSPINAXISB, // Clockwise
|
MT_FJSPINAXISB, // Clockwise
|
||||||
MT_FJSPINHELPERB,
|
|
||||||
|
|
||||||
MT_FLAMEJETFLAMEB, // Blade's flame
|
MT_FLAMEJETFLAMEB, // Blade's flame
|
||||||
|
|
||||||
|
@ -3499,8 +3482,10 @@ typedef enum mobj_type
|
||||||
MT_BSZVINE_ORANGE,
|
MT_BSZVINE_ORANGE,
|
||||||
MT_BSZSHRUB,
|
MT_BSZSHRUB,
|
||||||
MT_BSZCLOVER,
|
MT_BSZCLOVER,
|
||||||
MT_BSZFISH,
|
MT_BIG_PALMTREE_TRUNK,
|
||||||
MT_BSZSUNFLOWER,
|
MT_BIG_PALMTREE_TOP,
|
||||||
|
MT_PALMTREE_TRUNK,
|
||||||
|
MT_PALMTREE_TOP,
|
||||||
|
|
||||||
// Misc scenery
|
// Misc scenery
|
||||||
MT_DBALL,
|
MT_DBALL,
|
||||||
|
@ -3606,6 +3591,7 @@ typedef enum mobj_type
|
||||||
MT_FIREBALL,
|
MT_FIREBALL,
|
||||||
MT_SHELL,
|
MT_SHELL,
|
||||||
MT_PUMA,
|
MT_PUMA,
|
||||||
|
MT_PUMATRAIL,
|
||||||
MT_HAMMER,
|
MT_HAMMER,
|
||||||
MT_KOOPA,
|
MT_KOOPA,
|
||||||
MT_KOOPAFLAME,
|
MT_KOOPAFLAME,
|
||||||
|
|
145
src/p_enemy.c
145
src/p_enemy.c
|
@ -252,6 +252,7 @@ void A_FlickyFlounder(mobj_t *actor);
|
||||||
void A_FlickyCheck(mobj_t *actor);
|
void A_FlickyCheck(mobj_t *actor);
|
||||||
void A_FlickyHeightCheck(mobj_t *actor);
|
void A_FlickyHeightCheck(mobj_t *actor);
|
||||||
void A_FlickyFlutter(mobj_t *actor);
|
void A_FlickyFlutter(mobj_t *actor);
|
||||||
|
void A_FlameParticle(mobj_t *actor);
|
||||||
|
|
||||||
//
|
//
|
||||||
// ENEMY THINKING
|
// ENEMY THINKING
|
||||||
|
@ -2134,13 +2135,15 @@ void A_Boss1Laser(mobj_t *actor)
|
||||||
if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
||||||
{
|
{
|
||||||
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
|
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
|
||||||
|
point->angle = actor->angle;
|
||||||
point->fuse = actor->tics+1;
|
point->fuse = actor->tics+1;
|
||||||
P_SetTarget(&point->target, actor->target);
|
P_SetTarget(&point->target, actor->target);
|
||||||
P_SetTarget(&actor->target, point);
|
P_SetTarget(&actor->target, point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* -- the following was relevant when the MT_EGGMOBILE_TARGET was allowed to move left and right from its path
|
||||||
else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
||||||
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);
|
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/
|
||||||
|
|
||||||
if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)
|
if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)
|
||||||
angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT);
|
angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT);
|
||||||
|
@ -2190,11 +2193,16 @@ void A_Boss1Laser(mobj_t *actor)
|
||||||
// var1:
|
// var1:
|
||||||
// 0 - accelerative focus with friction
|
// 0 - accelerative focus with friction
|
||||||
// 1 - steady focus with fixed movement speed
|
// 1 - steady focus with fixed movement speed
|
||||||
// var2 = unused
|
// anything else - don't move
|
||||||
|
// var2:
|
||||||
|
// 0 - don't trace target, just move forwards
|
||||||
|
// & 1 - change horizontal angle
|
||||||
|
// & 2 - change vertical angle
|
||||||
//
|
//
|
||||||
void A_FocusTarget(mobj_t *actor)
|
void A_FocusTarget(mobj_t *actor)
|
||||||
{
|
{
|
||||||
INT32 locvar1 = var1;
|
INT32 locvar1 = var1;
|
||||||
|
INT32 locvar2 = var2;
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_FocusTarget", actor))
|
if (LUA_CallAction("A_FocusTarget", actor))
|
||||||
return;
|
return;
|
||||||
|
@ -2203,9 +2211,9 @@ void A_FocusTarget(mobj_t *actor)
|
||||||
if (actor->target)
|
if (actor->target)
|
||||||
{
|
{
|
||||||
fixed_t speed = FixedMul(actor->info->speed, actor->scale);
|
fixed_t speed = FixedMul(actor->info->speed, actor->scale);
|
||||||
fixed_t dist = R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y);
|
fixed_t dist = (locvar2 ? R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) : speed+1);
|
||||||
angle_t vangle = R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist);
|
angle_t hangle = ((locvar2 & 1) ? R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) : actor->angle);
|
||||||
angle_t hangle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y);
|
angle_t vangle = ((locvar2 & 2) ? R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist) : ANGLE_90);
|
||||||
switch(locvar1)
|
switch(locvar1)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -3534,41 +3542,49 @@ void A_ScoreRise(mobj_t *actor)
|
||||||
|
|
||||||
// Function: A_ParticleSpawn
|
// Function: A_ParticleSpawn
|
||||||
//
|
//
|
||||||
// Description: Spawns a particle at a specified interval
|
// Description: Hyper-specialised function for spawning a particle for MT_PARTICLEGEN.
|
||||||
//
|
//
|
||||||
// var1 = type (if 0, defaults to MT_PARTICLE)
|
// var1 = unused
|
||||||
// var2 = unused
|
// var2 = unused
|
||||||
//
|
//
|
||||||
void A_ParticleSpawn(mobj_t *actor)
|
void A_ParticleSpawn(mobj_t *actor)
|
||||||
{
|
{
|
||||||
INT32 locvar1 = var1;
|
INT32 i = 0;
|
||||||
fixed_t speed;
|
|
||||||
mobjtype_t type;
|
|
||||||
mobj_t *spawn;
|
mobj_t *spawn;
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_ParticleSpawn", actor))
|
if (LUA_CallAction("A_ParticleSpawn", actor))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
if (!actor->spawnpoint)
|
if (!actor->health)
|
||||||
{
|
|
||||||
P_RemoveMobj(actor);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!actor->lastlook)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!actor->threshold)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < actor->lastlook; i++)
|
||||||
|
{
|
||||||
|
spawn = P_SpawnMobj(
|
||||||
|
actor->x + FixedMul(FixedMul(actor->friction, actor->scale), FINECOSINE(actor->angle>>ANGLETOFINESHIFT)),
|
||||||
|
actor->y + FixedMul(FixedMul(actor->friction, actor->scale), FINESINE(actor->angle>>ANGLETOFINESHIFT)),
|
||||||
|
actor->z,
|
||||||
|
(mobjtype_t)actor->threshold);
|
||||||
|
P_SetScale(spawn, actor->scale);
|
||||||
|
spawn->momz = FixedMul(actor->movefactor, spawn->scale);
|
||||||
|
spawn->destscale = spawn->scale/100;
|
||||||
|
spawn->scalespeed = spawn->scale/actor->health;
|
||||||
|
spawn->tics = (tic_t)actor->health;
|
||||||
|
spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP);
|
||||||
|
spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||||
|
if (spawn->frame & FF_ANIMATE)
|
||||||
|
spawn->frame += P_RandomKey(spawn->state->var1);
|
||||||
|
|
||||||
|
actor->angle += actor->movedir;
|
||||||
}
|
}
|
||||||
|
actor->angle += (angle_t)actor->movecount;
|
||||||
if (locvar1)
|
|
||||||
type = (mobjtype_t)locvar1;
|
|
||||||
else
|
|
||||||
type = MT_PARTICLE;
|
|
||||||
|
|
||||||
speed = FixedMul((actor->spawnpoint->angle >> 12)<<FRACBITS, actor->scale);
|
|
||||||
|
|
||||||
spawn = P_SpawnMobj(actor->x, actor->y, actor->z, type);
|
|
||||||
P_SetScale(spawn, actor->scale);
|
|
||||||
spawn->momz = speed;
|
|
||||||
spawn->destscale = FixedDiv(spawn->scale<<FRACBITS, 100<<FRACBITS);
|
|
||||||
spawn->scalespeed = FixedDiv(((actor->spawnpoint->angle >> 8) & 63) << FRACBITS, 100<<FRACBITS);
|
|
||||||
actor->tics = actor->spawnpoint->extrainfo + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function: A_BunnyHop
|
// Function: A_BunnyHop
|
||||||
|
@ -3882,11 +3898,18 @@ void A_DropMine(mobj_t *actor)
|
||||||
void A_FishJump(mobj_t *actor)
|
void A_FishJump(mobj_t *actor)
|
||||||
{
|
{
|
||||||
INT32 locvar1 = var1;
|
INT32 locvar1 = var1;
|
||||||
|
INT32 locvar2 = var2;
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_FishJump", actor))
|
if (LUA_CallAction("A_FishJump", actor))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (locvar2)
|
||||||
|
{
|
||||||
|
fixed_t rad = actor->radius>>FRACBITS;
|
||||||
|
P_SpawnMobjFromMobj(actor, P_RandomRange(rad, -rad)<<FRACBITS, P_RandomRange(rad, -rad)<<FRACBITS, 0, (mobjtype_t)locvar2);
|
||||||
|
}
|
||||||
|
|
||||||
if ((actor->z <= actor->floorz) || (actor->z <= actor->watertop - FixedMul((64 << FRACBITS), actor->scale)))
|
if ((actor->z <= actor->floorz) || (actor->z <= actor->watertop - FixedMul((64 << FRACBITS), actor->scale)))
|
||||||
{
|
{
|
||||||
fixed_t jumpval;
|
fixed_t jumpval;
|
||||||
|
@ -9623,14 +9646,19 @@ void A_HomingChase(mobj_t *actor)
|
||||||
// lower 16 bits = object # to fire
|
// lower 16 bits = object # to fire
|
||||||
// upper 16 bits = front offset
|
// upper 16 bits = front offset
|
||||||
// var2:
|
// var2:
|
||||||
// lower 16 bits = vertical angle
|
// lower 15 bits = vertical angle variable
|
||||||
|
// 16th bit:
|
||||||
|
// - 0: use vertical angle variable as vertical angle in degrees
|
||||||
|
// - 1: mimic P_SpawnXYZMissile
|
||||||
|
// use z of actor minus z of missile as vertical distance to cover during momz calculation
|
||||||
|
// use vertical angle variable as horizontal distance to cover during momz calculation
|
||||||
// upper 16 bits = height offset
|
// upper 16 bits = height offset
|
||||||
//
|
//
|
||||||
void A_TrapShot(mobj_t *actor)
|
void A_TrapShot(mobj_t *actor)
|
||||||
{
|
{
|
||||||
INT32 locvar1 = var1;
|
INT32 locvar1 = var1;
|
||||||
INT32 locvar2 = var2;
|
INT32 locvar2 = var2;
|
||||||
angle_t vertang = FixedAngle(((INT16)(locvar2 & 65535))*FRACUNIT);
|
boolean oldstyle = (locvar2 & 32768) ? true : false;
|
||||||
mobjtype_t type = (mobjtype_t)(locvar1 & 65535);
|
mobjtype_t type = (mobjtype_t)(locvar1 & 65535);
|
||||||
mobj_t *missile;
|
mobj_t *missile;
|
||||||
INT16 frontoff = (INT16)(locvar1 >> 16);
|
INT16 frontoff = (INT16)(locvar1 >> 16);
|
||||||
|
@ -9646,10 +9674,7 @@ void A_TrapShot(mobj_t *actor)
|
||||||
y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(frontoff*FRACUNIT, actor->scale));
|
y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(frontoff*FRACUNIT, actor->scale));
|
||||||
|
|
||||||
if (actor->eflags & MFE_VERTICALFLIP)
|
if (actor->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
|
||||||
z = actor->z + actor->height - FixedMul(vertoff*FRACUNIT, actor->scale) - FixedMul(mobjinfo[type].height, actor->scale);
|
z = actor->z + actor->height - FixedMul(vertoff*FRACUNIT, actor->scale) - FixedMul(mobjinfo[type].height, actor->scale);
|
||||||
vertang = InvAngle(vertang); // flip firing angle
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
z = actor->z + FixedMul(vertoff*FRACUNIT, actor->scale);
|
z = actor->z + FixedMul(vertoff*FRACUNIT, actor->scale);
|
||||||
|
|
||||||
|
@ -9660,20 +9685,35 @@ void A_TrapShot(mobj_t *actor)
|
||||||
|
|
||||||
if (actor->eflags & MFE_VERTICALFLIP)
|
if (actor->eflags & MFE_VERTICALFLIP)
|
||||||
missile->flags2 |= MF2_OBJECTFLIP;
|
missile->flags2 |= MF2_OBJECTFLIP;
|
||||||
missile->destscale = actor->destscale;
|
|
||||||
P_SetScale(missile, missile->destscale);
|
missile->destscale = actor->scale;
|
||||||
|
P_SetScale(missile, actor->scale);
|
||||||
|
|
||||||
if (missile->info->seesound)
|
if (missile->info->seesound)
|
||||||
S_StartSound(actor, missile->info->seesound);
|
S_StartSound(missile, missile->info->seesound);
|
||||||
|
|
||||||
P_SetTarget(&missile->target, actor);
|
P_SetTarget(&missile->target, actor);
|
||||||
missile->angle = actor->angle;
|
missile->angle = actor->angle;
|
||||||
|
|
||||||
speed = FixedMul(missile->info->speed, missile->scale);
|
speed = FixedMul(missile->info->speed, missile->scale);
|
||||||
|
|
||||||
missile->momx = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(missile->angle>>ANGLETOFINESHIFT), speed));
|
if (oldstyle)
|
||||||
missile->momy = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINESINE(missile->angle>>ANGLETOFINESHIFT), speed));
|
{
|
||||||
missile->momz = FixedMul(FINESINE(vertang>>ANGLETOFINESHIFT), speed);
|
missile->momx = FixedMul(FINECOSINE(missile->angle>>ANGLETOFINESHIFT), speed);
|
||||||
|
missile->momy = FixedMul(FINESINE(missile->angle>>ANGLETOFINESHIFT), speed);
|
||||||
|
// The below line basically mimics P_SpawnXYZMissile's momz calculation.
|
||||||
|
missile->momz = (actor->z + ((actor->eflags & MFE_VERTICALFLIP) ? actor->height : 0) - z) / ((fixed_t)(locvar2 & 32767)*FRACUNIT / speed);
|
||||||
|
P_CheckMissileSpawn(missile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
angle_t vertang = FixedAngle(((INT16)(locvar2 & 32767))*FRACUNIT);
|
||||||
|
if (actor->eflags & MFE_VERTICALFLIP)
|
||||||
|
vertang = InvAngle(vertang); // flip firing angle
|
||||||
|
missile->momx = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(missile->angle>>ANGLETOFINESHIFT), speed));
|
||||||
|
missile->momy = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINESINE(missile->angle>>ANGLETOFINESHIFT), speed));
|
||||||
|
missile->momz = FixedMul(FINESINE(vertang>>ANGLETOFINESHIFT), speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function: A_VileTarget
|
// Function: A_VileTarget
|
||||||
|
@ -10735,3 +10775,32 @@ void A_FlickyFlutter(mobj_t *actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef FLICKYHITWALL
|
#undef FLICKYHITWALL
|
||||||
|
|
||||||
|
// Function: A_FlameParticle
|
||||||
|
//
|
||||||
|
// Description: Creates the mobj's painchance at a random position around the object's radius.
|
||||||
|
//
|
||||||
|
// var1 = momz of particle.
|
||||||
|
//
|
||||||
|
void A_FlameParticle(mobj_t *actor)
|
||||||
|
{
|
||||||
|
mobjtype_t type = (mobjtype_t)(mobjinfo[actor->type].painchance);
|
||||||
|
INT32 locvar1 = var1;
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUA_CallAction("A_FlameParticle", actor))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
{
|
||||||
|
fixed_t rad = 2*actor->radius>>FRACBITS;
|
||||||
|
fixed_t hei = actor->height>>FRACBITS;
|
||||||
|
mobj_t *particle = P_SpawnMobjFromMobj(actor,
|
||||||
|
P_RandomRange(rad, -rad)<<FRACBITS,
|
||||||
|
P_RandomRange(rad, -rad)<<FRACBITS,
|
||||||
|
P_RandomRange(hei/2, hei)<<FRACBITS,
|
||||||
|
type);
|
||||||
|
P_SetObjectMomZ(particle, locvar1<<FRACBITS, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
141
src/p_floor.c
141
src/p_floor.c
|
@ -13,7 +13,11 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
#include "m_random.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#ifdef ESLOPE
|
||||||
|
#include "p_slopes.h"
|
||||||
|
#endif
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
@ -1141,6 +1145,7 @@ void T_MarioBlock(levelspecthink_t *block)
|
||||||
block->sector->ceilingdata = NULL;
|
block->sector->ceilingdata = NULL;
|
||||||
block->sector->floorspeed = 0;
|
block->sector->floorspeed = 0;
|
||||||
block->sector->ceilspeed = 0;
|
block->sector->ceilspeed = 0;
|
||||||
|
block->direction = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;)
|
for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;)
|
||||||
|
@ -1800,10 +1805,24 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
|
||||||
void T_MarioBlockChecker(levelspecthink_t *block)
|
void T_MarioBlockChecker(levelspecthink_t *block)
|
||||||
{
|
{
|
||||||
line_t *masterline = block->sourceline;
|
line_t *masterline = block->sourceline;
|
||||||
|
if (block->vars[2] == 1) // Don't update the textures when the block's being bumped upwards.
|
||||||
|
return;
|
||||||
if (SearchMarioNode(block->sector->touching_thinglist))
|
if (SearchMarioNode(block->sector->touching_thinglist))
|
||||||
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture;
|
{
|
||||||
|
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures
|
||||||
|
if (masterline->backsector)
|
||||||
|
{
|
||||||
|
block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->ceilingpic; // Update flats to be backside's ceiling
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture;
|
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture;
|
||||||
|
if (masterline->backsector)
|
||||||
|
{
|
||||||
|
block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->floorpic; // Update flats to be backside's floor
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the Thwomp's 'brain'. It looks around for players nearby, and if
|
// This is the Thwomp's 'brain'. It looks around for players nearby, and if
|
||||||
|
@ -2523,6 +2542,29 @@ void T_CameraScanner(elevator_t *elevator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void T_PlaneDisplace(planedisplace_t *pd)
|
||||||
|
{
|
||||||
|
sector_t *control, *target;
|
||||||
|
INT32 direction;
|
||||||
|
fixed_t diff;
|
||||||
|
|
||||||
|
control = §ors[pd->control];
|
||||||
|
target = §ors[pd->affectee];
|
||||||
|
|
||||||
|
if (control->floorheight == pd->last_height)
|
||||||
|
return; // no change, no movement
|
||||||
|
|
||||||
|
direction = (control->floorheight > pd->last_height) ? 1 : -1;
|
||||||
|
diff = FixedMul(control->floorheight-pd->last_height, pd->speed);
|
||||||
|
|
||||||
|
if (pd->type == pd_floor || pd->type == pd_both)
|
||||||
|
T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor
|
||||||
|
if (pd->type == pd_ceiling || pd->type == pd_both)
|
||||||
|
T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, 0, 1, direction); // move ceiling
|
||||||
|
|
||||||
|
pd->last_height = control->floorheight;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// EV_DoFloor
|
// EV_DoFloor
|
||||||
//
|
//
|
||||||
|
@ -2880,18 +2922,41 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
||||||
size_t topmostvertex = 0, bottommostvertex = 0;
|
size_t topmostvertex = 0, bottommostvertex = 0;
|
||||||
fixed_t leftx, rightx;
|
fixed_t leftx, rightx;
|
||||||
fixed_t topy, bottomy;
|
fixed_t topy, bottomy;
|
||||||
fixed_t topz;
|
fixed_t topz, bottomz;
|
||||||
|
fixed_t widthfactor, heightfactor;
|
||||||
fixed_t a, b, c;
|
fixed_t a, b, c;
|
||||||
mobjtype_t type = MT_ROCKCRUMBLE1;
|
mobjtype_t type = MT_ROCKCRUMBLE1;
|
||||||
|
fixed_t spacing = (32<<FRACBITS);
|
||||||
|
tic_t lifetime = 3*TICRATE;
|
||||||
|
INT16 flags = 0;
|
||||||
|
|
||||||
// If the control sector has a special
|
#define controlsec rover->master->frontsector
|
||||||
// of Section3:7-15, use the custom debris.
|
|
||||||
if (GETSECSPECIAL(rover->master->frontsector->special, 3) >= 8)
|
if (controlsec->tag != 0)
|
||||||
type = MT_ROCKCRUMBLE1+(GETSECSPECIAL(rover->master->frontsector->special, 3)-7);
|
{
|
||||||
|
INT32 tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1);
|
||||||
|
if (tagline != -1)
|
||||||
|
{
|
||||||
|
if (sides[lines[tagline].sidenum[0]].toptexture)
|
||||||
|
type = (mobjtype_t)sides[lines[tagline].sidenum[0]].toptexture; // Set as object type in p_setup.c...
|
||||||
|
if (sides[lines[tagline].sidenum[0]].textureoffset)
|
||||||
|
spacing = sides[lines[tagline].sidenum[0]].textureoffset;
|
||||||
|
if (sides[lines[tagline].sidenum[0]].rowoffset)
|
||||||
|
{
|
||||||
|
if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS != -1)
|
||||||
|
lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS);
|
||||||
|
else
|
||||||
|
lifetime = 0;
|
||||||
|
}
|
||||||
|
flags = lines[tagline].flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef controlsec
|
||||||
|
|
||||||
// soundorg z height never gets set normally, so MEH.
|
// soundorg z height never gets set normally, so MEH.
|
||||||
sec->soundorg.z = sec->floorheight;
|
sec->soundorg.z = sec->floorheight;
|
||||||
S_StartSound(&sec->soundorg, sfx_crumbl);
|
S_StartSound(&sec->soundorg, mobjinfo[type].activesound);
|
||||||
|
|
||||||
// Find the outermost vertexes in the subsector
|
// Find the outermost vertexes in the subsector
|
||||||
for (i = 0; i < sec->linecount; i++)
|
for (i = 0; i < sec->linecount; i++)
|
||||||
|
@ -2910,23 +2975,46 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
||||||
bottommostvertex = i;
|
bottommostvertex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
leftx = sec->lines[leftmostvertex]->v1->x+(16<<FRACBITS);
|
leftx = sec->lines[leftmostvertex]->v1->x+(spacing>>1);
|
||||||
rightx = sec->lines[rightmostvertex]->v1->x;
|
rightx = sec->lines[rightmostvertex]->v1->x;
|
||||||
topy = sec->lines[topmostvertex]->v1->y-(16<<FRACBITS);
|
topy = sec->lines[topmostvertex]->v1->y-(spacing>>1);
|
||||||
bottomy = sec->lines[bottommostvertex]->v1->y;
|
bottomy = sec->lines[bottommostvertex]->v1->y;
|
||||||
topz = *rover->topheight-(16<<FRACBITS);
|
|
||||||
|
|
||||||
for (a = leftx; a < rightx; a += (32<<FRACBITS))
|
topz = *rover->topheight-(spacing>>1);
|
||||||
|
bottomz = *rover->bottomheight;
|
||||||
|
|
||||||
|
if (flags & ML_EFFECT1)
|
||||||
{
|
{
|
||||||
for (b = topy; b > bottomy; b -= (32<<FRACBITS))
|
widthfactor = (rightx + topy - leftx - bottomy)>>3;
|
||||||
|
heightfactor = (topz - *rover->bottomheight)>>2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (a = leftx; a < rightx; a += spacing)
|
||||||
|
{
|
||||||
|
for (b = topy; b > bottomy; b -= spacing)
|
||||||
{
|
{
|
||||||
if (R_PointInSubsector(a, b)->sector == sec)
|
if (R_PointInSubsector(a, b)->sector == sec)
|
||||||
{
|
{
|
||||||
mobj_t *spawned = NULL;
|
mobj_t *spawned = NULL;
|
||||||
for (c = topz; c > *rover->bottomheight; c -= (32<<FRACBITS))
|
#ifdef ESLOPE
|
||||||
|
if (*rover->t_slope)
|
||||||
|
topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1);
|
||||||
|
if (*rover->b_slope)
|
||||||
|
bottomz = P_GetZAt(*rover->b_slope, a, b);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (c = topz; c > bottomz; c -= spacing)
|
||||||
{
|
{
|
||||||
spawned = P_SpawnMobj(a, b, c, type);
|
spawned = P_SpawnMobj(a, b, c, type);
|
||||||
spawned->fuse = 3*TICRATE;
|
spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||||
|
|
||||||
|
if (flags & ML_EFFECT1)
|
||||||
|
{
|
||||||
|
P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor));
|
||||||
|
P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
spawned->fuse = lifetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3086,8 +3174,10 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mobj_t *puncher)
|
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
||||||
{
|
{
|
||||||
|
sector_t *roversec = rover->master->frontsector;
|
||||||
|
fixed_t topheight = *rover->topheight;
|
||||||
levelspecthink_t *block;
|
levelspecthink_t *block;
|
||||||
mobj_t *thing;
|
mobj_t *thing;
|
||||||
fixed_t oldx = 0, oldy = 0, oldz = 0;
|
fixed_t oldx = 0, oldy = 0, oldz = 0;
|
||||||
|
@ -3095,11 +3185,14 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
||||||
I_Assert(puncher != NULL);
|
I_Assert(puncher != NULL);
|
||||||
I_Assert(puncher->player != NULL);
|
I_Assert(puncher->player != NULL);
|
||||||
|
|
||||||
if (sec->floordata || sec->ceilingdata)
|
if (roversec->floordata || roversec->ceilingdata)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!(rover->flags & FF_SOLID))
|
||||||
|
rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL);
|
||||||
|
|
||||||
// Find an item to pop out!
|
// Find an item to pop out!
|
||||||
thing = SearchMarioNode(sec->touching_thinglist);
|
thing = SearchMarioNode(roversec->touching_thinglist);
|
||||||
|
|
||||||
// Found something!
|
// Found something!
|
||||||
if (thing)
|
if (thing)
|
||||||
|
@ -3109,13 +3202,13 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
||||||
|
|
||||||
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
|
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
|
||||||
P_AddThinker(&block->thinker);
|
P_AddThinker(&block->thinker);
|
||||||
sec->floordata = block;
|
roversec->floordata = block;
|
||||||
sec->ceilingdata = block;
|
roversec->ceilingdata = block;
|
||||||
block->thinker.function.acp1 = (actionf_p1)T_MarioBlock;
|
block->thinker.function.acp1 = (actionf_p1)T_MarioBlock;
|
||||||
|
|
||||||
// Set up the fields
|
// Set up the fields
|
||||||
block->sector = sec;
|
block->sector = roversec;
|
||||||
block->vars[0] = roversector->tag; // actionsector
|
block->vars[0] = sector->tag; // actionsector
|
||||||
block->vars[1] = 4*FRACUNIT; // speed
|
block->vars[1] = 4*FRACUNIT; // speed
|
||||||
block->vars[2] = 1; // Up // direction
|
block->vars[2] = 1; // Up // direction
|
||||||
block->vars[3] = block->sector->floorheight; // floorwasheight
|
block->vars[3] = block->sector->floorheight; // floorwasheight
|
||||||
|
@ -3131,8 +3224,8 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
||||||
}
|
}
|
||||||
|
|
||||||
P_UnsetThingPosition(thing);
|
P_UnsetThingPosition(thing);
|
||||||
thing->x = roversector->soundorg.x;
|
thing->x = sector->soundorg.x;
|
||||||
thing->y = roversector->soundorg.y;
|
thing->y = sector->soundorg.y;
|
||||||
thing->z = topheight;
|
thing->z = topheight;
|
||||||
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
|
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
|
||||||
P_SetThingPosition(thing);
|
P_SetThingPosition(thing);
|
||||||
|
@ -3149,7 +3242,7 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
||||||
{
|
{
|
||||||
if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL))
|
if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL))
|
||||||
{
|
{
|
||||||
mobj_t *tokenobj = P_SpawnMobj(roversector->soundorg.x, roversector->soundorg.y, topheight, MT_TOKEN);
|
mobj_t *tokenobj = P_SpawnMobj(sector->soundorg.x, sector->soundorg.y, topheight, MT_TOKEN);
|
||||||
P_SetTarget(&thing->tracer, tokenobj);
|
P_SetTarget(&thing->tracer, tokenobj);
|
||||||
P_SetTarget(&tokenobj->target, thing);
|
P_SetTarget(&tokenobj->target, thing);
|
||||||
P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate);
|
P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate);
|
||||||
|
|
|
@ -1174,15 +1174,33 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
// Mario //
|
// Mario //
|
||||||
// ***** //
|
// ***** //
|
||||||
case MT_SHELL:
|
case MT_SHELL:
|
||||||
if (special->state == &states[S_SHELL]) // Resting anim
|
|
||||||
{
|
{
|
||||||
// Kick that sucker around!
|
boolean bounceon = ((P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0));
|
||||||
special->angle = toucher->angle;
|
if (special->threshold == TICRATE) // it's moving
|
||||||
P_InstaThrust(special, special->angle, FixedMul(special->info->speed, special->scale));
|
{
|
||||||
S_StartSound(toucher, sfx_mario2);
|
if (bounceon)
|
||||||
P_SetMobjState(special, S_SHELL1);
|
{
|
||||||
P_SetTarget(&special->target, toucher);
|
// Stop it!
|
||||||
special->threshold = (3*TICRATE)/2;
|
special->momx = special->momy = 0;
|
||||||
|
S_StartSound(toucher, sfx_mario2);
|
||||||
|
P_SetTarget(&special->target, NULL);
|
||||||
|
special->threshold = TICRATE - 1;
|
||||||
|
toucher->momz = -toucher->momz;
|
||||||
|
}
|
||||||
|
else // can't handle in PIT_CheckThing because of landing-on causing it to stop
|
||||||
|
P_DamageMobj(toucher, special, special->target, 1, 0);
|
||||||
|
}
|
||||||
|
else if (special->threshold == 0)
|
||||||
|
{
|
||||||
|
// Kick that sucker around!
|
||||||
|
special->movedir = ((special->movedir == 1) ? -1 : 1);
|
||||||
|
P_InstaThrust(special, toucher->angle, (special->info->speed*special->scale));
|
||||||
|
S_StartSound(toucher, sfx_mario2);
|
||||||
|
P_SetTarget(&special->target, toucher);
|
||||||
|
special->threshold = (3*TICRATE)/2;
|
||||||
|
if (bounceon)
|
||||||
|
toucher->momz = -toucher->momz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case MT_AXE:
|
case MT_AXE:
|
||||||
|
@ -1792,7 +1810,7 @@ void P_CheckTimeLimit(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Tagmode round end but only on the tic before the
|
//Tagmode round end but only on the tic before the
|
||||||
//XD_EXITLEVEL packet is recieved by all players.
|
//XD_EXITLEVEL packet is received by all players.
|
||||||
if (G_TagGametype())
|
if (G_TagGametype())
|
||||||
{
|
{
|
||||||
if (leveltime == (timelimitintics + 1))
|
if (leveltime == (timelimitintics + 1))
|
||||||
|
@ -1803,7 +1821,7 @@ void P_CheckTimeLimit(void)
|
||||||
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
|
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]);
|
CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]);
|
||||||
P_AddPlayerScore(&players[i], players[i].score);
|
P_AddPlayerScore(&players[i], players[i].score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -768,8 +768,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmthing->type == MT_SHELL && tmthing->threshold > TICRATE)
|
|
||||||
return true;
|
|
||||||
// damage / explode
|
// damage / explode
|
||||||
if (tmthing->flags & MF_ENEMY) // An actual ENEMY! (Like the deton, for example)
|
if (tmthing->flags & MF_ENEMY) // An actual ENEMY! (Like the deton, for example)
|
||||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||||
|
@ -810,7 +808,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
tmthing->y = thing->y;
|
tmthing->y = thing->y;
|
||||||
P_SetThingPosition(tmthing);
|
P_SetThingPosition(tmthing);
|
||||||
}
|
}
|
||||||
else
|
else if (!(tmthing->type == MT_SHELL && thing->player)) // player collision handled in touchspecial
|
||||||
P_DamageMobj(thing, tmthing, tmthing->target, 1, 0);
|
P_DamageMobj(thing, tmthing, tmthing->target, 1, 0);
|
||||||
|
|
||||||
// don't traverse any more
|
// don't traverse any more
|
||||||
|
@ -1145,7 +1143,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tmfloorz = tmceilingz = INT32_MIN; // block while in air
|
tmfloorz = tmceilingz = topz; // block while in air
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = NULL;
|
tmceilingslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1191,7 +1189,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tmfloorz = tmceilingz = INT32_MAX; // block while in air
|
tmfloorz = tmceilingz = topz; // block while in air
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = NULL;
|
tmfloorslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
163
src/p_mobj.c
163
src/p_mobj.c
|
@ -564,7 +564,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
||||||
// Adjust the player's animation speed to match their velocity.
|
// Adjust the player's animation speed to match their velocity.
|
||||||
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
|
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
|
||||||
{
|
{
|
||||||
fixed_t speed;// = FixedDiv(player->speed, mobj->scale);
|
fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
|
||||||
if (player->panim == PA_FALL)
|
if (player->panim == PA_FALL)
|
||||||
{
|
{
|
||||||
speed = FixedDiv(abs(mobj->momz), mobj->scale);
|
speed = FixedDiv(abs(mobj->momz), mobj->scale);
|
||||||
|
@ -590,7 +590,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
speed = FixedDiv(player->speed, mobj->scale);
|
speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
|
||||||
if (player->panim == PA_ROLL || player->panim == PA_JUMP)
|
if (player->panim == PA_ROLL || player->panim == PA_JUMP)
|
||||||
{
|
{
|
||||||
if (speed > 16<<FRACBITS)
|
if (speed > 16<<FRACBITS)
|
||||||
|
@ -1135,9 +1135,6 @@ void P_ExplodeMissile(mobj_t *mo)
|
||||||
explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
|
explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
|
||||||
explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
|
explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
|
||||||
S_StartSound(explodemo, sfx_cybdth);
|
S_StartSound(explodemo, sfx_cybdth);
|
||||||
|
|
||||||
// Hack: Release an animal.
|
|
||||||
P_DamageMobj(mo, NULL, NULL, 1, DMG_INSTAKILL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mo->flags &= ~MF_MISSILE;
|
mo->flags &= ~MF_MISSILE;
|
||||||
|
@ -1845,7 +1842,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STOPSPEED (FRACUNIT)
|
#define STOPSPEED (FRACUNIT)
|
||||||
#define FRICTION (ORIG_FRICTION) // 0.90625
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_SceneryXYFriction
|
// P_SceneryXYFriction
|
||||||
|
@ -1878,7 +1874,6 @@ static void P_SceneryXYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
||||||
{
|
{
|
||||||
// Stolen from P_SpawnFriction
|
// Stolen from P_SpawnFriction
|
||||||
mo->friction = FRACUNIT - 0x100;
|
mo->friction = FRACUNIT - 0x100;
|
||||||
mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mo->friction = ORIG_FRICTION;
|
mo->friction = ORIG_FRICTION;
|
||||||
|
@ -1903,7 +1898,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
||||||
// spinning friction
|
// spinning friction
|
||||||
if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH))
|
if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH))
|
||||||
{
|
{
|
||||||
const fixed_t ns = FixedDiv(549*FRICTION,500*FRACUNIT);
|
const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT);
|
||||||
mo->momx = FixedMul(mo->momx, ns);
|
mo->momx = FixedMul(mo->momx, ns);
|
||||||
mo->momy = FixedMul(mo->momy, ns);
|
mo->momy = FixedMul(mo->momy, ns);
|
||||||
}
|
}
|
||||||
|
@ -2181,8 +2176,39 @@ void P_XYMovement(mobj_t *mo)
|
||||||
}
|
}
|
||||||
else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE))
|
else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE))
|
||||||
{ // try to slide along it
|
{ // try to slide along it
|
||||||
|
#ifdef ESLOPE
|
||||||
|
// Wall transfer part 1.
|
||||||
|
pslope_t *transferslope = NULL;
|
||||||
|
fixed_t transfermomz = 0;
|
||||||
|
if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls
|
||||||
|
{
|
||||||
|
transferslope = ((mo->standingslope) ? mo->standingslope : oldslope);
|
||||||
|
if (((transferslope->zangle < ANGLE_180) ? transferslope->zangle : InvAngle(transferslope->zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes.
|
||||||
|
transfermomz = P_GetWallTransferMomZ(mo, transferslope);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
P_SlideMove(mo);
|
P_SlideMove(mo);
|
||||||
xmove = ymove = 0;
|
xmove = ymove = 0;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
// Wall transfer part 2.
|
||||||
|
if (transfermomz && transferslope) // Are we "transferring onto the wall" (really just a disguised vertical launch)?
|
||||||
|
{
|
||||||
|
angle_t relation; // Scale transfer momentum based on how head-on it is to the slope.
|
||||||
|
if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum
|
||||||
|
relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||||
|
else // Give it for free, I guess.
|
||||||
|
relation = ANGLE_90;
|
||||||
|
transfermomz = FixedMul(transfermomz,
|
||||||
|
abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK)));
|
||||||
|
if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch!
|
||||||
|
{
|
||||||
|
mo->momz = transfermomz;
|
||||||
|
mo->standingslope = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (mo->type == MT_SPINFIRE)
|
else if (mo->type == MT_SPINFIRE)
|
||||||
{
|
{
|
||||||
|
@ -2412,14 +2438,16 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
||||||
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||||
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||||
|
|
||||||
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected
|
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should stand on lava or run on water
|
||||||
;
|
;
|
||||||
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
||||||
continue;
|
continue;
|
||||||
else if (rover->flags & FF_QUICKSAND) // quicksand
|
else if (rover->flags & FF_QUICKSAND) // quicksand
|
||||||
;
|
;
|
||||||
else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players?
|
else if (!( // if it's not either of the following...
|
||||||
|| (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others?
|
(rover->flags & (FF_BLOCKPLAYER|FF_MARIO) && mo->player) // ...solid to players? (mario blocks are always solid from beneath to players)
|
||||||
|
|| (rover->flags & FF_BLOCKOTHERS && !mo->player) // ...solid to others?
|
||||||
|
)) // ...don't take it into account.
|
||||||
continue;
|
continue;
|
||||||
if (rover->flags & FF_QUICKSAND)
|
if (rover->flags & FF_QUICKSAND)
|
||||||
{
|
{
|
||||||
|
@ -2444,7 +2472,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
||||||
|
|
||||||
delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
|
delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
|
||||||
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
|
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
|
||||||
|
|
||||||
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
|
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
|
||||||
|
&& (rover->flags & FF_SOLID) // Non-FF_SOLID Mario blocks are only solid from bottom
|
||||||
&& !(rover->flags & FF_REVERSEPLATFORM)
|
&& !(rover->flags & FF_REVERSEPLATFORM)
|
||||||
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
|
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
|
||||||
{
|
{
|
||||||
|
@ -2452,7 +2482,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
||||||
}
|
}
|
||||||
if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
|
if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
|
||||||
&& !(rover->flags & FF_PLATFORM)
|
&& !(rover->flags & FF_PLATFORM)
|
||||||
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
|
&& ((P_MobjFlip(mo)*mo->momz >= 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
|
||||||
{
|
{
|
||||||
mo->ceilingz = bottomheight;
|
mo->ceilingz = bottomheight;
|
||||||
}
|
}
|
||||||
|
@ -2937,7 +2967,6 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||||
|
|
||||||
// Stolen from P_SpawnFriction
|
// Stolen from P_SpawnFriction
|
||||||
mo->friction = FRACUNIT - 0x100;
|
mo->friction = FRACUNIT - 0x100;
|
||||||
mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158;
|
|
||||||
}
|
}
|
||||||
else if (mo->type == MT_FALLINGROCK)
|
else if (mo->type == MT_FALLINGROCK)
|
||||||
{
|
{
|
||||||
|
@ -3392,8 +3421,13 @@ nightsdone:
|
||||||
if (rover->flags & FF_MARIO
|
if (rover->flags & FF_MARIO
|
||||||
&& !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it?
|
&& !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it?
|
||||||
&& *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom!
|
&& *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom!
|
||||||
|
{
|
||||||
// DO THE MARIO!
|
// DO THE MARIO!
|
||||||
EV_MarioBlock(rover->master->frontsector, node->m_sector, *rover->topheight, mo);
|
if (rover->flags & FF_SHATTERBOTTOM) // Brick block!
|
||||||
|
EV_CrumbleChain(node->m_sector, rover);
|
||||||
|
else // Question block!
|
||||||
|
EV_MarioBlock(rover, node->m_sector, mo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // Ugly ugly billions of braces! Argh!
|
} // Ugly ugly billions of braces! Argh!
|
||||||
}
|
}
|
||||||
|
@ -4554,7 +4588,15 @@ static void P_Boss1Thinker(mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT && !(mobj->flags2 & MF2_SKULLFLY))
|
if (mobj->flags2 & MF2_SKULLFLY)
|
||||||
|
{
|
||||||
|
fixed_t dist = (mobj->eflags & MFE_VERTICALFLIP)
|
||||||
|
? ((mobj->ceilingz-(2*mobj->height)) - (mobj->z+mobj->height))
|
||||||
|
: (mobj->z - (mobj->floorz+(2*mobj->height)));
|
||||||
|
if (dist > 0 && P_MobjFlip(mobj)*mobj->momz > 0)
|
||||||
|
mobj->momz = FixedMul(mobj->momz, FRACUNIT - (dist>>12));
|
||||||
|
}
|
||||||
|
else if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT)
|
||||||
mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8);
|
mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8);
|
||||||
|
|
||||||
if (mobj->state == &states[mobj->info->meleestate]
|
if (mobj->state == &states[mobj->info->meleestate]
|
||||||
|
@ -6723,7 +6765,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||||
&& (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2)
|
&& (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2)
|
||||||
// fade out when nearing the end of fuse...
|
// fade out when nearing the end of fuse...
|
||||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
||||||
|
@ -7680,13 +7722,13 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
P_NightsItemChase(mobj);
|
P_NightsItemChase(mobj);
|
||||||
break;
|
break;
|
||||||
case MT_SHELL:
|
case MT_SHELL:
|
||||||
if (mobj->threshold > TICRATE)
|
if (mobj->threshold && mobj->threshold != TICRATE)
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
|
|
||||||
if (mobj->state != &states[S_SHELL])
|
if (mobj->threshold >= TICRATE)
|
||||||
{
|
{
|
||||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
mobj->angle += ((mobj->movedir == 1) ? ANGLE_22h : ANGLE_337h);
|
||||||
P_InstaThrust(mobj, mobj->angle, FixedMul(mobj->info->speed, mobj->scale));
|
P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), (mobj->info->speed*mobj->scale));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_TURRET:
|
case MT_TURRET:
|
||||||
|
@ -8258,7 +8300,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
|
|
||||||
mobj->friction = ORIG_FRICTION;
|
mobj->friction = ORIG_FRICTION;
|
||||||
|
|
||||||
mobj->movefactor = ORIG_FRICTION_FACTOR;
|
mobj->movefactor = FRACUNIT;
|
||||||
|
|
||||||
// All mobjs are created at 100% scale.
|
// All mobjs are created at 100% scale.
|
||||||
mobj->scale = FRACUNIT;
|
mobj->scale = FRACUNIT;
|
||||||
|
@ -9769,6 +9811,85 @@ ML_NOCLIMB : Direction not controllable
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_PARTICLEGEN:
|
||||||
|
{
|
||||||
|
fixed_t radius, speed, bottomheight, topheight;
|
||||||
|
INT32 type, numdivisions, time, anglespeed;
|
||||||
|
angle_t angledivision;
|
||||||
|
size_t line;
|
||||||
|
const size_t mthingi = (size_t)(mthing - mapthings);
|
||||||
|
|
||||||
|
for (line = 0; line < numlines; line++)
|
||||||
|
{
|
||||||
|
if (lines[line].special == 15 && lines[line].tag == mthing->angle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line == numlines)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sides[lines[line].sidenum[0]].toptexture)
|
||||||
|
type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c...
|
||||||
|
else
|
||||||
|
type = (INT32)MT_PARTICLE;
|
||||||
|
|
||||||
|
speed = abs(sides[lines[line].sidenum[0]].textureoffset);
|
||||||
|
bottomheight = lines[line].frontsector->floorheight;
|
||||||
|
topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height;
|
||||||
|
|
||||||
|
numdivisions = (mthing->options >> ZSHIFT);
|
||||||
|
|
||||||
|
if (numdivisions)
|
||||||
|
{
|
||||||
|
radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y);
|
||||||
|
anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360;
|
||||||
|
angledivision = 360/numdivisions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler.
|
||||||
|
radius = 0;
|
||||||
|
anglespeed = 0;
|
||||||
|
angledivision = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((speed) && (topheight > bottomheight))
|
||||||
|
time = (INT32)(FixedDiv((topheight - bottomheight), speed) >> FRACBITS);
|
||||||
|
else
|
||||||
|
time = 1; // There's no reasonable way to set it, so just show the object for one tic and move on.
|
||||||
|
|
||||||
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
|
{
|
||||||
|
mobj->z = topheight;
|
||||||
|
speed *= -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mobj->z = bottomheight;
|
||||||
|
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n"
|
||||||
|
"Radius is %d\n"
|
||||||
|
"Speed is %d\n"
|
||||||
|
"Anglespeed is %d\n"
|
||||||
|
"Numdivisions is %d\n"
|
||||||
|
"Angledivision is %d\n"
|
||||||
|
"Time is %d\n"
|
||||||
|
"Type is %d\n",
|
||||||
|
sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, time, type);
|
||||||
|
|
||||||
|
mobj->angle = 0;
|
||||||
|
mobj->movefactor = speed;
|
||||||
|
mobj->lastlook = numdivisions;
|
||||||
|
mobj->movedir = angledivision*ANG1;
|
||||||
|
mobj->movecount = anglespeed*ANG1;
|
||||||
|
mobj->health = time;
|
||||||
|
mobj->friction = radius;
|
||||||
|
mobj->threshold = type;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MT_ROCKSPAWNER:
|
case MT_ROCKSPAWNER:
|
||||||
mobj->threshold = mthing->angle;
|
mobj->threshold = mthing->angle;
|
||||||
mobj->movecount = mthing->extrainfo;
|
mobj->movecount = mthing->extrainfo;
|
||||||
|
|
|
@ -974,6 +974,7 @@ typedef enum
|
||||||
tc_noenemies,
|
tc_noenemies,
|
||||||
tc_eachtime,
|
tc_eachtime,
|
||||||
tc_disappear,
|
tc_disappear,
|
||||||
|
tc_planedisplace,
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
||||||
tc_polymove,
|
tc_polymove,
|
||||||
|
@ -1097,7 +1098,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
diff |= MD_TRACER;
|
diff |= MD_TRACER;
|
||||||
if (mobj->friction != ORIG_FRICTION)
|
if (mobj->friction != ORIG_FRICTION)
|
||||||
diff |= MD_FRICTION;
|
diff |= MD_FRICTION;
|
||||||
if (mobj->movefactor != ORIG_FRICTION_FACTOR)
|
if (mobj->movefactor != FRACUNIT)
|
||||||
diff |= MD_MOVEFACTOR;
|
diff |= MD_MOVEFACTOR;
|
||||||
if (mobj->fuse)
|
if (mobj->fuse)
|
||||||
diff |= MD_FUSE;
|
diff |= MD_FUSE;
|
||||||
|
@ -1537,6 +1538,21 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEINT32(save_p, ht->exists);
|
WRITEINT32(save_p, ht->exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SavePlaneDisplaceThinker
|
||||||
|
//
|
||||||
|
// Saves a planedisplace_t thinker
|
||||||
|
//
|
||||||
|
static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const planedisplace_t *ht = (const void *)th;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEINT32(save_p, ht->affectee);
|
||||||
|
WRITEINT32(save_p, ht->control);
|
||||||
|
WRITEFIXED(save_p, ht->last_height);
|
||||||
|
WRITEFIXED(save_p, ht->speed);
|
||||||
|
WRITEUINT8(save_p, ht->type);
|
||||||
|
}
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1818,6 +1834,12 @@ static void P_NetArchiveThinkers(void)
|
||||||
SaveDisappearThinker(th, tc_disappear);
|
SaveDisappearThinker(th, tc_disappear);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
|
||||||
|
{
|
||||||
|
SavePlaneDisplaceThinker(th, tc_planedisplace);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
|
||||||
{
|
{
|
||||||
|
@ -2083,7 +2105,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
if (diff & MD_MOVEFACTOR)
|
if (diff & MD_MOVEFACTOR)
|
||||||
mobj->movefactor = READFIXED(save_p);
|
mobj->movefactor = READFIXED(save_p);
|
||||||
else
|
else
|
||||||
mobj->movefactor = ORIG_FRICTION_FACTOR;
|
mobj->movefactor = FRACUNIT;
|
||||||
if (diff & MD_FUSE)
|
if (diff & MD_FUSE)
|
||||||
mobj->fuse = READINT32(save_p);
|
mobj->fuse = READINT32(save_p);
|
||||||
if (diff & MD_WATERTOP)
|
if (diff & MD_WATERTOP)
|
||||||
|
@ -2486,6 +2508,23 @@ static inline void LoadDisappearThinker(actionf_p1 thinker)
|
||||||
P_AddThinker(&ht->thinker);
|
P_AddThinker(&ht->thinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LoadPlaneDisplaceThinker
|
||||||
|
//
|
||||||
|
// Loads a planedisplace_t thinker
|
||||||
|
//
|
||||||
|
static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->affectee = READINT32(save_p);
|
||||||
|
ht->control = READINT32(save_p);
|
||||||
|
ht->last_height = READFIXED(save_p);
|
||||||
|
ht->speed = READFIXED(save_p);
|
||||||
|
ht->type = READUINT8(save_p);
|
||||||
|
P_AddThinker(&ht->thinker);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2769,6 +2808,10 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
case tc_disappear:
|
case tc_disappear:
|
||||||
LoadDisappearThinker((actionf_p1)T_Disappear);
|
LoadDisappearThinker((actionf_p1)T_Disappear);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_planedisplace:
|
||||||
|
LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
||||||
|
break;
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
case tc_polyrotate:
|
case tc_polyrotate:
|
||||||
LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);
|
LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);
|
||||||
|
|
|
@ -1562,6 +1562,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
sd->text[6] = 0;
|
sd->text[6] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 4: // Speed pad parameters
|
||||||
case 414: // Play SFX
|
case 414: // Play SFX
|
||||||
{
|
{
|
||||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||||
|
@ -1575,6 +1577,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 14: // Bustable block parameters
|
||||||
|
case 15: // Fan particle spawner parameters
|
||||||
case 425: // Calls P_SetMobjState on calling mobj
|
case 425: // Calls P_SetMobjState on calling mobj
|
||||||
case 434: // Custom Power
|
case 434: // Custom Power
|
||||||
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
||||||
|
|
|
@ -804,6 +804,39 @@ void P_SlopeLaunch(mobj_t *mo)
|
||||||
mo->standingslope = NULL;
|
mo->standingslope = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_GetWallTransferMomZ
|
||||||
|
//
|
||||||
|
// It would be nice to have a single function that does everything necessary for slope-to-wall transfer.
|
||||||
|
// However, it needs to be seperated out in P_XYMovement to take into account momentum before and after hitting the wall.
|
||||||
|
// This just performs the necessary calculations for getting the base vertical momentum; the horizontal is already reasonably calculated by P_SlideMove.
|
||||||
|
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
||||||
|
{
|
||||||
|
vector3_t slopemom, axis;
|
||||||
|
angle_t ang;
|
||||||
|
|
||||||
|
if (mo->standingslope->flags & SL_NOPHYSICS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If there's physics, time for launching.
|
||||||
|
// Doesn't kill the vertical momentum as much as P_SlopeLaunch does.
|
||||||
|
ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1);
|
||||||
|
if (ang > ANGLE_90 && ang < ANGLE_180)
|
||||||
|
ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
|
||||||
|
|
||||||
|
slopemom.x = mo->momx;
|
||||||
|
slopemom.y = mo->momy;
|
||||||
|
slopemom.z = 3*(mo->momz/2);
|
||||||
|
|
||||||
|
axis.x = -slope->d.y;
|
||||||
|
axis.y = slope->d.x;
|
||||||
|
axis.z = 0;
|
||||||
|
|
||||||
|
FV3_Rotate(&slopemom, &axis, ang >> ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
return 2*(slopemom.z/3);
|
||||||
|
}
|
||||||
|
|
||||||
// Function to help handle landing on slopes
|
// Function to help handle landing on slopes
|
||||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
|
||||||
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||||
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||||
void P_SlopeLaunch(mobj_t *mo);
|
void P_SlopeLaunch(mobj_t *mo);
|
||||||
|
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope);
|
||||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
|
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
|
||||||
void P_ButteredSlope(mobj_t *mo);
|
void P_ButteredSlope(mobj_t *mo);
|
||||||
|
|
||||||
|
|
340
src/p_spec.c
340
src/p_spec.c
|
@ -51,6 +51,9 @@ mobj_t *skyboxmo[2];
|
||||||
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
|
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
|
||||||
#define SCROLL_SHIFT 5
|
#define SCROLL_SHIFT 5
|
||||||
|
|
||||||
|
// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize.
|
||||||
|
#define MAXFLATSIZE (2048<<FRACBITS)
|
||||||
|
|
||||||
/** Animated texture descriptor
|
/** Animated texture descriptor
|
||||||
* This keeps track of an animated texture or an animated flat.
|
* This keeps track of an animated texture or an animated flat.
|
||||||
* \sa P_UpdateSpecials, P_InitPicAnims, animdef_t
|
* \sa P_UpdateSpecials, P_InitPicAnims, animdef_t
|
||||||
|
@ -108,6 +111,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker
|
||||||
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
||||||
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
||||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
|
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
|
||||||
|
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee);
|
||||||
|
|
||||||
|
|
||||||
//SoM: 3/7/2000: New sturcture without limits.
|
//SoM: 3/7/2000: New sturcture without limits.
|
||||||
|
@ -2440,7 +2444,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||||
{
|
{
|
||||||
fixed_t sfxnum;
|
fixed_t sfxnum;
|
||||||
|
|
||||||
sfxnum = sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
|
sfxnum = sides[line->sidenum[0]].toptexture;
|
||||||
|
|
||||||
if (line->tag != 0 && line->flags & ML_EFFECT5)
|
if (line->tag != 0 && line->flags & ML_EFFECT5)
|
||||||
{
|
{
|
||||||
|
@ -3683,14 +3687,13 @@ DoneSection2:
|
||||||
// Process Section 3
|
// Process Section 3
|
||||||
switch (special)
|
switch (special)
|
||||||
{
|
{
|
||||||
case 1: // Ice/Sludge
|
case 1: // Unused
|
||||||
case 2: // Wind/Current
|
case 2: // Wind/Current
|
||||||
case 3: // Ice/Sludge and Wind/Current
|
case 3: // Unused
|
||||||
case 4: // Conveyor Belt
|
case 4: // Conveyor Belt
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // Speed pad w/o spin
|
case 5: // Speed pad
|
||||||
case 6: // Speed pad w/ spin
|
|
||||||
if (player->powers[pw_flashing] != 0 && player->powers[pw_flashing] < TICRATE/2)
|
if (player->powers[pw_flashing] != 0 && player->powers[pw_flashing] < TICRATE/2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3700,9 +3703,16 @@ DoneSection2:
|
||||||
{
|
{
|
||||||
angle_t lineangle;
|
angle_t lineangle;
|
||||||
fixed_t linespeed;
|
fixed_t linespeed;
|
||||||
|
fixed_t sfxnum;
|
||||||
|
|
||||||
lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
||||||
linespeed = P_AproxDistance(lines[i].v2->x-lines[i].v1->x, lines[i].v2->y-lines[i].v1->y);
|
linespeed = sides[lines[i].sidenum[0]].textureoffset;
|
||||||
|
|
||||||
|
if (linespeed == 0)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sector->tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
player->mo->angle = lineangle;
|
player->mo->angle = lineangle;
|
||||||
|
|
||||||
|
@ -3732,7 +3742,7 @@ DoneSection2:
|
||||||
|
|
||||||
P_InstaThrust(player->mo, player->mo->angle, linespeed);
|
P_InstaThrust(player->mo, player->mo->angle, linespeed);
|
||||||
|
|
||||||
if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH))
|
if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll!
|
||||||
{
|
{
|
||||||
if (!(player->pflags & PF_SPINNING))
|
if (!(player->pflags & PF_SPINNING))
|
||||||
player->pflags |= PF_SPINNING;
|
player->pflags |= PF_SPINNING;
|
||||||
|
@ -3741,19 +3751,26 @@ DoneSection2:
|
||||||
}
|
}
|
||||||
|
|
||||||
player->powers[pw_flashing] = TICRATE/3;
|
player->powers[pw_flashing] = TICRATE/3;
|
||||||
S_StartSound(player->mo, sfx_spdpad);
|
|
||||||
|
sfxnum = sides[lines[i].sidenum[0]].toptexture;
|
||||||
|
|
||||||
|
if (!sfxnum)
|
||||||
|
sfxnum = sfx_spdpad;
|
||||||
|
|
||||||
|
S_StartSound(player->mo, sfxnum);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // Bustable block sprite parameter
|
case 6: // Unused
|
||||||
case 8:
|
case 7: // Unused
|
||||||
case 9:
|
case 8: // Unused
|
||||||
case 10:
|
case 9: // Unused
|
||||||
case 11:
|
case 10: // Unused
|
||||||
case 12:
|
case 11: // Unused
|
||||||
case 13:
|
case 12: // Unused
|
||||||
case 14:
|
case 13: // Unused
|
||||||
case 15:
|
case 14: // Unused
|
||||||
|
case 15: // Unused
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3923,8 +3940,14 @@ DoneSection2:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab speed and sequence values
|
// Grab speed and sequence values
|
||||||
speed = abs(lines[lineindex].dx)/8;
|
speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8;
|
||||||
sequence = abs(lines[lineindex].dy)>>FRACBITS;
|
sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS;
|
||||||
|
|
||||||
|
if (speed == 0)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// scan the thinkers
|
// scan the thinkers
|
||||||
// to find the first waypoint
|
// to find the first waypoint
|
||||||
|
@ -3996,8 +4019,14 @@ DoneSection2:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab speed and sequence values
|
// Grab speed and sequence values
|
||||||
speed = -(abs(lines[lineindex].dx)/8); // Negative means reverse
|
speed = -abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; // Negative means reverse
|
||||||
sequence = abs(lines[lineindex].dy)>>FRACBITS;
|
sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS;
|
||||||
|
|
||||||
|
if (speed == 0)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// scan the thinkers
|
// scan the thinkers
|
||||||
// to find the last waypoint
|
// to find the last waypoint
|
||||||
|
@ -4037,6 +4066,7 @@ DoneSection2:
|
||||||
player->speed = speed;
|
player->speed = speed;
|
||||||
player->pflags |= PF_SPINNING;
|
player->pflags |= PF_SPINNING;
|
||||||
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||||
|
player->climbing = 0;
|
||||||
|
|
||||||
if (player->mo->state-states != S_PLAY_SPIN)
|
if (player->mo->state-states != S_PLAY_SPIN)
|
||||||
{
|
{
|
||||||
|
@ -4135,8 +4165,14 @@ DoneSection2:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab speed and sequence values
|
// Grab speed and sequence values
|
||||||
speed = abs(lines[lineindex].dx)/8;
|
speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8;
|
||||||
sequence = abs(lines[lineindex].dy)>>FRACBITS;
|
sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS;
|
||||||
|
|
||||||
|
if (speed == 0)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Find the closest waypoint
|
// Find the closest waypoint
|
||||||
// Find the preceding waypoint
|
// Find the preceding waypoint
|
||||||
|
@ -4983,7 +5019,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
||||||
|
|
||||||
if ((flags & FF_MARIO))
|
if ((flags & FF_MARIO))
|
||||||
{
|
{
|
||||||
P_AddBlockThinker(sec2, master);
|
if (!(flags & FF_SHATTERBOTTOM)) // Don't change the textures of a brick block, just a question block
|
||||||
|
P_AddBlockThinker(sec2, master);
|
||||||
CheckForMarioBlocks = true;
|
CheckForMarioBlocks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5083,6 +5120,33 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a plane displacement thinker.
|
||||||
|
* Whenever the "control" sector moves,
|
||||||
|
* the "affectee" sector's floor or ceiling plane moves too!
|
||||||
|
*
|
||||||
|
* \param speed Rate of movement relative to control sector
|
||||||
|
* \param control Control sector.
|
||||||
|
* \param affectee Target sector.
|
||||||
|
* \sa P_SpawnSpecials, T_PlaneDisplace
|
||||||
|
* \author Monster Iestyn
|
||||||
|
*/
|
||||||
|
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee)
|
||||||
|
{
|
||||||
|
planedisplace_t *displace;
|
||||||
|
|
||||||
|
// create and initialize new displacement thinker
|
||||||
|
displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL);
|
||||||
|
P_AddThinker(&displace->thinker);
|
||||||
|
|
||||||
|
displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace;
|
||||||
|
displace->affectee = affectee;
|
||||||
|
displace->control = control;
|
||||||
|
displace->last_height = sectors[control].floorheight;
|
||||||
|
displace->speed = speed;
|
||||||
|
displace->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
/** Adds a Mario block thinker, which changes the block's texture between blank
|
/** Adds a Mario block thinker, which changes the block's texture between blank
|
||||||
* and ? depending on whether it has contents.
|
* and ? depending on whether it has contents.
|
||||||
* Needed in case objects respawn inside.
|
* Needed in case objects respawn inside.
|
||||||
|
@ -5321,7 +5385,7 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto
|
||||||
elevator->distance = FixedInt(AngleFixed(angle));
|
elevator->distance = FixedInt(AngleFixed(angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA;
|
static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT;
|
||||||
|
|
||||||
/** Flashes a laser block.
|
/** Flashes a laser block.
|
||||||
*
|
*
|
||||||
|
@ -5341,10 +5405,12 @@ void T_LaserFlash(laserthink_t *flash)
|
||||||
if (!ffloor || !(ffloor->flags & FF_EXISTS))
|
if (!ffloor || !(ffloor->flags & FF_EXISTS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (leveltime & 1)
|
if (leveltime & 2)
|
||||||
ffloor->flags |= FF_RENDERALL;
|
//ffloor->flags |= FF_RENDERALL;
|
||||||
|
ffloor->alpha = 0xB0;
|
||||||
else
|
else
|
||||||
ffloor->flags &= ~FF_RENDERALL;
|
//ffloor->flags &= ~FF_RENDERALL;
|
||||||
|
ffloor->alpha = 0x90;
|
||||||
|
|
||||||
sourcesec = ffloor->master->frontsector; // Less to type!
|
sourcesec = ffloor->master->frontsector; // Less to type!
|
||||||
|
|
||||||
|
@ -5572,32 +5638,27 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
// Init line EFFECTs
|
// Init line EFFECTs
|
||||||
for (i = 0; i < numlines; i++)
|
for (i = 0; i < numlines; i++)
|
||||||
{
|
{
|
||||||
// set line specials to 0 here too, same reason as above
|
if (lines[i].special != 7) // This is a hack. I can at least hope nobody wants to prevent flat alignment with arbitrary skin setups...
|
||||||
if (netgame || multiplayer)
|
|
||||||
{
|
{
|
||||||
// future: nonet flag?
|
// set line specials to 0 here too, same reason as above
|
||||||
}
|
if (netgame || multiplayer)
|
||||||
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
{
|
||||||
{
|
// future: nonet flag?
|
||||||
lines[i].special = 0;
|
}
|
||||||
continue;
|
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
|
||||||
{
|
{
|
||||||
lines[i].special = 0;
|
lines[i].special = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
else
|
||||||
{
|
{
|
||||||
lines[i].special = 0;
|
if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||||
continue;
|
|| (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||||
}
|
|| (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX)))
|
||||||
if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
|
{
|
||||||
{
|
lines[i].special = 0;
|
||||||
lines[i].special = 0;
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5643,47 +5704,53 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 7: // Flat alignment
|
case 7: // Flat alignment - redone by toast
|
||||||
if (lines[i].flags & ML_EFFECT4) // Align angle
|
if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something...
|
||||||
{
|
{
|
||||||
if (!(lines[i].flags & ML_EFFECT5)) // Align floor unless ALLTRIGGER flag is set
|
angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y));
|
||||||
|
fixed_t xoffs;
|
||||||
|
fixed_t yoffs;
|
||||||
|
|
||||||
|
if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set
|
||||||
{
|
{
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
xoffs = sides[lines[i].sidenum[0]].textureoffset;
|
||||||
sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
yoffs = sides[lines[i].sidenum[0]].rowoffset;
|
||||||
|
}
|
||||||
|
else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
|
||||||
|
{
|
||||||
|
fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT);
|
||||||
|
xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations.
|
||||||
|
yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(lines[i].flags & ML_BOUNCY)) // Align ceiling unless BOUNCY flag is set
|
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||||
{
|
{
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set
|
||||||
sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Do offsets
|
|
||||||
{
|
|
||||||
if (!(lines[i].flags & ML_BLOCKMONSTERS)) // Align floor unless BLOCKMONSTERS flag is set
|
|
||||||
{
|
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
|
||||||
{
|
{
|
||||||
sectors[s].floor_xoffs += lines[i].dx;
|
sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle;
|
||||||
sectors[s].floor_yoffs += lines[i].dy;
|
sectors[s].floor_xoffs += xoffs;
|
||||||
|
sectors[s].floor_yoffs += yoffs;
|
||||||
// saved for netgames
|
// saved for netgames
|
||||||
sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs;
|
sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs;
|
||||||
sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs;
|
sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!(lines[i].flags & ML_NOCLIMB)) // Align ceiling unless NOCLIMB flag is set
|
if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set
|
||||||
{
|
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
|
||||||
{
|
{
|
||||||
sectors[s].ceiling_xoffs += lines[i].dx;
|
sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle;
|
||||||
sectors[s].ceiling_yoffs += lines[i].dy;
|
sectors[s].ceiling_xoffs += xoffs;
|
||||||
|
sectors[s].ceiling_yoffs += yoffs;
|
||||||
// saved for netgames
|
// saved for netgames
|
||||||
sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs;
|
sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs;
|
||||||
sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs;
|
sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // Otherwise, print a helpful warning. Can I do no less?
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"),
|
||||||
|
lines[i].tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: // Sector Parameters
|
case 8: // Sector Parameters
|
||||||
|
@ -5795,6 +5862,19 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
P_AddBridgeThinker(&lines[i], §ors[s]);*/
|
P_AddBridgeThinker(&lines[i], §ors[s]);*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 66: // Displace floor by front sector
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||||
|
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||||
|
break;
|
||||||
|
case 67: // Displace ceiling by front sector
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||||
|
P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||||
|
break;
|
||||||
|
case 68: // Displace both floor AND ceiling by front sector
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||||
|
P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||||
|
break;
|
||||||
|
|
||||||
case 100: // FOF (solid, opaque, shadows)
|
case 100: // FOF (solid, opaque, shadows)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||||
break;
|
break;
|
||||||
|
@ -5809,11 +5889,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
// Draw the 'insides' of the block too
|
// Draw the 'insides' of the block too
|
||||||
if (lines[i].flags & ML_NOCLIMB)
|
if (lines[i].flags & ML_NOCLIMB)
|
||||||
{
|
{
|
||||||
ffloorflags |= FF_CUTLEVEL;
|
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||||
ffloorflags |= FF_BOTHPLANES;
|
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||||
ffloorflags |= FF_ALLSIDES;
|
|
||||||
ffloorflags &= ~FF_EXTRA;
|
|
||||||
ffloorflags &= ~FF_CUTEXTRA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
|
@ -5920,11 +5997,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
// Draw the 'insides' of the block too
|
// Draw the 'insides' of the block too
|
||||||
if (lines[i].flags & ML_EFFECT2)
|
if (lines[i].flags & ML_EFFECT2)
|
||||||
{
|
{
|
||||||
ffloorflags |= FF_CUTLEVEL;
|
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||||
ffloorflags |= FF_BOTHPLANES;
|
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||||
ffloorflags |= FF_ALLSIDES;
|
|
||||||
ffloorflags &= ~FF_EXTRA;
|
|
||||||
ffloorflags &= ~FF_CUTEXTRA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
|
@ -5938,11 +6012,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
// Draw the 'insides' of the block too
|
// Draw the 'insides' of the block too
|
||||||
if (lines[i].flags & ML_EFFECT2)
|
if (lines[i].flags & ML_EFFECT2)
|
||||||
{
|
{
|
||||||
ffloorflags |= FF_CUTLEVEL;
|
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||||
ffloorflags |= FF_BOTHPLANES;
|
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||||
ffloorflags |= FF_ALLSIDES;
|
|
||||||
ffloorflags &= ~FF_EXTRA;
|
|
||||||
ffloorflags &= ~FF_CUTEXTRA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
|
@ -5966,11 +6037,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
// Draw the 'insides' of the block too
|
// Draw the 'insides' of the block too
|
||||||
if (lines[i].flags & ML_EFFECT2)
|
if (lines[i].flags & ML_EFFECT2)
|
||||||
{
|
{
|
||||||
ffloorflags |= FF_CUTLEVEL;
|
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||||
ffloorflags |= FF_BOTHPLANES;
|
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||||
ffloorflags |= FF_ALLSIDES;
|
|
||||||
ffloorflags &= ~FF_EXTRA;
|
|
||||||
ffloorflags &= ~FF_CUTEXTRA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
|
@ -5984,11 +6052,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
// Draw the 'insides' of the block too
|
// Draw the 'insides' of the block too
|
||||||
if (lines[i].flags & ML_EFFECT2)
|
if (lines[i].flags & ML_EFFECT2)
|
||||||
{
|
{
|
||||||
ffloorflags |= FF_CUTLEVEL;
|
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||||
ffloorflags |= FF_BOTHPLANES;
|
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||||
ffloorflags |= FF_ALLSIDES;
|
|
||||||
ffloorflags &= ~FF_EXTRA;
|
|
||||||
ffloorflags &= ~FF_CUTEXTRA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
|
@ -6166,7 +6231,13 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 250: // Mario Block
|
case 250: // Mario Block
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers);
|
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO;
|
||||||
|
if (lines[i].flags & ML_NOCLIMB)
|
||||||
|
ffloorflags |= FF_SHATTERBOTTOM;
|
||||||
|
if (lines[i].flags & ML_EFFECT1)
|
||||||
|
ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL);
|
||||||
|
|
||||||
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 251: // A THWOMP!
|
case 251: // A THWOMP!
|
||||||
|
@ -6180,10 +6251,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 252: // Shatter block (breaks when touched)
|
case 252: // Shatter block (breaks when touched)
|
||||||
|
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER;
|
||||||
if (lines[i].flags & ML_NOCLIMB)
|
if (lines[i].flags & ML_NOCLIMB)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_SHATTERBOTTOM, secthinkers);
|
ffloorflags |= FF_SOLID|FF_SHATTERBOTTOM;
|
||||||
else
|
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 253: // Translucent shatter block (see 76)
|
case 253: // Translucent shatter block (see 76)
|
||||||
|
@ -6191,10 +6263,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 254: // Bustable block
|
case 254: // Bustable block
|
||||||
|
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP;
|
||||||
if (lines[i].flags & ML_NOCLIMB)
|
if (lines[i].flags & ML_NOCLIMB)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_ONLYKNUX, secthinkers);
|
ffloorflags |= FF_ONLYKNUX;
|
||||||
else
|
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 255: // Spin bust block (breaks when jumped or spun downwards onto)
|
case 255: // Spin bust block (breaks when jumped or spun downwards onto)
|
||||||
|
@ -6206,10 +6279,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 257: // Quicksand
|
case 257: // Quicksand
|
||||||
|
ffloorflags = FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES;
|
||||||
if (lines[i].flags & ML_EFFECT5)
|
if (lines[i].flags & ML_EFFECT5)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES|FF_RIPPLE, secthinkers);
|
ffloorflags |= FF_RIPPLE;
|
||||||
else
|
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 258: // Laser block
|
case 258: // Laser block
|
||||||
|
@ -6970,7 +7044,6 @@ void T_Disappear(disappear_t *d)
|
||||||
/** Adds friction thinker.
|
/** Adds friction thinker.
|
||||||
*
|
*
|
||||||
* \param friction Friction value, 0xe800 is normal.
|
* \param friction Friction value, 0xe800 is normal.
|
||||||
* \param movefactor Inertia factor.
|
|
||||||
* \param affectee Target sector.
|
* \param affectee Target sector.
|
||||||
* \param roverfriction FOF or not
|
* \param roverfriction FOF or not
|
||||||
* \sa T_Friction, P_SpawnFriction
|
* \sa T_Friction, P_SpawnFriction
|
||||||
|
@ -7008,22 +7081,10 @@ void T_Friction(friction_t *f)
|
||||||
|
|
||||||
sec = sectors + f->affectee;
|
sec = sectors + f->affectee;
|
||||||
|
|
||||||
// Make sure the sector type hasn't changed
|
// Get FOF control sector
|
||||||
if (f->roverfriction)
|
if (f->roverfriction)
|
||||||
{
|
|
||||||
referrer = sectors + f->referrer;
|
referrer = sectors + f->referrer;
|
||||||
|
|
||||||
if (!(GETSECSPECIAL(referrer->special, 3) == 1
|
|
||||||
|| GETSECSPECIAL(referrer->special, 3) == 3))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(GETSECSPECIAL(sec->special, 3) == 1
|
|
||||||
|| GETSECSPECIAL(sec->special, 3) == 3))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign the friction value to players on the floor, non-floating,
|
// Assign the friction value to players on the floor, non-floating,
|
||||||
// and clipped. Normally the object's friction value is kept at
|
// and clipped. Normally the object's friction value is kept at
|
||||||
// ORIG_FRICTION and this thinker changes it for icy or muddy floors.
|
// ORIG_FRICTION and this thinker changes it for icy or muddy floors.
|
||||||
|
@ -7053,14 +7114,16 @@ void T_Friction(friction_t *f)
|
||||||
|| (f->friction < thing->friction))
|
|| (f->friction < thing->friction))
|
||||||
{
|
{
|
||||||
thing->friction = f->friction;
|
thing->friction = f->friction;
|
||||||
thing->movefactor = f->movefactor;
|
if (thing->player)
|
||||||
|
thing->movefactor = f->movefactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
|
else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
|
||||||
|| f->friction < thing->friction))
|
|| f->friction < thing->friction))
|
||||||
{
|
{
|
||||||
thing->friction = f->friction;
|
thing->friction = f->friction;
|
||||||
thing->movefactor = f->movefactor;
|
if (thing->player)
|
||||||
|
thing->movefactor = f->movefactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node = node->m_thinglist_next;
|
node = node->m_thinglist_next;
|
||||||
|
@ -7076,33 +7139,32 @@ static void P_SpawnFriction(void)
|
||||||
size_t i;
|
size_t i;
|
||||||
line_t *l = lines;
|
line_t *l = lines;
|
||||||
register INT32 s;
|
register INT32 s;
|
||||||
fixed_t length; // line length controls magnitude
|
fixed_t strength; // frontside texture offset controls magnitude
|
||||||
fixed_t friction; // friction value to be applied during movement
|
fixed_t friction; // friction value to be applied during movement
|
||||||
INT32 movefactor; // applied to each player move to simulate inertia
|
INT32 movefactor; // applied to each player move to simulate inertia
|
||||||
|
|
||||||
for (i = 0; i < numlines; i++, l++)
|
for (i = 0; i < numlines; i++, l++)
|
||||||
if (l->special == 540)
|
if (l->special == 540)
|
||||||
{
|
{
|
||||||
length = P_AproxDistance(l->dx, l->dy)>>FRACBITS;
|
strength = sides[l->sidenum[0]].textureoffset>>FRACBITS;
|
||||||
friction = (0x1EB8*length)/0x80 + 0xD000;
|
if (strength > 0) // sludge
|
||||||
|
strength = strength*2; // otherwise, the maximum sludginess value is +967...
|
||||||
|
|
||||||
|
// The following might seem odd. At the time of movement,
|
||||||
|
// the move distance is multiplied by 'friction/0x10000', so a
|
||||||
|
// higher friction value actually means 'less friction'.
|
||||||
|
friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800
|
||||||
|
|
||||||
if (friction > FRACUNIT)
|
if (friction > FRACUNIT)
|
||||||
friction = FRACUNIT;
|
friction = FRACUNIT;
|
||||||
if (friction < 0)
|
if (friction < 0)
|
||||||
friction = 0;
|
friction = 0;
|
||||||
|
|
||||||
// The following check might seem odd. At the time of movement,
|
movefactor = FixedDiv(ORIG_FRICTION, friction);
|
||||||
// the move distance is multiplied by 'friction/0x10000', so a
|
if (movefactor < FRACUNIT)
|
||||||
// higher friction value actually means 'less friction'.
|
movefactor = 8*movefactor - 7*FRACUNIT;
|
||||||
|
|
||||||
if (friction > ORIG_FRICTION) // ice
|
|
||||||
movefactor = ((0x10092 - friction)*(0x70))/0x158;
|
|
||||||
else
|
else
|
||||||
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
|
movefactor = FRACUNIT;
|
||||||
|
|
||||||
// killough 8/28/98: prevent odd situations
|
|
||||||
if (movefactor < 32)
|
|
||||||
movefactor = 32;
|
|
||||||
|
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
Add_Friction(friction, movefactor, s, -1);
|
Add_Friction(friction, movefactor, s, -1);
|
||||||
|
@ -7352,12 +7414,10 @@ void T_Pusher(pusher_t *p)
|
||||||
{
|
{
|
||||||
referrer = §ors[p->referrer];
|
referrer = §ors[p->referrer];
|
||||||
|
|
||||||
if (!(GETSECSPECIAL(referrer->special, 3) == 2
|
if (GETSECSPECIAL(referrer->special, 3) != 2)
|
||||||
|| GETSECSPECIAL(referrer->special, 3) == 3))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!(GETSECSPECIAL(sec->special, 3) == 2
|
else if (GETSECSPECIAL(sec->special, 3) != 2)
|
||||||
|| GETSECSPECIAL(sec->special, 3) == 3))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// For constant pushers (wind/current) there are 3 situations:
|
// For constant pushers (wind/current) there are 3 situations:
|
||||||
|
|
24
src/p_spec.h
24
src/p_spec.h
|
@ -325,7 +325,7 @@ INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
|
||||||
|
|
||||||
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
|
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
|
||||||
|
|
||||||
INT32 EV_MarioBlock(sector_t *sector, sector_t *roversector, fixed_t topheight, mobj_t *puncher);
|
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
|
||||||
|
|
||||||
void T_MoveFloor(floormove_t *movefloor);
|
void T_MoveFloor(floormove_t *movefloor);
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
thinker_t thinker; ///< Thinker structure for friction.
|
thinker_t thinker; ///< Thinker structure for friction.
|
||||||
INT32 friction; ///< Friction value, 0xe800 = normal.
|
INT32 friction; ///< Friction value, 0xe800 = normal.
|
||||||
INT32 movefactor; ///< Inertia factor when adding to momentum.
|
INT32 movefactor; ///< Inertia factor when adding to momentum, FRACUNIT = normal.
|
||||||
INT32 affectee; ///< Number of affected sector.
|
INT32 affectee; ///< Number of affected sector.
|
||||||
INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied.
|
INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied.
|
||||||
UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not
|
UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not
|
||||||
|
@ -450,6 +450,26 @@ void T_Disappear(disappear_t *d);
|
||||||
void T_Pusher(pusher_t *p);
|
void T_Pusher(pusher_t *p);
|
||||||
mobj_t *P_GetPushThing(UINT32 s);
|
mobj_t *P_GetPushThing(UINT32 s);
|
||||||
|
|
||||||
|
// Plane displacement
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker; ///< Thinker structure for plane displacement effect.
|
||||||
|
INT32 affectee; ///< Number of affected sector.
|
||||||
|
INT32 control; ///< Control sector used to control plane positions.
|
||||||
|
fixed_t last_height; ///< Last known height of control sector.
|
||||||
|
fixed_t speed; ///< Plane movement speed.
|
||||||
|
/** Types of plane displacement effects.
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
pd_floor, ///< Displace floor.
|
||||||
|
pd_ceiling, ///< Displace ceiling.
|
||||||
|
pd_both, ///< Displace both floor AND ceiling.
|
||||||
|
} type;
|
||||||
|
} planedisplace_t;
|
||||||
|
|
||||||
|
void T_PlaneDisplace(planedisplace_t *pd);
|
||||||
|
|
||||||
void P_CalcHeight(player_t *player);
|
void P_CalcHeight(player_t *player);
|
||||||
|
|
||||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
||||||
|
|
17
src/p_user.c
17
src/p_user.c
|
@ -1624,6 +1624,12 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type)
|
||||||
// scale
|
// scale
|
||||||
P_SetScale(mobj, player->mo->scale);
|
P_SetScale(mobj, player->mo->scale);
|
||||||
mobj->destscale = player->mo->scale;
|
mobj->destscale = player->mo->scale;
|
||||||
|
|
||||||
|
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
|
||||||
|
{
|
||||||
|
mobj->frame = FF_TRANS70;
|
||||||
|
mobj->fuse = mobj->tics;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
||||||
|
@ -4791,6 +4797,9 @@ static void P_3dMovement(player_t *player)
|
||||||
acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration;
|
acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration...
|
||||||
|
acceleration = FixedMul(acceleration<<FRACBITS, player->mo->movefactor)>>FRACBITS;
|
||||||
|
|
||||||
// Forward movement
|
// Forward movement
|
||||||
if (player->climbing)
|
if (player->climbing)
|
||||||
{
|
{
|
||||||
|
@ -6447,7 +6456,7 @@ static void P_SkidStuff(player_t *player)
|
||||||
// If your push angle is more than this close to a full 180 degrees, trigger a skid.
|
// If your push angle is more than this close to a full 180 degrees, trigger a skid.
|
||||||
if (dang > ANGLE_157h)
|
if (dang > ANGLE_157h)
|
||||||
{
|
{
|
||||||
player->skidtime = TICRATE/2;
|
player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
|
||||||
S_StartSound(player->mo, sfx_skid);
|
S_StartSound(player->mo, sfx_skid);
|
||||||
if (player->panim != PA_WALK)
|
if (player->panim != PA_WALK)
|
||||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||||
|
@ -6484,6 +6493,9 @@ static void P_MovePlayer(player_t *player)
|
||||||
cmd = &player->cmd;
|
cmd = &player->cmd;
|
||||||
runspd = FixedMul(player->runspeed, player->mo->scale);
|
runspd = FixedMul(player->runspeed, player->mo->scale);
|
||||||
|
|
||||||
|
// Let's have some movement speed fun on low-friction surfaces, JUST for players... (high friction surfaces shouldn't have any adjustment, since the acceleration in this game is super high and that ends up cheesing high-friction surfaces.)
|
||||||
|
runspd = FixedMul(runspd, player->mo->movefactor);
|
||||||
|
|
||||||
// Control relinquishing stuff!
|
// Control relinquishing stuff!
|
||||||
if (player->powers[pw_ingoop])
|
if (player->powers[pw_ingoop])
|
||||||
player->pflags |= PF_FULLSTASIS;
|
player->pflags |= PF_FULLSTASIS;
|
||||||
|
@ -6674,6 +6686,7 @@ static void P_MovePlayer(player_t *player)
|
||||||
if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK)
|
if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK)
|
||||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||||
|
|
||||||
|
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
//GAMEPLAY STUFF//
|
//GAMEPLAY STUFF//
|
||||||
|
@ -6895,7 +6908,7 @@ static void P_MovePlayer(player_t *player)
|
||||||
P_ResetScore(player);
|
P_ResetScore(player);
|
||||||
|
|
||||||
// Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes)
|
// Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes)
|
||||||
if (player->pflags & PF_SPINNING && player->speed > FixedMul(15<<FRACBITS, player->mo->scale) && !(player->pflags & PF_JUMPED))
|
if (player->pflags & PF_SPINNING && P_AproxDistance(player->speed, player->mo->momz) > FixedMul(15<<FRACBITS, player->mo->scale) && !(player->pflags & PF_JUMPED))
|
||||||
{
|
{
|
||||||
P_SpawnSpinMobj(player, player->spinitem);
|
P_SpawnSpinMobj(player, player->spinitem);
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined (USEASM) //&& (!defined (_MSC_VER) || (_MSC_VER <= 1200))
|
#if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200))
|
||||||
#define RUSEASM //MSC.NET can't patch itself
|
#define RUSEASM //MSC.NET can't patch itself
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.14;
|
CURRENT_PROJECT_VERSION = 2.1.17;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.14;
|
CURRENT_PROJECT_VERSION = 2.1.17;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.14;
|
CURRENT_PROJECT_VERSION = 2.1.17;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.14;
|
CURRENT_PROJECT_VERSION = 2.1.17;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -267,7 +267,7 @@ static void CV_Gammaxxx_ONChange(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined (__GNUC__) && defined (__i386__) && !defined (NOASM) && !defined (__APPLE__)
|
#if defined (__GNUC__) && defined (__i386__) && !defined (NOASM) && !defined (__APPLE__) && !defined (NORUSEASM)
|
||||||
void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
|
void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
|
||||||
size_t destrowbytes);
|
size_t destrowbytes);
|
||||||
#define HAVE_VIDCOPY
|
#define HAVE_VIDCOPY
|
||||||
|
|
|
@ -1223,6 +1223,7 @@ int W_VerifyNMUSlumps(const char *filename)
|
||||||
{"COLORMAP", 8},
|
{"COLORMAP", 8},
|
||||||
{"PAL", 3},
|
{"PAL", 3},
|
||||||
{"CLM", 3},
|
{"CLM", 3},
|
||||||
|
{"TRANS", 5},
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
return W_VerifyFile(filename, NMUSlist, false);
|
return W_VerifyFile(filename, NMUSlist, false);
|
||||||
|
|
|
@ -69,7 +69,7 @@ static HCURSOR windowCursor = NULL; // main window cursor
|
||||||
|
|
||||||
static LPCSTR wClassName = "SRB2WC";
|
static LPCSTR wClassName = "SRB2WC";
|
||||||
|
|
||||||
boolean appActive = false; // app window is active
|
INT appActive = false; // app window is active
|
||||||
|
|
||||||
#ifdef LOGMESSAGES
|
#ifdef LOGMESSAGES
|
||||||
FILE *logstream;
|
FILE *logstream;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
extern HWND hWndMain;
|
extern HWND hWndMain;
|
||||||
|
|
||||||
extern boolean appActive;
|
extern INT appActive;
|
||||||
|
|
||||||
VOID I_GetSysMouseEvents(INT mouse_state);
|
VOID I_GetSysMouseEvents(INT mouse_state);
|
||||||
extern UINT MSHWheelMessage;
|
extern UINT MSHWheelMessage;
|
||||||
|
|
Loading…
Reference in a new issue