Merge remote-tracking branch 'remotes/public/master' into followme

This commit is contained in:
Wolfy 2019-04-06 13:48:46 -05:00
commit 97eb011a58
53 changed files with 1158 additions and 1074 deletions

View file

@ -3,7 +3,7 @@ jobs:
build: build:
working_directory: /root/SRB2 working_directory: /root/SRB2
docker: docker:
- image: debian:jessie - image: debian:stretch
environment: environment:
CC: ccache gcc -m32 CC: ccache gcc -m32
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
@ -36,17 +36,20 @@ jobs:
- v1-SRB2-APT - v1-SRB2-APT
- run: - run:
name: Install SDK name: Install SDK
command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
- save_cache: - save_cache:
key: v1-SRB2-APT key: v1-SRB2-APT
paths: paths:
- /var/cache/apt/archives - /var/cache/apt/archives
- checkout - checkout
- run: - run:
name: Compile without network support name: Compile without network support and BLUA
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1
- run: - run:
name: Clean build name: wipe build
command: make -C src LINUX=1 cleandep
- run:
name: rebuild depend
command: make -C src LINUX=1 clean command: make -C src LINUX=1 clean
- restore_cache: - restore_cache:
keys: keys:

View file

@ -26,6 +26,7 @@ matrix:
- p7zip-full - p7zip-full
- gcc-4.4 - gcc-4.4
compiler: gcc-4.4 compiler: gcc-4.4
env: GCC44=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7 #gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
- os: linux - os: linux
@ -39,6 +40,7 @@ matrix:
- p7zip-full - p7zip-full
- gcc-4.6 - gcc-4.6
compiler: gcc-4.6 compiler: gcc-4.6
env: GCC46=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4 #gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
- os: linux - os: linux
@ -52,10 +54,12 @@ matrix:
- p7zip-full - p7zip-full
- gcc-4.7 - gcc-4.7
compiler: gcc-4.7 compiler: gcc-4.7
env: GCC47=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.7 #gcc-4.7
- os: linux - os: linux
compiler: gcc compiler: gcc
env: GCC48=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 #gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
- os: linux - os: linux
@ -71,6 +75,7 @@ matrix:
- p7zip-full - p7zip-full
- gcc-4.8 - gcc-4.8
compiler: gcc-4.8 compiler: gcc-4.8
env: GCC48=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux - os: linux
@ -86,7 +91,7 @@ matrix:
- p7zip-full - p7zip-full
- gcc-7 - gcc-7
compiler: gcc-7 compiler: gcc-7
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802 #gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
- os: linux - os: linux
@ -102,7 +107,7 @@ matrix:
- p7zip-full - p7zip-full
- gcc-8 - gcc-8
compiler: gcc-8 compiler: gcc-8
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow" env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow" GCC81=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0 #gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
- os: linux - os: linux
@ -249,17 +254,21 @@ matrix:
# osx_image: xcode7.2 # osx_image: xcode7.2
# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
# #Apple LLVM version 7.0.2 (clang-700.1.81) # #Apple LLVM version 7.0.2 (clang-700.1.81)
# - os: osx
# osx_image: xcode7.3
# #Apple LLVM version 7.3.0 (clang-703.0.31)
# - os: osx
# osx_image: xcode7.3
# #Apple LLVM version 7.3.0 (clang-703.0.31)
- os: osx - os: osx
osx_image: xcode7.3
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#Apple LLVM version 7.3.0 (clang-703.0.31) #Default: macOS 10.13 and Xcode 9.4.1
################################ ################################
# Deployer Buildbots - OSX # Deployer Buildbots - OSX
################################ ################################
- os: osx - os: osx
osx_image: xcode7.3
if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
AND env(DPL_TERMINATE_MAIN) != "1" AND env(DPL_TERMINATE_MAIN) != "1"
@ -559,6 +568,16 @@ addons:
- libgme-dev - libgme-dev
- zlib1g-dev - zlib1g-dev
- p7zip-full - p7zip-full
homebrew:
taps:
- mazmazz/srb2
packages:
- sdl2_mixer
- game-music-emu
- p7zip
- cmake
update: true
before_install: before_install:
@ -591,18 +610,10 @@ install:
# * `sdl2_mixer` requires options from the formula tap https://github.com/mazmazz/homebrew-srb2 # * `sdl2_mixer` requires options from the formula tap https://github.com/mazmazz/homebrew-srb2
# * `brew postinstall` runs post-install scripts after building a bottle # * `brew postinstall` runs post-install scripts after building a bottle
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew update; if [[ "$__DPL_ACTIVE" == "1" ]]; then
brew tap mazmazz/srb2; brew install --build-bottle sdl2 game-music-emu;
fi;
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
if [[ "$__DPL_ACTIVE" != "1" ]]; then
brew install sdl2 sdl2_mixer game-music-emu p7zip;
brew install cmake||true;
else
brew install --build-bottle sdl2 game-music-emu p7zip;
brew install --build-bottle mazmazz/srb2/sdl2_mixer --with-flac --with-mpg123; brew install --build-bottle mazmazz/srb2/sdl2_mixer --with-flac --with-mpg123;
brew postinstall sdl2 game-music-emu p7zip mazmazz/srb2/sdl2_mixer; brew postinstall sdl2 game-music-emu mazmazz/srb2/sdl2_mixer;
brew install cmake||true;
fi; fi;
fi fi
- mkdir -p $HOME/srb2_cache - mkdir -p $HOME/srb2_cache
@ -667,7 +678,6 @@ before_script:
-DCPACK_PACKAGE_VENDOR="${PROGRAM_VENDOR}" -DCPACK_PACKAGE_VENDOR="${PROGRAM_VENDOR}"
-DSRB2_SDL2_EXE_NAME="${PROGRAM_FILENAME}" -DSRB2_SDL2_EXE_NAME="${PROGRAM_FILENAME}"
script: script:
# Build our Makefile from Cmake! # Build our Makefile from Cmake!
- if [[ "$__DPL_ACTIVE" == "1" ]]; then - if [[ "$__DPL_ACTIVE" == "1" ]]; then

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine. # Version change is fine.
project(SRB2 project(SRB2
VERSION 1.0.2 VERSION 1.0.4
LANGUAGES C) LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
@ -56,13 +56,19 @@ macro(copy_files_to_build_dir target dlllist_var)
endif() endif()
endmacro() endmacro()
# 64-bit check # bitness check
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set(SRB2_SYSTEM_BITS 0)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Target is 64-bit") message(STATUS "Target is 64-bit")
set(SRB2_SYSTEM_BITS 64) set(SRB2_SYSTEM_BITS 64)
else() endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
message(STATUS "Target is 32-bit")
set(SRB2_SYSTEM_BITS 32) set(SRB2_SYSTEM_BITS 32)
endif() endif()
if(${SRB2_SYSTEM_BITS} EQUAL 0)
message(STATUS "Target bitness is unknown")
endif()
# OS macros # OS macros
if (UNIX) if (UNIX)

View file

@ -1,4 +1,4 @@
version: 1.0.2.{branch}-{build} version: 1.0.4.{branch}-{build}
os: MinGW os: MinGW
environment: environment:
@ -29,7 +29,7 @@ environment:
############################## ##############################
DPL_ENABLED: 0 DPL_ENABLED: 0
DPL_TAG_ENABLED: 0 DPL_TAG_ENABLED: 0
DPL_INSTALLER_NAME: srb2kart-v102 DPL_INSTALLER_NAME: srb2kart-v104
# Asset handling is barebones vs. Travis Deployer. We operate on 7z only. # Asset handling is barebones vs. Travis Deployer. We operate on 7z only.
# Include the README files and the OpenGL batch in the main and patch archives. # Include the README files and the OpenGL batch in the main and patch archives.
# The x86/x64 archives contain the DLL binaries. # The x86/x64 archives contain the DLL binaries.

View file

@ -7,6 +7,10 @@
# and other things # and other things
# #
ifdef GCC81
GCC80=1
endif
ifdef GCC80 ifdef GCC80
GCC72=1 GCC72=1
endif endif

View file

@ -1254,7 +1254,8 @@ found:
var->string = var->zstring = Z_StrDup(valstr); var->string = var->zstring = Z_StrDup(valstr);
if (override) if (var->flags & CV_PASSWORD); // Don't change value for password field
else if (override)
var->value = overrideval; var->value = overrideval;
else if (var->flags & CV_FLOAT) else if (var->flags & CV_FLOAT)
{ {

View file

@ -95,7 +95,8 @@ typedef enum
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
// can only be set when we have the pointer to it // can only be set when we have the pointer to it
// used on menus // used on menus
CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on. CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on.
CV_PASSWORD = 4096 // Password field
} cvflags_t; } cvflags_t;
typedef struct CV_PossibleValue_s typedef struct CV_PossibleValue_s

View file

@ -37,7 +37,7 @@
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb * Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
* Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta * Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets * Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
* Last updated 2019 / 02 / 04 - Kart v1.0.3 - patch.kart * Last updated 2019 / 03 / 11 - Kart v1.0.4 - patch.kart
*/ */
// Base SRB2 hashes // Base SRB2 hashes
@ -52,7 +52,7 @@
#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964" #define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964"
#define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a" #define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a"
#ifdef USE_PATCH_KART #ifdef USE_PATCH_KART
#define ASSET_HASH_PATCH_KART "e06c1c90e5645c886026311964f8e1f5" #define ASSET_HASH_PATCH_KART "b5f48e1abccfa47a5745199182e2fef4"
#endif #endif
#endif #endif

View file

@ -544,6 +544,22 @@ static void CON_MoveConsole(void)
} }
} }
INT32 CON_ShiftChar(INT32 ch)
{
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
{
if (shiftdown ^ capslock)
ch = shiftxform[ch];
}
else // if we're holding shift we should still shift non letter symbols
{
if (shiftdown)
ch = shiftxform[ch];
}
return ch;
}
// Clear time of console heads up messages // Clear time of console heads up messages
// //
void CON_ClearHUD(void) void CON_ClearHUD(void)
@ -1084,16 +1100,6 @@ boolean CON_Responder(event_t *ev)
else if (key == KEY_KPADSLASH) else if (key == KEY_KPADSLASH)
key = '/'; key = '/';
// capslock
if (key == KEY_CAPSLOCK) // it's a toggle.
{
if (capslock)
capslock = false;
else
capslock = true;
return true;
}
// same capslock code as hu_stuff.c's HU_responder. Check there for details. // same capslock code as hu_stuff.c's HU_responder. Check there for details.
if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')) if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z'))
{ {

View file

@ -44,6 +44,8 @@ extern UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *or
// Console bg color (auto updated to match) // Console bg color (auto updated to match)
extern UINT8 *consolebgmap; extern UINT8 *consolebgmap;
INT32 CON_ShiftChar(INT32 ch);
void CON_SetupBackColormap(void); void CON_SetupBackColormap(void);
void CON_ClearHUD(void); // clear heads up messages void CON_ClearHUD(void); // clear heads up messages

View file

@ -22,6 +22,7 @@
#include "i_video.h" #include "i_video.h"
#include "d_net.h" #include "d_net.h"
#include "d_main.h" #include "d_main.h"
#include "d_event.h"
#include "g_game.h" #include "g_game.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "keys.h" #include "keys.h"
@ -72,6 +73,7 @@
#define PREDICTIONQUEUE BACKUPTICS #define PREDICTIONQUEUE BACKUPTICS
#define PREDICTIONMASK (PREDICTIONQUEUE-1) #define PREDICTIONMASK (PREDICTIONQUEUE-1)
#define MAX_REASONLENGTH 30 #define MAX_REASONLENGTH 30
#define FORCECLOSE 0x8000
boolean server = true; // true or false but !server == client boolean server = true; // true or false but !server == client
#define client (!server) #define client (!server)
@ -1126,12 +1128,22 @@ typedef enum
CL_DOWNLOADSAVEGAME, CL_DOWNLOADSAVEGAME,
#endif #endif
CL_CONNECTED, CL_CONNECTED,
CL_ABORTED CL_ABORTED,
CL_ASKDOWNLOADFILES,
CL_WAITDOWNLOADFILESRESPONSE,
CL_CHALLENGE
} cl_mode_t; } cl_mode_t;
static void GetPackets(void); static void GetPackets(void);
static cl_mode_t cl_mode = CL_SEARCHING; static cl_mode_t cl_mode = CL_SEARCHING;
static boolean cl_needsdownload = false;
static UINT8 cl_challengenum = 0;
static UINT8 cl_challengequestion[MD5_LEN+1];
static char cl_challengepassword[65];
static UINT8 cl_challengeanswer[MD5_LEN+1];
static UINT8 cl_challengeattempted = 0;
// Player name send/load // Player name send/load
@ -1168,6 +1180,8 @@ static void CV_LoadPlayerNames(UINT8 **p)
} }
#ifdef CLIENT_LOADINGSCREEN #ifdef CLIENT_LOADINGSCREEN
static UINT32 SL_SearchServer(INT32 node);
// //
// CL_DrawConnectionStatus // CL_DrawConnectionStatus
// //
@ -1191,11 +1205,42 @@ static inline void CL_DrawConnectionStatus(void)
// 15 pal entries total. // 15 pal entries total.
const char *cltext; const char *cltext;
for (i = 0; i < 16; ++i) if (cl_mode != CL_CHALLENGE)
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15)); for (i = 0; i < 16; ++i)
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
switch (cl_mode) switch (cl_mode)
{ {
case CL_CHALLENGE:
{
char asterisks[33];
size_t sl = min(32, strlen(cl_challengepassword));
UINT32 serverid;
memset(asterisks, '*', sl);
memset(asterisks+sl, 0, 33-sl);
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_MONOSPACE|V_ALLOWLOWERCASE, asterisks);
V_DrawFixedPatch((BASEVIDWIDTH/2) << FRACBITS, (BASEVIDHEIGHT/2) << FRACBITS, FRACUNIT, 0, W_CachePatchName("BSRVLOCK", PU_CACHE), NULL);
serverid = SL_SearchServer(servernode);
if (serverid == UINT32_MAX)
{
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT/2-8, 32, 1);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_REDMAP, M_GetText("This server is password protected."));
}
else
{
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT/2-8, 32, 3);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_REDMAP, M_GetText("This server,"));
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2+8, V_ALLOWLOWERCASE, serverlist[serverid].info.servername);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2+16, V_REDMAP, M_GetText("is password protected."));
}
cltext = M_GetText(cl_challengeattempted ? "Incorrect password. Please try again." : "Please enter the server password.");
}
break;
#ifdef JOININGAME #ifdef JOININGAME
case CL_DOWNLOADSAVEGAME: case CL_DOWNLOADSAVEGAME:
if (lastfilenum != -1) if (lastfilenum != -1)
@ -1215,6 +1260,9 @@ static inline void CL_DrawConnectionStatus(void)
case CL_WAITJOINRESPONSE: case CL_WAITJOINRESPONSE:
cltext = M_GetText("Requesting to join..."); cltext = M_GetText("Requesting to join...");
break; break;
case CL_ASKDOWNLOADFILES:
case CL_WAITDOWNLOADFILESRESPONSE:
cltext = M_GetText("Waiting to download files...");
default: default:
cltext = M_GetText("Connecting to server..."); cltext = M_GetText("Connecting to server...");
break; break;
@ -1292,6 +1340,9 @@ static boolean CL_SendJoin(void)
netbuffer->u.clientcfg.localplayers = localplayers; netbuffer->u.clientcfg.localplayers = localplayers;
netbuffer->u.clientcfg.version = VERSION; netbuffer->u.clientcfg.version = VERSION;
netbuffer->u.clientcfg.subversion = SUBVERSION; netbuffer->u.clientcfg.subversion = SUBVERSION;
netbuffer->u.clientcfg.needsdownload = cl_needsdownload;
netbuffer->u.clientcfg.challengenum = cl_challengenum;
memcpy(netbuffer->u.clientcfg.challengeanswer, cl_challengeanswer, MD5_LEN);
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
} }
@ -1312,7 +1363,13 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.gametype = (UINT8)(G_BattleGametype() ? VANILLA_GT_MATCH : VANILLA_GT_RACE); // SRB2Kart: Vanilla's gametype constants for MS support netbuffer->u.serverinfo.gametype = (UINT8)(G_BattleGametype() ? VANILLA_GT_MATCH : VANILLA_GT_RACE); // SRB2Kart: Vanilla's gametype constants for MS support
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated;
netbuffer->u.serverinfo.kartvars = (UINT8) (
(cv_kartspeed.value & SV_SPEEDMASK) |
(dedicated ? SV_DEDICATED : 0) |
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
);
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
MAXSERVERNAME); MAXSERVERNAME);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
@ -1745,8 +1802,6 @@ static void SendAskInfo(INT32 node, boolean viams)
serverelem_t serverlist[MAXSERVERLIST]; serverelem_t serverlist[MAXSERVERLIST];
UINT32 serverlistcount = 0; UINT32 serverlistcount = 0;
#define FORCECLOSE 0x8000
static void SL_ClearServerList(INT32 connectedserver) static void SL_ClearServerList(INT32 connectedserver)
{ {
UINT32 i; UINT32 i;
@ -1872,7 +1927,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
/** Called by CL_ServerConnectionTicker /** Called by CL_ServerConnectionTicker
* *
* \param viams ??? * \param viams ???
* \param asksent ??? * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
* \return False if the connection was aborted * \return False if the connection was aborted
* \sa CL_ServerConnectionTicker * \sa CL_ServerConnectionTicker
* \sa CL_ConnectToServer * \sa CL_ConnectToServer
@ -1965,9 +2020,12 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
), NULL, MM_NOTHING); ), NULL, MM_NOTHING);
return false; return false;
} }
cl_mode = CL_ASKDOWNLOADFILES;
// no problem if can't send packet, we will retry later // no problem if can't send packet, we will retry later
if (CL_SendRequestFile()) //if (CL_SendRequestFile())
cl_mode = CL_DOWNLOADFILES; // cl_mode = CL_DOWNLOADFILES;
} }
} }
else else
@ -1997,7 +2055,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
* \param viams ??? * \param viams ???
* \param tmpsave The name of the gamestate file??? * \param tmpsave The name of the gamestate file???
* \param oldtic Used for knowing when to poll events and redraw * \param oldtic Used for knowing when to poll events and redraw
* \param asksent ??? * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
* \return False if the connection was aborted * \return False if the connection was aborted
* \sa CL_ServerConnectionSearchTicker * \sa CL_ServerConnectionSearchTicker
* \sa CL_ConnectToServer * \sa CL_ConnectToServer
@ -2035,6 +2093,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
/* FALLTHRU */ /* FALLTHRU */
case CL_ASKJOIN: case CL_ASKJOIN:
cl_needsdownload = false;
CL_LoadServerFiles(); CL_LoadServerFiles();
#ifdef JOININGAME #ifdef JOININGAME
// prepare structures to save the file // prepare structures to save the file
@ -2043,9 +2102,23 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
CL_PrepareDownloadSaveGame(tmpsave); CL_PrepareDownloadSaveGame(tmpsave);
#endif #endif
if (CL_SendJoin()) if (CL_SendJoin())
{
*asksent = I_GetTime();
cl_mode = CL_WAITJOINRESPONSE; cl_mode = CL_WAITJOINRESPONSE;
}
break; break;
case CL_ASKDOWNLOADFILES:
cl_needsdownload = true;
if (CL_SendJoin())
{
*asksent = I_GetTime();
cl_mode = CL_WAITDOWNLOADFILESRESPONSE;
}
break;
#ifdef JOININGAME #ifdef JOININGAME
case CL_DOWNLOADSAVEGAME: case CL_DOWNLOADSAVEGAME:
// At this state, the first (and only) needed file is the gamestate // At this state, the first (and only) needed file is the gamestate
@ -2059,7 +2132,19 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
break; break;
#endif #endif
case CL_CHALLENGE:
(*asksent) = I_GetTime() - NEWTICRATE; // Send password immediately upon entering
break;
case CL_WAITJOINRESPONSE: case CL_WAITJOINRESPONSE:
case CL_WAITDOWNLOADFILESRESPONSE:
if (*asksent + NEWTICRATE < I_GetTime() && CL_SendJoin())
{
*asksent = I_GetTime();
}
break;
case CL_CONNECTED: case CL_CONNECTED:
default: default:
break; break;
@ -2077,20 +2162,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
// Call it only once by tic // Call it only once by tic
if (*oldtic != I_GetTime()) if (*oldtic != I_GetTime())
{ {
INT32 key;
I_OsPolling(); I_OsPolling();
key = I_GetKey(); D_ProcessEvents();
// Only ESC and non-keyboard keys abort connection if (gamestate != GS_WAITINGPLAYERS)
if (key == KEY_ESCAPE || key >= KEY_MOUSE1)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
D_QuitNetGame();
CL_Reset();
D_StartTitle();
return false; return false;
}
// why are these here? this is for servers, we're a client // why are these here? this is for servers, we're a client
//if (key == 's' && server) //if (key == 's' && server)
@ -2119,6 +2194,71 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
return true; return true;
} }
boolean CL_Responder(event_t *ev)
{
size_t len;
INT32 ch;
if (!(client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED))
return false; // Don't do anything outside of the connection screen
if (ev->type != ev_keydown)
return false;
ch = (INT32)ev->data1;
// Only ESC and non-keyboard keys abort connection
if (ch == KEY_ESCAPE || ch >= KEY_MOUSE1)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
//M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
D_QuitNetGame();
CL_Reset();
D_StartTitle();
return true;
}
if (cl_mode != CL_CHALLENGE)
return false;
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|| ch == ' ') // Allow spaces, of course
{
len = strlen(cl_challengepassword);
if (len < 64)
{
cl_challengepassword[len+1] = 0;
cl_challengepassword[len] = CON_ShiftChar(ch);
}
cl_challengeattempted = 0;
}
else if (ch == KEY_BACKSPACE)
{
len = strlen(cl_challengepassword);
if (len > 0)
cl_challengepassword[len-1] = 0;
cl_challengeattempted = 0;
}
else if (ch == KEY_ENTER)
{
netgame = true;
multiplayer = true;
#ifndef NONET
SL_ClearServerList(servernode);
#endif
cl_mode = CL_SEARCHING;
D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer);
cl_challengeattempted = 1;
}
return true;
}
/** Use adaptive send using net_bandwidth and stat.sendbytes /** Use adaptive send using net_bandwidth and stat.sendbytes
* *
* \param viams ??? * \param viams ???
@ -2139,6 +2279,7 @@ static void CL_ConnectToServer(boolean viams)
#endif #endif
cl_mode = CL_SEARCHING; cl_mode = CL_SEARCHING;
cl_challengenum = 0;
#ifdef CLIENT_LOADINGSCREEN #ifdef CLIENT_LOADINGSCREEN
lastfilenum = -1; lastfilenum = -1;
@ -2196,6 +2337,8 @@ static void CL_ConnectToServer(boolean viams)
SL_ClearServerList(servernode); SL_ClearServerList(servernode);
#endif #endif
cl_challengeattempted = 0;
do do
{ {
// If the connection was aborted for some reason, leave // If the connection was aborted for some reason, leave
@ -3142,6 +3285,9 @@ void D_ClientServerInit(void)
gametic = 0; gametic = 0;
localgametic = 0; localgametic = 0;
memset(cl_challengequestion, 0x00, MD5_LEN+1);
memset(cl_challengeanswer, 0x00, MD5_LEN+1);
// do not send anything before the real begin // do not send anything before the real begin
SV_StopServer(); SV_StopServer();
SV_ResetServer(); SV_ResetServer();
@ -3631,6 +3777,33 @@ static void HandleConnect(SINT8 node)
boolean newnode = false; boolean newnode = false;
#endif #endif
if (node != servernode && !nodeingame[node] && D_IsJoinPasswordOn())
{
// Ensure node sent the correct password challenge
boolean passed = false;
if (netbuffer->u.clientcfg.challengenum && D_VerifyJoinPasswordChallenge(netbuffer->u.clientcfg.challengenum, netbuffer->u.clientcfg.challengeanswer))
passed = true;
if (!passed)
{
D_MakeJoinPasswordChallenge(&netbuffer->u.joinchallenge.challengenum, netbuffer->u.joinchallenge.question);
netbuffer->packettype = PT_JOINCHALLENGE;
HSendPacket(node, true, 0, sizeof(joinchallenge_pak));
Net_CloseConnection(node);
return;
}
}
if (netbuffer->u.clientcfg.needsdownload)
{
netbuffer->packettype = PT_DOWNLOADFILESOKAY;
HSendPacket(node, true, 0, 0);
return;
}
// client authorised to join // client authorised to join
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
if (!nodeingame[node]) if (!nodeingame[node])
@ -3639,6 +3812,7 @@ static void HandleConnect(SINT8 node)
#ifndef NONET #ifndef NONET
newnode = true; newnode = true;
#endif #endif
SV_AddNode(node); SV_AddNode(node);
/// \note Wait what??? /// \note Wait what???
@ -3794,6 +3968,43 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node); Net_CloseConnection(node);
break; break;
case PT_JOINCHALLENGE:
if (server && serverrunning)
{ // But wait I thought I'm the server?
Net_CloseConnection(node);
break;
}
SERVERONLY
if (cl_mode == CL_WAITJOINRESPONSE || cl_mode == CL_WAITDOWNLOADFILESRESPONSE)
{
cl_challengenum = netbuffer->u.joinchallenge.challengenum;
memcpy(cl_challengequestion, netbuffer->u.joinchallenge.question, 16);
Net_CloseConnection(node|FORCECLOSE); // Don't need to stay connected while challenging
cl_mode = CL_CHALLENGE;
switch (cl_challengeattempted)
{
case 2:
// We already sent a correct password, so throw it back up again.
D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer);
cl_mode = CL_ASKJOIN;
break;
case 1:
// We entered the wrong password!
S_StartSound(NULL, sfx_s26d);
break;
default:
// First entry to the password screen.
S_StartSound(NULL, sfx_s224);
break;
}
}
break;
case PT_SERVERREFUSE: // Negative response of client join request case PT_SERVERREFUSE: // Negative response of client join request
if (server && serverrunning) if (server && serverrunning)
{ // But wait I thought I'm the server? { // But wait I thought I'm the server?
@ -3822,6 +4033,41 @@ static void HandlePacketFromAwayNode(SINT8 node)
} }
break; break;
case PT_DOWNLOADFILESOKAY:
if (server && serverrunning)
{ // But wait I thought I'm the server?
Net_CloseConnection(node);
break;
}
SERVERONLY
// This should've already been checked, but just to be safe...
if (!CL_CheckDownloadable())
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You cannot connect to this server\n"
"because you cannot download the files\n"
"that you are missing from the server.\n\n"
"See the console or log file for\n"
"more details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
break;
}
if (cl_challengeattempted == 1) // Successful password noise.
S_StartSound(NULL, sfx_s221);
cl_challengeattempted = 2;
CONS_Printf("trying to download\n");
if (CL_SendRequestFile())
cl_mode = CL_DOWNLOADFILES;
break;
case PT_SERVERCFG: // Positive response of client join request case PT_SERVERCFG: // Positive response of client join request
{ {
INT32 j; INT32 j;
@ -3837,6 +4083,9 @@ static void HandlePacketFromAwayNode(SINT8 node)
if (cl_mode != CL_WAITJOINRESPONSE) if (cl_mode != CL_WAITJOINRESPONSE)
break; break;
if (cl_challengeattempted == 1) // Successful password noise.
S_StartSound(NULL, sfx_s221);
if (client) if (client)
{ {
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);

View file

@ -13,11 +13,14 @@
#ifndef __D_CLISRV__ #ifndef __D_CLISRV__
#define __D_CLISRV__ #define __D_CLISRV__
#include "d_event.h"
#include "d_ticcmd.h" #include "d_ticcmd.h"
#include "d_netcmd.h" #include "d_netcmd.h"
#include "tables.h" #include "tables.h"
#include "d_player.h" #include "d_player.h"
#include "md5.h"
// Network play related stuff. // Network play related stuff.
// There is a data struct that stores network // There is a data struct that stores network
// communication related stuff, and another // communication related stuff, and another
@ -73,6 +76,9 @@ typedef enum
PT_CLIENT4MIS, PT_CLIENT4MIS,
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
PT_JOINCHALLENGE, // You must give a password to joinnnnn
PT_DOWNLOADFILESOKAY, // You can download files from the server....
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
// allows HSendPacket(*, true, *, *) to return false. // allows HSendPacket(*, true, *, *) to return false.
// In addition, this packet can't occupy all the available slots. // In addition, this packet can't occupy all the available slots.
@ -353,9 +359,21 @@ typedef struct
UINT8 version; // Different versions don't work UINT8 version; // Different versions don't work
UINT8 subversion; // Contains build version UINT8 subversion; // Contains build version
UINT8 localplayers; UINT8 localplayers;
UINT8 mode; UINT8 needsdownload;
UINT8 challengenum; // Non-zero if trying to join with a password attempt
UINT8 challengeanswer[MD5_LEN]; // Join challenge
} ATTRPACK clientconfig_pak; } ATTRPACK clientconfig_pak;
typedef struct
{
UINT8 challengenum; // Number to send back in join attempt
UINT8 question[MD5_LEN]; // Challenge data to be manipulated and answered with
} ATTRPACK joinchallenge_pak;
#define SV_SPEEDMASK 0x03
#define SV_DEDICATED 0x40
#define SV_PASSWORD 0x80
#define MAXSERVERNAME 32 #define MAXSERVERNAME 32
#define MAXFILENEEDED 915 #define MAXFILENEEDED 915
// This packet is too large // This packet is too large
@ -368,7 +386,7 @@ typedef struct
UINT8 gametype; UINT8 gametype;
UINT8 modifiedgame; UINT8 modifiedgame;
UINT8 cheatsenabled; UINT8 cheatsenabled;
UINT8 isdedicated; UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes
UINT8 fileneedednum; UINT8 fileneedednum;
SINT8 adminplayer; SINT8 adminplayer;
tic_t time; tic_t time;
@ -447,7 +465,8 @@ typedef struct
UINT8 resynchgot; // UINT8 resynchgot; //
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
filetx_pak filetxpak; // 139 bytes filetx_pak filetxpak; // 139 bytes
clientconfig_pak clientcfg; // 136 bytes clientconfig_pak clientcfg; // 153 bytes
joinchallenge_pak joinchallenge; // 17 bytes
serverinfo_pak serverinfo; // 1024 bytes serverinfo_pak serverinfo; // 1024 bytes
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes askinfo_pak askinfo; // 61 bytes
@ -555,6 +574,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p);
void CL_Reset(void); void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum); void CL_ClearPlayer(INT32 playernum);
void CL_UpdateServerList(boolean internetsearch, INT32 room); void CL_UpdateServerList(boolean internetsearch, INT32 room);
boolean CL_Responder(event_t *ev);
// Is there a game running // Is there a game running
boolean Playing(void); boolean Playing(void);

View file

@ -111,6 +111,7 @@ UINT8 window_notinfocus = false;
//static INT32 demosequence; //static INT32 demosequence;
static const char *pagename = "MAP1PIC"; static const char *pagename = "MAP1PIC";
static char *startupwadfiles[MAX_WADFILES]; static char *startupwadfiles[MAX_WADFILES];
static char *startuppwads[MAX_WADFILES];
boolean devparm = false; // started game with -devparm boolean devparm = false; // started game with -devparm
@ -203,6 +204,8 @@ static inline void D_ModifierKeyResponder(event_t *ev)
case KEY_RCTRL: ctrldown |= 0x2; return; case KEY_RCTRL: ctrldown |= 0x2; return;
case KEY_LALT: altdown |= 0x1; return; case KEY_LALT: altdown |= 0x1; return;
case KEY_RALT: altdown |= 0x2; return; case KEY_RALT: altdown |= 0x2; return;
case KEY_CAPSLOCK: capslock = !capslock; return;
default: return; default: return;
} }
else if (ev->type == ev_keyup) switch (ev->data1) else if (ev->type == ev_keyup) switch (ev->data1)
@ -236,6 +239,9 @@ void D_ProcessEvents(void)
if (M_ScreenshotResponder(ev)) if (M_ScreenshotResponder(ev))
continue; // ate the event continue; // ate the event
if (CL_Responder(ev))
continue;
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN) if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
{ {
if (cht_Responder(ev)) if (cht_Responder(ev))
@ -824,12 +830,12 @@ void D_StartTitle(void)
// //
// D_AddFile // D_AddFile
// //
static void D_AddFile(const char *file) static void D_AddFile(const char *file, char **filearray)
{ {
size_t pnumwadfiles; size_t pnumwadfiles;
char *newfile; char *newfile;
for (pnumwadfiles = 0; startupwadfiles[pnumwadfiles]; pnumwadfiles++) for (pnumwadfiles = 0; filearray[pnumwadfiles]; pnumwadfiles++)
; ;
newfile = malloc(strlen(file) + 1); newfile = malloc(strlen(file) + 1);
@ -839,16 +845,16 @@ static void D_AddFile(const char *file)
} }
strcpy(newfile, file); strcpy(newfile, file);
startupwadfiles[pnumwadfiles] = newfile; filearray[pnumwadfiles] = newfile;
} }
static inline void D_CleanFile(void) static inline void D_CleanFile(char **filearray)
{ {
size_t pnumwadfiles; size_t pnumwadfiles;
for (pnumwadfiles = 0; startupwadfiles[pnumwadfiles]; pnumwadfiles++) for (pnumwadfiles = 0; filearray[pnumwadfiles]; pnumwadfiles++)
{ {
free(startupwadfiles[pnumwadfiles]); free(filearray[pnumwadfiles]);
startupwadfiles[pnumwadfiles] = NULL; filearray[pnumwadfiles] = NULL;
} }
} }
@ -908,9 +914,9 @@ static void IdentifyVersion(void)
// Load the IWAD // Load the IWAD
if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2)) if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2))
D_AddFile(srb2wad2); D_AddFile(srb2wad2, startupwadfiles);
else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1)) else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1))
D_AddFile(srb2wad1); D_AddFile(srb2wad1, startupwadfiles);
else else
I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2); I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2);
@ -927,12 +933,12 @@ static void IdentifyVersion(void)
D_AddFile(va(pandf,srb2waddir,"patch.dta")); D_AddFile(va(pandf,srb2waddir,"patch.dta"));
#endif #endif
D_AddFile(va(pandf,srb2waddir,"gfx.kart")); D_AddFile(va(pandf,srb2waddir,"gfx.kart"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"textures.kart")); D_AddFile(va(pandf,srb2waddir,"textures.kart"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"chars.kart")); D_AddFile(va(pandf,srb2waddir,"chars.kart"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"maps.kart")); D_AddFile(va(pandf,srb2waddir,"maps.kart"), startupwadfiles);
#ifdef USE_PATCH_KART #ifdef USE_PATCH_KART
D_AddFile(va(pandf,srb2waddir,"patch.kart")); D_AddFile(va(pandf,srb2waddir,"patch.kart"), startupwadfiles);
#endif #endif
D_AddFile(va(pandf,srb2waddir,"followers.kart")); // merge this in GFX later, this is mostly to avoid uploading a MASSIVE patch.kart /gfx.kart for testing. -Lat' D_AddFile(va(pandf,srb2waddir,"followers.kart")); // merge this in GFX later, this is mostly to avoid uploading a MASSIVE patch.kart /gfx.kart for testing. -Lat'
@ -942,7 +948,7 @@ static void IdentifyVersion(void)
const char *musicpath = va(pandf,srb2waddir,str);\ const char *musicpath = va(pandf,srb2waddir,str);\
int ms = W_VerifyNMUSlumps(musicpath); \ int ms = W_VerifyNMUSlumps(musicpath); \
if (ms == 1) \ if (ms == 1) \
D_AddFile(musicpath); \ D_AddFile(musicpath, startupwadfiles); \
else if (ms == 0) \ else if (ms == 0) \
I_Error("File "str" has been modified with non-music/sound lumps"); \ I_Error("File "str" has been modified with non-music/sound lumps"); \
} }
@ -1007,9 +1013,12 @@ static inline void D_MakeTitleString(char *s)
// //
void D_SRB2Main(void) void D_SRB2Main(void)
{ {
INT32 p; INT32 p, i;
char srb2[82]; // srb2 title banner char srb2[82]; // srb2 title banner
char title[82]; char title[82];
lumpinfo_t *lumpinfo;
UINT16 wadnum;
char *name;
INT32 pstartmap = 1; INT32 pstartmap = 1;
boolean autostart = false; boolean autostart = false;
@ -1161,11 +1170,7 @@ void D_SRB2Main(void)
const char *s = M_GetNextParm(); const char *s = M_GetNextParm();
if (s) // Check for NULL? if (s) // Check for NULL?
{ D_AddFile(s, startuppwads);
if (!W_VerifyNMUSlumps(s))
G_SetGameModified(true, false);
D_AddFile(s);
}
} }
} }
} }
@ -1215,13 +1220,13 @@ void D_SRB2Main(void)
// load wad, including the main wad file // load wad, including the main wad file
CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
if (!W_InitMultipleFiles(startupwadfiles)) if (!W_InitMultipleFiles(startupwadfiles, false))
#ifdef _DEBUG #ifdef _DEBUG
CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
#else #else
I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
#endif #endif
D_CleanFile(); D_CleanFile(startupwadfiles);
mainwads = 0; mainwads = 0;
@ -1235,7 +1240,7 @@ void D_SRB2Main(void)
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.kart mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_KART); // textures.kart mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_KART); // textures.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart -- 4 - If you touch this, make sure to touch up the majormods stuff below.
#ifdef USE_PATCH_KART #ifdef USE_PATCH_KART
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart
#endif #endif
@ -1255,6 +1260,66 @@ void D_SRB2Main(void)
mainwadstally = packetsizetally; mainwadstally = packetsizetally;
//
// search for maps
//
for (wadnum = 4; wadnum < 6; wadnum++) // fucking arbitrary numbers
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{
INT16 num;
if (name[5] != '\0')
continue;
num = (INT16)M_MapNumber(name[3], name[4]);
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
if (num <= NUMMAPS && mapheaderinfo[num - 1])
{
mapheaderinfo[num - 1]->menuflags |= LF2_EXISTSHACK;
}
}
}
}
if (!W_InitMultipleFiles(startuppwads, true))
CONS_Error("A PWAD file was not found or not valid.\nCheck the log to see which ones.\n");
D_CleanFile(startuppwads);
//
// search for maps... again.
//
for (wadnum = mainwads+1; wadnum < numwadfiles; wadnum++)
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{
INT16 num;
if (name[5] != '\0')
continue;
num = (INT16)M_MapNumber(name[3], name[4]);
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
if (num <= NUMMAPS && mapheaderinfo[num - 1])
{
if (mapheaderinfo[num - 1]->menuflags & LF2_EXISTSHACK)
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
mapheaderinfo[num - 1]->menuflags |= LF2_EXISTSHACK;
}
CONS_Printf("%s\n", name);
}
}
}
cht_Init(); cht_Init();
//---------------------------------------------------- READY SCREEN //---------------------------------------------------- READY SCREEN

View file

@ -821,10 +821,6 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENTMIS", "CLIENTMIS",
"CLIENT2CMD", "CLIENT2CMD",
"CLIENT2MIS", "CLIENT2MIS",
"CLIENT3CMD",
"CLIENT3MIS",
"CLIENT4CMD",
"CLIENT4MIS",
"NODEKEEPALIVE", "NODEKEEPALIVE",
"NODEKEEPALIVEMIS", "NODEKEEPALIVEMIS",
"SERVERTICS", "SERVERTICS",
@ -841,6 +837,15 @@ static const char *packettypename[NUMPACKETTYPE] =
"RESYNCHEND", "RESYNCHEND",
"RESYNCHGET", "RESYNCHGET",
"CLIENT3CMD",
"CLIENT3MIS",
"CLIENT4CMD",
"CLIENT4MIS",
"BASICKEEPALIVE",
"JOINCHALLENGE",
"DOWNLOADFILESOKAY",
"FILEFRAGMENT", "FILEFRAGMENT",
"TEXTCMD", "TEXTCMD",
"TEXTCMD2", "TEXTCMD2",
@ -868,7 +873,7 @@ static void DebugPrintpacket(const char *header)
break; break;
case PT_CLIENTJOIN: case PT_CLIENTJOIN:
fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers, fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers,
netbuffer->u.clientcfg.mode); netbuffer->u.clientcfg.needsdownload);
break; break;
case PT_SERVERTICS: case PT_SERVERTICS:
{ {

View file

@ -173,6 +173,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum);
static void Command_Verify_f(void); static void Command_Verify_f(void);
static void Command_RemoveAdmin_f(void); static void Command_RemoveAdmin_f(void);
static void Command_ChangeJoinPassword_f(void);
static void Command_MotD_f(void); static void Command_MotD_f(void);
static void Got_MotD_f(UINT8 **cp, INT32 playernum); static void Got_MotD_f(UINT8 **cp, INT32 playernum);
@ -452,7 +453,7 @@ consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NU
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping) // show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}}; static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
consvar_t cv_showping = {"showping", "Warning", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_showping = {"showping", "Always", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
// Intermission time Tails 04-19-2002 // Intermission time Tails 04-19-2002
@ -544,6 +545,8 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd); RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd);
// Remote Administration // Remote Administration
CV_RegisterVar(&cv_dummyjoinpassword);
COM_AddCommand("joinpassword", Command_ChangeJoinPassword_f);
COM_AddCommand("password", Command_Changepassword_f); COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login); RegisterNetXCmd(XD_LOGIN, Got_Login);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
@ -832,6 +835,8 @@ void D_RegisterClientCommands(void)
//CV_RegisterVar(&cv_alwaysfreelook2); //CV_RegisterVar(&cv_alwaysfreelook2);
//CV_RegisterVar(&cv_chasefreelook); //CV_RegisterVar(&cv_chasefreelook);
//CV_RegisterVar(&cv_chasefreelook2); //CV_RegisterVar(&cv_chasefreelook2);
CV_RegisterVar(&cv_showfocuslost);
CV_RegisterVar(&cv_pauseifunfocused);
// g_input.c // g_input.c
CV_RegisterVar(&cv_turnaxis); CV_RegisterVar(&cv_turnaxis);
@ -3485,6 +3490,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
if (len > 256-sl) if (len > 256-sl)
len = 256-sl; len = 256-sl;
memcpy(tmpbuf, buffer, len); memcpy(tmpbuf, buffer, len);
memmove(&tmpbuf[len], salt, sl); memmove(&tmpbuf[len], salt, sl);
//strcpy(&tmpbuf[len], salt); //strcpy(&tmpbuf[len], salt);
@ -3498,7 +3504,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
} }
#define BASESALT "basepasswordstorage" #define BASESALT "basepasswordstorage"
static UINT8 adminpassmd5[16]; static UINT8 adminpassmd5[MD5_LEN];
static boolean adminpasswordset = false; static boolean adminpasswordset = false;
void D_SetPassword(const char *pw) void D_SetPassword(const char *pw)
@ -3537,7 +3543,7 @@ static void Command_Login_f(void)
// If we have no MD5 support then completely disable XD_LOGIN responses for security. // If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n"); CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else #else
XBOXSTATIC UINT8 finalmd5[16]; XBOXSTATIC UINT8 finalmd5[MD5_LEN];
const char *pw; const char *pw;
if (!netgame) if (!netgame)
@ -3560,11 +3566,11 @@ static void Command_Login_f(void)
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &finalmd5); D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &finalmd5);
// Do the final pass to get the comparison the server will come up with // Do the final pass to get the comparison the server will come up with
D_MD5PasswordPass(finalmd5, 16, va("PNUM%02d", consoleplayer), &finalmd5); D_MD5PasswordPass(finalmd5, MD5_LEN, va("PNUM%02d", consoleplayer), &finalmd5);
CONS_Printf(M_GetText("Sending login... (Notice only given if password is correct.)\n")); CONS_Printf(M_GetText("Sending login... (Notice only given if password is correct.)\n"));
SendNetXCmd(XD_LOGIN, finalmd5, 16); SendNetXCmd(XD_LOGIN, finalmd5, MD5_LEN);
#endif #endif
} }
@ -3575,9 +3581,9 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
(void)cp; (void)cp;
(void)playernum; (void)playernum;
#else #else
UINT8 sentmd5[16], finalmd5[16]; UINT8 sentmd5[MD5_LEN], finalmd5[MD5_LEN];
READMEM(*cp, sentmd5, 16); READMEM(*cp, sentmd5, MD5_LEN);
if (client) if (client)
return; return;
@ -3589,9 +3595,9 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
} }
// Do the final pass to compare with the sent md5 // Do the final pass to compare with the sent md5
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", playernum), &finalmd5); D_MD5PasswordPass(adminpassmd5, MD5_LEN, va("PNUM%02d", playernum), &finalmd5);
if (!memcmp(sentmd5, finalmd5, 16)) if (!memcmp(sentmd5, finalmd5, MD5_LEN))
{ {
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]); CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately
@ -3760,6 +3766,131 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
CONS_Printf(M_GetText("You are no longer a server administrator.\n")); CONS_Printf(M_GetText("You are no longer a server administrator.\n"));
} }
// Join password stuff
consvar_t cv_dummyjoinpassword = {"dummyjoinpassword", "", CV_HIDEN|CV_NOSHOWHELP|CV_PASSWORD, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
#define NUMJOINCHALLENGES 32
static UINT8 joinpassmd5[MD5_LEN+1];
boolean joinpasswordset = false;
static UINT8 joinpasschallenges[NUMJOINCHALLENGES][MD5_LEN];
static tic_t joinpasschallengeson[NUMJOINCHALLENGES];
boolean D_IsJoinPasswordOn(void)
{
return joinpasswordset;
}
static inline void GetChallengeAnswer(UINT8 *question, UINT8 *passwordmd5, UINT8 *answer)
{
D_MD5PasswordPass(question, MD5_LEN, (char *) passwordmd5, answer);
}
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer)
{
static UINT8 passwordmd5[MD5_LEN+1];
memset(passwordmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &passwordmd5);
GetChallengeAnswer(question, passwordmd5, answer);
}
void D_SetJoinPassword(const char *pw)
{
memset(joinpassmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &joinpassmd5);
joinpasswordset = true;
}
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer)
{
boolean passed = false;
num %= NUMJOINCHALLENGES;
//@TODO use a constant-time memcmp....
if (joinpasschallengeson[num] > 0 && memcmp(answer, joinpasschallenges[num], MD5_LEN) == 0)
passed = true;
// Wipe and reset the challenge so that it can't be tried against again, as a small measure against brute-force attacks.
memset(joinpasschallenges[num], 0x00, MD5_LEN);
joinpasschallengeson[num] = 0;
return passed;
}
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question)
{
size_t i;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
(*num) = M_RandomKey(NUMJOINCHALLENGES);
if (joinpasschallengeson[(*num)] == 0)
break;
}
if (joinpasschallengeson[(*num)] > 0)
{
// Ugh, all challenges are (probably) taken. Let's find the oldest one and overwrite it.
tic_t oldesttic = INT32_MAX;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
if (joinpasschallengeson[i] < oldesttic)
{
(*num) = i;
oldesttic = joinpasschallengeson[i];
}
}
}
joinpasschallengeson[(*num)] = I_GetTime();
memset(question, 0x00, MD5_LEN);
for (i = 0; i < MD5_LEN; i++)
question[i] = M_RandomByte();
// Store the answer in memory. What was the question again?
GetChallengeAnswer(question, joinpassmd5, joinpasschallenges[(*num)]);
// This ensures that num is always non-zero and will be valid when used for the answer
if ((*num) == 0)
(*num) = NUMJOINCHALLENGES;
}
// Remote Administration
static void Command_ChangeJoinPassword_f(void)
{
#ifdef NOMD5
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
if (client) // cannot change remotely
{
CONS_Printf(M_GetText("Only the server can use this.\n"));
return;
}
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("joinpassword <password>: set a password to join the server\nUse -remove to disable the password.\n"));
return;
}
if (strcmp(COM_Argv(1), "-remove") == 0)
{
joinpasswordset = false;
CONS_Printf(M_GetText("Join password removed.\n"));
}
else
{
D_SetJoinPassword(COM_Argv(1));
CONS_Printf(M_GetText("Join password set.\n"));
}
#endif
}
static void Command_MotD_f(void) static void Command_MotD_f(void)
{ {
size_t i, j; size_t i, j;

View file

@ -252,6 +252,14 @@ void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);
extern consvar_t cv_dummyjoinpassword;
extern boolean joinpasswordset;
boolean D_IsJoinPasswordOn(void);
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer);
void D_SetJoinPassword(const char *pw);
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer);
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question);
// used for the player setup menu // used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum); UINT8 CanChangeSkin(INT32 playernum);

View file

@ -32,13 +32,7 @@
// Extra abilities/settings for skins (combinable stuff) // Extra abilities/settings for skins (combinable stuff)
typedef enum typedef enum
{ {
SF_SUPER = 1, // Can turn super in singleplayer/co-op mode. SF_HIRES = 1, // Draw the sprite 2x as small?
SF_SUPERANIMS = 1<<1, // If super, use the super sonic animations
SF_SUPERSPIN = 1<<2, // Should spin frames be played while super?
SF_HIRES = 1<<3, // Draw the sprite 2x as small?
SF_NOSKID = 1<<4, // No skid particles etc
SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust
SF_RUNONWATER = 1<<6, // Run on top of water FOFs?
} skinflags_t; } skinflags_t;
//Primary and secondary skin abilities //Primary and secondary skin abilities
@ -275,6 +269,7 @@ typedef enum
k_nextcheck, // Next checkpoint distance; for p_user.c (was "pw_ncd") k_nextcheck, // Next checkpoint distance; for p_user.c (was "pw_ncd")
k_waypoint, // Waypoints. k_waypoint, // Waypoints.
k_starpostwp, // Temporarily stores player waypoint for... some reason. Used when respawning and finishing. k_starpostwp, // Temporarily stores player waypoint for... some reason. Used when respawning and finishing.
k_starpostflip, // the last starpost we hit requires flipping?
k_respawn, // Timer for the DEZ laser respawn effect k_respawn, // Timer for the DEZ laser respawn effect
k_dropdash, // Charge up for respawn Drop Dash k_dropdash, // Charge up for respawn Drop Dash

View file

@ -3339,11 +3339,6 @@ static void readmaincfg(MYFILE *f)
if (creditscutscene > 128) if (creditscutscene > 128)
creditscutscene = 128; creditscutscene = 128;
} }
else if (fastcmp(word, "DISABLESPEEDADJUST"))
{
DEH_WriteUndoline(word, va("%d", disableSpeedAdjust), UNDO_NONE);
disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "NUMDEMOS")) else if (fastcmp(word, "NUMDEMOS"))
{ {
DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE); DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE);
@ -8493,12 +8488,16 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"PURPLE", // SKINCOLOR_PURPLE "PURPLE", // SKINCOLOR_PURPLE
"FUCHSIA", // SKINCOLOR_FUCHSIA "FUCHSIA", // SKINCOLOR_FUCHSIA
"TOXIC", // SKINCOLOR_TOXIC "TOXIC", // SKINCOLOR_TOXIC
"MAUVE", // SKINCOLOR_MAUVE
"LAVENDER", // SKINCOLOR_LAVENDER "LAVENDER", // SKINCOLOR_LAVENDER
"BYZANTIUM", // SKINCOLOR_BYZANTIUM "BYZANTIUM", // SKINCOLOR_BYZANTIUM
"MAUVE", // SKINCOLOR_MAUVE
"POMEGRANATE", // SKINCOLOR_POMEGRANATE "POMEGRANATE", // SKINCOLOR_POMEGRANATE
"LILAC", // SKINCOLOR_LILAC "LILAC", // SKINCOLOR_LILAC
// Special super colors // Special super colors
// Super Sonic Yellow // Super Sonic Yellow
"SUPER1", // SKINCOLOR_SUPER1 "SUPER1", // SKINCOLOR_SUPER1
@ -8506,48 +8505,56 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"SUPER3", // SKINCOLOR_SUPER3, "SUPER3", // SKINCOLOR_SUPER3,
"SUPER4", // SKINCOLOR_SUPER4, "SUPER4", // SKINCOLOR_SUPER4,
"SUPER5", // SKINCOLOR_SUPER5, "SUPER5", // SKINCOLOR_SUPER5,
// Super Tails Orange // Super Tails Orange
"TSUPER1", // SKINCOLOR_TSUPER1, "TSUPER1", // SKINCOLOR_TSUPER1,
"TSUPER2", // SKINCOLOR_TSUPER2, "TSUPER2", // SKINCOLOR_TSUPER2,
"TSUPER3", // SKINCOLOR_TSUPER3, "TSUPER3", // SKINCOLOR_TSUPER3,
"TSUPER4", // SKINCOLOR_TSUPER4, "TSUPER4", // SKINCOLOR_TSUPER4,
"TSUPER5", // SKINCOLOR_TSUPER5, "TSUPER5", // SKINCOLOR_TSUPER5,
// Super Knuckles Red // Super Knuckles Red
"KSUPER1", // SKINCOLOR_KSUPER1, "KSUPER1", // SKINCOLOR_KSUPER1,
"KSUPER2", // SKINCOLOR_KSUPER2, "KSUPER2", // SKINCOLOR_KSUPER2,
"KSUPER3", // SKINCOLOR_KSUPER3, "KSUPER3", // SKINCOLOR_KSUPER3,
"KSUPER4", // SKINCOLOR_KSUPER4, "KSUPER4", // SKINCOLOR_KSUPER4,
"KSUPER5", // SKINCOLOR_KSUPER5, "KSUPER5", // SKINCOLOR_KSUPER5,
// Hyper Sonic Pink // Hyper Sonic Pink
"PSUPER1", // SKINCOLOR_PSUPER1, "PSUPER1", // SKINCOLOR_PSUPER1,
"PSUPER2", // SKINCOLOR_PSUPER2, "PSUPER2", // SKINCOLOR_PSUPER2,
"PSUPER3", // SKINCOLOR_PSUPER3, "PSUPER3", // SKINCOLOR_PSUPER3,
"PSUPER4", // SKINCOLOR_PSUPER4, "PSUPER4", // SKINCOLOR_PSUPER4,
"PSUPER5", // SKINCOLOR_PSUPER5, "PSUPER5", // SKINCOLOR_PSUPER5,
// Hyper Sonic Blue // Hyper Sonic Blue
"BSUPER1", // SKINCOLOR_BSUPER1, "BSUPER1", // SKINCOLOR_BSUPER1,
"BSUPER2", // SKINCOLOR_BSUPER2, "BSUPER2", // SKINCOLOR_BSUPER2,
"BSUPER3", // SKINCOLOR_BSUPER3, "BSUPER3", // SKINCOLOR_BSUPER3,
"BSUPER4", // SKINCOLOR_BSUPER4, "BSUPER4", // SKINCOLOR_BSUPER4,
"BSUPER5" // SKINCOLOR_BSUPER5, "BSUPER5", // SKINCOLOR_BSUPER5,
// Aqua Super // Aqua Super
"ASUPER1", // SKINCOLOR_ASUPER1, "ASUPER1", // SKINCOLOR_ASUPER1,
"ASUPER2", // SKINCOLOR_ASUPER2, "ASUPER2", // SKINCOLOR_ASUPER2,
"ASUPER3", // SKINCOLOR_ASUPER3, "ASUPER3", // SKINCOLOR_ASUPER3,
"ASUPER4", // SKINCOLOR_ASUPER4, "ASUPER4", // SKINCOLOR_ASUPER4,
"ASUPER5", // SKINCOLOR_ASUPER5, "ASUPER5", // SKINCOLOR_ASUPER5,
// Hyper Sonic Green // Hyper Sonic Green
"GSUPER1", // SKINCOLOR_GSUPER1, "GSUPER1", // SKINCOLOR_GSUPER1,
"GSUPER2", // SKINCOLOR_GSUPER2, "GSUPER2", // SKINCOLOR_GSUPER2,
"GSUPER3", // SKINCOLOR_GSUPER3, "GSUPER3", // SKINCOLOR_GSUPER3,
"GSUPER4", // SKINCOLOR_GSUPER4, "GSUPER4", // SKINCOLOR_GSUPER4,
"GSUPER5", // SKINCOLOR_GSUPER5, "GSUPER5", // SKINCOLOR_GSUPER5,
// Hyper Sonic White // Hyper Sonic White
"WSUPER1", // SKINCOLOR_WSUPER1, "WSUPER1", // SKINCOLOR_WSUPER1,
"WSUPER2", // SKINCOLOR_WSUPER2, "WSUPER2", // SKINCOLOR_WSUPER2,
"WSUPER3", // SKINCOLOR_WSUPER3, "WSUPER3", // SKINCOLOR_WSUPER3,
"WSUPER4", // SKINCOLOR_WSUPER4, "WSUPER4", // SKINCOLOR_WSUPER4,
"WSUPER5", // SKINCOLOR_WSUPER5, "WSUPER5", // SKINCOLOR_WSUPER5,
// Creamy Super (Shadow?) // Creamy Super (Shadow?)
"CSUPER1", // SKINCOLOR_CSUPER1, "CSUPER1", // SKINCOLOR_CSUPER1,
"CSUPER2", // SKINCOLOR_CSUPER2, "CSUPER2", // SKINCOLOR_CSUPER2,
@ -8600,6 +8607,7 @@ static const char *const KARTSTUFF_LIST[] = {
"NEXTCHECK", "NEXTCHECK",
"WAYPOINT", "WAYPOINT",
"STARPOSTWP", "STARPOSTWP",
"STARPOSTFLIP",
"RESPAWN", "RESPAWN",
"DROPDASH", "DROPDASH",
@ -8899,13 +8907,7 @@ struct {
{"RW_RAIL",RW_RAIL}, {"RW_RAIL",RW_RAIL},
// Character flags (skinflags_t) // Character flags (skinflags_t)
{"SF_SUPER",SF_SUPER},
{"SF_SUPERANIMS",SF_SUPERANIMS},
{"SF_SUPERSPIN",SF_SUPERSPIN},
{"SF_HIRES",SF_HIRES}, {"SF_HIRES",SF_HIRES},
{"SF_NOSKID",SF_NOSKID},
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
{"SF_RUNONWATER",SF_RUNONWATER},
// Character abilities! // Character abilities!
// Primary // Primary

View file

@ -150,9 +150,9 @@ extern FILE *logstream;
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 100 // Game version #define VERSION 100 // Game version
#define SUBVERSION 3 // more precise version number #define SUBVERSION 4 // more precise version number
#define VERSIONSTRING "v1.0.3" #define VERSIONSTRING "v1.0.4"
#define VERSIONSTRINGW L"v1.0.3" #define VERSIONSTRINGW L"v1.0.4"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
@ -221,7 +221,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 3 #define MODVERSION 4
// Filter consvars by version // Filter consvars by version
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
@ -244,7 +244,7 @@ extern FILE *logstream;
// NOTE: it needs more than this to increase the number of players... // NOTE: it needs more than this to increase the number of players...
#define MAXPLAYERS 16 #define MAXPLAYERS 16
#define MAXSKINS 64 #define MAXSKINS 128
#define PLAYERSMASK (MAXPLAYERS-1) #define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21 #define MAXPLAYERNAME 21
@ -256,8 +256,8 @@ typedef enum
SKINCOLOR_GREY, SKINCOLOR_GREY,
SKINCOLOR_NICKEL, SKINCOLOR_NICKEL,
SKINCOLOR_BLACK, SKINCOLOR_BLACK,
SKINCOLOR_POPCORN,
SKINCOLOR_FAIRY, SKINCOLOR_FAIRY,
SKINCOLOR_POPCORN,
SKINCOLOR_SEPIA, SKINCOLOR_SEPIA,
SKINCOLOR_BEIGE, SKINCOLOR_BEIGE,
SKINCOLOR_BROWN, SKINCOLOR_BROWN,

View file

@ -57,7 +57,6 @@ extern boolean modifiedgame;
extern boolean majormods; extern boolean majormods;
extern UINT16 mainwads; extern UINT16 mainwads;
extern boolean savemoddata; // This mod saves time/emblem data. extern boolean savemoddata; // This mod saves time/emblem data.
extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true
extern boolean imcontinuing; // Temporary flag while continuing extern boolean imcontinuing; // Temporary flag while continuing
extern boolean metalrecording; extern boolean metalrecording;

View file

@ -611,7 +611,7 @@ void F_CreditDrawer(void)
if (credits_pics[i].colorize != SKINCOLOR_NONE) if (credits_pics[i].colorize != SKINCOLOR_NONE)
{ {
colormap = R_GetTranslationColormap(TC_RAINBOW, credits_pics[i].colorize, 0); colormap = R_GetTranslationColormap(TC_RAINBOW, credits_pics[i].colorize, GTC_MENUCACHE);
sc = FRACUNIT; // quick hack so I don't have to add another field to credits_pics sc = FRACUNIT; // quick hack so I don't have to add another field to credits_pics
} }
@ -643,16 +643,34 @@ void F_CreditDrawer(void)
if (((y>>FRACBITS) * vid.dupy) > vid.height) if (((y>>FRACBITS) * vid.dupy) > vid.height)
break; break;
} }
}
void F_CreditTicker(void)
{
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
UINT16 i;
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
// Draw credits text on top
for (i = 0; credits[i]; i++)
{
switch(credits[i][0])
{
case 0: y += 80<<FRACBITS; break;
case 1: y += 30<<FRACBITS; break;
default: y += 12<<FRACBITS; break;
}
if (FixedMul(y,vid.dupy) > vid.height)
break;
}
// Do this here rather than in the drawer you doofus! (this is why dedicated mode broke at credits)
if (!credits[i] && y <= 120<<FRACBITS && !finalecount) if (!credits[i] && y <= 120<<FRACBITS && !finalecount)
{ {
timetonext = 5*TICRATE+1; timetonext = 5*TICRATE+1;
finalecount = 5*TICRATE; finalecount = 5*TICRATE;
} }
}
void F_CreditTicker(void)
{
if (timetonext) if (timetonext)
timetonext--; timetonext--;
else else
@ -1103,6 +1121,10 @@ void F_StartWaitingPlayers(void)
finalecount = 0; finalecount = 0;
randskin = M_RandomKey(numskins); randskin = M_RandomKey(numskins);
if (waitcolormap)
Z_Free(waitcolormap);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0); waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0);
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)

View file

@ -92,7 +92,6 @@ boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been a
boolean savemoddata = false; boolean savemoddata = false;
UINT8 paused; UINT8 paused;
UINT8 modeattacking = ATTACKING_NONE; UINT8 modeattacking = ATTACKING_NONE;
boolean disableSpeedAdjust = true;
boolean imcontinuing = false; boolean imcontinuing = false;
boolean runemeraldmanager = false; boolean runemeraldmanager = false;
@ -438,6 +437,9 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}}; static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// Pause game upon window losing focus
consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
// Display song credits // Display song credits
consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -1821,80 +1823,6 @@ static INT32 spectatedelay, spectatedelay2, spectatedelay3, spectatedelay4 = 0;
// //
boolean G_Responder(event_t *ev) boolean G_Responder(event_t *ev)
{ {
// allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
{
if (splitscreen || !netgame)
displayplayer = consoleplayer;
else
{
UINT8 i = 0; // spy mode
for (i = 0; i < MAXPLAYERS; i++)
{
displayplayer++;
if (displayplayer == MAXPLAYERS)
displayplayer = 0;
if (displayplayer == consoleplayer)
break; // End loop
if (!playeringame[displayplayer])
continue;
if (players[displayplayer].spectator)
continue;
// SRB2Kart: Only go through players who are actually playing
if (players[displayplayer].exiting)
continue;
if (players[displayplayer].pflags & PF_TIMEOVER)
continue;
// I don't know if we want this actually, but I'll humor the suggestion anyway
if (G_BattleGametype())
{
if (players[displayplayer].kartstuff[k_bumper] <= 0)
continue;
}
// SRB2Kart: we have no team-based modes, YET...
/*if (G_GametypeHasTeams())
{
if (players[consoleplayer].ctfteam
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
continue;
}
else if (gametype == GT_HIDEANDSEEK)
{
if (players[consoleplayer].pflags & PF_TAGIT)
continue;
}
// Other Tag-based gametypes?
else if (G_TagGametype())
{
if (!players[consoleplayer].spectator
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
continue;
}
else if (G_GametypeHasSpectators() && G_BattleGametype())
{
if (!players[consoleplayer].spectator)
continue;
}*/
break;
}
// change statusbar also if playing back demo
if (singledemo)
ST_changeDemoView();
return true;
}
}
// any other key pops up menu if in demos // any other key pops up menu if in demos
if (gameaction == ga_nothing && !singledemo && if (gameaction == ga_nothing && !singledemo &&
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN)) ((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
@ -1972,6 +1900,80 @@ boolean G_Responder(event_t *ev)
if (HU_Responder(ev)) if (HU_Responder(ev))
return true; // chat ate the event return true; // chat ate the event
// allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
{
if (splitscreen || !netgame)
displayplayer = consoleplayer;
else
{
UINT8 i = 0; // spy mode
for (i = 0; i < MAXPLAYERS; i++)
{
displayplayer++;
if (displayplayer == MAXPLAYERS)
displayplayer = 0;
if (displayplayer == consoleplayer)
break; // End loop
if (!playeringame[displayplayer])
continue;
if (players[displayplayer].spectator)
continue;
// SRB2Kart: Only go through players who are actually playing
if (players[displayplayer].exiting)
continue;
if (players[displayplayer].pflags & PF_TIMEOVER)
continue;
// I don't know if we want this actually, but I'll humor the suggestion anyway
if (G_BattleGametype())
{
if (players[displayplayer].kartstuff[k_bumper] <= 0)
continue;
}
// SRB2Kart: we have no team-based modes, YET...
/*if (G_GametypeHasTeams())
{
if (players[consoleplayer].ctfteam
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
continue;
}
else if (gametype == GT_HIDEANDSEEK)
{
if (players[consoleplayer].pflags & PF_TAGIT)
continue;
}
// Other Tag-based gametypes?
else if (G_TagGametype())
{
if (!players[consoleplayer].spectator
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
continue;
}
else if (G_GametypeHasSpectators() && G_BattleGametype())
{
if (!players[consoleplayer].spectator)
continue;
}*/
break;
}
// change statusbar also if playing back demo
if (singledemo)
ST_changeDemoView();
return true;
}
}
// update keys current state // update keys current state
G_MapEventsToControls(ev); G_MapEventsToControls(ev);
@ -2376,6 +2378,7 @@ void G_PlayerReborn(INT32 player)
INT32 bumper; INT32 bumper;
INT32 comebackpoints; INT32 comebackpoints;
INT32 wanted; INT32 wanted;
INT32 respawnflip;
boolean songcredit = false; boolean songcredit = false;
score = players[player].score; score = players[player].score;
@ -2420,6 +2423,7 @@ void G_PlayerReborn(INT32 player)
starposty = players[player].starposty; starposty = players[player].starposty;
starpostz = players[player].starpostz; starpostz = players[player].starpostz;
starpostnum = players[player].starpostnum; starpostnum = players[player].starpostnum;
respawnflip = players[player].kartstuff[k_starpostflip]; //SRB2KART
starpostangle = players[player].starpostangle; starpostangle = players[player].starpostangle;
jumpfactor = players[player].jumpfactor; jumpfactor = players[player].jumpfactor;
thokitem = players[player].thokitem; thokitem = players[player].thokitem;
@ -2540,6 +2544,7 @@ void G_PlayerReborn(INT32 player)
p->kartstuff[k_comebacktimer] = comebacktime; p->kartstuff[k_comebacktimer] = comebacktime;
p->kartstuff[k_wanted] = wanted; p->kartstuff[k_wanted] = wanted;
p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_eggmanblame] = -1;
p->kartstuff[k_starpostflip] = respawnflip;
if (follower) if (follower)
P_RemoveMobj(follower); P_RemoveMobj(follower);
@ -5128,17 +5133,16 @@ void G_GhostTicker(void)
INT32 type = -1; INT32 type = -1;
if (g->mo->skin) if (g->mo->skin)
{ {
skin_t *skin = (skin_t *)g->mo->skin;
switch (ziptic & EZT_THOKMASK) switch (ziptic & EZT_THOKMASK)
{ {
case EZT_THOK: case EZT_THOK:
type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; type = (UINT32)mobjinfo[MT_PLAYER].painchance;
break; break;
case EZT_SPIN: case EZT_SPIN:
type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; type = (UINT32)mobjinfo[MT_PLAYER].damage;
break; break;
case EZT_REV: case EZT_REV:
type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; type = (UINT32)mobjinfo[MT_PLAYER].raisestate;
break; break;
} }
} }

View file

@ -56,6 +56,7 @@ extern INT16 rw_maximums[NUM_WEAPONS];
// used in game menu // used in game menu
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/; extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/;
extern consvar_t cv_songcredits; extern consvar_t cv_songcredits;
extern consvar_t cv_pauseifunfocused;
//extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4; //extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4;
extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/; extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/;
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/; extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;

View file

@ -2056,7 +2056,7 @@ EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransfor
EXPORT void HWRAPI(SetTransform) (FTransform *stransform) EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
{ {
static boolean special_splitscreen; static boolean special_splitscreen;
double used_fov; GLdouble used_fov;
pglLoadIdentity(); pglLoadIdentity();
if (stransform) if (stransform)
{ {

View file

@ -1225,8 +1225,6 @@ static INT16 typelines = 1; // number of drawfill lines we need when drawing the
// //
boolean HU_Responder(event_t *ev) boolean HU_Responder(event_t *ev)
{ {
INT32 c=0;
if (ev->type != ev_keydown) if (ev->type != ev_keydown)
return false; return false;
@ -1252,18 +1250,6 @@ boolean HU_Responder(event_t *ev)
return false; return false;
} }
c = (INT32)ev->data1;
// capslock (now handled outside of chat on so that it works everytime......)
if (c && c == KEY_CAPSLOCK) // it's a toggle.
{
if (capslock)
capslock = false;
else
capslock = true;
return true;
}
#ifndef NONET #ifndef NONET
if (!chat_on) if (!chat_on)
{ {
@ -1291,6 +1277,7 @@ boolean HU_Responder(event_t *ev)
} }
else // if chat_on else // if chat_on
{ {
INT32 c = (INT32)ev->data1;
// Ignore modifier keys // Ignore modifier keys
// Note that we do this here so users can still set // Note that we do this here so users can still set
@ -1306,20 +1293,7 @@ boolean HU_Responder(event_t *ev)
&& ev->data1 != gamecontrol[gc_talkkey][1])) && ev->data1 != gamecontrol[gc_talkkey][1]))
return false; return false;
c = (INT32)ev->data1; c = CON_ShiftChar(c);
// I know this looks very messy but this works. If it ain't broke, don't fix it!
// shift LETTERS to uppercase if we have capslock or are holding shift
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (shiftdown ^ capslock)
c = shiftxform[c];
}
else // if we're holding shift we should still shift non letter symbols
{
if (shiftdown)
c = shiftxform[c];
}
// pasting. pasting is cool. chat is a bit limited, though :( // pasting. pasting is cool. chat is a bit limited, though :(
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE) if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)

View file

@ -612,7 +612,7 @@ static boolean SOCK_Get(void)
if (c != ERRSOCKET) if (c != ERRSOCKET)
{ {
// find remote node number // find remote node number
for (j = 0; j <= MAXNETNODES; j++) //include LAN for (j = 1; j <= MAXNETNODES; j++) //include LAN
{ {
if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0)) if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0))
{ {
@ -1340,8 +1340,12 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
while (runp != NULL) while (runp != NULL)
{ {
// find ip of the server // find ip of the server
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
runp = NULL; {
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
break;
}
runp = runp->ai_next;
} }
I_freeaddrinfo(ai); I_freeaddrinfo(ai);
return newnode; return newnode;

View file

@ -15051,8 +15051,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
8, // speed 8, // speed
8*FRACUNIT, // radius 32*FRACUNIT, // radius
8*FRACUNIT, // height 64*FRACUNIT, // height
1, // display offset 1, // display offset
100, // mass 100, // mass
0, // damage 0, // damage

View file

@ -725,7 +725,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
const INT32 distvar = (64*14); const INT32 distvar = (64*14);
INT32 newodds; INT32 newodds;
INT32 i; INT32 i;
UINT8 pingame = 0, pexiting = 0, pinvin = 0; UINT8 pingame = 0, pexiting = 0;
boolean thunderisout = false; boolean thunderisout = false;
SINT8 first = -1, second = -1; SINT8 first = -1, second = -1;
INT32 secondist = 0; INT32 secondist = 0;
@ -780,12 +780,6 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
if (players[i].mo) if (players[i].mo)
{ {
if (players[i].kartstuff[k_itemtype] == KITEM_INVINCIBILITY
|| players[i].kartstuff[k_itemtype] == KITEM_GROW
|| players[i].kartstuff[k_invincibilitytimer]
|| players[i].kartstuff[k_growshrinktimer] > 0)
pinvin++;
if (players[i].kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) if (players[i].kartstuff[k_itemtype] == KITEM_THUNDERSHIELD)
thunderisout = true; thunderisout = true;
@ -820,24 +814,18 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
#define PLAYERSCALING (8 - (spbrush ? 2 : pingame)) #define PLAYERSCALING (8 - (spbrush ? 2 : pingame))
#define POWERITEMODDS(odds) \ #define POWERITEMODDS(odds) {\
if (franticitems) \ if (franticitems) \
odds <<= 1; \ odds <<= 1; \
odds = FixedMul(odds<<FRACBITS, FRACUNIT + ((PLAYERSCALING << FRACBITS) / 25)) >> FRACBITS; \ odds = FixedMul(odds<<FRACBITS, FRACUNIT + ((PLAYERSCALING << FRACBITS) / 25)) >> FRACBITS; \
if (mashed > 0) \ if (mashed > 0) \
odds = FixedDiv(odds<<FRACBITS, FRACUNIT + mashed) >> FRACBITS \ odds = FixedDiv(odds<<FRACBITS, FRACUNIT + mashed) >> FRACBITS; \
}
#define COOLDOWNONSTART (leveltime < (30*TICRATE)+starttime) #define COOLDOWNONSTART (leveltime < (30*TICRATE)+starttime)
switch (item) switch (item)
{ {
case KITEM_INVINCIBILITY:
case KITEM_GROW:
if (pinvin >= max(1, (pingame+3) / 4) || COOLDOWNONSTART)
newodds = 0;
else
POWERITEMODDS(newodds);
break;
case KITEM_ROCKETSNEAKER: case KITEM_ROCKETSNEAKER:
case KITEM_JAWZ: case KITEM_JAWZ:
case KITEM_BALLHOG: case KITEM_BALLHOG:
@ -849,7 +837,9 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
case KRITEM_DUALJAWZ: case KRITEM_DUALJAWZ:
POWERITEMODDS(newodds); POWERITEMODDS(newodds);
break; break;
case KITEM_INVINCIBILITY:
case KITEM_MINE: case KITEM_MINE:
case KITEM_GROW:
if (COOLDOWNONSTART) if (COOLDOWNONSTART)
newodds = 0; newodds = 0;
else else
@ -1429,11 +1419,23 @@ static void K_UpdateOffroad(player_t *player)
player->kartstuff[k_offroad] = 0; player->kartstuff[k_offroad] = 0;
} }
// Adds gravity flipping to an object relative to its master and shifts the z coordinate accordingly.
void K_FlipFromObject(mobj_t *mo, mobj_t *master)
{
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP);
mo->flags2 = (mo->flags2 & ~MF2_OBJECTFLIP)|(master->flags2 & MF2_OBJECTFLIP);
if (mo->eflags & MFE_VERTICALFLIP)
mo->z += master->height - FixedMul(master->scale, mo->height);
}
// These have to go earlier than its sisters because of K_RespawnChecker... // These have to go earlier than its sisters because of K_RespawnChecker...
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master) void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
{ {
// flipping // flipping
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP); // handle z shifting from there too. This is here since there's no reason not to flip us if needed when we do this anyway;
K_FlipFromObject(mo, master);
// visibility (usually for hyudoro) // visibility (usually for hyudoro)
mo->flags2 = (mo->flags2 & ~MF2_DONTDRAW)|(master->flags2 & MF2_DONTDRAW); mo->flags2 = (mo->flags2 & ~MF2_DONTDRAW)|(master->flags2 & MF2_DONTDRAW);
mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP1)|(master->eflags & MFE_DRAWONLYFORP1); mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP1)|(master->eflags & MFE_DRAWONLYFORP1);
@ -2311,7 +2313,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
if (source && source != player->mo && source->player) if (source && source != player->mo && source->player)
K_PlayHitEmSound(source); K_PlayHitEmSound(source);
player->mo->momz = 18*mapobjectscale; player->mo->momz = 18*mapobjectscale*P_MobjFlip(player->mo); // please stop forgetting mobjflip checks!!!!
player->mo->momx = player->mo->momy = 0; player->mo->momx = player->mo->momy = 0;
player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_sneakertimer] = 0;
@ -2551,12 +2553,14 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32
// Spawns the purely visual explosion // Spawns the purely visual explosion
void K_SpawnMineExplosion(mobj_t *source, UINT8 color) void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
{ {
INT32 i, radius, height;
mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING);
mobj_t *dust; mobj_t *dust;
mobj_t *truc; mobj_t *truc;
INT32 speed, speed2; INT32 speed, speed2;
INT32 i, radius, height;
mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING);
K_MatchGenericExtraFlags(smoldering, source);
smoldering->tics = TICRATE*3; smoldering->tics = TICRATE*3;
radius = source->radius>>FRACBITS; radius = source->radius>>FRACBITS;
height = source->height>>FRACBITS; height = source->height>>FRACBITS;
@ -2577,6 +2581,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
source->y + P_RandomRange(-radius, radius)*FRACUNIT, source->y + P_RandomRange(-radius, radius)*FRACUNIT,
source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMEXPLODE); source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMEXPLODE);
K_MatchGenericExtraFlags(truc, source);
P_SetScale(truc, source->scale); P_SetScale(truc, source->scale);
truc->destscale = source->scale*6; truc->destscale = source->scale*6;
truc->scalespeed = source->scale/12; truc->scalespeed = source->scale/12;
@ -2584,7 +2589,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
truc->momx = P_RandomRange(-speed, speed)*FRACUNIT; truc->momx = P_RandomRange(-speed, speed)*FRACUNIT;
truc->momy = P_RandomRange(-speed, speed)*FRACUNIT; truc->momy = P_RandomRange(-speed, speed)*FRACUNIT;
speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS; speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS;
truc->momz = P_RandomRange(-speed, speed)*FRACUNIT; truc->momz = P_RandomRange(-speed, speed)*FRACUNIT*P_MobjFlip(truc);
if (truc->eflags & MFE_UNDERWATER) if (truc->eflags & MFE_UNDERWATER)
truc->momz = (117 * truc->momz) / 200; truc->momz = (117 * truc->momz) / 200;
truc->color = color; truc->color = color;
@ -2605,6 +2610,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
source->y + P_RandomRange(-radius, radius)*FRACUNIT, source->y + P_RandomRange(-radius, radius)*FRACUNIT,
source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMPARTICLE); source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMPARTICLE);
K_MatchGenericExtraFlags(truc, source);
P_SetScale(truc, source->scale); P_SetScale(truc, source->scale);
truc->destscale = source->scale*5; truc->destscale = source->scale*5;
truc->scalespeed = source->scale/12; truc->scalespeed = source->scale/12;
@ -2613,7 +2619,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
truc->momy = P_RandomRange(-speed, speed)*FRACUNIT; truc->momy = P_RandomRange(-speed, speed)*FRACUNIT;
speed = FixedMul(15*FRACUNIT, source->scale)>>FRACBITS; speed = FixedMul(15*FRACUNIT, source->scale)>>FRACBITS;
speed2 = FixedMul(45*FRACUNIT, source->scale)>>FRACBITS; speed2 = FixedMul(45*FRACUNIT, source->scale)>>FRACBITS;
truc->momz = P_RandomRange(speed, speed2)*FRACUNIT; truc->momz = P_RandomRange(speed, speed2)*FRACUNIT*P_MobjFlip(truc);
if (P_RandomChance(FRACUNIT/2)) if (P_RandomChance(FRACUNIT/2))
truc->momz = -truc->momz; truc->momz = -truc->momz;
if (truc->eflags & MFE_UNDERWATER) if (truc->eflags & MFE_UNDERWATER)
@ -2889,7 +2895,8 @@ void K_SpawnBoostTrail(player_t *player)
flame->fuse = TICRATE*2; flame->fuse = TICRATE*2;
flame->destscale = player->mo->scale; flame->destscale = player->mo->scale;
P_SetScale(flame, player->mo->scale); P_SetScale(flame, player->mo->scale);
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); // not K_MatchGenericExtraFlags so that a stolen sneaker can be seen // not K_MatchGenericExtraFlags so that a stolen sneaker can be seen
K_FlipFromObject(flame, player->mo);
flame->momx = 8; flame->momx = 8;
P_XYMovement(flame); P_XYMovement(flame);
@ -2922,6 +2929,7 @@ void K_SpawnSparkleTrail(mobj_t *mo)
fixed_t newz = mo->z + mo->momz + (P_RandomRange(0, mo->height>>FRACBITS)<<FRACBITS); fixed_t newz = mo->z + mo->momz + (P_RandomRange(0, mo->height>>FRACBITS)<<FRACBITS);
sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL);
K_FlipFromObject(sparkle, mo);
//if (i == 0) //if (i == 0)
//P_SetMobjState(sparkle, S_KARTINVULN_LARGE1); //P_SetMobjState(sparkle, S_KARTINVULN_LARGE1);
@ -2929,7 +2937,6 @@ void K_SpawnSparkleTrail(mobj_t *mo)
P_SetTarget(&sparkle->target, mo); P_SetTarget(&sparkle->target, mo);
sparkle->destscale = mo->destscale; sparkle->destscale = mo->destscale;
P_SetScale(sparkle, mo->scale); P_SetScale(sparkle, mo->scale);
sparkle->eflags = (sparkle->eflags & ~MFE_VERTICALFLIP)|(mo->eflags & MFE_VERTICALFLIP); // not K_MatchGenericExtraFlags so that a stolen invincibility can be seen
sparkle->color = mo->color; sparkle->color = mo->color;
//sparkle->colorized = mo->colorized; //sparkle->colorized = mo->colorized;
} }
@ -2963,7 +2970,7 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy); dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
dust->destscale = mo->scale; dust->destscale = mo->scale;
P_SetScale(dust, mo->scale); P_SetScale(dust, mo->scale);
dust->eflags = (dust->eflags & ~MFE_VERTICALFLIP)|(mo->eflags & MFE_VERTICALFLIP); // not K_MatchGenericExtraFlags because hyudoro shouldn't be able to wipeout K_FlipFromObject(dust, mo);
if (translucent) // offroad effect if (translucent) // offroad effect
{ {
@ -3029,10 +3036,6 @@ void K_DriftDustHandling(mobj_t *spawner)
fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS; fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
INT32 speedrange = 2; INT32 speedrange = 2;
mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST); mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
if (spawner->eflags & MFE_VERTICALFLIP)
{
dust->z += spawner->height - dust->height;
}
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4); dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4); dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momz = P_MobjFlip(spawner) * (P_RandomRange(1, 4) * (spawner->scale)); dust->momz = P_MobjFlip(spawner) * (P_RandomRange(1, 4) * (spawner->scale));
@ -3181,6 +3184,14 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
{ {
// Shoot forward // Shoot forward
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, mapthing); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, mapthing);
//K_FlipFromObject(mo, player->mo);
// These are really weird so let's make it a very specific case to make SURE it works...
if (player->mo->eflags & MFE_VERTICALFLIP)
{
mo->z -= player->mo->height;
mo->flags2 |= MF2_OBJECTFLIP;
mo->eflags |= MFE_VERTICALFLIP;
}
mo->threshold = 10; mo->threshold = 10;
P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->target, player->mo);
@ -3190,23 +3201,29 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
if (mo) if (mo)
{ {
angle_t fa = player->mo->angle>>ANGLETOFINESHIFT; angle_t fa = player->mo->angle>>ANGLETOFINESHIFT;
fixed_t HEIGHT = (20 + (dir*10))*mapobjectscale + player->mo->momz; fixed_t HEIGHT = (20 + (dir*10))*mapobjectscale + (player->mo->momz*P_MobjFlip(player->mo));
P_SetObjectMomZ(mo, HEIGHT, false);
mo->momx = player->mo->momx + FixedMul(FINECOSINE(fa), PROJSPEED*dir); mo->momx = player->mo->momx + FixedMul(FINECOSINE(fa), PROJSPEED*dir);
mo->momy = player->mo->momy + FixedMul(FINESINE(fa), PROJSPEED*dir); mo->momy = player->mo->momy + FixedMul(FINESINE(fa), PROJSPEED*dir);
mo->momz = P_MobjFlip(player->mo) * HEIGHT;
mo->extravalue2 = dir; mo->extravalue2 = dir;
if (mo->eflags & MFE_UNDERWATER) if (mo->eflags & MFE_UNDERWATER)
mo->momz = (117 * mo->momz) / 200; mo->momz = (117 * mo->momz) / 200;
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
} }
// this is the small graphic effect that plops in you when you throw an item:
throwmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FIREDITEM); throwmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FIREDITEM);
P_SetTarget(&throwmo->target, player->mo); P_SetTarget(&throwmo->target, player->mo);
// Ditto:
if (player->mo->eflags & MFE_VERTICALFLIP)
{
throwmo->z -= player->mo->height;
throwmo->flags2 |= MF2_OBJECTFLIP;
throwmo->eflags |= MFE_VERTICALFLIP;
}
throwmo->movecount = 0; // above player throwmo->movecount = 0; // above player
} }
else else
@ -3232,9 +3249,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
} }
mo = P_SpawnMobj(newx, newy, newz, mapthing); // this will never return null because collision isn't processed here mo = P_SpawnMobj(newx, newy, newz, mapthing); // this will never return null because collision isn't processed here
K_FlipFromObject(mo, player->mo);
if (P_MobjFlip(player->mo) < 0)
mo->z = player->mo->z + player->mo->height - mo->height;
mo->threshold = 10; mo->threshold = 10;
P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->target, player->mo);
@ -3496,6 +3511,7 @@ void K_DoSneaker(player_t *player, INT32 type)
P_SetTarget(&overlay->target, cur); P_SetTarget(&overlay->target, cur);
P_SetTarget(&cur->tracer, overlay); P_SetTarget(&cur->tracer, overlay);
P_SetScale(overlay, (overlay->destscale = 3*cur->scale/4)); P_SetScale(overlay, (overlay->destscale = 3*cur->scale/4));
K_FlipFromObject(overlay, cur);
} }
cur = cur->hnext; cur = cur->hnext;
} }
@ -3506,6 +3522,7 @@ void K_DoSneaker(player_t *player, INT32 type)
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BOOSTFLAME); mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BOOSTFLAME);
P_SetTarget(&overlay->target, player->mo); P_SetTarget(&overlay->target, player->mo);
P_SetScale(overlay, (overlay->destscale = player->mo->scale)); P_SetScale(overlay, (overlay->destscale = player->mo->scale));
K_FlipFromObject(overlay, player->mo);
} }
} }
@ -3610,7 +3627,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
thrust = 32<<FRACBITS; thrust = 32<<FRACBITS;
} }
mo->momz = FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, vscale)); mo->momz = P_MobjFlip(mo)*FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, vscale));
} }
else else
mo->momz = FixedMul(vertispeed, vscale); mo->momz = FixedMul(vertispeed, vscale);
@ -4040,6 +4057,7 @@ static void K_MoveHeldObjects(player_t *player)
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist); targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist);
targy = targ->y + P_ReturnThrustY(cur, ang + ANGLE_180, dist); targy = targ->y + P_ReturnThrustY(cur, ang + ANGLE_180, dist);
targz = targ->z; targz = targ->z;
speed = FixedMul(R_PointToDist2(cur->x, cur->y, targx, targy), 3*FRACUNIT/4); speed = FixedMul(R_PointToDist2(cur->x, cur->y, targx, targy), 3*FRACUNIT/4);
if (P_IsObjectOnGround(targ)) if (P_IsObjectOnGround(targ))
targz = cur->floorz; targz = cur->floorz;
@ -4130,8 +4148,11 @@ static void K_MoveHeldObjects(player_t *player)
{ // bobbing, copy pasted from my kimokawaiii entry { // bobbing, copy pasted from my kimokawaiii entry
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
fixed_t sine = 8 * FINESINE((((2*pi*(4*TICRATE)) * leveltime)>>ANGLETOFINESHIFT) & FINEMASK); fixed_t sine = FixedMul(player->mo->scale, 8 * FINESINE((((2*pi*(4*TICRATE)) * leveltime)>>ANGLETOFINESHIFT) & FINEMASK));
targz = (player->mo->z + (player->mo->height/2)) + sine; targz = (player->mo->z + (player->mo->height/2)) + sine;
if (player->mo->eflags & MFE_VERTICALFLIP)
targz += (player->mo->height/2 - 32*player->mo->scale)*6;
} }
if (cur->tracer) if (cur->tracer)
@ -4148,7 +4169,7 @@ static void K_MoveHeldObjects(player_t *player)
} }
P_TeleportMove(cur, targx, targy, targz); P_TeleportMove(cur, targx, targy, targz);
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
num = (num+1) % 2; num = (num+1) % 2;
cur = cur->hnext; cur = cur->hnext;
} }
@ -4693,8 +4714,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_comebacktimer]) if (player->kartstuff[k_comebacktimer])
player->kartstuff[k_comebackmode] = 0; player->kartstuff[k_comebackmode] = 0;
if (P_IsObjectOnGround(player->mo) && player->mo->momz <= 0 && player->kartstuff[k_pogospring]) if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_pogospring])
player->kartstuff[k_pogospring] = 0; {
if (P_MobjFlip(player->mo)*player->mo->momz <= 0)
player->kartstuff[k_pogospring] = 0;
}
if (cmd->buttons & BT_DRIFT) if (cmd->buttons & BT_DRIFT)
player->kartstuff[k_jmp] = 1; player->kartstuff[k_jmp] = 1;
@ -5335,6 +5359,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
for (moloop = 0; moloop < 2; moloop++) for (moloop = 0; moloop < 2; moloop++)
{ {
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ROCKETSNEAKER); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ROCKETSNEAKER);
K_MatchGenericExtraFlags(mo, player->mo);
mo->flags |= MF_NOCLIPTHING; mo->flags |= MF_NOCLIPTHING;
mo->angle = player->mo->angle; mo->angle = player->mo->angle;
mo->threshold = 10; mo->threshold = 10;
@ -6971,7 +6996,7 @@ static void K_drawKartItem(void)
} }
if (localcolor != SKINCOLOR_NONE) if (localcolor != SKINCOLOR_NONE)
colmap = R_GetTranslationColormap(colormode, localcolor, 0); colmap = R_GetTranslationColormap(colormode, localcolor, GTC_CACHE);
V_DrawScaledPatch(fx, fy, V_HUDTRANS|fflags, localbg); V_DrawScaledPatch(fx, fy, V_HUDTRANS|fflags, localbg);
@ -7633,7 +7658,7 @@ static void K_drawKartSpeedometer(void)
static void K_drawKartBumpersOrKarma(void) static void K_drawKartBumpersOrKarma(void)
{ {
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, 0); UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT); INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT);
INT32 fx = 0, fy = 0, fflags = 0; INT32 fx = 0, fy = 0, fflags = 0;
boolean flipstring = false; // same as laps, used for splitscreen boolean flipstring = false; // same as laps, used for splitscreen
@ -7841,7 +7866,7 @@ static void K_drawKartPlayerCheck(void)
else if (x > 306) else if (x > 306)
x = 306; x = 306;
colormap = R_GetTranslationColormap(TC_DEFAULT, players[i].mo->color, 0); colormap = R_GetTranslationColormap(TC_DEFAULT, players[i].mo->color, GTC_CACHE);
V_DrawMappedPatch(x, CHEK_Y, V_HUDTRANS|splitflags, kp_check[pnum], colormap); V_DrawMappedPatch(x, CHEK_Y, V_HUDTRANS|splitflags, kp_check[pnum], colormap);
} }
} }
@ -8370,16 +8395,16 @@ static void K_drawKartFirstPerson(void)
// drift sparks! // drift sparks!
if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsthree)) if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsthree))
colmap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), 0); colmap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE);
else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo)) else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo))
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, 0); colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE);
else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone)) else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone))
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, 0); colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE);
else else
#endif #endif
// invincibility/grow/shrink! // invincibility/grow/shrink!
if (stplyr->mo->colorized && stplyr->mo->color) if (stplyr->mo->colorized && stplyr->mo->color)
colmap = R_GetTranslationColormap(TC_RAINBOW, stplyr->mo->color, 0); colmap = R_GetTranslationColormap(TC_RAINBOW, stplyr->mo->color, GTC_CACHE);
} }
V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap); V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap);
@ -8489,7 +8514,7 @@ static void K_drawInput(void)
else else
{ {
UINT8 *colormap; UINT8 *colormap;
colormap = R_GetTranslationColormap(0, stplyr->skincolor, 0); colormap = R_GetTranslationColormap(0, stplyr->skincolor, GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, splitflags, kp_inputwheel[target], colormap); V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, splitflags, kp_inputwheel[target], colormap);
} }
} }
@ -8514,7 +8539,7 @@ static void K_drawLapStartAnim(void)
{ {
// This is an EVEN MORE insanely complicated animation. // This is an EVEN MORE insanely complicated animation.
const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation]; const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation];
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, 0); UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT, V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT,
(48 - (32*max(0, progress-76)))*FRACUNIT, (48 - (32*max(0, progress-76)))*FRACUNIT,
@ -8888,7 +8913,7 @@ void K_drawKartHUD(void)
for (c = 1; c < MAXSKINCOLORS; c++) for (c = 1; c < MAXSKINCOLORS; c++)
{ {
UINT8 *cm = R_GetTranslationColormap(TC_RAINBOW, c, 0); UINT8 *cm = R_GetTranslationColormap(TC_RAINBOW, c, GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT>>1, 0, facewantprefix[stplyr->skin], cm); V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT>>1, 0, facewantprefix[stplyr->skin], cm);
x += 16; x += 16;

View file

@ -23,6 +23,7 @@ void K_RegisterKartStuff(void);
boolean K_IsPlayerLosing(player_t *player); boolean K_IsPlayerLosing(player_t *player);
boolean K_IsPlayerWanted(player_t *player); boolean K_IsPlayerWanted(player_t *player);
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master); void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
void K_RespawnChecker(player_t *player); void K_RespawnChecker(player_t *player);
void K_KartMoveAnimation(player_t *player); void K_KartMoveAnimation(player_t *player);

View file

@ -632,19 +632,6 @@ static int lib_pCheckSolidLava(lua_State *L)
return 1; return 1;
} }
static int lib_pCanRunOnWater(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
//HUDSAFE
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!rover)
return LUA_ErrInvalid(L, "ffloor_t");
lua_pushboolean(L, P_CanRunOnWater(player, rover));
return 1;
}
static int lib_pSpawnShadowMobj(lua_State *L) static int lib_pSpawnShadowMobj(lua_State *L)
{ {
mobj_t *caster = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *caster = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2627,7 +2614,6 @@ static luaL_Reg lib[] = {
{"P_InsideANonSolidFFloor",lib_pInsideANonSolidFFloor}, {"P_InsideANonSolidFFloor",lib_pInsideANonSolidFFloor},
{"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide}, {"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide},
{"P_CheckSolidLava",lib_pCheckSolidLava}, {"P_CheckSolidLava",lib_pCheckSolidLava},
{"P_CanRunOnWater",lib_pCanRunOnWater},
{"P_SpawnShadowMobj",lib_pSpawnShadowMobj}, {"P_SpawnShadowMobj",lib_pSpawnShadowMobj},
// p_user // p_user

View file

@ -751,6 +751,8 @@ static int ticcmd_get(lua_State *L)
lua_pushinteger(L, cmd->buttons); lua_pushinteger(L, cmd->buttons);
else if (fastcmp(field,"driftturn")) else if (fastcmp(field,"driftturn"))
lua_pushinteger(L, cmd->driftturn); lua_pushinteger(L, cmd->driftturn);
else if (fastcmp(field,"latency"))
lua_pushinteger(L, cmd->latency);
else else
return NOFIELD; return NOFIELD;

View file

@ -30,24 +30,10 @@ enum skin {
skin_facerank, skin_facerank,
skin_facewant, skin_facewant,
skin_facemmap, skin_facemmap,
skin_ability,
skin_ability2,
skin_thokitem,
skin_spinitem,
skin_revitem,
skin_actionspd,
skin_mindash,
skin_maxdash,
// SRB2kart // SRB2kart
skin_kartspeed, skin_kartspeed,
skin_kartweight, skin_kartweight,
// //
skin_normalspeed,
skin_runspeed,
skin_thrustfactor,
skin_accelstart,
skin_acceleration,
skin_jumpfactor,
skin_starttranscolor, skin_starttranscolor,
skin_prefcolor, skin_prefcolor,
skin_highresscale, skin_highresscale,
@ -64,24 +50,10 @@ static const char *const skin_opt[] = {
"facerank", "facerank",
"facewant", "facewant",
"facemmap", "facemmap",
"ability",
"ability2",
"thokitem",
"spinitem",
"revitem",
"actionspd",
"mindash",
"maxdash",
// SRB2kart // SRB2kart
"kartspeed", "kartspeed",
"kartweight", "kartweight",
// //
"normalspeed",
"runspeed",
"thrustfactor",
"accelstart",
"acceleration",
"jumpfactor",
"starttranscolor", "starttranscolor",
"prefcolor", "prefcolor",
"highresscale", "highresscale",
@ -139,30 +111,6 @@ static int skin_get(lua_State *L)
break; break;
lua_pushlstring(L, skin->facemmap, i); lua_pushlstring(L, skin->facemmap, i);
break; break;
case skin_ability:
lua_pushinteger(L, skin->ability);
break;
case skin_ability2:
lua_pushinteger(L, skin->ability2);
break;
case skin_thokitem:
lua_pushinteger(L, skin->thokitem);
break;
case skin_spinitem:
lua_pushinteger(L, skin->spinitem);
break;
case skin_revitem:
lua_pushinteger(L, skin->revitem);
break;
case skin_actionspd:
lua_pushfixed(L, skin->actionspd);
break;
case skin_mindash:
lua_pushfixed(L, skin->mindash);
break;
case skin_maxdash:
lua_pushfixed(L, skin->maxdash);
break;
// SRB2kart // SRB2kart
case skin_kartspeed: case skin_kartspeed:
lua_pushinteger(L, skin->kartspeed); lua_pushinteger(L, skin->kartspeed);
@ -171,24 +119,6 @@ static int skin_get(lua_State *L)
lua_pushinteger(L, skin->kartweight); lua_pushinteger(L, skin->kartweight);
break; break;
// //
case skin_normalspeed:
lua_pushfixed(L, skin->normalspeed);
break;
case skin_runspeed:
lua_pushfixed(L, skin->runspeed);
break;
case skin_thrustfactor:
lua_pushinteger(L, skin->thrustfactor);
break;
case skin_accelstart:
lua_pushinteger(L, skin->accelstart);
break;
case skin_acceleration:
lua_pushinteger(L, skin->acceleration);
break;
case skin_jumpfactor:
lua_pushfixed(L, skin->jumpfactor);
break;
case skin_starttranscolor: case skin_starttranscolor:
lua_pushinteger(L, skin->starttranscolor); lua_pushinteger(L, skin->starttranscolor);
break; break;

View file

@ -400,6 +400,8 @@ static void Dummystaff_OnChange(void);
// CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE.
// ========================================================================== // ==========================================================================
consvar_t cv_showfocuslost = {"showfocuslost", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL };
static CV_PossibleValue_t map_cons_t[] = { static CV_PossibleValue_t map_cons_t[] = {
{0,"MIN"}, {0,"MIN"},
{NUMMAPS, "MAX"}, {NUMMAPS, "MAX"},
@ -949,14 +951,15 @@ static menuitem_t MP_MainMenu[] =
static menuitem_t MP_ServerMenu[] = static menuitem_t MP_ServerMenu[] =
{ {
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10}, {IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 0},
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20}, {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20},
{IT_STRING|IT_CVAR|IT_CV_PASSWORD, NULL, "Password", &cv_dummyjoinpassword, 44},
{IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68}, {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68},
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130},
}; };
#endif #endif
@ -1318,6 +1321,9 @@ static menuitem_t OP_SoundOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95}, {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95},
{IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 110}, {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 110},
{IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 125},
{IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 135},
}; };
/*static menuitem_t OP_DataOptionsMenu[] = /*static menuitem_t OP_DataOptionsMenu[] =
@ -1404,6 +1410,8 @@ static menuitem_t OP_HUDOptionsMenu[] =
// highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 105 (see M_DrawHUDOptions) // highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 105 (see M_DrawHUDOptions)
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120}, {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120},
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 135},
}; };
// Ok it's still called chatoptions but we'll put ping display in here to be clean // Ok it's still called chatoptions but we'll put ping display in here to be clean
@ -2385,6 +2393,9 @@ static void M_NextOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do do
{ {
if (itemOn + 1 > currentMenu->numitems - 1) if (itemOn + 1 > currentMenu->numitems - 1)
@ -2398,6 +2409,9 @@ static void M_PrevOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do do
{ {
if (!itemOn) if (!itemOn)
@ -2684,8 +2698,11 @@ boolean M_Responder(event_t *ev)
// BP: one of the more big hack i have never made // BP: one of the more big hack i have never made
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR) if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)
{ {
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING || (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
{ {
if (ch == KEY_TAB && (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value ^= 1;
if (shiftdown && ch >= 32 && ch <= 127) if (shiftdown && ch >= 32 && ch <= 127)
ch = shiftxform[ch]; ch = shiftxform[ch];
if (M_ChangeStringCvar(ch)) if (M_ChangeStringCvar(ch))
@ -2886,7 +2903,7 @@ void M_Drawer(void)
} }
// focus lost notification goes on top of everything, even the former everything // focus lost notification goes on top of everything, even the former everything
if (window_notinfocus) if (window_notinfocus && cv_showfocuslost.value)
{ {
M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2);
if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
@ -3461,7 +3478,7 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y)
if (emblem->collected) if (emblem->collected)
V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
else else
V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -3561,6 +3578,8 @@ static void M_DrawGenericMenu(void)
case IT_CVAR: case IT_CVAR:
{ {
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
char asterisks[MAXSTRINGLENGTH+1];
size_t sl;
switch (currentMenu->menuitems[i].status & IT_CVARTYPE) switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
{ {
case IT_CV_SLIDER: case IT_CV_SLIDER:
@ -3568,6 +3587,27 @@ static void M_DrawGenericMenu(void)
case IT_CV_NOPRINT: // color use this case IT_CV_NOPRINT: // color use this
case IT_CV_INVISSLIDER: // monitor toggles use this case IT_CV_INVISSLIDER: // monitor toggles use this
break; break;
case IT_CV_PASSWORD:
if (i == itemOn)
{
V_DrawRightAlignedThinString(x + MAXSTRINGLENGTH*8 + 10, y, V_ALLOWLOWERCASE, va(M_GetText("Tab: %s password"), cv->value ? "hide" : "show"));
}
if (!cv->value || i != itemOn)
{
sl = strlen(cv->string);
memset(asterisks, '*', sl);
memset(asterisks + sl, 0, MAXSTRINGLENGTH+1-sl);
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, asterisks);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(asterisks, 0), y + 12,
'_' | 0x80, false);
y += 16;
break;
}
/* fallthru */
case IT_CV_STRING: case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
@ -3775,7 +3815,7 @@ static void M_DrawPauseMenu(void)
if (emblem->collected) if (emblem->collected)
V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
else else
V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE)); V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -5323,7 +5363,7 @@ static void M_DrawEmblemHints(void)
{ {
collected = recommendedflags; collected = recommendedflags;
V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
} }
else else
{ {
@ -5666,7 +5706,7 @@ static void M_DrawLoadGameData(void)
V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE)); V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE));
else else
{ {
UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, 0); UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, GTC_MENUCACHE);
V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap); V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap);
} }
@ -6356,7 +6396,7 @@ static void M_DrawStatsMaps(int location)
if (exemblem->collected) if (exemblem->collected)
V_DrawSmallMappedPatch(295, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE), V_DrawSmallMappedPatch(295, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE)); R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_MENUCACHE));
else else
V_DrawSmallScaledPatch(295, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); V_DrawSmallScaledPatch(295, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -6491,7 +6531,7 @@ void M_DrawTimeAttackMenu(void)
// Character face! // Character face!
if (W_CheckNumForName(skins[cv_chooseskin.value-1].facewant) != LUMPERROR) if (W_CheckNumForName(skins[cv_chooseskin.value-1].facewant) != LUMPERROR)
{ {
UINT8 *colormap = R_GetTranslationColormap(cv_chooseskin.value-1, cv_playercolor.value, 0); UINT8 *colormap = R_GetTranslationColormap(cv_chooseskin.value-1, cv_playercolor.value, GTC_MENUCACHE);
V_DrawMappedPatch(BASEVIDWIDTH-x - SHORT(facewantprefix[cv_chooseskin.value-1]->width), y, 0, facewantprefix[cv_chooseskin.value-1], colormap); V_DrawMappedPatch(BASEVIDWIDTH-x - SHORT(facewantprefix[cv_chooseskin.value-1]->width), y, 0, facewantprefix[cv_chooseskin.value-1], colormap);
} }
@ -6616,7 +6656,7 @@ void M_DrawTimeAttackMenu(void)
if (em->collected) if (em->collected)
V_DrawMappedPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), V_DrawMappedPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_MENUCACHE));
else else
V_DrawScaledPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName("NEEDIT", PU_CACHE)); V_DrawScaledPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -6776,7 +6816,7 @@ static boolean M_QuitTimeAttackMenu(void)
if (em->collected) if (em->collected)
V_DrawSmallMappedPatch(160+88, yHeight, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), V_DrawSmallMappedPatch(160+88, yHeight, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_MENUCACHE));
else else
V_DrawSmallScaledPatch(160+88, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE)); V_DrawSmallScaledPatch(160+88, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -7245,6 +7285,7 @@ static void M_DrawConnectMenu(void)
{ {
UINT16 i, j; UINT16 i, j;
const char *gt = "Unknown"; const char *gt = "Unknown";
const char *spd = "";
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++)
@ -7298,7 +7339,17 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, va("Gametype: %s", gt)); V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt);
if (serverlist[slindex].info.gametype == GT_RACE)
{
spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue;
V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd));
}
if (serverlist[slindex].info.kartvars & SV_PASSWORD)
V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL);
MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL;
} }
@ -7533,6 +7584,11 @@ static void M_StartServer(INT32 choice)
// Still need to reset devmode // Still need to reset devmode
cv_debug = 0; cv_debug = 0;
if (strlen(cv_dummyjoinpassword.string) > 0)
D_SetJoinPassword(cv_dummyjoinpassword.string);
else
joinpasswordset = false;
if (demoplayback) if (demoplayback)
G_StopDemo(); G_StopDemo();
if (metalrecording) if (metalrecording)
@ -7834,7 +7890,7 @@ Update the maxplayers label...
if (!trans && i > cv_splitplayers.value) if (!trans && i > cv_splitplayers.value)
trans = V_TRANSLUCENT; trans = V_TRANSLUCENT;
colmap = R_GetTranslationColormap(pskin, pcol, 0); colmap = R_GetTranslationColormap(pskin, pcol, GTC_MENUCACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, trans, facewantprefix[pskin], colmap); V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, trans, facewantprefix[pskin], colmap);
@ -8174,7 +8230,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
statdot = W_CachePatchName("K_SDOT2", PU_CACHE); // coloured center statdot = W_CachePatchName("K_SDOT2", PU_CACHE); // coloured center
if (setupm_fakecolor) if (setupm_fakecolor)
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, 0)); V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
// 2.2 color bar backported with permission // 2.2 color bar backported with permission
#define charw 72 #define charw 72
@ -8244,7 +8300,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
offx = 8; offx = 8;
offy = 8; offy = 8;
} }
colmap = R_GetTranslationColormap(col, setupm_fakecolor, 0); colmap = R_GetTranslationColormap(col, setupm_fakecolor, GTC_MENUCACHE);
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, face, colmap); V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, face, colmap);
if (scale == FRACUNIT) // bit of a hack if (scale == FRACUNIT) // bit of a hack
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, cursor, colmap); V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, cursor, colmap);
@ -8290,7 +8346,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
// draw player sprite // draw player sprite
if (setupm_fakecolor) // inverse should never happen if (setupm_fakecolor) // inverse should never happen
{ {
UINT8 *colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0); UINT8 *colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, GTC_MENUCACHE);
if (skins[setupm_fakeskin].flags & SF_HIRES) if (skins[setupm_fakeskin].flags & SF_HIRES)
{ {
@ -8301,8 +8357,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
} }
else else
V_DrawMappedPatch(mx+43, my+131, flags, patch, colormap); V_DrawMappedPatch(mx+43, my+131, flags, patch, colormap);
Z_Free(colormap);
} }
// draw their follower if there is one // draw their follower if there is one

View file

@ -104,6 +104,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_CV_NOPRINT 1536 #define IT_CV_NOPRINT 1536
#define IT_CV_NOMOD 2048 #define IT_CV_NOMOD 2048
#define IT_CV_INVISSLIDER 2560 #define IT_CV_INVISSLIDER 2560
#define IT_CV_PASSWORD 3072
//call/submenu specific //call/submenu specific
// There used to be a lot more here but ... // There used to be a lot more here but ...
@ -211,6 +212,7 @@ typedef struct
extern description_t description[32]; extern description_t description[32];
extern consvar_t cv_showfocuslost;
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
extern CV_PossibleValue_t gametype_cons_t[]; extern CV_PossibleValue_t gametype_cons_t[];

View file

@ -22,6 +22,8 @@
# include <limits.h> # include <limits.h>
#endif #endif
#define MD5_LEN 16
/* The following contortions are an attempt to use the C preprocessor /* The following contortions are an attempt to use the C preprocessor
to determine an unsigned integral type that is 32 bits wide. An to determine an unsigned integral type that is 32 bits wide. An
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but

View file

@ -8640,6 +8640,7 @@ void A_LightningFollowPlayer(mobj_t *actor)
else // else just teleport to player directly else // else just teleport to player directly
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
actor->momx = actor->target->momx; actor->momx = actor->target->momx;
actor->momy = actor->target->momy; actor->momy = actor->target->momy;
actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame. actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame.

View file

@ -141,6 +141,9 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|| (weapon != 3 && player->kartstuff[k_itemamount]) || (weapon != 3 && player->kartstuff[k_itemamount])
|| player->kartstuff[k_itemheld]) || player->kartstuff[k_itemheld])
return false; return false;
if (weapon == 3 && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD)
return false; // No stacking thunder shields!
} }
} }
@ -1474,6 +1477,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->starpostz = special->z>>FRACBITS; player->starpostz = special->z>>FRACBITS;
player->starpostangle = special->angle; player->starpostangle = special->angle;
player->starpostnum = special->health; player->starpostnum = special->health;
player->kartstuff[k_starpostflip] = special->spawnpoint->options & MTF_OBJECTFLIP; // store flipping
//S_StartSound(toucher, special->info->painsound); //S_StartSound(toucher, special->info->painsound);
return; return;
@ -2958,66 +2962,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
} }
} }
/*
static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) // SRB2kart - unused.
{
fixed_t fallbackspeed;
angle_t ang;
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z--;
else
player->mo->z++;
if (player->mo->eflags & MFE_UNDERWATER)
P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false);
else
P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false);
ang = R_PointToAngle2(inflictor->x, inflictor->y, player->mo->x, player->mo->y);
// explosion and rail rings send you farther back, making it more difficult
// to recover
if (inflictor->flags2 & MF2_SCATTER && source)
{
fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z);
dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4;
if (dist < FixedMul(4*FRACUNIT, inflictor->scale))
dist = FixedMul(4*FRACUNIT, inflictor->scale);
fallbackspeed = dist;
}
else if (inflictor->flags2 & MF2_EXPLOSION)
{
if (inflictor->flags2 & MF2_RAILRING)
fallbackspeed = FixedMul(28*FRACUNIT, inflictor->scale); // 7x
else
fallbackspeed = FixedMul(20*FRACUNIT, inflictor->scale); // 5x
}
else if (inflictor->flags2 & MF2_RAILRING)
fallbackspeed = FixedMul(16*FRACUNIT, inflictor->scale); // 4x
else
fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force
P_InstaThrust(player->mo, ang, fallbackspeed);
// SRB2kart - This shouldn't be reachable, but this frame is invalid.
//if (player->charflags & SF_SUPERANIMS)
// P_SetPlayerMobjState(player->mo, S_PLAY_SUPERHIT);
//else
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
P_ResetPlayer(player);
if (player->timeshit != UINT8_MAX)
++player->timeshit;
}
*/
void P_RemoveShield(player_t *player) void P_RemoveShield(player_t *player)
{ {
if (player->powers[pw_shield] & SH_FORCE) if (player->powers[pw_shield] & SH_FORCE)

View file

@ -274,8 +274,6 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab); void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
mobj_t *P_GetClosestAxis(mobj_t *source); mobj_t *P_GetClosestAxis(mobj_t *source);
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover);
void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration); void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration);
#define PAL_WHITE 1 #define PAL_WHITE 1
#define PAL_MIXUP 2 #define PAL_MIXUP 2

View file

@ -2114,7 +2114,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
continue; continue;
} }
if (thing->player && (P_CheckSolidLava(thing, rover) || P_CanRunOnWater(thing->player, rover))) if (thing->player && P_CheckSolidLava(thing, rover))
; ;
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)) else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
; ;
@ -2787,8 +2787,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#ifdef ESLOPE #ifdef ESLOPE
// HACK TO FIX DSZ2: apply only if slopes are involved else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{ {
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
@ -2801,8 +2800,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#ifdef ESLOPE #ifdef ESLOPE
// HACK TO FIX DSZ2: apply only if slopes are involved else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{ {
thing->z = thing->floorz = tmfloorz; thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;

View file

@ -649,7 +649,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover))) if (mobj->player && P_CheckSolidLava(mobj, rover))
; ;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player))) || (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
@ -693,7 +693,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover))) if (mobj->player && P_CheckSolidLava(mobj, rover))
; ;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player))) || (rover->flags & FF_BLOCKOTHERS && !mobj->player)))

View file

@ -167,58 +167,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state); I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state);
#endif #endif
// Catch state changes for Super Sonic
/* // SRB2kart - don't need
if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS))
{
switch (state)
{
case S_PLAY_STND:
case S_PLAY_TAP1:
case S_PLAY_TAP2:
case S_PLAY_GASP:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERSTAND);
return true;
case S_PLAY_FALL1:
case S_PLAY_SPRING:
case S_PLAY_RUN1:
case S_PLAY_RUN2:
case S_PLAY_RUN3:
case S_PLAY_RUN4:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK1);
return true;
case S_PLAY_FALL2:
case S_PLAY_RUN5:
case S_PLAY_RUN6:
case S_PLAY_RUN7:
case S_PLAY_RUN8:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK2);
return true;
case S_PLAY_SPD1:
case S_PLAY_SPD2:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY1);
return true;
case S_PLAY_SPD3:
case S_PLAY_SPD4:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY2);
return true;
case S_PLAY_TEETER1:
case S_PLAY_TEETER2:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERTEETER);
return true;
case S_PLAY_ATK1:
case S_PLAY_ATK2:
case S_PLAY_ATK3:
case S_PLAY_ATK4:
if (!(player->charflags & SF_SUPERSPIN))
return true;
break;
default:
break;
}
}
// You were in pain state after taking a hit, and you're moving out of pain state now? // You were in pain state after taking a hit, and you're moving out of pain state now?
else */if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == K_GetKartFlashing(player) && state != mobj->info->painstate) if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == K_GetKartFlashing(player) && state != mobj->info->painstate)
{ {
// Start flashing, since you've landed. // Start flashing, since you've landed.
player->powers[pw_flashing] = K_GetKartFlashing(player)-1; player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
@ -260,51 +210,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
st = &states[state]; st = &states[state];
mobj->state = st; mobj->state = st;
mobj->tics = st->tics; mobj->tics = st->tics;
// Adjust the player's animation speed to match their velocity.
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
{
fixed_t speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); // fixed_t speed = FixedDiv(player->speed, mobj->scale);
if (player->panim == PA_ROLL)
{
if (speed > 16<<FRACBITS)
mobj->tics = 1;
else
mobj->tics = 2;
}
else if (player->panim == PA_FALL)
{
speed = FixedDiv(abs(mobj->momz), mobj->scale);
if (speed < 10<<FRACBITS)
mobj->tics = 4;
else if (speed < 20<<FRACBITS)
mobj->tics = 3;
else if (speed < 30<<FRACBITS)
mobj->tics = 2;
else
mobj->tics = 1;
}
else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying.
{
if (player->panim == PA_WALK)
{
if (speed > 12<<FRACBITS)
mobj->tics = 2;
else if (speed > 6<<FRACBITS)
mobj->tics = 3;
else
mobj->tics = 4;
}
else if (player->panim == PA_RUN)
{
if (speed > 52<<FRACBITS)
mobj->tics = 1;
else
mobj->tics = 2;
}
}
}
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
@ -2102,7 +2007,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected if (mo->player && P_CheckSolidLava(mo, rover)) // only the player should be affected
; ;
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
continue; continue;
@ -3225,27 +3130,6 @@ static boolean P_SceneryZMovement(mobj_t *mo)
return true; return true;
} }
// P_CanRunOnWater
//
// Returns true if player can waterrun on the 3D floor
//
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{
fixed_t topheight =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
#endif
*rover->topheight;
if (((player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height)
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
&& !(player->pflags & PF_SLIDING)
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
return true;
return false;
}
// //
// P_MobjCheckWater // P_MobjCheckWater
// //
@ -6647,7 +6531,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_SINK_SHIELD: case MT_SINK_SHIELD:
if ((mobj->health > 0 if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz) || (mobj->health <= 0 && P_IsObjectOnGround(mobj))
|| P_CheckDeathPitCollide(mobj)) // When in death state || P_CheckDeathPitCollide(mobj)) // When in death state
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
@ -6662,19 +6546,21 @@ void P_MobjThinker(mobj_t *mobj)
fixed_t z = P_RandomRange(0, 70)*mobj->scale; fixed_t z = P_RandomRange(0, 70)*mobj->scale;
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
P_SetMobjState(smoke, S_OPAQUESMOKE1); P_SetMobjState(smoke, S_OPAQUESMOKE1);
K_MatchGenericExtraFlags(smoke, mobj);
smoke->scale = mobj->scale * 2; smoke->scale = mobj->scale * 2;
smoke->destscale = mobj->scale * 6; smoke->destscale = mobj->scale * 6;
smoke->momz = P_RandomRange(4, 9)*FRACUNIT; smoke->momz = P_RandomRange(4, 9)*FRACUNIT*P_MobjFlip(smoke);
} }
break; break;
case MT_BOOMPARTICLE: case MT_BOOMPARTICLE:
{ {
fixed_t x = P_RandomRange(-16, 16)*mobj->scale; fixed_t x = P_RandomRange(-16, 16)*mobj->scale;
fixed_t y = P_RandomRange(-16, 16)*mobj->scale; fixed_t y = P_RandomRange(-16, 16)*mobj->scale;
fixed_t z = P_RandomRange(0, 32)*mobj->scale; fixed_t z = P_RandomRange(0, 32)*mobj->scale*P_MobjFlip(mobj);
if (leveltime % 2 == 0) if (leveltime % 2 == 0)
{ {
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_BOSSEXPLODE); mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_BOSSEXPLODE);
K_MatchGenericExtraFlags(smoke, mobj);
P_SetMobjState(smoke, S_QUICKBOOM1); P_SetMobjState(smoke, S_QUICKBOOM1);
smoke->scale = mobj->scale/2; smoke->scale = mobj->scale/2;
smoke->destscale = mobj->scale; smoke->destscale = mobj->scale;
@ -6684,6 +6570,7 @@ void P_MobjThinker(mobj_t *mobj)
{ {
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
P_SetMobjState(smoke, S_OPAQUESMOKE1); P_SetMobjState(smoke, S_OPAQUESMOKE1);
K_MatchGenericExtraFlags(smoke, mobj);
smoke->scale = mobj->scale; smoke->scale = mobj->scale;
smoke->destscale = mobj->scale*2; smoke->destscale = mobj->scale*2;
} }
@ -6789,7 +6676,7 @@ void P_MobjThinker(mobj_t *mobj)
} }
else if ((mobj->health > 0 else if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator)) && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz) || (mobj->health <= 0 && P_IsObjectOnGround(mobj))
|| P_CheckDeathPitCollide(mobj)) // When in death state || P_CheckDeathPitCollide(mobj)) // When in death state
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
@ -7237,6 +7124,9 @@ void P_MobjThinker(mobj_t *mobj)
y = mobj->target->y; y = mobj->target->y;
z = mobj->target->z + (80*mapobjectscale); z = mobj->target->z + (80*mapobjectscale);
} }
if (mobj->target->eflags & MFE_VERTICALFLIP)
z += mobj->target->height - FixedMul(mobj->target->scale, mobj->height);
P_TeleportMove(mobj, x, y, z); P_TeleportMove(mobj, x, y, z);
} }
break; break;
@ -7432,7 +7322,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_BANANA: case MT_BANANA:
case MT_EGGMANITEM: case MT_EGGMANITEM:
case MT_SPB: case MT_SPB:
if (mobj->z <= mobj->floorz) if (P_IsObjectOnGround(mobj))
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return; return;
@ -7445,7 +7335,7 @@ void P_MobjThinker(mobj_t *mobj)
break; break;
case MT_JAWZ: case MT_JAWZ:
case MT_JAWZ_DUD: case MT_JAWZ_DUD:
if (mobj->z <= mobj->floorz) if (P_IsObjectOnGround(mobj))
P_SetMobjState(mobj, mobj->info->xdeathstate); P_SetMobjState(mobj, mobj->info->xdeathstate);
// fallthru // fallthru
case MT_JAWZ_SHIELD: case MT_JAWZ_SHIELD:
@ -7479,7 +7369,7 @@ void P_MobjThinker(mobj_t *mobj)
/* FALLTHRU */ /* FALLTHRU */
case MT_SMK_MOLE: case MT_SMK_MOLE:
mobj->flags2 ^= MF2_DONTDRAW; mobj->flags2 ^= MF2_DONTDRAW;
if (mobj->z <= mobj->floorz) if (P_IsObjectOnGround(mobj))
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return; return;
@ -7500,7 +7390,7 @@ void P_MobjThinker(mobj_t *mobj)
} }
mobj->flags2 ^= MF2_DONTDRAW; mobj->flags2 ^= MF2_DONTDRAW;
if (mobj->z <= mobj->floorz) if (P_IsObjectOnGround(mobj))
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return; return;
@ -8169,7 +8059,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj->friction = ORIG_FRICTION/4; mobj->friction = ORIG_FRICTION/4;
if (mobj->momx || mobj->momy) if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj); P_SpawnGhostMobj(mobj);
if (mobj->z <= mobj->floorz && mobj->health > 1) if (P_IsObjectOnGround(mobj) && mobj->health > 1)
{ {
S_StartSound(mobj, mobj->info->activesound); S_StartSound(mobj, mobj->info->activesound);
mobj->momx = mobj->momy = 0; mobj->momx = mobj->momy = 0;
@ -8189,7 +8079,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_SINK: case MT_SINK:
if (mobj->momx || mobj->momy) if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj); P_SpawnGhostMobj(mobj);
if (mobj->z <= mobj->floorz) if (P_IsObjectOnGround(mobj))
{ {
S_StartSound(mobj, mobj->info->deathsound); S_StartSound(mobj, mobj->info->deathsound);
P_SetMobjState(mobj, S_NULL); P_SetMobjState(mobj, S_NULL);
@ -8365,6 +8255,7 @@ void P_MobjThinker(mobj_t *mobj)
break; break;
case MT_INSTASHIELDB: case MT_INSTASHIELDB:
mobj->flags2 ^= MF2_DONTDRAW; mobj->flags2 ^= MF2_DONTDRAW;
K_MatchGenericExtraFlags(mobj, mobj->target);
/* FALLTHRU */ /* FALLTHRU */
case MT_INSTASHIELDA: case MT_INSTASHIELDA:
if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield])) if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield]))
@ -8373,6 +8264,7 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
K_MatchGenericExtraFlags(mobj, mobj->target);
break; break;
case MT_BATTLEPOINT: case MT_BATTLEPOINT:
if (!mobj->target || P_MobjWasRemoved(mobj->target)) if (!mobj->target || P_MobjWasRemoved(mobj->target))
@ -8393,7 +8285,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->movefactor < mobj->target->height) if (mobj->movefactor < mobj->target->height)
mobj->movefactor = mobj->target->height; mobj->movefactor = mobj->target->height;
} }
K_MatchGenericExtraFlags(mobj, mobj->target);
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor); P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
break; break;
case MT_THUNDERSHIELD: case MT_THUNDERSHIELD:
@ -8518,6 +8410,10 @@ void P_MobjThinker(mobj_t *mobj)
mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags2 &= ~MF2_DONTDRAW;
} }
// Update mobj antigravity status:
mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP);
mobj->flags2 = (mobj->flags2 & ~MF2_OBJECTFLIP)|(mobj->target->flags2 & MF2_OBJECTFLIP);
// Now for the wheels // Now for the wheels
{ {
const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->target->scale); const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->target->scale);
@ -8539,6 +8435,7 @@ void P_MobjThinker(mobj_t *mobj)
P_SetScale(cur, mobj->target->scale); P_SetScale(cur, mobj->target->scale);
cur->color = mobj->target->color; cur->color = mobj->target->color;
cur->colorized = true; cur->colorized = true;
K_FlipFromObject(cur, mobj->target);
if (mobj->flags2 & MF2_DONTDRAW) if (mobj->flags2 & MF2_DONTDRAW)
cur->flags2 |= MF2_DONTDRAW; cur->flags2 |= MF2_DONTDRAW;
@ -11136,7 +11033,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
if (mthing->options >> ZSHIFT) if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS); z -= ((mthing->options >> ZSHIFT) << FRACBITS);
if (p->kartstuff[k_respawn]) if (p->kartstuff[k_respawn])
z -= 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale; z -= 128*mapobjectscale;
} }
else else
{ {
@ -11144,7 +11041,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
if (mthing->options >> ZSHIFT) if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS); z += ((mthing->options >> ZSHIFT) << FRACBITS);
if (p->kartstuff[k_respawn]) if (p->kartstuff[k_respawn])
z += 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale; z += 128*mapobjectscale;
} }
if (mthing->options & MTF_OBJECTFLIP) // flip the player! if (mthing->options & MTF_OBJECTFLIP) // flip the player!
@ -11205,7 +11102,14 @@ void P_MovePlayerToStarpost(INT32 playernum)
#endif #endif
sector->ceilingheight; sector->ceilingheight;
z = (p->starpostz + 128) << FRACBITS; // Respawn off the ground if (mobj->player->kartstuff[k_starpostflip])
z = (p->starpostz<<FRACBITS) - FixedMul(128<<FRACBITS, mapobjectscale) - mobj->height;
else
z = (p->starpostz<<FRACBITS) + FixedMul(128<<FRACBITS, mapobjectscale);
//z = (p->starpostz + 128) << FRACBITS; // reverse gravity exists, pls
mobj->player->kartstuff[k_starpostflip] = 0;
if (z < floor) if (z < floor)
z = floor; z = floor;
else if (z > ceiling - mobjinfo[MT_PLAYER].height) else if (z > ceiling - mobjinfo[MT_PLAYER].height)

