Merge branch 'next' into md3-vanilla-kart
# Conflicts: # src/hardware/r_opengl/r_opengl.c
This commit is contained in:
commit
6b743d383b
|
@ -36,12 +36,15 @@ jobs:
|
|||
- v1-SRB2-APT
|
||||
- run:
|
||||
name: Install SDK
|
||||
command: apt-get -qq -y install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx
|
||||
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
|
||||
- save_cache:
|
||||
key: v1-SRB2-APT
|
||||
paths:
|
||||
- /var/cache/apt/archives
|
||||
- checkout
|
||||
- run:
|
||||
name: Compile without network support
|
||||
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1
|
||||
- run:
|
||||
name: Clean build
|
||||
command: make -C src LINUX=1 clean
|
||||
|
|
|
@ -26,6 +26,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- 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.*$/
|
||||
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
|
||||
- os: linux
|
||||
|
@ -39,6 +40,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- 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.*$/
|
||||
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
|
||||
- os: linux
|
||||
|
@ -52,10 +54,12 @@ matrix:
|
|||
- p7zip-full
|
||||
- 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.*$/
|
||||
#gcc-4.7
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: GCC48=1
|
||||
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
|
||||
- os: linux
|
||||
|
@ -71,6 +75,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- 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.*$/
|
||||
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
|
||||
- os: linux
|
||||
|
@ -86,7 +91,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- 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.*$/
|
||||
#gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
|
||||
- os: linux
|
||||
|
@ -102,7 +107,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- 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.*$/
|
||||
#gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
|
||||
- os: linux
|
||||
|
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
|||
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
|
||||
# Version change is fine.
|
||||
project(SRB2
|
||||
VERSION 1.0.2
|
||||
VERSION 1.0.4
|
||||
LANGUAGES C)
|
||||
|
||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||
|
|
4
SRB2.cbp
4
SRB2.cbp
|
@ -1545,6 +1545,10 @@ HW3SOUND for 3D hardware sound support
|
|||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/info.h" />
|
||||
<Unit filename="src/k_kart.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/k_kart.h" />
|
||||
<Unit filename="src/keys.h" />
|
||||
<Unit filename="src/lua_baselib.c">
|
||||
<Option compilerVar="CC" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: 1.0.2.{branch}-{build}
|
||||
version: 1.0.4.{branch}-{build}
|
||||
os: MinGW
|
||||
|
||||
environment:
|
||||
|
@ -29,7 +29,7 @@ environment:
|
|||
##############################
|
||||
DPL_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.
|
||||
# Include the README files and the OpenGL batch in the main and patch archives.
|
||||
# The x86/x64 archives contain the DLL binaries.
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -4,7 +4,7 @@ project(libgme)
|
|||
include (CheckCXXCompilerFlag)
|
||||
|
||||
# When version is changed, also change the one in gme/gme.h to match
|
||||
set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version")
|
||||
set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
|
||||
|
||||
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
|
||||
# Of course, 2.4 might work, in which case you're welcome to drop
|
||||
|
@ -57,6 +57,8 @@ if (USE_GME_NSFE AND NOT USE_GME_NSF)
|
|||
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
|
||||
endif()
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
|
||||
|
||||
# Check for GCC "visibility" support.
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
|
||||
|
@ -79,10 +81,10 @@ if (CMAKE_COMPILER_IS_GNUCXX)
|
|||
endif()
|
||||
endif()
|
||||
endif() # test visibility
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# Cache this result
|
||||
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# Shared library defined here
|
||||
add_subdirectory(gme)
|
||||
|
|
|
@ -1,262 +1,5 @@
|
|||
Game_Music_Emu Change Log
|
||||
-------------------------
|
||||
|
||||
Game_Music_Emu 0.6.0
|
||||
--------------------
|
||||
|
||||
- Note: A 0.5.6 release was referenced but never tagged or packaged.
|
||||
|
||||
- SPC improvements:
|
||||
- Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP.
|
||||
- Fixed Spc_Emu::gain().
|
||||
- Fixed support for files <0x10200 bytes.
|
||||
|
||||
- Other bugfixes:
|
||||
- Fixed a couple of GBS bugs, one involving access of memory after
|
||||
realloc.
|
||||
- Blip_Buffer works on systems where 'double' is a single-precision
|
||||
floating-point type.
|
||||
- Fix uninitialized buffer size in dual_resampler.
|
||||
- Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2.
|
||||
|
||||
- API changes/additions:
|
||||
- Removed documentation of C++ interface, as the C interface in gme.h is
|
||||
the only supported one.
|
||||
- Added gme_enable_accuracy() for enabling more accurate sound emulation
|
||||
options (currently affects SPC only).
|
||||
|
||||
- Build system improvements:
|
||||
- Add pkg_config support.
|
||||
- Fix build on case-insensitive systems.
|
||||
- Allow for install on Cygwin.
|
||||
- Fix install on multilib systems, such as many 64-bit distros (CMake must
|
||||
be able to figure out your system's libsuffix, if any).
|
||||
- C++ implementation symbols are not leaked into the resultant library
|
||||
file (requires symbol visibility support).
|
||||
|
||||
- Sample player improvements:
|
||||
- Can toggle fast/accurate emulation (with the 'A' key).
|
||||
|
||||
Game_Music_Emu 0.5.5
|
||||
--------------------
|
||||
- CMake build support has been added. You can build Game_Music_Emu as
|
||||
a shared library and install it so that you do not have to include your
|
||||
own copy if you know libgme will be present on your target system.
|
||||
Requires CMake 2.6 or higher.
|
||||
|
||||
|
||||
Game_Music_Emu 0.5.2
|
||||
--------------------
|
||||
- *TONS* of changes and improvements. You should re-read the new header
|
||||
files and documentation as the changes will allow you to simplify your
|
||||
code a lot (it might even be simpler to just rewrite it). Existing code
|
||||
should continue to work without changes in most cases (see Deprecated
|
||||
features in gme.txt).
|
||||
|
||||
- New file formats: AY, HES, KSS, SAP, NSFE
|
||||
|
||||
- All-new comprehensive C interface (also usable from C++). Simplifies
|
||||
many things, especially file loading, and brings everything together in
|
||||
one header file (gme.h).
|
||||
|
||||
- Information tags and track names and times can be accessed for all
|
||||
game music formats
|
||||
|
||||
- New features supported by all emulators: end of track fading,
|
||||
automatic silence detection, adjustable song tempo, seek to new time in
|
||||
track
|
||||
|
||||
- Updated mini player example to support track names and times, echo,
|
||||
tempo, and channel muting, and added visual waveform display
|
||||
|
||||
- Improved configuration to use blargg_config.h, which you can modify
|
||||
and keep when you update to a newer libary version. Includes flag for
|
||||
library to automatically handle gzipped files using zlib (so you don't
|
||||
need to use Gzip_File_Reader anymore).
|
||||
|
||||
- GBS: Fixed wave channel to not reset waveform when APU is powered off
|
||||
(affected Garfield). Also improved invalid bank selection (affected Game
|
||||
& Watch and others).
|
||||
|
||||
- VGM: Added support for alternate noise shifter register
|
||||
configurations, used by other systems like the BBC Micro.
|
||||
|
||||
- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
|
||||
scanned needed it, and an SPC file can include a copy if necessary. Also
|
||||
re-enabled supposed clamping in gaussian interpolation between the third
|
||||
and fourth lookups, though I don't know whether it matters
|
||||
|
||||
- Added Music_Emu::load_mem() to use music data already in memory
|
||||
(without copying it)
|
||||
|
||||
- Added Music_Emu::warning(), which reports minor problems when loading
|
||||
and playing a music file
|
||||
|
||||
- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
|
||||
be set during initialization, so not useful as a general volume control.
|
||||
|
||||
- Added custom operator new to ensure that no exceptions are thrown in
|
||||
the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
|
||||
|
||||
- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
|
||||
bandlimited synthesis in "classic" emulators, which might help
|
||||
performance on ancient processors (measure first!). Don't use this
|
||||
unless absolutely necessary, as quality suffers.
|
||||
|
||||
- Improved performance a bit for x86 platforms
|
||||
|
||||
- Text files now in DOS newline format so they will open in Notepad
|
||||
properly
|
||||
|
||||
- Removed requirement that file header structures not have any padding
|
||||
added to the end
|
||||
|
||||
- Fixed common bug in all CPU emulators where negative program counter
|
||||
could crash emulator (occurred during a negative branch from the
|
||||
beginning of memory). Also fixed related bug in Z80 emulator for
|
||||
IX/IY+displacement mode.
|
||||
|
||||
- Eliminated all warnings when compiling on gcc 4.0. The following
|
||||
generates no diagnostics:
|
||||
|
||||
gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
|
||||
-fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
|
||||
-Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
|
||||
-Winline -Wlong-long -Wmultichar -Winvalid-offsetof
|
||||
-Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
|
||||
-Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
|
||||
-Wsign-promo -Wunknown-pragmas -Wwrite-strings
|
||||
|
||||
|
||||
Game_Music_Emu 0.3.0
|
||||
--------------------
|
||||
- Added more demos, including music player using the SDL multimedia
|
||||
library for sound, and improved documentation
|
||||
|
||||
- All: Improved interface to emulators to allow simpler setup and
|
||||
loading. Instead of various init() functions, all now support
|
||||
set_sample_rate( long rate ) and load( const char* file_path ).
|
||||
|
||||
- All: Removed error return from start_track() and play(), and added
|
||||
error_count() to get the total number of emulation errors since the
|
||||
track was last started. See demos for examples of new usage.
|
||||
|
||||
- All: Fixed mute_voices() muting to be preserved after loading files
|
||||
and starting tracks, instead of being cleared as it was whenever a track
|
||||
was started
|
||||
|
||||
- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
|
||||
any sample rate with optional FM oversampling, support for alternate
|
||||
YM2612 sound cores, and support for optional YM2413
|
||||
|
||||
- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
|
||||
music to 50Hz PAL
|
||||
|
||||
- VGM: Removed Vgm_Emu::track_data(), since I realized that this
|
||||
information is already present in the VGM header (oops!)
|
||||
|
||||
- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
|
||||
|
||||
- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
|
||||
soundtrack
|
||||
|
||||
- NSF: Fixed Namco 106 problems with Final Lap and others
|
||||
|
||||
- Moved library sources to gme/ directory to reduce clutter, and merged
|
||||
boost/ functionality into blargg_common.h
|
||||
|
||||
- Added Gzip_File_Reader for transparently using gzipped files
|
||||
|
||||
|
||||
Game_Music_Emu 0.2.4
|
||||
--------------------
|
||||
- Created a discussion forum for problems and feedback:
|
||||
http://groups-beta.google.com/group/blargg-sound-libs
|
||||
|
||||
- Changed error return value of Blip_Buffer::sample_rate() (also for
|
||||
Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
|
||||
blargg_common.h), to make error reporting consistent with other
|
||||
functions. This means the "no error" return value is the opposite of
|
||||
what it was before, which will break current code which checks the error
|
||||
return value:
|
||||
|
||||
// current code (broken)
|
||||
if ( !buf.sample_rate( samples_per_sec ) )
|
||||
out_of_memory();
|
||||
|
||||
// quick-and-dirty fix (just remove the ! operation)
|
||||
if ( buf.sample_rate( samples_per_sec ) )
|
||||
out_of_memory();
|
||||
|
||||
// proper fix
|
||||
blargg_err_t error = buf.sample_rate( samples_per_sec );
|
||||
if ( error )
|
||||
report_error( error );
|
||||
|
||||
- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
|
||||
to work on that compiler again
|
||||
|
||||
- Added sample clamping to avoid wrap-around at high volumes, allowing
|
||||
higher volume with little distortion
|
||||
|
||||
- Added to-do list and design notes
|
||||
|
||||
- Added Music_Emu::skip( long sample_count ) to skip ahead in current
|
||||
track
|
||||
|
||||
- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
|
||||
determining the length of non-looped GYM and VGM files
|
||||
|
||||
- Partially implemented DMC non-linearity when its value is directly set
|
||||
using $4011, which reduces previously over-emphasized "popping" of
|
||||
percussion on some games (TMNT II in particular)
|
||||
|
||||
- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
|
||||
using abs() instead of fabs()...argh)
|
||||
|
||||
- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
|
||||
now stops sample slightly earlier than the end, as the SNES does. Fixed
|
||||
a totally broken CPU addressing mode.
|
||||
|
||||
- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
|
||||
sounds decent
|
||||
|
||||
- Fixed a minor GBS emulation bug
|
||||
|
||||
- Fixed GYM loop point bug when track was restarted before loop point
|
||||
had been reached
|
||||
|
||||
- Made default GBS frequency equalization less muffled
|
||||
|
||||
- Added pseudo-surround effect removal for SPC files
|
||||
|
||||
- Added Music_Emu::voice_names() which returns names for each voice.
|
||||
|
||||
- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
|
||||
easily set for library sources
|
||||
|
||||
- Changed assignment of expansion sound chips in Nsf_Emu to be spread
|
||||
more evenly when using Effects_Buffer
|
||||
|
||||
- Changed 'size_t' values in Blip_Buffer interface to 'long'
|
||||
|
||||
- Changed demo to generate a WAVE sound file rather than an AIFF file
|
||||
|
||||
|
||||
Game_Music_Emu 0.2.0
|
||||
--------------------
|
||||
- Redid framework and rewrote/cleaned up emulators
|
||||
|
||||
- Changed licensing to GNU Lesser General Public License (LGPL)
|
||||
|
||||
- Added Sega Genesis GYM and Super Nintendo SPC emulators
|
||||
|
||||
- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
|
||||
|
||||
- Eliminated use of static mutable data in emulators, allowing
|
||||
multi-instance safety
|
||||
|
||||
|
||||
Game_Music_Emu 0.1.0
|
||||
--------------------
|
||||
- First release
|
||||
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
|
||||
for the accurate change log.
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
/* C example that opens a game music file and records 10 seconds to "out.wav" */
|
||||
|
||||
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
|
||||
|
||||
#include "gme/gme.h"
|
||||
|
||||
#include "Wave_Writer.h" /* wave_ functions for writing sound file */
|
||||
|
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
|
|||
|
||||
void handle_error( const char* str );
|
||||
|
||||
int main()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *filename = "test.nsf"; /* Default file to open */
|
||||
if ( argc >= 2 )
|
||||
filename = argv[1];
|
||||
|
||||
long sample_rate = 44100; /* number of samples per second */
|
||||
int track = 0; /* index of track to play (0 = first) */
|
||||
/* index of track to play (0 = first) */
|
||||
int track = argc >= 3 ? atoi(argv[2]) : 0;
|
||||
|
||||
/* Open music file in new emulator */
|
||||
Music_Emu* emu;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// C++ example that opens a game music file and records 10 seconds to "out.wav"
|
||||
|
||||
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
|
||||
|
||||
#include "gme/Music_Emu.h"
|
||||
|
||||
#include "Wave_Writer.h"
|
||||
|
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
|
|||
|
||||
void handle_error( const char* str );
|
||||
|
||||
int main()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *filename = "test.nsf"; /* Default file to open */
|
||||
if ( argc >= 2 )
|
||||
filename = argv[1];
|
||||
|
||||
long sample_rate = 44100; // number of samples per second
|
||||
int track = 0; // index of track to play (0 = first)
|
||||
// index of track to play (0 = first)
|
||||
int track = argc >= 3 ? atoi(argv[2]) : 0;
|
||||
|
||||
// Determine file type
|
||||
gme_type_t file_type;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Game_Music_Emu 0.6.0
|
||||
Game_Music_Emu 0.6.2
|
||||
--------------------
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Website: http://www.slack.net/~ant/libs/
|
||||
Forum : http://groups.google.com/group/blargg-sound-libs
|
||||
Source : https://code.google.com/p/game-music-emu/
|
||||
License: GNU Lesser General Public License (LGPL)
|
||||
Maintainer : Michael Pyne <mpyne@purinchu.net>
|
||||
Website : https://bitbucket.org/mpyne/game-music-emu/
|
||||
Source : https://bitbucket.org/mpyne/game-music-emu/
|
||||
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
|
|
@ -143,7 +143,7 @@ add_definitions(-DBLARGG_BUILD_DLL)
|
|||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Add library to be compiled.
|
||||
add_library(gme SHARED ${libgme_SRCS})
|
||||
add_library(gme ${libgme_SRCS})
|
||||
|
||||
# The version is the release. The "soversion" is the API version. As long
|
||||
# as only build fixes are performed (i.e. no backwards-incompatible changes
|
||||
|
@ -159,4 +159,4 @@ install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
|
|||
ARCHIVE DESTINATION lib) # DLL platforms
|
||||
|
||||
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib/pkgconfig)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)
|
||||
|
|
|
@ -22,8 +22,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
const char Data_Reader::eof_error [] = "Unexpected end of file";
|
||||
|
||||
#define RETURN_VALIDITY_CHECK( cond ) \
|
||||
do { if ( unlikely( !(cond) ) ) return "Corrupt file"; } while(0)
|
||||
|
||||
blargg_err_t Data_Reader::read( void* p, long s )
|
||||
{
|
||||
RETURN_VALIDITY_CHECK( s > 0 );
|
||||
|
||||
long result = read_avail( p, s );
|
||||
if ( result != s )
|
||||
{
|
||||
|
@ -38,6 +43,8 @@ blargg_err_t Data_Reader::read( void* p, long s )
|
|||
|
||||
blargg_err_t Data_Reader::skip( long count )
|
||||
{
|
||||
RETURN_VALIDITY_CHECK( count >= 0 );
|
||||
|
||||
char buf [512];
|
||||
while ( count )
|
||||
{
|
||||
|
@ -54,7 +61,8 @@ long File_Reader::remain() const { return size() - tell(); }
|
|||
|
||||
blargg_err_t File_Reader::skip( long n )
|
||||
{
|
||||
assert( n >= 0 );
|
||||
RETURN_VALIDITY_CHECK( n >= 0 );
|
||||
|
||||
if ( !n )
|
||||
return 0;
|
||||
return seek( tell() + n );
|
||||
|
@ -67,13 +75,14 @@ Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
|
|||
in = dr;
|
||||
remain_ = dr->remain();
|
||||
if ( remain_ > size )
|
||||
remain_ = size;
|
||||
remain_ = max( 0l, size );
|
||||
}
|
||||
|
||||
long Subset_Reader::remain() const { return remain_; }
|
||||
|
||||
long Subset_Reader::read_avail( void* p, long s )
|
||||
{
|
||||
s = max( 0l, s );
|
||||
if ( s > remain_ )
|
||||
s = remain_;
|
||||
remain_ -= s;
|
||||
|
@ -85,7 +94,7 @@ long Subset_Reader::read_avail( void* p, long s )
|
|||
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
|
||||
{
|
||||
header = (char const*) h;
|
||||
header_end = header + size;
|
||||
header_end = header + max( 0l, size );
|
||||
in = r;
|
||||
}
|
||||
|
||||
|
@ -93,6 +102,7 @@ long Remaining_Reader::remain() const { return header_end - header + in->remain(
|
|||
|
||||
long Remaining_Reader::read_first( void* out, long count )
|
||||
{
|
||||
count = max( 0l, count );
|
||||
long first = header_end - header;
|
||||
if ( first )
|
||||
{
|
||||
|
@ -107,8 +117,9 @@ long Remaining_Reader::read_first( void* out, long count )
|
|||
|
||||
long Remaining_Reader::read_avail( void* out, long count )
|
||||
{
|
||||
count = max( 0l, count );
|
||||
long first = read_first( out, count );
|
||||
long second = count - first;
|
||||
long second = max( 0l, count - first );
|
||||
if ( second )
|
||||
{
|
||||
second = in->read_avail( (char*) out + first, second );
|
||||
|
@ -120,8 +131,9 @@ long Remaining_Reader::read_avail( void* out, long count )
|
|||
|
||||
blargg_err_t Remaining_Reader::read( void* out, long count )
|
||||
{
|
||||
count = max( 0l, count );
|
||||
long first = read_first( out, count );
|
||||
long second = count - first;
|
||||
long second = max( 0l, count - first );
|
||||
if ( !second )
|
||||
return 0;
|
||||
return in->read( (char*) out + first, second );
|
||||
|
@ -131,7 +143,7 @@ blargg_err_t Remaining_Reader::read( void* out, long count )
|
|||
|
||||
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
|
||||
begin( (const char*) p ),
|
||||
size_( s )
|
||||
size_( max( 0l, s ) )
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
|
@ -141,6 +153,7 @@ long Mem_File_Reader::size() const { return size_; }
|
|||
long Mem_File_Reader::read_avail( void* p, long s )
|
||||
{
|
||||
long r = remain();
|
||||
s = max( 0l, s );
|
||||
if ( s > r )
|
||||
s = r;
|
||||
memcpy( p, begin + pos, s );
|
||||
|
@ -152,6 +165,7 @@ long Mem_File_Reader::tell() const { return pos; }
|
|||
|
||||
blargg_err_t Mem_File_Reader::seek( long n )
|
||||
{
|
||||
RETURN_VALIDITY_CHECK( n >= 0 );
|
||||
if ( n > size_ )
|
||||
return eof_error;
|
||||
pos = n;
|
||||
|
@ -164,7 +178,7 @@ Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
|
|||
callback( c ),
|
||||
data( d )
|
||||
{
|
||||
remain_ = size;
|
||||
remain_ = max( 0l, size );
|
||||
}
|
||||
|
||||
long Callback_Reader::remain() const { return remain_; }
|
||||
|
@ -173,13 +187,14 @@ long Callback_Reader::read_avail( void* out, long count )
|
|||
{
|
||||
if ( count > remain_ )
|
||||
count = remain_;
|
||||
if ( Callback_Reader::read( out, count ) )
|
||||
if ( count < 0 || Callback_Reader::read( out, count ) )
|
||||
count = -1;
|
||||
return count;
|
||||
}
|
||||
|
||||
blargg_err_t Callback_Reader::read( void* out, long count )
|
||||
{
|
||||
RETURN_VALIDITY_CHECK( count >= 0 );
|
||||
if ( count > remain_ )
|
||||
return eof_error;
|
||||
return callback( data, out, count );
|
||||
|
@ -210,11 +225,12 @@ long Std_File_Reader::size() const
|
|||
|
||||
long Std_File_Reader::read_avail( void* p, long s )
|
||||
{
|
||||
return fread( p, 1, s, (FILE*) file_ );
|
||||
return fread( p, 1, max( 0l, s ), (FILE*) file_ );
|
||||
}
|
||||
|
||||
blargg_err_t Std_File_Reader::read( void* p, long s )
|
||||
{
|
||||
RETURN_VALIDITY_CHECK( s > 0 );
|
||||
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
|
||||
return 0;
|
||||
if ( feof( (FILE*) file_ ) )
|
||||
|
|
|
@ -129,6 +129,8 @@ private:
|
|||
};
|
||||
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <zlib.h>
|
||||
|
||||
// Gzip compressed file reader
|
||||
class Gzip_File_Reader : public File_Reader {
|
||||
public:
|
||||
|
@ -143,7 +145,7 @@ public:
|
|||
long tell() const;
|
||||
blargg_err_t seek( long );
|
||||
private:
|
||||
void* file_;
|
||||
gzFile file_;
|
||||
long size_;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -178,6 +178,11 @@ blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
|
|||
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
|
||||
}
|
||||
|
||||
long Music_Emu::tell_samples() const
|
||||
{
|
||||
return out_time;
|
||||
}
|
||||
|
||||
long Music_Emu::tell() const
|
||||
{
|
||||
blargg_long rate = sample_rate() * stereo;
|
||||
|
@ -185,14 +190,18 @@ long Music_Emu::tell() const
|
|||
return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
|
||||
}
|
||||
|
||||
blargg_err_t Music_Emu::seek( long msec )
|
||||
blargg_err_t Music_Emu::seek_samples( long time )
|
||||
{
|
||||
blargg_long time = msec_to_samples( msec );
|
||||
if ( time < out_time )
|
||||
RETURN_ERR( start_track( current_track_ ) );
|
||||
return skip( time - out_time );
|
||||
}
|
||||
|
||||
blargg_err_t Music_Emu::seek( long msec )
|
||||
{
|
||||
return seek_samples( msec_to_samples( msec ) );
|
||||
}
|
||||
|
||||
blargg_err_t Music_Emu::skip( long count )
|
||||
{
|
||||
require( current_track() >= 0 ); // start_track() must have been called already
|
||||
|
|
|
@ -41,9 +41,15 @@ public:
|
|||
// Number of milliseconds (1000 msec = 1 second) played since beginning of track
|
||||
long tell() const;
|
||||
|
||||
// Number of samples generated since beginning of track
|
||||
long tell_samples() const;
|
||||
|
||||
// Seek to new time in track. Seeking backwards or far forward can take a while.
|
||||
blargg_err_t seek( long msec );
|
||||
|
||||
// Equivalent to restarting track then skipping n samples
|
||||
blargg_err_t seek_samples( long n );
|
||||
|
||||
// Skip n samples
|
||||
blargg_err_t skip( long n );
|
||||
|
||||
|
|
|
@ -135,6 +135,9 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
|
|||
blargg_long size = get_le32( block_header [0] );
|
||||
blargg_long tag = get_le32( block_header [1] );
|
||||
|
||||
if ( size <= 0 )
|
||||
return "Corrupt file";
|
||||
|
||||
//debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
|
||||
|
||||
switch ( tag )
|
||||
|
|
|
@ -433,9 +433,7 @@ void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
|
|||
#endif
|
||||
|
||||
// Registers other than $F2 and $F4-$F7
|
||||
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
|
||||
// TODO: this is a bit on the fragile side
|
||||
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
|
||||
if ( reg != 2 && (reg < 4 || reg > 7) ) // 36%
|
||||
cpu_write_smp_reg( data, time, reg );
|
||||
}
|
||||
// High mem/address wrap-around
|
||||
|
|
|
@ -76,8 +76,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
// TODO: remove non-wrapping versions?
|
||||
#define SPC_NO_SP_WRAPAROUND 0
|
||||
|
||||
#define SET_SP( v ) (sp = ram + 0x101 + (v))
|
||||
#define GET_SP() (sp - 0x101 - ram)
|
||||
#define SET_SP( v ) (sp = ram + 0x101 + ((uint8_t) v))
|
||||
#define GET_SP() (uint8_t (sp - 0x101 - ram))
|
||||
|
||||
#if SPC_NO_SP_WRAPAROUND
|
||||
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
|
||||
|
@ -485,7 +485,7 @@ loop:
|
|||
|
||||
case 0xAF: // MOV (X)+,A
|
||||
WRITE_DP( 0, x, a + no_read_before_write );
|
||||
x++;
|
||||
x = (uint8_t) (x + 1);
|
||||
goto loop;
|
||||
|
||||
// 5. 8-BIT LOGIC OPERATION COMMANDS
|
||||
|
@ -808,7 +808,7 @@ loop:
|
|||
unsigned temp = y * a;
|
||||
a = (uint8_t) temp;
|
||||
nz = ((temp >> 1) | temp) & 0x7F;
|
||||
y = temp >> 8;
|
||||
y = (uint8_t) (temp >> 8);
|
||||
nz |= y;
|
||||
goto loop;
|
||||
}
|
||||
|
@ -838,6 +838,7 @@ loop:
|
|||
|
||||
nz = (uint8_t) a;
|
||||
a = (uint8_t) a;
|
||||
y = (uint8_t) y;
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
@ -1004,7 +1005,7 @@ loop:
|
|||
case 0x7F: // RET1
|
||||
temp = *sp;
|
||||
SET_PC( GET_LE16( sp + 1 ) );
|
||||
sp += 3;
|
||||
SET_SP( GET_SP() + 3 );
|
||||
goto set_psw;
|
||||
case 0x8E: // POP PSW
|
||||
POP( temp );
|
||||
|
|
|
@ -18,6 +18,19 @@ all other #include lines. */
|
|||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
|
||||
// Use to provide hints to compiler for optimized code layout in situations where we
|
||||
// can almost always expect a conditional to go one way or the other. Should only be
|
||||
// used in situations where an unexpected branch is truly exceptional though!
|
||||
#undef likely
|
||||
#undef unlikely
|
||||
#ifdef __GNUC__
|
||||
#define likely( x ) __builtin_expect(x, 1)
|
||||
#define unlikely( x ) __builtin_expect(x, 0)
|
||||
#else
|
||||
#define likely( x ) (x)
|
||||
#define unlikely( x ) (x)
|
||||
#endif
|
||||
|
||||
// Like printf() except output goes to debug log file. Might be defined to do
|
||||
// nothing (not even evaluate its arguments).
|
||||
// void debug_printf( const char* format, ... );
|
||||
|
|
|
@ -337,7 +337,9 @@ BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p )
|
|||
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
|
||||
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
|
||||
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
|
||||
BLARGG_EXPORT int gme_tell_samples ( Music_Emu const* me ) { return me->tell_samples(); }
|
||||
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
|
||||
BLARGG_EXPORT gme_err_t gme_seek_samples ( Music_Emu* me, int n ) { return me->seek_samples( n ); }
|
||||
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
|
||||
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
|
||||
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Game music emulator library C interface (also usable from C++) */
|
||||
|
||||
/* Game_Music_Emu 0.6.0 */
|
||||
/* Game_Music_Emu 0.6.1 */
|
||||
#ifndef GME_H
|
||||
#define GME_H
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
|
||||
/* Error string returned by library functions, or NULL if no error (success) */
|
||||
typedef const char* gme_err_t;
|
||||
|
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
|
|||
/* Number of milliseconds (1000 = one second) played since beginning of track */
|
||||
int gme_tell( Music_Emu const* );
|
||||
|
||||
/* Number of samples generated since beginning of track */
|
||||
int gme_tell_samples( Music_Emu const* );
|
||||
|
||||
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
|
||||
gme_err_t gme_seek( Music_Emu*, int msec );
|
||||
|
||||
/* Equivalent to restarting track then skipping n samples */
|
||||
gme_err_t gme_seek_samples( Music_Emu*, int n );
|
||||
|
||||
|
||||
/******** Informational ********/
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# later are used by pkg-config.
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
lib_suffix=
|
||||
lib_suffix=@LIB_SUFFIX@
|
||||
libdir=${exec_prefix}/lib${lib_suffix}
|
||||
includedir=${prefix}/include
|
||||
|
||||
|
@ -13,3 +13,4 @@ URL: http://code.google.com/p/game-music-emu/
|
|||
Version: @GME_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lgme
|
||||
Libs.private: -lstdc++
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Game music emulator library C interface (also usable from C++) */
|
||||
|
||||
/* Game_Music_Emu 0.6.0 */
|
||||
/* Game_Music_Emu 0.6.1 */
|
||||
#ifndef GME_H
|
||||
#define GME_H
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
|
||||
/* Error string returned by library functions, or NULL if no error (success) */
|
||||
typedef const char* gme_err_t;
|
||||
|
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
|
|||
/* Number of milliseconds (1000 = one second) played since beginning of track */
|
||||
int gme_tell( Music_Emu const* );
|
||||
|
||||
/* Number of samples generated since beginning of track */
|
||||
int gme_tell_samples( Music_Emu const* );
|
||||
|
||||
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
|
||||
gme_err_t gme_seek( Music_Emu*, int msec );
|
||||
|
||||
/* Equivalent to restarting track then skipping n samples */
|
||||
gme_err_t gme_seek_samples( Music_Emu*, int n );
|
||||
|
||||
|
||||
/******** Informational ********/
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Game_Music_Emu 0.6.0: Game Music Emulators
|
||||
Game_Music_Emu 0.6.2: Game Music Emulators
|
||||
------------------------------------------
|
||||
Game_Music_Emu is a collection of video game music file emulators that
|
||||
support the following formats and systems:
|
||||
|
@ -34,30 +34,45 @@ several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
|
|||
GP2X, and Nintendo DS.
|
||||
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Website: http://www.slack.net/~ant/
|
||||
Forum : http://groups.google.com/group/blargg-sound-libs
|
||||
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
|
||||
License: GNU Lesser General Public License (LGPL)
|
||||
|
||||
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
|
||||
all source files in gme/. If you have CMake 2.6 or later, execute
|
||||
all source files in gme/.
|
||||
|
||||
run cmake
|
||||
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
|
||||
extracted source directory):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ../ # <-- Pass any needed CMake flags here
|
||||
make # To build the library
|
||||
cd demo
|
||||
run make
|
||||
make # To build the demo itself
|
||||
|
||||
Be sure "test.nsf" is in the same directory as the program. Running it
|
||||
Be sure "test.nsf" is in the same directory as the demo program. Running it
|
||||
should generate the recording "out.wav".
|
||||
|
||||
You can use "make install" to install the library. To choose where to install
|
||||
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
|
||||
(and replace /usr/local with the base path you wish to use). Alternately, you
|
||||
can specify the base path to install to when you run "make install" by passing
|
||||
'DESTDIR=/usr/local' on the make install command line (again, replace
|
||||
/usr/local as appropriate).
|
||||
|
||||
To build a static library instead of shared (the default), pass
|
||||
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
|
||||
|
||||
A slightly more extensive demo application is available in the player/
|
||||
directory. It requires SDL to build.
|
||||
|
||||
Read gme.txt for more information. Post to the discussion forum for
|
||||
assistance.
|
||||
|
||||
|
||||
Files
|
||||
-----
|
||||
gme.txt General notes about the library
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -379,6 +379,12 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
|
|||
set(SRB2_HAVE_PNG ON)
|
||||
add_definitions(-DHAVE_PNG)
|
||||
add_definitions(-D_LARGEFILE64_SOURCE)
|
||||
set(SRB2_PNG_SOURCES apng.c)
|
||||
set(SRB2_PNG_HEADERS apng.h)
|
||||
prepend_sources(SRB2_PNG_SOURCES)
|
||||
prepend_sources(SRB2_PNG_HEADERS)
|
||||
source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}
|
||||
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
|
||||
else()
|
||||
message(WARNING "You have specified that PNG is available but it was not found. SRB2Kart may not compile correctly.")
|
||||
endif()
|
||||
|
|
|
@ -342,6 +342,8 @@ endif
|
|||
|
||||
LIBS+=$(PNG_LDFLAGS)
|
||||
CFLAGS+=$(PNG_CFLAGS)
|
||||
|
||||
OBJS+=$(OBJDIR)/apng.o
|
||||
endif
|
||||
|
||||
ifdef HAVE_LIBGME
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
# and other things
|
||||
#
|
||||
|
||||
ifdef GCC81
|
||||
GCC80=1
|
||||
endif
|
||||
|
||||
ifdef GCC80
|
||||
GCC72=1
|
||||
endif
|
||||
|
@ -116,6 +120,7 @@ WFLAGS+=-Wfloat-equal
|
|||
#WFLAGS+=-Wtraditional
|
||||
ifdef VCHELP
|
||||
WFLAGS+=-Wdeclaration-after-statement
|
||||
WFLAGS+=-Wno-error=declaration-after-statement
|
||||
endif
|
||||
WFLAGS+=-Wundef
|
||||
ifndef GCC295
|
||||
|
@ -189,12 +194,6 @@ ifdef GCC46
|
|||
WFLAGS+=-Wno-suggest-attribute=noreturn
|
||||
endif
|
||||
|
||||
ifndef MINGW
|
||||
ifdef GCC45
|
||||
WFLAGS+=-Wunsuffixed-float-constants
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef NOLDWARNING
|
||||
LDFLAGS+=-Wl,--as-needed
|
||||
endif
|
||||
|
@ -208,6 +207,9 @@ WFLAGS+=$(OLDWFLAGS)
|
|||
ifdef GCC43
|
||||
#WFLAGS+=-Wno-error=clobbered
|
||||
endif
|
||||
ifdef GCC44
|
||||
WFLAGS+=-Wno-error=array-bounds
|
||||
endif
|
||||
ifdef GCC46
|
||||
WFLAGS+=-Wno-error=suggest-attribute=noreturn
|
||||
endif
|
||||
|
@ -228,6 +230,7 @@ ifdef GCC80
|
|||
WFLAGS+=-Wno-format-overflow
|
||||
WFLAGS+=-Wno-stringop-truncation
|
||||
WFLAGS+=-Wno-stringop-overflow
|
||||
WFLAGS+=-Wno-error=multistatement-macros
|
||||
endif
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
Copyright 2019, James R.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apng.h"
|
||||
|
||||
#define APNG_INFO_acTL 0x20000U
|
||||
|
||||
#define APNG_WROTE_acTL 0x10000U
|
||||
|
||||
struct apng_info_def
|
||||
{
|
||||
png_uint_32 mode;
|
||||
png_uint_32 valid;
|
||||
|
||||
png_uint_32 num_frames;
|
||||
png_uint_32 num_plays;
|
||||
|
||||
long start_acTL;/* acTL is written here */
|
||||
|
||||
png_flush_ptr output_flush_fn;
|
||||
apng_seek_ptr output_seek_fn;
|
||||
apng_tell_ptr output_tell_fn;
|
||||
|
||||
apng_set_acTL_ptr set_acTL_fn;
|
||||
};
|
||||
|
||||
/* PROTOS (FUCK COMPILER) */
|
||||
void apng_seek (png_structp, apng_const_infop, size_t);
|
||||
size_t apng_tell (png_structp, apng_const_infop);
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
void apng_flush (png_structp, apng_infop);
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
void apng_default_flush (png_structp);
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
void apng_default_seek (png_structp, size_t);
|
||||
size_t apng_default_tell (png_structp);
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
void apng_write_IEND (png_structp);
|
||||
void apng_write_acTL (png_structp, png_uint_32, png_uint_32);
|
||||
#ifndef PNG_WRITE_APNG_SUPPORTED
|
||||
png_uint_32 apng_set_acTL_dummy (png_structp, png_infop,
|
||||
png_uint_32, png_uint_32);
|
||||
#endif/* PNG_WRITE_APNG_SUPPORTED */
|
||||
|
||||
apng_infop
|
||||
apng_create_info_struct (png_structp pngp)
|
||||
{
|
||||
apng_infop ainfop;
|
||||
(void)pngp;
|
||||
if (( ainfop = calloc(sizeof (apng_info),1) ))
|
||||
{
|
||||
apng_set_write_fn(pngp, ainfop, 0, 0, 0, 0, 0);
|
||||
apng_set_set_acTL_fn(pngp, ainfop, 0);
|
||||
}
|
||||
return ainfop;
|
||||
}
|
||||
|
||||
void
|
||||
apng_destroy_info_struct (png_structp pngp, apng_infopp ainfopp)
|
||||
{
|
||||
(void)pngp;
|
||||
if (!( pngp && ainfopp ))
|
||||
return;
|
||||
|
||||
free((*ainfopp));
|
||||
}
|
||||
|
||||
void
|
||||
apng_seek (png_structp pngp, apng_const_infop ainfop, size_t l)
|
||||
{
|
||||
(*(ainfop->output_seek_fn))(pngp, l);
|
||||
}
|
||||
|
||||
size_t
|
||||
apng_tell (png_structp pngp, apng_const_infop ainfop)
|
||||
{
|
||||
return (*(ainfop->output_tell_fn))(pngp);
|
||||
}
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
void
|
||||
apng_flush (png_structp pngp, apng_infop ainfop)
|
||||
{
|
||||
if (ainfop->output_flush_fn)
|
||||
(*(ainfop->output_flush_fn))(pngp);
|
||||
}
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
void
|
||||
apng_default_flush (png_structp pngp)
|
||||
{
|
||||
if (!( pngp ))
|
||||
return;
|
||||
|
||||
fflush((png_FILE_p)png_get_io_ptr);
|
||||
}
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
void
|
||||
apng_default_seek (png_structp pngp, size_t l)
|
||||
{
|
||||
if (!( pngp ))
|
||||
return;
|
||||
|
||||
if (fseek((png_FILE_p)png_get_io_ptr(pngp), (long)l, SEEK_SET) == -1)
|
||||
png_error(pngp, "Seek Error");
|
||||
}
|
||||
|
||||
size_t
|
||||
apng_default_tell (png_structp pngp)
|
||||
{
|
||||
long l;
|
||||
|
||||
if (!( pngp ))
|
||||
{
|
||||
png_error(pngp, "Call to apng_default_tell with NULL pngp failed");
|
||||
}
|
||||
|
||||
if (( l = ftell((png_FILE_p)png_get_io_ptr(pngp)) ) == -1)
|
||||
png_error(pngp, "Tell Error");
|
||||
|
||||
return (size_t)l;
|
||||
}
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
|
||||
void
|
||||
apng_set_write_fn (png_structp pngp, apng_infop ainfop, png_voidp iop,
|
||||
png_rw_ptr write_f, png_flush_ptr flush_f,
|
||||
apng_seek_ptr seek_f, apng_tell_ptr tell_f)
|
||||
{
|
||||
if (!( pngp && ainfop ))
|
||||
return;
|
||||
|
||||
png_set_write_fn(pngp, iop, write_f, flush_f);
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
if (!flush_f)
|
||||
ainfop->output_flush_fn = &apng_default_flush;
|
||||
else
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
ainfop->output_flush_fn = flush_f;
|
||||
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
if (!seek_f)
|
||||
ainfop->output_seek_fn = &apng_default_seek;
|
||||
else
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
ainfop->output_seek_fn = seek_f;
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
if (!seek_f)
|
||||
ainfop->output_tell_fn = apng_default_tell;
|
||||
else
|
||||
#endif/* PNG_STDIO_SUPPORTED */
|
||||
ainfop->output_tell_fn = tell_f;
|
||||
}
|
||||
|
||||
void
|
||||
apng_write_IEND (png_structp pngp)
|
||||
{
|
||||
png_byte chunkc[] = "IEND";
|
||||
png_write_chunk(pngp, chunkc, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
apng_write_acTL (png_structp pngp, png_uint_32 frames, png_uint_32 plays)
|
||||
{
|
||||
png_byte chunkc[] = "acTL";
|
||||
png_byte buf[8];
|
||||
png_save_uint_32(buf, frames);
|
||||
png_save_uint_32(buf + 4, plays);
|
||||
png_write_chunk(pngp, chunkc, buf, 8);
|
||||
}
|
||||
|
||||
png_uint_32
|
||||
apng_set_acTL (png_structp pngp, png_infop infop, apng_infop ainfop,
|
||||
png_uint_32 frames, png_uint_32 plays)
|
||||
{
|
||||
(void)pngp;
|
||||
(void)infop;
|
||||
if (!( pngp && infop && ainfop ))
|
||||
return 0;
|
||||
|
||||
ainfop->num_frames = frames;
|
||||
ainfop->num_plays = plays;
|
||||
|
||||
ainfop->valid |= APNG_INFO_acTL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
apng_write_info_before_PLTE (png_structp pngp, png_infop infop,
|
||||
apng_infop ainfop)
|
||||
{
|
||||
if (!( pngp && infop && ainfop ))
|
||||
return;
|
||||
|
||||
png_write_info_before_PLTE(pngp, infop);
|
||||
|
||||
if (( ainfop->valid & APNG_INFO_acTL )&&!( ainfop->mode & APNG_WROTE_acTL ))
|
||||
{
|
||||
ainfop->start_acTL = apng_tell(pngp, ainfop);
|
||||
|
||||
apng_write_acTL(pngp, 0, 0);
|
||||
/* modified for runtime dynamic linking */
|
||||
(*(ainfop->set_acTL_fn))(pngp, infop, PNG_UINT_31_MAX, 0);
|
||||
|
||||
ainfop->mode |= APNG_WROTE_acTL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
apng_write_info (png_structp pngp, png_infop infop,
|
||||
apng_infop ainfop)
|
||||
{
|
||||
apng_write_info_before_PLTE(pngp, infop, ainfop);
|
||||
png_write_info(pngp, infop);
|
||||
}
|
||||
|
||||
void
|
||||
apng_write_end (png_structp pngp, png_infop infop, apng_infop ainfop)
|
||||
{
|
||||
(void)infop;
|
||||
apng_write_IEND(pngp);
|
||||
apng_seek(pngp, ainfop, ainfop->start_acTL);
|
||||
apng_write_acTL(pngp, ainfop->num_frames, ainfop->num_plays);
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
#ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
|
||||
apng_flush(pngp, infop);
|
||||
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||
#endif/* PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED */
|
||||
}
|
||||
|
||||
#ifndef PNG_WRITE_APNG_SUPPORTED
|
||||
png_uint_32
|
||||
apng_set_acTL_dummy (png_structp pngp, png_infop infop,
|
||||
png_uint_32 frames, png_uint_32 plays)
|
||||
{
|
||||
(void)pngp;
|
||||
(void)infop;
|
||||
(void)frames;
|
||||
(void)plays;
|
||||
return 0;
|
||||
}
|
||||
#endif/* PNG_WRITE_APNG_SUPPORTED */
|
||||
|
||||
/* Dynamic runtime linking capable! (Hopefully.) */
|
||||
void
|
||||
apng_set_set_acTL_fn (png_structp pngp, apng_infop ainfop,
|
||||
apng_set_acTL_ptr set_acTL_f)
|
||||
{
|
||||
(void)pngp;
|
||||
if (!ainfop->set_acTL_fn)
|
||||
#ifndef PNG_WRITE_APNG_SUPPORTED
|
||||
ainfop->set_acTL_fn = &apng_set_acTL_dummy;
|
||||
#else
|
||||
ainfop->set_acTL_fn = &png_set_acTL;
|
||||
#endif/* PNG_WRITE_APNG_SUPPORTED */
|
||||
else
|
||||
ainfop->set_acTL_fn = set_acTL_f;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright 2019, James R.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef APNG_H
|
||||
#define APNG_H
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _WII
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
#define _LFS64_LARGEFILE
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#include <png.h>
|
||||
|
||||
typedef struct apng_info_def apng_info;
|
||||
typedef apng_info * apng_infop;
|
||||
typedef const apng_info * apng_const_infop;
|
||||
typedef apng_info * * apng_infopp;
|
||||
|
||||
typedef void (*apng_seek_ptr)(png_structp, size_t);
|
||||
typedef size_t (*apng_tell_ptr)(png_structp);
|
||||
|
||||
typedef png_uint_32 (*apng_set_acTL_ptr)(png_structp, png_infop,
|
||||
png_uint_32, png_uint_32);
|
||||
|
||||
apng_infop apng_create_info_struct (png_structp png_ptr);
|
||||
|
||||
void apng_destroy_info_struct (png_structp png_ptr,
|
||||
apng_infopp info_ptr_ptr);
|
||||
|
||||
/* Call the following functions in place of the libpng counterparts. */
|
||||
|
||||
png_uint_32 apng_set_acTL (png_structp png_ptr, png_infop info_ptr,
|
||||
apng_infop ainfo_ptr,
|
||||
png_uint_32 num_frames, png_uint_32 num_plays);
|
||||
|
||||
void apng_write_info_before_PLTE (png_structp png_ptr, png_infop info_ptr,
|
||||
apng_infop ainfo_ptr);
|
||||
void apng_write_info (png_structp png_ptr, png_infop info_ptr,
|
||||
apng_infop ainfo_ptr);
|
||||
|
||||
void apng_write_end (png_structp png_ptr, png_infop info_ptr,
|
||||
apng_infop ainfo_ptr);
|
||||
|
||||
void apng_set_write_fn (png_structp png_ptr, apng_infop ainfo_ptr,
|
||||
png_voidp io_ptr,
|
||||
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn,
|
||||
apng_seek_ptr output_seek_fn, apng_tell_ptr output_tell_fn);
|
||||
|
||||
void apng_set_set_acTL_fn (png_structp png_ptr, apng_infop ainfo_ptr,
|
||||
apng_set_acTL_ptr set_acTL_fn);
|
||||
|
||||
#endif/* APNG_H */
|
|
@ -1254,7 +1254,8 @@ found:
|
|||
|
||||
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;
|
||||
else if (var->flags & CV_FLOAT)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,8 @@ typedef enum
|
|||
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
|
||||
// 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;
|
||||
|
||||
typedef struct CV_PossibleValue_s
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
/* Manually defined asset hashes for non-CMake builds
|
||||
* 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 / 11 / 16 - Kart v1.0.0 - Main assets
|
||||
* Last updated 2018 / 12 / 13 - Kart v1.0.2 - patch.kart
|
||||
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
|
||||
* Last updated 2019 / 03 / 11 - Kart v1.0.4 - patch.kart
|
||||
*/
|
||||
|
||||
// Base SRB2 hashes
|
||||
|
@ -49,10 +49,10 @@
|
|||
// SRB2Kart-specific hashes
|
||||
#define ASSET_HASH_GFX_KART "99c39f223d84ebc78e67ab68f3bead95"
|
||||
#define ASSET_HASH_TEXTURES_KART "ec8e9b7535cf585afe72ef277b08f490"
|
||||
#define ASSET_HASH_CHARS_KART "784ee9177b01c8cb26edff43eaf93d87"
|
||||
#define ASSET_HASH_MAPS_KART "84018d9b35d181ca9fcc2be5a9d43a45"
|
||||
#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964"
|
||||
#define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a"
|
||||
#ifdef USE_PATCH_KART
|
||||
#define ASSET_HASH_PATCH_KART "843a13a73935dc4df721427a8948fb89"
|
||||
#define ASSET_HASH_PATCH_KART "b5f48e1abccfa47a5745199182e2fef4"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
//
|
||||
void CON_ClearHUD(void)
|
||||
|
@ -1084,16 +1100,6 @@ boolean CON_Responder(event_t *ev)
|
|||
else if (key == KEY_KPADSLASH)
|
||||
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.
|
||||
if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z'))
|
||||
{
|
||||
|
|
|
@ -44,6 +44,8 @@ extern UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *or
|
|||
// Console bg color (auto updated to match)
|
||||
extern UINT8 *consolebgmap;
|
||||
|
||||
INT32 CON_ShiftChar(INT32 ch);
|
||||
|
||||
void CON_SetupBackColormap(void);
|
||||
void CON_ClearHUD(void); // clear heads up messages
|
||||
|
||||
|
|
538
src/d_clisrv.c
538
src/d_clisrv.c
|
@ -22,6 +22,7 @@
|
|||
#include "i_video.h"
|
||||
#include "d_net.h"
|
||||
#include "d_main.h"
|
||||
#include "d_event.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "keys.h"
|
||||
|
@ -72,6 +73,7 @@
|
|||
#define PREDICTIONQUEUE BACKUPTICS
|
||||
#define PREDICTIONMASK (PREDICTIONQUEUE-1)
|
||||
#define MAX_REASONLENGTH 30
|
||||
#define FORCECLOSE 0x8000
|
||||
|
||||
boolean server = true; // true or false but !server == client
|
||||
#define client (!server)
|
||||
|
@ -93,6 +95,7 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
|
|||
UINT16 pingmeasurecount = 1;
|
||||
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
|
||||
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
|
||||
tic_t servermaxping = 800; // server's max ping. Defaults to 800
|
||||
#endif
|
||||
SINT8 nodetoplayer[MAXNETNODES];
|
||||
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
|
||||
|
@ -648,6 +651,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
|
||||
rsp->jointime = (tic_t)LONG(players[i].jointime);
|
||||
|
||||
rsp->splitscreenindex = players[i].splitscreenindex;
|
||||
|
||||
rsp->hasmo = false;
|
||||
//Transfer important mo information if the player has a body.
|
||||
//This lets us resync players even if they are dead.
|
||||
|
@ -783,6 +788,8 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
|
||||
players[i].jointime = (tic_t)LONG(rsp->jointime);
|
||||
|
||||
players[i].splitscreenindex = rsp->splitscreenindex;
|
||||
|
||||
//We get a packet for each player in game.
|
||||
if (!playeringame[i])
|
||||
return;
|
||||
|
@ -1121,12 +1128,22 @@ typedef enum
|
|||
CL_DOWNLOADSAVEGAME,
|
||||
#endif
|
||||
CL_CONNECTED,
|
||||
CL_ABORTED
|
||||
CL_ABORTED,
|
||||
CL_ASKDOWNLOADFILES,
|
||||
CL_WAITDOWNLOADFILESRESPONSE,
|
||||
CL_CHALLENGE
|
||||
} cl_mode_t;
|
||||
|
||||
static void GetPackets(void);
|
||||
|
||||
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
|
||||
|
||||
|
@ -1163,6 +1180,8 @@ static void CV_LoadPlayerNames(UINT8 **p)
|
|||
}
|
||||
|
||||
#ifdef CLIENT_LOADINGSCREEN
|
||||
static UINT32 SL_SearchServer(INT32 node);
|
||||
|
||||
//
|
||||
// CL_DrawConnectionStatus
|
||||
//
|
||||
|
@ -1186,11 +1205,42 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
// 15 pal entries total.
|
||||
const char *cltext;
|
||||
|
||||
if (cl_mode != CL_CHALLENGE)
|
||||
for (i = 0; i < 16; ++i)
|
||||
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
|
||||
|
||||
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
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
if (lastfilenum != -1)
|
||||
|
@ -1210,6 +1260,9 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
case CL_WAITJOINRESPONSE:
|
||||
cltext = M_GetText("Requesting to join...");
|
||||
break;
|
||||
case CL_ASKDOWNLOADFILES:
|
||||
case CL_WAITDOWNLOADFILESRESPONSE:
|
||||
cltext = M_GetText("Waiting to download files...");
|
||||
default:
|
||||
cltext = M_GetText("Connecting to server...");
|
||||
break;
|
||||
|
@ -1287,6 +1340,9 @@ static boolean CL_SendJoin(void)
|
|||
netbuffer->u.clientcfg.localplayers = localplayers;
|
||||
netbuffer->u.clientcfg.version = VERSION;
|
||||
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));
|
||||
}
|
||||
|
@ -1307,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.modifiedgame = (UINT8)modifiedgame;
|
||||
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,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||
|
@ -1740,8 +1802,6 @@ static void SendAskInfo(INT32 node, boolean viams)
|
|||
serverelem_t serverlist[MAXSERVERLIST];
|
||||
UINT32 serverlistcount = 0;
|
||||
|
||||
#define FORCECLOSE 0x8000
|
||||
|
||||
static void SL_ClearServerList(INT32 connectedserver)
|
||||
{
|
||||
UINT32 i;
|
||||
|
@ -1867,7 +1927,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
|
|||
/** Called by CL_ServerConnectionTicker
|
||||
*
|
||||
* \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
|
||||
* \sa CL_ServerConnectionTicker
|
||||
* \sa CL_ConnectToServer
|
||||
|
@ -1960,9 +2020,12 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
|
||||
cl_mode = CL_ASKDOWNLOADFILES;
|
||||
|
||||
// no problem if can't send packet, we will retry later
|
||||
if (CL_SendRequestFile())
|
||||
cl_mode = CL_DOWNLOADFILES;
|
||||
//if (CL_SendRequestFile())
|
||||
// cl_mode = CL_DOWNLOADFILES;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1992,7 +2055,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
* \param viams ???
|
||||
* \param tmpsave The name of the gamestate file???
|
||||
* \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
|
||||
* \sa CL_ServerConnectionSearchTicker
|
||||
* \sa CL_ConnectToServer
|
||||
|
@ -2030,6 +2093,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
/* FALLTHRU */
|
||||
|
||||
case CL_ASKJOIN:
|
||||
cl_needsdownload = false;
|
||||
CL_LoadServerFiles();
|
||||
#ifdef JOININGAME
|
||||
// prepare structures to save the file
|
||||
|
@ -2038,9 +2102,23 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
CL_PrepareDownloadSaveGame(tmpsave);
|
||||
#endif
|
||||
if (CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime();
|
||||
cl_mode = CL_WAITJOINRESPONSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case CL_ASKDOWNLOADFILES:
|
||||
cl_needsdownload = true;
|
||||
|
||||
if (CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime();
|
||||
cl_mode = CL_WAITDOWNLOADFILESRESPONSE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#ifdef JOININGAME
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
// At this state, the first (and only) needed file is the gamestate
|
||||
|
@ -2054,7 +2132,19 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
break;
|
||||
#endif
|
||||
|
||||
case CL_CHALLENGE:
|
||||
(*asksent) = I_GetTime() - NEWTICRATE; // Send password immediately upon entering
|
||||
break;
|
||||
|
||||
case CL_WAITJOINRESPONSE:
|
||||
case CL_WAITDOWNLOADFILESRESPONSE:
|
||||
if (*asksent + NEWTICRATE < I_GetTime() && CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CL_CONNECTED:
|
||||
default:
|
||||
break;
|
||||
|
@ -2072,19 +2162,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
// Call it only once by tic
|
||||
if (*oldtic != I_GetTime())
|
||||
{
|
||||
INT32 key;
|
||||
|
||||
I_OsPolling();
|
||||
key = I_GetKey();
|
||||
if (key == KEY_ESCAPE || key == KEY_JOY1+1)
|
||||
{
|
||||
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();
|
||||
D_ProcessEvents();
|
||||
if (gamestate != GS_WAITINGPLAYERS)
|
||||
return false;
|
||||
}
|
||||
|
||||
// why are these here? this is for servers, we're a client
|
||||
//if (key == 's' && server)
|
||||
|
@ -2113,6 +2194,71 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
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
|
||||
*
|
||||
* \param viams ???
|
||||
|
@ -2133,6 +2279,7 @@ static void CL_ConnectToServer(boolean viams)
|
|||
#endif
|
||||
|
||||
cl_mode = CL_SEARCHING;
|
||||
cl_challengenum = 0;
|
||||
|
||||
#ifdef CLIENT_LOADINGSCREEN
|
||||
lastfilenum = -1;
|
||||
|
@ -2190,6 +2337,8 @@ static void CL_ConnectToServer(boolean viams)
|
|||
SL_ClearServerList(servernode);
|
||||
#endif
|
||||
|
||||
cl_challengeattempted = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// If the connection was aborted for some reason, leave
|
||||
|
@ -2210,8 +2359,10 @@ static void CL_ConnectToServer(boolean viams)
|
|||
}
|
||||
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
|
||||
|
||||
#ifndef NONET
|
||||
if (netgame)
|
||||
F_StartWaitingPlayers();
|
||||
#endif
|
||||
DEBFILE(va("Synchronisation Finished\n"));
|
||||
|
||||
displayplayer = consoleplayer;
|
||||
|
@ -2539,6 +2690,8 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||
#else
|
||||
(void)reason;
|
||||
#endif
|
||||
|
||||
// Reset player data
|
||||
|
@ -2722,7 +2875,10 @@ static void Command_Ban(void)
|
|||
else
|
||||
{
|
||||
if (server) // only the server is allowed to do this right now
|
||||
{
|
||||
Ban_Add(COM_Argv(2));
|
||||
D_SaveBan(); // save the ban list
|
||||
}
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
|
@ -2753,6 +2909,42 @@ static void Command_Ban(void)
|
|||
|
||||
}
|
||||
|
||||
static void Command_BanIP(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server) // Only the server can use this, otherwise does nothing.
|
||||
{
|
||||
const char *address = (COM_Argv(1));
|
||||
const char *reason;
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
reason = NULL;
|
||||
else
|
||||
reason = COM_Argv(2);
|
||||
|
||||
|
||||
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
|
||||
{
|
||||
if (reason)
|
||||
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
|
||||
else
|
||||
CONS_Printf("Banned IP address %s\n", address);
|
||||
|
||||
Ban_Add(reason);
|
||||
D_SaveBan();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_Kick(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
|
@ -3024,6 +3216,9 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
||||
|
@ -3056,6 +3251,7 @@ void D_ClientServerInit(void)
|
|||
COM_AddCommand("getplayernum", Command_GetPlayerNum);
|
||||
COM_AddCommand("kick", Command_Kick);
|
||||
COM_AddCommand("ban", Command_Ban);
|
||||
COM_AddCommand("banip", Command_BanIP);
|
||||
COM_AddCommand("clearbans", Command_ClearBans);
|
||||
COM_AddCommand("showbanlist", Command_ShowBan);
|
||||
COM_AddCommand("reloadbans", Command_ReloadBan);
|
||||
|
@ -3079,7 +3275,6 @@ void D_ClientServerInit(void)
|
|||
CV_RegisterVar(&cv_joinnextround);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_showjoinaddress);
|
||||
CV_RegisterVar(&cv_resynchattempts);
|
||||
CV_RegisterVar(&cv_blamecfail);
|
||||
#ifdef DUMPCONSISTENCY
|
||||
CV_RegisterVar(&cv_dumpconsistency);
|
||||
|
@ -3090,6 +3285,9 @@ void D_ClientServerInit(void)
|
|||
gametic = 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
|
||||
SV_StopServer();
|
||||
SV_ResetServer();
|
||||
|
@ -3311,6 +3509,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
addedtogame = true;
|
||||
}
|
||||
|
||||
players[newplayernum].splitscreenindex = splitscreenplayer;
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
if (server && cv_showjoinaddress.value)
|
||||
|
@ -3577,6 +3777,33 @@ static void HandleConnect(SINT8 node)
|
|||
boolean newnode = false;
|
||||
#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
|
||||
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
|
||||
if (!nodeingame[node])
|
||||
|
@ -3585,6 +3812,7 @@ static void HandleConnect(SINT8 node)
|
|||
#ifndef NONET
|
||||
newnode = true;
|
||||
#endif
|
||||
|
||||
SV_AddNode(node);
|
||||
|
||||
/// \note Wait what???
|
||||
|
@ -3740,6 +3968,43 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
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
|
||||
if (server && serverrunning)
|
||||
{ // But wait I thought I'm the server?
|
||||
|
@ -3768,6 +4033,41 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
}
|
||||
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
|
||||
{
|
||||
INT32 j;
|
||||
|
@ -3783,6 +4083,9 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
if (cl_mode != CL_WAITJOINRESPONSE)
|
||||
break;
|
||||
|
||||
if (cl_challengeattempted == 1) // Successful password noise.
|
||||
S_StartSound(NULL, sfx_s221);
|
||||
|
||||
if (client)
|
||||
{
|
||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||
|
@ -3882,6 +4185,32 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
#undef SERVERONLY
|
||||
}
|
||||
|
||||
/** Checks ticcmd for "speed hacks"
|
||||
*
|
||||
* \param p Which player
|
||||
* \return True if player is hacking
|
||||
* \sa HandlePacketFromPlayer
|
||||
*
|
||||
*/
|
||||
static boolean CheckForSpeedHacks(UINT8 p)
|
||||
{
|
||||
if (netcmds[maketic%BACKUPTICS][p].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][p].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[maketic%BACKUPTICS][p].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][p].sidemove < -MAXPLMOVE
|
||||
|| netcmds[maketic%BACKUPTICS][p].driftturn > KART_FULLTURN || netcmds[maketic%BACKUPTICS][p].driftturn < -KART_FULLTURN)
|
||||
{
|
||||
XBOXSTATIC char buf[2];
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), playernode[p]);
|
||||
//D_Clearticcmd(k);
|
||||
|
||||
buf[0] = (char)p;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Handles a packet received from a node that is in game
|
||||
*
|
||||
* \param node The packet sender
|
||||
|
@ -3976,18 +4305,8 @@ FILESTAMP
|
|||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||
|
||||
// Check ticcmd for "speed hacks"
|
||||
if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE)
|
||||
{
|
||||
XBOXSTATIC char buf[2];
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole);
|
||||
//D_Clearticcmd(k);
|
||||
|
||||
buf[0] = (char)netconsole;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
if (CheckForSpeedHacks((UINT8)netconsole))
|
||||
break;
|
||||
}
|
||||
|
||||
// Splitscreen cmd
|
||||
if (((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||
|
@ -3997,6 +4316,9 @@ FILESTAMP
|
|||
{
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer2[node]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (((netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS)
|
||||
|
@ -4005,6 +4327,9 @@ FILESTAMP
|
|||
{
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer3[node]],
|
||||
&netbuffer->u.client3pak.cmd3, 1);
|
||||
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer3[node]))
|
||||
break;
|
||||
}
|
||||
|
||||
if ((netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)
|
||||
|
@ -4012,6 +4337,9 @@ FILESTAMP
|
|||
{
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer4[node]],
|
||||
&netbuffer->u.client4pak.cmd4, 1);
|
||||
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer4[node]))
|
||||
break;
|
||||
}
|
||||
|
||||
// A delay before we check resynching
|
||||
|
@ -4055,6 +4383,21 @@ FILESTAMP
|
|||
else if (resynch_score[node])
|
||||
--resynch_score[node];
|
||||
break;
|
||||
case PT_BASICKEEPALIVE:
|
||||
if (client)
|
||||
break;
|
||||
|
||||
// This should probably still timeout though, as the node should always have a player 1 number
|
||||
if (netconsole == -1)
|
||||
break;
|
||||
|
||||
// If a client sends this it should mean they are done receiving the savegame
|
||||
sendingsavegame[node] = false;
|
||||
|
||||
// As long as clients send keep alives, the server can keep running, so reset the timeout
|
||||
/// \todo Use a separate cvar for that kind of timeout?
|
||||
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||
break;
|
||||
case PT_TEXTCMD:
|
||||
case PT_TEXTCMD2:
|
||||
case PT_TEXTCMD3:
|
||||
|
@ -4308,10 +4651,12 @@ FILESTAMP
|
|||
//Update client ping table from the server.
|
||||
if (client)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
|
||||
|
||||
servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS];
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -4558,6 +4903,15 @@ static INT16 Consistancy(void)
|
|||
return (INT16)(ret & 0xFFFF);
|
||||
}
|
||||
|
||||
// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE
|
||||
// used during wipes to tell the server that a node is still connected
|
||||
static void CL_SendClientKeepAlive(void)
|
||||
{
|
||||
netbuffer->packettype = PT_BASICKEEPALIVE;
|
||||
|
||||
HSendPacket(servernode, false, 0, 0);
|
||||
}
|
||||
|
||||
// send the client packet to the server
|
||||
static void CL_SendClientCmd(void)
|
||||
{
|
||||
|
@ -4932,6 +5286,10 @@ void TryRunTics(tic_t realtics)
|
|||
ExtraDataTicker();
|
||||
gametic++;
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
|
||||
// Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame.
|
||||
if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4941,6 +5299,18 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
|
||||
#ifdef NEWPING
|
||||
|
||||
/* Ping Update except better:
|
||||
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
|
||||
If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave.
|
||||
|
||||
Why do we do that? Well, I'm a person with unfortunately sometimes unstable internet and happen to keep getting kicked very unconveniently for very short high spikes. (700+ ms)
|
||||
Because my spikes are so high, the average ping is exponentially higher too (700s really add up...!) which leads me to getting kicked for a short burst of spiking.
|
||||
With this change here, this doesn't happen anymore as it checks if my ping has been CONSISTENTLY bad for long enough before killing me.
|
||||
*/
|
||||
|
||||
static INT32 pingtimeout[MAXPLAYERS];
|
||||
|
||||
static inline void PingUpdate(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -4961,6 +5331,9 @@ static inline void PingUpdate(void)
|
|||
laggers[i] = true;
|
||||
numlaggers++;
|
||||
}
|
||||
else
|
||||
pingtimeout[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
//kick lagging players... unless everyone but the server's ping sucks.
|
||||
|
@ -4970,14 +5343,22 @@ static inline void PingUpdate(void)
|
|||
for (i = 1; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && laggers[i])
|
||||
{
|
||||
pingtimeout[i]++;
|
||||
if (pingtimeout[i] > cv_pingtimeout.value) // ok your net has been bad for too long, you deserve to die.
|
||||
{
|
||||
XBOXSTATIC char buf[2];
|
||||
|
||||
pingtimeout[i] = 0;
|
||||
|
||||
buf[0] = (char)i;
|
||||
buf[1] = KICK_MSG_PING_HIGH;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
}
|
||||
else // you aren't lagging, but you aren't free yet. In case you'll keep spiking, we just make the timer go back down. (Very unstable net must still get kicked).
|
||||
pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4991,18 +5372,89 @@ static inline void PingUpdate(void)
|
|||
realpingtable[i] = 0; //Reset each as we go.
|
||||
}
|
||||
|
||||
// send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked.
|
||||
netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value;
|
||||
|
||||
//send out our ping packets
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i])
|
||||
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
||||
HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
|
||||
|
||||
pingmeasurecount = 1; //Reset count
|
||||
}
|
||||
#endif
|
||||
|
||||
static tic_t gametime = 0;
|
||||
|
||||
#ifdef NEWPING
|
||||
static void UpdatePingTable(void)
|
||||
{
|
||||
INT32 i;
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 35)) // update once per second.
|
||||
PingUpdate();
|
||||
// update node latency values so we can take an average later.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
static void HandleNodeTimeouts(void)
|
||||
{
|
||||
INT32 i;
|
||||
if (server)
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
||||
Net_ConnectionTimeout(i);
|
||||
}
|
||||
|
||||
// Keep the network alive while not advancing tics!
|
||||
void NetKeepAlive(void)
|
||||
{
|
||||
tic_t nowtime;
|
||||
INT32 realtics;
|
||||
|
||||
nowtime = I_GetTime();
|
||||
realtics = nowtime - gametime;
|
||||
|
||||
// return if there's no time passed since the last call
|
||||
if (realtics <= 0) // nothing new to update
|
||||
return;
|
||||
|
||||
#ifdef NEWPING
|
||||
UpdatePingTable();
|
||||
#endif
|
||||
|
||||
if (server)
|
||||
CL_SendClientKeepAlive();
|
||||
|
||||
// Sryder: What is FILESTAMP???
|
||||
FILESTAMP
|
||||
GetPackets();
|
||||
FILESTAMP
|
||||
|
||||
MasterClient_Ticker();
|
||||
|
||||
if (client)
|
||||
{
|
||||
// send keep alive
|
||||
CL_SendClientKeepAlive();
|
||||
// No need to check for resynch because we aren't running any tics
|
||||
}
|
||||
// No else because no tics are being run and we can't resynch during this
|
||||
|
||||
Net_AckTicker();
|
||||
HandleNodeTimeouts();
|
||||
SV_FileSendTicker();
|
||||
}
|
||||
|
||||
void NetUpdate(void)
|
||||
{
|
||||
static tic_t gametime = 0;
|
||||
static tic_t resptime = 0;
|
||||
tic_t nowtime;
|
||||
INT32 i;
|
||||
|
@ -5024,16 +5476,7 @@ void NetUpdate(void)
|
|||
gametime = nowtime;
|
||||
|
||||
#ifdef NEWPING
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 255))
|
||||
PingUpdate();
|
||||
// update node latency values so we can take an average later.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
UpdatePingTable();
|
||||
#endif
|
||||
|
||||
if (client)
|
||||
|
@ -5101,12 +5544,7 @@ FILESTAMP
|
|||
}
|
||||
}
|
||||
Net_AckTicker();
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
if (server)
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
||||
Net_ConnectionTimeout(i);
|
||||
nowtime /= NEWTICRATERATIO;
|
||||
HandleNodeTimeouts();
|
||||
if (nowtime > resptime)
|
||||
{
|
||||
resptime = nowtime;
|
||||
|
|
|
@ -13,11 +13,14 @@
|
|||
#ifndef __D_CLISRV__
|
||||
#define __D_CLISRV__
|
||||
|
||||
#include "d_event.h"
|
||||
#include "d_ticcmd.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
// Network play related stuff.
|
||||
// There is a data struct that stores network
|
||||
// communication related stuff, and another
|
||||
|
@ -71,6 +74,10 @@ typedef enum
|
|||
PT_CLIENT3MIS,
|
||||
PT_CLIENT4CMD, // 4P
|
||||
PT_CLIENT4MIS,
|
||||
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
|
||||
// allows HSendPacket(*, true, *, *) to return false.
|
||||
|
@ -282,6 +289,8 @@ typedef struct
|
|||
|
||||
tic_t jointime;
|
||||
|
||||
UINT8 splitscreenindex;
|
||||
|
||||
//player->mo stuff
|
||||
UINT8 hasmo; // Boolean
|
||||
|
||||
|
@ -350,9 +359,21 @@ typedef struct
|
|||
UINT8 version; // Different versions don't work
|
||||
UINT8 subversion; // Contains build version
|
||||
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;
|
||||
|
||||
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 MAXFILENEEDED 915
|
||||
// This packet is too large
|
||||
|
@ -365,7 +386,7 @@ typedef struct
|
|||
UINT8 gametype;
|
||||
UINT8 modifiedgame;
|
||||
UINT8 cheatsenabled;
|
||||
UINT8 isdedicated;
|
||||
UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes
|
||||
UINT8 fileneedednum;
|
||||
SINT8 adminplayer;
|
||||
tic_t time;
|
||||
|
@ -433,10 +454,10 @@ typedef struct
|
|||
UINT8 reserved; // Padding
|
||||
union
|
||||
{
|
||||
clientcmd_pak clientpak; // 144 bytes
|
||||
client2cmd_pak client2pak; // 200 bytes
|
||||
client3cmd_pak client3pak; // 256 bytes(?)
|
||||
client4cmd_pak client4pak; // 312 bytes(?)
|
||||
clientcmd_pak clientpak; // 145 bytes
|
||||
client2cmd_pak client2pak; // 202 bytes
|
||||
client3cmd_pak client3pak; // 258 bytes(?)
|
||||
client4cmd_pak client4pak; // 316 bytes(?)
|
||||
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
||||
serverconfig_pak servercfg; // 773 bytes
|
||||
resynchend_pak resynchend; //
|
||||
|
@ -444,15 +465,16 @@ typedef struct
|
|||
UINT8 resynchgot; //
|
||||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 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
|
||||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
||||
askinfo_pak askinfo; // 61 bytes
|
||||
msaskinfo_pak msaskinfo; // 22 bytes
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE)
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
||||
#ifdef NEWPING
|
||||
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
|
||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
||||
#endif
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
@ -518,13 +540,14 @@ extern tic_t jointimeout;
|
|||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
#endif
|
||||
|
||||
extern consvar_t
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
cv_joinnextround,
|
||||
#endif
|
||||
cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low);
|
||||
|
@ -538,6 +561,7 @@ void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam); // splitsreen
|
|||
void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
void NetKeepAlive(void);
|
||||
void NetUpdate(void);
|
||||
|
||||
void SV_StartSinglePlayerServer(void);
|
||||
|
@ -550,6 +574,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p);
|
|||
void CL_Reset(void);
|
||||
void CL_ClearPlayer(INT32 playernum);
|
||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
||||
boolean CL_Responder(event_t *ev);
|
||||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
|
|
127
src/d_main.c
127
src/d_main.c
|
@ -111,6 +111,7 @@ UINT8 window_notinfocus = false;
|
|||
//static INT32 demosequence;
|
||||
static const char *pagename = "MAP1PIC";
|
||||
static char *startupwadfiles[MAX_WADFILES];
|
||||
static char *startuppwads[MAX_WADFILES];
|
||||
|
||||
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_LALT: altdown |= 0x1; return;
|
||||
case KEY_RALT: altdown |= 0x2; return;
|
||||
case KEY_CAPSLOCK: capslock = !capslock; return;
|
||||
|
||||
default: return;
|
||||
}
|
||||
else if (ev->type == ev_keyup) switch (ev->data1)
|
||||
|
@ -236,6 +239,9 @@ void D_ProcessEvents(void)
|
|||
if (M_ScreenshotResponder(ev))
|
||||
continue; // ate the event
|
||||
|
||||
if (CL_Responder(ev))
|
||||
continue;
|
||||
|
||||
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
|
||||
{
|
||||
if (cht_Responder(ev))
|
||||
|
@ -821,12 +827,12 @@ void D_StartTitle(void)
|
|||
//
|
||||
// D_AddFile
|
||||
//
|
||||
static void D_AddFile(const char *file)
|
||||
static void D_AddFile(const char *file, char **filearray)
|
||||
{
|
||||
size_t pnumwadfiles;
|
||||
char *newfile;
|
||||
|
||||
for (pnumwadfiles = 0; startupwadfiles[pnumwadfiles]; pnumwadfiles++)
|
||||
for (pnumwadfiles = 0; filearray[pnumwadfiles]; pnumwadfiles++)
|
||||
;
|
||||
|
||||
newfile = malloc(strlen(file) + 1);
|
||||
|
@ -836,16 +842,16 @@ static void D_AddFile(const char *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;
|
||||
for (pnumwadfiles = 0; startupwadfiles[pnumwadfiles]; pnumwadfiles++)
|
||||
for (pnumwadfiles = 0; filearray[pnumwadfiles]; pnumwadfiles++)
|
||||
{
|
||||
free(startupwadfiles[pnumwadfiles]);
|
||||
startupwadfiles[pnumwadfiles] = NULL;
|
||||
free(filearray[pnumwadfiles]);
|
||||
filearray[pnumwadfiles] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -905,9 +911,9 @@ static void IdentifyVersion(void)
|
|||
|
||||
// Load the IWAD
|
||||
if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2))
|
||||
D_AddFile(srb2wad2);
|
||||
D_AddFile(srb2wad2, startupwadfiles);
|
||||
else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1))
|
||||
D_AddFile(srb2wad1);
|
||||
D_AddFile(srb2wad1, startupwadfiles);
|
||||
else
|
||||
I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2);
|
||||
|
||||
|
@ -924,12 +930,12 @@ static void IdentifyVersion(void)
|
|||
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
|
||||
#endif
|
||||
|
||||
D_AddFile(va(pandf,srb2waddir,"gfx.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"textures.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"chars.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"maps.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"gfx.kart"), startupwadfiles);
|
||||
D_AddFile(va(pandf,srb2waddir,"textures.kart"), startupwadfiles);
|
||||
D_AddFile(va(pandf,srb2waddir,"chars.kart"), startupwadfiles);
|
||||
D_AddFile(va(pandf,srb2waddir,"maps.kart"), startupwadfiles);
|
||||
#ifdef USE_PATCH_KART
|
||||
D_AddFile(va(pandf,srb2waddir,"patch.kart"));
|
||||
D_AddFile(va(pandf,srb2waddir,"patch.kart"), startupwadfiles);
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
|
||||
|
@ -938,7 +944,7 @@ static void IdentifyVersion(void)
|
|||
const char *musicpath = va(pandf,srb2waddir,str);\
|
||||
int ms = W_VerifyNMUSlumps(musicpath); \
|
||||
if (ms == 1) \
|
||||
D_AddFile(musicpath); \
|
||||
D_AddFile(musicpath, startupwadfiles); \
|
||||
else if (ms == 0) \
|
||||
I_Error("File "str" has been modified with non-music/sound lumps"); \
|
||||
}
|
||||
|
@ -1003,9 +1009,12 @@ static inline void D_MakeTitleString(char *s)
|
|||
//
|
||||
void D_SRB2Main(void)
|
||||
{
|
||||
INT32 p;
|
||||
INT32 p, i;
|
||||
char srb2[82]; // srb2 title banner
|
||||
char title[82];
|
||||
lumpinfo_t *lumpinfo;
|
||||
UINT16 wadnum;
|
||||
char *name;
|
||||
|
||||
INT32 pstartmap = 1;
|
||||
boolean autostart = false;
|
||||
|
@ -1157,11 +1166,7 @@ void D_SRB2Main(void)
|
|||
const char *s = M_GetNextParm();
|
||||
|
||||
if (s) // Check for NULL?
|
||||
{
|
||||
if (!W_VerifyNMUSlumps(s))
|
||||
G_SetGameModified(true);
|
||||
D_AddFile(s);
|
||||
}
|
||||
D_AddFile(s, startuppwads);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1186,7 +1191,7 @@ void D_SRB2Main(void)
|
|||
else
|
||||
{
|
||||
if (!M_CheckParm("-server"))
|
||||
G_SetGameModified(true);
|
||||
G_SetGameModified(true, true);
|
||||
autostart = true;
|
||||
}
|
||||
}
|
||||
|
@ -1211,13 +1216,13 @@ void D_SRB2Main(void)
|
|||
|
||||
// load wad, including the main wad file
|
||||
CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
|
||||
if (!W_InitMultipleFiles(startupwadfiles))
|
||||
if (!W_InitMultipleFiles(startupwadfiles, false))
|
||||
#ifdef _DEBUG
|
||||
CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
|
||||
#else
|
||||
I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
|
||||
#endif
|
||||
D_CleanFile();
|
||||
D_CleanFile(startupwadfiles);
|
||||
|
||||
mainwads = 0;
|
||||
|
||||
|
@ -1231,7 +1236,7 @@ void D_SRB2Main(void)
|
|||
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_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
|
||||
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart
|
||||
#endif
|
||||
|
@ -1251,6 +1256,66 @@ void D_SRB2Main(void)
|
|||
|
||||
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();
|
||||
|
||||
//---------------------------------------------------- READY SCREEN
|
||||
|
@ -1322,10 +1387,6 @@ void D_SRB2Main(void)
|
|||
midi_disabled = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
|
||||
}
|
||||
if (M_CheckParm("-nosound"))
|
||||
sound_disabled = true;
|
||||
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
|
||||
|
@ -1344,10 +1405,18 @@ void D_SRB2Main(void)
|
|||
if (M_CheckParm("-nodigmusic"))
|
||||
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||
}
|
||||
if (!( sound_disabled && digital_disabled
|
||||
#ifndef NO_MIDI
|
||||
&& midi_disabled
|
||||
#endif
|
||||
))
|
||||
{
|
||||
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
S_InitSfxChannels(cv_soundvolume.value);
|
||||
S_InitMusicDefs();
|
||||
}
|
||||
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
|
18
src/d_net.c
18
src/d_net.c
|
@ -821,10 +821,6 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"CLIENTMIS",
|
||||
"CLIENT2CMD",
|
||||
"CLIENT2MIS",
|
||||
"CLIENT3CMD",
|
||||
"CLIENT3MIS",
|
||||
"CLIENT4CMD",
|
||||
"CLIENT4MIS",
|
||||
"NODEKEEPALIVE",
|
||||
"NODEKEEPALIVEMIS",
|
||||
"SERVERTICS",
|
||||
|
@ -841,6 +837,15 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"RESYNCHEND",
|
||||
"RESYNCHGET",
|
||||
|
||||
"CLIENT3CMD",
|
||||
"CLIENT3MIS",
|
||||
"CLIENT4CMD",
|
||||
"CLIENT4MIS",
|
||||
"BASICKEEPALIVE",
|
||||
|
||||
"JOINCHALLENGE",
|
||||
"DOWNLOADFILESOKAY",
|
||||
|
||||
"FILEFRAGMENT",
|
||||
"TEXTCMD",
|
||||
"TEXTCMD2",
|
||||
|
@ -868,7 +873,7 @@ static void DebugPrintpacket(const char *header)
|
|||
break;
|
||||
case PT_CLIENTJOIN:
|
||||
fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers,
|
||||
netbuffer->u.clientcfg.mode);
|
||||
netbuffer->u.clientcfg.needsdownload);
|
||||
break;
|
||||
case PT_SERVERTICS:
|
||||
{
|
||||
|
@ -903,6 +908,9 @@ static void DebugPrintpacket(const char *header)
|
|||
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic),
|
||||
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom));
|
||||
break;
|
||||
case PT_BASICKEEPALIVE:
|
||||
fprintf(debugfile, " keep alive\n");
|
||||
break;
|
||||
case PT_TEXTCMD:
|
||||
case PT_TEXTCMD2:
|
||||
case PT_TEXTCMD3:
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define __D_NET__
|
||||
|
||||
// Max computers in a game
|
||||
#define MAXNETNODES 16
|
||||
#define MAXNETNODES (MAXPLAYERS+4)
|
||||
#define BROADCASTADDR MAXNETNODES
|
||||
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
|
||||
#define NETSPLITSCREEN // Kart's splitscreen netgame feature
|
||||
|
|
219
src/d_netcmd.c
219
src/d_netcmd.c
|
@ -169,6 +169,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum);
|
|||
static void Got_Removal(UINT8 **cp, INT32 playernum);
|
||||
static void Command_Verify_f(void);
|
||||
static void Command_RemoveAdmin_f(void);
|
||||
static void Command_ChangeJoinPassword_f(void);
|
||||
static void Command_MotD_f(void);
|
||||
static void Got_MotD_f(UINT8 **cp, INT32 playernum);
|
||||
|
||||
|
@ -214,7 +215,7 @@ static CV_PossibleValue_t autobalance_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NU
|
|||
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t sleeping_cons_t[] = {{0, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Teleports"},
|
||||
{3, "None"}, {0, NULL}};
|
||||
|
||||
|
@ -236,6 +237,9 @@ static consvar_t cv_dummyconsvar = {"dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP
|
|||
consvar_t cv_restrictskinchange = {"restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t ingamecap_cons_t[] = {{0, "MIN"}, {MAXPLAYERS-1, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_ingamecap = {"ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
|
@ -357,7 +361,7 @@ consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_
|
|||
consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
|
||||
consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Sometimes", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}};
|
||||
consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
|
||||
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
||||
|
@ -375,6 +379,7 @@ consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|C
|
|||
|
||||
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebugcolorize = {"kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -432,6 +437,14 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co
|
|||
#ifdef NEWPING
|
||||
static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// 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}};
|
||||
consvar_t cv_showping = {"showping", "Always", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#endif
|
||||
// Intermission time Tails 04-19-2002
|
||||
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
|
@ -447,7 +460,7 @@ consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL
|
|||
consvar_t cv_pause = {"pausepermission", "Server", CV_NETVAR, pause_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sleep = {"cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT16 gametype = GT_RACE; // SRB2kart
|
||||
boolean forceresetplayers = false;
|
||||
|
@ -483,6 +496,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
|||
"SETUPVOTE",
|
||||
"MODIFYVOTE",
|
||||
"PICKVOTE",
|
||||
"REMOVEPLAYER",
|
||||
#ifdef HAVE_BLUA
|
||||
"LUACMD",
|
||||
"LUAVAR"
|
||||
|
@ -521,6 +535,8 @@ void D_RegisterServerCommands(void)
|
|||
RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd);
|
||||
|
||||
// Remote Administration
|
||||
CV_RegisterVar(&cv_dummyjoinpassword);
|
||||
COM_AddCommand("joinpassword", Command_ChangeJoinPassword_f);
|
||||
COM_AddCommand("password", Command_Changepassword_f);
|
||||
RegisterNetXCmd(XD_LOGIN, Got_Login);
|
||||
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
|
||||
|
@ -641,11 +657,13 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_allowexitlevel);
|
||||
CV_RegisterVar(&cv_restrictskinchange);
|
||||
CV_RegisterVar(&cv_allowteamchange);
|
||||
CV_RegisterVar(&cv_ingamecap);
|
||||
CV_RegisterVar(&cv_respawntime);
|
||||
CV_RegisterVar(&cv_killingdead);
|
||||
|
||||
// d_clisrv
|
||||
CV_RegisterVar(&cv_maxplayers);
|
||||
CV_RegisterVar(&cv_resynchattempts);
|
||||
CV_RegisterVar(&cv_maxsend);
|
||||
CV_RegisterVar(&cv_noticedownload);
|
||||
CV_RegisterVar(&cv_downloadspeed);
|
||||
|
@ -658,6 +676,8 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_sleep);
|
||||
#ifdef NEWPING
|
||||
CV_RegisterVar(&cv_maxping);
|
||||
CV_RegisterVar(&cv_pingtimeout);
|
||||
CV_RegisterVar(&cv_showping);
|
||||
#endif
|
||||
|
||||
#ifdef SEENAMES
|
||||
|
@ -761,6 +781,7 @@ void D_RegisterClientCommands(void)
|
|||
#endif
|
||||
CV_RegisterVar(&cv_rollingdemos);
|
||||
CV_RegisterVar(&cv_netstat);
|
||||
CV_RegisterVar(&cv_netticbuffer);
|
||||
|
||||
#ifdef NETGAME_DEVMODE
|
||||
CV_RegisterVar(&cv_fishcake);
|
||||
|
@ -800,6 +821,8 @@ void D_RegisterClientCommands(void)
|
|||
//CV_RegisterVar(&cv_alwaysfreelook2);
|
||||
//CV_RegisterVar(&cv_chasefreelook);
|
||||
//CV_RegisterVar(&cv_chasefreelook2);
|
||||
CV_RegisterVar(&cv_showfocuslost);
|
||||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_turnaxis);
|
||||
|
@ -839,14 +862,6 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_addons_search_type);
|
||||
CV_RegisterVar(&cv_addons_search_case);
|
||||
|
||||
// filesrch.c
|
||||
CV_RegisterVar(&cv_addons_option);
|
||||
CV_RegisterVar(&cv_addons_folder);
|
||||
CV_RegisterVar(&cv_addons_md5);
|
||||
CV_RegisterVar(&cv_addons_showall);
|
||||
CV_RegisterVar(&cv_addons_search_type);
|
||||
CV_RegisterVar(&cv_addons_search_case);
|
||||
|
||||
// WARNING: the order is important when initialising mouse2
|
||||
// we need the mouse2port
|
||||
CV_RegisterVar(&cv_mouse2port);
|
||||
|
@ -2214,10 +2229,12 @@ static void Command_Map_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(netgame || multiplayer) && (!modifiedgame || savemoddata))
|
||||
if (!(netgame || multiplayer) && !majormods)
|
||||
{
|
||||
if (COM_CheckParm("-force"))
|
||||
G_SetGameModified(false);
|
||||
{
|
||||
G_SetGameModified(false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
|
||||
|
@ -2501,6 +2518,12 @@ static void Command_Respawn(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (players[consoleplayer].mo && !P_IsObjectOnGround(players[consoleplayer].mo)) // KART: Nice try, but no, you won't be cheesing spb anymore.
|
||||
{
|
||||
CONS_Printf(M_GetText("You must be on the floor to use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/*if (!G_RaceGametype()) // srb2kart: not necessary, respawning makes you lose a bumper in battle, so it's not desirable to use as a way to escape a hit
|
||||
{
|
||||
CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n"));
|
||||
|
@ -2537,6 +2560,10 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
// incase the above checks were modified to allow sending a respawn on these occasions:
|
||||
if (players[respawnplayer].mo && !P_IsObjectOnGround(players[respawnplayer].mo))
|
||||
return;
|
||||
|
||||
if (players[respawnplayer].mo)
|
||||
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 10000);
|
||||
}
|
||||
|
@ -3405,6 +3432,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
|
|||
|
||||
if (len > 256-sl)
|
||||
len = 256-sl;
|
||||
|
||||
memcpy(tmpbuf, buffer, len);
|
||||
memmove(&tmpbuf[len], salt, sl);
|
||||
//strcpy(&tmpbuf[len], salt);
|
||||
|
@ -3418,7 +3446,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
|
|||
}
|
||||
|
||||
#define BASESALT "basepasswordstorage"
|
||||
static UINT8 adminpassmd5[16];
|
||||
static UINT8 adminpassmd5[MD5_LEN];
|
||||
static boolean adminpasswordset = false;
|
||||
|
||||
void D_SetPassword(const char *pw)
|
||||
|
@ -3457,7 +3485,7 @@ static void Command_Login_f(void)
|
|||
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
|
||||
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
|
||||
#else
|
||||
XBOXSTATIC UINT8 finalmd5[16];
|
||||
XBOXSTATIC UINT8 finalmd5[MD5_LEN];
|
||||
const char *pw;
|
||||
|
||||
if (!netgame)
|
||||
|
@ -3480,11 +3508,11 @@ static void Command_Login_f(void)
|
|||
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &finalmd5);
|
||||
|
||||
// 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"));
|
||||
|
||||
SendNetXCmd(XD_LOGIN, finalmd5, 16);
|
||||
SendNetXCmd(XD_LOGIN, finalmd5, MD5_LEN);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3495,9 +3523,9 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
|
|||
(void)cp;
|
||||
(void)playernum;
|
||||
#else
|
||||
UINT8 sentmd5[16], finalmd5[16];
|
||||
UINT8 sentmd5[MD5_LEN], finalmd5[MD5_LEN];
|
||||
|
||||
READMEM(*cp, sentmd5, 16);
|
||||
READMEM(*cp, sentmd5, MD5_LEN);
|
||||
|
||||
if (client)
|
||||
return;
|
||||
|
@ -3509,9 +3537,9 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
// 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]);
|
||||
COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately
|
||||
|
@ -3680,6 +3708,131 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
|
|||
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)
|
||||
{
|
||||
size_t i, j;
|
||||
|
@ -3786,7 +3939,7 @@ static void Command_RunSOC(void)
|
|||
if (!P_RunSOC(fn))
|
||||
CONS_Printf(M_GetText("Could not find SOC.\n"));
|
||||
else
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3840,7 +3993,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
P_RunSOC(filename);
|
||||
G_SetGameModified(true);
|
||||
G_SetGameModified(true, false);
|
||||
}
|
||||
|
||||
/** Adds a pwad at runtime.
|
||||
|
@ -3877,7 +4030,7 @@ static void Command_Addfile(void)
|
|||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
return;
|
||||
}
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, false);
|
||||
}
|
||||
|
||||
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
||||
|
@ -4123,7 +4276,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
G_SetGameModified(true);
|
||||
G_SetGameModified(true, false);
|
||||
}
|
||||
|
||||
static void Command_ListWADS_f(void)
|
||||
|
@ -4480,7 +4633,7 @@ static void Ringslinger_OnChange(void)
|
|||
}
|
||||
|
||||
if (cv_ringslinger.value) // Only if it's been turned on
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
static void Gravity_OnChange(void)
|
||||
|
@ -4501,7 +4654,7 @@ static void Gravity_OnChange(void)
|
|||
#endif
|
||||
|
||||
if (!CV_IsSetToDefault(&cv_gravity))
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
gravity = cv_gravity.value;
|
||||
}
|
||||
|
||||
|
@ -4897,7 +5050,7 @@ static void Fishcake_OnChange(void)
|
|||
// so don't make modifiedgame always on!
|
||||
if (cv_debug)
|
||||
{
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
else if (cv_debug != cv_fishcake.value)
|
||||
|
@ -4913,12 +5066,14 @@ static void Fishcake_OnChange(void)
|
|||
*/
|
||||
static void Command_Isgamemodified_f(void)
|
||||
{
|
||||
if (savemoddata)
|
||||
CONS_Printf(M_GetText("modifiedgame is true, but you can save medal and record data in this mod.\n"));
|
||||
if (majormods)
|
||||
CONS_Printf("The game has been modified with major add-ons, so you cannot play Record Attack.\n");
|
||||
else if (savemoddata)
|
||||
CONS_Printf("The game has been modified with an add-on with its own save data, so you can play Record Attack and earn medals.\n");
|
||||
else if (modifiedgame)
|
||||
CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n"));
|
||||
CONS_Printf("The game has been modified with only minor add-ons. You can play Record Attack, earn medals and unlock extras.\n");
|
||||
else
|
||||
CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n"));
|
||||
CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n");
|
||||
}
|
||||
|
||||
static void Command_Cheats_f(void)
|
||||
|
|
|
@ -33,6 +33,8 @@ extern consvar_t cv_skin3;
|
|||
extern consvar_t cv_playername4;
|
||||
extern consvar_t cv_playercolor4;
|
||||
extern consvar_t cv_skin4;
|
||||
// preferred number of players
|
||||
extern consvar_t cv_splitplayers;
|
||||
|
||||
#ifdef SEENAMES
|
||||
extern consvar_t cv_seenames, cv_allowseenames;
|
||||
|
@ -91,7 +93,7 @@ extern consvar_t cv_mute;
|
|||
extern consvar_t cv_killingdead;
|
||||
extern consvar_t cv_pause;
|
||||
|
||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_respawntime;
|
||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_ingamecap, cv_respawntime;
|
||||
|
||||
/*extern consvar_t cv_teleporters, cv_superring, cv_supersneakers, cv_invincibility;
|
||||
extern consvar_t cv_jumpshield, cv_watershield, cv_ringshield, cv_forceshield, cv_bombshield;
|
||||
|
@ -124,7 +126,7 @@ extern consvar_t cv_karteliminatelast;
|
|||
extern consvar_t cv_votetime;
|
||||
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
|
||||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
||||
|
@ -143,6 +145,8 @@ extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionb
|
|||
|
||||
#ifdef NEWPING
|
||||
extern consvar_t cv_maxping;
|
||||
extern consvar_t cv_pingtimeout;
|
||||
extern consvar_t cv_showping;
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_skipmapcheck;
|
||||
|
@ -244,6 +248,14 @@ void RemoveAdminPlayer(INT32 playernum);
|
|||
void ItemFinder_OnChange(void);
|
||||
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
|
||||
UINT8 CanChangeSkin(INT32 playernum);
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ void CL_LoadServerFiles(void)
|
|||
else if (fileneeded[i].status == FS_FOUND)
|
||||
{
|
||||
P_AddWadFile(fileneeded[i].filename);
|
||||
G_SetGameModified(true);
|
||||
G_SetGameModified(true, false);
|
||||
fileneeded[i].status = FS_OPEN;
|
||||
}
|
||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||
|
|
|
@ -32,13 +32,7 @@
|
|||
// Extra abilities/settings for skins (combinable stuff)
|
||||
typedef enum
|
||||
{
|
||||
SF_SUPER = 1, // Can turn super in singleplayer/co-op mode.
|
||||
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?
|
||||
SF_HIRES = 1, // Draw the sprite 2x as small?
|
||||
} skinflags_t;
|
||||
|
||||
//Primary and secondary skin abilities
|
||||
|
@ -275,6 +269,7 @@ typedef enum
|
|||
k_nextcheck, // Next checkpoint distance; for p_user.c (was "pw_ncd")
|
||||
k_waypoint, // Waypoints.
|
||||
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_dropdash, // Charge up for respawn Drop Dash
|
||||
|
||||
|
@ -348,10 +343,13 @@ typedef enum
|
|||
k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo
|
||||
k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly
|
||||
|
||||
// v1.0.2 vars
|
||||
// v1.0.2+ vars
|
||||
k_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator
|
||||
k_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items)
|
||||
k_getsparks, // Disable drift sparks at low speed, JUST enough to give acceleration the actual headstart above speed
|
||||
k_jawztargetdelay, // Delay for Jawz target switching, to make it less twitchy
|
||||
k_spectatewait, // How long have you been waiting as a spectator
|
||||
k_growcancel, // Hold the item button down to cancel Grow
|
||||
|
||||
NUMKARTSTUFF
|
||||
} kartstufftype_t;
|
||||
|
@ -416,6 +414,8 @@ typedef struct player_s
|
|||
// SRB2kart stuff
|
||||
INT32 kartstuff[NUMKARTSTUFF];
|
||||
angle_t frameangle; // for the player add the ability to have the sprite only face other angles
|
||||
INT16 lturn_max[MAXPREDICTTICS]; // What's the expected turn value for full-left for a number of frames back (to account for netgame latency)?
|
||||
INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right
|
||||
|
||||
// Bit flags.
|
||||
// See pflags_t, above.
|
||||
|
@ -567,6 +567,8 @@ typedef struct player_s
|
|||
UINT8 bot;
|
||||
|
||||
tic_t jointime; // Timer when player joins game to change skin/color
|
||||
|
||||
UINT8 splitscreenindex;
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#pragma interface
|
||||
#endif
|
||||
|
||||
#define MAXPREDICTTICS 12
|
||||
|
||||
// Button/action code definitions.
|
||||
typedef enum
|
||||
{
|
||||
|
@ -60,6 +62,7 @@ typedef struct
|
|||
INT16 aiming; // vertical aiming, see G_BuildTicCmd
|
||||
UINT16 buttons;
|
||||
INT16 driftturn; // SRB2Kart: Used for getting drift turn speed
|
||||
UINT8 latency; // Netgames: how many tics ago was this ticcmd generated from this player's end?
|
||||
} ATTRPACK ticcmd_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
|
328
src/dehacked.c
328
src/dehacked.c
|
@ -21,6 +21,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "m_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "filesrch.h" // for refreshdirmenu
|
||||
#include "f_finale.h"
|
||||
#include "dehacked.h"
|
||||
#include "st_stuff.h"
|
||||
|
@ -79,8 +80,6 @@ static powertype_t get_power(const char *word);
|
|||
boolean deh_loaded = false;
|
||||
static int dbg_line;
|
||||
|
||||
static boolean gamedataadded = false;
|
||||
|
||||
#ifdef DELFILE
|
||||
typedef struct undehacked_s
|
||||
{
|
||||
|
@ -436,11 +435,11 @@ static void readAnimTex(MYFILE *f, INT32 num)
|
|||
static boolean findFreeSlot(INT32 *num)
|
||||
{
|
||||
// Send the character select entry to a free slot.
|
||||
while (*num < 32 && PlayerMenu[*num].status != IT_DISABLED)
|
||||
while (*num < MAXSKINS && PlayerMenu[*num].status != IT_DISABLED)
|
||||
*num = *num+1;
|
||||
|
||||
// No more free slots. :(
|
||||
if (*num >= 32)
|
||||
if (*num >= MAXSKINS)
|
||||
return false;
|
||||
|
||||
// Found one! ^_^
|
||||
|
@ -602,6 +601,14 @@ done:
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static int freeslotusage[2][2] = {{0, 0}, {0, 0}}; // [S_, MT_][max, previous .wad's max]
|
||||
|
||||
void DEH_UpdateMaxFreeslots(void)
|
||||
{
|
||||
freeslotusage[0][1] = freeslotusage[0][0];
|
||||
freeslotusage[1][1] = freeslotusage[1][0];
|
||||
}
|
||||
|
||||
// TODO: Figure out how to do undolines for this....
|
||||
// TODO: Warnings for running out of freeslots
|
||||
static void readfreeslots(MYFILE *f)
|
||||
|
@ -664,6 +671,7 @@ static void readfreeslots(MYFILE *f)
|
|||
if (!FREE_STATES[i]) {
|
||||
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||
strcpy(FREE_STATES[i],word);
|
||||
freeslotusage[0][0]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -673,6 +681,7 @@ static void readfreeslots(MYFILE *f)
|
|||
if (!FREE_MOBJS[i]) {
|
||||
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||
strcpy(FREE_MOBJS[i],word);
|
||||
freeslotusage[1][0]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3094,11 +3103,6 @@ static void readmaincfg(MYFILE *f)
|
|||
if (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"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE);
|
||||
|
@ -3139,6 +3143,7 @@ static void readmaincfg(MYFILE *f)
|
|||
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
|
||||
strlwr(gamedatafilename);
|
||||
savemoddata = true;
|
||||
majormods = false;
|
||||
|
||||
// Also save a time attack folder
|
||||
filenamelen = strlen(gamedatafilename)-4; // Strip off the extension
|
||||
|
@ -3151,7 +3156,7 @@ static void readmaincfg(MYFILE *f)
|
|||
// can't use sprintf since there is %u in savegamename
|
||||
strcatbf(savegamename, srb2home, PATHSEP);
|
||||
|
||||
gamedataadded = true;
|
||||
refreshdirmenu |= REFRESHDIR_GAMEDATA;
|
||||
}
|
||||
else if (fastcmp(word, "RESETDATA"))
|
||||
{
|
||||
|
@ -3382,8 +3387,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
for (i = 0; i < NUMSFX; i++)
|
||||
savesfxnames[i] = S_sfx[i].name;
|
||||
|
||||
gamedataadded = false;
|
||||
|
||||
// it doesn't test the version of SRB2 and version of dehacked file
|
||||
dbg_line = -1; // start at -1 so the first line is 0.
|
||||
while (!myfeof(f))
|
||||
|
@ -3417,10 +3420,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
if (fastcmp(word, "FREESLOT"))
|
||||
{
|
||||
readfreeslots(f);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
else if (fastcmp(word, "MAINCFG"))
|
||||
{
|
||||
G_SetGameModified(multiplayer, true);
|
||||
readmaincfg(f);
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
continue;
|
||||
|
@ -3429,6 +3434,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
{
|
||||
readwipes(f);
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
word2 = strtok(NULL, " ");
|
||||
|
@ -3449,6 +3455,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
if (word2)
|
||||
|
@ -3462,19 +3469,25 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// Read texture from spec file.
|
||||
readtexture(f, word2);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "PATCH"))
|
||||
{
|
||||
// Read patch from spec file.
|
||||
readpatch(f, word2, wad);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_mobjtype(word2); // find a thing by name
|
||||
if (i < NUMMOBJTYPES && i >= 0)
|
||||
{
|
||||
if (i < (MT_FIRSTFREESLOT+freeslotusage[1][1]))
|
||||
G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED
|
||||
readthing(f, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
|
||||
|
@ -3485,6 +3498,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
/* else if (fastcmp(word, "ANIMTEX"))
|
||||
{
|
||||
readAnimTex(f, i);
|
||||
// This is not a major mod.
|
||||
}*/
|
||||
else if (fastcmp(word, "LIGHT"))
|
||||
{
|
||||
|
@ -3498,6 +3512,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
#endif
|
||||
}
|
||||
else if (fastcmp(word, "SPRITE"))
|
||||
|
@ -3513,6 +3528,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
#endif
|
||||
}
|
||||
else if (fastcmp(word, "LEVEL"))
|
||||
|
@ -3525,7 +3541,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
if (i > 0 && i <= NUMMAPS)
|
||||
{
|
||||
if (mapheaderinfo[i])
|
||||
G_SetGameModified(multiplayer, true); // only mark as a major mod if it replaces an already-existing mapheaderinfo
|
||||
readlevelheader(f, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS);
|
||||
|
@ -3543,13 +3563,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
//G_SetGameModified(multiplayer, true); -- might have to reconsider in a future update
|
||||
}
|
||||
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_state(word2); // find a state by name
|
||||
if (i < NUMSTATES && i >= 0)
|
||||
{
|
||||
if (i < (S_FIRSTFREESLOT+freeslotusage[0][1]))
|
||||
G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED
|
||||
readframe(f, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1);
|
||||
|
@ -3578,6 +3603,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
else
|
||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}*/
|
||||
else if (fastcmp(word, "SOUND"))
|
||||
{
|
||||
|
@ -3591,6 +3617,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
/* else if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
|
@ -3611,6 +3638,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
else
|
||||
deh_warning("Sprite %d doesn't exist",i);
|
||||
// This is not a major mod.
|
||||
}*/
|
||||
else if (fastcmp(word, "HUDITEM"))
|
||||
{
|
||||
|
@ -3624,10 +3652,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "EMBLEM"))
|
||||
{
|
||||
if (!gamedataadded)
|
||||
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||
{
|
||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||
ignorelines(f);
|
||||
|
@ -3647,7 +3676,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
else if (fastcmp(word, "EXTRAEMBLEM"))
|
||||
{
|
||||
if (!gamedataadded)
|
||||
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||
{
|
||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||
ignorelines(f);
|
||||
|
@ -3667,7 +3696,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
if (!gamedataadded)
|
||||
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||
{
|
||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||
ignorelines(f);
|
||||
|
@ -3683,7 +3712,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
{
|
||||
if (!gamedataadded)
|
||||
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||
{
|
||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||
ignorelines(f);
|
||||
|
@ -3698,13 +3727,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// no undo support for this insanity yet
|
||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
else if (fastcmp(word, "SRB2KART"))
|
||||
{
|
||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||
if (ver != PATCHVERSION)
|
||||
deh_warning("Patch is for SRB2Kart version %d,\nonly version %d is supported", ver, PATCHVERSION);
|
||||
//DEH_WriteUndoline(word, va("%d", ver), UNDO_NONE);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
{
|
||||
if (mainwads) // srb2.srb triggers this warning otherwise
|
||||
deh_warning("Patch is only compatible with base SRB2.");
|
||||
}
|
||||
// Clear all data in certain locations (mostly for unlocks)
|
||||
// Unless you REALLY want to piss people off,
|
||||
// define a custom gamedata /before/ doing this!!
|
||||
|
@ -3713,7 +3747,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
{
|
||||
boolean clearall = (fastcmp(word2, "ALL"));
|
||||
|
||||
if (!gamedataadded)
|
||||
if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
|
||||
{
|
||||
deh_warning("You must define a custom gamedata to use \"%s\"", word);
|
||||
continue;
|
||||
|
@ -3750,8 +3784,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
deh_warning("No word in this line: %s", s);
|
||||
} // end while
|
||||
|
||||
if (gamedataadded)
|
||||
G_LoadGameData();
|
||||
/*if (gamedataadded) -- REFRESHDIR_GAMEDATA murdered this
|
||||
G_LoadGameData();*/
|
||||
|
||||
dbg_line = -1;
|
||||
if (deh_num_warning)
|
||||
|
@ -7111,6 +7145,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_KARMAFIREWORK4",
|
||||
"S_KARMAFIREWORKTRAIL",
|
||||
|
||||
// Opaque smoke version, to prevent lag
|
||||
"S_OPAQUESMOKE1",
|
||||
"S_OPAQUESMOKE2",
|
||||
"S_OPAQUESMOKE3",
|
||||
"S_OPAQUESMOKE4",
|
||||
"S_OPAQUESMOKE5",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"S_NAMECHECK",
|
||||
#endif
|
||||
|
@ -8095,89 +8136,164 @@ static const char *const ML_LIST[16] = {
|
|||
// This DOES differ from r_draw's Color_Names, unfortunately.
|
||||
// Also includes Super colors
|
||||
static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
|
||||
"NONE", // 00 // SKINCOLOR_NONE
|
||||
"WHITE", // 01 // SKINCOLOR_WHITE
|
||||
"SILVER", // 02 // SKINCOLOR_SILVER
|
||||
"GREY", // 03 // SKINCOLOR_GREY
|
||||
"NICKEL", // 04 // SKINCOLOR_NICKEL
|
||||
"BLACK", // 05 // SKINCOLOR_BLACK
|
||||
"SEPIA", // 06 // SKINCOLOR_SEPIA
|
||||
"BEIGE", // 07 // SKINCOLOR_BEIGE
|
||||
"BROWN", // 08 // SKINCOLOR_BROWN
|
||||
"LEATHER", // 09 // SKINCOLOR_LEATHER
|
||||
"SALMON", // 10 // SKINCOLOR_SALMON
|
||||
"PINK", // 11 // SKINCOLOR_PINK
|
||||
"ROSE", // 12 // SKINCOLOR_ROSE
|
||||
"RUBY", // 13 // SKINCOLOR_RUBY
|
||||
"RASPBERRY", // 14 // SKINCOLOR_RASPBERRY
|
||||
"RED", // 15 // SKINCOLOR_RED
|
||||
"CRIMSON", // 16 // SKINCOLOR_CRIMSON
|
||||
"KETCHUP", // 17 // SKINCOLOR_KETCHUP
|
||||
"DAWN", // 18 // SKINCOLOR_DAWN
|
||||
"CREAMSICLE", // 19 // SKINCOLOR_CREAMSICLE
|
||||
"ORANGE", // 20 // SKINCOLOR_ORANGE
|
||||
"PUMPKIN", // 21 // SKINCOLOR_PUMPKIN
|
||||
"ROSEWOOD", // 22 // SKINCOLOR_ROSEWOOD
|
||||
"BURGUNDY", // 23 // SKINCOLOR_BURGUNDY
|
||||
"TANGERINE", // 24 // SKINCOLOR_TANGERINE
|
||||
"PEACH", // 25 // SKINCOLOR_PEACH
|
||||
"CARAMEL", // 26 // SKINCOLOR_CARAMEL
|
||||
"GOLD", // 27 // SKINCOLOR_GOLD
|
||||
"BRONZE", // 28 // SKINCOLOR_BRONZE
|
||||
"YELLOW", // 29 // SKINCOLOR_YELLOW
|
||||
"MUSTARD", // 30 // SKINCOLOR_MUSTARD
|
||||
"OLIVE", // 31 // SKINCOLOR_OLIVE
|
||||
"VOMIT", // 32 // SKINCOLOR_VOMIT
|
||||
"GARDEN", // 33 // SKINCOLOR_GARDEN
|
||||
"LIME", // 34 // SKINCOLOR_LIME
|
||||
"TEA", // 35 // SKINCOLOR_TEA
|
||||
"PISTACHIO", // 36 // SKINCOLOR_PISTACHIO
|
||||
"ROBOHOOD", // 37 // SKINCOLOR_ROBOHOOD
|
||||
"MOSS", // 38 // SKINCOLOR_MOSS
|
||||
"MINT", // 39 // SKINCOLOR_MINT
|
||||
"GREEN", // 40 // SKINCOLOR_GREEN
|
||||
"PINETREE", // 41 // SKINCOLOR_PINETREE
|
||||
"EMERALD", // 42 // SKINCOLOR_EMERALD
|
||||
"SWAMP", // 43 // SKINCOLOR_SWAMP
|
||||
"DREAM", // 44 // SKINCOLOR_DREAM
|
||||
"AQUA", // 45 // SKINCOLOR_AQUA
|
||||
"TEAL", // 46 // SKINCOLOR_TEAL
|
||||
"CYAN", // 47 // SKINCOLOR_CYAN
|
||||
"JAWZ", // 48 // SKINCOLOR_JAWZ
|
||||
"CERULEAN", // 49 // SKINCOLOR_CERULEAN
|
||||
"NAVY", // 50 // SKINCOLOR_NAVY
|
||||
"SLATE", // 51 // SKINCOLOR_SLATE
|
||||
"STEEL", // 52 // SKINCOLOR_STEEL
|
||||
"JET", // 53 // SKINCOLOR_JET
|
||||
"SAPPHIRE", // 54 // SKINCOLOR_SAPPHIRE
|
||||
"PERIWINKLE", // 55 // SKINCOLOR_PERIWINKLE
|
||||
"BLUE", // 56 // SKINCOLOR_BLUE
|
||||
"BLUEBERRY", // 57 // SKINCOLOR_BLUEBERRY
|
||||
"DUSK", // 58 // SKINCOLOR_DUSK
|
||||
"PURPLE", // 59 // SKINCOLOR_PURPLE
|
||||
"LAVENDER", // 60 // SKINCOLOR_LAVENDER
|
||||
"BYZANTIUM", // 61 // SKINCOLOR_BYZANTIUM
|
||||
"POMEGRANATE", // 62 // SKINCOLOR_POMEGRANATE
|
||||
"LILAC", // 63 // SKINCOLOR_LILAC
|
||||
"NONE", // SKINCOLOR_NONE
|
||||
"WHITE", // SKINCOLOR_WHITE
|
||||
"SILVER", // SKINCOLOR_SILVER
|
||||
"GREY", // SKINCOLOR_GREY
|
||||
"NICKEL", // SKINCOLOR_NICKEL
|
||||
"BLACK", // SKINCOLOR_BLACK
|
||||
"FAIRY", // SKINCOLOR_FAIRY
|
||||
"POPCORN", // SKINCOLOR_POPCORN
|
||||
"SEPIA", // SKINCOLOR_SEPIA
|
||||
"BEIGE", // SKINCOLOR_BEIGE
|
||||
"BROWN", // SKINCOLOR_BROWN
|
||||
"LEATHER", // SKINCOLOR_LEATHER
|
||||
"SALMON", // SKINCOLOR_SALMON
|
||||
"PINK", // SKINCOLOR_PINK
|
||||
"ROSE", // SKINCOLOR_ROSE
|
||||
"BRICK", // SKINCOLOR_BRICK
|
||||
"RUBY", // SKINCOLOR_RUBY
|
||||
"RASPBERRY", // SKINCOLOR_RASPBERRY
|
||||
"CHERRY", // SKINCOLOR_CHERRY
|
||||
"RED", // SKINCOLOR_RED
|
||||
"CRIMSON", // SKINCOLOR_CRIMSON
|
||||
"MAROON", // SKINCOLOR_MAROON
|
||||
"FLAME", // SKINCOLOR_FLAME
|
||||
"SCARLET", // SKINCOLOR_SCARLET
|
||||
"KETCHUP", // SKINCOLOR_KETCHUP
|
||||
"DAWN", // SKINCOLOR_DAWN
|
||||
"SUNSET", // SKINCOLOR_SUNSET
|
||||
"CREAMSICLE", // SKINCOLOR_CREAMSICLE
|
||||
"ORANGE", // SKINCOLOR_ORANGE
|
||||
"PUMPKIN", // SKINCOLOR_PUMPKIN
|
||||
"ROSEWOOD", // SKINCOLOR_ROSEWOOD
|
||||
"BURGUNDY", // SKINCOLOR_BURGUNDY
|
||||
"TANGERINE", // SKINCOLOR_TANGERINE
|
||||
"PEACH", // SKINCOLOR_PEACH
|
||||
"CARAMEL", // SKINCOLOR_CARAMEL
|
||||
"CREAM", // SKINCOLOR_CREAM
|
||||
"GOLD", // SKINCOLOR_GOLD
|
||||
"ROYAL", // SKINCOLOR_ROYAL
|
||||
"BRONZE", // SKINCOLOR_BRONZE
|
||||
"COPPER", // SKINCOLOR_COPPER
|
||||
"YELLOW", // SKINCOLOR_YELLOW
|
||||
"MUSTARD", // SKINCOLOR_MUSTARD
|
||||
"OLIVE", // SKINCOLOR_OLIVE
|
||||
"VOMIT", // SKINCOLOR_VOMIT
|
||||
"GARDEN", // SKINCOLOR_GARDEN
|
||||
"LIME", // SKINCOLOR_LIME
|
||||
"HANDHELD", // SKINCOLOR_HANDHELD
|
||||
"TEA", // SKINCOLOR_TEA
|
||||
"PISTACHIO", // SKINCOLOR_PISTACHIO
|
||||
"MOSS", // SKINCOLOR_MOSS
|
||||
"CAMOUFLAGE", // SKINCOLOR_CAMOUFLAGE
|
||||
"ROBOHOOD", // SKINCOLOR_ROBOHOOD
|
||||
"MINT", // SKINCOLOR_MINT
|
||||
"GREEN", // SKINCOLOR_GREEN
|
||||
"PINETREE", // SKINCOLOR_PINETREE
|
||||
"EMERALD", // SKINCOLOR_EMERALD
|
||||
"SWAMP", // SKINCOLOR_SWAMP
|
||||
"DREAM", // SKINCOLOR_DREAM
|
||||
"PLAGUE", // SKINCOLOR_PLAGUE
|
||||
"ALGAE", // SKINCOLOR_ALGAE
|
||||
"CARIBBEAN", // SKINCOLOR_CARIBBEAN
|
||||
"AQUA", // SKINCOLOR_AQUA
|
||||
"TEAL", // SKINCOLOR_TEAL
|
||||
"CYAN", // SKINCOLOR_CYAN
|
||||
"JAWZ", // SKINCOLOR_JAWZ
|
||||
"CERULEAN", // SKINCOLOR_CERULEAN
|
||||
"NAVY", // SKINCOLOR_NAVY
|
||||
"PLATINUM", // SKINCOLOR_PLATINUM
|
||||
"SLATE", // SKINCOLOR_SLATE
|
||||
"STEEL", // SKINCOLOR_STEEL
|
||||
"RUST", // SKINCOLOR_RUST
|
||||
"JET", // SKINCOLOR_JET
|
||||
"SAPPHIRE", // SKINCOLOR_SAPPHIRE
|
||||
"PERIWINKLE", // SKINCOLOR_PERIWINKLE
|
||||
"BLUE", // SKINCOLOR_BLUE
|
||||
"BLUEBERRY", // SKINCOLOR_BLUEBERRY
|
||||
"NOVA", // SKINCOLOR_NOVA
|
||||
"PASTEL", // SKINCOLOR_PASTEL
|
||||
"MOONSLAM", // SKINCOLOR_MOONSLAM
|
||||
"ULTRAVIOLET", // SKINCOLOR_ULTRAVIOLET
|
||||
"DUSK", // SKINCOLOR_DUSK
|
||||
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM
|
||||
"PURPLE", // SKINCOLOR_PURPLE
|
||||
"FUCHSIA", // SKINCOLOR_FUCHSIA
|
||||
"TOXIC", // SKINCOLOR_TOXIC
|
||||
"MAUVE", // SKINCOLOR_MAUVE
|
||||
"LAVENDER", // SKINCOLOR_LAVENDER
|
||||
"BYZANTIUM", // SKINCOLOR_BYZANTIUM
|
||||
"POMEGRANATE", // SKINCOLOR_POMEGRANATE
|
||||
"LILAC", // SKINCOLOR_LILAC
|
||||
|
||||
// Super special awesome Super flashing colors!
|
||||
|
||||
|
||||
|
||||
|
||||
// Special super colors
|
||||
// Super Sonic Yellow
|
||||
"SUPER1", // SKINCOLOR_SUPER1
|
||||
"SUPER2", // SKINCOLOR_SUPER2,
|
||||
"SUPER3", // SKINCOLOR_SUPER3,
|
||||
"SUPER4", // SKINCOLOR_SUPER4,
|
||||
"SUPER5", // SKINCOLOR_SUPER5,
|
||||
// Super Tails
|
||||
|
||||
// Super Tails Orange
|
||||
"TSUPER1", // SKINCOLOR_TSUPER1,
|
||||
"TSUPER2", // SKINCOLOR_TSUPER2,
|
||||
"TSUPER3", // SKINCOLOR_TSUPER3,
|
||||
"TSUPER4", // SKINCOLOR_TSUPER4,
|
||||
"TSUPER5", // SKINCOLOR_TSUPER5,
|
||||
// Super Knuckles
|
||||
|
||||
// Super Knuckles Red
|
||||
"KSUPER1", // SKINCOLOR_KSUPER1,
|
||||
"KSUPER2", // SKINCOLOR_KSUPER2,
|
||||
"KSUPER3", // SKINCOLOR_KSUPER3,
|
||||
"KSUPER4", // SKINCOLOR_KSUPER4,
|
||||
"KSUPER5" // SKINCOLOR_KSUPER5,
|
||||
"KSUPER5", // SKINCOLOR_KSUPER5,
|
||||
|
||||
// Hyper Sonic Pink
|
||||
"PSUPER1", // SKINCOLOR_PSUPER1,
|
||||
"PSUPER2", // SKINCOLOR_PSUPER2,
|
||||
"PSUPER3", // SKINCOLOR_PSUPER3,
|
||||
"PSUPER4", // SKINCOLOR_PSUPER4,
|
||||
"PSUPER5", // SKINCOLOR_PSUPER5,
|
||||
|
||||
// Hyper Sonic Blue
|
||||
"BSUPER1", // SKINCOLOR_BSUPER1,
|
||||
"BSUPER2", // SKINCOLOR_BSUPER2,
|
||||
"BSUPER3", // SKINCOLOR_BSUPER3,
|
||||
"BSUPER4", // SKINCOLOR_BSUPER4,
|
||||
"BSUPER5", // SKINCOLOR_BSUPER5,
|
||||
|
||||
// Aqua Super
|
||||
"ASUPER1", // SKINCOLOR_ASUPER1,
|
||||
"ASUPER2", // SKINCOLOR_ASUPER2,
|
||||
"ASUPER3", // SKINCOLOR_ASUPER3,
|
||||
"ASUPER4", // SKINCOLOR_ASUPER4,
|
||||
"ASUPER5", // SKINCOLOR_ASUPER5,
|
||||
|
||||
// Hyper Sonic Green
|
||||
"GSUPER1", // SKINCOLOR_GSUPER1,
|
||||
"GSUPER2", // SKINCOLOR_GSUPER2,
|
||||
"GSUPER3", // SKINCOLOR_GSUPER3,
|
||||
"GSUPER4", // SKINCOLOR_GSUPER4,
|
||||
"GSUPER5", // SKINCOLOR_GSUPER5,
|
||||
|
||||
// Hyper Sonic White
|
||||
"WSUPER1", // SKINCOLOR_WSUPER1,
|
||||
"WSUPER2", // SKINCOLOR_WSUPER2,
|
||||
"WSUPER3", // SKINCOLOR_WSUPER3,
|
||||
"WSUPER4", // SKINCOLOR_WSUPER4,
|
||||
"WSUPER5", // SKINCOLOR_WSUPER5,
|
||||
|
||||
// Creamy Super (Shadow?)
|
||||
"CSUPER1", // SKINCOLOR_CSUPER1,
|
||||
"CSUPER2", // SKINCOLOR_CSUPER2,
|
||||
"CSUPER3", // SKINCOLOR_CSUPER3,
|
||||
"CSUPER4", // SKINCOLOR_CSUPER4,
|
||||
"CSUPER5" // SKINCOLOR_CSUPER5,
|
||||
};
|
||||
|
||||
static const char *const POWERS_LIST[] = {
|
||||
|
@ -8215,6 +8331,7 @@ static const char *const POWERS_LIST[] = {
|
|||
"INGOOP" // In goop
|
||||
};
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
static const char *const KARTSTUFF_LIST[] = {
|
||||
"POSITION",
|
||||
"OLDPOSITION",
|
||||
|
@ -8223,6 +8340,7 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
"NEXTCHECK",
|
||||
"WAYPOINT",
|
||||
"STARPOSTWP",
|
||||
"STARPOSTFLIP",
|
||||
"RESPAWN",
|
||||
"DROPDASH",
|
||||
|
||||
|
@ -8294,8 +8412,12 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
|
||||
"ITEMBLINK",
|
||||
"ITEMBLINKMODE",
|
||||
"GETSPARKS"
|
||||
"GETSPARKS",
|
||||
"JAWZTARGETDELAY",
|
||||
"SPECTATEWAIT",
|
||||
"GROWCANCEL"
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *const HUDITEMS_LIST[] = {
|
||||
"LIVESNAME",
|
||||
|
@ -8518,13 +8640,7 @@ struct {
|
|||
{"RW_RAIL",RW_RAIL},
|
||||
|
||||
// Character flags (skinflags_t)
|
||||
{"SF_SUPER",SF_SUPER},
|
||||
{"SF_SUPERANIMS",SF_SUPERANIMS},
|
||||
{"SF_SUPERSPIN",SF_SUPERSPIN},
|
||||
{"SF_HIRES",SF_HIRES},
|
||||
{"SF_NOSKID",SF_NOSKID},
|
||||
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
|
||||
{"SF_RUNONWATER",SF_RUNONWATER},
|
||||
|
||||
// Character abilities!
|
||||
// Primary
|
||||
|
@ -9001,20 +9117,6 @@ static powertype_t get_power(const char *word)
|
|||
return pw_invulnerability;
|
||||
}
|
||||
|
||||
static kartstufftype_t get_kartstuff(const char *word)
|
||||
{ // Returns the vlaue of k_ enumerations
|
||||
kartstufftype_t i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
if (fastncmp("K_",word,2))
|
||||
word += 2; // take off the k_
|
||||
for (i = 0; i < NUMKARTSTUFF; i++)
|
||||
if (fastcmp(word, KARTSTUFF_LIST[i]))
|
||||
return i;
|
||||
deh_warning("Couldn't find power named 'k_%s'",word);
|
||||
return k_position;
|
||||
}
|
||||
|
||||
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
|
||||
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
|
||||
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
|
||||
|
@ -9351,6 +9453,7 @@ static inline int lib_freeslot(lua_State *L)
|
|||
CONS_Printf("State S_%s allocated.\n",word);
|
||||
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||
strcpy(FREE_STATES[i],word);
|
||||
freeslotusage[0][0]++;
|
||||
lua_pushinteger(L, i);
|
||||
r++;
|
||||
break;
|
||||
|
@ -9366,6 +9469,7 @@ static inline int lib_freeslot(lua_State *L)
|
|||
CONS_Printf("MobjType MT_%s allocated.\n",word);
|
||||
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||
strcpy(FREE_MOBJS[i],word);
|
||||
freeslotusage[1][0]++;
|
||||
lua_pushinteger(L, i);
|
||||
r++;
|
||||
break;
|
||||
|
@ -9735,6 +9839,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"modifiedgame")) {
|
||||
lua_pushboolean(L, modifiedgame && !savemoddata);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"majormods")) {
|
||||
lua_pushboolean(L, majormods);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"menuactive")) {
|
||||
lua_pushboolean(L, menuactive);
|
||||
return 1;
|
||||
|
@ -9806,6 +9913,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"indirectitemcooldown")) {
|
||||
lua_pushinteger(L, indirectitemcooldown);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"hyubgone")) {
|
||||
lua_pushinteger(L, hyubgone);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"thwompsactive")) {
|
||||
lua_pushboolean(L, thwompsactive);
|
||||
return 1;
|
||||
|
|
|
@ -37,6 +37,8 @@ void DEH_UnloadDehackedWad(UINT16 wad);
|
|||
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
|
||||
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
|
||||
|
||||
void DEH_UpdateMaxFreeslots(void);
|
||||
|
||||
void DEH_Check(void);
|
||||
|
||||
fixed_t get_number(const char *word);
|
||||
|
@ -54,7 +56,7 @@ extern const char *superactions[MAXRECURSION];
|
|||
extern UINT8 superstack;
|
||||
|
||||
// If the dehacked patch does not match this version, we throw a warning
|
||||
#define PATCHVERSION 210
|
||||
#define PATCHVERSION 1
|
||||
|
||||
#define MAXLINELEN 1024
|
||||
|
||||
|
|
|
@ -94,6 +94,9 @@ void I_FinishUpdate (void)
|
|||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
||||
if (cv_showping.value && netgame && consoleplayer != serverplayer)
|
||||
SCR_DisplayLocalPing();
|
||||
|
||||
//blast it to the screen
|
||||
// this code sucks
|
||||
//memcpy(dascreen,screens[0],screenwidth*screenheight);
|
||||
|
|
|
@ -150,9 +150,9 @@ extern FILE *logstream;
|
|||
// we use comprevision and compbranch instead.
|
||||
#else
|
||||
#define VERSION 100 // Game version
|
||||
#define SUBVERSION 2 // more precise version number
|
||||
#define VERSIONSTRING "v1.0.2"
|
||||
#define VERSIONSTRINGW L"v1.0.2"
|
||||
#define SUBVERSION 4 // more precise version number
|
||||
#define VERSIONSTRING "v1.0.4"
|
||||
#define VERSIONSTRINGW L"v1.0.4"
|
||||
// Hey! If you change this, add 1 to the MODVERSION below!
|
||||
// Otherwise we can't force updates!
|
||||
#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.
|
||||
// Only set it higher, not lower, obviously.
|
||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||
#define MODVERSION 2
|
||||
#define MODVERSION 4
|
||||
|
||||
// Filter consvars by version
|
||||
// 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...
|
||||
|
||||
#define MAXPLAYERS 16
|
||||
#define MAXSKINS 32
|
||||
#define MAXSKINS 128
|
||||
#define PLAYERSMASK (MAXPLAYERS-1)
|
||||
#define MAXPLAYERNAME 21
|
||||
|
||||
|
@ -256,6 +256,8 @@ typedef enum
|
|||
SKINCOLOR_GREY,
|
||||
SKINCOLOR_NICKEL,
|
||||
SKINCOLOR_BLACK,
|
||||
SKINCOLOR_FAIRY,
|
||||
SKINCOLOR_POPCORN,
|
||||
SKINCOLOR_SEPIA,
|
||||
SKINCOLOR_BEIGE,
|
||||
SKINCOLOR_BROWN,
|
||||
|
@ -263,12 +265,18 @@ typedef enum
|
|||
SKINCOLOR_SALMON,
|
||||
SKINCOLOR_PINK,
|
||||
SKINCOLOR_ROSE,
|
||||
SKINCOLOR_BRICK,
|
||||
SKINCOLOR_RUBY,
|
||||
SKINCOLOR_RASPBERRY,
|
||||
SKINCOLOR_CHERRY,
|
||||
SKINCOLOR_RED,
|
||||
SKINCOLOR_CRIMSON,
|
||||
SKINCOLOR_MAROON,
|
||||
SKINCOLOR_FLAME,
|
||||
SKINCOLOR_SCARLET,
|
||||
SKINCOLOR_KETCHUP,
|
||||
SKINCOLOR_DAWN,
|
||||
SKINCOLOR_SUNSET,
|
||||
SKINCOLOR_CREAMSICLE,
|
||||
SKINCOLOR_ORANGE,
|
||||
SKINCOLOR_PUMPKIN,
|
||||
|
@ -277,68 +285,130 @@ typedef enum
|
|||
SKINCOLOR_TANGERINE,
|
||||
SKINCOLOR_PEACH,
|
||||
SKINCOLOR_CARAMEL,
|
||||
SKINCOLOR_CREAM,
|
||||
SKINCOLOR_GOLD,
|
||||
SKINCOLOR_ROYAL,
|
||||
SKINCOLOR_BRONZE,
|
||||
SKINCOLOR_COPPER,
|
||||
SKINCOLOR_YELLOW,
|
||||
SKINCOLOR_MUSTARD,
|
||||
SKINCOLOR_OLIVE,
|
||||
SKINCOLOR_VOMIT,
|
||||
SKINCOLOR_GARDEN,
|
||||
SKINCOLOR_LIME,
|
||||
SKINCOLOR_HANDHELD,
|
||||
SKINCOLOR_TEA,
|
||||
SKINCOLOR_PISTACHIO,
|
||||
SKINCOLOR_ROBOHOOD,
|
||||
SKINCOLOR_MOSS,
|
||||
SKINCOLOR_CAMOUFLAGE,
|
||||
SKINCOLOR_ROBOHOOD,
|
||||
SKINCOLOR_MINT,
|
||||
SKINCOLOR_GREEN,
|
||||
SKINCOLOR_PINETREE,
|
||||
SKINCOLOR_EMERALD,
|
||||
SKINCOLOR_SWAMP,
|
||||
SKINCOLOR_DREAM,
|
||||
SKINCOLOR_PLAGUE,
|
||||
SKINCOLOR_ALGAE,
|
||||
SKINCOLOR_CARIBBEAN,
|
||||
SKINCOLOR_AQUA,
|
||||
SKINCOLOR_TEAL,
|
||||
SKINCOLOR_CYAN,
|
||||
SKINCOLOR_JAWZ, // Oni's torment
|
||||
SKINCOLOR_CERULEAN,
|
||||
SKINCOLOR_NAVY,
|
||||
SKINCOLOR_PLATINUM,
|
||||
SKINCOLOR_SLATE,
|
||||
SKINCOLOR_STEEL,
|
||||
SKINCOLOR_RUST,
|
||||
SKINCOLOR_JET,
|
||||
SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave - slender aphrodite has overcome me with longing for a girl
|
||||
SKINCOLOR_PERIWINKLE,
|
||||
SKINCOLOR_BLUE,
|
||||
SKINCOLOR_BLUEBERRY,
|
||||
SKINCOLOR_NOVA,
|
||||
SKINCOLOR_PASTEL,
|
||||
SKINCOLOR_MOONSLAM,
|
||||
SKINCOLOR_ULTRAVIOLET,
|
||||
SKINCOLOR_DUSK,
|
||||
SKINCOLOR_BUBBLEGUM,
|
||||
SKINCOLOR_PURPLE,
|
||||
SKINCOLOR_FUCHSIA,
|
||||
SKINCOLOR_TOXIC,
|
||||
SKINCOLOR_MAUVE,
|
||||
SKINCOLOR_LAVENDER,
|
||||
SKINCOLOR_BYZANTIUM,
|
||||
SKINCOLOR_POMEGRANATE,
|
||||
SKINCOLOR_LILAC,
|
||||
|
||||
// Careful! MAXSKINCOLORS cannot be greater than 0x40 -- Which it is now.
|
||||
// "Careful! MAXSKINCOLORS cannot be greater than 0x40 -- Which it is now."
|
||||
// (This comment is a dirty liar! This is only limited by the integer type, so 255 for UINT8.)
|
||||
MAXSKINCOLORS,
|
||||
|
||||
// Super special awesome Super flashing colors!
|
||||
// Super Sonic Yellow
|
||||
SKINCOLOR_SUPER1 = MAXSKINCOLORS,
|
||||
SKINCOLOR_SUPER2,
|
||||
SKINCOLOR_SUPER3,
|
||||
SKINCOLOR_SUPER4,
|
||||
SKINCOLOR_SUPER5,
|
||||
|
||||
// Super Tails
|
||||
// Super Tails Orange
|
||||
SKINCOLOR_TSUPER1,
|
||||
SKINCOLOR_TSUPER2,
|
||||
SKINCOLOR_TSUPER3,
|
||||
SKINCOLOR_TSUPER4,
|
||||
SKINCOLOR_TSUPER5,
|
||||
|
||||
// Super Knuckles
|
||||
// Super Knuckles Red
|
||||
SKINCOLOR_KSUPER1,
|
||||
SKINCOLOR_KSUPER2,
|
||||
SKINCOLOR_KSUPER3,
|
||||
SKINCOLOR_KSUPER4,
|
||||
SKINCOLOR_KSUPER5,
|
||||
|
||||
// Hyper Sonic Pink
|
||||
SKINCOLOR_PSUPER1,
|
||||
SKINCOLOR_PSUPER2,
|
||||
SKINCOLOR_PSUPER3,
|
||||
SKINCOLOR_PSUPER4,
|
||||
SKINCOLOR_PSUPER5,
|
||||
|
||||
// Hyper Sonic Blue
|
||||
SKINCOLOR_BSUPER1,
|
||||
SKINCOLOR_BSUPER2,
|
||||
SKINCOLOR_BSUPER3,
|
||||
SKINCOLOR_BSUPER4,
|
||||
SKINCOLOR_BSUPER5,
|
||||
|
||||
// Aqua Super
|
||||
SKINCOLOR_ASUPER1,
|
||||
SKINCOLOR_ASUPER2,
|
||||
SKINCOLOR_ASUPER3,
|
||||
SKINCOLOR_ASUPER4,
|
||||
SKINCOLOR_ASUPER5,
|
||||
|
||||
// Hyper Sonic Green
|
||||
SKINCOLOR_GSUPER1,
|
||||
SKINCOLOR_GSUPER2,
|
||||
SKINCOLOR_GSUPER3,
|
||||
SKINCOLOR_GSUPER4,
|
||||
SKINCOLOR_GSUPER5,
|
||||
|
||||
// Hyper Sonic White
|
||||
SKINCOLOR_WSUPER1,
|
||||
SKINCOLOR_WSUPER2,
|
||||
SKINCOLOR_WSUPER3,
|
||||
SKINCOLOR_WSUPER4,
|
||||
SKINCOLOR_WSUPER5,
|
||||
|
||||
// Creamy Super (Shadow?)
|
||||
SKINCOLOR_CSUPER1,
|
||||
SKINCOLOR_CSUPER2,
|
||||
SKINCOLOR_CSUPER3,
|
||||
SKINCOLOR_CSUPER4,
|
||||
SKINCOLOR_CSUPER5,
|
||||
|
||||
MAXTRANSLATIONS
|
||||
} skincolors_t;
|
||||
|
||||
|
@ -471,13 +541,17 @@ INT32 I_GetKey(void);
|
|||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
|
||||
// Floating point comparison epsilons from float.h
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON 1.1920928955078125e-7f
|
||||
#endif
|
||||
|
||||
#ifndef DBL_EPSILON
|
||||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#define DBL_EPSILON 2.2204460492503131e-16l
|
||||
#endif
|
||||
|
||||
// An assert-type mechanism.
|
||||
|
|
|
@ -54,9 +54,9 @@ extern boolean gamecomplete;
|
|||
|
||||
// Set if homebrew PWAD stuff has been added.
|
||||
extern boolean modifiedgame;
|
||||
extern boolean majormods;
|
||||
extern UINT16 mainwads;
|
||||
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 metalrecording;
|
||||
|
||||
|
@ -280,6 +280,8 @@ typedef struct
|
|||
#define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu
|
||||
#define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level
|
||||
|
||||
#define LF2_EXISTSHACK 128 ///< Map lump exists; as noted, a single-bit hack that can be freely movable to other variables without concern.
|
||||
|
||||
// Save override
|
||||
#define SAVE_NEVER -1
|
||||
#define SAVE_DEFAULT 0
|
||||
|
@ -465,6 +467,7 @@ extern boolean comeback;
|
|||
extern SINT8 battlewanted[4];
|
||||
extern tic_t wantedcalcdelay;
|
||||
extern tic_t indirectitemcooldown;
|
||||
extern tic_t hyubgone;
|
||||
extern tic_t mapreset;
|
||||
extern UINT8 nospectategrief;
|
||||
extern boolean thwompsactive;
|
||||
|
|
|
@ -438,7 +438,7 @@ static const char *credits[] = {
|
|||
"\"ZarroTsu\"",
|
||||
"",
|
||||
"\1Support Programming",
|
||||
"\"fickle\"",
|
||||
"Colette \"fickleheart\" Bordelon",
|
||||
"\"Lat\'\"",
|
||||
"\"Monster Iestyn\"",
|
||||
"\"Shuffle\"",
|
||||
|
@ -479,40 +479,10 @@ static const char *credits[] = {
|
|||
"\"VAdaPEGA\"",
|
||||
"\"VelocitOni\"",
|
||||
"",
|
||||
"\1Music", // Can't list song names here, so we're listing artists
|
||||
"\"Arrow\"",
|
||||
"Jonny Atma",
|
||||
"Moot Booxle", // Booxlé, add the accent char later?
|
||||
"Malcolm Brown",
|
||||
"Karl Brueggemann",
|
||||
"\1Music",
|
||||
"\"DrTapeworm\"",
|
||||
"\"Elwood\"",
|
||||
"Wesley \"Charyb\" Gillebaard",
|
||||
"\"gxf4c3\"",
|
||||
"James \"SeventhSentinel\" Hall",
|
||||
"Chris Holland",
|
||||
"Johnny \"J\"",
|
||||
"Masato Kouda",
|
||||
"Fumie Kumatani",
|
||||
"Luke Kwing",
|
||||
"James Landino",
|
||||
"\"Lange\"",
|
||||
"Takenobu Mitsuyoshi",
|
||||
"\"Nib Roc\"",
|
||||
"Tomoya Ohtani",
|
||||
"Vincent Rubinetti",
|
||||
"Jun Senoue",
|
||||
"\"SSNTails\"",
|
||||
"Michael \"MaxieDaMan\" Staple",
|
||||
"Simon Stalenhag", // Stålenhag, add the accent char later?
|
||||
"\"Synthescissor\"",
|
||||
"Yuko Takehara",
|
||||
"Tony Thai",
|
||||
"\"The8BitDrummer\"",
|
||||
"Kenichi Tokoi",
|
||||
"\"Tokyo Active NEETs\"",
|
||||
"\"xaki\"",
|
||||
"Michiru Yamane",
|
||||
"",
|
||||
"\1Lead Level Design",
|
||||
"\"Blitz-T\"",
|
||||
|
@ -586,7 +556,7 @@ static struct {
|
|||
// This Tyler52 gag is troublesome
|
||||
// Alignment should be ((spaces+1 * 100) + (headers+1 * 38) + (lines * 15))
|
||||
// Current max image spacing: (200*17)
|
||||
{112, (15*100)+(17*38)+(102*15), "TYLER52", SKINCOLOR_NONE},
|
||||
{112, (15*100)+(17*38)+(72*15), "TYLER52", SKINCOLOR_NONE},
|
||||
{0, 0, NULL, SKINCOLOR_NONE}
|
||||
};
|
||||
|
||||
|
@ -641,7 +611,7 @@ void F_CreditDrawer(void)
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -1133,6 +1103,10 @@ void F_StartWaitingPlayers(void)
|
|||
finalecount = 0;
|
||||
|
||||
randskin = M_RandomKey(numskins);
|
||||
|
||||
if (waitcolormap)
|
||||
Z_Free(waitcolormap);
|
||||
|
||||
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
|
|
14
src/f_wipe.c
14
src/f_wipe.c
|
@ -26,6 +26,7 @@
|
|||
#include "console.h"
|
||||
#include "d_main.h"
|
||||
#include "m_misc.h" // movie mode
|
||||
#include "d_clisrv.h" // So the network state can be updated during the wipe
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -96,7 +97,7 @@ static fixed_t paldiv;
|
|||
* \return fademask_t for lump
|
||||
*/
|
||||
static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
||||
static char lumpname[10] = "FADEmmss";
|
||||
static char lumpname[9] = "FADEmmss";
|
||||
static fademask_t fm = {NULL,0,0,0,0,0};
|
||||
lumpnum_t lumpnum;
|
||||
UINT8 *lump, *mask;
|
||||
|
@ -106,7 +107,14 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
|||
if (masknum > 99 || scrnnum > 99)
|
||||
goto freemask;
|
||||
|
||||
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
|
||||
// SRB2Kart: This suddenly triggers ERRORMODE now
|
||||
//sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
|
||||
|
||||
lumpname[4] = '0'+(masknum/10);
|
||||
lumpname[5] = '0'+(masknum%10);
|
||||
|
||||
lumpname[6] = '0'+(scrnnum/10);
|
||||
lumpname[7] = '0'+(scrnnum%10);
|
||||
|
||||
lumpnum = W_CheckNumForName(lumpname);
|
||||
if (lumpnum == LUMPERROR)
|
||||
|
@ -375,6 +383,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
||||
NetKeepAlive(); // Update the network so we don't cause timeouts
|
||||
}
|
||||
WipeInAction = false;
|
||||
#endif
|
||||
|
|
|
@ -88,7 +88,8 @@ typedef enum
|
|||
REFRESHDIR_WARNING = 4,
|
||||
REFRESHDIR_ERROR = 8,
|
||||
REFRESHDIR_NOTLOADED = 16,
|
||||
REFRESHDIR_MAX = 32
|
||||
REFRESHDIR_MAX = 32,
|
||||
REFRESHDIR_GAMEDATA = 64
|
||||
} refreshdir_enum;
|
||||
|
||||
void closefilemenu(boolean validsize);
|
||||
|
|
372
src/g_game.c
372
src/g_game.c
|
@ -16,6 +16,7 @@
|
|||
#include "d_main.h"
|
||||
#include "d_player.h"
|
||||
#include "f_finale.h"
|
||||
#include "filesrch.h" // for refreshdirmenu
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "i_system.h"
|
||||
|
@ -86,11 +87,11 @@ INT16 lastmapsaved = 0; // Last map we auto-saved at
|
|||
boolean gamecomplete = false;
|
||||
|
||||
UINT16 mainwads = 0;
|
||||
boolean modifiedgame; // Set if homebrew PWAD stuff has been added.
|
||||
boolean modifiedgame = false; // Set if homebrew PWAD stuff has been added.
|
||||
boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been added.
|
||||
boolean savemoddata = false;
|
||||
UINT8 paused;
|
||||
UINT8 modeattacking = ATTACKING_NONE;
|
||||
boolean disableSpeedAdjust = true;
|
||||
boolean imcontinuing = false;
|
||||
boolean runemeraldmanager = false;
|
||||
|
||||
|
@ -265,6 +266,7 @@ SINT8 pickedvote; // What vote the host rolls
|
|||
SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points
|
||||
tic_t wantedcalcdelay; // Time before it recalculates WANTED
|
||||
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
|
||||
tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled
|
||||
tic_t mapreset; // Map reset delay when enough players have joined an empty game
|
||||
UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing
|
||||
boolean thwompsactive; // Thwomps activate on lap 2
|
||||
|
@ -435,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}};
|
||||
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
|
||||
consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -752,16 +757,21 @@ void G_SetNightsRecords(void)
|
|||
}*/
|
||||
|
||||
// for consistency among messages: this modifies the game and removes savemoddata.
|
||||
void G_SetGameModified(boolean silent)
|
||||
void G_SetGameModified(boolean silent, boolean major)
|
||||
{
|
||||
if (modifiedgame && !savemoddata)
|
||||
if ((majormods && modifiedgame) || !mainwads || (refreshdirmenu & REFRESHDIR_GAMEDATA)) // new gamedata amnesty?
|
||||
return;
|
||||
|
||||
modifiedgame = true;
|
||||
savemoddata = false;
|
||||
|
||||
if (!major)
|
||||
return;
|
||||
|
||||
//savemoddata = false; -- there is literally no reason to do this anymore.
|
||||
majormods = true;
|
||||
|
||||
if (!silent)
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n"));
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play record attack.\n"));
|
||||
|
||||
// If in record attack recording, cancel it.
|
||||
if (modeattacking)
|
||||
|
@ -1209,7 +1219,7 @@ boolean camspin, camspin2, camspin3, camspin4;
|
|||
|
||||
static fixed_t forwardmove[2] = {25<<FRACBITS>>16, 50<<FRACBITS>>16};
|
||||
static fixed_t sidemove[2] = {2<<FRACBITS>>16, 4<<FRACBITS>>16};
|
||||
static fixed_t angleturn[3] = {400, 800, 200}; // + slow turn
|
||||
static fixed_t angleturn[3] = {KART_FULLTURN/2, KART_FULLTURN, KART_FULLTURN/4}; // + slow turn
|
||||
|
||||
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
{
|
||||
|
@ -1352,41 +1362,30 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
// let movement keys cancel each other out
|
||||
if (turnright && !(turnleft))
|
||||
{
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - (angleturn[tspeed] * realtics));
|
||||
cmd->driftturn = (INT16)(cmd->driftturn - (angleturn[tspeed] * realtics));
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - (angleturn[tspeed]));
|
||||
cmd->driftturn = (INT16)(cmd->driftturn - (angleturn[tspeed]));
|
||||
side += sidemove[1];
|
||||
}
|
||||
else if (turnleft && !(turnright))
|
||||
{
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + (angleturn[tspeed] * realtics));
|
||||
cmd->driftturn = (INT16)(cmd->driftturn + (angleturn[tspeed] * realtics));
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + (angleturn[tspeed]));
|
||||
cmd->driftturn = (INT16)(cmd->driftturn + (angleturn[tspeed]));
|
||||
side -= sidemove[1];
|
||||
}
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
{
|
||||
// JOYAXISRANGE should be 1023 (divide by 1024)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - (((axis * angleturn[1]) >> 10) * realtics)); // ANALOG!
|
||||
cmd->driftturn = (INT16)(cmd->driftturn - (((axis * angleturn[1]) >> 10) * realtics));
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - (((axis * angleturn[1]) >> 10))); // ANALOG!
|
||||
cmd->driftturn = (INT16)(cmd->driftturn - (((axis * angleturn[1]) >> 10)));
|
||||
side += ((axis * sidemove[0]) >> 10);
|
||||
}
|
||||
|
||||
// Specator mouse turning
|
||||
if (player->spectator)
|
||||
{
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((mousex*(encoremode ? -1 : 1)*8) * realtics));
|
||||
cmd->driftturn = (INT16)(cmd->driftturn - ((mousex*(encoremode ? -1 : 1)*8) * realtics));
|
||||
}
|
||||
|
||||
// Speed bump strafing
|
||||
if (!demoplayback && ((player->pflags & PF_FORCESTRAFE) || (player->kartstuff[k_pogospring])))
|
||||
{
|
||||
if (turnright)
|
||||
side += sidemove[1];
|
||||
if (turnleft)
|
||||
side -= sidemove[1];
|
||||
if (analogjoystickmove && axis != 0)
|
||||
{
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
side += ((axis * sidemove[0]) >> 10);
|
||||
}
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((mousex*(encoremode ? -1 : 1)*8)));
|
||||
cmd->driftturn = (INT16)(cmd->driftturn - ((mousex*(encoremode ? -1 : 1)*8)));
|
||||
}
|
||||
|
||||
if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls
|
||||
|
@ -1531,15 +1530,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
else if (side < -MAXPLMOVE)
|
||||
side = -MAXPLMOVE;
|
||||
|
||||
// No additional acceleration when moving forward/backward and strafing simultaneously.
|
||||
// do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this.
|
||||
// SRB2Kart: We don't need this; we WANT bounce strafing to plain stack on top of normal movement.
|
||||
/*if (!bouncestrafe && forward && side)
|
||||
{
|
||||
forward = FixedMul(forward, 3*FRACUNIT/4);
|
||||
side = FixedMul(side, 3*FRACUNIT/4);
|
||||
}*/
|
||||
|
||||
if (forward || side)
|
||||
{
|
||||
cmd->forwardmove = (SINT8)(cmd->forwardmove + forward);
|
||||
|
@ -1549,19 +1539,21 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
//{ SRB2kart - Drift support
|
||||
// Not grouped with the rest of turn stuff because it needs to know what buttons you're pressing for rubber-burn turn
|
||||
// limit turning to angleturn[1] to stop mouselook letting you look too fast
|
||||
if (cmd->angleturn > (angleturn[1] * realtics))
|
||||
cmd->angleturn = (angleturn[1] * realtics);
|
||||
else if (cmd->angleturn < (-angleturn[1] * realtics))
|
||||
cmd->angleturn = (-angleturn[1] * realtics);
|
||||
if (cmd->angleturn > (angleturn[1]))
|
||||
cmd->angleturn = (angleturn[1]);
|
||||
else if (cmd->angleturn < (-angleturn[1]))
|
||||
cmd->angleturn = (-angleturn[1]);
|
||||
|
||||
if (cmd->driftturn > (angleturn[1] * realtics))
|
||||
cmd->driftturn = (angleturn[1] * realtics);
|
||||
else if (cmd->driftturn < (-angleturn[1] * realtics))
|
||||
cmd->driftturn = (-angleturn[1] * realtics);
|
||||
if (cmd->driftturn > (angleturn[1]))
|
||||
cmd->driftturn = (angleturn[1]);
|
||||
else if (cmd->driftturn < (-angleturn[1]))
|
||||
cmd->driftturn = (-angleturn[1]);
|
||||
|
||||
if (player->mo)
|
||||
cmd->angleturn = K_GetKartTurnValue(player, cmd->angleturn);
|
||||
|
||||
cmd->angleturn *= realtics;
|
||||
|
||||
// SRB2kart - no additional angle if not moving
|
||||
if (((player->mo && player->speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|
@ -1571,6 +1563,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
lang += (cmd->angleturn<<16);
|
||||
|
||||
cmd->angleturn = (INT16)(lang >> 16);
|
||||
cmd->latency = modeattacking ? 0 : (leveltime & 0xFF); // Send leveltime when this tic was generated to the server for control lag calculations
|
||||
|
||||
if (!hu_stopped)
|
||||
{
|
||||
|
@ -1612,10 +1605,26 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
}
|
||||
}
|
||||
|
||||
/* Lua: Allow this hook to overwrite ticcmd.
|
||||
We check if we're actually in a level because for some reason this Hook would run in menus and on the titlescreen otherwise.
|
||||
Be aware that within this hook, nothing but this player's cmd can be edited (otherwise we'd run in some pretty bad synching problems since this is clientsided, or something)
|
||||
|
||||
Possible usages for this are:
|
||||
-Forcing the player to perform an action, which could otherwise require terrible, terrible hacking to replicate.
|
||||
-Preventing the player to perform an action, which would ALSO require some weirdo hacks.
|
||||
-Making some galaxy brain autopilot Lua if you're a masochist
|
||||
-Making a Mario Kart 8 Deluxe tier baby mode that steers you away from walls and whatnot. You know what, do what you want!
|
||||
*/
|
||||
#ifdef HAVE_BLUA
|
||||
if (gamestate == GS_LEVEL)
|
||||
LUAh_PlayerCmd(player, cmd);
|
||||
#endif
|
||||
|
||||
//Reset away view if a command is given.
|
||||
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
||||
&& displayplayer != consoleplayer && ssplayer == 1)
|
||||
displayplayer = consoleplayer;
|
||||
|
||||
}
|
||||
|
||||
// User has designated that they want
|
||||
|
@ -1814,80 +1823,6 @@ static INT32 spectatedelay, spectatedelay2, spectatedelay3, spectatedelay4 = 0;
|
|||
//
|
||||
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
|
||||
if (gameaction == ga_nothing && !singledemo &&
|
||||
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
|
||||
|
@ -1965,6 +1900,80 @@ boolean G_Responder(event_t *ev)
|
|||
if (HU_Responder(ev))
|
||||
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
|
||||
G_MapEventsToControls(ev);
|
||||
|
||||
|
@ -2154,6 +2163,9 @@ void G_Ticker(boolean run)
|
|||
players[i].kartstuff[k_throwdir] = 0;
|
||||
|
||||
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
|
||||
|
||||
// Use the leveltime sent in the player's ticcmd to determine control lag
|
||||
cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2348,6 +2360,7 @@ void G_PlayerReborn(INT32 player)
|
|||
UINT8 skincolor;
|
||||
INT32 skin;
|
||||
tic_t jointime;
|
||||
UINT8 splitscreenindex;
|
||||
boolean spectator;
|
||||
INT16 bot;
|
||||
SINT8 pity;
|
||||
|
@ -2362,6 +2375,7 @@ void G_PlayerReborn(INT32 player)
|
|||
INT32 bumper;
|
||||
INT32 comebackpoints;
|
||||
INT32 wanted;
|
||||
INT32 respawnflip;
|
||||
boolean songcredit = false;
|
||||
|
||||
score = players[player].score;
|
||||
|
@ -2371,6 +2385,7 @@ void G_PlayerReborn(INT32 player)
|
|||
ctfteam = players[player].ctfteam;
|
||||
exiting = players[player].exiting;
|
||||
jointime = players[player].jointime;
|
||||
splitscreenindex = players[player].splitscreenindex;
|
||||
spectator = players[player].spectator;
|
||||
pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE|PF_WANTSTOJOIN));
|
||||
|
||||
|
@ -2402,6 +2417,7 @@ void G_PlayerReborn(INT32 player)
|
|||
starposty = players[player].starposty;
|
||||
starpostz = players[player].starpostz;
|
||||
starpostnum = players[player].starpostnum;
|
||||
respawnflip = players[player].kartstuff[k_starpostflip]; //SRB2KART
|
||||
starpostangle = players[player].starpostangle;
|
||||
jumpfactor = players[player].jumpfactor;
|
||||
thokitem = players[player].thokitem;
|
||||
|
@ -2467,6 +2483,7 @@ void G_PlayerReborn(INT32 player)
|
|||
p->pflags = pflags;
|
||||
p->ctfteam = ctfteam;
|
||||
p->jointime = jointime;
|
||||
p->splitscreenindex = splitscreenindex;
|
||||
p->spectator = spectator;
|
||||
|
||||
// save player config truth reborn
|
||||
|
@ -2521,6 +2538,7 @@ void G_PlayerReborn(INT32 player)
|
|||
p->kartstuff[k_comebacktimer] = comebacktime;
|
||||
p->kartstuff[k_wanted] = wanted;
|
||||
p->kartstuff[k_eggmanblame] = -1;
|
||||
p->kartstuff[k_starpostflip] = respawnflip;
|
||||
|
||||
// Don't do anything immediately
|
||||
p->pflags |= PF_USEDOWN;
|
||||
|
@ -3173,7 +3191,7 @@ INT16 G_SometimesGetDifferentGametype(void)
|
|||
break;
|
||||
case 1: // sometimes
|
||||
default:
|
||||
encorepossible = M_RandomChance(FRACUNIT>>3);
|
||||
encorepossible = M_RandomChance(FRACUNIT>>2);
|
||||
break;
|
||||
}
|
||||
if (encorepossible != (boolean)cv_kartencore.value)
|
||||
|
@ -3188,12 +3206,12 @@ INT16 G_SometimesGetDifferentGametype(void)
|
|||
randmapbuffer[NUMMAPS] = 1; // every other vote (or always if !encorepossible)
|
||||
break;
|
||||
case 1: // sometimes
|
||||
randmapbuffer[NUMMAPS] = 10; // ...every two cups?
|
||||
randmapbuffer[NUMMAPS] = 5; // per "cup"
|
||||
break;
|
||||
default:
|
||||
// fallthrough - happens when clearing buffer, but needs a reasonable countdown if cvar is modified
|
||||
case 2: // frequent
|
||||
randmapbuffer[NUMMAPS] = 5; // per "cup"
|
||||
randmapbuffer[NUMMAPS] = 2; // ...every 1/2th-ish cup?
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3940,7 +3958,6 @@ void G_LoadGameData(void)
|
|||
// Saves the main data file, which stores information such as emblems found, etc.
|
||||
void G_SaveGameData(boolean force)
|
||||
{
|
||||
const boolean wasmodified = modifiedgame;
|
||||
size_t length;
|
||||
INT32 i, j;
|
||||
UINT8 btemp;
|
||||
|
@ -3957,9 +3974,7 @@ void G_SaveGameData(boolean force)
|
|||
return;
|
||||
}
|
||||
|
||||
if (force) // SRB2Kart: for enabling unlocks online, even if the game is modified
|
||||
modifiedgame = savemoddata; // L-let's just sort of... hack around the cheat protection, because I'm too worried about just removing it @@;
|
||||
else if (modifiedgame && !savemoddata)
|
||||
if (majormods && !force)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
@ -3972,7 +3987,7 @@ void G_SaveGameData(boolean force)
|
|||
WRITEUINT32(save_p, totalplaytime);
|
||||
WRITEUINT32(save_p, matchesplayed);
|
||||
|
||||
btemp = (UINT8)(savemoddata || modifiedgame);
|
||||
btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded
|
||||
WRITEUINT8(save_p, btemp);
|
||||
|
||||
// TODO put another cipher on these things? meh, I don't care...
|
||||
|
@ -4058,9 +4073,6 @@ void G_SaveGameData(boolean force)
|
|||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
||||
if (force) // Eeeek, I'm sorry for my sins!
|
||||
modifiedgame = wasmodified;
|
||||
}
|
||||
|
||||
#define VERSIONSIZE 16
|
||||
|
@ -4561,6 +4573,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
|
|||
dest[i].aiming = (INT16)SHORT(src[i].aiming);
|
||||
dest[i].buttons = (UINT16)SHORT(src[i].buttons);
|
||||
dest[i].driftturn = (INT16)SHORT(src[i].driftturn);
|
||||
dest[i].latency = (INT16)SHORT(src[i].latency);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
@ -4759,7 +4772,8 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
// GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic.
|
||||
if (abs(ghost->x-oldghost.x) > MAXMOM
|
||||
|| abs(ghost->y-oldghost.y) > MAXMOM
|
||||
|| abs(ghost->z-oldghost.z) > MAXMOM)
|
||||
|| abs(ghost->z-oldghost.z) > MAXMOM
|
||||
|| (leveltime & 255) == 1) // Hack to enable slightly nicer resyncing
|
||||
{
|
||||
oldghost.x = ghost->x;
|
||||
oldghost.y = ghost->y;
|
||||
|
@ -4773,8 +4787,8 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
{
|
||||
// For moving normally:
|
||||
// Store one full byte of movement, plus one byte of fractional movement.
|
||||
INT16 momx = (INT16)((ghost->x-oldghost.x)>>8);
|
||||
INT16 momy = (INT16)((ghost->y-oldghost.y)>>8);
|
||||
INT16 momx = (INT16)((ghost->x-oldghost.x + (1<<4))>>8);
|
||||
INT16 momy = (INT16)((ghost->y-oldghost.y + (1<<4))>>8);
|
||||
if (momx != oldghost.momx
|
||||
|| momy != oldghost.momy)
|
||||
{
|
||||
|
@ -4784,7 +4798,7 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
WRITEINT16(demo_p,momx);
|
||||
WRITEINT16(demo_p,momy);
|
||||
}
|
||||
momx = (INT16)((ghost->z-oldghost.z)>>8);
|
||||
momx = (INT16)((ghost->z-oldghost.z + (1<<4))>>8);
|
||||
if (momx != oldghost.momz)
|
||||
{
|
||||
oldghost.momz = momx;
|
||||
|
@ -4888,8 +4902,9 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
void G_ConsGhostTic(void)
|
||||
{
|
||||
UINT8 ziptic;
|
||||
UINT16 px,py,pz,gx,gy,gz;
|
||||
fixed_t px,py,pz,gx,gy,gz;
|
||||
mobj_t *testmo;
|
||||
fixed_t syncleeway;
|
||||
boolean nightsfail = false;
|
||||
|
||||
if (!demo_p || !demo_start)
|
||||
|
@ -4906,6 +4921,7 @@ void G_ConsGhostTic(void)
|
|||
oldghost.x = READFIXED(demo_p);
|
||||
oldghost.y = READFIXED(demo_p);
|
||||
oldghost.z = READFIXED(demo_p);
|
||||
syncleeway = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4919,6 +4935,7 @@ void G_ConsGhostTic(void)
|
|||
oldghost.x += oldghost.momx;
|
||||
oldghost.y += oldghost.momy;
|
||||
oldghost.z += oldghost.momz;
|
||||
syncleeway = FRACUNIT;
|
||||
}
|
||||
if (ziptic & GZT_ANGLE)
|
||||
demo_p++;
|
||||
|
@ -4984,14 +5001,14 @@ void G_ConsGhostTic(void)
|
|||
}
|
||||
|
||||
// Re-synchronise
|
||||
px = testmo->x>>FRACBITS;
|
||||
py = testmo->y>>FRACBITS;
|
||||
pz = testmo->z>>FRACBITS;
|
||||
gx = oldghost.x>>FRACBITS;
|
||||
gy = oldghost.y>>FRACBITS;
|
||||
gz = oldghost.z>>FRACBITS;
|
||||
px = testmo->x;
|
||||
py = testmo->y;
|
||||
pz = testmo->z;
|
||||
gx = oldghost.x;
|
||||
gy = oldghost.y;
|
||||
gz = oldghost.z;
|
||||
|
||||
if (nightsfail || px != gx || py != gy || pz != gz)
|
||||
if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway)
|
||||
{
|
||||
if (demosynced)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||
|
@ -5102,17 +5119,16 @@ void G_GhostTicker(void)
|
|||
INT32 type = -1;
|
||||
if (g->mo->skin)
|
||||
{
|
||||
skin_t *skin = (skin_t *)g->mo->skin;
|
||||
switch (ziptic & EZT_THOKMASK)
|
||||
{
|
||||
case EZT_THOK:
|
||||
type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
|
||||
type = (UINT32)mobjinfo[MT_PLAYER].painchance;
|
||||
break;
|
||||
case EZT_SPIN:
|
||||
type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
|
||||
type = (UINT32)mobjinfo[MT_PLAYER].damage;
|
||||
break;
|
||||
case EZT_REV:
|
||||
type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
|
||||
type = (UINT32)mobjinfo[MT_PLAYER].raisestate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5147,22 +5163,20 @@ void G_GhostTicker(void)
|
|||
if (ziptic & EZT_HIT)
|
||||
{ // Spawn hit poofs for killing things!
|
||||
UINT16 i, count = READUINT16(g->p), health;
|
||||
UINT32 type;
|
||||
//UINT32 type;
|
||||
fixed_t x,y,z;
|
||||
angle_t angle;
|
||||
mobj_t *poof;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
g->p += 4; // reserved
|
||||
type = READUINT32(g->p);
|
||||
g->p += 4; // backwards compat., type used to be here
|
||||
health = READUINT16(g->p);
|
||||
x = READFIXED(g->p);
|
||||
y = READFIXED(g->p);
|
||||
z = READFIXED(g->p);
|
||||
angle = READANGLE(g->p);
|
||||
if (!(mobjinfo[type].flags & MF_SHOOTABLE)
|
||||
|| !(mobjinfo[type].flags & (MF_ENEMY|MF_MONITOR))
|
||||
|| health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
|
||||
if (health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
|
||||
continue;
|
||||
poof = P_SpawnMobj(x, y, z, MT_GHOST);
|
||||
poof->angle = angle;
|
||||
|
@ -5918,6 +5932,32 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
// Skin not loaded?
|
||||
if (!SetPlayerSkin(0, skin))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demoplayback = false;
|
||||
titledemo = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demoplayback = false;
|
||||
titledemo = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Z_Free(pdemoname);
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
|
@ -5949,9 +5989,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
P_SetRandSeed(randseed);
|
||||
G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
||||
|
||||
// Set skin
|
||||
SetPlayerSkin(0, skin);
|
||||
|
||||
// Set color
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
if (!stricmp(KartColor_Names[i],color)) // SRB2kart
|
||||
|
@ -6001,6 +6038,7 @@ void G_AddGhost(char *defdemoname)
|
|||
UINT8 *buffer,*p;
|
||||
mapthing_t *mthing;
|
||||
UINT16 count, ghostversion;
|
||||
skin_t *ghskin = &skins[0];
|
||||
|
||||
name[16] = '\0';
|
||||
skin[16] = '\0';
|
||||
|
@ -6146,6 +6184,21 @@ void G_AddGhost(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
if (!stricmp(skins[i].name,skin))
|
||||
{
|
||||
ghskin = &skins[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == numskins)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid character.\n"), pdemoname);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
gh = Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL);
|
||||
gh->next = ghosts;
|
||||
gh->buffer = buffer;
|
||||
|
@ -6191,14 +6244,7 @@ void G_AddGhost(char *defdemoname)
|
|||
gh->oldmo.z = gh->mo->z;
|
||||
|
||||
// Set skin
|
||||
gh->mo->skin = &skins[0];
|
||||
for (i = 0; i < numskins; i++)
|
||||
if (!stricmp(skins[i].name,skin))
|
||||
{
|
||||
gh->mo->skin = &skins[i];
|
||||
break;
|
||||
}
|
||||
gh->oldmo.skin = gh->mo->skin;
|
||||
gh->mo->skin = gh->oldmo.skin = ghskin;
|
||||
|
||||
// Set color
|
||||
gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor;
|
||||
|
|
|
@ -56,6 +56,7 @@ extern INT16 rw_maximums[NUM_WEAPONS];
|
|||
// 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_songcredits;
|
||||
extern consvar_t cv_pauseifunfocused;
|
||||
//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_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;
|
||||
|
@ -66,7 +67,6 @@ extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis
|
|||
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3;
|
||||
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4;
|
||||
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
|
||||
extern consvar_t cv_splitplayers;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -227,7 +227,7 @@ boolean G_GetRetryFlag(void);
|
|||
void G_LoadGameData(void);
|
||||
void G_LoadGameSettings(void);
|
||||
|
||||
void G_SetGameModified(boolean silent);
|
||||
void G_SetGameModified(boolean silent, boolean major);
|
||||
|
||||
void G_SetGamestate(gamestate_t newstate);
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void G_MapEventsToControls(event_t *ev)
|
|||
|
||||
case ev_joystick2: // buttons are virtual keys
|
||||
i = ev->data1;
|
||||
if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on)
|
||||
if (i >= JOYAXISSET || menuactive)
|
||||
break;
|
||||
if (ev->data2 != INT32_MAX) joy2xmove[i] = ev->data2;
|
||||
if (ev->data3 != INT32_MAX) joy2ymove[i] = ev->data3;
|
||||
|
|
|
@ -201,7 +201,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
|||
// (do not accept hit with the extensions)
|
||||
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
|
||||
frac = num / den;
|
||||
if (frac < 0.0 || frac > 1.0)
|
||||
if (frac < 0.0l || frac > 1.0l)
|
||||
return NULL;
|
||||
|
||||
// now get the frac along the BSP line
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "../v_video.h"
|
||||
#include "hw_clip.h"
|
||||
#include "hw_glob.h"
|
||||
#include "../r_main.h"
|
||||
#include "../r_state.h"
|
||||
#include "../tables.h"
|
||||
#include "r_opengl/r_opengl.h"
|
||||
|
@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(void)
|
|||
|
||||
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
|
||||
|
||||
float render_fov = FIXED_TO_FLOAT(cv_grfov.value);
|
||||
float render_fov = FIXED_TO_FLOAT(cv_fov.value);
|
||||
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
|
||||
float render_multiplier = 64.0f / render_fovratio / RMUL;
|
||||
|
||||
|
|
|
@ -61,9 +61,6 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
|
|||
// ==========================================================================
|
||||
|
||||
// Constants
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
#define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360
|
||||
|
||||
void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/;
|
||||
|
|
|
@ -86,12 +86,10 @@ static UINT32 atohex(const char *s);
|
|||
static void CV_filtermode_ONChange(void);
|
||||
static void CV_anisotropic_ONChange(void);
|
||||
static void CV_FogDensity_ONChange(void);
|
||||
static void CV_grFov_OnChange(void);
|
||||
// ==========================================================================
|
||||
// 3D ENGINE COMMANDS & CONSOLE VARS
|
||||
// ==========================================================================
|
||||
|
||||
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
||||
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
||||
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
|
||||
|
@ -112,7 +110,6 @@ static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NUL
|
|||
|
||||
static float HWRWipeCounter = 1.0f;
|
||||
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grFov_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
|
||||
CV_FogDensity_ONChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -5263,7 +5260,8 @@ static void HWR_DrawSprites(void)
|
|||
#endif
|
||||
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
|
||||
// 8/1/19: Only don't display player models if no default SPR_PLAY is found.
|
||||
if (!cv_grmd2.value || ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) && (md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)))
|
||||
HWR_DrawSprite(spr);
|
||||
else
|
||||
HWR_DrawMD2(spr);
|
||||
|
@ -5906,7 +5904,7 @@ void HWR_SetViewSize(void)
|
|||
// ==========================================================================
|
||||
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
||||
{
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
UINT8 ssplayer = 0;
|
||||
|
||||
|
@ -6072,7 +6070,7 @@ if (0)
|
|||
viewangle = localaiming4;
|
||||
|
||||
// Handle stuff when you are looking farther up or down.
|
||||
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
|
||||
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
|
||||
{
|
||||
dup_viewangle += ANGLE_90;
|
||||
HWR_ClearClipSegs();
|
||||
|
@ -6150,7 +6148,7 @@ if (0)
|
|||
// ==========================================================================
|
||||
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||
{
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
UINT8 ssplayer = 0;
|
||||
|
||||
|
@ -6331,7 +6329,7 @@ if (0)
|
|||
viewangle = localaiming4;
|
||||
|
||||
// Handle stuff when you are looking farther up or down.
|
||||
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
|
||||
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
|
||||
{
|
||||
dup_viewangle += ANGLE_90;
|
||||
HWR_ClearClipSegs();
|
||||
|
@ -6454,11 +6452,6 @@ static void HWR_FoggingOn(void)
|
|||
// ==========================================================================
|
||||
|
||||
|
||||
static void CV_grFov_OnChange(void)
|
||||
{
|
||||
if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT)
|
||||
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
|
||||
}
|
||||
|
||||
static void Command_GrStats_f(void)
|
||||
{
|
||||
|
@ -6481,7 +6474,6 @@ static void Command_GrStats_f(void)
|
|||
void HWR_AddCommands(void)
|
||||
{
|
||||
CV_RegisterVar(&cv_grrounddown);
|
||||
CV_RegisterVar(&cv_grfov);
|
||||
CV_RegisterVar(&cv_grfogdensity);
|
||||
CV_RegisterVar(&cv_grfiltermode);
|
||||
CV_RegisterVar(&cv_granisotropicmode);
|
||||
|
|
|
@ -79,7 +79,6 @@ extern consvar_t cv_grstaticlighting;
|
|||
extern consvar_t cv_grcoronas;
|
||||
extern consvar_t cv_grcoronasize;
|
||||
#endif
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmd2;
|
||||
extern consvar_t cv_grfog;
|
||||
extern consvar_t cv_grfogcolor;
|
||||
|
|
|
@ -162,7 +162,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
|
|||
jmp_buf jmpbuf;
|
||||
#endif
|
||||
#endif
|
||||
png_FILE_p png_FILE;
|
||||
volatile png_FILE_p png_FILE;
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
char *pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
|
||||
|
||||
|
@ -508,11 +508,12 @@ void HWR_InitMD2(void)
|
|||
}
|
||||
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
{
|
||||
if (stricmp(name, "PLAY") == 0)
|
||||
/*if (stricmp(name, "PLAY") == 0)
|
||||
{
|
||||
CONS_Printf("MD2 for sprite PLAY detected in kmd2.dat, use a player skin instead!\n");
|
||||
continue;
|
||||
}
|
||||
}*/
|
||||
// 8/1/19: Allow PLAY to load for default MD2.
|
||||
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
{
|
||||
|
@ -874,6 +875,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
|
||||
// MD2 colormap fix
|
||||
// colormap test
|
||||
if (spr->mobj->subsector)
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
|
@ -905,6 +907,10 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
else
|
||||
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Surf.FlatColor.rgba = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// Look at HWR_ProjectSprite for more
|
||||
{
|
||||
|
@ -933,19 +939,19 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
|
||||
// 1. load model+texture if not already loaded
|
||||
// 2. draw model with correct position, rotation,...
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // Use the player MD2 list if the mobj has a skin and is using the player sprites
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && !md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound) // Use the player MD2 list if the mobj has a skin and is using the player sprites
|
||||
{
|
||||
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
|
||||
md2->skin = (skin_t*)spr->mobj->skin-skins;
|
||||
}
|
||||
else
|
||||
else // if we can't find the player md2, use SPR_PLAY's MD2.
|
||||
md2 = &md2_models[spr->mobj->sprite];
|
||||
|
||||
if (md2->error)
|
||||
return; // we already failed loading this before :(
|
||||
if (!md2->model)
|
||||
{
|
||||
//CONS_Debug(DBG_RENDER, "Loading MD2... (%s)", sprnames[spr->mobj->sprite]);
|
||||
CONS_Debug(DBG_RENDER, "Loading MD2... (%s, %s)", sprnames[spr->mobj->sprite], md2->filename);
|
||||
sprintf(filename, "md2/%s", md2->filename);
|
||||
md2->model = md2_readModel(filename);
|
||||
|
||||
|
|
|
@ -1951,10 +1951,11 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration,
|
|||
EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
||||
{
|
||||
static boolean special_splitscreen;
|
||||
GLdouble used_fov;
|
||||
pglLoadIdentity();
|
||||
if (stransform)
|
||||
{
|
||||
boolean fovx90;
|
||||
used_fov = stransform->fovxangle;
|
||||
// keep a trace of the transformation for md2
|
||||
memcpy(&md2_transform, stransform, sizeof (md2_transform));
|
||||
|
||||
|
@ -1973,31 +1974,26 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
|||
pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f);
|
||||
pglTranslatef(-stransform->x, -stransform->z, -stransform->y);
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f;
|
||||
special_splitscreen = (stransform->splitscreen == 1 && fovx90);
|
||||
if (special_splitscreen)
|
||||
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
|
||||
else
|
||||
GLPerspective(stransform->fovxangle, ASPECT_RATIO);
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
special_splitscreen = (stransform->splitscreen == 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Hurdler: is "fov" correct?
|
||||
used_fov = fov;
|
||||
pglScalef(1.0f, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
if (special_splitscreen)
|
||||
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
|
||||
{
|
||||
used_fov = atan(tan(used_fov*M_PIl/360.0l)*0.8l)*360/M_PIl;
|
||||
GLPerspective(used_fov, 2*ASPECT_RATIO);
|
||||
}
|
||||
else
|
||||
//Hurdler: is "fov" correct?
|
||||
GLPerspective(fov, ASPECT_RATIO);
|
||||
GLPerspective(used_fov, ASPECT_RATIO);
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer)
|
||||
}
|
||||
|
|
233
src/hu_stuff.c
233
src/hu_stuff.c
|
@ -74,6 +74,14 @@ patch_t *nightsnum[10]; // 0-9
|
|||
patch_t *lt_font[LT_FONTSIZE];
|
||||
patch_t *cred_font[CRED_FONTSIZE];
|
||||
|
||||
// ping font
|
||||
// Note: I'd like to adress that at this point we might *REALLY* want to work towards a common drawString function that can take any font we want because this is really turning into a MESS. :V -Lat'
|
||||
patch_t *pingnum[10];
|
||||
patch_t *pinggfx[5]; // small ping graphic
|
||||
|
||||
patch_t *framecounter;
|
||||
patch_t *frameslash; // framerate stuff. Used in screen.c
|
||||
|
||||
static player_t *plr;
|
||||
boolean chat_on; // entering a chat message?
|
||||
static char w_chat[HU_MAXMSGLEN];
|
||||
|
@ -263,6 +271,8 @@ void HU_LoadGraphics(void)
|
|||
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
sprintf(buffer, "NGTNUM%d", i);
|
||||
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
|
||||
sprintf(buffer, "PINGN%d", i);
|
||||
pingnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// minus for negative tallnums
|
||||
|
@ -295,6 +305,17 @@ void HU_LoadGraphics(void)
|
|||
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
|
||||
|
||||
songcreditbg = W_CachePatchName("K_SONGCR", PU_HUDGFX);
|
||||
|
||||
// cache ping gfx:
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
sprintf(buffer, "PINGGFX%d", i+1);
|
||||
pinggfx[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// fps stuff
|
||||
framecounter = W_CachePatchName("FRAMER", PU_HUDGFX);
|
||||
frameslash = W_CachePatchName("FRAMESL", PU_HUDGFX);;
|
||||
}
|
||||
|
||||
// Initialise Heads up
|
||||
|
@ -762,39 +783,134 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
|
||||
cstart = "\x83";
|
||||
|
||||
if (color <= SKINCOLOR_SILVER || color == SKINCOLOR_SLATE)
|
||||
cstart = "\x80"; // white
|
||||
else if (color <= SKINCOLOR_BLACK || color == SKINCOLOR_JET)
|
||||
switch (color)
|
||||
{
|
||||
case SKINCOLOR_WHITE:
|
||||
case SKINCOLOR_SILVER:
|
||||
case SKINCOLOR_SLATE:
|
||||
cstart = "\x80"; // White
|
||||
break;
|
||||
case SKINCOLOR_GREY:
|
||||
case SKINCOLOR_NICKEL:
|
||||
case SKINCOLOR_BLACK:
|
||||
case SKINCOLOR_JET:
|
||||
cstart = "\x86"; // V_GRAYMAP
|
||||
else if (color <= SKINCOLOR_LEATHER)
|
||||
break;
|
||||
case SKINCOLOR_SEPIA:
|
||||
case SKINCOLOR_BEIGE:
|
||||
case SKINCOLOR_BROWN:
|
||||
case SKINCOLOR_LEATHER:
|
||||
case SKINCOLOR_RUST:
|
||||
cstart = "\x8e"; // V_BROWNMAP
|
||||
else if (color <= SKINCOLOR_ROSE || color == SKINCOLOR_LILAC)
|
||||
break;
|
||||
case SKINCOLOR_FAIRY:
|
||||
case SKINCOLOR_SALMON:
|
||||
case SKINCOLOR_PINK:
|
||||
case SKINCOLOR_ROSE:
|
||||
case SKINCOLOR_BRICK:
|
||||
case SKINCOLOR_BUBBLEGUM:
|
||||
case SKINCOLOR_LILAC:
|
||||
cstart = "\x8d"; // V_PINKMAP
|
||||
else if (color <= SKINCOLOR_KETCHUP)
|
||||
break;
|
||||
case SKINCOLOR_RUBY:
|
||||
case SKINCOLOR_RASPBERRY:
|
||||
case SKINCOLOR_CHERRY:
|
||||
case SKINCOLOR_RED:
|
||||
case SKINCOLOR_CRIMSON:
|
||||
case SKINCOLOR_MAROON:
|
||||
case SKINCOLOR_FLAME:
|
||||
case SKINCOLOR_SCARLET:
|
||||
case SKINCOLOR_KETCHUP:
|
||||
cstart = "\x85"; // V_REDMAP
|
||||
else if (color <= SKINCOLOR_TANGERINE)
|
||||
break;
|
||||
case SKINCOLOR_DAWN:
|
||||
case SKINCOLOR_SUNSET:
|
||||
case SKINCOLOR_CREAMSICLE:
|
||||
case SKINCOLOR_ORANGE:
|
||||
case SKINCOLOR_PUMPKIN:
|
||||
case SKINCOLOR_ROSEWOOD:
|
||||
case SKINCOLOR_BURGUNDY:
|
||||
case SKINCOLOR_TANGERINE:
|
||||
cstart = "\x87"; // V_ORANGEMAP
|
||||
else if (color <= SKINCOLOR_CARAMEL)
|
||||
break;
|
||||
case SKINCOLOR_PEACH:
|
||||
case SKINCOLOR_CARAMEL:
|
||||
case SKINCOLOR_CREAM:
|
||||
cstart = "\x8f"; // V_PEACHMAP
|
||||
else if (color <= SKINCOLOR_BRONZE)
|
||||
break;
|
||||
case SKINCOLOR_GOLD:
|
||||
case SKINCOLOR_ROYAL:
|
||||
case SKINCOLOR_BRONZE:
|
||||
case SKINCOLOR_COPPER:
|
||||
cstart = "\x8A"; // V_GOLDMAP
|
||||
else if (color <= SKINCOLOR_OLIVE)
|
||||
break;
|
||||
case SKINCOLOR_POPCORN:
|
||||
case SKINCOLOR_YELLOW:
|
||||
case SKINCOLOR_MUSTARD:
|
||||
case SKINCOLOR_OLIVE:
|
||||
cstart = "\x82"; // V_YELLOWMAP
|
||||
else if (color <= SKINCOLOR_PISTACHIO)
|
||||
break;
|
||||
case SKINCOLOR_VOMIT:
|
||||
case SKINCOLOR_GARDEN:
|
||||
case SKINCOLOR_TEA:
|
||||
case SKINCOLOR_PISTACHIO:
|
||||
cstart = "\x8b"; // V_TEAMAP
|
||||
else if (color <= SKINCOLOR_DREAM || color == SKINCOLOR_LIME)
|
||||
break;
|
||||
case SKINCOLOR_LIME:
|
||||
case SKINCOLOR_HANDHELD:
|
||||
case SKINCOLOR_MOSS:
|
||||
case SKINCOLOR_CAMOUFLAGE:
|
||||
case SKINCOLOR_ROBOHOOD:
|
||||
case SKINCOLOR_MINT:
|
||||
case SKINCOLOR_GREEN:
|
||||
case SKINCOLOR_PINETREE:
|
||||
case SKINCOLOR_EMERALD:
|
||||
case SKINCOLOR_SWAMP:
|
||||
case SKINCOLOR_DREAM:
|
||||
case SKINCOLOR_PLAGUE:
|
||||
case SKINCOLOR_ALGAE:
|
||||
cstart = "\x83"; // V_GREENMAP
|
||||
else if (color <= SKINCOLOR_NAVY || color == SKINCOLOR_SAPPHIRE)
|
||||
break;
|
||||
case SKINCOLOR_CARIBBEAN:
|
||||
case SKINCOLOR_AQUA:
|
||||
case SKINCOLOR_TEAL:
|
||||
case SKINCOLOR_CYAN:
|
||||
case SKINCOLOR_JAWZ:
|
||||
case SKINCOLOR_CERULEAN:
|
||||
case SKINCOLOR_NAVY:
|
||||
case SKINCOLOR_SAPPHIRE:
|
||||
cstart = "\x88"; // V_SKYMAP
|
||||
else if (color <= SKINCOLOR_STEEL)
|
||||
break;
|
||||
case SKINCOLOR_PLATINUM:
|
||||
case SKINCOLOR_STEEL:
|
||||
cstart = "\x8c"; // V_STEELMAP
|
||||
else if (color <= SKINCOLOR_BLUEBERRY)
|
||||
break;
|
||||
case SKINCOLOR_PERIWINKLE:
|
||||
case SKINCOLOR_BLUE:
|
||||
case SKINCOLOR_BLUEBERRY:
|
||||
case SKINCOLOR_NOVA:
|
||||
cstart = "\x84"; // V_BLUEMAP
|
||||
else if (color == SKINCOLOR_PURPLE)
|
||||
break;
|
||||
case SKINCOLOR_ULTRAVIOLET:
|
||||
case SKINCOLOR_PURPLE:
|
||||
case SKINCOLOR_FUCHSIA:
|
||||
cstart = "\x81"; // V_PURPLEMAP
|
||||
else //if (color <= SKINCOLOR_POMEGRANATE)
|
||||
break;
|
||||
case SKINCOLOR_PASTEL:
|
||||
case SKINCOLOR_MOONSLAM:
|
||||
case SKINCOLOR_DUSK:
|
||||
case SKINCOLOR_TOXIC:
|
||||
case SKINCOLOR_MAUVE:
|
||||
case SKINCOLOR_LAVENDER:
|
||||
case SKINCOLOR_BYZANTIUM:
|
||||
case SKINCOLOR_POMEGRANATE:
|
||||
cstart = "\x89"; // V_LAVENDERMAP
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prefix = cstart;
|
||||
|
||||
// Give admins and remote admins their symbols.
|
||||
|
@ -1109,8 +1225,6 @@ static INT16 typelines = 1; // number of drawfill lines we need when drawing the
|
|||
//
|
||||
boolean HU_Responder(event_t *ev)
|
||||
{
|
||||
INT32 c=0;
|
||||
|
||||
if (ev->type != ev_keydown)
|
||||
return false;
|
||||
|
||||
|
@ -1136,18 +1250,6 @@ boolean HU_Responder(event_t *ev)
|
|||
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
|
||||
if (!chat_on)
|
||||
{
|
||||
|
@ -1175,6 +1277,7 @@ boolean HU_Responder(event_t *ev)
|
|||
}
|
||||
else // if chat_on
|
||||
{
|
||||
INT32 c = (INT32)ev->data1;
|
||||
|
||||
// Ignore modifier keys
|
||||
// Note that we do this here so users can still set
|
||||
|
@ -1184,20 +1287,13 @@ boolean HU_Responder(event_t *ev)
|
|||
|| ev->data1 == KEY_LALT || ev->data1 == KEY_RALT)
|
||||
return true;
|
||||
|
||||
c = (INT32)ev->data1;
|
||||
// Ignore non-keyboard keys, except when the talk key is bound
|
||||
if (ev->data1 >= KEY_MOUSE1
|
||||
&& (ev->data1 != gamecontrol[gc_talkkey][0]
|
||||
&& ev->data1 != gamecontrol[gc_talkkey][1]))
|
||||
return false;
|
||||
|
||||
// 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];
|
||||
}
|
||||
c = CON_ShiftChar(c);
|
||||
|
||||
// pasting. pasting is cool. chat is a bit limited, though :(
|
||||
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)
|
||||
|
@ -1421,12 +1517,15 @@ static void HU_drawMiniChat(void)
|
|||
|
||||
y = chaty - charheight*(msglines+1);
|
||||
|
||||
#ifdef NETSPLITSCREEN
|
||||
if (splitscreen)
|
||||
{
|
||||
y -= BASEVIDHEIGHT/2;
|
||||
if (splitscreen > 1)
|
||||
y += 16;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
y -= (cv_kartspeedometer.value ? 16 : 0);
|
||||
|
||||
dx = 0;
|
||||
|
@ -1603,9 +1702,9 @@ static void HU_drawChatLog(INT32 offset)
|
|||
|
||||
// draw arrows to indicate that we can (or not) scroll.
|
||||
if (chat_scroll > 0)
|
||||
V_DrawThinString(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1A"); // up arrow
|
||||
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1A', false); // up arrow
|
||||
if (chat_scroll < chat_maxscroll)
|
||||
V_DrawThinString(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1B"); // down arrow
|
||||
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1B', false); // down arrow
|
||||
|
||||
justscrolleddown = false;
|
||||
justscrolledup = false;
|
||||
|
@ -2169,6 +2268,7 @@ static void HU_DrawSongCredits(void)
|
|||
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
|
||||
}
|
||||
|
||||
|
||||
// Heads up displays drawer, call each frame
|
||||
//
|
||||
void HU_Drawer(void)
|
||||
|
@ -2360,36 +2460,25 @@ void HU_Erase(void)
|
|||
//
|
||||
// HU_drawPing
|
||||
//
|
||||
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags)
|
||||
{
|
||||
UINT8 numbars = 1; // how many ping bars do we draw?
|
||||
UINT8 barcolor = 128; // color we use for the bars (green, yellow or red)
|
||||
SINT8 i = 0;
|
||||
SINT8 yoffset = 6;
|
||||
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
|
||||
INT32 gfxnum = 4; // gfx to draw
|
||||
UINT8 const *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
|
||||
|
||||
if (ping < 128)
|
||||
{
|
||||
numbars = 3;
|
||||
barcolor = 184;
|
||||
}
|
||||
if (ping < 76)
|
||||
gfxnum = 0;
|
||||
else if (ping < 137)
|
||||
gfxnum = 1;
|
||||
else if (ping < 256)
|
||||
{
|
||||
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
|
||||
barcolor = 103;
|
||||
}
|
||||
gfxnum = 2;
|
||||
else if (ping < 500)
|
||||
gfxnum = 3;
|
||||
|
||||
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
|
||||
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping));
|
||||
|
||||
for (i=0; (i<3); i++) // Draw the ping bar
|
||||
{
|
||||
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31);
|
||||
if (i < numbars)
|
||||
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor);
|
||||
|
||||
yoffset -= 2;
|
||||
}
|
||||
V_DrawScaledPatch(x, y, flags, pinggfx[gfxnum]);
|
||||
if (servermaxping && ping > servermaxping && hu_tick < 4) // flash ping red if too high
|
||||
V_DrawPingNum(x, y+9, flags, ping, colormap);
|
||||
else
|
||||
V_DrawPingNum(x, y+9, flags, ping, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct
|
|||
//------------------------------------
|
||||
#define HU_MAXMSGLEN 224
|
||||
#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand.
|
||||
#define NETSPLITSCREEN // why the hell WOULDN'T we want this?
|
||||
#ifdef NETSPLITSCREEN
|
||||
#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640)
|
||||
#else
|
||||
|
@ -79,7 +80,11 @@ extern boolean chat_on;
|
|||
|
||||
extern patch_t *hu_font[HU_FONTSIZE], *kart_font[KART_FONTSIZE], *tny_font[HU_FONTSIZE]; // SRB2kart
|
||||
extern patch_t *tallnum[10];
|
||||
extern patch_t *pingnum[10];
|
||||
extern patch_t *pinggfx[5];
|
||||
extern patch_t *nightsnum[10];
|
||||
extern patch_t *framecounter;
|
||||
extern patch_t *frameslash;
|
||||
extern patch_t *lt_font[LT_FONTSIZE];
|
||||
extern patch_t *cred_font[CRED_FONTSIZE];
|
||||
extern patch_t *emeraldpics[7];
|
||||
|
@ -108,7 +113,7 @@ void HU_Drawer(void);
|
|||
char HU_dequeueChatChar(void);
|
||||
void HU_Erase(void);
|
||||
void HU_clearChatChars(void);
|
||||
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); // Lat': Ping drawer for scoreboard.
|
||||
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
|
||||
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
||||
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
|
||||
|
|
29
src/info.c
29
src/info.c
|
@ -3140,11 +3140,11 @@ state_t states[NUMSTATES] =
|
|||
{SPR_NULL, 0, 1, {A_FZBoomSmoke}, 1, 0, S_FZEROBOOM12}, // S_FZEROBOOM11
|
||||
{SPR_NULL, 0, 1, {A_FZBoomSmoke}, 0, 0, S_NULL}, // S_FZEROBOOM12
|
||||
|
||||
{SPR_SMOK, FF_TRANS30, 30, {NULL}, 0, 0, S_FZSLOWSMOKE2}, // S_FZSLOWSMOKE1
|
||||
{SPR_SMOK, FF_TRANS30|1, 30, {NULL}, 0, 0, S_FZSLOWSMOKE3}, // S_FZSLOWSMOKE2
|
||||
{SPR_SMOK, FF_TRANS30|2, 30, {NULL}, 0, 0, S_FZSLOWSMOKE4}, // S_FZSLOWSMOKE3
|
||||
{SPR_SMOK, FF_TRANS30|3, 30, {NULL}, 0, 0, S_FZSLOWSMOKE5}, // S_FZSLOWSMOKE4
|
||||
{SPR_SMOK, FF_TRANS30|4, 30, {NULL}, 0, 0, S_NULL}, // S_FZSLOWSMOKE5
|
||||
{SPR_SMOK, 0, 30, {NULL}, 0, 0, S_FZSLOWSMOKE2}, // S_FZSLOWSMOKE1
|
||||
{SPR_SMOK, 1, 30, {NULL}, 0, 0, S_FZSLOWSMOKE3}, // S_FZSLOWSMOKE2
|
||||
{SPR_SMOK, 2, 30, {NULL}, 0, 0, S_FZSLOWSMOKE4}, // S_FZSLOWSMOKE3
|
||||
{SPR_SMOK, 3, 30, {NULL}, 0, 0, S_FZSLOWSMOKE5}, // S_FZSLOWSMOKE4
|
||||
{SPR_SMOK, 4, 30, {NULL}, 0, 0, S_NULL}, // S_FZSLOWSMOKE5
|
||||
|
||||
// Various plants
|
||||
{SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH
|
||||
|
@ -3394,6 +3394,13 @@ state_t states[NUMSTATES] =
|
|||
{SPR_FWRK, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4
|
||||
{SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL
|
||||
|
||||
// Opaque smoke
|
||||
{SPR_SMOK, 0, 4, {NULL}, 0, 0, S_OPAQUESMOKE2}, // S_OPAQUESMOKE1
|
||||
{SPR_SMOK, 1, 5, {NULL}, 0, 0, S_OPAQUESMOKE3}, // S_OPAQUESMOKE2
|
||||
{SPR_SMOK, 2, 6, {NULL}, 0, 0, S_OPAQUESMOKE4}, // S_OPAQUESMOKE3
|
||||
{SPR_SMOK, 3, 7, {NULL}, 0, 0, S_OPAQUESMOKE5}, // S_OPAQUESMOKE4
|
||||
{SPR_SMOK, 4, 8, {NULL}, 0, 0, S_NULL}, // S_OPAQUESMOKE5
|
||||
|
||||
#ifdef SEENAMES
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
|
||||
#endif
|
||||
|
@ -15018,8 +15025,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
8*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
32*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
1, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
|
@ -15449,7 +15456,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_ORBINAUT_SHIELDDEAD, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
10*FRACUNIT, // speed
|
||||
4*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
@ -15530,7 +15537,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_JAWZ_DEAD1, // deathstate
|
||||
S_JAWZ_DEAD2, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
10*FRACUNIT, // speed
|
||||
4*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
@ -15574,7 +15581,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_tossed, // seesound
|
||||
6*TICRATE, // reactiontime
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
192*FRACUNIT, // painchance
|
||||
|
@ -15861,7 +15868,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
1, // damage
|
||||
sfx_None, // activesound
|
||||
MF_BOUNCE|MF_FLOAT|MF_NOCLIPTHING|MF_MISSILE|MF_SHOOTABLE|MF_DONTENCOREMAP, // flags
|
||||
MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
@ -4052,6 +4052,12 @@ typedef enum state
|
|||
S_KARMAFIREWORK4,
|
||||
S_KARMAFIREWORKTRAIL,
|
||||
|
||||
S_OPAQUESMOKE1,
|
||||
S_OPAQUESMOKE2,
|
||||
S_OPAQUESMOKE3,
|
||||
S_OPAQUESMOKE4,
|
||||
S_OPAQUESMOKE5,
|
||||
|
||||
#ifdef SEENAMES
|
||||
S_NAMECHECK,
|
||||
#endif
|
||||
|
|
1700
src/k_kart.c
1700
src/k_kart.c
File diff suppressed because it is too large
Load Diff
13
src/k_kart.h
13
src/k_kart.h
|
@ -9,7 +9,9 @@
|
|||
#include "doomdef.h"
|
||||
#include "d_player.h" // Need for player_t
|
||||
|
||||
UINT8 colortranslations[MAXSKINCOLORS][16];
|
||||
#define KART_FULLTURN 800
|
||||
|
||||
UINT8 colortranslations[MAXTRANSLATIONS][16];
|
||||
extern const char *KartColor_Names[MAXSKINCOLORS];
|
||||
extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
|
||||
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
|
||||
|
@ -21,6 +23,7 @@ void K_RegisterKartStuff(void);
|
|||
boolean K_IsPlayerLosing(player_t *player);
|
||||
boolean K_IsPlayerWanted(player_t *player);
|
||||
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_RespawnChecker(player_t *player);
|
||||
void K_KartMoveAnimation(player_t *player);
|
||||
|
@ -39,6 +42,7 @@ void K_SpawnBoostTrail(player_t *player);
|
|||
void K_SpawnSparkleTrail(mobj_t *mo);
|
||||
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent);
|
||||
void K_DriftDustHandling(mobj_t *spawner);
|
||||
void K_PuntMine(mobj_t *mine, mobj_t *punter);
|
||||
void K_DoSneaker(player_t *player, INT32 type);
|
||||
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
|
||||
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
|
||||
|
@ -63,6 +67,13 @@ void K_CalculateBattleWanted(void);
|
|||
void K_CheckBumpers(void);
|
||||
void K_CheckSpectateStatus(void);
|
||||
|
||||
// sound stuff for lua
|
||||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
void K_PlayBoostTaunt(mobj_t *source);
|
||||
void K_PlayOvertakeSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||
INT32 K_calcSplitFlags(INT32 snapflags);
|
||||
void K_LoadKartHUDGraphics(void);
|
||||
|
|
|
@ -31,9 +31,10 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // hook_cmd_running
|
||||
|
||||
#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!");
|
||||
|
||||
#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!"); else if (hook_cmd_running) return luaL_error(L, "CMD Building code should not call this function!");
|
||||
// Yes technically cmd hook isn't a hud but whatever, this avoids having 2 defines for virtually the same thing.
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg) {
|
||||
luaL_checktype(L, narg, LUA_TBOOLEAN);
|
||||
|
@ -631,19 +632,6 @@ static int lib_pCheckSolidLava(lua_State *L)
|
|||
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)
|
||||
{
|
||||
mobj_t *caster = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -677,16 +665,6 @@ static int lib_pGetPlayerSpinHeight(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pGetPlayerControlDirection(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
//HUDSAFE
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
lua_pushinteger(L, P_GetPlayerControlDirection(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pAddPlayerScore(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
@ -2141,6 +2119,72 @@ static int lib_gTicsToMilliseconds(lua_State *L)
|
|||
// K_KART
|
||||
////////////
|
||||
|
||||
// Seriously, why weren't those exposed before?
|
||||
static int lib_kAttackSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayAttackTaunt: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayAttackTaunt(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kBoostSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayBoostTaunt: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayBoostTaunt(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kOvertakeSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayOvertakeSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayOvertakeSound(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kHitEmSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayHitEmSound(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kGloatSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayPowerGloatSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayPowerGloatSound(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kLossSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); // let's require a mobj for consistency with the other functions
|
||||
sfxenum_t sfx_id;
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayLossSound: mobj_t isn't a player object.");
|
||||
|
||||
sfx_id = ((skin_t *)mobj->skin)->soundsid[S_sfx[sfx_klose].skinsound];
|
||||
S_StartSound(mobj, sfx_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Note: Pain, Death and Victory are already exposed.
|
||||
|
||||
static int lib_kGetKartColorByName(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
|
@ -2570,13 +2614,11 @@ static luaL_Reg lib[] = {
|
|||
{"P_InsideANonSolidFFloor",lib_pInsideANonSolidFFloor},
|
||||
{"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide},
|
||||
{"P_CheckSolidLava",lib_pCheckSolidLava},
|
||||
{"P_CanRunOnWater",lib_pCanRunOnWater},
|
||||
{"P_SpawnShadowMobj",lib_pSpawnShadowMobj},
|
||||
|
||||
// p_user
|
||||
{"P_GetPlayerHeight",lib_pGetPlayerHeight},
|
||||
{"P_GetPlayerSpinHeight",lib_pGetPlayerSpinHeight},
|
||||
{"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection},
|
||||
{"P_AddPlayerScore",lib_pAddPlayerScore},
|
||||
{"P_PlayerInPain",lib_pPlayerInPain},
|
||||
{"P_DoPlayerPain",lib_pDoPlayerPain},
|
||||
|
@ -2708,6 +2750,12 @@ static luaL_Reg lib[] = {
|
|||
{"G_TicsToMilliseconds",lib_gTicsToMilliseconds},
|
||||
|
||||
// k_kart
|
||||
{"K_PlayAttackTaunt", lib_kAttackSound},
|
||||
{"K_PlayBoostTaunt", lib_kBoostSound},
|
||||
{"K_PlayPowerGloatSund", lib_kGloatSound},
|
||||
{"K_PlayOvertakeSound", lib_kOvertakeSound},
|
||||
{"K_PlayLossSound", lib_kLossSound},
|
||||
{"K_PlayHitEmSound", lib_kHitEmSound},
|
||||
{"K_GetKartColorByName",lib_kGetKartColorByName},
|
||||
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
||||
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
|
||||
|
|
|
@ -50,11 +50,14 @@ enum hook {
|
|||
hook_PlayerSpin, //SRB2KART
|
||||
hook_PlayerExplode, //SRB2KART
|
||||
hook_PlayerSquish, //SRB2KART
|
||||
hook_PlayerCmd, //SRB2KART
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
extern const char *const hookNames[];
|
||||
|
||||
extern boolean hook_cmd_running; // This is used by PlayerCmd and lua_playerlib to prevent anything from being wirtten to player while we run PlayerCmd.
|
||||
|
||||
void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load)
|
||||
void LUAh_MapLoad(void); // Hook for map load
|
||||
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
|
||||
|
@ -93,4 +96,7 @@ UINT8 LUAh_ShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source); //
|
|||
boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SpinPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"PlayerSpin",
|
||||
"PlayerExplode",
|
||||
"PlayerSquish",
|
||||
"PlayerCmd",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -877,6 +878,47 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd)
|
|||
return hooked;
|
||||
}
|
||||
|
||||
// Hook for G_BuildTicCmd
|
||||
boolean hook_cmd_running = false;
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean hooked = false;
|
||||
if (!gL || !(hooksAvailable[hook_PlayerCmd/8] & (1<<(hook_PlayerCmd%8))))
|
||||
return false;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
|
||||
hook_cmd_running = true;
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_PlayerCmd)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
LUA_PushUserdata(gL, cmd, META_TICCMD);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
if (lua_pcall(gL, 2, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (lua_toboolean(gL, -1))
|
||||
hooked = true;
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
hook_cmd_running = false;
|
||||
lua_settop(gL, 0);
|
||||
return hooked;
|
||||
}
|
||||
|
||||
// Hook for B_BuildTailsTiccmd by skin name
|
||||
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
||||
{
|
||||
|
|
|
@ -20,8 +20,10 @@ enum hud {
|
|||
hud_item,
|
||||
hud_position,
|
||||
hud_minirankings, // Rankings to the left
|
||||
hud_battlebumpers, // mini rankings battle bumpers.
|
||||
hud_wanted,
|
||||
hud_speedometer,
|
||||
hud_freeplay,
|
||||
hud_rankings, // Tab rankings
|
||||
|
||||
hud_MAX
|
||||
|
|
|
@ -34,6 +34,8 @@ static UINT8 hud_enabled[(hud_MAX/8)+1];
|
|||
|
||||
static UINT8 hudAvailable; // hud hooks field
|
||||
|
||||
static UINT8 camnum = 1;
|
||||
|
||||
// must match enum hud in lua_hud.h
|
||||
static const char *const hud_disable_options[] = {
|
||||
"stagetitle",
|
||||
|
@ -45,8 +47,10 @@ static const char *const hud_disable_options[] = {
|
|||
"item",
|
||||
"position",
|
||||
"minirankings", // Gametype rankings to the left
|
||||
"battlerankingsbumpers", // bumper drawer for battle. Useful if you want to make a custom battle gamemode without bumpers being involved.
|
||||
"wanted",
|
||||
"speedometer",
|
||||
"freeplay",
|
||||
"rankings",
|
||||
NULL};
|
||||
|
||||
|
@ -132,7 +136,8 @@ enum cameraf {
|
|||
camera_height,
|
||||
camera_momx,
|
||||
camera_momy,
|
||||
camera_momz
|
||||
camera_momz,
|
||||
camera_pnum
|
||||
};
|
||||
|
||||
|
||||
|
@ -151,6 +156,7 @@ static const char *const camera_opt[] = {
|
|||
"momx",
|
||||
"momy",
|
||||
"momz",
|
||||
"pnum",
|
||||
NULL};
|
||||
|
||||
static int lib_getHudInfo(lua_State *L)
|
||||
|
@ -306,6 +312,9 @@ static int camera_get(lua_State *L)
|
|||
case camera_momz:
|
||||
lua_pushinteger(L, cam->momz);
|
||||
break;
|
||||
case camera_pnum:
|
||||
lua_pushinteger(L, camnum);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -401,6 +410,24 @@ static int libd_drawPaddedNum(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int libd_drawPingNum(lua_State *L)
|
||||
{
|
||||
INT32 x, y, flags, num;
|
||||
const UINT8 *colormap = NULL;
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
num = luaL_checkinteger(L, 3);
|
||||
flags = luaL_optinteger(L, 4, 0);
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
if (!lua_isnoneornil(L, 5))
|
||||
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
|
||||
|
||||
V_DrawPingNum(x, y, flags, num, colormap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawFill(lua_State *L)
|
||||
{
|
||||
INT32 x = luaL_optinteger(L, 1, 0);
|
||||
|
@ -482,6 +509,20 @@ static int libd_drawString(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawKartString(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkinteger(L, 1);
|
||||
fixed_t y = luaL_checkinteger(L, 2);
|
||||
const char *str = luaL_checkstring(L, 3);
|
||||
INT32 flags = luaL_optinteger(L, 4, V_ALLOWLOWERCASE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
HUDONLY
|
||||
V_DrawKartString(x, y, flags, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_stringWidth(lua_State *L)
|
||||
{
|
||||
const char *str = luaL_checkstring(L, 1);
|
||||
|
@ -590,9 +631,11 @@ static luaL_Reg lib_draw[] = {
|
|||
{"drawScaled", libd_drawScaled},
|
||||
{"drawNum", libd_drawNum},
|
||||
{"drawPaddedNum", libd_drawPaddedNum},
|
||||
{"drawPingNum", libd_drawPingNum},
|
||||
{"drawFill", libd_drawFill},
|
||||
{"fadeScreen", libd_fadeScreen},
|
||||
{"drawString", libd_drawString},
|
||||
{"drawKartString", libd_drawKartString},
|
||||
{"stringWidth", libd_stringWidth},
|
||||
{"getColormap", libd_getColormap},
|
||||
{"width", libd_width},
|
||||
|
@ -755,13 +798,25 @@ void LUAh_GameHUD(player_t *stplayr)
|
|||
LUA_PushUserdata(gL, stplayr, META_PLAYER);
|
||||
|
||||
if (splitscreen > 2 && stplayr == &players[fourthdisplayplayer])
|
||||
{
|
||||
LUA_PushUserdata(gL, &camera4, META_CAMERA);
|
||||
camnum = 4;
|
||||
}
|
||||
else if (splitscreen > 1 && stplayr == &players[thirddisplayplayer])
|
||||
{
|
||||
LUA_PushUserdata(gL, &camera3, META_CAMERA);
|
||||
camnum = 3;
|
||||
}
|
||||
else if (splitscreen && stplayr == &players[secondarydisplayplayer])
|
||||
{
|
||||
LUA_PushUserdata(gL, &camera2, META_CAMERA);
|
||||
camnum = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
LUA_PushUserdata(gL, &camera, META_CAMERA);
|
||||
camnum = 1;
|
||||
}
|
||||
|
||||
lua_pushnil(gL);
|
||||
while (lua_next(gL, -5) != 0) {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
|
||||
boolean LUA_CallAction(const char *action, mobj_t *actor);
|
||||
state_t *astate;
|
||||
|
@ -169,6 +170,8 @@ static int lib_setState(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter states in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter states in BuildCMD code!");
|
||||
|
||||
// clear the state to start with, in case of missing table elements
|
||||
memset(state,0,sizeof(state_t));
|
||||
|
@ -378,6 +381,8 @@ static int state_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter states in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter states in BuildCMD code!");
|
||||
|
||||
if (fastcmp(field,"sprite")) {
|
||||
value = luaL_checknumber(L, 3);
|
||||
|
@ -466,6 +471,8 @@ static int lib_setMobjInfo(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mobjinfo in BuildCMD code!");
|
||||
|
||||
// clear the mobjinfo to start with, in case of missing table elements
|
||||
memset(info,0,sizeof(mobjinfo_t));
|
||||
|
@ -633,6 +640,8 @@ static int mobjinfo_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mobjinfo in BuildCMD code!");
|
||||
|
||||
I_Assert(info != NULL);
|
||||
I_Assert(info >= mobjinfo);
|
||||
|
@ -755,6 +764,8 @@ static int lib_setSfxInfo(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter sfxinfo in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter sfxinfo in BuildCMD code!");
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
|
@ -830,6 +841,8 @@ static int sfxinfo_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter S_sfx in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter S_sfx in BuildCMD code!");
|
||||
|
||||
I_Assert(sfx != NULL);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
|
||||
#include "dehacked.h"
|
||||
#include "fastcmp.h"
|
||||
|
@ -484,6 +485,8 @@ static int sector_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter sector_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter sector_t in BuildCMD code!");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
|
@ -1174,6 +1177,8 @@ static int ffloor_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter ffloor_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter ffloor_t in BuildCMD code!");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
|
@ -1303,6 +1308,8 @@ static int slope_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter pslope_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter pslope_t in BuildCMD code!");
|
||||
|
||||
switch(field) // todo: reorganize this shit
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
|
||||
|
@ -391,6 +392,9 @@ static int mobj_set(lua_State *L)
|
|||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter mobj_t in HUD rendering code!");
|
||||
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mobj_t in BuildCMD code!");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case mobj_valid:
|
||||
|
@ -756,6 +760,8 @@ static int mapthing_set(lua_State *L)
|
|||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter mapthing_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mapthing_t in BuildCMD code!");
|
||||
|
||||
if(fastcmp(field,"x"))
|
||||
mt->x = (INT16)luaL_checkinteger(L, 3);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // hook_cmd_running
|
||||
|
||||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
|
@ -324,6 +325,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->bot);
|
||||
else if (fastcmp(field,"jointime"))
|
||||
lua_pushinteger(L, plr->jointime);
|
||||
else if (fastcmp(field,"splitscreenindex"))
|
||||
lua_pushinteger(L, plr->splitscreenindex);
|
||||
#ifdef HWRENDER
|
||||
else if (fastcmp(field,"fovadd"))
|
||||
lua_pushfixed(L, plr->fovadd);
|
||||
|
@ -356,6 +359,9 @@ static int player_set(lua_State *L)
|
|||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||
|
||||
if (fastcmp(field,"mo")) {
|
||||
mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
plr->mo->player = NULL; // remove player pointer from old mobj
|
||||
|
@ -609,6 +615,8 @@ static int player_set(lua_State *L)
|
|||
return NOSET;
|
||||
else if (fastcmp(field,"jointime"))
|
||||
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"splitscreenindex"))
|
||||
return NOSET;
|
||||
#ifdef HWRENDER
|
||||
else if (fastcmp(field,"fovadd"))
|
||||
plr->fovadd = luaL_checkfixed(L, 3);
|
||||
|
@ -667,6 +675,8 @@ static int power_set(lua_State *L)
|
|||
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||
powers[p] = i;
|
||||
return 0;
|
||||
}
|
||||
|
@ -699,6 +709,8 @@ static int kartstuff_set(lua_State *L)
|
|||
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
||||
kartstuff[ks] = i;
|
||||
return 0;
|
||||
}
|
||||
|
@ -731,6 +743,8 @@ static int ticcmd_get(lua_State *L)
|
|||
lua_pushinteger(L, cmd->buttons);
|
||||
else if (fastcmp(field,"driftturn"))
|
||||
lua_pushinteger(L, cmd->driftturn);
|
||||
else if (fastcmp(field,"latency"))
|
||||
lua_pushinteger(L, cmd->latency);
|
||||
else
|
||||
return NOFIELD;
|
||||
|
||||
|
|
|
@ -212,6 +212,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
|||
|
||||
LUA_LoadFile(&f, name); // actually load file!
|
||||
|
||||
// Okay, we've modified the game beyond the point of no return.
|
||||
G_SetGameModified(multiplayer, true);
|
||||
|
||||
free(name);
|
||||
Z_Free(f.data);
|
||||
}
|
||||
|
@ -1017,7 +1020,7 @@ void LUA_Archive(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
|
||||
continue;
|
||||
// all players in game will be archived, even if they just add a 0.
|
||||
ArchiveExtVars(&players[i], "player");
|
||||
|
@ -1053,7 +1056,7 @@ void LUA_UnArchive(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
if (!playeringame[i] && i > 0) // same here, this is to synch dediservs properly.
|
||||
continue;
|
||||
UnArchiveExtVars(&players[i]);
|
||||
}
|
||||
|
|
|
@ -30,24 +30,10 @@ enum skin {
|
|||
skin_facerank,
|
||||
skin_facewant,
|
||||
skin_facemmap,
|
||||
skin_ability,
|
||||
skin_ability2,
|
||||
skin_thokitem,
|
||||
skin_spinitem,
|
||||
skin_revitem,
|
||||
skin_actionspd,
|
||||
skin_mindash,
|
||||
skin_maxdash,
|
||||
// SRB2kart
|
||||
skin_kartspeed,
|
||||
skin_kartweight,
|
||||
//
|
||||
skin_normalspeed,
|
||||
skin_runspeed,
|
||||
skin_thrustfactor,
|
||||
skin_accelstart,
|
||||
skin_acceleration,
|
||||
skin_jumpfactor,
|
||||
skin_starttranscolor,
|
||||
skin_prefcolor,
|
||||
skin_highresscale,
|
||||
|
@ -64,24 +50,10 @@ static const char *const skin_opt[] = {
|
|||
"facerank",
|
||||
"facewant",
|
||||
"facemmap",
|
||||
"ability",
|
||||
"ability2",
|
||||
"thokitem",
|
||||
"spinitem",
|
||||
"revitem",
|
||||
"actionspd",
|
||||
"mindash",
|
||||
"maxdash",
|
||||
// SRB2kart
|
||||
"kartspeed",
|
||||
"kartweight",
|
||||
//
|
||||
"normalspeed",
|
||||
"runspeed",
|
||||
"thrustfactor",
|
||||
"accelstart",
|
||||
"acceleration",
|
||||
"jumpfactor",
|
||||
"starttranscolor",
|
||||
"prefcolor",
|
||||
"highresscale",
|
||||
|
@ -139,30 +111,6 @@ static int skin_get(lua_State *L)
|
|||
break;
|
||||
lua_pushlstring(L, skin->facemmap, i);
|
||||
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
|
||||
case skin_kartspeed:
|
||||
lua_pushinteger(L, skin->kartspeed);
|
||||
|
@ -171,24 +119,6 @@ static int skin_get(lua_State *L)
|
|||
lua_pushinteger(L, skin->kartweight);
|
||||
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:
|
||||
lua_pushinteger(L, skin->starttranscolor);
|
||||
break;
|
||||
|
|
|
@ -121,7 +121,7 @@ static UINT8 cheatf_devmode(void)
|
|||
S_StartSound(0, sfx_itemup);
|
||||
|
||||
// Just unlock all the things and turn on -debug and console devmode.
|
||||
G_SetGameModified(false);
|
||||
G_SetGameModified(false, false); // might need to revist the latter later
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
unlockables[i].unlocked = true;
|
||||
devparm = true;
|
||||
|
@ -295,7 +295,7 @@ void Command_CheatNoClip_f(void)
|
|||
plyr->pflags ^= PF_NOCLIP;
|
||||
CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
void Command_CheatGod_f(void)
|
||||
|
@ -310,7 +310,7 @@ void Command_CheatGod_f(void)
|
|||
plyr->pflags ^= PF_GODMODE;
|
||||
CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
void Command_CheatNoTarget_f(void)
|
||||
|
@ -325,7 +325,7 @@ void Command_CheatNoTarget_f(void)
|
|||
plyr->pflags ^= PF_INVIS;
|
||||
CONS_Printf(M_GetText("SEP Field %s\n"), plyr->pflags & PF_INVIS ? M_GetText("On") : M_GetText("Off"));
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
void Command_Scale_f(void)
|
||||
|
@ -727,7 +727,7 @@ void Command_Devmode_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
/*void Command_Setrings_f(void)
|
||||
|
@ -1130,12 +1130,12 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
}
|
||||
if (cmd->sidemove != 0)
|
||||
/*if (cmd->sidemove != 0) -- was disabled in practice anyways, since sidemove was suppressed
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle-ANGLE_90, (cmd->sidemove*FRACUNIT/MAXPLMOVE)*cv_speed.value);
|
||||
P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (player->mo->z > player->mo->ceilingz - player->mo->height)
|
||||
player->mo->z = player->mo->ceilingz - player->mo->height;
|
||||
|
@ -1267,7 +1267,7 @@ void Command_ObjectPlace_f(void)
|
|||
REQUIRE_SINGLEPLAYER;
|
||||
REQUIRE_NOULTIMATE;
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
|
||||
// Entering objectplace?
|
||||
if (!objectplacing)
|
||||
|
|
|
@ -385,8 +385,7 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force)
|
|||
char cechoText[992] = "";
|
||||
UINT8 cechoLines = 0;
|
||||
|
||||
if (modifiedgame && !savemoddata
|
||||
&& !force) // SRB2Kart: for enabling unlocks online in modified servers
|
||||
if (majormods && !force) // SRB2Kart: for enabling unlocks online in modified servers
|
||||
return false;
|
||||
|
||||
M_CheckUnlockConditions();
|
||||
|
|
260
src/m_menu.c
260
src/m_menu.c
|
@ -274,14 +274,13 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
|
|||
#ifndef NONET
|
||||
static void M_StartServerMenu(INT32 choice);
|
||||
static void M_ConnectMenu(INT32 choice);
|
||||
#endif
|
||||
static void M_StartOfflineServerMenu(INT32 choice);
|
||||
static void M_StartServer(INT32 choice);
|
||||
#ifndef NONET
|
||||
static void M_ConnectMenuModChecks(INT32 choice);
|
||||
static void M_Refresh(INT32 choice);
|
||||
static void M_Connect(INT32 choice);
|
||||
static void M_ChooseRoom(INT32 choice);
|
||||
#endif
|
||||
static void M_StartOfflineServerMenu(INT32 choice);
|
||||
static void M_StartServer(INT32 choice);
|
||||
static void M_SetupMultiPlayer(INT32 choice);
|
||||
static void M_SetupMultiPlayer2(INT32 choice);
|
||||
static void M_SetupMultiPlayer3(INT32 choice);
|
||||
|
@ -400,6 +399,8 @@ static void Dummystaff_OnChange(void);
|
|||
// 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[] = {
|
||||
{0,"MIN"},
|
||||
{NUMMAPS, "MAX"},
|
||||
|
@ -439,11 +440,11 @@ static CV_PossibleValue_t serversort_cons_t[] = {
|
|||
{1,"Modified State"},
|
||||
{2,"Most Players"},
|
||||
{3,"Least Players"},
|
||||
{4,"Max Players"},
|
||||
{4,"Max Player Slots"},
|
||||
{5,"Gametype"},
|
||||
{0,NULL}
|
||||
};
|
||||
consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_serversort = {"serversort", "Ping", CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// autorecord demos for time attack
|
||||
static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -911,41 +912,7 @@ static menuitem_t SP_LevelStatsMenu[] =
|
|||
// External files modify this menu, so we can't call it static.
|
||||
// And I'm too lazy to go through and rename it everywhere. ARRGH!
|
||||
#define M_ChoosePlayer NULL
|
||||
menuitem_t PlayerMenu[32] =
|
||||
{
|
||||
{IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
|
||||
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0}
|
||||
};
|
||||
menuitem_t PlayerMenu[MAXSKINS];
|
||||
|
||||
// -----------------------------------
|
||||
// Multiplayer and all of its submenus
|
||||
|
@ -969,11 +936,11 @@ static menuitem_t MP_MainMenu[] =
|
|||
|
||||
{IT_HEADER, NULL, "Join a game", NULL, 132-24},
|
||||
#ifndef NONET
|
||||
{IT_STRING|IT_CALL, NULL, "Internet server browser...",M_ConnectMenu, 142-24},
|
||||
{IT_STRING|IT_CALL, NULL, "Internet server browser...",M_ConnectMenuModChecks, 142-24},
|
||||
{IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24},
|
||||
#else
|
||||
{IT_GRAYEDOUT, NULL, "Internet server browser...",M_ConnectMenu, 142-24},
|
||||
{IT_GRAYEDOUT, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24},
|
||||
{IT_GRAYEDOUT, NULL, "Internet server browser...",NULL, 142-24},
|
||||
{IT_GRAYEDOUT, NULL, "Specify IPv4 address:", NULL, 150-24},
|
||||
#endif
|
||||
//{IT_HEADER, NULL, "Player setup", NULL, 80},
|
||||
//{IT_STRING|IT_CALL, NULL, "Name, character, color...", M_SetupMultiPlayer, 90},
|
||||
|
@ -983,9 +950,10 @@ static menuitem_t MP_MainMenu[] =
|
|||
|
||||
static menuitem_t MP_ServerMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10},
|
||||
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20},
|
||||
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30},
|
||||
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 0},
|
||||
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10},
|
||||
{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, "Level", &cv_nextmap, 78},
|
||||
|
@ -1284,7 +1252,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
|
|||
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 10},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 20},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of View", &cv_grfov, 35},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of View", &cv_fov, 35},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 45},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 55},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 65},
|
||||
|
@ -1351,6 +1319,9 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
|||
{IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95},
|
||||
|
||||
{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[] =
|
||||
|
@ -1425,7 +1396,7 @@ static menuitem_t OP_HUDOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "HUD Visibility", &cv_translucenthud, 20},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Online chat options...",&OP_ChatOptionsDef, 35},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Online HUD options...",&OP_ChatOptionsDef, 35},
|
||||
{IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
|
@ -1437,8 +1408,11 @@ static menuitem_t OP_HUDOptionsMenu[] =
|
|||
// 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, "Show \"FOCUS LOST\"", &cv_showfocuslost, 135},
|
||||
};
|
||||
|
||||
// Ok it's still called chatoptions but we'll put ping display in here to be clean
|
||||
static menuitem_t OP_ChatOptionsMenu[] =
|
||||
{
|
||||
// will ANYONE who doesn't know how to use the console want to touch this one?
|
||||
|
@ -1452,6 +1426,8 @@ static menuitem_t OP_ChatOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 90}, // shows ping next to framerate if we want to.
|
||||
};
|
||||
|
||||
static menuitem_t OP_GameOptionsMenu[] =
|
||||
|
@ -1504,15 +1480,16 @@ static menuitem_t OP_AdvServerOptionsMenu[] =
|
|||
|
||||
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping limit (ms)", &cv_maxping, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping timeout (s)", &cv_pingtimeout, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 80},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 110},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 130},
|
||||
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 140},
|
||||
{IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 130},
|
||||
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 140},
|
||||
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 150},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1865,7 +1842,6 @@ static menu_t SP_NightsGhostDef =
|
|||
NULL
|
||||
};*/
|
||||
|
||||
#ifndef NONET
|
||||
// Multiplayer
|
||||
menu_t MP_MainDef =
|
||||
{
|
||||
|
@ -1876,12 +1852,18 @@ menu_t MP_MainDef =
|
|||
M_DrawMPMainMenu,
|
||||
42, 30,
|
||||
0,
|
||||
M_CancelConnect
|
||||
};
|
||||
menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef);
|
||||
#endif
|
||||
menu_t MP_OfflineServerDef = MAPICONMENUSTYLE("M_MULTI", MP_OfflineServerMenu, &MP_MainDef);
|
||||
#ifndef NONET
|
||||
M_CancelConnect
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
menu_t MP_OfflineServerDef = MAPICONMENUSTYLE("M_MULTI", MP_OfflineServerMenu, &MP_MainDef);
|
||||
|
||||
#ifndef NONET
|
||||
menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef);
|
||||
|
||||
menu_t MP_ConnectDef =
|
||||
{
|
||||
"M_MULTI",
|
||||
|
@ -2409,6 +2391,9 @@ static void M_NextOpt(void)
|
|||
{
|
||||
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
|
||||
{
|
||||
if (itemOn + 1 > currentMenu->numitems - 1)
|
||||
|
@ -2422,6 +2407,9 @@ static void M_PrevOpt(void)
|
|||
{
|
||||
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
|
||||
{
|
||||
if (!itemOn)
|
||||
|
@ -2584,7 +2572,7 @@ boolean M_Responder(event_t *ev)
|
|||
return false;
|
||||
else if (ch == gamecontrol[gc_systemmenu][0] || ch == gamecontrol[gc_systemmenu][1]) // allow remappable ESC key
|
||||
ch = KEY_ESCAPE;
|
||||
else if (ch == gamecontrol[gc_accelerate][0] || ch == gamecontrol[gc_accelerate][1])
|
||||
else if ((ch == gamecontrol[gc_accelerate][0] || ch == gamecontrol[gc_accelerate][1]) && ch >= KEY_MOUSE1)
|
||||
ch = KEY_ENTER;
|
||||
|
||||
// F-Keys
|
||||
|
@ -2662,7 +2650,7 @@ boolean M_Responder(event_t *ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ch == gamecontrol[gc_brake][0] || ch == gamecontrol[gc_brake][1]) // do this here, otherwise brake opens the menu mid-game
|
||||
if ((ch == gamecontrol[gc_brake][0] || ch == gamecontrol[gc_brake][1]) && ch >= KEY_MOUSE1) // do this here, otherwise brake opens the menu mid-game
|
||||
ch = KEY_ESCAPE;
|
||||
|
||||
routine = currentMenu->menuitems[itemOn].itemaction;
|
||||
|
@ -2708,8 +2696,11 @@ boolean M_Responder(event_t *ev)
|
|||
// BP: one of the more big hack i have never made
|
||||
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)
|
||||
ch = shiftxform[ch];
|
||||
if (M_ChangeStringCvar(ch))
|
||||
|
@ -2773,10 +2764,10 @@ boolean M_Responder(event_t *ev)
|
|||
|| (currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_SUBMENU)
|
||||
&& (currentMenu->menuitems[itemOn].status & IT_CALLTYPE))
|
||||
{
|
||||
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata)
|
||||
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && majormods)
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
M_StartMessage(M_GetText("This cannot be done with add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
||||
M_StartMessage(M_GetText("This cannot be done with complex add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2910,7 +2901,7 @@ void M_Drawer(void)
|
|||
}
|
||||
|
||||
// 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);
|
||||
if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
|
||||
|
@ -3188,6 +3179,8 @@ void M_Ticker(void)
|
|||
//
|
||||
void M_Init(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
COM_AddCommand("manual", Command_Manual_f);
|
||||
|
||||
CV_RegisterVar(&cv_nextmap);
|
||||
|
@ -3199,7 +3192,6 @@ void M_Init(void)
|
|||
return;
|
||||
|
||||
// Menu hacks
|
||||
CV_RegisterVar(&cv_splitplayers);
|
||||
CV_RegisterVar(&cv_dummymenuplayer);
|
||||
CV_RegisterVar(&cv_dummyteam);
|
||||
CV_RegisterVar(&cv_dummyspectate);
|
||||
|
@ -3235,6 +3227,15 @@ void M_Init(void)
|
|||
quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n...right?\n\n(Press 'Y' to quit)");
|
||||
quitmsg[QUIT3MSG6] = M_GetText("Aww, is Eggman's Nightclub too\ndifficult for you?\n\n(Press 'Y' to quit)");
|
||||
|
||||
// Setup PlayerMenu table
|
||||
for (i = 0; i < MAXSKINS; i++)
|
||||
{
|
||||
PlayerMenu[i].status = (i == 0 ? IT_CALL : IT_DISABLED);
|
||||
PlayerMenu[i].patch = PlayerMenu[i].text = NULL;
|
||||
PlayerMenu[i].itemaction = M_ChoosePlayer;
|
||||
PlayerMenu[i].alphaKey = 0;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Permanently hide some options based on render mode
|
||||
if (rendermode == render_soft)
|
||||
|
@ -3473,7 +3474,7 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y)
|
|||
|
||||
if (emblem->collected)
|
||||
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
|
||||
V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
|
@ -3573,6 +3574,8 @@ static void M_DrawGenericMenu(void)
|
|||
case IT_CVAR:
|
||||
{
|
||||
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
|
||||
char asterisks[MAXSTRINGLENGTH+1];
|
||||
size_t sl;
|
||||
switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
|
||||
{
|
||||
case IT_CV_SLIDER:
|
||||
|
@ -3580,6 +3583,27 @@ static void M_DrawGenericMenu(void)
|
|||
case IT_CV_NOPRINT: // color use this
|
||||
case IT_CV_INVISSLIDER: // monitor toggles use this
|
||||
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:
|
||||
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
|
||||
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
|
||||
|
@ -3787,7 +3811,7 @@ static void M_DrawPauseMenu(void)
|
|||
|
||||
if (emblem->collected)
|
||||
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
|
||||
V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
|
@ -4551,9 +4575,14 @@ static char *M_AddonsHeaderPath(void)
|
|||
#define CLEARNAME Z_Free(refreshdirname);\
|
||||
refreshdirname = NULL
|
||||
|
||||
static boolean prevmajormods = false;
|
||||
|
||||
static void M_AddonsClearName(INT32 choice)
|
||||
{
|
||||
if (!majormods || prevmajormods)
|
||||
{
|
||||
CLEARNAME;
|
||||
}
|
||||
M_StopMessage(choice);
|
||||
}
|
||||
|
||||
|
@ -4563,10 +4592,17 @@ static boolean M_AddonsRefresh(void)
|
|||
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||
{
|
||||
UNEXIST;
|
||||
if (refreshdirname)
|
||||
{
|
||||
CLEARNAME;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (refreshdirmenu & REFRESHDIR_ADDFILE)
|
||||
if (!majormods && prevmajormods)
|
||||
prevmajormods = false;
|
||||
|
||||
if ((refreshdirmenu & REFRESHDIR_ADDFILE) || (majormods && !prevmajormods))
|
||||
{
|
||||
char *message = NULL;
|
||||
|
||||
|
@ -4574,7 +4610,7 @@ static boolean M_AddonsRefresh(void)
|
|||
{
|
||||
S_StartSound(NULL, sfx_s26d);
|
||||
if (refreshdirmenu & REFRESHDIR_MAX)
|
||||
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||
else
|
||||
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||
}
|
||||
|
@ -4583,6 +4619,12 @@ static boolean M_AddonsRefresh(void)
|
|||
S_StartSound(NULL, sfx_s224);
|
||||
message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
|
||||
}
|
||||
else if (majormods && !prevmajormods)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s221);
|
||||
message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing add-ons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||
prevmajormods = majormods;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
|
@ -4733,7 +4775,7 @@ static void M_DrawAddons(void)
|
|||
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
|
||||
|
||||
x = BASEVIDWIDTH - x - 16;
|
||||
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||
V_DrawSmallScaledPatch(x, y + 4, ((!majormods) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||
|
||||
if (modifiedgame)
|
||||
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
|
||||
|
@ -5130,7 +5172,7 @@ static void M_GetAllEmeralds(INT32 choice)
|
|||
emeralds = ((EMERALD7)*2)-1;
|
||||
M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING);
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
static void M_DestroyRobotsResponse(INT32 ch)
|
||||
|
@ -5141,7 +5183,7 @@ static void M_DestroyRobotsResponse(INT32 ch)
|
|||
// Destroy all robots
|
||||
P_DestroyRobots();
|
||||
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
static void M_DestroyRobots(INT32 choice)
|
||||
|
@ -5317,7 +5359,7 @@ static void M_DrawEmblemHints(void)
|
|||
{
|
||||
collected = recommendedflags;
|
||||
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
|
||||
{
|
||||
|
@ -5660,7 +5702,7 @@ static void M_DrawLoadGameData(void)
|
|||
V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE));
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -6350,7 +6392,7 @@ static void M_DrawStatsMaps(int location)
|
|||
|
||||
if (exemblem->collected)
|
||||
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
|
||||
V_DrawSmallScaledPatch(295, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
|
@ -6485,7 +6527,7 @@ void M_DrawTimeAttackMenu(void)
|
|||
// Character face!
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -6610,7 +6652,7 @@ void M_DrawTimeAttackMenu(void)
|
|||
|
||||
if (em->collected)
|
||||
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
|
||||
V_DrawScaledPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
|
@ -6770,7 +6812,7 @@ static boolean M_QuitTimeAttackMenu(void)
|
|||
|
||||
if (em->collected)
|
||||
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
|
||||
V_DrawSmallScaledPatch(160+88, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
|
@ -7239,6 +7281,7 @@ static void M_DrawConnectMenu(void)
|
|||
{
|
||||
UINT16 i, j;
|
||||
const char *gt = "Unknown";
|
||||
const char *spd = "";
|
||||
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
|
||||
|
||||
for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++)
|
||||
|
@ -7292,7 +7335,17 @@ static void M_DrawConnectMenu(void)
|
|||
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
|
||||
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;
|
||||
}
|
||||
|
@ -7408,6 +7461,20 @@ static void M_ConnectMenu(INT32 choice)
|
|||
M_Refresh(0);
|
||||
}
|
||||
|
||||
static void M_ConnectMenuModChecks(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
// okay never mind we want to COMMUNICATE to the player pre-emptively instead of letting them try and then get confused when it doesn't work
|
||||
|
||||
if (modifiedgame)
|
||||
{
|
||||
M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER);
|
||||
return;
|
||||
}
|
||||
|
||||
M_ConnectMenu(-1);
|
||||
}
|
||||
|
||||
static UINT32 roomIds[NUM_LIST_ROOMS];
|
||||
|
||||
static void M_RoomMenu(INT32 choice)
|
||||
|
@ -7513,6 +7580,11 @@ static void M_StartServer(INT32 choice)
|
|||
// Still need to reset devmode
|
||||
cv_debug = 0;
|
||||
|
||||
if (strlen(cv_dummyjoinpassword.string) > 0)
|
||||
D_SetJoinPassword(cv_dummyjoinpassword.string);
|
||||
else
|
||||
joinpasswordset = false;
|
||||
|
||||
if (demoplayback)
|
||||
G_StopDemo();
|
||||
if (metalrecording)
|
||||
|
@ -7732,7 +7804,7 @@ static void M_StartServerMenu(INT32 choice)
|
|||
// CONNECT VIA IP
|
||||
// ==============
|
||||
|
||||
static char setupm_ip[16];
|
||||
static char setupm_ip[28];
|
||||
#endif
|
||||
static UINT8 setupm_pselect = 1;
|
||||
|
||||
|
@ -7765,12 +7837,12 @@ Update the maxplayers label...
|
|||
V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 239);
|
||||
|
||||
// draw name string
|
||||
V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip);
|
||||
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip);
|
||||
|
||||
// draw text cursor for name
|
||||
if (itemOn == 8
|
||||
&& skullAnimCounter < 4) //blink cursor
|
||||
V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false);
|
||||
V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false);
|
||||
#endif
|
||||
|
||||
// character bar, ripped off the color bar :V
|
||||
|
@ -7814,7 +7886,7 @@ Update the maxplayers label...
|
|||
if (!trans && i > cv_splitplayers.value)
|
||||
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);
|
||||
|
||||
|
@ -7984,10 +8056,11 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
|
||||
default:
|
||||
l = strlen(setupm_ip);
|
||||
if (l >= 16-1)
|
||||
if (l >= 28-1)
|
||||
break;
|
||||
|
||||
if (choice == 46 || (choice >= 48 && choice <= 57)) // Rudimentary number and period enforcing
|
||||
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
|
||||
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z'))
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1); // Tails
|
||||
setupm_ip[l] = (char)choice;
|
||||
|
@ -8001,7 +8074,6 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
setupm_ip[l] = (char)choice;
|
||||
setupm_ip[l+1] = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8125,7 +8197,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
|
||||
statdot = W_CachePatchName("K_SDOT2", PU_CACHE); // coloured center
|
||||
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
|
||||
#define charw 72
|
||||
|
@ -8195,7 +8267,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
offx = 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);
|
||||
if (scale == FRACUNIT) // bit of a hack
|
||||
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, cursor, colmap);
|
||||
|
@ -8241,7 +8313,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
// draw player sprite
|
||||
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)
|
||||
{
|
||||
|
@ -8252,8 +8324,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
}
|
||||
else
|
||||
V_DrawMappedPatch(mx+43, my+131, flags, patch, colormap);
|
||||
|
||||
Z_Free(colormap);
|
||||
}
|
||||
#undef charw
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
#define IT_CV_NOPRINT 1536
|
||||
#define IT_CV_NOMOD 2048
|
||||
#define IT_CV_INVISSLIDER 2560
|
||||
#define IT_CV_PASSWORD 3072
|
||||
|
||||
//call/submenu specific
|
||||
// There used to be a lot more here but ...
|
||||
|
@ -150,7 +151,7 @@ typedef struct menuitem_s
|
|||
UINT8 alphaKey;
|
||||
} menuitem_t;
|
||||
|
||||
extern menuitem_t PlayerMenu[32];
|
||||
extern menuitem_t PlayerMenu[MAXSKINS];
|
||||
|
||||
typedef struct menu_s
|
||||
{
|
||||
|
@ -211,6 +212,7 @@ typedef struct
|
|||
|
||||
extern description_t description[32];
|
||||
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||
extern CV_PossibleValue_t gametype_cons_t[];
|
||||
|
||||
|
|
121
src/m_misc.c
121
src/m_misc.c
|
@ -93,6 +93,7 @@ typedef off_t off64_t;
|
|||
#ifdef PNG_WRITE_SUPPORTED
|
||||
#define USE_PNG // Only actually use PNG if write is supported.
|
||||
#if defined (PNG_WRITE_APNG_SUPPORTED) //|| !defined(PNG_STATIC)
|
||||
#include "apng.h"
|
||||
#define USE_APNG
|
||||
#endif
|
||||
// See hardware/hw_draw.c for a similar check to this one.
|
||||
|
@ -793,13 +794,13 @@ static inline void M_PNGImage(png_structp png_ptr, png_infop png_info_ptr, PNG_C
|
|||
#ifdef USE_APNG
|
||||
static png_structp apng_ptr = NULL;
|
||||
static png_infop apng_info_ptr = NULL;
|
||||
static apng_infop apng_ainfo_ptr = NULL;
|
||||
static png_FILE_p apng_FILE = NULL;
|
||||
static png_uint_32 apng_frames = 0;
|
||||
static png_byte acTL_cn[5] = { 97, 99, 84, 76, '\0'};
|
||||
#ifdef PNG_STATIC // Win32 build have static libpng
|
||||
#define apng_set_acTL png_set_acTL
|
||||
#define apng_write_frame_head png_write_frame_head
|
||||
#define apng_write_frame_tail png_write_frame_tail
|
||||
#define aPNG_set_acTL png_set_acTL
|
||||
#define aPNG_write_frame_head png_write_frame_head
|
||||
#define aPNG_write_frame_tail png_write_frame_tail
|
||||
#else // outside libpng may not have apng support
|
||||
|
||||
#ifndef PNG_WRITE_APNG_SUPPORTED // libpng header may not have apng patch
|
||||
|
@ -836,20 +837,20 @@ static png_byte acTL_cn[5] = { 97, 99, 84, 76, '\0'};
|
|||
#endif
|
||||
|
||||
#endif
|
||||
typedef PNG_EXPORT(png_uint_32, (*P_png_set_acTL)) PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
|
||||
typedef PNG_EXPORT (void, (*P_png_write_frame_head)) PNGARG((png_structp png_ptr,
|
||||
typedef png_uint_32 (*P_png_set_acTL) (png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays);
|
||||
typedef void (*P_png_write_frame_head) (png_structp png_ptr,
|
||||
png_infop info_ptr, png_bytepp row_pointers,
|
||||
png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
|
||||
png_byte blend_op));
|
||||
png_byte blend_op);
|
||||
|
||||
typedef PNG_EXPORT (void, (*P_png_write_frame_tail)) PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
static P_png_set_acTL apng_set_acTL = NULL;
|
||||
static P_png_write_frame_head apng_write_frame_head = NULL;
|
||||
static P_png_write_frame_tail apng_write_frame_tail = NULL;
|
||||
typedef void (*P_png_write_frame_tail) (png_structp png_ptr,
|
||||
png_infop info_ptr);
|
||||
static P_png_set_acTL aPNG_set_acTL = NULL;
|
||||
static P_png_write_frame_head aPNG_write_frame_head = NULL;
|
||||
static P_png_write_frame_tail aPNG_write_frame_tail = NULL;
|
||||
#endif
|
||||
|
||||
static inline boolean M_PNGLib(void)
|
||||
|
@ -858,7 +859,7 @@ static inline boolean M_PNGLib(void)
|
|||
return true;
|
||||
#else
|
||||
static void *pnglib = NULL;
|
||||
if (apng_set_acTL && apng_write_frame_head && apng_write_frame_tail)
|
||||
if (aPNG_set_acTL && aPNG_write_frame_head && aPNG_write_frame_tail)
|
||||
return true;
|
||||
if (pnglib)
|
||||
return false;
|
||||
|
@ -878,16 +879,16 @@ static inline boolean M_PNGLib(void)
|
|||
if (!pnglib)
|
||||
return false;
|
||||
#ifdef HAVE_SDL
|
||||
apng_set_acTL = hwSym("png_set_acTL", pnglib);
|
||||
apng_write_frame_head = hwSym("png_write_frame_head", pnglib);
|
||||
apng_write_frame_tail = hwSym("png_write_frame_tail", pnglib);
|
||||
aPNG_set_acTL = hwSym("png_set_acTL", pnglib);
|
||||
aPNG_write_frame_head = hwSym("png_write_frame_head", pnglib);
|
||||
aPNG_write_frame_tail = hwSym("png_write_frame_tail", pnglib);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
apng_set_acTL = GetProcAddress("png_set_acTL", pnglib);
|
||||
apng_write_frame_head = GetProcAddress("png_write_frame_head", pnglib);
|
||||
apng_write_frame_tail = GetProcAddress("png_write_frame_tail", pnglib);
|
||||
aPNG_set_acTL = GetProcAddress("png_set_acTL", pnglib);
|
||||
aPNG_write_frame_head = GetProcAddress("png_write_frame_head", pnglib);
|
||||
aPNG_write_frame_tail = GetProcAddress("png_write_frame_tail", pnglib);
|
||||
#endif
|
||||
return (apng_set_acTL && apng_write_frame_head && apng_write_frame_tail);
|
||||
return (aPNG_set_acTL && aPNG_write_frame_head && aPNG_write_frame_tail);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -901,11 +902,6 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
|
|||
|
||||
apng_frames++;
|
||||
|
||||
#ifndef PNG_STATIC
|
||||
if (apng_set_acTL)
|
||||
#endif
|
||||
apng_set_acTL(apng_ptr, apng_info_ptr, apng_frames, 0);
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
row_pointers[y] = png_buf;
|
||||
|
@ -913,9 +909,9 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
|
|||
}
|
||||
|
||||
#ifndef PNG_STATIC
|
||||
if (apng_write_frame_head)
|
||||
if (aPNG_write_frame_head)
|
||||
#endif
|
||||
apng_write_frame_head(apng_ptr, apng_info_ptr, row_pointers,
|
||||
aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers,
|
||||
vid.width, /* width */
|
||||
height, /* height */
|
||||
0, /* x offset */
|
||||
|
@ -928,57 +924,21 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
|
|||
png_write_image(png_ptr, row_pointers);
|
||||
|
||||
#ifndef PNG_STATIC
|
||||
if (apng_write_frame_tail)
|
||||
if (aPNG_write_frame_tail)
|
||||
#endif
|
||||
apng_write_frame_tail(apng_ptr, apng_info_ptr);
|
||||
aPNG_write_frame_tail(apng_ptr, apng_info_ptr);
|
||||
|
||||
png_free(png_ptr, (png_voidp)row_pointers);
|
||||
}
|
||||
|
||||
static inline boolean M_PNGfind_acTL(void)
|
||||
static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr,
|
||||
apng_infop png_ainfo_ptr)
|
||||
{
|
||||
png_byte cn[8]; // 4 bytes for len then 4 byes for name
|
||||
long endpos = ftell(apng_FILE); // not the real end of file, just what of libpng wrote
|
||||
for (fseek(apng_FILE, 0, SEEK_SET); // let go to the start of the file
|
||||
ftell(apng_FILE)+12 < endpos; // let not go over the file bound
|
||||
fseek(apng_FILE, 1, SEEK_CUR) // we went 8 steps back and now we go 1 step forward
|
||||
)
|
||||
{
|
||||
if (fread(cn, sizeof(cn), 1, apng_FILE) != 1) // read 8 bytes
|
||||
return false; // failed to read data
|
||||
if (fseek(apng_FILE, -8, SEEK_CUR) != 0) //rewind 8 bytes
|
||||
return false; // failed to rewird
|
||||
if (!png_memcmp(cn+4, acTL_cn, 4)) //cmp for chuck header
|
||||
return true; // found it
|
||||
}
|
||||
return false; // acTL chuck not found
|
||||
}
|
||||
|
||||
static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr)
|
||||
{
|
||||
png_byte data[16];
|
||||
long oldpos;
|
||||
|
||||
#ifndef PNG_STATIC
|
||||
if (apng_set_acTL)
|
||||
#endif
|
||||
apng_set_acTL(png_ptr, png_info_ptr, apng_frames, 0);
|
||||
apng_set_acTL(png_ptr, png_info_ptr, png_ainfo_ptr, apng_frames, 0);
|
||||
|
||||
#ifndef NO_PNG_DEBUG
|
||||
png_debug(1, "in png_write_acTL\n");
|
||||
#endif
|
||||
|
||||
png_ptr->num_frames_to_write = apng_frames;
|
||||
|
||||
png_save_uint_32(data, apng_frames);
|
||||
png_save_uint_32(data + 4, 0);
|
||||
|
||||
oldpos = ftell(apng_FILE);
|
||||
|
||||
if (M_PNGfind_acTL())
|
||||
png_write_chunk(png_ptr, (png_bytep)acTL_cn, data, (png_size_t)8);
|
||||
|
||||
fseek(apng_FILE, oldpos, SEEK_SET);
|
||||
}
|
||||
|
||||
static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
||||
|
@ -1010,6 +970,16 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
|||
return false;
|
||||
}
|
||||
|
||||
apng_ainfo_ptr = apng_create_info_struct(apng_ptr);
|
||||
if (!apng_ainfo_ptr)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "M_StartMovie: Error on allocate for apng\n");
|
||||
png_destroy_write_struct(&apng_ptr, &apng_info_ptr);
|
||||
fclose(apng_FILE);
|
||||
remove(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_init_io(apng_ptr, apng_FILE);
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
|
@ -1027,12 +997,11 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
|||
|
||||
M_PNGText(apng_ptr, apng_info_ptr, true);
|
||||
|
||||
#ifndef PNG_STATIC
|
||||
if (apng_set_acTL)
|
||||
#endif
|
||||
apng_set_acTL(apng_ptr, apng_info_ptr, PNG_UINT_31_MAX, 0);
|
||||
apng_set_set_acTL_fn(apng_ptr, apng_ainfo_ptr, aPNG_set_acTL);
|
||||
|
||||
png_write_info(apng_ptr, apng_info_ptr);
|
||||
apng_set_acTL(apng_ptr, apng_info_ptr, apng_ainfo_ptr, PNG_UINT_31_MAX, 0);
|
||||
|
||||
apng_write_info(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
|
||||
|
||||
apng_frames = 0;
|
||||
|
||||
|
@ -1235,8 +1204,8 @@ void M_StopMovie(void)
|
|||
|
||||
if (apng_frames)
|
||||
{
|
||||
M_PNGfix_acTL(apng_ptr, apng_info_ptr);
|
||||
png_write_end(apng_ptr, apng_info_ptr);
|
||||
M_PNGfix_acTL(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
|
||||
apng_write_end(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
|
||||
}
|
||||
|
||||
png_destroy_write_struct(&apng_ptr, &apng_info_ptr);
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#define MD5_LEN 16
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
|
|
|
@ -8264,8 +8264,8 @@ void A_JawzChase(mobj_t *actor)
|
|||
|
||||
if (actor->tracer)
|
||||
{
|
||||
if (G_RaceGametype()) // Stop looking after first target in race
|
||||
actor->extravalue1 = 1;
|
||||
/*if (G_RaceGametype()) // Stop looking after first target in race
|
||||
actor->extravalue1 = 1;*/
|
||||
|
||||
if (actor->tracer->health)
|
||||
{
|
||||
|
@ -8364,13 +8364,13 @@ void A_SPBChase(mobj_t *actor)
|
|||
if (!playeringame[i] || players[i].spectator || players[i].exiting)
|
||||
continue; // not in-game
|
||||
|
||||
if (!players[i].mo)
|
||||
/*if (!players[i].mo)
|
||||
continue; // no mobj
|
||||
|
||||
if (players[i].mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
/*if (players[i].kartstuff[k_respawn])
|
||||
if (players[i].kartstuff[k_respawn])
|
||||
continue;*/ // respawning
|
||||
|
||||
if (players[i].kartstuff[k_position] < bestrank)
|
||||
|
@ -8386,18 +8386,35 @@ void A_SPBChase(mobj_t *actor)
|
|||
{
|
||||
fixed_t defspeed = wspeed;
|
||||
fixed_t range = (160*actor->tracer->scale);
|
||||
fixed_t cx = 0, cy =0;
|
||||
|
||||
// Play the intimidating gurgle
|
||||
if (!S_SoundPlaying(actor, actor->info->activesound))
|
||||
S_StartSound(actor, actor->info->activesound);
|
||||
|
||||
// Maybe we want SPB to target an object later? IDK lol
|
||||
if (actor->tracer->player) // 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel
|
||||
if (actor->tracer->player)
|
||||
{
|
||||
UINT8 fracmax = 32;
|
||||
UINT8 spark = ((10-actor->tracer->player->kartspeed) + actor->tracer->player->kartweight) / 2;
|
||||
fixed_t easiness = ((actor->tracer->player->kartspeed + (10-spark)) << FRACBITS) / 2;
|
||||
|
||||
actor->lastlook = actor->tracer->player-players; // Save the player num for death scumming...
|
||||
|
||||
if (!P_IsObjectOnGround(actor->tracer) /*&& !actor->tracer->player->kartstuff[k_pogospring]*/)
|
||||
defspeed = (7*actor->tracer->player->speed)/8; // In the air you have no control; basically don't hit unless you make a near complete stop
|
||||
{
|
||||
// In the air you have no control; basically don't hit unless you make a near complete stop
|
||||
defspeed = (7 * actor->tracer->player->speed) / 8;
|
||||
}
|
||||
else
|
||||
defspeed = ((33 - actor->tracer->player->kartspeed) * K_GetKartSpeed(actor->tracer->player, false)) / 32;
|
||||
{
|
||||
// 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel
|
||||
defspeed = FixedMul(((fracmax+1)<<FRACBITS) - easiness, K_GetKartSpeed(actor->tracer->player, false)) / fracmax;
|
||||
}
|
||||
|
||||
defspeed -= (9*R_PointToDist2(0, 0, actor->tracer->player->cmomx, actor->tracer->player->cmomy))/8; // Be fairer on conveyors
|
||||
// Be fairer on conveyors
|
||||
cx = actor->tracer->player->cmomx;
|
||||
cy = actor->tracer->player->cmomy;
|
||||
|
||||
// Switch targets if you're no longer 1st for long enough
|
||||
if (actor->tracer->player->kartstuff[k_position] <= bestrank)
|
||||
|
@ -8408,10 +8425,6 @@ void A_SPBChase(mobj_t *actor)
|
|||
spbplace = actor->tracer->player->kartstuff[k_position];
|
||||
}
|
||||
|
||||
// Play the intimidating gurgle
|
||||
if (!S_SoundPlaying(actor, actor->info->activesound))
|
||||
S_StartSound(actor, actor->info->activesound);
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
||||
|
||||
wspeed = FixedMul(defspeed, FRACUNIT + FixedDiv(dist-range, range));
|
||||
|
@ -8419,10 +8432,18 @@ void A_SPBChase(mobj_t *actor)
|
|||
wspeed = defspeed;
|
||||
if (wspeed > (3*defspeed)/2)
|
||||
wspeed = (3*defspeed)/2;
|
||||
if (wspeed < 20*actor->tracer->scale)
|
||||
wspeed = 20*actor->tracer->scale;
|
||||
|
||||
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
|
||||
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);
|
||||
|
||||
// Modify stored speed
|
||||
if (wspeed > actor->cvmem)
|
||||
actor->cvmem += (wspeed - actor->cvmem) / TICRATE;
|
||||
else
|
||||
actor->cvmem = wspeed;
|
||||
|
||||
{
|
||||
// Smoothly rotate horz angle
|
||||
angle_t input = hang - actor->angle;
|
||||
|
@ -8431,7 +8452,7 @@ void A_SPBChase(mobj_t *actor)
|
|||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; it looks better and makes U-turns not unfair
|
||||
xyspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
xyspeed = FixedMul(actor->cvmem, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
|
@ -8446,7 +8467,7 @@ void A_SPBChase(mobj_t *actor)
|
|||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; might as well do it for momz, since we do it above too
|
||||
zspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
zspeed = FixedMul(actor->cvmem, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
|
@ -8455,8 +8476,8 @@ void A_SPBChase(mobj_t *actor)
|
|||
actor->movedir += input;
|
||||
}
|
||||
|
||||
actor->momx = FixedMul(FixedMul(xyspeed, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momy = FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momx = cx + FixedMul(FixedMul(xyspeed, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momy = cy + FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
|
||||
// Red speed lines for when it's gaining on its target. A tell for when you're starting to lose too much speed!
|
||||
|
@ -8491,15 +8512,18 @@ void A_SPBChase(mobj_t *actor)
|
|||
{
|
||||
actor->momx = actor->momy = actor->momz = 0; // Stoooop
|
||||
|
||||
if (actor->lastlook != -1 && playeringame[actor->lastlook] && players[actor->lastlook].mo)
|
||||
if (actor->lastlook != -1
|
||||
&& playeringame[actor->lastlook]
|
||||
&& !players[actor->lastlook].spectator
|
||||
&& !players[actor->lastlook].exiting)
|
||||
{
|
||||
spbplace = players[actor->lastlook].kartstuff[k_position];
|
||||
if (actor->extravalue2-- <= 0)
|
||||
if (actor->extravalue2-- <= 0 && players[actor->lastlook].mo)
|
||||
{
|
||||
P_SetTarget(&actor->tracer, players[actor->lastlook].mo);
|
||||
actor->extravalue1 = 1; // TARGETING
|
||||
actor->extravalue1 = 1; // TARGET ACQUIRED
|
||||
actor->extravalue2 = 7*TICRATE;
|
||||
actor->extravalue2 = 0;
|
||||
actor->cvmem = wspeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -8513,21 +8537,11 @@ void A_SPBChase(mobj_t *actor)
|
|||
{
|
||||
actor->lastlook = -1; // Just make sure this is reset
|
||||
|
||||
// No one there?
|
||||
if (player == NULL || !player->mo)
|
||||
if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn])
|
||||
{
|
||||
#if 0
|
||||
// SELF-DESTRUCT?
|
||||
mobj_t *spbexplode;
|
||||
|
||||
S_StopSound(actor); // Don't continue playing the gurgle or the siren
|
||||
spbexplode = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SPBEXPLOSION);
|
||||
P_SetTarget(&spbexplode->target, actor->target);
|
||||
|
||||
P_RemoveMobj(actor);
|
||||
#else
|
||||
// No one there? Completely STOP.
|
||||
actor->momx = actor->momy = actor->momz = 0;
|
||||
#endif
|
||||
if (!player)
|
||||
spbplace = -1;
|
||||
return;
|
||||
}
|
||||
|
@ -8582,6 +8596,7 @@ void A_SPBChase(mobj_t *actor)
|
|||
S_StartSound(actor, actor->info->attacksound); // Siren sound; might not need this anymore, but I'm keeping it for now just for debugging.
|
||||
actor->extravalue1 = 1; // TARGET ACQUIRED
|
||||
actor->extravalue2 = 7*TICRATE;
|
||||
actor->cvmem = wspeed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8625,6 +8640,7 @@ void A_LightningFollowPlayer(mobj_t *actor)
|
|||
else // else just teleport to player directly
|
||||
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->momy = actor->target->momy;
|
||||
actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame.
|
||||
|
|
|
@ -141,6 +141,9 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|
|||
|| (weapon != 3 && player->kartstuff[k_itemamount])
|
||||
|| player->kartstuff[k_itemheld])
|
||||
return false;
|
||||
|
||||
if (weapon == 3 && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD)
|
||||
return false; // No stacking thunder shields!
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,6 +414,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
player->kartstuff[k_roulettetype] = 2;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Eggbox snipe!
|
||||
if (special->type == MT_EGGMANITEM && special->health > 1)
|
||||
S_StartSound(toucher, sfx_bsnipe);
|
||||
#endif
|
||||
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->deathsound);
|
||||
|
@ -579,30 +588,31 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (special->health <= 0 || toucher->health <= 0)
|
||||
return;
|
||||
|
||||
if (!player->mo || player->spectator)
|
||||
if (player->spectator)
|
||||
return;
|
||||
|
||||
if (special->tracer && toucher == special->tracer)
|
||||
if (special->tracer && !P_MobjWasRemoved(special->tracer) && toucher == special->tracer)
|
||||
{
|
||||
mobj_t *spbexplode;
|
||||
|
||||
S_StopSound(special); // Don't continue playing the gurgle or the siren
|
||||
|
||||
if (!player->kartstuff[k_invincibilitytimer] && !player->kartstuff[k_growshrinktimer])
|
||||
if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0)
|
||||
{
|
||||
//player->powers[pw_flashing] = 0;
|
||||
K_DropHnextList(player);
|
||||
K_StripItems(player);
|
||||
//player->powers[pw_flashing] = 0;
|
||||
}
|
||||
|
||||
S_StopSound(special); // Don't continue playing the gurgle or the siren
|
||||
|
||||
spbexplode = P_SpawnMobj(toucher->x, toucher->y, toucher->z, MT_SPBEXPLOSION);
|
||||
spbexplode->extravalue1 = 1; // Tell K_ExplodePlayer to use extra knockback
|
||||
if (special->target && !P_MobjWasRemoved(special->target))
|
||||
P_SetTarget(&spbexplode->target, special->target);
|
||||
|
||||
P_RemoveMobj(special);
|
||||
}
|
||||
else
|
||||
K_SpinPlayer(player, NULL, 0, special, false);
|
||||
K_SpinPlayer(player, special->target, 0, special, false);
|
||||
return;
|
||||
/*case MT_EERIEFOG:
|
||||
special->frame &= ~FF_TRANS80;
|
||||
|
@ -1467,6 +1477,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
player->starpostz = special->z>>FRACBITS;
|
||||
player->starpostangle = special->angle;
|
||||
player->starpostnum = special->health;
|
||||
player->kartstuff[k_starpostflip] = special->spawnpoint->options & MTF_OBJECTFLIP; // store flipping
|
||||
|
||||
//S_StartSound(toucher, special->info->painsound);
|
||||
return;
|
||||
|
@ -2951,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)
|
||||
{
|
||||
if (player->powers[pw_shield] & SH_FORCE)
|
||||
|
|
|
@ -128,7 +128,6 @@ extern fixed_t t_cam4_dist, t_cam4_height, t_cam4_rotate;
|
|||
|
||||
fixed_t P_GetPlayerHeight(player_t *player);
|
||||
fixed_t P_GetPlayerSpinHeight(player_t *player);
|
||||
INT32 P_GetPlayerControlDirection(player_t *player);
|
||||
void P_AddPlayerScore(player_t *player, UINT32 amount);
|
||||
void P_ResetCamera(player_t *player, camera_t *thiscam);
|
||||
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
|
@ -275,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);
|
||||
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);
|
||||
#define PAL_WHITE 1
|
||||
#define PAL_MIXUP 2
|
||||
|
|
273
src/p_map.c
273
src/p_map.c
|
@ -747,13 +747,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
&& !(tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD))
|
||||
return true;
|
||||
|
||||
if (thing->player && thing->player->kartstuff[k_hyudorotimer])
|
||||
return true; // no interaction
|
||||
|
||||
if (thing->type == MT_PLAYER)
|
||||
{
|
||||
// Player Damage
|
||||
P_DamageMobj(thing, tmthing, tmthing->target, 1);
|
||||
K_KartBouncing(thing, tmthing, false, false);
|
||||
|
||||
if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD)
|
||||
S_StartSound(thing, sfx_s3k7b);
|
||||
|
||||
// This Item Damage
|
||||
|
@ -852,7 +853,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_PLAYER)
|
||||
{
|
||||
S_StartSound(NULL, sfx_cgot); //let all players hear it.
|
||||
S_StartSound(NULL, sfx_bsnipe); //let all players hear it.
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
|
||||
|
@ -914,6 +915,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_PLAYER)
|
||||
{
|
||||
// Banana snipe!
|
||||
if (tmthing->type == MT_BANANA && tmthing->health > 1)
|
||||
S_StartSound(thing, sfx_bsnipe);
|
||||
|
||||
// Player Damage
|
||||
K_SpinPlayer(thing->player, tmthing->target, 0, tmthing, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD));
|
||||
|
||||
|
@ -982,7 +987,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_PLAYER)
|
||||
{
|
||||
// Bomb punting
|
||||
if ((tmthing->state >= &states[S_SSMINE1] && tmthing->state <= &states[S_SSMINE4])
|
||||
|| (tmthing->state >= &states[S_SSMINE_DEPLOY8] && tmthing->state <= &states[S_SSMINE_DEPLOY13]))
|
||||
P_KillMobj(tmthing, thing, thing);
|
||||
else
|
||||
K_PuntMine(tmthing, thing);
|
||||
}
|
||||
else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD
|
||||
|| thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD)
|
||||
|
@ -1023,6 +1033,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
&& !(thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD))
|
||||
return true;
|
||||
|
||||
if (tmthing->player && tmthing->player->kartstuff[k_hyudorotimer]) // I thought about doing this for just the objects below but figured it should apply to everything.
|
||||
return true; // no interaction
|
||||
|
||||
if (thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD
|
||||
|| thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)
|
||||
{
|
||||
|
@ -1035,8 +1048,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
// Player Damage
|
||||
P_DamageMobj(tmthing, thing, thing->target, 1);
|
||||
K_KartBouncing(tmthing, thing, false, false);
|
||||
|
||||
if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)
|
||||
S_StartSound(tmthing, sfx_s3k7b);
|
||||
|
||||
// Other Item Damage
|
||||
|
@ -1060,6 +1071,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (tmthing->health <= 0 || thing->health <= 0)
|
||||
return true;
|
||||
|
||||
// Banana snipe!
|
||||
if (thing->type == MT_BANANA && thing->health > 1)
|
||||
S_StartSound(tmthing, sfx_bsnipe);
|
||||
|
||||
// Player Damage
|
||||
K_SpinPlayer(tmthing->player, thing->target, 0, tmthing, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD));
|
||||
|
||||
|
@ -1083,7 +1098,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (tmthing->health <= 0 || thing->health <= 0)
|
||||
return true;
|
||||
|
||||
// Bomb punting
|
||||
if ((thing->state >= &states[S_SSMINE1] && thing->state <= &states[S_SSMINE4])
|
||||
|| (thing->state >= &states[S_SSMINE_DEPLOY8] && thing->state <= &states[S_SSMINE_DEPLOY13]))
|
||||
P_KillMobj(thing, tmthing, tmthing);
|
||||
else
|
||||
K_PuntMine(thing, tmthing);
|
||||
}
|
||||
else if (thing->type == MT_MINEEXPLOSION && tmthing->player)
|
||||
{
|
||||
|
@ -2094,7 +2114,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
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))
|
||||
;
|
||||
|
@ -2767,8 +2787,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
// HACK TO FIX DSZ2: apply only if slopes are involved
|
||||
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||
{
|
||||
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
|
@ -2781,8 +2800,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
// HACK TO FIX DSZ2: apply only if slopes are involved
|
||||
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||
{
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
|
@ -3231,129 +3249,6 @@ isblocking:
|
|||
return false; // stop
|
||||
}
|
||||
|
||||
//
|
||||
// P_IsClimbingValid
|
||||
//
|
||||
// Unlike P_DoClimbing, don't use when up against a one-sided linedef.
|
||||
//
|
||||
static boolean P_IsClimbingValid(player_t *player, angle_t angle)
|
||||
{
|
||||
fixed_t platx, platy;
|
||||
subsector_t *glidesector;
|
||||
fixed_t floorz, ceilingz;
|
||||
|
||||
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
||||
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
||||
|
||||
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
|
||||
|
||||
#ifdef ESLOPE
|
||||
floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight;
|
||||
ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight;
|
||||
#else
|
||||
floorz = glidesector->sector->floorheight;
|
||||
ceilingz = glidesector->sector->ceilingheight;
|
||||
#endif
|
||||
|
||||
if (glidesector->sector != player->mo->subsector->sector)
|
||||
{
|
||||
boolean floorclimb = false;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (glidesector->sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
|
||||
continue;
|
||||
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
|
||||
if (*rover->b_slope)
|
||||
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
|
||||
#endif
|
||||
|
||||
floorclimb = true;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
|
||||
{
|
||||
floorclimb = true;
|
||||
}
|
||||
if (topheight < player->mo->z) // Waaaay below the ledge.
|
||||
{
|
||||
floorclimb = false;
|
||||
}
|
||||
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
|
||||
{
|
||||
floorclimb = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
|
||||
{
|
||||
floorclimb = true;
|
||||
}
|
||||
if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
|
||||
{
|
||||
floorclimb = false;
|
||||
}
|
||||
if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
|
||||
{
|
||||
floorclimb = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (floorclimb)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if ((floorz <= player->mo->z + player->mo->height)
|
||||
&& ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
|
||||
floorclimb = true;
|
||||
|
||||
if ((floorz > player->mo->z)
|
||||
&& glidesector->sector->floorpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
|
||||
|| (player->mo->z + player->mo->height <= floorz))
|
||||
floorclimb = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ceilingz >= player->mo->z)
|
||||
&& ((player->mo->z - player->mo->momz) >= ceilingz))
|
||||
floorclimb = true;
|
||||
|
||||
if ((ceilingz < player->mo->z+player->mo->height)
|
||||
&& glidesector->sector->ceilingpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|
||||
|| (player->mo->z >= ceilingz))
|
||||
floorclimb = true;
|
||||
}
|
||||
|
||||
if (!floorclimb)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// PTR_SlideTraverse
|
||||
//
|
||||
|
@ -3407,117 +3302,7 @@ isblocking:
|
|||
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
|
||||
}
|
||||
|
||||
if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)
|
||||
&& slidemo->player->charability == CA_GLIDEANDCLIMB)
|
||||
{
|
||||
line_t *checkline = li;
|
||||
sector_t *checksector;
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
boolean fofline = false;
|
||||
INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li);
|
||||
|
||||
if (!side && li->backsector)
|
||||
checksector = li->backsector;
|
||||
else
|
||||
checksector = li->frontsector;
|
||||
|
||||
if (checksector->ffloors)
|
||||
{
|
||||
for (rover = checksector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
|
||||
continue;
|
||||
|
||||
topheight = *rover->topheight;
|
||||
bottomheight = *rover->bottomheight;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
|
||||
if (*rover->b_slope)
|
||||
bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
|
||||
#endif
|
||||
|
||||
if (topheight < slidemo->z)
|
||||
continue;
|
||||
|
||||
if (bottomheight > slidemo->z + slidemo->height)
|
||||
continue;
|
||||
|
||||
// Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this?
|
||||
if (rover->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = li-checksector->lines[0];
|
||||
checkline = rover->master->frontsector->lines[0] + linenum;
|
||||
fofline = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// see about climbing on the wall
|
||||
if (!(checkline->flags & ML_NOCLIMB))
|
||||
{
|
||||
boolean canclimb;
|
||||
angle_t climbangle, climbline;
|
||||
INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li);
|
||||
|
||||
climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y);
|
||||
|
||||
if (whichside) // on second side?
|
||||
climbline += ANGLE_180;
|
||||
|
||||
climbangle += (ANGLE_90 * (whichside ? -1 : 1));
|
||||
|
||||
canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true);
|
||||
|
||||
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|
||||
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
|
||||
&& canclimb)
|
||||
{
|
||||
slidemo->angle = climbangle;
|
||||
if (!demoplayback || P_AnalogMove(slidemo->player))
|
||||
{
|
||||
if (slidemo->player == &players[consoleplayer])
|
||||
localangle = slidemo->angle;
|
||||
else if (slidemo->player == &players[secondarydisplayplayer])
|
||||
localangle2 = slidemo->angle;
|
||||
else if (slidemo->player == &players[thirddisplayplayer])
|
||||
localangle3 = slidemo->angle;
|
||||
else if (slidemo->player == &players[fourthdisplayplayer])
|
||||
localangle4 = slidemo->angle;
|
||||
}
|
||||
|
||||
if (!slidemo->player->climbing)
|
||||
{
|
||||
S_StartSound(slidemo->player->mo, sfx_s3k4a);
|
||||
slidemo->player->climbing = 5;
|
||||
}
|
||||
|
||||
slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_THOKKED);
|
||||
slidemo->player->glidetime = 0;
|
||||
slidemo->player->secondjump = 0;
|
||||
|
||||
if (slidemo->player->climbing > 1)
|
||||
slidemo->momz = slidemo->momx = slidemo->momy = 0;
|
||||
|
||||
if (fofline)
|
||||
whichside = 0;
|
||||
|
||||
if (!whichside)
|
||||
{
|
||||
slidemo->player->lastsidehit = checkline->sidenum[whichside];
|
||||
slidemo->player->lastlinehit = (INT16)(checkline - lines);
|
||||
}
|
||||
|
||||
P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing))
|
||||
if (in->frac < bestslidefrac)
|
||||
{
|
||||
secondslidefrac = bestslidefrac;
|
||||
secondslideline = bestslideline;
|
||||
|
|
|
@ -649,7 +649,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
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)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||
|
@ -693,7 +693,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
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)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||
|
|
211
src/p_mobj.c
211
src/p_mobj.c
|
@ -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);
|
||||
#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?
|
||||
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.
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
|
||||
|
@ -260,51 +210,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
st = &states[state];
|
||||
mobj->state = st;
|
||||
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->frame = st->frame;
|
||||
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
|
||||
|
@ -1354,7 +1259,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way
|
||||
P_PlayerFlip(mo);
|
||||
if (mo->player->kartstuff[k_pogospring])
|
||||
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
|
||||
gravityadd = (5*gravityadd)/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1405,10 +1310,14 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
case MT_BANANA:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_SSMINE:
|
||||
gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2);
|
||||
break;
|
||||
case MT_SINK:
|
||||
gravityadd = FixedMul(gravityadd, 5*FRACUNIT); // Double gravity
|
||||
if (mo->extravalue2 > 0)
|
||||
gravityadd *= mo->extravalue2;
|
||||
/* FALLTHRU */
|
||||
case MT_ORBINAUT:
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_DUD:
|
||||
gravityadd = (5*gravityadd)/2;
|
||||
break;
|
||||
case MT_SIGN:
|
||||
gravityadd /= 8;
|
||||
|
@ -2098,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);
|
||||
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
|
||||
continue;
|
||||
|
@ -3221,28 +3130,6 @@ static boolean P_SceneryZMovement(mobj_t *mo)
|
|||
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->pflags & PF_NIGHTSMODE) && !player->homing
|
||||
&& (((player->charability == CA_SWIM) || player->powers[pw_super] || 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
|
||||
//
|
||||
|
@ -3399,8 +3286,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|
||||
// skipping stone!
|
||||
if (p && p->kartstuff[k_waterskip] < 2
|
||||
&& ((p->speed/2 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|
||||
|| (p->speed > K_GetKartSpeed(p,false)/4 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more!
|
||||
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|
||||
|| (p->speed > K_GetKartSpeed(p,false)/3 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more!
|
||||
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop)
|
||||
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
|
||||
{
|
||||
|
@ -6637,7 +6524,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_SINK_SHIELD:
|
||||
if ((mobj->health > 0
|
||||
&& (!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_RemoveMobj(mobj);
|
||||
|
@ -6651,19 +6538,22 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
fixed_t y = P_RandomRange(-35, 35)*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);
|
||||
P_SetMobjState(smoke, S_OPAQUESMOKE1);
|
||||
K_MatchGenericExtraFlags(smoke, mobj);
|
||||
smoke->scale = mobj->scale * 2;
|
||||
smoke->destscale = mobj->scale * 6;
|
||||
smoke->momz = P_RandomRange(4, 9)*FRACUNIT;
|
||||
smoke->momz = P_RandomRange(4, 9)*FRACUNIT*P_MobjFlip(smoke);
|
||||
}
|
||||
break;
|
||||
case MT_BOOMPARTICLE:
|
||||
{
|
||||
fixed_t x = 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)
|
||||
{
|
||||
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);
|
||||
smoke->scale = mobj->scale/2;
|
||||
smoke->destscale = mobj->scale;
|
||||
|
@ -6672,6 +6562,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
else
|
||||
{
|
||||
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
|
||||
P_SetMobjState(smoke, S_OPAQUESMOKE1);
|
||||
K_MatchGenericExtraFlags(smoke, mobj);
|
||||
smoke->scale = mobj->scale;
|
||||
smoke->destscale = mobj->scale*2;
|
||||
}
|
||||
|
@ -6777,7 +6669,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
else if ((mobj->health > 0
|
||||
&& (!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_RemoveMobj(mobj);
|
||||
|
@ -7225,6 +7117,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
y = mobj->target->y;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
@ -7420,7 +7315,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_BANANA:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_SPB:
|
||||
if (mobj->z <= mobj->floorz)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
|
@ -7433,7 +7328,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
break;
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_DUD:
|
||||
if (mobj->z <= mobj->floorz)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
P_SetMobjState(mobj, mobj->info->xdeathstate);
|
||||
// fallthru
|
||||
case MT_JAWZ_SHIELD:
|
||||
|
@ -7441,10 +7336,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
break;
|
||||
case MT_SSMINE:
|
||||
case MT_SPBEXPLOSION:
|
||||
if (mobj->health > -100)
|
||||
if (mobj->extravalue2 != -100)
|
||||
{
|
||||
P_SetMobjState(mobj, mobj->info->deathstate);
|
||||
mobj->health = -100;
|
||||
mobj->extravalue2 = -100;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7467,7 +7362,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
/* FALLTHRU */
|
||||
case MT_SMK_MOLE:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
if (mobj->z <= mobj->floorz)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
|
@ -7488,7 +7383,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
if (mobj->z <= mobj->floorz)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
|
@ -8157,7 +8052,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->friction = ORIG_FRICTION/4;
|
||||
if (mobj->momx || mobj->momy)
|
||||
P_SpawnGhostMobj(mobj);
|
||||
if (mobj->z <= mobj->floorz && mobj->health > 1)
|
||||
if (P_IsObjectOnGround(mobj) && mobj->health > 1)
|
||||
{
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
mobj->momx = mobj->momy = 0;
|
||||
|
@ -8177,7 +8072,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_SINK:
|
||||
if (mobj->momx || mobj->momy)
|
||||
P_SpawnGhostMobj(mobj);
|
||||
if (mobj->z <= mobj->floorz)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
S_StartSound(mobj, mobj->info->deathsound);
|
||||
P_SetMobjState(mobj, S_NULL);
|
||||
|
@ -8190,28 +8085,26 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->color = mobj->target->player->skincolor;
|
||||
else
|
||||
mobj->color = SKINCOLOR_KETCHUP;
|
||||
|
||||
if (mobj->momx || mobj->momy)
|
||||
P_SpawnGhostMobj(mobj);
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
|
||||
if (P_IsObjectOnGround(mobj) && (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2]))
|
||||
{
|
||||
if (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2])
|
||||
P_SetMobjState(mobj, S_SSMINE_DEPLOY1);
|
||||
if (mobj->reactiontime >= mobj->info->reactiontime)
|
||||
if (mobj->extravalue1 > 0)
|
||||
mobj->extravalue1--;
|
||||
else
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
mobj->reactiontime--;
|
||||
P_SetMobjState(mobj, S_SSMINE_DEPLOY1);
|
||||
}
|
||||
}
|
||||
if (mobj->reactiontime && mobj->reactiontime < mobj->info->reactiontime)
|
||||
{
|
||||
mobj->reactiontime--;
|
||||
if (!mobj->reactiontime)
|
||||
P_KillMobj(mobj, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((mobj->state >= &states[S_SSMINE1] && mobj->state <= &states[S_SSMINE4])
|
||||
|| (mobj->state >= &states[S_SSMINE_DEPLOY8] && mobj->state <= &states[S_SSMINE_DEPLOY13]))
|
||||
A_GrenadeRing(mobj);
|
||||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
break;
|
||||
|
@ -8355,6 +8248,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
break;
|
||||
case MT_INSTASHIELDB:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
/* FALLTHRU */
|
||||
case MT_INSTASHIELDA:
|
||||
if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield]))
|
||||
|
@ -8363,6 +8257,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
break;
|
||||
case MT_BATTLEPOINT:
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target))
|
||||
|
@ -8383,7 +8278,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (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);
|
||||
break;
|
||||
case MT_THUNDERSHIELD:
|
||||
|
@ -8508,6 +8403,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
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
|
||||
{
|
||||
const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->target->scale);
|
||||
|
@ -8529,6 +8428,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetScale(cur, mobj->target->scale);
|
||||
cur->color = mobj->target->color;
|
||||
cur->colorized = true;
|
||||
K_FlipFromObject(cur, mobj->target);
|
||||
|
||||
if (mobj->flags2 & MF2_DONTDRAW)
|
||||
cur->flags2 |= MF2_DONTDRAW;
|
||||
|
@ -11124,7 +11024,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
|
|||
if (mthing->options >> ZSHIFT)
|
||||
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
if (p->kartstuff[k_respawn])
|
||||
z -= 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale;
|
||||
z -= 128*mapobjectscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11132,7 +11032,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
|
|||
if (mthing->options >> ZSHIFT)
|
||||
z += ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
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!
|
||||
|
@ -11193,7 +11093,14 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
|||
#endif
|
||||
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)
|
||||
z = floor;
|
||||
else if (z > ceiling - mobjinfo[MT_PLAYER].height)
|
||||
|
|
|
@ -249,6 +249,8 @@ static void P_NetArchivePlayers(void)
|
|||
|
||||
WRITEUINT32(save_p, players[i].jointime);
|
||||
|
||||
WRITEUINT8(save_p, players[i].splitscreenindex);
|
||||
|
||||
WRITEUINT16(save_p, flags);
|
||||
|
||||
if (flags & CAPSULE)
|
||||
|
@ -282,6 +284,12 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEUINT8(save_p, players[i].accelstart);
|
||||
WRITEUINT8(save_p, players[i].acceleration);
|
||||
WRITEFIXED(save_p, players[i].jumpfactor);
|
||||
|
||||
for (j = 0; j < MAXPREDICTTICS; j++)
|
||||
{
|
||||
WRITEINT16(save_p, players[i].lturn_max[j]);
|
||||
WRITEINT16(save_p, players[i].rturn_max[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,6 +428,8 @@ static void P_NetUnArchivePlayers(void)
|
|||
|
||||
players[i].jointime = READUINT32(save_p);
|
||||
|
||||
players[i].splitscreenindex = READUINT8(save_p);
|
||||
|
||||
flags = READUINT16(save_p);
|
||||
|
||||
if (flags & CAPSULE)
|
||||
|
@ -456,6 +466,12 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].accelstart = READUINT8(save_p);
|
||||
players[i].acceleration = READUINT8(save_p);
|
||||
players[i].jumpfactor = READFIXED(save_p);
|
||||
|
||||
for (j = 0; j < MAXPREDICTTICS; j++)
|
||||
{
|
||||
players[i].lturn_max[j] = READINT16(save_p);
|
||||
players[i].rturn_max[j] = READINT16(save_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,8 +679,6 @@ static void P_NetArchiveWorld(void)
|
|||
|
||||
WRITEUINT16(put, 0xffff);
|
||||
|
||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
||||
// do lines
|
||||
for (i = 0; i < numlines; i++, mld++, li++)
|
||||
{
|
||||
|
@ -3301,6 +3315,7 @@ static void P_NetArchiveMisc(void)
|
|||
|
||||
WRITEUINT32(save_p, wantedcalcdelay);
|
||||
WRITEUINT32(save_p, indirectitemcooldown);
|
||||
WRITEUINT32(save_p, hyubgone);
|
||||
WRITEUINT32(save_p, mapreset);
|
||||
WRITEUINT8(save_p, nospectategrief);
|
||||
WRITEUINT8(save_p, thwompsactive);
|
||||
|
@ -3409,6 +3424,7 @@ static inline boolean P_NetUnArchiveMisc(void)
|
|||
|
||||
wantedcalcdelay = READUINT32(save_p);
|
||||
indirectitemcooldown = READUINT32(save_p);
|
||||
hyubgone = READUINT32(save_p);
|
||||
mapreset = READUINT32(save_p);
|
||||
nospectategrief = READUINT8(save_p);
|
||||
thwompsactive = (boolean)READUINT8(save_p);
|
||||
|
|
|
@ -234,7 +234,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE);
|
||||
mapheaderinfo[num]->levelflags = 0;
|
||||
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
|
||||
mapheaderinfo[num]->menuflags = 0;
|
||||
mapheaderinfo[num]->menuflags = (mainwads ? 0 : LF2_EXISTSHACK); // see p_setup.c - prevents replacing maps in addons with easier versions
|
||||
// TODO grades support for delfile (pfft yeah right)
|
||||
P_DeleteGrades(num);
|
||||
// SRB2Kart
|
||||
|
@ -1120,7 +1120,7 @@ static inline void P_SpawnEmblems(void)
|
|||
static void P_SpawnSecretItems(boolean loademblems)
|
||||
{
|
||||
// Now let's spawn those funky emblem things! Tails 12-08-2002
|
||||
if (netgame || multiplayer || (modifiedgame && !savemoddata)) // No cheating!!
|
||||
if (netgame || multiplayer || majormods) // No cheating!!
|
||||
return;
|
||||
|
||||
if (loademblems)
|
||||
|
@ -2857,6 +2857,9 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
lastwipetic = nowtime;
|
||||
if (moviemode) // make sure we save frames for the white hold too
|
||||
M_SaveFrame();
|
||||
|
||||
// Keep the network alive
|
||||
NetKeepAlive();
|
||||
}
|
||||
|
||||
ranspecialwipe = 1;
|
||||
|
@ -3211,10 +3214,9 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
if (!cv_analog4.changed)
|
||||
CV_SetValue(&cv_analog4, 0);*/
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
|
||||
#endif
|
||||
// Shouldn't be necessary with render parity?
|
||||
/*if (rendermode != render_none)
|
||||
CV_Set(&cv_fov, cv_fov.defaultvalue);*/
|
||||
|
||||
displayplayer = consoleplayer; // Start with your OWN view, please!
|
||||
}
|
||||
|
@ -3241,6 +3243,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
hyubgone = 0;
|
||||
mapreset = 0;
|
||||
nospectategrief = 0;
|
||||
thwompsactive = false;
|
||||
|
@ -3272,7 +3275,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
nextmapoverride = 0;
|
||||
skipstats = false;
|
||||
|
||||
if (!(netgame || multiplayer) && (!modifiedgame || savemoddata))
|
||||
if (!(netgame || multiplayer) && !majormods)
|
||||
mapvisited[gamemap-1] |= MV_VISITED;
|
||||
|
||||
levelloading = false;
|
||||
|
@ -3455,6 +3458,14 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
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;
|
||||
}
|
||||
|
||||
//If you replaced the map you're on, end the level when done.
|
||||
if (num == gamemap)
|
||||
replacedcurrentmap = true;
|
||||
|
@ -3481,6 +3492,8 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
||||
refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that...
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
22
src/p_spec.c
22
src/p_spec.c
|
@ -1758,12 +1758,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
|
||||
switch (specialtype)
|
||||
{
|
||||
case 305: // continuous
|
||||
/*case 305: // continuous
|
||||
case 306: // each time
|
||||
case 307: // once
|
||||
if (!(actor && actor->player && actor->player->charability == dist/10))
|
||||
return false;
|
||||
break;
|
||||
break;*/
|
||||
case 309: // continuous
|
||||
case 310: // each time
|
||||
// Only red team members can activate this.
|
||||
|
@ -3864,14 +3864,6 @@ DoneSection2:
|
|||
|
||||
P_InstaThrust(player->mo, player->mo->angle, linespeed);
|
||||
|
||||
/*if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH)) // SRB2kart
|
||||
{
|
||||
if (!(player->pflags & PF_SPINNING))
|
||||
player->pflags |= PF_SPINNING;
|
||||
|
||||
//P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
|
||||
}*/
|
||||
|
||||
player->kartstuff[k_dashpadcooldown] = TICRATE/3;
|
||||
player->kartstuff[k_drift] = 0;
|
||||
player->kartstuff[k_driftcharge] = 0;
|
||||
|
@ -4255,13 +4247,14 @@ DoneSection2:
|
|||
player->starpostx = player->mo->x>>FRACBITS;
|
||||
player->starposty = player->mo->y>>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...
|
||||
}
|
||||
else
|
||||
{
|
||||
// SRB2kart 200117
|
||||
// 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))
|
||||
|
@ -5781,7 +5774,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
lines[i].special = 0;
|
||||
continue;
|
||||
}
|
||||
/*else -- commented out because irrelevant to kart
|
||||
/*else -- commented out because irrelevant to kart. keeping here because we can use these flags for something else now
|
||||
{
|
||||
if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||
|| (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||
|
@ -7997,12 +7990,13 @@ static void P_SearchForDisableLinedefs(void)
|
|||
}
|
||||
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
||||
continue; // Net-only never triggers in single player
|
||||
else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||
// commented out because irrelevant to kart. keeping here because we can use these flags for something else now
|
||||
/*else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||
continue;
|
||||
else if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||
continue;
|
||||
else if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
|
||||
continue;
|
||||
continue;*/
|
||||
|
||||
// Disable any linedef specials with our tag.
|
||||
for (j = -1; (j = P_FindLineFromLineTag(&lines[i], j)) >= 0;)
|
||||
|
|
|
@ -680,6 +680,8 @@ void P_Ticker(boolean run)
|
|||
|
||||
if (indirectitemcooldown)
|
||||
indirectitemcooldown--;
|
||||
if (hyubgone)
|
||||
hyubgone--;
|
||||
|
||||
if (G_BattleGametype())
|
||||
{
|
||||
|
|
467
src/p_user.c
467
src/p_user.c
|
@ -172,7 +172,7 @@ boolean P_AutoPause(void)
|
|||
if (netgame || modeattacking)
|
||||
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
|
||||
//
|
||||
|
@ -4509,7 +4350,7 @@ boolean P_AnalogMove(player_t *player)
|
|||
// 1 = pressing in the direction of movement
|
||||
// 2 = pressing in the opposite direction of movement
|
||||
//
|
||||
INT32 P_GetPlayerControlDirection(player_t *player)
|
||||
/*INT32 P_GetPlayerControlDirection(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
angle_t controllerdirection, controlplayerdirection;
|
||||
|
@ -4584,7 +4425,7 @@ INT32 P_GetPlayerControlDirection(player_t *player)
|
|||
}
|
||||
|
||||
// Control scheme for 2d levels.
|
||||
/*static void P_2dMovement(player_t *player)
|
||||
static void P_2dMovement(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd;
|
||||
INT32 topspeed, acceleration, thrustfactor;
|
||||
|
@ -4794,24 +4635,11 @@ static void P_3dMovement(player_t *player)
|
|||
cmd->forwardmove = cmd->sidemove = 0;
|
||||
if (player->kartstuff[k_sneakertimer])
|
||||
cmd->forwardmove = 50;
|
||||
if (player->pflags & PF_GLIDING)
|
||||
{
|
||||
if (!player->skidtime)
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
else if (player->exiting || mapreset)
|
||||
{
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
P_SetPlayerMobjState(player->mo, S_KART_WALK1); // SRB2kart - was S_PLAY_RUN1
|
||||
player->skidtime = 0;
|
||||
}
|
||||
}
|
||||
if (player->pflags & PF_SPINNING && !(player->exiting || mapreset))
|
||||
{
|
||||
player->pflags &= ~PF_SPINNING;
|
||||
P_SetPlayerMobjState(player->mo, S_KART_STND1); // SRB2kart - was S_PLAY_STND
|
||||
}
|
||||
}
|
||||
|
||||
if (!(player->pflags & PF_FORCESTRAFE) && !player->kartstuff[k_pogospring])
|
||||
cmd->sidemove = 0;
|
||||
|
||||
if (analogmove)
|
||||
{
|
||||
movepushangle = (cmd->angleturn<<16 /* not FRACBITS */);
|
||||
|
@ -4819,9 +4647,7 @@ static void P_3dMovement(player_t *player)
|
|||
else
|
||||
{
|
||||
if (player->kartstuff[k_drift] != 0)
|
||||
{
|
||||
movepushangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift];
|
||||
}
|
||||
else
|
||||
movepushangle = player->mo->angle;
|
||||
}
|
||||
|
@ -5039,10 +4865,10 @@ static void P_SpectatorMovement(player_t *player)
|
|||
// Quake-style flying spectators :D
|
||||
player->mo->momz += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(player->aiming));
|
||||
}
|
||||
if (cmd->sidemove != 0)
|
||||
/*if (cmd->sidemove != 0) -- was disabled in practice anyways, since sidemove was suppressed
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle-ANGLE_90, cmd->sidemove*mapobjectscale);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -6397,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
|
||||
static void P_MovePlayer(player_t *player)
|
||||
|
@ -6633,8 +6366,53 @@ static void P_MovePlayer(player_t *player)
|
|||
P_2dMovement(player);
|
||||
else*/
|
||||
{
|
||||
if (!player->climbing && (!P_AnalogMove(player)))
|
||||
player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */);
|
||||
INT16 angle_diff, max_left_turn, max_right_turn;
|
||||
boolean add_delta = true;
|
||||
|
||||
// Kart: store the current turn range for later use
|
||||
if (((player->mo && player->speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|| (player->kartstuff[k_respawn]) // Respawning
|
||||
|| (player->spectator || objectplacing)) // Not a physical player
|
||||
&& !(player->kartstuff[k_spinouttimer] && player->kartstuff[k_sneakertimer])) // Spinning and boosting cancels out turning
|
||||
{
|
||||
player->lturn_max[leveltime%MAXPREDICTTICS] = K_GetKartTurnValue(player, KART_FULLTURN)+1;
|
||||
player->rturn_max[leveltime%MAXPREDICTTICS] = K_GetKartTurnValue(player, -KART_FULLTURN)-1;
|
||||
} else {
|
||||
player->lturn_max[leveltime%MAXPREDICTTICS] = player->rturn_max[leveltime%MAXPREDICTTICS] = 0;
|
||||
}
|
||||
|
||||
if (leveltime >= starttime)
|
||||
{
|
||||
// KART: Don't directly apply angleturn! It may have been either A) forged by a malicious client, or B) not be a smooth turn due to a player dropping frames.
|
||||
// Instead, turn the player only up to the amount they're supposed to turn accounting for latency. Allow exactly 1 extra turn unit to try to keep old replays synced.
|
||||
angle_diff = cmd->angleturn - (player->mo->angle>>16);
|
||||
max_left_turn = player->lturn_max[(leveltime + MAXPREDICTTICS - cmd->latency) % MAXPREDICTTICS];
|
||||
max_right_turn = player->rturn_max[(leveltime + MAXPREDICTTICS - cmd->latency) % MAXPREDICTTICS];
|
||||
|
||||
//CONS_Printf("----------------\nangle diff: %d - turning options: %d to %d - ", angle_diff, max_left_turn, max_right_turn);
|
||||
|
||||
if (angle_diff > max_left_turn)
|
||||
angle_diff = max_left_turn;
|
||||
else if (angle_diff < max_right_turn)
|
||||
angle_diff = max_right_turn;
|
||||
else
|
||||
{
|
||||
// Try to keep normal turning as accurate to 1.0.1 as possible to reduce replay desyncs.
|
||||
player->mo->angle = cmd->angleturn<<16;
|
||||
add_delta = false;
|
||||
}
|
||||
//CONS_Printf("applied turn: %d\n", angle_diff);
|
||||
|
||||
if (add_delta) {
|
||||
player->mo->angle += angle_diff<<16;
|
||||
player->mo->angle &= ~0xFFFF; // Try to keep the turning somewhat similar to how it was before?
|
||||
//CONS_Printf("leftover turn (%s): %5d or %4d%%\n",
|
||||
// player_names[player-players],
|
||||
// (INT16) (cmd->angleturn - (player->mo->angle>>16)),
|
||||
// (INT16) (cmd->angleturn - (player->mo->angle>>16)) * 100 / (angle_diff ? angle_diff : 1));
|
||||
}
|
||||
}
|
||||
|
||||
ticruned++;
|
||||
if ((cmd->angleturn & TICCMD_RECEIVED) == 0)
|
||||
|
@ -7032,6 +6810,7 @@ static void P_MovePlayer(player_t *player)
|
|||
//ANALOG CONTROL//
|
||||
//////////////////
|
||||
|
||||
#if 0
|
||||
// This really looks like it should be moved to P_3dMovement. -Red
|
||||
if (P_AnalogMove(player)
|
||||
&& (cmd->forwardmove != 0 || cmd->sidemove != 0) && !player->climbing && !twodlevel && !(player->mo->flags2 & MF2_TWOD))
|
||||
|
@ -7088,6 +6867,7 @@ static void P_MovePlayer(player_t *player)
|
|||
else if (player == &players[fourthdisplayplayer])
|
||||
localangle4 = player->mo->angle;
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////
|
||||
//BOMB SHIELD ACTIVATION,//
|
||||
|
@ -7291,74 +7071,6 @@ static void P_MovePlayer(player_t *player)
|
|||
if (CheckForBustableBlocks)
|
||||
P_CheckBustableBlocks(player);
|
||||
|
||||
// Special handling for
|
||||
// gliding in 2D mode
|
||||
if ((twodlevel || player->mo->flags2 & MF2_TWOD) && player->pflags & PF_GLIDING && player->charability == CA_GLIDEANDCLIMB
|
||||
&& !(player->mo->flags & MF_NOCLIP))
|
||||
{
|
||||
msecnode_t *node; // only place it's being used in P_MovePlayer now
|
||||
fixed_t oldx;
|
||||
fixed_t oldy;
|
||||
fixed_t floorz, ceilingz;
|
||||
|
||||
oldx = player->mo->x;
|
||||
oldy = player->mo->y;
|
||||
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x += player->mo->momx;
|
||||
player->mo->y += player->mo->momy;
|
||||
P_SetThingPosition(player->mo);
|
||||
|
||||
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (!node->m_sector)
|
||||
break;
|
||||
|
||||
if (node->m_sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
if (topheight > player->mo->z && bottomheight < player->mo->z)
|
||||
{
|
||||
P_ResetPlayer(player);
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
player->climbing = 5;
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
|
||||
ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
|
||||
|
||||
if (player->mo->z+player->mo->height > ceilingz
|
||||
&& node->m_sector->ceilingpic == skyflatnum)
|
||||
continue;
|
||||
|
||||
if (floorz > player->mo->z || ceilingz < player->mo->z)
|
||||
{
|
||||
P_ResetPlayer(player);
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
player->climbing = 5;
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x = oldx;
|
||||
player->mo->y = oldy;
|
||||
P_SetThingPosition(player->mo);
|
||||
}
|
||||
|
||||
// Check for a BOUNCY sector!
|
||||
if (CheckForBouncySector)
|
||||
P_CheckBouncySectors(player);
|
||||
|
@ -7690,12 +7402,14 @@ static void P_NukeAllPlayers(player_t *player)
|
|||
//
|
||||
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;
|
||||
angle_t fa;
|
||||
thinker_t *think;
|
||||
INT32 i;
|
||||
|
||||
radius = FixedMul(radius, mapobjectscale);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
fa = (i*(FINEANGLES/16));
|
||||
|
@ -8133,6 +7847,8 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
|
|||
|
||||
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled)
|
||||
{
|
||||
static UINT8 lookbackdelay[4] = {0,0,0,0};
|
||||
UINT8 num;
|
||||
angle_t angle = 0, focusangle = 0, focusaiming = 0;
|
||||
fixed_t x, y, z, dist, height, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
|
||||
fixed_t pan, xpan, ypan;
|
||||
|
@ -8261,6 +7977,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
if (thiscam == &camera)
|
||||
{
|
||||
num = 0;
|
||||
camspeed = cv_cam_speed.value;
|
||||
camstill = cv_cam_still.value;
|
||||
camrotate = cv_cam_rotate.value;
|
||||
|
@ -8270,6 +7987,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else if (thiscam == &camera2) // Camera 2
|
||||
{
|
||||
num = 1;
|
||||
camspeed = cv_cam2_speed.value;
|
||||
camstill = cv_cam2_still.value;
|
||||
camrotate = cv_cam2_rotate.value;
|
||||
|
@ -8279,6 +7997,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else if (thiscam == &camera3) // Camera 3
|
||||
{
|
||||
num = 2;
|
||||
camspeed = cv_cam3_speed.value;
|
||||
camstill = cv_cam3_still.value;
|
||||
camrotate = cv_cam3_rotate.value;
|
||||
|
@ -8288,6 +8007,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else // Camera 4
|
||||
{
|
||||
num = 3;
|
||||
camspeed = cv_cam4_speed.value;
|
||||
camstill = cv_cam4_still.value;
|
||||
camrotate = cv_cam4_rotate.value;
|
||||
|
@ -8310,19 +8030,23 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else if (player->exiting) // SRB2Kart: Leave the camera behind while exiting, for dramatic effect!
|
||||
camstill = true;
|
||||
else if (lookback) // SRB2kart - Camera flipper
|
||||
else if (lookback || lookbackdelay[num]) // SRB2kart - Camera flipper
|
||||
{
|
||||
camspeed = FRACUNIT;
|
||||
if (lookback)
|
||||
{
|
||||
camrotate += 180;
|
||||
camspeed *= 2;
|
||||
if (camspeed > FRACUNIT)
|
||||
camspeed = FRACUNIT;
|
||||
lookbackdelay[num] = 2;
|
||||
}
|
||||
else
|
||||
lookbackdelay[num]--;
|
||||
}
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
camheight += thiscam->height;
|
||||
|
||||
if (splitscreen == 1)
|
||||
camspeed = (3*camspeed)/4;
|
||||
if (camspeed > FRACUNIT)
|
||||
camspeed = FRACUNIT;
|
||||
|
||||
if (timeover)
|
||||
angle = mo->angle + FixedAngle(camrotate*FRACUNIT);
|
||||
|
@ -8331,6 +8055,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
else if (camstill || resetcalled || player->playerstate == PST_DEAD)
|
||||
angle = thiscam->angle;
|
||||
else
|
||||
{
|
||||
if (camspeed == FRACUNIT)
|
||||
angle = focusangle + FixedAngle(camrotate<<FRACBITS);
|
||||
else
|
||||
{
|
||||
angle_t input = focusangle + FixedAngle(camrotate<<FRACBITS) - thiscam->angle;
|
||||
boolean invert = (input > ANGLE_180);
|
||||
|
@ -8343,6 +8071,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
angle = thiscam->angle + input;
|
||||
}
|
||||
}
|
||||
|
||||
if (!resetcalled && (leveltime > starttime && timeover != 2)
|
||||
&& ((thiscam == &camera && t_cam_rotate != -42)
|
||||
|
@ -8369,13 +8098,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
height -= FixedMul(height, player->kartstuff[k_boostcam]);
|
||||
}
|
||||
|
||||
// in splitscreen modes, mess with the camera distances to make it feel proportional to how it feels normally
|
||||
if (splitscreen == 1) // widescreen splits should get x1.5 distance
|
||||
{
|
||||
dist = FixedMul(dist, 3*FRACUNIT/2);
|
||||
height = FixedMul(height, 3*FRACUNIT/2);
|
||||
}
|
||||
|
||||
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
|
||||
|
@ -8641,9 +8363,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
{
|
||||
thiscam->momx = x - thiscam->x;
|
||||
thiscam->momy = y - thiscam->y;
|
||||
if (splitscreen == 1) // Wide-screen needs to follow faster, due to a smaller vertical:horizontal ratio of screen space
|
||||
thiscam->momz = FixedMul(z - thiscam->z, (3*camspeed)/4);
|
||||
else
|
||||
thiscam->momz = FixedMul(z - thiscam->z, camspeed/2);
|
||||
}
|
||||
|
||||
|
@ -8665,8 +8384,25 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (twodlevel || (mo->flags2 & MF2_TWOD) || (!camstill && !timeover)) // Keep the view still...
|
||||
{
|
||||
G_ClipAimingPitch((INT32 *)&angle);
|
||||
dist = thiscam->aiming - angle;
|
||||
thiscam->aiming -= (dist>>3);
|
||||
|
||||
if (camspeed == FRACUNIT)
|
||||
thiscam->aiming = angle;
|
||||
else
|
||||
{
|
||||
angle_t input;
|
||||
boolean invert;
|
||||
|
||||
input = thiscam->aiming - angle;
|
||||
invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
input = FixedAngle(FixedMul(AngleFixed(input), (5*camspeed)/16));
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
thiscam->aiming -= input;
|
||||
}
|
||||
}
|
||||
|
||||
if (!resetcalled && (player->playerstate == PST_DEAD || player->playerstate == PST_REBORN))
|
||||
|
@ -8731,6 +8467,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
}
|
||||
player->spectator = false;
|
||||
player->pflags &= ~PF_WANTSTOJOIN;
|
||||
player->kartstuff[k_spectatewait] = 0;
|
||||
player->ctfteam = changeto;
|
||||
player->playerstate = PST_REBORN;
|
||||
|
||||
|
@ -8755,6 +8492,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
}
|
||||
player->spectator = false;
|
||||
player->pflags &= ~PF_WANTSTOJOIN;
|
||||
player->kartstuff[k_spectatewait] = 0;
|
||||
player->playerstate = PST_REBORN;
|
||||
|
||||
//Reset away view
|
||||
|
@ -9844,4 +9582,3 @@ void P_PlayerAfterThink(player_t *player)
|
|||
|
||||
K_KartPlayerAfterThink(player);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue