mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-13 00:24:17 +00:00
Merge branch 'next' into lua_mapchange
This commit is contained in:
commit
6d7689c1a7
39 changed files with 2103 additions and 687 deletions
|
@ -63,6 +63,7 @@ CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
|||
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||
|
||||
#define COM_BUF_SIZE 8192 // command buffer size
|
||||
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
|
||||
|
||||
static INT32 com_wait; // one command per frame (for cmd sequences)
|
||||
|
||||
|
@ -485,6 +486,7 @@ static void COM_ExecuteString(char *ptext)
|
|||
{
|
||||
xcommand_t *cmd;
|
||||
cmdalias_t *a;
|
||||
static INT32 recursion = 0; // detects recursion and stops it if it goes too far
|
||||
|
||||
COM_TokenizeString(ptext);
|
||||
|
||||
|
@ -497,6 +499,7 @@ static void COM_ExecuteString(char *ptext)
|
|||
{
|
||||
if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase!
|
||||
{
|
||||
recursion = 0;
|
||||
cmd->function();
|
||||
return;
|
||||
}
|
||||
|
@ -507,11 +510,20 @@ static void COM_ExecuteString(char *ptext)
|
|||
{
|
||||
if (!stricmp(com_argv[0], a->name))
|
||||
{
|
||||
if (recursion > MAX_ALIAS_RECURSION)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n"));
|
||||
recursion = 0;
|
||||
return;
|
||||
}
|
||||
recursion++;
|
||||
COM_BufInsertText(a->value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
recursion = 0;
|
||||
|
||||
// check cvars
|
||||
// Hurdler: added at Ebola's request ;)
|
||||
// (don't flood the console in software mode with bad gr_xxx command)
|
||||
|
|
|
@ -2354,7 +2354,7 @@ void CL_ClearPlayer(INT32 playernum)
|
|||
//
|
||||
// Removes a player from the current game
|
||||
//
|
||||
static void CL_RemovePlayer(INT32 playernum)
|
||||
static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
{
|
||||
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
||||
// kick commands to be issued for the same player.
|
||||
|
@ -2409,6 +2409,10 @@ static void CL_RemovePlayer(INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||
#endif
|
||||
|
||||
// Reset player data
|
||||
CL_ClearPlayer(playernum);
|
||||
|
||||
|
@ -2684,6 +2688,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
INT32 pnum, msg;
|
||||
XBOXSTATIC char buf[3 + MAX_REASONLENGTH];
|
||||
char *reason = buf;
|
||||
kickreason_t kickreason = KR_KICK;
|
||||
|
||||
pnum = READUINT8(*p);
|
||||
msg = READUINT8(*p);
|
||||
|
@ -2766,14 +2771,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
case KICK_MSG_GO_AWAY:
|
||||
CONS_Printf(M_GetText("has been kicked (Go away)\n"));
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
#ifdef NEWPING
|
||||
case KICK_MSG_PING_HIGH:
|
||||
CONS_Printf(M_GetText("left the game (Broke ping limit)\n"));
|
||||
kickreason = KR_PINGLIMIT;
|
||||
break;
|
||||
#endif
|
||||
case KICK_MSG_CON_FAIL:
|
||||
CONS_Printf(M_GetText("left the game (Synch failure)\n"));
|
||||
kickreason = KR_SYNCH;
|
||||
|
||||
if (M_CheckParm("-consisdump")) // Helps debugging some problems
|
||||
{
|
||||
|
@ -2810,21 +2818,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
break;
|
||||
case KICK_MSG_TIMEOUT:
|
||||
CONS_Printf(M_GetText("left the game (Connection timeout)\n"));
|
||||
kickreason = KR_TIMEOUT;
|
||||
break;
|
||||
case KICK_MSG_PLAYER_QUIT:
|
||||
if (netgame) // not splitscreen/bots
|
||||
CONS_Printf(M_GetText("left the game\n"));
|
||||
kickreason = KR_LEAVE;
|
||||
break;
|
||||
case KICK_MSG_BANNED:
|
||||
CONS_Printf(M_GetText("has been banned (Don't come back)\n"));
|
||||
kickreason = KR_BAN;
|
||||
break;
|
||||
case KICK_MSG_CUSTOM_KICK:
|
||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||
CONS_Printf(M_GetText("has been kicked (%s)\n"), reason);
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
case KICK_MSG_CUSTOM_BAN:
|
||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||
CONS_Printf(M_GetText("has been banned (%s)\n"), reason);
|
||||
kickreason = KR_BAN;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2852,7 +2865,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
}
|
||||
else
|
||||
CL_RemovePlayer(pnum);
|
||||
CL_RemovePlayer(pnum, kickreason);
|
||||
}
|
||||
|
||||
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
@ -4461,6 +4474,7 @@ static void Local_Maketic(INT32 realtics)
|
|||
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
||||
{
|
||||
tic_t tic;
|
||||
UINT8 numadjust = 0;
|
||||
|
||||
(void)x;
|
||||
(void)y;
|
||||
|
@ -4470,7 +4484,21 @@ void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
|||
// spawning, but will be applied afterwards.
|
||||
|
||||
for (tic = server ? maketic : (neededtic - 1); tic >= gametic; tic--)
|
||||
{
|
||||
if (numadjust++ == BACKUPTICS)
|
||||
{
|
||||
DEBFILE(va("SV_SpawnPlayer: All netcmds for player %d adjusted!\n", playernum));
|
||||
// We already adjusted them all, waste of time doing the same thing over and over
|
||||
// This shouldn't happen normally though, either gametic was 0 (which is handled now anyway)
|
||||
// or maketic >= gametic + BACKUPTICS
|
||||
// -- Monster Iestyn 16/01/18
|
||||
break;
|
||||
}
|
||||
netcmds[tic%BACKUPTICS][playernum].angleturn = (INT16)((angle>>16) | TICCMD_RECEIVED);
|
||||
|
||||
if (!tic) // failsafe for gametic == 0 -- Monster Iestyn 16/01/18
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// create missed tic
|
||||
|
|
|
@ -444,6 +444,17 @@ extern consvar_t cv_playbackspeed;
|
|||
#define KICK_MSG_CUSTOM_KICK 7
|
||||
#define KICK_MSG_CUSTOM_BAN 8
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KR_KICK = 1, //Kicked by server
|
||||
KR_PINGLIMIT = 2, //Broke Ping Limit
|
||||
KR_SYNCH = 3, //Synch Failure
|
||||
KR_TIMEOUT = 4, //Connection Timeout
|
||||
KR_BAN = 5, //Banned by server
|
||||
KR_LEAVE = 6, //Quit the game
|
||||
|
||||
} kickreason_t;
|
||||
|
||||
extern boolean server;
|
||||
#define client (!server)
|
||||
extern boolean dedicated; // For dedicated server
|
||||
|
|
|
@ -674,6 +674,8 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_crosshair2);
|
||||
CV_RegisterVar(&cv_alwaysfreelook);
|
||||
CV_RegisterVar(&cv_alwaysfreelook2);
|
||||
CV_RegisterVar(&cv_chasefreelook);
|
||||
CV_RegisterVar(&cv_chasefreelook2);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_sideaxis);
|
||||
|
@ -1443,7 +1445,12 @@ static void Command_Playdemo_f(void)
|
|||
|
||||
CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name);
|
||||
|
||||
G_DoPlayDemo(name);
|
||||
// Internal if no extension, external if one exists
|
||||
// If external, convert the file name to a path in SRB2's home directory
|
||||
if (FIL_CheckExtension(name))
|
||||
G_DoPlayDemo(va("%s"PATHSEP"%s", srb2home, name));
|
||||
else
|
||||
G_DoPlayDemo(name);
|
||||
}
|
||||
|
||||
static void Command_Timedemo_f(void)
|
||||
|
@ -2698,6 +2705,12 @@ static void Command_Login_f(void)
|
|||
XBOXSTATIC UINT8 finalmd5[16];
|
||||
const char *pw;
|
||||
|
||||
if (!netgame)
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// If the server uses login, it will effectively just remove admin privileges
|
||||
// from whoever has them. This is good.
|
||||
if (COM_Argc() != 2)
|
||||
|
@ -2765,6 +2778,12 @@ static void Command_Verify_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!netgame)
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("verify <node>: give admin privileges to a node\n"));
|
||||
|
@ -3012,7 +3031,7 @@ static void Command_Addfile(void)
|
|||
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
||||
if (!(netgame || multiplayer) || musiconly)
|
||||
{
|
||||
P_AddWadFile(fn, NULL);
|
||||
P_AddWadFile(fn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3076,7 +3095,7 @@ static void Command_Addfile(void)
|
|||
WRITEMEM(buf_p, md5sum, 16);
|
||||
}
|
||||
|
||||
if (adminplayer == consoleplayer) // Request to add file
|
||||
if (adminplayer == consoleplayer && (!server)) // Request to add file
|
||||
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
|
||||
else
|
||||
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
|
||||
|
@ -3244,7 +3263,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
||||
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL))
|
||||
if (ncs != FS_FOUND || !P_AddWadFile(filename))
|
||||
{
|
||||
Command_ExitGame_f();
|
||||
if (ncs == FS_FOUND)
|
||||
|
|
|
@ -444,7 +444,7 @@ void CL_LoadServerFiles(void)
|
|||
continue; // Already loaded
|
||||
else if (fileneeded[i].status == FS_FOUND)
|
||||
{
|
||||
P_AddWadFile(fileneeded[i].filename, NULL);
|
||||
P_AddWadFile(fileneeded[i].filename);
|
||||
G_SetGameModified(true);
|
||||
fileneeded[i].status = FS_OPEN;
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ void CL_LoadServerFiles(void)
|
|||
fileneeded[i].filename);
|
||||
|
||||
// Okay, NOW we know it's safe. Whew.
|
||||
P_AddWadFile(fileneeded[i].filename, NULL);
|
||||
P_AddWadFile(fileneeded[i].filename);
|
||||
if (fileneeded[i].important)
|
||||
G_SetGameModified(true);
|
||||
fileneeded[i].status = FS_OPEN;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "d_clisrv.h"
|
||||
|
||||
#include "m_cond.h"
|
||||
|
||||
|
@ -1035,7 +1036,10 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -1616,7 +1620,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -1860,7 +1867,6 @@ static void readframe(MYFILE *f, INT32 num)
|
|||
char *word1;
|
||||
char *word2 = NULL;
|
||||
char *tmp;
|
||||
INT32 j;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -1875,16 +1881,6 @@ static void readframe(MYFILE *f, INT32 num)
|
|||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
for (j = 0; s[j] != '\n'; j++)
|
||||
{
|
||||
if (s[j] == '=')
|
||||
{
|
||||
j += 2;
|
||||
j = atoi(&s[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
word1 = strtok(s, " ");
|
||||
if (word1)
|
||||
strupr(word1);
|
||||
|
@ -2129,7 +2125,10 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2269,7 +2268,10 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2353,7 +2355,10 @@ static void readunlockable(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2640,7 +2645,10 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2885,7 +2893,10 @@ static void readmaincfg(MYFILE *f)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -3124,7 +3135,10 @@ static void readwipes(MYFILE *f)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -7272,6 +7286,14 @@ struct {
|
|||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
||||
#ifdef ESLOPE
|
||||
// Slope flags
|
||||
{"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope
|
||||
{"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it
|
||||
{"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position
|
||||
{"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things
|
||||
#endif
|
||||
|
||||
// Angles
|
||||
{"ANG1",ANG1},
|
||||
{"ANG2",ANG2},
|
||||
|
@ -7395,6 +7417,14 @@ struct {
|
|||
|
||||
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
|
||||
{"V_ALPHASHIFT",V_ALPHASHIFT},
|
||||
|
||||
//Kick Reasons
|
||||
{"KR_KICK",KR_KICK},
|
||||
{"KR_PINGLIMIT",KR_PINGLIMIT},
|
||||
{"KR_SYNCH",KR_SYNCH},
|
||||
{"KR_TIMEOUT",KR_TIMEOUT},
|
||||
{"KR_BAN",KR_BAN},
|
||||
{"KR_LEAVE",KR_LEAVE},
|
||||
#endif
|
||||
|
||||
{NULL,0}
|
||||
|
@ -8204,6 +8234,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"maptol")) {
|
||||
lua_pushinteger(L, maptol);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"ultimatemode")) {
|
||||
lua_pushboolean(L, ultimatemode != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mariomode")) {
|
||||
lua_pushboolean(L, mariomode != 0);
|
||||
return 1;
|
||||
|
|
|
@ -1739,7 +1739,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)
|
||||
|
@ -1754,7 +1754,7 @@ void F_EndCutScene(void)
|
|||
else if (nextmap < 1100-1)
|
||||
G_NextLevel();
|
||||
else
|
||||
Y_EndGame();
|
||||
G_EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
53
src/g_game.c
53
src/g_game.c
|
@ -350,11 +350,13 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
|||
consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_alwaysfreelook2 = {"alwaysmlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousemove = {"mousemove", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousemove2 = {"mousemove2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_chasefreelook = {"chasemlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_chasefreelook2 = {"chasemlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
#ifdef DC
|
||||
|
@ -979,7 +981,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
|
||||
turnright = PLAYER1INPUTDOWN(gc_turnright);
|
||||
turnleft = PLAYER1INPUTDOWN(gc_turnleft);
|
||||
mouseaiming = (PLAYER1INPUTDOWN(gc_mouseaiming)) ^ cv_alwaysfreelook.value;
|
||||
mouseaiming = (PLAYER1INPUTDOWN(gc_mouseaiming)) ^
|
||||
(cv_chasecam.value ? cv_chasefreelook.value : cv_alwaysfreelook.value);
|
||||
analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle;
|
||||
gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle;
|
||||
|
||||
|
@ -1270,7 +1273,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
|
||||
turnright = PLAYER2INPUTDOWN(gc_turnright);
|
||||
turnleft = PLAYER2INPUTDOWN(gc_turnleft);
|
||||
mouseaiming = (PLAYER2INPUTDOWN(gc_mouseaiming)) ^ cv_alwaysfreelook2.value;
|
||||
mouseaiming = (PLAYER2INPUTDOWN(gc_mouseaiming)) ^
|
||||
(cv_chasecam2.value ? cv_chasefreelook2.value : cv_alwaysfreelook2.value);
|
||||
analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle;
|
||||
gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle;
|
||||
|
||||
|
@ -1814,7 +1818,8 @@ boolean G_Responder(event_t *ev)
|
|||
{
|
||||
case ev_keydown:
|
||||
if (ev->data1 == gamecontrol[gc_pause][0]
|
||||
|| ev->data1 == gamecontrol[gc_pause][1])
|
||||
|| ev->data1 == gamecontrol[gc_pause][1]
|
||||
|| ev->data1 == KEY_PAUSE)
|
||||
{
|
||||
if (!pausedelay)
|
||||
{
|
||||
|
@ -2603,7 +2608,7 @@ void G_ExitLevel(void)
|
|||
CONS_Printf(M_GetText("The round has ended.\n"));
|
||||
|
||||
// Remove CEcho text on round end.
|
||||
HU_DoCEcho("");
|
||||
HU_ClearCEcho();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2899,7 +2904,7 @@ void G_AfterIntermission(void)
|
|||
if (nextmap < 1100-1)
|
||||
G_NextLevel();
|
||||
else
|
||||
Y_EndGame();
|
||||
G_EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2985,6 +2990,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
|
||||
//
|
||||
|
|
|
@ -55,8 +55,8 @@ extern INT16 rw_maximums[NUM_WEAPONS];
|
|||
|
||||
// used in game menu
|
||||
extern consvar_t cv_crosshair, cv_crosshair2;
|
||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
|
||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
|
||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove;
|
||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2;
|
||||
extern consvar_t cv_useranalog, cv_useranalog2;
|
||||
extern consvar_t cv_analog, cv_analog2;
|
||||
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis;
|
||||
|
@ -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);
|
||||
|
|
|
@ -25,10 +25,10 @@ static CV_PossibleValue_t mousesens_cons_t[] = {{1, "MIN"}, {MAXMOUSESENSITIVITY
|
|||
static CV_PossibleValue_t onecontrolperkey_cons_t[] = {{1, "One"}, {2, "Several"}, {0, NULL}};
|
||||
|
||||
// mouse values are used once
|
||||
consvar_t cv_mousesens = {"mousesens", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousesens2 = {"mousesens2", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens = {"mouseysens", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens2 = {"mouseysens2", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousesens = {"mousesens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousesens2 = {"mousesens2", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens = {"mouseysens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens2 = {"mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT32 mousex, mousey;
|
||||
|
@ -1154,10 +1154,8 @@ void G_Controldefault(void)
|
|||
#else
|
||||
void G_Controldefault(void)
|
||||
{
|
||||
gamecontrol[gc_forward ][0] = KEY_UPARROW;
|
||||
gamecontrol[gc_forward ][1] = 'w';
|
||||
gamecontrol[gc_backward ][0] = KEY_DOWNARROW;
|
||||
gamecontrol[gc_backward ][1] = 's';
|
||||
gamecontrol[gc_forward ][0] = 'w';
|
||||
gamecontrol[gc_backward ][0] = 's';
|
||||
gamecontrol[gc_strafeleft ][0] = 'a';
|
||||
gamecontrol[gc_straferight][0] = 'd';
|
||||
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW;
|
||||
|
@ -1178,21 +1176,20 @@ void G_Controldefault(void)
|
|||
gamecontrol[gc_fire ][1] = KEY_MOUSE1+0;
|
||||
gamecontrol[gc_firenormal ][0] = 'c';
|
||||
gamecontrol[gc_tossflag ][0] = '\'';
|
||||
gamecontrol[gc_use ][0] = 'x';
|
||||
gamecontrol[gc_use ][0] = KEY_LSHIFT;
|
||||
gamecontrol[gc_camtoggle ][0] = 'v';
|
||||
gamecontrol[gc_camleft ][0] = '[';
|
||||
gamecontrol[gc_camright ][0] = ']';
|
||||
gamecontrol[gc_camreset ][0] = 'r';
|
||||
gamecontrol[gc_lookup ][0] = KEY_PGUP;
|
||||
gamecontrol[gc_lookdown ][0] = KEY_PGDN;
|
||||
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
|
||||
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;
|
||||
gamecontrol[gc_centerview ][0] = KEY_END;
|
||||
gamecontrol[gc_talkkey ][0] = 't';
|
||||
gamecontrol[gc_teamkey ][0] = 'y';
|
||||
gamecontrol[gc_scores ][0] = KEY_TAB;
|
||||
gamecontrol[gc_jump ][0] = 'z';
|
||||
gamecontrol[gc_jump ][1] = KEY_MOUSE1+1;
|
||||
gamecontrol[gc_jump ][0] = KEY_SPACE;
|
||||
gamecontrol[gc_console ][0] = KEY_CONSOLE;
|
||||
gamecontrol[gc_pause ][0] = KEY_PAUSE;
|
||||
gamecontrol[gc_pause ][0] = 'p';
|
||||
#ifdef WMINPUT
|
||||
gamecontrol[gc_forward ][0] = KEY_JOY1+02; //UP
|
||||
gamecontrol[gc_backward ][0] = KEY_JOY1+03; //DOWN
|
||||
|
@ -1330,11 +1327,31 @@ static void setcontrol(INT32 (*gc)[2], INT32 na)
|
|||
return;
|
||||
}
|
||||
keynum = G_KeyStringtoNum(COM_Argv(2));
|
||||
|
||||
if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded
|
||||
{
|
||||
if (na == 4)
|
||||
{
|
||||
na--;
|
||||
keynum = G_KeyStringtoNum(COM_Argv(3));
|
||||
if (keynum == KEY_PAUSE)
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
G_CheckDoubleUsage(keynum);
|
||||
gc[numctrl][0] = keynum;
|
||||
|
||||
if (na == 4)
|
||||
gc[numctrl][1] = G_KeyStringtoNum(COM_Argv(3));
|
||||
{
|
||||
keynum = G_KeyStringtoNum(COM_Argv(3));
|
||||
if (keynum != KEY_PAUSE)
|
||||
gc[numctrl][1] = keynum;
|
||||
else
|
||||
gc[numctrl][1] = 0;
|
||||
}
|
||||
else
|
||||
gc[numctrl][1] = 0;
|
||||
}
|
||||
|
|
68
src/i_tcp.c
68
src/i_tcp.c
|
@ -713,14 +713,29 @@ static boolean SOCK_CanGet(void)
|
|||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
static void SOCK_Send(void)
|
||||
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
|
||||
{
|
||||
ssize_t c = ERRSOCKET;
|
||||
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
||||
#ifdef HAVE_IPV6
|
||||
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
|
||||
|
||||
switch (sockaddr->any.sa_family)
|
||||
{
|
||||
case AF_INET: d = d4; break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6: d = d6; break;
|
||||
#endif
|
||||
default: d = da; break;
|
||||
}
|
||||
|
||||
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
|
||||
}
|
||||
|
||||
static void SOCK_Send(void)
|
||||
{
|
||||
ssize_t c = ERRSOCKET;
|
||||
size_t i, j;
|
||||
|
||||
if (!nodeconnected[doomcom->remotenode])
|
||||
|
@ -733,19 +748,7 @@ static void SOCK_Send(void)
|
|||
for (j = 0; j < broadcastaddresses; j++)
|
||||
{
|
||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||
{
|
||||
if (broadcastaddress[i].any.sa_family == AF_INET)
|
||||
d = d4;
|
||||
#ifdef HAVE_IPV6
|
||||
else if (broadcastaddress[i].any.sa_family == AF_INET6)
|
||||
d = d6;
|
||||
#endif
|
||||
else
|
||||
d = da;
|
||||
|
||||
c = sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0,
|
||||
&broadcastaddress[j].any, d);
|
||||
}
|
||||
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -755,35 +758,13 @@ static void SOCK_Send(void)
|
|||
for (i = 0; i < mysocketses; i++)
|
||||
{
|
||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||
{
|
||||
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET)
|
||||
d = d4;
|
||||
#ifdef HAVE_IPV6
|
||||
else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6)
|
||||
d = d6;
|
||||
#endif
|
||||
else
|
||||
d = da;
|
||||
|
||||
sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0,
|
||||
&clientaddress[doomcom->remotenode].any, d);
|
||||
}
|
||||
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET)
|
||||
d = d4;
|
||||
#ifdef HAVE_IPV6
|
||||
else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6)
|
||||
d = d6;
|
||||
#endif
|
||||
else
|
||||
d = da;
|
||||
|
||||
c = sendto(nodesocket[doomcom->remotenode], (char *)&doomcom->data, doomcom->datalength, 0,
|
||||
&clientaddress[doomcom->remotenode].any, d);
|
||||
c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
|
||||
}
|
||||
|
||||
if (c == ERRSOCKET)
|
||||
|
@ -1075,7 +1056,7 @@ static boolean UDP_Socket(void)
|
|||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
while (runp != NULL)
|
||||
while (runp != NULL && s < MAXNETNODES+1)
|
||||
{
|
||||
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||
s++;
|
||||
|
@ -1090,12 +1071,15 @@ static boolean UDP_Socket(void)
|
|||
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
|
||||
s++;
|
||||
}
|
||||
|
||||
s = 0;
|
||||
|
||||
// setup broadcast adress to BROADCASTADDR entry
|
||||
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
while (runp != NULL)
|
||||
while (runp != NULL && s < MAXNETNODES+1)
|
||||
{
|
||||
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||
s++;
|
||||
|
@ -1118,7 +1102,7 @@ static boolean UDP_Socket(void)
|
|||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
while (runp != NULL)
|
||||
while (runp != NULL && s < MAXNETNODES+1)
|
||||
{
|
||||
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||
s++;
|
||||
|
|
|
@ -12733,7 +12733,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
10, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#ifdef HAVE_BLUA
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h" // So we can have P_SetupLevelSky
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h" // P_GetZAt
|
||||
#endif
|
||||
#include "z_zone.h"
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
|
@ -1547,6 +1550,24 @@ static int lib_evCrumbleChain(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
// P_SLOPES
|
||||
////////////
|
||||
|
||||
static int lib_pGetZAt(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
//HUDSAFE
|
||||
if (!slope)
|
||||
return LUA_ErrInvalid(L, "pslope_t");
|
||||
|
||||
lua_pushfixed(L, P_GetZAt(slope, x, y));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// R_DEFS
|
||||
////////////
|
||||
|
||||
|
@ -2113,6 +2134,11 @@ static luaL_Reg lib[] = {
|
|||
{"P_StartQuake",lib_pStartQuake},
|
||||
{"EV_CrumbleChain",lib_evCrumbleChain},
|
||||
|
||||
#ifdef ESLOPE
|
||||
// p_slopes
|
||||
{"P_GetZAt",lib_pGetZAt},
|
||||
#endif
|
||||
|
||||
// r_defs
|
||||
{"R_PointToAngle",lib_rPointToAngle},
|
||||
{"R_PointToAngle2",lib_rPointToAngle2},
|
||||
|
|
|
@ -43,6 +43,7 @@ enum hook {
|
|||
hook_PlayerMsg,
|
||||
hook_HurtMsg,
|
||||
hook_PlayerSpawn,
|
||||
hook_PlayerQuit,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -77,5 +78,6 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook
|
|||
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
|
||||
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
|
||||
#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"PlayerMsg",
|
||||
"HurtMsg",
|
||||
"PlayerSpawn",
|
||||
"PlayerQuit",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1074,4 +1075,30 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc)
|
|||
// stack: tables
|
||||
}
|
||||
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason)
|
||||
{
|
||||
hook_p hookp;
|
||||
if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8))))
|
||||
return;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_PlayerQuit)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit
|
||||
lua_pushinteger(gL, reason); // Reason for quitting
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
LUA_Call(gL, 2);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -560,6 +560,15 @@ static int libd_renderer(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// 30/10/18 Lat': Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
|
||||
// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn
|
||||
static int libd_getlocaltransflag(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg lib_draw[] = {
|
||||
{"patchExists", libd_patchExists},
|
||||
{"cachePatch", libd_cachePatch},
|
||||
|
@ -576,6 +585,7 @@ static luaL_Reg lib_draw[] = {
|
|||
{"dupx", libd_dupx},
|
||||
{"dupy", libd_dupy},
|
||||
{"renderer", libd_renderer},
|
||||
{"localTransFlag", libd_getlocaltransflag},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -599,6 +609,19 @@ static int lib_huddisable(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// 30/10/18: Lat': How come this wasn't here before?
|
||||
static int lib_hudenabled(lua_State *L)
|
||||
{
|
||||
enum hud option = luaL_checkoption(L, 1, NULL, hud_disable_options);
|
||||
if (hud_enabled[option/8] & (1<<(option%8)))
|
||||
lua_pushboolean(L, true);
|
||||
else
|
||||
lua_pushboolean(L, false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// add a HUD element for rendering
|
||||
static int lib_hudadd(lua_State *L)
|
||||
{
|
||||
|
@ -623,6 +646,7 @@ static int lib_hudadd(lua_State *L)
|
|||
static luaL_Reg lib_hud[] = {
|
||||
{"enable", lib_hudenable},
|
||||
{"disable", lib_huddisable},
|
||||
{"enabled", lib_hudenabled},
|
||||
{"add", lib_hudadd},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
|
@ -38,6 +38,11 @@ extern lua_State *gL;
|
|||
#define META_SUBSECTOR "SUBSECTOR_T*"
|
||||
#define META_SECTOR "SECTOR_T*"
|
||||
#define META_FFLOOR "FFLOOR_T*"
|
||||
#ifdef ESLOPE
|
||||
#define META_SLOPE "PSLOPE_T*"
|
||||
#define META_VECTOR2 "VECTOR2_T"
|
||||
#define META_VECTOR3 "VECTOR3_T"
|
||||
#endif
|
||||
#define META_MAPHEADER "MAPHEADER_T*"
|
||||
|
||||
#define META_CVAR "CONSVAR_T*"
|
||||
|
|
299
src/lua_maplib.c
299
src/lua_maplib.c
|
@ -16,6 +16,10 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "z_zone.h"
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h"
|
||||
#endif
|
||||
#include "r_main.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
@ -38,7 +42,13 @@ enum sector_e {
|
|||
sector_heightsec,
|
||||
sector_camsec,
|
||||
sector_lines,
|
||||
#ifdef ESLOPE
|
||||
sector_ffloors,
|
||||
sector_fslope,
|
||||
sector_cslope
|
||||
#else
|
||||
sector_ffloors
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char *const sector_opt[] = {
|
||||
|
@ -55,6 +65,10 @@ static const char *const sector_opt[] = {
|
|||
"camsec",
|
||||
"lines",
|
||||
"ffloors",
|
||||
#ifdef ESLOPE
|
||||
"f_slope",
|
||||
"c_slope",
|
||||
#endif
|
||||
NULL};
|
||||
|
||||
enum subsector_e {
|
||||
|
@ -160,6 +174,10 @@ enum ffloor_e {
|
|||
ffloor_toplightlevel,
|
||||
ffloor_bottomheight,
|
||||
ffloor_bottompic,
|
||||
#ifdef ESLOPE
|
||||
ffloor_tslope,
|
||||
ffloor_bslope,
|
||||
#endif
|
||||
ffloor_sector,
|
||||
ffloor_flags,
|
||||
ffloor_master,
|
||||
|
@ -176,6 +194,10 @@ static const char *const ffloor_opt[] = {
|
|||
"toplightlevel",
|
||||
"bottomheight",
|
||||
"bottompic",
|
||||
#ifdef ESLOPE
|
||||
"t_slope",
|
||||
"b_slope",
|
||||
#endif
|
||||
"sector", // secnum pushed as control sector userdata
|
||||
"flags",
|
||||
"master", // control linedef
|
||||
|
@ -185,6 +207,47 @@ static const char *const ffloor_opt[] = {
|
|||
"alpha",
|
||||
NULL};
|
||||
|
||||
#ifdef ESLOPE
|
||||
enum slope_e {
|
||||
slope_valid = 0,
|
||||
slope_o,
|
||||
slope_d,
|
||||
slope_zdelta,
|
||||
slope_normal,
|
||||
slope_zangle,
|
||||
slope_xydirection,
|
||||
slope_sourceline,
|
||||
slope_refpos,
|
||||
slope_flags
|
||||
};
|
||||
|
||||
static const char *const slope_opt[] = {
|
||||
"valid",
|
||||
"o",
|
||||
"d",
|
||||
"zdelta",
|
||||
"normal",
|
||||
"zangle",
|
||||
"xydirection",
|
||||
"sourceline",
|
||||
"refpos",
|
||||
"flags",
|
||||
NULL};
|
||||
|
||||
// shared by both vector2_t and vector3_t
|
||||
enum vector_e {
|
||||
vector_x = 0,
|
||||
vector_y,
|
||||
vector_z
|
||||
};
|
||||
|
||||
static const char *const vector_opt[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
NULL};
|
||||
#endif
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
static const char *const valid_opt[] ={"valid",NULL};
|
||||
|
||||
|
@ -327,6 +390,7 @@ static int sector_get(lua_State *L)
|
|||
{
|
||||
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
||||
INT16 i;
|
||||
|
||||
if (!sector)
|
||||
{
|
||||
|
@ -349,11 +413,23 @@ static int sector_get(lua_State *L)
|
|||
lua_pushfixed(L, sector->ceilingheight);
|
||||
return 1;
|
||||
case sector_floorpic: // floorpic
|
||||
lua_pushlstring(L, levelflats[sector->floorpic].name, 8);
|
||||
{
|
||||
levelflat_t *levelflat = &levelflats[sector->floorpic];
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!levelflat->name[i])
|
||||
break;
|
||||
lua_pushlstring(L, levelflat->name, i);
|
||||
return 1;
|
||||
}
|
||||
case sector_ceilingpic: // ceilingpic
|
||||
lua_pushlstring(L, levelflats[sector->ceilingpic].name, 8);
|
||||
{
|
||||
levelflat_t *levelflat = &levelflats[sector->ceilingpic];
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!levelflat->name[i])
|
||||
break;
|
||||
lua_pushlstring(L, levelflat->name, i);
|
||||
return 1;
|
||||
}
|
||||
case sector_lightlevel:
|
||||
lua_pushinteger(L, sector->lightlevel);
|
||||
return 1;
|
||||
|
@ -386,6 +462,14 @@ static int sector_get(lua_State *L)
|
|||
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
|
||||
lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function
|
||||
return 1;
|
||||
#ifdef ESLOPE
|
||||
case sector_fslope: // f_slope
|
||||
LUA_PushUserdata(L, sector->f_slope, META_SLOPE);
|
||||
return 1;
|
||||
case sector_cslope: // c_slope
|
||||
LUA_PushUserdata(L, sector->c_slope, META_SLOPE);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -408,6 +492,10 @@ static int sector_set(lua_State *L)
|
|||
case sector_heightsec: // heightsec
|
||||
case sector_camsec: // camsec
|
||||
case sector_ffloors: // ffloors
|
||||
#ifdef ESLOPE
|
||||
case sector_fslope: // f_slope
|
||||
case sector_cslope: // c_slope
|
||||
#endif
|
||||
default:
|
||||
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
|
||||
case sector_floorheight: { // floorheight
|
||||
|
@ -1042,6 +1130,14 @@ static int ffloor_get(lua_State *L)
|
|||
lua_pushlstring(L, levelflat->name, 8);
|
||||
return 1;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
case ffloor_tslope:
|
||||
LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE);
|
||||
return 1;
|
||||
case ffloor_bslope:
|
||||
LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE);
|
||||
return 1;
|
||||
#endif
|
||||
case ffloor_sector:
|
||||
LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR);
|
||||
return 1;
|
||||
|
@ -1081,6 +1177,10 @@ static int ffloor_set(lua_State *L)
|
|||
switch(field)
|
||||
{
|
||||
case ffloor_valid: // valid
|
||||
#ifdef ESLOPE
|
||||
case ffloor_tslope: // t_slope
|
||||
case ffloor_bslope: // b_slope
|
||||
#endif
|
||||
case ffloor_sector: // sector
|
||||
case ffloor_master: // master
|
||||
case ffloor_target: // target
|
||||
|
@ -1141,6 +1241,181 @@ static int ffloor_set(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
static int slope_get(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
|
||||
if (!slope)
|
||||
{
|
||||
if (field == slope_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed pslope_t doesn't exist anymore.");
|
||||
}
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case slope_valid: // valid
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
case slope_o: // o
|
||||
LUA_PushUserdata(L, &slope->o, META_VECTOR3);
|
||||
return 1;
|
||||
case slope_d: // d
|
||||
LUA_PushUserdata(L, &slope->d, META_VECTOR2);
|
||||
return 1;
|
||||
case slope_zdelta: // zdelta
|
||||
lua_pushfixed(L, slope->zdelta);
|
||||
return 1;
|
||||
case slope_normal: // normal
|
||||
LUA_PushUserdata(L, &slope->normal, META_VECTOR3);
|
||||
return 1;
|
||||
case slope_zangle: // zangle
|
||||
lua_pushangle(L, slope->zangle);
|
||||
return 1;
|
||||
case slope_xydirection: // xydirection
|
||||
lua_pushangle(L, slope->xydirection);
|
||||
return 1;
|
||||
case slope_sourceline: // source linedef
|
||||
LUA_PushUserdata(L, slope->sourceline, META_LINE);
|
||||
return 1;
|
||||
case slope_refpos: // refpos
|
||||
lua_pushinteger(L, slope->refpos);
|
||||
return 1;
|
||||
case slope_flags: // flags
|
||||
lua_pushinteger(L, slope->flags);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slope_set(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
|
||||
if (!slope)
|
||||
return luaL_error(L, "accessed pslope_t doesn't exist anymore.");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter pslope_t in HUD rendering code!");
|
||||
|
||||
switch(field) // todo: reorganize this shit
|
||||
{
|
||||
case slope_valid: // valid
|
||||
case slope_sourceline: // sourceline
|
||||
case slope_d: // d
|
||||
case slope_flags: // flags
|
||||
case slope_normal: // normal
|
||||
case slope_refpos: // refpos
|
||||
default:
|
||||
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
|
||||
case slope_o: { // o
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
|
||||
lua_getfield(L, 3, "x");
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, 3, 1);
|
||||
}
|
||||
if (!lua_isnil(L, -1))
|
||||
slope->o.x = luaL_checkfixed(L, -1);
|
||||
else
|
||||
slope->o.x = 0;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "y");
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, 3, 2);
|
||||
}
|
||||
if (!lua_isnil(L, -1))
|
||||
slope->o.y = luaL_checkfixed(L, -1);
|
||||
else
|
||||
slope->o.y = 0;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "z");
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, 3, 3);
|
||||
}
|
||||
if (!lua_isnil(L, -1))
|
||||
slope->o.z = luaL_checkfixed(L, -1);
|
||||
else
|
||||
slope->o.z = 0;
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
case slope_zdelta: { // zdelta, this is temp until i figure out wtf to do
|
||||
slope->zdelta = luaL_checkfixed(L, 3);
|
||||
slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, -slope->zdelta);
|
||||
P_CalculateSlopeNormal(slope);
|
||||
break;
|
||||
}
|
||||
case slope_zangle: { // zangle
|
||||
angle_t zangle = luaL_checkangle(L, 3);
|
||||
if (zangle == ANGLE_90 || zangle == ANGLE_270)
|
||||
return luaL_error(L, "invalid zangle for slope!");
|
||||
slope->zangle = zangle;
|
||||
slope->zdelta = -FINETANGENT(((slope->zangle+ANGLE_90)>>ANGLETOFINESHIFT) & 4095);
|
||||
P_CalculateSlopeNormal(slope);
|
||||
break;
|
||||
}
|
||||
case slope_xydirection: // xydirection
|
||||
slope->xydirection = luaL_checkangle(L, 3);
|
||||
slope->d.x = -FINECOSINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
slope->d.y = -FINESINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
P_CalculateSlopeNormal(slope);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vector2_get(lua_State *L)
|
||||
{
|
||||
vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2));
|
||||
enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector2_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vector_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vector_y: lua_pushfixed(L, vec->y); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vector3_get(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = *((vector3_t **)luaL_checkudata(L, 1, META_VECTOR3));
|
||||
enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector3_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vector_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vector_y: lua_pushfixed(L, vec->y); return 1;
|
||||
case vector_z: lua_pushfixed(L, vec->z); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lib_getMapheaderinfo(lua_State *L)
|
||||
{
|
||||
// i -> mapheaderinfo[i-1]
|
||||
|
@ -1317,6 +1592,26 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
#ifdef ESLOPE
|
||||
luaL_newmetatable(L, META_SLOPE);
|
||||
lua_pushcfunction(L, slope_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, slope_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR2);
|
||||
lua_pushcfunction(L, vector2_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR3);
|
||||
lua_pushcfunction(L, vector3_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
#endif
|
||||
|
||||
luaL_newmetatable(L, META_MAPHEADER);
|
||||
lua_pushcfunction(L, mapheaderinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
@ -80,7 +80,12 @@ enum mobj_e {
|
|||
mobj_extravalue1,
|
||||
mobj_extravalue2,
|
||||
mobj_cusval,
|
||||
#ifdef ESLOPE
|
||||
mobj_cvmem,
|
||||
mobj_standingslope
|
||||
#else
|
||||
mobj_cvmem
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char *const mobj_opt[] = {
|
||||
|
@ -140,6 +145,9 @@ static const char *const mobj_opt[] = {
|
|||
"extravalue2",
|
||||
"cusval",
|
||||
"cvmem",
|
||||
#ifdef ESLOPE
|
||||
"standingslope",
|
||||
#endif
|
||||
NULL};
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
|
||||
|
@ -343,6 +351,11 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_cvmem:
|
||||
lua_pushinteger(L, mo->cvmem);
|
||||
break;
|
||||
#ifdef ESLOPE
|
||||
case mobj_standingslope:
|
||||
LUA_PushUserdata(L, mo->standingslope, META_SLOPE);
|
||||
break;
|
||||
#endif
|
||||
default: // extra custom variables in Lua memory
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
@ -634,6 +647,10 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_cvmem:
|
||||
mo->cvmem = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
#ifdef ESLOPE
|
||||
case mobj_standingslope:
|
||||
return NOSET;
|
||||
#endif
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
|
108
src/lua_script.c
108
src/lua_script.c
|
@ -22,6 +22,9 @@
|
|||
#include "byteptr.h"
|
||||
#include "p_saveg.h"
|
||||
#include "p_local.h"
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h" // for P_SlopeById
|
||||
#endif
|
||||
#ifdef LUA_ALLOW_BYTECODE
|
||||
#include "d_netfil.h" // for LUA_DumpFile
|
||||
#endif
|
||||
|
@ -170,6 +173,7 @@ static inline void LUA_LoadFile(MYFILE *f, char *name)
|
|||
LUA_ClearState();
|
||||
lua_pushinteger(gL, f->wad);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "WAD");
|
||||
|
||||
if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, 0)) {
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
|
||||
lua_pop(gL,1);
|
||||
|
@ -189,17 +193,23 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
|||
W_ReadLumpPwad(wad, lump, f.data);
|
||||
f.curpos = f.data;
|
||||
|
||||
len = strlen(wadfiles[wad]->filename);
|
||||
name = malloc(len+10);
|
||||
strcpy(name, wadfiles[wad]->filename);
|
||||
if (!fasticmp(&name[len - 4], ".lua")) {
|
||||
// If it's not a .lua file, copy the lump name in too.
|
||||
name[len] = '|';
|
||||
M_Memcpy(name+len+1, wadfiles[wad]->lumpinfo[lump].name, 8);
|
||||
name[len+9] = '\0';
|
||||
len = strlen(wadfiles[wad]->filename); // length of file name
|
||||
|
||||
if (wadfiles[wad]->type == RET_LUA)
|
||||
{
|
||||
name = malloc(len+1);
|
||||
strcpy(name, wadfiles[wad]->filename);
|
||||
}
|
||||
else // If it's not a .lua file, copy the lump name in too.
|
||||
{
|
||||
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
||||
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
name = malloc(len+1);
|
||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
|
||||
name[len] = '\0';
|
||||
}
|
||||
|
||||
LUA_LoadFile(&f, name);
|
||||
LUA_LoadFile(&f, name); // actually load file!
|
||||
|
||||
free(name);
|
||||
Z_Free(f.data);
|
||||
|
@ -457,6 +467,9 @@ enum
|
|||
ARCH_SIDE,
|
||||
ARCH_SUBSECTOR,
|
||||
ARCH_SECTOR,
|
||||
#ifdef ESLOPE
|
||||
ARCH_SLOPE,
|
||||
#endif
|
||||
ARCH_MAPHEADER,
|
||||
|
||||
ARCH_TEND=0xFF,
|
||||
|
@ -476,6 +489,9 @@ static const struct {
|
|||
{META_SIDE, ARCH_SIDE},
|
||||
{META_SUBSECTOR,ARCH_SUBSECTOR},
|
||||
{META_SECTOR, ARCH_SECTOR},
|
||||
#ifdef ESLOPE
|
||||
{META_SLOPE, ARCH_SLOPE},
|
||||
#endif
|
||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||
{NULL, ARCH_NULL}
|
||||
};
|
||||
|
@ -528,9 +544,23 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
break;
|
||||
}
|
||||
case LUA_TSTRING:
|
||||
{
|
||||
UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros
|
||||
const char *s = lua_tostring(gL, myindex);
|
||||
UINT16 i = 0;
|
||||
WRITEUINT8(save_p, ARCH_STRING);
|
||||
WRITESTRING(save_p, lua_tostring(gL, myindex));
|
||||
// if you're wondering why we're writing a string to save_p this way,
|
||||
// it turns out that Lua can have embedded zeros ('\0') in the strings,
|
||||
// so we can't use WRITESTRING as that cuts off when it finds a '\0'.
|
||||
// Saving the size of the string also allows us to get the size of the string on the other end,
|
||||
// fixing the awful crashes previously encountered for reading strings longer than 1024
|
||||
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
|
||||
// -- Monster Iestyn 05/08/18
|
||||
WRITEUINT16(save_p, len); // save size of string
|
||||
while (i < len)
|
||||
WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros
|
||||
break;
|
||||
}
|
||||
case LUA_TTABLE:
|
||||
{
|
||||
boolean found = false;
|
||||
|
@ -666,6 +696,19 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
case ARCH_SLOPE:
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
|
||||
if (!slope)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SLOPE);
|
||||
WRITEUINT16(save_p, slope->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ARCH_MAPHEADER:
|
||||
{
|
||||
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
||||
|
@ -769,11 +812,19 @@ static void ArchiveTables(void)
|
|||
lua_pushnil(gL);
|
||||
while (lua_next(gL, -2))
|
||||
{
|
||||
ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
|
||||
// Write key
|
||||
e = ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
|
||||
if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise)
|
||||
{
|
||||
lua_pushvalue(gL, -2);
|
||||
CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -1), luaL_typename(gL, -1), i);
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
// Write value
|
||||
e = ArchiveValue(TABLESINDEX, -1);
|
||||
if (e == 1)
|
||||
n++; // the table contained a new table we'll have to archive. :(
|
||||
else if (e == 2)
|
||||
else if (e == 2) // invalid value type
|
||||
{
|
||||
lua_pushvalue(gL, -2);
|
||||
CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1));
|
||||
|
@ -803,9 +854,19 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
break;
|
||||
case ARCH_STRING:
|
||||
{
|
||||
char value[1024];
|
||||
READSTRING(save_p, value);
|
||||
lua_pushstring(gL, value);
|
||||
UINT16 len = READUINT16(save_p); // length of string, including embedded zeros
|
||||
char *value;
|
||||
UINT16 i = 0;
|
||||
// See my comments in the ArchiveValue function;
|
||||
// it's much the same for reading strings as writing them!
|
||||
// (i.e. we can't use READSTRING either)
|
||||
// -- Monster Iestyn 05/08/18
|
||||
value = malloc(len); // make temp buffer of size len
|
||||
// now read the actual string
|
||||
while (i < len)
|
||||
value[i++] = READCHAR(save_p); // read chars individually, including the embedded zeros
|
||||
lua_pushlstring(gL, value, len); // push the string (note: this function supports embedded zeros)
|
||||
free(value); // free the buffer
|
||||
break;
|
||||
}
|
||||
case ARCH_TABLE:
|
||||
|
@ -852,6 +913,11 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
case ARCH_SECTOR:
|
||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR);
|
||||
break;
|
||||
#ifdef ESLOPE
|
||||
case ARCH_SLOPE:
|
||||
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
|
||||
break;
|
||||
#endif
|
||||
case ARCH_MAPHEADER:
|
||||
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
|
||||
break;
|
||||
|
@ -915,11 +981,17 @@ static void UnArchiveTables(void)
|
|||
lua_rawgeti(gL, TABLESINDEX, i);
|
||||
while (true)
|
||||
{
|
||||
if (UnArchiveValue(TABLESINDEX) == 1)
|
||||
if (UnArchiveValue(TABLESINDEX) == 1) // read key
|
||||
break;
|
||||
if (UnArchiveValue(TABLESINDEX) == 2)
|
||||
if (UnArchiveValue(TABLESINDEX) == 2) // read value
|
||||
n++;
|
||||
lua_rawset(gL, -3);
|
||||
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "A nil key in table %d was found! (Invalid key type or corrupted save?)\n", i);
|
||||
lua_pop(gL, 2); // pop key and value instead of setting them in the table, to prevent Lua panic errors
|
||||
}
|
||||
else
|
||||
lua_rawset(gL, -3);
|
||||
}
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
|
|
@ -214,4 +214,4 @@ void M_FindResponseFile(void)
|
|||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
95
src/m_menu.c
95
src/m_menu.c
|
@ -270,7 +270,7 @@ static void M_SetupMultiPlayer2(INT32 choice);
|
|||
// Split into multiple parts due to size
|
||||
// Controls
|
||||
menu_t OP_ControlsDef, OP_ControlListDef, OP_MoveControlsDef;
|
||||
menu_t OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef;
|
||||
menu_t OP_MPControlsDef, OP_MiscControlsDef;
|
||||
menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef;
|
||||
menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def;
|
||||
static void M_VideoModeMenu(INT32 choice);
|
||||
|
@ -1021,20 +1021,30 @@ static menuitem_t OP_ControlListMenu[] =
|
|||
{
|
||||
{IT_SUBMENU | IT_STRING, NULL, "Movement Controls...", &OP_MoveControlsDef, 10},
|
||||
{IT_SUBMENU | IT_STRING, NULL, "Multiplayer Controls...", &OP_MPControlsDef, 20},
|
||||
{IT_SUBMENU | IT_STRING, NULL, "Camera Controls...", &OP_CameraControlsDef, 30},
|
||||
{IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 40},
|
||||
{IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 30},
|
||||
};
|
||||
|
||||
static menuitem_t OP_MoveControlsMenu[] =
|
||||
{
|
||||
{IT_CALL | IT_STRING2, NULL, "Forward", M_ChangeControl, gc_forward },
|
||||
{IT_CALL | IT_STRING2, NULL, "Reverse", M_ChangeControl, gc_backward },
|
||||
{IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft },
|
||||
{IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright },
|
||||
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump },
|
||||
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use },
|
||||
{IT_CALL | IT_STRING2, NULL, "Strafe Left", M_ChangeControl, gc_strafeleft },
|
||||
{IT_CALL | IT_STRING2, NULL, "Strafe Right", M_ChangeControl, gc_straferight},
|
||||
{IT_HEADER, NULL, " Movement", NULL, 0},
|
||||
{IT_CALL | IT_STRING2, NULL, "Move Forward", M_ChangeControl, gc_forward },
|
||||
{IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, gc_backward },
|
||||
{IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, gc_strafeleft },
|
||||
{IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, gc_straferight },
|
||||
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump },
|
||||
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use },
|
||||
{IT_HEADER, NULL, " Camera", NULL, 0},
|
||||
{IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup },
|
||||
{IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown },
|
||||
{IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft },
|
||||
{IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright },
|
||||
{IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview },
|
||||
{IT_CALL | IT_STRING2, NULL, "Toggle Mouselook", M_ChangeControl, gc_mouseaiming },
|
||||
{IT_CALL | IT_STRING2, NULL, "Toggle Third-Person", M_ChangeControl, gc_camtoggle},
|
||||
{IT_CALL | IT_STRING2, NULL, "Reset Camera", M_ChangeControl, gc_camreset },
|
||||
{IT_HEADER, NULL, " Advanced", NULL, 0},
|
||||
{IT_CALL | IT_STRING2, NULL, "Rotate Camera L", M_ChangeControl, gc_camleft },
|
||||
{IT_CALL | IT_STRING2, NULL, "Rotate Camera R", M_ChangeControl, gc_camright },
|
||||
};
|
||||
|
||||
static menuitem_t OP_MPControlsMenu[] =
|
||||
|
@ -1056,18 +1066,6 @@ static menuitem_t OP_MPControlsMenu[] =
|
|||
{IT_CALL | IT_STRING2, NULL, "Ring Toss Normal", M_ChangeControl, gc_firenormal },
|
||||
};
|
||||
|
||||
static menuitem_t OP_CameraControlsMenu[] =
|
||||
{
|
||||
{IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup },
|
||||
{IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown },
|
||||
{IT_CALL | IT_STRING2, NULL, "Rotate Camera L", M_ChangeControl, gc_camleft },
|
||||
{IT_CALL | IT_STRING2, NULL, "Rotate Camera R", M_ChangeControl, gc_camright },
|
||||
{IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview },
|
||||
{IT_CALL | IT_STRING2, NULL, "Mouselook", M_ChangeControl, gc_mouseaiming },
|
||||
{IT_CALL | IT_STRING2, NULL, "Reset Camera", M_ChangeControl, gc_camreset },
|
||||
{IT_CALL | IT_STRING2, NULL, "Toggle Chasecam", M_ChangeControl, gc_camtoggle },
|
||||
};
|
||||
|
||||
static menuitem_t OP_MiscControlsMenu[] =
|
||||
{
|
||||
{IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 },
|
||||
|
@ -1116,13 +1114,14 @@ static menuitem_t OP_MouseOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10},
|
||||
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Always MouseLook", &cv_alwaysfreelook, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "First-Person MouseLook", &cv_alwaysfreelook, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 60},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Mouse X Speed", &cv_mousesens, 60},
|
||||
NULL, "Mouse X Speed", &cv_mousesens, 70},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Mouse Y Speed", &cv_mouseysens, 70},
|
||||
NULL, "Mouse Y Speed", &cv_mouseysens, 80},
|
||||
};
|
||||
|
||||
static menuitem_t OP_Mouse2OptionsMenu[] =
|
||||
|
@ -1130,13 +1129,14 @@ static menuitem_t OP_Mouse2OptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Use Mouse 2", &cv_usemouse2, 10},
|
||||
{IT_STRING | IT_CVAR, NULL, "Second Mouse Serial Port",
|
||||
&cv_mouse2port, 20},
|
||||
{IT_STRING | IT_CVAR, NULL, "Always MouseLook", &cv_alwaysfreelook2, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove2, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse2, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "First-Person MouseLook", &cv_alwaysfreelook2, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook2, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove2, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse2, 60},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Mouse X Speed", &cv_mousesens2, 60},
|
||||
NULL, "Mouse X Speed", &cv_mousesens2, 70},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Mouse Y Speed", &cv_mouseysens2, 70},
|
||||
NULL, "Mouse Y Speed", &cv_mouseysens2, 80},
|
||||
};
|
||||
|
||||
static menuitem_t OP_VideoOptionsMenu[] =
|
||||
|
@ -1656,7 +1656,6 @@ menu_t OP_ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlsMenu, &OP_MainDe
|
|||
menu_t OP_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30);
|
||||
menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlListDef);
|
||||
menu_t OP_MPControlsDef = CONTROLMENUSTYLE(OP_MPControlsMenu, &OP_ControlListDef);
|
||||
menu_t OP_CameraControlsDef = CONTROLMENUSTYLE(OP_CameraControlsMenu, &OP_ControlListDef);
|
||||
menu_t OP_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef);
|
||||
menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30);
|
||||
menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30);
|
||||
|
@ -6856,6 +6855,7 @@ static void M_DrawControl(void)
|
|||
}
|
||||
|
||||
static INT32 controltochange;
|
||||
static char controltochangetext[55];
|
||||
|
||||
static void M_ChangecontrolResponse(event_t *ev)
|
||||
{
|
||||
|
@ -6863,8 +6863,8 @@ static void M_ChangecontrolResponse(event_t *ev)
|
|||
INT32 found;
|
||||
INT32 ch = ev->data1;
|
||||
|
||||
// ESCAPE cancels
|
||||
if (ch != KEY_ESCAPE)
|
||||
// ESCAPE cancels; dummy out PAUSE
|
||||
if (ch != KEY_ESCAPE && ch != KEY_PAUSE)
|
||||
{
|
||||
|
||||
switch (ev->type)
|
||||
|
@ -6923,8 +6923,28 @@ static void M_ChangecontrolResponse(event_t *ev)
|
|||
G_CheckDoubleUsage(ch);
|
||||
setupcontrols[control][found] = ch;
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_strpst);
|
||||
}
|
||||
else if (ch == KEY_PAUSE)
|
||||
{
|
||||
static char tmp[155];
|
||||
menu_t *prev = currentMenu->prevMenu;
|
||||
|
||||
if (controltochange == gc_pause)
|
||||
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"),
|
||||
controltochangetext);
|
||||
else
|
||||
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"),
|
||||
controltochangetext);
|
||||
|
||||
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
||||
currentMenu->prevMenu = prev;
|
||||
|
||||
S_StartSound(NULL, sfx_s3k42);
|
||||
return;
|
||||
}
|
||||
else
|
||||
S_StartSound(NULL, sfx_skid);
|
||||
|
||||
M_StopMessage(0);
|
||||
}
|
||||
|
@ -6936,6 +6956,7 @@ static void M_ChangeControl(INT32 choice)
|
|||
controltochange = currentMenu->menuitems[choice].alphaKey;
|
||||
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
||||
currentMenu->menuitems[choice].text);
|
||||
strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55);
|
||||
|
||||
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
||||
}
|
||||
|
|
|
@ -811,6 +811,8 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
|||
{
|
||||
bouncer->sector->ceilingheight = actionsector->ceilingheight;
|
||||
bouncer->sector->floorheight = bouncer->sector->ceilingheight - (halfheight*2);
|
||||
T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling
|
||||
T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor
|
||||
P_RecalcPrecipInSector(actionsector);
|
||||
bouncer->sector->ceilingdata = NULL;
|
||||
bouncer->sector->floordata = NULL;
|
||||
|
@ -825,6 +827,8 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
|||
{
|
||||
bouncer->sector->ceilingheight = floorheight + (halfheight << 1);
|
||||
bouncer->sector->floorheight = floorheight;
|
||||
T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling
|
||||
T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor
|
||||
P_RecalcPrecipInSector(actionsector);
|
||||
bouncer->sector->ceilingdata = NULL;
|
||||
bouncer->sector->floordata = NULL;
|
||||
|
@ -841,9 +845,9 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
|||
}
|
||||
|
||||
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight -
|
||||
70*FRACUNIT, 0, 1, -1); // move floor
|
||||
70*FRACUNIT, 0, 1, -1); // move ceiling
|
||||
T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT,
|
||||
0, 0, -1); // move ceiling
|
||||
0, 0, -1); // move floor
|
||||
|
||||
bouncer->sector->floorspeed = -bouncer->speed/2;
|
||||
bouncer->sector->ceilspeed = 42;
|
||||
|
@ -893,6 +897,8 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
|||
{
|
||||
bouncer->sector->floorheight = bouncer->floorwasheight;
|
||||
bouncer->sector->ceilingheight = bouncer->ceilingwasheight;
|
||||
T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling
|
||||
T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor
|
||||
bouncer->sector->ceilingdata = NULL;
|
||||
bouncer->sector->floordata = NULL;
|
||||
bouncer->sector->floorspeed = 0;
|
||||
|
@ -1818,6 +1824,7 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
#define ceilingwasheight vars[5]
|
||||
fixed_t thwompx, thwompy;
|
||||
sector_t *actionsector;
|
||||
ffloor_t *rover = NULL;
|
||||
INT32 secnum;
|
||||
|
||||
// If you just crashed down, wait a second before coming back up.
|
||||
|
@ -1832,7 +1839,16 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
|
||||
|
||||
if (secnum > 0)
|
||||
{
|
||||
actionsector = §ors[secnum];
|
||||
|
||||
// Look for thwomp FFloor
|
||||
for (rover = actionsector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master == thwomp->sourceline)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return; // Bad bad bad!
|
||||
|
||||
|
@ -1921,10 +1937,13 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
{
|
||||
mobj_t *mp = (void *)&actionsector->soundorg;
|
||||
|
||||
if (thwomp->sourceline->flags & ML_EFFECT4)
|
||||
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
||||
else
|
||||
S_StartSound(mp, sfx_thwomp);
|
||||
if (!rover || (rover->flags & FF_EXISTS))
|
||||
{
|
||||
if (thwomp->sourceline->flags & ML_EFFECT4)
|
||||
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
||||
else
|
||||
S_StartSound(mp, sfx_thwomp);
|
||||
}
|
||||
|
||||
thwomp->direction = 1; // start heading back up
|
||||
thwomp->distance = TICRATE; // but only after a small delay
|
||||
|
@ -1938,18 +1957,22 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
thinker_t *th;
|
||||
mobj_t *mo;
|
||||
|
||||
// scan the thinkers to find players!
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
if (!rover || (rover->flags & FF_EXISTS))
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
if (mo->type == MT_PLAYER && mo->health && mo->z <= thwomp->sector->ceilingheight
|
||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||
// scan the thinkers to find players!
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
thwomp->direction = -1;
|
||||
break;
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator
|
||||
&& mo->z <= thwomp->sector->ceilingheight
|
||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||
{
|
||||
thwomp->direction = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2103,6 +2126,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
boolean floortouch = false;
|
||||
fixed_t bottomheight, topheight;
|
||||
msecnode_t *node;
|
||||
ffloor_t *rover;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -2150,6 +2174,19 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
{
|
||||
targetsec = §ors[targetsecnum];
|
||||
|
||||
// Find the FOF corresponding to the control linedef
|
||||
for (rover = targetsec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master == sec->lines[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rover) // This should be impossible, but don't complain if it is the case somehow
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
if (!playeringame[j])
|
||||
|
|
|
@ -777,14 +777,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
// not (your direction) xor (stored direction)
|
||||
// In other words, you can't u-turn and respawn rings near the drone.
|
||||
if (pl->bonustime && (pl->pflags & PF_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && (
|
||||
!(pl->anotherflyangle >= 90 && pl->anotherflyangle <= 270)
|
||||
^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270)
|
||||
!(pl->flyangle > 90 && pl->flyangle < 270)
|
||||
^ (droneobj->extravalue1 > 90 && droneobj->extravalue1 < 270)
|
||||
))
|
||||
{
|
||||
// Reload all the fancy ring stuff!
|
||||
P_ReloadRings();
|
||||
}
|
||||
droneobj->extravalue1 = pl->anotherflyangle;
|
||||
droneobj->extravalue1 = pl->flyangle;
|
||||
droneobj->extravalue2 = (INT32)leveltime + TICRATE;
|
||||
}
|
||||
|
||||
|
|
11
src/p_mobj.c
11
src/p_mobj.c
|
@ -9198,9 +9198,6 @@ ML_NOCLIMB : Direction not controllable
|
|||
// the bumper in 30 degree increments.
|
||||
mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold);
|
||||
|
||||
// you can shut up now, OBJECTFLIP. And all of the other options, for that matter.
|
||||
mthing->options &= ~0xF;
|
||||
break;
|
||||
case MT_EGGCAPSULE:
|
||||
if (mthing->angle <= 0)
|
||||
|
@ -9388,6 +9385,14 @@ ML_NOCLIMB : Direction not controllable
|
|||
}
|
||||
}
|
||||
|
||||
// ignore MTF_ flags and return early
|
||||
if (i == MT_NIGHTSBUMPER)
|
||||
{
|
||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
||||
mthing->mobj = mobj;
|
||||
return;
|
||||
}
|
||||
|
||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
||||
|
||||
if ((mthing->options & MTF_AMBUSH)
|
||||
|
|
|
@ -489,16 +489,34 @@ static void P_NetArchiveWorld(void)
|
|||
UINT8 *put;
|
||||
|
||||
// reload the map just to see difference
|
||||
const mapsector_t *ms;
|
||||
const mapsidedef_t *msd;
|
||||
const maplinedef_t *mld;
|
||||
mapsector_t *ms;
|
||||
mapsidedef_t *msd;
|
||||
maplinedef_t *mld;
|
||||
const sector_t *ss = sectors;
|
||||
UINT8 diff, diff2;
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||
put = save_p;
|
||||
|
||||
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can get the data from the relevant lumps
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
#define retrieve_mapdata(d, f)\
|
||||
d = Z_Malloc((f)->size, PU_CACHE, NULL); \
|
||||
M_Memcpy(d, wadData + (f)->filepos, (f)->size)
|
||||
retrieve_mapdata(ms, fileinfo + ML_SECTORS);
|
||||
retrieve_mapdata(mld, fileinfo + ML_LINEDEFS);
|
||||
retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS);
|
||||
#undef retrieve_mapdata
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
{
|
||||
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
|
||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
||||
}
|
||||
|
||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||
{
|
||||
|
@ -950,6 +968,7 @@ typedef enum
|
|||
tc_bouncecheese,
|
||||
tc_startcrumble,
|
||||
tc_marioblock,
|
||||
tc_marioblockchecker,
|
||||
tc_spikesector,
|
||||
tc_floatsector,
|
||||
tc_bridgethinker,
|
||||
|
@ -1259,7 +1278,10 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
|
|||
size_t i;
|
||||
WRITEUINT8(save_p, type);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
||||
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
|
||||
}
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
}
|
||||
|
@ -1772,6 +1794,11 @@ static void P_NetArchiveThinkers(void)
|
|||
SaveSpecialLevelThinker(th, tc_marioblock);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_marioblockchecker);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_spikesector);
|
||||
|
@ -2155,7 +2182,10 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
|
|||
size_t i;
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ht->vars[i] = READFIXED(save_p); //var[16]
|
||||
ht->var2s[i] = READFIXED(save_p); //var[16]
|
||||
}
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
|
||||
|
@ -2728,6 +2758,10 @@ static void P_NetUnArchiveThinkers(void)
|
|||
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
||||
break;
|
||||
|
||||
case tc_marioblockchecker:
|
||||
LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
|
||||
break;
|
||||
|
||||
case tc_spikesector:
|
||||
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
||||
break;
|
||||
|
|
439
src/p_setup.c
439
src/p_setup.c
|
@ -348,16 +348,13 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade)
|
|||
* \param lump VERTEXES lump number.
|
||||
* \sa ML_VERTEXES
|
||||
*/
|
||||
static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||
|
||||
static inline void P_LoadRawVertexes(UINT8 *data, size_t i)
|
||||
{
|
||||
UINT8 *data;
|
||||
size_t i;
|
||||
mapvertex_t *ml;
|
||||
vertex_t *li;
|
||||
|
||||
// Determine number of lumps:
|
||||
// total lump length / vertex record length.
|
||||
numvertexes = W_LumpLength(lumpnum) / sizeof (mapvertex_t);
|
||||
numvertexes = i / sizeof (mapvertex_t);
|
||||
|
||||
if (numvertexes <= 0)
|
||||
I_Error("Level has no vertices"); // instead of crashing
|
||||
|
@ -365,9 +362,6 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
|||
// Allocate zone memory for buffer.
|
||||
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
||||
|
||||
// Load data into cache.
|
||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
|
||||
ml = (mapvertex_t *)data;
|
||||
li = vertexes;
|
||||
|
||||
|
@ -377,11 +371,16 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
|||
li->x = SHORT(ml->x)<<FRACBITS;
|
||||
li->y = SHORT(ml->y)<<FRACBITS;
|
||||
}
|
||||
}
|
||||
|
||||
// Free buffer memory.
|
||||
static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawVertexes(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Computes the line length in fracunits, the OpenGL render needs this
|
||||
//
|
||||
|
@ -421,20 +420,17 @@ static inline float P_SegLengthf(seg_t *seg)
|
|||
* \param lump Lump number of the SEGS resource.
|
||||
* \sa ::ML_SEGS
|
||||
*/
|
||||
static void P_LoadSegs(lumpnum_t lumpnum)
|
||||
static void P_LoadRawSegs(UINT8 *data, size_t i)
|
||||
{
|
||||
UINT8 *data;
|
||||
size_t i;
|
||||
INT32 linedef, side;
|
||||
mapseg_t *ml;
|
||||
seg_t *li;
|
||||
line_t *ldef;
|
||||
|
||||
numsegs = W_LumpLength(lumpnum) / sizeof (mapseg_t);
|
||||
numsegs = i / sizeof (mapseg_t);
|
||||
if (numsegs <= 0)
|
||||
I_Error("Level has no segs"); // instead of crashing
|
||||
segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL);
|
||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
|
||||
ml = (mapseg_t *)data;
|
||||
li = segs;
|
||||
|
@ -470,27 +466,30 @@ static void P_LoadSegs(lumpnum_t lumpnum)
|
|||
li->numlights = 0;
|
||||
li->rlights = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void P_LoadSegs(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawSegs(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
|
||||
/** Loads the SSECTORS resource from a level.
|
||||
*
|
||||
* \param lump Lump number of the SSECTORS resource.
|
||||
* \sa ::ML_SSECTORS
|
||||
*/
|
||||
static inline void P_LoadSubsectors(lumpnum_t lumpnum)
|
||||
static inline void P_LoadRawSubsectors(void *data, size_t i)
|
||||
{
|
||||
void *data;
|
||||
size_t i;
|
||||
mapsubsector_t *ms;
|
||||
subsector_t *ss;
|
||||
|
||||
numsubsectors = W_LumpLength(lumpnum) / sizeof (mapsubsector_t);
|
||||
numsubsectors = i / sizeof (mapsubsector_t);
|
||||
if (numsubsectors <= 0)
|
||||
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
|
||||
ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL);
|
||||
data = W_CacheLumpNum(lumpnum,PU_STATIC);
|
||||
|
||||
ms = (mapsubsector_t *)data;
|
||||
|
||||
|
@ -504,7 +503,12 @@ static inline void P_LoadSubsectors(lumpnum_t lumpnum)
|
|||
#endif
|
||||
ss->validcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void P_LoadSubsectors(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawSubsectors(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
|
@ -638,29 +642,31 @@ INT32 P_CheckLevelFlat(const char *flatname)
|
|||
return (INT32)i;
|
||||
}
|
||||
|
||||
static void P_LoadSectors(lumpnum_t lumpnum)
|
||||
// Sets up the ingame sectors structures.
|
||||
// Lumpnum is the lumpnum of a SECTORS lump.
|
||||
static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||
{
|
||||
UINT8 *data;
|
||||
size_t i;
|
||||
mapsector_t *ms;
|
||||
sector_t *ss;
|
||||
levelflat_t *foundflats;
|
||||
|
||||
numsectors = W_LumpLength(lumpnum) / sizeof (mapsector_t);
|
||||
// We count how many sectors we got.
|
||||
numsectors = i / sizeof (mapsector_t);
|
||||
if (numsectors <= 0)
|
||||
I_Error("Level has no sectors");
|
||||
|
||||
// Allocate as much memory as we need into the global sectors table.
|
||||
sectors = Z_Calloc(numsectors*sizeof (*sectors), PU_LEVEL, NULL);
|
||||
data = W_CacheLumpNum(lumpnum,PU_STATIC);
|
||||
|
||||
//Fab : FIXME: allocate for whatever number of flats
|
||||
// 512 different flats per level should be plenty
|
||||
|
||||
// Allocate a big chunk of memory as big as our MAXLEVELFLATS limit.
|
||||
//Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty
|
||||
foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats));
|
||||
if (foundflats == NULL)
|
||||
I_Error("Ran out of memory while loading sectors\n");
|
||||
|
||||
numlevelflats = 0;
|
||||
|
||||
// For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss.
|
||||
ms = (mapsector_t *)data;
|
||||
ss = sectors;
|
||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||
|
@ -668,9 +674,6 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
|||
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
||||
ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
|
||||
|
||||
//
|
||||
// flats
|
||||
//
|
||||
ss->floorpic = P_AddLevelFlat(ms->floorpic, foundflats);
|
||||
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
||||
|
||||
|
@ -735,8 +738,6 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
|||
#endif // ----- end special tricks -----
|
||||
}
|
||||
|
||||
Z_Free(data);
|
||||
|
||||
// set the sky flat num
|
||||
skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats);
|
||||
|
||||
|
@ -748,22 +749,26 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
|||
P_SetupLevelFlatAnims();
|
||||
}
|
||||
|
||||
static void P_LoadSectors(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawSectors(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
//
|
||||
// P_LoadNodes
|
||||
//
|
||||
static void P_LoadNodes(lumpnum_t lumpnum)
|
||||
static void P_LoadRawNodes(UINT8 *data, size_t i)
|
||||
{
|
||||
UINT8 *data;
|
||||
size_t i;
|
||||
UINT8 j, k;
|
||||
mapnode_t *mn;
|
||||
node_t *no;
|
||||
|
||||
numnodes = W_LumpLength(lumpnum) / sizeof (mapnode_t);
|
||||
numnodes = i / sizeof (mapnode_t);
|
||||
if (numnodes <= 0)
|
||||
I_Error("Level has no nodes");
|
||||
nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL);
|
||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
|
||||
mn = (mapnode_t *)data;
|
||||
no = nodes;
|
||||
|
@ -781,7 +786,12 @@ static void P_LoadNodes(lumpnum_t lumpnum)
|
|||
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void P_LoadNodes(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawNodes(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
|
@ -916,18 +926,16 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
|||
//
|
||||
// P_LoadThings
|
||||
//
|
||||
static void P_PrepareThings(lumpnum_t lumpnum)
|
||||
{
|
||||
size_t i;
|
||||
mapthing_t *mt;
|
||||
UINT8 *data, *datastart;
|
||||
|
||||
nummapthings = W_LumpLength(lumpnum) / (5 * sizeof (INT16));
|
||||
static void P_PrepareRawThings(UINT8 *data, size_t i)
|
||||
{
|
||||
mapthing_t *mt;
|
||||
|
||||
nummapthings = i / (5 * sizeof (INT16));
|
||||
mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
||||
|
||||
// Spawn axis points first so they are
|
||||
// at the front of the list for fast searching.
|
||||
data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||
mt = mapthings;
|
||||
for (i = 0; i < nummapthings; i++, mt++)
|
||||
{
|
||||
|
@ -952,8 +960,13 @@ static void P_PrepareThings(lumpnum_t lumpnum)
|
|||
break;
|
||||
}
|
||||
}
|
||||
Z_Free(datastart);
|
||||
}
|
||||
|
||||
static void P_PrepareThings(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_PrepareRawThings(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
static void P_LoadThings(void)
|
||||
|
@ -1140,22 +1153,16 @@ void P_WriteThings(lumpnum_t lumpnum)
|
|||
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
||||
}
|
||||
|
||||
//
|
||||
// P_LoadLineDefs
|
||||
//
|
||||
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||
static void P_LoadRawLineDefs(UINT8 *data, size_t i)
|
||||
{
|
||||
UINT8 *data;
|
||||
size_t i;
|
||||
maplinedef_t *mld;
|
||||
line_t *ld;
|
||||
vertex_t *v1, *v2;
|
||||
|
||||
numlines = W_LumpLength(lumpnum) / sizeof (maplinedef_t);
|
||||
numlines = i / sizeof (maplinedef_t);
|
||||
if (numlines <= 0)
|
||||
I_Error("Level has no linedefs");
|
||||
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
|
||||
mld = (maplinedef_t *)data;
|
||||
ld = lines;
|
||||
|
@ -1177,7 +1184,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|||
ld->slopetype = ST_VERTICAL;
|
||||
else if (!ld->dy)
|
||||
ld->slopetype = ST_HORIZONTAL;
|
||||
else if (FixedDiv(ld->dy, ld->dx) > 0)
|
||||
else if ((ld->dy > 0) == (ld->dx > 0))
|
||||
ld->slopetype = ST_POSITIVE;
|
||||
else
|
||||
ld->slopetype = ST_NEGATIVE;
|
||||
|
@ -1217,7 +1224,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|||
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
||||
{
|
||||
ld->sidenum[j] = 0xffff;
|
||||
CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1));
|
||||
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1232,14 +1239,14 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|||
{
|
||||
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
||||
// cph - print a warning about the bug
|
||||
CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1));
|
||||
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1));
|
||||
}
|
||||
|
||||
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
||||
{
|
||||
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
||||
// cph - print a warning about the bug
|
||||
CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1));
|
||||
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1));
|
||||
}
|
||||
|
||||
if (ld->sidenum[0] != 0xffff && ld->special)
|
||||
|
@ -1251,7 +1258,12 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|||
ld->polyobj = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawLineDefs(data, W_LumpLength(lumpnum));
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
|
@ -1353,22 +1365,24 @@ static void P_LoadLineDefs2(void)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_LoadSideDefs
|
||||
//
|
||||
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
||||
|
||||
|
||||
static inline void P_LoadRawSideDefs(size_t i)
|
||||
{
|
||||
numsides = W_LumpLength(lumpnum) / sizeof (mapsidedef_t);
|
||||
numsides = i / sizeof (mapsidedef_t);
|
||||
if (numsides <= 0)
|
||||
I_Error("Level has no sidedefs");
|
||||
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
||||
}
|
||||
|
||||
// Delay loading texture names until after loaded linedefs.
|
||||
|
||||
static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
||||
{
|
||||
P_LoadRawSideDefs(W_LumpLength(lumpnum));
|
||||
}
|
||||
|
||||
|
||||
static void P_LoadRawSideDefs2(void *data)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
UINT16 i;
|
||||
INT32 num;
|
||||
|
||||
|
@ -1386,7 +1400,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
|
||||
if (sector_num >= numsectors)
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "P_LoadSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num);
|
||||
CONS_Debug(DBG_SETUP, "P_LoadRawSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num);
|
||||
sector_num = 0;
|
||||
}
|
||||
sd->sector = sec = §ors[sector_num];
|
||||
|
@ -1528,6 +1542,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
sd->text[6] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // Speed pad parameters
|
||||
case 414: // Play SFX
|
||||
{
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
|
@ -1541,6 +1557,9 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
break;
|
||||
}
|
||||
|
||||
case 9: // Mace parameters
|
||||
case 14: // Bustable block parameters
|
||||
case 15: // Fan particle spawner parameters
|
||||
case 425: // Calls P_SetMobjState on calling mobj
|
||||
case 434: // Custom Power
|
||||
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
||||
|
@ -1595,11 +1614,18 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(data);
|
||||
R_ClearTextureNumCache(true);
|
||||
}
|
||||
|
||||
// Delay loading texture names until after loaded linedefs.
|
||||
static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||
P_LoadRawSideDefs2(data);
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
|
||||
static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1)
|
||||
{
|
||||
fixed_t bbox[4];
|
||||
|
@ -1855,6 +1881,30 @@ static void P_CreateBlockMap(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Split from P_LoadBlockMap for convenience
|
||||
// -- Monster Iestyn 08/01/18
|
||||
static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
blockmaplump = Z_Calloc(sizeof (*blockmaplump) * count, PU_LEVEL, NULL);
|
||||
|
||||
// killough 3/1/98: Expand wad blockmap into larger internal one,
|
||||
// by treating all offsets except -1 as unsigned and zero-extending
|
||||
// them. This potentially doubles the size of blockmaps allowed,
|
||||
// because Doom originally considered the offsets as always signed.
|
||||
|
||||
blockmaplump[0] = SHORT(wadblockmaplump[0]);
|
||||
blockmaplump[1] = SHORT(wadblockmaplump[1]);
|
||||
blockmaplump[2] = (INT32)(SHORT(wadblockmaplump[2])) & 0xffff;
|
||||
blockmaplump[3] = (INT32)(SHORT(wadblockmaplump[3])) & 0xffff;
|
||||
|
||||
for (i = 4; i < count; i++)
|
||||
{
|
||||
INT16 t = SHORT(wadblockmaplump[i]); // killough 3/1/98
|
||||
blockmaplump[i] = t == -1 ? (INT32)-1 : (INT32) t & 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_LoadBlockMap
|
||||
//
|
||||
|
@ -1881,38 +1931,20 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
|
|||
return false;
|
||||
|
||||
{
|
||||
size_t i;
|
||||
INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL);
|
||||
|
||||
if (wadblockmaplump) W_ReadLump(lumpnum, wadblockmaplump);
|
||||
else return false;
|
||||
if (!wadblockmaplump)
|
||||
return false;
|
||||
W_ReadLump(lumpnum, wadblockmaplump);
|
||||
count /= 2;
|
||||
blockmaplump = Z_Calloc(sizeof (*blockmaplump) * count, PU_LEVEL, 0);
|
||||
|
||||
// killough 3/1/98: Expand wad blockmap into larger internal one,
|
||||
// by treating all offsets except -1 as unsigned and zero-extending
|
||||
// them. This potentially doubles the size of blockmaps allowed,
|
||||
// because Doom originally considered the offsets as always signed.
|
||||
|
||||
blockmaplump[0] = SHORT(wadblockmaplump[0]);
|
||||
blockmaplump[1] = SHORT(wadblockmaplump[1]);
|
||||
blockmaplump[2] = (INT32)(SHORT(wadblockmaplump[2])) & 0xffff;
|
||||
blockmaplump[3] = (INT32)(SHORT(wadblockmaplump[3])) & 0xffff;
|
||||
|
||||
for (i = 4; i < count; i++)
|
||||
{
|
||||
INT16 t = SHORT(wadblockmaplump[i]); // killough 3/1/98
|
||||
blockmaplump[i] = t == -1 ? (INT32)-1 : (INT32) t & 0xffff;
|
||||
}
|
||||
|
||||
P_ReadBlockMapLump(wadblockmaplump, count);
|
||||
free(wadblockmaplump);
|
||||
|
||||
bmaporgx = blockmaplump[0]<<FRACBITS;
|
||||
bmaporgy = blockmaplump[1]<<FRACBITS;
|
||||
bmapwidth = blockmaplump[2];
|
||||
bmapheight = blockmaplump[3];
|
||||
}
|
||||
|
||||
bmaporgx = blockmaplump[0]<<FRACBITS;
|
||||
bmaporgy = blockmaplump[1]<<FRACBITS;
|
||||
bmapwidth = blockmaplump[2];
|
||||
bmapheight = blockmaplump[3];
|
||||
|
||||
// clear out mobj chains
|
||||
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
|
||||
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
||||
|
@ -1946,6 +1978,53 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
|
|||
#endif
|
||||
}
|
||||
|
||||
// This needs to be a separate function
|
||||
// because making both the WAD and PK3 loading code use
|
||||
// the same functions is trickier than it looks for blockmap
|
||||
// -- Monster Iestyn 09/01/18
|
||||
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname)
|
||||
{
|
||||
#if 0
|
||||
(void)data;
|
||||
(void)count;
|
||||
(void)lumpname;
|
||||
return false;
|
||||
#else
|
||||
// Check if the lump is named "BLOCKMAP"
|
||||
if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0)
|
||||
{
|
||||
CONS_Printf("No blockmap lump found for pk3!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!count || count >= 0x20000)
|
||||
return false;
|
||||
|
||||
CONS_Printf("Reading blockmap lump for pk3...\n");
|
||||
|
||||
// no need to malloc anything, assume the data is uncompressed for now
|
||||
count /= 2;
|
||||
P_ReadBlockMapLump((INT16 *)data, count);
|
||||
|
||||
bmaporgx = blockmaplump[0]<<FRACBITS;
|
||||
bmaporgy = blockmaplump[1]<<FRACBITS;
|
||||
bmapwidth = blockmaplump[2];
|
||||
bmapheight = blockmaplump[3];
|
||||
|
||||
// clear out mobj chains
|
||||
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
|
||||
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
||||
blockmap = blockmaplump+4;
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
// haleyjd 2/22/06: setup polyobject blockmap
|
||||
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
|
||||
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// P_GroupLines
|
||||
// Builds sector line lists and subsector sector numbers.
|
||||
|
@ -2071,6 +2150,30 @@ static void P_LoadReject(lumpnum_t lumpnum)
|
|||
rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||
}
|
||||
|
||||
// PK3 version
|
||||
// -- Monster Iestyn 09/01/18
|
||||
static void P_LoadRawReject(UINT8 *data, size_t count, const char *lumpname)
|
||||
{
|
||||
// Check if the lump is named "REJECT"
|
||||
if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0)
|
||||
{
|
||||
rejectmatrix = NULL;
|
||||
CONS_Debug(DBG_SETUP, "P_LoadRawReject: No valid REJECT lump found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!count) // zero length, someone probably used ZDBSP
|
||||
{
|
||||
rejectmatrix = NULL;
|
||||
CONS_Debug(DBG_SETUP, "P_LoadRawReject: REJECT lump has size 0, will not be loaded\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rejectmatrix = Z_Malloc(count, PU_LEVEL, NULL); // allocate memory for the reject matrix
|
||||
M_Memcpy(rejectmatrix, data, count); // copy the data into it
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static char *levellumps[] =
|
||||
{
|
||||
|
@ -2250,7 +2353,16 @@ void P_LoadThingsOnly(void)
|
|||
|
||||
P_LevelInitStuff();
|
||||
|
||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can use the things lump
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
fileinfo += ML_THINGS; // we only need the THINGS lump
|
||||
P_PrepareRawThings(wadData + fileinfo->filepos, fileinfo->size);
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||
P_LoadThings();
|
||||
|
||||
P_SpawnSecretItems(true);
|
||||
|
@ -2688,7 +2800,12 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
}
|
||||
|
||||
// internal game map
|
||||
lastloadedmaplumpnum = W_GetNumForName(maplumpname = G_BuildMapName(gamemap));
|
||||
maplumpname = G_BuildMapName(gamemap);
|
||||
//lastloadedmaplumpnum = LUMPERROR;
|
||||
lastloadedmaplumpnum = W_CheckNumForName(maplumpname);
|
||||
|
||||
if (lastloadedmaplumpnum == INT16_MAX)
|
||||
I_Error("Map %s not found.\n", maplumpname);
|
||||
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
|
||||
CON_SetupBackColormap();
|
||||
|
@ -2698,38 +2815,93 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
|
||||
P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);
|
||||
|
||||
// note: most of this ordering is important
|
||||
loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP);
|
||||
// HACK ALERT: Cache the WAD, get the map data into the tables, free memory.
|
||||
// As it is implemented right now, we're assuming an uncompressed WAD.
|
||||
// (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.)
|
||||
// We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error.
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum))
|
||||
{
|
||||
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
//filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs;
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
UINT32 numlumps = ((wadinfo_t *)wadData)->numlumps;
|
||||
|
||||
P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES);
|
||||
P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS);
|
||||
if (numlumps < ML_REJECT) // at least 9 lumps should be in the wad for a map to be loaded
|
||||
{
|
||||
I_Error("Bad WAD file for map %s!\n", maplumpname);
|
||||
}
|
||||
|
||||
P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS);
|
||||
if (numlumps > ML_BLOCKMAP) // enough room for a BLOCKMAP lump at least
|
||||
{
|
||||
loadedbm = P_LoadRawBlockMap(
|
||||
wadData + (fileinfo + ML_BLOCKMAP)->filepos,
|
||||
(fileinfo + ML_BLOCKMAP)->size,
|
||||
(fileinfo + ML_BLOCKMAP)->name);
|
||||
}
|
||||
P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size);
|
||||
P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size);
|
||||
P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size);
|
||||
P_LoadRawLineDefs(wadData + (fileinfo + ML_LINEDEFS)->filepos, (fileinfo + ML_LINEDEFS)->size);
|
||||
P_LoadRawSideDefs2(wadData + (fileinfo + ML_SIDEDEFS)->filepos);
|
||||
P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size);
|
||||
P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size);
|
||||
P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size);
|
||||
if (numlumps > ML_REJECT) // enough room for a REJECT lump at least
|
||||
{
|
||||
P_LoadRawReject(
|
||||
wadData + (fileinfo + ML_REJECT)->filepos,
|
||||
(fileinfo + ML_REJECT)->size,
|
||||
(fileinfo + ML_REJECT)->name);
|
||||
}
|
||||
|
||||
P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS);
|
||||
if (!loadedbm)
|
||||
P_CreateBlockMap(); // Graue 02-29-2004
|
||||
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
|
||||
// Important: take care of the ordering of the next functions.
|
||||
if (!loadedbm)
|
||||
P_CreateBlockMap(); // Graue 02-29-2004
|
||||
P_LoadLineDefs2();
|
||||
P_GroupLines();
|
||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||
|
||||
P_LoadLineDefs2();
|
||||
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
|
||||
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
|
||||
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
|
||||
P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
|
||||
P_GroupLines();
|
||||
// reset the player starts
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
playerstarts[i] = NULL;
|
||||
for (i = 0; i < 2; i++)
|
||||
skyboxmo[i] = NULL;
|
||||
P_MapStart();
|
||||
|
||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||
P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size);
|
||||
Z_Free(wadData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Important: take care of the ordering of the next functions.
|
||||
loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP);
|
||||
P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES);
|
||||
P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS);
|
||||
P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS);
|
||||
P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS);
|
||||
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
|
||||
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
|
||||
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
|
||||
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
|
||||
P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
|
||||
|
||||
// reset the player starts
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
playerstarts[i] = NULL;
|
||||
// Important: take care of the ordering of the next functions.
|
||||
if (!loadedbm)
|
||||
P_CreateBlockMap(); // Graue 02-29-2004
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
skyboxmo[i] = NULL;
|
||||
P_LoadLineDefs2();
|
||||
P_GroupLines();
|
||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||
|
||||
P_MapStart();
|
||||
|
||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||
// reset the player starts
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
playerstarts[i] = NULL;
|
||||
for (i = 0; i < 2; i++)
|
||||
skyboxmo[i] = NULL;
|
||||
P_MapStart();
|
||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
P_ResetDynamicSlopes();
|
||||
|
@ -2977,7 +3149,7 @@ boolean P_RunSOC(const char *socfilename)
|
|||
lumpnum_t lump;
|
||||
|
||||
if (strstr(socfilename, ".soc") != NULL)
|
||||
return P_AddWadFile(socfilename, NULL);
|
||||
return P_AddWadFile(socfilename);
|
||||
|
||||
lump = W_CheckNumForName(socfilename);
|
||||
if (lump == LUMPERROR)
|
||||
|
@ -2993,17 +3165,17 @@ boolean P_RunSOC(const char *socfilename)
|
|||
// Add a wadfile to the active wad files,
|
||||
// replace sounds, musics, patches, textures, sprites and maps
|
||||
//
|
||||
boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||
boolean P_AddWadFile(const char *wadfilename)
|
||||
{
|
||||
size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||
UINT16 numlumps, wadnum;
|
||||
INT16 firstmapreplaced = 0, num;
|
||||
char *name;
|
||||
lumpinfo_t *lumpinfo;
|
||||
boolean texturechange = false;
|
||||
boolean mapsadded = false;
|
||||
boolean replacedcurrentmap = false;
|
||||
|
||||
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
||||
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
||||
{
|
||||
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
|
||||
return false;
|
||||
|
@ -3059,6 +3231,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
if (!devparm && digmreplaces)
|
||||
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
||||
|
||||
|
||||
//
|
||||
// search for sprite replacements
|
||||
//
|
||||
|
@ -3093,10 +3266,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
num = firstmapreplaced;
|
||||
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5]!='\0')
|
||||
continue;
|
||||
num = (INT16)M_MapNumber(name[3], name[4]);
|
||||
|
@ -3106,16 +3279,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
replacedcurrentmap = true;
|
||||
|
||||
CONS_Printf("%s\n", name);
|
||||
}
|
||||
|
||||
if (num && (num < firstmapreplaced || !firstmapreplaced))
|
||||
{
|
||||
firstmapreplaced = num;
|
||||
if (firstmapname)
|
||||
*firstmapname = name;
|
||||
mapsadded = true;
|
||||
}
|
||||
}
|
||||
if (!firstmapreplaced)
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
// reload status bar (warning should have valid player!)
|
||||
|
|
|
@ -59,7 +59,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
|
|||
#endif
|
||||
void P_LoadThingsOnly(void);
|
||||
boolean P_SetupLevel(boolean skipprecip);
|
||||
boolean P_AddWadFile(const char *wadfilename, char **firstmapname);
|
||||
boolean P_AddWadFile(const char *wadfilename);
|
||||
#ifdef DELFILE
|
||||
boolean P_DelWadFile(void);
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@ static pslope_t *slopelist = NULL;
|
|||
static UINT16 slopecount = 0;
|
||||
|
||||
// Calculate line normal
|
||||
static void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
|
||||
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define P_SLOPES_H__
|
||||
|
||||
#ifdef ESLOPE
|
||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||
void P_ResetDynamicSlopes(void);
|
||||
void P_RunDynamicSlopes(void);
|
||||
// P_SpawnSlope_Line
|
||||
|
|
48
src/p_spec.c
48
src/p_spec.c
|
@ -279,10 +279,13 @@ void P_InitPicAnims(void)
|
|||
Z_Free(animatedLump);
|
||||
}
|
||||
|
||||
// Now find ANIMDEFS
|
||||
// Find ANIMDEFS lump in the WAD
|
||||
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0);
|
||||
if (animdefsLumpNum != INT16_MAX)
|
||||
while (animdefsLumpNum != INT16_MAX)
|
||||
{
|
||||
P_ParseANIMDEFSLump(w, animdefsLumpNum);
|
||||
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1);
|
||||
}
|
||||
}
|
||||
// Define the last one
|
||||
animdefs[maxanims].istexture = -1;
|
||||
|
@ -6243,9 +6246,21 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 259: // Make-Your-Own FOF!
|
||||
if (lines[i].sidenum[1] != 0xffff)
|
||||
{
|
||||
UINT8 *data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC);
|
||||
UINT8 *data;
|
||||
UINT16 b;
|
||||
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can get the data from the sidedefs lump
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
fileinfo += ML_SIDEDEFS; // we only need the SIDEDEFS lump
|
||||
data = Z_Malloc(fileinfo->size, PU_STATIC, NULL);
|
||||
M_Memcpy(data, wadData + fileinfo->filepos, fileinfo->size); // copy data
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC);
|
||||
|
||||
for (b = 0; b < (INT16)numsides; b++)
|
||||
{
|
||||
register mapsidedef_t *msd = (mapsidedef_t *)data + b;
|
||||
|
@ -6614,6 +6629,7 @@ void T_Scroll(scroll_t *s)
|
|||
line_t *line;
|
||||
size_t i;
|
||||
INT32 sect;
|
||||
ffloor_t *rover;
|
||||
|
||||
case sc_side: // scroll wall texture
|
||||
side = sides + s->affectee;
|
||||
|
@ -6655,6 +6671,19 @@ void T_Scroll(scroll_t *s)
|
|||
sector_t *psec;
|
||||
psec = sectors + sect;
|
||||
|
||||
// Find the FOF corresponding to the control linedef
|
||||
for (rover = psec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master == sec->lines[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rover) // This should be impossible, but don't complain if it is the case somehow
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
|
||||
continue;
|
||||
|
||||
for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
|
||||
{
|
||||
thing = node->m_thing;
|
||||
|
@ -6718,6 +6747,19 @@ void T_Scroll(scroll_t *s)
|
|||
sector_t *psec;
|
||||
psec = sectors + sect;
|
||||
|
||||
// Find the FOF corresponding to the control linedef
|
||||
for (rover = psec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master == sec->lines[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rover) // This should be impossible, but don't complain if it is the case somehow
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
|
||||
continue;
|
||||
|
||||
for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
|
||||
{
|
||||
thing = node->m_thing;
|
||||
|
|
|
@ -607,7 +607,8 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
|
||||
// Keep track of how long they've been playing!
|
||||
totalplaytime++;
|
||||
if (!demoplayback) // Don't increment if a demo is playing.
|
||||
totalplaytime++;
|
||||
|
||||
if (!useNightsSS && G_IsSpecialStage(gamemap))
|
||||
P_DoSpecialStageStuff();
|
||||
|
|
50
src/p_user.c
50
src/p_user.c
|
@ -1621,6 +1621,9 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
|||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
|
||||
continue;
|
||||
#ifdef ESLOPE
|
||||
|
@ -1835,6 +1838,12 @@ static void P_CheckBouncySectors(player_t *player)
|
|||
|
||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue; // FOFs should not be bouncy if they don't even "exist"
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15)
|
||||
continue; // this sector type is required for FOFs to be bouncy
|
||||
|
||||
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
|
||||
|
@ -1848,7 +1857,6 @@ static void P_CheckBouncySectors(player_t *player)
|
|||
&& oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
|
||||
top = false;
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
|
||||
{
|
||||
fixed_t linedist;
|
||||
|
||||
|
@ -7845,7 +7853,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
subsector_t *newsubsec;
|
||||
fixed_t f1, f2;
|
||||
|
||||
cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||
// We probably shouldn't move the camera if there is no player or player mobj somehow
|
||||
if (!player || !player->mo)
|
||||
return true;
|
||||
|
||||
mo = player->mo;
|
||||
|
||||
cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||
|
||||
if (!(player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD))
|
||||
{
|
||||
|
@ -7866,7 +7880,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
else if (player == &players[secondarydisplayplayer])
|
||||
focusangle = localangle2;
|
||||
else
|
||||
focusangle = player->mo->angle;
|
||||
focusangle = mo->angle;
|
||||
if (thiscam == &camera)
|
||||
camrotate = cv_cam_rotate.value;
|
||||
else if (thiscam == &camera2)
|
||||
|
@ -7878,17 +7892,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!player || !player->mo)
|
||||
return true;
|
||||
|
||||
mo = player->mo;
|
||||
|
||||
thiscam->radius = FixedMul(20*FRACUNIT, mo->scale);
|
||||
thiscam->height = FixedMul(16*FRACUNIT, mo->scale);
|
||||
|
||||
if (!mo)
|
||||
return true;
|
||||
|
||||
// Don't run while respawning from a starpost
|
||||
// Inu 4/8/13 Why not?!
|
||||
// if (leveltime > 0 && timeinmap <= 0)
|
||||
|
@ -7896,7 +7902,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
focusangle = player->mo->angle;
|
||||
focusangle = mo->angle;
|
||||
focusaiming = 0;
|
||||
}
|
||||
else if (player == &players[consoleplayer])
|
||||
|
@ -7911,7 +7917,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else
|
||||
{
|
||||
focusangle = player->mo->angle;
|
||||
focusangle = mo->angle;
|
||||
focusaiming = player->aiming;
|
||||
}
|
||||
|
||||
|
@ -7958,12 +7964,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
angle = R_PointToAngle2(player->axis1->x, player->axis1->y, player->axis2->x, player->axis2->y);
|
||||
angle += ANGLE_90;
|
||||
}
|
||||
else if (player->mo->target)
|
||||
else if (mo->target)
|
||||
{
|
||||
if (player->mo->target->flags & MF_AMBUSH)
|
||||
angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
|
||||
if (mo->target->flags & MF_AMBUSH)
|
||||
angle = R_PointToAngle2(mo->target->x, mo->target->y, mo->x, mo->y);
|
||||
else
|
||||
angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y);
|
||||
angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y);
|
||||
}
|
||||
}
|
||||
else if (P_AnalogMove(player)) // Analog
|
||||
|
@ -8058,7 +8064,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||
{
|
||||
// Camera doesn't ALWAYS need to move, only when running...
|
||||
if (abs(player->mo->momx) > 10)
|
||||
if (abs(mo->momx) > 10)
|
||||
{
|
||||
// Move the camera all smooth-like, not jerk it around...
|
||||
if (mo->momx > 0)
|
||||
|
@ -8372,13 +8378,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
vy = player->awayviewmobj->y;
|
||||
}
|
||||
|
||||
if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
player->mo->flags2 |= MF2_SHADOW;
|
||||
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
mo->flags2 |= MF2_SHADOW;
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
mo->flags2 &= ~MF2_SHADOW;
|
||||
}
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
mo->flags2 &= ~MF2_SHADOW;
|
||||
|
||||
/* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting))
|
||||
{
|
||||
|
|
141
src/r_data.c
141
src/r_data.c
|
@ -365,8 +365,8 @@ void R_FlushTextureCache(void)
|
|||
}
|
||||
|
||||
// Need these prototypes for later; defining them here instead of r_data.h so they're "private"
|
||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum);
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *index);
|
||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
|
@ -404,13 +404,22 @@ 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++)
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w);
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
}
|
||||
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// Add all the textures between TX_START and TX_END
|
||||
|
@ -447,12 +456,25 @@ void R_LoadTextures(void)
|
|||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w,&i);
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
@ -472,40 +494,22 @@ void R_LoadTextures(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
UINT16 patchcount = 1;
|
||||
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height);
|
||||
if (SHORT(patchlump->width) == 64
|
||||
&& SHORT(patchlump->height) == 64)
|
||||
{ // 64x64 patch
|
||||
const column_t *column;
|
||||
for (k = 0; k < SHORT(patchlump->width); k++)
|
||||
{ // Find use of transparency.
|
||||
column = (const column_t *)((const UINT8 *)patchlump + LONG(patchlump->columnofs[k]));
|
||||
if (column->length != SHORT(patchlump->height))
|
||||
break;
|
||||
}
|
||||
if (k == SHORT(patchlump->width))
|
||||
patchcount = 2; // No transparency? 64x128 texture.
|
||||
}
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * patchcount), PU_STATIC, NULL);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name));
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height)*patchcount;
|
||||
texture->patchcount = patchcount;
|
||||
texture->height = SHORT(patchlump->height);
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
for (k = 0; k < patchcount; k++)
|
||||
{
|
||||
patch = &texture->patches[k];
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = 0;
|
||||
patch->originy = (INT16)(k*patchlump->height);
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
}
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
|
||||
Z_Unlock(patchlump);
|
||||
|
||||
|
@ -817,7 +821,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
|||
}
|
||||
|
||||
// Parses the TEXTURES lump... but just to count the number of textures.
|
||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum)
|
||||
{
|
||||
char *texturesLump;
|
||||
size_t texturesLumpLength;
|
||||
|
@ -828,11 +832,11 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
|||
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
||||
// need to make a space of memory where I can ensure that it will terminate
|
||||
// correctly. Start by loading the relevant data from the WAD.
|
||||
texturesLump = (char *)W_CacheLumpNumPwad(wadNum,W_CheckNumForNamePwad("TEXTURES", wadNum, 0),PU_STATIC);
|
||||
texturesLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC);
|
||||
// If that didn't exist, we have nothing to do here.
|
||||
if (texturesLump == NULL) return 0;
|
||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
||||
texturesLumpLength = W_LumpLengthPwad(wadNum,W_CheckNumForNamePwad("TEXTURES",wadNum,0));
|
||||
texturesLumpLength = W_LumpLengthPwad(wadNum, lumpNum);
|
||||
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||
// Now move the contents of the lump into this new location.
|
||||
memmove(texturesText,texturesLump,texturesLumpLength);
|
||||
|
@ -864,7 +868,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
|||
}
|
||||
|
||||
// Parses the TEXTURES lump... for real, this time.
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *texindex)
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex)
|
||||
{
|
||||
char *texturesLump;
|
||||
size_t texturesLumpLength;
|
||||
|
@ -877,11 +881,11 @@ void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *texindex)
|
|||
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
||||
// need to make a space of memory where I can ensure that it will terminate
|
||||
// correctly. Start by loading the relevant data from the WAD.
|
||||
texturesLump = (char *)W_CacheLumpNumPwad(wadNum,W_CheckNumForNamePwad("TEXTURES", wadNum, 0),PU_STATIC);
|
||||
texturesLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC);
|
||||
// If that didn't exist, we have nothing to do here.
|
||||
if (texturesLump == NULL) return;
|
||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
||||
texturesLumpLength = W_LumpLengthPwad(wadNum,W_CheckNumForNamePwad("TEXTURES",wadNum,0));
|
||||
texturesLumpLength = W_LumpLengthPwad(wadNum, lumpNum);
|
||||
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||
// Now move the contents of the lump into this new location.
|
||||
memmove(texturesText,texturesLump,texturesLumpLength);
|
||||
|
@ -968,12 +972,51 @@ static void R_InitExtraColormaps(void)
|
|||
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
|
||||
}
|
||||
|
||||
// 12/14/14 -- only take flats in F_START/F_END
|
||||
// Search for flat name.
|
||||
lumpnum_t R_GetFlatNumForName(const char *name)
|
||||
{
|
||||
lumpnum_t lump = W_CheckNumForNameInBlock(name, "F_START", "F_END");
|
||||
if (lump == LUMPERROR)
|
||||
lump = W_CheckNumForNameInBlock(name, "FF_START", "FF_END"); // deutex, some other old things
|
||||
INT32 i;
|
||||
lumpnum_t lump;
|
||||
lumpnum_t start;
|
||||
lumpnum_t end;
|
||||
|
||||
// Scan wad files backwards so patched flats take preference.
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
switch (wadfiles[i]->type)
|
||||
{
|
||||
case RET_WAD:
|
||||
if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX)
|
||||
{
|
||||
if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX)
|
||||
continue;
|
||||
else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if ((end = W_CheckNumForNamePwad("F_END", (UINT16)i, start)) == INT16_MAX)
|
||||
continue;
|
||||
break;
|
||||
case RET_PK3:
|
||||
if ((start = W_CheckNumForFolderStartPK3("Flats/", i, 0)) == INT16_MAX)
|
||||
continue;
|
||||
if ((end = W_CheckNumForFolderEndPK3("Flats/", i, start)) == INT16_MAX)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now find lump with specified name in that range.
|
||||
lump = W_CheckNumForNamePwad(name, (UINT16)i, start);
|
||||
if (lump < end)
|
||||
{
|
||||
lump += (i<<16); // found it, in our constraints
|
||||
break;
|
||||
}
|
||||
lump = LUMPERROR;
|
||||
}
|
||||
|
||||
if (lump == LUMPERROR)
|
||||
{
|
||||
if (strcmp(name, SKYFLATNAME))
|
||||
|
|
|
@ -327,21 +327,28 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
UINT16 start, end;
|
||||
char wadname[MAX_WADPATH];
|
||||
|
||||
// find the sprites section in this pwad
|
||||
// we need at least the S_END
|
||||
// (not really, but for speedup)
|
||||
switch (wadfiles[wadnum]->type)
|
||||
{
|
||||
case RET_WAD:
|
||||
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
|
||||
if (start == INT16_MAX)
|
||||
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
|
||||
if (start == INT16_MAX)
|
||||
start = 0; //let say S_START is lump 0
|
||||
else
|
||||
start++; // just after S_START
|
||||
end = W_CheckNumForNamePwad("S_END",wadnum,start);
|
||||
if (end == INT16_MAX)
|
||||
end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib.
|
||||
break;
|
||||
case RET_PK3:
|
||||
start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0);
|
||||
end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
|
||||
if (start == INT16_MAX)
|
||||
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
|
||||
if (start == INT16_MAX)
|
||||
start = 0; //let say S_START is lump 0
|
||||
else
|
||||
start++; // just after S_START
|
||||
|
||||
end = W_CheckNumForNamePwad("S_END",wadnum,start);
|
||||
if (end == INT16_MAX)
|
||||
end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib.
|
||||
if (end == INT16_MAX)
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum);
|
||||
|
|
893
src/w_wad.c
893
src/w_wad.c
File diff suppressed because it is too large
Load diff
56
src/w_wad.h
56
src/w_wad.h
|
@ -22,6 +22,22 @@
|
|||
#pragma interface
|
||||
#endif
|
||||
|
||||
// a raw entry of the wad directory
|
||||
// NOTE: This sits here and not in w_wad.c because p_setup.c makes use of it to load map WADs inside PK3s.
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
UINT32 filepos; // file offset of the resource
|
||||
UINT32 size; // size of the resource
|
||||
char name[8]; // name of the resource
|
||||
} ATTRPACK filelump_t;
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
|
||||
// ==============================================================
|
||||
// WAD FILE STRUCTURE DEFINITIONS
|
||||
// ==============================================================
|
||||
|
@ -34,14 +50,26 @@ typedef struct
|
|||
UINT32 infotableofs; // the 'directory' of resources
|
||||
} wadinfo_t;
|
||||
|
||||
// Available compression methods for lumps.
|
||||
typedef enum
|
||||
{
|
||||
CM_NOCOMPRESSION,
|
||||
#ifdef HAVE_ZLIB
|
||||
CM_DEFLATE,
|
||||
#endif
|
||||
CM_LZF,
|
||||
CM_UNSUPPORTED
|
||||
} compmethod;
|
||||
|
||||
// a memory entry of the wad directory
|
||||
typedef struct
|
||||
{
|
||||
unsigned long position; // filelump_t filepos
|
||||
unsigned long disksize; // filelump_t size
|
||||
char name[9]; // filelump_t name[]
|
||||
char *name2; // Used by PK3s. Dynamically allocated name.
|
||||
size_t size; // real (uncompressed) size
|
||||
INT32 compressed; // i
|
||||
compmethod compression; // lump compression method
|
||||
} lumpinfo_t;
|
||||
|
||||
// =========================================================================
|
||||
|
@ -58,9 +86,21 @@ typedef struct
|
|||
#include "m_aatree.h"
|
||||
#endif
|
||||
|
||||
// Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further.
|
||||
typedef enum restype
|
||||
{
|
||||
RET_WAD,
|
||||
RET_SOC,
|
||||
RET_LUA,
|
||||
RET_PK3,
|
||||
RET_UNKNOWN,
|
||||
} restype_t;
|
||||
|
||||
|
||||
typedef struct wadfile_s
|
||||
{
|
||||
char *filename;
|
||||
restype_t type;
|
||||
lumpinfo_t *lumpinfo;
|
||||
lumpcache_t *lumpcache;
|
||||
#ifdef HWRENDER
|
||||
|
@ -85,7 +125,7 @@ void W_Shutdown(void);
|
|||
// Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened
|
||||
FILE *W_OpenWadFile(const char **filename, boolean useerrors);
|
||||
// Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error
|
||||
UINT16 W_LoadWadFile(const char *filename);
|
||||
UINT16 W_InitFile(const char *filename);
|
||||
#ifdef DELFILE
|
||||
void W_UnloadWadFile(UINT16 num);
|
||||
#endif
|
||||
|
@ -98,6 +138,12 @@ const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
|
|||
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
||||
|
||||
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
|
||||
|
||||
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
|
||||
lumpnum_t W_CheckNumForMap(const char *name);
|
||||
lumpnum_t W_CheckNumForName(const char *name);
|
||||
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
||||
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
|
||||
|
@ -106,6 +152,12 @@ UINT8 W_LumpExists(const char *name); // Lua uses this.
|
|||
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
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
void zerr(int ret); // zlib error checking
|
||||
#endif
|
||||
|
||||
size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset);
|
||||
size_t W_ReadLumpHeader(lumpnum_t lump, void *dest, size_t size, size_t offest); // read all or a part of a lump
|
||||
void W_ReadLumpPwad(UINT16 wad, UINT16 lump, void *dest);
|
||||
|
|
|
@ -1796,37 +1796,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
|
||||
//
|
||||
|
@ -1838,21 +1807,10 @@ static void Y_FollowIntermission(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (nextmap < 1100-1)
|
||||
{
|
||||
// normal level
|
||||
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();
|
||||
// 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();
|
||||
}
|
||||
|
||||
#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