View file

@ -700,89 +700,84 @@ static void P_NetArchiveWorld(void)
WRITEUINT16(put, 0xffff); WRITEUINT16(put, 0xffff);
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE); // do lines
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE); for (i = 0; i < numlines; i++, mld++, li++)
if (mld && msd)
{ {
// do lines diff = diff2 = 0;
for (i = 0; i < numlines; i++, mld++, li++)
if (li->special != SHORT(mld->special))
diff |= LD_SPECIAL;
if (SHORT(mld->special) == 321 || SHORT(mld->special) == 322) // only reason li->callcount would be non-zero is if either of these are involved
diff |= LD_CLLCOUNT;
if (li->sidenum[0] != 0xffff)
{ {
diff = diff2 = 0; si = &sides[li->sidenum[0]];
if (si->textureoffset != SHORT(msd[li->sidenum[0]].textureoffset)<<FRACBITS)
diff |= LD_S1TEXOFF;
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
if (R_CheckTextureNumForName(msd[li->sidenum[0]].toptexture) != -1
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture))
diff |= LD_S1TOPTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[0]].bottomtexture) != -1
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture))
diff |= LD_S1BOTTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[0]].midtexture) != -1
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture))
diff |= LD_S1MIDTEX;
}
if (li->sidenum[1] != 0xffff)
{
si = &sides[li->sidenum[1]];
if (si->textureoffset != SHORT(msd[li->sidenum[1]].textureoffset)<<FRACBITS)
diff2 |= LD_S2TEXOFF;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].toptexture) != -1
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture))
diff2 |= LD_S2TOPTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].bottomtexture) != -1
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture))
diff2 |= LD_S2BOTTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].midtexture) != -1
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture))
diff2 |= LD_S2MIDTEX;
if (diff2)
diff |= LD_DIFF2;
}
if (li->special != SHORT(mld->special)) if (diff)
diff |= LD_SPECIAL; {
statline++;
WRITEINT16(put, i);
WRITEUINT8(put, diff);
if (diff & LD_DIFF2)
WRITEUINT8(put, diff2);
if (diff & LD_FLAG)
WRITEINT16(put, li->flags);
if (diff & LD_SPECIAL)
WRITEINT16(put, li->special);
if (diff & LD_CLLCOUNT)
WRITEINT16(put, li->callcount);
if (SHORT(mld->special) == 321 || SHORT(mld->special) == 322) // only reason li->callcount would be non-zero is if either of these are involved si = &sides[li->sidenum[0]];
diff |= LD_CLLCOUNT; if (diff & LD_S1TEXOFF)
WRITEFIXED(put, si->textureoffset);
if (diff & LD_S1TOPTEX)
WRITEINT32(put, si->toptexture);
if (diff & LD_S1BOTTEX)
WRITEINT32(put, si->bottomtexture);
if (diff & LD_S1MIDTEX)
WRITEINT32(put, si->midtexture);
if (li->sidenum[0] != 0xffff) si = &sides[li->sidenum[1]];
{ if (diff2 & LD_S2TEXOFF)
si = &sides[li->sidenum[0]]; WRITEFIXED(put, si->textureoffset);
if (si->textureoffset != SHORT(msd[li->sidenum[0]].textureoffset)<<FRACBITS) if (diff2 & LD_S2TOPTEX)
diff |= LD_S1TEXOFF; WRITEINT32(put, si->toptexture);
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures. if (diff2 & LD_S2BOTTEX)
if (R_CheckTextureNumForName(msd[li->sidenum[0]].toptexture) != -1 WRITEINT32(put, si->bottomtexture);
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture)) if (diff2 & LD_S2MIDTEX)
diff |= LD_S1TOPTEX; WRITEINT32(put, si->midtexture);
if (R_CheckTextureNumForName(msd[li->sidenum[0]].bottomtexture) != -1
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture))
diff |= LD_S1BOTTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[0]].midtexture) != -1
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture))
diff |= LD_S1MIDTEX;
}
if (li->sidenum[1] != 0xffff)
{
si = &sides[li->sidenum[1]];
if (si->textureoffset != SHORT(msd[li->sidenum[1]].textureoffset)<<FRACBITS)
diff2 |= LD_S2TEXOFF;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].toptexture) != -1
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture))
diff2 |= LD_S2TOPTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].bottomtexture) != -1
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture))
diff2 |= LD_S2BOTTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].midtexture) != -1
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture))
diff2 |= LD_S2MIDTEX;
if (diff2)
diff |= LD_DIFF2;
}
if (diff)
{
statline++;
WRITEINT16(put, i);
WRITEUINT8(put, diff);
if (diff & LD_DIFF2)
WRITEUINT8(put, diff2);
if (diff & LD_FLAG)
WRITEINT16(put, li->flags);
if (diff & LD_SPECIAL)
WRITEINT16(put, li->special);
if (diff & LD_CLLCOUNT)
WRITEINT16(put, li->callcount);
si = &sides[li->sidenum[0]];
if (diff & LD_S1TEXOFF)
WRITEFIXED(put, si->textureoffset);
if (diff & LD_S1TOPTEX)
WRITEINT32(put, si->toptexture);
if (diff & LD_S1BOTTEX)
WRITEINT32(put, si->bottomtexture);
if (diff & LD_S1MIDTEX)
WRITEINT32(put, si->midtexture);
si = &sides[li->sidenum[1]];
if (diff2 & LD_S2TEXOFF)
WRITEFIXED(put, si->textureoffset);
if (diff2 & LD_S2TOPTEX)
WRITEINT32(put, si->toptexture);
if (diff2 & LD_S2BOTTEX)
WRITEINT32(put, si->bottomtexture);
if (diff2 & LD_S2MIDTEX)
WRITEINT32(put, si->midtexture);
}
} }
} }
WRITEUINT16(put, 0xffff); WRITEUINT16(put, 0xffff);

