mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-17 10:11:02 +00:00
Merge branch 'master' into lua-spritedefs
This commit is contained in:
commit
3d2fd5d5a4
38 changed files with 991 additions and 829 deletions
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(SRB2
|
||||
VERSION 2.1.18
|
||||
VERSION 2.1.19
|
||||
LANGUAGES C)
|
||||
|
||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||
|
|
37
appveyor.yml
37
appveyor.yml
|
@ -1,4 +1,4 @@
|
|||
version: 2.1.18.{branch}-{build}
|
||||
version: 2.1.19.{branch}-{build}
|
||||
os: MinGW
|
||||
|
||||
environment:
|
||||
|
@ -47,7 +47,7 @@ before_build:
|
|||
- upx -V
|
||||
- ccache -V
|
||||
- ccache -s
|
||||
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1
|
||||
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1 NOOBJDUMP=1
|
||||
|
||||
build_script:
|
||||
- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
|
||||
|
@ -58,26 +58,29 @@ after_build:
|
|||
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
|
||||
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
||||
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
|
||||
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
|
||||
- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
|
||||
- appveyor PushArtifact %BUILD_ARCHIVE%
|
||||
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
|
||||
- appveyor PushArtifact %BUILDSARCHIVE%
|
||||
|
||||
test: off
|
||||
|
||||
deploy:
|
||||
- provider: FTP
|
||||
protocol: ftps
|
||||
host:
|
||||
secure: NsLJEPIBvmwCOj8Tg8RoRQ==
|
||||
username:
|
||||
secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
|
||||
password:
|
||||
secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
|
||||
folder: appveyor
|
||||
application:
|
||||
active_mode: false
|
||||
on:
|
||||
branch: master
|
||||
appveyor_repo_tag: true
|
||||
#deploy:
|
||||
# - provider: FTP
|
||||
# protocol: ftps
|
||||
# host:
|
||||
# secure: NsLJEPIBvmwCOj8Tg8RoRQ==
|
||||
# username:
|
||||
# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
|
||||
# password:
|
||||
# secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
|
||||
# folder: appveyor
|
||||
# application:
|
||||
# active_mode: false
|
||||
# on:
|
||||
# branch: master
|
||||
# appveyor_repo_tag: true
|
||||
|
||||
|
||||
on_finish:
|
||||
|
|
|
@ -511,13 +511,11 @@ OBJS:=$(i_main_o) \
|
|||
# For reference, this is the command I use to build a srb2.pot file from the source code.
|
||||
# (The listed source files are the ones containing translated strings).
|
||||
# FILES=""; for file in `find ./ | grep "\.c" | grep -v svn`; do [ "`grep "M_GetText(" $file`" ] && FILES="$FILES $file"; done; xgettext -d srb2 -o locale/srb2.pot -kM_GetText -F --no-wrap $FILES
|
||||
ifndef NOGETTEXT
|
||||
ifdef GETTEXT
|
||||
POS:=$(BIN)/en.mo
|
||||
|
||||
OPTS+=-DGETTEXT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef DJGPPDOS
|
||||
all: pre-build $(BIN)/$(EXENAME)
|
||||
|
|
|
@ -283,9 +283,6 @@ else
|
|||
ifdef LINUX
|
||||
NASMFORMAT=elf -DLINUX
|
||||
SDL=1
|
||||
ifndef NOGETTEXT
|
||||
GETTEXT=1
|
||||
endif
|
||||
ifdef LINUX64
|
||||
OBJDIR:=$(OBJDIR)/Linux64
|
||||
BIN:=$(BIN)/Linux64
|
||||
|
@ -321,9 +318,6 @@ else
|
|||
ifdef MINGW64
|
||||
INTERFACE=win32
|
||||
#NASMFORMAT=win64
|
||||
ifndef NOGETTEXT
|
||||
#GETTEXT=1
|
||||
endif
|
||||
OBJDIR:=$(OBJDIR)/Mingw64
|
||||
BIN:=$(BIN)/Mingw64
|
||||
else
|
||||
|
@ -354,9 +348,6 @@ else
|
|||
ifdef MINGW
|
||||
INTERFACE=win32
|
||||
NASMFORMAT=win32
|
||||
ifndef NOGETTEXT
|
||||
GETTEXT=1
|
||||
endif
|
||||
OBJDIR:=$(OBJDIR)/Mingw
|
||||
BIN:=$(BIN)/Mingw
|
||||
else
|
||||
|
|
150
src/d_clisrv.c
150
src/d_clisrv.c
|
@ -1740,9 +1740,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
{
|
||||
#ifndef NONET
|
||||
INT32 i;
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
// serverlist is updated by GetPacket function
|
||||
if (serverlistcount > 0)
|
||||
{
|
||||
|
@ -1776,7 +1774,20 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
serverlist[i].info.fileneeded);
|
||||
CONS_Printf(M_GetText("Checking files...\n"));
|
||||
i = CL_CheckFiles();
|
||||
if (i == 2) // cannot join for some reason
|
||||
if (i == 3) // too many files
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have too many WAD files loaded\n"
|
||||
"to add ones the server is using.\n"
|
||||
"Please restart SRB2 before connecting.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
else if (i == 2) // cannot join for some reason
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
|
@ -2516,12 +2527,18 @@ static void Command_Nodes(void)
|
|||
|
||||
static void Command_Ban(void)
|
||||
{
|
||||
if (COM_Argc() == 1)
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame) // Don't kick Tails in splitscreen!
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server || adminplayer == consoleplayer)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
|
@ -2531,8 +2548,9 @@ static void Command_Ban(void)
|
|||
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
else
|
||||
|
||||
WRITEUINT8(p, pn);
|
||||
|
||||
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||
|
@ -2575,21 +2593,27 @@ static void Command_Ban(void)
|
|||
|
||||
static void Command_Kick(void)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
UINT8 *p = buf;
|
||||
|
||||
if (COM_Argc() == 1)
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame) // Don't kick Tails in splitscreen!
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server || adminplayer == consoleplayer)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
UINT8 *p = buf;
|
||||
const SINT8 pn = nametonum(COM_Argv(1));
|
||||
WRITESINT8(p, pn);
|
||||
|
||||
if (pn == -1 || pn == 0)
|
||||
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
|
||||
|
@ -2598,6 +2622,9 @@ static void Command_Kick(void)
|
|||
Net_ConnectionTimeout(playernode[pn]);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITESINT8(p, pn);
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||
|
@ -3404,17 +3431,42 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
if (node != servernode)
|
||||
DEBFILE(va("Received packet from unknown host %d\n", node));
|
||||
|
||||
// macro for packets that should only be sent by the server
|
||||
// if it is NOT from the server, bail out and close the connection!
|
||||
#define SERVERONLY \
|
||||
if (node != servernode) \
|
||||
{ \
|
||||
Net_CloseConnection(node); \
|
||||
break; \
|
||||
}
|
||||
switch (netbuffer->packettype)
|
||||
{
|
||||
case PT_ASKINFOVIAMS:
|
||||
#if 0
|
||||
if (server && serverrunning)
|
||||
{
|
||||
INT32 clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
||||
INT32 clientnode;
|
||||
if (ms_RoomId < 0) // ignore if we're not actually on the MS right now
|
||||
{
|
||||
Net_CloseConnection(node); // and yes, close connection
|
||||
return;
|
||||
}
|
||||
clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
||||
if (clientnode != -1)
|
||||
{
|
||||
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
|
||||
SV_SendPlayerInfo(clientnode); // Send extra info
|
||||
Net_CloseConnection(clientnode);
|
||||
// Don't close connection to MS.
|
||||
// Don't close connection to MS...
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // ...unless the IP address is not valid
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // you're not supposed to get it, so ignore it
|
||||
#else
|
||||
Net_CloseConnection(node);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PT_ASKINFO:
|
||||
|
@ -3422,8 +3474,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
{
|
||||
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
||||
SV_SendPlayerInfo(node); // Send extra info
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
Net_CloseConnection(node);
|
||||
break;
|
||||
|
||||
case PT_SERVERREFUSE: // Negative response of client join request
|
||||
|
@ -3432,6 +3484,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
SERVERONLY
|
||||
if (cl_mode == CL_WAITJOINRESPONSE)
|
||||
{
|
||||
// Save the reason so it can be displayed after quitting the netgame
|
||||
|
@ -3463,6 +3516,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
SERVERONLY
|
||||
/// \note how would this happen? and is it doing the right thing if it does?
|
||||
if (cl_mode != CL_WAITJOINRESPONSE)
|
||||
break;
|
||||
|
@ -3528,13 +3582,18 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
else
|
||||
SERVERONLY
|
||||
Got_Filetxpak();
|
||||
break;
|
||||
|
||||
case PT_REQUESTFILE:
|
||||
if (server)
|
||||
Got_RequestFilePak(node);
|
||||
{
|
||||
if (!cv_downloading.value || !Got_RequestFilePak(node))
|
||||
Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // nope
|
||||
break;
|
||||
|
||||
case PT_NODETIMEOUT:
|
||||
|
@ -3557,6 +3616,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
break; // Ignore it
|
||||
|
||||
}
|
||||
#undef SERVERONLY
|
||||
}
|
||||
|
||||
/** Handles a packet received from a node that is in game
|
||||
|
@ -3589,6 +3649,8 @@ FILESTAMP
|
|||
{
|
||||
// -------------------------------------------- SERVER RECEIVE ----------
|
||||
case PT_RESYNCHGET:
|
||||
if (client)
|
||||
break;
|
||||
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
|
||||
break;
|
||||
case PT_CLIENTCMD:
|
||||
|
@ -3655,7 +3717,8 @@ FILESTAMP
|
|||
}
|
||||
|
||||
// Splitscreen cmd
|
||||
if (netbuffer->packettype == PT_CLIENT2CMD && nodetoplayer2[node] >= 0)
|
||||
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||
&& nodetoplayer2[node] >= 0)
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
|
@ -3714,6 +3777,27 @@ FILESTAMP
|
|||
tic_t tic = maketic;
|
||||
UINT8 *textcmd;
|
||||
|
||||
// ignore if the textcmd has a reported size of zero
|
||||
// this shouldn't be sent at all
|
||||
if (!netbuffer->u.textcmd[0])
|
||||
{
|
||||
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore if the textcmd size var is actually larger than it should be
|
||||
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
||||
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
||||
{
|
||||
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
||||
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
break;
|
||||
}
|
||||
|
||||
// check if tic that we are making isn't too large else we cannot send it :(
|
||||
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
||||
j = software_MAXPACKETLENGTH
|
||||
|
@ -3907,7 +3991,7 @@ FILESTAMP
|
|||
if (client)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
|
||||
}
|
||||
|
@ -3917,6 +4001,21 @@ FILESTAMP
|
|||
case PT_SERVERCFG:
|
||||
break;
|
||||
case PT_FILEFRAGMENT:
|
||||
// Only accept PT_FILEFRAGMENT from the server.
|
||||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[2];
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (client)
|
||||
Got_Filetxpak();
|
||||
break;
|
||||
|
@ -4450,8 +4549,8 @@ static inline void PingUpdate(void)
|
|||
}
|
||||
|
||||
//send out our ping packets
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i])
|
||||
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
||||
|
||||
pingmeasurecount = 1; //Reset count
|
||||
|
@ -4481,20 +4580,15 @@ void NetUpdate(void)
|
|||
|
||||
gametime = nowtime;
|
||||
|
||||
if (!(gametime % 255) && netgame && server)
|
||||
{
|
||||
#ifdef NEWPING
|
||||
PingUpdate();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NEWPING
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 255))
|
||||
PingUpdate();
|
||||
// update node latency values so we can take an average later.
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(i));
|
||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
#endif
|
||||
|
|
68
src/d_main.c
68
src/d_main.c
|
@ -107,8 +107,6 @@ UINT8 window_notinfocus = false;
|
|||
//
|
||||
// DEMO LOOP
|
||||
//
|
||||
//static INT32 demosequence;
|
||||
static const char *pagename = "MAP1PIC";
|
||||
static char *startupwadfiles[MAX_WADFILES];
|
||||
|
||||
boolean devparm = false; // started game with -devparm
|
||||
|
@ -721,7 +719,6 @@ void D_StartTitle(void)
|
|||
|
||||
gameaction = ga_nothing;
|
||||
displayplayer = consoleplayer = 0;
|
||||
//demosequence = -1;
|
||||
gametype = GT_COOP;
|
||||
paused = false;
|
||||
advancedemo = false;
|
||||
|
@ -886,27 +883,10 @@ static void IdentifyVersion(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
// Just print the nice red titlebar like the original SRB2 for DOS.
|
||||
/* ======================================================================== */
|
||||
#ifdef PC_DOS
|
||||
static inline void D_Titlebar(char *title1, char *title2)
|
||||
{
|
||||
// SRB2 banner
|
||||
clrscr();
|
||||
textattr((BLUE<<4)+WHITE);
|
||||
clreol();
|
||||
cputs(title1);
|
||||
|
||||
// standard srb2 banner
|
||||
textattr((RED<<4)+WHITE);
|
||||
clreol();
|
||||
gotoxy((80-strlen(title2))/2, 2);
|
||||
cputs(title2);
|
||||
normvideo();
|
||||
gotoxy(1,3);
|
||||
}
|
||||
#endif
|
||||
/* ======================================================================== */
|
||||
// Code for printing SRB2's title bar in DOS
|
||||
/* ======================================================================== */
|
||||
|
||||
//
|
||||
// Center the title string, then add the date and time of compilation.
|
||||
|
@ -935,6 +915,31 @@ static inline void D_MakeTitleString(char *s)
|
|||
strcpy(s, temp);
|
||||
}
|
||||
|
||||
static inline void D_Titlebar(void)
|
||||
{
|
||||
char title1[82]; // srb2 title banner
|
||||
char title2[82];
|
||||
|
||||
strcpy(title1, "Sonic Robo Blast 2");
|
||||
strcpy(title2, "Sonic Robo Blast 2");
|
||||
|
||||
D_MakeTitleString(title1);
|
||||
|
||||
// SRB2 banner
|
||||
clrscr();
|
||||
textattr((BLUE<<4)+WHITE);
|
||||
clreol();
|
||||
cputs(title1);
|
||||
|
||||
// standard srb2 banner
|
||||
textattr((RED<<4)+WHITE);
|
||||
clreol();
|
||||
gotoxy((80-strlen(title2))/2, 2);
|
||||
cputs(title2);
|
||||
normvideo();
|
||||
gotoxy(1,3);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// D_SRB2Main
|
||||
|
@ -942,8 +947,6 @@ static inline void D_MakeTitleString(char *s)
|
|||
void D_SRB2Main(void)
|
||||
{
|
||||
INT32 p;
|
||||
char srb2[82]; // srb2 title banner
|
||||
char title[82];
|
||||
|
||||
INT32 pstartmap = 1;
|
||||
boolean autostart = false;
|
||||
|
@ -986,20 +989,8 @@ void D_SRB2Main(void)
|
|||
dedicated = M_CheckParm("-dedicated") != 0;
|
||||
#endif
|
||||
|
||||
strcpy(title, "Sonic Robo Blast 2");
|
||||
strcpy(srb2, "Sonic Robo Blast 2");
|
||||
D_MakeTitleString(srb2);
|
||||
|
||||
#ifdef PC_DOS
|
||||
D_Titlebar(srb2, title);
|
||||
#endif
|
||||
|
||||
#if defined (__OS2__) && !defined (HAVE_SDL)
|
||||
// set PM window title
|
||||
snprintf(pmData->title, sizeof (pmData->title),
|
||||
"Sonic Robo Blast 2" VERSIONSTRING ": %s",
|
||||
title);
|
||||
pmData->title[sizeof (pmData->title) - 1] = '\0';
|
||||
D_Titlebar();
|
||||
#endif
|
||||
|
||||
if (devparm)
|
||||
|
@ -1399,7 +1390,6 @@ void D_SRB2Main(void)
|
|||
|
||||
if (dedicated && server)
|
||||
{
|
||||
pagename = "TITLESKY";
|
||||
levelstarttic = gametic;
|
||||
G_SetGamestate(GS_LEVEL);
|
||||
if (!P_SetupLevel(false))
|
||||
|
|
|
@ -713,6 +713,13 @@ void Net_CloseConnection(INT32 node)
|
|||
#else
|
||||
INT32 i;
|
||||
boolean forceclose = (node & FORCECLOSE) != 0;
|
||||
|
||||
if (node == -1)
|
||||
{
|
||||
DEBFILE(M_GetText("Net_CloseConnection: node -1 detected!\n"));
|
||||
return; // nope, just ignore it
|
||||
}
|
||||
|
||||
node &= ~FORCECLOSE;
|
||||
|
||||
if (!node)
|
||||
|
@ -720,7 +727,7 @@ void Net_CloseConnection(INT32 node)
|
|||
|
||||
if (node < 0 || node >= MAXNETNODES) // prevent invalid nodes from crashing the game
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node);
|
||||
DEBFILE(va(M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1609,8 +1609,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
mapchangepending = 0;
|
||||
// spawn the server if needed
|
||||
// reset players if there is a new one
|
||||
if (!(adminplayer == consoleplayer) && SV_SpawnServer())
|
||||
if (!(adminplayer == consoleplayer))
|
||||
{
|
||||
if (SV_SpawnServer())
|
||||
buf[0] &= ~(1<<1);
|
||||
if (!Playing()) // you failed to start a server somehow, so cancel the map change
|
||||
return;
|
||||
}
|
||||
|
||||
// Kick bot from special stages
|
||||
if (botskin)
|
||||
|
@ -3116,7 +3121,13 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
filestatus_t ncs = FS_NOTFOUND;
|
||||
UINT8 md5sum[16];
|
||||
boolean kick = false;
|
||||
boolean toomany = false;
|
||||
INT32 i;
|
||||
size_t packetsize = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
READSTRINGN(*cp, filename, 240);
|
||||
READMEM(*cp, md5sum, 16);
|
||||
|
@ -3142,13 +3153,25 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
|
||||
packetsize += nameonlylength(filename) + 22;
|
||||
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
toomany = true;
|
||||
else
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
||||
if (ncs != FS_FOUND)
|
||||
if (ncs != FS_FOUND || toomany)
|
||||
{
|
||||
char message[256];
|
||||
|
||||
if (ncs == FS_NOTFOUND)
|
||||
if (toomany)
|
||||
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
|
||||
else if (ncs == FS_NOTFOUND)
|
||||
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
|
||||
else if (ncs == FS_MD5SUMBAD)
|
||||
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
|
||||
|
@ -3218,10 +3241,15 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
||||
if (ncs != FS_FOUND)
|
||||
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL))
|
||||
{
|
||||
Command_ExitGame_f();
|
||||
if (ncs == FS_NOTFOUND)
|
||||
if (ncs == FS_FOUND)
|
||||
{
|
||||
CONS_Printf(M_GetText("The server tried to add %s,\nbut you have too many files added.\nRestart the game to clear loaded files\nand play on this server."), filename);
|
||||
M_StartMessage(va("The server added a file \n(%s)\nbut you have too many files added.\nRestart the game to clear loaded files.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
||||
}
|
||||
else if (ncs == FS_NOTFOUND)
|
||||
{
|
||||
CONS_Printf(M_GetText("The server tried to add %s,\nbut you don't have this file.\nYou need to find it in order\nto play on this server."), filename);
|
||||
M_StartMessage(va("The server added a file \n(%s)\nthat you do not have.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
||||
|
@ -3239,7 +3267,6 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
P_AddWadFile(filename, NULL);
|
||||
G_SetGameModified(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
||||
// Prototypes
|
||||
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
||||
|
||||
// Sender structure
|
||||
typedef struct filetx_s
|
||||
|
@ -303,7 +304,8 @@ boolean CL_SendRequestFile(void)
|
|||
}
|
||||
|
||||
// get request filepak and put it on the send queue
|
||||
void Got_RequestFilePak(INT32 node)
|
||||
// returns false if a requested file was not found or cannot be sent
|
||||
boolean Got_RequestFilePak(INT32 node)
|
||||
{
|
||||
char wad[MAX_WADPATH+1];
|
||||
UINT8 *p = netbuffer->u.textcmd;
|
||||
|
@ -314,9 +316,14 @@ void Got_RequestFilePak(INT32 node)
|
|||
if (id == 0xFF)
|
||||
break;
|
||||
READSTRINGN(p, wad, MAX_WADPATH);
|
||||
SV_SendFile(node, wad, id);
|
||||
if (!SV_SendFile(node, wad, id))
|
||||
{
|
||||
SV_AbortSendFiles(node);
|
||||
return false; // don't read the rest of the files
|
||||
}
|
||||
}
|
||||
return true; // no problems with any files
|
||||
}
|
||||
|
||||
/** Checks if the files needed aren't already loaded or on the disk
|
||||
*
|
||||
|
@ -330,6 +337,12 @@ INT32 CL_CheckFiles(void)
|
|||
INT32 i, j;
|
||||
char wadfilename[MAX_WADPATH];
|
||||
INT32 ret = 1;
|
||||
size_t packetsize = 0;
|
||||
size_t filestoget = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
// if (M_CheckParm("-nofiles"))
|
||||
// return 1;
|
||||
|
@ -378,6 +391,10 @@ INT32 CL_CheckFiles(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
|
||||
for (i = 1; i < fileneedednum; i++)
|
||||
{
|
||||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||
|
@ -397,6 +414,14 @@ INT32 CL_CheckFiles(void)
|
|||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
||||
continue;
|
||||
|
||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||
|
||||
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
return 3;
|
||||
|
||||
filestoget++;
|
||||
|
||||
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
||||
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
||||
if (fileneeded[i].status != FS_FOUND)
|
||||
|
@ -480,7 +505,7 @@ static INT32 filestosend = 0;
|
|||
* \sa SV_SendRam
|
||||
*
|
||||
*/
|
||||
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||
{
|
||||
filetx_t **q; // A pointer to the "next" field of the last file in the list
|
||||
filetx_t *p; // The new file request
|
||||
|
@ -488,7 +513,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
char wadfilename[MAX_WADPATH];
|
||||
|
||||
if (cv_noticedownload.value)
|
||||
CONS_Printf("Sending file \"%s\" to node %d\n", filename, node);
|
||||
CONS_Printf("Sending file \"%s\" to node %d (%s)\n", filename, node, I_GetNodeAddress(node));
|
||||
|
||||
// Find the last file in the list and set a pointer to its "next" field
|
||||
q = &transfer[node].txlist;
|
||||
|
@ -537,7 +562,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
free(p->id.filename);
|
||||
free(p);
|
||||
*q = NULL;
|
||||
return;
|
||||
return false; // cancel the rest of the requests
|
||||
}
|
||||
|
||||
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
|
||||
|
@ -549,7 +574,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
free(p->id.filename);
|
||||
free(p);
|
||||
*q = NULL;
|
||||
return;
|
||||
return false; // cancel the rest of the requests
|
||||
}
|
||||
|
||||
DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node));
|
||||
|
@ -557,6 +582,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
p->fileid = fileid;
|
||||
p->next = NULL; // End of list
|
||||
filestosend++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Adds a memory block to the file list for a node
|
||||
|
|
|
@ -69,7 +69,7 @@ boolean SV_SendingFile(INT32 node);
|
|||
|
||||
boolean CL_CheckDownloadable(void);
|
||||
boolean CL_SendRequestFile(void);
|
||||
void Got_RequestFilePak(INT32 node);
|
||||
boolean Got_RequestFilePak(INT32 node);
|
||||
|
||||
void SV_AbortSendFiles(INT32 node);
|
||||
void CloseNetFile(void);
|
||||
|
|
339
src/dehacked.c
339
src/dehacked.c
|
@ -382,56 +382,6 @@ static void clear_levels(void)
|
|||
P_AllocMapHeader(gamemap-1);
|
||||
}
|
||||
|
||||
/*
|
||||
// Edits an animated texture slot on the array
|
||||
// Tails 12-27-2003
|
||||
static void readAnimTex(MYFILE *f, INT32 num)
|
||||
{
|
||||
char s[MAXLINELEN];
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
|
||||
do {
|
||||
if (myfgets(s, sizeof s, f) != NULL)
|
||||
{
|
||||
if (s[0] == '\n') break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
// set the value in the appropriate field
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
|
||||
i = atoi(word2);
|
||||
|
||||
if (fastcmp(word, "START"))
|
||||
strncpy(harddefs[num].startname, word2, 8);
|
||||
if (fastcmp(word, "END"))
|
||||
strncpy(harddefs[num].endname, word2, 8);
|
||||
else if (fastcmp(word, "SPEED")) harddefs[num].speed = i;
|
||||
else if (fastcmp(word, "ISTEXTURE")) harddefs[num].istexture = i;
|
||||
|
||||
else deh_warning("readAnimTex %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (s[0] != '\n' && !myfeof(f)); //finish when the line is empty
|
||||
}
|
||||
*/
|
||||
|
||||
static boolean findFreeSlot(INT32 *num)
|
||||
{
|
||||
// Send the character select entry to a free slot.
|
||||
|
@ -2106,7 +2056,7 @@ static void readframe(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||
static void readsound(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
|
@ -2142,21 +2092,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
|||
continue;
|
||||
}
|
||||
|
||||
/* if (fastcmp(word, "OFFSET"))
|
||||
{
|
||||
value -= 150360;
|
||||
if (value <= 64)
|
||||
value /= 8;
|
||||
else if (value <= 260)
|
||||
value = (value+4)/8;
|
||||
else
|
||||
value = (value+8)/8;
|
||||
if (value >= -1 && value < sfx_freeslot0 - 1)
|
||||
S_sfx[num].name = savesfxnames[value+1];
|
||||
else
|
||||
deh_warning("Sound %d: offset out of bounds", num);
|
||||
}
|
||||
else */if (fastcmp(word, "SINGULAR"))
|
||||
if (fastcmp(word, "SINGULAR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||
S_sfx[num].singularity = value;
|
||||
|
@ -2182,8 +2118,6 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
|||
} while (!myfeof(f));
|
||||
|
||||
Z_Free(s);
|
||||
|
||||
(void)savesfxnames;
|
||||
}
|
||||
|
||||
/** Checks if a game data file name for a mod is good.
|
||||
|
@ -2811,190 +2745,6 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readtexture(MYFILE *f, const char *name)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 i, j, value;
|
||||
UINT16 width = 0, height = 0;
|
||||
INT16 patchcount = 0;
|
||||
texture_t *texture;
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
value = searchvalue(s);
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
// Width of the texture.
|
||||
if (fastcmp(word, "WIDTH"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", width), UNDO_NONE);
|
||||
width = SHORT((UINT16)value);
|
||||
}
|
||||
// Height of the texture.
|
||||
else if (fastcmp(word, "HEIGHT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", height), UNDO_NONE);
|
||||
height = SHORT((UINT16)value);
|
||||
}
|
||||
// Number of patches the texture has.
|
||||
else if (fastcmp(word, "NUMPATCHES"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", patchcount), UNDO_NONE);
|
||||
patchcount = SHORT((UINT16)value);
|
||||
}
|
||||
else
|
||||
deh_warning("readtexture: unknown word '%s'", word);
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
// Error checking.
|
||||
if (!width)
|
||||
I_Error("Texture %s has no width!\n", name);
|
||||
|
||||
if (!height)
|
||||
I_Error("Texture %s has no height!\n", name);
|
||||
|
||||
if (!patchcount)
|
||||
I_Error("Texture %s has no patches!\n", name);
|
||||
|
||||
// Allocate memory for the texture, and fill in information.
|
||||
texture = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * SHORT(patchcount)), PU_STATIC, NULL);
|
||||
M_Memcpy(texture->name, name, sizeof(texture->name));
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->patchcount = patchcount;
|
||||
texture->holes = false;
|
||||
// Fill out the texture patches, to allow them to be detected
|
||||
// accurately by readpatch.
|
||||
for (i = 0; i < patchcount; i++)
|
||||
{
|
||||
texture->patches[i].originx = 0;
|
||||
texture->patches[i].originy = 0;
|
||||
texture->patches[i].wad = UINT16_MAX;
|
||||
texture->patches[i].lump = UINT16_MAX;
|
||||
}
|
||||
|
||||
// Jump to the next empty texture entry.
|
||||
i = 0;
|
||||
while (textures[i])
|
||||
i++;
|
||||
|
||||
// Fill the global texture buffer entries.
|
||||
j = 1;
|
||||
while (j << 1 <= texture->width)
|
||||
j <<= 1;
|
||||
|
||||
textures[i] = texture;
|
||||
texturewidthmask[i] = j - 1;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
|
||||
// Clean up.
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 i = 0, j = 0, value;
|
||||
texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0, 255, AST_COPY};
|
||||
|
||||
// Jump to the texture this patch belongs to, which,
|
||||
// coincidentally, is always the last one on the buffer cache.
|
||||
while (textures[i+1])
|
||||
i++;
|
||||
|
||||
// Jump to the next empty patch entry.
|
||||
while (memcmp(&(textures[i]->patches[j]), &patch, sizeof(patch)))
|
||||
j++;
|
||||
|
||||
patch.wad = wad;
|
||||
// Set the texture number, but only if the lump exists.
|
||||
if ((patch.lump = W_CheckNumForNamePwad(name, wad, 0)) == INT16_MAX)
|
||||
I_Error("readpatch: Missing patch in texture %s", textures[i]->name);
|
||||
|
||||
// note: undoing this patch will be done by other means
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
value = searchvalue(s);
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
// X position of the patch in the texture.
|
||||
if (fastcmp(word, "X"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE);
|
||||
patch.originx = (INT16)value;
|
||||
}
|
||||
// Y position of the patch in the texture.
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE);
|
||||
patch.originy = (INT16)value;
|
||||
}
|
||||
else
|
||||
deh_warning("readpatch: unknown word '%s'", word);
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
// Error checking.
|
||||
/* // Irrelevant. Origins cannot be unsigned.
|
||||
if (patch.originx == UINT16_MAX)
|
||||
I_Error("Patch %s on texture %s has no X position!\n", name, textures[i]->name);
|
||||
|
||||
if (patch.originy == UINT16_MAX)
|
||||
I_Error("Patch %s on texture %s has no Y position!\n", name, textures[i]->name);
|
||||
*/
|
||||
|
||||
// Set the patch as that patch number.
|
||||
textures[i]->patches[j] = patch;
|
||||
|
||||
// Clean up.
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readmaincfg(MYFILE *f)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
@ -3405,30 +3155,17 @@ static void ignorelines(MYFILE *f)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
static void DEH_LoadDehackedFile(MYFILE *f)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
// do a copy of this for cross references probleme
|
||||
//XBOXSTATIC actionf_t saveactions[NUMSTATES];
|
||||
//XBOXSTATIC const char *savesprnames[NUMSPRITES];
|
||||
XBOXSTATIC const char *savesfxnames[NUMSFX];
|
||||
|
||||
if (!deh_loaded)
|
||||
initfreeslots();
|
||||
|
||||
deh_num_warning = 0;
|
||||
// save values for cross reference
|
||||
/*
|
||||
for (i = 0; i < NUMSTATES; i++)
|
||||
saveactions[i] = states[i].action;
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
savesprnames[i] = sprnames[i];
|
||||
*/
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
savesfxnames[i] = S_sfx[i].name;
|
||||
|
||||
gamedataadded = false;
|
||||
|
||||
|
@ -3505,19 +3242,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
i = atoi(word2);
|
||||
if (fastcmp(word, "TEXTURE"))
|
||||
{
|
||||
// Read texture from spec file.
|
||||
readtexture(f, word2);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "PATCH"))
|
||||
{
|
||||
// Read patch from spec file.
|
||||
readpatch(f, word2, wad);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_mobjtype(word2); // find a thing by name
|
||||
|
@ -3530,10 +3255,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
/* else if (fastcmp(word, "ANIMTEX"))
|
||||
{
|
||||
readAnimTex(f, i);
|
||||
}*/
|
||||
else if (fastcmp(word, "LIGHT"))
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
|
@ -3605,34 +3326,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
// <Callum> Added translations to this just in case its re-enabled
|
||||
/* else if (fastcmp(word, "POINTER"))
|
||||
{
|
||||
word = strtok(NULL, " "); // get frame
|
||||
word = strtok(NULL, ")");
|
||||
if (word)
|
||||
{
|
||||
i = atoi(word);
|
||||
if (i < NUMSTATES && i >= 0)
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
states[i].action = saveactions[searchvalue(s)];
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Pointer: Frame %d doesn't exist", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
||||
}*/
|
||||
else if (fastcmp(word, "SOUND"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_sfx(word2); // find a sound by name
|
||||
if (i < NUMSFX && i > 0)
|
||||
readsound(f, i, savesfxnames);
|
||||
readsound(f, i);
|
||||
else
|
||||
{
|
||||
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
|
||||
|
@ -3640,26 +3339,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
/* else if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
if (i < NUMSPRITES && i >= 0)
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
INT32 k;
|
||||
k = (searchvalue(s) - 151328)/8;
|
||||
if (k >= 0 && k < NUMSPRITES)
|
||||
sprnames[i] = savesprnames[k];
|
||||
else
|
||||
{
|
||||
deh_warning("Sprite %d: offset out of bounds", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("Sprite %d doesn't exist",i);
|
||||
}*/
|
||||
else if (fastcmp(word, "HUDITEM"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
|
@ -3746,7 +3425,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// no undo support for this insanity yet
|
||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
// Last I heard this crashes the game if you try to use it
|
||||
// so this is disabled for now
|
||||
// -- Monster Iestyn
|
||||
/* else if (fastcmp(word, "SRB2"))
|
||||
{
|
||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||
if (ver != PATCHVERSION)
|
||||
|
@ -3757,6 +3439,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// Unless you REALLY want to piss people off,
|
||||
// define a custom gamedata /before/ doing this!!
|
||||
// (then again, modifiedgame will prevent game data saving anyway)
|
||||
*/
|
||||
else if (fastcmp(word, "CLEAR"))
|
||||
{
|
||||
boolean clearall = (fastcmp(word2, "ALL"));
|
||||
|
@ -3830,7 +3513,7 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
|||
W_ReadLumpPwad(wad, lump, f.data);
|
||||
f.curpos = f.data;
|
||||
f.data[f.size] = 0;
|
||||
DEH_LoadDehackedFile(&f, wad);
|
||||
DEH_LoadDehackedFile(&f);
|
||||
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
||||
Z_Free(f.data);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
// 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".
|
||||
#define MODVERSION 23
|
||||
#define MODVERSION 24
|
||||
|
||||
// =========================================================================
|
||||
|
||||
|
@ -546,4 +546,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// Hudname padding.
|
||||
#define SKINNAMEPADDING
|
||||
|
||||
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
|
||||
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
|
||||
//#define SECTORSPECIALSAFTERTHINK
|
||||
|
||||
#endif // __DOOMDEF__
|
||||
|
|
|
@ -1723,7 +1723,7 @@ static void F_AdvanceToNextScene(void)
|
|||
|
||||
void F_EndCutScene(void)
|
||||
{
|
||||
cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
|
||||
cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later
|
||||
if (runningprecutscene)
|
||||
{
|
||||
if (server)
|
||||
|
@ -1738,7 +1738,7 @@ void F_EndCutScene(void)
|
|||
else if (nextmap < 1100-1)
|
||||
G_NextLevel();
|
||||
else
|
||||
Y_EndGame();
|
||||
G_EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
41
src/g_game.c
41
src/g_game.c
|
@ -2309,6 +2309,9 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
|||
if (starpost) //Don't even bother with looking for a place to spawn.
|
||||
{
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2633,7 +2636,7 @@ void G_ExitLevel(void)
|
|||
CONS_Printf(M_GetText("The round has ended.\n"));
|
||||
|
||||
// Remove CEcho text on round end.
|
||||
HU_DoCEcho("");
|
||||
HU_ClearCEcho();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2927,7 +2930,7 @@ void G_AfterIntermission(void)
|
|||
if (nextmap < 1100-1)
|
||||
G_NextLevel();
|
||||
else
|
||||
Y_EndGame();
|
||||
G_EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3013,6 +3016,38 @@ static void G_DoContinued(void)
|
|||
gameaction = ga_nothing;
|
||||
}
|
||||
|
||||
//
|
||||
// G_EndGame (formerly Y_EndGame)
|
||||
// Frankly this function fits better in g_game.c than it does in y_inter.c
|
||||
//
|
||||
// ...Gee, (why) end the game?
|
||||
// Because G_AfterIntermission and F_EndCutscene would
|
||||
// both do this exact same thing *in different ways* otherwise,
|
||||
// which made it so that you could only unlock Ultimate mode
|
||||
// if you had a cutscene after the final level and crap like that.
|
||||
// This function simplifies it so only one place has to be updated
|
||||
// when something new is added.
|
||||
void G_EndGame(void)
|
||||
{
|
||||
// Only do evaluation and credits in coop games.
|
||||
if (gametype == GT_COOP)
|
||||
{
|
||||
if (nextmap == 1102-1) // end game with credits
|
||||
{
|
||||
F_StartCredits();
|
||||
return;
|
||||
}
|
||||
if (nextmap == 1101-1) // end game with evaluation
|
||||
{
|
||||
F_StartGameEvaluation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 1100 or competitive multiplayer, so go back to title screen.
|
||||
D_StartTitle();
|
||||
}
|
||||
|
||||
//
|
||||
// G_LoadGameSettings
|
||||
//
|
||||
|
@ -3898,7 +3933,7 @@ void G_GhostAddColor(ghostcolor_t color)
|
|||
ghostext.color = (UINT8)color;
|
||||
}
|
||||
|
||||
void G_GhostAddScale(UINT16 scale)
|
||||
void G_GhostAddScale(fixed_t scale)
|
||||
{
|
||||
if (!demorecording || !(demoflags & DF_GHOST))
|
||||
return;
|
||||
|
|
|
@ -142,7 +142,7 @@ void G_GhostAddSpin(void);
|
|||
void G_GhostAddRev(void);
|
||||
void G_GhostAddColor(ghostcolor_t color);
|
||||
void G_GhostAddFlip(void);
|
||||
void G_GhostAddScale(UINT16 scale);
|
||||
void G_GhostAddScale(fixed_t scale);
|
||||
void G_GhostAddHit(mobj_t *victim);
|
||||
void G_WriteGhostTic(mobj_t *ghost);
|
||||
void G_ConsGhostTic(void);
|
||||
|
@ -174,6 +174,7 @@ void G_NextLevel(void);
|
|||
void G_Continue(void);
|
||||
void G_UseContinue(void);
|
||||
void G_AfterIntermission(void);
|
||||
void G_EndGame(void); // moved from y_inter.c/h and renamed
|
||||
|
||||
void G_Ticker(boolean run);
|
||||
boolean G_Responder(event_t *ev);
|
||||
|
|
|
@ -78,6 +78,7 @@ typedef struct gr_vissprite_s
|
|||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
UINT8 *colormap;
|
||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
float z1, z2;
|
||||
} gr_vissprite_t;
|
||||
|
||||
// --------
|
||||
|
|
|
@ -1084,9 +1084,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
|||
float endheight = 0.0f, endbheight = 0.0f;
|
||||
|
||||
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].y);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
|
||||
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].y);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
|
||||
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
||||
// use this as a temp var to store P_GetZAt's return value each time
|
||||
fixed_t temp;
|
||||
|
@ -3721,6 +3721,9 @@ static void HWR_Subsector(size_t num)
|
|||
|
||||
while (count--)
|
||||
{
|
||||
#ifdef POLYOBJECTS
|
||||
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||
#endif
|
||||
HWR_AddLine(line);
|
||||
line++;
|
||||
}
|
||||
|
@ -4226,6 +4229,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
GLPatch_t *gpatch; // sprite patch converted to hardware
|
||||
FSurfaceInfo Surf;
|
||||
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
||||
//const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE));
|
||||
if (spr->mobj)
|
||||
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
||||
if (hires)
|
||||
|
@ -4269,7 +4273,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
|
||||
// make a wall polygon (with 2 triangles), using the floor/ceiling heights,
|
||||
// and the 2d map coords of start/end vertices
|
||||
wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz;
|
||||
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||
wallVerts[2].z = wallVerts[1].z = spr->z2;
|
||||
|
||||
// transform
|
||||
wv = wallVerts;
|
||||
|
@ -5065,6 +5070,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
angle_t ang;
|
||||
INT32 heightsec, phs;
|
||||
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||
float offset;
|
||||
float ang_scale = 1.0f, ang_scalez = 0.0f;
|
||||
float z1, z2;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
@ -5079,7 +5088,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
||||
// thing is behind view plane?
|
||||
if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
return;
|
||||
|
||||
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
|
||||
|
@ -5117,6 +5126,27 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||
#endif
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
// Use the actual view angle, rather than the angle formed
|
||||
// between the view point and the thing
|
||||
// this makes sure paper sprites always appear at the right angle!
|
||||
// Note: DO NOT do this in software mode version, it actually
|
||||
// makes papersprites look WORSE there (I know, I've tried)
|
||||
// Monster Iestyn - 13/05/17
|
||||
ang = dup_viewangle - thing->angle;
|
||||
ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
if (ang_scale < 0)
|
||||
{
|
||||
ang_scale = -ang_scale;
|
||||
ang_scalez = -ang_scalez;
|
||||
}
|
||||
}
|
||||
else if (sprframe->rotate != SRF_SINGLE)
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
|
||||
if (sprframe->rotate == SRF_SINGLE)
|
||||
{
|
||||
// use single rotation for all views
|
||||
|
@ -5127,8 +5157,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// choose a different rotation based on player view
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
|
@ -5146,9 +5174,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
// calculate edges of the shape
|
||||
if (flip)
|
||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
else
|
||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
|
||||
z1 = tz - (offset * ang_scalez);
|
||||
tx -= offset * ang_scale;
|
||||
|
||||
// project x
|
||||
x1 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||
|
@ -5159,7 +5190,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
x1 = tx;
|
||||
|
||||
tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
||||
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
||||
|
||||
z2 = z1 + (offset * ang_scalez);
|
||||
tx += offset * ang_scale;
|
||||
|
||||
if (papersprite && max(z1, z2) < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
x2 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||
|
||||
if (vflip)
|
||||
|
@ -5208,6 +5246,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
vis->flip = flip;
|
||||
vis->mobj = thing;
|
||||
vis->z1 = z1;
|
||||
vis->z2 = z2;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
|
|
|
@ -244,6 +244,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
|||
#define pglMaterialfv glMaterialfv
|
||||
|
||||
/* Raster functions */
|
||||
#define pglPixelStorei glPixelStorei
|
||||
#define pglReadPixels glReadPixels
|
||||
|
||||
/* Texture mapping */
|
||||
|
@ -262,15 +263,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
|||
/* texture mapping */ //GL_EXT_copy_texture
|
||||
#ifndef KOS_GL_COMPATIBILITY
|
||||
#define pglCopyTexImage2D glCopyTexImage2D
|
||||
#endif
|
||||
|
||||
/* GLU functions */
|
||||
#define pgluBuild2DMipmaps gluBuild2DMipmaps
|
||||
#endif
|
||||
#ifndef MINI_GL_COMPATIBILITY
|
||||
/* 1.3 functions for multitexturing */
|
||||
#define pglActiveTexture glActiveTexture
|
||||
#define pglMultiTexCoord2f glMultiTexCoord2f
|
||||
#endif
|
||||
#else //!STATIC_OPENGL
|
||||
|
||||
/* 1.0 functions */
|
||||
|
@ -365,6 +359,8 @@ typedef void (APIENTRY * PFNglMaterialfv) (GLint face, GLenum pname, GLfloat *pa
|
|||
static PFNglMaterialfv pglMaterialfv;
|
||||
|
||||
/* Raster functions */
|
||||
typedef void (APIENTRY * PFNglPixelStorei) (GLenum pname, GLint param);
|
||||
static PFNglPixelStorei pglPixelStorei;
|
||||
typedef void (APIENTRY * PFNglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||
static PFNglReadPixels pglReadPixels;
|
||||
|
||||
|
@ -391,7 +387,7 @@ static PFNglBindTexture pglBindTexture;
|
|||
/* texture mapping */ //GL_EXT_copy_texture
|
||||
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
static PFNglCopyTexImage2D pglCopyTexImage2D;
|
||||
|
||||
#endif
|
||||
/* GLU functions */
|
||||
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
|
||||
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
|
||||
|
@ -403,7 +399,6 @@ static PFNglActiveTexture pglActiveTexture;
|
|||
typedef void (APIENTRY *PFNglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
|
||||
static PFNglMultiTexCoord2f pglMultiTexCoord2f;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MINI_GL_COMPATIBILITY
|
||||
/* 1.2 Parms */
|
||||
|
@ -494,6 +489,7 @@ boolean SetupGLfunc(void)
|
|||
GETOPENGLFUNC(pglLightModelfv , glLightModelfv)
|
||||
GETOPENGLFUNC(pglMaterialfv , glMaterialfv)
|
||||
|
||||
GETOPENGLFUNC(pglPixelStorei , glPixelStorei)
|
||||
GETOPENGLFUNC(pglReadPixels , glReadPixels)
|
||||
|
||||
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
|
||||
|
@ -519,35 +515,23 @@ boolean SetupGLfunc(void)
|
|||
// This has to be done after the context is created so the version number can be obtained
|
||||
boolean SetupGLFunc13(void)
|
||||
{
|
||||
#ifdef MINI_GL_COMPATIBILITY
|
||||
return false;
|
||||
#else
|
||||
const GLubyte *version = pglGetString(GL_VERSION);
|
||||
int glmajor, glminor;
|
||||
|
||||
gl13 = false;
|
||||
#ifdef MINI_GL_COMPATIBILITY
|
||||
return false;
|
||||
#else
|
||||
#ifdef STATIC_OPENGL
|
||||
gl13 = true;
|
||||
#else
|
||||
|
||||
// Parse the GL version
|
||||
if (version != NULL)
|
||||
{
|
||||
if (sscanf((const char*)version, "%d.%d", &glmajor, &glminor) == 2)
|
||||
{
|
||||
// Look, we gotta prepare for the inevitable arrival of GL 2.0 code...
|
||||
switch (glmajor)
|
||||
{
|
||||
case 1:
|
||||
if (glminor == 3) gl13 = true;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (glmajor == 1 && glminor >= 3)
|
||||
gl13 = true;
|
||||
else if (glmajor > 1)
|
||||
gl13 = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,9 +552,6 @@ boolean SetupGLFunc13(void)
|
|||
}
|
||||
else
|
||||
DBG_Printf("GL_ARB_multitexture support: disabled\n");
|
||||
#undef GETOPENGLFUNC
|
||||
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -897,7 +878,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
|||
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1);
|
||||
GLubyte *row = malloc(dst_stride);
|
||||
if (!row) return;
|
||||
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
|
||||
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
for(i = 0; i < height/2; i++)
|
||||
{
|
||||
memcpy(row, top, dst_stride);
|
||||
|
@ -913,7 +896,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
|||
INT32 j;
|
||||
GLubyte *image = malloc(width*height*3*sizeof (*image));
|
||||
if (!image) return;
|
||||
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
for (i = height-1; i >= 0; i--)
|
||||
{
|
||||
for (j = 0; j < width; j++)
|
||||
|
@ -1815,13 +1800,11 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
|||
min_filter = GL_NEAREST;
|
||||
#endif
|
||||
}
|
||||
#ifndef STATIC_OPENGL
|
||||
if (!pgluBuild2DMipmaps)
|
||||
{
|
||||
MipMap = GL_FALSE;
|
||||
min_filter = GL_LINEAR;
|
||||
}
|
||||
#endif
|
||||
Flush(); //??? if we want to change filter mode by texture, remove this
|
||||
break;
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ enum hook {
|
|||
hook_ShieldSpawn,
|
||||
hook_ShieldSpecial,
|
||||
hook_MobjMoveBlocked,
|
||||
hook_MapThingSpawn,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -83,5 +84,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
|||
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
||||
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
||||
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
||||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"ShieldSpawn",
|
||||
"ShieldSpecial",
|
||||
"MobjMoveBlocked",
|
||||
"MapThingSpawn",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -128,6 +129,7 @@ static int lib_addHook(lua_State *L)
|
|||
case hook_MobjRemoved:
|
||||
case hook_HurtMsg:
|
||||
case hook_MobjMoveBlocked:
|
||||
case hook_MapThingSpawn:
|
||||
hook.s.mt = MT_NULL;
|
||||
if (lua_isnumber(L, 2))
|
||||
hook.s.mt = lua_tonumber(L, 2);
|
||||
|
@ -187,6 +189,7 @@ static int lib_addHook(lua_State *L)
|
|||
case hook_BossDeath:
|
||||
case hook_MobjRemoved:
|
||||
case hook_MobjMoveBlocked:
|
||||
case hook_MapThingSpawn:
|
||||
lastp = &mobjhooks[hook.s.mt];
|
||||
break;
|
||||
case hook_JumpSpecial:
|
||||
|
@ -1073,4 +1076,66 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc)
|
|||
// stack: tables
|
||||
}
|
||||
|
||||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean hooked = false;
|
||||
if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8))))
|
||||
return false;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
|
||||
// Look for all generic mobj map thing spawn hooks
|
||||
for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_MapThingSpawn)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
if (lua_pcall(gL, 2, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (lua_toboolean(gL, -1))
|
||||
hooked = true;
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_MapThingSpawn)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
if (lua_pcall(gL, 2, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (lua_toboolean(gL, -1))
|
||||
hooked = true;
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
return hooked;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -596,14 +596,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
||||
WRITEUINT8(save_p, info - mobjinfo);
|
||||
WRITEUINT16(save_p, info - mobjinfo);
|
||||
break;
|
||||
}
|
||||
case ARCH_STATE:
|
||||
{
|
||||
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_STATE);
|
||||
WRITEUINT8(save_p, state - states);
|
||||
WRITEUINT16(save_p, state - states);
|
||||
break;
|
||||
}
|
||||
case ARCH_MOBJ:
|
||||
|
|
|
@ -16,70 +16,93 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
#define META_ITERATIONSTATE "iteration state"
|
||||
|
||||
static const char *const iter_opt[] = {
|
||||
"all",
|
||||
"mobj",
|
||||
NULL};
|
||||
|
||||
static const actionf_p1 iter_funcs[] = {
|
||||
NULL,
|
||||
(actionf_p1)P_MobjThinker
|
||||
};
|
||||
|
||||
struct iterationState {
|
||||
actionf_p1 filter;
|
||||
int next;
|
||||
};
|
||||
|
||||
static int iterationState_gc(lua_State *L)
|
||||
{
|
||||
struct iterationState *it = luaL_checkudata(L, -1, META_ITERATIONSTATE);
|
||||
if (it->next != LUA_REFNIL)
|
||||
{
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
|
||||
it->next = LUA_REFNIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define push_thinker(th) {\
|
||||
if ((th)->function.acp1 == (actionf_p1)P_MobjThinker) \
|
||||
LUA_PushUserdata(L, (th), META_MOBJ); \
|
||||
else \
|
||||
lua_pushlightuserdata(L, (th)); \
|
||||
}
|
||||
|
||||
static int lib_iterateThinkers(lua_State *L)
|
||||
{
|
||||
int state = luaL_checkoption(L, 1, "mobj", iter_opt);
|
||||
|
||||
thinker_t *th = NULL;
|
||||
actionf_p1 searchFunc;
|
||||
const char *searchMeta;
|
||||
thinker_t *th = NULL, *next = NULL;
|
||||
struct iterationState *it;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
|
||||
it = luaL_checkudata(L, 1, META_ITERATIONSTATE);
|
||||
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // remove state now.
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
searchFunc = NULL;
|
||||
searchMeta = NULL;
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
searchFunc = (actionf_p1)P_MobjThinker;
|
||||
searchMeta = META_MOBJ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!lua_isnil(L, 1)) {
|
||||
if (lua_islightuserdata(L, 1))
|
||||
th = (thinker_t *)lua_touserdata(L, 1);
|
||||
else if (searchMeta)
|
||||
th = *((thinker_t **)luaL_checkudata(L, 1, searchMeta));
|
||||
else
|
||||
th = *((thinker_t **)lua_touserdata(L, 1));
|
||||
} else
|
||||
if (lua_isnil(L, 2))
|
||||
th = &thinkercap;
|
||||
|
||||
if (!th) // something got our userdata invalidated!
|
||||
return 0;
|
||||
|
||||
if (searchFunc == NULL)
|
||||
else if (lua_isuserdata(L, 2))
|
||||
{
|
||||
if ((th = th->next) != &thinkercap)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
LUA_PushUserdata(L, th, META_MOBJ);
|
||||
if (lua_islightuserdata(L, 2))
|
||||
th = lua_touserdata(L, 2);
|
||||
else
|
||||
lua_pushlightuserdata(L, th);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (th = th->next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != searchFunc)
|
||||
continue;
|
||||
th = *(thinker_t **)lua_touserdata(L, -1);
|
||||
if (!th)
|
||||
{
|
||||
if (it->next == LUA_REFNIL)
|
||||
return 0;
|
||||
|
||||
LUA_PushUserdata(L, th, searchMeta);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, it->next);
|
||||
if (lua_islightuserdata(L, -1))
|
||||
next = lua_touserdata(L, -1);
|
||||
else
|
||||
next = *(thinker_t **)lua_touserdata(L, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
|
||||
it->next = LUA_REFNIL;
|
||||
|
||||
if (th && !next)
|
||||
next = th->next;
|
||||
if (!next)
|
||||
return luaL_error(L, "next thinker invalidated during iteration");
|
||||
|
||||
for (; next != &thinkercap; next = next->next)
|
||||
if (!it->filter || next->function.acp1 == it->filter)
|
||||
{
|
||||
push_thinker(next);
|
||||
if (next->next != &thinkercap)
|
||||
{
|
||||
push_thinker(next->next);
|
||||
it->next = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -87,18 +110,33 @@ static int lib_iterateThinkers(lua_State *L)
|
|||
|
||||
static int lib_startIterate(lua_State *L)
|
||||
{
|
||||
struct iterationState *it;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
luaL_checkoption(L, 1, iter_opt[0], iter_opt);
|
||||
lua_pushcfunction(L, lib_iterateThinkers);
|
||||
lua_pushvalue(L, 1);
|
||||
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
it = lua_newuserdata(L, sizeof(struct iterationState));
|
||||
luaL_getmetatable(L, META_ITERATIONSTATE);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
it->filter = iter_funcs[luaL_checkoption(L, 1, "mobj", iter_opt)];
|
||||
it->next = LUA_REFNIL;
|
||||
return 2;
|
||||
}
|
||||
|
||||
#undef push_thinker
|
||||
|
||||
int LUA_ThinkerLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_ITERATIONSTATE);
|
||||
lua_pushcfunction(L, iterationState_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushcfunction(L, lib_startIterate);
|
||||
lua_pushcfunction(L, lib_iterateThinkers);
|
||||
lua_pushcclosure(L, lib_startIterate, 1);
|
||||
lua_setfield(L, -2, "iterate");
|
||||
lua_setglobal(L, "thinkers");
|
||||
return 0;
|
||||
|
|
|
@ -2113,6 +2113,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
boolean inAndOut = false;
|
||||
boolean floortouch = false;
|
||||
fixed_t bottomheight, topheight;
|
||||
msecnode_t *node;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -2174,7 +2175,23 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
if ((netgame || multiplayer) && players[j].spectator)
|
||||
continue;
|
||||
|
||||
if (players[j].mo->subsector->sector != targetsec)
|
||||
if (players[j].mo->subsector->sector == targetsec)
|
||||
;
|
||||
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
for (node = players[j].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == targetsec)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
|
||||
|
@ -2224,7 +2241,27 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
if ((netgame || multiplayer) && players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (players[i].mo->subsector->sector != sec)
|
||||
if (players[i].mo->subsector->sector == sec)
|
||||
;
|
||||
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == sec)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
if (!(players[i].mo->subsector->sector == sec
|
||||
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
|
||||
continue;
|
||||
|
||||
if (floortouch == true && P_IsObjectOnGroundIn(players[i].mo, sec))
|
||||
|
|
14
src/p_map.c
14
src/p_map.c
|
@ -1117,6 +1117,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
||||
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
||||
}
|
||||
else if (tmthing->flags & MF_SPRING && (thing->player || thing->flags & MF_PUSHABLE))
|
||||
; // Fix a few nasty spring-jumping bugs that happen sometimes.
|
||||
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
||||
// unless it's a CTF team monitor and you're on the wrong team
|
||||
else if (thing->flags & MF_MONITOR && tmthing->player
|
||||
|
@ -1155,11 +1157,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||
|
||||
if (thing->flags & MF_SPRING)
|
||||
;
|
||||
// block only when jumping not high enough,
|
||||
// (dont climb max. 24units while already in air)
|
||||
// since return false doesn't handle momentum properly,
|
||||
// we lie to P_TryMove() so it's always too high
|
||||
if (tmthing->player && tmthing->z + tmthing->height > topz
|
||||
else if (tmthing->player && tmthing->z + tmthing->height > topz
|
||||
&& tmthing->z + tmthing->height < tmthing->ceilingz)
|
||||
{
|
||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||
|
@ -1171,8 +1175,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
#endif
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
}
|
||||
else if (thing->flags & MF_SPRING)
|
||||
;
|
||||
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
||||
{
|
||||
tmceilingz = topz;
|
||||
|
@ -1201,11 +1203,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||
|
||||
if (thing->flags & MF_SPRING)
|
||||
;
|
||||
// block only when jumping not high enough,
|
||||
// (dont climb max. 24units while already in air)
|
||||
// since return false doesn't handle momentum properly,
|
||||
// we lie to P_TryMove() so it's always too high
|
||||
if (tmthing->player && tmthing->z < topz
|
||||
else if (tmthing->player && tmthing->z < topz
|
||||
&& tmthing->z > tmthing->floorz)
|
||||
{
|
||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||
|
@ -1217,8 +1221,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
#endif
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
}
|
||||
else if (thing->flags & MF_SPRING)
|
||||
;
|
||||
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
||||
{
|
||||
tmfloorz = topz;
|
||||
|
|
33
src/p_mobj.c
33
src/p_mobj.c
|
@ -2560,10 +2560,18 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover)
|
|||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
{
|
||||
fixed_t topheight =
|
||||
#ifdef ESLOPE
|
||||
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
|
||||
#endif
|
||||
*rover->topheight;
|
||||
|
||||
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
||||
&& !(rover->master->flags & ML_BLOCKMONSTERS)
|
||||
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale)))
|
||||
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > topheight - FixedMul(16*FRACUNIT, mo->scale)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2802,7 +2810,7 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
mo->z = mo->floorz;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (mo->standingslope) // You're still on the ground; why are we here?
|
||||
if (!(mo->flags & MF_MISSILE) && mo->standingslope) // You're still on the ground; why are we here?
|
||||
{
|
||||
mo->momz = 0;
|
||||
return true;
|
||||
|
@ -3578,11 +3586,17 @@ static boolean P_SceneryZMovement(mobj_t *mo)
|
|||
//
|
||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
||||
{
|
||||
fixed_t topheight =
|
||||
#ifdef ESLOPE
|
||||
*rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
|
||||
#endif
|
||||
*rover->topheight;
|
||||
|
||||
if (!player->powers[pw_carry] && !player->homing
|
||||
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
|
||||
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height)
|
||||
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
|
||||
&& !(player->pflags & PF_SLIDING)
|
||||
&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
||||
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -8515,6 +8529,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
break;
|
||||
case MT_EGGCAPSULE:
|
||||
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
|
||||
break;
|
||||
case MT_REDTEAMRING:
|
||||
mobj->color = skincolor_redteam;
|
||||
break;
|
||||
|
@ -9714,6 +9729,16 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
mobj = P_SpawnMobj(x, y, z, i);
|
||||
mobj->spawnpoint = mthing;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MapThingSpawn(mobj, mthing))
|
||||
{
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
}
|
||||
else if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
else
|
||||
#endif
|
||||
switch(mobj->type)
|
||||
{
|
||||
case MT_SKYBOX:
|
||||
|
|
116
src/p_spec.c
116
src/p_spec.c
|
@ -456,7 +456,8 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
|||
|
||||
// Search for existing animdef
|
||||
for (i = 0; i < maxanims; i++)
|
||||
if (stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||
if (animdefs[i].istexture == istexture // Check if it's the same type!
|
||||
&& stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||
{
|
||||
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
||||
|
||||
|
@ -2444,12 +2445,22 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
|
||||
case 414: // Play SFX
|
||||
{
|
||||
fixed_t sfxnum;
|
||||
INT32 sfxnum;
|
||||
|
||||
sfxnum = sides[line->sidenum[0]].toptexture;
|
||||
|
||||
if (line->tag != 0 && line->flags & ML_EFFECT5)
|
||||
if (sfxnum == sfx_None)
|
||||
return; // Do nothing!
|
||||
if (sfxnum < sfx_None || sfxnum >= NUMSFX)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum);
|
||||
return;
|
||||
}
|
||||
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
|
||||
{
|
||||
if (line->flags & ML_EFFECT5) // Repeat Midtexture
|
||||
{
|
||||
// Additionally play the sound from tagged sectors' soundorgs
|
||||
sector_t *sec;
|
||||
|
||||
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
|
||||
|
@ -2458,7 +2469,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
S_StartSound(&sec->soundorg, sfxnum);
|
||||
}
|
||||
}
|
||||
else if (line->tag != 0 && mo)
|
||||
else if (mo) // A mobj must have triggered the executor
|
||||
{
|
||||
// Only trigger if mobj is touching the tag
|
||||
ffloor_t *rover;
|
||||
|
@ -2484,9 +2495,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
if (!foundit)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sfxnum < NUMSFX && sfxnum > sfx_None)
|
||||
{
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
// play the sound from nowhere, but only if display player triggered it
|
||||
|
@ -2512,7 +2522,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
S_StartSound(mo, sfxnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 415: // Run a script
|
||||
|
@ -3569,7 +3578,7 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
|||
//
|
||||
// Is player standing on the sector's "ground"?
|
||||
//
|
||||
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
||||
static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
|
||||
|
@ -3702,14 +3711,49 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
{
|
||||
if (roversector)
|
||||
{
|
||||
if (players[i].mo->subsector->sector != roversector)
|
||||
if (players[i].mo->subsector->sector == roversector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == roversector)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
goto DoneSection2;
|
||||
|
||||
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].mo->subsector->sector != sector)
|
||||
if (players[i].mo->subsector->sector == sector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == sector)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
goto DoneSection2;
|
||||
|
||||
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
|
||||
|
@ -4490,6 +4534,7 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
{
|
||||
sector_t *sector;
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
sector = mo->subsector->sector;
|
||||
if (!sector->ffloors)
|
||||
|
@ -4497,8 +4542,6 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!rover->master->frontsector->special)
|
||||
continue;
|
||||
|
||||
|
@ -4546,6 +4589,8 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define TELEPORTED (player->mo->subsector->sector != originalsector)
|
||||
|
||||
/** Checks if a player is standing on or is inside a 3D floor (e.g. water) and
|
||||
* applies any specials.
|
||||
*
|
||||
|
@ -4554,12 +4599,12 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
*/
|
||||
static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
||||
{
|
||||
sector_t *originalsector = player->mo->subsector->sector;
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!rover->master->frontsector->special)
|
||||
continue;
|
||||
|
||||
|
@ -4603,7 +4648,10 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
// This FOF has the special we're looking for, but are we allowed to touch it?
|
||||
if (sector == player->mo->subsector->sector
|
||||
|| (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||
{
|
||||
P_ProcessSpecialSector(player, rover->master->frontsector, sector);
|
||||
if TELEPORTED return;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow sector specials to be applied to polyobjects!
|
||||
|
@ -4690,6 +4738,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
}
|
||||
|
||||
P_ProcessSpecialSector(player, polysec, sector);
|
||||
if TELEPORTED return;
|
||||
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
}
|
||||
|
@ -4794,40 +4843,43 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
|
|||
*/
|
||||
void P_PlayerInSpecialSector(player_t *player)
|
||||
{
|
||||
sector_t *sector;
|
||||
sector_t *originalsector;
|
||||
sector_t *loopsector;
|
||||
msecnode_t *node;
|
||||
|
||||
if (!player->mo)
|
||||
return;
|
||||
|
||||
// Do your ->subsector->sector first
|
||||
sector = player->mo->subsector->sector;
|
||||
P_PlayerOnSpecial3DFloor(player, sector);
|
||||
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
|
||||
// because the player can be teleported in between these times.
|
||||
if (sector == player->mo->subsector->sector)
|
||||
P_RunSpecialSectorCheck(player, sector);
|
||||
originalsector = player->mo->subsector->sector;
|
||||
|
||||
// Iterate through touching_sectorlist
|
||||
P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first.
|
||||
if TELEPORTED return;
|
||||
|
||||
P_RunSpecialSectorCheck(player, originalsector);
|
||||
if TELEPORTED return;
|
||||
|
||||
// Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH
|
||||
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
sector = node->m_sector;
|
||||
loopsector = node->m_sector;
|
||||
|
||||
if (sector == player->mo->subsector->sector) // Don't duplicate
|
||||
if (loopsector == originalsector) // Don't duplicate
|
||||
continue;
|
||||
|
||||
// Check 3D floors...
|
||||
P_PlayerOnSpecial3DFloor(player, sector);
|
||||
P_PlayerOnSpecial3DFloor(player, loopsector);
|
||||
if TELEPORTED return;
|
||||
|
||||
if (!(sector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||
return;
|
||||
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
|
||||
// because the player can be teleported in between these times.
|
||||
if (sector == player->mo->subsector->sector)
|
||||
P_RunSpecialSectorCheck(player, sector);
|
||||
if (!(loopsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||
continue;
|
||||
|
||||
P_RunSpecialSectorCheck(player, loopsector);
|
||||
if TELEPORTED return;
|
||||
}
|
||||
}
|
||||
|
||||
#undef TELEPORTED
|
||||
|
||||
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
|
||||
*
|
||||
* \sa P_CheckTimeLimit, P_CheckPointLimit
|
||||
|
|
127
src/p_user.c
127
src/p_user.c
|
@ -1706,9 +1706,8 @@ void P_DoPlayerExit(player_t *player)
|
|||
#define SPACESPECIAL 12
|
||||
boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
||||
{
|
||||
sector_t *sector;
|
||||
|
||||
sector = mo->subsector->sector;
|
||||
sector_t *sector = mo->subsector->sector;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (GETSECSPECIAL(sector->special, 1) == SPACESPECIAL)
|
||||
return true;
|
||||
|
@ -1721,11 +1720,18 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
|||
{
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
|
||||
continue;
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
#endif
|
||||
|
||||
if (mo->z > *rover->topheight)
|
||||
if (mo->z + (mo->height/2) > topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z + (mo->height/2) < *rover->bottomheight)
|
||||
if (mo->z + (mo->height/2) < bottomheight)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
|
@ -1737,9 +1743,10 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
|||
|
||||
boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
|
||||
{
|
||||
sector_t *sector;
|
||||
sector_t *sector = mo->subsector->sector;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
sector = mo->subsector->sector;
|
||||
fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
|
||||
|
||||
if (sector->ffloors)
|
||||
{
|
||||
|
@ -1753,10 +1760,18 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
|
|||
if (!(rover->flags & FF_QUICKSAND))
|
||||
continue;
|
||||
|
||||
if (mo->z > *rover->topheight)
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
#endif
|
||||
|
||||
if (mo->z + flipoffset > topheight)
|
||||
continue;
|
||||
|
||||
if (mo->z + (mo->height/2) < *rover->bottomheight)
|
||||
if (mo->z + (mo->height/2) + flipoffset < bottomheight)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
|
@ -2067,6 +2082,7 @@ static void P_CheckQuicksand(player_t *player)
|
|||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t sinkspeed, friction;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0))
|
||||
return;
|
||||
|
@ -2078,16 +2094,38 @@ static void P_CheckQuicksand(player_t *player)
|
|||
if (!(rover->flags & FF_QUICKSAND))
|
||||
continue;
|
||||
|
||||
if (*rover->topheight >= player->mo->z && *rover->bottomheight < player->mo->z + player->mo->height)
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
#endif
|
||||
|
||||
if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height)
|
||||
{
|
||||
sinkspeed = abs(rover->master->v1->x - rover->master->v2->x)>>1;
|
||||
|
||||
sinkspeed = FixedDiv(sinkspeed,TICRATE*FRACUNIT);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
fixed_t ceilingheight = P_GetCeilingZ(player->mo, player->mo->subsector->sector, player->mo->x, player->mo->y, NULL);
|
||||
|
||||
player->mo->z += sinkspeed;
|
||||
|
||||
if (player->mo->z + player->mo->height >= ceilingheight)
|
||||
player->mo->z = ceilingheight - player->mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t floorheight = P_GetFloorZ(player->mo, player->mo->subsector->sector, player->mo->x, player->mo->y, NULL);
|
||||
|
||||
player->mo->z -= sinkspeed;
|
||||
|
||||
if (player->mo->z <= player->mo->subsector->sector->floorheight)
|
||||
player->mo->z = player->mo->subsector->sector->floorheight;
|
||||
if (player->mo->z <= floorheight)
|
||||
player->mo->z = floorheight;
|
||||
}
|
||||
|
||||
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
|
||||
|
||||
|
@ -2437,11 +2475,11 @@ static void P_DoClimbing(player_t *player)
|
|||
floorclimb = true;
|
||||
|
||||
#ifdef ESLOPE
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
bottomheight = *rover->bottomheight;
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
#endif
|
||||
|
||||
// Only supports rovers that are moving like an 'elevator', not just the top or bottom.
|
||||
|
@ -2630,13 +2668,20 @@ static void P_DoClimbing(player_t *player)
|
|||
// Is there a FOF directly below that we can move onto?
|
||||
if (glidesector->sector->ffloors)
|
||||
{
|
||||
fixed_t topheight;
|
||||
ffloor_t *rover;
|
||||
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
|
||||
continue;
|
||||
|
||||
if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
#endif
|
||||
|
||||
if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
|
||||
{
|
||||
foundfof = true;
|
||||
break;
|
||||
|
@ -3014,14 +3059,12 @@ static void P_DoTeeter(player_t *player)
|
|||
{
|
||||
if (!(rover->flags & FF_EXISTS)) continue;
|
||||
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
|
||||
if (*rover->b_slope)
|
||||
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
|
||||
#endif
|
||||
|
||||
if (P_CheckSolidLava(player->mo, rover))
|
||||
|
@ -9007,13 +9050,23 @@ static void P_CalcPostImg(player_t *player)
|
|||
else if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight;
|
||||
fixed_t bottomheight;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (pviewheight >= *rover->topheight || pviewheight <= *rover->bottomheight)
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
#endif
|
||||
|
||||
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||
continue;
|
||||
|
||||
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
||||
|
@ -9025,13 +9078,23 @@ static void P_CalcPostImg(player_t *player)
|
|||
if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight;
|
||||
fixed_t bottomheight;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER)
|
||||
continue;
|
||||
|
||||
if (pviewheight >= *rover->topheight || pviewheight <= *rover->bottomheight)
|
||||
#ifdef ESLOPE
|
||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||
#else
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
#endif
|
||||
|
||||
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||
continue;
|
||||
|
||||
*type = postimg_water;
|
||||
|
@ -9137,8 +9200,9 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->panim != PA_ABILITY)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
||||
}
|
||||
else if ((player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE))
|
||||
&& ((player->charflags & SF_NOJUMPSPIN && player->panim != PA_ROLL)
|
||||
else if ((player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE)
|
||||
&& (player->mo->state-states != S_PLAY_FLOAT && player->mo->state-states != S_PLAY_FLOAT_RUN))
|
||||
&& ((((player->charflags & (SF_NOJUMPSPIN|SF_NOJUMPDAMAGE)) == (SF_NOJUMPSPIN|SF_NOJUMPDAMAGE)) && player->panim != PA_ROLL)
|
||||
|| (!(player->charflags & SF_NOJUMPSPIN) && player->panim != PA_JUMP)))
|
||||
{
|
||||
if (!(player->charflags & SF_NOJUMPSPIN))
|
||||
|
@ -9262,6 +9326,7 @@ void P_PlayerThink(player_t *player)
|
|||
// check water content, set stuff in mobj
|
||||
P_MobjCheckWater(player->mo);
|
||||
|
||||
#ifndef SECTORSPECIALSAFTERTHINK
|
||||
#ifdef POLYOBJECTS
|
||||
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||
#endif
|
||||
|
@ -9270,6 +9335,7 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
if (!player->spectator)
|
||||
P_PlayerInSpecialSector(player);
|
||||
#endif
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
|
@ -9661,6 +9727,17 @@ void P_PlayerAfterThink(player_t *player)
|
|||
|
||||
cmd = &player->cmd;
|
||||
|
||||
#ifdef SECTORSPECIALSAFTERTHINK
|
||||
#ifdef POLYOBJECTS
|
||||
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||
#endif
|
||||
player->onconveyor = 0;
|
||||
// check special sectors : damage & secrets
|
||||
|
||||
if (!player->spectator)
|
||||
P_PlayerInSpecialSector(player);
|
||||
#endif
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
thiscam = &camera2;
|
||||
else if (player == &players[displayplayer])
|
||||
|
|
|
@ -1222,6 +1222,9 @@ static void R_Subsector(size_t num)
|
|||
while (count--)
|
||||
{
|
||||
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
||||
#ifdef POLYOBJECTS
|
||||
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||
#endif
|
||||
R_AddLine(line);
|
||||
line++;
|
||||
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
||||
|
|
13
src/r_data.c
13
src/r_data.c
|
@ -1151,23 +1151,24 @@ static void R_InitExtraColormaps(void)
|
|||
for (cfile = clump = 0; cfile < numwadfiles; cfile++, clump = 0)
|
||||
{
|
||||
startnum = W_CheckNumForNamePwad("C_START", cfile, clump);
|
||||
if (startnum == LUMPERROR)
|
||||
if (startnum == INT16_MAX)
|
||||
continue;
|
||||
|
||||
endnum = W_CheckNumForNamePwad("C_END", cfile, clump);
|
||||
|
||||
if (endnum == LUMPERROR)
|
||||
if (endnum == INT16_MAX)
|
||||
I_Error("R_InitExtraColormaps: C_START without C_END\n");
|
||||
|
||||
if (WADFILENUM(startnum) != WADFILENUM(endnum))
|
||||
I_Error("R_InitExtraColormaps: C_START and C_END in different wad files!\n");
|
||||
// This shouldn't be possible when you use the Pwad function, silly
|
||||
//if (WADFILENUM(startnum) != WADFILENUM(endnum))
|
||||
//I_Error("R_InitExtraColormaps: C_START and C_END in different wad files!\n");
|
||||
|
||||
if (numcolormaplumps >= maxcolormaplumps)
|
||||
maxcolormaplumps *= 2;
|
||||
colormaplumps = Z_Realloc(colormaplumps,
|
||||
sizeof (*colormaplumps) * maxcolormaplumps, PU_STATIC, NULL);
|
||||
colormaplumps[numcolormaplumps].wadfile = WADFILENUM(startnum);
|
||||
colormaplumps[numcolormaplumps].firstlump = LUMPNUM(startnum+1);
|
||||
colormaplumps[numcolormaplumps].wadfile = cfile;
|
||||
colormaplumps[numcolormaplumps].firstlump = startnum+1;
|
||||
colormaplumps[numcolormaplumps].numlumps = endnum - (startnum + 1);
|
||||
numcolormaplumps++;
|
||||
}
|
||||
|
|
|
@ -590,51 +590,44 @@ static BOOL I_ReadyConsole(HANDLE ci)
|
|||
|
||||
static boolean entering_con_command = false;
|
||||
|
||||
void I_GetConsoleEvents(void)
|
||||
static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co)
|
||||
{
|
||||
event_t ev = {0,0,0,0};
|
||||
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
||||
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
event_t event;
|
||||
CONSOLE_SCREEN_BUFFER_INFO CSBI;
|
||||
INPUT_RECORD input;
|
||||
DWORD t;
|
||||
|
||||
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t)
|
||||
memset(&event,0x00,sizeof (event));
|
||||
|
||||
if (evt.bKeyDown)
|
||||
{
|
||||
memset(&ev,0x00,sizeof (ev));
|
||||
switch (input.EventType)
|
||||
{
|
||||
case KEY_EVENT:
|
||||
if (input.Event.KeyEvent.bKeyDown)
|
||||
{
|
||||
ev.type = ev_console;
|
||||
event.type = ev_console;
|
||||
entering_con_command = true;
|
||||
switch (input.Event.KeyEvent.wVirtualKeyCode)
|
||||
switch (evt.wVirtualKeyCode)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
case VK_TAB:
|
||||
ev.data1 = KEY_NULL;
|
||||
event.data1 = KEY_NULL;
|
||||
break;
|
||||
case VK_SHIFT:
|
||||
ev.data1 = KEY_LSHIFT;
|
||||
event.data1 = KEY_LSHIFT;
|
||||
break;
|
||||
case VK_RETURN:
|
||||
entering_con_command = false;
|
||||
// Fall through.
|
||||
default:
|
||||
ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char
|
||||
event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char
|
||||
}
|
||||
if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t))
|
||||
{
|
||||
if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT)
|
||||
if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL);
|
||||
WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL);
|
||||
#else
|
||||
WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL);
|
||||
WriteConsole(co, &evt.uChar.AsciiChar, 1 , &t, NULL);
|
||||
#endif
|
||||
}
|
||||
if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK
|
||||
if (evt.wVirtualKeyCode == VK_BACK
|
||||
&& GetConsoleScreenBufferInfo(co,&CSBI))
|
||||
{
|
||||
WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t);
|
||||
|
@ -643,17 +636,32 @@ void I_GetConsoleEvents(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
ev.type = ev_keyup;
|
||||
switch (input.Event.KeyEvent.wVirtualKeyCode)
|
||||
event.type = ev_keyup;
|
||||
switch (evt.wVirtualKeyCode)
|
||||
{
|
||||
case VK_SHIFT:
|
||||
ev.data1 = KEY_LSHIFT;
|
||||
event.data1 = KEY_LSHIFT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ev.data1) D_PostEvent(&ev);
|
||||
if (event.data1) D_PostEvent(&event);
|
||||
}
|
||||
|
||||
void I_GetConsoleEvents(void)
|
||||
{
|
||||
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
||||
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
INPUT_RECORD input;
|
||||
DWORD t;
|
||||
|
||||
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t)
|
||||
{
|
||||
switch (input.EventType)
|
||||
{
|
||||
case KEY_EVENT:
|
||||
Impl_HandleKeyboardConsoleEvent(input.Event.KeyEvent, co);
|
||||
break;
|
||||
case MOUSE_EVENT:
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
|
|
|
@ -158,7 +158,7 @@ static INT32 windowedModes[MAXWINMODES][2] =
|
|||
static void Impl_VideoSetupSDLBuffer(void);
|
||||
static void Impl_VideoSetupBuffer(void);
|
||||
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
|
||||
static void Impl_SetWindowName(const char *title);
|
||||
//static void Impl_SetWindowName(const char *title);
|
||||
static void Impl_SetWindowIcon(void);
|
||||
|
||||
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||
|
@ -181,15 +181,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
|||
wasfullscreen = SDL_TRUE;
|
||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
else if (wasfullscreen)
|
||||
else // windowed mode
|
||||
{
|
||||
if (wasfullscreen)
|
||||
{
|
||||
wasfullscreen = SDL_FALSE;
|
||||
SDL_SetWindowFullscreen(window, 0);
|
||||
SDL_SetWindowSize(window, width, height);
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reposition window only in windowed mode
|
||||
SDL_SetWindowSize(window, width, height);
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
|
||||
|
@ -899,7 +897,7 @@ static inline boolean I_SkipFrame(void)
|
|||
{
|
||||
static boolean skip = false;
|
||||
|
||||
if (render_soft != rendermode)
|
||||
if (rendermode != render_soft)
|
||||
return false;
|
||||
|
||||
skip = !skip;
|
||||
|
@ -935,7 +933,7 @@ void I_FinishUpdate(void)
|
|||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
||||
if (render_soft == rendermode && screens[0])
|
||||
if (rendermode == render_soft && screens[0])
|
||||
{
|
||||
SDL_Rect rect;
|
||||
|
||||
|
@ -962,7 +960,7 @@ void I_FinishUpdate(void)
|
|||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
else
|
||||
else if (rendermode == render_opengl)
|
||||
{
|
||||
OglSdlFinishUpdate(cv_vidwait.value);
|
||||
}
|
||||
|
@ -1190,11 +1188,11 @@ INT32 VID_SetMode(INT32 modeNum)
|
|||
}
|
||||
vid.modenum = -1;
|
||||
}
|
||||
Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
||||
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
||||
|
||||
SDLSetMode(windowedModes[modeNum][0], windowedModes[modeNum][1], USE_FULLSCREEN);
|
||||
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
|
||||
|
||||
if (render_soft == rendermode)
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (bufSurface)
|
||||
{
|
||||
|
@ -1213,30 +1211,20 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
|||
int flags = 0;
|
||||
|
||||
if (rendermode == render_none) // dedicated
|
||||
{
|
||||
return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh
|
||||
}
|
||||
|
||||
if (window != NULL)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
if (borderlesswindow)
|
||||
{
|
||||
flags |= SDL_WINDOW_BORDERLESS;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create a window
|
||||
|
@ -1265,7 +1253,13 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
|||
#endif
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
renderer = SDL_CreateRenderer(window, -1, (usesdl2soft ? SDL_RENDERER_SOFTWARE : 0) | (cv_vidwait.value && !usesdl2soft ? SDL_RENDERER_PRESENTVSYNC : 0));
|
||||
flags = 0; // Use this to set SDL_RENDERER_* flags now
|
||||
if (usesdl2soft)
|
||||
flags |= SDL_RENDERER_SOFTWARE;
|
||||
else if (cv_vidwait.value)
|
||||
flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
|
||||
renderer = SDL_CreateRenderer(window, -1, flags);
|
||||
if (renderer == NULL)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
|
||||
|
@ -1277,14 +1271,16 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
static void Impl_SetWindowName(const char *title)
|
||||
{
|
||||
if (window != NULL)
|
||||
if (window == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SDL_SetWindowTitle(window, title);
|
||||
}
|
||||
*/
|
||||
|
||||
static void Impl_SetWindowIcon(void)
|
||||
{
|
||||
|
@ -1487,7 +1483,7 @@ void I_ShutdownGraphics(void)
|
|||
rendermode = render_none;
|
||||
if (icoSurface) SDL_FreeSurface(icoSurface);
|
||||
icoSurface = NULL;
|
||||
if (render_soft == oldrendermode)
|
||||
if (oldrendermode == render_soft)
|
||||
{
|
||||
if (vidSurface) SDL_FreeSurface(vidSurface);
|
||||
vidSurface = NULL;
|
||||
|
|
|
@ -1214,7 +1214,7 @@
|
|||
C01FCF4B08A954540054247B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
||||
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
NORMALSRB2,
|
||||
|
@ -1226,7 +1226,7 @@
|
|||
C01FCF4C08A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
||||
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
|
|
|
@ -71,7 +71,6 @@ INT32 oglflags = 0;
|
|||
void *GLUhandle = NULL;
|
||||
SDL_GLContext sdlglcontext = 0;
|
||||
|
||||
#ifndef STATIC_OPENGL
|
||||
void *GetGLFunc(const char *proc)
|
||||
{
|
||||
if (strncmp(proc, "glu", 3) == 0)
|
||||
|
@ -83,7 +82,6 @@ void *GetGLFunc(const char *proc)
|
|||
}
|
||||
return SDL_GL_GetProcAddress(proc);
|
||||
}
|
||||
#endif
|
||||
|
||||
boolean LoadGL(void)
|
||||
{
|
||||
|
|
|
@ -1214,7 +1214,7 @@
|
|||
C01FCF4B08A954540054247B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
||||
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
NORMALSRB2,
|
||||
|
@ -1226,7 +1226,7 @@
|
|||
C01FCF4C08A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
||||
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
|
|
|
@ -180,9 +180,9 @@ static LPSTR hms(UINT seconds)
|
|||
hours = minutes / 60;
|
||||
minutes %= 60;
|
||||
if (hours > 0)
|
||||
sprintf (s, "%lu:%02lu:%02lu", hours, minutes, seconds);
|
||||
sprintf (s, "%lu:%02lu:%02lu", (long unsigned int)hours, (long unsigned int)minutes, (long unsigned int)seconds);
|
||||
else
|
||||
sprintf (s, "%2lu:%02lu", minutes, seconds);
|
||||
sprintf (s, "%2lu:%02lu", (long unsigned int)minutes, (long unsigned int)seconds);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -470,7 +470,7 @@ static inline BOOL tlErrorMessage(const TCHAR *err)
|
|||
//
|
||||
// warn user if there is one
|
||||
//
|
||||
printf("Error %Ts..\n", err);
|
||||
printf("Error %s..\n", err);
|
||||
fflush(stdout);
|
||||
|
||||
MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK);
|
||||
|
|
|
@ -160,6 +160,20 @@ static void Y_CalculateMatchWinners(void);
|
|||
static void Y_FollowIntermission(void);
|
||||
static void Y_UnloadData(void);
|
||||
|
||||
// Stuff copy+pasted from st_stuff.c
|
||||
static INT32 SCX(INT32 x)
|
||||
{
|
||||
return FixedInt(FixedMul(x<<FRACBITS, vid.fdupx));
|
||||
}
|
||||
static INT32 SCY(INT32 z)
|
||||
{
|
||||
return FixedInt(FixedMul(z<<FRACBITS, vid.fdupy));
|
||||
}
|
||||
|
||||
#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n)
|
||||
#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n, q)
|
||||
#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, p)
|
||||
|
||||
static void Y_IntermissionTokenDrawer(void)
|
||||
{
|
||||
INT32 y;
|
||||
|
@ -242,28 +256,31 @@ void Y_IntermissionDrawer(void)
|
|||
Y_IntermissionTokenDrawer();
|
||||
|
||||
// draw score
|
||||
V_DrawScaledPatch(hudinfo[HUD_SCORE].x, hudinfo[HUD_SCORE].y, V_SNAPTOLEFT, sboscore);
|
||||
V_DrawTallNum(hudinfo[HUD_SCORENUM].x, hudinfo[HUD_SCORENUM].y, V_SNAPTOLEFT, data.coop.score);
|
||||
ST_DrawPatchFromHud(HUD_SCORE, sboscore);
|
||||
ST_DrawNumFromHud(HUD_SCORENUM, data.coop.score);
|
||||
|
||||
// draw time
|
||||
V_DrawScaledPatch(hudinfo[HUD_TIME].x, hudinfo[HUD_TIME].y, V_SNAPTOLEFT, sbotime);
|
||||
ST_DrawPatchFromHud(HUD_TIME, sbotime);
|
||||
if (cv_timetic.value == 1)
|
||||
V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT, data.coop.tics);
|
||||
ST_DrawNumFromHud(HUD_SECONDS, data.coop.tics);
|
||||
else
|
||||
{
|
||||
INT32 seconds, minutes, tictrn;
|
||||
|
||||
seconds = G_TicsToSeconds(data.coop.tics);
|
||||
minutes = G_TicsToMinutes(data.coop.tics, true);
|
||||
tictrn = G_TicsToCentiseconds(data.coop.tics);
|
||||
|
||||
ST_DrawNumFromHud(HUD_MINUTES, minutes); // Minutes
|
||||
ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon
|
||||
ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds
|
||||
|
||||
// we should show centiseconds on the intermission screen too, if the conditions are right.
|
||||
if (modeattacking || cv_timetic.value == 2)
|
||||
{
|
||||
V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT,
|
||||
G_TicsToCentiseconds(data.coop.tics), 2);
|
||||
V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod);
|
||||
ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period
|
||||
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics
|
||||
}
|
||||
|
||||
V_DrawPaddedTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT,
|
||||
G_TicsToSeconds(data.coop.tics), 2);
|
||||
V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, V_SNAPTOLEFT, sbocolon);
|
||||
V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, V_SNAPTOLEFT,
|
||||
G_TicsToMinutes(data.coop.tics, false));
|
||||
}
|
||||
|
||||
// draw the "got through act" lines and act number
|
||||
|
@ -1008,7 +1025,8 @@ void Y_StartIntermission(void)
|
|||
}
|
||||
|
||||
// We couldn't display the intermission even if we wanted to.
|
||||
if (dedicated) return;
|
||||
// But we still need to give the players their score bonuses, dummy.
|
||||
//if (dedicated) return;
|
||||
|
||||
// This should always exist, but just in case...
|
||||
if(!mapheaderinfo[prevmap])
|
||||
|
@ -1823,37 +1841,6 @@ void Y_EndIntermission(void)
|
|||
usebuffer = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Y_EndGame
|
||||
//
|
||||
// Why end the game?
|
||||
// Because Y_FollowIntermission and F_EndCutscene would
|
||||
// both do this exact same thing *in different ways* otherwise,
|
||||
// which made it so that you could only unlock Ultimate mode
|
||||
// if you had a cutscene after the final level and crap like that.
|
||||
// This function simplifies it so only one place has to be updated
|
||||
// when something new is added.
|
||||
void Y_EndGame(void)
|
||||
{
|
||||
// Only do evaluation and credits in coop games.
|
||||
if (gametype == GT_COOP)
|
||||
{
|
||||
if (nextmap == 1102-1) // end game with credits
|
||||
{
|
||||
F_StartCredits();
|
||||
return;
|
||||
}
|
||||
if (nextmap == 1101-1) // end game with evaluation
|
||||
{
|
||||
F_StartGameEvaluation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 1100 or competitive multiplayer, so go back to title screen.
|
||||
D_StartTitle();
|
||||
}
|
||||
|
||||
//
|
||||
// Y_FollowIntermission
|
||||
//
|
||||
|
@ -1865,21 +1852,10 @@ static void Y_FollowIntermission(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (nextmap < 1100-1)
|
||||
{
|
||||
// normal level
|
||||
// This handles whether to play a post-level cutscene, end the game,
|
||||
// or simply go to the next level.
|
||||
// No need to duplicate the code here!
|
||||
G_AfterIntermission();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start a custom cutscene if there is one.
|
||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking)
|
||||
{
|
||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
Y_EndGame();
|
||||
}
|
||||
|
||||
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
|
||||
|
|
|
@ -15,7 +15,6 @@ void Y_IntermissionDrawer(void);
|
|||
void Y_Ticker(void);
|
||||
void Y_StartIntermission(void);
|
||||
void Y_EndIntermission(void);
|
||||
void Y_EndGame(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue