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