View file

@ -4247,13 +4247,14 @@ DoneSection2:
player->starpostx = player->mo->x>>FRACBITS; player->starpostx = player->mo->x>>FRACBITS;
player->starposty = player->mo->y>>FRACBITS; player->starposty = player->mo->y>>FRACBITS;
player->starpostz = player->mo->floorz>>FRACBITS; player->starpostz = player->mo->floorz>>FRACBITS;
player->kartstuff[k_starpostflip] = player->mo->flags2 & MF2_OBJECTFLIP; // store flipping
player->starpostangle = player->mo->angle; //R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); torn; a momentum-based guess is less likely to be wrong in general, but when it IS wrong, it fucks you over entirely... player->starpostangle = player->mo->angle; //R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); torn; a momentum-based guess is less likely to be wrong in general, but when it IS wrong, it fucks you over entirely...
} }
else else
{ {
// SRB2kart 200117 // SRB2kart 200117
// Reset starposts (checkpoints) info // Reset starposts (checkpoints) info
player->starpostangle = player->starpostx = player->starposty = player->starpostz = 0; player->starpostangle = player->starpostx = player->starposty = player->starpostz = player->kartstuff[k_starpostflip] = 0;
} }
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))

View file

@ -172,7 +172,7 @@ boolean P_AutoPause(void)
if (netgame || modeattacking) if (netgame || modeattacking)
return false; return false;
return (menuactive || window_notinfocus); return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value ));
} }
// //
@ -3634,165 +3634,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) // SRB2kart - unused.
} }
*/ */
#if 0
//
// P_DoSuperStuff()
//
// Handle related superform functionality.
//
static void P_DoSuperStuff(player_t *player)
{
mobj_t *spark;
ticcmd_t *cmd = &player->cmd;
//if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9])
// return; // don't do anything right now, we're in the middle of transforming!
if (player->pflags & PF_NIGHTSMODE)
return; // NiGHTS Super doesn't mix with normal super
// Does player have all emeralds? If so, flag the "Ready For Super!"
/*if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50)
player->pflags |= PF_SUPERREADY;
else
player->pflags &= ~PF_SUPERREADY;*/
if (player->powers[pw_super])
{
// If you're super and not Sonic, de-superize!
if (!((ALL7EMERALDS(emeralds)) && (player->charflags & SF_SUPER)) && !(ALL7EMERALDS(player->powers[pw_emeralds])))
{
player->powers[pw_super] = 0;
P_SetPlayerMobjState(player->mo, S_KART_STND1);
P_RestoreMusic(player);
P_SpawnShieldOrb(player);
// Restore color
if (player->powers[pw_shield] & SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL);
}
if (gametype != GT_COOP)
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
return;
}
// Deplete one ring every second while super
if ((leveltime % TICRATE == 0) && !(player->exiting))
{
player->health--;
player->mo->health--;
}
// future todo: a skin option for this, and possibly more colors
switch (player->skin)
{
case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break;
case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break;
default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break;
}
player->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
{
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
spark->destscale = player->mo->scale;
P_SetScale(spark, player->mo->scale);
}
G_GhostAddColor(GHC_SUPER);
// Ran out of rings while super!
if (player->health <= 1 || player->exiting)
{
player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo);
player->powers[pw_super] = 0;
// Restore color
if (player->powers[pw_shield] & SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL);
}
if (gametype != GT_COOP)
player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
/*
if (player->mo->health > 0)
{
if ((player->pflags & PF_JUMPED) || (player->pflags & PF_SPINNING))
P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
else if (player->panim == PA_RUN)
P_SetPlayerMobjState(player->mo, S_PLAY_SPD1);
else if (player->panim == PA_WALK)
P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
else
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
if (!player->exiting)
{
player->health = 1;
player->mo->health = 1;
}
}
*/
// Inform the netgame that the champion has fallen in the heat of battle.
if (gametype != GT_COOP)
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
// Resume normal music if you're the console player
P_RestoreMusic(player);
// If you had a shield, restore its visual significance.
P_SpawnShieldOrb(player);
}
}
}
#endif
//
// P_SuperReady
//
// Returns true if player is ready to turn super, duh
//
/*boolean P_SuperReady(player_t *player)
{
if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly]
&& !(player->powers[pw_shield] & SH_NOSTACK)
&& !player->powers[pw_invulnerability]
&& !(maptol & TOL_NIGHTS) // don't turn 'regular super' in nights levels
&& player->pflags & PF_JUMPED
&& ((player->charflags & SF_SUPER) || ALL7EMERALDS(player->powers[pw_emeralds])))
return true;
return false;
}*/
// //
// P_DoJump // P_DoJump
// //
@ -6382,99 +6223,6 @@ void P_ElementalFireTrail(player_t *player)
} }
} }
/*static void P_SkidStuff(player_t *player)
{
fixed_t pmx = player->rmomx + player->cmomx;
fixed_t pmy = player->rmomy + player->cmomy;
// Knuckles glides into the dirt.
// SRB2kart - don't need
if (player->pflags & PF_GLIDING && player->skidtime)
{
// Fell off a ledge...
if (!onground)
{
player->skidtime = 0;
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
}
// Get up and brush yourself off, idiot.
else if (player->glidetime > 15)
{
P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
player->mo->momx = player->cmomx;
player->mo->momy = player->cmomy;
}
// Didn't stop yet? Skid FOREVER!
else if (player->skidtime == 1)
player->skidtime = 3*TICRATE+1;
// Spawn a particle every 3 tics.
else if (!(player->skidtime % 3))
{
mobj_t *particle = P_SpawnMobj(player->mo->x + P_RandomRange(-player->mo->radius, player->mo->radius), player->mo->y + P_RandomRange(-player->mo->radius, player->mo->radius),
player->mo->z + (player->mo->eflags & MFE_VERTICALFLIP ? player->mo->height - mobjinfo[MT_PARTICLE].height : 0),
MT_PARTICLE);
particle->tics = 10;
particle->eflags |= player->mo->eflags & MFE_VERTICALFLIP;
P_SetScale(particle, player->mo->scale >> 2);
particle->destscale = player->mo->scale << 2;
particle->scalespeed = FixedMul(particle->scalespeed, player->mo->scale); // scale the scaling speed!
P_SetObjectMomZ(particle, FRACUNIT, false);
S_StartSound(player->mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx.
}
}
// Skidding!
elseif (onground && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID))
{
if (player->skidtime)
{
// Spawn a particle every 3 tics.
if (!(player->skidtime % 3))
{
mobj_t *particle = P_SpawnMobj(player->mo->x, player->mo->y,
player->mo->z + (player->mo->eflags & MFE_VERTICALFLIP ? player->mo->height - mobjinfo[MT_PARTICLE].height : 0),
MT_PARTICLE);
particle->tics = 10;
particle->eflags |= player->mo->eflags & MFE_VERTICALFLIP;
P_SetScale(particle, player->mo->scale >> 2);
particle->destscale = player->mo->scale << 2;
particle->scalespeed = FixedMul(particle->scalespeed, player->mo->scale); // scale the scaling speed!
P_SetObjectMomZ(particle, FRACUNIT, false);
}
}
else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame
&& (player->mo->momx != pmx || player->mo->momy != pmy) // and you are moving differently this frame
&& P_GetPlayerControlDirection(player) == 2) // and your controls are pointing in the opposite direction to your movement
{ // check for skidding
angle_t mang = R_PointToAngle2(0,0,pmx,pmy); // movement angle
angle_t pang = R_PointToAngle2(pmx,pmy,player->mo->momx,player->mo->momy); // push angle
angle_t dang = mang - pang; // delta angle
if (dang > ANGLE_180) // Make delta angle always positive, invert it if it's negative.
dang = InvAngle(dang);
// If your push angle is more than this close to a full 180 degrees, trigger a skid.
if (dang > ANGLE_157h)
{
player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; //player->skidtime = TICRATE/2;
S_StartSound(player->mo, sfx_skid);
if (player->panim != PA_WALK)
P_SetPlayerMobjState(player->mo, S_KART_WALK2); // SRB2kart - was S_PLAY_RUN4
player->mo->tics = player->skidtime;
}
}
}
else {
if (player->skidtime) {
player->skidtime = 0;
S_StopSound(player->mo);
}
}
}*/
// //
// P_MovePlayer // P_MovePlayer
static void P_MovePlayer(player_t *player) static void P_MovePlayer(player_t *player)
@ -7654,12 +7402,14 @@ static void P_NukeAllPlayers(player_t *player)
// //
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
{ {
const fixed_t ns = 60 << FRACBITS; const fixed_t ns = 60 * mapobjectscale;
mobj_t *mo; mobj_t *mo;
angle_t fa; angle_t fa;
thinker_t *think; thinker_t *think;
INT32 i; INT32 i;
radius = FixedMul(radius, mapobjectscale);
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
fa = (i*(FINEANGLES/16)); fa = (i*(FINEANGLES/16));

View file

@ -102,6 +102,8 @@ extern lumpnum_t viewborderlump[8];
// ------------------------------------------------ // ------------------------------------------------
#define GTC_CACHE 1 #define GTC_CACHE 1
#define GTC_MENUCACHE GTC_CACHE
//@TODO Add a separate caching mechanism for menu colormaps distinct from in-level GTC_CACHE. For now this is still preferable to memory leaks...
#define TC_DEFAULT -1 #define TC_DEFAULT -1
#define TC_BOSS -2 #define TC_BOSS -2

View file

@ -870,16 +870,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
#define OVERFLOWTEST(height, scale) \ #define CLAMPMAX INT32_MAX
overflow_test = (INT64)centeryfrac - (((INT64)height*scale)>>FRACBITS); \ #define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
if (overflow_test < 0) overflow_test = -overflow_test; \ // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue; overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test;
else rlight->height = CLAMPMIN;
OVERFLOWTEST(leftheight, ds->scale1) overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
OVERFLOWTEST(rightheight, ds->scale2) if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test;
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); else rlight->heightstep = CLAMPMIN;
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
#else #else
if (light->height < *pfloor->bottomheight) if (light->height < *pfloor->bottomheight)
@ -901,12 +903,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
leftheight -= viewz; leftheight -= viewz;
rightheight -= viewz; rightheight -= viewz;
OVERFLOWTEST(leftheight, ds->scale1) // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
OVERFLOWTEST(rightheight, ds->scale2) overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
#undef OVERFLOWTEST if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test;
else rlight->botheight = CLAMPMIN;
rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1); overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test;
else rlight->botheightstep = CLAMPMIN;
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
#else #else
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
@ -1079,9 +1085,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
} }
#endif #endif
#define CLAMPMAX INT32_MAX
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
// draw the columns // draw the columns
for (dc_x = x1; dc_x <= x2; dc_x++) for (dc_x = x1; dc_x <= x2; dc_x++)
{ {

View file

@ -2542,23 +2542,6 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->kartweight = 5; skin->kartweight = 5;
// //
skin->normalspeed = 36<<FRACBITS;
skin->runspeed = 28<<FRACBITS;
skin->thrustfactor = 5;
skin->accelstart = 96;
skin->acceleration = 40;
skin->ability = CA_NONE;
skin->ability2 = CA2_SPINDASH;
skin->jumpfactor = FRACUNIT;
skin->actionspd = 30<<FRACBITS;
skin->mindash = 15<<FRACBITS;
skin->maxdash = 90<<FRACBITS;
skin->thokitem = -1;
skin->spinitem = -1;
skin->revitem = -1;
skin->highresscale = FRACUNIT>>1; skin->highresscale = FRACUNIT>>1;
for (i = 0; i < sfx_skinsoundslot0; i++) for (i = 0; i < sfx_skinsoundslot0; i++)
@ -2592,7 +2575,7 @@ void R_InitSkins(void)
#ifdef SKINVALUES #ifdef SKINVALUES
skin_cons_t[0].strvalue = skins[0].name; skin_cons_t[0].strvalue = skins[0].name;
#endif #endif
skin->flags = SF_SUPER|SF_SUPERANIMS|SF_SUPERSPIN; skin->flags = 0;
strcpy(skin->realname, "Sonic"); strcpy(skin->realname, "Sonic");
strcpy(skin->hudname, "SONIC"); strcpy(skin->hudname, "SONIC");
@ -2601,20 +2584,11 @@ void R_InitSkins(void)
strncpy(skin->facemmap, "PLAYMMAP", 9); strncpy(skin->facemmap, "PLAYMMAP", 9);
skin->prefcolor = SKINCOLOR_BLUE; skin->prefcolor = SKINCOLOR_BLUE;
skin->ability = CA_THOK;
skin->actionspd = 60<<FRACBITS;
// SRB2kart // SRB2kart
skin->kartspeed = 8; skin->kartspeed = 8;
skin->kartweight = 2; skin->kartweight = 2;
// //
skin->normalspeed = 36<<FRACBITS;
skin->runspeed = 28<<FRACBITS;
skin->thrustfactor = 5;
skin->accelstart = 96;
skin->acceleration = 40;
skin->spritedef.numframes = sprites[SPR_PLAY].numframes; skin->spritedef.numframes = sprites[SPR_PLAY].numframes;
skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes; skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes;
ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, 0); ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, 0);
@ -2715,31 +2689,12 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (player->mo) if (player->mo)
player->mo->skin = skin; player->mo->skin = skin;
player->charability = (UINT8)skin->ability;
player->charability2 = (UINT8)skin->ability2;
player->charflags = (UINT32)skin->flags; player->charflags = (UINT32)skin->flags;
player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
player->actionspd = skin->actionspd;
player->mindash = skin->mindash;
player->maxdash = skin->maxdash;
// SRB2kart // SRB2kart
player->kartspeed = skin->kartspeed; player->kartspeed = skin->kartspeed;
player->kartweight = skin->kartweight; player->kartweight = skin->kartweight;
player->normalspeed = skin->normalspeed;
player->runspeed = skin->runspeed;
player->thrustfactor = skin->thrustfactor;
player->accelstart = skin->accelstart;
player->acceleration = skin->acceleration;
player->jumpfactor = skin->jumpfactor;
/*if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback || modeattacking)) /*if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback || modeattacking))
{ {
if (playernum == consoleplayer) if (playernum == consoleplayer)
@ -2968,28 +2923,8 @@ void R_AddSkins(UINT16 wadnum)
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); #define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
// character type identification // character type identification
FULLPROCESS(flags) FULLPROCESS(flags)
//FULLPROCESS(ability)
//FULLPROCESS(ability2)
//FULLPROCESS(thokitem)
//FULLPROCESS(spinitem)
//FULLPROCESS(revitem)
#undef FULLPROCESS #undef FULLPROCESS
#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
//GETSPEED(normalspeed)
GETSPEED(runspeed)
//GETSPEED(mindash)
//GETSPEED(maxdash)
//GETSPEED(actionspd)
#undef GETSPEED
/*#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
GETINT(thrustfactor)
GETINT(accelstart)
GETINT(acceleration)
#undef GETINT*/
#define GETKARTSTAT(field) \ #define GETKARTSTAT(field) \
else if (!stricmp(stoken, #field)) \ else if (!stricmp(stoken, #field)) \
{ \ { \
@ -3007,8 +2942,6 @@ void R_AddSkins(UINT16 wadnum)
else if (!stricmp(stoken, "prefcolor")) else if (!stricmp(stoken, "prefcolor"))
skin->prefcolor = K_GetKartColorByName(value); skin->prefcolor = K_GetKartColorByName(value);
//else if (!stricmp(stoken, "jumpfactor"))
//skin->jumpfactor = FLOAT_TO_FIXED(atof(value));
else if (!stricmp(stoken, "highresscale")) else if (!stricmp(stoken, "highresscale"))
skin->highresscale = FLOAT_TO_FIXED(atof(value)); skin->highresscale = FLOAT_TO_FIXED(atof(value));
else else
@ -3118,9 +3051,6 @@ next_token:
HWR_AddPlayerMD2(numskins); HWR_AddPlayerMD2(numskins);
#endif #endif
if (skin->flags & SF_RUNONWATER) // this is literally the only way a skin can be a major mod... this might be a bit heavy handed
G_SetGameModified(multiplayer, true);
numskins++; numskins++;
} }
return; return;

View file

@ -83,29 +83,11 @@ typedef struct
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long) char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps
UINT8 ability; // ability definition
UINT8 ability2; // secondary ability definition
INT32 thokitem;
INT32 spinitem;
INT32 revitem;
fixed_t actionspd;
fixed_t mindash;
fixed_t maxdash;
// SRB2kart // SRB2kart
UINT8 kartspeed; UINT8 kartspeed;
UINT8 kartweight; UINT8 kartweight;
// //
fixed_t normalspeed; // Normal ground
fixed_t runspeed; // Speed that you break into your run animation
UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
UINT8 accelstart; // Acceleration if speed = 0
UINT8 acceleration; // Acceleration
fixed_t jumpfactor; // multiple of standard jump height
// Definable color translation table // Definable color translation table
UINT8 starttranscolor; UINT8 starttranscolor;
UINT8 prefcolor; UINT8 prefcolor;

View file

@ -57,6 +57,9 @@ static void GameMIDIMusic_OnChange(void);
static void GameSounds_OnChange(void); static void GameSounds_OnChange(void);
static void GameDigiMusic_OnChange(void); static void GameDigiMusic_OnChange(void);
static void PlayMusicIfUnfocused_OnChange(void);
static void PlaySoundIfUnfocused_OnChange(void);
// commands for music and sound servers // commands for music and sound servers
#ifdef MUSSERV #ifdef MUSSERV
consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -110,6 +113,9 @@ consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O
#endif #endif
consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlayMusicIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlaySoundIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL};
#define S_MAX_VOLUME 127 #define S_MAX_VOLUME 127
// when to clip out sounds // when to clip out sounds
@ -270,6 +276,9 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&cv_gamemidimusic); CV_RegisterVar(&cv_gamemidimusic);
#endif #endif
CV_RegisterVar(&cv_playmusicifunfocused);
CV_RegisterVar(&cv_playsoundifunfocused);
COM_AddCommand("tunes", Command_Tunes_f); COM_AddCommand("tunes", Command_Tunes_f);
COM_AddCommand("restartaudio", Command_RestartAudio_f); COM_AddCommand("restartaudio", Command_RestartAudio_f);
@ -1897,6 +1906,10 @@ static boolean S_PlayMusic(boolean looping)
} }
S_InitMusicVolume(); // switch between digi and sequence volume S_InitMusicVolume(); // switch between digi and sequence volume
if (window_notinfocus && !cv_playmusicifunfocused.value)
I_PauseSong();
return true; return true;
} }
@ -1978,6 +1991,24 @@ void S_ResumeAudio(void)
I_ResumeCD(); I_ResumeCD();
} }
void S_DisableSound(void)
{
if (sound_started && !sound_disabled)
{
sound_disabled = true;
S_StopSounds();
}
}
void S_EnableSound(void)
{
if (sound_started && sound_disabled)
{
sound_disabled = false;
S_InitSfxChannels(cv_soundvolume.value);
}
}
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
{ {
if (digvolume < 0) if (digvolume < 0)
@ -2156,15 +2187,11 @@ void GameSounds_OnChange(void)
if (sound_disabled) if (sound_disabled)
{ {
sound_disabled = false; if (!( cv_playsoundifunfocused.value && window_notinfocus ))
S_InitSfxChannels(cv_soundvolume.value); S_EnableSound();
S_StartSound(NULL, sfx_strpst);
} }
else else
{ S_DisableSound();
sound_disabled = true;
S_StopSounds();
}
} }
void GameDigiMusic_OnChange(void) void GameDigiMusic_OnChange(void)
@ -2251,3 +2278,28 @@ void GameMIDIMusic_OnChange(void)
} }
} }
#endif #endif
static void PlayMusicIfUnfocused_OnChange(void)
{
if (window_notinfocus)
{
if (cv_playmusicifunfocused.value)
I_PauseSong();
else
I_ResumeSong();
}
}
static void PlaySoundIfUnfocused_OnChange(void)
{
if (!cv_gamesounds.value)
return;
if (window_notinfocus)
{
if (cv_playsoundifunfocused.value)
S_DisableSound();
else
S_EnableSound();
}
}

