mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-13 13:21:31 +00:00
Merge remote-tracking branch 'public-gitlab/next' into addons-backport
This commit is contained in:
commit
37950341ec
95 changed files with 3175 additions and 1649 deletions
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(SRB2
|
project(SRB2
|
||||||
VERSION 2.1.20
|
VERSION 2.1.21
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||||
|
|
3
SRB2.cbp
3
SRB2.cbp
|
@ -1549,6 +1549,9 @@ HW3SOUND for 3D hardware sound support
|
||||||
<Unit filename="src/lua_baselib.c">
|
<Unit filename="src/lua_baselib.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit filename="src/lua_blockmaplib.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
<Unit filename="src/lua_consolelib.c">
|
<Unit filename="src/lua_consolelib.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2.1.20.{branch}-{build}
|
version: 2.1.21.{branch}-{build}
|
||||||
os: MinGW
|
os: MinGW
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
Binary file not shown.
43
libs/DLL-README.txt
Normal file
43
libs/DLL-README.txt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# SRB2 - Which DLLs do I need to bundle?
|
||||||
|
|
||||||
|
Updated 12/4/2018 (v2.1.21)
|
||||||
|
|
||||||
|
Here are the required DLLs, per build. For each architecture, copy all the binaries from these folders:
|
||||||
|
|
||||||
|
* libs\dll-binaries\[i686/x86_64]
|
||||||
|
* libs\SDL2\[i686/x86_64]...\bin
|
||||||
|
* libs\SDL2_mixer\[i686/x86_64]...\bin
|
||||||
|
|
||||||
|
and don't forget to build r_opengl.dll for srb2dd.
|
||||||
|
|
||||||
|
## srb2win, 32-bit
|
||||||
|
|
||||||
|
* libs\dll-binaries\i686\exchndl.dll
|
||||||
|
* libs\dll-binaries\i686\libgme.dll
|
||||||
|
* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll)
|
||||||
|
* libs\SDL2\i686-w64-mingw32\bin\SDL2.dll
|
||||||
|
* libs\SDL2_mixer\i686-w64-mingw32\bin\*.dll (get everything)
|
||||||
|
|
||||||
|
## srb2win, 64-bit
|
||||||
|
|
||||||
|
* libs\dll-binaries\x86_64\exchndl.dll
|
||||||
|
* libs\dll-binaries\x86_64\libgme.dll
|
||||||
|
* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll)
|
||||||
|
* libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll
|
||||||
|
* libs\SDL2_mixer\x86_64-w64-mingw32\bin\*.dll (get everything)
|
||||||
|
|
||||||
|
## srb2dd, 32-bit
|
||||||
|
|
||||||
|
* libs\dll-binaries\i686\exchndl.dll
|
||||||
|
* libs\dll-binaries\i686\fmodex.dll
|
||||||
|
* libs\dll-binaries\i686\libgme.dll
|
||||||
|
* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll)
|
||||||
|
* r_opengl.dll (build this from make)
|
||||||
|
|
||||||
|
## srb2dd, 64-bit
|
||||||
|
|
||||||
|
* libs\dll-binaries\x86_64\exchndl.dll
|
||||||
|
* libs\dll-binaries\x86_64\fmodex.dll
|
||||||
|
* libs\dll-binaries\x86_64\libgme.dll
|
||||||
|
* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll)
|
||||||
|
* r_opengl.dll (build this from make)
|
BIN
libs/dll-binaries/i686/exchndl.dll
Normal file
BIN
libs/dll-binaries/i686/exchndl.dll
Normal file
Binary file not shown.
BIN
libs/dll-binaries/i686/mgwhelp.dll
Normal file
BIN
libs/dll-binaries/i686/mgwhelp.dll
Normal file
Binary file not shown.
BIN
libs/dll-binaries/x86_64/exchndl.dll
Normal file
BIN
libs/dll-binaries/x86_64/exchndl.dll
Normal file
Binary file not shown.
BIN
libs/dll-binaries/x86_64/mgwhelp.dll
Normal file
BIN
libs/dll-binaries/x86_64/mgwhelp.dll
Normal file
Binary file not shown.
|
@ -237,6 +237,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
||||||
add_definitions(-DHAVE_BLUA)
|
add_definitions(-DHAVE_BLUA)
|
||||||
set(SRB2_LUA_SOURCES
|
set(SRB2_LUA_SOURCES
|
||||||
lua_baselib.c
|
lua_baselib.c
|
||||||
|
lua_blockmaplib.c
|
||||||
lua_consolelib.c
|
lua_consolelib.c
|
||||||
lua_hooklib.c
|
lua_hooklib.c
|
||||||
lua_hudlib.c
|
lua_hudlib.c
|
||||||
|
|
|
@ -39,6 +39,7 @@ OBJS:=$(OBJS) \
|
||||||
$(OBJDIR)/lvm.o \
|
$(OBJDIR)/lvm.o \
|
||||||
$(OBJDIR)/lua_script.o \
|
$(OBJDIR)/lua_script.o \
|
||||||
$(OBJDIR)/lua_baselib.o \
|
$(OBJDIR)/lua_baselib.o \
|
||||||
|
$(OBJDIR)/lua_blockmaplib.o \
|
||||||
$(OBJDIR)/lua_mathlib.o \
|
$(OBJDIR)/lua_mathlib.o \
|
||||||
$(OBJDIR)/lua_hooklib.o \
|
$(OBJDIR)/lua_hooklib.o \
|
||||||
$(OBJDIR)/lua_consolelib.o \
|
$(OBJDIR)/lua_consolelib.o \
|
||||||
|
|
247
src/command.c
247
src/command.c
|
@ -32,6 +32,7 @@
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
|
#include "d_netfil.h" // findfile
|
||||||
|
|
||||||
//========
|
//========
|
||||||
// protos.
|
// protos.
|
||||||
|
@ -49,6 +50,7 @@ static void COM_Wait_f(void);
|
||||||
static void COM_Help_f(void);
|
static void COM_Help_f(void);
|
||||||
static void COM_Toggle_f(void);
|
static void COM_Toggle_f(void);
|
||||||
|
|
||||||
|
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
|
||||||
static boolean CV_Command(void);
|
static boolean CV_Command(void);
|
||||||
static consvar_t *CV_FindVar(const char *name);
|
static consvar_t *CV_FindVar(const char *name);
|
||||||
static const char *CV_StringValue(const char *var_name);
|
static const char *CV_StringValue(const char *var_name);
|
||||||
|
@ -62,7 +64,19 @@ CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
|
||||||
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||||
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||||
|
|
||||||
|
// Filter consvars by MODVERSION
|
||||||
|
// First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
|
||||||
|
// Also set CV_HIDEN during runtime, after config is loaded
|
||||||
|
consvar_t cv_execversion = {"execversion","25",0,CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// for default joyaxis detection
|
||||||
|
static boolean joyaxis_default = false;
|
||||||
|
static boolean joyaxis2_default = false;
|
||||||
|
static INT32 joyaxis_count = 0;
|
||||||
|
static INT32 joyaxis2_count = 0;
|
||||||
|
|
||||||
#define COM_BUF_SIZE 8192 // command buffer size
|
#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)
|
static INT32 com_wait; // one command per frame (for cmd sequences)
|
||||||
|
|
||||||
|
@ -485,6 +499,7 @@ static void COM_ExecuteString(char *ptext)
|
||||||
{
|
{
|
||||||
xcommand_t *cmd;
|
xcommand_t *cmd;
|
||||||
cmdalias_t *a;
|
cmdalias_t *a;
|
||||||
|
static INT32 recursion = 0; // detects recursion and stops it if it goes too far
|
||||||
|
|
||||||
COM_TokenizeString(ptext);
|
COM_TokenizeString(ptext);
|
||||||
|
|
||||||
|
@ -497,6 +512,7 @@ static void COM_ExecuteString(char *ptext)
|
||||||
{
|
{
|
||||||
if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase!
|
if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase!
|
||||||
{
|
{
|
||||||
|
recursion = 0;
|
||||||
cmd->function();
|
cmd->function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -507,11 +523,20 @@ static void COM_ExecuteString(char *ptext)
|
||||||
{
|
{
|
||||||
if (!stricmp(com_argv[0], a->name))
|
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);
|
COM_BufInsertText(a->value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recursion = 0;
|
||||||
|
|
||||||
// check cvars
|
// check cvars
|
||||||
// Hurdler: added at Ebola's request ;)
|
// Hurdler: added at Ebola's request ;)
|
||||||
// (don't flood the console in software mode with bad gr_xxx command)
|
// (don't flood the console in software mode with bad gr_xxx command)
|
||||||
|
@ -617,6 +642,7 @@ static void COM_CEchoDuration_f(void)
|
||||||
static void COM_Exec_f(void)
|
static void COM_Exec_f(void)
|
||||||
{
|
{
|
||||||
UINT8 *buf = NULL;
|
UINT8 *buf = NULL;
|
||||||
|
char filename[256];
|
||||||
|
|
||||||
if (COM_Argc() < 2 || COM_Argc() > 3)
|
if (COM_Argc() < 2 || COM_Argc() > 3)
|
||||||
{
|
{
|
||||||
|
@ -625,13 +651,23 @@ static void COM_Exec_f(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// load file
|
// load file
|
||||||
|
// Try with Argv passed verbatim first, for back compat
|
||||||
FIL_ReadFile(COM_Argv(1), &buf);
|
FIL_ReadFile(COM_Argv(1), &buf);
|
||||||
|
|
||||||
if (!buf)
|
if (!buf)
|
||||||
{
|
{
|
||||||
if (!COM_CheckParm("-noerror"))
|
// Now try by searching the file path
|
||||||
CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1));
|
// filename is modified with the full found path
|
||||||
return;
|
strcpy(filename, COM_Argv(1));
|
||||||
|
if (findfile(filename, NULL, true) != FS_NOTFOUND)
|
||||||
|
FIL_ReadFile(filename, &buf);
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
if (!COM_CheckParm("-noerror"))
|
||||||
|
CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!COM_CheckParm("-silent"))
|
if (!COM_CheckParm("-silent"))
|
||||||
|
@ -1220,7 +1256,7 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
|
||||||
char *svalue;
|
char *svalue;
|
||||||
UINT8 stealth = false;
|
UINT8 stealth = false;
|
||||||
|
|
||||||
if (playernum != serverplayer && playernum != adminplayer && !serverloading)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum) && !serverloading)
|
||||||
{
|
{
|
||||||
// not from server or remote admin, must be hacked/buggy client
|
// not from server or remote admin, must be hacked/buggy client
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
|
||||||
|
@ -1349,7 +1385,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
||||||
// send the value of the variable
|
// send the value of the variable
|
||||||
XBOXSTATIC UINT8 buf[128];
|
XBOXSTATIC UINT8 buf[128];
|
||||||
UINT8 *p = buf;
|
UINT8 *p = buf;
|
||||||
if (!(server || (adminplayer == consoleplayer)))
|
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string);
|
CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string);
|
||||||
return;
|
return;
|
||||||
|
@ -1556,6 +1592,200 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
||||||
var->changed = 1; // user has changed it now
|
var->changed = 1; // user has changed it now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CV_InitFilterVar(void)
|
||||||
|
{
|
||||||
|
joyaxis_default = joyaxis2_default = true;
|
||||||
|
joyaxis_count = joyaxis2_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
||||||
|
{
|
||||||
|
// If ALL axis settings are previous defaults, set them to the new defaults
|
||||||
|
// MODVERSION < 26 (2.1.21)
|
||||||
|
|
||||||
|
if (joyaxis_default)
|
||||||
|
{
|
||||||
|
#if !defined (_WII) && !defined (WMINPUT)
|
||||||
|
if (!stricmp(v->name, "joyaxis_turn"))
|
||||||
|
{
|
||||||
|
if (joyaxis_count > 6) return false;
|
||||||
|
// we're currently setting the new defaults, don't interfere
|
||||||
|
else if (joyaxis_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "X-Axis")) joyaxis_count++;
|
||||||
|
else joyaxis_default = false;
|
||||||
|
}
|
||||||
|
#if !defined (PSP)
|
||||||
|
if (!stricmp(v->name, "joyaxis_move"))
|
||||||
|
{
|
||||||
|
if (joyaxis_count > 6) return false;
|
||||||
|
else if (joyaxis_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "Y-Axis")) joyaxis_count++;
|
||||||
|
else joyaxis_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (PSP)
|
||||||
|
if (!stricmp(v->name, "joyaxis_side"))
|
||||||
|
{
|
||||||
|
if (joyaxis_count > 6) return false;
|
||||||
|
else if (joyaxis_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "Z-Axis")) joyaxis_count++;
|
||||||
|
else joyaxis_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined (_XBOX) && !defined (PSP)
|
||||||
|
if (!stricmp(v->name, "joyaxis_look"))
|
||||||
|
{
|
||||||
|
if (joyaxis_count > 6) return false;
|
||||||
|
else if (joyaxis_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "None")) joyaxis_count++;
|
||||||
|
else joyaxis_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!stricmp(v->name, "joyaxis_fire")
|
||||||
|
|| !stricmp(v->name, "joyaxis_firenormal"))
|
||||||
|
{
|
||||||
|
if (joyaxis_count > 6) return false;
|
||||||
|
else if (joyaxis_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "None")) joyaxis_count++;
|
||||||
|
else joyaxis_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// reset all axis settings to defaults
|
||||||
|
if (joyaxis_count == 6)
|
||||||
|
{
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis.name, cv_turnaxis.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis.name, cv_moveaxis.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis.name, cv_sideaxis.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis.name, cv_lookaxis.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis.name, cv_fireaxis.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis.name, cv_firenaxis.defaultvalue));
|
||||||
|
joyaxis_count++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joyaxis2_default)
|
||||||
|
{
|
||||||
|
#if !defined (_WII) && !defined (WMINPUT)
|
||||||
|
if (!stricmp(v->name, "joyaxis2_turn"))
|
||||||
|
{
|
||||||
|
if (joyaxis2_count > 6) return false;
|
||||||
|
// we're currently setting the new defaults, don't interfere
|
||||||
|
else if (joyaxis2_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "X-Axis")) joyaxis2_count++;
|
||||||
|
else joyaxis2_default = false;
|
||||||
|
}
|
||||||
|
// #if !defined (PSP)
|
||||||
|
if (!stricmp(v->name, "joyaxis2_move"))
|
||||||
|
{
|
||||||
|
if (joyaxis2_count > 6) return false;
|
||||||
|
else if (joyaxis2_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "Y-Axis")) joyaxis2_count++;
|
||||||
|
else joyaxis2_default = false;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (PSP)
|
||||||
|
if (!stricmp(v->name, "joyaxis2_side"))
|
||||||
|
{
|
||||||
|
if (joyaxis2_count > 6) return false;
|
||||||
|
else if (joyaxis2_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "Z-Axis")) joyaxis2_count++;
|
||||||
|
else joyaxis2_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined (_XBOX) // && !defined (PSP)
|
||||||
|
if (!stricmp(v->name, "joyaxis2_look"))
|
||||||
|
{
|
||||||
|
if (joyaxis2_count > 6) return false;
|
||||||
|
else if (joyaxis2_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "None")) joyaxis2_count++;
|
||||||
|
else joyaxis2_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!stricmp(v->name, "joyaxis2_fire")
|
||||||
|
|| !stricmp(v->name, "joyaxis2_firenormal"))
|
||||||
|
{
|
||||||
|
if (joyaxis2_count > 6) return false;
|
||||||
|
else if (joyaxis2_count == 6) return true;
|
||||||
|
|
||||||
|
if (!stricmp(valstr, "None")) joyaxis2_count++;
|
||||||
|
else joyaxis2_default = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// reset all axis settings to defaults
|
||||||
|
if (joyaxis2_count == 6)
|
||||||
|
{
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis2.name, cv_turnaxis2.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis2.name, cv_moveaxis2.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis2.name, cv_sideaxis2.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis2.name, cv_lookaxis2.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis2.name, cv_fireaxis2.defaultvalue));
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis2.name, cv_firenaxis2.defaultvalue));
|
||||||
|
joyaxis2_count++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we haven't reached our counts yet, or we're not default
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
||||||
|
{
|
||||||
|
// True means allow the CV change, False means block it
|
||||||
|
|
||||||
|
// We only care about CV_SAVE because this filters the user's config files
|
||||||
|
// We do this same check in CV_Command
|
||||||
|
if (!(v->flags & CV_SAVE))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// We go by MODVERSION here
|
||||||
|
if (cv_execversion.value < 26) // 26 = 2.1.21
|
||||||
|
{
|
||||||
|
// MOUSE SETTINGS
|
||||||
|
// alwaysfreelook split between first and third person (chasefreelook)
|
||||||
|
// mousemove was on by default, which invalidates the current approach
|
||||||
|
if (!stricmp(v->name, "alwaysmlook")
|
||||||
|
|| !stricmp(v->name, "alwaysmlook2")
|
||||||
|
|| !stricmp(v->name, "mousemove")
|
||||||
|
|| !stricmp(v->name, "mousemove2"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// mousesens was changed from 35 to 20 due to oversensitivity
|
||||||
|
if ((!stricmp(v->name, "mousesens")
|
||||||
|
|| !stricmp(v->name, "mousesens2")
|
||||||
|
|| !stricmp(v->name, "mouseysens")
|
||||||
|
|| !stricmp(v->name, "mouseysens2"))
|
||||||
|
&& atoi(valstr) == 35)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// JOYSTICK DEFAULTS
|
||||||
|
// use_joystick was changed from 0 to 1 to automatically use a joystick if available
|
||||||
|
#if defined(HAVE_SDL) || defined(_WINDOWS)
|
||||||
|
if ((!stricmp(v->name, "use_joystick")
|
||||||
|
|| !stricmp(v->name, "use_joystick2"))
|
||||||
|
&& atoi(valstr) == 0)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// axis defaults were changed to be friendly to 360 controllers
|
||||||
|
// if ALL axis settings are defaults, then change them to new values
|
||||||
|
if (!CV_FilterJoyAxisVars(v, valstr))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Displays or changes a variable from the console.
|
/** Displays or changes a variable from the console.
|
||||||
* Since the user is presumed to have been directly responsible
|
* Since the user is presumed to have been directly responsible
|
||||||
* for this change, the variable is marked as changed this game.
|
* for this change, the variable is marked as changed this game.
|
||||||
|
@ -1580,8 +1810,11 @@ static boolean CV_Command(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CV_Set(v, COM_Argv(1));
|
if (!(v->flags & CV_SAVE) || CV_FilterVarByVersion(v, COM_Argv(1)))
|
||||||
v->changed = 1; // now it's been changed by (presumably) the user
|
{
|
||||||
|
CV_Set(v, COM_Argv(1));
|
||||||
|
v->changed = 1; // now it's been changed by (presumably) the user
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,12 @@ extern CV_PossibleValue_t CV_OnOff[];
|
||||||
extern CV_PossibleValue_t CV_YesNo[];
|
extern CV_PossibleValue_t CV_YesNo[];
|
||||||
extern CV_PossibleValue_t CV_Unsigned[];
|
extern CV_PossibleValue_t CV_Unsigned[];
|
||||||
extern CV_PossibleValue_t CV_Natural[];
|
extern CV_PossibleValue_t CV_Natural[];
|
||||||
|
|
||||||
|
// Filter consvars by version
|
||||||
|
extern consvar_t cv_execversion;
|
||||||
|
|
||||||
|
void CV_InitFilterVar(void);
|
||||||
|
|
||||||
// register a variable for use at the console
|
// register a variable for use at the console
|
||||||
void CV_RegisterVar(consvar_t *variable);
|
void CV_RegisterVar(consvar_t *variable);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
#include "g_input.h" // JOY1
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
|
@ -1365,15 +1366,18 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||||
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
||||||
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||||
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||||
netbuffer->u.servercfg.adminplayer = (SINT8)adminplayer;
|
|
||||||
|
|
||||||
// we fill these structs with FFs so that any players not in game get sent as 0xFFFF
|
// we fill these structs with FFs so that any players not in game get sent as 0xFFFF
|
||||||
// which is nice and easy for us to detect
|
// which is nice and easy for us to detect
|
||||||
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
|
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
|
||||||
memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
|
memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
|
||||||
|
|
||||||
|
memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers));
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
|
||||||
|
|
||||||
if (!playeringame[i])
|
if (!playeringame[i])
|
||||||
continue;
|
continue;
|
||||||
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
|
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
|
||||||
|
@ -1959,7 +1963,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
||||||
|
|
||||||
I_OsPolling();
|
I_OsPolling();
|
||||||
key = I_GetKey();
|
key = I_GetKey();
|
||||||
if (key == KEY_ESCAPE)
|
if (key == KEY_ESCAPE || key == KEY_JOY1+1)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||||
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
|
@ -2042,7 +2046,7 @@ static void CL_ConnectToServer(boolean viams)
|
||||||
G_SetGamestate(GS_WAITINGPLAYERS);
|
G_SetGamestate(GS_WAITINGPLAYERS);
|
||||||
wipegamestate = GS_WAITINGPLAYERS;
|
wipegamestate = GS_WAITINGPLAYERS;
|
||||||
|
|
||||||
adminplayer = -1;
|
ClearAdminPlayers();
|
||||||
pnumnodes = 1;
|
pnumnodes = 1;
|
||||||
oldtic = I_GetTime() - 1;
|
oldtic = I_GetTime() - 1;
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
|
@ -2354,7 +2358,7 @@ void CL_ClearPlayer(INT32 playernum)
|
||||||
//
|
//
|
||||||
// Removes a player from the current game
|
// Removes a player from the current game
|
||||||
//
|
//
|
||||||
static void CL_RemovePlayer(INT32 playernum)
|
static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||||
{
|
{
|
||||||
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
||||||
// kick commands to be issued for the same player.
|
// kick commands to be issued for the same player.
|
||||||
|
@ -2409,6 +2413,10 @@ static void CL_RemovePlayer(INT32 playernum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reset player data
|
// Reset player data
|
||||||
CL_ClearPlayer(playernum);
|
CL_ClearPlayer(playernum);
|
||||||
|
|
||||||
|
@ -2421,8 +2429,10 @@ static void CL_RemovePlayer(INT32 playernum)
|
||||||
// Reset the name
|
// Reset the name
|
||||||
sprintf(player_names[playernum], "Player %d", playernum+1);
|
sprintf(player_names[playernum], "Player %d", playernum+1);
|
||||||
|
|
||||||
if (playernum == adminplayer)
|
if (IsPlayerAdmin(playernum))
|
||||||
adminplayer = -1; // don't stay admin after you're gone
|
{
|
||||||
|
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
|
||||||
|
}
|
||||||
|
|
||||||
if (playernum == displayplayer)
|
if (playernum == displayplayer)
|
||||||
displayplayer = consoleplayer; // don't look through someone's view who isn't there
|
displayplayer = consoleplayer; // don't look through someone's view who isn't there
|
||||||
|
@ -2540,7 +2550,7 @@ static void Command_Nodes(void)
|
||||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
|
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
|
||||||
CONS_Printf(" - %s", address);
|
CONS_Printf(" - %s", address);
|
||||||
|
|
||||||
if (i == adminplayer)
|
if (IsPlayerAdmin(i))
|
||||||
CONS_Printf(M_GetText(" (verified admin)"));
|
CONS_Printf(M_GetText(" (verified admin)"));
|
||||||
|
|
||||||
if (players[i].spectator)
|
if (players[i].spectator)
|
||||||
|
@ -2565,7 +2575,7 @@ static void Command_Ban(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server || adminplayer == consoleplayer)
|
if (server || IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
UINT8 *p = buf;
|
UINT8 *p = buf;
|
||||||
|
@ -2631,7 +2641,7 @@ static void Command_Kick(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server || adminplayer == consoleplayer)
|
if (server || IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
UINT8 *p = buf;
|
UINT8 *p = buf;
|
||||||
|
@ -2640,13 +2650,16 @@ static void Command_Kick(void)
|
||||||
if (pn == -1 || pn == 0)
|
if (pn == -1 || pn == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Special case if we are trying to kick a player who is downloading the game state:
|
if (server)
|
||||||
// trigger a timeout instead of kicking them, because a kick would only
|
|
||||||
// take effect after they have finished downloading
|
|
||||||
if (sendingsavegame[playernode[pn]])
|
|
||||||
{
|
{
|
||||||
Net_ConnectionTimeout(playernode[pn]);
|
// Special case if we are trying to kick a player who is downloading the game state:
|
||||||
return;
|
// trigger a timeout instead of kicking them, because a kick would only
|
||||||
|
// take effect after they have finished downloading
|
||||||
|
if (sendingsavegame[playernode[pn]])
|
||||||
|
{
|
||||||
|
Net_ConnectionTimeout(playernode[pn]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITESINT8(p, pn);
|
WRITESINT8(p, pn);
|
||||||
|
@ -2684,11 +2697,12 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
INT32 pnum, msg;
|
INT32 pnum, msg;
|
||||||
XBOXSTATIC char buf[3 + MAX_REASONLENGTH];
|
XBOXSTATIC char buf[3 + MAX_REASONLENGTH];
|
||||||
char *reason = buf;
|
char *reason = buf;
|
||||||
|
kickreason_t kickreason = KR_KICK;
|
||||||
|
|
||||||
pnum = READUINT8(*p);
|
pnum = READUINT8(*p);
|
||||||
msg = READUINT8(*p);
|
msg = READUINT8(*p);
|
||||||
|
|
||||||
if (pnum == serverplayer && playernum == adminplayer)
|
if (pnum == serverplayer && IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n"));
|
CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n"));
|
||||||
|
|
||||||
|
@ -2699,7 +2713,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is playernum authorized to make this kick?
|
// Is playernum authorized to make this kick?
|
||||||
if (playernum != serverplayer && playernum != adminplayer
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum)
|
||||||
&& !(playerpernode[playernode[playernum]] == 2
|
&& !(playerpernode[playernode[playernum]] == 2
|
||||||
&& nodetoplayer2[playernode[playernum]] == pnum))
|
&& nodetoplayer2[playernode[playernum]] == pnum))
|
||||||
{
|
{
|
||||||
|
@ -2766,14 +2780,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
{
|
{
|
||||||
case KICK_MSG_GO_AWAY:
|
case KICK_MSG_GO_AWAY:
|
||||||
CONS_Printf(M_GetText("has been kicked (Go away)\n"));
|
CONS_Printf(M_GetText("has been kicked (Go away)\n"));
|
||||||
|
kickreason = KR_KICK;
|
||||||
break;
|
break;
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
case KICK_MSG_PING_HIGH:
|
case KICK_MSG_PING_HIGH:
|
||||||
CONS_Printf(M_GetText("left the game (Broke ping limit)\n"));
|
CONS_Printf(M_GetText("left the game (Broke ping limit)\n"));
|
||||||
|
kickreason = KR_PINGLIMIT;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KICK_MSG_CON_FAIL:
|
case KICK_MSG_CON_FAIL:
|
||||||
CONS_Printf(M_GetText("left the game (Synch failure)\n"));
|
CONS_Printf(M_GetText("left the game (Synch failure)\n"));
|
||||||
|
kickreason = KR_SYNCH;
|
||||||
|
|
||||||
if (M_CheckParm("-consisdump")) // Helps debugging some problems
|
if (M_CheckParm("-consisdump")) // Helps debugging some problems
|
||||||
{
|
{
|
||||||
|
@ -2810,21 +2827,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_TIMEOUT:
|
case KICK_MSG_TIMEOUT:
|
||||||
CONS_Printf(M_GetText("left the game (Connection timeout)\n"));
|
CONS_Printf(M_GetText("left the game (Connection timeout)\n"));
|
||||||
|
kickreason = KR_TIMEOUT;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_PLAYER_QUIT:
|
case KICK_MSG_PLAYER_QUIT:
|
||||||
if (netgame) // not splitscreen/bots
|
if (netgame) // not splitscreen/bots
|
||||||
CONS_Printf(M_GetText("left the game\n"));
|
CONS_Printf(M_GetText("left the game\n"));
|
||||||
|
kickreason = KR_LEAVE;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_BANNED:
|
case KICK_MSG_BANNED:
|
||||||
CONS_Printf(M_GetText("has been banned (Don't come back)\n"));
|
CONS_Printf(M_GetText("has been banned (Don't come back)\n"));
|
||||||
|
kickreason = KR_BAN;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_CUSTOM_KICK:
|
case KICK_MSG_CUSTOM_KICK:
|
||||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||||
CONS_Printf(M_GetText("has been kicked (%s)\n"), reason);
|
CONS_Printf(M_GetText("has been kicked (%s)\n"), reason);
|
||||||
|
kickreason = KR_KICK;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_CUSTOM_BAN:
|
case KICK_MSG_CUSTOM_BAN:
|
||||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||||
CONS_Printf(M_GetText("has been banned (%s)\n"), reason);
|
CONS_Printf(M_GetText("has been banned (%s)\n"), reason);
|
||||||
|
kickreason = KR_BAN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2852,7 +2874,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);
|
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
}
|
}
|
||||||
else
|
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 };
|
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||||
|
@ -2962,6 +2984,7 @@ void SV_ResetServer(void)
|
||||||
playeringame[i] = false;
|
playeringame[i] = false;
|
||||||
playernode[i] = UINT8_MAX;
|
playernode[i] = UINT8_MAX;
|
||||||
sprintf(player_names[i], "Player %d", i + 1);
|
sprintf(player_names[i], "Player %d", i + 1);
|
||||||
|
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
||||||
}
|
}
|
||||||
|
|
||||||
mynode = 0;
|
mynode = 0;
|
||||||
|
@ -3036,7 +3059,7 @@ void D_QuitNetGame(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
D_CloseConnection();
|
D_CloseConnection();
|
||||||
adminplayer = -1;
|
ClearAdminPlayers();
|
||||||
|
|
||||||
DEBFILE("===========================================================================\n"
|
DEBFILE("===========================================================================\n"
|
||||||
" Log finish\n"
|
" Log finish\n"
|
||||||
|
@ -3067,7 +3090,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
INT16 node, newplayernum;
|
INT16 node, newplayernum;
|
||||||
boolean splitscreenplayer;
|
boolean splitscreenplayer;
|
||||||
|
|
||||||
if (playernum != serverplayer && playernum != adminplayer)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
// protect against hacked/buggy client
|
// protect against hacked/buggy client
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
|
||||||
|
@ -3592,7 +3615,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||||
gametype = netbuffer->u.servercfg.gametype;
|
gametype = netbuffer->u.servercfg.gametype;
|
||||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||||
adminplayer = netbuffer->u.servercfg.adminplayer;
|
for (j = 0; j < MAXPLAYERS; j++)
|
||||||
|
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
|
||||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4461,6 +4485,7 @@ static void Local_Maketic(INT32 realtics)
|
||||||
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
||||||
{
|
{
|
||||||
tic_t tic;
|
tic_t tic;
|
||||||
|
UINT8 numadjust = 0;
|
||||||
|
|
||||||
(void)x;
|
(void)x;
|
||||||
(void)y;
|
(void)y;
|
||||||
|
@ -4470,7 +4495,21 @@ void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
||||||
// spawning, but will be applied afterwards.
|
// spawning, but will be applied afterwards.
|
||||||
|
|
||||||
for (tic = server ? maketic : (neededtic - 1); tic >= gametic; tic--)
|
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);
|
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
|
// create missed tic
|
||||||
|
|
|
@ -282,7 +282,7 @@ typedef struct
|
||||||
|
|
||||||
UINT8 gametype;
|
UINT8 gametype;
|
||||||
UINT8 modifiedgame;
|
UINT8 modifiedgame;
|
||||||
SINT8 adminplayer; // Needs to be signed
|
SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
|
||||||
|
|
||||||
char server_context[8]; // Unique context id, generated at server startup.
|
char server_context[8]; // Unique context id, generated at server startup.
|
||||||
|
|
||||||
|
@ -445,6 +445,17 @@ extern consvar_t cv_playbackspeed;
|
||||||
#define KICK_MSG_CUSTOM_KICK 7
|
#define KICK_MSG_CUSTOM_KICK 7
|
||||||
#define KICK_MSG_CUSTOM_BAN 8
|
#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;
|
extern boolean server;
|
||||||
#define client (!server)
|
#define client (!server)
|
||||||
extern boolean dedicated; // For dedicated server
|
extern boolean dedicated; // For dedicated server
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "i_tcp.h"
|
#include "i_tcp.h"
|
||||||
|
#include "d_main.h" // srb2home
|
||||||
|
|
||||||
//
|
//
|
||||||
// NETWORKING
|
// NETWORKING
|
||||||
|
@ -1374,12 +1375,12 @@ boolean D_CheckNetGame(void)
|
||||||
{
|
{
|
||||||
k++;
|
k++;
|
||||||
sprintf(filename, "debug%d.txt", k);
|
sprintf(filename, "debug%d.txt", k);
|
||||||
debugfile = fopen(filename, "w");
|
debugfile = fopen(va("%s" PATHSEP "%s", srb2home, filename), "w");
|
||||||
}
|
}
|
||||||
if (debugfile)
|
if (debugfile)
|
||||||
CONS_Printf(M_GetText("debug output to: %s\n"), filename);
|
CONS_Printf(M_GetText("debug output to: %s\n"), va("%s" PATHSEP "%s", srb2home, filename));
|
||||||
else
|
else
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("cannot debug output to file %s!\n"), filename);
|
CONS_Alert(CONS_WARNING, M_GetText("cannot debug output to file %s!\n"), va("%s" PATHSEP "%s", srb2home, filename));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
257
src/d_netcmd.c
257
src/d_netcmd.c
|
@ -145,7 +145,9 @@ static void Command_Changepassword_f(void);
|
||||||
static void Command_Login_f(void);
|
static void Command_Login_f(void);
|
||||||
static void Got_Login(UINT8 **cp, INT32 playernum);
|
static void Got_Login(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_Verification(UINT8 **cp, INT32 playernum);
|
static void Got_Verification(UINT8 **cp, INT32 playernum);
|
||||||
|
static void Got_Removal(UINT8 **cp, INT32 playernum);
|
||||||
static void Command_Verify_f(void);
|
static void Command_Verify_f(void);
|
||||||
|
static void Command_RemoveAdmin_f(void);
|
||||||
static void Command_MotD_f(void);
|
static void Command_MotD_f(void);
|
||||||
static void Got_MotD_f(UINT8 **cp, INT32 playernum);
|
static void Got_MotD_f(UINT8 **cp, INT32 playernum);
|
||||||
|
|
||||||
|
@ -241,7 +243,7 @@ INT32 cv_debug;
|
||||||
consvar_t cv_usemouse = {"use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_usemouse = {"use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
#if defined (DC) || defined (_XBOX) || defined (WMINPUT) || defined (_WII) //joystick 1 and 2
|
#if defined (DC) || defined (_XBOX) || defined (WMINPUT) || defined (_WII) || defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2
|
||||||
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||||
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
|
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||||
|
@ -318,7 +320,6 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL,
|
||||||
consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
|
consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
|
||||||
|
|
||||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
||||||
PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
@ -366,7 +367,7 @@ consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL
|
||||||
INT16 gametype = GT_COOP;
|
INT16 gametype = GT_COOP;
|
||||||
boolean splitscreen = false;
|
boolean splitscreen = false;
|
||||||
boolean circuitmap = false;
|
boolean circuitmap = false;
|
||||||
INT32 adminplayer = -1;
|
INT32 adminplayers[MAXPLAYERS];
|
||||||
|
|
||||||
/// \warning Keep this up-to-date if you add/remove/rename net text commands
|
/// \warning Keep this up-to-date if you add/remove/rename net text commands
|
||||||
const char *netxcmdnames[MAXNETXCMD - 1] =
|
const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||||
|
@ -428,8 +429,10 @@ void D_RegisterServerCommands(void)
|
||||||
COM_AddCommand("password", Command_Changepassword_f);
|
COM_AddCommand("password", Command_Changepassword_f);
|
||||||
RegisterNetXCmd(XD_LOGIN, Got_Login);
|
RegisterNetXCmd(XD_LOGIN, Got_Login);
|
||||||
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
||||||
COM_AddCommand("verify", Command_Verify_f);
|
COM_AddCommand("promote", Command_Verify_f);
|
||||||
RegisterNetXCmd(XD_VERIFIED, Got_Verification);
|
RegisterNetXCmd(XD_VERIFIED, Got_Verification);
|
||||||
|
COM_AddCommand("demote", Command_RemoveAdmin_f);
|
||||||
|
RegisterNetXCmd(XD_DEMOTED, Got_Removal);
|
||||||
|
|
||||||
COM_AddCommand("motd", Command_MotD_f);
|
COM_AddCommand("motd", Command_MotD_f);
|
||||||
RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin
|
RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin
|
||||||
|
@ -675,6 +678,8 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_crosshair2);
|
CV_RegisterVar(&cv_crosshair2);
|
||||||
CV_RegisterVar(&cv_alwaysfreelook);
|
CV_RegisterVar(&cv_alwaysfreelook);
|
||||||
CV_RegisterVar(&cv_alwaysfreelook2);
|
CV_RegisterVar(&cv_alwaysfreelook2);
|
||||||
|
CV_RegisterVar(&cv_chasefreelook);
|
||||||
|
CV_RegisterVar(&cv_chasefreelook2);
|
||||||
|
|
||||||
// g_input.c
|
// g_input.c
|
||||||
CV_RegisterVar(&cv_sideaxis);
|
CV_RegisterVar(&cv_sideaxis);
|
||||||
|
@ -1014,7 +1019,7 @@ UINT8 CanChangeSkin(INT32 playernum)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Force skin in effect.
|
// Force skin in effect.
|
||||||
if (client && (cv_forceskin.value != -1) && !(adminplayer == playernum && serverplayer == -1))
|
if (client && (cv_forceskin.value != -1) && !(IsPlayerAdmin(playernum) && serverplayer == -1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can change skin in intermission and whatnot.
|
// Can change skin in intermission and whatnot.
|
||||||
|
@ -1165,7 +1170,7 @@ static void SendNameAndColor(void)
|
||||||
snacpending++;
|
snacpending++;
|
||||||
|
|
||||||
// Don't change name if muted
|
// Don't change name if muted
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
|
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
|
||||||
else // Cleanup name if changing it
|
else // Cleanup name if changing it
|
||||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||||
|
@ -1452,7 +1457,12 @@ static void Command_Playdemo_f(void)
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name);
|
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)
|
static void Command_Timedemo_f(void)
|
||||||
|
@ -1572,7 +1582,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
||||||
mapchangepending = 0;
|
mapchangepending = 0;
|
||||||
// spawn the server if needed
|
// spawn the server if needed
|
||||||
// reset players if there is a new one
|
// reset players if there is a new one
|
||||||
if (!(adminplayer == consoleplayer))
|
if (!IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
if (SV_SpawnServer())
|
if (SV_SpawnServer())
|
||||||
buf[0] &= ~(1<<1);
|
buf[0] &= ~(1<<1);
|
||||||
|
@ -1630,7 +1640,7 @@ static void Command_Map_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client && !(adminplayer == consoleplayer))
|
if (client && !IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -1758,8 +1768,11 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
UINT8 flags;
|
UINT8 flags;
|
||||||
INT32 resetplayer = 1, lastgametype;
|
INT32 resetplayer = 1, lastgametype;
|
||||||
UINT8 skipprecutscene, FLS;
|
UINT8 skipprecutscene, FLS;
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
INT16 mapnumber;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (playernum != serverplayer && playernum != adminplayer)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -1819,7 +1832,8 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
LUAh_MapChange();
|
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||||
|
LUAh_MapChange(mapnumber);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene);
|
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene);
|
||||||
|
@ -1860,7 +1874,7 @@ static void Command_Pause(void)
|
||||||
else
|
else
|
||||||
WRITEUINT8(cp, 0);
|
WRITEUINT8(cp, 0);
|
||||||
|
|
||||||
if (cv_pause.value || server || (adminplayer == consoleplayer))
|
if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
|
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
|
||||||
{
|
{
|
||||||
|
@ -1878,7 +1892,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
|
||||||
UINT8 dedicatedpause = false;
|
UINT8 dedicatedpause = false;
|
||||||
const char *playername;
|
const char *playername;
|
||||||
|
|
||||||
if (netgame && !cv_pause.value && playernum != serverplayer && playernum != adminplayer)
|
if (netgame && !cv_pause.value && playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -2007,7 +2021,7 @@ static void Got_RandomSeed(UINT8 **cp, INT32 playernum)
|
||||||
*/
|
*/
|
||||||
static void Command_Clearscores_f(void)
|
static void Command_Clearscores_f(void)
|
||||||
{
|
{
|
||||||
if (!(server || (adminplayer == consoleplayer)))
|
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SendNetXCmd(XD_CLEARSCORES, NULL, 1);
|
SendNetXCmd(XD_CLEARSCORES, NULL, 1);
|
||||||
|
@ -2027,7 +2041,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
(void)cp;
|
(void)cp;
|
||||||
if (playernum != serverplayer && playernum != adminplayer)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -2248,7 +2262,7 @@ static void Command_ServerTeamChange_f(void)
|
||||||
UINT16 usvalue;
|
UINT16 usvalue;
|
||||||
NetPacket.value.l = NetPacket.value.b = 0;
|
NetPacket.value.l = NetPacket.value.b = 0;
|
||||||
|
|
||||||
if (!(server || (adminplayer == consoleplayer)))
|
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -2395,7 +2409,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
if (NetPacket.packet.verification) // Special marker that the server sent the request
|
if (NetPacket.packet.verification) // Special marker that the server sent the request
|
||||||
{
|
{
|
||||||
if (playernum != serverplayer && (playernum != adminplayer))
|
if (playernum != serverplayer && (!IsPlayerAdmin(playernum)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -2434,7 +2448,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (playernum != serverplayer && (playernum != adminplayer))
|
if (playernum != serverplayer && (!IsPlayerAdmin(playernum)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -2703,6 +2717,12 @@ static void Command_Login_f(void)
|
||||||
XBOXSTATIC UINT8 finalmd5[16];
|
XBOXSTATIC UINT8 finalmd5[16];
|
||||||
const char *pw;
|
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
|
// If the server uses login, it will effectively just remove admin privileges
|
||||||
// from whoever has them. This is good.
|
// from whoever has them. This is good.
|
||||||
if (COM_Argc() != 2)
|
if (COM_Argc() != 2)
|
||||||
|
@ -2751,13 +2771,56 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
|
||||||
if (!memcmp(sentmd5, finalmd5, 16))
|
if (!memcmp(sentmd5, finalmd5, 16))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
|
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
|
||||||
COM_BufInsertText(va("verify %d\n", playernum)); // do this immediately
|
COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]);
|
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean IsPlayerAdmin(INT32 playernum)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
if (playernum == adminplayers[i])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAdminPlayer(INT32 playernum)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playernum == adminplayers[i])
|
||||||
|
return; // Player is already admin
|
||||||
|
|
||||||
|
if (adminplayers[i] == -1)
|
||||||
|
{
|
||||||
|
adminplayers[i] = playernum; // Set the player to a free spot
|
||||||
|
break; // End the loop now. If it keeps going, the same player might get assigned to two slots.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearAdminPlayers(void)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
adminplayers[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAdminPlayer(INT32 playernum)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
if (playernum == adminplayers[i])
|
||||||
|
adminplayers[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void Command_Verify_f(void)
|
static void Command_Verify_f(void)
|
||||||
{
|
{
|
||||||
XBOXSTATIC char buf[8]; // Should be plenty
|
XBOXSTATIC char buf[8]; // Should be plenty
|
||||||
|
@ -2770,9 +2833,15 @@ static void Command_Verify_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!netgame)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (COM_Argc() != 2)
|
if (COM_Argc() != 2)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("verify <node>: give admin privileges to a node\n"));
|
CONS_Printf(M_GetText("promote <node>: give admin privileges to a node\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2806,7 +2875,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
adminplayer = num;
|
SetAdminPlayer(num);
|
||||||
|
|
||||||
if (num != consoleplayer)
|
if (num != consoleplayer)
|
||||||
return;
|
return;
|
||||||
|
@ -2814,6 +2883,62 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
|
||||||
CONS_Printf(M_GetText("You are now a server administrator.\n"));
|
CONS_Printf(M_GetText("You are now a server administrator.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Command_RemoveAdmin_f(void)
|
||||||
|
{
|
||||||
|
XBOXSTATIC char buf[8]; // Should be plenty
|
||||||
|
char *temp;
|
||||||
|
INT32 playernum;
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COM_Argc() != 2)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("demote <node>: remove admin privileges from a node\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(buf, COM_Argv(1), sizeof(buf));
|
||||||
|
|
||||||
|
playernum = atoi(buf);
|
||||||
|
|
||||||
|
temp = buf;
|
||||||
|
|
||||||
|
WRITEUINT8(temp, playernum);
|
||||||
|
|
||||||
|
if (playeringame[playernum])
|
||||||
|
SendNetXCmd(XD_DEMOTED, buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Got_Removal(UINT8 **cp, INT32 playernum)
|
||||||
|
{
|
||||||
|
INT16 num = READUINT8(*cp);
|
||||||
|
|
||||||
|
if (playernum != serverplayer) // it's not from the server (hacker or bug)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
XBOXSTATIC UINT8 buf[2];
|
||||||
|
|
||||||
|
buf[0] = (UINT8)playernum;
|
||||||
|
buf[1] = KICK_MSG_CON_FAIL;
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveAdminPlayer(num);
|
||||||
|
|
||||||
|
if (num != consoleplayer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CONS_Printf(M_GetText("You are no longer a server administrator.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
static void Command_MotD_f(void)
|
static void Command_MotD_f(void)
|
||||||
{
|
{
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
@ -2825,7 +2950,7 @@ static void Command_MotD_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(server || (adminplayer == consoleplayer)))
|
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -2849,7 +2974,7 @@ static void Command_MotD_f(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((netgame || multiplayer) && client)
|
if ((netgame || multiplayer) && client)
|
||||||
SendNetXCmd(XD_SETMOTD, mymotd, sizeof(motd));
|
SendNetXCmd(XD_SETMOTD, mymotd, i); // send the actual size of the motd string, not the full buffer's size
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(motd, mymotd);
|
strcpy(motd, mymotd);
|
||||||
|
@ -2872,7 +2997,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum)
|
||||||
if (!isprint(mymotd[i]) || mymotd[i] == ';')
|
if (!isprint(mymotd[i]) || mymotd[i] == ';')
|
||||||
kick = true;
|
kick = true;
|
||||||
|
|
||||||
if ((playernum != serverplayer && playernum != adminplayer) || kick)
|
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -2909,7 +3034,7 @@ static void Command_RunSOC(void)
|
||||||
else
|
else
|
||||||
fn = COM_Argv(1);
|
fn = COM_Argv(1);
|
||||||
|
|
||||||
if (netgame && !(server || consoleplayer == adminplayer))
|
if (netgame && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -2935,7 +3060,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
||||||
char filename[256];
|
char filename[256];
|
||||||
filestatus_t ncs = FS_NOTFOUND;
|
filestatus_t ncs = FS_NOTFOUND;
|
||||||
|
|
||||||
if (playernum != serverplayer && playernum != adminplayer)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -3006,7 +3131,7 @@ static void Command_Addfile(void)
|
||||||
if (!musiconly)
|
if (!musiconly)
|
||||||
{
|
{
|
||||||
// ... But only so long as they contain nothing more then music and sprites.
|
// ... But only so long as they contain nothing more then music and sprites.
|
||||||
if (netgame && !(server || adminplayer == consoleplayer))
|
if (netgame && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -3017,7 +3142,7 @@ static void Command_Addfile(void)
|
||||||
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
||||||
if (!(netgame || multiplayer) || musiconly)
|
if (!(netgame || multiplayer) || musiconly)
|
||||||
{
|
{
|
||||||
P_AddWadFile(fn, NULL);
|
P_AddWadFile(fn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3068,7 +3193,7 @@ static void Command_Addfile(void)
|
||||||
WRITEMEM(buf_p, md5sum, 16);
|
WRITEMEM(buf_p, md5sum, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adminplayer == consoleplayer) // Request to add file
|
if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file
|
||||||
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
|
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
|
||||||
else
|
else
|
||||||
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
|
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
|
||||||
|
@ -3117,7 +3242,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
boolean kick = false;
|
boolean kick = false;
|
||||||
boolean toomany = false;
|
boolean toomany = false;
|
||||||
INT32 i;
|
INT32 i,j;
|
||||||
size_t packetsize = 0;
|
size_t packetsize = 0;
|
||||||
serverinfo_pak *dummycheck = NULL;
|
serverinfo_pak *dummycheck = NULL;
|
||||||
|
|
||||||
|
@ -3136,7 +3261,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
if (!isprint(filename[i]) || filename[i] == ';')
|
if (!isprint(filename[i]) || filename[i] == ';')
|
||||||
kick = true;
|
kick = true;
|
||||||
|
|
||||||
if ((playernum != serverplayer && playernum != adminplayer) || kick)
|
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[2];
|
XBOXSTATIC UINT8 buf[2];
|
||||||
|
|
||||||
|
@ -3170,8 +3295,9 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
CONS_Printf("%s",message);
|
CONS_Printf("%s",message);
|
||||||
|
|
||||||
if (adminplayer)
|
for (j = 0; j < MAXPLAYERS; j++)
|
||||||
COM_BufAddText(va("sayto %d %s", adminplayer, message));
|
if (adminplayers[j])
|
||||||
|
COM_BufAddText(va("sayto %d %s", adminplayers[j], message));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3231,7 +3357,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
ncs = findfile(filename,md5sum,true);
|
ncs = findfile(filename,md5sum,true);
|
||||||
|
|
||||||
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL))
|
if (ncs != FS_FOUND || !P_AddWadFile(filename))
|
||||||
{
|
{
|
||||||
Command_ExitGame_f();
|
Command_ExitGame_f();
|
||||||
if (ncs == FS_FOUND)
|
if (ncs == FS_FOUND)
|
||||||
|
@ -3286,10 +3412,51 @@ static void Command_ListWADS_f(void)
|
||||||
static void Command_Version_f(void)
|
static void Command_Version_f(void)
|
||||||
{
|
{
|
||||||
#ifdef DEVELOP
|
#ifdef DEVELOP
|
||||||
CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s)\n", compbranch, comprevision, compdate, comptime);
|
CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime);
|
||||||
#else
|
#else
|
||||||
CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s)\n", VERSIONSTRING, compdate, comptime, comprevision);
|
CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Base library
|
||||||
|
#if defined( HAVE_SDL)
|
||||||
|
CONS_Printf("SDL ");
|
||||||
|
#elif defined(_WINDOWS)
|
||||||
|
CONS_Printf("DD ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// OS
|
||||||
|
// Would be nice to use SDL_GetPlatform for this
|
||||||
|
#if defined (_WIN32) || defined (_WIN64)
|
||||||
|
CONS_Printf("Windows ");
|
||||||
|
#elif defined(__linux__)
|
||||||
|
CONS_Printf("Linux ");
|
||||||
|
#elif defined(MACOSX)
|
||||||
|
CONS_Printf("macOS" );
|
||||||
|
#elif defined(UNIXCOMMON)
|
||||||
|
CONS_Printf("Unix (Common) ");
|
||||||
|
#else
|
||||||
|
CONS_Printf("Other OS ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Bitness
|
||||||
|
if (sizeof(void*) == 4)
|
||||||
|
CONS_Printf("32-bit ");
|
||||||
|
else if (sizeof(void*) == 8)
|
||||||
|
CONS_Printf("64-bit ");
|
||||||
|
else // 16-bit? 128-bit?
|
||||||
|
CONS_Printf("Bits Unknown ");
|
||||||
|
|
||||||
|
// No ASM?
|
||||||
|
#ifdef NOASM
|
||||||
|
CONS_Printf("\x85" "NOASM " "\x80");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Debug build
|
||||||
|
#ifdef _DEBUG
|
||||||
|
CONS_Printf("\x85" "DEBUG " "\x80");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CONS_Printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UPDATE_ALERT
|
#ifdef UPDATE_ALERT
|
||||||
|
@ -3568,7 +3735,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
players[i].ctfteam = 0;
|
players[i].ctfteam = 0;
|
||||||
|
|
||||||
if (server || (adminplayer == consoleplayer))
|
if (server || (IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CV_StealthSetValue(&cv_teamscramble, 0);
|
CV_StealthSetValue(&cv_teamscramble, 0);
|
||||||
teamscramble = 0;
|
teamscramble = 0;
|
||||||
|
@ -3651,7 +3818,7 @@ static void TeamScramble_OnChange(void)
|
||||||
if (!cv_teamscramble.value)
|
if (!cv_teamscramble.value)
|
||||||
teamscramble = 0;
|
teamscramble = 0;
|
||||||
|
|
||||||
if (!G_GametypeHasTeams() && (server || consoleplayer == adminplayer))
|
if (!G_GametypeHasTeams() && (server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n"));
|
||||||
CV_StealthSetValue(&cv_teamscramble, 0);
|
CV_StealthSetValue(&cv_teamscramble, 0);
|
||||||
|
@ -3830,7 +3997,7 @@ static void Command_ExitLevel_f(void)
|
||||||
{
|
{
|
||||||
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
|
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
|
||||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
else if (!(server || (adminplayer == consoleplayer)))
|
else if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
else if (gamestate != GS_LEVEL || demoplayback)
|
else if (gamestate != GS_LEVEL || demoplayback)
|
||||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||||
|
@ -3846,7 +4013,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
||||||
if (gameaction == ga_completed)
|
if (gameaction == ga_completed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (playernum != serverplayer && playernum != adminplayer)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -3954,7 +4121,7 @@ static void Command_Cheats_f(void)
|
||||||
{
|
{
|
||||||
if (COM_CheckParm("off"))
|
if (COM_CheckParm("off"))
|
||||||
{
|
{
|
||||||
if (!(server || (adminplayer == consoleplayer)))
|
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
else
|
else
|
||||||
CV_ResetCheatNetVars();
|
CV_ResetCheatNetVars();
|
||||||
|
@ -3964,7 +4131,7 @@ static void Command_Cheats_f(void)
|
||||||
if (CV_CheatsEnabled())
|
if (CV_CheatsEnabled())
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n"));
|
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n"));
|
||||||
if (server || (adminplayer == consoleplayer))
|
if (server || (IsPlayerAdmin(consoleplayer)))
|
||||||
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
|
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4033,7 +4200,7 @@ static void Command_Archivetest_f(void)
|
||||||
*/
|
*/
|
||||||
static void ForceSkin_OnChange(void)
|
static void ForceSkin_OnChange(void)
|
||||||
{
|
{
|
||||||
if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins))
|
if ((server || IsPlayerAdmin(consoleplayer)) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins))
|
||||||
{
|
{
|
||||||
if (cv_forceskin.value == -2)
|
if (cv_forceskin.value == -2)
|
||||||
CV_SetValue(&cv_forceskin, numskins-1);
|
CV_SetValue(&cv_forceskin, numskins-1);
|
||||||
|
@ -4063,7 +4230,7 @@ static void ForceSkin_OnChange(void)
|
||||||
//Allows the player's name to be changed if cv_mute is off.
|
//Allows the player's name to be changed if cv_mute is off.
|
||||||
static void Name_OnChange(void)
|
static void Name_OnChange(void)
|
||||||
{
|
{
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
|
||||||
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
|
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
|
||||||
|
@ -4186,7 +4353,7 @@ static void Color2_OnChange(void)
|
||||||
*/
|
*/
|
||||||
static void Mute_OnChange(void)
|
static void Mute_OnChange(void)
|
||||||
{
|
{
|
||||||
if (server || (adminplayer == consoleplayer))
|
if (server || (IsPlayerAdmin(consoleplayer)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cv_mute.value)
|
if (cv_mute.value)
|
||||||
|
|
|
@ -133,9 +133,10 @@ typedef enum
|
||||||
XD_DELFILE, // 18
|
XD_DELFILE, // 18
|
||||||
XD_SETMOTD, // 19
|
XD_SETMOTD, // 19
|
||||||
XD_SUICIDE, // 20
|
XD_SUICIDE, // 20
|
||||||
|
XD_DEMOTED, // 21
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
XD_LUACMD, // 21
|
XD_LUACMD, // 22
|
||||||
XD_LUAVAR, // 22
|
XD_LUAVAR, // 23
|
||||||
#endif
|
#endif
|
||||||
MAXNETXCMD
|
MAXNETXCMD
|
||||||
} netxcmd_t;
|
} netxcmd_t;
|
||||||
|
@ -190,6 +191,10 @@ void Command_ExitGame_f(void);
|
||||||
void Command_Retry_f(void);
|
void Command_Retry_f(void);
|
||||||
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
||||||
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
|
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
|
||||||
|
boolean IsPlayerAdmin(INT32 playernum);
|
||||||
|
void SetAdminPlayer(INT32 playernum);
|
||||||
|
void ClearAdminPlayers(void);
|
||||||
|
void RemoveAdminPlayer(INT32 playernum);
|
||||||
void ItemFinder_OnChange(void);
|
void ItemFinder_OnChange(void);
|
||||||
void D_SetPassword(const char *pw);
|
void D_SetPassword(const char *pw);
|
||||||
|
|
||||||
|
|
|
@ -425,7 +425,7 @@ void CL_LoadServerFiles(void)
|
||||||
continue; // Already loaded
|
continue; // Already loaded
|
||||||
else if (fileneeded[i].status == FS_FOUND)
|
else if (fileneeded[i].status == FS_FOUND)
|
||||||
{
|
{
|
||||||
P_AddWadFile(fileneeded[i].filename, NULL);
|
P_AddWadFile(fileneeded[i].filename);
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true);
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
|
||||||
#include "m_cond.h"
|
#include "m_cond.h"
|
||||||
|
|
||||||
|
@ -1035,7 +1036,10 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -1616,7 +1620,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -1860,7 +1867,6 @@ static void readframe(MYFILE *f, INT32 num)
|
||||||
char *word1;
|
char *word1;
|
||||||
char *word2 = NULL;
|
char *word2 = NULL;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
INT32 j;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -1875,16 +1881,6 @@ static void readframe(MYFILE *f, INT32 num)
|
||||||
if (s == tmp)
|
if (s == tmp)
|
||||||
continue; // Skip comment lines, but don't break.
|
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, " ");
|
word1 = strtok(s, " ");
|
||||||
if (word1)
|
if (word1)
|
||||||
strupr(word1);
|
strupr(word1);
|
||||||
|
@ -2129,7 +2125,10 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -2269,7 +2268,10 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -2353,7 +2355,10 @@ static void readunlockable(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -2640,7 +2645,10 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -2885,7 +2893,10 @@ static void readmaincfg(MYFILE *f)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -3069,7 +3080,7 @@ static void readmaincfg(MYFILE *f)
|
||||||
strncpy(timeattackfolder, gamedatafilename, min(filenamelen, sizeof (timeattackfolder)));
|
strncpy(timeattackfolder, gamedatafilename, min(filenamelen, sizeof (timeattackfolder)));
|
||||||
timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0';
|
timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0';
|
||||||
|
|
||||||
strncpy(savegamename, timeattackfolder, strlen(timeattackfolder));
|
strcpy(savegamename, timeattackfolder);
|
||||||
strlcat(savegamename, "%u.ssg", sizeof(savegamename));
|
strlcat(savegamename, "%u.ssg", sizeof(savegamename));
|
||||||
// can't use sprintf since there is %u in savegamename
|
// can't use sprintf since there is %u in savegamename
|
||||||
strcatbf(savegamename, srb2home, PATHSEP);
|
strcatbf(savegamename, srb2home, PATHSEP);
|
||||||
|
@ -3124,7 +3135,10 @@ static void readwipes(MYFILE *f)
|
||||||
|
|
||||||
// Get the part before the " = "
|
// Get the part before the " = "
|
||||||
tmp = strchr(s, '=');
|
tmp = strchr(s, '=');
|
||||||
*(tmp-1) = '\0';
|
if (tmp)
|
||||||
|
*(tmp-1) = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
strupr(word);
|
strupr(word);
|
||||||
|
|
||||||
// Now get the part after
|
// Now get the part after
|
||||||
|
@ -7272,6 +7286,14 @@ struct {
|
||||||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
{"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
|
// Angles
|
||||||
{"ANG1",ANG1},
|
{"ANG1",ANG1},
|
||||||
{"ANG2",ANG2},
|
{"ANG2",ANG2},
|
||||||
|
@ -7395,6 +7417,14 @@ struct {
|
||||||
|
|
||||||
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
|
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
|
||||||
{"V_ALPHASHIFT",V_ALPHASHIFT},
|
{"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
|
#endif
|
||||||
|
|
||||||
{NULL,0}
|
{NULL,0}
|
||||||
|
@ -8204,6 +8234,9 @@ static inline int lib_getenum(lua_State *L)
|
||||||
} else if (fastcmp(word,"maptol")) {
|
} else if (fastcmp(word,"maptol")) {
|
||||||
lua_pushinteger(L, maptol);
|
lua_pushinteger(L, maptol);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (fastcmp(word,"ultimatemode")) {
|
||||||
|
lua_pushboolean(L, ultimatemode != 0);
|
||||||
|
return 1;
|
||||||
} else if (fastcmp(word,"mariomode")) {
|
} else if (fastcmp(word,"mariomode")) {
|
||||||
lua_pushboolean(L, mariomode != 0);
|
lua_pushboolean(L, mariomode != 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -8269,10 +8302,10 @@ static inline int lib_getenum(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
|
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (fastcmp(word,"admin")) {
|
} else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array.
|
||||||
if (!playeringame[adminplayer] || adminplayer == serverplayer)
|
if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
|
||||||
return 0;
|
return 0;
|
||||||
LUA_PushUserdata(L, &players[adminplayer], META_PLAYER);
|
LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (fastcmp(word,"emeralds")) {
|
} else if (fastcmp(word,"emeralds")) {
|
||||||
lua_pushinteger(L, emeralds);
|
lua_pushinteger(L, emeralds);
|
||||||
|
|
|
@ -150,9 +150,9 @@ extern FILE *logstream;
|
||||||
// we use comprevision and compbranch instead.
|
// we use comprevision and compbranch instead.
|
||||||
#else
|
#else
|
||||||
#define VERSION 201 // Game version
|
#define VERSION 201 // Game version
|
||||||
#define SUBVERSION 20 // more precise version number
|
#define SUBVERSION 21 // more precise version number
|
||||||
#define VERSIONSTRING "v2.1.20"
|
#define VERSIONSTRING "v2.1.21"
|
||||||
#define VERSIONSTRINGW L"v2.1.20"
|
#define VERSIONSTRINGW L"v2.1.21"
|
||||||
// Hey! If you change this, add 1 to the MODVERSION below!
|
// Hey! If you change this, add 1 to the MODVERSION below!
|
||||||
// Otherwise we can't force updates!
|
// Otherwise we can't force updates!
|
||||||
#endif
|
#endif
|
||||||
|
@ -214,7 +214,7 @@ extern FILE *logstream;
|
||||||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||||
// Only set it higher, not lower, obviously.
|
// Only set it higher, not lower, obviously.
|
||||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||||
#define MODVERSION 25
|
#define MODVERSION 26
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
|
|
@ -476,7 +476,8 @@ extern consvar_t cv_timetic; // display high resolution timer
|
||||||
extern consvar_t cv_forceskin; // force clients to use the server's skin
|
extern consvar_t cv_forceskin; // force clients to use the server's skin
|
||||||
extern consvar_t cv_downloading; // allow clients to downloading WADs.
|
extern consvar_t cv_downloading; // allow clients to downloading WADs.
|
||||||
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||||
extern INT32 adminplayer, serverplayer;
|
extern INT32 serverplayer;
|
||||||
|
extern INT32 adminplayers[MAXPLAYERS];
|
||||||
|
|
||||||
/// \note put these in d_clisrv outright?
|
/// \note put these in d_clisrv outright?
|
||||||
|
|
||||||
|
|
|
@ -1739,7 +1739,7 @@ static void F_AdvanceToNextScene(void)
|
||||||
|
|
||||||
void F_EndCutScene(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 (runningprecutscene)
|
||||||
{
|
{
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -1754,7 +1754,7 @@ void F_EndCutScene(void)
|
||||||
else if (nextmap < 1100-1)
|
else if (nextmap < 1100-1)
|
||||||
G_NextLevel();
|
G_NextLevel();
|
||||||
else
|
else
|
||||||
Y_EndGame();
|
G_EndGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1858,7 +1858,7 @@ void F_CutsceneTicker(void)
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (netgame && i != serverplayer && i != adminplayer)
|
if (netgame && i != serverplayer && !IsPlayerAdmin(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (players[i].cmd.buttons & BT_USE)
|
if (players[i].cmd.buttons & BT_USE)
|
||||||
|
|
114
src/g_game.c
114
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_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_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_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_invertmouse2 = {"invertmouse2", "Off", 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_alwaysfreelook = {"alwaysmlook", "On", 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_alwaysfreelook2 = {"alwaysmlook2", "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_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};
|
consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#ifdef DC
|
#ifdef DC
|
||||||
|
@ -385,7 +387,7 @@ consvar_t cv_lookaxis = {"joyaxis_look", "RStick.Y", CV_SAVE, joyaxis_cons_t, NU
|
||||||
consvar_t cv_fireaxis = {"joyaxis_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_fireaxis = {"joyaxis_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_firenaxis = {"joyaxis_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_firenaxis = {"joyaxis_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#else
|
#else
|
||||||
consvar_t cv_turnaxis = {"joyaxis_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_turnaxis = {"joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#ifdef PSP
|
#ifdef PSP
|
||||||
consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#else
|
#else
|
||||||
|
@ -399,17 +401,17 @@ consvar_t cv_lookaxis = {"joyaxis_look", "Alt Y-Axis", CV_SAVE, joyaxis_cons_t,
|
||||||
#elif defined (PSP)
|
#elif defined (PSP)
|
||||||
consvar_t cv_sideaxis = {"joyaxis_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_sideaxis = {"joyaxis_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#else
|
#else
|
||||||
consvar_t cv_sideaxis = {"joyaxis_side", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_sideaxis = {"joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
#ifndef _XBOX
|
#ifndef _XBOX
|
||||||
#ifdef PSP
|
#ifdef PSP
|
||||||
consvar_t cv_lookaxis = {"joyaxis_look", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_lookaxis = {"joyaxis_look", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#else
|
#else
|
||||||
consvar_t cv_lookaxis = {"joyaxis_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_lookaxis = {"joyaxis_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
consvar_t cv_fireaxis = {"joyaxis_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_fireaxis = {"joyaxis_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_firenaxis = {"joyaxis_firenormal", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_firenaxis = {"joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (_WII) || defined (WMINPUT)
|
#if defined (_WII) || defined (WMINPUT)
|
||||||
|
@ -420,7 +422,7 @@ consvar_t cv_lookaxis2 = {"joyaxis2_look", "RStick.Y", CV_SAVE, joyaxis_cons_t,
|
||||||
consvar_t cv_fireaxis2 = {"joyaxis2_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_fireaxis2 = {"joyaxis2_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#else
|
#else
|
||||||
consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_moveaxis2 = {"joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_moveaxis2 = {"joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#ifdef _arch_dreamcast
|
#ifdef _arch_dreamcast
|
||||||
consvar_t cv_sideaxis2 = {"joyaxis2_side", "Triggers", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_sideaxis2 = {"joyaxis2_side", "Triggers", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
@ -430,13 +432,13 @@ consvar_t cv_lookaxis2 = {"joyaxis2_look", "Alt Y-Axis", CV_SAVE, joyaxis_cons_t
|
||||||
#elif defined (_PSP)
|
#elif defined (_PSP)
|
||||||
consvar_t cv_sideaxis2 = {"joyaxis2_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_sideaxis2 = {"joyaxis2_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#else
|
#else
|
||||||
consvar_t cv_sideaxis2 = {"joyaxis2_side", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_sideaxis2 = {"joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
#ifndef _XBOX
|
#ifndef _XBOX
|
||||||
consvar_t cv_lookaxis2 = {"joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_lookaxis2 = {"joyaxis2_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
consvar_t cv_fireaxis2 = {"joyaxis2_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -958,13 +960,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
||||||
INT32 tspeed, forward, side, axis, i;
|
INT32 tspeed, forward, side, axis, i;
|
||||||
const INT32 speed = 1;
|
const INT32 speed = 1;
|
||||||
// these ones used for multiple conditions
|
// these ones used for multiple conditions
|
||||||
boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove;
|
boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming;
|
||||||
player_t *player = &players[consoleplayer];
|
player_t *player = &players[consoleplayer];
|
||||||
camera_t *thiscam = &camera;
|
camera_t *thiscam = &camera;
|
||||||
|
|
||||||
static INT32 turnheld; // for accelerative turning
|
static INT32 turnheld; // for accelerative turning
|
||||||
static boolean keyboard_look; // true if lookup/down using keyboard
|
static boolean keyboard_look; // true if lookup/down using keyboard
|
||||||
static boolean resetdown; // don't cam reset every frame
|
static boolean resetdown; // don't cam reset every frame
|
||||||
|
static boolean joyaiming; // check the last frame's value if we need to reset the camera
|
||||||
|
|
||||||
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
|
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
|
||||||
|
|
||||||
|
@ -979,10 +982,18 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
||||||
|
|
||||||
turnright = PLAYER1INPUTDOWN(gc_turnright);
|
turnright = PLAYER1INPUTDOWN(gc_turnright);
|
||||||
turnleft = PLAYER1INPUTDOWN(gc_turnleft);
|
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;
|
analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle;
|
||||||
gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle;
|
gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle;
|
||||||
|
|
||||||
|
thisjoyaiming = (cv_chasecam.value) ? cv_chasefreelook.value : cv_alwaysfreelook.value;
|
||||||
|
|
||||||
|
// Reset the vertical look if we're no longer joyaiming
|
||||||
|
if (!thisjoyaiming && joyaiming)
|
||||||
|
localaiming = 0;
|
||||||
|
joyaiming = thisjoyaiming;
|
||||||
|
|
||||||
axis = JoyAxis(AXISTURN);
|
axis = JoyAxis(AXISTURN);
|
||||||
if (gamepadjoystickmove && axis != 0)
|
if (gamepadjoystickmove && axis != 0)
|
||||||
{
|
{
|
||||||
|
@ -1158,11 +1169,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
||||||
}
|
}
|
||||||
|
|
||||||
axis = JoyAxis(AXISLOOK);
|
axis = JoyAxis(AXISLOOK);
|
||||||
if (analogjoystickmove && axis != 0 && cv_lookaxis.value != 0)
|
if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis.value != 0)
|
||||||
localaiming += (axis<<16) * screen_invert;
|
localaiming += (axis<<16) * screen_invert;
|
||||||
|
|
||||||
// spring back if not using keyboard neither mouselookin'
|
// spring back if not using keyboard neither mouselookin'
|
||||||
if (!keyboard_look && cv_lookaxis.value == 0 && !mouseaiming)
|
if (!keyboard_look && cv_lookaxis.value == 0 && !joyaiming && !mouseaiming)
|
||||||
localaiming = 0;
|
localaiming = 0;
|
||||||
|
|
||||||
if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0))
|
if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0))
|
||||||
|
@ -1249,13 +1260,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
||||||
INT32 tspeed, forward, side, axis, i;
|
INT32 tspeed, forward, side, axis, i;
|
||||||
const INT32 speed = 1;
|
const INT32 speed = 1;
|
||||||
// these ones used for multiple conditions
|
// these ones used for multiple conditions
|
||||||
boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove;
|
boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming;
|
||||||
player_t *player = &players[secondarydisplayplayer];
|
player_t *player = &players[secondarydisplayplayer];
|
||||||
camera_t *thiscam = (player->bot == 2 ? &camera : &camera2);
|
camera_t *thiscam = (player->bot == 2 ? &camera : &camera2);
|
||||||
|
|
||||||
static INT32 turnheld; // for accelerative turning
|
static INT32 turnheld; // for accelerative turning
|
||||||
static boolean keyboard_look; // true if lookup/down using keyboard
|
static boolean keyboard_look; // true if lookup/down using keyboard
|
||||||
static boolean resetdown; // don't cam reset every frame
|
static boolean resetdown; // don't cam reset every frame
|
||||||
|
static boolean joyaiming; // check the last frame's value if we need to reset the camera
|
||||||
|
|
||||||
G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver
|
G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver
|
||||||
|
|
||||||
|
@ -1270,10 +1282,18 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
||||||
|
|
||||||
turnright = PLAYER2INPUTDOWN(gc_turnright);
|
turnright = PLAYER2INPUTDOWN(gc_turnright);
|
||||||
turnleft = PLAYER2INPUTDOWN(gc_turnleft);
|
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;
|
analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle;
|
||||||
gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle;
|
gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle;
|
||||||
|
|
||||||
|
thisjoyaiming = (cv_chasecam2.value) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value;
|
||||||
|
|
||||||
|
// Reset the vertical look if we're no longer joyaiming
|
||||||
|
if (!thisjoyaiming && joyaiming)
|
||||||
|
localaiming2 = 0;
|
||||||
|
joyaiming = thisjoyaiming;
|
||||||
|
|
||||||
axis = Joy2Axis(AXISTURN);
|
axis = Joy2Axis(AXISTURN);
|
||||||
if (gamepadjoystickmove && axis != 0)
|
if (gamepadjoystickmove && axis != 0)
|
||||||
{
|
{
|
||||||
|
@ -1446,11 +1466,11 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
||||||
}
|
}
|
||||||
|
|
||||||
axis = Joy2Axis(AXISLOOK);
|
axis = Joy2Axis(AXISLOOK);
|
||||||
if (analogjoystickmove && axis != 0 && cv_lookaxis2.value != 0)
|
if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis2.value != 0)
|
||||||
localaiming2 += (axis<<16) * screen_invert;
|
localaiming2 += (axis<<16) * screen_invert;
|
||||||
|
|
||||||
// spring back if not using keyboard neither mouselookin'
|
// spring back if not using keyboard neither mouselookin'
|
||||||
if (!keyboard_look && cv_lookaxis2.value == 0 && !mouseaiming)
|
if (!keyboard_look && cv_lookaxis2.value == 0 && !joyaiming && !mouseaiming)
|
||||||
localaiming2 = 0;
|
localaiming2 = 0;
|
||||||
|
|
||||||
if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0))
|
if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0))
|
||||||
|
@ -1673,7 +1693,8 @@ static INT32 camtoggledelay, camtoggledelay2 = 0;
|
||||||
boolean G_Responder(event_t *ev)
|
boolean G_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
// allow spy mode changes even during the demo
|
// allow spy mode changes even during the demo
|
||||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown && ev->data1 == KEY_F12)
|
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||||
|
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
|
||||||
{
|
{
|
||||||
if (splitscreen || !netgame)
|
if (splitscreen || !netgame)
|
||||||
displayplayer = consoleplayer;
|
displayplayer = consoleplayer;
|
||||||
|
@ -1814,7 +1835,8 @@ boolean G_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
case ev_keydown:
|
case ev_keydown:
|
||||||
if (ev->data1 == gamecontrol[gc_pause][0]
|
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)
|
if (!pausedelay)
|
||||||
{
|
{
|
||||||
|
@ -2547,14 +2569,12 @@ void G_DoReborn(INT32 playernum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
{
|
{
|
||||||
LUAh_MapChange();
|
#ifdef HAVE_BLUA
|
||||||
|
LUAh_MapChange(gamemap);
|
||||||
#endif
|
#endif
|
||||||
G_DoLoadLevel(true);
|
G_DoLoadLevel(true);
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2605,7 +2625,7 @@ void G_ExitLevel(void)
|
||||||
CONS_Printf(M_GetText("The round has ended.\n"));
|
CONS_Printf(M_GetText("The round has ended.\n"));
|
||||||
|
|
||||||
// Remove CEcho text on round end.
|
// Remove CEcho text on round end.
|
||||||
HU_DoCEcho("");
|
HU_ClearCEcho();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,7 +2921,7 @@ void G_AfterIntermission(void)
|
||||||
if (nextmap < 1100-1)
|
if (nextmap < 1100-1)
|
||||||
G_NextLevel();
|
G_NextLevel();
|
||||||
else
|
else
|
||||||
Y_EndGame();
|
G_EndGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2987,6 +3007,38 @@ static void G_DoContinued(void)
|
||||||
gameaction = ga_nothing;
|
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
|
// G_LoadGameSettings
|
||||||
//
|
//
|
||||||
|
@ -5091,7 +5143,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
demo_start = false;
|
demo_start = false;
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
LUAh_MapChange();
|
LUAh_MapChange(gamemap);
|
||||||
#endif
|
#endif
|
||||||
displayplayer = consoleplayer = 0;
|
displayplayer = consoleplayer = 0;
|
||||||
memset(playeringame,0,sizeof(playeringame));
|
memset(playeringame,0,sizeof(playeringame));
|
||||||
|
|
|
@ -55,8 +55,8 @@ extern INT16 rw_maximums[NUM_WEAPONS];
|
||||||
|
|
||||||
// used in game menu
|
// used in game menu
|
||||||
extern consvar_t cv_crosshair, cv_crosshair2;
|
extern consvar_t cv_crosshair, cv_crosshair2;
|
||||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
|
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove;
|
||||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
|
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2;
|
||||||
extern consvar_t cv_useranalog, cv_useranalog2;
|
extern consvar_t cv_useranalog, cv_useranalog2;
|
||||||
extern consvar_t cv_analog, cv_analog2;
|
extern consvar_t cv_analog, cv_analog2;
|
||||||
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis;
|
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_Continue(void);
|
||||||
void G_UseContinue(void);
|
void G_UseContinue(void);
|
||||||
void G_AfterIntermission(void);
|
void G_AfterIntermission(void);
|
||||||
|
void G_EndGame(void); // moved from y_inter.c/h and renamed
|
||||||
|
|
||||||
void G_Ticker(boolean run);
|
void G_Ticker(boolean run);
|
||||||
boolean G_Responder(event_t *ev);
|
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}};
|
static CV_PossibleValue_t onecontrolperkey_cons_t[] = {{1, "One"}, {2, "Several"}, {0, NULL}};
|
||||||
|
|
||||||
// mouse values are used once
|
// 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_mousesens = {"mousesens", "20", 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_mousesens2 = {"mousesens2", "20", 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_mouseysens = {"mouseysens", "20", 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_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};
|
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
INT32 mousex, mousey;
|
INT32 mousex, mousey;
|
||||||
|
@ -990,6 +990,10 @@ static const char *gamecontrolname[num_gamecontrols] =
|
||||||
"jump",
|
"jump",
|
||||||
"console",
|
"console",
|
||||||
"pause",
|
"pause",
|
||||||
|
"systemmenu",
|
||||||
|
"screenshot",
|
||||||
|
"recordgif",
|
||||||
|
"viewpoint",
|
||||||
"custom1",
|
"custom1",
|
||||||
"custom2",
|
"custom2",
|
||||||
"custom3",
|
"custom3",
|
||||||
|
@ -1154,10 +1158,8 @@ void G_Controldefault(void)
|
||||||
#else
|
#else
|
||||||
void G_Controldefault(void)
|
void G_Controldefault(void)
|
||||||
{
|
{
|
||||||
gamecontrol[gc_forward ][0] = KEY_UPARROW;
|
gamecontrol[gc_forward ][0] = 'w';
|
||||||
gamecontrol[gc_forward ][1] = 'w';
|
gamecontrol[gc_backward ][0] = 's';
|
||||||
gamecontrol[gc_backward ][0] = KEY_DOWNARROW;
|
|
||||||
gamecontrol[gc_backward ][1] = 's';
|
|
||||||
gamecontrol[gc_strafeleft ][0] = 'a';
|
gamecontrol[gc_strafeleft ][0] = 'a';
|
||||||
gamecontrol[gc_straferight][0] = 'd';
|
gamecontrol[gc_straferight][0] = 'd';
|
||||||
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW;
|
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW;
|
||||||
|
@ -1178,21 +1180,24 @@ void G_Controldefault(void)
|
||||||
gamecontrol[gc_fire ][1] = KEY_MOUSE1+0;
|
gamecontrol[gc_fire ][1] = KEY_MOUSE1+0;
|
||||||
gamecontrol[gc_firenormal ][0] = 'c';
|
gamecontrol[gc_firenormal ][0] = 'c';
|
||||||
gamecontrol[gc_tossflag ][0] = '\'';
|
gamecontrol[gc_tossflag ][0] = '\'';
|
||||||
gamecontrol[gc_use ][0] = 'x';
|
gamecontrol[gc_use ][0] = KEY_LSHIFT;
|
||||||
gamecontrol[gc_camtoggle ][0] = 'v';
|
gamecontrol[gc_camtoggle ][0] = 'v';
|
||||||
gamecontrol[gc_camleft ][0] = '[';
|
gamecontrol[gc_camleft ][0] = '[';
|
||||||
gamecontrol[gc_camright ][0] = ']';
|
gamecontrol[gc_camright ][0] = ']';
|
||||||
gamecontrol[gc_camreset ][0] = 'r';
|
gamecontrol[gc_camreset ][0] = 'r';
|
||||||
gamecontrol[gc_lookup ][0] = KEY_PGUP;
|
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
|
||||||
gamecontrol[gc_lookdown ][0] = KEY_PGDN;
|
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;
|
||||||
gamecontrol[gc_centerview ][0] = KEY_END;
|
gamecontrol[gc_centerview ][0] = KEY_END;
|
||||||
gamecontrol[gc_talkkey ][0] = 't';
|
gamecontrol[gc_talkkey ][0] = 't';
|
||||||
gamecontrol[gc_teamkey ][0] = 'y';
|
gamecontrol[gc_teamkey ][0] = 'y';
|
||||||
gamecontrol[gc_scores ][0] = KEY_TAB;
|
gamecontrol[gc_scores ][0] = KEY_TAB;
|
||||||
gamecontrol[gc_jump ][0] = 'z';
|
gamecontrol[gc_jump ][0] = KEY_SPACE;
|
||||||
gamecontrol[gc_jump ][1] = KEY_MOUSE1+1;
|
|
||||||
gamecontrol[gc_console ][0] = KEY_CONSOLE;
|
gamecontrol[gc_console ][0] = KEY_CONSOLE;
|
||||||
gamecontrol[gc_pause ][0] = KEY_PAUSE;
|
gamecontrol[gc_pause ][0] = 'p';
|
||||||
|
gamecontrol[gc_screenshot ][0] = KEY_F8;
|
||||||
|
gamecontrol[gc_recordgif ][0] = KEY_F9;
|
||||||
|
gamecontrol[gc_viewpoint ][0] = KEY_F12;
|
||||||
|
gamecontrol[gc_systemmenu ][0] = KEY_JOY1+7; // Start
|
||||||
#ifdef WMINPUT
|
#ifdef WMINPUT
|
||||||
gamecontrol[gc_forward ][0] = KEY_JOY1+02; //UP
|
gamecontrol[gc_forward ][0] = KEY_JOY1+02; //UP
|
||||||
gamecontrol[gc_backward ][0] = KEY_JOY1+03; //DOWN
|
gamecontrol[gc_backward ][0] = KEY_JOY1+03; //DOWN
|
||||||
|
@ -1330,11 +1335,31 @@ static void setcontrol(INT32 (*gc)[2], INT32 na)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
keynum = G_KeyStringtoNum(COM_Argv(2));
|
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);
|
G_CheckDoubleUsage(keynum);
|
||||||
gc[numctrl][0] = keynum;
|
gc[numctrl][0] = keynum;
|
||||||
|
|
||||||
if (na == 4)
|
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
|
else
|
||||||
gc[numctrl][1] = 0;
|
gc[numctrl][1] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,10 @@ typedef enum
|
||||||
gc_jump,
|
gc_jump,
|
||||||
gc_console,
|
gc_console,
|
||||||
gc_pause,
|
gc_pause,
|
||||||
|
gc_systemmenu,
|
||||||
|
gc_screenshot,
|
||||||
|
gc_recordgif,
|
||||||
|
gc_viewpoint,
|
||||||
gc_custom1, // Lua scriptable
|
gc_custom1, // Lua scriptable
|
||||||
gc_custom2, // Lua scriptable
|
gc_custom2, // Lua scriptable
|
||||||
gc_custom3, // Lua scriptable
|
gc_custom3, // Lua scriptable
|
||||||
|
|
|
@ -347,14 +347,14 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||||
numwords = COM_Argc() - usedargs;
|
numwords = COM_Argc() - usedargs;
|
||||||
I_Assert(numwords > 0);
|
I_Assert(numwords > 0);
|
||||||
|
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only servers/admins can CSAY.
|
// Only servers/admins can CSAY.
|
||||||
if(!server && adminplayer != consoleplayer)
|
if(!server && IsPlayerAdmin(consoleplayer))
|
||||||
flags &= ~HU_CSAY;
|
flags &= ~HU_CSAY;
|
||||||
|
|
||||||
// We handle HU_SERVER_SAY, not the caller.
|
// We handle HU_SERVER_SAY, not the caller.
|
||||||
|
@ -448,7 +448,7 @@ static void Command_CSay_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!server && adminplayer != consoleplayer)
|
if(!server && !IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use csay.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use csay.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -477,7 +477,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
msg = (char *)*p;
|
msg = (char *)*p;
|
||||||
SKIPSTRING(*p);
|
SKIPSTRING(*p);
|
||||||
|
|
||||||
if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && playernum != adminplayer)
|
if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, cv_mute.value ?
|
CONS_Alert(CONS_WARNING, cv_mute.value ?
|
||||||
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
|
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
|
||||||
|
@ -575,7 +575,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
// Give admins and remote admins their symbols.
|
// Give admins and remote admins their symbols.
|
||||||
if (playernum == serverplayer)
|
if (playernum == serverplayer)
|
||||||
tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(adminchar) + 1, PU_STATIC, NULL);
|
tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(adminchar) + 1, PU_STATIC, NULL);
|
||||||
else if (playernum == adminplayer)
|
else if (IsPlayerAdmin(playernum))
|
||||||
tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(remotechar) + 1, PU_STATIC, NULL);
|
tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(remotechar) + 1, PU_STATIC, NULL);
|
||||||
if (tempchar)
|
if (tempchar)
|
||||||
{
|
{
|
||||||
|
@ -710,7 +710,7 @@ static void HU_queueChatChar(char c)
|
||||||
} while (c);
|
} while (c);
|
||||||
|
|
||||||
// last minute mute check
|
// last minute mute check
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
|
||||||
return;
|
return;
|
||||||
|
@ -768,9 +768,9 @@ boolean HU_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
// enter chat mode
|
// enter chat mode
|
||||||
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
|
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
|
||||||
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer)))
|
&& netgame && (!cv_mute.value || server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
return false;
|
return false;
|
||||||
chat_on = true;
|
chat_on = true;
|
||||||
w_chat[0] = 0;
|
w_chat[0] = 0;
|
||||||
|
@ -778,9 +778,9 @@ boolean HU_Responder(event_t *ev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
|
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
|
||||||
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer)))
|
&& netgame && (!cv_mute.value || server || (IsPlayerAdmin(consoleplayer))))
|
||||||
{
|
{
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||||
return false;
|
return false;
|
||||||
chat_on = true;
|
chat_on = true;
|
||||||
w_chat[0] = 0;
|
w_chat[0] = 0;
|
||||||
|
|
68
src/i_tcp.c
68
src/i_tcp.c
|
@ -713,14 +713,29 @@ static boolean SOCK_CanGet(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NONET
|
#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);
|
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
|
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
|
||||||
#endif
|
#endif
|
||||||
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
|
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;
|
size_t i, j;
|
||||||
|
|
||||||
if (!nodeconnected[doomcom->remotenode])
|
if (!nodeconnected[doomcom->remotenode])
|
||||||
|
@ -733,19 +748,7 @@ static void SOCK_Send(void)
|
||||||
for (j = 0; j < broadcastaddresses; j++)
|
for (j = 0; j < broadcastaddresses; j++)
|
||||||
{
|
{
|
||||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||||
{
|
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -755,35 +758,13 @@ static void SOCK_Send(void)
|
||||||
for (i = 0; i < mysocketses; i++)
|
for (i = 0; i < mysocketses; i++)
|
||||||
{
|
{
|
||||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||||
{
|
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET)
|
c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == ERRSOCKET)
|
if (c == ERRSOCKET)
|
||||||
|
@ -1075,7 +1056,7 @@ static boolean UDP_Socket(void)
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
runp = ai;
|
runp = ai;
|
||||||
while (runp != NULL)
|
while (runp != NULL && s < MAXNETNODES+1)
|
||||||
{
|
{
|
||||||
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||||
s++;
|
s++;
|
||||||
|
@ -1090,12 +1071,15 @@ static boolean UDP_Socket(void)
|
||||||
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
|
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = 0;
|
||||||
|
|
||||||
// setup broadcast adress to BROADCASTADDR entry
|
// setup broadcast adress to BROADCASTADDR entry
|
||||||
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
|
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
runp = ai;
|
runp = ai;
|
||||||
while (runp != NULL)
|
while (runp != NULL && s < MAXNETNODES+1)
|
||||||
{
|
{
|
||||||
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||||
s++;
|
s++;
|
||||||
|
@ -1118,7 +1102,7 @@ static boolean UDP_Socket(void)
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
runp = ai;
|
runp = ai;
|
||||||
while (runp != NULL)
|
while (runp != NULL && s < MAXNETNODES+1)
|
||||||
{
|
{
|
||||||
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||||
s++;
|
s++;
|
||||||
|
|
|
@ -12733,7 +12733,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
10, // mass
|
10, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -3629,7 +3629,7 @@ msgid "another castle!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: st_stuff.c:2328 st_stuff.c:2334 st_stuff.c:2356
|
#: st_stuff.c:2328 st_stuff.c:2334 st_stuff.c:2356
|
||||||
msgid "Press F12 to watch another player."
|
msgid "Press Viewpoint Key to watch a player."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: st_stuff.c:2333
|
#: st_stuff.c:2333
|
||||||
|
|
|
@ -3820,7 +3820,7 @@ msgid "another castle!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: st_stuff.c:2092 st_stuff.c:2098 st_stuff.c:2120
|
#: st_stuff.c:2092 st_stuff.c:2098 st_stuff.c:2120
|
||||||
msgid "Press F12 to watch another player."
|
msgid "Press Viewpoint Key to watch a player."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: st_stuff.c:2097
|
#: st_stuff.c:2097
|
||||||
|
|
|
@ -14,12 +14,18 @@
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_setup.h" // So we can have P_SetupLevelSky
|
#include "p_setup.h" // So we can have P_SetupLevelSky
|
||||||
|
#ifdef ESLOPE
|
||||||
|
#include "p_slopes.h" // P_GetZAt
|
||||||
|
#endif
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
|
#include "hu_stuff.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "d_netcmd.h" // IsPlayerAdmin
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
|
@ -93,6 +99,16 @@ static int lib_evalMath(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_isPlayerAdmin(lua_State *L)
|
||||||
|
{
|
||||||
|
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||||
|
//HUDSAFE
|
||||||
|
if (!player)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
lua_pushboolean(L, IsPlayerAdmin(player-players));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// M_RANDOM
|
// M_RANDOM
|
||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
|
@ -1547,6 +1563,24 @@ static int lib_evCrumbleChain(lua_State *L)
|
||||||
return 0;
|
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
|
// R_DEFS
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
|
@ -1983,6 +2017,7 @@ static int lib_gTicsToMilliseconds(lua_State *L)
|
||||||
static luaL_Reg lib[] = {
|
static luaL_Reg lib[] = {
|
||||||
{"print", lib_print},
|
{"print", lib_print},
|
||||||
{"EvalMath", lib_evalMath},
|
{"EvalMath", lib_evalMath},
|
||||||
|
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
||||||
|
|
||||||
// m_random
|
// m_random
|
||||||
{"P_RandomFixed",lib_pRandomFixed},
|
{"P_RandomFixed",lib_pRandomFixed},
|
||||||
|
@ -2113,6 +2148,11 @@ static luaL_Reg lib[] = {
|
||||||
{"P_StartQuake",lib_pStartQuake},
|
{"P_StartQuake",lib_pStartQuake},
|
||||||
{"EV_CrumbleChain",lib_evCrumbleChain},
|
{"EV_CrumbleChain",lib_evCrumbleChain},
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
// p_slopes
|
||||||
|
{"P_GetZAt",lib_pGetZAt},
|
||||||
|
#endif
|
||||||
|
|
||||||
// r_defs
|
// r_defs
|
||||||
{"R_PointToAngle",lib_rPointToAngle},
|
{"R_PointToAngle",lib_rPointToAngle},
|
||||||
{"R_PointToAngle2",lib_rPointToAngle2},
|
{"R_PointToAngle2",lib_rPointToAngle2},
|
||||||
|
|
266
src/lua_blockmaplib.c
Normal file
266
src/lua_blockmaplib.c
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2016 by Iestyn "Monster Iestyn" Jealous.
|
||||||
|
// Copyright (C) 2016 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file lua_blockmaplib.c
|
||||||
|
/// \brief blockmap library for Lua scripting
|
||||||
|
|
||||||
|
#include "doomdef.h"
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
#include "p_local.h"
|
||||||
|
#include "r_main.h" // validcount
|
||||||
|
#include "lua_script.h"
|
||||||
|
#include "lua_libs.h"
|
||||||
|
//#include "lua_hud.h" // hud_running errors
|
||||||
|
|
||||||
|
static const char *const search_opt[] = {
|
||||||
|
"objects",
|
||||||
|
"lines",
|
||||||
|
NULL};
|
||||||
|
|
||||||
|
// a quickly-made function pointer typedef used by lib_searchBlockmap...
|
||||||
|
// return values:
|
||||||
|
// 0 - normal, no interruptions
|
||||||
|
// 1 - stop search through current block
|
||||||
|
// 2 - stop search completely
|
||||||
|
typedef UINT8 (*blockmap_func)(lua_State *, INT32, INT32, mobj_t *);
|
||||||
|
|
||||||
|
static boolean blockfuncerror = false; // errors should only print once per search blockmap call
|
||||||
|
|
||||||
|
// Helper function for "objects" search
|
||||||
|
static UINT8 lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
|
||||||
|
{
|
||||||
|
mobj_t *mobj, *bnext = NULL;
|
||||||
|
|
||||||
|
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Check interaction with the objects in the blockmap.
|
||||||
|
for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
|
||||||
|
{
|
||||||
|
P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed!
|
||||||
|
if (mobj == thing)
|
||||||
|
continue; // our thing just found itself, so move on
|
||||||
|
lua_pushvalue(L, 1); // push function
|
||||||
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
|
LUA_PushUserdata(L, mobj, META_MOBJ);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!blockfuncerror || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
blockfuncerror = true;
|
||||||
|
return 0; // *shrugs*
|
||||||
|
}
|
||||||
|
if (!lua_isnil(gL, -1))
|
||||||
|
{ // if nil, continue
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
return 2; // stop whole search
|
||||||
|
else
|
||||||
|
return 1; // stop block search
|
||||||
|
}
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue.
|
||||||
|
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
|
||||||
|
{
|
||||||
|
P_SetTarget(&bnext, NULL);
|
||||||
|
return (P_MobjWasRemoved(thing)) ? 2 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function for "lines" search
|
||||||
|
static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
|
||||||
|
{
|
||||||
|
INT32 offset;
|
||||||
|
const INT32 *list; // Big blockmap
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
polymaplink_t *plink; // haleyjd 02/22/06
|
||||||
|
#endif
|
||||||
|
line_t *ld;
|
||||||
|
|
||||||
|
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
offset = y*bmapwidth + x;
|
||||||
|
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
// haleyjd 02/22/06: consider polyobject lines
|
||||||
|
plink = polyblocklinks[offset];
|
||||||
|
|
||||||
|
while (plink)
|
||||||
|
{
|
||||||
|
polyobj_t *po = plink->po;
|
||||||
|
|
||||||
|
if (po->validcount != validcount) // if polyobj hasn't been checked
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
po->validcount = validcount;
|
||||||
|
|
||||||
|
for (i = 0; i < po->numLines; ++i)
|
||||||
|
{
|
||||||
|
if (po->lines[i]->validcount == validcount) // line has been checked
|
||||||
|
continue;
|
||||||
|
po->lines[i]->validcount = validcount;
|
||||||
|
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
|
LUA_PushUserdata(L, po->lines[i], META_LINE);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!blockfuncerror || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
blockfuncerror = true;
|
||||||
|
return 0; // *shrugs*
|
||||||
|
}
|
||||||
|
if (!lua_isnil(gL, -1))
|
||||||
|
{ // if nil, continue
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
return 2; // stop whole search
|
||||||
|
else
|
||||||
|
return 1; // stop block search
|
||||||
|
}
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
if (P_MobjWasRemoved(thing))
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
plink = (polymaplink_t *)(plink->link.next);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];
|
||||||
|
|
||||||
|
// First index is really empty, so +1 it.
|
||||||
|
for (list = blockmaplump + offset + 1; *list != -1; list++)
|
||||||
|
{
|
||||||
|
ld = &lines[*list];
|
||||||
|
|
||||||
|
if (ld->validcount == validcount)
|
||||||
|
continue; // Line has already been checked.
|
||||||
|
|
||||||
|
ld->validcount = validcount;
|
||||||
|
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||||
|
LUA_PushUserdata(L, ld, META_LINE);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!blockfuncerror || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
blockfuncerror = true;
|
||||||
|
return 0; // *shrugs*
|
||||||
|
}
|
||||||
|
if (!lua_isnil(gL, -1))
|
||||||
|
{ // if nil, continue
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
return 2; // stop whole search
|
||||||
|
else
|
||||||
|
return 1; // stop block search
|
||||||
|
}
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
if (P_MobjWasRemoved(thing))
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0; // Everything was checked.
|
||||||
|
}
|
||||||
|
|
||||||
|
// The searchBlockmap function
|
||||||
|
// arguments: searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2])
|
||||||
|
// return value:
|
||||||
|
// true = search completely uninteruppted,
|
||||||
|
// false = searching of at least one block stopped mid-way (including if the whole search was stopped)
|
||||||
|
static int lib_searchBlockmap(lua_State *L)
|
||||||
|
{
|
||||||
|
int searchtype = luaL_checkoption(L, 1, "objects", search_opt);
|
||||||
|
int n;
|
||||||
|
mobj_t *mobj;
|
||||||
|
INT32 xl, xh, yl, yh, bx, by;
|
||||||
|
fixed_t x1, x2, y1, y2;
|
||||||
|
boolean retval = true;
|
||||||
|
UINT8 funcret = 0;
|
||||||
|
blockmap_func searchFunc;
|
||||||
|
|
||||||
|
lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2]
|
||||||
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
|
|
||||||
|
switch (searchtype)
|
||||||
|
{
|
||||||
|
case 0: // "objects"
|
||||||
|
default:
|
||||||
|
searchFunc = lib_searchBlockmap_Objects;
|
||||||
|
break;
|
||||||
|
case 1: // "lines"
|
||||||
|
searchFunc = lib_searchBlockmap_Lines;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the mobj we are searching around, the "calling" mobj we could say
|
||||||
|
mobj = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||||
|
if (!mobj)
|
||||||
|
return LUA_ErrInvalid(L, "mobj_t");
|
||||||
|
|
||||||
|
n = lua_gettop(L);
|
||||||
|
|
||||||
|
if (n > 2) // specific x/y ranges have been supplied
|
||||||
|
{
|
||||||
|
if (n < 6)
|
||||||
|
return luaL_error(L, "arguments 4 to 6 not all given (expected 4 fixed-point integers)");
|
||||||
|
|
||||||
|
x1 = luaL_checkfixed(L, 3);
|
||||||
|
x2 = luaL_checkfixed(L, 4);
|
||||||
|
y1 = luaL_checkfixed(L, 5);
|
||||||
|
y2 = luaL_checkfixed(L, 6);
|
||||||
|
}
|
||||||
|
else // mobj and function only - search around mobj's radius by default
|
||||||
|
{
|
||||||
|
fixed_t radius = mobj->radius + MAXRADIUS;
|
||||||
|
x1 = mobj->x - radius;
|
||||||
|
x2 = mobj->x + radius;
|
||||||
|
y1 = mobj->y - radius;
|
||||||
|
y2 = mobj->y + radius;
|
||||||
|
}
|
||||||
|
lua_settop(L, 2); // pop everything except function, mobj
|
||||||
|
|
||||||
|
xl = (unsigned)(x1 - bmaporgx)>>MAPBLOCKSHIFT;
|
||||||
|
xh = (unsigned)(x2 - bmaporgx)>>MAPBLOCKSHIFT;
|
||||||
|
yl = (unsigned)(y1 - bmaporgy)>>MAPBLOCKSHIFT;
|
||||||
|
yh = (unsigned)(y2 - bmaporgy)>>MAPBLOCKSHIFT;
|
||||||
|
|
||||||
|
BMBOUNDFIX(xl, xh, yl, yh);
|
||||||
|
|
||||||
|
blockfuncerror = false; // reset
|
||||||
|
validcount++;
|
||||||
|
for (bx = xl; bx <= xh; bx++)
|
||||||
|
for (by = yl; by <= yh; by++)
|
||||||
|
{
|
||||||
|
funcret = searchFunc(L, bx, by, mobj);
|
||||||
|
// return value of searchFunc determines searchFunc's return value and/or when to stop
|
||||||
|
if (funcret == 2){ // stop whole search
|
||||||
|
lua_pushboolean(L, false); // return false
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (funcret == 1) // search was interrupted for this block
|
||||||
|
retval = false; // this changes the return value, but doesn't stop the whole search
|
||||||
|
// else don't do anything, continue as normal
|
||||||
|
if (P_MobjWasRemoved(mobj)){ // ...unless the original object was removed
|
||||||
|
lua_pushboolean(L, false); // in which case we have to stop now regardless
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pushboolean(L, retval);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LUA_BlockmapLib(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_register(L, "searchBlockmap", lib_searchBlockmap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -55,7 +55,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
|
||||||
lua_pop(gL, 1); // pop flags
|
lua_pop(gL, 1); // pop flags
|
||||||
|
|
||||||
// requires server/admin and the player is not one of them
|
// requires server/admin and the player is not one of them
|
||||||
if ((flags & 1) && playernum != serverplayer && playernum != adminplayer)
|
if ((flags & 1) && playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
goto deny;
|
goto deny;
|
||||||
|
|
||||||
lua_rawgeti(gL, -1, 1); // push function from command info table
|
lua_rawgeti(gL, -1, 1); // push function from command info table
|
||||||
|
@ -133,7 +133,7 @@ void COM_Lua_f(void)
|
||||||
UINT8 argc;
|
UINT8 argc;
|
||||||
lua_pop(gL, 1); // pop command info table
|
lua_pop(gL, 1); // pop command info table
|
||||||
|
|
||||||
if (flags & 1 && !server && adminplayer != playernum) // flag 1: only server/admin can use this command.
|
if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command.
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -43,12 +43,13 @@ enum hook {
|
||||||
hook_PlayerMsg,
|
hook_PlayerMsg,
|
||||||
hook_HurtMsg,
|
hook_HurtMsg,
|
||||||
hook_PlayerSpawn,
|
hook_PlayerSpawn,
|
||||||
|
hook_PlayerQuit,
|
||||||
|
|
||||||
hook_MAX // last hook
|
hook_MAX // last hook
|
||||||
};
|
};
|
||||||
extern const char *const hookNames[];
|
extern const char *const hookNames[];
|
||||||
|
|
||||||
void LUAh_MapChange(void); // Hook for map change (before load)
|
void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load)
|
||||||
void LUAh_MapLoad(void); // Hook for map load
|
void LUAh_MapLoad(void); // Hook for map load
|
||||||
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
|
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
|
||||||
void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers)
|
void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers)
|
||||||
|
@ -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_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
|
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
|
#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
|
#endif
|
||||||
|
|
|
@ -54,6 +54,7 @@ const char *const hookNames[hook_MAX+1] = {
|
||||||
"PlayerMsg",
|
"PlayerMsg",
|
||||||
"HurtMsg",
|
"HurtMsg",
|
||||||
"PlayerSpawn",
|
"PlayerSpawn",
|
||||||
|
"PlayerQuit",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,14 +315,14 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook for map change (before load)
|
// Hook for map change (before load)
|
||||||
void LUAh_MapChange(void)
|
void LUAh_MapChange(INT16 mapnumber)
|
||||||
{
|
{
|
||||||
hook_p hookp;
|
hook_p hookp;
|
||||||
if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8))))
|
if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lua_settop(gL, 0);
|
lua_settop(gL, 0);
|
||||||
lua_pushinteger(gL, gamemap);
|
lua_pushinteger(gL, mapnumber);
|
||||||
|
|
||||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||||
if (hookp->type == hook_MapChange)
|
if (hookp->type == hook_MapChange)
|
||||||
|
@ -1074,4 +1075,30 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc)
|
||||||
// stack: tables
|
// 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
|
#endif
|
||||||
|
|
|
@ -560,6 +560,15 @@ static int libd_renderer(lua_State *L)
|
||||||
return 1;
|
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[] = {
|
static luaL_Reg lib_draw[] = {
|
||||||
{"patchExists", libd_patchExists},
|
{"patchExists", libd_patchExists},
|
||||||
{"cachePatch", libd_cachePatch},
|
{"cachePatch", libd_cachePatch},
|
||||||
|
@ -576,6 +585,7 @@ static luaL_Reg lib_draw[] = {
|
||||||
{"dupx", libd_dupx},
|
{"dupx", libd_dupx},
|
||||||
{"dupy", libd_dupy},
|
{"dupy", libd_dupy},
|
||||||
{"renderer", libd_renderer},
|
{"renderer", libd_renderer},
|
||||||
|
{"localTransFlag", libd_getlocaltransflag},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -599,6 +609,19 @@ static int lib_huddisable(lua_State *L)
|
||||||
return 0;
|
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
|
// add a HUD element for rendering
|
||||||
static int lib_hudadd(lua_State *L)
|
static int lib_hudadd(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -623,6 +646,7 @@ static int lib_hudadd(lua_State *L)
|
||||||
static luaL_Reg lib_hud[] = {
|
static luaL_Reg lib_hud[] = {
|
||||||
{"enable", lib_hudenable},
|
{"enable", lib_hudenable},
|
||||||
{"disable", lib_huddisable},
|
{"disable", lib_huddisable},
|
||||||
|
{"enabled", lib_hudenabled},
|
||||||
{"add", lib_hudadd},
|
{"add", lib_hudadd},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,11 @@ extern lua_State *gL;
|
||||||
#define META_SUBSECTOR "SUBSECTOR_T*"
|
#define META_SUBSECTOR "SUBSECTOR_T*"
|
||||||
#define META_SECTOR "SECTOR_T*"
|
#define META_SECTOR "SECTOR_T*"
|
||||||
#define META_FFLOOR "FFLOOR_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_MAPHEADER "MAPHEADER_T*"
|
||||||
|
|
||||||
#define META_CVAR "CONSVAR_T*"
|
#define META_CVAR "CONSVAR_T*"
|
||||||
|
@ -64,6 +69,7 @@ int LUA_PlayerLib(lua_State *L);
|
||||||
int LUA_SkinLib(lua_State *L);
|
int LUA_SkinLib(lua_State *L);
|
||||||
int LUA_ThinkerLib(lua_State *L);
|
int LUA_ThinkerLib(lua_State *L);
|
||||||
int LUA_MapLib(lua_State *L);
|
int LUA_MapLib(lua_State *L);
|
||||||
|
int LUA_BlockmapLib(lua_State *L);
|
||||||
int LUA_HudLib(lua_State *L);
|
int LUA_HudLib(lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
299
src/lua_maplib.c
299
src/lua_maplib.c
|
@ -16,6 +16,10 @@
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
#ifdef ESLOPE
|
||||||
|
#include "p_slopes.h"
|
||||||
|
#endif
|
||||||
|
#include "r_main.h"
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
|
@ -38,7 +42,13 @@ enum sector_e {
|
||||||
sector_heightsec,
|
sector_heightsec,
|
||||||
sector_camsec,
|
sector_camsec,
|
||||||
sector_lines,
|
sector_lines,
|
||||||
|
#ifdef ESLOPE
|
||||||
|
sector_ffloors,
|
||||||
|
sector_fslope,
|
||||||
|
sector_cslope
|
||||||
|
#else
|
||||||
sector_ffloors
|
sector_ffloors
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const sector_opt[] = {
|
static const char *const sector_opt[] = {
|
||||||
|
@ -55,6 +65,10 @@ static const char *const sector_opt[] = {
|
||||||
"camsec",
|
"camsec",
|
||||||
"lines",
|
"lines",
|
||||||
"ffloors",
|
"ffloors",
|
||||||
|
#ifdef ESLOPE
|
||||||
|
"f_slope",
|
||||||
|
"c_slope",
|
||||||
|
#endif
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
enum subsector_e {
|
enum subsector_e {
|
||||||
|
@ -160,6 +174,10 @@ enum ffloor_e {
|
||||||
ffloor_toplightlevel,
|
ffloor_toplightlevel,
|
||||||
ffloor_bottomheight,
|
ffloor_bottomheight,
|
||||||
ffloor_bottompic,
|
ffloor_bottompic,
|
||||||
|
#ifdef ESLOPE
|
||||||
|
ffloor_tslope,
|
||||||
|
ffloor_bslope,
|
||||||
|
#endif
|
||||||
ffloor_sector,
|
ffloor_sector,
|
||||||
ffloor_flags,
|
ffloor_flags,
|
||||||
ffloor_master,
|
ffloor_master,
|
||||||
|
@ -176,6 +194,10 @@ static const char *const ffloor_opt[] = {
|
||||||
"toplightlevel",
|
"toplightlevel",
|
||||||
"bottomheight",
|
"bottomheight",
|
||||||
"bottompic",
|
"bottompic",
|
||||||
|
#ifdef ESLOPE
|
||||||
|
"t_slope",
|
||||||
|
"b_slope",
|
||||||
|
#endif
|
||||||
"sector", // secnum pushed as control sector userdata
|
"sector", // secnum pushed as control sector userdata
|
||||||
"flags",
|
"flags",
|
||||||
"master", // control linedef
|
"master", // control linedef
|
||||||
|
@ -185,6 +207,47 @@ static const char *const ffloor_opt[] = {
|
||||||
"alpha",
|
"alpha",
|
||||||
NULL};
|
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 array_opt[] ={"iterate",NULL};
|
||||||
static const char *const valid_opt[] ={"valid",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));
|
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||||
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
||||||
|
INT16 i;
|
||||||
|
|
||||||
if (!sector)
|
if (!sector)
|
||||||
{
|
{
|
||||||
|
@ -349,11 +413,23 @@ static int sector_get(lua_State *L)
|
||||||
lua_pushfixed(L, sector->ceilingheight);
|
lua_pushfixed(L, sector->ceilingheight);
|
||||||
return 1;
|
return 1;
|
||||||
case sector_floorpic: // floorpic
|
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;
|
return 1;
|
||||||
|
}
|
||||||
case sector_ceilingpic: // ceilingpic
|
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;
|
return 1;
|
||||||
|
}
|
||||||
case sector_lightlevel:
|
case sector_lightlevel:
|
||||||
lua_pushinteger(L, sector->lightlevel);
|
lua_pushinteger(L, sector->lightlevel);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -386,6 +462,14 @@ static int sector_get(lua_State *L)
|
||||||
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
|
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
|
||||||
lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function
|
lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -408,6 +492,10 @@ static int sector_set(lua_State *L)
|
||||||
case sector_heightsec: // heightsec
|
case sector_heightsec: // heightsec
|
||||||
case sector_camsec: // camsec
|
case sector_camsec: // camsec
|
||||||
case sector_ffloors: // ffloors
|
case sector_ffloors: // ffloors
|
||||||
|
#ifdef ESLOPE
|
||||||
|
case sector_fslope: // f_slope
|
||||||
|
case sector_cslope: // c_slope
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
|
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
|
||||||
case sector_floorheight: { // floorheight
|
case sector_floorheight: { // floorheight
|
||||||
|
@ -1042,6 +1130,14 @@ static int ffloor_get(lua_State *L)
|
||||||
lua_pushlstring(L, levelflat->name, 8);
|
lua_pushlstring(L, levelflat->name, 8);
|
||||||
return 1;
|
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:
|
case ffloor_sector:
|
||||||
LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR);
|
LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1081,6 +1177,10 @@ static int ffloor_set(lua_State *L)
|
||||||
switch(field)
|
switch(field)
|
||||||
{
|
{
|
||||||
case ffloor_valid: // valid
|
case ffloor_valid: // valid
|
||||||
|
#ifdef ESLOPE
|
||||||
|
case ffloor_tslope: // t_slope
|
||||||
|
case ffloor_bslope: // b_slope
|
||||||
|
#endif
|
||||||
case ffloor_sector: // sector
|
case ffloor_sector: // sector
|
||||||
case ffloor_master: // master
|
case ffloor_master: // master
|
||||||
case ffloor_target: // target
|
case ffloor_target: // target
|
||||||
|
@ -1141,6 +1241,181 @@ static int ffloor_set(lua_State *L)
|
||||||
return 0;
|
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)
|
static int lib_getMapheaderinfo(lua_State *L)
|
||||||
{
|
{
|
||||||
// i -> mapheaderinfo[i-1]
|
// i -> mapheaderinfo[i-1]
|
||||||
|
@ -1317,6 +1592,26 @@ int LUA_MapLib(lua_State *L)
|
||||||
lua_setfield(L, -2, "__newindex");
|
lua_setfield(L, -2, "__newindex");
|
||||||
lua_pop(L, 1);
|
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);
|
luaL_newmetatable(L, META_MAPHEADER);
|
||||||
lua_pushcfunction(L, mapheaderinfo_get);
|
lua_pushcfunction(L, mapheaderinfo_get);
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
|
@ -80,7 +80,12 @@ enum mobj_e {
|
||||||
mobj_extravalue1,
|
mobj_extravalue1,
|
||||||
mobj_extravalue2,
|
mobj_extravalue2,
|
||||||
mobj_cusval,
|
mobj_cusval,
|
||||||
|
#ifdef ESLOPE
|
||||||
|
mobj_cvmem,
|
||||||
|
mobj_standingslope
|
||||||
|
#else
|
||||||
mobj_cvmem
|
mobj_cvmem
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const mobj_opt[] = {
|
static const char *const mobj_opt[] = {
|
||||||
|
@ -140,6 +145,9 @@ static const char *const mobj_opt[] = {
|
||||||
"extravalue2",
|
"extravalue2",
|
||||||
"cusval",
|
"cusval",
|
||||||
"cvmem",
|
"cvmem",
|
||||||
|
#ifdef ESLOPE
|
||||||
|
"standingslope",
|
||||||
|
#endif
|
||||||
NULL};
|
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])
|
#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:
|
case mobj_cvmem:
|
||||||
lua_pushinteger(L, mo->cvmem);
|
lua_pushinteger(L, mo->cvmem);
|
||||||
break;
|
break;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
case mobj_standingslope:
|
||||||
|
LUA_PushUserdata(L, mo->standingslope, META_SLOPE);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default: // extra custom variables in Lua memory
|
default: // extra custom variables in Lua memory
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||||
I_Assert(lua_istable(L, -1));
|
I_Assert(lua_istable(L, -1));
|
||||||
|
@ -634,6 +647,10 @@ static int mobj_set(lua_State *L)
|
||||||
case mobj_cvmem:
|
case mobj_cvmem:
|
||||||
mo->cvmem = luaL_checkinteger(L, 3);
|
mo->cvmem = luaL_checkinteger(L, 3);
|
||||||
break;
|
break;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
case mobj_standingslope:
|
||||||
|
return NOSET;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||||
I_Assert(lua_istable(L, -1));
|
I_Assert(lua_istable(L, -1));
|
||||||
|
|
109
src/lua_script.c
109
src/lua_script.c
|
@ -22,6 +22,9 @@
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#ifdef ESLOPE
|
||||||
|
#include "p_slopes.h" // for P_SlopeById
|
||||||
|
#endif
|
||||||
#ifdef LUA_ALLOW_BYTECODE
|
#ifdef LUA_ALLOW_BYTECODE
|
||||||
#include "d_netfil.h" // for LUA_DumpFile
|
#include "d_netfil.h" // for LUA_DumpFile
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,6 +51,7 @@ static lua_CFunction liblist[] = {
|
||||||
LUA_SkinLib, // skin_t, skins[]
|
LUA_SkinLib, // skin_t, skins[]
|
||||||
LUA_ThinkerLib, // thinker_t
|
LUA_ThinkerLib, // thinker_t
|
||||||
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
|
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
|
||||||
|
LUA_BlockmapLib, // blockmap stuff
|
||||||
LUA_HudLib, // HUD stuff
|
LUA_HudLib, // HUD stuff
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -170,6 +174,7 @@ static inline void LUA_LoadFile(MYFILE *f, char *name)
|
||||||
LUA_ClearState();
|
LUA_ClearState();
|
||||||
lua_pushinteger(gL, f->wad);
|
lua_pushinteger(gL, f->wad);
|
||||||
lua_setfield(gL, LUA_REGISTRYINDEX, "WAD");
|
lua_setfield(gL, LUA_REGISTRYINDEX, "WAD");
|
||||||
|
|
||||||
if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, 0)) {
|
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));
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
|
||||||
lua_pop(gL,1);
|
lua_pop(gL,1);
|
||||||
|
@ -189,17 +194,23 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
||||||
W_ReadLumpPwad(wad, lump, f.data);
|
W_ReadLumpPwad(wad, lump, f.data);
|
||||||
f.curpos = f.data;
|
f.curpos = f.data;
|
||||||
|
|
||||||
len = strlen(wadfiles[wad]->filename);
|
len = strlen(wadfiles[wad]->filename); // length of file name
|
||||||
name = malloc(len+10);
|
|
||||||
strcpy(name, wadfiles[wad]->filename);
|
if (wadfiles[wad]->type == RET_LUA)
|
||||||
if (!fasticmp(&name[len - 4], ".lua")) {
|
{
|
||||||
// If it's not a .lua file, copy the lump name in too.
|
name = malloc(len+1);
|
||||||
name[len] = '|';
|
strcpy(name, wadfiles[wad]->filename);
|
||||||
M_Memcpy(name+len+1, wadfiles[wad]->lumpinfo[lump].name, 8);
|
}
|
||||||
name[len+9] = '\0';
|
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);
|
free(name);
|
||||||
Z_Free(f.data);
|
Z_Free(f.data);
|
||||||
|
@ -457,6 +468,9 @@ enum
|
||||||
ARCH_SIDE,
|
ARCH_SIDE,
|
||||||
ARCH_SUBSECTOR,
|
ARCH_SUBSECTOR,
|
||||||
ARCH_SECTOR,
|
ARCH_SECTOR,
|
||||||
|
#ifdef ESLOPE
|
||||||
|
ARCH_SLOPE,
|
||||||
|
#endif
|
||||||
ARCH_MAPHEADER,
|
ARCH_MAPHEADER,
|
||||||
|
|
||||||
ARCH_TEND=0xFF,
|
ARCH_TEND=0xFF,
|
||||||
|
@ -476,6 +490,9 @@ static const struct {
|
||||||
{META_SIDE, ARCH_SIDE},
|
{META_SIDE, ARCH_SIDE},
|
||||||
{META_SUBSECTOR,ARCH_SUBSECTOR},
|
{META_SUBSECTOR,ARCH_SUBSECTOR},
|
||||||
{META_SECTOR, ARCH_SECTOR},
|
{META_SECTOR, ARCH_SECTOR},
|
||||||
|
#ifdef ESLOPE
|
||||||
|
{META_SLOPE, ARCH_SLOPE},
|
||||||
|
#endif
|
||||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||||
{NULL, ARCH_NULL}
|
{NULL, ARCH_NULL}
|
||||||
};
|
};
|
||||||
|
@ -528,9 +545,23 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TSTRING:
|
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);
|
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;
|
break;
|
||||||
|
}
|
||||||
case LUA_TTABLE:
|
case LUA_TTABLE:
|
||||||
{
|
{
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
@ -666,6 +697,19 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case ARCH_MAPHEADER:
|
||||||
{
|
{
|
||||||
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
||||||
|
@ -769,11 +813,19 @@ static void ArchiveTables(void)
|
||||||
lua_pushnil(gL);
|
lua_pushnil(gL);
|
||||||
while (lua_next(gL, -2))
|
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);
|
e = ArchiveValue(TABLESINDEX, -1);
|
||||||
if (e == 1)
|
if (e == 1)
|
||||||
n++; // the table contained a new table we'll have to archive. :(
|
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);
|
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));
|
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 +855,19 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
||||||
break;
|
break;
|
||||||
case ARCH_STRING:
|
case ARCH_STRING:
|
||||||
{
|
{
|
||||||
char value[1024];
|
UINT16 len = READUINT16(save_p); // length of string, including embedded zeros
|
||||||
READSTRING(save_p, value);
|
char *value;
|
||||||
lua_pushstring(gL, 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;
|
break;
|
||||||
}
|
}
|
||||||
case ARCH_TABLE:
|
case ARCH_TABLE:
|
||||||
|
@ -852,6 +914,11 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
||||||
case ARCH_SECTOR:
|
case ARCH_SECTOR:
|
||||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR);
|
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR);
|
||||||
break;
|
break;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
case ARCH_SLOPE:
|
||||||
|
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case ARCH_MAPHEADER:
|
case ARCH_MAPHEADER:
|
||||||
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
|
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
|
||||||
break;
|
break;
|
||||||
|
@ -915,11 +982,17 @@ static void UnArchiveTables(void)
|
||||||
lua_rawgeti(gL, TABLESINDEX, i);
|
lua_rawgeti(gL, TABLESINDEX, i);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (UnArchiveValue(TABLESINDEX) == 1)
|
if (UnArchiveValue(TABLESINDEX) == 1) // read key
|
||||||
break;
|
break;
|
||||||
if (UnArchiveValue(TABLESINDEX) == 2)
|
if (UnArchiveValue(TABLESINDEX) == 2) // read value
|
||||||
n++;
|
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);
|
lua_pop(gL, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,4 +214,4 @@ void M_FindResponseFile(void)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
233
src/m_menu.c
233
src/m_menu.c
|
@ -57,6 +57,8 @@
|
||||||
#include "st_stuff.h"
|
#include "st_stuff.h"
|
||||||
#include "i_sound.h"
|
#include "i_sound.h"
|
||||||
|
|
||||||
|
#include "i_joy.h" // for joystick menu controls
|
||||||
|
|
||||||
// Condition Sets
|
// Condition Sets
|
||||||
#include "m_cond.h"
|
#include "m_cond.h"
|
||||||
|
|
||||||
|
@ -278,7 +280,7 @@ static void M_SetupMultiPlayer2(INT32 choice);
|
||||||
// Split into multiple parts due to size
|
// Split into multiple parts due to size
|
||||||
// Controls
|
// Controls
|
||||||
menu_t OP_ControlsDef, OP_ControlListDef, OP_MoveControlsDef;
|
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_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef;
|
||||||
menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def;
|
menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def;
|
||||||
static void M_VideoModeMenu(INT32 choice);
|
static void M_VideoModeMenu(INT32 choice);
|
||||||
|
@ -1047,20 +1049,30 @@ static menuitem_t OP_ControlListMenu[] =
|
||||||
{
|
{
|
||||||
{IT_SUBMENU | IT_STRING, NULL, "Movement Controls...", &OP_MoveControlsDef, 10},
|
{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, "Multiplayer Controls...", &OP_MPControlsDef, 20},
|
||||||
{IT_SUBMENU | IT_STRING, NULL, "Camera Controls...", &OP_CameraControlsDef, 30},
|
{IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 30},
|
||||||
{IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 40},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_MoveControlsMenu[] =
|
static menuitem_t OP_MoveControlsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_CALL | IT_STRING2, NULL, "Forward", M_ChangeControl, gc_forward },
|
{IT_HEADER, NULL, " Movement", NULL, 0},
|
||||||
{IT_CALL | IT_STRING2, NULL, "Reverse", M_ChangeControl, gc_backward },
|
{IT_CALL | IT_STRING2, NULL, "Move Forward", M_ChangeControl, gc_forward },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft },
|
{IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, gc_backward },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright },
|
{IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, gc_strafeleft },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump },
|
{IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, gc_straferight },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use },
|
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Strafe Left", M_ChangeControl, gc_strafeleft },
|
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Strafe Right", M_ChangeControl, gc_straferight},
|
{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[] =
|
static menuitem_t OP_MPControlsMenu[] =
|
||||||
|
@ -1082,18 +1094,6 @@ static menuitem_t OP_MPControlsMenu[] =
|
||||||
{IT_CALL | IT_STRING2, NULL, "Ring Toss Normal", M_ChangeControl, gc_firenormal },
|
{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[] =
|
static menuitem_t OP_MiscControlsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 },
|
{IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 },
|
||||||
|
@ -1101,6 +1101,10 @@ static menuitem_t OP_MiscControlsMenu[] =
|
||||||
{IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3 },
|
{IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3 },
|
||||||
|
|
||||||
{IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause },
|
{IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause },
|
||||||
|
{IT_CALL | IT_STRING2, NULL, "Screenshot", M_ChangeControl, gc_screenshot },
|
||||||
|
{IT_CALL | IT_STRING2, NULL, "Toggle GIF Recording", M_ChangeControl, gc_recordgif },
|
||||||
|
{IT_CALL | IT_STRING2, NULL, "Open/Close Menu (ESC)", M_ChangeControl, gc_systemmenu },
|
||||||
|
{IT_CALL | IT_STRING2, NULL, "Change Viewpoint", M_ChangeControl, gc_viewpoint },
|
||||||
{IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console },
|
{IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1113,6 +1117,9 @@ static menuitem_t OP_Joystick1Menu[] =
|
||||||
{IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis , 60},
|
{IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis , 60},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis , 70},
|
{IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis , 70},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis , 80},
|
{IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis , 80},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 100},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 110},
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_Joystick2Menu[] =
|
static menuitem_t OP_Joystick2Menu[] =
|
||||||
|
@ -1124,6 +1131,9 @@ static menuitem_t OP_Joystick2Menu[] =
|
||||||
{IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis2 , 60},
|
{IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis2 , 60},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis2 , 70},
|
{IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis2 , 70},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis2 , 80},
|
{IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis2 , 80},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2, 100},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 110},
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_JoystickSetMenu[] =
|
static menuitem_t OP_JoystickSetMenu[] =
|
||||||
|
@ -1142,13 +1152,14 @@ static menuitem_t OP_MouseOptionsMenu[] =
|
||||||
{IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10},
|
{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, "First-Person MouseLook", &cv_alwaysfreelook, 30},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove, 40},
|
{IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook, 40},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 50},
|
{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,
|
{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,
|
{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[] =
|
static menuitem_t OP_Mouse2OptionsMenu[] =
|
||||||
|
@ -1156,13 +1167,14 @@ static menuitem_t OP_Mouse2OptionsMenu[] =
|
||||||
{IT_STRING | IT_CVAR, NULL, "Use Mouse 2", &cv_usemouse2, 10},
|
{IT_STRING | IT_CVAR, NULL, "Use Mouse 2", &cv_usemouse2, 10},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Second Mouse Serial Port",
|
{IT_STRING | IT_CVAR, NULL, "Second Mouse Serial Port",
|
||||||
&cv_mouse2port, 20},
|
&cv_mouse2port, 20},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Always MouseLook", &cv_alwaysfreelook2, 30},
|
{IT_STRING | IT_CVAR, NULL, "First-Person MouseLook", &cv_alwaysfreelook2, 30},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove2, 40},
|
{IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook2, 40},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse2, 50},
|
{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,
|
{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,
|
{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[] =
|
static menuitem_t OP_VideoOptionsMenu[] =
|
||||||
|
@ -1711,7 +1723,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_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30);
|
||||||
menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlListDef);
|
menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlListDef);
|
||||||
menu_t OP_MPControlsDef = CONTROLMENUSTYLE(OP_MPControlsMenu, &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_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef);
|
||||||
menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30);
|
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);
|
menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30);
|
||||||
|
@ -2127,6 +2138,7 @@ boolean M_Responder(event_t *ev)
|
||||||
INT32 ch = -1;
|
INT32 ch = -1;
|
||||||
// INT32 i;
|
// INT32 i;
|
||||||
static tic_t joywait = 0, mousewait = 0;
|
static tic_t joywait = 0, mousewait = 0;
|
||||||
|
static INT32 pjoyx = 0, pjoyy = 0;
|
||||||
static INT32 pmousex = 0, pmousey = 0;
|
static INT32 pmousex = 0, pmousey = 0;
|
||||||
static INT32 lastx = 0, lasty = 0;
|
static INT32 lastx = 0, lasty = 0;
|
||||||
void (*routine)(INT32 choice); // for some casting problem
|
void (*routine)(INT32 choice); // for some casting problem
|
||||||
|
@ -2142,63 +2154,84 @@ boolean M_Responder(event_t *ev)
|
||||||
// (but still allow shift keyup so caps doesn't get stuck)
|
// (but still allow shift keyup so caps doesn't get stuck)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (ev->type == ev_keydown)
|
|
||||||
{
|
|
||||||
ch = ev->data1;
|
|
||||||
|
|
||||||
// added 5-2-98 remap virtual keys (mouse & joystick buttons)
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case KEY_MOUSE1:
|
|
||||||
case KEY_JOY1:
|
|
||||||
case KEY_JOY1 + 2:
|
|
||||||
ch = KEY_ENTER;
|
|
||||||
break;
|
|
||||||
case KEY_JOY1 + 3:
|
|
||||||
ch = 'n';
|
|
||||||
break;
|
|
||||||
case KEY_MOUSE1 + 1:
|
|
||||||
case KEY_JOY1 + 1:
|
|
||||||
ch = KEY_BACKSPACE;
|
|
||||||
break;
|
|
||||||
case KEY_HAT1:
|
|
||||||
ch = KEY_UPARROW;
|
|
||||||
break;
|
|
||||||
case KEY_HAT1 + 1:
|
|
||||||
ch = KEY_DOWNARROW;
|
|
||||||
break;
|
|
||||||
case KEY_HAT1 + 2:
|
|
||||||
ch = KEY_LEFTARROW;
|
|
||||||
break;
|
|
||||||
case KEY_HAT1 + 3:
|
|
||||||
ch = KEY_RIGHTARROW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (menuactive)
|
else if (menuactive)
|
||||||
{
|
{
|
||||||
if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime())
|
if (ev->type == ev_keydown)
|
||||||
{
|
{
|
||||||
if (ev->data3 == -1)
|
ch = ev->data1;
|
||||||
|
|
||||||
|
// added 5-2-98 remap virtual keys (mouse & joystick buttons)
|
||||||
|
switch (ch)
|
||||||
{
|
{
|
||||||
ch = KEY_UPARROW;
|
case KEY_MOUSE1:
|
||||||
joywait = I_GetTime() + NEWTICRATE/7;
|
case KEY_JOY1:
|
||||||
|
ch = KEY_ENTER;
|
||||||
|
break;
|
||||||
|
case KEY_JOY1 + 3:
|
||||||
|
ch = 'n';
|
||||||
|
break;
|
||||||
|
case KEY_MOUSE1 + 1:
|
||||||
|
case KEY_JOY1 + 1:
|
||||||
|
ch = KEY_ESCAPE;
|
||||||
|
break;
|
||||||
|
case KEY_JOY1 + 2:
|
||||||
|
ch = KEY_BACKSPACE;
|
||||||
|
break;
|
||||||
|
case KEY_HAT1:
|
||||||
|
ch = KEY_UPARROW;
|
||||||
|
break;
|
||||||
|
case KEY_HAT1 + 1:
|
||||||
|
ch = KEY_DOWNARROW;
|
||||||
|
break;
|
||||||
|
case KEY_HAT1 + 2:
|
||||||
|
ch = KEY_LEFTARROW;
|
||||||
|
break;
|
||||||
|
case KEY_HAT1 + 3:
|
||||||
|
ch = KEY_RIGHTARROW;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (ev->data3 == 1)
|
}
|
||||||
|
else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime())
|
||||||
|
{
|
||||||
|
const INT32 jdeadzone = JOYAXISRANGE/4;
|
||||||
|
if (ev->data3 != INT32_MAX)
|
||||||
{
|
{
|
||||||
ch = KEY_DOWNARROW;
|
if (Joystick.bGamepadStyle || abs(ev->data3) > jdeadzone)
|
||||||
joywait = I_GetTime() + NEWTICRATE/7;
|
{
|
||||||
|
if (ev->data3 < 0 && pjoyy >= 0)
|
||||||
|
{
|
||||||
|
ch = KEY_UPARROW;
|
||||||
|
joywait = I_GetTime() + NEWTICRATE/7;
|
||||||
|
}
|
||||||
|
else if (ev->data3 > 0 && pjoyy <= 0)
|
||||||
|
{
|
||||||
|
ch = KEY_DOWNARROW;
|
||||||
|
joywait = I_GetTime() + NEWTICRATE/7;
|
||||||
|
}
|
||||||
|
pjoyy = ev->data3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pjoyy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->data2 == -1)
|
if (ev->data2 != INT32_MAX)
|
||||||
{
|
{
|
||||||
ch = KEY_LEFTARROW;
|
if (Joystick.bGamepadStyle || abs(ev->data2) > jdeadzone)
|
||||||
joywait = I_GetTime() + NEWTICRATE/17;
|
{
|
||||||
}
|
if (ev->data2 < 0 && pjoyx >= 0)
|
||||||
else if (ev->data2 == 1)
|
{
|
||||||
{
|
ch = KEY_LEFTARROW;
|
||||||
ch = KEY_RIGHTARROW;
|
joywait = I_GetTime() + NEWTICRATE/17;
|
||||||
joywait = I_GetTime() + NEWTICRATE/17;
|
}
|
||||||
|
else if (ev->data2 > 0 && pjoyx <= 0)
|
||||||
|
{
|
||||||
|
ch = KEY_RIGHTARROW;
|
||||||
|
joywait = I_GetTime() + NEWTICRATE/17;
|
||||||
|
}
|
||||||
|
pjoyx = ev->data2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pjoyx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ev->type == ev_mouse && mousewait < I_GetTime())
|
else if (ev->type == ev_mouse && mousewait < I_GetTime())
|
||||||
|
@ -2232,9 +2265,13 @@ boolean M_Responder(event_t *ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ev->type == ev_keydown) // Preserve event for other responders
|
||||||
|
ch = ev->data1;
|
||||||
|
|
||||||
if (ch == -1)
|
if (ch == -1)
|
||||||
return false;
|
return false;
|
||||||
|
else if (ch == gamecontrol[gc_systemmenu][0] || ch == gamecontrol[gc_systemmenu][1]) // allow remappable ESC key
|
||||||
|
ch = KEY_ESCAPE;
|
||||||
|
|
||||||
// F-Keys
|
// F-Keys
|
||||||
if (!menuactive)
|
if (!menuactive)
|
||||||
|
@ -2636,7 +2673,7 @@ void M_StartControlPanel(void)
|
||||||
MPauseMenu[mpause_switchteam].status = IT_DISABLED;
|
MPauseMenu[mpause_switchteam].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetup].status = IT_DISABLED;
|
MPauseMenu[mpause_psetup].status = IT_DISABLED;
|
||||||
|
|
||||||
if ((server || adminplayer == consoleplayer))
|
if ((server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
||||||
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
||||||
|
@ -4519,7 +4556,7 @@ static void M_Options(INT32 choice)
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
||||||
// if the player is not admin or server, disable server options
|
// if the player is not admin or server, disable server options
|
||||||
OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||||
|
|
||||||
// if the player is playing _at all_, disable the erase data options
|
// if the player is playing _at all_, disable the erase data options
|
||||||
OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||||
|
@ -7458,6 +7495,7 @@ static void M_DrawControl(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT32 controltochange;
|
static INT32 controltochange;
|
||||||
|
static char controltochangetext[55];
|
||||||
|
|
||||||
static void M_ChangecontrolResponse(event_t *ev)
|
static void M_ChangecontrolResponse(event_t *ev)
|
||||||
{
|
{
|
||||||
|
@ -7465,8 +7503,8 @@ static void M_ChangecontrolResponse(event_t *ev)
|
||||||
INT32 found;
|
INT32 found;
|
||||||
INT32 ch = ev->data1;
|
INT32 ch = ev->data1;
|
||||||
|
|
||||||
// ESCAPE cancels
|
// ESCAPE cancels; dummy out PAUSE
|
||||||
if (ch != KEY_ESCAPE)
|
if (ch != KEY_ESCAPE && ch != KEY_PAUSE)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (ev->type)
|
switch (ev->type)
|
||||||
|
@ -7525,8 +7563,28 @@ static void M_ChangecontrolResponse(event_t *ev)
|
||||||
G_CheckDoubleUsage(ch);
|
G_CheckDoubleUsage(ch);
|
||||||
setupcontrols[control][found] = 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);
|
M_StopMessage(0);
|
||||||
}
|
}
|
||||||
|
@ -7538,6 +7596,7 @@ static void M_ChangeControl(INT32 choice)
|
||||||
controltochange = currentMenu->menuitems[choice].alphaKey;
|
controltochange = currentMenu->menuitems[choice].alphaKey;
|
||||||
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
||||||
currentMenu->menuitems[choice].text);
|
currentMenu->menuitems[choice].text);
|
||||||
|
strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55);
|
||||||
|
|
||||||
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
||||||
}
|
}
|
||||||
|
|
47
src/m_misc.c
47
src/m_misc.c
|
@ -37,6 +37,7 @@
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
#include "command.h" // cv_execversion
|
||||||
|
|
||||||
#include "m_anigif.h"
|
#include "m_anigif.h"
|
||||||
|
|
||||||
|
@ -440,7 +441,18 @@ void Command_LoadConfig_f(void)
|
||||||
|
|
||||||
strcpy(configfile, COM_Argv(1));
|
strcpy(configfile, COM_Argv(1));
|
||||||
FIL_ForceExtension(configfile, ".cfg");
|
FIL_ForceExtension(configfile, ".cfg");
|
||||||
|
|
||||||
|
// temporarily reset execversion to default
|
||||||
|
cv_execversion.flags &= ~CV_HIDEN;
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
|
||||||
|
CV_InitFilterVar();
|
||||||
|
|
||||||
|
// exec the config
|
||||||
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
||||||
|
|
||||||
|
// don't filter anymore vars and don't let this convsvar be changed
|
||||||
|
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, MODVERSION));
|
||||||
|
cv_execversion.flags |= CV_HIDEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Saves the current configuration and loads another.
|
/** Saves the current configuration and loads another.
|
||||||
|
@ -477,10 +489,23 @@ void M_FirstLoadConfig(void)
|
||||||
// load default control
|
// load default control
|
||||||
G_Controldefault();
|
G_Controldefault();
|
||||||
|
|
||||||
|
// register execversion here before we load any configs
|
||||||
|
CV_RegisterVar(&cv_execversion);
|
||||||
|
|
||||||
|
// temporarily reset execversion to default
|
||||||
|
// we shouldn't need to do this, but JUST in case...
|
||||||
|
cv_execversion.flags &= ~CV_HIDEN;
|
||||||
|
COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
|
||||||
|
CV_InitFilterVar();
|
||||||
|
|
||||||
// load config, make sure those commands doesnt require the screen...
|
// load config, make sure those commands doesnt require the screen...
|
||||||
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
||||||
// no COM_BufExecute() needed; that does it right away
|
// no COM_BufExecute() needed; that does it right away
|
||||||
|
|
||||||
|
// don't filter anymore vars and don't let this convsvar be changed
|
||||||
|
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, MODVERSION));
|
||||||
|
cv_execversion.flags |= CV_HIDEN;
|
||||||
|
|
||||||
// make sure I_Quit() will write back the correct config
|
// make sure I_Quit() will write back the correct config
|
||||||
// (do not write back the config if it crash before)
|
// (do not write back the config if it crash before)
|
||||||
gameconfig_loaded = true;
|
gameconfig_loaded = true;
|
||||||
|
@ -493,6 +518,7 @@ void M_FirstLoadConfig(void)
|
||||||
void M_SaveConfig(const char *filename)
|
void M_SaveConfig(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
char *filepath;
|
||||||
|
|
||||||
// make sure not to write back the config until it's been correctly loaded
|
// make sure not to write back the config until it's been correctly loaded
|
||||||
if (!gameconfig_loaded)
|
if (!gameconfig_loaded)
|
||||||
|
@ -507,13 +533,20 @@ void M_SaveConfig(const char *filename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = fopen(filename, "w");
|
// append srb2home to beginning of filename
|
||||||
|
// but check if srb2home isn't already there, first
|
||||||
|
if (!strstr(filename, srb2home))
|
||||||
|
filepath = va(pandf,srb2home, filename);
|
||||||
|
else
|
||||||
|
filepath = Z_StrDup(filename);
|
||||||
|
|
||||||
|
f = fopen(filepath, "w");
|
||||||
// change it only if valid
|
// change it only if valid
|
||||||
if (f)
|
if (f)
|
||||||
strcpy(configfile, filename);
|
strcpy(configfile, filepath);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), filename);
|
CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), filepath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,6 +569,10 @@ void M_SaveConfig(const char *filename)
|
||||||
// header message
|
// header message
|
||||||
fprintf(f, "// SRB2 configuration file.\n");
|
fprintf(f, "// SRB2 configuration file.\n");
|
||||||
|
|
||||||
|
// print execversion FIRST, because subsequent consvars need to be filtered
|
||||||
|
// always print current MODVERSION
|
||||||
|
fprintf(f, "%s \"%d\"\n", cv_execversion.name, MODVERSION);
|
||||||
|
|
||||||
// FIXME: save key aliases if ever implemented..
|
// FIXME: save key aliases if ever implemented..
|
||||||
|
|
||||||
CV_SaveVariables(f);
|
CV_SaveVariables(f);
|
||||||
|
@ -1494,9 +1531,9 @@ boolean M_ScreenshotResponder(event_t *ev)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ch = ev->data1;
|
ch = ev->data1;
|
||||||
if (ch == KEY_F8)
|
if (ch == KEY_F8 || ch == gamecontrol[gc_screenshot][0] || ch == gamecontrol[gc_screenshot][1]) // remappable F8
|
||||||
M_ScreenShot();
|
M_ScreenShot();
|
||||||
else if (ch == KEY_F9)
|
else if (ch == KEY_F9 || ch == gamecontrol[gc_recordgif][0] || ch == gamecontrol[gc_recordgif][1]) // remappable F9
|
||||||
((moviemode) ? M_StopMovie : M_StartMovie)();
|
((moviemode) ? M_StopMovie : M_StartMovie)();
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -811,6 +811,8 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
||||||
{
|
{
|
||||||
bouncer->sector->ceilingheight = actionsector->ceilingheight;
|
bouncer->sector->ceilingheight = actionsector->ceilingheight;
|
||||||
bouncer->sector->floorheight = bouncer->sector->ceilingheight - (halfheight*2);
|
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);
|
P_RecalcPrecipInSector(actionsector);
|
||||||
bouncer->sector->ceilingdata = NULL;
|
bouncer->sector->ceilingdata = NULL;
|
||||||
bouncer->sector->floordata = NULL;
|
bouncer->sector->floordata = NULL;
|
||||||
|
@ -825,6 +827,8 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
||||||
{
|
{
|
||||||
bouncer->sector->ceilingheight = floorheight + (halfheight << 1);
|
bouncer->sector->ceilingheight = floorheight + (halfheight << 1);
|
||||||
bouncer->sector->floorheight = floorheight;
|
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);
|
P_RecalcPrecipInSector(actionsector);
|
||||||
bouncer->sector->ceilingdata = NULL;
|
bouncer->sector->ceilingdata = NULL;
|
||||||
bouncer->sector->floordata = 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 -
|
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,
|
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->floorspeed = -bouncer->speed/2;
|
||||||
bouncer->sector->ceilspeed = 42;
|
bouncer->sector->ceilspeed = 42;
|
||||||
|
@ -893,6 +897,8 @@ void T_BounceCheese(levelspecthink_t *bouncer)
|
||||||
{
|
{
|
||||||
bouncer->sector->floorheight = bouncer->floorwasheight;
|
bouncer->sector->floorheight = bouncer->floorwasheight;
|
||||||
bouncer->sector->ceilingheight = bouncer->ceilingwasheight;
|
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->ceilingdata = NULL;
|
||||||
bouncer->sector->floordata = NULL;
|
bouncer->sector->floordata = NULL;
|
||||||
bouncer->sector->floorspeed = 0;
|
bouncer->sector->floorspeed = 0;
|
||||||
|
@ -1818,6 +1824,7 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
#define ceilingwasheight vars[5]
|
#define ceilingwasheight vars[5]
|
||||||
fixed_t thwompx, thwompy;
|
fixed_t thwompx, thwompy;
|
||||||
sector_t *actionsector;
|
sector_t *actionsector;
|
||||||
|
ffloor_t *rover = NULL;
|
||||||
INT32 secnum;
|
INT32 secnum;
|
||||||
|
|
||||||
// If you just crashed down, wait a second before coming back up.
|
// 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);
|
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
|
||||||
|
|
||||||
if (secnum > 0)
|
if (secnum > 0)
|
||||||
|
{
|
||||||
actionsector = §ors[secnum];
|
actionsector = §ors[secnum];
|
||||||
|
|
||||||
|
// Look for thwomp FFloor
|
||||||
|
for (rover = actionsector->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rover->master == thwomp->sourceline)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return; // Bad bad bad!
|
return; // Bad bad bad!
|
||||||
|
|
||||||
|
@ -1921,10 +1937,13 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
{
|
{
|
||||||
mobj_t *mp = (void *)&actionsector->soundorg;
|
mobj_t *mp = (void *)&actionsector->soundorg;
|
||||||
|
|
||||||
if (thwomp->sourceline->flags & ML_EFFECT4)
|
if (!rover || (rover->flags & FF_EXISTS))
|
||||||
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
{
|
||||||
else
|
if (thwomp->sourceline->flags & ML_EFFECT4)
|
||||||
S_StartSound(mp, sfx_thwomp);
|
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
||||||
|
else
|
||||||
|
S_StartSound(mp, sfx_thwomp);
|
||||||
|
}
|
||||||
|
|
||||||
thwomp->direction = 1; // start heading back up
|
thwomp->direction = 1; // start heading back up
|
||||||
thwomp->distance = TICRATE; // but only after a small delay
|
thwomp->distance = TICRATE; // but only after a small delay
|
||||||
|
@ -1938,18 +1957,22 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
thinker_t *th;
|
thinker_t *th;
|
||||||
mobj_t *mo;
|
mobj_t *mo;
|
||||||
|
|
||||||
// scan the thinkers to find players!
|
if (!rover || (rover->flags & FF_EXISTS))
|
||||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
|
||||||
{
|
{
|
||||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
// scan the thinkers to find players!
|
||||||
continue;
|
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
thwomp->direction = -1;
|
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||||
break;
|
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;
|
boolean floortouch = false;
|
||||||
fixed_t bottomheight, topheight;
|
fixed_t bottomheight, topheight;
|
||||||
msecnode_t *node;
|
msecnode_t *node;
|
||||||
|
ffloor_t *rover;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -2150,6 +2174,19 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
||||||
{
|
{
|
||||||
targetsec = §ors[targetsecnum];
|
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++)
|
for (j = 0; j < MAXPLAYERS; j++)
|
||||||
{
|
{
|
||||||
if (!playeringame[j])
|
if (!playeringame[j])
|
||||||
|
|
|
@ -777,14 +777,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
// not (your direction) xor (stored direction)
|
// not (your direction) xor (stored direction)
|
||||||
// In other words, you can't u-turn and respawn rings near the drone.
|
// 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 && (
|
if (pl->bonustime && (pl->pflags & PF_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && (
|
||||||
!(pl->anotherflyangle >= 90 && pl->anotherflyangle <= 270)
|
!(pl->flyangle > 90 && pl->flyangle < 270)
|
||||||
^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270)
|
^ (droneobj->extravalue1 > 90 && droneobj->extravalue1 < 270)
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
// Reload all the fancy ring stuff!
|
// Reload all the fancy ring stuff!
|
||||||
P_ReloadRings();
|
P_ReloadRings();
|
||||||
}
|
}
|
||||||
droneobj->extravalue1 = pl->anotherflyangle;
|
droneobj->extravalue1 = pl->flyangle;
|
||||||
droneobj->extravalue2 = (INT32)leveltime + TICRATE;
|
droneobj->extravalue2 = (INT32)leveltime + TICRATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/p_mobj.c
13
src/p_mobj.c
|
@ -3506,7 +3506,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
||||||
|
|
||||||
if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
postimg = postimg_flip;
|
postimg = postimg_flip;
|
||||||
else if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist
|
else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||||
{
|
{
|
||||||
camera_t dummycam;
|
camera_t dummycam;
|
||||||
dummycam.subsector = player->awayviewmobj->subsector;
|
dummycam.subsector = player->awayviewmobj->subsector;
|
||||||
|
@ -9198,9 +9198,6 @@ ML_NOCLIMB : Direction not controllable
|
||||||
// the bumper in 30 degree increments.
|
// the bumper in 30 degree increments.
|
||||||
mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc
|
mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc
|
||||||
P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold);
|
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;
|
break;
|
||||||
case MT_EGGCAPSULE:
|
case MT_EGGCAPSULE:
|
||||||
if (mthing->angle <= 0)
|
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);
|
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
||||||
|
|
||||||
if ((mthing->options & MTF_AMBUSH)
|
if ((mthing->options & MTF_AMBUSH)
|
||||||
|
|
|
@ -489,16 +489,34 @@ static void P_NetArchiveWorld(void)
|
||||||
UINT8 *put;
|
UINT8 *put;
|
||||||
|
|
||||||
// reload the map just to see difference
|
// reload the map just to see difference
|
||||||
const mapsector_t *ms;
|
mapsector_t *ms;
|
||||||
const mapsidedef_t *msd;
|
mapsidedef_t *msd;
|
||||||
const maplinedef_t *mld;
|
maplinedef_t *mld;
|
||||||
const sector_t *ss = sectors;
|
const sector_t *ss = sectors;
|
||||||
UINT8 diff, diff2;
|
UINT8 diff, diff2;
|
||||||
|
|
||||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||||
put = save_p;
|
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++)
|
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||||
{
|
{
|
||||||
|
@ -950,6 +968,7 @@ typedef enum
|
||||||
tc_bouncecheese,
|
tc_bouncecheese,
|
||||||
tc_startcrumble,
|
tc_startcrumble,
|
||||||
tc_marioblock,
|
tc_marioblock,
|
||||||
|
tc_marioblockchecker,
|
||||||
tc_spikesector,
|
tc_spikesector,
|
||||||
tc_floatsector,
|
tc_floatsector,
|
||||||
tc_bridgethinker,
|
tc_bridgethinker,
|
||||||
|
@ -1259,7 +1278,10 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
|
||||||
size_t i;
|
size_t i;
|
||||||
WRITEUINT8(save_p, type);
|
WRITEUINT8(save_p, type);
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
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, SaveLine(ht->sourceline));
|
||||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
}
|
}
|
||||||
|
@ -1772,6 +1794,11 @@ static void P_NetArchiveThinkers(void)
|
||||||
SaveSpecialLevelThinker(th, tc_marioblock);
|
SaveSpecialLevelThinker(th, tc_marioblock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
||||||
|
{
|
||||||
|
SaveSpecialLevelThinker(th, tc_marioblockchecker);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_spikesector);
|
SaveSpecialLevelThinker(th, tc_spikesector);
|
||||||
|
@ -2155,7 +2182,10 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
|
||||||
size_t i;
|
size_t i;
|
||||||
ht->thinker.function.acp1 = thinker;
|
ht->thinker.function.acp1 = thinker;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
ht->vars[i] = READFIXED(save_p); //var[16]
|
ht->vars[i] = READFIXED(save_p); //var[16]
|
||||||
|
ht->var2s[i] = READFIXED(save_p); //var[16]
|
||||||
|
}
|
||||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
ht->sector = LoadSector(READUINT32(save_p));
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
|
||||||
|
@ -2728,6 +2758,10 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_marioblockchecker:
|
||||||
|
LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case tc_spikesector:
|
case tc_spikesector:
|
||||||
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
||||||
break;
|
break;
|
||||||
|
|
439
src/p_setup.c
439
src/p_setup.c
|
@ -350,16 +350,13 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade)
|
||||||
* \param lump VERTEXES lump number.
|
* \param lump VERTEXES lump number.
|
||||||
* \sa ML_VERTEXES
|
* \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;
|
mapvertex_t *ml;
|
||||||
vertex_t *li;
|
vertex_t *li;
|
||||||
|
|
||||||
// Determine number of lumps:
|
numvertexes = i / sizeof (mapvertex_t);
|
||||||
// total lump length / vertex record length.
|
|
||||||
numvertexes = W_LumpLength(lumpnum) / sizeof (mapvertex_t);
|
|
||||||
|
|
||||||
if (numvertexes <= 0)
|
if (numvertexes <= 0)
|
||||||
I_Error("Level has no vertices"); // instead of crashing
|
I_Error("Level has no vertices"); // instead of crashing
|
||||||
|
@ -367,9 +364,6 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||||
// Allocate zone memory for buffer.
|
// Allocate zone memory for buffer.
|
||||||
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
||||||
|
|
||||||
// Load data into cache.
|
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
ml = (mapvertex_t *)data;
|
ml = (mapvertex_t *)data;
|
||||||
li = vertexes;
|
li = vertexes;
|
||||||
|
|
||||||
|
@ -379,11 +373,16 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||||
li->x = SHORT(ml->x)<<FRACBITS;
|
li->x = SHORT(ml->x)<<FRACBITS;
|
||||||
li->y = SHORT(ml->y)<<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);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Computes the line length in fracunits, the OpenGL render needs this
|
// Computes the line length in fracunits, the OpenGL render needs this
|
||||||
//
|
//
|
||||||
|
@ -423,20 +422,17 @@ static inline float P_SegLengthf(seg_t *seg)
|
||||||
* \param lump Lump number of the SEGS resource.
|
* \param lump Lump number of the SEGS resource.
|
||||||
* \sa ::ML_SEGS
|
* \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;
|
INT32 linedef, side;
|
||||||
mapseg_t *ml;
|
mapseg_t *ml;
|
||||||
seg_t *li;
|
seg_t *li;
|
||||||
line_t *ldef;
|
line_t *ldef;
|
||||||
|
|
||||||
numsegs = W_LumpLength(lumpnum) / sizeof (mapseg_t);
|
numsegs = i / sizeof (mapseg_t);
|
||||||
if (numsegs <= 0)
|
if (numsegs <= 0)
|
||||||
I_Error("Level has no segs"); // instead of crashing
|
I_Error("Level has no segs"); // instead of crashing
|
||||||
segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL);
|
segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
ml = (mapseg_t *)data;
|
ml = (mapseg_t *)data;
|
||||||
li = segs;
|
li = segs;
|
||||||
|
@ -472,27 +468,30 @@ static void P_LoadSegs(lumpnum_t lumpnum)
|
||||||
li->numlights = 0;
|
li->numlights = 0;
|
||||||
li->rlights = NULL;
|
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);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Loads the SSECTORS resource from a level.
|
/** Loads the SSECTORS resource from a level.
|
||||||
*
|
*
|
||||||
* \param lump Lump number of the SSECTORS resource.
|
* \param lump Lump number of the SSECTORS resource.
|
||||||
* \sa ::ML_SSECTORS
|
* \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;
|
mapsubsector_t *ms;
|
||||||
subsector_t *ss;
|
subsector_t *ss;
|
||||||
|
|
||||||
numsubsectors = W_LumpLength(lumpnum) / sizeof (mapsubsector_t);
|
numsubsectors = i / sizeof (mapsubsector_t);
|
||||||
if (numsubsectors <= 0)
|
if (numsubsectors <= 0)
|
||||||
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
|
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);
|
ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum,PU_STATIC);
|
|
||||||
|
|
||||||
ms = (mapsubsector_t *)data;
|
ms = (mapsubsector_t *)data;
|
||||||
|
|
||||||
|
@ -506,7 +505,12 @@ static inline void P_LoadSubsectors(lumpnum_t lumpnum)
|
||||||
#endif
|
#endif
|
||||||
ss->validcount = 0;
|
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);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,29 +644,31 @@ INT32 P_CheckLevelFlat(const char *flatname)
|
||||||
return (INT32)i;
|
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;
|
mapsector_t *ms;
|
||||||
sector_t *ss;
|
sector_t *ss;
|
||||||
levelflat_t *foundflats;
|
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)
|
if (numsectors <= 0)
|
||||||
I_Error("Level has no sectors");
|
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);
|
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));
|
foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats));
|
||||||
if (foundflats == NULL)
|
if (foundflats == NULL)
|
||||||
I_Error("Ran out of memory while loading sectors\n");
|
I_Error("Ran out of memory while loading sectors\n");
|
||||||
|
|
||||||
numlevelflats = 0;
|
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;
|
ms = (mapsector_t *)data;
|
||||||
ss = sectors;
|
ss = sectors;
|
||||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||||
|
@ -670,9 +676,6 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
||||||
ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
|
ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
|
||||||
|
|
||||||
//
|
|
||||||
// flats
|
|
||||||
//
|
|
||||||
ss->floorpic = P_AddLevelFlat(ms->floorpic, foundflats);
|
ss->floorpic = P_AddLevelFlat(ms->floorpic, foundflats);
|
||||||
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
||||||
|
|
||||||
|
@ -737,8 +740,6 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
#endif // ----- end special tricks -----
|
#endif // ----- end special tricks -----
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Free(data);
|
|
||||||
|
|
||||||
// set the sky flat num
|
// set the sky flat num
|
||||||
skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats);
|
skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats);
|
||||||
|
|
||||||
|
@ -750,22 +751,26 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
P_SetupLevelFlatAnims();
|
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
|
// 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;
|
UINT8 j, k;
|
||||||
mapnode_t *mn;
|
mapnode_t *mn;
|
||||||
node_t *no;
|
node_t *no;
|
||||||
|
|
||||||
numnodes = W_LumpLength(lumpnum) / sizeof (mapnode_t);
|
numnodes = i / sizeof (mapnode_t);
|
||||||
if (numnodes <= 0)
|
if (numnodes <= 0)
|
||||||
I_Error("Level has no nodes");
|
I_Error("Level has no nodes");
|
||||||
nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL);
|
nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
mn = (mapnode_t *)data;
|
mn = (mapnode_t *)data;
|
||||||
no = nodes;
|
no = nodes;
|
||||||
|
@ -783,7 +788,12 @@ static void P_LoadNodes(lumpnum_t lumpnum)
|
||||||
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
|
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);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,18 +928,16 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
||||||
//
|
//
|
||||||
// P_LoadThings
|
// 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);
|
mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
||||||
|
|
||||||
// Spawn axis points first so they are
|
// Spawn axis points first so they are
|
||||||
// at the front of the list for fast searching.
|
// at the front of the list for fast searching.
|
||||||
data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
|
||||||
mt = mapthings;
|
mt = mapthings;
|
||||||
for (i = 0; i < nummapthings; i++, mt++)
|
for (i = 0; i < nummapthings; i++, mt++)
|
||||||
{
|
{
|
||||||
|
@ -954,8 +962,13 @@ static void P_PrepareThings(lumpnum_t lumpnum)
|
||||||
break;
|
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)
|
static void P_LoadThings(void)
|
||||||
|
@ -1142,22 +1155,16 @@ void P_WriteThings(lumpnum_t lumpnum)
|
||||||
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
static void P_LoadRawLineDefs(UINT8 *data, size_t i)
|
||||||
// P_LoadLineDefs
|
|
||||||
//
|
|
||||||
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
|
||||||
size_t i;
|
|
||||||
maplinedef_t *mld;
|
maplinedef_t *mld;
|
||||||
line_t *ld;
|
line_t *ld;
|
||||||
vertex_t *v1, *v2;
|
vertex_t *v1, *v2;
|
||||||
|
|
||||||
numlines = W_LumpLength(lumpnum) / sizeof (maplinedef_t);
|
numlines = i / sizeof (maplinedef_t);
|
||||||
if (numlines <= 0)
|
if (numlines <= 0)
|
||||||
I_Error("Level has no linedefs");
|
I_Error("Level has no linedefs");
|
||||||
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
mld = (maplinedef_t *)data;
|
mld = (maplinedef_t *)data;
|
||||||
ld = lines;
|
ld = lines;
|
||||||
|
@ -1179,7 +1186,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
ld->slopetype = ST_VERTICAL;
|
ld->slopetype = ST_VERTICAL;
|
||||||
else if (!ld->dy)
|
else if (!ld->dy)
|
||||||
ld->slopetype = ST_HORIZONTAL;
|
ld->slopetype = ST_HORIZONTAL;
|
||||||
else if (FixedDiv(ld->dy, ld->dx) > 0)
|
else if ((ld->dy > 0) == (ld->dx > 0))
|
||||||
ld->slopetype = ST_POSITIVE;
|
ld->slopetype = ST_POSITIVE;
|
||||||
else
|
else
|
||||||
ld->slopetype = ST_NEGATIVE;
|
ld->slopetype = ST_NEGATIVE;
|
||||||
|
@ -1219,7 +1226,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
||||||
{
|
{
|
||||||
ld->sidenum[j] = 0xffff;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1234,14 +1241,14 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
{
|
{
|
||||||
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
||||||
// cph - print a warning about the bug
|
// 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))
|
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
||||||
{
|
{
|
||||||
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
||||||
// cph - print a warning about the bug
|
// 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)
|
if (ld->sidenum[0] != 0xffff && ld->special)
|
||||||
|
@ -1253,7 +1260,12 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
ld->polyobj = NULL;
|
ld->polyobj = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawLineDefs(data, W_LumpLength(lumpnum));
|
||||||
Z_Free(data);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1355,22 +1367,24 @@ static void P_LoadLineDefs2(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_LoadSideDefs
|
|
||||||
//
|
static inline void P_LoadRawSideDefs(size_t i)
|
||||||
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
|
||||||
{
|
{
|
||||||
numsides = W_LumpLength(lumpnum) / sizeof (mapsidedef_t);
|
numsides = i / sizeof (mapsidedef_t);
|
||||||
if (numsides <= 0)
|
if (numsides <= 0)
|
||||||
I_Error("Level has no sidedefs");
|
I_Error("Level has no sidedefs");
|
||||||
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay loading texture names until after loaded linedefs.
|
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
P_LoadRawSideDefs(W_LumpLength(lumpnum));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void P_LoadRawSideDefs2(void *data)
|
||||||
{
|
{
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
INT32 num;
|
INT32 num;
|
||||||
|
|
||||||
|
@ -1388,7 +1402,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
|
|
||||||
if (sector_num >= numsectors)
|
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;
|
sector_num = 0;
|
||||||
}
|
}
|
||||||
sd->sector = sec = §ors[sector_num];
|
sd->sector = sec = §ors[sector_num];
|
||||||
|
@ -1530,6 +1544,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
sd->text[6] = 0;
|
sd->text[6] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 4: // Speed pad parameters
|
||||||
case 414: // Play SFX
|
case 414: // Play SFX
|
||||||
{
|
{
|
||||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||||
|
@ -1543,6 +1559,9 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
break;
|
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 425: // Calls P_SetMobjState on calling mobj
|
||||||
case 434: // Custom Power
|
case 434: // Custom Power
|
||||||
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
||||||
|
@ -1597,11 +1616,18 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Free(data);
|
|
||||||
R_ClearTextureNumCache(true);
|
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)
|
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];
|
fixed_t bbox[4];
|
||||||
|
@ -1857,6 +1883,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
|
// P_LoadBlockMap
|
||||||
//
|
//
|
||||||
|
@ -1883,38 +1933,20 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL);
|
INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL);
|
||||||
|
if (!wadblockmaplump)
|
||||||
if (wadblockmaplump) W_ReadLump(lumpnum, wadblockmaplump);
|
return false;
|
||||||
else return false;
|
W_ReadLump(lumpnum, wadblockmaplump);
|
||||||
count /= 2;
|
count /= 2;
|
||||||
blockmaplump = Z_Calloc(sizeof (*blockmaplump) * count, PU_LEVEL, 0);
|
P_ReadBlockMapLump(wadblockmaplump, count);
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(wadblockmaplump);
|
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
|
// clear out mobj chains
|
||||||
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
|
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
|
||||||
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
||||||
|
@ -1948,6 +1980,53 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
|
||||||
#endif
|
#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
|
// P_GroupLines
|
||||||
// Builds sector line lists and subsector sector numbers.
|
// Builds sector line lists and subsector sector numbers.
|
||||||
|
@ -2073,6 +2152,30 @@ static void P_LoadReject(lumpnum_t lumpnum)
|
||||||
rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
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
|
#if 0
|
||||||
static char *levellumps[] =
|
static char *levellumps[] =
|
||||||
{
|
{
|
||||||
|
@ -2252,7 +2355,16 @@ void P_LoadThingsOnly(void)
|
||||||
|
|
||||||
P_LevelInitStuff();
|
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_LoadThings();
|
||||||
|
|
||||||
P_SpawnSecretItems(true);
|
P_SpawnSecretItems(true);
|
||||||
|
@ -2690,7 +2802,12 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal game map
|
// 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);
|
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
|
||||||
CON_SetupBackColormap();
|
CON_SetupBackColormap();
|
||||||
|
@ -2700,38 +2817,93 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
|
|
||||||
P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);
|
P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);
|
||||||
|
|
||||||
// note: most of this ordering is important
|
// HACK ALERT: Cache the WAD, get the map data into the tables, free memory.
|
||||||
loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP);
|
// 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);
|
if (numlumps < ML_REJECT) // at least 9 lumps should be in the wad for a map to be loaded
|
||||||
P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS);
|
{
|
||||||
|
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);
|
// Important: take care of the ordering of the next functions.
|
||||||
if (!loadedbm)
|
if (!loadedbm)
|
||||||
P_CreateBlockMap(); // Graue 02-29-2004
|
P_CreateBlockMap(); // Graue 02-29-2004
|
||||||
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
|
P_LoadLineDefs2();
|
||||||
|
P_GroupLines();
|
||||||
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
|
||||||
P_LoadLineDefs2();
|
// reset the player starts
|
||||||
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
|
playerstarts[i] = NULL;
|
||||||
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
|
for (i = 0; i < 2; i++)
|
||||||
P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
|
skyboxmo[i] = NULL;
|
||||||
P_GroupLines();
|
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
|
// Important: take care of the ordering of the next functions.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
if (!loadedbm)
|
||||||
playerstarts[i] = NULL;
|
P_CreateBlockMap(); // Graue 02-29-2004
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
P_LoadLineDefs2();
|
||||||
skyboxmo[i] = NULL;
|
P_GroupLines();
|
||||||
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
|
||||||
P_MapStart();
|
// reset the player starts
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
playerstarts[i] = NULL;
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
skyboxmo[i] = NULL;
|
||||||
|
P_MapStart();
|
||||||
|
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
P_ResetDynamicSlopes();
|
P_ResetDynamicSlopes();
|
||||||
|
@ -2979,7 +3151,7 @@ boolean P_RunSOC(const char *socfilename)
|
||||||
lumpnum_t lump;
|
lumpnum_t lump;
|
||||||
|
|
||||||
if (strstr(socfilename, ".soc") != NULL)
|
if (strstr(socfilename, ".soc") != NULL)
|
||||||
return P_AddWadFile(socfilename, NULL);
|
return P_AddWadFile(socfilename);
|
||||||
|
|
||||||
lump = W_CheckNumForName(socfilename);
|
lump = W_CheckNumForName(socfilename);
|
||||||
if (lump == LUMPERROR)
|
if (lump == LUMPERROR)
|
||||||
|
@ -2995,17 +3167,17 @@ boolean P_RunSOC(const char *socfilename)
|
||||||
// Add a wadfile to the active wad files,
|
// Add a wadfile to the active wad files,
|
||||||
// replace sounds, musics, patches, textures, sprites and maps
|
// 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;
|
size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||||
UINT16 numlumps, wadnum;
|
UINT16 numlumps, wadnum;
|
||||||
INT16 firstmapreplaced = 0, num;
|
|
||||||
char *name;
|
char *name;
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
boolean texturechange = false;
|
boolean texturechange = false;
|
||||||
|
boolean mapsadded = false;
|
||||||
boolean replacedcurrentmap = false;
|
boolean replacedcurrentmap = false;
|
||||||
|
|
||||||
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
||||||
{
|
{
|
||||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||||
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
|
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
|
||||||
|
@ -3062,6 +3234,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
if (!devparm && digmreplaces)
|
if (!devparm && digmreplaces)
|
||||||
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// search for sprite replacements
|
// search for sprite replacements
|
||||||
//
|
//
|
||||||
|
@ -3096,10 +3269,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||||
{
|
{
|
||||||
name = lumpinfo->name;
|
name = lumpinfo->name;
|
||||||
num = firstmapreplaced;
|
|
||||||
|
|
||||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||||
{
|
{
|
||||||
|
INT16 num;
|
||||||
if (name[5]!='\0')
|
if (name[5]!='\0')
|
||||||
continue;
|
continue;
|
||||||
num = (INT16)M_MapNumber(name[3], name[4]);
|
num = (INT16)M_MapNumber(name[3], name[4]);
|
||||||
|
@ -3109,16 +3282,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
replacedcurrentmap = true;
|
replacedcurrentmap = true;
|
||||||
|
|
||||||
CONS_Printf("%s\n", name);
|
CONS_Printf("%s\n", name);
|
||||||
}
|
mapsadded = true;
|
||||||
|
|
||||||
if (num && (num < firstmapreplaced || !firstmapreplaced))
|
|
||||||
{
|
|
||||||
firstmapreplaced = num;
|
|
||||||
if (firstmapname)
|
|
||||||
*firstmapname = name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!firstmapreplaced)
|
if (!mapsadded)
|
||||||
CONS_Printf(M_GetText("No maps added\n"));
|
CONS_Printf(M_GetText("No maps added\n"));
|
||||||
|
|
||||||
// reload status bar (warning should have valid player!)
|
// reload status bar (warning should have valid player!)
|
||||||
|
|
|
@ -59,7 +59,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
|
||||||
#endif
|
#endif
|
||||||
void P_LoadThingsOnly(void);
|
void P_LoadThingsOnly(void);
|
||||||
boolean P_SetupLevel(boolean skipprecip);
|
boolean P_SetupLevel(boolean skipprecip);
|
||||||
boolean P_AddWadFile(const char *wadfilename, char **firstmapname);
|
boolean P_AddWadFile(const char *wadfilename);
|
||||||
#ifdef DELFILE
|
#ifdef DELFILE
|
||||||
boolean P_DelWadFile(void);
|
boolean P_DelWadFile(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@ static pslope_t *slopelist = NULL;
|
||||||
static UINT16 slopecount = 0;
|
static UINT16 slopecount = 0;
|
||||||
|
|
||||||
// Calculate line normal
|
// 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.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||||
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
|
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
|
||||||
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
|
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define P_SLOPES_H__
|
#define P_SLOPES_H__
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||||
void P_ResetDynamicSlopes(void);
|
void P_ResetDynamicSlopes(void);
|
||||||
void P_RunDynamicSlopes(void);
|
void P_RunDynamicSlopes(void);
|
||||||
// P_SpawnSlope_Line
|
// P_SpawnSlope_Line
|
||||||
|
|
48
src/p_spec.c
48
src/p_spec.c
|
@ -279,10 +279,13 @@ void P_InitPicAnims(void)
|
||||||
Z_Free(animatedLump);
|
Z_Free(animatedLump);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find ANIMDEFS
|
// Find ANIMDEFS lump in the WAD
|
||||||
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0);
|
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0);
|
||||||
if (animdefsLumpNum != INT16_MAX)
|
while (animdefsLumpNum != INT16_MAX)
|
||||||
|
{
|
||||||
P_ParseANIMDEFSLump(w, animdefsLumpNum);
|
P_ParseANIMDEFSLump(w, animdefsLumpNum);
|
||||||
|
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Define the last one
|
// Define the last one
|
||||||
animdefs[maxanims].istexture = -1;
|
animdefs[maxanims].istexture = -1;
|
||||||
|
@ -6243,9 +6246,21 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
case 259: // Make-Your-Own FOF!
|
case 259: // Make-Your-Own FOF!
|
||||||
if (lines[i].sidenum[1] != 0xffff)
|
if (lines[i].sidenum[1] != 0xffff)
|
||||||
{
|
{
|
||||||
UINT8 *data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC);
|
UINT8 *data;
|
||||||
UINT16 b;
|
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++)
|
for (b = 0; b < (INT16)numsides; b++)
|
||||||
{
|
{
|
||||||
register mapsidedef_t *msd = (mapsidedef_t *)data + b;
|
register mapsidedef_t *msd = (mapsidedef_t *)data + b;
|
||||||
|
@ -6614,6 +6629,7 @@ void T_Scroll(scroll_t *s)
|
||||||
line_t *line;
|
line_t *line;
|
||||||
size_t i;
|
size_t i;
|
||||||
INT32 sect;
|
INT32 sect;
|
||||||
|
ffloor_t *rover;
|
||||||
|
|
||||||
case sc_side: // scroll wall texture
|
case sc_side: // scroll wall texture
|
||||||
side = sides + s->affectee;
|
side = sides + s->affectee;
|
||||||
|
@ -6655,6 +6671,19 @@ void T_Scroll(scroll_t *s)
|
||||||
sector_t *psec;
|
sector_t *psec;
|
||||||
psec = sectors + sect;
|
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)
|
for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
|
||||||
{
|
{
|
||||||
thing = node->m_thing;
|
thing = node->m_thing;
|
||||||
|
@ -6718,6 +6747,19 @@ void T_Scroll(scroll_t *s)
|
||||||
sector_t *psec;
|
sector_t *psec;
|
||||||
psec = sectors + sect;
|
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)
|
for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
|
||||||
{
|
{
|
||||||
thing = node->m_thing;
|
thing = node->m_thing;
|
||||||
|
|
|
@ -607,7 +607,8 @@ void P_Ticker(boolean run)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep track of how long they've been playing!
|
// 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))
|
if (!useNightsSS && G_IsSpecialStage(gamemap))
|
||||||
P_DoSpecialStageStuff();
|
P_DoSpecialStageStuff();
|
||||||
|
|
61
src/p_user.c
61
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)
|
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
|
if (!(rover->flags & FF_EXISTS))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
|
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
|
||||||
continue;
|
continue;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
@ -1835,6 +1838,12 @@ static void P_CheckBouncySectors(player_t *player)
|
||||||
|
|
||||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
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);
|
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);
|
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))
|
&& oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
|
||||||
top = false;
|
top = false;
|
||||||
|
|
||||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
|
|
||||||
{
|
{
|
||||||
fixed_t linedist;
|
fixed_t linedist;
|
||||||
|
|
||||||
|
@ -7845,7 +7853,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
subsector_t *newsubsec;
|
subsector_t *newsubsec;
|
||||||
fixed_t f1, f2;
|
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))
|
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])
|
else if (player == &players[secondarydisplayplayer])
|
||||||
focusangle = localangle2;
|
focusangle = localangle2;
|
||||||
else
|
else
|
||||||
focusangle = player->mo->angle;
|
focusangle = mo->angle;
|
||||||
if (thiscam == &camera)
|
if (thiscam == &camera)
|
||||||
camrotate = cv_cam_rotate.value;
|
camrotate = cv_cam_rotate.value;
|
||||||
else if (thiscam == &camera2)
|
else if (thiscam == &camera2)
|
||||||
|
@ -7878,17 +7892,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player || !player->mo)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
mo = player->mo;
|
|
||||||
|
|
||||||
thiscam->radius = FixedMul(20*FRACUNIT, mo->scale);
|
thiscam->radius = FixedMul(20*FRACUNIT, mo->scale);
|
||||||
thiscam->height = FixedMul(16*FRACUNIT, mo->scale);
|
thiscam->height = FixedMul(16*FRACUNIT, mo->scale);
|
||||||
|
|
||||||
if (!mo)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Don't run while respawning from a starpost
|
// Don't run while respawning from a starpost
|
||||||
// Inu 4/8/13 Why not?!
|
// Inu 4/8/13 Why not?!
|
||||||
// if (leveltime > 0 && timeinmap <= 0)
|
// 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)
|
if (player->pflags & PF_NIGHTSMODE)
|
||||||
{
|
{
|
||||||
focusangle = player->mo->angle;
|
focusangle = mo->angle;
|
||||||
focusaiming = 0;
|
focusaiming = 0;
|
||||||
}
|
}
|
||||||
else if (player == &players[consoleplayer])
|
else if (player == &players[consoleplayer])
|
||||||
|
@ -7911,7 +7917,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
focusangle = player->mo->angle;
|
focusangle = mo->angle;
|
||||||
focusaiming = player->aiming;
|
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 = R_PointToAngle2(player->axis1->x, player->axis1->y, player->axis2->x, player->axis2->y);
|
||||||
angle += ANGLE_90;
|
angle += ANGLE_90;
|
||||||
}
|
}
|
||||||
else if (player->mo->target)
|
else if (mo->target)
|
||||||
{
|
{
|
||||||
if (player->mo->target->flags & MF_AMBUSH)
|
if (mo->target->flags & MF_AMBUSH)
|
||||||
angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
|
angle = R_PointToAngle2(mo->target->x, mo->target->y, mo->x, mo->y);
|
||||||
else
|
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
|
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))
|
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||||
{
|
{
|
||||||
// Camera doesn't ALWAYS need to move, only when running...
|
// 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...
|
// Move the camera all smooth-like, not jerk it around...
|
||||||
if (mo->momx > 0)
|
if (mo->momx > 0)
|
||||||
|
@ -8366,19 +8372,19 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
if (!(multiplayer || netgame) && !splitscreen)
|
if (!(multiplayer || netgame) && !splitscreen)
|
||||||
{
|
{
|
||||||
fixed_t vx = thiscam->x, vy = thiscam->y;
|
fixed_t vx = thiscam->x, vy = thiscam->y;
|
||||||
if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist
|
if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||||
{
|
{
|
||||||
vx = player->awayviewmobj->x;
|
vx = player->awayviewmobj->x;
|
||||||
vy = player->awayviewmobj->y;
|
vy = player->awayviewmobj->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||||
player->mo->flags2 |= MF2_SHADOW;
|
mo->flags2 |= MF2_SHADOW;
|
||||||
else
|
else
|
||||||
player->mo->flags2 &= ~MF2_SHADOW;
|
mo->flags2 &= ~MF2_SHADOW;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player->mo->flags2 &= ~MF2_SHADOW;
|
mo->flags2 &= ~MF2_SHADOW;
|
||||||
|
|
||||||
/* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting))
|
/* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting))
|
||||||
{
|
{
|
||||||
|
@ -8528,7 +8534,7 @@ static void P_CalcPostImg(player_t *player)
|
||||||
else
|
else
|
||||||
pviewheight = player->mo->z + player->viewheight;
|
pviewheight = player->mo->z + player->viewheight;
|
||||||
|
|
||||||
if (player->awayviewtics)
|
if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj))
|
||||||
{
|
{
|
||||||
sector = player->awayviewmobj->subsector->sector;
|
sector = player->awayviewmobj->subsector->sector;
|
||||||
pviewheight = player->awayviewmobj->z + 20*FRACUNIT;
|
pviewheight = player->awayviewmobj->z + 20*FRACUNIT;
|
||||||
|
@ -8695,6 +8701,13 @@ void P_PlayerThink(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
|
||||||
|
{
|
||||||
|
P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid
|
||||||
|
player->awayviewtics = 0; // reset to zero
|
||||||
|
}
|
||||||
|
|
||||||
if (player->pflags & PF_GLIDING)
|
if (player->pflags & PF_GLIDING)
|
||||||
{
|
{
|
||||||
if (player->panim != PA_ABILITY)
|
if (player->panim != PA_ABILITY)
|
||||||
|
|
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"
|
// Need these prototypes for later; defining them here instead of r_data.h so they're "private"
|
||||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum);
|
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
|
||||||
void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *index);
|
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_LoadTextures
|
// 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.
|
// 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++)
|
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||||
{
|
{
|
||||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
|
||||||
|
|
||||||
if (texturesLumpPos != INT16_MAX)
|
|
||||||
{
|
{
|
||||||
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
|
// 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++)
|
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||||
{
|
{
|
||||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
{
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||||
|
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||||
if (texturesLumpPos != INT16_MAX)
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||||
R_ParseTEXTURESLump(w,&i);
|
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)
|
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||||
continue;
|
continue;
|
||||||
|
@ -472,40 +494,22 @@ void R_LoadTextures(void)
|
||||||
}
|
}
|
||||||
else
|
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);
|
//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
|
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||||
&& 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);
|
|
||||||
|
|
||||||
// Set texture properties.
|
// Set texture properties.
|
||||||
M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name));
|
M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name));
|
||||||
texture->width = SHORT(patchlump->width);
|
texture->width = SHORT(patchlump->width);
|
||||||
texture->height = SHORT(patchlump->height)*patchcount;
|
texture->height = SHORT(patchlump->height);
|
||||||
texture->patchcount = patchcount;
|
texture->patchcount = 1;
|
||||||
texture->holes = false;
|
texture->holes = false;
|
||||||
|
|
||||||
// Allocate information for the texture's patches.
|
// Allocate information for the texture's patches.
|
||||||
for (k = 0; k < patchcount; k++)
|
patch = &texture->patches[0];
|
||||||
{
|
|
||||||
patch = &texture->patches[k];
|
|
||||||
|
|
||||||
patch->originx = 0;
|
patch->originx = patch->originy = 0;
|
||||||
patch->originy = (INT16)(k*patchlump->height);
|
patch->wad = (UINT16)w;
|
||||||
patch->wad = (UINT16)w;
|
patch->lump = texstart + j;
|
||||||
patch->lump = texstart + j;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z_Unlock(patchlump);
|
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.
|
// 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;
|
char *texturesLump;
|
||||||
size_t texturesLumpLength;
|
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
|
// 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
|
// 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.
|
// 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 that didn't exist, we have nothing to do here.
|
||||||
if (texturesLump == NULL) return 0;
|
if (texturesLump == NULL) return 0;
|
||||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
// 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);
|
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||||
// Now move the contents of the lump into this new location.
|
// Now move the contents of the lump into this new location.
|
||||||
memmove(texturesText,texturesLump,texturesLumpLength);
|
memmove(texturesText,texturesLump,texturesLumpLength);
|
||||||
|
@ -864,7 +868,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the TEXTURES lump... for real, this time.
|
// 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;
|
char *texturesLump;
|
||||||
size_t texturesLumpLength;
|
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
|
// 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
|
// 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.
|
// 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 that didn't exist, we have nothing to do here.
|
||||||
if (texturesLump == NULL) return;
|
if (texturesLump == NULL) return;
|
||||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
// 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);
|
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||||
// Now move the contents of the lump into this new location.
|
// Now move the contents of the lump into this new location.
|
||||||
memmove(texturesText,texturesLump,texturesLumpLength);
|
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));
|
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 R_GetFlatNumForName(const char *name)
|
||||||
{
|
{
|
||||||
lumpnum_t lump = W_CheckNumForNameInBlock(name, "F_START", "F_END");
|
INT32 i;
|
||||||
if (lump == LUMPERROR)
|
lumpnum_t lump;
|
||||||
lump = W_CheckNumForNameInBlock(name, "FF_START", "FF_END"); // deutex, some other old things
|
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 (lump == LUMPERROR)
|
||||||
{
|
{
|
||||||
if (strcmp(name, SKYFLATNAME))
|
if (strcmp(name, SKYFLATNAME))
|
||||||
|
|
|
@ -327,21 +327,28 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
||||||
UINT16 start, end;
|
UINT16 start, end;
|
||||||
char wadname[MAX_WADPATH];
|
char wadname[MAX_WADPATH];
|
||||||
|
|
||||||
// find the sprites section in this pwad
|
switch (wadfiles[wadnum]->type)
|
||||||
// we need at least the S_END
|
{
|
||||||
// (not really, but for speedup)
|
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)
|
if (end == INT16_MAX)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum);
|
CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum);
|
||||||
|
@ -2441,7 +2448,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||||
|
|
||||||
if (P_IsLocalPlayer(player))
|
if (P_IsLocalPlayer(player))
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname);
|
CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname);
|
||||||
else if(server || adminplayer == consoleplayer)
|
else if(server || IsPlayerAdmin(consoleplayer))
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
|
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
|
||||||
|
|
||||||
SetPlayerSkinByNum(playernum, 0);
|
SetPlayerSkinByNum(playernum, 0);
|
||||||
|
@ -2499,7 +2506,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
||||||
|
|
||||||
if (P_IsLocalPlayer(player))
|
if (P_IsLocalPlayer(player))
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum);
|
CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum);
|
||||||
else if(server || adminplayer == consoleplayer)
|
else if(server || IsPlayerAdmin(consoleplayer))
|
||||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
||||||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,6 +297,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\i_tcp.c" />
|
<ClCompile Include="..\i_tcp.c" />
|
||||||
<ClCompile Include="..\lua_baselib.c" />
|
<ClCompile Include="..\lua_baselib.c" />
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||||
<ClCompile Include="..\lua_consolelib.c" />
|
<ClCompile Include="..\lua_consolelib.c" />
|
||||||
<ClCompile Include="..\lua_hooklib.c" />
|
<ClCompile Include="..\lua_hooklib.c" />
|
||||||
<ClCompile Include="..\lua_hudlib.c" />
|
<ClCompile Include="..\lua_hudlib.c" />
|
||||||
|
|
|
@ -639,6 +639,9 @@
|
||||||
<ClCompile Include="..\lua_baselib.c">
|
<ClCompile Include="..\lua_baselib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c">
|
||||||
|
<Filter>LUA</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\lua_consolelib.c">
|
<ClCompile Include="..\lua_consolelib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -894,8 +894,8 @@ void I_GetJoystickEvents(void)
|
||||||
UINT64 joyhats = 0;
|
UINT64 joyhats = 0;
|
||||||
#if 0
|
#if 0
|
||||||
UINT64 joybuttons = 0;
|
UINT64 joybuttons = 0;
|
||||||
#endif
|
|
||||||
Sint16 axisx, axisy;
|
Sint16 axisx, axisy;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!joystick_started) return;
|
if (!joystick_started) return;
|
||||||
|
|
||||||
|
@ -963,6 +963,7 @@ void I_GetJoystickEvents(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// send joystick axis positions
|
// send joystick axis positions
|
||||||
event.type = ev_joystick;
|
event.type = ev_joystick;
|
||||||
|
|
||||||
|
@ -1013,6 +1014,7 @@ void I_GetJoystickEvents(void)
|
||||||
}
|
}
|
||||||
D_PostEvent(&event);
|
D_PostEvent(&event);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Open joystick handle
|
/** \brief Open joystick handle
|
||||||
|
@ -1176,8 +1178,8 @@ void I_GetJoystick2Events(void)
|
||||||
UINT64 joyhats = 0;
|
UINT64 joyhats = 0;
|
||||||
#if 0
|
#if 0
|
||||||
INT64 joybuttons = 0;
|
INT64 joybuttons = 0;
|
||||||
#endif
|
|
||||||
INT32 axisx, axisy;
|
INT32 axisx, axisy;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!joystick2_started)
|
if (!joystick2_started)
|
||||||
return;
|
return;
|
||||||
|
@ -1247,6 +1249,7 @@ void I_GetJoystick2Events(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// send joystick axis positions
|
// send joystick axis positions
|
||||||
event.type = ev_joystick2;
|
event.type = ev_joystick2;
|
||||||
|
|
||||||
|
@ -1297,7 +1300,7 @@ void I_GetJoystick2Events(void)
|
||||||
}
|
}
|
||||||
D_PostEvent(&event);
|
D_PostEvent(&event);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Open joystick handle
|
/** \brief Open joystick handle
|
||||||
|
|
|
@ -767,6 +767,33 @@ static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt)
|
||||||
D_PostEvent(&event);
|
D_PostEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt)
|
||||||
|
{
|
||||||
|
event_t event;
|
||||||
|
SDL_JoystickID joyid[2];
|
||||||
|
|
||||||
|
// Determine the Joystick IDs for each current open joystick
|
||||||
|
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
|
||||||
|
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
|
||||||
|
|
||||||
|
if (evt.hat >= JOYHATS)
|
||||||
|
return; // ignore hats with too high an index
|
||||||
|
|
||||||
|
if (evt.which == joyid[0])
|
||||||
|
{
|
||||||
|
event.data1 = KEY_HAT1 + (evt.hat*4);
|
||||||
|
}
|
||||||
|
else if (evt.which == joyid[1])
|
||||||
|
{
|
||||||
|
event.data1 = KEY_2HAT1 + (evt.hat*4);
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
|
||||||
|
// NOTE: UNFINISHED
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
||||||
{
|
{
|
||||||
event_t event;
|
event_t event;
|
||||||
|
@ -804,6 +831,8 @@ static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
||||||
if (event.type != ev_console) D_PostEvent(&event);
|
if (event.type != ev_console) D_PostEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void I_GetEvent(void)
|
void I_GetEvent(void)
|
||||||
{
|
{
|
||||||
SDL_Event evt;
|
SDL_Event evt;
|
||||||
|
@ -844,6 +873,11 @@ void I_GetEvent(void)
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
Impl_HandleJoystickAxisEvent(evt.jaxis);
|
Impl_HandleJoystickAxisEvent(evt.jaxis);
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
case SDL_JOYHATMOTION:
|
||||||
|
Impl_HandleJoystickHatEvent(evt.jhat)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case SDL_JOYBUTTONUP:
|
case SDL_JOYBUTTONUP:
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_JOYBUTTONDOWN:
|
||||||
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
|
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.20;
|
CURRENT_PROJECT_VERSION = 2.1.21;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.20;
|
CURRENT_PROJECT_VERSION = 2.1.21;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.20;
|
CURRENT_PROJECT_VERSION = 2.1.21;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.20;
|
CURRENT_PROJECT_VERSION = 2.1.21;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -1871,12 +1871,12 @@ static void ST_overlayDrawer(void)
|
||||||
if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer)
|
if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer)
|
||||||
{
|
{
|
||||||
if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)
|
if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press Viewpoint Key to watch a player."));
|
||||||
else if (gametype == GT_HIDEANDSEEK &&
|
else if (gametype == GT_HIDEANDSEEK &&
|
||||||
(!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE))
|
(!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE))
|
||||||
{
|
{
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding."));
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press Viewpoint Key to watch a player."));
|
||||||
}
|
}
|
||||||
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
|
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
|
||||||
{
|
{
|
||||||
|
@ -1899,7 +1899,7 @@ static void ST_overlayDrawer(void)
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended."));
|
||||||
else
|
else
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game."));
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press F12 to watch another player."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press Viewpoint Key to watch a player."));
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
894
src/w_wad.c
894
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
|
#pragma interface
|
||||||
#endif
|
#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
|
// WAD FILE STRUCTURE DEFINITIONS
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
@ -34,14 +50,26 @@ typedef struct
|
||||||
UINT32 infotableofs; // the 'directory' of resources
|
UINT32 infotableofs; // the 'directory' of resources
|
||||||
} wadinfo_t;
|
} 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
|
// a memory entry of the wad directory
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned long position; // filelump_t filepos
|
unsigned long position; // filelump_t filepos
|
||||||
unsigned long disksize; // filelump_t size
|
unsigned long disksize; // filelump_t size
|
||||||
char name[9]; // filelump_t name[]
|
char name[9]; // filelump_t name[]
|
||||||
|
char *name2; // Used by PK3s. Dynamically allocated name.
|
||||||
size_t size; // real (uncompressed) size
|
size_t size; // real (uncompressed) size
|
||||||
INT32 compressed; // i
|
compmethod compression; // lump compression method
|
||||||
} lumpinfo_t;
|
} lumpinfo_t;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
@ -58,9 +86,21 @@ typedef struct
|
||||||
#include "m_aatree.h"
|
#include "m_aatree.h"
|
||||||
#endif
|
#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
|
typedef struct wadfile_s
|
||||||
{
|
{
|
||||||
char *filename;
|
char *filename;
|
||||||
|
restype_t type;
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
lumpcache_t *lumpcache;
|
lumpcache_t *lumpcache;
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
@ -86,7 +126,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
|
// 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);
|
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
|
// 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
|
#ifdef DELFILE
|
||||||
void W_UnloadWadFile(UINT16 num);
|
void W_UnloadWadFile(UINT16 num);
|
||||||
#endif
|
#endif
|
||||||
|
@ -99,6 +139,12 @@ const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
|
||||||
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
||||||
|
|
||||||
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
|
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_CheckNumForName(const char *name);
|
||||||
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
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);
|
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
|
||||||
|
@ -107,6 +153,12 @@ UINT8 W_LumpExists(const char *name); // Lua uses this.
|
||||||
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
|
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
|
||||||
size_t W_LumpLength(lumpnum_t lumpnum);
|
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_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
|
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);
|
void W_ReadLumpPwad(UINT16 wad, UINT16 lump, void *dest);
|
||||||
|
|
|
@ -132,6 +132,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\i_tcp.c" />
|
<ClCompile Include="..\i_tcp.c" />
|
||||||
<ClCompile Include="..\lua_baselib.c" />
|
<ClCompile Include="..\lua_baselib.c" />
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||||
<ClCompile Include="..\lua_consolelib.c" />
|
<ClCompile Include="..\lua_consolelib.c" />
|
||||||
<ClCompile Include="..\lua_hooklib.c" />
|
<ClCompile Include="..\lua_hooklib.c" />
|
||||||
<ClCompile Include="..\lua_hudlib.c" />
|
<ClCompile Include="..\lua_hudlib.c" />
|
||||||
|
|
|
@ -228,6 +228,9 @@
|
||||||
<ClCompile Include="..\lua_baselib.c">
|
<ClCompile Include="..\lua_baselib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c">
|
||||||
|
<Filter>LUA</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\lua_consolelib.c">
|
<ClCompile Include="..\lua_consolelib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -1796,37 +1796,6 @@ void Y_EndIntermission(void)
|
||||||
usebuffer = false;
|
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
|
// Y_FollowIntermission
|
||||||
//
|
//
|
||||||
|
@ -1838,21 +1807,10 @@ static void Y_FollowIntermission(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextmap < 1100-1)
|
// This handles whether to play a post-level cutscene, end the game,
|
||||||
{
|
// or simply go to the next level.
|
||||||
// normal level
|
// No need to duplicate the code here!
|
||||||
G_AfterIntermission();
|
G_AfterIntermission();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start a custom cutscene if there is one.
|
|
||||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking)
|
|
||||||
{
|
|
||||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Y_EndGame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
|
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
|
||||||
|
|
|
@ -15,7 +15,6 @@ void Y_IntermissionDrawer(void);
|
||||||
void Y_Ticker(void);
|
void Y_Ticker(void);
|
||||||
void Y_StartIntermission(void);
|
void Y_StartIntermission(void);
|
||||||
void Y_EndIntermission(void);
|
void Y_EndIntermission(void);
|
||||||
void Y_EndGame(void);
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
10
windows-installer/.gitignore
vendored
10
windows-installer/.gitignore
vendored
|
@ -1,10 +0,0 @@
|
||||||
*
|
|
||||||
*.*
|
|
||||||
!staging
|
|
||||||
!sfx
|
|
||||||
!uninstaller
|
|
||||||
!! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt
|
|
||||||
!BuildInstaller.bat
|
|
||||||
!README.txt
|
|
||||||
!VersionFileName.txt
|
|
||||||
!.gitignore
|
|
|
@ -1,76 +0,0 @@
|
||||||
@echo off
|
|
||||||
|
|
||||||
set "SCRIPTDIR=%~dp0"
|
|
||||||
set "SCRIPTDIR=%SCRIPTDIR:~0,-1%"
|
|
||||||
|
|
||||||
IF [%SRB2VERSIONNAME%] == [] set /p SRB2VERSIONNAME=<"%SCRIPTDIR%\VersionFileName.txt"
|
|
||||||
|
|
||||||
:: Find 7z
|
|
||||||
|
|
||||||
set SVZIP=
|
|
||||||
|
|
||||||
if NOT [%1] == [] (
|
|
||||||
echo.%~1 | findstr /C:"7z" 1>nul
|
|
||||||
if NOT errorlevel 1 (
|
|
||||||
if exist "%~1" set "SVZIP=%~1"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if ["%SVZIP%"] == [""] (
|
|
||||||
if exist "%ProgramFiles(x86)%\7-Zip\7z.exe" set "SVZIP=%ProgramFiles(x86)%\7-Zip\7z.exe"
|
|
||||||
if exist "%ProgramFiles%\7-Zip\7z.exe" set "SVZIP=%ProgramFiles%\7-Zip\7z.exe"
|
|
||||||
if exist "%ProgramW6432%\7-Zip\7z.exe" set "SVZIP=%ProgramW6432%\7-Zip\7z.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Is it in PATH?
|
|
||||||
|
|
||||||
if ["%SVZIP%"] == [""] (
|
|
||||||
"7z.exe" --help > NUL 2> NUL
|
|
||||||
if NOT errorlevel 1 (
|
|
||||||
set "SVZIP=7z.exe"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Create the uninstaller
|
|
||||||
|
|
||||||
if NOT ["%SVZIP%"] == [""] (
|
|
||||||
del /f /q "%SCRIPTDIR%\Uninstaller.7z" 2> NUL
|
|
||||||
"%SVZIP%" a -t7z "%SCRIPTDIR%\Uninstaller.7z" "%SCRIPTDIR%\uninstaller\*" -m5=LZMA2
|
|
||||||
copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-uninstaller.txt" + "%SCRIPTDIR%\Uninstaller.7z" "%SCRIPTDIR%\staging\new-install\uninstall.exe"
|
|
||||||
del /f /q "%SCRIPTDIR%\uninstaller.7z"
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Operate on install archives
|
|
||||||
|
|
||||||
type NUL > "%SCRIPTDIR%\staging\new-install\staging.txt"
|
|
||||||
|
|
||||||
if exist "%SCRIPTDIR%\Installer.7z" (
|
|
||||||
if NOT ["%SVZIP%"] == [""] (
|
|
||||||
"%SVZIP%" a "%SCRIPTDIR%\Installer.7z" "%SCRIPTDIR%\staging\*"
|
|
||||||
)
|
|
||||||
copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-installer.txt" + "%SCRIPTDIR%\Installer.7z" "%SCRIPTDIR%\SRB2-%SRB2VERSIONNAME%-Installer.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
if exist "%SCRIPTDIR%\Patch.7z" (
|
|
||||||
if NOT ["%SVZIP%"] == [""] (
|
|
||||||
"%SVZIP%" a "%SCRIPTDIR%\Patch.7z" "%SCRIPTDIR%\staging\*"
|
|
||||||
)
|
|
||||||
copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-patch.txt" + "%SCRIPTDIR%\Patch.7z" "%SCRIPTDIR%\SRB2-%SRB2VERSIONNAME%-Patch.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
if exist "%SCRIPTDIR%\Installer_x64.7z" (
|
|
||||||
if NOT ["%SVZIP%"] == [""] (
|
|
||||||
"%SVZIP%" a "%SCRIPTDIR%\Installer_x64.7z" "%SCRIPTDIR%\staging\*"
|
|
||||||
)
|
|
||||||
copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2_x64.sfx" + "%SCRIPTDIR%\sfx\config-installer.txt" + "%SCRIPTDIR%\Installer_x64.7z" "%SCRIPTDIR%\SRB2-%SRB2VERSIONNAME%-x64-Installer.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
if exist "%SCRIPTDIR%\Patch_x64.7z" (
|
|
||||||
if NOT ["%SVZIP%"] == [""] (
|
|
||||||
"%SVZIP%" a "%SCRIPTDIR%\Patch_x64.7z" "%SCRIPTDIR%\staging\*"
|
|
||||||
)
|
|
||||||
copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2_x64.sfx" + "%SCRIPTDIR%\sfx\config-patch.txt" + "%SCRIPTDIR%\Patch_x64.7z" "%SCRIPTDIR%\SRB2-%SRB2VERSIONNAME%-x64-Patch.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
del /f /q "%SCRIPTDIR%\staging\new-install\staging.txt"
|
|
||||||
del /f /q "%SCRIPTDIR%\staging\new-install\uninstall.exe"
|
|
|
@ -1,48 +0,0 @@
|
||||||
Windows Install Builder
|
|
||||||
for SRB2
|
|
||||||
|
|
||||||
This installer is much like the 7-Zip self-extracting archive, except
|
|
||||||
this allows for scripting the post-install step.
|
|
||||||
|
|
||||||
This also allows for some light customization, including dialog messages
|
|
||||||
and program shortcuts.
|
|
||||||
|
|
||||||
The included install scripts manage the game data location depending on the
|
|
||||||
install location -- if installed in Program Files or AppData\Local, the
|
|
||||||
game data location is set to %UserProfile%\SRB2.
|
|
||||||
|
|
||||||
Program shortcuts are also added, as well as an uninstaller that
|
|
||||||
will remove the icons and also selectively uninstall the core game files.
|
|
||||||
The uninstaller gives you the option to preserve your game data and mods.
|
|
||||||
|
|
||||||
How to Use
|
|
||||||
----------
|
|
||||||
|
|
||||||
1. Zip up the install contents in 7z format.
|
|
||||||
* ALL FILES MUST BE IN THE `new-install/` ARCHIVE SUBFOLDER, OR THE
|
|
||||||
POST-INSTALL SCRIPT WILL NOT WORK!
|
|
||||||
* Make sure you are using the LZMA2 algorithm, which is 7-Zip's default.
|
|
||||||
|
|
||||||
2. Copy the 7z archive to this folder using the following names:
|
|
||||||
* Installer.7z - 32-bit full installer
|
|
||||||
* Patch.7z - 32-bit patch
|
|
||||||
* Installer_x64.7z - 64-bit full installer
|
|
||||||
* Patch_x64.7z - 64-bit patch
|
|
||||||
|
|
||||||
3. Set the text in VersionFilename.txt to the version identifier for the
|
|
||||||
installer's filename.
|
|
||||||
* e.g., v2121 for v2.1.21, from "SRB2-v2121-Installer.exe"
|
|
||||||
* Also look through sfx/config-installer.txt and sfx/config-patch.txt
|
|
||||||
and update the version strings. Templating is TODO.
|
|
||||||
|
|
||||||
4. Run BuildInstaller.bat [7z.exe install path]
|
|
||||||
* First argument is the path to 7z.exe. If this is not specified, the
|
|
||||||
script will try to look for it in C:\Program Files [(x86)]
|
|
||||||
* This script will automatically add the install scripts to each
|
|
||||||
installer.
|
|
||||||
|
|
||||||
Credit
|
|
||||||
------
|
|
||||||
|
|
||||||
OlegScherbakov/7zSFX
|
|
||||||
https://github.com/OlegScherbakov/7zSFX
|
|
|
@ -1 +0,0 @@
|
||||||
v2121
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,24 +0,0 @@
|
||||||
;!@Install@!UTF-8!
|
|
||||||
|
|
||||||
GUIFlags="8+32+64+4096"
|
|
||||||
GUIMode="1"
|
|
||||||
|
|
||||||
Title="Sonic Robo Blast 2 v2.1.21"
|
|
||||||
BeginPrompt="Sonic Robo Blast 2 v2.1.21\nFull Installer\n\nSelect a folder to install SRB2 in.\n\nIf you install in \"AppData\\Local\" or \"Program Files\", your game data will be saved to:\n%UserProfile%\\SRB2\n\nOtherwise, your game data will be in the installation folder.\n\nShortcuts will be created in your Start Menu."
|
|
||||||
|
|
||||||
ExtractPathText="Installation folder: (no exclamation points, please!)"
|
|
||||||
InstallPath="%LocalAppData%\\SRB2"
|
|
||||||
ExtractTitle="Installing..."
|
|
||||||
ExtractDialogText="Installing SRB2 v2.1.21...\n\nCheck out our modding community!\nWe make levels, characters, and much more!\n\nVisit http://www.srb2.org/mods"
|
|
||||||
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{-win},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (Windowed)},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{-opengl},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (OpenGL)},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{-opengl -win},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (OpenGL, Windowed)},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2dd.exe},{},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (DirectDraw)},{%%T\\},{%%T\\srb2dd.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2dd.exe},{-win},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (DirectDraw, Windowed)},{%%T\\},{%%T\\srb2dd.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\uninstall.exe},{},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{Uninstall SRB2},{%%T\\},{shell32.dll},{31}"
|
|
||||||
|
|
||||||
RunProgram="nowait:\"%%T\\new-install\\staging.bat\""
|
|
||||||
|
|
||||||
;!@InstallEnd@!
|
|
|
@ -1,24 +0,0 @@
|
||||||
;!@Install@!UTF-8!
|
|
||||||
|
|
||||||
GUIFlags="8+32+64+4096"
|
|
||||||
GUIMode="1"
|
|
||||||
|
|
||||||
Title="Sonic Robo Blast 2 v2.1.21"
|
|
||||||
BeginPrompt="Sonic Robo Blast 2 v2.1.21\nPatch Installer\n\nYou must have at least v2.1.15 to use this patch.\n\nSelect your current SRB2 folder.\n\nShortcuts will be created in your Start Menu."
|
|
||||||
|
|
||||||
ExtractPathText="Current SRB2 folder: (no exclamation points, please!)"
|
|
||||||
InstallPath="%LocalAppData%\\SRB2"
|
|
||||||
ExtractTitle="Installing..."
|
|
||||||
ExtractDialogText="Installing SRB2 v2.1.21...\n\nCheck out our modding community!\nWe make levels, characters, and much more!\n\nVisit http://www.srb2.org/mods"
|
|
||||||
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{-win},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (Windowed)},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{-opengl},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (OpenGL)},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2win.exe},{-opengl -win},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (OpenGL, Windowed)},{%%T\\},{%%T\\srb2win.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2dd.exe},{},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (DirectDraw)},{%%T\\},{%%T\\srb2dd.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\srb2dd.exe},{-win},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{SRB2 (DirectDraw, Windowed)},{%%T\\},{%%T\\srb2dd.exe},{0}"
|
|
||||||
Shortcut="Pu,{%%T\\uninstall.exe},{},{Sonic Robo Blast 2},{Sonic Robo Blast 2 (SRB2), a 3D Sonic the Hedgehog fangame.},{Uninstall SRB2},{%%T\\},{shell32.dll},{31}"
|
|
||||||
|
|
||||||
RunProgram="nowait:\"%%T\\new-install\\staging.bat\""
|
|
||||||
|
|
||||||
;!@InstallEnd@!
|
|
|
@ -1,13 +0,0 @@
|
||||||
;!@Install@!UTF-8!
|
|
||||||
|
|
||||||
GUIFlags="1+2+8"
|
|
||||||
GUIMode="2"
|
|
||||||
|
|
||||||
Title="Uninstall SRB2"
|
|
||||||
BeginPrompt="Are you sure you want to uninstall Sonic Robo Blast 2?\n\nYour game data and mods will be preserved, as well as\nany extra files in your install folder."
|
|
||||||
|
|
||||||
InstallPath="%%S"
|
|
||||||
|
|
||||||
RunProgram="nowait:\"%%S\\uninstall.bat\" /y"
|
|
||||||
|
|
||||||
;!@InstallEnd@!
|
|
|
@ -1,11 +0,0 @@
|
||||||
SRB2 Install Instructions
|
|
||||||
|
|
||||||
1. Move every file from the "new-install" folder to this main install folder.
|
|
||||||
|
|
||||||
2. DELETE "staging.bat" and "staging.txt"! These can mess up your installation if run by accident!
|
|
||||||
|
|
||||||
3. Optionally, create a folder in your user profile named "SRB2". This is where your game data and addons may live. For example,
|
|
||||||
|
|
||||||
C:\Users\[User]\SRB2
|
|
||||||
|
|
||||||
4. Run the game! Double-click srb2win.exe -- or see if you have Start Menu icons under "Sonic Robo Blast 2".
|
|
|
@ -1,15 +0,0 @@
|
||||||
exchndl.dll
|
|
||||||
fmodex.dll
|
|
||||||
libFLAC-8.dll
|
|
||||||
libgme.dll
|
|
||||||
libintl-8.dll
|
|
||||||
libmikmod-2.dll
|
|
||||||
libogg-0.dll
|
|
||||||
libvorbis-0.dll
|
|
||||||
libvorbisfile-3.dll
|
|
||||||
r_opengl.dll
|
|
||||||
SDL2.dll
|
|
||||||
SDL2_mixer.dll
|
|
||||||
smpeg2.dll
|
|
||||||
srb2dd.exe
|
|
||||||
srb2win.exe
|
|
|
@ -1,363 +0,0 @@
|
||||||
@echo off
|
|
||||||
|
|
||||||
setlocal enabledelayedexpansion
|
|
||||||
|
|
||||||
cls
|
|
||||||
|
|
||||||
:: SRB2 Install Staging
|
|
||||||
::
|
|
||||||
:: This accomplishes the following tasks:
|
|
||||||
::
|
|
||||||
:: 1. Creates a user profile folder if SRB2 is installed in AppData or Program Files, and config.cfg is not already in the install folder
|
|
||||||
::
|
|
||||||
:: 2. Moves old installation files into old-install
|
|
||||||
::
|
|
||||||
:: 3. Moves new installaton files into install folder
|
|
||||||
::
|
|
||||||
|
|
||||||
:: Get Parent folder (the SRB2 install folder)
|
|
||||||
::
|
|
||||||
:: https://wiert.me/2011/08/30/batch-file-to-get-parent-directory-not-the-directory-of-the-batch-file-but-the-parent-of-that-directory/
|
|
||||||
|
|
||||||
set "STAGINGDIR=%~dp0"
|
|
||||||
:: strip trailing backslash
|
|
||||||
set "STAGINGDIR=!STAGINGDIR:~0,-1!"
|
|
||||||
:: ~dp only works for batch file parameters and loop indexes
|
|
||||||
for %%d in ("!STAGINGDIR!") do set "INSTALLDIR=%%~dpd"
|
|
||||||
set "INSTALLDIR=!INSTALLDIR:~0,-1!"
|
|
||||||
|
|
||||||
:: Find 7z
|
|
||||||
|
|
||||||
set SVZIP=
|
|
||||||
if ["%SVZIP%"] == [""] (
|
|
||||||
if exist "!ProgramFiles(x86)!\7-Zip\7z.exe" set "SVZIP=!ProgramFiles(x86)!\7-Zip\7z.exe"
|
|
||||||
if exist "!ProgramFiles!\7-Zip\7z.exe" set "SVZIP=!ProgramFiles!\7-Zip\7z.exe"
|
|
||||||
if exist "!ProgramW6432!\7-Zip\7z.exe" set "SVZIP=!ProgramW6432!\7-Zip\7z.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Is it in PATH?
|
|
||||||
|
|
||||||
if ["%SVZIP%"] == [""] (
|
|
||||||
"7z.exe" --help > NUL 2> NUL
|
|
||||||
if NOT errorlevel 1 (
|
|
||||||
set "SVZIP=7z.exe"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: FAILSAFE: Check if staging.txt exists in the directory
|
|
||||||
:: If not, exit, so we don't mess up anything by accident.
|
|
||||||
|
|
||||||
if NOT exist "!STAGINGDIR!\staging.txt" (
|
|
||||||
exit
|
|
||||||
)
|
|
||||||
|
|
||||||
: CheckPermissionsInstall
|
|
||||||
|
|
||||||
:: Write a dummy file and check for an error. If error, we need administrator rights
|
|
||||||
|
|
||||||
:: NOTE: We should never have to deal with this because the main installer should
|
|
||||||
:: already have the rights.
|
|
||||||
|
|
||||||
mkdir "!INSTALLDIR!\install-dummy"
|
|
||||||
|
|
||||||
:: TODO elevate automatically
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo Finish installing SRB2 with these steps:
|
|
||||||
echo.
|
|
||||||
echo 1. Go to your SRB2 install folder
|
|
||||||
echo.
|
|
||||||
echo !INSTALLDIR!
|
|
||||||
echo.
|
|
||||||
echo 2. Copy all files from the "new-install" subfolder into the main folder
|
|
||||||
echo and DELETE staging.bat and staging.txt!!!
|
|
||||||
echo.
|
|
||||||
echo 3. Optionally, create a folder in your user profile named "SRB2".
|
|
||||||
echo This is where your game data and addons may live.
|
|
||||||
echo To create the folder, go here:
|
|
||||||
echo.
|
|
||||||
echo !USERPROFILE!
|
|
||||||
echo.
|
|
||||||
echo If anything fails, you may delete the files and try to run the installer
|
|
||||||
echo again with Administrator Rights: Right-click on the icon and click
|
|
||||||
echo "Run as administrator."
|
|
||||||
echo.
|
|
||||||
"!SystemRoot!\explorer.exe" "!INSTALLDIR!"
|
|
||||||
set /p ADMINFINAL="Press Enter key to exit. "
|
|
||||||
|
|
||||||
exit
|
|
||||||
) else (
|
|
||||||
rmdir /s /q "!INSTALLDIR!\install-dummy"
|
|
||||||
goto CheckUserDir
|
|
||||||
)
|
|
||||||
|
|
||||||
: CheckUserDir
|
|
||||||
|
|
||||||
:: Check if we need to create !userprofile!\SRB2
|
|
||||||
|
|
||||||
set "USERDIR=!INSTALLDIR!"
|
|
||||||
|
|
||||||
:: Is config.cfg in our install dir?
|
|
||||||
if exist "!INSTALLDIR!\config.cfg" goto MoveOldInstall
|
|
||||||
|
|
||||||
:: Are we in AppData?
|
|
||||||
echo.!STAGINGDIR! | findstr /C:"!LocalAppData!" 1>nul
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo.
|
|
||||||
) else (
|
|
||||||
goto SetUserDir
|
|
||||||
)
|
|
||||||
|
|
||||||
: Are we in Program Files?
|
|
||||||
echo.!STAGINGDIR! | findstr /C:"!ProgramFiles!" 1>nul
|
|
||||||
if NOT errorlevel 1 (
|
|
||||||
goto SetUserDir
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Are we in Program Files (x86)?
|
|
||||||
echo.!STAGINGDIR! | findstr /C:"!ProgramFiles(X86)!" 1>nul
|
|
||||||
if NOT errorlevel 1 (
|
|
||||||
goto SetUserDir
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Are we 32-bit and actually in Program Files?
|
|
||||||
echo.!STAGINGDIR! | findstr /C:"!ProgramW6432!" 1>nul
|
|
||||||
if NOT errorlevel 1 (
|
|
||||||
goto SetUserDir
|
|
||||||
)
|
|
||||||
|
|
||||||
goto MoveOldInstall
|
|
||||||
|
|
||||||
: SetUserDir
|
|
||||||
: CheckPermissionsUserDir
|
|
||||||
|
|
||||||
set "USERDIR=!UserProfile!\SRB2"
|
|
||||||
|
|
||||||
:: Check for permissions and create the folder
|
|
||||||
if exist "!USERDIR!\*" (
|
|
||||||
mkdir "!USERDIR!\install-dummy"
|
|
||||||
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo User profile folder exists, but we won't operate on it.
|
|
||||||
echo.
|
|
||||||
goto MoveOldInstall
|
|
||||||
) else (
|
|
||||||
rmdir /s /q "!USERDIR!\install-dummy"
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
mkdir "!USERDIR!"
|
|
||||||
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo Could not create user profile folder
|
|
||||||
echo Defaulting to install dir: "!INSTALLDIR!"
|
|
||||||
echo.
|
|
||||||
set "USERDIR=!INSTALLDIR!"
|
|
||||||
goto MoveOldInstall
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Now copy READMEs
|
|
||||||
:: echo f answers xcopy's prompt as to whether the destination is a file or a folder
|
|
||||||
echo f | xcopy /y "!STAGINGDIR!\README.txt" "!USERDIR!\README.txt"
|
|
||||||
echo f | xcopy /y "!STAGINGDIR!\LICENSE.txt" "!USERDIR!\LICENSE.txt"
|
|
||||||
echo f | xcopy /y "!STAGINGDIR!\LICENSE-3RD-PARTY.txt" "!USERDIR!\LICENSE-3RD-PARTY.txt"
|
|
||||||
echo Your game data and mods folder is: > "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo !USERDIR! >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo Your install folder is: >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo !INSTALLDIR! >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo To run SRB2, go to: >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
echo Start Menu ^> Programs ^> Sonic Robo Blast 2 >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
|
|
||||||
|
|
||||||
:: Copy path to install folder
|
|
||||||
|
|
||||||
set "SCRIPT=!TEMP!\!RANDOM!-!RANDOM!-!RANDOM!-!RANDOM!.vbs"
|
|
||||||
echo Set oWS = WScript.CreateObject("WScript.Shell") >> "!SCRIPT!"
|
|
||||||
echo sLinkFile = "!USERDIR!\^! SRB2 Install Folder ^!.lnk" >> "!SCRIPT!"
|
|
||||||
echo Set oLink = oWS.CreateShortcut(sLinkFile) >> "!SCRIPT!"
|
|
||||||
echo oLink.TargetPath = "!INSTALLDIR!" >> "!SCRIPT!"
|
|
||||||
echo oLink.WorkingDirectory = "!INSTALLDIR!" >> "!SCRIPT!"
|
|
||||||
echo oLink.Arguments = "" >> "!SCRIPT!"
|
|
||||||
echo oLink.IconLocation = "!INSTALLDIR!\srb2win.exe,0" >> "!SCRIPT!"
|
|
||||||
echo oLink.Save >> "!SCRIPT!"
|
|
||||||
cscript /nologo "!SCRIPT!"
|
|
||||||
del "!SCRIPT!"
|
|
||||||
|
|
||||||
:: Also do it the other way around
|
|
||||||
|
|
||||||
set "SCRIPT=!TEMP!\!RANDOM!-!RANDOM!-!RANDOM!-!RANDOM!.vbs"
|
|
||||||
echo Set oWS = WScript.CreateObject("WScript.Shell") >> "!SCRIPT!"
|
|
||||||
echo sLinkFile = "!INSTALLDIR!\^! SRB2 Data Folder ^!.lnk" >> "!SCRIPT!"
|
|
||||||
echo Set oLink = oWS.CreateShortcut(sLinkFile) >> "!SCRIPT!"
|
|
||||||
echo oLink.TargetPath = "!USERDIR!" >> "!SCRIPT!"
|
|
||||||
echo oLink.WorkingDirectory = "!USERDIR!" >> "!SCRIPT!"
|
|
||||||
echo oLink.Arguments = "" >> "!SCRIPT!"
|
|
||||||
echo oLink.IconLocation = "!INSTALLDIR!\srb2win.exe,0" >> "!SCRIPT!"
|
|
||||||
echo oLink.Save >> "!SCRIPT!"
|
|
||||||
cscript /nologo "!SCRIPT!"
|
|
||||||
del "!SCRIPT!"
|
|
||||||
|
|
||||||
: MoveOldInstall
|
|
||||||
|
|
||||||
if exist "!INSTALLDIR!\old-install\*" (
|
|
||||||
set "OLDINSTALLDIR=!INSTALLDIR!\old-install-!RANDOM!"
|
|
||||||
) else (
|
|
||||||
set "OLDINSTALLDIR=!INSTALLDIR!\old-install"
|
|
||||||
)
|
|
||||||
|
|
||||||
mkdir "!OLDINSTALLDIR!"
|
|
||||||
|
|
||||||
::
|
|
||||||
:: Move all old install files
|
|
||||||
:: We support a list of explicit files to copy to old-install
|
|
||||||
:: And later, we also loop through our staging files, look for the pre-existing copy in
|
|
||||||
:: install root, then copy that also to old-install
|
|
||||||
::
|
|
||||||
|
|
||||||
:: Extract the uninstall-list.txt and uninstall-userdir.txt files from uninstaller.exe
|
|
||||||
:: if it exists
|
|
||||||
|
|
||||||
if exist "!INSTALLDIR!\uninstall.exe" (
|
|
||||||
if NOT ["!SVZIP!"] == [""] (
|
|
||||||
"!SVZIP!" x "!INSTALLDIR!\uninstall.exe" "uninstall-list.txt" -o"!INSTALLDIR!"
|
|
||||||
"!SVZIP!" x "!INSTALLDIR!\uninstall.exe" "uninstall-userdir.txt" -o"!INSTALLDIR!"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
set OLDINSTALLCHANGED=
|
|
||||||
|
|
||||||
if exist "!STAGINGDIR!\old-install-list.txt" (
|
|
||||||
goto MoveOldInstallOldFiles
|
|
||||||
) else (
|
|
||||||
goto MoveOldInstallNewFiles
|
|
||||||
)
|
|
||||||
|
|
||||||
: MoveOldInstallOldFiles
|
|
||||||
|
|
||||||
set "TESTFILE=!TEMP!\!RANDOM!.txt"
|
|
||||||
|
|
||||||
:: Do our failsafes before copying the file in the list
|
|
||||||
:: See uninstall.bat for details
|
|
||||||
for /F "usebackq tokens=*" %%A in ("!STAGINGDIR!\old-install-list.txt") do (
|
|
||||||
if exist "!INSTALLDIR!\%%A" (
|
|
||||||
if NOT ["%%A"] == [""] (
|
|
||||||
if NOT ["%%A"] == ["%~nx0"] (
|
|
||||||
echo %%A> "!TESTFILE!"
|
|
||||||
findstr /r ".*[<>:\"\"/\\|?*%%].*" "!TESTFILE!" >nul
|
|
||||||
if !errorlevel! equ 0 (
|
|
||||||
echo %%A has invalid characters, skipping...
|
|
||||||
) else (
|
|
||||||
if exist "!INSTALLDIR!\%%A\*" (
|
|
||||||
echo %%A is a folder, skipping...
|
|
||||||
) else (
|
|
||||||
echo Moving !INSTALLDIR!\%%A to "old-install" folder
|
|
||||||
echo f | xcopy /y /v "!INSTALLDIR!\%%A" "!OLDINSTALLDIR!\%%A"
|
|
||||||
if errorlevel 0 del /f /q "!INSTALLDIR!\%%A"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
del /q /f "!STAGINGDIR!\old-install-list.txt"
|
|
||||||
|
|
||||||
for %%F in ("!OLDINSTALLDIR!\*") DO (
|
|
||||||
set OLDINSTALLCHANGED=1
|
|
||||||
goto MoveOldInstallNewFiles
|
|
||||||
)
|
|
||||||
|
|
||||||
: MoveOldInstallNewFiles
|
|
||||||
|
|
||||||
:: Save a list of standard files
|
|
||||||
:: So the uninstall script will know what to remove
|
|
||||||
:: Append to any existing file, in case we are a patch
|
|
||||||
|
|
||||||
dir /b /a-d "!STAGINGDIR!" >> "!INSTALLDIR!\uninstall-list.txt"
|
|
||||||
|
|
||||||
:: Overwrite the last known gamedata folder
|
|
||||||
|
|
||||||
echo !USERDIR! > "!INSTALLDIR!\uninstall-userdir.txt"
|
|
||||||
|
|
||||||
:: Add the install-generated to the uninstall list
|
|
||||||
:: NO FOLLOWING SPACES AFTER THE FILENAME!!!
|
|
||||||
|
|
||||||
echo uninstall.bat>> "!INSTALLDIR!\uninstall-list.txt"
|
|
||||||
echo uninstall-list.txt>> "!INSTALLDIR!\uninstall-list.txt"
|
|
||||||
echo uninstall-userdir.txt>> "!INSTALLDIR!\uninstall-list.txt"
|
|
||||||
:: *ahem* Prints as ^! SRB2 Data Folder ^!.lnk
|
|
||||||
:: We need to escape the exclamations (^^!) and the carets themselves (^^^^)
|
|
||||||
echo ^^^^^^! SRB2 Data Folder ^^^^^^!.lnk>> "!INSTALLDIR!\uninstall-list.txt"
|
|
||||||
|
|
||||||
:: Add the uninstall list files to the uninstall EXE
|
|
||||||
|
|
||||||
if NOT ["!SVZIP!"] == [""] (
|
|
||||||
if exist "!INSTALLDIR!\new-install\uninstall.exe" (
|
|
||||||
"!SVZIP!" a "!INSTALLDIR!\new-install\uninstall.exe" "!INSTALLDIR!\uninstall-list.txt" -sdel
|
|
||||||
"!SVZIP!" a "!INSTALLDIR!\new-install\uninstall.exe" "!INSTALLDIR!\uninstall-userdir.txt" -sdel
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Start moving files
|
|
||||||
|
|
||||||
for %%F in ("!STAGINGDIR!\*") DO (
|
|
||||||
if exist "!INSTALLDIR!\%%~nxF" (
|
|
||||||
set OLDINSTALLCHANGED=1
|
|
||||||
move "!INSTALLDIR!\%%~nxF" "!OLDINSTALLDIR!\%%~nxF"
|
|
||||||
)
|
|
||||||
if NOT ["%%~nxF"] == ["staging.bat"] (
|
|
||||||
if NOT ["%%~nxF"] == ["staging.txt"] (
|
|
||||||
move "!STAGINGDIR!\%%~nxF" "!INSTALLDIR!\%%~nxF"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
: Finished
|
|
||||||
|
|
||||||
del /q /f "!INSTALLDIR!\^! SRB2 INSTALL INSTRUCTIONS ^!.txt"
|
|
||||||
|
|
||||||
set MSGEXE=
|
|
||||||
if exist "!SystemRoot!\System32\msg.exe" (
|
|
||||||
set MSGEXE=!SystemRoot!\System32\msg.exe
|
|
||||||
) else (
|
|
||||||
if exist "!SystemRoot!\Sysnative\msg.exe" (
|
|
||||||
set MSGEXE=!SystemRoot!\Sysnative\msg.exe
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if ["!OLDINSTALLCHANGED!"] == ["1"] (
|
|
||||||
"!systemroot!\explorer.exe" /select, "!OLDINSTALLDIR!"
|
|
||||||
echo Finished^^! Some of your old installation files were moved to the "old-install" folder. > !TEMP!\srb2msgprompt.txt
|
|
||||||
echo. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo If you no longer need these files, you may delete the folder safely. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo To run SRB2, go to: Start Menu ^> Programs ^> Sonic Robo Blast 2. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
!MSGEXE! "!username!" < !TEMP!\srb2msgprompt.txt
|
|
||||||
del !TEMP!\srb2msgprompt.txt
|
|
||||||
) else (
|
|
||||||
if /I ["!USERDIR!"] == ["!INSTALLDIR!"] (
|
|
||||||
"!systemroot!\explorer.exe" "!INSTALLDIR!"
|
|
||||||
echo Finished^^! > !TEMP!\srb2msgprompt.txt
|
|
||||||
echo. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo To run SRB2, go to: Start Menu ^> Programs ^> Sonic Robo Blast 2. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
!MSGEXE! "!username!" < !TEMP!\srb2msgprompt.txt
|
|
||||||
del !TEMP!\srb2msgprompt.txt
|
|
||||||
) else (
|
|
||||||
"!systemroot!\explorer.exe" "!USERDIR!"
|
|
||||||
echo Finished^^! You may find your game data in this folder: > !TEMP!\srb2msgprompt.txt
|
|
||||||
echo. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo !USERDIR! >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
echo To run SRB2, go to: Start Menu ^> Programs ^> Sonic Robo Blast 2. >> !TEMP!\srb2msgprompt.txt
|
|
||||||
!MSGEXE! "!username!" < !TEMP!\srb2msgprompt.txt
|
|
||||||
del !TEMP!\srb2msgprompt.txt
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
: Attempt to remove OLDINSTALLDIR, in case it's empty
|
|
||||||
rmdir /q "!OLDINSTALLDIR!"
|
|
||||||
cd \
|
|
||||||
start "" /b "cmd" /s /c " del /f /q "%STAGINGDIR%\*"&rmdir /s /q "%STAGINGDIR%"&exit /b "
|
|
|
@ -1,183 +0,0 @@
|
||||||
@echo off
|
|
||||||
|
|
||||||
setlocal enabledelayedexpansion
|
|
||||||
|
|
||||||
cls
|
|
||||||
|
|
||||||
set "INSTALLDIR=%~dp0"
|
|
||||||
set "INSTALLDIR=!INSTALLDIR:~0,-1!"
|
|
||||||
set /p USERDIR=<"!INSTALLDIR!\uninstall-userdir.txt"
|
|
||||||
set "USERDIR=!USERDIR:~0,-1!"
|
|
||||||
|
|
||||||
: ProceedPrompt
|
|
||||||
|
|
||||||
if ["%1"] == ["/y"] (
|
|
||||||
set "PROCEED=1"
|
|
||||||
) else (
|
|
||||||
set PROCEED=
|
|
||||||
set /p PROCEED="Are you sure you want to uninstall SRB2? [yes/no] "
|
|
||||||
|
|
||||||
if /I ["!PROCEED:~0,1!"] == ["n"] exit
|
|
||||||
if /I ["!PROCEED!"] == ["y"] (
|
|
||||||
echo Type Yes or No
|
|
||||||
echo.
|
|
||||||
goto ProceedPrompt
|
|
||||||
) else (
|
|
||||||
if /I ["!PROCEED!"] == ["yes"] (
|
|
||||||
set PROCEED=1
|
|
||||||
) else (
|
|
||||||
echo.
|
|
||||||
goto ProceedPrompt
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Failsafe, in case we Ctrl+C and decline "Terminate batch file?"
|
|
||||||
|
|
||||||
if NOT ["!PROCEED!"] == ["1"] (
|
|
||||||
exit
|
|
||||||
)
|
|
||||||
|
|
||||||
: CheckPermissions
|
|
||||||
|
|
||||||
:: Write a dummy file and check for an error. If error, we need administrator rights
|
|
||||||
|
|
||||||
mkdir "!INSTALLDIR!\uninstall-dummy"
|
|
||||||
|
|
||||||
:: TODO elevate automatically
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo We need Administrator Rights to uninstall SRB2.
|
|
||||||
echo.
|
|
||||||
echo Try running this uninstaller by right-clicking on the icon
|
|
||||||
echo and click "Run as administrator"
|
|
||||||
echo.
|
|
||||||
set /p ADMINFINAL="Press Enter key to exit. "
|
|
||||||
exit
|
|
||||||
) else (
|
|
||||||
rmdir /s /q "!INSTALLDIR!\uninstall-dummy"
|
|
||||||
goto DeleteFiles
|
|
||||||
)
|
|
||||||
|
|
||||||
: DeleteFiles
|
|
||||||
|
|
||||||
:: Our deletion list is a list of filenames, no paths, in the current folder
|
|
||||||
::
|
|
||||||
:: We apply the following failsafes:
|
|
||||||
:: 1. Is filename the script itself?
|
|
||||||
:: 2. Does filename have illegal characters? https://stackoverflow.com/a/33625339/241046
|
|
||||||
:: 3. Is filename a directory?
|
|
||||||
::
|
|
||||||
:: TODO hack this to support .\file.txt relative paths
|
|
||||||
:: Can %%A be substring'd to get only the filename and extension?
|
|
||||||
:: If so, print that to the temp file instead of the whole line
|
|
||||||
:: And possibly do the folder check before the invalid char check.
|
|
||||||
:: ALSO: Don't honor upward relative paths! (..\)
|
|
||||||
::
|
|
||||||
set "TESTFILE=!TEMP!\!RANDOM!.txt"
|
|
||||||
|
|
||||||
for /F "usebackq tokens=*" %%A in ("!INSTALLDIR!\uninstall-list.txt") do (
|
|
||||||
if exist "!INSTALLDIR!\%%A" (
|
|
||||||
if NOT ["%%A"] == [""] (
|
|
||||||
if NOT ["%%A"] == ["%~nx0"] (
|
|
||||||
echo %%A> "!TESTFILE!"
|
|
||||||
findstr /r ".*[<>:\"\"/\\|?*%%].*" "!TESTFILE!" >nul
|
|
||||||
if !errorlevel! equ 0 (
|
|
||||||
echo %%A has invalid characters, skipping...
|
|
||||||
) else (
|
|
||||||
if exist "!INSTALLDIR!\%%A\*" (
|
|
||||||
echo %%A is a folder, skipping...
|
|
||||||
) else (
|
|
||||||
echo Deleting !INSTALLDIR!\%%A
|
|
||||||
del /q /f "!INSTALLDIR!\%%A"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
del /q /f "!TESTFILE!"
|
|
||||||
|
|
||||||
: AllDone
|
|
||||||
|
|
||||||
:: Delete the program icons
|
|
||||||
echo Deleting your program icons...
|
|
||||||
echo.
|
|
||||||
|
|
||||||
cd \
|
|
||||||
rmdir /s /q "!AppData!\Microsoft\Windows\Start Menu\Programs\Sonic Robo Blast 2"
|
|
||||||
|
|
||||||
:: Check if our install folder is non-empty
|
|
||||||
|
|
||||||
set USERDIRFILLED=
|
|
||||||
set INSTALLDIRFILLED=
|
|
||||||
for /F %%i in ('dir /b /a "!USERDIR!\*"') do (
|
|
||||||
if NOT ["%%i"] == ["%~nx0"] (
|
|
||||||
set USERDIRFILLED=1
|
|
||||||
goto InstallFilledCheck
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
: InstallFilledCheck
|
|
||||||
|
|
||||||
if /I NOT ["!USERDIR!"] == ["!INSTALLDIR!"] (
|
|
||||||
for /F %%i in ('dir /b /a "!INSTALLDIR!\*"') do (
|
|
||||||
if ["%%i"] == ["%~nx0"] (
|
|
||||||
echo.
|
|
||||||
) else (
|
|
||||||
set INSTALLDIRFILLED=1
|
|
||||||
goto Final
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
: Final
|
|
||||||
|
|
||||||
echo All done^^! Visit http://www.srb2.org if you want to play SRB2 again^^!
|
|
||||||
echo.
|
|
||||||
|
|
||||||
set "FINALPROMPT=Press Enter key to exit."
|
|
||||||
if ["!USERDIRFILLED!"] == ["1"] (
|
|
||||||
echo We left your game data and mods alone, so you may delete those manually.
|
|
||||||
echo.
|
|
||||||
echo !USERDIR!
|
|
||||||
echo.
|
|
||||||
set "FINALPROMPT=Do you want to view your data? [yes/no]"
|
|
||||||
)
|
|
||||||
|
|
||||||
if ["!INSTALLDIRFILLED!"] == ["1"] (
|
|
||||||
echo We left some extra files alone in your install folder.
|
|
||||||
echo.
|
|
||||||
echo !INSTALLDIR!
|
|
||||||
echo.
|
|
||||||
set "FINALPROMPT=Do you want to view your data? [yes/no]"
|
|
||||||
)
|
|
||||||
|
|
||||||
set FINALRESPONSE=
|
|
||||||
set /p FINALRESPONSE="!FINALPROMPT! "
|
|
||||||
|
|
||||||
if NOT ["!FINALPROMPT!"] == ["Press Enter key to exit."] (
|
|
||||||
if /I ["!FINALRESPONSE:~0,1!"] == ["y"] (
|
|
||||||
if ["!USERDIRFILLED!"] == ["1"] (
|
|
||||||
"!SystemRoot!\explorer.exe" "!USERDIR!"
|
|
||||||
)
|
|
||||||
if ["!INSTALLDIRFILLED!"] == ["1"] (
|
|
||||||
"!SystemRoot!\explorer.exe" "!INSTALLDIR!"
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
if ["!FINALRESPONSE!"] == [""] (
|
|
||||||
if ["!USERDIRFILLED!"] == ["1"] (
|
|
||||||
"!SystemRoot!\explorer.exe" "!USERDIR!"
|
|
||||||
)
|
|
||||||
if ["!INSTALLDIRFILLED!"] == ["1"] (
|
|
||||||
"!SystemRoot!\explorer.exe" "!INSTALLDIR!"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
: DeferredDelete
|
|
||||||
|
|
||||||
:: Now let's delete our installation folder!
|
|
||||||
cd \
|
|
||||||
start "" /b "cmd" /s /c " del /q /f "%INSTALLDIR%\uninstall.bat"&timeout /t 2 > NUL&rmdir "%INSTALLDIR%"&exit /b "
|
|
Loading…
Reference in a new issue