mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-18 14:02:51 +00:00
Merge master
Slopes in a few maps are really broken ... think it's anchors, I'm gonna leave that to jart :V
This commit is contained in:
commit
b5fcd74ef9
63 changed files with 3395 additions and 1163 deletions
23
cmake/Modules/FindDiscordRPC.cmake
Normal file
23
cmake/Modules/FindDiscordRPC.cmake
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
include(LibFindMacros)
|
||||||
|
|
||||||
|
libfind_pkg_check_modules(DISCORDRPC_PKGCONF DISCORDRPC)
|
||||||
|
|
||||||
|
find_path(DISCORDRPC_INCLUDE_DIR
|
||||||
|
NAMES discord_rpc.h
|
||||||
|
PATHS
|
||||||
|
${DISCORDRPC_PKGCONF_INCLUDE_DIRS}
|
||||||
|
"/usr/include"
|
||||||
|
"/usr/local/include"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(DISCORDRPC_LIBRARY
|
||||||
|
NAMES discord-rpc
|
||||||
|
PATHS
|
||||||
|
${DISCORDRPC_PKGCONF_LIBRARY_DIRS}
|
||||||
|
"/usr/lib"
|
||||||
|
"/usr/local/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(DISCORDRPC_PROCESS_INCLUDES DISCORDRPC_INCLUDE_DIR)
|
||||||
|
set(DISCORDRPC_PROCESS_LIBS DISCORDRPC_LIBRARY)
|
||||||
|
libfind_process(DISCORDRPC)
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# SRB2Kart - Which DLLs do I need to bundle?
|
# SRB2Kart - Which DLLs do I need to bundle?
|
||||||
|
|
||||||
Updated 12/6/2019 (v2.2)
|
Updated 8/23/2020 (v1.3)
|
||||||
|
|
||||||
Here are the required DLLs, per build. For each architecture, copy all the binaries from these folders:
|
Here are the required DLLs, per build. For each architecture, copy all the binaries from these folders:
|
||||||
|
|
||||||
|
|
@ -15,6 +15,7 @@ and don't forget to build r_opengl.dll for srb2dd.
|
||||||
|
|
||||||
* libs\dll-binaries\i686\exchndl.dll
|
* libs\dll-binaries\i686\exchndl.dll
|
||||||
* libs\dll-binaries\i686\libgme.dll
|
* libs\dll-binaries\i686\libgme.dll
|
||||||
|
* libs\dll-binaries\i686\discord-rpc.dll
|
||||||
* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll)
|
* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll)
|
||||||
* libs\SDL2\i686-w64-mingw32\bin\SDL2.dll
|
* libs\SDL2\i686-w64-mingw32\bin\SDL2.dll
|
||||||
* libs\SDL2mixerX\i686-w64-mingw32\bin\*.dll (get everything)
|
* libs\SDL2mixerX\i686-w64-mingw32\bin\*.dll (get everything)
|
||||||
|
|
@ -24,27 +25,8 @@ and don't forget to build r_opengl.dll for srb2dd.
|
||||||
|
|
||||||
* libs\dll-binaries\x86_64\exchndl.dll
|
* libs\dll-binaries\x86_64\exchndl.dll
|
||||||
* libs\dll-binaries\x86_64\libgme.dll
|
* libs\dll-binaries\x86_64\libgme.dll
|
||||||
|
* libs\dll-binaries\x86_64\discord-rpc.dll
|
||||||
* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll)
|
* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll)
|
||||||
* libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll
|
* libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll
|
||||||
<<<<<<< HEAD
|
|
||||||
* libs\SDL2_mixer\x86_64-w64-mingw32\bin\*.dll (get everything)
|
|
||||||
|
|
||||||
## srb2kartdd, 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)
|
|
||||||
|
|
||||||
## srb2kartdd, 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)
|
|
||||||
=======
|
|
||||||
* libs\SDL2mixerX\x86_64-w64-mingw32\bin\*.dll (get everything)
|
* libs\SDL2mixerX\x86_64-w64-mingw32\bin\*.dll (get everything)
|
||||||
* libs\libopenmpt\x86_64\bin\mingw\libopenmpt.dll
|
* libs\libopenmpt\x86_64\bin\mingw\libopenmpt.dll
|
||||||
>>>>>>> srb2/next
|
|
||||||
|
|
|
||||||
16
libs/discord-rpc.props
Normal file
16
libs/discord-rpc.props
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Label="PropertySheets" />
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<LibraryPath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\discord-rpc\win32-dynamic\lib;$(LibraryPath)</LibraryPath>
|
||||||
|
<IncludePath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\discord-rpc\win32-dynamic\lib;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\discord-rpc\win64-dynamic\lib;$(LibraryPath)</LibraryPath>
|
||||||
|
<IncludePath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\discord-rpc\win64-dynamic\lib;$(IncludePath)</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>discord-rpc.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
||||||
26
libs/discord-rpc/win32-dynamic/include/discord_register.h
Normal file
26
libs/discord-rpc/win32-dynamic/include/discord_register.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(DISCORD_DYNAMIC_LIB)
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(DISCORD_BUILDING_SDK)
|
||||||
|
#define DISCORD_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define DISCORD_EXPORT __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DISCORD_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command);
|
||||||
|
DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
87
libs/discord-rpc/win32-dynamic/include/discord_rpc.h
Normal file
87
libs/discord-rpc/win32-dynamic/include/discord_rpc.h
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#if defined(DISCORD_DYNAMIC_LIB)
|
||||||
|
# if defined(_WIN32)
|
||||||
|
# if defined(DISCORD_BUILDING_SDK)
|
||||||
|
# define DISCORD_EXPORT __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define DISCORD_EXPORT __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define DISCORD_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct DiscordRichPresence {
|
||||||
|
const char* state; /* max 128 bytes */
|
||||||
|
const char* details; /* max 128 bytes */
|
||||||
|
int64_t startTimestamp;
|
||||||
|
int64_t endTimestamp;
|
||||||
|
const char* largeImageKey; /* max 32 bytes */
|
||||||
|
const char* largeImageText; /* max 128 bytes */
|
||||||
|
const char* smallImageKey; /* max 32 bytes */
|
||||||
|
const char* smallImageText; /* max 128 bytes */
|
||||||
|
const char* partyId; /* max 128 bytes */
|
||||||
|
int partySize;
|
||||||
|
int partyMax;
|
||||||
|
const char* matchSecret; /* max 128 bytes */
|
||||||
|
const char* joinSecret; /* max 128 bytes */
|
||||||
|
const char* spectateSecret; /* max 128 bytes */
|
||||||
|
int8_t instance;
|
||||||
|
} DiscordRichPresence;
|
||||||
|
|
||||||
|
typedef struct DiscordUser {
|
||||||
|
const char* userId;
|
||||||
|
const char* username;
|
||||||
|
const char* discriminator;
|
||||||
|
const char* avatar;
|
||||||
|
} DiscordUser;
|
||||||
|
|
||||||
|
typedef struct DiscordEventHandlers {
|
||||||
|
void (*ready)(const DiscordUser* request);
|
||||||
|
void (*disconnected)(int errorCode, const char* message);
|
||||||
|
void (*errored)(int errorCode, const char* message);
|
||||||
|
void (*joinGame)(const char* joinSecret);
|
||||||
|
void (*spectateGame)(const char* spectateSecret);
|
||||||
|
void (*joinRequest)(const DiscordUser* request);
|
||||||
|
} DiscordEventHandlers;
|
||||||
|
|
||||||
|
#define DISCORD_REPLY_NO 0
|
||||||
|
#define DISCORD_REPLY_YES 1
|
||||||
|
#define DISCORD_REPLY_IGNORE 2
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||||
|
DiscordEventHandlers* handlers,
|
||||||
|
int autoRegister,
|
||||||
|
const char* optionalSteamId);
|
||||||
|
DISCORD_EXPORT void Discord_Shutdown(void);
|
||||||
|
|
||||||
|
/* checks for incoming messages, dispatches callbacks */
|
||||||
|
DISCORD_EXPORT void Discord_RunCallbacks(void);
|
||||||
|
|
||||||
|
/* If you disable the lib starting its own io thread, you'll need to call this from your own */
|
||||||
|
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||||
|
DISCORD_EXPORT void Discord_UpdateConnection(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
||||||
|
DISCORD_EXPORT void Discord_ClearPresence(void);
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply);
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
BIN
libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib
Normal file
BIN
libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib
Normal file
Binary file not shown.
26
libs/discord-rpc/win64-dynamic/include/discord_register.h
Normal file
26
libs/discord-rpc/win64-dynamic/include/discord_register.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(DISCORD_DYNAMIC_LIB)
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(DISCORD_BUILDING_SDK)
|
||||||
|
#define DISCORD_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define DISCORD_EXPORT __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DISCORD_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command);
|
||||||
|
DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
87
libs/discord-rpc/win64-dynamic/include/discord_rpc.h
Normal file
87
libs/discord-rpc/win64-dynamic/include/discord_rpc.h
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#if defined(DISCORD_DYNAMIC_LIB)
|
||||||
|
# if defined(_WIN32)
|
||||||
|
# if defined(DISCORD_BUILDING_SDK)
|
||||||
|
# define DISCORD_EXPORT __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define DISCORD_EXPORT __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define DISCORD_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct DiscordRichPresence {
|
||||||
|
const char* state; /* max 128 bytes */
|
||||||
|
const char* details; /* max 128 bytes */
|
||||||
|
int64_t startTimestamp;
|
||||||
|
int64_t endTimestamp;
|
||||||
|
const char* largeImageKey; /* max 32 bytes */
|
||||||
|
const char* largeImageText; /* max 128 bytes */
|
||||||
|
const char* smallImageKey; /* max 32 bytes */
|
||||||
|
const char* smallImageText; /* max 128 bytes */
|
||||||
|
const char* partyId; /* max 128 bytes */
|
||||||
|
int partySize;
|
||||||
|
int partyMax;
|
||||||
|
const char* matchSecret; /* max 128 bytes */
|
||||||
|
const char* joinSecret; /* max 128 bytes */
|
||||||
|
const char* spectateSecret; /* max 128 bytes */
|
||||||
|
int8_t instance;
|
||||||
|
} DiscordRichPresence;
|
||||||
|
|
||||||
|
typedef struct DiscordUser {
|
||||||
|
const char* userId;
|
||||||
|
const char* username;
|
||||||
|
const char* discriminator;
|
||||||
|
const char* avatar;
|
||||||
|
} DiscordUser;
|
||||||
|
|
||||||
|
typedef struct DiscordEventHandlers {
|
||||||
|
void (*ready)(const DiscordUser* request);
|
||||||
|
void (*disconnected)(int errorCode, const char* message);
|
||||||
|
void (*errored)(int errorCode, const char* message);
|
||||||
|
void (*joinGame)(const char* joinSecret);
|
||||||
|
void (*spectateGame)(const char* spectateSecret);
|
||||||
|
void (*joinRequest)(const DiscordUser* request);
|
||||||
|
} DiscordEventHandlers;
|
||||||
|
|
||||||
|
#define DISCORD_REPLY_NO 0
|
||||||
|
#define DISCORD_REPLY_YES 1
|
||||||
|
#define DISCORD_REPLY_IGNORE 2
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||||
|
DiscordEventHandlers* handlers,
|
||||||
|
int autoRegister,
|
||||||
|
const char* optionalSteamId);
|
||||||
|
DISCORD_EXPORT void Discord_Shutdown(void);
|
||||||
|
|
||||||
|
/* checks for incoming messages, dispatches callbacks */
|
||||||
|
DISCORD_EXPORT void Discord_RunCallbacks(void);
|
||||||
|
|
||||||
|
/* If you disable the lib starting its own io thread, you'll need to call this from your own */
|
||||||
|
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||||
|
DISCORD_EXPORT void Discord_UpdateConnection(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
||||||
|
DISCORD_EXPORT void Discord_ClearPresence(void);
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply);
|
||||||
|
|
||||||
|
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
BIN
libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib
Normal file
BIN
libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib
Normal file
Binary file not shown.
BIN
libs/dll-binaries/i686/discord-rpc.dll
Normal file
BIN
libs/dll-binaries/i686/discord-rpc.dll
Normal file
Binary file not shown.
BIN
libs/dll-binaries/x86_64/discord-rpc.dll
Normal file
BIN
libs/dll-binaries/x86_64/discord-rpc.dll
Normal file
Binary file not shown.
39
libs/drmingw/include/exchndl.h
Normal file
39
libs/drmingw/include/exchndl.h
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 Jose Fonseca
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Set the unhandled exception handler.
|
||||||
|
// Must be called when exchndll.dll is statically loaded (as opposed to loaded
|
||||||
|
// dynamically via LoadLibrary)
|
||||||
|
EXTERN_C VOID APIENTRY
|
||||||
|
ExcHndlInit(void);
|
||||||
|
|
||||||
|
|
||||||
|
// Override the report file name.
|
||||||
|
//
|
||||||
|
// Default is prog_name.RPT, in the same directory as the main executable.
|
||||||
|
//
|
||||||
|
// You can also pass "-" for stderr.
|
||||||
|
EXTERN_C BOOL APIENTRY
|
||||||
|
ExcHndlSetLogFileNameA(const char *szLogFileName);
|
||||||
BIN
libs/drmingw/lib/win32/libexchndl.a
Normal file
BIN
libs/drmingw/lib/win32/libexchndl.a
Normal file
Binary file not shown.
BIN
libs/drmingw/lib/win32/libmgwhelp.a
Normal file
BIN
libs/drmingw/lib/win32/libmgwhelp.a
Normal file
Binary file not shown.
|
|
@ -103,7 +103,6 @@ set(SRB2_CORE_HEADERS
|
||||||
m_swap.h
|
m_swap.h
|
||||||
md5.h
|
md5.h
|
||||||
mserv.h
|
mserv.h
|
||||||
http-mserv.h
|
|
||||||
p5prof.h
|
p5prof.h
|
||||||
s_sound.h
|
s_sound.h
|
||||||
screen.h
|
screen.h
|
||||||
|
|
@ -253,6 +252,8 @@ set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL
|
||||||
"Enable zlib support.")
|
"Enable zlib support.")
|
||||||
set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL
|
set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL
|
||||||
"Enable GME support.")
|
"Enable GME support.")
|
||||||
|
set(SRB2_CONFIG_HAVE_DISCORDRPC OFF CACHE BOOL
|
||||||
|
"Enable Discord rich presence support.")
|
||||||
set(SRB2_CONFIG_HAVE_CURL ON CACHE BOOL
|
set(SRB2_CONFIG_HAVE_CURL ON CACHE BOOL
|
||||||
"Enable cURL support, used for downloading files via HTTP.")
|
"Enable cURL support, used for downloading files via HTTP.")
|
||||||
set(SRB2_CONFIG_HAVE_OPENMPT ON CACHE BOOL
|
set(SRB2_CONFIG_HAVE_OPENMPT ON CACHE BOOL
|
||||||
|
|
@ -369,7 +370,7 @@ if(${SRB2_CONFIG_HAVE_GME})
|
||||||
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
||||||
set(GME_FOUND ON)
|
set(GME_FOUND ON)
|
||||||
set(GME_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/gme/include)
|
set(GME_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/gme/include)
|
||||||
if(${SRB2_SYSTEM_BITS} EQUAL 64)
|
if(${SRB2_SYSTEM_BITS} EQUAL 64)
|
||||||
set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win64 -lgme")
|
set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win64 -lgme")
|
||||||
else() # 32-bit
|
else() # 32-bit
|
||||||
set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win32 -lgme")
|
set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win32 -lgme")
|
||||||
|
|
@ -429,6 +430,32 @@ if(${SRB2_CONFIG_HAVE_MIXERX})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${SRB2_CONFIG_HAVE_DISCORDRPC})
|
||||||
|
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
||||||
|
set(DISCORDRPC_FOUND ON)
|
||||||
|
if(${SRB2_SYSTEM_BITS} EQUAL 64)
|
||||||
|
set(DISCORDRPC_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/discord-rpc/win64-dynamic/include)
|
||||||
|
set(DISCORDRPC_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/discord-rpc/win64-dynamic/lib -ldiscord-rpc")
|
||||||
|
else() # 32-bit
|
||||||
|
set(DISCORDRPC_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/discord-rpc/win32-dynamic/include)
|
||||||
|
set(DISCORDRPC_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/discord-rpc/win32-dynamic/lib -ldiscord-rpc")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
find_package(DiscordRPC)
|
||||||
|
endif()
|
||||||
|
if(${DISCORDRPC_FOUND})
|
||||||
|
set(SRB2_HAVE_DISCORDRPC ON)
|
||||||
|
add_definitions(-DHAVE_DISCORDRPC)
|
||||||
|
set(SRB2_DISCORDRPC_SOURCES discord.c)
|
||||||
|
set(SRB2_DISCORDRPC_HEADERS discord.h)
|
||||||
|
prepend_sources(SRB2_DISCORDRPC_SOURCES)
|
||||||
|
prepend_sources(SRB2_DISCORDRPC_HEADERS)
|
||||||
|
source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS})
|
||||||
|
else()
|
||||||
|
message(WARNING "You have specified that Discord Rich Presence is available but it was not found.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(${SRB2_CONFIG_HAVE_ZLIB})
|
if(${SRB2_CONFIG_HAVE_ZLIB})
|
||||||
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
||||||
set(ZLIB_FOUND ON)
|
set(ZLIB_FOUND ON)
|
||||||
|
|
@ -481,7 +508,7 @@ endif()
|
||||||
if(${SRB2_CONFIG_HAVE_CURL})
|
if(${SRB2_CONFIG_HAVE_CURL})
|
||||||
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
|
||||||
set(CURL_FOUND ON)
|
set(CURL_FOUND ON)
|
||||||
set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl)
|
set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl/include)
|
||||||
if(${SRB2_SYSTEM_BITS} EQUAL 64)
|
if(${SRB2_SYSTEM_BITS} EQUAL 64)
|
||||||
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl")
|
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl")
|
||||||
else() # 32-bit
|
else() # 32-bit
|
||||||
|
|
|
||||||
84
src/Makefile
84
src/Makefile
|
|
@ -57,10 +57,10 @@
|
||||||
# Compile a profile version, add 'PROFILEMODE=1'
|
# Compile a profile version, add 'PROFILEMODE=1'
|
||||||
# Compile a debug version, add 'DEBUGMODE=1'
|
# Compile a debug version, add 'DEBUGMODE=1'
|
||||||
# Compile for the testers group (they don't get to play unless we're watching *wink*), add 'TESTERS=1'
|
# Compile for the testers group (they don't get to play unless we're watching *wink*), add 'TESTERS=1'
|
||||||
# Compile with extra warnings, add 'WARNINGMODE=1'
|
# Compile with less warnings, add 'RELAXWARNINGS=1'
|
||||||
|
# Generate compiler errors for most compiler warnings, add 'ERRORMODE=1'
|
||||||
# Compile without NASM's tmap.nas, add 'NOASM=1'
|
# Compile without NASM's tmap.nas, add 'NOASM=1'
|
||||||
# Compile without 3D hardware support, add 'NOHW=1'
|
# Compile without 3D hardware support, add 'NOHW=1'
|
||||||
# Compile without 3D sound support, add 'NOHS=1'
|
|
||||||
# Compile with GDBstubs, add 'RDB=1'
|
# Compile with GDBstubs, add 'RDB=1'
|
||||||
# Compile without PNG, add 'NOPNG=1'
|
# Compile without PNG, add 'NOPNG=1'
|
||||||
# Compile without zlib, add 'NOZLIB=1'
|
# Compile without zlib, add 'NOZLIB=1'
|
||||||
|
|
@ -81,6 +81,58 @@
|
||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
|
ALL_SYSTEMS=\
|
||||||
|
PANDORA\
|
||||||
|
LINUX64\
|
||||||
|
MINGW64\
|
||||||
|
HAIKU\
|
||||||
|
DUMMY\
|
||||||
|
DJGPPDOS\
|
||||||
|
MINGW\
|
||||||
|
UNIX\
|
||||||
|
LINUX\
|
||||||
|
SOLARIS\
|
||||||
|
FREEBSD\
|
||||||
|
MACOSX\
|
||||||
|
SDL\
|
||||||
|
|
||||||
|
# check for user specified system
|
||||||
|
ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES)))
|
||||||
|
ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
|
||||||
|
|
||||||
|
$(info Detected a Windows system, compiling for 32-bit MinGW SDL2...)
|
||||||
|
|
||||||
|
# go for a 32-bit sdl mingw exe by default
|
||||||
|
MINGW=1
|
||||||
|
SDL=1
|
||||||
|
WINDOWSHELL=1
|
||||||
|
|
||||||
|
else # if you on the *nix
|
||||||
|
|
||||||
|
system:=$(shell uname -s)
|
||||||
|
|
||||||
|
ifeq ($(system),Linux)
|
||||||
|
new_system=LINUX
|
||||||
|
else
|
||||||
|
|
||||||
|
$(error \
|
||||||
|
Could not automatically detect your system,\
|
||||||
|
try specifying a system manually)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(shell getconf LONG_BIT),64)
|
||||||
|
system+=64-bit
|
||||||
|
new_system:=$(new_system)64
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(info Detected $(system) ($(new_system))...)
|
||||||
|
$(new_system)=1
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# SRB2 data files
|
# SRB2 data files
|
||||||
D_DIR?=../bin/Resources
|
D_DIR?=../bin/Resources
|
||||||
D_FILES=$(D_DIR)/main.kart \
|
D_FILES=$(D_DIR)/main.kart \
|
||||||
|
|
@ -124,7 +176,6 @@ NOPNG=1
|
||||||
NOZLIB=1
|
NOZLIB=1
|
||||||
NONET=1
|
NONET=1
|
||||||
NOHW=1
|
NOHW=1
|
||||||
NOHS=1
|
|
||||||
NOASM=1
|
NOASM=1
|
||||||
NOIPX=1
|
NOIPX=1
|
||||||
EXENAME?=srb2dummy
|
EXENAME?=srb2dummy
|
||||||
|
|
@ -146,7 +197,6 @@ endif
|
||||||
ifdef PANDORA
|
ifdef PANDORA
|
||||||
NONX86=1
|
NONX86=1
|
||||||
NOHW=1
|
NOHW=1
|
||||||
NOHS=1
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NOOPENMPT
|
ifndef NOOPENMPT
|
||||||
|
|
@ -228,13 +278,6 @@ else
|
||||||
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o
|
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NOHS
|
|
||||||
OPTS+=-DNOHS
|
|
||||||
else
|
|
||||||
OPTS+=-DHW3SOUND
|
|
||||||
OBJS+=$(OBJDIR)/hw3sound.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
OPTS += -DCOMPVERSION
|
OPTS += -DCOMPVERSION
|
||||||
|
|
||||||
ifndef NONX86
|
ifndef NONX86
|
||||||
|
|
@ -348,6 +391,12 @@ CFLAGS+=-DHAVE_MINIUPNPC
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef HAVE_DISCORDRPC
|
||||||
|
LIBS+=-ldiscord-rpc
|
||||||
|
CFLAGS+=-DHAVE_DISCORDRPC
|
||||||
|
OBJS+=$(OBJDIR)/discord.o
|
||||||
|
endif
|
||||||
|
|
||||||
include blua/Makefile.cfg
|
include blua/Makefile.cfg
|
||||||
|
|
||||||
ifdef NOMD5
|
ifdef NOMD5
|
||||||
|
|
@ -780,19 +829,6 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
|
||||||
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NOHS
|
|
||||||
$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \
|
|
||||||
hardware/hw_dll.h
|
|
||||||
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_ds3d.o $(WFLAGS) -D_WINDOWS -mwindows -c hardware/s_ds3d/s_ds3d.c
|
|
||||||
|
|
||||||
$(OBJDIR)/s_fmod.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
|
|
||||||
hardware/hw_dll.h
|
|
||||||
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o $(WFLAGS) -D_WINDOWS -mwindows -c hardware/s_fmod/s_fmod.c
|
|
||||||
|
|
||||||
$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
|
|
||||||
hardware/hw_dll.h
|
|
||||||
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o $(WFLAGS) -D_WINDOWS -mwindows -c hardware/s_openal/s_openal.c
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -210,10 +210,7 @@ WFLAGS=-Wall
|
||||||
ifndef GCC295
|
ifndef GCC295
|
||||||
#WFLAGS+=-Wno-packed
|
#WFLAGS+=-Wno-packed
|
||||||
endif
|
endif
|
||||||
ifdef ERRORMODE
|
ifndef RELAXWARNINGS
|
||||||
WARNINGMODE=1
|
|
||||||
endif
|
|
||||||
ifdef WARNINGMODE
|
|
||||||
WFLAGS+=-W
|
WFLAGS+=-W
|
||||||
#WFLAGS+=-Wno-sign-compare
|
#WFLAGS+=-Wno-sign-compare
|
||||||
ifndef GCC295
|
ifndef GCC295
|
||||||
|
|
|
||||||
|
|
@ -322,8 +322,8 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
|
||||||
case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
|
case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
|
||||||
case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
|
case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
|
||||||
case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
|
case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
|
||||||
case TM_DIV: if (nc == 0) { lua_pushliteral(L, "divide by zero error"); lua_error(L); } else setnvalue(ra, luai_numdiv(nb, nc)); break;
|
case TM_DIV: if (nc == 0) { luaG_runerror(L, "divide by zero error"); } else setnvalue(ra, luai_numdiv(nb, nc)); break;
|
||||||
case TM_MOD: if (nc == 0) { lua_pushliteral(L, "modulo by zero error"); lua_error(L); } else setnvalue(ra, luai_nummod(nb, nc)); break;
|
case TM_MOD: if (nc == 0) { luaG_runerror(L, "modulo by zero error"); } else setnvalue(ra, luai_nummod(nb, nc)); break;
|
||||||
case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
|
case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
|
||||||
case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
|
case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
|
||||||
case TM_AND: setnvalue(ra, luai_numand(nb, nc)); break;
|
case TM_AND: setnvalue(ra, luai_numand(nb, nc)); break;
|
||||||
|
|
@ -492,8 +492,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
||||||
if (ttisnumber(rb) && ttisnumber(rc)) {
|
if (ttisnumber(rb) && ttisnumber(rc)) {
|
||||||
lua_Number nb = nvalue(rb), nc = nvalue(rc);
|
lua_Number nb = nvalue(rb), nc = nvalue(rc);
|
||||||
if (nc == 0) {
|
if (nc == 0) {
|
||||||
lua_pushliteral(L, "divide by zero error");
|
luaG_runerror(L, "divide by zero error");
|
||||||
lua_error(L);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
setnvalue(ra, luai_numdiv(nb, nc));
|
setnvalue(ra, luai_numdiv(nb, nc));
|
||||||
|
|
@ -508,8 +507,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
||||||
if (ttisnumber(rb) && ttisnumber(rc)) {
|
if (ttisnumber(rb) && ttisnumber(rc)) {
|
||||||
lua_Number nb = nvalue(rb), nc = nvalue(rc);
|
lua_Number nb = nvalue(rb), nc = nvalue(rc);
|
||||||
if (nc == 0) {
|
if (nc == 0) {
|
||||||
lua_pushliteral(L, "modulo by zero error");
|
luaG_runerror(L, "modulo by zero error");
|
||||||
lua_error(L);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
setnvalue(ra, luai_nummod(nb, nc));
|
setnvalue(ra, luai_nummod(nb, nc));
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
/* Manually defined asset hashes for non-CMake builds
|
/* Manually defined asset hashes for non-CMake builds
|
||||||
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
|
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
|
||||||
* Last updated 2020 / 05 / 09 - Kart v1.2 - patch.kart
|
* Last updated 2020 / 08 / 30 - Kart v1.3 - patch.kart
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ASSET_HASH_MAIN_KART "00000000000000000000000000000000"
|
#define ASSET_HASH_MAIN_KART "00000000000000000000000000000000"
|
||||||
|
|
|
||||||
645
src/d_clisrv.c
645
src/d_clisrv.c
File diff suppressed because it is too large
Load diff
|
|
@ -367,6 +367,11 @@ typedef struct
|
||||||
|
|
||||||
char server_context[8]; // Unique context id, generated at server startup.
|
char server_context[8]; // Unique context id, generated at server startup.
|
||||||
|
|
||||||
|
// Discord info (always defined for net compatibility)
|
||||||
|
UINT8 maxplayer;
|
||||||
|
boolean allownewplayer;
|
||||||
|
boolean discordinvites;
|
||||||
|
|
||||||
UINT8 varlengthinputs[0]; // Playernames and netvars
|
UINT8 varlengthinputs[0]; // Playernames and netvars
|
||||||
} ATTRPACK serverconfig_pak;
|
} ATTRPACK serverconfig_pak;
|
||||||
|
|
||||||
|
|
@ -592,6 +597,10 @@ typedef enum
|
||||||
|
|
||||||
} kickreason_t;
|
} kickreason_t;
|
||||||
|
|
||||||
|
/* the max number of name changes in some time period */
|
||||||
|
#define MAXNAMECHANGES (5)
|
||||||
|
#define NAMECHANGERATE (60*TICRATE)
|
||||||
|
|
||||||
extern boolean server;
|
extern boolean server;
|
||||||
extern boolean serverrunning;
|
extern boolean serverrunning;
|
||||||
#define client (!server)
|
#define client (!server)
|
||||||
|
|
@ -619,6 +628,8 @@ extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||||
extern consvar_t cv_joinnextround;
|
extern consvar_t cv_joinnextround;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern consvar_t cv_discordinvites;
|
||||||
|
|
||||||
// Used in d_net, the only dependence
|
// Used in d_net, the only dependence
|
||||||
tic_t ExpandTics(INT32 low, tic_t basetic);
|
tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||||
void D_ClientServerInit(void);
|
void D_ClientServerInit(void);
|
||||||
|
|
@ -643,7 +654,7 @@ void CL_Reset(void);
|
||||||
void CL_ClearPlayer(INT32 playernum);
|
void CL_ClearPlayer(INT32 playernum);
|
||||||
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
||||||
void CL_QueryServerList(msg_server_t *list);
|
void CL_QueryServerList(msg_server_t *list);
|
||||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
void CL_UpdateServerList(void);
|
||||||
// Is there a game running
|
// Is there a game running
|
||||||
boolean Playing(void);
|
boolean Playing(void);
|
||||||
|
|
||||||
|
|
|
||||||
73
src/d_main.c
73
src/d_main.c
|
|
@ -59,7 +59,6 @@
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "y_inter.h"
|
#include "y_inter.h"
|
||||||
#include "p_local.h" // chasecam
|
#include "p_local.h" // chasecam
|
||||||
#include "mserv.h" // ms_RoomId
|
|
||||||
#include "m_misc.h" // screenshot functionality
|
#include "m_misc.h" // screenshot functionality
|
||||||
#include "dehacked.h" // Dehacked list test
|
#include "dehacked.h" // Dehacked list test
|
||||||
#include "m_cond.h" // condition initialization
|
#include "m_cond.h" // condition initialization
|
||||||
|
|
@ -96,6 +95,10 @@
|
||||||
int VERSION;
|
int VERSION;
|
||||||
int SUBVERSION;
|
int SUBVERSION;
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
#include "discord.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// platform independant focus loss
|
// platform independant focus loss
|
||||||
UINT8 window_notinfocus = false;
|
UINT8 window_notinfocus = false;
|
||||||
|
|
||||||
|
|
@ -901,6 +904,13 @@ void D_SRB2Loop(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LUA_Step();
|
LUA_Step();
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
if (! dedicated)
|
||||||
|
{
|
||||||
|
Discord_RunCallbacks();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1078,9 +1088,23 @@ static void ChangeDirForUrlHandler(void)
|
||||||
// Identify the SRB2 version, and IWAD file to use.
|
// Identify the SRB2 version, and IWAD file to use.
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
|
static boolean AddIWAD(void)
|
||||||
|
{
|
||||||
|
char * path = va(pandf,srb2path,"main.kart");
|
||||||
|
|
||||||
|
if (FIL_ReadFileOK(path))
|
||||||
|
{
|
||||||
|
D_AddFile(path, startupiwads);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void IdentifyVersion(void)
|
static void IdentifyVersion(void)
|
||||||
{
|
{
|
||||||
char *mainresource;
|
|
||||||
const char *srb2waddir = NULL;
|
const char *srb2waddir = NULL;
|
||||||
|
|
||||||
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
||||||
|
|
@ -1098,36 +1122,19 @@ static void IdentifyVersion(void)
|
||||||
if (getcwd(srb2path, 256) != NULL)
|
if (getcwd(srb2path, 256) != NULL)
|
||||||
srb2waddir = srb2path;
|
srb2waddir = srb2path;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
srb2waddir = ".";
|
srb2waddir = ".";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (macintosh) && !defined (HAVE_SDL)
|
// Load the IWAD
|
||||||
// cwd is always "/" when app is dbl-clicked
|
if (! AddIWAD())
|
||||||
if (!stricmp(srb2waddir, "/"))
|
{
|
||||||
srb2waddir = I_GetWadDir();
|
I_Error("MAIN.KART not found! Expected in %s\n", srb2waddir);
|
||||||
#endif
|
}
|
||||||
// Commercial.
|
|
||||||
mainresource = malloc(strlen(srb2waddir)+1+9+1);
|
|
||||||
if (mainresource == NULL)
|
|
||||||
I_Error("No more free memory to look in %s", srb2waddir);
|
|
||||||
else
|
|
||||||
sprintf(mainresource, pandf, srb2waddir, "main.kart");
|
|
||||||
|
|
||||||
// will be overwritten in case of -cdrom or unix/win home
|
// will be overwritten in case of -cdrom or unix/win home
|
||||||
snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, srb2waddir);
|
snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, srb2waddir);
|
||||||
configfile[sizeof configfile - 1] = '\0';
|
configfile[sizeof configfile - 1] = '\0';
|
||||||
|
|
||||||
// Load the IWAD
|
|
||||||
if (mainresource != NULL && FIL_ReadFileOK(mainresource))
|
|
||||||
D_AddFile(mainresource, startupiwads);
|
|
||||||
else
|
|
||||||
I_Error("main.kart not found! Expected in %s, ss file: %s \n", srb2waddir, mainresource);
|
|
||||||
|
|
||||||
if (mainresource)
|
|
||||||
free(mainresource);
|
|
||||||
|
|
||||||
// if you change the ordering of this or add/remove a file, be sure to update the md5
|
// if you change the ordering of this or add/remove a file, be sure to update the md5
|
||||||
// checking in D_SRB2Main
|
// checking in D_SRB2Main
|
||||||
|
|
||||||
|
|
@ -1662,17 +1669,6 @@ void D_SRB2Main(void)
|
||||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||||
ST_Init();
|
ST_Init();
|
||||||
|
|
||||||
if (M_CheckParm("-room"))
|
|
||||||
{
|
|
||||||
if (!M_IsNextParm())
|
|
||||||
I_Error("usage: -room <room_id>\nCheck the Master Server's webpage for room ID numbers.\n");
|
|
||||||
ms_RoomId = atoi(M_GetNextParm());
|
|
||||||
|
|
||||||
#ifdef UPDATE_ALERT
|
|
||||||
GetMODVersion_Console();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up splitscreen players before joining!
|
// Set up splitscreen players before joining!
|
||||||
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
|
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
|
||||||
{
|
{
|
||||||
|
|
@ -1890,6 +1886,13 @@ void D_SRB2Main(void)
|
||||||
if (!P_LoadLevel(false))
|
if (!P_LoadLevel(false))
|
||||||
I_Quit(); // fail so reset game stuff
|
I_Quit(); // fail so reset game stuff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
if (! dedicated)
|
||||||
|
{
|
||||||
|
DRPC_Init();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *D_Home(void)
|
const char *D_Home(void)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,10 @@
|
||||||
#define CV_RESTRICT 0
|
#define CV_RESTRICT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
#include "discord.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// ------
|
// ------
|
||||||
// protos
|
// protos
|
||||||
// ------
|
// ------
|
||||||
|
|
@ -89,6 +93,7 @@ static void Got_RandomSeed(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum);
|
static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_Teamchange(UINT8 **cp, INT32 playernum);
|
static void Got_Teamchange(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_Clearscores(UINT8 **cp, INT32 playernum);
|
static void Got_Clearscores(UINT8 **cp, INT32 playernum);
|
||||||
|
static void Got_DiscordInfo(UINT8 **cp, INT32 playernum);
|
||||||
|
|
||||||
static void PointLimit_OnChange(void);
|
static void PointLimit_OnChange(void);
|
||||||
static void TimeLimit_OnChange(void);
|
static void TimeLimit_OnChange(void);
|
||||||
|
|
@ -748,10 +753,13 @@ void D_RegisterServerCommands(void)
|
||||||
CV_RegisterVar(&cv_showviewpointtext);
|
CV_RegisterVar(&cv_showviewpointtext);
|
||||||
|
|
||||||
#ifdef SEENAMES
|
#ifdef SEENAMES
|
||||||
CV_RegisterVar(&cv_allowseenames);
|
CV_RegisterVar(&cv_allowseenames);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CV_RegisterVar(&cv_dummyconsvar);
|
CV_RegisterVar(&cv_dummyconsvar);
|
||||||
|
|
||||||
|
CV_RegisterVar(&cv_discordinvites);
|
||||||
|
RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
@ -1038,6 +1046,12 @@ void D_RegisterClientCommands(void)
|
||||||
#ifdef LUA_ALLOW_BYTECODE
|
#ifdef LUA_ALLOW_BYTECODE
|
||||||
COM_AddCommand("dumplua", Command_Dumplua_f);
|
COM_AddCommand("dumplua", Command_Dumplua_f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
CV_RegisterVar(&cv_discordrp);
|
||||||
|
CV_RegisterVar(&cv_discordstreamer);
|
||||||
|
CV_RegisterVar(&cv_discordasks);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if a name (as received from another player) is okay.
|
/** Checks if a name (as received from another player) is okay.
|
||||||
|
|
@ -1255,6 +1269,8 @@ static void SetPlayerName(INT32 playernum, char *newname)
|
||||||
if (netgame)
|
if (netgame)
|
||||||
HU_AddChatText(va("\x82*%s renamed to %s", player_names[playernum], newname), false);
|
HU_AddChatText(va("\x82*%s renamed to %s", player_names[playernum], newname), false);
|
||||||
|
|
||||||
|
player_name_changes[playernum]++;
|
||||||
|
|
||||||
strcpy(player_names[playernum], newname);
|
strcpy(player_names[playernum], newname);
|
||||||
demo_extradata[playernum] |= DXD_NAME;
|
demo_extradata[playernum] |= DXD_NAME;
|
||||||
}
|
}
|
||||||
|
|
@ -1455,7 +1471,12 @@ static void SendNameAndColor(UINT8 n)
|
||||||
snacpending[n]++;
|
snacpending[n]++;
|
||||||
|
|
||||||
// Don't change name if muted
|
// Don't change name if muted
|
||||||
if (cv_mute.value && !(server || IsPlayerAdmin(playernum)))
|
if (player_name_changes[playernum] >= MAXNAMECHANGES)
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
||||||
|
HU_AddChatText("\x85*You must wait to change your name again", false);
|
||||||
|
}
|
||||||
|
else if (cv_mute.value && !(server || IsPlayerAdmin(playernum)))
|
||||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
||||||
else // Cleanup name if changing it
|
else // Cleanup name if changing it
|
||||||
CleanupPlayerName(playernum, cv_playername[n].zstring);
|
CleanupPlayerName(playernum, cv_playername[n].zstring);
|
||||||
|
|
@ -1491,6 +1512,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
UINT16 color, followercolor;
|
UINT16 color, followercolor;
|
||||||
UINT8 skin;
|
UINT8 skin;
|
||||||
SINT8 follower;
|
SINT8 follower;
|
||||||
|
SINT8 localplayer = -1;
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
|
|
@ -1509,7 +1531,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
I_Error("snacpending[%d] negative!", i);
|
I_Error("snacpending[%d] negative!", i);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// i is now player screen id
|
localplayer = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1590,8 +1612,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
const INT32 forcedskin = cv_forceskin.value;
|
const INT32 forcedskin = cv_forceskin.value;
|
||||||
SetPlayerSkinByNum(playernum, forcedskin);
|
SetPlayerSkinByNum(playernum, forcedskin);
|
||||||
|
|
||||||
if (playernum == g_localplayers[i])
|
if (localplayer != -1)
|
||||||
CV_StealthSet(&cv_skin[i], skins[forcedskin].name);
|
CV_StealthSet(&cv_skin[localplayer], skins[forcedskin].name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetPlayerSkinByNum(playernum, skin);
|
SetPlayerSkinByNum(playernum, skin);
|
||||||
|
|
@ -1602,6 +1624,11 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
// set follower
|
// set follower
|
||||||
SetFollower(playernum, follower);
|
SetFollower(playernum, follower);
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
if (playernum == consoleplayer)
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendWeaponPref(UINT8 n)
|
void SendWeaponPref(UINT8 n)
|
||||||
|
|
@ -2865,6 +2892,10 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
if (demo.recording) // Okay, level loaded, character spawned and skinned,
|
if (demo.recording) // Okay, level loaded, character spawned and skinned,
|
||||||
G_BeginRecording(); // I AM NOW READY TO RECORD.
|
G_BeginRecording(); // I AM NOW READY TO RECORD.
|
||||||
demo.deferstart = true;
|
demo.deferstart = true;
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Command_Pause(void)
|
static void Command_Pause(void)
|
||||||
|
|
@ -3799,7 +3830,7 @@ static void Command_RunSOC(void)
|
||||||
static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
filestatus_t ncs = FS_NOTFOUND;
|
filestatus_t ncs = FS_NOTCHECKED;
|
||||||
|
|
||||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
|
|
@ -3937,7 +3968,7 @@ static void Command_Addfile(void)
|
||||||
static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
char filename[241];
|
char filename[241];
|
||||||
filestatus_t ncs = FS_NOTFOUND;
|
filestatus_t ncs = FS_NOTCHECKED;
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
boolean kick = false;
|
boolean kick = false;
|
||||||
boolean toomany = false;
|
boolean toomany = false;
|
||||||
|
|
@ -3996,7 +4027,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
char filename[241];
|
char filename[241];
|
||||||
filestatus_t ncs = FS_NOTFOUND;
|
filestatus_t ncs = FS_NOTCHECKED;
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
|
||||||
READSTRINGN(*cp, filename, 240);
|
READSTRINGN(*cp, filename, 240);
|
||||||
|
|
@ -4289,6 +4320,10 @@ static void TimeLimit_OnChange(void)
|
||||||
}
|
}
|
||||||
else if (netgame || multiplayer)
|
else if (netgame || multiplayer)
|
||||||
CONS_Printf(M_GetText("Time limit disabled\n"));
|
CONS_Printf(M_GetText("Time limit disabled\n"));
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adjusts certain settings to match a changed gametype.
|
/** Adjusts certain settings to match a changed gametype.
|
||||||
|
|
@ -5603,3 +5638,26 @@ static void KartEliminateLast_OnChange(void)
|
||||||
|
|
||||||
P_CheckRacers();
|
P_CheckRacers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Got_DiscordInfo(UINT8 **p, INT32 playernum)
|
||||||
|
{
|
||||||
|
if (playernum != serverplayer /*&& !IsPlayerAdmin(playernum)*/)
|
||||||
|
{
|
||||||
|
// protect against hacked/buggy client
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal Discord info command received from %s\n"), player_names[playernum]);
|
||||||
|
if (server)
|
||||||
|
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't do anything with the information if we don't have Discord RP support
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
discordInfo.maxPlayers = READUINT8(*p);
|
||||||
|
discordInfo.joinsAllowed = (boolean)READUINT8(*p);
|
||||||
|
discordInfo.everyoneCanInvite = (boolean)READUINT8(*p);
|
||||||
|
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
#else
|
||||||
|
(*p) += 3;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ typedef enum
|
||||||
XD_CANCELPARTYINVITE, // 31
|
XD_CANCELPARTYINVITE, // 31
|
||||||
XD_GIVEITEM, // 32
|
XD_GIVEITEM, // 32
|
||||||
XD_ADDBOT, // 33
|
XD_ADDBOT, // 33
|
||||||
|
XD_DISCORD, // 34
|
||||||
|
|
||||||
MAXNETXCMD
|
MAXNETXCMD
|
||||||
} netxcmd_t;
|
} netxcmd_t;
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,10 @@ static pauseddownload_t *pauseddownload = NULL;
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
// for cl loading screen
|
// for cl loading screen
|
||||||
INT32 lastfilenum = -1;
|
INT32 lastfilenum = -1;
|
||||||
|
INT32 downloadcompletednum = 0;
|
||||||
|
UINT32 downloadcompletedsize = 0;
|
||||||
|
INT32 totalfilesrequestednum = 0;
|
||||||
|
UINT32 totalfilesrequestedsize = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#ifdef HAVE_CURL
|
||||||
|
|
@ -156,7 +160,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
|
||||||
char wadfilename[MAX_WADPATH] = "";
|
char wadfilename[MAX_WADPATH] = "";
|
||||||
UINT8 filestatus;
|
UINT8 filestatus;
|
||||||
|
|
||||||
for (i = mainwads; i < numwadfiles; i++)
|
for (i = mainwads+1; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad
|
||||||
{
|
{
|
||||||
// If it has only music/sound lumps, don't put it in the list
|
// If it has only music/sound lumps, don't put it in the list
|
||||||
if (!wadfiles[i]->important)
|
if (!wadfiles[i]->important)
|
||||||
|
|
@ -222,7 +226,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
|
||||||
p = (UINT8 *)fileneededstr;
|
p = (UINT8 *)fileneededstr;
|
||||||
for (i = firstfile; i < fileneedednum; i++)
|
for (i = firstfile; i < fileneedednum; i++)
|
||||||
{
|
{
|
||||||
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
|
||||||
fileneeded[i].justdownloaded = false;
|
fileneeded[i].justdownloaded = false;
|
||||||
filestatus = READUINT8(p); // The first byte is the file status
|
filestatus = READUINT8(p); // The first byte is the file status
|
||||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||||
|
|
@ -416,15 +420,17 @@ boolean PT_RequestFile(INT32 node)
|
||||||
* \return 0 if some files are missing
|
* \return 0 if some files are missing
|
||||||
* 1 if all files exist
|
* 1 if all files exist
|
||||||
* 2 if some already loaded files are not requested or are in a different order
|
* 2 if some already loaded files are not requested or are in a different order
|
||||||
|
* 3 too many files, over WADLIMIT
|
||||||
|
* 4 still checking, continuing next tic
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
INT32 CL_CheckFiles(void)
|
INT32 CL_CheckFiles(void)
|
||||||
{
|
{
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
char wadfilename[MAX_WADPATH];
|
char wadfilename[MAX_WADPATH];
|
||||||
INT32 ret = 1;
|
|
||||||
size_t packetsize = 0;
|
size_t packetsize = 0;
|
||||||
size_t filestoget = 0;
|
size_t filestoload = 0;
|
||||||
|
boolean downloadrequired = false;
|
||||||
|
|
||||||
// if (M_CheckParm("-nofiles"))
|
// if (M_CheckParm("-nofiles"))
|
||||||
// return 1;
|
// return 1;
|
||||||
|
|
@ -441,7 +447,7 @@ INT32 CL_CheckFiles(void)
|
||||||
if (modifiedgame)
|
if (modifiedgame)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||||
for (i = 0, j = mainwads; i < fileneedednum || j < numwadfiles;)
|
for (i = 0, j = mainwads+1; i < fileneedednum || j < numwadfiles;)
|
||||||
{
|
{
|
||||||
if (j < numwadfiles && !wadfiles[j]->important)
|
if (j < numwadfiles && !wadfiles[j]->important)
|
||||||
{
|
{
|
||||||
|
|
@ -470,10 +476,19 @@ INT32 CL_CheckFiles(void)
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
{
|
{
|
||||||
|
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_FALLBACK)
|
||||||
|
downloadrequired = true;
|
||||||
|
|
||||||
|
if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND)
|
||||||
|
filestoload++;
|
||||||
|
|
||||||
|
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
|
||||||
|
continue;
|
||||||
|
|
||||||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||||
|
|
||||||
// Check in already loaded files
|
// Check in already loaded files
|
||||||
for (j = mainwads; wadfiles[j]; j++)
|
for (j = mainwads+1; wadfiles[j]; j++)
|
||||||
{
|
{
|
||||||
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
||||||
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
||||||
|
|
@ -481,36 +496,35 @@ INT32 CL_CheckFiles(void)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_NETPLAY, "already loaded\n");
|
CONS_Debug(DBG_NETPLAY, "already loaded\n");
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
break;
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fileneeded[i].status != FS_NOTFOUND)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||||
|
|
||||||
if (mainwads+filestoget >= MAX_WADFILES)
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
filestoget++;
|
|
||||||
|
|
||||||
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
||||||
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
||||||
if (fileneeded[i].status != FS_FOUND)
|
return 4;
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
//now making it here means we've checked the entire list and no FS_NOTCHECKED files remain
|
||||||
|
if (numwadfiles+filestoload > MAX_WADFILES)
|
||||||
|
return 3;
|
||||||
|
else if (downloadrequired)
|
||||||
|
return 0; //some stuff is FS_NOTFOUND, needs download
|
||||||
|
else
|
||||||
|
return 1; //everything is FS_OPEN or FS_FOUND, proceed to loading
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load it now
|
// Load it now
|
||||||
void CL_LoadServerFiles(void)
|
boolean CL_LoadServerFiles(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
// if (M_CheckParm("-nofiles"))
|
// if (M_CheckParm("-nofiles"))
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
for (i = 1; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
{
|
{
|
||||||
if (fileneeded[i].status == FS_OPEN)
|
if (fileneeded[i].status == FS_OPEN)
|
||||||
continue; // Already loaded
|
continue; // Already loaded
|
||||||
|
|
@ -519,6 +533,7 @@ void CL_LoadServerFiles(void)
|
||||||
P_AddWadFile(fileneeded[i].filename);
|
P_AddWadFile(fileneeded[i].filename);
|
||||||
G_SetGameModified(true, false);
|
G_SetGameModified(true, false);
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||||
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
||||||
|
|
@ -544,6 +559,7 @@ void CL_LoadServerFiles(void)
|
||||||
fileneeded[i].status, s);
|
fileneeded[i].status, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddLuaFileTransfer(const char *filename, const char *mode)
|
void AddLuaFileTransfer(const char *filename, const char *mode)
|
||||||
|
|
@ -1374,6 +1390,11 @@ void PT_FileFragment(void)
|
||||||
netbuffer->packettype = PT_HASLUAFILE;
|
netbuffer->packettype = PT_HASLUAFILE;
|
||||||
HSendPacket(servernode, true, 0, 0);
|
HSendPacket(servernode, true, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NONET
|
||||||
|
downloadcompletednum++;
|
||||||
|
downloadcompletedsize += file->totalsize;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Already received
|
else // Already received
|
||||||
|
|
@ -1732,6 +1753,8 @@ void CURLGetFile(void)
|
||||||
{
|
{
|
||||||
nameonly(curl_realname);
|
nameonly(curl_realname);
|
||||||
CONS_Printf(M_GetText("Finished downloading %s\n"), curl_realname);
|
CONS_Printf(M_GetText("Finished downloading %s\n"), curl_realname);
|
||||||
|
downloadcompletednum++;
|
||||||
|
downloadcompletedsize += curl_curfile->totalsize;
|
||||||
curl_curfile->status = FS_FOUND;
|
curl_curfile->status = FS_FOUND;
|
||||||
fclose(curl_curfile->file);
|
fclose(curl_curfile->file);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ typedef enum
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
FS_NOTCHECKED,
|
||||||
FS_NOTFOUND,
|
FS_NOTFOUND,
|
||||||
FS_FOUND,
|
FS_FOUND,
|
||||||
FS_REQUESTED,
|
FS_REQUESTED,
|
||||||
|
|
@ -61,6 +62,10 @@ extern char downloaddir[512];
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
extern INT32 lastfilenum;
|
extern INT32 lastfilenum;
|
||||||
|
extern INT32 downloadcompletednum;
|
||||||
|
extern UINT32 downloadcompletedsize;
|
||||||
|
extern INT32 totalfilesrequestednum;
|
||||||
|
extern UINT32 totalfilesrequestedsize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#ifdef HAVE_CURL
|
||||||
|
|
@ -74,7 +79,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
|
||||||
void CL_PrepareDownloadSaveGame(const char *tmpsave);
|
void CL_PrepareDownloadSaveGame(const char *tmpsave);
|
||||||
|
|
||||||
INT32 CL_CheckFiles(void);
|
INT32 CL_CheckFiles(void);
|
||||||
void CL_LoadServerFiles(void);
|
boolean CL_LoadServerFiles(void);
|
||||||
void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod,
|
void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod,
|
||||||
UINT8 fileid);
|
UINT8 fileid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10362,7 +10362,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_TWINKLECARTAMBIENCE",
|
"MT_TWINKLECARTAMBIENCE",
|
||||||
"MT_EXPLODINGBARREL",
|
"MT_EXPLODINGBARREL",
|
||||||
"MT_MERRYHORSE",
|
"MT_MERRYHORSE",
|
||||||
"MT_ARIDTOAD",
|
|
||||||
"MT_BLUEFRUIT",
|
"MT_BLUEFRUIT",
|
||||||
"MT_ORANGEFRUIT",
|
"MT_ORANGEFRUIT",
|
||||||
"MT_REDFRUIT",
|
"MT_REDFRUIT",
|
||||||
|
|
@ -10373,6 +10372,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_BOOSTPROMPT",
|
"MT_BOOSTPROMPT",
|
||||||
"MT_BOOSTOFF",
|
"MT_BOOSTOFF",
|
||||||
"MT_BOOSTON",
|
"MT_BOOSTON",
|
||||||
|
"MT_ARIDTOAD",
|
||||||
"MT_LIZARDMAN",
|
"MT_LIZARDMAN",
|
||||||
"MT_LIONMAN",
|
"MT_LIONMAN",
|
||||||
|
|
||||||
|
|
@ -12689,8 +12689,6 @@ static inline int lib_getenum(lua_State *L)
|
||||||
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||||
|
|
||||||
// DYNAMIC variables too!!
|
// DYNAMIC variables too!!
|
||||||
// Try not to add anything that would break netgames or timeattack replays here.
|
|
||||||
// You know, like consoleplayer, displayplayer, secondarydisplayplayer, or gametime.
|
|
||||||
return LUA_PushGlobals(L, word);
|
return LUA_PushGlobals(L, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
712
src/discord.c
Normal file
712
src/discord.c
Normal file
|
|
@ -0,0 +1,712 @@
|
||||||
|
// SONIC ROBO BLAST 2 KART
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2018-2020 by Sally "TehRealSalt" Cochenour.
|
||||||
|
// Copyright (C) 2018-2020 by Kart Krew.
|
||||||
|
//
|
||||||
|
// 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 discord.h
|
||||||
|
/// \brief Discord Rich Presence handling
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#endif // HAVE_CURL
|
||||||
|
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "d_clisrv.h"
|
||||||
|
#include "d_netcmd.h"
|
||||||
|
#include "i_net.h"
|
||||||
|
#include "g_game.h"
|
||||||
|
#include "p_tick.h"
|
||||||
|
#include "m_menu.h" // gametype_cons_t
|
||||||
|
#include "r_things.h" // skins
|
||||||
|
#include "mserv.h" // cv_advertise
|
||||||
|
#include "z_zone.h"
|
||||||
|
#include "byteptr.h"
|
||||||
|
|
||||||
|
#include "discord.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
|
||||||
|
// Feel free to provide your own, if you care enough to create another Discord app for this :P
|
||||||
|
#define DISCORD_APPID "503531144395096085"
|
||||||
|
|
||||||
|
// length of IP strings
|
||||||
|
#define IP_SIZE 21
|
||||||
|
|
||||||
|
consvar_t cv_discordrp = {"discordrp", "On", CV_SAVE|CV_CALL, CV_OnOff, DRPC_UpdatePresence, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_discordstreamer = {"discordstreamer", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_discordasks = {"discordasks", "Yes", CV_SAVE|CV_CALL, CV_YesNo, DRPC_UpdatePresence, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
struct discordInfo_s discordInfo;
|
||||||
|
|
||||||
|
discordRequest_t *discordRequestList = NULL;
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL
|
||||||
|
struct SelfIPbuffer
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
char *pointer;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
static char self_ip[IP_SIZE];
|
||||||
|
#endif // HAVE_CURL
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static char *DRPC_XORIPString(const char *input)
|
||||||
|
|
||||||
|
Simple XOR encryption/decryption. Not complex or
|
||||||
|
very secretive because we aren't sending anything
|
||||||
|
that isn't easily accessible via our Master Server anyway.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static char *DRPC_XORIPString(const char *input)
|
||||||
|
{
|
||||||
|
const UINT8 xor[IP_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
|
||||||
|
char *output = malloc(sizeof(char) * (IP_SIZE+1));
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i < IP_SIZE; i++)
|
||||||
|
{
|
||||||
|
char xorinput;
|
||||||
|
|
||||||
|
if (!input[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
xorinput = input[i] ^ xor[i];
|
||||||
|
|
||||||
|
if (xorinput < 32 || xorinput > 126)
|
||||||
|
{
|
||||||
|
xorinput = input[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = xorinput;
|
||||||
|
}
|
||||||
|
|
||||||
|
output[i] = '\0';
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void DRPC_HandleReady(const DiscordUser *user)
|
||||||
|
|
||||||
|
Callback function, ran when the game connects to Discord.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
user - Struct containing Discord user info.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void DRPC_HandleReady(const DiscordUser *user)
|
||||||
|
{
|
||||||
|
if (cv_discordstreamer.value)
|
||||||
|
{
|
||||||
|
CONS_Printf("Discord: connected to %s\n", user->username);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Printf("Discord: connected to %s#%s (%s)\n", user->username, user->discriminator, user->userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void DRPC_HandleDisconnect(int err, const char *msg)
|
||||||
|
|
||||||
|
Callback function, ran when disconnecting from Discord.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
err - Error type
|
||||||
|
msg - Error message
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void DRPC_HandleDisconnect(int err, const char *msg)
|
||||||
|
{
|
||||||
|
CONS_Printf("Discord: disconnected (%d: %s)\n", err, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void DRPC_HandleError(int err, const char *msg)
|
||||||
|
|
||||||
|
Callback function, ran when Discord outputs an error.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
err - Error type
|
||||||
|
msg - Error message
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void DRPC_HandleError(int err, const char *msg)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, "Discord error (%d: %s)\n", err, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void DRPC_HandleJoin(const char *secret)
|
||||||
|
|
||||||
|
Callback function, ran when Discord wants to
|
||||||
|
connect a player to the game via a channel invite
|
||||||
|
or a join request.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
secret - Value that links you to the server.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void DRPC_HandleJoin(const char *secret)
|
||||||
|
{
|
||||||
|
char *ip = DRPC_XORIPString(secret);
|
||||||
|
CONS_Printf("Connecting to %s via Discord\n", ip);
|
||||||
|
COM_BufAddText(va("connect \"%s\"\n", ip));
|
||||||
|
free(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static boolean DRPC_InvitesAreAllowed(void)
|
||||||
|
|
||||||
|
Determines whenever or not invites or
|
||||||
|
ask to join requests are allowed.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
None
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
true if invites are allowed, false otherwise.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static boolean DRPC_InvitesAreAllowed(void)
|
||||||
|
{
|
||||||
|
if (!Playing())
|
||||||
|
{
|
||||||
|
// We're not playing, so we should not be getting invites.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cv_discordasks.value == 0)
|
||||||
|
{
|
||||||
|
// Client has the CVar set to off, so never allow invites from this client.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discordInfo.joinsAllowed == true)
|
||||||
|
{
|
||||||
|
if (discordInfo.everyoneCanInvite == true)
|
||||||
|
{
|
||||||
|
// Everyone's allowed!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (consoleplayer == serverplayer || IsPlayerAdmin(consoleplayer))
|
||||||
|
{
|
||||||
|
// Only admins are allowed!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did not pass any of the checks
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void DRPC_HandleJoinRequest(const DiscordUser *requestUser)
|
||||||
|
|
||||||
|
Callback function, ran when Discord wants to
|
||||||
|
ask the player if another Discord user can join
|
||||||
|
or not.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
requestUser - DiscordUser struct for the user trying to connect.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void DRPC_HandleJoinRequest(const DiscordUser *requestUser)
|
||||||
|
{
|
||||||
|
discordRequest_t *append = discordRequestList;
|
||||||
|
discordRequest_t *newRequest;
|
||||||
|
|
||||||
|
if (DRPC_InvitesAreAllowed() == false)
|
||||||
|
{
|
||||||
|
// Something weird happened if this occurred...
|
||||||
|
Discord_Respond(requestUser->userId, DISCORD_REPLY_IGNORE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newRequest = Z_Calloc(sizeof(discordRequest_t), PU_STATIC, NULL);
|
||||||
|
|
||||||
|
newRequest->username = Z_Calloc(344, PU_STATIC, NULL);
|
||||||
|
snprintf(newRequest->username, 344, "%s", requestUser->username);
|
||||||
|
|
||||||
|
newRequest->discriminator = Z_Calloc(8, PU_STATIC, NULL);
|
||||||
|
snprintf(newRequest->discriminator, 8, "%s", requestUser->discriminator);
|
||||||
|
|
||||||
|
newRequest->userID = Z_Calloc(32, PU_STATIC, NULL);
|
||||||
|
snprintf(newRequest->userID, 32, "%s", requestUser->userId);
|
||||||
|
|
||||||
|
if (append != NULL)
|
||||||
|
{
|
||||||
|
discordRequest_t *prev = NULL;
|
||||||
|
|
||||||
|
while (append != NULL)
|
||||||
|
{
|
||||||
|
// CHECK FOR DUPES!! Ignore any that already exist from the same user.
|
||||||
|
if (!strcmp(newRequest->userID, append->userID))
|
||||||
|
{
|
||||||
|
Discord_Respond(newRequest->userID, DISCORD_REPLY_IGNORE);
|
||||||
|
DRPC_RemoveRequest(newRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = append;
|
||||||
|
append = append->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
newRequest->prev = prev;
|
||||||
|
prev->next = newRequest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
discordRequestList = newRequest;
|
||||||
|
M_RefreshPauseMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Made it to the end, request was valid, so play the request sound :)
|
||||||
|
S_StartSound(NULL, sfx_requst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_RemoveRequest(discordRequest_t *removeRequest)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
void DRPC_RemoveRequest(discordRequest_t *removeRequest)
|
||||||
|
{
|
||||||
|
if (removeRequest->prev != NULL)
|
||||||
|
{
|
||||||
|
removeRequest->prev->next = removeRequest->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeRequest->next != NULL)
|
||||||
|
{
|
||||||
|
removeRequest->next->prev = removeRequest->prev;
|
||||||
|
|
||||||
|
if (removeRequest == discordRequestList)
|
||||||
|
{
|
||||||
|
discordRequestList = removeRequest->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (removeRequest == discordRequestList)
|
||||||
|
{
|
||||||
|
discordRequestList = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(removeRequest->username);
|
||||||
|
Z_Free(removeRequest->userID);
|
||||||
|
Z_Free(removeRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_Init(void)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
void DRPC_Init(void)
|
||||||
|
{
|
||||||
|
DiscordEventHandlers handlers;
|
||||||
|
memset(&handlers, 0, sizeof(handlers));
|
||||||
|
|
||||||
|
handlers.ready = DRPC_HandleReady;
|
||||||
|
handlers.disconnected = DRPC_HandleDisconnect;
|
||||||
|
handlers.errored = DRPC_HandleError;
|
||||||
|
handlers.joinGame = DRPC_HandleJoin;
|
||||||
|
handlers.joinRequest = DRPC_HandleJoinRequest;
|
||||||
|
|
||||||
|
Discord_Initialize(DISCORD_APPID, &handlers, 1, NULL);
|
||||||
|
I_AddExitFunc(Discord_Shutdown);
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata)
|
||||||
|
|
||||||
|
Writing function for use with curl. Only intended to be used with simple text.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
s - Data to write
|
||||||
|
size - Always 1.
|
||||||
|
n - Length of data
|
||||||
|
userdata - Passed in from CURLOPT_WRITEDATA, intended to be SelfIPbuffer
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
Number of bytes wrote in this pass.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata)
|
||||||
|
{
|
||||||
|
struct SelfIPbuffer *buffer;
|
||||||
|
size_t newlength;
|
||||||
|
|
||||||
|
buffer = userdata;
|
||||||
|
|
||||||
|
newlength = buffer->length + size*n;
|
||||||
|
buffer->pointer = realloc(buffer->pointer, newlength+1);
|
||||||
|
|
||||||
|
memcpy(buffer->pointer + buffer->length, s, size*n);
|
||||||
|
|
||||||
|
buffer->pointer[newlength] = '\0';
|
||||||
|
buffer->length = newlength;
|
||||||
|
|
||||||
|
return size*n;
|
||||||
|
}
|
||||||
|
#endif // HAVE_CURL
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static const char *DRPC_GetServerIP(void)
|
||||||
|
|
||||||
|
Retrieves the IP address of the server that you're
|
||||||
|
connected to. Will attempt to use curl for getting your
|
||||||
|
own IP address, if it's not yours.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static const char *DRPC_GetServerIP(void)
|
||||||
|
{
|
||||||
|
const char *address;
|
||||||
|
|
||||||
|
// If you're connected
|
||||||
|
if (I_GetNodeAddress && (address = I_GetNodeAddress(servernode)) != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(address, "self"))
|
||||||
|
{
|
||||||
|
// We're not the server, so we could successfully get the IP!
|
||||||
|
// No need to do anything else :)
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL
|
||||||
|
// This is a little bit goofy, but
|
||||||
|
// there's practically no good way to get your own public IP address,
|
||||||
|
// so we've gotta break out curl for this :V
|
||||||
|
if (!self_ip[0])
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
curl = curl_easy_init();
|
||||||
|
|
||||||
|
if (curl)
|
||||||
|
{
|
||||||
|
// The API to get your public IP address from.
|
||||||
|
// Picked because it's stupid simple and it's been up for a long time.
|
||||||
|
const char *api = "http://ip4only.me/api/";
|
||||||
|
|
||||||
|
struct SelfIPbuffer buffer;
|
||||||
|
CURLcode success;
|
||||||
|
|
||||||
|
buffer.length = 0;
|
||||||
|
buffer.pointer = malloc(buffer.length+1);
|
||||||
|
buffer.pointer[0] = '\0';
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, api);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DRPC_WriteServerIP);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
|
||||||
|
|
||||||
|
success = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
if (success == CURLE_OK)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
tmp = strtok(buffer.pointer, ",");
|
||||||
|
|
||||||
|
if (!strcmp(tmp, "IPv4")) // ensure correct type of IP
|
||||||
|
{
|
||||||
|
tmp = strtok(NULL, ",");
|
||||||
|
strncpy(self_ip, tmp, IP_SIZE); // Yay, we have the IP :)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer.pointer);
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_global_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self_ip[0])
|
||||||
|
return self_ip;
|
||||||
|
else
|
||||||
|
#endif // HAVE_CURL
|
||||||
|
return NULL; // Could not get your IP for whatever reason, so we cannot do Discord invites
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_EmptyRequests(void)
|
||||||
|
|
||||||
|
Empties the request list. Any existing requests
|
||||||
|
will get an ignore reply.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void DRPC_EmptyRequests(void)
|
||||||
|
{
|
||||||
|
while (discordRequestList != NULL)
|
||||||
|
{
|
||||||
|
Discord_Respond(discordRequestList->userID, DISCORD_REPLY_IGNORE);
|
||||||
|
DRPC_RemoveRequest(discordRequestList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_UpdatePresence(void)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
void DRPC_UpdatePresence(void)
|
||||||
|
{
|
||||||
|
char detailstr[48+1];
|
||||||
|
|
||||||
|
char mapimg[8+1];
|
||||||
|
char mapname[5+21+21+2+1];
|
||||||
|
|
||||||
|
char charimg[4+SKINNAMESIZE+1];
|
||||||
|
char charname[11+SKINNAMESIZE+1];
|
||||||
|
|
||||||
|
boolean joinSecretSet = false;
|
||||||
|
|
||||||
|
DiscordRichPresence discordPresence;
|
||||||
|
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||||
|
|
||||||
|
if (dedicated)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cv_discordrp.value)
|
||||||
|
{
|
||||||
|
// User doesn't want to show their game information, so update with empty presence.
|
||||||
|
// This just shows that they're playing SRB2Kart. (If that's too much, then they should disable game activity :V)
|
||||||
|
DRPC_EmptyRequests();
|
||||||
|
Discord_UpdatePresence(&discordPresence);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEVELOP
|
||||||
|
// This way, we can use the invite feature in-dev, but not have snoopers seeing any potential secrets! :P
|
||||||
|
discordPresence.largeImageKey = "miscdevelop";
|
||||||
|
discordPresence.largeImageText = "No peeking!";
|
||||||
|
discordPresence.state = "Testing the game";
|
||||||
|
|
||||||
|
DRPC_EmptyRequests();
|
||||||
|
Discord_UpdatePresence(&discordPresence);
|
||||||
|
return;
|
||||||
|
#endif // DEVELOP
|
||||||
|
|
||||||
|
// Server info
|
||||||
|
if (netgame)
|
||||||
|
{
|
||||||
|
if (cv_advertise.value)
|
||||||
|
{
|
||||||
|
discordPresence.state = "Public";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
discordPresence.state = "Private";
|
||||||
|
}
|
||||||
|
|
||||||
|
discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field!
|
||||||
|
discordPresence.partySize = D_NumPlayers(); // Players in server
|
||||||
|
discordPresence.partyMax = discordInfo.maxPlayers; // Max players
|
||||||
|
|
||||||
|
if (DRPC_InvitesAreAllowed() == true)
|
||||||
|
{
|
||||||
|
const char *join;
|
||||||
|
|
||||||
|
// Grab the host's IP for joining.
|
||||||
|
if ((join = DRPC_GetServerIP()) != NULL)
|
||||||
|
{
|
||||||
|
char *xorjoin = DRPC_XORIPString(join);
|
||||||
|
discordPresence.joinSecret = xorjoin;
|
||||||
|
free(xorjoin);
|
||||||
|
|
||||||
|
joinSecretSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Reset discord info if you're not in a place that uses it!
|
||||||
|
// Important for if you join a server that compiled without HAVE_DISCORDRPC,
|
||||||
|
// so that you don't ever end up using bad information from another server.
|
||||||
|
memset(&discordInfo, 0, sizeof(discordInfo));
|
||||||
|
|
||||||
|
// Offline info
|
||||||
|
if (Playing())
|
||||||
|
discordPresence.state = "Offline";
|
||||||
|
else if (demo.playback && !demo.title)
|
||||||
|
discordPresence.state = "Watching Replay";
|
||||||
|
else
|
||||||
|
discordPresence.state = "Menu";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gametype info
|
||||||
|
if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING) && Playing())
|
||||||
|
{
|
||||||
|
if (modeattacking)
|
||||||
|
discordPresence.details = "Time Attack";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(detailstr, 48, "%s%s%s",
|
||||||
|
gametype_cons_t[gametype].strvalue,
|
||||||
|
(gametype == GT_RACE) ? va(" | %s", kartspeed_cons_t[gamespeed].strvalue) : "",
|
||||||
|
(encoremode == true) ? " | Encore" : ""
|
||||||
|
);
|
||||||
|
discordPresence.details = detailstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) // Map info
|
||||||
|
&& !(demo.playback && demo.title))
|
||||||
|
{
|
||||||
|
if ((gamemap >= 1 && gamemap <= 60) // supported race maps
|
||||||
|
|| (gamemap >= 136 && gamemap <= 164)) // supported battle maps
|
||||||
|
{
|
||||||
|
snprintf(mapimg, 8, "%s", G_BuildMapName(gamemap));
|
||||||
|
strlwr(mapimg);
|
||||||
|
discordPresence.largeImageKey = mapimg; // Map image
|
||||||
|
}
|
||||||
|
else if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
||||||
|
{
|
||||||
|
// Hell map, use the method that got you here :P
|
||||||
|
discordPresence.largeImageKey = "miscdice";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is probably a custom map!
|
||||||
|
discordPresence.largeImageKey = "mapcustom";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
||||||
|
{
|
||||||
|
// Hell map, hide the name
|
||||||
|
discordPresence.largeImageText = "Map: ???";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Map name on tool tip
|
||||||
|
snprintf(mapname, 48, "Map: %s", G_BuildMapTitle(gamemap));
|
||||||
|
discordPresence.largeImageText = mapname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamestate == GS_LEVEL && Playing())
|
||||||
|
{
|
||||||
|
const time_t currentTime = time(NULL);
|
||||||
|
const time_t mapTimeStart = currentTime - ((leveltime + (modeattacking ? starttime : 0)) / TICRATE);
|
||||||
|
|
||||||
|
discordPresence.startTimestamp = mapTimeStart;
|
||||||
|
|
||||||
|
if (timelimitintics > 0)
|
||||||
|
{
|
||||||
|
const time_t mapTimeEnd = mapTimeStart + ((timelimitintics + starttime + 1) / TICRATE);
|
||||||
|
discordPresence.endTimestamp = mapTimeEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gamestate == GS_VOTING)
|
||||||
|
{
|
||||||
|
discordPresence.largeImageKey = ((gametype == GT_BATTLE) ? "miscredplanet" : "miscblueplanet");
|
||||||
|
discordPresence.largeImageText = "Voting";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
discordPresence.largeImageKey = "misctitle";
|
||||||
|
discordPresence.largeImageText = "Title Screen";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Character info
|
||||||
|
if (Playing() && playeringame[consoleplayer] && !players[consoleplayer].spectator)
|
||||||
|
{
|
||||||
|
// Supported skin names
|
||||||
|
static const char *supportedSkins[] = {
|
||||||
|
// base game
|
||||||
|
"sonic",
|
||||||
|
"tails",
|
||||||
|
"knuckles",
|
||||||
|
"eggman",
|
||||||
|
"metalsonic",
|
||||||
|
// bonus chars
|
||||||
|
"flicky",
|
||||||
|
"motobug",
|
||||||
|
"amy",
|
||||||
|
"mighty",
|
||||||
|
"ray",
|
||||||
|
"espio",
|
||||||
|
"vector",
|
||||||
|
"chao",
|
||||||
|
"gamma",
|
||||||
|
"chaos",
|
||||||
|
"shadow",
|
||||||
|
"rouge",
|
||||||
|
"herochao",
|
||||||
|
"darkchao",
|
||||||
|
"cream",
|
||||||
|
"omega",
|
||||||
|
"blaze",
|
||||||
|
"silver",
|
||||||
|
"wonderboy",
|
||||||
|
"arle",
|
||||||
|
"nights",
|
||||||
|
"sakura",
|
||||||
|
"ulala",
|
||||||
|
"beat",
|
||||||
|
"vyse",
|
||||||
|
"aiai",
|
||||||
|
"kiryu",
|
||||||
|
"aigis",
|
||||||
|
"miku",
|
||||||
|
"doom",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
boolean customChar = true;
|
||||||
|
UINT8 checkSkin = 0;
|
||||||
|
|
||||||
|
// Character image
|
||||||
|
while (supportedSkins[checkSkin] != NULL)
|
||||||
|
{
|
||||||
|
if (!strcmp(skins[players[consoleplayer].skin].name, supportedSkins[checkSkin]))
|
||||||
|
{
|
||||||
|
snprintf(charimg, 21, "char%s", supportedSkins[checkSkin]);
|
||||||
|
discordPresence.smallImageKey = charimg;
|
||||||
|
customChar = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSkin++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customChar == true)
|
||||||
|
{
|
||||||
|
// Use the custom character icon!
|
||||||
|
discordPresence.smallImageKey = "charcustom";
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(charname, 28, "Character: %s", skins[players[consoleplayer].skin].realname);
|
||||||
|
discordPresence.smallImageText = charname; // Character name
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joinSecretSet == false)
|
||||||
|
{
|
||||||
|
// Not able to join? Flush the request list, if it exists.
|
||||||
|
DRPC_EmptyRequests();
|
||||||
|
}
|
||||||
|
|
||||||
|
Discord_UpdatePresence(&discordPresence);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_DISCORDRPC
|
||||||
80
src/discord.h
Normal file
80
src/discord.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
// SONIC ROBO BLAST 2 KART
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2018-2020 by Sally "TehRealSalt" Cochenour.
|
||||||
|
// Copyright (C) 2018-2020 by Kart Krew.
|
||||||
|
//
|
||||||
|
// 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 discord.h
|
||||||
|
/// \brief Discord Rich Presence handling
|
||||||
|
|
||||||
|
#ifndef __DISCORD__
|
||||||
|
#define __DISCORD__
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
|
||||||
|
#include "discord_rpc.h"
|
||||||
|
|
||||||
|
extern consvar_t cv_discordrp;
|
||||||
|
extern consvar_t cv_discordstreamer;
|
||||||
|
extern consvar_t cv_discordasks;
|
||||||
|
|
||||||
|
extern struct discordInfo_s {
|
||||||
|
UINT8 maxPlayers;
|
||||||
|
boolean joinsAllowed;
|
||||||
|
boolean everyoneCanInvite;
|
||||||
|
} discordInfo;
|
||||||
|
|
||||||
|
typedef struct discordRequest_s {
|
||||||
|
char *username; // Discord user name.
|
||||||
|
char *discriminator; // Discord discriminator (The little hashtag thing after the username). Separated for a "hide discriminators" cvar.
|
||||||
|
char *userID; // The ID of the Discord user, gets used with Discord_Respond()
|
||||||
|
|
||||||
|
// HAHAHA, no.
|
||||||
|
// *Maybe* if it was only PNG I would boot up curl just to get AND convert this to Doom GFX,
|
||||||
|
// but it can *also* be a JEPG, WebP, or GIF :)
|
||||||
|
// Hey, wanna add ImageMagick as a dependency? :dying:
|
||||||
|
//patch_t *avatar;
|
||||||
|
|
||||||
|
struct discordRequest_s *next; // Next request in the list.
|
||||||
|
struct discordRequest_s *prev; // Previous request in the list. Not used normally, but just in case something funky happens, this should repair the list.
|
||||||
|
} discordRequest_t;
|
||||||
|
|
||||||
|
extern discordRequest_t *discordRequestList;
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_RemoveRequest(void);
|
||||||
|
|
||||||
|
Removes an invite from the list.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
void DRPC_RemoveRequest(discordRequest_t *removeRequest);
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_Init(void);
|
||||||
|
|
||||||
|
Initalizes Discord Rich Presence by linking the Application ID
|
||||||
|
and setting the callback functions.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
void DRPC_Init(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
void DRPC_UpdatePresence(void);
|
||||||
|
|
||||||
|
Updates what is displayed by Rich Presence on the user's profile.
|
||||||
|
Should be called whenever something that is displayed is
|
||||||
|
changed in-game.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
void DRPC_UpdatePresence(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HAVE_DISCORDRPC
|
||||||
|
|
||||||
|
#endif // __DISCORD__
|
||||||
|
|
@ -220,4 +220,11 @@ typedef struct
|
||||||
|
|
||||||
#define NUMMAPS 1035
|
#define NUMMAPS 1035
|
||||||
|
|
||||||
|
/* slope thing types */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FLOOR_SLOPE_THING = 777,
|
||||||
|
CEILING_SLOPE_THING = 778,
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __DOOMDATA__
|
#endif // __DOOMDATA__
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
// Use Mixer interface?
|
// Use Mixer interface?
|
||||||
#ifdef HAVE_MIXER
|
#ifdef HAVE_MIXER
|
||||||
#define SOUND SOUND_MIXER
|
#define SOUND SOUND_MIXER
|
||||||
#define NOHS // No HW3SOUND
|
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
#undef HW3SOUND
|
#undef HW3SOUND
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -45,7 +44,6 @@
|
||||||
// Use FMOD?
|
// Use FMOD?
|
||||||
#ifdef HAVE_FMOD
|
#ifdef HAVE_FMOD
|
||||||
#define SOUND SOUND_FMOD
|
#define SOUND SOUND_FMOD
|
||||||
#define NOHS // No HW3SOUND
|
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
#undef HW3SOUND
|
#undef HW3SOUND
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -62,10 +60,6 @@
|
||||||
#if !defined (HWRENDER) && !defined (NOHW)
|
#if !defined (HWRENDER) && !defined (NOHW)
|
||||||
#define HWRENDER
|
#define HWRENDER
|
||||||
#endif
|
#endif
|
||||||
// judgecutor: 3D sound support
|
|
||||||
#if !defined(HW3SOUND) && !defined (NOHS)
|
|
||||||
#define HW3SOUND
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
@ -165,32 +159,13 @@ extern char logfilename[1024];
|
||||||
// Please change to apply to your modification (we don't want everyone asking where your mod is on SRB2.org!).
|
// Please change to apply to your modification (we don't want everyone asking where your mod is on SRB2.org!).
|
||||||
#define UPDATE_ALERT_STRING \
|
#define UPDATE_ALERT_STRING \
|
||||||
"A new update is available for SRB2Kart.\n"\
|
"A new update is available for SRB2Kart.\n"\
|
||||||
"Please visit mb.srb2.org to download it.\n"\
|
"Please visit kartkrew.org to download it.\n"\
|
||||||
"\n"\
|
"\n"\
|
||||||
"You are using version: %s\n"\
|
"You are using version: %s\n"\
|
||||||
"The newest version is: %s\n"\
|
"The newest version is: %s\n"\
|
||||||
"\n"\
|
"\n"\
|
||||||
"This update is required for online\n"\
|
|
||||||
"play using the Master Server.\n"\
|
|
||||||
"You will not be able to connect to\n"\
|
|
||||||
"the Master Server until you update to\n"\
|
|
||||||
"the newest version of the game.\n"\
|
|
||||||
"\n"\
|
|
||||||
"(Press a key)\n"
|
"(Press a key)\n"
|
||||||
|
|
||||||
// The string used in the I_Error alert upon trying to host through command line parameters.
|
|
||||||
// Generally less filled with newlines, since Windows gives you lots more room to work with.
|
|
||||||
#define UPDATE_ALERT_STRING_CONSOLE \
|
|
||||||
"A new update is available for SRB2Kart.\n"\
|
|
||||||
"Please visit mb.srb2.org to download it.\n"\
|
|
||||||
"\n"\
|
|
||||||
"You are using version: %s\n"\
|
|
||||||
"The newest version is: %s\n"\
|
|
||||||
"\n"\
|
|
||||||
"This update is required for online play using the Master Server.\n"\
|
|
||||||
"You will not be able to connect to the Master Server\n"\
|
|
||||||
"until you update to the newest version of the game.\n"
|
|
||||||
|
|
||||||
// For future use, the codebase is the version of SRB2 that the modification is based on,
|
// For future use, the codebase is the version of SRB2 that the modification is based on,
|
||||||
// and should not be changed unless you have merged changes between versions of SRB2
|
// and should not be changed unless you have merged changes between versions of SRB2
|
||||||
// (such as 2.0.4 to 2.0.5, etc) into your working copy.
|
// (such as 2.0.4 to 2.0.5, etc) into your working copy.
|
||||||
|
|
@ -683,4 +658,10 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||||
/// MIDI support is really shitty -- we don't use it anyway, so lets throw it behind a define
|
/// MIDI support is really shitty -- we don't use it anyway, so lets throw it behind a define
|
||||||
#define NO_MIDI
|
#define NO_MIDI
|
||||||
|
|
||||||
|
#if defined (HAVE_CURL) && ! defined (NONET)
|
||||||
|
#define MASTERSERVER
|
||||||
|
#else
|
||||||
|
#undef UPDATE_ALERT
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __DOOMDEF__
|
#endif // __DOOMDEF__
|
||||||
|
|
|
||||||
13
src/g_game.c
13
src/g_game.c
|
|
@ -58,6 +58,10 @@
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
#include "discord.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
gameaction_t gameaction;
|
gameaction_t gameaction;
|
||||||
gamestate_t gamestate = GS_NULL;
|
gamestate_t gamestate = GS_NULL;
|
||||||
UINT8 ultimatemode = false;
|
UINT8 ultimatemode = false;
|
||||||
|
|
@ -471,6 +475,7 @@ player_t *seenplayer; // player we're aiming at right now
|
||||||
// now automatically allocated in D_RegisterClientCommands
|
// now automatically allocated in D_RegisterClientCommands
|
||||||
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
|
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
|
||||||
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||||
|
INT32 player_name_changes[MAXPLAYERS];
|
||||||
|
|
||||||
// Allocation for time and nights data
|
// Allocation for time and nights data
|
||||||
void G_AllocMainRecordData(INT16 i)
|
void G_AllocMainRecordData(INT16 i)
|
||||||
|
|
@ -1957,6 +1962,11 @@ void G_Ticker(boolean run)
|
||||||
if (camtoggledelay[i])
|
if (camtoggledelay[i])
|
||||||
camtoggledelay[i]--;
|
camtoggledelay[i]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gametic % NAMECHANGERATE == 0)
|
||||||
|
{
|
||||||
|
memset(player_name_changes, 0, sizeof player_name_changes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4744,6 +4754,9 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
|
||||||
void G_SetGamestate(gamestate_t newstate)
|
void G_SetGamestate(gamestate_t newstate)
|
||||||
{
|
{
|
||||||
gamestate = newstate;
|
gamestate = newstate;
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These functions handle the exitgame flag. Before, when the user
|
/* These functions handle the exitgame flag. Before, when the user
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ extern char customversionstring[32];
|
||||||
#ifdef SEENAMES
|
#ifdef SEENAMES
|
||||||
extern player_t *seenplayer;
|
extern player_t *seenplayer;
|
||||||
#endif
|
#endif
|
||||||
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||||
|
extern INT32 player_name_changes[MAXPLAYERS];
|
||||||
|
|
||||||
extern player_t players[MAXPLAYERS];
|
extern player_t players[MAXPLAYERS];
|
||||||
extern boolean playeringame[MAXPLAYERS];
|
extern boolean playeringame[MAXPLAYERS];
|
||||||
|
|
|
||||||
275
src/http-mserv.c
275
src/http-mserv.c
|
|
@ -11,10 +11,12 @@
|
||||||
/*
|
/*
|
||||||
Documentation available here.
|
Documentation available here.
|
||||||
|
|
||||||
<http://mb.srb2.org/MS/tools/api/v1/>
|
<https://ms.kartkrew.org/tools/api/2/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_clisrv.h"
|
#include "d_clisrv.h"
|
||||||
|
|
@ -49,6 +51,8 @@ consvar_t cv_masterserver_token = {
|
||||||
NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */
|
NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef MASTERSERVER
|
||||||
|
|
||||||
static int hms_started;
|
static int hms_started;
|
||||||
|
|
||||||
static char *hms_api;
|
static char *hms_api;
|
||||||
|
|
@ -137,7 +141,7 @@ HMS_connect (const char *format, ...)
|
||||||
if (cv_masterserver_token.string[0])
|
if (cv_masterserver_token.string[0])
|
||||||
{
|
{
|
||||||
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
|
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
|
||||||
token_length = ( sizeof "?token="-1 )+ strlen(quack_token);
|
token_length = ( sizeof "&token="-1 )+ strlen(quack_token);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +156,9 @@ HMS_connect (const char *format, ...)
|
||||||
seek = strlen(hms_api) + 1;/* + '/' */
|
seek = strlen(hms_api) + 1;/* + '/' */
|
||||||
|
|
||||||
va_start (ap, format);
|
va_start (ap, format);
|
||||||
url = malloc(seek + vsnprintf(0, 0, format, ap) + token_length + 1);
|
url = malloc(seek + vsnprintf(0, 0, format, ap) +
|
||||||
|
sizeof "?v=2" - 1 +
|
||||||
|
token_length + 1);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
sprintf(url, "%s/", hms_api);
|
sprintf(url, "%s/", hms_api);
|
||||||
|
|
@ -165,8 +171,11 @@ HMS_connect (const char *format, ...)
|
||||||
seek += vsprintf(&url[seek], format, ap);
|
seek += vsprintf(&url[seek], format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
|
strcpy(&url[seek], "?v=2");
|
||||||
|
seek += sizeof "?v=2" - 1;
|
||||||
|
|
||||||
if (quack_token)
|
if (quack_token)
|
||||||
sprintf(&url[seek], "?token=%s", quack_token);
|
sprintf(&url[seek], "&token=%s", quack_token);
|
||||||
|
|
||||||
CONS_Printf("HMS: connecting '%s'...\n", url);
|
CONS_Printf("HMS: connecting '%s'...\n", url);
|
||||||
|
|
||||||
|
|
@ -254,117 +263,6 @@ HMS_end (struct HMS_buffer *buffer)
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
HMS_fetch_rooms (int joining, int query_id)
|
|
||||||
{
|
|
||||||
struct HMS_buffer *hms;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
int doing_shit;
|
|
||||||
|
|
||||||
char *id;
|
|
||||||
char *title;
|
|
||||||
char *room_motd;
|
|
||||||
|
|
||||||
int id_no;
|
|
||||||
|
|
||||||
char *p;
|
|
||||||
char *end;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
(void)query_id;
|
|
||||||
|
|
||||||
hms = HMS_connect("rooms");
|
|
||||||
|
|
||||||
if (! hms)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (HMS_do(hms))
|
|
||||||
{
|
|
||||||
doing_shit = 1;
|
|
||||||
|
|
||||||
p = hms->buffer;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_LIST_ROOMS && ( end = strstr(p, "\n\n\n") );)
|
|
||||||
{
|
|
||||||
*end = '\0';
|
|
||||||
|
|
||||||
id = strtok(p, "\n");
|
|
||||||
title = strtok(0, "\n");
|
|
||||||
room_motd = strtok(0, "");
|
|
||||||
|
|
||||||
if (id && title && room_motd)
|
|
||||||
{
|
|
||||||
id_no = atoi(id);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Don't show the 'All' room if hosting. And it's a hack like this
|
|
||||||
because I'm way too lazy to add another feature to the MS.
|
|
||||||
*/
|
|
||||||
if (joining || id_no != 0)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_THREADS
|
|
||||||
I_lock_mutex(&ms_QueryId_mutex);
|
|
||||||
{
|
|
||||||
if (query_id != ms_QueryId)
|
|
||||||
doing_shit = 0;
|
|
||||||
}
|
|
||||||
I_unlock_mutex(ms_QueryId_mutex);
|
|
||||||
|
|
||||||
if (! doing_shit)
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
room_list[i].header.buffer[0] = 1;
|
|
||||||
|
|
||||||
room_list[i].id = id_no;
|
|
||||||
strlcpy(room_list[i].name, title, sizeof room_list[i].name);
|
|
||||||
strlcpy(room_list[i].motd, room_motd, sizeof room_list[i].motd);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = ( end + 3 );/* skip the three linefeeds */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doing_shit)
|
|
||||||
room_list[i].header.buffer[0] = 0;
|
|
||||||
|
|
||||||
ok = 1;
|
|
||||||
|
|
||||||
if (doing_shit)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_THREADS
|
|
||||||
I_lock_mutex(&m_menu_mutex);
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
for (i = 0; room_list[i].header.buffer[0]; i++)
|
|
||||||
{
|
|
||||||
if(*room_list[i].name != '\0')
|
|
||||||
{
|
|
||||||
MP_RoomMenu[i+1].text = room_list[i].name;
|
|
||||||
roomIds[i] = room_list[i].id;
|
|
||||||
MP_RoomMenu[i+1].status = IT_STRING|IT_CALL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef HAVE_THREADS
|
|
||||||
I_unlock_mutex(m_menu_mutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ok = 0;
|
|
||||||
|
|
||||||
HMS_end(hms);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
HMS_register (void)
|
HMS_register (void)
|
||||||
{
|
{
|
||||||
|
|
@ -373,28 +271,26 @@ HMS_register (void)
|
||||||
|
|
||||||
char post[256];
|
char post[256];
|
||||||
|
|
||||||
char *title;
|
char *contact;
|
||||||
|
|
||||||
hms = HMS_connect("rooms/%d/register", ms_RoomId);
|
hms = HMS_connect(
|
||||||
|
"games/%s/%d/servers/register", SRB2APPLICATION, MODVERSION);
|
||||||
|
|
||||||
if (! hms)
|
if (! hms)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
title = curl_easy_escape(hms->curl, cv_servername.string, 0);
|
contact = curl_easy_escape(hms->curl, cv_server_contact.string, 0);
|
||||||
|
|
||||||
snprintf(post, sizeof post,
|
snprintf(post, sizeof post,
|
||||||
"port=%d&"
|
"port=%d&"
|
||||||
"title=%s&"
|
"contact=%s",
|
||||||
"version=%s",
|
|
||||||
|
|
||||||
current_port,
|
current_port,
|
||||||
|
|
||||||
title,
|
contact
|
||||||
|
|
||||||
SRB2VERSION
|
|
||||||
);
|
);
|
||||||
|
|
||||||
curl_free(title);
|
curl_free(contact);
|
||||||
|
|
||||||
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
|
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
|
||||||
|
|
||||||
|
|
@ -468,19 +364,13 @@ HMS_list_servers (void)
|
||||||
{
|
{
|
||||||
struct HMS_buffer *hms;
|
struct HMS_buffer *hms;
|
||||||
|
|
||||||
char *p;
|
hms = HMS_connect("games/%s/%d/servers", SRB2APPLICATION, MODVERSION);
|
||||||
|
|
||||||
hms = HMS_connect("servers");
|
|
||||||
|
|
||||||
if (! hms)
|
if (! hms)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HMS_do(hms))
|
if (HMS_do(hms))
|
||||||
{
|
{
|
||||||
p = &hms->buffer[strlen(hms->buffer)];
|
|
||||||
while (*--p == '\n')
|
|
||||||
;
|
|
||||||
|
|
||||||
CONS_Printf("%s\n", hms->buffer);
|
CONS_Printf("%s\n", hms->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,35 +378,24 @@ HMS_list_servers (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_server_t *
|
msg_server_t *
|
||||||
HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
|
HMS_fetch_servers (msg_server_t *list, int query_id)
|
||||||
{
|
{
|
||||||
struct HMS_buffer *hms;
|
struct HMS_buffer *hms;
|
||||||
|
|
||||||
int doing_shit;
|
int doing_shit;
|
||||||
|
|
||||||
char local_version[9];
|
|
||||||
|
|
||||||
char *room;
|
|
||||||
|
|
||||||
char *address;
|
char *address;
|
||||||
char *port;
|
char *port;
|
||||||
char *title;
|
char *contact;
|
||||||
char *version;
|
|
||||||
|
|
||||||
char *end;
|
char *end;
|
||||||
char *section_end;
|
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
(void)query_id;
|
(void)query_id;
|
||||||
|
|
||||||
if (room_number > 0)
|
hms = HMS_connect("games/%s/%d/servers", SRB2APPLICATION, MODVERSION);
|
||||||
{
|
|
||||||
hms = HMS_connect("rooms/%d/servers", room_number);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
hms = HMS_connect("servers");
|
|
||||||
|
|
||||||
if (! hms)
|
if (! hms)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -525,80 +404,51 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
|
||||||
{
|
{
|
||||||
doing_shit = 1;
|
doing_shit = 1;
|
||||||
|
|
||||||
snprintf(local_version, sizeof local_version,
|
|
||||||
"%s",
|
|
||||||
SRB2VERSION
|
|
||||||
);
|
|
||||||
|
|
||||||
p = hms->buffer;
|
p = hms->buffer;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
do
|
while (i < MAXSERVERLIST && ( end = strchr(p, '\n') ))
|
||||||
{
|
{
|
||||||
section_end = strstr(p, "\n\n");
|
*end = '\0';
|
||||||
|
|
||||||
room = strtok(p, "\n");
|
address = strtok(p, " ");
|
||||||
|
port = strtok(0, " ");
|
||||||
|
contact = strtok(0, "");
|
||||||
|
|
||||||
p = strtok(0, "");
|
if (address && port)
|
||||||
|
|
||||||
if (! p)
|
|
||||||
break;
|
|
||||||
|
|
||||||
while (i < MAXSERVERLIST && ( end = strchr(p, '\n') ))
|
|
||||||
{
|
{
|
||||||
*end = '\0';
|
|
||||||
|
|
||||||
address = strtok(p, " ");
|
|
||||||
port = strtok(0, " ");
|
|
||||||
title = strtok(0, " ");
|
|
||||||
version = strtok(0, "");
|
|
||||||
|
|
||||||
if (address && port && title && version)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
I_lock_mutex(&ms_QueryId_mutex);
|
I_lock_mutex(&ms_QueryId_mutex);
|
||||||
{
|
{
|
||||||
if (query_id != ms_QueryId)
|
if (query_id != ms_QueryId)
|
||||||
doing_shit = 0;
|
doing_shit = 0;
|
||||||
}
|
}
|
||||||
I_unlock_mutex(ms_QueryId_mutex);
|
I_unlock_mutex(ms_QueryId_mutex);
|
||||||
|
|
||||||
if (! doing_shit)
|
if (! doing_shit)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (strcmp(version, local_version) == 0)
|
strlcpy(list[i].ip, address, sizeof list[i].ip);
|
||||||
{
|
strlcpy(list[i].port, port, sizeof list[i].port);
|
||||||
strlcpy(list[i].ip, address, sizeof list[i].ip);
|
|
||||||
strlcpy(list[i].port, port, sizeof list[i].port);
|
|
||||||
strlcpy(list[i].name, title, sizeof list[i].name);
|
|
||||||
strlcpy(list[i].version, version, sizeof list[i].version);
|
|
||||||
|
|
||||||
list[i].room = atoi(room);
|
if (contact)
|
||||||
|
|
||||||
list[i].header.buffer[0] = 1;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end == section_end)/* end of list for this room */
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
p = ( end + 1 );/* skip server delimiter */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
section_end = 0;/* malformed so quit the parsing */
|
strlcpy(list[i].contact, contact, sizeof list[i].contact);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list[i].header.buffer[0] = 1;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
p = ( end + 1 );/* skip server delimiter */
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (! doing_shit)
|
{
|
||||||
|
/* malformed so quit the parsing */
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
p = ( section_end + 2 );
|
|
||||||
}
|
}
|
||||||
while (section_end) ;
|
|
||||||
|
|
||||||
if (doing_shit)
|
if (doing_shit)
|
||||||
list[i].header.buffer[0] = 0;
|
list[i].header.buffer[0] = 0;
|
||||||
|
|
@ -620,7 +470,7 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
|
||||||
char *version;
|
char *version;
|
||||||
char *version_name;
|
char *version_name;
|
||||||
|
|
||||||
hms = HMS_connect("versions/%d", MODID);
|
hms = HMS_connect("games/%s/version", SRB2APPLICATION);
|
||||||
|
|
||||||
if (! hms)
|
if (! hms)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -649,6 +499,19 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
Strip_trailing_slashes (char *api)
|
||||||
|
{
|
||||||
|
char * p = &api[strlen(api)];
|
||||||
|
|
||||||
|
while (*--p == '/')
|
||||||
|
;
|
||||||
|
|
||||||
|
p[1] = '\0';
|
||||||
|
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HMS_set_api (char *api)
|
HMS_set_api (char *api)
|
||||||
{
|
{
|
||||||
|
|
@ -657,17 +520,21 @@ HMS_set_api (char *api)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
free(hms_api);
|
free(hms_api);
|
||||||
hms_api = api;
|
hms_api = Strip_trailing_slashes(api);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
I_unlock_mutex(hms_api_mutex);
|
I_unlock_mutex(hms_api_mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MasterServer_Debug_OnChange (void)
|
MasterServer_Debug_OnChange (void)
|
||||||
{
|
{
|
||||||
|
#ifdef MASTERSERVER
|
||||||
/* TODO: change to 'latest-log.txt' for log files revision. */
|
/* TODO: change to 'latest-log.txt' for log files revision. */
|
||||||
if (cv_masterserver_debug.value)
|
if (cv_masterserver_debug.value)
|
||||||
CONS_Printf("Master server debug messages will appear in log.txt\n");
|
CONS_Printf("Master server debug messages will appear in log.txt\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
281
src/k_kart.c
281
src/k_kart.c
|
|
@ -306,35 +306,35 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
|
||||||
/*Jawz x2*/ { 0, 0, 1, 2, 0, 0, 0, 0 } // Jawz x2
|
/*Jawz x2*/ { 0, 0, 1, 2, 0, 0, 0, 0 } // Jawz x2
|
||||||
};
|
};
|
||||||
|
|
||||||
static INT32 K_KartItemOddsBattle[NUMKARTRESULTS-1][6] =
|
static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
|
||||||
{
|
{
|
||||||
//P-Odds 0 1 2 3 4 5
|
//P-Odds 0 1
|
||||||
/*Sneaker*/ { 3, 2, 2, 2, 0, 2 }, // Sneaker
|
/*Sneaker*/ { 2, 1 }, // Sneaker
|
||||||
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 0 }, // Rocket Sneaker
|
/*Rocket Sneaker*/ { 0, 0 }, // Rocket Sneaker
|
||||||
/*Invincibility*/ { 0, 1, 2, 3, 4, 2 }, // Invincibility
|
/*Invincibility*/ { 2, 1 }, // Invincibility
|
||||||
/*Banana*/ { 2, 1, 0, 0, 0, 0 }, // Banana
|
/*Banana*/ { 1, 0 }, // Banana
|
||||||
/*Eggman Monitor*/ { 1, 1, 0, 0, 0, 0 }, // Eggman Monitor
|
/*Eggman Monitor*/ { 1, 0 }, // Eggman Monitor
|
||||||
/*Orbinaut*/ { 6, 2, 1, 0, 0, 0 }, // Orbinaut
|
/*Orbinaut*/ { 8, 0 }, // Orbinaut
|
||||||
/*Jawz*/ { 3, 3, 3, 2, 0, 2 }, // Jawz
|
/*Jawz*/ { 8, 1 }, // Jawz
|
||||||
/*Mine*/ { 2, 3, 3, 1, 0, 2 }, // Mine
|
/*Mine*/ { 4, 1 }, // Mine
|
||||||
/*Ballhog*/ { 0, 1, 2, 1, 0, 2 }, // Ballhog
|
/*Ballhog*/ { 2, 1 }, // Ballhog
|
||||||
/*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 0 }, // Self-Propelled Bomb
|
/*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb
|
||||||
/*Grow*/ { 0, 0, 1, 2, 4, 2 }, // Grow
|
/*Grow*/ { 2, 1 }, // Grow
|
||||||
/*Shrink*/ { 0, 0, 0, 0, 0, 0 }, // Shrink
|
/*Shrink*/ { 0, 0 }, // Shrink
|
||||||
/*Thunder Shield*/ { 0, 0, 0, 0, 0, 0 }, // Thunder Shield
|
/*Thunder Shield*/ { 0, 0 }, // Thunder Shield
|
||||||
/*Bubble Shield*/ { 0, 0, 0, 0, 0, 0 }, // Bubble Shield
|
/*Bubble Shield*/ { 0, 0 }, // Bubble Shield
|
||||||
/*Flame Shield*/ { 0, 0, 0, 0, 0, 0 }, // Flame Shield
|
/*Flame Shield*/ { 0, 0 }, // Flame Shield
|
||||||
/*Hyudoro*/ { 1, 1, 0, 0, 0, 0 }, // Hyudoro
|
/*Hyudoro*/ { 2, 0 }, // Hyudoro
|
||||||
/*Pogo Spring*/ { 1, 1, 0, 0, 0, 0 }, // Pogo Spring
|
/*Pogo Spring*/ { 2, 0 }, // Pogo Spring
|
||||||
/*Super Ring*/ { 0, 0, 0, 0, 0, 0 }, // Super Ring
|
/*Super Ring*/ { 0, 0 }, // Super Ring
|
||||||
/*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0 }, // Kitchen Sink
|
/*Kitchen Sink*/ { 0, 0 }, // Kitchen Sink
|
||||||
/*Sneaker x2*/ { 0, 0, 0, 0, 0, 0 }, // Sneaker x2
|
/*Sneaker x2*/ { 0, 0 }, // Sneaker x2
|
||||||
/*Sneaker x3*/ { 0, 0, 0, 2, 4, 2 }, // Sneaker x3
|
/*Sneaker x3*/ { 0, 1 }, // Sneaker x3
|
||||||
/*Banana x3*/ { 1, 2, 1, 0, 0, 0 }, // Banana x3
|
/*Banana x3*/ { 1, 0 }, // Banana x3
|
||||||
/*Banana x10*/ { 0, 0, 1, 1, 0, 2 }, // Banana x10
|
/*Banana x10*/ { 0, 1 }, // Banana x10
|
||||||
/*Orbinaut x3*/ { 0, 1, 2, 1, 0, 0 }, // Orbinaut x3
|
/*Orbinaut x3*/ { 2, 0 }, // Orbinaut x3
|
||||||
/*Orbinaut x4*/ { 0, 0, 1, 3, 4, 2 }, // Orbinaut x4
|
/*Orbinaut x4*/ { 1, 1 }, // Orbinaut x4
|
||||||
/*Jawz x2*/ { 0, 0, 1, 2, 4, 2 } // Jawz x2
|
/*Jawz x2*/ { 2, 1 } // Jawz x2
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DISTVAR (2048) // Magic number distance for use with item roulette tiers
|
#define DISTVAR (2048) // Magic number distance for use with item roulette tiers
|
||||||
|
|
@ -620,19 +620,20 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush,
|
||||||
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush)
|
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
UINT8 n = 0;
|
|
||||||
UINT8 useodds = 0;
|
UINT8 useodds = 0;
|
||||||
UINT8 disttable[14];
|
UINT8 disttable[14];
|
||||||
UINT8 totallen = 0;
|
|
||||||
UINT8 distlen = 0;
|
UINT8 distlen = 0;
|
||||||
boolean oddsvalid[8];
|
boolean oddsvalid[8];
|
||||||
|
|
||||||
|
// Unused now, oops :V
|
||||||
|
(void)bestbumper;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
UINT8 j;
|
UINT8 j;
|
||||||
boolean available = false;
|
boolean available = false;
|
||||||
|
|
||||||
if (gametype == GT_BATTLE && i > 5)
|
if (gametype == GT_BATTLE && i > 1)
|
||||||
{
|
{
|
||||||
oddsvalid[i] = false;
|
oddsvalid[i] = false;
|
||||||
break;
|
break;
|
||||||
|
|
@ -653,30 +654,24 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
||||||
#define SETUPDISTTABLE(odds, num) \
|
#define SETUPDISTTABLE(odds, num) \
|
||||||
if (oddsvalid[odds]) \
|
if (oddsvalid[odds]) \
|
||||||
for (i = num; i; --i) \
|
for (i = num; i; --i) \
|
||||||
disttable[distlen++] = odds; \
|
disttable[distlen++] = odds;
|
||||||
totallen += num;
|
|
||||||
|
|
||||||
if (gametype == GT_BATTLE) // Battle Mode
|
if (gametype == GT_BATTLE) // Battle Mode
|
||||||
{
|
{
|
||||||
SETUPDISTTABLE(0,1);
|
if (player->kartstuff[k_roulettetype] == 1 && oddsvalid[1] == true)
|
||||||
SETUPDISTTABLE(1,1);
|
{
|
||||||
SETUPDISTTABLE(2,1);
|
// 1 is the extreme odds of player-controlled "Karma" items
|
||||||
SETUPDISTTABLE(3,1);
|
useodds = 1;
|
||||||
SETUPDISTTABLE(4,1);
|
}
|
||||||
|
|
||||||
if (player->kartstuff[k_roulettetype] == 1 && oddsvalid[5]) // 5 is the extreme odds of player-controlled "Karma" items
|
|
||||||
useodds = 5;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SINT8 wantedpos = (bestbumper-player->kartstuff[k_bumper]); // 0 is the best player's bumper count, 1 is a bumper below best, 2 is two bumpers below, etc
|
useodds = 0;
|
||||||
if (K_IsPlayerWanted(player))
|
|
||||||
wantedpos++;
|
if (oddsvalid[0] == false && oddsvalid[1] == true)
|
||||||
if (wantedpos > 4) // Don't run off into karma items
|
{
|
||||||
wantedpos = 4;
|
// try to use karma odds as a fallback
|
||||||
if (wantedpos < 0) // Don't go below somehow
|
useodds = 1;
|
||||||
wantedpos = 0;
|
}
|
||||||
n = (wantedpos * distlen) / totallen;
|
|
||||||
useodds = disttable[n];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1240,7 +1235,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Checks that the player is on an offroad subsector for realsies
|
/** \brief Checks that the player is on an offroad subsector for realsies. Also accounts for line riding to prevent cheese.
|
||||||
|
|
||||||
\param mo player mobj object
|
\param mo player mobj object
|
||||||
|
|
||||||
|
|
@ -1248,18 +1243,64 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||||
*/
|
*/
|
||||||
static UINT8 K_CheckOffroadCollide(mobj_t *mo)
|
static UINT8 K_CheckOffroadCollide(mobj_t *mo)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
// Check for sectors in touching_sectorlist
|
||||||
|
UINT8 i; // special type iter
|
||||||
|
msecnode_t *node; // touching_sectorlist iter
|
||||||
|
sector_t *s; // main sector shortcut
|
||||||
|
sector_t *s2; // FOF sector shortcut
|
||||||
|
ffloor_t *rover; // FOF
|
||||||
|
|
||||||
|
fixed_t flr;
|
||||||
|
fixed_t cel; // floor & ceiling for height checks to make sure we're touching the offroad sector.
|
||||||
|
|
||||||
I_Assert(mo != NULL);
|
I_Assert(mo != NULL);
|
||||||
I_Assert(!P_MobjWasRemoved(mo));
|
I_Assert(!P_MobjWasRemoved(mo));
|
||||||
|
|
||||||
for (i = 2; i < 5; i++)
|
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||||
{
|
{
|
||||||
if (P_MobjTouchingSectorSpecial(mo, 1, i, true))
|
if (!node->m_sector)
|
||||||
return i-1;
|
break; // shouldn't happen.
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
s = node->m_sector;
|
||||||
|
// 1: Check for the main sector, make sure we're on the floor of that sector and see if we can apply offroad.
|
||||||
|
// Make arbitrary Z checks because we want to check for 1 sector in particular, we don't want to affect the player if the offroad sector is way below them and they're lineriding a normal sector above.
|
||||||
|
|
||||||
|
flr = P_MobjFloorZ(mo, s, s, mo->x, mo->y, NULL, false, true);
|
||||||
|
cel = P_MobjCeilingZ(mo, s, s, mo->x, mo->y, NULL, true, true); // get Z coords of both floors and ceilings for this sector (this accounts for slopes properly.)
|
||||||
|
// NOTE: we don't use P_GetZAt with our x/y directly because the mobj won't have the same height because of its hitbox on the slope. Complex garbage but tldr it doesn't work.
|
||||||
|
|
||||||
|
if ( ((s->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == flr) // floor check
|
||||||
|
|| ((mo->eflags & MFE_VERTICALFLIP && (s->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == cel)) ) // ceiling check.
|
||||||
|
|
||||||
|
for (i = 2; i < 5; i++) // check for sector special
|
||||||
|
|
||||||
|
if (GETSECSPECIAL(s->special, 1) == i)
|
||||||
|
return i-1; // return offroad type
|
||||||
|
|
||||||
|
// 2: If we're here, we haven't found anything. So let's try looking for FOFs in the sectors using the same logic.
|
||||||
|
for (rover = s->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (!(rover->flags & FF_EXISTS)) // This FOF doesn't exist anymore.
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s2 = §ors[rover->secnum]; // makes things easier for us
|
||||||
|
|
||||||
|
flr = P_GetFOFBottomZ(mo, s, rover, mo->x, mo->y, NULL);
|
||||||
|
cel = P_GetFOFTopZ(mo, s, rover, mo->x, mo->y, NULL); // Z coords for fof top/bottom.
|
||||||
|
|
||||||
|
// we will do essentially the same checks as above instead of bothering with top/bottom height of the FOF.
|
||||||
|
// Reminder that an FOF's floor is its bottom, silly!
|
||||||
|
if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check
|
||||||
|
|| ((s2->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == flr) ) // "ceiling" check.
|
||||||
|
|
||||||
|
for (i = 2; i < 5; i++) // check for sector special
|
||||||
|
|
||||||
|
if (GETSECSPECIAL(s2->special, 1) == i)
|
||||||
|
return i-1; // return offroad type
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // couldn't find any offroad
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Updates the Player's offroad value once per frame
|
/** \brief Updates the Player's offroad value once per frame
|
||||||
|
|
@ -3680,13 +3721,13 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
|
||||||
mine->flags2 = thismine->flags2;
|
mine->flags2 = thismine->flags2;
|
||||||
mine->floorz = thismine->floorz;
|
mine->floorz = thismine->floorz;
|
||||||
mine->ceilingz = thismine->ceilingz;
|
mine->ceilingz = thismine->ceilingz;
|
||||||
|
|
||||||
//Since we aren't using P_KillMobj, we need to clean up the hnext reference
|
//Since we aren't using P_KillMobj, we need to clean up the hnext reference
|
||||||
{
|
{
|
||||||
P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine
|
P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine
|
||||||
thismine->target->player->kartstuff[k_bananadrag] = 0;
|
thismine->target->player->kartstuff[k_bananadrag] = 0;
|
||||||
thismine->target->player->kartstuff[k_itemheld] = 0;
|
thismine->target->player->kartstuff[k_itemheld] = 0;
|
||||||
|
|
||||||
if (--thismine->target->player->kartstuff[k_itemamount] <= 0)
|
if (--thismine->target->player->kartstuff[k_itemamount] <= 0)
|
||||||
thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE;
|
thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE;
|
||||||
}
|
}
|
||||||
|
|
@ -4340,7 +4381,7 @@ void K_DropRocketSneaker(player_t *player)
|
||||||
flingangle = -(ANG60);
|
flingangle = -(ANG60);
|
||||||
else
|
else
|
||||||
flingangle = ANG60;
|
flingangle = ANG60;
|
||||||
|
|
||||||
S_StartSound(shoe, shoe->info->deathsound);
|
S_StartSound(shoe, shoe->info->deathsound);
|
||||||
P_SetObjectMomZ(shoe, 8*FRACUNIT, false);
|
P_SetObjectMomZ(shoe, 8*FRACUNIT, false);
|
||||||
P_InstaThrust(shoe, R_PointToAngle2(shoe->target->x, shoe->target->y, shoe->x, shoe->y)+flingangle, 16*FRACUNIT);
|
P_InstaThrust(shoe, R_PointToAngle2(shoe->target->x, shoe->target->y, shoe->x, shoe->y)+flingangle, 16*FRACUNIT);
|
||||||
|
|
@ -4944,14 +4985,22 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
|
||||||
static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
const INT32 numsnds = 13;
|
const INT32 numsnds = 13;
|
||||||
|
|
||||||
|
const fixed_t closedist = 160*FRACUNIT;
|
||||||
|
const fixed_t fardist = 1536*FRACUNIT;
|
||||||
|
|
||||||
|
const UINT8 dampenval = 48; // 255 * 48 = close enough to FRACUNIT/6
|
||||||
|
|
||||||
INT32 class, s, w; // engine class number
|
INT32 class, s, w; // engine class number
|
||||||
|
|
||||||
UINT8 volume = 255;
|
UINT8 volume = 255;
|
||||||
fixed_t volumedampen = 0;
|
fixed_t volumedampen = FRACUNIT;
|
||||||
|
|
||||||
INT32 targetsnd = 0;
|
INT32 targetsnd = 0;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
s = (player->kartspeed-1)/3;
|
s = (player->kartspeed - 1) / 3;
|
||||||
w = (player->kartweight-1)/3;
|
w = (player->kartweight - 1) / 3;
|
||||||
|
|
||||||
#define LOCKSTAT(stat) \
|
#define LOCKSTAT(stat) \
|
||||||
if (stat < 0) { stat = 0; } \
|
if (stat < 0) { stat = 0; } \
|
||||||
|
|
@ -4960,83 +5009,119 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
||||||
LOCKSTAT(w);
|
LOCKSTAT(w);
|
||||||
#undef LOCKSTAT
|
#undef LOCKSTAT
|
||||||
|
|
||||||
class = s+(3*w);
|
class = s + (3*w);
|
||||||
|
|
||||||
// Silence the engines
|
|
||||||
if (leveltime < 8 || player->spectator)
|
if (leveltime < 8 || player->spectator)
|
||||||
{
|
{
|
||||||
player->karthud[khud_enginesnd] = 0; // Reset sound number
|
// Silence the engines, and reset sound number while we're at it.
|
||||||
|
player->karthud[khud_enginesnd] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ((leveltime % 8) != ((player-players) % 8)) // Per-player offset, to make engines sound distinct!
|
if ((leveltime % 8) != ((player-players) % 8)) // Per-player offset, to make engines sound distinct!
|
||||||
#else
|
#else
|
||||||
if (leveltime % 8) // .25 seconds of wait time between engine sounds
|
if (leveltime % 8)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
// .25 seconds of wait time between each engine sound playback
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (player->respawn.state == RESPAWNST_DROP) // Dropdashing
|
if (player->respawn.state == RESPAWNST_DROP) // Dropdashing
|
||||||
|
{
|
||||||
|
// Dropdashing
|
||||||
targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0);
|
targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0);
|
||||||
else if (K_PlayerEBrake(player) == true) // Spindashing
|
}
|
||||||
|
else if (K_PlayerEBrake(player) == true)
|
||||||
|
{
|
||||||
|
// Spindashing
|
||||||
targetsnd = ((cmd->buttons & BT_DRIFT) ? 12 : 0);
|
targetsnd = ((cmd->buttons & BT_DRIFT) ? 12 : 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
targetsnd = (((6*K_GetForwardMove(player))/25) + ((player->speed / mapobjectscale)/5))/2;
|
{
|
||||||
|
// Average out the value of forwardmove and the speed that you're moving at.
|
||||||
|
targetsnd = (((6 * cmd->forwardmove) / 25) + ((player->speed / mapobjectscale) / 5)) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (targetsnd < 0)
|
if (targetsnd < 0) { targetsnd = 0; }
|
||||||
targetsnd = 0;
|
if (targetsnd > 12) { targetsnd = 12; }
|
||||||
if (targetsnd > 12)
|
|
||||||
targetsnd = 12;
|
|
||||||
|
|
||||||
if (player->karthud[khud_enginesnd] < targetsnd)
|
if (player->karthud[khud_enginesnd] < targetsnd) { player->karthud[khud_enginesnd]++; }
|
||||||
player->karthud[khud_enginesnd]++;
|
if (player->karthud[khud_enginesnd] > targetsnd) { player->karthud[khud_enginesnd]--; }
|
||||||
if (player->karthud[khud_enginesnd] > targetsnd)
|
|
||||||
player->karthud[khud_enginesnd]--;
|
|
||||||
|
|
||||||
if (player->karthud[khud_enginesnd] < 0)
|
if (player->karthud[khud_enginesnd] < 0) { player->karthud[khud_enginesnd] = 0; }
|
||||||
player->karthud[khud_enginesnd] = 0;
|
if (player->karthud[khud_enginesnd] > 12) { player->karthud[khud_enginesnd] = 12; }
|
||||||
if (player->karthud[khud_enginesnd] > 12)
|
|
||||||
player->karthud[khud_enginesnd] = 12;
|
// This code calculates how many players (and thus, how many engine sounds) are within ear shot,
|
||||||
|
// and rebalances the volume of your engine sound based on how far away they are.
|
||||||
|
|
||||||
|
// This results in multiple things:
|
||||||
|
// - When on your own, you will hear your own engine sound extremely clearly.
|
||||||
|
// - When you were alone but someone is gaining on you, yours will go quiet, and you can hear theirs more clearly.
|
||||||
|
// - When around tons of people, engine sounds will try to rebalance to not be as obnoxious.
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
UINT8 thisvol = 0;
|
UINT8 thisvol = 0;
|
||||||
fixed_t dist;
|
fixed_t dist;
|
||||||
|
|
||||||
if (!playeringame[i] || !players[i].mo || players[i].spectator || players[i].exiting)
|
if (!playeringame[i] || !players[i].mo)
|
||||||
continue;
|
|
||||||
|
|
||||||
if (P_IsDisplayPlayer(&players[i]))
|
|
||||||
{
|
{
|
||||||
volumedampen += FRACUNIT; // We already know what this is gonna be, let's not waste our time.
|
// This player doesn't exist.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dist = P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x,
|
if (players[i].spectator)
|
||||||
player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) / 2;
|
{
|
||||||
|
// This player isn't playing an engine sound.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (P_IsDisplayPlayer(&players[i]))
|
||||||
|
{
|
||||||
|
// Don't dampen yourself!
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = P_AproxDistance(
|
||||||
|
P_AproxDistance(
|
||||||
|
player->mo->x - players[i].mo->x,
|
||||||
|
player->mo->y - players[i].mo->y),
|
||||||
|
player->mo->z - players[i].mo->z) / 2;
|
||||||
|
|
||||||
dist = FixedDiv(dist, mapobjectscale);
|
dist = FixedDiv(dist, mapobjectscale);
|
||||||
|
|
||||||
if (dist > 1536<<FRACBITS)
|
if (dist > fardist)
|
||||||
|
{
|
||||||
|
// ENEMY OUT OF RANGE !
|
||||||
continue;
|
continue;
|
||||||
else if (dist < 160<<FRACBITS) // engine sounds' approx. range
|
}
|
||||||
|
else if (dist < closedist)
|
||||||
|
{
|
||||||
|
// engine sounds' approx. range
|
||||||
thisvol = 255;
|
thisvol = 255;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
thisvol = (15 * (((160<<FRACBITS) - dist)>>FRACBITS)) / (((1536<<FRACBITS)-(160<<FRACBITS))>>(FRACBITS+4));
|
{
|
||||||
|
thisvol = (15 * ((closedist - dist) / FRACUNIT)) / ((fardist - closedist) >> (FRACBITS+4));
|
||||||
|
}
|
||||||
|
|
||||||
if (thisvol == 0)
|
volumedampen += (thisvol * dampenval);
|
||||||
continue;
|
|
||||||
|
|
||||||
volumedampen += (thisvol * 257); // 255 * 257 = FRACUNIT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (volumedampen > FRACUNIT)
|
if (volumedampen > FRACUNIT)
|
||||||
volume = FixedDiv(volume<<FRACBITS, volumedampen)>>FRACBITS;
|
{
|
||||||
|
volume = FixedDiv(volume * FRACUNIT, volumedampen) / FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
if (volume <= 0) // Might as well
|
if (volume <= 0)
|
||||||
|
{
|
||||||
|
// Don't need to play the sound at all.
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->karthud[khud_enginesnd]) + (class*numsnds), volume);
|
S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->karthud[khud_enginesnd]) + (class * numsnds), volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_UpdateInvincibilitySounds(player_t *player)
|
static void K_UpdateInvincibilitySounds(player_t *player)
|
||||||
|
|
|
||||||
|
|
@ -3624,41 +3624,6 @@ static int lib_kGetItemPatch(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets the remaining time before players blow up
|
|
||||||
static int lib_kSetRaceCountdown(lua_State *L)
|
|
||||||
{
|
|
||||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
|
||||||
racecountdown = c;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sets the remaining time before the race ends after everyone finishes
|
|
||||||
static int lib_kSetExitCountdown(lua_State *L)
|
|
||||||
{
|
|
||||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
|
||||||
NOHUD
|
|
||||||
exitcountdown = c;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the item cooldown before another shrink / SPB can be rolled
|
|
||||||
static int lib_kSetIndirectItemCountdown(lua_State *L)
|
|
||||||
{
|
|
||||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
|
||||||
NOHUD
|
|
||||||
indirectitemcooldown = c;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the item cooldown before another shrink / SPB can be rolled
|
|
||||||
static int lib_kSetHyuCountdown(lua_State *L)
|
|
||||||
{
|
|
||||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
|
||||||
NOHUD
|
|
||||||
hyubgone = c;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static luaL_Reg lib[] = {
|
static luaL_Reg lib[] = {
|
||||||
{"print", lib_print},
|
{"print", lib_print},
|
||||||
{"chatprint", lib_chatprint},
|
{"chatprint", lib_chatprint},
|
||||||
|
|
@ -3920,10 +3885,6 @@ static luaL_Reg lib[] = {
|
||||||
{"K_GetKartAccel",lib_kGetKartAccel},
|
{"K_GetKartAccel",lib_kGetKartAccel},
|
||||||
{"K_GetKartFlashing",lib_kGetKartFlashing},
|
{"K_GetKartFlashing",lib_kGetKartFlashing},
|
||||||
{"K_GetItemPatch",lib_kGetItemPatch},
|
{"K_GetItemPatch",lib_kGetItemPatch},
|
||||||
{"K_SetRaceCountdown",lib_kSetRaceCountdown},
|
|
||||||
{"K_SetExitCountdown",lib_kSetExitCountdown},
|
|
||||||
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
|
|
||||||
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
|
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -370,7 +370,11 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
||||||
} else if (fastcmp(word,"exitcountdown")) {
|
} else if (fastcmp(word,"exitcountdown")) {
|
||||||
lua_pushinteger(L, exitcountdown); // This name is pretty dumb. Hence why we'll prefer more descriptive names at least in Lua...
|
lua_pushinteger(L, exitcountdown); // This name is pretty dumb. Hence why we'll prefer more descriptive names at least in Lua...
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (fastcmp(word,"replayplayback")) {
|
||||||
|
lua_pushboolean(L, demo.playback);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,6 +385,15 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
|
||||||
redscore = (UINT32)luaL_checkinteger(L, 2);
|
redscore = (UINT32)luaL_checkinteger(L, 2);
|
||||||
else if (fastcmp(word, "bluescore"))
|
else if (fastcmp(word, "bluescore"))
|
||||||
bluescore = (UINT32)luaL_checkinteger(L, 2);
|
bluescore = (UINT32)luaL_checkinteger(L, 2);
|
||||||
|
// SRB2Kart
|
||||||
|
else if (fastcmp(word,"racecountdown"))
|
||||||
|
racecountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||||
|
else if (fastcmp(word,"exitcountdown"))
|
||||||
|
exitcountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||||
|
else if (fastcmp(word,"indirectitemcooldown"))
|
||||||
|
indirectitemcooldown = (tic_t)luaL_checkinteger(L, 2);
|
||||||
|
else if (fastcmp(word,"hyubgone"))
|
||||||
|
hyubgone = (tic_t)luaL_checkinteger(L, 2);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
||||||
799
src/m_menu.c
799
src/m_menu.c
File diff suppressed because it is too large
Load diff
|
|
@ -239,7 +239,6 @@ typedef enum
|
||||||
M_NOT_WAITING,
|
M_NOT_WAITING,
|
||||||
|
|
||||||
M_WAITING_VERSION,
|
M_WAITING_VERSION,
|
||||||
M_WAITING_ROOMS,
|
|
||||||
M_WAITING_SERVERS,
|
M_WAITING_SERVERS,
|
||||||
}
|
}
|
||||||
M_waiting_mode_t;
|
M_waiting_mode_t;
|
||||||
|
|
@ -336,12 +335,6 @@ typedef struct menuitem_s
|
||||||
UINT8 alphaKey;
|
UINT8 alphaKey;
|
||||||
} menuitem_t;
|
} menuitem_t;
|
||||||
|
|
||||||
extern menuitem_t MP_RoomMenu[];
|
|
||||||
extern UINT32 roomIds[NUM_LIST_ROOMS];
|
|
||||||
|
|
||||||
extern menuitem_t MP_RoomMenu[];
|
|
||||||
extern UINT32 roomIds[NUM_LIST_ROOMS];
|
|
||||||
|
|
||||||
typedef struct menu_s
|
typedef struct menu_s
|
||||||
{
|
{
|
||||||
UINT32 menuid; // ID to encode menu type and hierarchy
|
UINT32 menuid; // ID to encode menu type and hierarchy
|
||||||
|
|
@ -478,6 +471,8 @@ void Addons_option_Onchange(void);
|
||||||
void M_ReplayHut(INT32 choice);
|
void M_ReplayHut(INT32 choice);
|
||||||
void M_SetPlaybackMenuPointer(void);
|
void M_SetPlaybackMenuPointer(void);
|
||||||
|
|
||||||
|
void M_RefreshPauseMenu(void);
|
||||||
|
|
||||||
INT32 HU_GetHighlightColor(void);
|
INT32 HU_GetHighlightColor(void);
|
||||||
|
|
||||||
// Moviemode menu updating
|
// Moviemode menu updating
|
||||||
|
|
|
||||||
153
src/mserv.c
153
src/mserv.c
|
|
@ -23,6 +23,12 @@
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
#include "discord.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MASTERSERVER
|
||||||
|
|
||||||
static int MSId;
|
static int MSId;
|
||||||
static int MSRegisteredId = -1;
|
static int MSRegisteredId = -1;
|
||||||
|
|
||||||
|
|
@ -43,27 +49,33 @@ static I_cond MSCond;
|
||||||
# define Unlock_state()
|
# define Unlock_state()
|
||||||
#endif/*HAVE_THREADS*/
|
#endif/*HAVE_THREADS*/
|
||||||
|
|
||||||
static void Update_parameters (void);
|
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
static void Command_Listserv_f(void);
|
static void Command_Listserv_f(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
|
static void Update_parameters (void);
|
||||||
|
|
||||||
static void MasterServer_OnChange(void);
|
static void MasterServer_OnChange(void);
|
||||||
|
|
||||||
|
static void Advertise_OnChange(void);
|
||||||
|
|
||||||
static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
||||||
{2, "MIN"},
|
{2, "MIN"},
|
||||||
{60, "MAX"},
|
{60, "MAX"},
|
||||||
{0}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
consvar_t cv_masterserver = {"masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_masterserver = {"masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_server_contact = {"server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, MasterClient_Ticker, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
INT16 ms_RoomId = -1;
|
consvar_t cv_advertise = {"advertise", "No", CV_NETVAR|CV_CALL|CV_NOINIT, CV_YesNo, Advertise_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
#ifdef HAVE_THREADS
|
#if defined (MASTERSERVER) && defined (HAVE_THREADS)
|
||||||
int ms_QueryId;
|
int ms_QueryId;
|
||||||
I_mutex ms_QueryId_mutex;
|
I_mutex ms_QueryId_mutex;
|
||||||
|
|
||||||
|
|
@ -73,10 +85,6 @@ I_mutex ms_ServerList_mutex;
|
||||||
|
|
||||||
UINT16 current_port = 0;
|
UINT16 current_port = 0;
|
||||||
|
|
||||||
// Room list is an external variable now.
|
|
||||||
// Avoiding having to get info ten thousand times...
|
|
||||||
msg_rooms_t room_list[NUM_LIST_ROOMS+1]; // +1 for easy test
|
|
||||||
|
|
||||||
/** Adds variables and commands relating to the master server.
|
/** Adds variables and commands relating to the master server.
|
||||||
*
|
*
|
||||||
* \sa cv_masterserver, cv_servername,
|
* \sa cv_masterserver, cv_servername,
|
||||||
|
|
@ -90,11 +98,17 @@ void AddMServCommands(void)
|
||||||
CV_RegisterVar(&cv_masterserver_timeout);
|
CV_RegisterVar(&cv_masterserver_timeout);
|
||||||
CV_RegisterVar(&cv_masterserver_debug);
|
CV_RegisterVar(&cv_masterserver_debug);
|
||||||
CV_RegisterVar(&cv_masterserver_token);
|
CV_RegisterVar(&cv_masterserver_token);
|
||||||
|
CV_RegisterVar(&cv_advertise);
|
||||||
CV_RegisterVar(&cv_servername);
|
CV_RegisterVar(&cv_servername);
|
||||||
|
CV_RegisterVar(&cv_server_contact);
|
||||||
|
#ifdef MASTERSERVER
|
||||||
COM_AddCommand("listserv", Command_Listserv_f);
|
COM_AddCommand("listserv", Command_Listserv_f);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MASTERSERVER
|
||||||
|
|
||||||
static void WarnGUI (void)
|
static void WarnGUI (void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
|
|
@ -107,14 +121,14 @@ static void WarnGUI (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_LIST_SERVER MAXSERVERLIST
|
#define NUM_LIST_SERVER MAXSERVERLIST
|
||||||
msg_server_t *GetShortServersList(INT32 room, int id)
|
msg_server_t *GetShortServersList(int id)
|
||||||
{
|
{
|
||||||
msg_server_t *server_list;
|
msg_server_t *server_list;
|
||||||
|
|
||||||
// +1 for easy test
|
// +1 for easy test
|
||||||
server_list = malloc(( NUM_LIST_SERVER + 1 ) * sizeof *server_list);
|
server_list = malloc(( NUM_LIST_SERVER + 1 ) * sizeof *server_list);
|
||||||
|
|
||||||
if (HMS_fetch_servers(server_list, room, id))
|
if (HMS_fetch_servers(server_list, id))
|
||||||
return server_list;
|
return server_list;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -124,17 +138,6 @@ msg_server_t *GetShortServersList(INT32 room, int id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 GetRoomsList(boolean hosting, int id)
|
|
||||||
{
|
|
||||||
if (HMS_fetch_rooms( ! hosting, id))
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WarnGUI();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef UPDATE_ALERT
|
#ifdef UPDATE_ALERT
|
||||||
char *GetMODVersion(int id)
|
char *GetMODVersion(int id)
|
||||||
{
|
{
|
||||||
|
|
@ -168,15 +171,6 @@ char *GetMODVersion(int id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console only version of the above (used before game init)
|
|
||||||
void GetMODVersion_Console(void)
|
|
||||||
{
|
|
||||||
char buffer[16];
|
|
||||||
|
|
||||||
if (HMS_compare_mod_version(buffer, sizeof buffer) > 0)
|
|
||||||
I_Error(UPDATE_ALERT_STRING_CONSOLE, VERSIONSTRING, buffer);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
|
|
@ -267,6 +261,9 @@ Finish_unlist (void)
|
||||||
Lock_state();
|
Lock_state();
|
||||||
{
|
{
|
||||||
registered = MSRegistered;
|
registered = MSRegistered;
|
||||||
|
|
||||||
|
if (MSId == MSRegisteredId)
|
||||||
|
MSId++;
|
||||||
}
|
}
|
||||||
Unlock_state();
|
Unlock_state();
|
||||||
|
|
||||||
|
|
@ -287,13 +284,6 @@ Finish_unlist (void)
|
||||||
I_wake_all_cond(&MSCond);
|
I_wake_all_cond(&MSCond);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Lock_state();
|
|
||||||
{
|
|
||||||
if (MSId == MSRegisteredId)
|
|
||||||
MSId++;
|
|
||||||
}
|
|
||||||
Unlock_state();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
|
|
@ -395,6 +385,7 @@ Change_masterserver_thread (char *api)
|
||||||
|
|
||||||
void RegisterServer(void)
|
void RegisterServer(void)
|
||||||
{
|
{
|
||||||
|
#ifdef MASTERSERVER
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
I_spawn_thread(
|
I_spawn_thread(
|
||||||
"register-server",
|
"register-server",
|
||||||
|
|
@ -404,6 +395,7 @@ void RegisterServer(void)
|
||||||
#else
|
#else
|
||||||
Finish_registration();
|
Finish_registration();
|
||||||
#endif
|
#endif
|
||||||
|
#endif/*MASTERSERVER*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateServer(void)
|
static void UpdateServer(void)
|
||||||
|
|
@ -421,6 +413,7 @@ static void UpdateServer(void)
|
||||||
|
|
||||||
void UnregisterServer(void)
|
void UnregisterServer(void)
|
||||||
{
|
{
|
||||||
|
#ifdef MASTERSERVER
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
I_spawn_thread(
|
I_spawn_thread(
|
||||||
"unlist-server",
|
"unlist-server",
|
||||||
|
|
@ -430,12 +423,13 @@ void UnregisterServer(void)
|
||||||
#else
|
#else
|
||||||
Finish_unlist();
|
Finish_unlist();
|
||||||
#endif
|
#endif
|
||||||
|
#endif/*MASTERSERVER*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
Online (void)
|
Online (void)
|
||||||
{
|
{
|
||||||
return ( serverrunning && ms_RoomId > 0 );
|
return ( serverrunning && cv_advertise.value );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void SendPingToMasterServer(void)
|
static inline void SendPingToMasterServer(void)
|
||||||
|
|
@ -465,9 +459,33 @@ static inline void SendPingToMasterServer(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MasterClient_Ticker(void)
|
||||||
|
{
|
||||||
|
#ifdef MASTERSERVER
|
||||||
|
SendPingToMasterServer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Set_api (const char *api)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
I_spawn_thread(
|
||||||
|
"change-masterserver",
|
||||||
|
(I_thread_fn)Change_masterserver_thread,
|
||||||
|
strdup(api)
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
HMS_set_api(strdup(api));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Update_parameters (void)
|
Update_parameters (void)
|
||||||
{
|
{
|
||||||
|
#ifdef MASTERSERVER
|
||||||
int registered;
|
int registered;
|
||||||
int delayed;
|
int delayed;
|
||||||
|
|
||||||
|
|
@ -487,29 +505,12 @@ Update_parameters (void)
|
||||||
if (! delayed && registered)
|
if (! delayed && registered)
|
||||||
UpdateServer();
|
UpdateServer();
|
||||||
}
|
}
|
||||||
}
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
void MasterClient_Ticker(void)
|
|
||||||
{
|
|
||||||
SendPingToMasterServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
Set_api (const char *api)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_THREADS
|
|
||||||
I_spawn_thread(
|
|
||||||
"change-masterserver",
|
|
||||||
(I_thread_fn)Change_masterserver_thread,
|
|
||||||
strdup(api)
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
HMS_set_api(strdup(api));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MasterServer_OnChange(void)
|
static void MasterServer_OnChange(void)
|
||||||
{
|
{
|
||||||
|
#ifdef MASTERSERVER
|
||||||
UnregisterServer();
|
UnregisterServer();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -527,4 +528,36 @@ static void MasterServer_OnChange(void)
|
||||||
|
|
||||||
if (Online())
|
if (Online())
|
||||||
RegisterServer();
|
RegisterServer();
|
||||||
|
#endif/*MASTERSERVER*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Advertise_OnChange(void)
|
||||||
|
{
|
||||||
|
int different;
|
||||||
|
|
||||||
|
if (cv_advertise.value)
|
||||||
|
{
|
||||||
|
if (serverrunning)
|
||||||
|
{
|
||||||
|
Lock_state();
|
||||||
|
{
|
||||||
|
different = ( MSId != MSRegisteredId );
|
||||||
|
}
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
|
if (different)
|
||||||
|
{
|
||||||
|
RegisterServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UnregisterServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
DRPC_UpdatePresence();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
src/mserv.h
28
src/mserv.h
|
|
@ -16,9 +16,6 @@
|
||||||
|
|
||||||
#include "i_threads.h"
|
#include "i_threads.h"
|
||||||
|
|
||||||
// lowered from 32 due to menu changes
|
|
||||||
#define NUM_LIST_ROOMS 16
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -35,19 +32,10 @@ typedef struct
|
||||||
msg_header_t header;
|
msg_header_t header;
|
||||||
char ip[16];
|
char ip[16];
|
||||||
char port[8];
|
char port[8];
|
||||||
char name[32];
|
char contact[32];
|
||||||
INT32 room;
|
|
||||||
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
|
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
|
||||||
} ATTRPACK msg_server_t;
|
} ATTRPACK msg_server_t;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
msg_header_t header;
|
|
||||||
INT32 id;
|
|
||||||
char name[32];
|
|
||||||
char motd[255];
|
|
||||||
} ATTRPACK msg_rooms_t;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
msg_header_t header;
|
msg_header_t header;
|
||||||
|
|
@ -65,15 +53,13 @@ typedef struct
|
||||||
// ================================ GLOBALS ===============================
|
// ================================ GLOBALS ===============================
|
||||||
|
|
||||||
extern consvar_t cv_masterserver, cv_servername;
|
extern consvar_t cv_masterserver, cv_servername;
|
||||||
|
extern consvar_t cv_server_contact;
|
||||||
extern consvar_t cv_masterserver_update_rate;
|
extern consvar_t cv_masterserver_update_rate;
|
||||||
extern consvar_t cv_masterserver_timeout;
|
extern consvar_t cv_masterserver_timeout;
|
||||||
extern consvar_t cv_masterserver_debug;
|
extern consvar_t cv_masterserver_debug;
|
||||||
extern consvar_t cv_masterserver_token;
|
extern consvar_t cv_masterserver_token;
|
||||||
|
|
||||||
// < 0 to not connect (usually -1) (offline mode)
|
extern consvar_t cv_advertise;
|
||||||
// == 0 to show all rooms, not a valid hosting room
|
|
||||||
// anything else is whatever room the MS assigns to that number (online mode)
|
|
||||||
extern INT16 ms_RoomId;
|
|
||||||
|
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
extern int ms_QueryId;
|
extern int ms_QueryId;
|
||||||
|
|
@ -88,24 +74,20 @@ void UnregisterServer(void);
|
||||||
|
|
||||||
void MasterClient_Ticker(void);
|
void MasterClient_Ticker(void);
|
||||||
|
|
||||||
msg_server_t *GetShortServersList(INT32 room, int id);
|
msg_server_t *GetShortServersList(int id);
|
||||||
INT32 GetRoomsList(boolean hosting, int id);
|
|
||||||
#ifdef UPDATE_ALERT
|
#ifdef UPDATE_ALERT
|
||||||
char *GetMODVersion(int id);
|
char *GetMODVersion(int id);
|
||||||
void GetMODVersion_Console(void);
|
|
||||||
#endif
|
#endif
|
||||||
extern msg_rooms_t room_list[NUM_LIST_ROOMS+1];
|
|
||||||
|
|
||||||
void AddMServCommands(void);
|
void AddMServCommands(void);
|
||||||
|
|
||||||
/* HTTP */
|
/* HTTP */
|
||||||
void HMS_set_api (char *api);
|
void HMS_set_api (char *api);
|
||||||
int HMS_fetch_rooms (int joining, int id);
|
|
||||||
int HMS_register (void);
|
int HMS_register (void);
|
||||||
int HMS_unlist (void);
|
int HMS_unlist (void);
|
||||||
int HMS_update (void);
|
int HMS_update (void);
|
||||||
void HMS_list_servers (void);
|
void HMS_list_servers (void);
|
||||||
msg_server_t * HMS_fetch_servers (msg_server_t *list, int room, int id);
|
msg_server_t * HMS_fetch_servers (msg_server_t *list, int id);
|
||||||
int HMS_compare_mod_version (char *buffer, size_t size_of_buffer);
|
int HMS_compare_mod_version (char *buffer, size_t size_of_buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -432,8 +432,17 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
front = linedef->frontsector;
|
// Treat polyobjects kind of like 3D Floors
|
||||||
back = linedef->backsector;
|
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
|
||||||
|
{
|
||||||
|
front = linedef->frontsector;
|
||||||
|
back = linedef->frontsector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
front = linedef->frontsector;
|
||||||
|
back = linedef->backsector;
|
||||||
|
}
|
||||||
|
|
||||||
I_Assert(front != NULL);
|
I_Assert(front != NULL);
|
||||||
I_Assert(back != NULL);
|
I_Assert(back != NULL);
|
||||||
|
|
|
||||||
|
|
@ -10464,6 +10464,7 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn)
|
else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn)
|
||||||
|
|| (mthing->type == 777 || mthing->type == 778) // Slope anchors
|
||||||
|| (mthing->type >= 600 && mthing->type <= 609) // Special placement patterns
|
|| (mthing->type >= 600 && mthing->type <= 609) // Special placement patterns
|
||||||
|| mthing->type == 1705 || mthing->type == 1713) // Hoops
|
|| mthing->type == 1705 || mthing->type == 1713) // Hoops
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2123,7 +2123,7 @@ static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type
|
||||||
WRITEFIXED(save_p, ht->extent);
|
WRITEFIXED(save_p, ht->extent);
|
||||||
|
|
||||||
WRITEMEM(save_p, ht->tags, sizeof(ht->tags));
|
WRITEMEM(save_p, ht->tags, sizeof(ht->tags));
|
||||||
WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
|
WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type)
|
static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
|
|
||||||
|
|
@ -3980,8 +3980,16 @@ boolean P_LoadLevel(boolean fromnetsave)
|
||||||
// init anything that P_SpawnSlopes/P_LoadThings needs to know
|
// init anything that P_SpawnSlopes/P_LoadThings needs to know
|
||||||
P_InitSpecials();
|
P_InitSpecials();
|
||||||
|
|
||||||
|
// set up world state
|
||||||
|
// jart: needs to be done here so anchored slopes know the attached list
|
||||||
|
P_SpawnSpecials(fromnetsave);
|
||||||
|
|
||||||
P_SpawnSlopes(fromnetsave);
|
P_SpawnSlopes(fromnetsave);
|
||||||
|
|
||||||
|
P_RaiseThings();
|
||||||
|
|
||||||
|
P_SpawnSpecialsThatRequireObjects();
|
||||||
|
|
||||||
P_SpawnMapThings(!fromnetsave);
|
P_SpawnMapThings(!fromnetsave);
|
||||||
skyboxmo[0] = skyboxviewpnts[0];
|
skyboxmo[0] = skyboxviewpnts[0];
|
||||||
skyboxmo[1] = skyboxcenterpnts[0];
|
skyboxmo[1] = skyboxcenterpnts[0];
|
||||||
|
|
@ -3990,8 +3998,6 @@ boolean P_LoadLevel(boolean fromnetsave)
|
||||||
if (!playerstarts[numcoopstarts])
|
if (!playerstarts[numcoopstarts])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// set up world state
|
|
||||||
P_SpawnSpecials(fromnetsave);
|
|
||||||
K_AdjustWaypointsParameters();
|
K_AdjustWaypointsParameters();
|
||||||
|
|
||||||
if (!fromnetsave) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame)
|
if (!fromnetsave) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@
|
||||||
pslope_t *slopelist = NULL;
|
pslope_t *slopelist = NULL;
|
||||||
UINT16 slopecount = 0;
|
UINT16 slopecount = 0;
|
||||||
|
|
||||||
|
static void P_BuildSlopeAnchorList (void);
|
||||||
|
static void P_SetupAnchoredSlopes (void);
|
||||||
|
|
||||||
// Calculate line normal
|
// Calculate line normal
|
||||||
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);
|
||||||
|
|
@ -72,7 +75,7 @@ static void P_CalculateLineSlopeHighLow(pslope_t *slope, line_t *line, boolean c
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Setup slope via 3 vertexes.
|
/// Setup slope via 3 vertexes.
|
||||||
static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3)
|
void P_ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3)
|
||||||
{
|
{
|
||||||
vector3_t vec1, vec2;
|
vector3_t vec1, vec2;
|
||||||
|
|
||||||
|
|
@ -185,7 +188,7 @@ void T_DynamicSlopeVert (dynplanethink_t* th)
|
||||||
th->vex[i].z = 0;
|
th->vex[i].z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
|
P_ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3])
|
static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3])
|
||||||
|
|
@ -492,7 +495,7 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
|
||||||
vx[i].z += R_PointInSubsector(vx[i].x, vx[i].y)->sector->floorheight;
|
vx[i].z += R_PointInSubsector(vx[i].x, vx[i].y)->sector->floorheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]);
|
P_ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]);
|
||||||
|
|
||||||
if (spawnthinker && (flags & SL_DYNAMIC))
|
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||||
P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx);
|
P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx);
|
||||||
|
|
@ -574,7 +577,7 @@ static void SpawnVertexSlopes(void)
|
||||||
pslope_t *slop = Slope_Add(0);
|
pslope_t *slop = Slope_Add(0);
|
||||||
sc->f_slope = slop;
|
sc->f_slope = slop;
|
||||||
sc->hasslope = true;
|
sc->hasslope = true;
|
||||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
P_ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset)
|
if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset)
|
||||||
|
|
@ -586,7 +589,7 @@ static void SpawnVertexSlopes(void)
|
||||||
pslope_t *slop = Slope_Add(0);
|
pslope_t *slop = Slope_Add(0);
|
||||||
sc->c_slope = slop;
|
sc->c_slope = slop;
|
||||||
sc->hasslope = true;
|
sc->hasslope = true;
|
||||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
P_ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -709,6 +712,14 @@ void P_SpawnSlopes(const boolean fromsave) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jart
|
||||||
|
|
||||||
|
/// Build list of slope anchors--faster searching.
|
||||||
|
P_BuildSlopeAnchorList();
|
||||||
|
|
||||||
|
/// Setup anchor based slopes.
|
||||||
|
P_SetupAnchoredSlopes();
|
||||||
|
|
||||||
/// Copies slopes from tagged sectors via line specials.
|
/// Copies slopes from tagged sectors via line specials.
|
||||||
/// \note Doesn't actually copy, but instead they share the same pointers.
|
/// \note Doesn't actually copy, but instead they share the same pointers.
|
||||||
for (i = 0; i < numlines; i++)
|
for (i = 0; i < numlines; i++)
|
||||||
|
|
@ -966,3 +977,6 @@ void P_ButteredSlope(mobj_t *mo)
|
||||||
|
|
||||||
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jart
|
||||||
|
#include "slope_anchors.c"
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ typedef enum
|
||||||
void P_LinkSlopeThinkers (void);
|
void P_LinkSlopeThinkers (void);
|
||||||
|
|
||||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||||
|
void P_ReconfigureViaVertexes(pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3);
|
||||||
void P_SpawnSlopes(const boolean fromsave);
|
void P_SpawnSlopes(const boolean fromsave);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
45
src/p_spec.c
45
src/p_spec.c
|
|
@ -1081,7 +1081,6 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parses arguments for parameterized polyobject door types
|
// Parses arguments for parameterized polyobject door types
|
||||||
static boolean PolyDoor(line_t *line)
|
static boolean PolyDoor(line_t *line)
|
||||||
{
|
{
|
||||||
|
|
@ -1355,7 +1354,6 @@ static boolean PolyDisplace(line_t *line)
|
||||||
return EV_DoPolyObjDisplace(&pdd);
|
return EV_DoPolyObjDisplace(&pdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parses arguments for parameterized polyobject rotate-by-sector-heights specials
|
// Parses arguments for parameterized polyobject rotate-by-sector-heights specials
|
||||||
static boolean PolyRotDisplace(line_t *line)
|
static boolean PolyRotDisplace(line_t *line)
|
||||||
{
|
{
|
||||||
|
|
@ -5547,6 +5545,26 @@ P_RaiseTaggedThingsToFakeFloor (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
P_RaiseThings (void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < numlines; ++i)
|
||||||
|
{
|
||||||
|
switch (lines[i].special)
|
||||||
|
{
|
||||||
|
case 80: // Raise tagged things by type to this FOF
|
||||||
|
P_RaiseTaggedThingsToFakeFloor(
|
||||||
|
( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ),
|
||||||
|
lines[i].tag,
|
||||||
|
lines[i].frontsector
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SPECIAL SPAWNING
|
// SPECIAL SPAWNING
|
||||||
//
|
//
|
||||||
|
|
@ -6931,28 +6949,19 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* some things have to be done after FOF spawn */
|
|
||||||
|
|
||||||
for (i = 0; i < numlines; ++i)
|
|
||||||
{
|
|
||||||
switch (lines[i].special)
|
|
||||||
{
|
|
||||||
case 80: // Raise tagged things by type to this FOF
|
|
||||||
P_RaiseTaggedThingsToFakeFloor(
|
|
||||||
( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ),
|
|
||||||
lines[i].tag,
|
|
||||||
lines[i].frontsector
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate each list
|
// Allocate each list
|
||||||
for (i = 0; i < numsectors; i++)
|
for (i = 0; i < numsectors; i++)
|
||||||
if(secthinkers[i].thinkers)
|
if(secthinkers[i].thinkers)
|
||||||
Z_Free(secthinkers[i].thinkers);
|
Z_Free(secthinkers[i].thinkers);
|
||||||
|
|
||||||
Z_Free(secthinkers);
|
Z_Free(secthinkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fuck polyobjects
|
||||||
|
*/
|
||||||
|
void P_SpawnSpecialsThatRequireObjects(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
// haleyjd 02/20/06: spawn polyobjects
|
// haleyjd 02/20/06: spawn polyobjects
|
||||||
Polyobj_InitLevel();
|
Polyobj_InitLevel();
|
||||||
|
|
|
||||||
10
src/p_spec.h
10
src/p_spec.h
|
|
@ -43,6 +43,8 @@ void P_SetupLevelFlatAnims(void);
|
||||||
// at map load
|
// at map load
|
||||||
void P_InitSpecials(void);
|
void P_InitSpecials(void);
|
||||||
void P_SpawnSpecials(boolean fromnetsave);
|
void P_SpawnSpecials(boolean fromnetsave);
|
||||||
|
void P_RaiseThings(void);
|
||||||
|
void P_SpawnSpecialsThatRequireObjects(void);
|
||||||
|
|
||||||
// every tic
|
// every tic
|
||||||
void P_UpdateSpecials(void);
|
void P_UpdateSpecials(void);
|
||||||
|
|
@ -648,4 +650,12 @@ void P_CalcHeight(player_t *player);
|
||||||
|
|
||||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
||||||
|
|
||||||
|
/* line specials */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LT_SLOPE_ANCHORS_FLOOR = 777,
|
||||||
|
LT_SLOPE_ANCHORS_CEILING = 778,
|
||||||
|
LT_SLOPE_ANCHORS = 779,
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -536,6 +536,7 @@ void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan)
|
||||||
|
|
||||||
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||||
{
|
{
|
||||||
|
const INT32 initial_volume = volume;
|
||||||
INT32 sep, pitch, priority, cnum;
|
INT32 sep, pitch, priority, cnum;
|
||||||
const sfxenum_t actual_id = sfx_id;
|
const sfxenum_t actual_id = sfx_id;
|
||||||
sfxinfo_t *sfx;
|
sfxinfo_t *sfx;
|
||||||
|
|
@ -900,6 +901,7 @@ dontplay4:
|
||||||
|
|
||||||
// Assigns the handle to one of the channels in the
|
// Assigns the handle to one of the channels in the
|
||||||
// mix/output buffer.
|
// mix/output buffer.
|
||||||
|
channels[cnum].volume = initial_volume;
|
||||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1110,7 +1112,7 @@ void S_UpdateSounds(void)
|
||||||
if (I_SoundIsPlaying(c->handle))
|
if (I_SoundIsPlaying(c->handle))
|
||||||
{
|
{
|
||||||
// initialize parameters
|
// initialize parameters
|
||||||
volume = 255; // 8 bits internal volume precision
|
volume = c->volume; // 8 bits internal volume precision
|
||||||
pitch = NORM_PITCH;
|
pitch = NORM_PITCH;
|
||||||
sep = NORM_SEP;
|
sep = NORM_SEP;
|
||||||
|
|
||||||
|
|
@ -1444,15 +1446,12 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
|
||||||
}
|
}
|
||||||
|
|
||||||
// volume calculation
|
// volume calculation
|
||||||
if (approx_dist < S_CLOSE_DIST)
|
/* not sure if it should be > (no =), but this matches the old behavior */
|
||||||
{
|
if (approx_dist >= S_CLOSE_DIST)
|
||||||
// SfxVolume is now hardware volume
|
|
||||||
*vol = 255; // not snd_SfxVolume
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// distance effect
|
// distance effect
|
||||||
*vol = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) / S_ATTENUATOR;
|
INT32 n = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS));
|
||||||
|
*vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_splitscreen)
|
if (r_splitscreen)
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,9 @@ typedef struct
|
||||||
// origin of sound
|
// origin of sound
|
||||||
const void *origin;
|
const void *origin;
|
||||||
|
|
||||||
|
// initial volume of sound, which is applied after distance and direction
|
||||||
|
INT32 volume;
|
||||||
|
|
||||||
// handle of the sound being played
|
// handle of the sound being played
|
||||||
INT32 handle;
|
INT32 handle;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ if(${SDL2_FOUND})
|
||||||
set(SRB2_SDL2_TOTAL_SOURCES
|
set(SRB2_SDL2_TOTAL_SOURCES
|
||||||
${SRB2_CORE_SOURCES}
|
${SRB2_CORE_SOURCES}
|
||||||
${SRB2_CORE_HEADERS}
|
${SRB2_CORE_HEADERS}
|
||||||
|
${SRB2_DISCORDRPC_SOURCES}
|
||||||
|
${SRB2_DISCORDRPC_HEADERS}
|
||||||
${SRB2_PNG_SOURCES}
|
${SRB2_PNG_SOURCES}
|
||||||
${SRB2_PNG_HEADERS}
|
${SRB2_PNG_HEADERS}
|
||||||
${SRB2_CORE_RENDER_SOURCES}
|
${SRB2_CORE_RENDER_SOURCES}
|
||||||
|
|
@ -91,9 +93,11 @@ if(${SDL2_FOUND})
|
||||||
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
|
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
|
||||||
source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES})
|
source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES})
|
||||||
source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES})
|
source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES})
|
||||||
|
source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS})
|
||||||
source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})
|
source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})
|
||||||
source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS})
|
source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS})
|
||||||
source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS})
|
source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS})
|
||||||
|
|
||||||
|
|
||||||
if(${SRB2_CONFIG_HWRENDER})
|
if(${SRB2_CONFIG_HWRENDER})
|
||||||
set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
|
set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
|
||||||
|
|
@ -166,6 +170,7 @@ if(${SDL2_FOUND})
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
|
${DISCORDRPC_LIBRARIES}
|
||||||
)
|
)
|
||||||
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||||
else()
|
else()
|
||||||
|
|
@ -179,6 +184,7 @@ if(${SDL2_FOUND})
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
|
${DISCORDRPC_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM} MATCHES Linux)
|
if(${CMAKE_SYSTEM} MATCHES Linux)
|
||||||
|
|
@ -261,6 +267,7 @@ if(${SDL2_FOUND})
|
||||||
${ZLIB_INCLUDE_DIRS}
|
${ZLIB_INCLUDE_DIRS}
|
||||||
${OPENGL_INCLUDE_DIRS}
|
${OPENGL_INCLUDE_DIRS}
|
||||||
${CURL_INCLUDE_DIRS}
|
${CURL_INCLUDE_DIRS}
|
||||||
|
${DISCORDRPC_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
if((${SRB2_HAVE_MIXER}) OR (${SRB2_HAVE_MIXERX}))
|
if((${SRB2_HAVE_MIXER}) OR (${SRB2_HAVE_MIXERX}))
|
||||||
|
|
@ -375,6 +382,10 @@ if(${SDL2_FOUND})
|
||||||
getwinlib(libstdc++-6 "libstdc++-6.dll")
|
getwinlib(libstdc++-6 "libstdc++-6.dll")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${SRB2_CONFIG_HAVE_DISCORDRPC})
|
||||||
|
getwinlib(discord-rpc "discord-rpc.dll")
|
||||||
|
endif()
|
||||||
|
|
||||||
install(PROGRAMS
|
install(PROGRAMS
|
||||||
${win_extra_dll_list}
|
${win_extra_dll_list}
|
||||||
DESTINATION .
|
DESTINATION .
|
||||||
|
|
|
||||||
|
|
@ -53,28 +53,6 @@ ifndef NOHW
|
||||||
OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o
|
OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef NOHS
|
|
||||||
ifdef OPENAL
|
|
||||||
OBJS+=$(OBJDIR)/s_openal.o
|
|
||||||
OPTS+=-DSTATIC3DS
|
|
||||||
STATICHS=1
|
|
||||||
else
|
|
||||||
ifdef FMOD
|
|
||||||
OBJS+=$(OBJDIR)/s_fmod.o
|
|
||||||
OPTS+=-DSTATIC3DS
|
|
||||||
STATICHS=1
|
|
||||||
else
|
|
||||||
ifdef MINGW
|
|
||||||
ifdef DS3D
|
|
||||||
OBJS+=$(OBJDIR)/s_ds3d.o
|
|
||||||
OPTS+=-DSTATIC3DS
|
|
||||||
STATICHS=1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NOMIXER
|
ifdef NOMIXER
|
||||||
i_sound_o=$(OBJDIR)/sdl_sound.o
|
i_sound_o=$(OBJDIR)/sdl_sound.o
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,10 @@ char logfilename[1024];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (_WIN32)
|
||||||
|
#include "exchndl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
#include "../win32/win_dbg.h"
|
#include "../win32/win_dbg.h"
|
||||||
typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID);
|
typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID);
|
||||||
|
|
@ -191,6 +195,20 @@ static void InitLogging(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static void
|
||||||
|
ChDirToExe (void)
|
||||||
|
{
|
||||||
|
CHAR path[MAX_PATH];
|
||||||
|
if (GetModuleFileNameA(NULL, path, MAX_PATH) > 0)
|
||||||
|
{
|
||||||
|
strrchr(path, '\\')[0] = '\0';
|
||||||
|
SetCurrentDirectoryA(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** \brief The main function
|
/** \brief The main function
|
||||||
|
|
||||||
\param argc number of arg
|
\param argc number of arg
|
||||||
|
|
@ -219,6 +237,10 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
ChDirToExe();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOGMESSAGES
|
#ifdef LOGMESSAGES
|
||||||
if (!M_CheckParm("-nolog"))
|
if (!M_CheckParm("-nolog"))
|
||||||
InitLogging();
|
InitLogging();
|
||||||
|
|
@ -237,7 +259,7 @@ int main(int argc, char **argv)
|
||||||
)
|
)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LoadLibraryA("exchndl.dll");
|
ExcHndlInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
|
|
|
||||||
|
|
@ -152,11 +152,6 @@ int TimeFunction(int requested_frequency);
|
||||||
#define DEFAULTSEARCHPATH1 "/usr/local/games"
|
#define DEFAULTSEARCHPATH1 "/usr/local/games"
|
||||||
#define DEFAULTSEARCHPATH2 "/usr/games"
|
#define DEFAULTSEARCHPATH2 "/usr/games"
|
||||||
#define DEFAULTSEARCHPATH3 "/usr/local"
|
#define DEFAULTSEARCHPATH3 "/usr/local"
|
||||||
#elif defined (_WIN32)
|
|
||||||
#define DEFAULTWADLOCATION1 "c:\\games\\srb2kart"
|
|
||||||
#define DEFAULTWADLOCATION2 "\\games\\srb2kart"
|
|
||||||
#define DEFAULTSEARCHPATH1 "c:\\games"
|
|
||||||
#define DEFAULTSEARCHPATH2 "\\games"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \brief WAD file to look for
|
/** \brief WAD file to look for
|
||||||
|
|
@ -2341,6 +2336,18 @@ static const char *locateWad(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEFAULTDIR
|
||||||
|
I_OutputMsg(",HOME/" DEFAULTDIR);
|
||||||
|
// examine user jart directory
|
||||||
|
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||||
|
{
|
||||||
|
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
|
||||||
|
if (isWadPathOk(returnWadPath))
|
||||||
|
return returnWadPath;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
I_OutputMsg(","CMAKE_ASSETS_DIR);
|
I_OutputMsg(","CMAKE_ASSETS_DIR);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
/// \brief SRB2 graphics stuff for SDL
|
/// \brief SRB2 graphics stuff for SDL
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
@ -85,6 +86,10 @@
|
||||||
#include "ogl_sdl.h"
|
#include "ogl_sdl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
#include "../discord.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// maximum number of windowed modes (see windowedModes[][])
|
// maximum number of windowed modes (see windowedModes[][])
|
||||||
#define MAXWINMODES (18)
|
#define MAXWINMODES (18)
|
||||||
|
|
||||||
|
|
@ -1324,6 +1329,11 @@ void I_FinishUpdate(void)
|
||||||
if (cv_closedcaptioning.value)
|
if (cv_closedcaptioning.value)
|
||||||
SCR_ClosedCaptions();
|
SCR_ClosedCaptions();
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
if (discordRequestList != NULL)
|
||||||
|
ST_AskToJoinEnvelope();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (rendermode == render_soft && screens[0])
|
if (rendermode == render_soft && screens[0])
|
||||||
{
|
{
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
|
|
|
||||||
492
src/slope_anchors.c
Normal file
492
src/slope_anchors.c
Normal file
|
|
@ -0,0 +1,492 @@
|
||||||
|
// SONIC ROBO BLAST 2 KART
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2020 by James R.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \brief Charyb's vertex slope anchors.
|
||||||
|
/// This file is self contained to avoid a Big Large merge conflict.
|
||||||
|
|
||||||
|
/*
|
||||||
|
FIXME
|
||||||
|
FIXME
|
||||||
|
FIXME
|
||||||
|
FIXME WHEN 2.2 MERGE IS OVER, REFACTOR A LOT OF THE CODE IN P_SLOPES.C AND
|
||||||
|
FIXME MAKE THIS NOT REDUNDANT.
|
||||||
|
FIXME
|
||||||
|
FIXME
|
||||||
|
FIXME
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct anchor_list
|
||||||
|
{
|
||||||
|
mapthing_t ** anchors;
|
||||||
|
const vertex_t ** points;
|
||||||
|
fixed_t * closeness;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct anchor_list floor_anchors;
|
||||||
|
struct anchor_list ceiling_anchors;
|
||||||
|
|
||||||
|
static void * new_list (size_t n) {
|
||||||
|
return Z_Malloc(n, PU_LEVEL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void make_new_anchor_list (struct anchor_list * list) {
|
||||||
|
list->anchors = new_list(list->count * sizeof *list->anchors);
|
||||||
|
list->points = new_list(list->count * sizeof *list->points);
|
||||||
|
list->closeness = new_list(list->count * sizeof *list->closeness);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void allocate_anchors (void) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
floor_anchors.count = 0;
|
||||||
|
ceiling_anchors.count = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nummapthings; ++i)
|
||||||
|
{
|
||||||
|
switch (mapthings[i].type)
|
||||||
|
{
|
||||||
|
case FLOOR_SLOPE_THING:
|
||||||
|
floor_anchors.count++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CEILING_SLOPE_THING:
|
||||||
|
ceiling_anchors.count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
make_new_anchor_list(&floor_anchors);
|
||||||
|
make_new_anchor_list(&ceiling_anchors);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compare_vertex_distance
|
||||||
|
(
|
||||||
|
const vertex_t ** nearest,
|
||||||
|
fixed_t * nearest_distance,
|
||||||
|
const fixed_t origin_x,
|
||||||
|
const fixed_t origin_y,
|
||||||
|
const vertex_t * v
|
||||||
|
){
|
||||||
|
const fixed_t distance = abs(P_AproxDistance
|
||||||
|
(
|
||||||
|
origin_x - v->x,
|
||||||
|
origin_y - v->y
|
||||||
|
));
|
||||||
|
|
||||||
|
if (distance < (*nearest_distance))
|
||||||
|
{
|
||||||
|
(*nearest) = v;
|
||||||
|
(*nearest_distance) = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const vertex_t *
|
||||||
|
nearest_point
|
||||||
|
(
|
||||||
|
fixed_t * closeness,
|
||||||
|
mapthing_t * a,
|
||||||
|
const sector_t * sector
|
||||||
|
){
|
||||||
|
const fixed_t x = a->x << FRACBITS;
|
||||||
|
const fixed_t y = a->y << FRACBITS;
|
||||||
|
|
||||||
|
const vertex_t * v = NULL;/* shut compiler up, should never be NULL */
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
(*closeness) = INT32_MAX;
|
||||||
|
|
||||||
|
for (i = 0; i < sector->linecount; ++i)
|
||||||
|
{
|
||||||
|
compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v1);
|
||||||
|
compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT16
|
||||||
|
anchor_height
|
||||||
|
(
|
||||||
|
const mapthing_t * a,
|
||||||
|
const sector_t * s
|
||||||
|
){
|
||||||
|
{
|
||||||
|
INT16 z = ( a->options >> ZSHIFT );
|
||||||
|
|
||||||
|
if (a->options & MTF_OBJECTFLIP)
|
||||||
|
{
|
||||||
|
return ( s->ceilingheight >> FRACBITS ) - z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ( s->floorheight >> FRACBITS ) + z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_anchor
|
||||||
|
(
|
||||||
|
struct anchor_list * list,
|
||||||
|
mapthing_t * a
|
||||||
|
){
|
||||||
|
const subsector_t * sub = R_PointInSubsector
|
||||||
|
(
|
||||||
|
a->x << FRACBITS,
|
||||||
|
a->y << FRACBITS
|
||||||
|
);
|
||||||
|
|
||||||
|
const vertex_t * v;
|
||||||
|
|
||||||
|
fixed_t closeness;
|
||||||
|
|
||||||
|
a->z = anchor_height(a, sub->sector);
|
||||||
|
|
||||||
|
v = nearest_point(&closeness, a, sub->sector);
|
||||||
|
|
||||||
|
a->x = ( v->x >> FRACBITS );
|
||||||
|
a->y = ( v->y >> FRACBITS );
|
||||||
|
|
||||||
|
list->anchors [list->count] = a;
|
||||||
|
list->points [list->count] = v;
|
||||||
|
list->closeness[list->count] = closeness;
|
||||||
|
|
||||||
|
list->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void build_anchors (void) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
floor_anchors.count = 0;
|
||||||
|
ceiling_anchors.count = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nummapthings; ++i)
|
||||||
|
{
|
||||||
|
switch (mapthings[i].type)
|
||||||
|
{
|
||||||
|
case FLOOR_SLOPE_THING:
|
||||||
|
set_anchor(&floor_anchors, &mapthings[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CEILING_SLOPE_THING:
|
||||||
|
set_anchor(&ceiling_anchors, &mapthings[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_anchor
|
||||||
|
(
|
||||||
|
mapthing_t ** anchors,
|
||||||
|
fixed_t distances[3],
|
||||||
|
const struct anchor_list * list,
|
||||||
|
const INT16 tag,
|
||||||
|
const vertex_t * v
|
||||||
|
){
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
int k;
|
||||||
|
|
||||||
|
for (i = 0; i < list->count; ++i)
|
||||||
|
{
|
||||||
|
if (list->points[i] == v && list->anchors[i]->extrainfo == tag)
|
||||||
|
{
|
||||||
|
for (k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
if (list->closeness[i] < distances[k])
|
||||||
|
{
|
||||||
|
if (k == 0)
|
||||||
|
{
|
||||||
|
distances[2] = distances[1];
|
||||||
|
distances[1] = distances[0];
|
||||||
|
|
||||||
|
anchors [2] = anchors [1];
|
||||||
|
anchors [1] = anchors [0];
|
||||||
|
}
|
||||||
|
else if (k == 1)
|
||||||
|
{
|
||||||
|
distances[2] = distances[1];
|
||||||
|
anchors [2] = anchors [1];
|
||||||
|
}
|
||||||
|
|
||||||
|
distances[k] = list->closeness[i];
|
||||||
|
|
||||||
|
anchors[k] = list->anchors[i];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (list->anchors[i] == anchors[k])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_sector_anchors
|
||||||
|
(
|
||||||
|
mapthing_t ** anchors,
|
||||||
|
fixed_t distances[3],
|
||||||
|
const struct anchor_list * list,
|
||||||
|
const INT16 tag,
|
||||||
|
const sector_t * sector
|
||||||
|
){
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < sector->linecount; ++i)
|
||||||
|
{
|
||||||
|
get_anchor(anchors, distances, list, tag, sector->lines[i]->v1);
|
||||||
|
get_anchor(anchors, distances, list, tag, sector->lines[i]->v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mapthing_t **
|
||||||
|
find_closest_anchors
|
||||||
|
(
|
||||||
|
const sector_t * sector,
|
||||||
|
const struct anchor_list * list,
|
||||||
|
const INT16 tag
|
||||||
|
){
|
||||||
|
fixed_t distances[3] = { INT32_MAX, INT32_MAX, INT32_MAX };
|
||||||
|
|
||||||
|
mapthing_t ** anchors;
|
||||||
|
|
||||||
|
int last = 0;
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (list->count < 3)
|
||||||
|
{
|
||||||
|
I_Error("At least three slope anchors are required to make a slope.");
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors = Z_Malloc(3 * sizeof *anchors, PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
if (sector->numattached > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < sector->numattached; ++i)
|
||||||
|
{
|
||||||
|
get_sector_anchors
|
||||||
|
(anchors, distances, list, tag, §ors[sector->attached[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
get_sector_anchors(anchors, distances, list, tag, sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distances[2] < INT32_MAX)
|
||||||
|
{
|
||||||
|
return anchors;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distances[1] < INT32_MAX)
|
||||||
|
last = 2;
|
||||||
|
else if (distances[0] < INT32_MAX)
|
||||||
|
last = 1;
|
||||||
|
else
|
||||||
|
last = 0;
|
||||||
|
|
||||||
|
if (sector->numattached > 0)
|
||||||
|
{
|
||||||
|
CONS_Printf("\nSearched for anchors in sectors...\n\n");
|
||||||
|
|
||||||
|
for (i = 0; i < sector->numattached; ++i)
|
||||||
|
{
|
||||||
|
CONS_Printf("#%s\n", sizeu1 (sector->attached[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
I_Error(
|
||||||
|
"(Control Sector #%s)"
|
||||||
|
" Slope requires anchors (with Parameter %d)"
|
||||||
|
" near 3 of its target sectors' vertices (%d found)"
|
||||||
|
|
||||||
|
"\n\nCheck the log to see which sectors were searched.",
|
||||||
|
|
||||||
|
sizeu1 (sector - sectors),
|
||||||
|
tag,
|
||||||
|
last
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_Error(
|
||||||
|
"(Sector #%s)"
|
||||||
|
" Slope requires anchors (with Parameter %d)"
|
||||||
|
" near 3 of its vertices (%d found)",
|
||||||
|
|
||||||
|
sizeu1 (sector - sectors),
|
||||||
|
tag,
|
||||||
|
last
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static pslope_t *
|
||||||
|
new_vertex_slope
|
||||||
|
(
|
||||||
|
mapthing_t ** anchors,
|
||||||
|
const INT16 flags
|
||||||
|
){
|
||||||
|
pslope_t * slope = Z_Calloc(sizeof (pslope_t), PU_LEVEL, NULL);
|
||||||
|
const vector3_t anchorVertices[3] = {
|
||||||
|
{anchors[0]->x << FRACBITS, anchors[0]->y << FRACBITS, anchors[0]->z << FRACBITS},
|
||||||
|
{anchors[1]->x << FRACBITS, anchors[1]->y << FRACBITS, anchors[1]->z << FRACBITS},
|
||||||
|
{anchors[2]->x << FRACBITS, anchors[2]->y << FRACBITS, anchors[2]->z << FRACBITS}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (flags & ML_NETONLY)
|
||||||
|
{
|
||||||
|
slope->flags |= SL_NOPHYSICS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & ML_NONET)
|
||||||
|
{
|
||||||
|
slope->flags |= SL_DYNAMIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
P_ReconfigureViaVertexes(slope, anchorVertices[0], anchorVertices[1], anchorVertices[2]);
|
||||||
|
//slope->refpos = 5;
|
||||||
|
|
||||||
|
// Add to the slope list
|
||||||
|
slope->next = slopelist;
|
||||||
|
slopelist = slope;
|
||||||
|
|
||||||
|
slopecount++;
|
||||||
|
slope->id = slopecount;
|
||||||
|
|
||||||
|
return slope;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mapthing_t **
|
||||||
|
flip_slope
|
||||||
|
(
|
||||||
|
mapthing_t ** origin,
|
||||||
|
const sector_t * sector
|
||||||
|
){
|
||||||
|
mapthing_t * copy = Z_Malloc(3 * sizeof (mapthing_t), PU_LEVEL, NULL);
|
||||||
|
mapthing_t ** anchors = Z_Malloc(3 * sizeof (mapthing_t *), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
memcpy(©[i], origin[i], sizeof copy[i]);
|
||||||
|
|
||||||
|
copy[i].options ^= MTF_OBJECTFLIP;
|
||||||
|
copy[i].z = anchor_height(©[i], sector);
|
||||||
|
|
||||||
|
anchors[i] = ©[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return anchors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
slope_sector
|
||||||
|
(
|
||||||
|
pslope_t ** slope,
|
||||||
|
pslope_t ** alt,
|
||||||
|
sector_t * sector,
|
||||||
|
const INT16 flags,
|
||||||
|
const struct anchor_list * list,
|
||||||
|
const INT16 tag
|
||||||
|
){
|
||||||
|
mapthing_t ** anchors = find_closest_anchors(sector, list, tag);
|
||||||
|
|
||||||
|
if (anchors != NULL)
|
||||||
|
{
|
||||||
|
(*slope) = new_vertex_slope(anchors, flags);
|
||||||
|
|
||||||
|
/* Effect 6 - invert slope to opposite side */
|
||||||
|
if (flags & ML_EFFECT6)
|
||||||
|
{
|
||||||
|
(*alt) = new_vertex_slope(flip_slope(anchors, sector), flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
sector->hasslope = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_anchored_slope
|
||||||
|
(
|
||||||
|
const line_t * line,
|
||||||
|
const int plane
|
||||||
|
){
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FLOOR = 0x1,
|
||||||
|
CEILING = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
INT16 flags = line->flags;
|
||||||
|
|
||||||
|
const int side = ( flags & ML_NOCLIMB ) != 0;
|
||||||
|
|
||||||
|
sector_t * s;
|
||||||
|
|
||||||
|
if (side == 0 || flags & ML_TWOSIDED)
|
||||||
|
{
|
||||||
|
s = sides[line->sidenum[side]].sector;
|
||||||
|
|
||||||
|
if (plane == (FLOOR|CEILING))
|
||||||
|
{
|
||||||
|
flags &= ~ML_EFFECT6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plane & FLOOR)
|
||||||
|
{
|
||||||
|
slope_sector
|
||||||
|
(&s->f_slope, &s->c_slope, s, flags, &floor_anchors, line->tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plane & CEILING)
|
||||||
|
{
|
||||||
|
slope_sector
|
||||||
|
(&s->c_slope, &s->f_slope, s, flags, &ceiling_anchors, line->tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_BuildSlopeAnchorList (void) {
|
||||||
|
allocate_anchors();
|
||||||
|
build_anchors();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_SetupAnchoredSlopes (void) {
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FLOOR = 0x1,
|
||||||
|
CEILING = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < numlines; ++i)
|
||||||
|
{
|
||||||
|
if (lines[i].special == LT_SLOPE_ANCHORS_FLOOR)
|
||||||
|
{
|
||||||
|
make_anchored_slope(&lines[i], FLOOR);
|
||||||
|
}
|
||||||
|
else if (lines[i].special == LT_SLOPE_ANCHORS_CEILING)
|
||||||
|
{
|
||||||
|
make_anchored_slope(&lines[i], CEILING);
|
||||||
|
}
|
||||||
|
else if (lines[i].special == LT_SLOPE_ANCHORS)
|
||||||
|
{
|
||||||
|
make_anchored_slope(&lines[i], FLOOR|CEILING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -888,6 +888,10 @@ sfxinfo_t S_sfx[NUMSFX] =
|
||||||
{"bhurry", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // v1.0.2 Battle overtime
|
{"bhurry", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // v1.0.2 Battle overtime
|
||||||
{"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Banana sniping
|
{"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Banana sniping
|
||||||
{"sploss", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Down to yellow sparks
|
{"sploss", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Down to yellow sparks
|
||||||
|
{"join", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Player joined server
|
||||||
|
{"leave", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Player left server
|
||||||
|
{"requst", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Got a Discord join request
|
||||||
|
{"syfail", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Funny sync failure
|
||||||
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // :shitsfree:
|
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // :shitsfree:
|
||||||
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Debug notification
|
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Debug notification
|
||||||
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang
|
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang
|
||||||
|
|
|
||||||
|
|
@ -952,6 +952,10 @@ typedef enum
|
||||||
sfx_bhurry,
|
sfx_bhurry,
|
||||||
sfx_bsnipe,
|
sfx_bsnipe,
|
||||||
sfx_sploss,
|
sfx_sploss,
|
||||||
|
sfx_join,
|
||||||
|
sfx_leave,
|
||||||
|
sfx_requst,
|
||||||
|
sfx_syfail,
|
||||||
sfx_itfree,
|
sfx_itfree,
|
||||||
sfx_dbgsal,
|
sfx_dbgsal,
|
||||||
sfx_cock,
|
sfx_cock,
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,11 @@ static patch_t *fnshico;
|
||||||
static patch_t *hud_tv1;
|
static patch_t *hud_tv1;
|
||||||
static patch_t *hud_tv2;
|
static patch_t *hud_tv2;
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
// Discord Rich Presence
|
||||||
|
static patch_t *envelope;
|
||||||
|
#endif
|
||||||
|
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
|
|
||||||
hudinfo_t hudinfo[NUMHUDITEMS] =
|
hudinfo_t hudinfo[NUMHUDITEMS] =
|
||||||
|
|
@ -363,6 +368,11 @@ void ST_LoadGraphics(void)
|
||||||
// Midnight Channel:
|
// Midnight Channel:
|
||||||
hud_tv1 = W_CachePatchName("HUD_TV1", PU_HUDGFX);
|
hud_tv1 = W_CachePatchName("HUD_TV1", PU_HUDGFX);
|
||||||
hud_tv2 = W_CachePatchName("HUD_TV2", PU_HUDGFX);
|
hud_tv2 = W_CachePatchName("HUD_TV2", PU_HUDGFX);
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
// Discord Rich Presence
|
||||||
|
envelope = W_CachePatchName("K_REQUES", PU_HUDGFX);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// made separate so that skins code can reload custom face graphics
|
// made separate so that skins code can reload custom face graphics
|
||||||
|
|
@ -1009,6 +1019,22 @@ static void ST_MayonakaStatic(void)
|
||||||
V_DrawFixedPatch(320<<FRACBITS, 142<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_FLIP|flag, hud_tv2, NULL);
|
V_DrawFixedPatch(320<<FRACBITS, 142<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_FLIP|flag, hud_tv2, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
void ST_AskToJoinEnvelope(void)
|
||||||
|
{
|
||||||
|
const tic_t freq = TICRATE/2;
|
||||||
|
|
||||||
|
if (menuactive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((leveltime % freq) < freq/2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
V_DrawFixedPatch(296*FRACUNIT, 2*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTORIGHT, envelope, NULL);
|
||||||
|
// maybe draw number of requests with V_DrawPingNum ?
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ST_Drawer(void)
|
void ST_Drawer(void)
|
||||||
{
|
{
|
||||||
boolean stagetitle = false; // Decide whether to draw the stage title or not
|
boolean stagetitle = false; // Decide whether to draw the stage title or not
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,11 @@ void ST_Ticker(boolean run);
|
||||||
// Called when naming a replay.
|
// Called when naming a replay.
|
||||||
void ST_DrawDemoTitleEntry(void);
|
void ST_DrawDemoTitleEntry(void);
|
||||||
|
|
||||||
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
// Called when you have Discord asks
|
||||||
|
void ST_AskToJoinEnvelope(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Called by main loop.
|
// Called by main loop.
|
||||||
void ST_Drawer(void);
|
void ST_Drawer(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,10 @@ ifndef MINGW64 #miniupnc is broken with MINGW64
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef NO_DISCORDRPC
|
||||||
|
HAVE_DISCORDRPC=1
|
||||||
|
endif
|
||||||
|
|
||||||
OPTS=-DSTDC_HEADERS
|
OPTS=-DSTDC_HEADERS
|
||||||
|
|
||||||
ifndef GCC44
|
ifndef GCC44
|
||||||
|
|
@ -76,6 +80,12 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef MINGW64
|
||||||
|
CPPFLAGS+=-I../libs/drmingw/include
|
||||||
|
LDFLAGS+=-L../libs/drmingw/lib/win32
|
||||||
|
LIBS+=-lmgwhelp -lexchndl
|
||||||
|
endif
|
||||||
|
|
||||||
# name of the exefile
|
# name of the exefile
|
||||||
ifdef SDL
|
ifdef SDL
|
||||||
EXENAME?=srb2kart.exe
|
EXENAME?=srb2kart.exe
|
||||||
|
|
@ -162,4 +172,15 @@ ifdef MINGW64
|
||||||
else
|
else
|
||||||
CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl
|
CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl
|
||||||
endif #MINGW64
|
endif #MINGW64
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef HAVE_DISCORDRPC
|
||||||
|
ifdef MINGW64
|
||||||
|
CPPFLAGS+=-I../libs/discord-rpc/win64-dynamic/include
|
||||||
|
LDFLAGS+=-L../libs/discord-rpc/win64-dynamic/lib
|
||||||
|
else
|
||||||
|
CPPFLAGS+=-I../libs/discord-rpc/win32-dynamic/include
|
||||||
|
LDFLAGS+=-L../libs/discord-rpc/win32-dynamic/lib
|
||||||
|
endif
|
||||||
|
LIBS+=-ldiscord-rpc
|
||||||
|
endif
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
SRB2Kart 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 "SRB2Kart". This is where your game data and addons may live. For example,
|
|
||||||
|
|
||||||
C:\Users\[User]\SRB2Kart
|
|
||||||
|
|
||||||
4. Run the game! Double-click srb2kart.exe -- or see if you have Start Menu icons under "SRB2Kart".
|
|
||||||
Loading…
Add table
Reference in a new issue