View file

@ -33,6 +33,8 @@ extern consvar_t cv_gamedigimusic;
extern consvar_t cv_gamemidimusic; extern consvar_t cv_gamemidimusic;
#endif #endif
extern consvar_t cv_gamesounds; extern consvar_t cv_gamesounds;
extern consvar_t cv_playmusicifunfocused;
extern consvar_t cv_playsoundifunfocused;
#ifdef SNDSERV #ifdef SNDSERV
extern consvar_t sndserver_cmd, sndserver_arg; extern consvar_t sndserver_cmd, sndserver_arg;
@ -169,6 +171,10 @@ void S_StopMusic(void);
void S_PauseAudio(void); void S_PauseAudio(void);
void S_ResumeAudio(void); void S_ResumeAudio(void);
// Enable and disable sound effects
void S_EnableSound(void);
void S_DisableSound(void);
// //
// Updates music & sounds // Updates music & sounds
// //

View file

@ -615,9 +615,13 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{ {
// Tell game we got focus back, resume music if necessary // Tell game we got focus back, resume music if necessary
window_notinfocus = false; window_notinfocus = false;
if (!paused) if (!paused)
I_ResumeSong(); //resume it I_ResumeSong(); //resume it
if (cv_gamesounds.value)
S_EnableSound();
if (!firsttimeonmouse) if (!firsttimeonmouse)
{ {
if (cv_usemouse.value) I_StartupMouse(); if (cv_usemouse.value) I_StartupMouse();
@ -630,7 +634,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{ {
// Tell game we lost focus, pause music // Tell game we lost focus, pause music
window_notinfocus = true; window_notinfocus = true;
I_PauseSong(); if (!cv_playmusicifunfocused.value)
I_PauseSong();
if (!cv_playsoundifunfocused.value)
S_DisableSound();
if (!disable_mouse) if (!disable_mouse)
{ {
@ -1327,6 +1334,7 @@ void I_UpdateNoBlit(void)
// from PrBoom's src/SDL/i_video.c // from PrBoom's src/SDL/i_video.c
static inline boolean I_SkipFrame(void) static inline boolean I_SkipFrame(void)
{ {
#if 0
static boolean skip = false; static boolean skip = false;
if (rendermode != render_soft) if (rendermode != render_soft)
@ -1345,6 +1353,8 @@ static inline boolean I_SkipFrame(void)
default: default:
return false; return false;
} }
#endif
return false;
} }
// //

View file

@ -106,7 +106,7 @@ static UINT16 lumpnumcacheindex = 0;
//=========================================================================== //===========================================================================
// GLOBALS // GLOBALS
//=========================================================================== //===========================================================================
UINT16 numwadfiles; // number of active wadfiles UINT16 numwadfiles = 0; // number of active wadfiles
wadfile_t *wadfiles[MAX_WADFILES]; // 0 to numwadfiles-1 are valid wadfile_t *wadfiles[MAX_WADFILES]; // 0 to numwadfiles-1 are valid
// W_Shutdown // W_Shutdown
@ -855,16 +855,16 @@ void W_UnloadWadFile(UINT16 num)
* \return 1 if all files were loaded, 0 if at least one was missing or * \return 1 if all files were loaded, 0 if at least one was missing or
* invalid. * invalid.
*/ */
INT32 W_InitMultipleFiles(char **filenames) INT32 W_InitMultipleFiles(char **filenames, boolean addons)
{ {
INT32 rc = 1; INT32 rc = 1;
// open all the files, load headers, and count lumps
numwadfiles = 0;
// will be realloced as lumps are added // will be realloced as lumps are added
for (; *filenames; filenames++) for (; *filenames; filenames++)
{ {
if (addons && !W_VerifyNMUSlumps(*filenames))
G_SetGameModified(true, false);
//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames); //CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
rc &= (W_InitFile(*filenames) != INT16_MAX) ? 1 : 0; rc &= (W_InitFile(*filenames) != INT16_MAX) ? 1 : 0;
} }
@ -1187,23 +1187,17 @@ void zerr(int ret)
#define NO_PNG_LUMPS #define NO_PNG_LUMPS
#ifdef NO_PNG_LUMPS #ifdef NO_PNG_LUMPS
static void ErrorIfPNG(void *d, size_t s, char *f, char *l) static void ErrorIfPNG(UINT8 *d, size_t s, char *f, char *l)
{ {
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/ if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
return; return;
#define sigcheck ((UINT8 *)d) // Check for PNG file signature using memcmp
if (sigcheck[0] == 0x89 // As it may be faster on CPUs with slow unaligned memory access
&& sigcheck[1] == 0x50 // Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
&& sigcheck[2] == 0x4e if (memcmp(&d[0], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
&& sigcheck[3] == 0x47
&& sigcheck[4] == 0x0d
&& sigcheck[5] == 0x0a
&& sigcheck[6] == 0x1a
&& sigcheck[7] == 0x0a)
{ {
I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .PNG - please convert to either Doom or Flat (raw) image format.", l, f); I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .PNG - please convert to either Doom or Flat (raw) image format.", l, f);
} }
#undef sigcheck
} }
#endif #endif
@ -1297,6 +1291,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
//I_Error("ZWAD files not supported on this platform."); //I_Error("ZWAD files not supported on this platform.");
return 0; return 0;
#endif #endif
} }
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support. case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
@ -1556,7 +1551,6 @@ void *W_CachePatchName(const char *name, INT32 tag)
return W_CachePatchNum(num, tag); return W_CachePatchNum(num, tag);
} }
#ifndef NOMD5 #ifndef NOMD5
#define MD5_LEN 16
/** /**
* Prints an MD5 string into a human-readable textual format. * Prints an MD5 string into a human-readable textual format.

View file

@ -133,7 +133,7 @@ void W_UnloadWadFile(UINT16 num);
// W_InitMultipleFiles returns 1 if all is okay, 0 otherwise, // W_InitMultipleFiles returns 1 if all is okay, 0 otherwise,
// so that it stops with a message if a file was not found, but not if all is okay. // so that it stops with a message if a file was not found, but not if all is okay.
INT32 W_InitMultipleFiles(char **filenames); INT32 W_InitMultipleFiles(char **filenames, boolean addons);
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
const char *W_CheckNameForNum(lumpnum_t lumpnum); const char *W_CheckNameForNum(lumpnum_t lumpnum);