diff --git a/.gitignore b/.gitignore index 3090417dd..7023aaa80 100644 --- a/.gitignore +++ b/.gitignore @@ -13,11 +13,11 @@ Win32_LIB_ASM_Release *.dgb *.debug *.debug.txt -/bin/VC10/ -/objs/VC10/ *.user *.db *.opendb /.vs /debian /assets/debian +/make +/bin diff --git a/CMakeLists.txt b/CMakeLists.txt index 39ad80698..b58101f7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.13) # Enable CCache early set(SRB2_USE_CCACHE OFF CACHE BOOL "Use CCache") @@ -34,12 +34,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") ### Useful functions -# Prepend sources with current source directory -function(prepend_sources SOURCE_FILES) - foreach(SOURCE_FILE ${${SOURCE_FILES}}) - set(MODIFIED ${MODIFIED} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}) - endforeach() - set(${SOURCE_FILES} ${MODIFIED} PARENT_SCOPE) +# Add sources from Sourcefile +function(target_sourcefile type) + file(STRINGS Sourcefile list + REGEX "[-0-9A-Za-z_]+\.${type}") + target_sources(SRB2SDL2 PRIVATE ${list}) endfunction() # Macro to add OSX framework diff --git a/appveyor.yml b/appveyor.yml index aa7a4c7cd..474a2adb3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,15 +2,11 @@ version: 2.0.{branch}-{build} os: MinGW environment: - CC: ccache - CCACHE_CC: i686-w64-mingw32-gcc - CCACHE_CC_64: x86_64-w64-mingw32-gcc + CC: i686-w64-mingw32-gcc WINDRES: windres # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead MINGW_SDK: c:\msys64\mingw32 - # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead - MINGW_SDK_64: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64 - CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn + CFLAGS: -Wno-implicit-fallthrough NASM_ZIP: nasm-2.12.01 NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip UPX_ZIP: upx391w @@ -19,8 +15,6 @@ environment: CCACHE_URL: http://alam.srb2.org/ccache.exe CCACHE_COMPRESS: true CCACHE_DIR: C:\Users\appveyor\.ccache - # Disable UPX by default. The user can override this in their Appveyor project settings - NOUPX: 1 ############################## # DEPLOYER VARIABLES # DPL_ENABLED=1 builds installers for branch names starting with `deployer`. @@ -53,11 +47,6 @@ cache: - C:\Users\appveyor\srb2_cache install: -- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" ) -- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" ) -- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" ) -- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" ) - - if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip" - 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null - robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0 @@ -72,39 +61,27 @@ install: configuration: - SDL -- SDL64 before_build: - set "Path=%MINGW_SDK%\bin;%Path%" -- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version ) - mingw32-make --version -- if not [%X86_64%] == [1] ( nasm -v ) +- nasm -v - if not [%NOUPX%] == [1] ( upx -V ) - ccache -V - ccache -s -- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) - if defined [%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%] ( set "COMMIT=%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%" ) else ( set "COMMIT=%APPVEYOR_REPO_COMMIT%" ) - cmd: git rev-parse --short %COMMIT%>%TMP%/gitshort.txt - cmd: set /P GITSHORT=<%TMP%/gitshort.txt # for pull requests, take the owner's name only, if this isn't the same repo of course - set "REPO=%APPVEYOR_REPO_BRANCH%" - if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) ) -- set "EXENAME=EXENAME=srb2win-%REPO%-%GITSHORT%.exe" -- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX% %EXENAME%" -- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" ) -- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" +- set "SRB2_MFLAGS=-C src NOECHOFILENAMES=1 CCACHE=1 EXENAME=srb2win-%REPO%-%GITSHORT%.exe" build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% clean - cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k after_build: -- if [%X86_64%] == [1] ( - set "BUILD_PATH=bin\Mingw64\Release" - ) else ( - set "BUILD_PATH=bin\Mingw\Release" - ) -- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) - ccache -s - set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z - set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z @@ -139,3 +116,4 @@ test: off on_finish: #- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: #- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +# vim: et ts=1 diff --git a/bin/FreeBSD/Debug/.gitignore b/bin/FreeBSD/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/FreeBSD/Release/.gitignore b/bin/FreeBSD/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/Linux/Debug/.gitignore b/bin/Linux/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux/Release/.gitignore b/bin/Linux/Release/.gitignore deleted file mode 100644 index 5b5c54a54..000000000 --- a/bin/Linux/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/lsdlsrb2 -/pnd -/*.mo diff --git a/bin/Linux64/Debug/.gitignore b/bin/Linux64/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux64/Release/.gitignore b/bin/Linux64/Release/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Release/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Mingw/Debug/.gitignore b/bin/Mingw/Debug/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Debug/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Release/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw64/Debug/.gitignore b/bin/Mingw64/Debug/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/Mingw64/Release/.gitignore b/bin/Mingw64/Release/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/SDL/Debug/.gitignore b/bin/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/SDL/Release/.gitignore b/bin/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/VC/.gitignore b/bin/VC/.gitignore deleted file mode 100644 index e52f825b2..000000000 --- a/bin/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Release -/Debug diff --git a/bin/VC9/.gitignore b/bin/VC9/.gitignore deleted file mode 100644 index 205fe45de..000000000 --- a/bin/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Win32 -/x64 diff --git a/bin/dummy/.gitignore b/bin/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/.gitignore b/dep/.gitignore deleted file mode 100644 index fb941664f..000000000 --- a/dep/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -#All folders -*.d diff --git a/dep/FreeBSD/SDL/Debug/.gitignore b/dep/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/FreeBSD/SDL/Release/.gitignore b/dep/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Debug/.gitignore b/dep/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Release/.gitignore b/dep/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Debug/.gitignore b/dep/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Release/.gitignore b/dep/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/MasterClient/.gitignore b/dep/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/MasterServer/.gitignore b/dep/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/Debug/.gitignore b/dep/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/Release/.gitignore b/dep/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Debug/.gitignore b/dep/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Release/.gitignore b/dep/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/Debug/.gitignore b/dep/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/Release/.gitignore b/dep/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Debug/.gitignore b/dep/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Release/.gitignore b/dep/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/SDL/Release/.gitignore b/dep/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/VC/.gitignore b/dep/VC/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/VC9/.gitignore b/dep/VC9/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/cygwin/Debug/.gitignore b/dep/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/cygwin/Release/.gitignore b/dep/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/dummy/.gitignore b/dep/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/.gitignore b/objs/.gitignore deleted file mode 100644 index 35ecd6def..000000000 --- a/objs/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -#All folders -SRB2.res -depend.dep -depend.ped -*.o -#VC9 folder only -/VC9/Win32 -/VC9/x64 diff --git a/objs/FreeBSD/SDL/Debug/.gitignore b/objs/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/FreeBSD/SDL/Release/.gitignore b/objs/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Debug/.gitignore b/objs/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Release/.gitignore b/objs/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Debug/.gitignore b/objs/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Release/.gitignore b/objs/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterClient/.gitignore b/objs/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterServer/.gitignore b/objs/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Debug/.gitignore b/objs/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Release/.gitignore b/objs/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Debug/.gitignore b/objs/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Debug/.gitignore b/objs/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Release/.gitignore b/objs/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Debug/.gitignore b/objs/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Release/.gitignore b/objs/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/SDL/Release/.gitignore b/objs/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/VC/.gitignore b/objs/VC/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/VC9/.gitignore b/objs/VC9/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Debug/.gitignore b/objs/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Release/.gitignore b/objs/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/dummy/.gitignore b/objs/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2678bb31..39b71cda7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,269 +1,14 @@ # SRB2 Core +add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) + # Core sources -set(SRB2_CORE_SOURCES - am_map.c - command.c - comptime.c - console.c - d_clisrv.c - d_main.c - d_net.c - d_netcmd.c - d_netfil.c - dehacked.c - deh_soc.c - deh_lua.c - deh_tables.c - f_finale.c - f_wipe.c - filesrch.c - g_demo.c - g_game.c - g_input.c - g_splitscreen.c - font.c - hu_stuff.c - i_tcp.c - info.c - lzf.c - m_aatree.c - m_anigif.c - m_argv.c - m_bbox.c - m_cheat.c - m_cond.c - m_fixed.c - m_menu.c - m_misc.c - m_perfstats.c - m_queue.c - m_random.c - md5.c - mserv.c - http-mserv.c - s_sound.c - screen.c - sounds.c - st_stuff.c - #string.c - tables.c - v_video.c - w_wad.c - y_inter.c - z_zone.c -) +target_sourcefile(c) +target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in) -set(SRB2_CORE_HEADERS - am_map.h - byteptr.h - command.h - console.h - d_clisrv.h - d_event.h - d_main.h - d_net.h - d_netcmd.h - d_netfil.h - d_player.h - d_think.h - d_ticcmd.h - dehacked.h - deh_soc.h - deh_lua.h - deh_tables.h - doomdata.h - doomdef.h - doomstat.h - doomtype.h - endian.h - f_finale.h - fastcmp.h - filesrch.h - g_demo.h - g_game.h - g_input.h - g_state.h - font.h - hu_stuff.h - i_joy.h - i_net.h - i_sound.h - i_system.h - i_tcp.h - i_video.h - info.h - keys.h - lzf.h - m_aatree.h - m_anigif.h - m_argv.h - m_bbox.h - m_cheat.h - m_cond.h - m_dllist.h - m_fixed.h - m_menu.h - m_misc.h - m_perfstats.h - m_queue.h - m_random.h - m_swap.h - md5.h - mserv.h - p5prof.h - s_sound.h - screen.h - sounds.h - st_stuff.h - tables.h - v_video.h - w_wad.h - y_inter.h - z_zone.h - - config.h.in -) - -set(SRB2_CORE_RENDER_SOURCES - r_bsp.c - r_data.c - r_draw.c - r_main.c - r_plane.c - r_segs.c - r_skins.c - r_sky.c - r_splats.c - r_things.c - r_textures.c - r_patch.c - r_patchrotation.c - r_picformats.c - r_portal.c - - r_bsp.h - r_data.h - r_defs.h - r_draw.h - r_local.h - r_main.h - r_plane.h - r_segs.h - r_skins.h - r_sky.h - r_splats.h - r_state.h - r_things.h - r_textures.h - r_patch.h - r_patchrotation.h - r_picformats.h - r_portal.h -) - -set(SRB2_CORE_GAME_SOURCES - p_ceilng.c - p_enemy.c - p_floor.c - p_inter.c - p_lights.c - p_map.c - p_maputl.c - p_mobj.c - p_polyobj.c - p_saveg.c - p_setup.c - p_sight.c - p_slopes.c - p_spec.c - p_telept.c - p_tick.c - p_user.c - taglist.c - - k_race.c - k_battle.c - k_bheap.c - k_collide.c - k_kart.c - k_pathfind.c - k_pwrlv.c - k_waypoint.c - k_color.c - k_bot.c - k_botitem.c - k_botsearch.c - k_respawn.c - k_grandprix.c - k_hud.c - - p_local.h - p_maputl.h - p_mobj.h - p_polyobj.h - p_pspr.h - p_saveg.h - p_setup.h - p_slopes.h - p_spec.h - p_tick.h - taglist.h - - k_race.h - k_battle.h - k_bheap.h - k_collide.h - k_kart.h - k_pathfind.h - k_pwrlv.h - k_waypoint.h - k_color.h - k_bot.h - k_respawn.h - k_grandprix.h - k_hud.h -) - -if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c) -endif() - -prepend_sources(SRB2_CORE_SOURCES) -prepend_sources(SRB2_CORE_HEADERS) -prepend_sources(SRB2_CORE_RENDER_SOURCES) -prepend_sources(SRB2_CORE_GAME_SOURCES) - -set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/config.h) -source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}) -source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) -source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) - - -set(SRB2_ASM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/vid_copy.s -) - -set(SRB2_NASM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/tmap_mmx.nas - ${CMAKE_CURRENT_SOURCE_DIR}/tmap.nas -) - -if(MSVC) - list(APPEND SRB2_NASM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tmap_vc.nas) -endif() - -set(SRB2_NASM_OBJECTS - ${CMAKE_CURRENT_BINARY_DIR}/tmap_mmx.obj - ${CMAKE_CURRENT_BINARY_DIR}/tmap.obj -) - -if(MSVC) - list(APPEND SRB2_NASM_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/tmap_vc.obj) -endif() - -source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) +set(SRB2_ASM_SOURCES vid_copy.s) +set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas) ### Configuration set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL @@ -303,92 +48,7 @@ if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only "Use SRB2Kart's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT, cURL).") endif() -set(SRB2_LUA_SOURCES - lua_baselib.c - lua_blockmaplib.c - lua_consolelib.c - lua_hooklib.c - lua_hudlib.c - lua_infolib.c - lua_maplib.c - lua_taglib.c - lua_mathlib.c - lua_mobjlib.c - lua_playerlib.c - lua_polyobjlib.c - lua_script.c - lua_skinlib.c - lua_thinkerlib.c -) -set(SRB2_LUA_HEADERS - lua_hook.h - lua_hud.h - lua_libs.h - lua_script.h -) - -prepend_sources(SRB2_LUA_SOURCES) -prepend_sources(SRB2_LUA_HEADERS) - -source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) - -set(SRB2_BLUA_SOURCES - blua/lapi.c - blua/lauxlib.c - blua/lbaselib.c - blua/lcode.c - blua/ldebug.c - blua/ldo.c - blua/ldump.c - blua/lfunc.c - blua/lgc.c - blua/linit.c - blua/liolib.c - blua/llex.c - blua/lmem.c - blua/lobject.c - blua/lopcodes.c - blua/lparser.c - blua/lstate.c - blua/lstring.c - blua/lstrlib.c - blua/ltable.c - blua/ltablib.c - blua/ltm.c - blua/lundump.c - blua/lvm.c - blua/lzio.c -) -set(SRB2_BLUA_HEADERS - blua/lapi.h - blua/lauxlib.h - blua/lcode.h - blua/ldebug.h - blua/ldo.h - blua/lfunc.h - blua/lgc.h - blua/llex.h - blua/llimits.h - blua/lmem.h - blua/lobject.h - blua/lopcodes.h - blua/lparser.h - blua/lstate.h - blua/lstring.h - blua/ltable.h - blua/ltm.h - blua/lua.h - blua/luaconf.h - blua/lualib.h - blua/lundump.h - blua/lvm.h - blua/lzio.h -) - -prepend_sources(SRB2_BLUA_SOURCES) -prepend_sources(SRB2_BLUA_HEADERS) - -source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) +add_subdirectory(blua) if(${SRB2_CONFIG_HAVE_GME}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) @@ -404,7 +64,7 @@ if(${SRB2_CONFIG_HAVE_GME}) endif() if(${GME_FOUND}) set(SRB2_HAVE_GME ON) - add_definitions(-DHAVE_LIBGME) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_GME) else() message(WARNING "You have specified that GME is available but it was not found.") endif() @@ -424,7 +84,7 @@ if(${SRB2_CONFIG_HAVE_OPENMPT}) endif() if(${OPENMPT_FOUND}) set(SRB2_HAVE_OPENMPT ON) - add_definitions(-DHAVE_OPENMPT) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_OPENMPT) else() message(WARNING "You have specified that OpenMPT is available but it was not found.") endif() @@ -447,8 +107,7 @@ if(${SRB2_CONFIG_HAVE_MIXERX}) endif() if(${MIXERX_FOUND}) set(SRB2_HAVE_MIXERX ON) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) - add_definitions(-DHAVE_MIXERX) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MIXERX) else() message(WARNING "You have specified that SDL Mixer X is available but it was not found.") endif() @@ -469,13 +128,9 @@ if(${SRB2_CONFIG_HAVE_DISCORDRPC}) endif() if(${DISCORDRPC_FOUND}) set(SRB2_HAVE_DISCORDRPC ON) - add_definitions(-DHAVE_DISCORDRPC) - add_definitions(-DUSE_STUN) - set(SRB2_DISCORDRPC_SOURCES discord.c stun.c) - set(SRB2_DISCORDRPC_HEADERS discord.h stun.h) - prepend_sources(SRB2_DISCORDRPC_SOURCES) - prepend_sources(SRB2_DISCORDRPC_HEADERS) - source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_DISCORDRPC) + target_compile_definitions(SRB2SDL2 PRIVATE -DUSE_STUN) + target_sources(SRB2SDL2 PRIVATE discord.c stun.c) else() message(WARNING "You have specified that Discord Rich Presence is available but it was not found.") endif() @@ -495,7 +150,7 @@ if(${SRB2_CONFIG_HAVE_ZLIB}) endif() if(${ZLIB_FOUND}) set(SRB2_HAVE_ZLIB ON) - add_definitions(-DHAVE_ZLIB) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB) else() message(WARNING "You have specified that ZLIB is available but it was not found. SRB2Kart may not compile correctly.") endif() @@ -516,14 +171,9 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB}) endif() if(${PNG_FOUND}) 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}) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_PNG) + target_compile_definitions(SRB2SDL2 PRIVATE -D_LARGEFILE64_SOURCE) + target_sources(SRB2SDL2 PRIVATE apng.c) else() message(WARNING "You have specified that PNG is available but it was not found. SRB2Kart may not compile correctly.") endif() @@ -544,7 +194,7 @@ if(${SRB2_CONFIG_HAVE_CURL}) endif() if(${CURL_FOUND}) set(SRB2_HAVE_CURL ON) - add_definitions(-DHAVE_CURL) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_CURL) else() message(WARNING "You have specified that CURL is available but it was not found. SRB2Kart may not compile correctly.") endif() @@ -552,59 +202,19 @@ endif() if(${SRB2_CONFIG_HAVE_THREADS}) set(SRB2_HAVE_THREADS ON) - set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/i_threads.h) - add_definitions(-DHAVE_THREADS) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS) endif() if(${SRB2_CONFIG_HWRENDER}) - add_definitions(-DHWRENDER) - set(SRB2_HWRENDER_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c - ) - - set (SRB2_HWRENDER_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.h - ) - - set(SRB2_R_OPENGL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.c - ) - - set(SRB2_R_OPENGL_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.h - ) - + target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) + add_subdirectory(hardware) endif() if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL}) find_package(OpenGL) if(${OPENGL_FOUND}) - add_definitions(-DHWRENDER) - add_definitions(-DSTATIC_OPENGL) + target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) + target_compile_definitions(SRB2SDL2 PRIVATE -DSTATIC_OPENGL) else() message(WARNING "You have specified static opengl but opengl was not found. Not setting HWRENDER.") endif() @@ -625,12 +235,16 @@ if(${SRB2_CONFIG_USEASM}) set(CMAKE_ASM_NASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.") enable_language(ASM_NASM) endif() + set(SRB2_USEASM ON) - add_definitions(-DUSEASM) + target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse") + + target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} + ${SRB2_NASM_SOURCES}) else() set(SRB2_USEASM OFF) - add_definitions(-DNONX86 -DNORUSEASM) + target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM) endif() # Targets @@ -666,7 +280,9 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value) endif() -add_definitions(-DCMAKECONFIG) +set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-trigraphs) + +target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG) #add_library(SRB2Core STATIC # ${SRB2_CORE_SOURCES} diff --git a/src/Makefile b/src/Makefile index a390557a6..9659a4994 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,861 +1,416 @@ - -# GNU Make makefile for SRB2 -############################################################################# -# Copyright (C) 1998-2000 by DooM Legacy Team. -# Copyright (C) 2003-2021 by Sonic Team Junior. +# GNU Makefile for SRB2 +# the poly3 Makefile adapted over and over... +# +# Copyright 1998-2000 DooM Legacy Team. +# Copyright 2020-2021 James R. +# Copyright 2003-2021 Sonic Team Junior. # # This program is free software distributed under the # terms of the GNU General Public License, version 2. # See the 'LICENSE' file for more details. # -# -DLINUX -> use for the GNU/Linux specific -# -D_WINDOWS -> use for the Win32/DirectX specific -# -DHAVE_SDL -> use for the SDL interface +# Special targets: # -# Sets: -# Compile the SDL/Mingw version with 'make MINGW=1' -# Compile the SDL/Linux version with 'make LINUX=1' -# Compile the SDL/Solaris version with 'make SOLARIS=1' -# Compile the SDL/FreeBSD version with 'gmake FREEBSD=1' -# Compile the SDL/Cygwin version with 'make CYGWIN32=1' -# Compile the SDL/other version try with 'make SDL=1' +# clean - remove executables and objects for this build +# cleandep - remove dependency files for this build +# distclean - remove entire executable, object and +# dependency file directory structure. +# dump - disassemble executable +# info - print settings # -# 'Targets': -# clean -# Remove all object files -# cleandep -# Remove dependency files -# distclean -# Remove autogenerated files -# dll -# compile primary HW render DLL/SO -# all_dll -# compile all HW render and 3D sound DLLs for the set -# opengl_dll -# Pure Mingw only, compile OpenGL HW render DLL -# ds3d_dll -# Pure Mingw only, compile DirectX DirectSound HW sound DLL -# fmod_dll -# Pure Mingw only, compile FMOD HW sound DLL -# openal_dll -# Pure Mingw only, compile OpenAL HW sound DLL -# fmod_so -# Non-Mingw, compile FMOD HW sound SO -# openal_so -# Non-Mingw, compile OpenAL HW sound SO +# This Makefile can automatically detect the host system +# as well as the compiler version. If system or compiler +# version cannot be detected, you may need to set a flag +# manually. # +# On Windows machines, 32-bit Windows is always targetted. # -# Addon: -# To Cross-Compile, CC=gcc-version make * PREFIX= -# Compile with GCC 2.97 version, add 'GCC29=1' -# Compile with GCC 4.0x version, add 'GCC40=1' -# Compile with GCC 4.1x version, add 'GCC41=1' -# Compile with GCC 4.2x version, add 'GCC42=1' -# Compile with GCC 4.3x version, add 'GCC43=1' -# Compile with GCC 4.4x version, add 'GCC44=1' -# Compile with GCC 4.5x version, add 'GCC45=1' -# Compile with GCC 4.6x version, add 'GCC46=1' -# Compile a profile version, add 'PROFILEMODE=1' -# Compile a debug version, add 'DEBUGMODE=1' -# Compile for the testers group (they don't get to play unless we're watching *wink*), add 'TESTERS=1' -# Compile with less warnings, add 'RELAXWARNINGS=1' -# Generate compiler errors for most compiler warnings, add 'ERRORMODE=1' -# Compile without NASM's tmap.nas, add 'NOASM=1' -# Compile without 3D hardware support, add 'NOHW=1' -# Compile with GDBstubs, add 'RDB=1' -# Compile without PNG, add 'NOPNG=1' -# Compile without zlib, add 'NOZLIB=1' +# Platform/system flags: # -# Addon for SDL: -# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config' -# Compile without SDL_Mixer, add 'NOMIXER=1' -# Compile without SDL_Mixer_X, add 'NOMIXERX=1' (Win32 only) -# Compile without GME, add 'NOGME=1' -# Compile without BSD API, add 'NONET=1' -# Compile without IPX/SPX, add 'NOIPX=1' -# Compile Mingw/SDL with S_DS3S, add 'DS3D=1' -# Compile without libopenmpt, add 'NOOPENMPT=1' -# Compile with S_FMOD3D, add 'FMOD=1' (WIP) -# Compile with S_OPENAL, add 'OPENAL=1' (WIP) -# To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed -# To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1' +# LINUX=1, LINUX64=1 +# MINGW=1, MINGW64=1 - Windows (MinGW toolchain) +# UNIX=1 - Generic Unix like system +# FREEBSD=1 +# SDL=1 - Use SDL backend. SDL is the only backend though +# and thus, always enabled. # -############################################################################# +# A list of supported GCC versions can be found in +# Makefile.d/detect.mk -- search 'gcc_versions'. +# +# Feature flags: +# +# Safe to use online +# ------------------ +# NO_IPV6=1 - Disable IPv6 address support. +# NOHW=1 - Disable OpenGL renderer. +# ZDEBUG=1 - Enable more detailed memory debugging +# HAVE_MINIUPNPC=1 - Enable automated port forwarding. +# Already enabled by default for 32-bit +# Windows. +# NOASM=1 - Disable hand optimized assembly code for the +# Software renderer. +# NOPNG=1 - Disable PNG graphics support. (TODO: double +# check netplay compatible.) +# NOCURL=1 - Disable libcurl--HTTP capability. +# NOGME=1 - Disable game music emu, retro VGM support. +# NOOPENMPT=1 - Disable module (tracker) music support. +# NOMIXER=1 - Disable SDL Mixer (audio playback). +# NOMIXERX=1 - Forgo SDL Mixer X--revert to standard SDL +# Mixer. Mixer X is the default for Windows +# builds. +# HAVE_MIXERX=1 - Enable SDL Mixer X. Outside of Windows +# builds, SDL Mixer X is not the default. +# NOTHREADS=1 - Disable multithreading. +# +# Netplay incompatible +# -------------------- +# NONET=1 - Disable online capability. +# NOMD5=1 - Disable MD5 checksum (validation tool). +# NOPOSTPROCESSING=1 - ? +# MOBJCONSISTANCY=1 - ?? +# PACKETDROP=1 - ?? +# DEBUGMODE=1 - Enable various debugging capabilities. +# Also disables optimizations. +# NOZLIB=1 - Disable some compression capability. Implies +# NOPNG=1. +# +# Development flags: +# +# VALGRIND=1 - Enable Valgrind memory debugging support. +# PROFILEMODE=1 - Enable performance profiling (gprof). +# +# General flags for building: +# +# STATIC=1 - Use static linking. +# DISTCC=1 +# CCACHE=1 +# UPX= - UPX command to use for compressing final +# executable. +# WINDOWSHELL=1 - Use Windows commands. +# PREFIX= - Prefix to many commands, for cross compiling. +# YASM=1 - Use Yasm instead of NASM assembler. +# STABS=1 - ? +# ECHO=1 - Print out each command in the build process. +# NOECHOFILENAMES=1 - Don't print out each that is being +# worked on. +# SILENT=1 - Print absolutely nothing except errors. +# RELAXWARNINGS=1 - Use less compiler warnings/errors. +# ERRORMODE=1 - Treat most compiler warnings as errors. +# NOCASTALIGNWARN=1 - ? +# NOLDWARNING=1 - ? +# NOSDLMAIN=1 - ? +# SDLMAIN=1 - ? +# +# Library configuration flags: +# Everything here is an override. +# +# PNG_PKGCONFIG= - libpng-config command. +# PNG_CFLAGS=, PNG_LDFLAGS= +# +# CURLCONFIG= - curl-config command. +# CURL_CFLAGS=, CURL_LDFLAGS= +# +# VALGRIND_PKGCONFIG= - pkg-config package name. +# VALGRIND_CFLAGS=, VALGRIND_LDFLAGS= +# +# LIBGME_PKGCONFIG=, LIBGME_CFLAGS=, LIBGME_LDFLAGS= -,=, +# LIBOPENMPT_PKGCONFIG= +# LIBOPENMPT_CFLAGS=, LIBOPENMPT_LDFLAGS= +# +# ZLIB_PKGCONFIG=, ZLIB_CFLAGS=, ZLIB_LDFLAGS= +# +# SDL_PKGCONFIG= +# SDL_CONFIG= - sdl-config command. +# SDL_CFLAGS=, SDL_LDFLAGS= -ifeq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all))) -CLEANONLY=1 -else ifndef SILENT -echo=@echo "$(1)" -ifndef MAKE_RESTARTS -print=$(info $(1)) -endif +clean_targets=cleandep clean distclean info + +.PHONY : $(clean_targets) all + +goals:=$(or $(MAKECMDGOALS),all) +cleanonly:=$(filter $(clean_targets),$(goals)) +destructive:=$(filter-out info,$(cleanonly)) + +ifndef cleanonly +include Makefile.d/old.mk endif -ALL_SYSTEMS=\ - PANDORA\ - LINUX64\ - MINGW64\ - HAIKU\ - DUMMY\ - DJGPPDOS\ - MINGW\ - UNIX\ - LINUX\ - SOLARIS\ - FREEBSD\ - MACOSX\ - SDL\ +include Makefile.d/util.mk -# check for user specified system -ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) -ifeq ($(OS),Windows_NT) # all windows are Windows_NT... - - $(call print,Detected a Windows system$(,) compiling for 32-bit MinGW SDL2...) - - # go for a 32-bit sdl mingw exe by default - MINGW=1 - WINDOWSHELL=1 - -else # if you on the *nix - - system:=$(shell uname -s) - - ifeq ($(system),Linux) - new_system=LINUX - else - - $(error \ - Could not automatically detect your system,\ - try specifying a system manually) - - endif - - ifeq ($(shell getconf LONG_BIT),64) - system+=64-bit - new_system:=$(new_system)64 - endif - - $(call print,Detected $(system) ($(new_system))...) - $(new_system)=1 - -endif -endif - - -# SRB2 data files -D_DIR?=../bin/Resources -D_FILES=$(D_DIR)/main.kart \ - $(D_DIR)/gfx.pk3 \ - $(D_DIR)/textures.pk3 \ - $(D_DIR)/chars.pk3 \ - $(D_DIR)/maps.wad \ - $(D_DIR)/patch.pk3 \ - $(D_DIR)/sounds.wad \ - $(D_DIR)/music.wad \ - -PKG_CONFIG?=pkg-config - -ifdef PANDORA -LINUX=1 -endif - -ifdef LINUX64 -LINUX=1 -NONX86=1 -# LINUX64 does not imply X86_64=1; could mean ARM64 or Itanium -endif - -ifdef MINGW64 -MINGW=1 -NONX86=1 -NOASM=1 -# MINGW64 should not necessarily imply X86_64=1, but we make that assumption elsewhere -# Once that changes, remove this -X86_64=1 -endif #ifdef MINGW64 - -ifdef HAIKU -SDL=1 -endif - -include Makefile.cfg - -ifdef DUMMY -NOPNG=1 -NOZLIB=1 -NONET=1 -NOHW=1 -NOASM=1 -NOIPX=1 -EXENAME?=srb2dummy -OBJS=$(OBJDIR)/i_video.o -LIBS=-lm -endif - -ifdef HAIKU -NOIPX=1 -NOASM=1 -ifndef NONET -LIBS=-lnetwork -endif -CFLAGS+=-DUNIXCOMMON -PNG_CFLAGS?= -PNG_LDFLAGS?=-lpng -endif - -ifdef PANDORA -NONX86=1 -NOHW=1 -endif - -ifndef NOOPENMPT -HAVE_OPENMPT=1 -endif - -ifdef MINGW -include win32/Makefile.cfg -endif #ifdef MINGW - -ifdef UNIX -UNIXCOMMON=1 -endif - -ifdef LINUX -UNIXCOMMON=1 -ifndef NOGME -HAVE_LIBGME=1 -endif -endif - -ifdef SOLARIS -UNIXCOMMON=1 -endif - -ifdef FREEBSD -UNIXCOMMON=1 -endif - -ifdef MACOSX -UNIXCOMMON=1 -endif - -ifdef SDL - include sdl/Makefile.cfg -endif #ifdef SDL - -ifdef DISTCC - CC:=distcc $(CC) -endif - -ifdef CCACHE - CC:=ccache $(CC) -endif - -MSGFMT?=msgfmt - -ifdef WINDOWSHELL - COMPTIME=-..\comptime.bat -else - COMPTIME=-../comptime.sh -endif - -ifndef ECHO - NASM:=@$(NASM) - REMOVE:=@$(REMOVE) - CC:=@$(CC) - CXX:=@$(CXX) - OBJCOPY:=@$(OBJCOPY) - OBJDUMP:=@$(OBJDUMP) - STRIP:=@$(STRIP) - WINDRES:=@$(WINDRES) - MKDIR:=@$(MKDIR) - GZIP:=@$(GZIP) - MSGFMT:=@$(MSGFMT) - UPX:=@$(UPX) - UPX_OPTS+=-q - COMPTIME:=@$(COMPTIME) -endif - -ifdef NONET - OPTS+=-DNONET - NOCURL=1 -else -ifdef NO_IPV6 - OPTS+=-DNO_IPV6 -endif -endif - -ifdef NOHW - OPTS+=-DNOHW -else - OPTS+=-DHWRENDER - OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \ - $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o -endif - -OPTS += -DCOMPVERSION - -ifndef NONX86 -ifndef GCC29 - ARCHOPTS?=-msse3 -mfpmath=sse -else - ARCHOPTS?=-mpentium -endif -else -ifdef X86_64 - ARCHOPTS?=-march=nocona -endif -endif - -ifndef NOASM -ifndef NONX86 - OBJS+=$(OBJDIR)/tmap.o $(OBJDIR)/tmap_mmx.o - OPTS+=-DUSEASM -endif -endif - -ifndef NOPNG -OPTS+=-DHAVE_PNG - -ifdef PNG_PKGCONFIG -PNG_CFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --libs) -else ifdef PREFIX -PNG_CONFIG?=$(PREFIX)-libpng-config +CC:=$(PREFIX)-gcc +endif + +OBJDUMP_OPTS?=--wide --source --line-numbers + +OBJCOPY:=$(call Prefix,objcopy) +OBJDUMP:=$(call Prefix,objdump) +WINDRES:=$(call Prefix,windres) + +ifdef YASM +NASM?=yasm else -PNG_CONFIG?=libpng-config -endif - -ifdef PNG_STATIC -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --static --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --static --ldflags) -else -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --ldflags) -endif -endif - -ifdef LINUX -PNG_CFLAGS+=-D_LARGEFILE64_SOURCE -endif - -LIBS+=$(PNG_LDFLAGS) -CFLAGS+=$(PNG_CFLAGS) - -OBJS+=$(OBJDIR)/apng.o -endif - -ifdef HAVE_LIBGME -OPTS+=-DHAVE_LIBGME - -LIBGME_PKGCONFIG?=libgme -LIBGME_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --cflags) -LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs) - -LIBS+=$(LIBGME_LDFLAGS) -CFLAGS+=$(LIBGME_CFLAGS) -endif - -ifdef HAVE_OPENMPT -OPTS+=-DHAVE_OPENMPT - -LIBOPENMPT_PKGCONFIG?=libopenmpt -LIBOPENMPT_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --cflags) -LIBOPENMPT_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --libs) - -LIBS+=$(LIBOPENMPT_LDFLAGS) -CFLAGS+=$(LIBOPENMPT_CFLAGS) -endif - -ifndef NOZLIB -OPTS+=-DHAVE_ZLIB -ZLIB_PKGCONFIG?=zlib -ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) -ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) - -LIBS+=$(ZLIB_LDFLAGS) -CFLAGS+=$(ZLIB_CFLAGS) -else -NOPNG=1 -endif - -ifndef NOCURL -OPTS+=-DHAVE_CURL -CURLCONFIG?=curl-config -CURL_CFLAGS?=$(shell $(CURLCONFIG) --cflags) -CURL_LDFLAGS?=$(shell $(CURLCONFIG) --libs) - -LIBS+=$(CURL_LDFLAGS) -CFLAGS+=$(CURL_CFLAGS) -endif - -ifdef STATIC -LIBS:=-static $(LIBS) -endif - -ifdef HAVE_MINIUPNPC -ifdef NONET -HAVE_MINIUPNPC='' -else -LIBS+=-lminiupnpc -ifdef MINGW -LIBS+=-lws2_32 -liphlpapi -endif -CFLAGS+=-DHAVE_MINIUPNPC -endif -endif - -ifdef HAVE_DISCORDRPC -LIBS+=-ldiscord-rpc -CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN -OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o -endif - -include blua/Makefile.cfg - -ifdef NOMD5 - OPTS+=-DNOMD5 -else - OBJS:=$(OBJDIR)/md5.o $(OBJS) -endif - -ifdef NOPOSTPROCESSING - OPTS+=-DNOPOSTPROCESSING -endif - - OPTS:=-fno-exceptions $(OPTS) - -ifdef MOBJCONSISTANCY - OPTS+=-DMOBJCONSISTANCY -endif - -ifdef PACKETDROP - OPTS+=-DPACKETDROP -endif - -ifdef DEBUGMODE - - # build with debugging information - WINDRESFLAGS = -D_DEBUG -ifdef GCC48 - CFLAGS+=-Og -else - CFLAGS+=-O0 -endif - CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP -else - - - # build a normal optimised version - WINDRESFLAGS = -DNDEBUG - CFLAGS+=-O3 -endif - CFLAGS+=-g $(OPTS) $(ARCHOPTS) $(WINDRESFLAGS) - -ifdef TESTERS - OPTS+=-DTESTERS +NASM?=nasm endif ifdef YASM ifdef STABS - NASMOPTS?= -g stabs +NASMOPTS?=-g stabs else - NASMOPTS?= -g dwarf2 +NASMOPTS?=-g dwarf2 endif else - NASMOPTS?= -g +NASMOPTS?=-g endif -ifdef PROFILEMODE - # build with profiling information - CFLAGS+=-pg - LDFLAGS+=-pg +GZIP?=gzip +GZIP_OPTS?=-9 -f -n +ifdef WINDOWSHELL +GZIP_OPTS+=--rsyncable endif -ifdef ZDEBUG - CPPFLAGS+=-DZDEBUG +UPX_OPTS?=--best --preserve-build-id +ifndef ECHO +UPX_OPTS+=-qq endif -ifdef DEVELOP - CPPFLAGS+=-DDEVELOP +include Makefile.d/detect.mk + +# make would try to remove the implicitly made directories +.PRECIOUS : %/ comptime.c + +sources:= +makedir:=../make + +# -DCOMPVERSION: flag to use comptime.h +opts:=-DCOMPVERSION -g +libs:= + +nasm_format:= + +# This is a list of variables names, of which if defined, +# also defines the name as a macro to the compiler. +passthru_opts:= + +include Makefile.d/platform.mk +include Makefile.d/features.mk +include Makefile.d/versions.mk + +ifdef DEBUGMODE +makedir:=$(makedir)/debug endif -OPTS+=$(CPPFLAGS) +depdir:=$(makedir)/deps +objdir:=$(makedir)/objs -# default EXENAME if all else fails +# very sophisticated dependency +sources+=\ + $(call List,Sourcefile)\ + $(call List,blua/Sourcefile)\ + +depends:=$(basename $(filter %.c %.s,$(sources))) +objects:=$(basename $(filter %.c %.s %.nas,$(sources))) + +depends:=$(depends:%=$(depdir)/%.d) + +# comptime.o added directly to objects instead of thru +# sources because comptime.c includes comptime.h, but +# comptime.h may not exist yet. It's a headache so this is +# easier. +objects:=$(objects:=.o) comptime.o + +# windows resource file +rc_file:=$(basename $(filter %.rc,$(sources))) +ifdef rc_file +objects+=$(rc_file:=.res) +endif + +objects:=$(addprefix $(objdir)/,$(objects)) + +ifdef DEBUGMODE +bin:=../bin/debug +else +bin:=../bin +endif + +# default EXENAME (usually set by platform) EXENAME?=srb2 DBGNAME?=$(EXENAME).debug -# $(OBJDIR)/dstrings.o \ +exe:=$(bin)/$(EXENAME) +dbg:=$(bin)/$(DBGNAME) -# not too sophisticated dependency -# SRB2kart kart.o on line 433 below -OBJS:=$(i_main_o) \ - $(OBJDIR)/string.o \ - $(OBJDIR)/d_main.o \ - $(OBJDIR)/d_clisrv.o \ - $(OBJDIR)/d_net.o \ - $(OBJDIR)/d_netfil.o \ - $(OBJDIR)/d_netcmd.o \ - $(OBJDIR)/dehacked.o \ - $(OBJDIR)/deh_soc.o \ - $(OBJDIR)/deh_lua.o \ - $(OBJDIR)/deh_tables.o \ - $(OBJDIR)/z_zone.o \ - $(OBJDIR)/f_finale.o \ - $(OBJDIR)/f_wipe.o \ - $(OBJDIR)/g_demo.o \ - $(OBJDIR)/g_game.o \ - $(OBJDIR)/g_input.o \ - $(OBJDIR)/g_splitscreen.o\ - $(OBJDIR)/am_map.o \ - $(OBJDIR)/command.o \ - $(OBJDIR)/console.o \ - $(OBJDIR)/font.o \ - $(OBJDIR)/hu_stuff.o \ - $(OBJDIR)/y_inter.o \ - $(OBJDIR)/st_stuff.o \ - $(OBJDIR)/m_aatree.o \ - $(OBJDIR)/m_anigif.o \ - $(OBJDIR)/m_argv.o \ - $(OBJDIR)/m_bbox.o \ - $(OBJDIR)/m_cheat.o \ - $(OBJDIR)/m_cond.o \ - $(OBJDIR)/m_fixed.o \ - $(OBJDIR)/m_menu.o \ - $(OBJDIR)/m_misc.o \ - $(OBJDIR)/m_perfstats.o \ - $(OBJDIR)/m_random.o \ - $(OBJDIR)/m_queue.o \ - $(OBJDIR)/info.o \ - $(OBJDIR)/p_ceilng.o \ - $(OBJDIR)/p_enemy.o \ - $(OBJDIR)/p_floor.o \ - $(OBJDIR)/p_inter.o \ - $(OBJDIR)/p_lights.o \ - $(OBJDIR)/p_map.o \ - $(OBJDIR)/p_maputl.o \ - $(OBJDIR)/p_mobj.o \ - $(OBJDIR)/p_polyobj.o\ - $(OBJDIR)/p_saveg.o \ - $(OBJDIR)/p_setup.o \ - $(OBJDIR)/p_sight.o \ - $(OBJDIR)/p_spec.o \ - $(OBJDIR)/p_telept.o \ - $(OBJDIR)/p_tick.o \ - $(OBJDIR)/p_user.o \ - $(OBJDIR)/p_slopes.o \ - $(OBJDIR)/tables.o \ - $(OBJDIR)/r_bsp.o \ - $(OBJDIR)/r_data.o \ - $(OBJDIR)/r_draw.o \ - $(OBJDIR)/r_main.o \ - $(OBJDIR)/r_plane.o \ - $(OBJDIR)/r_segs.o \ - $(OBJDIR)/r_skins.o \ - $(OBJDIR)/r_sky.o \ - $(OBJDIR)/r_splats.o \ - $(OBJDIR)/r_things.o \ - $(OBJDIR)/r_textures.o \ - $(OBJDIR)/r_patch.o \ - $(OBJDIR)/r_patchrotation.o \ - $(OBJDIR)/r_picformats.o \ - $(OBJDIR)/r_portal.o \ - $(OBJDIR)/screen.o \ - $(OBJDIR)/taglist.o \ - $(OBJDIR)/v_video.o \ - $(OBJDIR)/s_sound.o \ - $(OBJDIR)/sounds.o \ - $(OBJDIR)/w_wad.o \ - $(OBJDIR)/filesrch.o \ - $(OBJDIR)/mserv.o \ - $(OBJDIR)/http-mserv.o\ - $(OBJDIR)/i_tcp.o \ - $(OBJDIR)/lzf.o \ - $(OBJDIR)/vid_copy.o \ - $(OBJDIR)/k_kart.o \ - $(OBJDIR)/k_respawn.o\ - $(OBJDIR)/k_collide.o\ - $(OBJDIR)/k_color.o \ - $(OBJDIR)/k_race.o \ - $(OBJDIR)/k_battle.o \ - $(OBJDIR)/k_pwrlv.o \ - $(OBJDIR)/k_waypoint.o\ - $(OBJDIR)/k_pathfind.o\ - $(OBJDIR)/k_bheap.o \ - $(OBJDIR)/k_bot.o \ - $(OBJDIR)/k_botitem.o\ - $(OBJDIR)/k_botsearch.o\ - $(OBJDIR)/k_grandprix.o\ - $(OBJDIR)/k_hud.o \ - $(i_cdmus_o) \ - $(i_net_o) \ - $(i_system_o) \ - $(i_sound_o) \ - $(OBJS) +build_done==== Build is done, look for \ + $( $@ + $(.)$(GZIP) $(GZIP_OPTS) $@ -ifdef SDL -all: $(BIN)/$(EXENAME) -endif - -ifdef DUMMY -all: $(BIN)/$(EXENAME) -endif - -cleandep: - $(REMOVE) $(DEPS) - $(REMOVE) comptime.h - -clean: - $(REMOVE) *~ *.flc - $(REMOVE) $(OBJDIR)/*.o - -distclean: clean cleandep - -ifdef MINGW - $(REMOVE) $(OBJDIR)/*.res -endif - -ifdef CYGWIN32 - $(REMOVE) $(OBJDIR)/*.res -endif - -#make a big srb2.s that is the disasm of the exe (dos only ?) -asm: - $(CC) $(LDFLAGS) $(OBJS) -o $(OBJDIR)/tmp.exe $(LIBS) - $(OBJDUMP) -d $(OBJDIR)/tmp.exe --no-show-raw-insn > srb2.s - $(REMOVE) $(OBJDIR)/tmp.exe - -# executable -# NOTE: DJGPP's objcopy do not have --add-gnu-debuglink - -$(BIN)/$(EXENAME): $(POS) $(OBJS) - -$(MKDIR) $(BIN) - $(call echo,Linking $(EXENAME)...) - $(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS) -ifndef VALGRIND -ifndef NOOBJDUMP - $(call echo,Dumping debugging info) - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt +# '::' means run unconditionally +# this really updates comptime.h +comptime.c :: ifdef WINDOWSHELL - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt + $(.)..\comptime.bat . else - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt -endif + $(.)../comptime.sh . endif -# mac os x lsdlsrb2 does not like objcopy -ifndef MACOSX - $(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME) - $(OBJCOPY) --strip-debug $(BIN)/$(EXENAME) - -$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME) -endif -ifndef NOUPX - -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) -endif -endif - $(call echo,Build is done$(,) please look for $(EXENAME) in $(BIN)$(,) (checking for post steps)) +# I wish I could make dependencies out of rc files :( +$(objdir)/win32/Srb2win.res : \ + win32/afxres.h win32/resource.h -reobjdump: - $(call echo,Redumping debugging info) - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt -ifdef WINDOWSHELL - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt -else - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt -endif - -$(OBJDIR): - -$(MKDIR) $(OBJDIR) - -ifdef SDL -ifdef MINGW -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -else -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ -endif -endif - -#dependecy made by gcc itself ! -ifndef DUMMY -ifndef CLEANONLY -$(call print,Checking dependency files...) --include $(DEPS) -endif -endif - -undefine deps_rule - -# windows makes it too hard ! +# dependency recipe template +# 1: source file suffix +# 2: extra flags to gcc +define _recipe = +$(depdir)/%.d : %.$(1) | $$$$(@D)/ ifndef WINDOWSHELL -ifdef echoName -define deps_rule = - @printf "%-20.20s\r" $< - -endef +ifdef Echo_name + @printf '%-20.20s\r' $$< endif endif - -define deps_rule += - $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$(<:.c=.o) $< + $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< endef -$(DEPDIR)/%.d: %.c - $(deps_rule) +$(eval $(call _recipe,c)) +$(eval $(call _recipe,s,$(asflags))) -$(DEPDIR)/%.d: $(INTERFACE)/%.c - $(deps_rule) +# compiling recipe template +# 1: target file suffix +# 2: source file suffix +# 3: compile command +define _recipe = +$(objdir)/%.$(1) : %.$(2) | $$$$(@D)/ + $(call Echo_name,$$<) + $(.)$(3) +endef -$(DEPDIR)/%.d: hardware/%.c - $(deps_rule) +$(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<)) +$(eval $(call _recipe,o,nas,$(nasm) -o $$@ $$<)) +$(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<)) +$(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@)) -$(DEPDIR)/%.d: blua/%.c - $(deps_rule) +_rm=$(.)$(rmrf) $(call Windows_path,$(1)) -ifdef VALGRIND -$(OBJDIR)/z_zone.o: z_zone.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@ -endif +cleandep : + $(call _rm,$(depends) comptime.h) -$(OBJDIR)/comptime.o:: -ifdef echoName - @echo -- comptime.c ... -endif - $(COMPTIME) . - $(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@ +clean : + $(call _rm,$(exe) $(dbg) $(dbg).txt $(objects)) -$(BIN)/%.mo: locale/%.po - -$(MKDIR) $(BIN) - $(echoName) - $(MSGFMT) -f -o $@ $< +distclean : + $(call _rm,../bin ../objs ../dep ../make comptime.h) -$(OBJDIR)/%.o: %.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: $(INTERFACE)/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MACOSX -$(OBJDIR)/%.o: sdl/macosx/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -$(OBJDIR)/%.o: hardware/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: blua/%.c - $(echoName) - $(CC) $(CFLAGS) $(LUA_CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: %.nas - $(echoName) - $(NASM) $(NASMOPTS) -o $@ -f $(NASMFORMAT) $< - -$(OBJDIR)/vid_copy.o: vid_copy.s asm_defs.inc - $(echoName) - $(CC) $(OPTS) $(ASFLAGS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/%.o: %.s - $(echoName) - $(CC) $(OPTS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h - $(echoName) - $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff - - -ifdef SDL - -ifdef MINGW -$(OBJDIR)/win_dbg.o: win32/win_dbg.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -ifdef STATICHS -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MINGW -$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif +info: +ifdef WINDOWSHELL + @REM else - -$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_fmod/s_fmod.c - -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c + @: endif -endif - -############################################################# -# -############################################################# diff --git a/src/Makefile.cfg b/src/Makefile.cfg deleted file mode 100644 index a4fef3c3e..000000000 --- a/src/Makefile.cfg +++ /dev/null @@ -1,482 +0,0 @@ -# vim: ft=make -# -# Makefile.cfg for SRB2 -# - -# -# GNU compiler & tools' flags -# and other things -# - -# See the following variable don't start with 'GCC'. This is -# to avoid a false positive with the version detection... - -SUPPORTED_GCC_VERSIONS:=\ - 101 102\ - 91 92 93\ - 81 82 83 84\ - 71 72 73 74 75\ - 61 62 63 64\ - 51 52 53 54 55\ - 40 41 42 43 44 45 46 47 48 49 - -LATEST_GCC_VERSION=10.2 - -# gcc or g++ -ifdef PREFIX - CC=$(PREFIX)-gcc - CXX=$(PREFIX)-g++ - OBJCOPY=$(PREFIX)-objcopy - OBJDUMP=$(PREFIX)-objdump - STRIP=$(PREFIX)-strip - WINDRES=$(PREFIX)-windres -else - OBJCOPY=objcopy - OBJDUMP=objdump - STRIP=strip - WINDRES=windres -endif - -# because Apple screws with us on this -# need to get bintools from homebrew -ifdef MACOSX - CC=clang - CXX=clang - OBJCOPY=gobjcopy - OBJDUMP=gobjdump -endif - -# Automatically set version flag, but not if one was manually set -# And don't bother if this is a clean only run -ifeq (,$(filter GCC% CLEANONLY,$(.VARIABLES))) - version:=$(shell $(CC) --version) - # check if this is in fact GCC - ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version)))) - version:=$(shell $(CC) -dumpversion) - - # Turn version into words of major, minor - v:=$(subst ., ,$(version)) - # concat. major minor - v:=$(word 1,$(v))$(word 2,$(v)) - - # If this version is not in the list, default to the latest supported - ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS))) - define line = - Your compiler version, GCC $(version), is not supported by the Makefile. - The Makefile will assume GCC $(LATEST_GCC_VERSION).)) - endef - $(call print,$(line)) - GCC$(subst .,,$(LATEST_GCC_VERSION))=1 - else - $(call print,Detected GCC $(version) (GCC$(v))) - GCC$(v)=1 - endif - endif -endif - -ifdef GCC102 -GCC101=1 -endif - -ifdef GCC101 -GCC93=1 -endif - -ifdef GCC93 -GCC92=1 -endif - -ifdef GCC92 -GCC91=1 -endif - -ifdef GCC91 -GCC84=1 -endif - -ifdef GCC84 -GCC83=1 -endif - -ifdef GCC83 -GCC82=1 -endif - -ifdef GCC82 -GCC81=1 -endif - -ifdef GCC81 -GCC75=1 -endif - -ifdef GCC75 -GCC74=1 -endif - -ifdef GCC74 -GCC73=1 -endif - -ifdef GCC73 -GCC72=1 -endif - -ifdef GCC72 -GCC71=1 -endif - -ifdef GCC71 -GCC64=1 -endif - -ifdef GCC64 -GCC63=1 -endif - -ifdef GCC63 -GCC62=1 -endif - -ifdef GCC62 -GCC61=1 -endif - -ifdef GCC61 -GCC55=1 -endif - -ifdef GCC55 -GCC54=1 -endif - -ifdef GCC54 -GCC53=1 -endif - -ifdef GCC53 -GCC52=1 -endif - -ifdef GCC52 -GCC51=1 -endif - -ifdef GCC51 -GCC49=1 -endif - -ifdef GCC49 -GCC48=1 -endif - -ifdef GCC48 -GCC47=1 -endif - -ifdef GCC47 -GCC46=1 -endif - -ifdef GCC46 -GCC45=1 -endif - -ifdef GCC45 -GCC44=1 -endif - -ifdef GCC44 -GCC43=1 -endif - -ifdef GCC43 -GCC42=1 -endif - -ifdef GCC42 -GCC41=1 -endif - -ifdef GCC41 -GCC40=1 -VCHELP=1 -endif - -ifdef GCC295 -GCC29=1 -endif - -OLDWFLAGS:=$(WFLAGS) -# -W -Wno-unused -WFLAGS=-Wall -ifndef GCC295 -#WFLAGS+=-Wno-packed -endif -ifndef RELAXWARNINGS - WFLAGS+=-W -#WFLAGS+=-Wno-sign-compare -ifndef GCC295 - WFLAGS+=-Wno-div-by-zero -endif -#WFLAGS+=-Wsystem-headers -WFLAGS+=-Wfloat-equal -#WFLAGS+=-Wtraditional -ifdef VCHELP - WFLAGS+=-Wdeclaration-after-statement - WFLAGS+=-Wno-error=declaration-after-statement -endif - WFLAGS+=-Wundef -ifndef GCC295 - WFLAGS+=-Wendif-labels -endif -ifdef GCC40 - WFLAGS+=-std=gnu89 -endif -ifdef GCC41 - WFLAGS+=-Wshadow -endif -#WFLAGS+=-Wlarger-than-%len% - WFLAGS+=-Wpointer-arith -Wbad-function-cast -ifdef GCC45 -#WFLAGS+=-Wc++-compat -endif - WFLAGS+=-Wcast-qual -ifndef NOCASTALIGNWARN - WFLAGS+=-Wcast-align -endif - WFLAGS+=-Wwrite-strings -ifndef ERRORMODE -#WFLAGS+=-Wconversion -ifdef GCC43 - #WFLAGS+=-Wno-sign-conversion -endif -endif - WFLAGS+=-Wsign-compare -ifdef GCC91 - WFLAGS+=-Wno-error=address-of-packed-member -endif -ifdef GCC45 - WFLAGS+=-Wlogical-op -endif - WFLAGS+=-Waggregate-return -ifdef HAIKU -ifdef GCC41 - #WFLAGS+=-Wno-attributes -endif -endif -#WFLAGS+=-Wstrict-prototypes -ifdef GCC40 - WFLAGS+=-Wold-style-definition -endif - WFLAGS+=-Wmissing-prototypes -Wmissing-declarations -ifdef GCC40 - WFLAGS+=-Wmissing-field-initializers -endif - WFLAGS+=-Wmissing-noreturn -#WFLAGS+=-Wmissing-format-attribute -#WFLAGS+=-Wno-multichar -#WFLAGS+=-Wno-deprecated-declarations -#WFLAGS+=-Wpacked -#WFLAGS+=-Wpadded -#WFLAGS+=-Wredundant-decls - WFLAGS+=-Wnested-externs -#WFLAGS+=-Wunreachable-code - WFLAGS+=-Winline -ifdef GCC43 - WFLAGS+=-funit-at-a-time - WFLAGS+=-Wlogical-op -endif -ifndef GCC295 - WFLAGS+=-Wdisabled-optimization -endif -endif -WFLAGS+=-Wformat-y2k -ifdef GCC71 -WFLAGS+=-Wno-error=format-overflow=2 -endif -WFLAGS+=-Wformat-security -ifndef GCC29 -#WFLAGS+=-Winit-self -endif -ifdef GCC46 -WFLAGS+=-Wno-suggest-attribute=noreturn -endif - -ifdef NOLDWARNING -LDFLAGS+=-Wl,--as-needed -endif - -ifdef ERRORMODE -WFLAGS+=-Werror -endif - -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 -ifdef GCC54 - WFLAGS+=-Wno-logical-op -Wno-error=logical-op -endif -ifdef GCC61 - WFLAGS+=-Wno-tautological-compare -Wno-error=tautological-compare -endif -ifdef GCC71 - WFLAGS+=-Wimplicit-fallthrough=4 - WFLAGS+=-Wno-format-truncation -endif -ifdef GCC81 - WFLAGS+=-Wno-error=format-overflow - WFLAGS+=-Wno-error=stringop-truncation - WFLAGS+=-Wno-error=stringop-overflow - WFLAGS+=-Wno-format-overflow - WFLAGS+=-Wno-stringop-truncation - WFLAGS+=-Wno-stringop-overflow - WFLAGS+=-Wno-error=multistatement-macros -endif - - -#indicate platform and what interface use with -ifndef LINUX -ifndef FREEBSD -ifndef CYGWIN32 -ifndef MINGW -ifndef MINGW64 -ifndef SDL -ifndef DUMMY -$(error No interface or platform flag defined) -endif -endif -endif -endif -endif -endif -endif - -#determine the interface directory (where you put all i_*.c) -i_net_o=$(OBJDIR)/i_net.o -i_system_o=$(OBJDIR)/i_system.o -i_sound_o=$(OBJDIR)/i_sound.o -i_main_o=$(OBJDIR)/i_main.o -#set OBJDIR and BIN's starting place -OBJDIR=../objs -BIN=../bin -DEPDIR=../dep -#Nasm ASM and rm -ifdef YASM -NASM?=yasm -else -NASM?=nasm -endif -REMOVE?=rm -f -MKDIR?=mkdir -p -GZIP?=gzip -GZIP_OPTS?=-9 -f -n -GZIP_OPT2=$(GZIP_OPTS) --rsyncable -UPX?=upx -UPX_OPTS?=--best --preserve-build-id -ifndef ECHO -UPX_OPTS+=-q -endif - -#Interface Setup -ifdef DUMMY - INTERFACE=dummy - OBJDIR:=$(OBJDIR)/dummy - BIN:=$(BIN)/dummy - DEPDIR:=$(DEPDIR)/dummy -else -ifdef LINUX - NASMFORMAT=elf -DLINUX - SDL=1 -ifdef LINUX64 - OBJDIR:=$(OBJDIR)/Linux64 - BIN:=$(BIN)/Linux64 - DEPDIR:=$(DEPDIR)/Linux64 -else - OBJDIR:=$(OBJDIR)/Linux - BIN:=$(BIN)/Linux - DEPDIR:=$(DEPDIR)/Linux -endif -else -ifdef FREEBSD - INTERFACE=sdl - NASMFORMAT=elf -DLINUX - SDL=1 - - OBJDIR:=$(OBJDIR)/FreeBSD - BIN:=$(BIN)/FreeBSD - DEPDIR:=$(DEPDIR)/Linux -else -ifdef SOLARIS - INTERFACE=sdl - NASMFORMAT=elf -DLINUX - SDL=1 - - OBJDIR:=$(OBJDIR)/Solaris - BIN:=$(BIN)/Solaris - DEPDIR:=$(DEPDIR)/Solaris -else -ifdef CYGWIN32 - INTERFACE=sdl - NASMFORMAT=win32 - SDL=1 - - OBJDIR:=$(OBJDIR)/cygwin - BIN:=$(BIN)/Cygwin - DEPDIR:=$(DEPDIR)/Cygwin -else -ifdef MINGW64 - #NASMFORMAT=win64 - SDL=1 - OBJDIR:=$(OBJDIR)/Mingw64 - BIN:=$(BIN)/Mingw64 - DEPDIR:=$(DEPDIR)/Mingw64 -else -ifdef MINGW - NASMFORMAT=win32 - SDL=1 - OBJDIR:=$(OBJDIR)/Mingw - BIN:=$(BIN)/Mingw - DEPDIR:=$(DEPDIR)/Mingw -endif -endif -endif -endif -endif -endif -endif - -ifdef ARCHNAME - OBJDIR:=$(OBJDIR)/$(ARCHNAME) - BIN:=$(BIN)/$(ARCHNAME) - DEPDIR:=$(DEPDIR)/$(ARCHNAME) -endif - -OBJDUMP_OPTS?=--wide --source --line-numbers -LD=$(CC) - -ifdef SDL - INTERFACE=sdl - OBJDIR:=$(OBJDIR)/SDL - DEPDIR:=$(DEPDIR)/SDL -endif - -ifndef DUMMY -ifdef DEBUGMODE - OBJDIR:=$(OBJDIR)/Debug - BIN:=$(BIN)/Debug - DEPDIR:=$(DEPDIR)/Debug -else - OBJDIR:=$(OBJDIR)/Release - BIN:=$(BIN)/Release - DEPDIR:=$(DEPDIR)/Release -endif -endif diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk new file mode 100644 index 000000000..f458b044c --- /dev/null +++ b/src/Makefile.d/detect.mk @@ -0,0 +1,107 @@ +# +# Detect the host system and compiler version. +# + +# Previously featured:\ + PANDORA\ + HAIKU\ + DUMMY\ + DJGPPDOS\ + SOLARIS\ + MACOSX\ + +all_systems:=\ + LINUX64\ + MINGW64\ + MINGW\ + UNIX\ + LINUX\ + FREEBSD\ + SDL\ + +# check for user specified system +ifeq (,$(filter $(all_systems),$(.VARIABLES))) +ifeq ($(OS),Windows_NT) # all windows are Windows_NT... + +_m=Detected a Windows system,\ + compiling for 32-bit MinGW SDL...) +$(call Print,$(_m)) + +# go for a 32-bit sdl mingw exe by default +MINGW:=1 + +else # if you on the *nix + +system:=$(shell uname -s) + +ifeq ($(system),Linux) +new_system:=LINUX +else + +$(error \ + Could not automatically detect your system,\ + try specifying a system manually) + +endif + +ifeq ($(shell getconf LONG_BIT),64) +system+=64-bit +new_system:=$(new_system)64 +endif + +$(call Print,Detected $(system) ($(new_system))...) +$(new_system):=1 + +endif +endif + +# This must have high to low order. +gcc_versions:=\ + 102 101\ + 93 92 91\ + 84 83 82 81\ + 75 74 73 72 71\ + 64 63 62 61\ + 55 54 53 52 51\ + 49 48 47 46 45 44 43 42 41 40 + +latest_gcc_version:=10.2 + +# Automatically set version flag, but not if one was +# manually set. And don't bother if this is a clean only +# run. +ifeq (,$(call Wildvar,GCC% destructive)) + +# can't use $(CC) --version here since that uses argv[0] to display the name +# also gcc outputs the information to stderr, so I had to do 2>&1 +# this program really doesn't like identifying itself +version:=$(shell $(CC) -v 2>&1) + +# check if this is in fact GCC +ifneq (,$(findstring gcc version,$(version))) + +# in stark contrast to the name, gcc will give me a nicely formatted version number for free +version:=$(shell $(CC) -dumpfullversion) + +# Turn version into words of major, minor +v:=$(subst ., ,$(version)) +# concat. major minor +v:=$(word 1,$(v))$(word 2,$(v)) + +# If this version is not in the list, +# default to the latest supported +ifeq (,$(filter $(v),$(gcc_versions))) +define line = +Your compiler version, GCC $(version), \ +is not supported by the Makefile. +The Makefile will assume GCC $(latest_gcc_version). +endef +$(call Print,$(line)) +GCC$(subst .,,$(latest_gcc_version)):=1 +else +$(call Print,Detected GCC $(version) (GCC$(v))) +GCC$(v):=1 +endif + +endif +endif diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk new file mode 100644 index 000000000..a29a8a153 --- /dev/null +++ b/src/Makefile.d/features.mk @@ -0,0 +1,84 @@ +# +# Makefile for feature flags. +# + +passthru_opts+=\ + NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ + MOBJCONSISTANCY PACKETDROP ZDEBUG\ + HAVE_MINIUPNPC\ + HAVE_DISCORDRPC TESTERS DEVELOP + +# build with debugging information +ifdef DEBUGMODE +MOBJCONSISTANCY=1 +PACKETDROP=1 +opts+=-DPARANOIA -DRANGECHECK +endif + +ifndef NOHW +opts+=-DHWRENDER +sources+=$(call List,hardware/Sourcefile) +endif + +ifndef NOASM +ifndef NONX86 +sources+=tmap.nas tmap_mmx.nas +opts+=-DUSEASM +endif +endif + +ifndef NOMD5 +sources+=md5.c +endif + +ifndef NOZLIB +ifndef NOPNG +ifdef PNG_PKGCONFIG +$(eval $(call Use_pkg_config,PNG_PKGCONFIG)) +else +PNG_CONFIG?=$(call Prefix,libpng-config) +$(eval $(call Configure,PNG,$(PNG_CONFIG) \ + $(if $(PNG_STATIC),--static),,--ldflags)) +endif +ifdef LINUX +opts+=-D_LARGFILE64_SOURCE +endif +opts+=-DHAVE_PNG +sources+=apng.c +endif +endif + +ifndef NONET +ifndef NOCURL +CURLCONFIG?=curl-config +$(eval $(call Configure,CURL,$(CURLCONFIG))) +opts+=-DHAVE_CURL +endif +endif + +ifdef HAVE_MINIUPNPC +libs+=-lminiupnpc +endif + +ifdef HAVE_DISCORDRPC +$(eval $(call Propogate_flags,DISCORDRPC)) +libs+=-ldiscord-rpc +opts+=-DUSE_STUN +sources+=discord.c stun.c +endif + +# (Valgrind is a memory debugger.) +ifdef VALGRIND +VALGRIND_PKGCONFIG?=valgrind +$(eval $(call Use_pkg_config,VALGRIND)) +ZDEBUG=1 +opts+=-DHAVE_VALGRIND +endif + +default_packages:=\ + GME/libgme/LIBGME\ + OPENMPT/libopenmpt/LIBOPENMPT\ + ZLIB/zlib\ + +$(foreach p,$(default_packages),\ + $(eval $(call Check_pkg_config,$(p)))) diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk new file mode 100644 index 000000000..98703e769 --- /dev/null +++ b/src/Makefile.d/nix.mk @@ -0,0 +1,40 @@ +# +# Makefile options for unices (linux, bsd...) +# + +EXENAME?=lsdl2srb2kart + +opts+=-DUNIXCOMMON -DLUA_USE_POSIX +libs+=-lm + +ifndef nasm_format +nasm_format:=elf -DLINUX +endif + +ifndef NOHW +opts+=-I/usr/X11R6/include +libs+=-L/usr/X11R6/lib +endif + +SDL=1 + +# In common usage. +ifdef LINUX +libs+=-lrt +passthru_opts+=NOTERMIOS +endif + +# Tested by Steel, as of release 2.2.8. +ifdef FREEBSD +opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD +libs+=-L/usr/X11R6/lib -lipx -lkvm +endif + +# FIXME: UNTESTED +#ifdef SOLARIS +#NOIPX=1 +#NOASM=1 +#opts+=-I/usr/local/include -I/opt/sfw/include \ +# -DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP +#libs+=-L/opt/sfw/lib -lsocket -lnsl +#endif diff --git a/src/Makefile.d/old.mk b/src/Makefile.d/old.mk new file mode 100644 index 000000000..ec9b6d776 --- /dev/null +++ b/src/Makefile.d/old.mk @@ -0,0 +1,16 @@ +# +# Warn about old build directories and offer to purge. +# + +_old:=$(wildcard $(addprefix ../bin/,FreeBSD Linux \ + Linux64 Mingw Mingw64 SDL dummy) ../objs ../dep) + +ifdef _old +$(foreach v,$(_old),$(info $(abspath $(v)))) +$(info ) +$(info These directories are no longer\ + required and should be removed.) +$(info You may remove them manually or\ + by using 'make distclean') +$(error ) +endif diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk new file mode 100644 index 000000000..fad4be191 --- /dev/null +++ b/src/Makefile.d/platform.mk @@ -0,0 +1,69 @@ +# +# Platform specific options. +# + +PKG_CONFIG?=pkg-config + +ifdef WINDOWSHELL +rmrf=-2>NUL DEL /S /Q +mkdir=-2>NUL MD +cat=TYPE +else +rmrf=rm -rf +mkdir=mkdir -p +cat=cat +endif + +ifdef LINUX64 +LINUX=1 +endif + +ifdef MINGW64 +MINGW=1 +endif + +ifdef LINUX +UNIX=1 +ifdef LINUX64 +NONX86=1 +# LINUX64 does not imply X86_64=1; +# could mean ARM64 or Itanium +platform=linux/64 +else +platform=linux +endif +else ifdef FREEBSD +UNIX=1 +platform=freebsd +else ifdef SOLARIS # FIXME: UNTESTED +UNIX=1 +platform=solaris +else ifdef CYGWIN32 # FIXME: UNTESTED +nasm_format=win32 +platform=cygwin +else ifdef MINGW +ifdef MINGW64 +NONX86=1 +NOASM=1 +# MINGW64 should not necessarily imply X86_64=1, +# but we make that assumption elsewhere +# Once that changes, remove this +X86_64=1 +platform=mingw/64 +else +platform=mingw +endif +include Makefile.d/win32.mk +endif + +ifdef platform +makedir:=$(makedir)/$(platform) +endif + +ifdef UNIX +include Makefile.d/nix.mk +endif + +ifdef SDL +include Makefile.d/sdl.mk +endif diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk new file mode 100644 index 000000000..99ca624e6 --- /dev/null +++ b/src/Makefile.d/sdl.mk @@ -0,0 +1,79 @@ +# +# Makefile options for SDL2 backend. +# + +# +# SDL...., *looks at Alam*, THIS IS A MESS! +# +# ...a little bird flexes its muscles... +# + +makedir:=$(makedir)/SDL + +sources+=$(call List,sdl/Sourcefile) +opts+=-DDIRECTFULLSCREEN -DHAVE_SDL + +# FIXME: UNTESTED +#ifdef PANDORA +#include sdl/SRB2Pandora/Makefile.cfg +#endif #ifdef PANDORA + +# FIXME: UNTESTED +#ifdef CYGWIN32 +#include sdl/MakeCYG.cfg +#endif #ifdef CYGWIN32 + +ifndef NOHW +sources+=sdl/ogl_sdl.c +endif + +ifdef NOMIXER +sources+=sdl/sdl_sound.c +else +opts+=-DHAVE_MIXER +sources+=sdl/mixer_sound.c + + ifdef HAVE_MIXERX + opts+=-DHAVE_MIXERX + libs+=-lSDL2_mixer_ext + else + libs+=-lSDL2_mixer + endif +endif + +ifndef NOTHREADS +opts+=-DHAVE_THREADS +sources+=sdl/i_threads.c +endif + +ifdef SDL_PKGCONFIG +$(eval $(call Use_pkg_config,SDL)) +else +SDL_CONFIG?=$(call Prefix,sdl2-config) +SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) +SDL_LDFLAGS?=$(shell $(SDL_CONFIG) \ + $(if $(STATIC),--static-libs,--libs)) +$(eval $(call Propogate_flags,SDL)) +endif + +# use the x86 asm code +ifndef CYGWIN32 +ifndef NOASM +USEASM=1 +endif +endif + +ifdef MINGW +ifndef NOSDLMAIN +SDLMAIN=1 +endif +endif + +ifdef SDLMAIN +opts+=-DSDLMAIN +else +ifdef MINGW +opts+=-Umain +libs+=-mconsole +endif +endif diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk new file mode 100644 index 000000000..bda68df13 --- /dev/null +++ b/src/Makefile.d/util.mk @@ -0,0 +1,93 @@ +# +# Utility macros for the rest of the Makefiles. +# + +Ifnot=$(if $(1),$(3),$(2)) +Ifndef=$(call Ifnot,$($(1)),$(2),$(3)) + +# Match and expand a list of variables by pattern. +Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v))) + +# Read a list of words from file and prepend each with the +# directory of the file. +_cat=$(shell $(cat) $(call Windows_path,$(1))) +List=$(addprefix $(dir $(1)),$(call _cat,$(1))) + +# Convert path separators to backslash on Windows. +Windows_path=$(if $(WINDOWSHELL),$(subst /,\,$(1)),$(1)) + +define Propogate_flags = +opts+=$$($(1)_CFLAGS) +libs+=$$($(1)_LDFLAGS) +endef + +# Set library's _CFLAGS and _LDFLAGS from some command. +# Automatically propogates the flags too. +# 1: variable prefix (e.g. CURL) +# 2: start of command (e.g. curl-config) +# --- optional ---- +# 3: CFLAGS command arguments, default '--cflags' +# 4: LDFLAGS command arguments, default '--libs' +# 5: common command arguments at the end of command +define Configure = +$(1)_CFLAGS?=$$(shell $(2) $(or $(3),--cflags) $(5)) +$(1)_LDFLAGS?=$$(shell $(2) $(or $(4),--libs) $(5)) +$(call Propogate_flags,$(1)) +endef + +# Configure library with pkg-config. The package name is +# taken from a _PKGCONFIG variable. +# 1: variable prefix +# +# LIBGME_PKGCONFIG=libgme +# $(eval $(call Use_pkg_config,LIBGME)) +define Use_pkg_config = +$(call Configure,$(1),$(PKG_CONFIG),,,$($(1)_PKGCONFIG)) +endef + +# Check disabling flag and configure package in one step +# according to delimited argument. +# (There is only one argument, but it split by slash.) +# 1/: short form library name (uppercase). This is +# prefixed with 'NO' and 'HAVE_'. E.g. NOGME, HAVE_GME +# /2: package name (e.g. libgme) +# /3: variable prefix +# +# The following example would check if NOGME is not +# defined before attempting to define LIBGME_CFLAGS and +# LIBGME_LDFLAGS as with Use_pkg_config. +# +# $(eval $(call Check_pkg_config,GME/libgme/LIBGME)) +define Check_pkg_config = +_p:=$(subst /, ,$(1)) +_v1:=$$(word 1,$$(_p)) +_v2:=$$(or $$(word 3,$$(_p)),$$(_v1)) +ifndef NO$$(_v1) +$$(_v2)_PKGCONFIG?=$$(word 2,$$(_p)) +$$(eval $$(call Use_pkg_config,$$(_v2))) +opts+=-DHAVE_$$(_v1) +endif +endef + +# $(call Prefix,gcc) +Prefix=$(if $(PREFIX),$(PREFIX)-)$(1) + +Echo= +Echo_name= +Print= + +ifndef SILENT +Echo=@echo $(1) +ifndef ECHO +ifndef NOECHOFILENAMES +Echo_name=$(call Echo,-- $(1) ...) +endif +endif +ifndef MAKE_RESTARTS +ifndef destructive +Print=$(info $(1)) +endif +endif +endif + +.=$(call Ifndef,ECHO,@) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk new file mode 100644 index 000000000..7a021dda7 --- /dev/null +++ b/src/Makefile.d/versions.mk @@ -0,0 +1,181 @@ +# +# Flags to put a sock in GCC! +# + +# See the versions list in detect.mk +# This will define all version flags going backward. +# Yes, it's magic. +define _predecessor = +ifdef GCC$(firstword $(1)) +GCC$(lastword $(1)):=1 +endif +endef +_n:=$(words $(gcc_versions)) +$(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\ + $(addprefix =,$(wordlist 2,$(_n),$(gcc_versions)))),\ + $(and $(findstring =,$(v)),\ + $(eval $(call _predecessor,$(subst =, ,$(v)))))) + +# -W -Wno-unused +WFLAGS:=-Wall -Wno-trigraphs +ifndef GCC295 +#WFLAGS+=-Wno-packed +endif +ifndef RELAXWARNINGS + WFLAGS+=-W +#WFLAGS+=-Wno-sign-compare +ifndef GCC295 + WFLAGS+=-Wno-div-by-zero +endif +#WFLAGS+=-Wsystem-headers +WFLAGS+=-Wfloat-equal +#WFLAGS+=-Wtraditional + WFLAGS+=-Wundef +ifndef GCC295 + WFLAGS+=-Wendif-labels +endif +ifdef GCC40 + WFLAGS+=-std=gnu89 +endif +ifdef GCC41 + WFLAGS+=-Wdeclaration-after-statement + WFLAGS+=-Wno-error=declaration-after-statement + WFLAGS+=-Wshadow +endif +#WFLAGS+=-Wlarger-than-%len% + WFLAGS+=-Wpointer-arith -Wbad-function-cast +ifdef GCC45 +#WFLAGS+=-Wc++-compat +endif + WFLAGS+=-Wcast-qual +ifndef NOCASTALIGNWARN + WFLAGS+=-Wcast-align +endif + WFLAGS+=-Wwrite-strings +ifndef ERRORMODE +#WFLAGS+=-Wconversion +ifdef GCC43 + #WFLAGS+=-Wno-sign-conversion +endif +endif + WFLAGS+=-Wsign-compare +ifdef GCC91 + WFLAGS+=-Wno-error=address-of-packed-member +endif +ifdef GCC45 + WFLAGS+=-Wlogical-op +endif + WFLAGS+=-Waggregate-return +ifdef HAIKU +ifdef GCC41 + #WFLAGS+=-Wno-attributes +endif +endif +#WFLAGS+=-Wstrict-prototypes +ifdef GCC40 + WFLAGS+=-Wold-style-definition +endif + WFLAGS+=-Wmissing-prototypes -Wmissing-declarations +ifdef GCC40 + WFLAGS+=-Wmissing-field-initializers +endif + WFLAGS+=-Wmissing-noreturn +#WFLAGS+=-Wmissing-format-attribute +#WFLAGS+=-Wno-multichar +#WFLAGS+=-Wno-deprecated-declarations +#WFLAGS+=-Wpacked +#WFLAGS+=-Wpadded +#WFLAGS+=-Wredundant-decls + WFLAGS+=-Wnested-externs +#WFLAGS+=-Wunreachable-code + WFLAGS+=-Winline +ifdef GCC43 + WFLAGS+=-funit-at-a-time + WFLAGS+=-Wlogical-op +endif +ifndef GCC295 + WFLAGS+=-Wdisabled-optimization +endif +endif +WFLAGS+=-Wformat-y2k +ifdef GCC71 +WFLAGS+=-Wno-error=format-overflow=2 +endif +WFLAGS+=-Wformat-security +ifndef GCC29 +#WFLAGS+=-Winit-self +endif +ifdef GCC46 +WFLAGS+=-Wno-suggest-attribute=noreturn +endif + +ifdef NOLDWARNING +LDFLAGS+=-Wl,--as-needed +endif + +ifdef ERRORMODE +WFLAGS+=-Werror +endif + +ifdef GCC43 + #WFLAGS+=-Wno-error=clobbered +endif +ifdef GCC44 + WFLAGS+=-Wno-error=array-bounds +endif +ifdef GCC46 + WFLAGS+=-Wno-error=suggest-attribute=noreturn +endif +ifdef GCC54 + WFLAGS+=-Wno-logical-op -Wno-error=logical-op +endif +ifdef GCC61 + WFLAGS+=-Wno-tautological-compare -Wno-error=tautological-compare +endif +ifdef GCC71 + WFLAGS+=-Wimplicit-fallthrough=4 + WFLAGS+=-Wno-format-truncation +endif +ifdef GCC81 + WFLAGS+=-Wno-error=format-overflow + WFLAGS+=-Wno-error=stringop-truncation + WFLAGS+=-Wno-error=stringop-overflow + WFLAGS+=-Wno-format-overflow + WFLAGS+=-Wno-stringop-truncation + WFLAGS+=-Wno-stringop-overflow + WFLAGS+=-Wno-error=multistatement-macros +endif + +ifdef NONX86 + ifdef X86_64 # yeah that SEEMS contradictory + opts+=-march=nocona + endif +else + ifndef GCC29 + opts+=-msse3 -mfpmath=sse + else + opts+=-mpentium + endif +endif + +ifdef DEBUGMODE +ifdef GCC48 +opts+=-Og +else +opts+=O0 +endif +endif + +ifdef VALGRIND +ifdef GCC46 +WFLAGS+=-Wno-error=unused-but-set-variable +WFLAGS+=-Wno-unused-but-set-variable +endif +endif + +# Lua +ifdef GCC43 +ifndef GCC44 +WFLAGS+=-Wno-logical-op +endif +endif diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk new file mode 100644 index 000000000..ec66107d4 --- /dev/null +++ b/src/Makefile.d/win32.mk @@ -0,0 +1,117 @@ +# +# Mingw, if you don't know, that's Win32/Win64 +# + +ifndef MINGW64 +EXENAME?=srb2kart.exe +else +EXENAME?=srb2kart64.exe +endif + +sources+=win32/Srb2win.rc +opts+=-DSTDC_HEADERS +libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 + +nasm_format:=win32 + +SDL=1 + +ifndef NOHW +opts+=-DUSE_WGL_SWAP +endif + +ifdef MINGW64 +libs+=-lws2_32 +else +ifdef NO_IPV6 +libs+=-lwsock32 +else +libs+=-lws2_32 +endif +endif + +ifndef MINGW64 +opts+=-I../libs/drmingw/include +libs+=-L../libs/drmingw/lib/win32 -lmgwhelp -lexchndl +endif + +ifndef MINGW64 +libs+=-Wl,--large-address-aware +endif + +ifndef NONET +ifndef MINGW64 # miniupnc is broken with MINGW64 +opts+=-I../libs -DSTATIC_MINIUPNPC +libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi +endif +endif + +ifndef NO_DISCORDRPC +HAVE_DISCORDRPC=1 +endif + +ifndef MINGW64 +32=32 +x86=x86 +i686=i686 +else +32=64 +x86=x86_64 +i686=x86_64 +endif + +mingw:=$(i686)-w64-mingw32 + +define _set = +$(1)_CFLAGS?=$($(1)_opts) +$(1)_LDFLAGS?=$($(1)_libs) +endef + +lib:=../libs/gme +LIBGME_opts:=-I$(lib)/include +LIBGME_libs:=-L$(lib)/win$(32) -lgme +$(eval $(call _set,LIBGME)) + +lib:=../libs/libopenmpt +LIBOPENMPT_opts:=-I$(lib)/inc +LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt +$(eval $(call _set,LIBOPENMPT)) + +ifndef NOMIXERX +HAVE_MIXERX=1 +lib:=../libs/SDLMixerX/$(mingw) +else +lib:=../libs/SDL2_mixer/$(mingw) +endif + +mixer_opts:=-I$(lib)/include/SDL2 +mixer_libs:=-L$(lib)/lib + +lib:=../libs/SDL2/$(mingw) +SDL_opts:=-I$(lib)/include/SDL2\ + $(mixer_opts) -Dmain=SDL_main +SDL_libs:=-L$(lib)/lib $(mixer_libs)\ + -lmingw32 -lSDL2main -lSDL2 -mwindows +$(eval $(call _set,SDL)) + +lib:=../libs/zlib +ZLIB_opts:=-I$(lib) +ZLIB_libs:=-L$(lib)/win32 -lz$(32) +$(eval $(call _set,ZLIB)) + +ifndef PNG_CONFIG +lib:=../libs/libpng-src +PNG_opts:=-I$(lib) +PNG_libs:=-L$(lib)/projects -lpng$(32) +$(eval $(call _set,PNG)) +endif + +lib:=../libs/curl +CURL_opts:=-I$(lib)/include +CURL_libs:=-L$(lib)/lib$(32) -lcurl +$(eval $(call _set,CURL)) + +lib:=../libs/discord-rpc/win$(32)-dynamic +DISCORDRPC_opts:=-I$(lib)/include +DISCORDRPC_libs:=-L$(lib)/lib +$(eval $(call _set,DISCORDRPC)) diff --git a/src/Sourcefile b/src/Sourcefile new file mode 100644 index 000000000..384af8da7 --- /dev/null +++ b/src/Sourcefile @@ -0,0 +1,112 @@ +string.c +d_main.c +d_clisrv.c +d_net.c +d_netfil.c +d_netcmd.c +dehacked.c +deh_soc.c +deh_lua.c +deh_tables.c +z_zone.c +f_finale.c +f_wipe.c +g_demo.c +g_game.c +g_input.c +g_splitscreen.c +am_map.c +command.c +console.c +font.c +hu_stuff.c +y_inter.c +st_stuff.c +m_aatree.c +m_anigif.c +m_argv.c +m_bbox.c +m_cheat.c +m_cond.c +m_fixed.c +m_menu.c +m_misc.c +m_perfstats.c +m_random.c +m_queue.c +info.c +p_ceilng.c +p_enemy.c +p_floor.c +p_inter.c +p_lights.c +p_map.c +p_maputl.c +p_mobj.c +p_polyobj.c +p_saveg.c +p_setup.c +p_sight.c +p_spec.c +p_telept.c +p_tick.c +p_user.c +p_slopes.c +tables.c +r_bsp.c +r_data.c +r_draw.c +r_main.c +r_plane.c +r_segs.c +r_skins.c +r_sky.c +r_splats.c +r_things.c +r_textures.c +r_patch.c +r_patchrotation.c +r_picformats.c +r_portal.c +screen.c +taglist.c +v_video.c +s_sound.c +sounds.c +w_wad.c +filesrch.c +mserv.c +http-mserv.c +i_tcp.c +lzf.c +vid_copy.s +lua_script.c +lua_baselib.c +lua_mathlib.c +lua_hooklib.c +lua_consolelib.c +lua_infolib.c +lua_mobjlib.c +lua_playerlib.c +lua_skinlib.c +lua_thinkerlib.c +lua_maplib.c +lua_taglib.c +lua_polyobjlib.c +lua_blockmaplib.c +lua_hudlib.c +k_kart.c +k_respawn.c +k_collide.c +k_color.c +k_race.c +k_battle.c +k_pwrlv.c +k_waypoint.c +k_pathfind.c +k_bheap.c +k_bot.c +k_botitem.c +k_botsearch.c +k_grandprix.c +k_hud.c diff --git a/src/blua/CMakeLists.txt b/src/blua/CMakeLists.txt new file mode 100644 index 000000000..4e9c67d2f --- /dev/null +++ b/src/blua/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(c) diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg deleted file mode 100644 index 3a2962e65..000000000 --- a/src/blua/Makefile.cfg +++ /dev/null @@ -1,53 +0,0 @@ -ifdef UNIXCOMMON -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef LINUX -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef GCC43 -ifndef GCC44 -WFLAGS+=-Wno-logical-op -endif -endif - -OBJS:=$(OBJS) \ - $(OBJDIR)/lapi.o \ - $(OBJDIR)/lbaselib.o \ - $(OBJDIR)/ldo.o \ - $(OBJDIR)/lfunc.o \ - $(OBJDIR)/linit.o \ - $(OBJDIR)/liolib.o \ - $(OBJDIR)/llex.o \ - $(OBJDIR)/lmem.o \ - $(OBJDIR)/lobject.o \ - $(OBJDIR)/lstate.o \ - $(OBJDIR)/lstrlib.o \ - $(OBJDIR)/ltablib.o \ - $(OBJDIR)/lundump.o \ - $(OBJDIR)/lzio.o \ - $(OBJDIR)/lauxlib.o \ - $(OBJDIR)/lcode.o \ - $(OBJDIR)/ldebug.o \ - $(OBJDIR)/ldump.o \ - $(OBJDIR)/lgc.o \ - $(OBJDIR)/lopcodes.o \ - $(OBJDIR)/lparser.o \ - $(OBJDIR)/lstring.o \ - $(OBJDIR)/ltable.o \ - $(OBJDIR)/ltm.o \ - $(OBJDIR)/lvm.o \ - $(OBJDIR)/lua_script.o \ - $(OBJDIR)/lua_baselib.o \ - $(OBJDIR)/lua_mathlib.o \ - $(OBJDIR)/lua_hooklib.o \ - $(OBJDIR)/lua_consolelib.o \ - $(OBJDIR)/lua_infolib.o \ - $(OBJDIR)/lua_mobjlib.o \ - $(OBJDIR)/lua_playerlib.o \ - $(OBJDIR)/lua_skinlib.o \ - $(OBJDIR)/lua_thinkerlib.o \ - $(OBJDIR)/lua_maplib.o \ - $(OBJDIR)/lua_taglib.o \ - $(OBJDIR)/lua_polyobjlib.o \ - $(OBJDIR)/lua_blockmaplib.o \ - $(OBJDIR)/lua_hudlib.o diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile new file mode 100644 index 000000000..f99c89c8d --- /dev/null +++ b/src/blua/Sourcefile @@ -0,0 +1,25 @@ +lapi.c +lbaselib.c +ldo.c +lfunc.c +linit.c +liolib.c +llex.c +lmem.c +lobject.c +lstate.c +lstrlib.c +ltablib.c +lundump.c +lzio.c +lauxlib.c +lcode.c +ldebug.c +ldump.c +lgc.c +lopcodes.c +lparser.c +lstring.c +ltable.c +ltm.c +lvm.c diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 377bc8740..5b4141328 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1051,15 +1051,6 @@ static void SV_SendPlayerInfo(INT32 node) // Extra data netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor; - - if (players[i].pflags & PF_TAGIT) - netbuffer->u.playerinfo[i].data |= 0x20; - - if (players[i].gotflag) - netbuffer->u.playerinfo[i].data |= 0x40; - - if (players[i].powers[pw_super]) - netbuffer->u.playerinfo[i].data |= 0x80; } HSendPacket(node, false, 0, sizeof(plrinfo) * MSCOMPAT_MAXPLAYERS); @@ -1347,7 +1338,7 @@ static void CL_ReloadReceivedSavegame(void) neededtic = gametic; maketic = neededtic; - for (i = 0; i <= splitscreen; i++) + for (i = 0; i <= r_splitscreen; i++) { P_ForceLocalAngle(&players[displayplayers[i]], players[displayplayers[i]].angleturn); } @@ -2384,7 +2375,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting // don't look through someone's view who isn't there - if (playernum == displayplayers[0]) + if (playernum == displayplayers[0] && !demo.playback) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. @@ -2413,9 +2404,6 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) RemoveAdminPlayer(playernum); // don't stay admin after you're gone } - if (playernum == displayplayers[0] && !demo.playback) - displayplayers[0] = consoleplayer; // don't look through someone's view who isn't there - LUA_InvalidatePlayer(&players[playernum]); K_CheckBumpers(); @@ -4790,7 +4778,7 @@ static INT16 Consistancy(void) { ret += players[i].mo->x; ret -= players[i].mo->y; - ret += players[i].kartstuff[k_itemtype]; // powers[pw_shield] + ret += players[i].itemtype; ret *= i+1; } } diff --git a/src/d_main.c b/src/d_main.c index 57dcdefea..5ded2bf14 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -615,16 +615,6 @@ static void D_Display(void) { F_WipeEndScreen(); - // Funny. - if (WipeStageTitle && st_overlay) - { - lt_ticker--; - lt_lasttic = lt_ticker; - ST_preLevelTitleCardDrawer(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - F_WipeStartScreen(); - } - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN, "FADEMAP0", true, false); } @@ -1057,15 +1047,6 @@ static void IdentifyVersion(void) D_AddFile(startupiwads, va(pandf,srb2waddir,"patch.pk3")); #endif -#if 0 - // TODO: pk3 doesn't support music replacement IIRC - // music barely benefits from the compression anyway - // would be nice for the folders, though - D_AddFile(startupiwads, va(pandf,srb2waddir,"sounds.pk3")); - D_AddFile(startupiwads, va(pandf,srb2waddir,"music.pk3")); - -#else - #if !defined (HAVE_SDL) || defined (HAVE_MIXER) #define MUSICTEST(str) \ @@ -1078,12 +1059,11 @@ static void IdentifyVersion(void) I_Error("File "str" has been modified with non-music/sound lumps"); \ } - MUSICTEST("sounds.wad") + MUSICTEST("sounds.pk3") MUSICTEST("music.pk3") #undef MUSICTEST -#endif #endif } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 70ebde1fb..4ed110f35 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1006,7 +1006,6 @@ void D_RegisterClientCommands(void) // add cheat commands COM_AddCommand("noclip", Command_CheatNoClip_f); COM_AddCommand("god", Command_CheatGod_f); - COM_AddCommand("notarget", Command_CheatNoTarget_f); COM_AddCommand("setrings", Command_Setrings_f); COM_AddCommand("setlives", Command_Setlives_f); COM_AddCommand("devmode", Command_Devmode_f); @@ -1418,7 +1417,7 @@ static void SendNameAndColor(UINT8 n) player->skincolor = cv_playercolor[n].value; - if (player->mo && !player->powers[pw_dye]) + if (player->mo && !player->dye) player->mo->color = player->skincolor; // Update follower for local games: @@ -1879,7 +1878,7 @@ static INT32 FindPlayerByPlace(INT32 place) for (playernum = 0; playernum < MAXPLAYERS; ++playernum) if (playeringame[playernum]) { - if (players[playernum].kartstuff[k_position] == place) + if (players[playernum].position == place) { return playernum; } @@ -1903,7 +1902,7 @@ static void GetViewablePlayerPlaceRange(INT32 *first, INT32 *last) for (i = 0; i < MAXPLAYERS; ++i) if (G_CouldView(i)) { - place = players[i].kartstuff[k_position]; + place = players[i].position; if (place < (*first)) (*first) = place; if (place > (*last)) @@ -2974,7 +2973,7 @@ static void Command_Respawn(void) } // todo: this probably isnt necessary anymore with v2 - if (players[consoleplayer].mo && (P_PlayerInPain(&players[consoleplayer]) || spbplace == players[consoleplayer].kartstuff[k_position])) // KART: Nice try, but no, you won't be cheesing spb anymore (x2) + if (players[consoleplayer].mo && (P_PlayerInPain(&players[consoleplayer]) || spbplace == players[consoleplayer].position)) // KART: Nice try, but no, you won't be cheesing spb anymore (x2) { CONS_Printf(M_GetText("Nice try.\n")); return; @@ -2989,7 +2988,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum) INT32 respawnplayer = READINT32(*cp); // You can't respawn someone else. Nice try, there. - if (respawnplayer != playernum || P_PlayerInPain(&players[respawnplayer]) || spbplace == players[respawnplayer].kartstuff[k_position]) // srb2kart: "|| (!(gametyperules & GTR_CIRCUIT))" + if (respawnplayer != playernum || P_PlayerInPain(&players[respawnplayer]) || spbplace == players[respawnplayer].position) // srb2kart: "|| (!(gametyperules & GTR_CIRCUIT))" { CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]); if (server) @@ -3144,7 +3143,7 @@ static void HandleTeamChangeCommand(UINT8 localplayer) if (players[g_localplayers[localplayer]].spectator) error = !(NetPacket.packet.newteam || (players[g_localplayers[localplayer]].pflags & PF_WANTSTOJOIN)); // :lancer: else if (G_GametypeHasTeams()) - error = (NetPacket.packet.newteam == (unsigned)players[g_localplayers[localplayer]].ctfteam); + error = (NetPacket.packet.newteam == players[g_localplayers[localplayer]].ctfteam); else if (G_GametypeHasSpectators() && !players[g_localplayers[localplayer]].spectator) error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA @@ -3260,7 +3259,7 @@ static void Command_ServerTeamChange_f(void) if (G_GametypeHasTeams()) { - if (NetPacket.packet.newteam == (unsigned)players[NetPacket.packet.playernum].ctfteam || + if (NetPacket.packet.newteam == players[NetPacket.packet.playernum].ctfteam || (players[NetPacket.packet.playernum].spectator && !NetPacket.packet.newteam)) error = true; } @@ -3437,7 +3436,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) displayplayers[0] = consoleplayer; } - if (G_GametypeHasTeams()) + /*if (G_GametypeHasTeams()) { if (NetPacket.packet.newteam) { @@ -3445,10 +3444,10 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) for (i = 0; i <= splitscreen; i++) { if (playernum == g_localplayers[i]) //CTF and Team Match colors. - CV_SetValue(&cv_playercolor[i], NetPacket.packet.newteam + 5); + CV_SetValue(&cv_playercolor[i], NetPacket.packet.newteam + 5); - -this calculation is totally wrong } } - } + }*/ if (gamestate != GS_LEVEL) return; @@ -3460,7 +3459,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) { if (gametyperules & GTR_BUMPERS) // SRB2kart { - players[playernum].marescore = 0; + players[playernum].roundscore = 0; K_CalculateBattleWanted(); } @@ -4861,8 +4860,6 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) int item; int amt; - INT32 *kartstuff; - item = READSINT8 (*cp); amt = READUINT8 (*cp); @@ -4879,10 +4876,8 @@ static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) return; } - kartstuff = players[playernum].kartstuff; - - kartstuff[k_itemtype] = item; - kartstuff[k_itemamount] = amt; + players[playernum].itemtype = item; + players[playernum].itemamount = amt; } /** Prints the number of displayplayers[0]. diff --git a/src/d_netfil.c b/src/d_netfil.c index d3058681b..5714c39cd 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1299,16 +1299,18 @@ void PT_FileFragment(void) filename = va("%s", file->filename); nameonly(filename); - if (!(strcmp(filename, "main.kart") - && strcmp(filename, "gfx.pk3") - && strcmp(filename, "textures.pk3") - && strcmp(filename, "chars.pk3") - && strcmp(filename, "maps.wad") - && strcmp(filename, "patch.pk3") - && strcmp(filename, "sounds.wad") - && strcmp(filename, "music.wad") - )) + if (!strcmp(filename, "main.kart") + || !strcmp(filename, "gfx.pk3") + || !strcmp(filename, "textures.pk3") + || !strcmp(filename, "chars.pk3") + || !strcmp(filename, "maps.pk3") + || !strcmp(filename, "patch.pk3") + || !strcmp(filename, "sounds.pk3") + || !strcmp(filename, "music.pk3") + ) + { I_Error("Tried to download \"%s\"", filename); + } filename = file->filename; diff --git a/src/d_player.h b/src/d_player.h index a245bf096..f5808a166 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -58,54 +58,48 @@ typedef enum // typedef enum { - PF_FAULT = 1, - - // Cheats - PF_GODMODE = 1<<4, - PF_NOCLIP = 1<<5, - PF_INVIS = 1<<6, - // True if button down last tic. - PF_ATTACKDOWN = 1<<7, - PF_ACCELDOWN = 1<<8, - PF_BRAKEDOWN = 1<<9, - PF_WPNDOWN = 1<<10, // unused + PF_ATTACKDOWN = 1, + PF_ACCELDOWN = 1<<1, + PF_BRAKEDOWN = 1<<2, + PF_LOOKDOWN = 1<<3, - // Unmoving states - PF_STASIS = 1<<11, // Player is not allowed to move - PF_JUMPSTASIS = 1<<12, // unused + // Accessibility and cheats + PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode? + PF_GODMODE = 1<<5, + PF_NOCLIP = 1<<6, - // SRB2Kart: Spectator that wants to join - PF_WANTSTOJOIN = 1<<13, + PF_WANTSTOJOIN = 1<<7, // Spectator that wants to join - // Character action status - PF_STARTJUMP = 1<<14, // unused - PF_JUMPED = 1<<15, // unused - PF_NOJUMPDAMAGE = 1<<16, // unused - PF_SPINNING = 1<<17, // unused - PF_STARTDASH = 1<<18, // unused - PF_THOKKED = 1<<19, // unused - PF_SHIELDABILITY = 1<<20, // unused - PF_GLIDING = 1<<21, // unused - PF_BOUNCING = 1<<22, // unused + PF_STASIS = 1<<8, // Player is not allowed to move + PF_FAULT = 1<<9, // F A U L T + PF_ELIMINATED = 1<<10, // Battle-style elimination, no extra penalty + PF_NOCONTEST = 1<<11, // Did not finish (last place explosion) + PF_LOSTLIFE = 1<<12, // Do not lose life more than once - // Sliding (usually in water) like Labyrinth/Oil Ocean - PF_SLIDING = 1<<23, + PF_RINGLOCK = 1<<13, // Prevent picking up rings while SPB is locked on - // NiGHTS stuff - PF_TRANSFERTOCLOSEST = 1<<24, // unused - PF_DRILLING = 1<<25, // unused + // The following four flags are mutually exclusive, although they can also all be off at the same time. If we ever run out of pflags, eventually turn them into a seperate five(+) mode UINT8..? + PF_USERINGS = 1<<14, // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness + PF_ITEMOUT = 1<<15, // Are you holding an item out? + PF_EGGMANOUT = 1<<16, // Eggman mark held, separate from PF_ITEMOUT so it doesn't stop you from getting items + PF_HOLDREADY = 1<<17, // Hold button-style item is ready to activate - // Gametype-specific stuff - PF_GAMETYPEOVER = 1<<26, // Race time over - PF_TAGIT = 1<<27, // unused + PF_DRIFTINPUT = 1<<18, // Drifting! + PF_GETSPARKS = 1<<19, // Can get sparks + PF_DRIFTEND = 1<<20, // Drift has ended, used to adjust character angle after drift + PF_BRAKEDRIFT = 1<<21, // Helper for brake-drift spark spawning - /*** misc ***/ - PF_KICKSTARTACCEL = 1<<28, // Accessibility feature - is accelerate in kickstart mode? - PF_CANCARRY = 1<<29, // unused - PF_HITFINISHLINE = 1<<30, // Already hit the finish line this tic + PF_AIRFAILSAFE = 1<<22, // Whenever or not try the air boost + PF_TRICKDELAY = 1<<23, // Prevent tricks until control stick is neutral - // up to 1<<31 is free, but try to hit unused stuff first + PF_TUMBLELASTBOUNCE = 1<<24, // One more time for the funny + PF_TUMBLESOUND = 1<<25, // Don't play more than once + + PF_HITFINISHLINE = 1<<26, // Already hit the finish line this tic + PF_WRONGWAY = 1<<27, // Moving the wrong way with respect to waypoints? + + // up to 1<<31 is free } pflags_t; typedef enum @@ -119,104 +113,13 @@ typedef enum PA_HURT } panim_t; -// -// All of the base srb2 shields are either a single constant, -// or use damagetype-protecting flags applied to a constant, -// or are the force shield (which does everything weirdly). -// -// Base flags by themselves aren't used so modders can make -// abstract, ability-less shields should they so choose. -// -typedef enum -{ - SH_NONE = 0, - - // Shield flags - SH_PROTECTFIRE = 0x400, - SH_PROTECTWATER = 0x800, - SH_PROTECTELECTRIC = 0x1000, - SH_PROTECTSPIKE = 0x2000, // cactus shield one day? thanks, subarashii - //SH_PROTECTNUKE = 0x4000, // intentionally no hardcoded defense against nukes - - // Indivisible shields - SH_PITY = 1, // the world's most basic shield ever, given to players who suck at Match - SH_WHIRLWIND, - SH_ARMAGEDDON, - SH_PINK, // PITY IN PINK! - - // Normal shields that use flags - SH_ATTRACT = SH_PITY|SH_PROTECTELECTRIC, - SH_ELEMENTAL = SH_PITY|SH_PROTECTFIRE|SH_PROTECTWATER, - - // Sonic 3 shields - SH_FLAMEAURA = SH_PITY|SH_PROTECTFIRE, - SH_BUBBLEWRAP = SH_PITY|SH_PROTECTWATER, - SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC, - - // The force shield uses the lower 8 bits to count how many extra hits are left. - SH_FORCE = 0x100, - SH_FORCEHP = 0xFF, // to be used as a bitmask only - - // Mostly for use with Mario mode. - SH_FIREFLOWER = 0x200, - - SH_STACK = SH_FIREFLOWER, // second-layer shields - SH_NOSTACK = ~SH_STACK -} shieldtype_t; // pw_shield - typedef enum { CR_NONE = 0, // Specific level gimmicks. + CR_SLIDING, CR_ZOOMTUBE, -} carrytype_t; // pw_carry - -// Player powers. (don't edit this comment) -typedef enum -{ - pw_invulnerability, - pw_sneakers, - pw_flashing, - pw_shield, - pw_carry, - pw_tailsfly, // tails flying - pw_underwater, // underwater timer - pw_spacetime, // In space, no one can hear you spin! - pw_extralife, // Extra Life timer - pw_pushing, - pw_justsprung, - pw_noautobrake, - - pw_super, // Are you super? - pw_gravityboots, // gravity boots - - // Weapon ammunition - pw_infinityring, - pw_automaticring, - pw_bouncering, - pw_scatterring, - pw_grenadering, - pw_explosionring, - pw_railring, - - // Power Stones - pw_emeralds, // stored like global 'emeralds' variable - - // NiGHTS powerups - pw_nights_superloop, - pw_nights_helper, - pw_nights_linkfreeze, - - pw_nocontrol, //for linedef exec 427 - - pw_dye, // for dyes - - pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch) - - pw_ignorelatch, // Don't grab onto CR_GENERIC, add 32768 (powers[pw_ignorelatch] & 1<<15) to avoid ALL not-NiGHTS CR_ types - - NUMPOWERS -} powertype_t; +} carrytype_t; // carry /* To use: #define FOREACH( name, number ) @@ -295,109 +198,12 @@ typedef enum #undef KSPIN_TYPE } kartspinoutflags_t; -//{ SRB2kart - kartstuff typedef enum { - // TODO: Kill this giant array. Add them as actual player_t variables, or condense related timers into their own, smaller arrays. - // Basic gameplay things - k_position, // Used for Kart positions, mostly for deterministic stuff - k_oldposition, // Used for taunting when you pass someone - k_positiondelay, // Used for position number, so it can grow when passing/being passed - - k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir") - k_instashield, // Instashield no-damage animation timer - - k_floorboost, // Prevents Sneaker sounds for a breif duration when triggered by a floor panel - k_spinouttype, // Determines the mode of spinout/wipeout, see kartspinoutflags_t - - k_drift, // Drifting Left or Right, plus a bigger counter = sharper turn - k_driftend, // Drift has ended, used to adjust character angle after drift - k_driftcharge, // Charge your drift so you can release a burst of speed - k_driftboost, // Boost you get from drifting - k_boostcharge, // Charge-up for boosting at the start of the race - k_startboost, // Boost you get from start of race or respawn drop dash - k_rings, // Number of held rings - k_pickuprings, // Number of rings being picked up before added to the counter (prevents rings from being deleted forever over 20) - k_userings, // Have to be not holding the item button to change from using rings to using items (or vice versa), to prevent some weirdness with the button - k_ringdelay, // 3 tic delay between every ring usage - k_ringboost, // Ring boost timer - k_ringlock, // Prevent picking up rings while SPB is locked on - k_sparkleanim, // Angle offset for ring sparkle animation - k_jmp, // In Mario Kart, letting go of the jump button stops the drift - k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed - k_brakestop, // Wait until you've made a complete stop for a few tics before letting brake go in reverse. - k_spindash, // Spindash charge timer - k_spindashspeed, // Spindash release speed - k_spindashboost, // Spindash release boost timer - k_waterskip, // Water skipping counter - k_dashpadcooldown, // Separate the vanilla SA-style dash pads from using pw_flashing - k_numboosts, // Count of how many boosts are being stacked, for after image spawning - k_boostpower, // Base boost value, for offroad - k_speedboost, // Boost value smoothing for max speed - k_accelboost, // Boost value smoothing for acceleration - k_handleboost, // Boost value smoothing for handling - k_draftpower, // Drafting power (from 0 to FRACUNIT), doubles your top speed & acceleration at max - k_draftleeway, // Leniency timer before removing draft power - k_lastdraft, // Last player being drafted - k_boostangle, // angle set when not spun out OR boosted to determine what direction you should keep going at if you're spun out and boosted. - k_aizdriftstrat, // Let go of your drift while boosting? Helper for the SICK STRATZ you have just unlocked - k_brakedrift, // Helper for brake-drift spark spawning - - k_itemroulette, // Used for the roulette when deciding what item to give you (was "pw_kartitem") - k_roulettetype, // Used for the roulette, for deciding type (currently only used for Battle, to give you better items from Karma items) - - // Item held stuff - k_itemtype, // KITEM_ constant for item number - k_itemamount, // Amount of said item - k_itemheld, // Are you holding an item? - k_holdready, // Hold button-style item is ready to activate - - // Some items use timers for their duration or effects - k_curshield, // 0 = no shield, 1 = thunder shield - k_hyudorotimer, // Duration of the Hyudoro offroad effect itself - k_stealingtimer, // You are stealing an item, this is your timer - k_stolentimer, // You are being stolen from, this is your timer - k_superring, // Spawn rings on top of you every tic! - k_sneakertimer, // Duration of a Sneaker Boost (from Sneakers or level boosters) - k_numsneakers, // Number of stacked sneaker effects - k_growshrinktimer, // > 0 = Big, < 0 = small - k_squishedtimer, // Squished frame timer - k_rocketsneakertimer, // Rocket Sneaker duration timer - k_invincibilitytimer, // Invincibility timer - k_bubblecool, // Bubble Shield use cooldown - k_bubbleblowup, // Bubble Shield usage blowup - k_flamedash, // Flame Shield dash power - k_flamemeter, // Flame Shield dash meter left - k_flamelength, // Flame Shield dash meter, number of segments - k_eggmanheld, // Eggman monitor held, separate from k_itemheld so it doesn't stop you from getting items - k_eggmanexplode, // Fake item recieved, explode in a few seconds - k_eggmanblame, // Fake item recieved, who set this fake - k_lastjawztarget, // Last person you target with jawz, for playing the target switch sfx - k_bananadrag, // After a second of holding a banana behind you, you start to slow down - k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam") - k_wipeoutslow, // Timer before you slowdown when getting wiped out - k_justbumped, // Prevent players from endlessly bumping into each other - k_comebacktimer, // Battle mode, how long before you become a bomb after death - k_sadtimer, // How long you've been sad - - // Battle Mode vars - k_bumper, // Number of bumpers left - k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a bumper - k_comebackmode, // 0 = bomb, 1 = item - k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo - - // v1.0.2+ vars - 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_tiregrease, // Reduced friction timer after hitting a horizontal spring - k_springstars, // Spawn stars around a player when they hit a spring - k_springcolor, // Color of spring stars - k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper - k_wrongway, // Display WRONG WAY on screen - - NUMKARTSTUFF -} kartstufftype_t; + TRIP_NONE, + TRIP_PASSED, + TRIP_BLOCKED, +} tripwirestate_t; typedef enum { @@ -433,15 +239,19 @@ typedef enum khud_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics khud_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly + // Tricks + khud_trickcool, + NUMKARTHUD } karthudtype_t; // QUICKLY GET RING TOTAL, INCLUDING RINGS CURRENTLY IN THE PICKUP ANIMATION -#define RINGTOTAL(p) (p->rings + p->kartstuff[k_pickuprings]) +#define RINGTOTAL(p) (p->rings + p->pickuprings) // CONSTANTS FOR TRICK PANELS #define TRICKMOMZRAMP (30) #define TRICKLAG (9) +#define TRICKDELAY (TICRATE/4) #define TUMBLEBOUNCES 3 @@ -453,13 +263,14 @@ typedef enum // player_t struct for all respawn variables typedef struct respawnvars_s { - UINT8 state; // 0: not respawning, 1: heading towards respawn point, 2: about to drop + UINT8 state; // see RESPAWNST_ constants in k_respawn.h waypoint_t *wp; // Waypoint that we're going towards, NULL if the position isn't linked to one fixed_t pointx; // Respawn position coords to go towards fixed_t pointy; fixed_t pointz; boolean flip; // Flip upside down or not tic_t timer; // Time left on respawn animation once you're there + tic_t airtimer; // Time spent in the air before respawning UINT32 distanceleft; // How far along the course to respawn you tic_t dropdash; // Drop Dash charge timer } respawnvars_t; @@ -475,6 +286,8 @@ typedef struct botvars_s tic_t itemconfirm; // When high enough, they will use their item SINT8 turnconfirm; // Confirm turn direction + + tic_t spindashconfirm; // When high enough, they will try spindashing } botvars_t; // ======================================================================== @@ -513,37 +326,6 @@ typedef struct player_s // fun thing for player sprite angle_t drawangle; - // player's ring count - INT16 rings; - INT16 spheres; - - // Power ups. invinc and invis are tic counters. - UINT16 powers[NUMPOWERS]; - - // SRB2kart stuff - INT32 kartstuff[NUMKARTSTUFF]; - INT32 karthud[NUMKARTHUD]; - - UINT32 distancetofinish; - waypoint_t *nextwaypoint; - respawnvars_t respawn; // Respawn info - tic_t airtime; // Keep track of how long you've been in the air - boolean driftInput; // Whenever or not try drifting. - boolean airFailsafe; // Whenever or not try the air boost - INT32 aizDriftTilt; - INT32 aizDriftTurn; - - UINT8 trickpanel; // Trick panel state - boolean trickdelay; // Prevent tricks until control stick is neutral - fixed_t trickmomx; - fixed_t trickmomy; - fixed_t trickmomz; // Instead of stupid auxiliary variables let's... just make some ourselves. - - UINT8 bumpers; - INT16 karmadelay; - boolean eliminated; - - // Bit flags. // See pflags_t, above. pflags_t pflags; @@ -561,10 +343,6 @@ typedef struct player_s INT32 skin; UINT32 availabilities; - UINT32 score; // player score - fixed_t dashspeed; // dashing speed - - // SRB2kart UINT8 kartspeed; // Kart speed stat between 1 and 9 UINT8 kartweight; // Kart weight stat between 1 and 9 @@ -573,45 +351,147 @@ typedef struct player_s UINT16 followercolor; // Kart: Used to store the follower colour the player wishes to use mobj_t *follower; // Kart: This is the follower object we have. (If any) - UINT8 tumbleBounces; - UINT16 tumbleHeight; - boolean tumbleLastBounce; - boolean tumbleSound; - - SINT8 glanceDir; // Direction the player is trying to look backwards in - - // - UINT32 charflags; // Extra abilities/settings for skins (combinable stuff) // See SF_ flags mobjtype_t followitem; // Object # to spawn for Smiles mobj_t *followmobj; // Smiles all around + UINT32 score; // player score + + UINT16 nocontrol; //for linedef exec 427 + UINT8 carry; + UINT16 dye; + + // SRB2kart stuff + INT32 karthud[NUMKARTHUD]; + + // Basic gameplay things + UINT8 position; // Used for Kart positions, mostly for deterministic stuff + UINT8 oldposition; // Used for taunting when you pass someone + UINT8 positiondelay; // Used for position number, so it can grow when passing/being passed + UINT32 distancetofinish; + waypoint_t *nextwaypoint; + respawnvars_t respawn; // Respawn info + tic_t airtime; // Keep track of how long you've been in the air + UINT8 startboost; // (0 to 125) - Boost you get from start of race or respawn drop dash + + UINT16 flashing; + UINT16 spinouttimer; // Spin-out from a banana peel or oil slick (was "pw_bananacam") + UINT8 spinouttype; // Determines the mode of spinout/wipeout, see kartspinoutflags_t + UINT8 instashield; // Instashield no-damage animation timer + UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out + UINT8 justbumped; // Prevent players from endlessly bumping into each other + UINT8 tumbleBounces; + UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu + + SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn + fixed_t driftcharge; // Charge your drift so you can release a burst of speed + UINT8 driftboost; // (0 to 125) - Boost you get from drifting + UINT8 strongdriftboost; // (0 to 125) - While active, boost from drifting gives a stronger speed increase + + SINT8 aizdriftstrat; // (-1 to 1) - Let go of your drift while boosting? Helper for the SICK STRATZ (sliptiding!) you have just unlocked + INT32 aizdrifttilt; + INT32 aizdriftturn; + + fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed + UINT8 waterskip; // Water skipping counter + + UINT16 tiregrease; // Reduced friction timer after hitting a spring + UINT16 springstars; // Spawn stars around a player when they hit a spring + UINT16 springcolor; // Color of spring stars + UINT8 dashpadcooldown; // Separate the vanilla SA-style dash pads from using flashing + + UINT16 spindash; // Spindash charge timer + fixed_t spindashspeed; // Spindash release speed + UINT8 spindashboost; // Spindash release boost timer + + UINT8 numboosts; // Count of how many boosts are being stacked, for after image spawning + fixed_t boostpower; // Base boost value, for offroad + fixed_t speedboost; // Boost value smoothing for max speed + fixed_t accelboost; // Boost value smoothing for acceleration + fixed_t handleboost; // Boost value smoothing for handling + angle_t boostangle; // angle set when not spun out OR boosted to determine what direction you should keep going at if you're spun out and boosted. + + fixed_t draftpower; // (0 to FRACUNIT) - Drafting power, doubles your top speed & acceleration at max + UINT16 draftleeway; // Leniency timer before removing draft power + SINT8 lastdraft; // (-1 to 15) - Last player being drafted + + UINT16 itemroulette; // Used for the roulette when deciding what item to give you (was "pw_kartitem") + UINT8 roulettetype; // Used for the roulette, for deciding type (0 = normal, 1 = better, 2 = eggman mark) + + // Item held stuff + SINT8 itemtype; // KITEM_ constant for item number + UINT8 itemamount; // Amount of said item + SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir") + + UINT8 sadtimer; // How long you've been sad + + // player's ring count + SINT8 rings; + UINT8 pickuprings; // Number of rings being picked up before added to the counter (prevents rings from being deleted forever over 20) + UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage + UINT16 ringboost; // Ring boost timer + UINT8 sparkleanim; // (0 to 19) - Angle offset for ring sparkle animation + UINT16 superring; // Spawn rings on top of you every tic! + + UINT8 curshield; // see kartshields_t + UINT8 bubblecool; // Bubble Shield use cooldown + UINT8 bubbleblowup; // Bubble Shield usage blowup + UINT16 flamedash; // Flame Shield dash power + UINT16 flamemeter; // Flame Shield dash meter left + UINT8 flamelength; // Flame Shield dash meter, number of segments + + UINT16 hyudorotimer; // Duration of the Hyudoro offroad effect itself + SINT8 stealingtimer; // if >0 you are stealing, if <0 you are being stolen from + + UINT16 sneakertimer; // Duration of a Sneaker Boost (from Sneakers or level boosters) + UINT8 numsneakers; // Number of stacked sneaker effects + UINT8 floorboost; // (0 to 3) - Prevents Sneaker sounds for a brief duration when triggered by a floor panel + + INT16 growshrinktimer; // > 0 = Big, < 0 = small + UINT16 rocketsneakertimer; // Rocket Sneaker duration timer + UINT16 invincibilitytimer; // Invincibility timer + + UINT8 eggmanexplode; // Fake item recieved, explode in a few seconds + SINT8 eggmanblame; // (-1 to 15) - Fake item recieved, who set this fake + + UINT8 bananadrag; // After a second of holding a banana behind you, you start to slow down + + SINT8 lastjawztarget; // (-1 to 15) - Last person you target with jawz, for playing the target switch sfx + UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy + + UINT8 trickpanel; // Trick panel state + UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold + fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks. + UINT8 trickboostdecay; // used to know how long you've waited + UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god. + + + UINT32 roundscore; // battle score this round + UINT8 emeralds; + UINT8 bumpers; + INT16 karmadelay; + tic_t overtimekarma; // time to live in overtime comeback + INT16 spheres; + + SINT8 glanceDir; // Direction the player is trying to look backwards in + + UINT8 tripWireState; // see tripwirestate_t + + // + SINT8 lives; - boolean lostlife; - SINT8 continues; // continues that player has acquired SINT8 xtralife; // Ring Extra Life counter - UINT8 gotcontinue; // Got continue from this stage? fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values) fixed_t lastspeed; fixed_t lastmomz; - UINT8 secondjump; // Jump counter - UINT8 fly1; // Tails flying - UINT8 scoreadd; // Used for multiple enemy attack bonus - tic_t glidetime; // Glide counter for thrust - UINT8 climbing; // Climbing on the wall INT32 deadtimer; // End game if game over lasts too long tic_t exiting; // Exitlevel timer - UINT8 homing; // Are you homing? - tic_t dashmode; // counter for dashmode ability - - tic_t skidtime; // Skid timer - //////////////////////////// // Conveyor Belt Movement // //////////////////////////// @@ -620,73 +500,18 @@ typedef struct player_s fixed_t rmomx; // "Real" momx (momx - cmomx) fixed_t rmomy; // "Real" momy (momy - cmomy) - ///////////////////// - // Race Mode Stuff // - ///////////////////// - INT16 numboxes; // Number of item boxes obtained for Race Mode - INT16 totalring; // Total number of rings obtained for Race Mode + INT16 totalring; // Total number of rings obtained for GP tic_t realtime; // integer replacement for leveltime UINT8 laps; // Number of laps (optional) INT32 starpostnum; // The number of the last starpost you hit - //////////////////// - // CTF Mode Stuff // - //////////////////// - INT32 ctfteam; // 0 == Spectator, 1 == Red, 2 == Blue - UINT16 gotflag; // 1 == Red, 2 == Blue Do you have the flag? + UINT8 ctfteam; // 0 == Spectator, 1 == Red, 2 == Blue - INT32 weapondelay; // Delay (if any) to fire the weapon again - INT32 tossdelay; // Delay (if any) to toss a flag/emeralds again - - ///////////////// - // NiGHTS Stuff// - ///////////////// - angle_t angle_pos; - angle_t old_angle_pos; - - mobj_t *axis1; - mobj_t *axis2; - tic_t bumpertime; // Currently being bounced by MT_NIGHTSBUMPER - INT32 flyangle; - tic_t drilltimer; - INT32 linkcount; - tic_t linktimer; - INT32 anotherflyangle; - tic_t nightstime; // How long you can fly as NiGHTS. - INT32 drillmeter; - UINT8 drilldelay; - boolean bonustime; // Capsule destroyed, now it's bonus time! - mobj_t *capsule; // Go inside the capsule - mobj_t *drone; // Move center to the drone - fixed_t oldscale; // Pre-Nightserize scale - UINT8 mare; // Current mare - UINT8 marelap; // Current mare lap - UINT8 marebonuslap; // Current mare lap starting from bonus time - - // Statistical purposes. - tic_t marebegunat; // Leveltime when mare begun - tic_t startedtime; // Time which you started this mare with. - tic_t finishedtime; // Time it took you to finish the mare (used for display) - tic_t lapbegunat; // Leveltime when lap begun - tic_t lapstartedtime; // Time which you started this lap with. - INT16 finishedspheres; // The spheres you had left upon finishing the mare - INT16 finishedrings; // The rings/stars you had left upon finishing the mare - UINT32 marescore; // score for this nights stage - UINT32 lastmarescore; // score for the last mare - UINT32 totalmarescore; // score for all mares - UINT8 lastmare; // previous mare - UINT8 lastmarelap; // previous mare lap - UINT8 lastmarebonuslap; // previous mare bonus lap - UINT8 totalmarelap; // total mare lap - UINT8 totalmarebonuslap; // total mare bonus lap - INT32 maxlink; // maximum link obtained - UINT8 texttimer; // nights_texttime should not be local - UINT8 textvar; // which line of NiGHTS text to show -- let's not use cheap hacks + UINT8 checkskip; // Skipping checkpoints? Oh no no no INT16 lastsidehit, lastlinehit; - tic_t losstime; - UINT8 timeshit; // That's TIMES HIT, not TIME SHIT, you doofus! + //UINT8 timeshit; // That's TIMES HIT, not TIME SHIT, you doofus! -- in memoriam INT32 onconveyor; // You are on a conveyor belt if nonzero @@ -695,6 +520,7 @@ typedef struct player_s angle_t awayviewaiming; // Used for cut-away view boolean spectator; + tic_t spectatewait; // reimplementable as UINT8 queue - How long have you been waiting as a spectator boolean bot; botvars_t botvars; @@ -709,15 +535,13 @@ typedef struct player_s UINT8 kickstartaccel; + UINT8 stairjank; + #ifdef HWRENDER fixed_t fovadd; // adjust FOV for hw rendering #endif } player_t; -// Values for dashmode -#define DASHMODE_THRESHOLD (3*TICRATE) -#define DASHMODE_MAX (DASHMODE_THRESHOLD + 3) - // Value for infinite lives #define INFLIVES 0x7F diff --git a/src/deh_lua.c b/src/deh_lua.c index c36ebc034..52fd4b83e 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -445,42 +445,6 @@ static inline int lib_getenum(lua_State *L) return 1; } #endif - else if (!mathlib && fastncmp("pw_",word,3)) { - p = word+3; - for (i = 0; i < NUMPOWERS; i++) - if (fasticmp(p, POWERS_LIST[i])) { - lua_pushinteger(L, i); - return 1; - } - return 0; - } - else if (mathlib && fastncmp("PW_",word,3)) { // SOCs are ALL CAPS! - p = word+3; - for (i = 0; i < NUMPOWERS; i++) - if (fastcmp(p, POWERS_LIST[i])) { - lua_pushinteger(L, i); - return 1; - } - return luaL_error(L, "power '%s' could not be found.\n", word); - } - else if (!mathlib && fastncmp("k_",word,2)) { - p = word+2; - for (i = 0; i < NUMKARTSTUFF; i++) - if (fasticmp(p, KARTSTUFF_LIST[i])) { - lua_pushinteger(L, i); - return 1; - } - return 0; - } - else if (mathlib && fastncmp("K_",word,2)) { // SOCs are ALL CAPS! - p = word+2; - for (i = 0; i < NUMKARTSTUFF; i++) - if (fastcmp(p, KARTSTUFF_LIST[i])) { - lua_pushinteger(L, i); - return 1; - } - return luaL_error(L, "kartstuff '%s' could not be found.\n", word); - } else if (!mathlib && fastncmp("khud_",word,5)) { p = word+5; for (i = 0; i < NUMKARTHUD; i++) diff --git a/src/deh_soc.c b/src/deh_soc.c index c6ad81b7b..4ab4a29aa 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2683,6 +2683,10 @@ void readsound(MYFILE *f, INT32 num) { S_sfx[num].pitch = value; } + else if (fastcmp(word, "VOLUME")) + { + S_sfx[num].volume = value; + } else if (fastcmp(word, "CAPTION") || fastcmp(word, "DESCRIPTION")) { deh_strlcpy(S_sfx[num].caption, word2, @@ -3556,10 +3560,6 @@ void readmaincfg(MYFILE *f) { maxXtraLife = (UINT8)get_number(word2); } - else if (fastcmp(word, "USECONTINUES")) - { - useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y'); - } else if (fastcmp(word, "GAMEDATA")) { @@ -4337,20 +4337,6 @@ menutype_t get_menutype(const char *word) return i; deh_warning("Couldn't find gametype named 'GT_%s'",word); return GT_COOP; -} - -static powertype_t get_power(const char *word) -{ // Returns the value of pw_ enumerations - powertype_t i; - if (*word >= '0' && *word <= '9') - return atoi(word); - if (fastncmp("PW_",word,3)) - word += 3; // take off the pw_ - for (i = 0; i < NUMPOWERS; i++) - if (fastcmp(word, POWERS_LIST[i])) - return i; - deh_warning("Couldn't find power named 'pw_%s'",word); - return pw_invulnerability; }*/ /// \todo Make ANY of this completely over-the-top math craziness obey the order of operations. diff --git a/src/deh_tables.c b/src/deh_tables.c index a6a7c35cb..ae9b90964 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -85,18 +85,13 @@ actionpointer_t actionpointers[] = {{A_FaceTracer}, "A_FACETRACER"}, {{A_Scream}, "A_SCREAM"}, {{A_BossDeath}, "A_BOSSDEATH"}, - {{A_CustomPower}, "A_CUSTOMPOWER"}, {{A_RingBox}, "A_RINGBOX"}, - {{A_Invincibility}, "A_INVINCIBILITY"}, - {{A_SuperSneakers}, "A_SUPERSNEAKERS"}, {{A_BunnyHop}, "A_BUNNYHOP"}, {{A_BubbleSpawn}, "A_BUBBLESPAWN"}, {{A_FanBubbleSpawn}, "A_FANBUBBLESPAWN"}, {{A_BubbleRise}, "A_BUBBLERISE"}, {{A_BubbleCheck}, "A_BUBBLECHECK"}, {{A_AwardScore}, "A_AWARDSCORE"}, - {{A_GiveShield}, "A_GIVESHIELD"}, - {{A_GravityBox}, "A_GRAVITYBOX"}, {{A_ScoreRise}, "A_SCORERISE"}, {{A_AttractChase}, "A_ATTRACTCHASE"}, {{A_DropMine}, "A_DROPMINE"}, @@ -339,6 +334,7 @@ actionpointer_t actionpointers[] = {{A_ReaperThinker}, "A_REAPERTHINKER"}, {{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"}, {{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"}, + {{A_SpawnItemCapsuleParts}, "A_SPAWNITEMCAPSULEPARTS"}, {{NULL}, "NONE"}, @@ -3489,6 +3485,15 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_ITEMICON", + // Item capsules + "S_ITEMCAPSULE", + "S_ITEMCAPSULE_TOP_SIDE", + "S_ITEMCAPSULE_BOTTOM_SIDE_AIR", + "S_ITEMCAPSULE_BOTTOM_SIDE_GROUND", + "S_ITEMCAPSULE_TOP", + "S_ITEMCAPSULE_BOTTOM", + "S_ITEMCAPSULE_INSIDE", + // Signpost sparkles "S_SIGNSPARK1", "S_SIGNSPARK2", @@ -3527,6 +3532,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_DRIFTWARNSPARK3", "S_DRIFTWARNSPARK4", + // Drift electricity + "S_DRIFTELECTRICITY", + "S_DRIFTELECTRICSPARK", + // Fast lines "S_FASTLINE1", "S_FASTLINE2", @@ -4584,6 +4593,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_RINGSPARKS14", "S_RINGSPARKS15", + "S_GAINAX_TINY", + "S_GAINAX_HUGE", + "S_GAINAX_MID1", + "S_GAINAX_MID2", + "S_DRAFTDUST1", "S_DRAFTDUST2", "S_DRAFTDUST3", @@ -4650,6 +4664,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_DEBTSPIKEC", "S_DEBTSPIKED", "S_DEBTSPIKEE", + + // Sparks when driving on stairs + "S_JANKSPARK1", + "S_JANKSPARK2", + "S_JANKSPARK3", + "S_JANKSPARK4", }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -5433,6 +5453,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_RANDOMITEM", "MT_RANDOMITEMPOP", "MT_FLOATINGITEM", + "MT_ITEMCAPSULE", + "MT_ITEMCAPSULE_PART", "MT_SIGNSPARKLE", @@ -5451,6 +5473,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DRIFTSPARK", "MT_BRAKEDRIFT", "MT_DRIFTDUST", + "MT_DRIFTELECTRICITY", + "MT_DRIFTELECTRICSPARK", + "MT_JANKSPARK", "MT_ROCKETSNEAKER", // Rocket sneakers @@ -5710,6 +5735,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_KARMAFIREWORK", "MT_RINGSPARKS", + "MT_GAINAX", "MT_DRAFTDUST", "MT_SPBDUST", "MT_TIREGREASE", @@ -5828,56 +5854,46 @@ const char *const MAPTHINGFLAG_LIST[4] = { }; const char *const PLAYERFLAG_LIST[] = { - "FAULT", - "ANALOGMODE", // Analog mode? - "DIRECTIONCHAR", // Directional character sprites? - "AUTOBRAKE", // Autobrake? - - // Cheats - "GODMODE", - "NOCLIP", - "INVIS", - // True if button down last tic. "ATTACKDOWN", "ACCELDOWN", "BRAKEDOWN", - "WPNDOWN", + "LOOKDOWN", + + // Accessibility and cheats + "KICKSTARTACCEL", // Is accelerate in kickstart mode? + "GODMODE", + "NOCLIP", + + "WANTSTOJOIN", // Spectator that wants to join - // Unmoving states "STASIS", // Player is not allowed to move - "JUMPSTASIS", // and that includes jumping. + "FAULT", // F A U L T + "ELIMINATED", // Battle-style elimination, no extra penalty + "NOCONTEST", // Did not finish (last place explosion) + "LOSTLIFE", // Do not lose life more than once - // SRB2Kart: spectator that wants to join - "WANTSTOJOIN", + "RINGLOCK", // Prevent picking up rings while SPB is locked on - // Character action status - "STARTJUMP", - "JUMPED", - "NOJUMPDAMAGE", - "SPINNING", - "STARTDASH", - "THOKKED", - "SHIELDABILITY", - "GLIDING", - "BOUNCING", + // The following four flags are mutually exclusive, although they can also all be off at the same time. If we ever run out of pflags, eventually turn them into a seperate five(+) mode UINT8..? + "USERINGS", // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness + "ITEMOUT", // Are you holding an item out? + "EGGMANOUT", // Eggman mark held, separate from PF_ITEMOUT so it doesn't stop you from getting items + "HOLDREADY", // Hold button-style item is ready to activate - // Sliding (usually in water) like Labyrinth/Oil Ocean - "SLIDING", + "DRIFTINPUT", // Drifting! + "GETSPARKS", // Can get sparks + "DRIFTEND", // Drift has ended, used to adjust character angle after drift + "BRAKEDRIFT", // Helper for brake-drift spark spawning - // NiGHTS stuff - "TRANSFERTOCLOSEST", - "DRILLING", + "AIRFAILSAFE", // Whenever or not try the air boost + "TRICKDELAY", // Prevent tricks until control stick is neutral - // Gametype-specific stuff - "GAMETYPEOVER", // Race time over - "TAGIT", + "TUMBLELASTBOUNCE", // One more time for the funny + "TUMBLESOUND", // Don't play more than once - /*** misc ***/ - "FORCESTRAFE", // Accessibility feature - is accelerate in kickstart mode? - "CANCARRY", "HITFINISHLINE", // Already hit the finish line this tic - + "WRONGWAY", // Moving the wrong way with respect to waypoints? NULL // stop loop here. }; @@ -6105,145 +6121,6 @@ const char *COLOR_ENUMS[] = { "CHAOSEMERALD7" }; -const char *const POWERS_LIST[] = { - "INVULNERABILITY", - "SNEAKERS", - "FLASHING", - "SHIELD", - "CARRY", - "TAILSFLY", // tails flying - "UNDERWATER", // underwater timer - "SPACETIME", // In space, no one can hear you spin! - "EXTRALIFE", // Extra Life timer - "PUSHING", - "JUSTSPRUNG", - "NOAUTOBRAKE", - - "SUPER", // Are you super? - "GRAVITYBOOTS", // gravity boots - - // Weapon ammunition - "INFINITYRING", - "AUTOMATICRING", - "BOUNCERING", - "SCATTERRING", - "GRENADERING", - "EXPLOSIONRING", - "RAILRING", - - // Power Stones - "EMERALDS", // stored like global 'emeralds' variable - - // NiGHTS powerups - "NIGHTS_SUPERLOOP", - "NIGHTS_HELPER", - "NIGHTS_LINKFREEZE", - - //for linedef exec 427 - "NOCONTROL", - - //for dyes - "DYE", - - "JUSTLAUNCHED", - - "IGNORELATCH" -}; - -const char *const KARTSTUFF_LIST[] = { - "POSITION", - "OLDPOSITION", - "POSITIONDELAY", - - "THROWDIR", - "INSTASHIELD", - - "FLOORBOOST", - "SPINOUTTYPE", - - "DRIFT", - "DRIFTEND", - "DRIFTCHARGE", - "DRIFTBOOST", - "BOOSTCHARGE", - "STARTBOOST", - "RINGS", - "PICKUPRINGS", - "USERINGS", - "RINGDELAY", - "RINGBOOST", - "RINGLOCK", - "SPARKLEANIM", - "JMP", - "OFFROAD", - "BRAKESTOP", - "SPINDASH", - "SPINDASHSPEED", - "SPINDASHBOOST", - "WATERSKIP", - "DASHPADCOOLDOWN", - "NUMBOOSTS", - "BOOSTPOWER", - "SPEEDBOOST", - "ACCELBOOST", - "HANDLEBOOST", - "DRAFTPOWER", - "DRAFTLEEWAY", - "LASTDRAFT", - "BOOSTANGLE", - "AIZDRIFTSTRAT", - "BRAKEDRIFT", - - "ITEMROULETTE", - "ROULETTETYPE", - - "ITEMTYPE", - "ITEMAMOUNT", - "ITEMHELD", - "HOLDREADY", - - "CURSHIELD", - "HYUDOROTIMER", - "STEALINGTIMER", - "STOLENTIMER", - "SUPERRING", - "SNEAKERTIMER", - "NUMSNEAKERS", - "GROWSHRINKTIMER", - "SQUISHEDTIMER", - "ROCKETSNEAKERTIMER", - "INVINCIBILITYTIMER", - "BUBBLECOOL", - "BUBBLEBLOWUP", - "FLAMEDASH", - "FLAMEMETER", - "FLAMELENGTH", - "EGGMANHELD", - "EGGMANEXPLODE", - "EGGMANBLAME", - "LASTJAWZTARGET", - "BANANADRAG", - "SPINOUTTIMER", - "WIPEOUTSLOW", - "JUSTBUMPED", - "COMEBACKTIMER", - "SADTIMER", - - "BUMPER", - "COMEBACKPOINTS", - "COMEBACKMODE", - "WANTED", - - "GETSPARKS", - "JAWZTARGETDELAY", - "SPECTATEWAIT", - "TIREGREASE", - "SPRINGSTARS", - "SPRINGCOLOR", - "KILLFIELD", - "WRONGWAY" -}; - const char *const KARTHUD_LIST[] = { "ITEMBLINK", "ITEMBLINKMODE", @@ -6605,33 +6482,6 @@ struct int_const_s const INT_CONST[] = { {"PRECIP_STORM_NORAIN",PRECIP_STORM_NORAIN}, {"PRECIP_STORM_NOSTRIKES",PRECIP_STORM_NOSTRIKES}, - // Shields - {"SH_NONE",SH_NONE}, - // Shield flags - {"SH_PROTECTFIRE",SH_PROTECTFIRE}, - {"SH_PROTECTWATER",SH_PROTECTWATER}, - {"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC}, - {"SH_PROTECTSPIKE",SH_PROTECTSPIKE}, - // Indivisible shields - {"SH_PITY",SH_PITY}, - {"SH_WHIRLWIND",SH_WHIRLWIND}, - {"SH_ARMAGEDDON",SH_ARMAGEDDON}, - {"SH_PINK",SH_PINK}, - // normal shields that use flags - {"SH_ATTRACT",SH_ATTRACT}, - {"SH_ELEMENTAL",SH_ELEMENTAL}, - // Sonic 3 shields - {"SH_FLAMEAURA",SH_FLAMEAURA}, - {"SH_BUBBLEWRAP",SH_BUBBLEWRAP}, - {"SH_THUNDERCOIN",SH_THUNDERCOIN}, - // The force shield uses the lower 8 bits to count how many extra hits are left. - {"SH_FORCE",SH_FORCE}, - {"SH_FORCEHP",SH_FORCEHP}, // to be used as a bitmask only - // Mostly for use with Mario mode. - {"SH_FIREFLOWER",SH_FIREFLOWER}, - {"SH_STACK",SH_STACK}, - {"SH_NOSTACK",SH_NOSTACK}, - // Carrying {"CR_NONE",CR_NONE}, {"CR_ZOOMTUBE",CR_ZOOMTUBE}, @@ -6640,10 +6490,6 @@ struct int_const_s const INT_CONST[] = { {"SF_HIRES",SF_HIRES}, {"SF_MACHINE",SF_MACHINE}, - // Dashmode constants - {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, - {"DASHMODE_MAX",DASHMODE_MAX}, - // Sound flags {"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE}, {"SF_NOMULTIPLESOUND",SF_NOMULTIPLESOUND}, @@ -6999,6 +6845,7 @@ struct int_const_s const INT_CONST[] = { {"TC_RAINBOW",TC_RAINBOW}, {"TC_BLINK",TC_BLINK}, {"TC_DASHMODE",TC_DASHMODE}, + {"TC_HITLAG",TC_HITLAG}, // marathonmode flags {"MA_INIT",MA_INIT}, @@ -7079,7 +6926,6 @@ void DEH_TableCheck(void) #if defined(_DEBUG) || defined(PARANOIA) const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*); - const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*); const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*); if (dehstates != S_FIRSTFREESLOT) @@ -7088,9 +6934,6 @@ void DEH_TableCheck(void) if (dehmobjs != MT_FIRSTFREESLOT) I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs)); - if (dehpowers != NUMPOWERS) - I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); - if (dehcolors != SKINCOLOR_FIRSTFREESLOT) I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); #endif diff --git a/src/deh_tables.h b/src/deh_tables.h index 53c52fbfa..3c5d64830 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -67,7 +67,6 @@ extern const char *const GAMETYPERULE_LIST[]; extern const char *const ML_LIST[16]; // Linedef flags extern const char *COLOR_ENUMS[]; extern const char *const POWERS_LIST[]; -extern const char *const KARTSTUFF_LIST[]; extern const char *const KARTHUD_LIST[]; extern const char *const HUDITEMS_LIST[]; extern const char *const MENUTYPES_LIST[]; diff --git a/src/doomstat.h b/src/doomstat.h index 159f83172..19359df3b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -420,7 +420,7 @@ typedef struct extern mapheader_t* mapheaderinfo[NUMMAPS]; // This could support more, but is that a good idea? -// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory. +// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory. #define MAXLEVELLIST 5 typedef struct cupheader_s @@ -465,7 +465,7 @@ enum GameTypeRules GTR_BUMPERS = 1<<3, // Enables the bumper health system GTR_SPHERES = 1<<4, // Replaces rings with blue spheres GTR_PAPERITEMS = 1<<5, // Replaces item boxes with paper item spawners - GTR_WANTED = 1<<6, // Enables the wanted anti-camping system + GTR_WANTED = 1<<6, // unused GTR_KARMA = 1<<7, // Enables the Karma system if you're out of bumpers GTR_ITEMARROWS = 1<<8, // Show item box arrows above players GTR_CAPSULES = 1<<9, // Enables the wanted anti-camping system @@ -655,8 +655,6 @@ extern UINT8 useBlackRock; extern UINT8 use1upSound; extern UINT8 maxXtraLife; // Max extra lives from rings -extern UINT8 useContinues; -#define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0)))) extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations diff --git a/src/f_finale.c b/src/f_finale.c index 9780dc068..099fa422d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2909,7 +2909,7 @@ void F_TextPromptDrawer(void) } #define nocontrolallowed(j) {\ - players[j].powers[pw_nocontrol] = 1;\ + players[j].nocontrol = 1;\ if (players[j].mo)\ {\ if (players[j].mo->state == states+S_KART_STILL && players[j].mo->tics != -1)\ @@ -2980,7 +2980,7 @@ void F_TextPromptTicker(void) { UINT8 j; - players[i].powers[pw_nocontrol] = 1; + players[i].nocontrol = 1; // Both players' controls are locked, // But only the triggering player can advance the prompt. diff --git a/src/f_finale.h b/src/f_finale.h index cc731f7f3..a45de5734 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -143,7 +143,7 @@ extern INT32 lastwipetic; // Don't know where else to place this constant // But this file seems appropriate -#define PRELEVELTIME 24 // frames in tics +#define PRELEVELTIME TICRATE // frames in tics void F_WipeStartScreen(void); void F_WipeEndScreen(void); diff --git a/src/f_wipe.c b/src/f_wipe.c index 9399598f5..ddc719e6d 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -415,7 +415,7 @@ void F_WipeStageTitle(void) if ((WipeStageTitle) && G_IsTitleCardAvailable()) { ST_runTitleCard(); - ST_drawWipeTitleCard(); + ST_drawTitleCard(); } } diff --git a/src/g_demo.c b/src/g_demo.c index 8ca756723..16ca2a859 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -347,6 +347,7 @@ void G_ReadDemoExtraData(void) players[p].pflags &= ~(PF_KICKSTARTACCEL); if (extradata & 1) players[p].pflags |= PF_KICKSTARTACCEL; + //CONS_Printf("weaponpref is %d for player %d\n", extradata, p); } p = READUINT8(demo_p); @@ -505,7 +506,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) if (ziptic & ZT_LATENCY) oldcmd[playernum].latency = READUINT8(demo_p); if (ziptic & ZT_FLAGS) - oldcmd[playernum].latency = READUINT8(demo_p); + oldcmd[playernum].flags = READUINT8(demo_p); G_CopyTiccmd(cmd, &oldcmd[playernum], 1); @@ -620,7 +621,7 @@ void G_GhostAddHit(INT32 playernum, mobj_t *victim) ghostext[playernum].flags |= EZT_HIT; ghostext[playernum].hits++; ghostext[playernum].hitlist = Z_Realloc(ghostext[playernum].hitlist, ghostext[playernum].hits * sizeof(mobj_t *), PU_LEVEL, NULL); - ghostext[playernum].hitlist[ghostext[playernum].hits-1] = victim; + P_SetTarget(ghostext[playernum].hitlist + (ghostext[playernum].hits-1), victim); } void G_WriteAllGhostTics(void) @@ -748,15 +749,15 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) } if (ghost->player && ( - ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || - ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || - ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] + ghostext[playernum].kartitem != ghost->player->itemtype || + ghostext[playernum].kartamount != ghost->player->itemamount || + ghostext[playernum].kartbumpers != ghost->player->bumpers )) { ghostext[playernum].flags |= EZT_KART; - ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; - ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; - ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; + ghostext[playernum].kartitem = ghost->player->itemtype; + ghostext[playernum].kartamount = ghost->player->itemamount; + ghostext[playernum].kartbumpers = ghost->player->bumpers; } if (ghostext[playernum].flags) @@ -792,6 +793,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) WRITEFIXED(demo_p,mo->y); WRITEFIXED(demo_p,mo->z); WRITEANGLE(demo_p,mo->angle); + P_SetTarget(ghostext[playernum].hitlist+i, NULL); } Z_Free(ghostext[playernum].hitlist); ghostext[playernum].hits = 0; @@ -1035,17 +1037,17 @@ void G_ConsGhostTic(INT32 playernum) else ghostext[playernum].desyncframes = 0; - if (players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem - || players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount - || players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers) + if (players[playernum].itemtype != ghostext[playernum].kartitem + || players[playernum].itemamount != ghostext[playernum].kartamount + || players[playernum].bumpers != ghostext[playernum].kartbumpers) { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); demosynced = false; - players[playernum].kartstuff[k_itemtype] = ghostext[playernum].kartitem; - players[playernum].kartstuff[k_itemamount] = ghostext[playernum].kartamount; - players[playernum].kartstuff[k_bumper] = ghostext[playernum].kartbumpers; + players[playernum].itemtype = ghostext[playernum].kartitem; + players[playernum].itemamount = ghostext[playernum].kartamount; + players[playernum].bumpers = ghostext[playernum].kartbumpers; } } @@ -1402,7 +1404,7 @@ void G_StoreRewindInfo(void) void G_PreviewRewind(tic_t previewtime) { SINT8 i; - size_t j; + //size_t j; fixed_t tweenvalue = 0; rewindinfo_t *info = rewindhead, *next_info = rewindhead; @@ -1461,8 +1463,9 @@ void G_PreviewRewind(tic_t previewtime) players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag; players[i].realtime = info->playerinfo[i].player.realtime; - for (j = 0; j < NUMKARTSTUFF; j++) - players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j]; + // Genuinely CANNOT be fucked. I can redo lua and I can redo netsaves but I draw the line at this abysmal hack. + /*for (j = 0; j < NUMKARTSTUFF; j++) + players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];*/ } for (i = splitscreen; i >= 0; i--) @@ -2655,7 +2658,7 @@ void G_DoPlayDemo(char *defdemoname) UINT32 randseed; char msg[1024]; - boolean spectator; + boolean spectator, kickstart; UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0; #if defined(SKIPERRORS) && !defined(DEVELOP) @@ -2924,16 +2927,8 @@ void G_DoPlayDemo(char *defdemoname) while (p != 0xFF) { - players[p].pflags &= ~PF_KICKSTARTACCEL; - if (p & DEMO_KICKSTART) + if ((spectator = (p & DEMO_SPECTATOR))) { - players[p].pflags |= PF_KICKSTARTACCEL; - p &= ~DEMO_KICKSTART; - } - spectator = false; - if (p & DEMO_SPECTATOR) - { - spectator = true; p &= ~DEMO_SPECTATOR; if (modeattacking) @@ -2948,6 +2943,10 @@ void G_DoPlayDemo(char *defdemoname) return; } } + + if ((kickstart = (p & DEMO_KICKSTART))) + p &= ~DEMO_KICKSTART; + slots[numslots] = p; numslots++; if (modeattacking && numslots > 1) @@ -2967,6 +2966,10 @@ void G_DoPlayDemo(char *defdemoname) playeringame[p] = true; players[p].spectator = spectator; + if (kickstart) + players[p].pflags |= PF_KICKSTARTACCEL; + else + players[p].pflags &= ~PF_KICKSTARTACCEL; // Name M_Memcpy(player_names[p],demo_p,16); diff --git a/src/g_game.c b/src/g_game.c index 925f71ca0..e964fb65d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -270,7 +270,6 @@ INT32 flameseg = TICRATE/4; UINT8 use1upSound = 0; UINT8 maxXtraLife = 2; // Max extra lives from rings -UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scenarioes UINT8 introtoplay; UINT8 creditscutscene; @@ -545,7 +544,7 @@ static void G_UpdateRecordReplays(void) if (!mainrecords[gamemap-1]) G_AllocMainRecordData(gamemap-1); - if (players[consoleplayer].pflags & PF_GAMETYPEOVER) + if (players[consoleplayer].pflags & PF_NOCONTEST) { players[consoleplayer].realtime = UINT32_MAX; } @@ -1112,7 +1111,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->forwardmove += (SINT8)forward; - cmd->latency = (leveltime & 0xFF); // Send leveltime when this tic was generated to the server for control lag calculations cmd->flags = 0; if (chat_on || CON_Ready()) @@ -1138,6 +1136,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (addedtogame && gamestate == GS_LEVEL) { LUAh_PlayerCmd(player, cmd); + + // Send leveltime when this tic was generated to the server for control lag calculations. + // Only do this when in a level. Also do this after the hook, so that it can't overwrite this. + cmd->latency = (leveltime & 0xFF); } if (cmd->forwardmove > MAXPLMOVE) @@ -1261,7 +1263,7 @@ void G_DoLoadLevel(boolean resetplayer) for (i = 0; i <= r_splitscreen; i++) { if (camera[i].chase) - P_ResetCamera(&players[g_localplayers[i]], &camera[i]); + P_ResetCamera(&players[displayplayers[i]], &camera[i]); } // clear cmd building stuff @@ -1299,7 +1301,7 @@ void G_StartTitleCard(void) ST_startTitleCard(); // start the title card - WipeStageTitle = false; //(!titlemapinaction); -- temporary until titlecards are reworked + WipeStageTitle = (!titlemapinaction); } // @@ -1308,26 +1310,27 @@ void G_StartTitleCard(void) void G_PreLevelTitleCard(void) { #ifndef NOWIPE - tic_t strtime = I_GetTime(); - tic_t endtime = strtime + (PRELEVELTIME*NEWTICRATERATIO); - tic_t nowtime = strtime; - tic_t lasttime = strtime; - while (nowtime < endtime) - { - // draw loop - while (!((nowtime = I_GetTime()) - lasttime)) - I_Sleep(); - lasttime = nowtime; + tic_t strtime = I_GetTime(); + tic_t endtime = strtime + (PRELEVELTIME*NEWTICRATERATIO); + tic_t nowtime = strtime; + tic_t lasttime = strtime; + while (nowtime < endtime) + { + // draw loop + ST_runTitleCard(); + ST_preLevelTitleCardDrawer(); + I_FinishUpdate(); // page flip or blit buffer + NetKeepAlive(); // Prevent timeouts - ST_runTitleCard(); - ST_preLevelTitleCardDrawer(); - I_FinishUpdate(); // page flip or blit buffer + if (moviemode) + M_SaveFrame(); + if (takescreenshot) // Only take screenshots after drawing. + M_DoScreenShot(); - if (moviemode) - M_SaveFrame(); - if (takescreenshot) // Only take screenshots after drawing. - M_DoScreenShot(); - } + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + } #endif } @@ -1617,7 +1620,7 @@ boolean G_CouldView(INT32 playernum) // SRB2Kart: Only go through players who are actually playing if (player->exiting) return false; - if (( player->pflags & PF_GAMETYPEOVER )) + if (( player->pflags & PF_NOCONTEST )) return false; // I don't know if we want this actually, but I'll humor the suggestion anyway @@ -2033,9 +2036,6 @@ static inline void G_PlayerFinishLevel(INT32 player) p = &players[player]; - memset(p->powers, 0, sizeof (p->powers)); - memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart - p->mo->renderflags &= ~(RF_TRANSMASK|RF_BRIGHTMASK); // cancel invisibility P_FlashPal(p, 0, 0); // Resets @@ -2064,10 +2064,8 @@ static inline void G_PlayerFinishLevel(INT32 player) void G_PlayerReborn(INT32 player, boolean betweenmaps) { player_t *p; - INT32 score, marescore; + INT32 score, roundscore; INT32 lives; - boolean lostlife; - INT32 continues; UINT8 kartspeed; UINT8 kartweight; @@ -2082,15 +2080,12 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT32 pflags; - INT32 ctfteam; + UINT8 ctfteam; INT32 starpostnum; INT32 exiting; - tic_t dashmode; - INT16 numboxes; INT16 totalring; UINT8 laps; - UINT8 mare; UINT16 skincolor; INT32 skin; UINT32 availabilities; @@ -2121,20 +2116,14 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT32 roulettetype; INT32 growshrinktimer; INT32 bumper; - INT32 wanted; boolean songcredit = false; - boolean eliminated; UINT16 nocontrol; INT32 khudfault; INT32 kickstartaccel; score = players[player].score; - marescore = players[player].marescore; lives = players[player].lives; - lostlife = players[player].lostlife; - continues = players[player].continues; ctfteam = players[player].ctfteam; - exiting = players[player].exiting; jointime = players[player].jointime; quittime = players[player].quittime; @@ -2142,21 +2131,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) splitscreenindex = players[player].splitscreenindex; spectator = players[player].spectator; - pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_GAMETYPEOVER|PF_FAULT|PF_KICKSTARTACCEL)); - steering = players[player].steering; playerangleturn = players[player].angleturn; - // As long as we're not in multiplayer, carry over cheatcodes from map to map - if (!(netgame || multiplayer)) - pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP|PF_INVIS)); - - dashmode = players[player].dashmode; - - numboxes = players[player].numboxes; - laps = players[player].laps; - totalring = players[player].totalring; - skincolor = players[player].skincolor; skin = players[player].skin; @@ -2164,7 +2141,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) kartspeed = players[player].kartspeed; kartweight = players[player].kartweight; - follower = players[player].follower; followerready = players[player].followerready; followercolor = players[player].followercolor; followerskin = players[player].followerskin; @@ -2173,20 +2149,18 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) charflags = players[player].charflags; - starpostnum = players[player].starpostnum; followitem = players[player].followitem; - mare = players[player].mare; bot = players[player].bot; botdifficulty = players[player].botvars.difficulty; botdiffincrease = players[player].botvars.diffincrease; botrival = players[player].botvars.rival; - xtralife = players[player].xtralife; + pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL)); // SRB2kart - if (betweenmaps || leveltime < starttime) + if (betweenmaps || leveltime < introtime) { itemroulette = 0; roulettetype = 0; @@ -2196,47 +2170,64 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); spheres = 0; - eliminated = false; - wanted = 0; kickstartaccel = 0; + khudfault = nocontrol = 0; + laps = 0; + totalring = 0; + roundscore = 0; + exiting = 0; + starpostnum = 0; + xtralife = 0; + + follower = NULL; } else { - itemroulette = (players[player].kartstuff[k_itemroulette] > 0 ? 1 : 0); - roulettetype = players[player].kartstuff[k_roulettetype]; + itemroulette = (players[player].itemroulette > 0 ? 1 : 0); + roulettetype = players[player].roulettetype; - if (players[player].kartstuff[k_itemheld]) + if (players[player].pflags & PF_ITEMOUT) { itemtype = 0; itemamount = 0; } else { - itemtype = players[player].kartstuff[k_itemtype]; - itemamount = players[player].kartstuff[k_itemamount]; + itemtype = players[player].itemtype; + itemamount = players[player].itemamount; } // Keep Shrink status, remove Grow status - if (players[player].kartstuff[k_growshrinktimer] < 0) - growshrinktimer = players[player].kartstuff[k_growshrinktimer]; + if (players[player].growshrinktimer < 0) + growshrinktimer = players[player].growshrinktimer; else growshrinktimer = 0; bumper = players[player].bumpers; rings = players[player].rings; spheres = players[player].spheres; - eliminated = players[player].eliminated; - wanted = players[player].kartstuff[k_wanted]; kickstartaccel = players[player].kickstartaccel; + + khudfault = players[player].karthud[khud_fault]; + nocontrol = players[player].nocontrol; + + laps = players[player].laps; + totalring = players[player].totalring; + roundscore = players[player].roundscore; + exiting = players[player].exiting; + starpostnum = players[player].starpostnum; + + xtralife = players[player].xtralife; + + follower = players[player].follower; + + pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE)); } - if (!betweenmaps) - { - khudfault = players[player].karthud[khud_fault]; - nocontrol = players[player].powers[pw_nocontrol]; - } - else - khudfault = nocontrol = 0; + // As long as we're not in multiplayer, carry over cheatcodes from map to map + if (!(netgame || multiplayer)) + pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP)); + // Obliterate follower from existence P_SetTarget(&players[player].follower, NULL); @@ -2247,10 +2238,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) memset(p, 0, sizeof (*p)); p->score = score; - p->marescore = marescore; + p->roundscore = roundscore; p->lives = lives; - p->lostlife = lostlife; - p->continues = continues; p->pflags = pflags; p->ctfteam = ctfteam; p->jointime = jointime; @@ -2273,13 +2262,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->starpostnum = starpostnum; p->exiting = exiting; - p->dashmode = dashmode; - - p->numboxes = numboxes; p->laps = laps; p->totalring = totalring; - p->mare = mare; p->bot = bot; p->botvars.difficulty = botdifficulty; p->rings = rings; @@ -2289,20 +2274,20 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->xtralife = xtralife; // SRB2kart - p->kartstuff[k_itemroulette] = itemroulette; - p->kartstuff[k_roulettetype] = roulettetype; - p->kartstuff[k_itemtype] = itemtype; - p->kartstuff[k_itemamount] = itemamount; - p->kartstuff[k_growshrinktimer] = growshrinktimer; + p->itemroulette = itemroulette; + p->roulettetype = roulettetype; + p->itemtype = itemtype; + p->itemamount = itemamount; + p->growshrinktimer = growshrinktimer; p->bumpers = bumper; p->karmadelay = comebacktime; - p->eliminated = eliminated; - p->kartstuff[k_wanted] = wanted; - p->kartstuff[k_eggmanblame] = -1; - p->kartstuff[k_lastdraft] = -1; + p->overtimekarma = 0; + p->eggmanblame = -1; + p->lastdraft = -1; p->karthud[khud_fault] = khudfault; - p->powers[pw_nocontrol] = nocontrol; + p->nocontrol = nocontrol; p->kickstartaccel = kickstartaccel; + p->tripWireState = TRIP_NONE; memcpy(&p->respawn, &respawn, sizeof (p->respawn)); @@ -2866,7 +2851,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Race GTR_CIRCUIT|GTR_BOTS, // Battle - GTR_SPHERES|GTR_BUMPERS|GTR_PAPERITEMS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME + GTR_SPHERES|GTR_BUMPERS|GTR_PAPERITEMS|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME }; // @@ -3476,7 +3461,7 @@ static void G_DoCompleted(void) if (playeringame[i]) { // SRB2Kart: exitlevel shouldn't get you the points - if (!players[i].exiting && !(players[i].pflags & PF_GAMETYPEOVER)) + if (!players[i].exiting && !(players[i].pflags & PF_NOCONTEST)) { if (players[i].bot) { @@ -3484,7 +3469,7 @@ static void G_DoCompleted(void) } else { - players[i].pflags |= PF_GAMETYPEOVER; + players[i].pflags |= PF_NOCONTEST; if (P_IsLocalPlayer(&players[i])) { @@ -3798,8 +3783,8 @@ static void G_DoContinued(void) I_Assert(!netgame && !multiplayer); I_Assert(pl->continues > 0); - if (pl->continues) - pl->continues--; + /*if (pl->continues) + pl->continues--;*/ // Reset score pl->score = 0; @@ -4467,16 +4452,12 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool for (i = 0; i < MAXPLAYERS; i++) { players[i].playerstate = PST_REBORN; - players[i].starpostnum = 0; memset(&players[i].respawn, 0, sizeof (players[i].respawn)); - // The latter two should clear by themselves, but just in case - players[i].pflags &= ~(PF_GAMETYPEOVER|PF_STASIS|PF_FAULT); - // Clear cheatcodes too, just in case. - players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); + players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP); - players[i].marescore = 0; + players[i].roundscore = 0; if (resetplayer && !(multiplayer && demo.playback)) // SRB2Kart { diff --git a/src/g_splitscreen.c b/src/g_splitscreen.c index 0354c0d10..e510a474c 100644 --- a/src/g_splitscreen.c +++ b/src/g_splitscreen.c @@ -50,10 +50,10 @@ G_ResetSplitscreen (INT32 playernum) displayplayers[i] = g_localplayers[i]; P_ResetCamera(&players[displayplayers[i]], &camera[i]); } + while (i < MAXSPLITSCREENPLAYERS) { displayplayers[i] = consoleplayer; - i++; } diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt new file mode 100644 index 000000000..4e9c67d2f --- /dev/null +++ b/src/hardware/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(c) diff --git a/src/hardware/Sourcefile b/src/hardware/Sourcefile new file mode 100644 index 000000000..1c05de76c --- /dev/null +++ b/src/hardware/Sourcefile @@ -0,0 +1,13 @@ +hw_bsp.c +hw_draw.c +hw_light.c +hw_main.c +hw_clip.c +hw_md2.c +hw_cache.c +hw_md2load.c +hw_md3load.c +hw_model.c +u_list.c +hw_batching.c +r_opengl/r_opengl.c diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2c2f21406..205fc3ff6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1478,7 +1478,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom transnum_t transtable = R_GetLinedefTransTable(gl_linedef); if (transtable == NUMTRANSMAPS) transtable = 0; - if (gl_linedef->special == 910) + if (gl_linedef->special == 910 || + P_IsLineTripWire(gl_linedef)) blend = AST_ADD; else if (gl_linedef->special == 911) blend = AST_SUBTRACT; @@ -3643,7 +3644,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) pslope_t *groundslope; // hitlag vibrating - if (thing->hitlag > 0) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) { fixed_t mul = thing->hitlag * (FRACUNIT / 10); @@ -4085,8 +4086,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) gpatch = spr->gpatch; #ifdef ALAM_LIGHTING - if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || - (spr->mobj->player && spr->mobj->player->powers[pw_super]))) + if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY)) HWR_DL_AddLight(spr, gpatch); #endif @@ -5063,7 +5063,7 @@ static void HWR_ProjectSprite(mobj_t *thing) return; // hitlag vibrating - if (thing->hitlag > 0) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) { fixed_t mul = thing->hitlag * (FRACUNIT / 10); @@ -5402,7 +5402,11 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->mobj = thing; //Hurdler: 25/04/2000: now support colormap in hardware mode - if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" + if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG)) + { + vis->colormap = R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE); + } + else if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized) vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 974a0b067..4b8d1de6f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -819,7 +819,12 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi while (size--) { - if (skinnum == TC_BOSS) + if (skinnum == TC_HITLAG) + { + cur->s.red = cur->s.green = cur->s.blue = K_HitlagColorValue(*image); + cur->s.alpha = image->s.alpha; + } + else if (skinnum == TC_BOSS) { // Turn everything below a certain threshold white if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127) @@ -1367,7 +1372,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) float finalscale; // hitlag vibrating - if (spr->mobj->hitlag > 0) + if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG)) { fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10); @@ -1486,7 +1491,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { INT32 skinnum = TC_DEFAULT; - if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" + if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG)) + { + skinnum = TC_HITLAG; + } + else if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) skinnum = TC_ALLWHITE; @@ -1565,7 +1574,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) && (spr->mobj->frame & FF_ANIMATE || (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite == SPR_PLAY - && ((P_GetSkinSprite2(spr->mobj->skin, (((spr->mobj->player && spr->mobj->player->powers[pw_super]) ? FF_SPR2SUPER : 0)|states[spr->mobj->state->nextstate].frame) & FF_FRAMEMASK, spr->mobj->player) == spr->mobj->sprite2))))) + && ((P_GetSkinSprite2(spr->mobj->skin, (states[spr->mobj->state->nextstate].frame) & FF_FRAMEMASK, spr->mobj->player) == spr->mobj->sprite2))))) { nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; if (nextFrame >= mod) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 55930b85e..7afc7d531 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,6 +73,8 @@ patch_t *pinggfx[5]; // small ping graphic patch_t *mping[5]; // smaller ping graphic +patch_t *tc_font[2][LT_FONTSIZE]; // Special font stuff for titlecard + patch_t *framecounter; patch_t *frameslash; // framerate stuff. Used in screen.c @@ -178,7 +180,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum); void HU_LoadGraphics(void) { - INT32 i; + char buffer[9]; + INT32 i, j; if (dedicated) return; @@ -191,6 +194,27 @@ void HU_LoadGraphics(void) emblemicon = HU_CachePatch("EMBLICON"); songcreditbg = HU_CachePatch("K_SONGCR"); + // Cache titlecard font + j = LT_FONTSTART; + for (i = 0; i < LT_FONTSIZE; i++, j++) + { + // cache the titlecard font + + // Bottom layer + sprintf(buffer, "GTOL%.3d", j); + if (W_CheckNumForName(buffer) == LUMPERROR) + tc_font[0][i] = NULL; + else + tc_font[0][i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + + // Top layer + sprintf(buffer, "GTFN%.3d", j); + if (W_CheckNumForName(buffer) == LUMPERROR) + tc_font[1][i] = NULL; + else + tc_font[1][i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + } + // cache ping gfx: for (i = 0; i < 5; i++) { @@ -704,7 +728,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } else if (target == -1) // say team { - if (players[playernum].ctfteam == 1) + if (players[playernum].ctfteam == 1) { // red text cstart = textcolor = "\x85"; @@ -2353,11 +2377,11 @@ static void HU_DrawRankings(void) if (completed[i] || !playeringame[i] || players[i].spectator || !players[i].mo) continue; - if (players[i].kartstuff[k_position] >= lowestposition) + if (players[i].position >= lowestposition) continue; tab[scorelines].num = i; - lowestposition = players[i].kartstuff[k_position]; + lowestposition = players[i].position; } i = tab[scorelines].num; @@ -2374,7 +2398,7 @@ static void HU_DrawRankings(void) tab[scorelines].count = players[i].realtime; } else - tab[scorelines].count = players[i].marescore; + tab[scorelines].count = players[i].roundscore; scorelines++; diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 6a425926b..4d686516e 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -39,6 +39,11 @@ #define LT_FONTEND 'z' // the last font characters #define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1) +// Under regular circumstances, we'd use the built in font stuff, however this font is a bit messy because of how we're gonna draw shit. +// tc_font[0][n] is used for the "bottom" layer +// tc_font[1][n] is used for the "top" layer +extern patch_t *tc_font[2][LT_FONTSIZE]; + #define CRED_FONTSTART '!' // the first font character #define CRED_FONTEND 'Z' // the last font character #define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1) diff --git a/src/info.c b/src/info.c index 51cce3e7d..c28c81dfd 100644 --- a/src/info.c +++ b/src/info.c @@ -537,10 +537,15 @@ char sprnames[NUMSPRITES + 1][5] = "KINB", // Darker invincibility sparkle trail "KINF", // Invincibility flash "INVI", // Invincibility speedlines + "ICAP", // Item capsules + "WIPD", // Wipeout dust trail "DRIF", // Drift Sparks "BDRF", // Brake drift sparks "DRWS", // Drift dust sparks + "DREL", // Drift electricity + "DRES", // Drift electric sparks + "JANK", // Stair janking sparks // Kart Items "RSHE", // Rocket sneaker @@ -722,6 +727,7 @@ char sprnames[NUMSPRITES + 1][5] = "FWRK", "MXCL", "RGSP", + "LENS", "DRAF", "GRES", @@ -745,6 +751,8 @@ char sprnames[NUMSPRITES + 1][5] = "SDDS", // Spindash dust "SDWN", // Spindash wind + "TRCK", + "FLBM", // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later @@ -2126,31 +2134,31 @@ state_t states[NUMSTATES] = // Box Icons -- 2 states each, animation and action {SPR_TVRI, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_RING_ICON2}, // S_RING_ICON1 - {SPR_TVRI, 2, 18, {A_RingBox}, 0, 0, S_NULL}, // S_RING_ICON2 + {SPR_TVRI, 2, 18, {NULL}, 0, 0, S_NULL}, // S_RING_ICON2 {SPR_TVPI, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_PITY_ICON2}, // S_PITY_ICON1 - {SPR_TVPI, 2, 18, {A_GiveShield}, SH_PITY, 0, S_NULL}, // S_PITY_ICON2 + {SPR_TVPI, 2, 18, {NULL}, 0, 0, S_NULL}, // S_PITY_ICON2 {SPR_TVAT, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ATTRACT_ICON2}, // S_ATTRACT_ICON1 - {SPR_TVAT, 2, 18, {A_GiveShield}, SH_ATTRACT, 0, S_NULL}, // S_ATTRACT_ICON2 + {SPR_TVAT, 2, 18, {NULL}, 0, 0, S_NULL}, // S_ATTRACT_ICON2 {SPR_TVFO, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FORCE_ICON2}, // S_FORCE_ICON1 - {SPR_TVFO, 2, 18, {A_GiveShield}, SH_FORCE|1, 0, S_NULL}, // S_FORCE_ICON2 + {SPR_TVFO, 2, 18, {NULL}, 0, 0, S_NULL}, // S_FORCE_ICON2 {SPR_TVAR, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ARMAGEDDON_ICON2}, // S_ARMAGEDDON_ICON1 - {SPR_TVAR, 2, 18, {A_GiveShield}, SH_ARMAGEDDON, 0, S_NULL}, // S_ARMAGEDDON_ICON2 + {SPR_TVAR, 2, 18, {NULL}, 0, 0, S_NULL}, // S_ARMAGEDDON_ICON2 {SPR_TVWW, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_WHIRLWIND_ICON2}, // S_WHIRLWIND_ICON1 - {SPR_TVWW, 2, 18, {A_GiveShield}, SH_WHIRLWIND, 0, S_NULL}, // S_WHIRLWIND_ICON2 + {SPR_TVWW, 2, 18, {NULL}, 0, 0, S_NULL}, // S_WHIRLWIND_ICON2 {SPR_TVEL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ELEMENTAL_ICON2}, // S_ELEMENTAL_ICON1 - {SPR_TVEL, 2, 18, {A_GiveShield}, SH_ELEMENTAL, 0, S_NULL}, // S_ELEMENTAL_ICON2 + {SPR_TVEL, 2, 18, {NULL}, 0, 0, S_NULL}, // S_ELEMENTAL_ICON2 {SPR_TVSS, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SNEAKERS_ICON2}, // S_SNEAKERS_ICON1 - {SPR_TVSS, 2, 18, {A_SuperSneakers}, 0, 0, S_NULL}, // S_SNEAKERS_ICON2 + {SPR_TVSS, 2, 18, {NULL}, 0, 0, S_NULL}, // S_SNEAKERS_ICON2 {SPR_TVIV, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_INVULN_ICON2}, // S_INVULN_ICON1 - {SPR_TVIV, 2, 18, {A_Invincibility}, 0, 0, S_NULL}, // S_INVULN_ICON2 + {SPR_TVIV, 2, 18, {NULL}, 0, 0, S_NULL}, // S_INVULN_ICON2 {SPR_TV1U, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_1UP_ICON2}, // S_1UP_ICON1 {SPR_TV1U, 2, 18, {NULL}, 0, 0, S_NULL}, // S_1UP_ICON2 @@ -2162,7 +2170,7 @@ state_t states[NUMSTATES] = {SPR_TVMX, 2, 18, {A_MixUp}, 0, 0, S_NULL}, // S_MIXUP_ICON2 {SPR_TVGV, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_GRAVITY_ICON2}, // S_GRAVITY_ICON1 - {SPR_TVGV, 2, 18, {A_GravityBox}, 0, 0, S_NULL}, // S_GRAVITY_ICON2 + {SPR_TVGV, 2, 18, {NULL}, 0, 0, S_NULL}, // S_GRAVITY_ICON2 {SPR_TVRC, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_RECYCLER_ICON2}, // S_RECYCLER_ICON1 {SPR_TVRC, 2, 18, {NULL}, 0, 0, S_NULL}, // S_RECYCLER_ICON2 @@ -2174,13 +2182,13 @@ state_t states[NUMSTATES] = {SPR_TVTK, 2, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORE10K_ICON2 {SPR_TVFL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FLAMEAURA_ICON2}, // S_FLAMEAURA_ICON1 - {SPR_TVFL, 2, 18, {A_GiveShield}, SH_FLAMEAURA, 0, S_NULL}, // S_FLAMEAURA_ICON2 + {SPR_TVFL, 2, 18, {NULL}, 0, 0, S_NULL}, // S_FLAMEAURA_ICON2 {SPR_TVBB, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_BUBBLEWRAP_ICON2}, // S_BUBBLEWRAP_ICON1 - {SPR_TVBB, 2, 18, {A_GiveShield}, SH_BUBBLEWRAP, 0, S_NULL}, // S_BUBBLERWAP_ICON2 + {SPR_TVBB, 2, 18, {NULL}, 0, 0, S_NULL}, // S_BUBBLERWAP_ICON2 {SPR_TVZP, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_THUNDERCOIN_ICON2}, // S_THUNDERCOIN_ICON1 - {SPR_TVZP, 2, 18, {A_GiveShield}, SH_THUNDERCOIN, 0, S_NULL}, // S_THUNDERCOIN_ICON2 + {SPR_TVZP, 2, 18, {NULL}, 0, 0, S_NULL}, // S_THUNDERCOIN_ICON2 // --- @@ -4060,6 +4068,14 @@ state_t states[NUMSTATES] = {SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON + {SPR_ICAP, FF_ADD|0, -1, {A_SpawnItemCapsuleParts}, 0, 0, S_NULL}, // S_ITEMCAPSULE + {SPR_ICAP, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP_SIDE + {SPR_ICAP, FF_VERTICALFLIP|FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_AIR + {SPR_ICAP, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_GROUND + {SPR_ICAP, FF_FLOORSPRITE|3, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP + {SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM + {SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE + {SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1 {SPR_SGNS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2 {SPR_SGNS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3 @@ -4096,6 +4112,9 @@ state_t states[NUMSTATES] = {SPR_DRWS, FF_FULLBRIGHT|FF_TRANS20|2, 3, {NULL}, 0, 0, S_DRIFTWARNSPARK4}, // S_DRIFTWARNSPARK3 {SPR_DRWS, FF_FULLBRIGHT|FF_TRANS20|3, 3, {NULL}, 0, 0, S_NULL}, // S_DRIFTWARNSPARK4 + {SPR_DREL, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|FF_GLOBALANIM, 2, {NULL}, 5, 2, S_NULL}, // S_DRIFTELECTRICITY + {SPR_DRES, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 20, {NULL}, 1, 10, S_NULL}, // S_DRIFTELECTRICSPARK + {SPR_FAST, FF_PAPERSPRITE|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_FASTLINE2}, // S_FASTLINE1 {SPR_FAST, FF_PAPERSPRITE|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_FASTLINE3}, // S_FASTLINE2 {SPR_FAST, FF_PAPERSPRITE|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_FASTLINE4}, // S_FASTLINE3 @@ -5160,6 +5179,11 @@ state_t states[NUMSTATES] = {SPR_RGSP, FF_PAPERSPRITE|FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_RINGSPARKS15}, // S_RINGSPARKS14 {SPR_RGSP, FF_PAPERSPRITE|FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_NULL}, // S_RINGSPARKS15 + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE|11, -1, {NULL}, 3, 1, S_NULL}, // S_GAINAX_TINY + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE, 5, {NULL}, 5, 1, S_GAINAX_MID1}, // S_GAINAX_HUGE + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE|5, 14, {NULL}, 14, 1, S_GAINAX_MID2}, // S_GAINAX_MID1 + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE|19, -1, {NULL}, 1, 1, S_NULL}, // S_GAINAX_MID2 + {SPR_DRAF, 0, 2, {NULL}, 0, 0, S_DRAFTDUST2}, // S_DRAFTDUST1 {SPR_DRAF, 1, 1, {NULL}, 0, 0, S_DRAFTDUST3}, // S_DRAFTDUST2 {SPR_DRAF, 2, 1, {NULL}, 0, 0, S_DRAFTDUST4}, // S_DRAFTDUST3 @@ -5227,6 +5251,12 @@ state_t states[NUMSTATES] = {SPR_DEBT, 7|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_DEBTSPIKED}, // S_DEBTSPIKEC {SPR_DEBT, 6|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_DEBTSPIKEE}, // S_DEBTSPIKED {SPR_DEBT, 7|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_DEBTSPIKE1}, // S_DEBTSPIKEE + + // Sparks when driving on stairs + {SPR_JANK, 0, 1, {NULL}, 0, 0, S_JANKSPARK2}, // S_JANKSPARK1 + {SPR_JANK, FF_PAPERSPRITE|FF_FULLBRIGHT|FF_ANIMATE, 4, {NULL}, 3, 1, S_JANKSPARK3}, // S_JANKSPARK2 + {SPR_JANK, 0, 0, {A_SetCustomValue}, -1, 5, S_JANKSPARK4}, // S_JANKSPARK3 + {SPR_JANK, 0, 0, {A_ChangeAngleRelative}, 180, 180, S_JANKSPARK2}, // S_JANKSPARK4 }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -8656,7 +8686,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 20*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY, // flags + MF_SPECIAL|MF_NOGRAVITY, // flags S_BALLOONPOP1 // raisestate }, @@ -17454,7 +17484,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_ELEMENTAL, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17481,7 +17511,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_ATTRACT, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17508,7 +17538,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_FORCE, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17535,7 +17565,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_ARMAGEDDON, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17562,7 +17592,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_WHIRLWIND, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17589,7 +17619,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_PITY, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17616,7 +17646,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_FLAMEAURA, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height -4, // display offset @@ -17643,7 +17673,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_BUBBLEWRAP, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 4, // display offset @@ -17670,7 +17700,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_THUNDERCOIN, // speed + 0, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height -4, // display offset @@ -19763,7 +19793,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_bouncering, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19790,7 +19820,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_railring, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19817,7 +19847,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_infinityring,// mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19844,7 +19874,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_automaticring, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19871,7 +19901,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_explosionring, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19898,7 +19928,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_scatterring, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19925,7 +19955,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_grenadering, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19953,7 +19983,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_bouncering, // mass + 0, // mass 2*TICRATE, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -19980,7 +20010,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_railring, // mass + 0, // mass 2*TICRATE, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -20007,7 +20037,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_automaticring, // mass + 0, // mass 2*TICRATE, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -20034,7 +20064,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_explosionring, // mass + 0, // mass 2*TICRATE, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -20061,7 +20091,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_scatterring, // mass + 0, // mass 2*TICRATE, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -20088,7 +20118,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - pw_grenadering, // mass + 0, // mass 2*TICRATE, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags @@ -23041,6 +23071,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_ITEMCAPSULE + 2010, // doomednum + S_ITEMCAPSULE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_INVISIBLE, // deathstate + S_NULL, // xdeathstate + sfx_itcaps, // deathsound + 0, // speed + 56*FRACUNIT, // radius + 112*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_RUNSPAWNFUNC|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_ITEMCAPSULE_PART + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 26*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_SIGNSPARKLE -1, // doomednum S_SIGNSPARK1, // spawnstate @@ -23473,6 +23557,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_DRIFTELECTRICITY + -1, // doomednum + S_DRIFTELECTRICITY, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_DRIFTELECTRICSPARK + -1, // doomednum + S_DRIFTELECTRICSPARK, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 4*FRACUNIT, // speed + 9*FRACUNIT, // radius + 37*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_JANKSPARK + -1, // doomednum + S_JANKSPARK1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_FLOAT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_ROCKETSNEAKER -1, // doomednum S_ROCKETSNEAKER_L, // spawnstate @@ -28524,6 +28689,32 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, + { // MT_GAINAX + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8<kartstuff[k_position] == 1); -#else - UINT8 i; - - if (!(gametyperules & GTR_WANTED)) - return false; - - for (i = 0; i < 4; i++) - { - if (battlewanted[i] == -1) - break; - if (player == &players[battlewanted[i]]) - return true; - } - return false; -#endif -} - -void K_CalculateBattleWanted(void) -{ - UINT8 numingame = 0, numwanted = 0; - SINT8 camppos[MAXPLAYERS]; // who is the biggest camper - UINT8 ties = 0, nextcamppos = 0; - UINT8 i, j; - -#if 0 - if (!(gametyperules & GTR_WANTED)) -#endif - { - memset(battlewanted, -1, sizeof (battlewanted)); - return; - } - - wantedcalcdelay = wantedfrequency; - memset(camppos, -1, sizeof (camppos)); // initialize - - for (i = 0; i < MAXPLAYERS; i++) - { - UINT8 position = 1; - - if (!playeringame[i] || players[i].spectator) // Not playing - continue; - - if (players[i].exiting) // We're done, don't calculate. - return; - - if (players[i].bumpers <= 0) // Not alive, so don't do anything else - continue; - - numingame++; - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j] || players[j].spectator) - continue; - - if (players[j].bumpers <= 0) - continue; - - if (j == i) - continue; - - if (K_NumEmeralds(&players[j]) > K_NumEmeralds(&players[i])) - { - position++; - } - else if (players[j].bumpers > players[i].bumpers) - { - position++; - } - else if (players[j].marescore > players[i].marescore) - { - position++; - } - else if (players[j].kartstuff[k_wanted] > players[i].kartstuff[k_wanted]) - { - position++; - } - } - - position--; // Make zero based - - while (camppos[position] != -1) // Port priority! - position++; - - camppos[position] = i; - } - - if (numingame <= 2) // In 1v1s then there's no need for WANTED. - numwanted = 0; - else - numwanted = min(4, 1 + ((numingame-2) / 4)); - - for (i = 0; i < 4; i++) - { - if (i+1 > numwanted) // Not enough players for this slot to be wanted! - { - battlewanted[i] = -1; - } - else - { - // Do not add *any* more people if there's too many times that are tied with others. - // This could theoretically happen very easily if people don't hit each other for a while after the start of a match. - // (I will be sincerely impressed if more than 2 people tie after people start hitting each other though) - - if (camppos[nextcamppos] == -1 // Out of entries - || ties >= (numwanted-i)) // Already counted ties - { - battlewanted[i] = -1; - continue; - } - - if (ties < (numwanted-i)) - { - ties = 0; // Reset - for (j = 0; j < 2; j++) - { - if (camppos[nextcamppos+(j+1)] == -1) // Nothing beyond, cancel - break; - if (players[camppos[nextcamppos]].kartstuff[k_wanted] == players[camppos[nextcamppos+(j+1)]].kartstuff[k_wanted]) - ties++; - } - } - - if (ties < (numwanted-i)) // Is it still low enough after counting? - { - battlewanted[i] = camppos[nextcamppos]; - nextcamppos++; - } - else - battlewanted[i] = -1; - } - } + return (player->position == 1); } void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount) @@ -226,7 +93,7 @@ void K_CheckBumpers(void) return; numingame++; - winnerscoreadd += players[i].marescore; + winnerscoreadd += players[i].roundscore; if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner { @@ -237,7 +104,7 @@ void K_CheckBumpers(void) return; winnernum = i; - winnerscoreadd -= players[i].marescore; + winnerscoreadd -= players[i].roundscore; } if (numingame <= 1) @@ -253,7 +120,7 @@ void K_CheckBumpers(void) { for (i = 0; i < MAXPLAYERS; i++) { - players[i].pflags |= PF_GAMETYPEOVER; + players[i].pflags |= PF_NOCONTEST; P_DoPlayerExit(&players[i]); } } @@ -264,7 +131,7 @@ void K_CheckBumpers(void) if (winnernum > -1 && playeringame[winnernum]) { - players[winnernum].marescore += winnerscoreadd; + players[winnernum].roundscore += winnerscoreadd; CONS_Printf(M_GetText("%s recieved %d point%s for winning!\n"), player_names[winnernum], winnerscoreadd, (winnerscoreadd == 1 ? "" : "s")); } @@ -279,12 +146,12 @@ void K_CheckEmeralds(player_t *player) { UINT8 i; - if (!ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + if (!ALLCHAOSEMERALDS(player->emeralds)) { return; } - player->marescore++; // lol + player->roundscore++; // lol for (i = 0; i < MAXPLAYERS; i++) { @@ -312,7 +179,7 @@ mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT P_Thrust(emerald, FixedAngle(P_RandomFixed() * 180) + angle, - 32 * mapobjectscale); + 24 * mapobjectscale); emerald->momz = flip * 24 * mapobjectscale; if (emerald->eflags & MFE_UNDERWATER) @@ -371,12 +238,12 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) { UINT32 emeraldFlag = (1 << i); - if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) + if ((player->emeralds & emeraldFlag) && (emeraldFlag & emeraldType)) { mobj_t *emerald = K_SpawnChaosEmerald(player->mo->x, player->mo->y, player->mo->z, player->mo->angle - ANGLE_90, flip, emeraldFlag); P_SetTarget(&emerald->target, player->mo); - player->powers[pw_emeralds] &= ~emeraldFlag; + player->emeralds &= ~emeraldFlag; } } } @@ -390,7 +257,7 @@ UINT8 K_NumEmeralds(player_t *player) { UINT32 emeraldFlag = (1 << i); - if (player->powers[pw_emeralds] & emeraldFlag) + if (player->emeralds & emeraldFlag) { num++; } @@ -421,12 +288,6 @@ void K_RunPaperItemSpawners(void) if (overtime == true) { - if (battleovertime.radius < 512*mapobjectscale) - { - // Barrier has closed in too much - return; - } - // Double frequency of items interval /= 2; } @@ -443,9 +304,9 @@ void K_RunPaperItemSpawners(void) continue; } - emeraldsSpawned |= players[i].powers[pw_emeralds]; + emeraldsSpawned |= players[i].emeralds; - if ((players[i].exiting > 0 || players[i].eliminated) + if ((players[i].exiting > 0 || (players[i].pflags & PF_ELIMINATED)) || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) { continue; @@ -690,10 +551,12 @@ void K_RunBattleOvertime(void) } else if (battleovertime.radius > 0) { - if (battleovertime.radius > 2*mapobjectscale) + const fixed_t minradius = 768 * mapobjectscale; + + if (battleovertime.radius > minradius) battleovertime.radius -= 2*mapobjectscale; else - battleovertime.radius = 0; + battleovertime.radius = minradius; } if (battleovertime.radius > 0) diff --git a/src/k_battle.h b/src/k_battle.h index 4b1508cbf..221873b04 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -17,7 +17,7 @@ extern UINT8 maptargets, numtargets; INT32 K_StartingBumperCount(void); boolean K_IsPlayerWanted(player_t *player); -void K_CalculateBattleWanted(void); +#define K_CalculateBattleWanted() (void)0 // not nulled out so we know where we need to recalculate some other form of battle mode importance void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); void K_CheckEmeralds(player_t *player); diff --git a/src/k_bot.c b/src/k_bot.c index f6d3a993f..29aa4f177 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -274,10 +274,10 @@ boolean K_PlayerUsesBotMovement(player_t *player) boolean K_BotCanTakeCut(player_t *player) { if (!K_ApplyOffroad(player) - || player->kartstuff[k_itemtype] == KITEM_SNEAKER - || player->kartstuff[k_itemtype] == KITEM_ROCKETSNEAKER - || player->kartstuff[k_itemtype] == KITEM_INVINCIBILITY - || player->kartstuff[k_itemtype] == KITEM_HYUDORO) + || player->itemtype == KITEM_SNEAKER + || player->itemtype == KITEM_ROCKETSNEAKER + || player->itemtype == KITEM_INVINCIBILITY + || player->itemtype == KITEM_HYUDORO) return true; return false; @@ -716,9 +716,14 @@ static UINT8 K_TrySpindash(player_t *player) { const tic_t difficultyModifier = (TICRATE/6); - if (player->kartstuff[k_spindashboost] || player->kartstuff[k_tiregrease]) + const fixed_t oldSpeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); + const fixed_t baseAccel = K_GetNewSpeed(player) - oldSpeed; + const fixed_t speedDiff = player->speed - player->lastspeed; + + if (player->spindashboost || player->tiregrease) { // You just released a spindash, you don't need to try again yet, jeez. + player->botvars.spindashconfirm = 0; return 0; } @@ -749,15 +754,29 @@ static UINT8 K_TrySpindash(player_t *player) } // Logic for normal racing. - if (player->powers[pw_flashing] > 0) + if (player->flashing > 0) { // Don't bother trying to spindash. // Trying to spindash while flashing is fine during POSITION, but not during the actual race. return 0; } - if (player->speed < 10*mapobjectscale // Below the speed threshold - && player->kartstuff[k_speedboost] < (FRACUNIT/8)) // If you have other boosts, you can probably trust it. + if (speedDiff < (3 * baseAccel / 4)) + { + if (player->botvars.spindashconfirm < BOTSPINDASHCONFIRM) + { + player->botvars.spindashconfirm++; + } + } + else + { + if (player->botvars.spindashconfirm > 0) + { + player->botvars.spindashconfirm--; + } + } + + if (player->botvars.spindashconfirm >= BOTSPINDASHCONFIRM) { INT32 chargingPoint = (K_GetSpindashChargeTime(player) + difficultyModifier); @@ -765,7 +784,7 @@ static UINT8 K_TrySpindash(player_t *player) // Sounds counter-productive, but that's actually the best strategy after the race has started. chargingPoint -= player->botvars.difficulty * difficultyModifier; - if (player->kartstuff[k_spindash] > chargingPoint) + if (player->spindash > chargingPoint) { // Time to release. return 0; diff --git a/src/k_bot.h b/src/k_bot.h index 38408c6af..94694c2dd 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -23,6 +23,9 @@ // Made it as small as possible without making it look like the bots are twitching constantly. #define BOTTURNCONFIRM 4 +// How many tics without being able to accelerate before we'll let you spindash. +#define BOTSPINDASHCONFIRM (TICRATE/4) + // Point for bots to aim for typedef struct botprediction_s { fixed_t x, y; diff --git a/src/k_botitem.c b/src/k_botitem.c index 070f927c8..212a84929 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -64,7 +64,7 @@ static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t r if (target->mo == NULL || P_MobjWasRemoved(target->mo) || player == target || target->spectator - || target->powers[pw_flashing]) + || target->flashing) { continue; } @@ -117,7 +117,7 @@ static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t if (target->mo == NULL || P_MobjWasRemoved(target->mo) || player == target || target->spectator - || target->powers[pw_flashing]) + || target->flashing) { continue; } @@ -190,7 +190,7 @@ static boolean K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boo if (target->mo == NULL || P_MobjWasRemoved(target->mo) || player == target || target->spectator - || target->powers[pw_flashing] + || target->flashing || !P_CheckSight(player->mo, target->mo)) { continue; @@ -354,7 +354,7 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean --------------------------------------------------*/ static void K_BotItemGenericTrapShield(player_t *player, ticcmd_t *cmd, INT16 turnamt, boolean mine) { - if (player->kartstuff[k_itemheld]) + if (player->pflags & PF_ITEMOUT) { return; } @@ -379,7 +379,7 @@ static void K_BotItemGenericTrapShield(player_t *player, ticcmd_t *cmd, INT16 tu --------------------------------------------------*/ static void K_BotItemGenericOrbitShield(player_t *player, ticcmd_t *cmd) { - if (player->kartstuff[k_itemheld]) + if (player->pflags & PF_ITEMOUT) { return; } @@ -401,13 +401,13 @@ static void K_BotItemGenericOrbitShield(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd) { - if ((player->kartstuff[k_offroad] && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW + if ((player->offroad && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW || K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut! || player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much - || player->kartstuff[k_speedboost] > (FRACUNIT/8) // Have another type of boost (tethering) + || player->speedboost > (FRACUNIT/8) // Have another type of boost (tethering) || player->botvars.itemconfirm > 4*TICRATE) // Held onto it for too long { - if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN)) + if (!player->sneakertimer && !(player->pflags & PF_ATTACKDOWN)) { cmd->buttons |= BT_ATTACK; player->botvars.itemconfirm = 2*TICRATE; @@ -435,7 +435,7 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd) { if (player->botvars.itemconfirm > TICRATE) { - if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN)) + if (!player->sneakertimer && !(player->pflags & PF_ATTACKDOWN)) { cmd->buttons |= BT_ATTACK; player->botvars.itemconfirm = 0; @@ -487,7 +487,7 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) throwdir = -1; } - if (player->botvars.itemconfirm > 2*TICRATE || player->kartstuff[k_bananadrag] >= TICRATE) + if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -540,7 +540,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) - if (player->botvars.itemconfirm > 2*TICRATE || player->kartstuff[k_bananadrag] >= TICRATE) + if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -577,13 +577,13 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) throwdir = -1; } - if (stealth > 1 || player->kartstuff[k_itemroulette] > 0) + if (stealth > 1 || player->itemroulette > 0) { player->botvars.itemconfirm += player->botvars.difficulty * 4; throwdir = -1; } - if (player->botvars.itemconfirm > 2*TICRATE || player->kartstuff[k_bananadrag] >= TICRATE) + if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -639,7 +639,7 @@ static boolean K_BotRevealsEggbox(player_t *player) --------------------------------------------------*/ static void K_BotItemEggmanShield(player_t *player, ticcmd_t *cmd) { - if (player->kartstuff[k_eggmanheld]) + if (player->pflags & PF_EGGMANOUT) { return; } @@ -664,7 +664,7 @@ static void K_BotItemEggmanShield(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd) { - if (player->kartstuff[k_position] == 1) + if (player->position == 1) { cmd->forwardmove /= 2; cmd->buttons |= BT_BRAKE; @@ -746,7 +746,7 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) throwdir = -1; } - if (player->kartstuff[k_lastjawztarget] != -1) + if (player->lastjawztarget != -1) { player->botvars.itemconfirm += player->botvars.difficulty * 2; throwdir = 1; @@ -801,13 +801,13 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd) { boolean hold = false; - if (player->kartstuff[k_bubbleblowup] <= 0) + if (player->bubbleblowup <= 0) { UINT8 i; player->botvars.itemconfirm++; - if (player->kartstuff[k_bubblecool] <= 0) + if (player->bubblecool <= 0) { const fixed_t radius = 192 * player->mo->scale; @@ -825,7 +825,7 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd) if (target->mo == NULL || P_MobjWasRemoved(target->mo) || player == target || target->spectator - || target->powers[pw_flashing]) + || target->flashing) { continue; } @@ -844,19 +844,19 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd) } } } - else if (player->kartstuff[k_bubbleblowup] >= bubbletime) + else if (player->bubbleblowup >= bubbletime) { if (player->botvars.itemconfirm >= 10*TICRATE) { hold = true; } } - else if (player->kartstuff[k_bubbleblowup] < bubbletime) + else if (player->bubbleblowup < bubbletime) { hold = true; } - if (hold && player->kartstuff[k_holdready]) + if (hold && (player->pflags & PF_HOLDREADY)) { cmd->buttons |= BT_ATTACK; } @@ -880,11 +880,11 @@ static void K_BotItemFlame(player_t *player, ticcmd_t *cmd) { player->botvars.itemconfirm--; } - else if (player->kartstuff[k_holdready]) + else if (player->pflags & PF_HOLDREADY) { - INT32 flamemax = player->kartstuff[k_flamelength] * flameseg; + INT32 flamemax = player->flamelength * flameseg; - if (player->kartstuff[k_flamemeter] < flamemax || flamemax == 0) + if (player->flamemeter < flamemax || flamemax == 0) { cmd->buttons |= BT_ATTACK; } @@ -912,7 +912,7 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd) INT32 saferingsval = 16 - K_GetKartRingPower(player, false); if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much - || player->kartstuff[k_speedboost] > (FRACUNIT/5)) // Have another type of boost (tethering) + || player->speedboost > (FRACUNIT/5)) // Have another type of boost (tethering) { saferingsval -= 5; } @@ -967,7 +967,7 @@ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) { - if (player->kartstuff[k_userings] == 1) + if (player->pflags & PF_USERINGS) { // Use rings! @@ -985,33 +985,33 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) return; } - if (player->kartstuff[k_itemroulette]) + if (player->itemroulette) { // Mashing behaviors K_BotItemRouletteMash(player, cmd); return; } - if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0) + if (player->stealingtimer == 0) { - if (player->kartstuff[k_eggmanexplode]) + if (player->eggmanexplode) { K_BotItemEggmanExplosion(player, cmd); } - else if (player->kartstuff[k_eggmanheld]) + else if (player->pflags & PF_EGGMANOUT) { K_BotItemEggman(player, cmd); } - else if (player->kartstuff[k_rocketsneakertimer] > 0) + else if (player->rocketsneakertimer > 0) { K_BotItemRocketSneaker(player, cmd); } else { - switch (player->kartstuff[k_itemtype]) + switch (player->itemtype) { default: - if (player->kartstuff[k_itemtype] != KITEM_NONE) + if (player->itemtype != KITEM_NONE) { K_BotItemGenericTap(player, cmd); } @@ -1027,7 +1027,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) K_BotItemGenericTap(player, cmd); break; case KITEM_ROCKETSNEAKER: - if (player->kartstuff[k_rocketsneakertimer] <= 0) + if (player->rocketsneakertimer <= 0) { K_BotItemGenericTap(player, cmd); } @@ -1037,7 +1037,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) break; case KITEM_BANANA: case KITEM_LANDMINE: - if (!player->kartstuff[k_itemheld]) + if (!(player->pflags & PF_ITEMOUT)) { K_BotItemGenericTrapShield(player, cmd, turnamt, false); } @@ -1050,11 +1050,11 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) K_BotItemEggmanShield(player, cmd); break; case KITEM_ORBINAUT: - if (!player->kartstuff[k_itemheld]) + if (!(player->pflags & PF_ITEMOUT)) { K_BotItemGenericOrbitShield(player, cmd); } - else if (player->kartstuff[k_position] != 1) // Hold onto orbiting items when in 1st :) + else if (player->position != 1) // Hold onto orbiting items when in 1st :) /* FALL-THRU */ case KITEM_BALLHOG: { @@ -1062,17 +1062,17 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) } break; case KITEM_JAWZ: - if (!player->kartstuff[k_itemheld]) + if (!(player->pflags & PF_ITEMOUT)) { K_BotItemGenericOrbitShield(player, cmd); } - else if (player->kartstuff[k_position] != 1) // Hold onto orbiting items when in 1st :) + else if (player->position != 1) // Hold onto orbiting items when in 1st :) { K_BotItemJawz(player, cmd); } break; case KITEM_MINE: - if (!player->kartstuff[k_itemheld]) + if (!(player->pflags & PF_ITEMOUT)) { K_BotItemGenericTrapShield(player, cmd, turnamt, true); } diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 880eb5ef9..55533d02a 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -322,7 +322,7 @@ static boolean K_FindBlockingWalls(line_t *line) // set openrange, opentop, openbottom P_LineOpening(line, globalsmuggle.botmo); - if (globalsmuggle.botmo->player->kartstuff[k_waterskip]) + if (globalsmuggle.botmo->player->waterskip) maxstep += maxstepmove; if (P_MobjTouchingSectorSpecial(globalsmuggle.botmo, 1, 13, false)) @@ -648,18 +648,18 @@ static boolean K_FindObjectsForNudging(mobj_t *thing) break; } - if ((RINGTOTAL(globalsmuggle.botmo->player) < 20 && !globalsmuggle.botmo->player->kartstuff[k_ringlock] + if ((RINGTOTAL(globalsmuggle.botmo->player) < 20 && !(globalsmuggle.botmo->player->pflags & PF_RINGLOCK) && P_CanPickupItem(globalsmuggle.botmo->player, 0)) && !thing->extravalue1 - && (globalsmuggle.botmo->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD)) + && (globalsmuggle.botmo->player->itemtype != KITEM_THUNDERSHIELD)) { K_AddAttackObject(thing, side, (RINGTOTAL(globalsmuggle.botmo->player) < 3) ? 5 : 1); } break; case MT_PLAYER: if (thing->player - && !thing->player->kartstuff[k_hyudorotimer] - && !globalsmuggle.botmo->player->kartstuff[k_hyudorotimer]) + && !thing->player->hyudorotimer + && !globalsmuggle.botmo->player->hyudorotimer) { // There REALLY ought to be a better way to handle this logic, right?! // Squishing @@ -672,40 +672,40 @@ static boolean K_FindObjectsForNudging(mobj_t *thing) } // Invincibility else if (K_PlayerAttackSteer(thing, side, 20, - globalsmuggle.botmo->player->kartstuff[k_invincibilitytimer], - thing->player->kartstuff[k_invincibilitytimer] + globalsmuggle.botmo->player->invincibilitytimer, + thing->player->invincibilitytimer )) { break; } // Thunder Shield else if (K_PlayerAttackSteer(thing, side, 20, - globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD, - thing->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD + globalsmuggle.botmo->player->itemtype == KITEM_THUNDERSHIELD, + thing->player->itemtype == KITEM_THUNDERSHIELD )) { break; } // Bubble Shield else if (K_PlayerAttackSteer(thing, side, 20, - globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD, - thing->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD + globalsmuggle.botmo->player->itemtype == KITEM_BUBBLESHIELD, + thing->player->itemtype == KITEM_BUBBLESHIELD )) { break; } // Flame Shield else if (K_PlayerAttackSteer(thing, side, 20, - globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD, - thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD + globalsmuggle.botmo->player->itemtype == KITEM_FLAMESHIELD, + thing->player->itemtype == KITEM_FLAMESHIELD )) { break; } // Has held item shield else if (K_PlayerAttackSteer(thing, side, 20, - (globalsmuggle.botmo->player->kartstuff[k_itemheld] || globalsmuggle.botmo->player->kartstuff[k_eggmanheld]), - (thing->player->kartstuff[k_itemheld] || thing->player->kartstuff[k_eggmanheld]) + (thing->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)), + (globalsmuggle.botmo->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)) )) { break; diff --git a/src/k_collide.c b/src/k_collide.c index 2dba32202..96fe30182 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -30,14 +30,14 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if ((t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) + if ((t2->player->flashing > 0 && t2->hitlag == 0) && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD)) return true; - if (t2->player->kartstuff[k_hyudorotimer]) + if (t2->player->hyudorotimer) return true; // no interaction - if (t2->player->kartstuff[k_flamedash] && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) { // Melt item S_StartSound(t2, sfx_s3k43); @@ -46,7 +46,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) { // Player Damage P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT); - K_KartBouncing(t2, t1, false, false); + K_KartBouncing(t2, t1); S_StartSound(t2, sfx_s3k7b); } @@ -123,14 +123,14 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) + if (t2->player->flashing > 0 && t2->hitlag == 0) return true; // Banana snipe! if (t1->type == MT_BANANA && t1->health > 1) S_StartSound(t2, sfx_bsnipe); - if (t2->player->kartstuff[k_flamedash] && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) { // Melt item S_StartSound(t2, sfx_s3k43); @@ -206,23 +206,17 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if ((gametyperules & GTR_BUMPERS) && t2->player->bumpers <= 0) { -#ifdef OTHERKARMAMODES - if (t2->player->kartstuff[k_comebackmode] || t2->player->karmadelay) - return true; - t2->player->kartstuff[k_comebackmode] = 2; -#else return true; -#endif } else { K_DropItems(t2->player); //K_StripItems(t2->player); //K_StripOther(t2->player); - t2->player->kartstuff[k_itemroulette] = 1; - t2->player->kartstuff[k_roulettetype] = 2; + t2->player->itemroulette = 1; + t2->player->roulettetype = 2; } - if (t2->player->kartstuff[k_flamedash] && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) { // Melt item S_StartSound(t2, sfx_s3k43); @@ -243,14 +237,14 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (t1->target && t1->target->player) { if ((gametyperules & GTR_CIRCUIT) || t1->target->player->bumpers > 0) - t2->player->kartstuff[k_eggmanblame] = t1->target->player-players; + t2->player->eggmanblame = t1->target->player-players; else - t2->player->kartstuff[k_eggmanblame] = t2->player-players; + t2->player->eggmanblame = t2->player-players; if (t1->target->hnext == t1) { P_SetTarget(&t1->target->hnext, NULL); - t1->target->player->kartstuff[k_eggmanheld] = 0; + t1->target->player->pflags &= ~PF_EGGMANOUT; } } @@ -272,7 +266,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) + if (t2->player->flashing > 0 && t2->hitlag == 0) return true; // Bomb punting @@ -314,7 +308,7 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) { if (t2->player) { - if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) + if (t2->player->flashing > 0 && t2->hitlag == 0) return true; if (t1->state == &states[S_MINEEXPLOSION1]) @@ -345,14 +339,14 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing]) + if (t2->player->flashing) return true; // Banana snipe! if (t1->health > 1) S_StartSound(t2, sfx_bsnipe); - if (t2->player->kartstuff[k_flamedash] && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) { // Melt item S_StartSound(t2, sfx_s3k43); @@ -409,7 +403,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) + if (t2->player->flashing > 0 && t2->hitlag == 0) return true; S_StartSound(NULL, sfx_bsnipe); // let all players hear it. @@ -436,7 +430,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2) { if (t2->player || t2->type == MT_FALLINGROCK) - K_KartBouncing(t2, t1, false, false); + K_KartBouncing(t2, t1); return true; } @@ -458,13 +452,13 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) P_KillMobj(t1, t2, t2, DMG_NORMAL); /* - if (t2->player && (t2->player->kartstuff[k_invincibilitytimer] > 0 - || t2->player->kartstuff[k_growshrinktimer] > 0)) + if (t2->player && (t2->player->invincibilitytimer > 0 + || t2->player->growshrinktimer > 0)) return true; */ - K_KartBouncing(t2, t1, false, true); - return false; + K_KartSolidBounce(t1, t2); + return true; } boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) @@ -489,8 +483,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) } // Invincibility damage - t1Condition = (t1->player->kartstuff[k_invincibilitytimer] > 0); - t2Condition = (t2->player->kartstuff[k_invincibilitytimer] > 0); + t1Condition = (t1->player->invincibilitytimer > 0); + t2Condition = (t2->player->invincibilitytimer > 0); if (t1Condition == true && t2Condition == false) { @@ -504,8 +498,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) } // Flame Shield dash damage - t1Condition = (t1->player->kartstuff[k_flamedash] > 0 && t1->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD); - t2Condition = (t2->player->kartstuff[k_flamedash] > 0 && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD); + t1Condition = (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD); + t2Condition = (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD); if (t1Condition == true && t2Condition == false) { @@ -522,8 +516,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) // (Pogo Spring damage is handled in head-stomping code) if (gametyperules & GTR_BUMPERS) { - t1Condition = (t1->player->kartstuff[k_sneakertimer] > 0 && t1->player->powers[pw_flashing] != 0); - t2Condition = (t2->player->kartstuff[k_sneakertimer] > 0 && t2->player->powers[pw_flashing] != 0); + t1Condition = (t1->player->sneakertimer > 0 && t1->player->flashing != 0); + t2Condition = (t2->player->sneakertimer > 0 && t2->player->flashing != 0); if (t1Condition == true && t2Condition == false) { @@ -538,30 +532,29 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) } // Ring sting, this is a bit more unique - t1Condition = (K_GetShieldFromItem(t2->player->kartstuff[k_itemtype]) == KSHIELD_NONE); - t2Condition = (K_GetShieldFromItem(t1->player->kartstuff[k_itemtype]) == KSHIELD_NONE); + t1Condition = (K_GetShieldFromItem(t2->player->itemtype) == KSHIELD_NONE); + t2Condition = (K_GetShieldFromItem(t1->player->itemtype) == KSHIELD_NONE); if (t1Condition == true) { + P_PlayerRingBurst(t2->player, 1); + if (t2->player->rings <= 0) { P_DamageMobj(t2, t1, t1, 1, DMG_STING); stung = true; } - - P_PlayerRingBurst(t2->player, 1); - stung = true; } if (t2Condition == true) { + P_PlayerRingBurst(t1->player, 1); + if (t1->player->rings <= 0) { P_DamageMobj(t1, t2, t2, 1, DMG_STING); stung = true; } - - P_PlayerRingBurst(t2->player, 1); } return stung; diff --git a/src/k_color.c b/src/k_color.c index 6cfe4d5a8..0821c4437 100644 --- a/src/k_color.c +++ b/src/k_color.c @@ -90,6 +90,59 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) } } +/*-------------------------------------------------- + UINT8 K_HitlagColorValue(RGBA_t color) + + See header file for description. +--------------------------------------------------*/ +UINT8 K_HitlagColorValue(RGBA_t color) +{ + // Outputs a raw brightness value (makes OGL support easier) + INT32 output = K_ColorRelativeLuminance(color.s.red, color.s.green, color.s.blue); + + // Invert the color + output = 255 - output; + + // Increase the contrast + output = ((output-128) * 2) + 128; + + // Make sure to cap it. + if (output > 255) + { + output = 255; + } + else if (output < 0) + { + output = 0; + } + + return output; +} + +/*-------------------------------------------------- + void K_HitlagColormap(UINT8 *dest_colormap) + + See header file for description. +--------------------------------------------------*/ +void K_HitlagColormap(UINT8 *dest_colormap) +{ + RGBA_t color; + UINT8 v, offset; + INT32 i; + + // for every colour in the palette, invert, greyscale, and increase the contrast. + for (i = 0; i < NUM_PALETTE_ENTRIES; i++) + { + color = V_GetColor(i); + v = K_HitlagColorValue(color); + + // Convert raw brightness value to an offset from the greyscale palette line + offset = (255 - v) / 8; + + dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves. + } +} + /*-------------------------------------------------- void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) @@ -100,13 +153,18 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) INT32 i; INT32 starttranscolor; - // Handle a couple of simple special cases - if (skinnum == TC_BOSS + if (skinnum == TC_HITLAG) + { + K_HitlagColormap(dest_colormap); + return; + } + else if (skinnum == TC_BOSS || skinnum == TC_ALLWHITE || skinnum == TC_METALSONIC || skinnum == TC_BLINK || color == SKINCOLOR_NONE) { + // Handle a couple of simple special cases for (i = 0; i < NUM_PALETTE_ENTRIES; i++) { if (skinnum == TC_ALLWHITE) diff --git a/src/k_color.h b/src/k_color.h index e90ab0fc4..6e6778d75 100644 --- a/src/k_color.h +++ b/src/k_color.h @@ -66,6 +66,35 @@ UINT16 K_RainbowColor(tic_t time); void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); +/*-------------------------------------------------- + UINT8 K_HitlagColorValue(RGBA_t color); + + Gets the new replacement brightness value for the hitlag effect. + + Input Arguments:- + color - Input color we intend to replace. + + Return:- + 0 to 255 brightness value. +--------------------------------------------------*/ + +UINT8 K_HitlagColorValue(RGBA_t color); + +/*-------------------------------------------------- + void K_HitlagColormap(UINT8 *dest_colormap); + + Generates a inverted hi-contrast greyscale colormap, + for the hitlag effect. + + Input Arguments:- + dest_colormap - Colormap to populate. + + Return:- + None +--------------------------------------------------*/ + +void K_HitlagColormap(UINT8 *dest_colormap); + /*-------------------------------------------------- void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); diff --git a/src/k_grandprix.c b/src/k_grandprix.c index e46a6a7be..c9e6b391b 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -472,7 +472,7 @@ void K_IncreaseBotDifficulty(player_t *bot) // Increment bot difficulty based on what position you were meant to come in! expectedstanding = K_BotExpectedStanding(bot); - standingdiff = expectedstanding - bot->kartstuff[k_position]; + standingdiff = expectedstanding - bot->position; if (standingdiff >= -2) { @@ -533,7 +533,7 @@ void K_FakeBotResults(player_t *bot) if (besttime == UINT32_MAX // No one finished, so you don't finish either. || bot->distancetofinish >= worstdist) // Last place, you aren't going to finish. { - bot->pflags |= PF_GAMETYPEOVER; + bot->pflags |= PF_NOCONTEST; return; } @@ -556,13 +556,13 @@ void K_PlayerLoseLife(player_t *player) return; } - if (player->spectator || player->exiting || player->bot || player->lostlife) + if (player->spectator || player->exiting || player->bot || (player->pflags & PF_LOSTLIFE)) { return; } player->lives--; - player->lostlife = true; + player->pflags |= PF_LOSTLIFE; #if 0 if (player->lives <= 0) diff --git a/src/k_hud.c b/src/k_hud.c index 31bf7cabc..0068bc836 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -162,6 +162,8 @@ static patch_t *kp_cpu; static patch_t *kp_nametagstem; +static patch_t *kp_trickcool[2]; + void K_LoadKartHUDGraphics(void) { INT32 i, j; @@ -601,6 +603,9 @@ void K_LoadKartHUDGraphics(void) kp_cpu = (patch_t *) W_CachePatchName("K_CPU", PU_HUDGFX); kp_nametagstem = (patch_t *) W_CachePatchName("K_NAMEST", PU_HUDGFX); + + kp_trickcool[0] = W_CachePatchName("K_COOL1", PU_HUDGFX); + kp_trickcool[1] = W_CachePatchName("K_COOL2", PU_HUDGFX); } // For the item toggle menu @@ -679,6 +684,9 @@ INT32 ITEM2_X, ITEM2_Y; INT32 LAPS2_X, LAPS2_Y; INT32 POSI2_X, POSI2_Y; +// trick "cool" +INT32 TCOOL_X, TCOOL_Y; + void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 dupy) { @@ -982,6 +990,10 @@ static void K_initKartHUD(void) WANT_X = BASEVIDWIDTH - 55; // 270 WANT_Y = BASEVIDHEIGHT- 71; // 176 + // trick COOL + TCOOL_X = (BASEVIDWIDTH)/2; + TCOOL_Y = (BASEVIDHEIGHT)/2 -10; + if (r_splitscreen) // Splitscreen { ITEM_X = 5; @@ -1024,6 +1036,8 @@ static void K_initKartHUD(void) MINI_X = (3*BASEVIDWIDTH/4); MINI_Y = (3*BASEVIDHEIGHT/4); + TCOOL_X = (BASEVIDWIDTH)/4; + if (r_splitscreen > 2) // 4P-only { MINI_X = (BASEVIDWIDTH/2); @@ -1045,7 +1059,7 @@ static void K_drawKartItem(void) patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]); patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]); INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags... - const INT32 numberdisplaymin = ((!offset && stplyr->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2); + const INT32 numberdisplaymin = ((!offset && stplyr->itemtype == KITEM_ORBINAUT) ? 5 : 2); INT32 itembar = 0; INT32 maxl = 0; // itembar's normal highest value const INT32 barlength = (r_splitscreen > 1 ? 12 : 26); @@ -1054,12 +1068,12 @@ static void K_drawKartItem(void) UINT8 *colmap = NULL; boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff - if (stplyr->kartstuff[k_itemroulette]) + if (stplyr->itemroulette) { if (stplyr->skincolor) localcolor = stplyr->skincolor; - switch((stplyr->kartstuff[k_itemroulette] % (15*3)) / 3) + switch((stplyr->itemroulette % (15*3)) / 3) { // Each case is handled in threes, to give three frames of in-game time to see the item on the roulette case 0: // Sneaker @@ -1144,27 +1158,27 @@ static void K_drawKartItem(void) // The only actual reason is to make sneakers line up this way in the code below // This shouldn't have any actual baring over how it functions // Hyudoro is first, because we're drawing it on top of the player's current item - if (stplyr->kartstuff[k_stolentimer] > 0) + if (stplyr->stealingtimer < 0) { if (leveltime & 2) localpatch = kp_hyudoro[offset]; else localpatch = kp_nodraw; } - else if ((stplyr->kartstuff[k_stealingtimer] > 0) && (leveltime & 2)) + else if ((stplyr->stealingtimer > 0) && (leveltime & 2)) { localpatch = kp_hyudoro[offset]; } - else if (stplyr->kartstuff[k_eggmanexplode] > 1) + else if (stplyr->eggmanexplode > 1) { if (leveltime & 1) localpatch = kp_eggman[offset]; else localpatch = kp_nodraw; } - else if (stplyr->kartstuff[k_rocketsneakertimer] > 1) + else if (stplyr->rocketsneakertimer > 1) { - itembar = stplyr->kartstuff[k_rocketsneakertimer]; + itembar = stplyr->rocketsneakertimer; maxl = (itemtime*3) - barlength; if (leveltime & 1) @@ -1172,7 +1186,7 @@ static void K_drawKartItem(void) else localpatch = kp_nodraw; } - else if (stplyr->kartstuff[k_sadtimer] > 0) + else if (stplyr->sadtimer > 0) { if (leveltime & 2) localpatch = kp_sadface[offset]; @@ -1181,10 +1195,10 @@ static void K_drawKartItem(void) } else { - if (stplyr->kartstuff[k_itemamount] <= 0) + if (stplyr->itemamount <= 0) return; - switch(stplyr->kartstuff[k_itemtype]) + switch(stplyr->itemtype) { case KITEM_SNEAKER: localpatch = kp_sneaker[offset]; @@ -1203,7 +1217,7 @@ static void K_drawKartItem(void) localpatch = kp_eggman[offset]; break; case KITEM_ORBINAUT: - localpatch = kp_orbinaut[(offset ? 4 : min(stplyr->kartstuff[k_itemamount]-1, 3))]; + localpatch = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))]; break; case KITEM_JAWZ: localpatch = kp_jawz[offset]; @@ -1258,7 +1272,7 @@ static void K_drawKartItem(void) return; } - if (stplyr->kartstuff[k_itemheld] && !(leveltime & 1)) + if ((stplyr->pflags & PF_ITEMOUT) && !(leveltime & 1)) localpatch = kp_nodraw; } @@ -1311,19 +1325,19 @@ static void K_drawKartItem(void) V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); // Then, the numbers: - if (stplyr->kartstuff[k_itemamount] >= numberdisplaymin && !stplyr->kartstuff[k_itemroulette]) + if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette) { V_DrawScaledPatch(fx + (flipamount ? 48 : 0), fy, V_HUDTRANS|V_SLIDEIN|fflags|(flipamount ? V_FLIP : 0), kp_itemmulsticker[offset]); // flip this graphic for p2 and p4 in split and shift it. V_DrawFixedPatch(fx<kartstuff[k_itemamount])); + V_DrawString(fx+2, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount)); else - V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->kartstuff[k_itemamount])); + V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount)); else { V_DrawScaledPatch(fy+28, fy+41, V_HUDTRANS|V_SLIDEIN|fflags, kp_itemx); - V_DrawKartString(fx+38, fy+36, V_HUDTRANS|V_SLIDEIN|fflags, va("%d", stplyr->kartstuff[k_itemamount])); + V_DrawKartString(fx+38, fy+36, V_HUDTRANS|V_SLIDEIN|fflags, va("%d", stplyr->itemamount)); } } else @@ -1351,17 +1365,17 @@ static void K_drawKartItem(void) } // Quick Eggman numbers - if (stplyr->kartstuff[k_eggmanexplode] > 1 /*&& stplyr->kartstuff[k_eggmanexplode] <= 3*TICRATE*/) - V_DrawScaledPatch(fx+17, fy+13-offset, V_HUDTRANS|V_SLIDEIN|fflags, kp_eggnum[min(3, G_TicsToSeconds(stplyr->kartstuff[k_eggmanexplode]))]); + if (stplyr->eggmanexplode > 1) + V_DrawScaledPatch(fx+17, fy+13-offset, V_HUDTRANS|V_SLIDEIN|fflags, kp_eggnum[min(3, G_TicsToSeconds(stplyr->eggmanexplode))]); - if (stplyr->kartstuff[k_itemtype] == KITEM_FLAMESHIELD && stplyr->kartstuff[k_flamelength] > 0) + if (stplyr->itemtype == KITEM_FLAMESHIELD && stplyr->flamelength > 0) { INT32 numframes = 104; INT32 absolutemax = 16 * flameseg; - INT32 flamemax = stplyr->kartstuff[k_flamelength] * flameseg; - INT32 flamemeter = min(stplyr->kartstuff[k_flamemeter], flamemax); + INT32 flamemax = stplyr->flamelength * flameseg; + INT32 flamemeter = min(stplyr->flamemeter, flamemax); - INT32 bf = 16 - stplyr->kartstuff[k_flamelength]; + INT32 bf = 16 - stplyr->flamelength; INT32 ff = numframes - ((flamemeter * numframes) / absolutemax); INT32 fmin = (8 * (bf-1)); @@ -1385,9 +1399,9 @@ static void K_drawKartItem(void) if (bf >= 0 && bf < 16) V_DrawScaledPatch(fx-xo, fy-yo, V_HUDTRANS|V_SLIDEIN|fflags|flip, kp_flameshieldmeter_bg[bf][offset]); - if (ff >= 0 && ff < numframes && stplyr->kartstuff[k_flamemeter] > 0) + if (ff >= 0 && ff < numframes && stplyr->flamemeter > 0) { - if ((stplyr->kartstuff[k_flamemeter] > flamemax) && (leveltime & 1)) + if ((stplyr->flamemeter > flamemax) && (leveltime & 1)) { UINT8 *fsflash = R_GetTranslationColormap(TC_BLINK, SKINCOLOR_WHITE, GTC_CACHE); V_DrawMappedPatch(fx-xo, fy-yo, V_HUDTRANS|V_SLIDEIN|fflags|flip, kp_flameshieldmeter[ff][offset], fsflash); @@ -1572,7 +1586,7 @@ static void K_DrawKartPositionNum(INT32 num) addOrSub = V_SUBTRACT; } - if (stplyr->kartstuff[k_positiondelay] || stplyr->exiting) + if (stplyr->positiondelay || stplyr->exiting) { scale *= 2; overtake = true; // this is used for splitscreen stuff in conjunction with flipdraw. @@ -1735,11 +1749,11 @@ static boolean K_drawKartPositionFaces(void) if (completed[i] || !playeringame[i] || players[i].spectator || !players[i].mo) continue; - if (players[i].kartstuff[k_position] >= lowestposition) + if (players[i].position >= lowestposition) continue; rankplayer[ranklines] = i; - lowestposition = players[i].kartstuff[k_position]; + lowestposition = players[i].position; } i = rankplayer[ranklines]; @@ -1816,7 +1830,7 @@ static boolean K_drawKartPositionFaces(void) UINT32 emeraldFlag = (1 << j); UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + j; - if (players[rankplayer[i]].powers[pw_emeralds] & emeraldFlag) + if (players[rankplayer[i]].emeralds & emeraldFlag) { colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); V_DrawMappedPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemerald, colormap); @@ -1831,7 +1845,7 @@ static boolean K_drawKartPositionFaces(void) V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers); else { - INT32 pos = players[rankplayer[i]].kartstuff[k_position]; + INT32 pos = players[rankplayer[i]].position; if (pos < 0 || pos > MAXPLAYERS) pos = 0; // Draws the little number over the face @@ -1868,7 +1882,7 @@ static void K_drawKartEmeralds(void) UINT32 emeraldFlag = (1 << i); UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + i; - if (stplyr->powers[pw_emeralds] & emeraldFlag) + if (stplyr->emeralds & emeraldFlag) { boolean whiteFlash = (leveltime & 1); UINT8 *colormap; @@ -1997,7 +2011,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers); else { - INT32 pos = players[tab[i].num].kartstuff[k_position]; + INT32 pos = players[tab[i].num].position; if (pos < 0 || pos > MAXPLAYERS) pos = 0; // Draws the little number over the face @@ -2011,7 +2025,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN { if (players[tab[i].num].exiting) V_DrawRightAlignedThinString(x+rightoffset, y-1, hilicol|V_6WIDTHSPACE, timestring(players[tab[i].num].realtime)); - else if (players[tab[i].num].pflags & PF_GAMETYPEOVER) + else if (players[tab[i].num].pflags & PF_NOCONTEST) V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, "NO CONTEST."); else if (circuitmap) V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, va("Lap %d", tab[i].count)); @@ -2020,7 +2034,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN { if (players[tab[i].num].exiting) V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime)); - else if (players[tab[i].num].pflags & PF_GAMETYPEOVER) + else if (players[tab[i].num].pflags & PF_NOCONTEST) V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "NO CONTEST."); else if (circuitmap) V_DrawRightAlignedString(x+rightoffset, y, 0, va("Lap %d", tab[i].count)); @@ -2146,7 +2160,7 @@ static void K_drawKartLapsAndRings(void) V_DrawMappedPatch(fr+15, fy-10, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[1]], ringmap); // SPB ring lock - if (stplyr->kartstuff[k_ringlock]) + if (stplyr->pflags & PF_RINGLOCK) V_DrawScaledPatch(fr-12, fy-23, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringspblocksmall[stplyr->karthud[khud_ringspblock]]); // Lives @@ -2184,7 +2198,7 @@ static void K_drawKartLapsAndRings(void) } // SPB ring lock - if (stplyr->kartstuff[k_ringlock]) + if (stplyr->pflags & PF_RINGLOCK) V_DrawScaledPatch(LAPS_X-5, LAPS_Y-28, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringspblock[stplyr->karthud[khud_ringspblock]]); // Lives @@ -2446,7 +2460,8 @@ static void K_drawKartBumpersOrKarma(void) else V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper)); + // TODO BETTER HUD + V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d %d", stplyr->bumpers, maxbumper, stplyr->overtimekarma / TICRATE)); } } } @@ -2602,16 +2617,16 @@ static void K_drawKartPlayerCheck(void) continue; } - if ((checkplayer->kartstuff[k_invincibilitytimer] <= 0) && (leveltime & 2)) + if ((checkplayer->invincibilitytimer <= 0) && (leveltime & 2)) { pnum++; // white frames } - if (checkplayer->kartstuff[k_itemtype] == KITEM_GROW || checkplayer->kartstuff[k_growshrinktimer] > 0) + if (checkplayer->itemtype == KITEM_GROW || checkplayer->growshrinktimer > 0) { pnum += 4; } - else if (checkplayer->kartstuff[k_itemtype] == KITEM_INVINCIBILITY || checkplayer->kartstuff[k_invincibilitytimer]) + else if (checkplayer->itemtype == KITEM_INVINCIBILITY || checkplayer->invincibilitytimer) { pnum += 2; } @@ -2645,8 +2660,8 @@ static boolean K_ShowPlayerNametag(player_t *p) if (gametyperules & GTR_CIRCUIT) { - if ((p->kartstuff[k_position] < stplyr->kartstuff[k_position]-2) - || (p->kartstuff[k_position] > stplyr->kartstuff[k_position]+2)) + if ((p->position < stplyr->position-2) + || (p->position > stplyr->position+2)) { return false; } @@ -3144,10 +3159,10 @@ static void K_drawKartMinimap(void) if (gametype == GT_BATTLE && players[i].bumpers <= 0) continue; - if (players[i].kartstuff[k_hyudorotimer] > 0) + if (players[i].hyudorotimer > 0) { - if (!((players[i].kartstuff[k_hyudorotimer] < TICRATE/2 - || players[i].kartstuff[k_hyudorotimer] > hyu-(TICRATE/2)) + if (!((players[i].hyudorotimer < TICRATE/2 + || players[i].hyudorotimer > hyu-(TICRATE/2)) && !(leveltime & 1))) continue; } @@ -3178,7 +3193,7 @@ static void K_drawKartMinimap(void) K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); // Target reticule - if ((gametype == GT_RACE && players[i].kartstuff[k_position] == spbplace) + if ((gametype == GT_RACE && players[i].position == spbplace) || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i]))) K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); } @@ -3231,7 +3246,7 @@ static void K_drawKartMinimap(void) K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); // Target reticule - if ((gametype == GT_RACE && players[localplayers[i]].kartstuff[k_position] == spbplace) + if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace) || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]]))) K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); } @@ -3569,7 +3584,7 @@ static void K_drawBattleFullscreen(void) if (K_IsPlayerLosing(stplyr)) p = kp_battlelose; - else if (stplyr->kartstuff[k_position] == 1) + else if (stplyr->position == 1) p = kp_battlewin; V_DrawFixedPatch(x<steering/50) tn -= (tn - (stplyr->steering/50))/8; - if (dr != stplyr->kartstuff[k_drift]*16) - dr -= (dr - (stplyr->kartstuff[k_drift]*16))/8; + if (dr != stplyr->drift*16) + dr -= (dr - (stplyr->drift*16))/8; if (r_splitscreen == 1) { @@ -3721,14 +3736,14 @@ static void K_drawKartFirstPerson(void) if (stplyr->mo) { - UINT8 driftcolor = K_DriftSparkColor(stplyr, stplyr->kartstuff[k_driftcharge]); + UINT8 driftcolor = K_DriftSparkColor(stplyr, stplyr->driftcharge); const angle_t ang = R_PointToAngle2(0, 0, stplyr->rmomx, stplyr->rmomy) - stplyr->drawangle; // yes, the following is correct. no, you do not need to swap the x and y. fixed_t xoffs = -P_ReturnThrustY(stplyr->mo, ang, (BASEVIDWIDTH<<(FRACBITS-2))/2); fixed_t yoffs = -P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT); // hitlag vibrating - if (stplyr->mo->hitlag > 0) + if (stplyr->mo->hitlag > 0 && (stplyr->mo->eflags & MFE_DAMAGEHITLAG)) { fixed_t mul = stplyr->mo->hitlag * (FRACUNIT / 10); if (r_splitscreen && mul > FRACUNIT) @@ -3951,6 +3966,32 @@ static void K_drawLapStartAnim(void) } } +// stretch for "COOOOOL" popup. +// I can't be fucked to find out any math behind this so have a table lmao +static fixed_t stretch[6][2] = { + {FRACUNIT/4, FRACUNIT*4}, + {FRACUNIT/2, FRACUNIT*2}, + {FRACUNIT, FRACUNIT}, + {FRACUNIT*4, FRACUNIT/2}, + {FRACUNIT*8, FRACUNIT/4}, + {FRACUNIT*4, FRACUNIT/2}, +}; + +static void K_drawTrickCool(void) +{ + + tic_t timer = TICRATE - stplyr->karthud[khud_trickcool]; + + if (timer <= 6) + { + V_DrawStretchyFixedPatch(TCOOL_X<distancetofinish - players[i].distancetofinish; @@ -4062,28 +4104,32 @@ static void K_drawDistributionDebugger(void) } } - if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items - pdis = (15 * pdis) / 14; - - if (spbplace != -1 && stplyr->kartstuff[k_position] == spbplace+1) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell + if (spbplace != -1 && stplyr->position == spbplace+1) { + // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell pdis = (3 * pdis) / 2; spbrush = true; } + pdis = K_ScaleItemDistance(pdis, pingame, spbrush); + if (stplyr->bot && stplyr->botvars.rival) { // Rival has better odds :) pdis = (15 * pdis) / 14; } - pdis = ((28 + (8-pingame)) * pdis) / 28; // scale with player count - useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush); for (i = 1; i < NUMKARTRESULTS; i++) { - const INT32 itemodds = K_KartGetItemOdds(useodds, i, 0, spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival)); + INT32 itemodds = K_KartGetItemOdds( + useodds, i, + stplyr->distancetofinish, + 0, + spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival) + ); + if (itemodds <= 0) continue; @@ -4105,6 +4151,9 @@ static void K_drawDistributionDebugger(void) case KRITEM_DUALJAWZ: amount = 2; break; + case KRITEM_DUALSNEAKER: + amount = 2; + break; default: amount = 3; break; @@ -4172,7 +4221,7 @@ void K_drawKartHUD(void) && (stplyr->exiting || (stplyr->bumpers <= 0 && stplyr->karmadelay > 0 - && stplyr->eliminated == false + && !(stplyr->pflags & PF_ELIMINATED) && comeback == true && stplyr->playerstate == PST_LIVE))); @@ -4255,7 +4304,7 @@ void K_drawKartHUD(void) { // Draw the numerical position if (LUA_HudEnabled(hud_position)) - K_DrawKartPositionNum(stplyr->kartstuff[k_position]); + K_DrawKartPositionNum(stplyr->position); } else //if (!(demo.playback && hu_showscores)) { @@ -4315,6 +4364,10 @@ void K_drawKartHUD(void) K_drawLapStartAnim(); } + // trick panel cool trick + if (stplyr->karthud[khud_trickcool]) + K_drawTrickCool(); + if (modeattacking || freecam) // everything after here is MP and debug only return; @@ -4328,7 +4381,7 @@ void K_drawKartHUD(void) K_drawKartFreePlay(); } - if (r_splitscreen == 0 && stplyr->kartstuff[k_wrongway] && ((leveltime / 8) & 1)) + if (r_splitscreen == 0 && (stplyr->pflags & PF_WRONGWAY) && ((leveltime / 8) & 1)) { V_DrawCenteredString(BASEVIDWIDTH>>1, 176, V_REDMAP|V_SNAPTOBOTTOM, "WRONG WAY"); } diff --git a/src/k_kart.c b/src/k_kart.c index bf8065e49..bb709a850 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -269,15 +269,15 @@ boolean K_IsPlayerLosing(player_t *player) if (battlecapsules && player->bumpers <= 0) return true; // DNF in break the capsules - if (player->kartstuff[k_position] == 1) + if (player->position == 1) return false; for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) continue; - if (players[i].kartstuff[k_position] > pcount) - pcount = players[i].kartstuff[k_position]; + if (players[i].position > pcount) + pcount = players[i].position; } if (pcount <= 1) @@ -287,7 +287,7 @@ boolean K_IsPlayerLosing(player_t *player) if (pcount % 2) // any remainder? winningpos++; - return (player->kartstuff[k_position] > winningpos); + return (player->position > winningpos); } fixed_t K_GetKartGameSpeedScalar(SINT8 value) @@ -348,7 +348,7 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = /*Mine*/ { 0, 2, 3, 1, 0, 0, 0, 0 }, // Mine /*Land Mine*/ { 4, 0, 0, 0, 0, 0, 0, 0 }, // Land Mine /*Ballhog*/ { 0, 0, 2, 1, 0, 0, 0, 0 }, // Ballhog - /*Self-Propelled Bomb*/ { 0, 1, 2, 3, 4, 2, 2, 0 }, // Self-Propelled Bomb + /*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb /*Grow*/ { 0, 0, 0, 1, 2, 3, 0, 0 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink /*Thunder Shield*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield @@ -400,6 +400,9 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = }; #define DISTVAR (2048) // Magic number distance for use with item roulette tiers +#define SPBSTARTDIST (5*DISTVAR) // Distance when SPB is forced onto 2nd place +#define SPBFORCEDIST (15*DISTVAR) // Distance when SPB is forced onto 2nd place +#define ENDDIST (12*DISTVAR) // Distance when the game stops giving you bananas // Array of states to pick the starting point of the animation, based on the actual time left for invincibility. static INT32 K_SparkleTrailStartStates[KART_NUMINVSPARKLESANIM][2] = { @@ -450,47 +453,98 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) { // Special roulettes first, then the generic ones are handled by default case KRITEM_DUALSNEAKER: // Sneaker x2 - player->kartstuff[k_itemtype] = KITEM_SNEAKER; - player->kartstuff[k_itemamount] = 2; + player->itemtype = KITEM_SNEAKER; + player->itemamount = 2; break; case KRITEM_TRIPLESNEAKER: // Sneaker x3 - player->kartstuff[k_itemtype] = KITEM_SNEAKER; - player->kartstuff[k_itemamount] = 3; + player->itemtype = KITEM_SNEAKER; + player->itemamount = 3; break; case KRITEM_TRIPLEBANANA: // Banana x3 - player->kartstuff[k_itemtype] = KITEM_BANANA; - player->kartstuff[k_itemamount] = 3; + player->itemtype = KITEM_BANANA; + player->itemamount = 3; break; case KRITEM_TENFOLDBANANA: // Banana x10 - player->kartstuff[k_itemtype] = KITEM_BANANA; - player->kartstuff[k_itemamount] = 10; + player->itemtype = KITEM_BANANA; + player->itemamount = 10; break; case KRITEM_TRIPLEORBINAUT: // Orbinaut x3 - player->kartstuff[k_itemtype] = KITEM_ORBINAUT; - player->kartstuff[k_itemamount] = 3; + player->itemtype = KITEM_ORBINAUT; + player->itemamount = 3; break; case KRITEM_QUADORBINAUT: // Orbinaut x4 - player->kartstuff[k_itemtype] = KITEM_ORBINAUT; - player->kartstuff[k_itemamount] = 4; + player->itemtype = KITEM_ORBINAUT; + player->itemamount = 4; break; case KRITEM_DUALJAWZ: // Jawz x2 - player->kartstuff[k_itemtype] = KITEM_JAWZ; - player->kartstuff[k_itemamount] = 2; + player->itemtype = KITEM_JAWZ; + player->itemamount = 2; break; default: if (getitem <= 0 || getitem >= NUMKARTRESULTS) // Sad (Fallback) { if (getitem != 0) CONS_Printf("ERROR: P_KartGetItemResult - Item roulette gave bad item (%d) :(\n", getitem); - player->kartstuff[k_itemtype] = KITEM_SAD; + player->itemtype = KITEM_SAD; } else - player->kartstuff[k_itemtype] = getitem; - player->kartstuff[k_itemamount] = 1; + player->itemtype = getitem; + player->itemamount = 1; break; } } +fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush) +{ + const UINT8 basePlayer = 8; // The player count we design most of the game around. + UINT8 playerCount = (spbrush ? 2 : numPlayers); + fixed_t playerScaling = 0; + + // Then, it multiplies it further if the player count isn't equal to basePlayer. + // This is done to make low player count races more interesting and high player count rates more fair. + // (If you're in SPB mode and in 2nd place, it acts like it's a 1v1, so the catch-up game is not weakened.) + if (playerCount < basePlayer) + { + // Less than basePlayer: increase odds significantly. + // 2P: x2.5 + playerScaling = (basePlayer - playerCount) * (FRACUNIT / 4); + } + else if (playerCount > basePlayer) + { + // More than basePlayer: reduce odds slightly. + // 16P: x0.75 + playerScaling = (basePlayer - playerCount) * (FRACUNIT / 32); + } + + return playerScaling; +} + +UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush) +{ + if (mapobjectscale != FRACUNIT) + { + // Bring back to normal scale. + distance = FixedDiv(distance * FRACUNIT, mapobjectscale) / FRACUNIT; + } + + if (franticitems == true) + { + // Frantic items pretends everyone's farther apart, for crazier items. + distance = (15 * distance) / 14; + } + + if (numPlayers > 0) + { + // Items get crazier with the fewer players that you have. + distance = FixedMul( + distance * FRACUNIT, + FRACUNIT + (K_ItemOddsScale(numPlayers, spbrush) / 2) + ) / FRACUNIT; + } + + return distance; +} + /** \brief Item Roulette for Kart \param player player object passed from P_KartPlayerThink @@ -498,13 +552,26 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) \return void */ -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival) +INT32 K_KartGetItemOdds( + UINT8 pos, SINT8 item, + UINT32 ourDist, + fixed_t mashed, + boolean spbrush, boolean bot, boolean rival) { INT32 newodds; INT32 i; + UINT8 pingame = 0, pexiting = 0; + SINT8 first = -1, second = -1; - INT32 secondist = 0; + UINT32 firstDist = UINT32_MAX; + UINT32 secondToFirst = UINT32_MAX; + + boolean powerItem = false; + boolean cooldownOnStart = false; + boolean indirectItem = false; + boolean notNearEnd = false; + INT32 shieldtype = KSHIELD_NONE; I_Assert(item > KITEM_NONE); // too many off by one scenarioes. @@ -513,6 +580,24 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (!KartItemCVars[item-1]->value && !modeattacking) return 0; + /* + if (bot) + { + // TODO: Item use on bots should all be passed-in functions. + // Instead of manually inserting these, it should return 0 + // for any items without an item use function supplied + + switch (item) + { + case KITEM_SNEAKER: + break; + default: + return 0; + } + } + */ + (void)bot; + if (gametype == GT_BATTLE) { I_Assert(pos < 6); // DO NOT allow positions past the bounds of the table @@ -540,7 +625,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (players[i].exiting) pexiting++; - if (shieldtype != KSHIELD_NONE && shieldtype == K_GetShieldFromItem(players[i].kartstuff[k_itemtype])) + if (shieldtype != KSHIELD_NONE && shieldtype == K_GetShieldFromItem(players[i].itemtype)) { // Don't allow more than one of each shield type at a time return 0; @@ -548,149 +633,158 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (players[i].mo && gametype == GT_RACE) { - if (players[i].kartstuff[k_position] == 1 && first == -1) + if (players[i].position == 1 && first == -1) first = i; - if (players[i].kartstuff[k_position] == 2 && second == -1) + if (players[i].position == 2 && second == -1) second = i; } } if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB { - secondist = players[second].distancetofinish - players[first].distancetofinish; - if (franticitems) - secondist = (15 * secondist) / 14; - secondist = ((28 + (8-pingame)) * secondist) / 28; - } + firstDist = players[first].distancetofinish; - // POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items. - // First, it multiplies it by 2 if franticitems is true; easy-peasy. - // Next, it multiplies it again if it's in SPB mode and 2nd needs to apply pressure to 1st. - // Then, it multiplies it further if the player count isn't equal to 8. - // This is done to make low player count races more interesting and high player count rates more fair. - // (2P normal would be about halfway between 8P normal and 8P frantic.) - // (This scaling is not done for SPB Rush, so that catchup strength is not weakened.) - // Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, for lesser items needed in a pinch. - -#define PLAYERSCALING (8 - (spbrush ? 2 : pingame)) - -#define POWERITEMODDS(odds) {\ - if (franticitems) \ - odds *= 2; \ - if (rival) \ - odds *= 2; \ - odds = FixedMul(odds * FRACUNIT, FRACUNIT + ((PLAYERSCALING * FRACUNIT) / 25)) / FRACUNIT; \ - if (mashed > 0) \ - odds = FixedDiv(odds * FRACUNIT, FRACUNIT + mashed) / FRACUNIT; \ -} - -#define COOLDOWNONSTART (leveltime < (30*TICRATE)+starttime) - - /* - if (bot) - { - // TODO: Item use on bots should all be passed-in functions. - // Instead of manually inserting these, it should return 0 - // for any items without an item use function supplied - - switch (item) + if (mapobjectscale != FRACUNIT) { - case KITEM_SNEAKER: - case KITEM_ROCKETSNEAKER: - case KITEM_INVINCIBILITY: - case KITEM_BANANA: - case KITEM_EGGMAN: - case KITEM_ORBINAUT: - case KITEM_JAWZ: - case KITEM_MINE: - case KITEM_LANDMINE: - case KITEM_BALLHOG: - case KITEM_SPB: - case KITEM_GROW: - case KITEM_SHRINK: - case KITEM_HYUDORO: - case KITEM_SUPERRING: - case KITEM_THUNDERSHIELD: - case KITEM_BUBBLESHIELD: - case KITEM_FLAMESHIELD: - case KRITEM_DUALSNEAKER: - case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEBANANA: - case KRITEM_TENFOLDBANANA: - case KRITEM_TRIPLEORBINAUT: - case KRITEM_QUADORBINAUT: - case KRITEM_DUALJAWZ: - break; - default: - return 0; + firstDist = FixedDiv(firstDist * FRACUNIT, mapobjectscale) / FRACUNIT; } + + secondToFirst = K_ScaleItemDistance( + players[second].distancetofinish - players[first].distancetofinish, + pingame, spbrush + ); } - */ - (void)bot; switch (item) { + case KITEM_BANANA: + case KITEM_EGGMAN: + case KITEM_SUPERRING: + notNearEnd = true; + break; case KITEM_ROCKETSNEAKER: case KITEM_JAWZ: case KITEM_LANDMINE: case KITEM_BALLHOG: case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEBANANA: - case KRITEM_TENFOLDBANANA: case KRITEM_TRIPLEORBINAUT: case KRITEM_QUADORBINAUT: case KRITEM_DUALJAWZ: - POWERITEMODDS(newodds); + powerItem = true; + break; + case KRITEM_TRIPLEBANANA: + case KRITEM_TENFOLDBANANA: + powerItem = true; + notNearEnd = true; break; case KITEM_INVINCIBILITY: case KITEM_MINE: case KITEM_GROW: case KITEM_BUBBLESHIELD: case KITEM_FLAMESHIELD: - if (COOLDOWNONSTART) - newodds = 0; - else - POWERITEMODDS(newodds); + cooldownOnStart = true; + powerItem = true; break; case KITEM_SPB: - if ((indirectitemcooldown > 0) || COOLDOWNONSTART - || (first != -1 && players[first].distancetofinish < 8*DISTVAR)) // No SPB near the end of the race + cooldownOnStart = true; + indirectItem = true; + notNearEnd = true; + + if (firstDist < ENDDIST) // No SPB near the end of the race { newodds = 0; } else { - INT32 multiplier = (secondist - (5*DISTVAR)) / DISTVAR; + const INT32 distFromStart = max(0, (INT32)secondToFirst - SPBSTARTDIST); + const INT32 distRange = SPBFORCEDIST - SPBSTARTDIST; + const INT32 mulMax = 3; + + INT32 multiplier = (distFromStart * mulMax) / distRange; if (multiplier < 0) multiplier = 0; - if (multiplier > 3) - multiplier = 3; + if (multiplier > mulMax) + multiplier = mulMax; newodds *= multiplier; } break; case KITEM_SHRINK: - if ((indirectitemcooldown > 0) || COOLDOWNONSTART || (pingame-1 <= pexiting)) + cooldownOnStart = true; + powerItem = true; + indirectItem = true; + notNearEnd = true; + + if (pingame-1 <= pexiting) newodds = 0; - else - POWERITEMODDS(newodds); break; case KITEM_THUNDERSHIELD: - if (spbplace != -1 || COOLDOWNONSTART) + cooldownOnStart = true; + powerItem = true; + + if (spbplace != -1) newodds = 0; - else - POWERITEMODDS(newodds); break; case KITEM_HYUDORO: - if ((hyubgone > 0) || COOLDOWNONSTART) + cooldownOnStart = true; + notNearEnd = true; + + if (hyubgone > 0) newodds = 0; break; default: break; } -#undef POWERITEMODDS + if (newodds == 0) + { + // Nothing else we want to do with odds matters at this point :p + return newodds; + } + + if ((indirectItem == true) && (indirectitemcooldown > 0)) + { + // Too many items that act indirectly in a match can feel kind of bad. + newodds = 0; + } + else if ((cooldownOnStart == true) && (leveltime < (30*TICRATE)+starttime)) + { + // This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items) + newodds = 0; + } + else if ((notNearEnd == true) && (ourDist < ENDDIST)) + { + // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) + newodds = 0; + } + else if (powerItem == true) + { + // This item is a "power item". This activates "frantic item" toggle related functionality. + fixed_t fracOdds = newodds * FRACUNIT; + + if (franticitems == true) + { + // First, power items multiply their odds by 2 if frantic items are on; easy-peasy. + fracOdds *= 2; + } + + if (rival == true) + { + // The Rival bot gets frantic-like items, also :p + fracOdds *= 2; + } + + fracOdds = FixedMul(fracOdds, FRACUNIT + K_ItemOddsScale(pingame, spbrush)); + + if (mashed > 0) + { + // Lastly, it *divides* it based on your mashed value, so that power items are less likely when you mash. + fracOdds = FixedDiv(fracOdds, FRACUNIT + mashed); + } + + newodds = fracOdds / FRACUNIT; + } return newodds; } @@ -721,7 +815,12 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum for (j = 1; j < NUMKARTRESULTS; j++) { - if (K_KartGetItemOdds(i, j, mashed, spbrush, player->bot, (player->bot && player->botvars.rival)) > 0) + if (K_KartGetItemOdds( + i, j, + player->distancetofinish, + mashed, + spbrush, player->bot, (player->bot && player->botvars.rival) + ) > 0) { available = true; break; @@ -738,7 +837,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum if (gametype == GT_BATTLE) // Battle Mode { - if (player->kartstuff[k_roulettetype] == 1 && oddsvalid[1] == true) + if (player->roulettetype == 1 && oddsvalid[1] == true) { // 1 is the extreme odds of player-controlled "Karma" items useodds = 1; @@ -802,10 +901,9 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) boolean spbrush = false; // This makes the roulette cycle through items - if this is 0, you shouldn't be here. - if (player->kartstuff[k_itemroulette]) - player->kartstuff[k_itemroulette]++; - else + if (!player->itemroulette) return; + player->itemroulette++; // Gotta check how many players are active at this moment. for (i = 0; i < MAXPLAYERS; i++) @@ -824,29 +922,29 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) dontforcespb = true; // This makes the roulette produce the random noises. - if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam) + if ((player->itemroulette % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam) { -#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->kartstuff[k_itemroulette] / 3) % 8)) +#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->itemroulette / 3) % 8)) for (i = 0; i <= r_splitscreen; i++) { - if (player == &players[displayplayers[i]] && players[displayplayers[i]].kartstuff[k_itemroulette]) + if (player == &players[displayplayers[i]] && players[displayplayers[i]].itemroulette) PLAYROULETTESND; } #undef PLAYROULETTESND } - roulettestop = TICRATE + (3*(pingame - player->kartstuff[k_position])); + roulettestop = TICRATE + (3*(pingame - player->position)); // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. // Finally, if you get past this check, now you can actually start calculating what item you get. - if ((cmd->buttons & BT_ATTACK) && (player->kartstuff[k_itemroulette] >= roulettestop) - && !(player->kartstuff[k_eggmanheld] || player->kartstuff[k_itemheld] || player->kartstuff[k_userings])) + if ((cmd->buttons & BT_ATTACK) && (player->itemroulette >= roulettestop) + && !(player->pflags & (PF_ITEMOUT|PF_EGGMANOUT|PF_USERINGS))) { // Mashing reduces your chances for the good items - mashed = FixedDiv((player->kartstuff[k_itemroulette])*FRACUNIT, ((TICRATE*3)+roulettestop)*FRACUNIT) - FRACUNIT; + mashed = FixedDiv((player->itemroulette)*FRACUNIT, ((TICRATE*3)+roulettestop)*FRACUNIT) - FRACUNIT; } - else if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) + else if (!(player->itemroulette >= (TICRATE*3))) return; if (cmd->buttons & BT_ATTACK) @@ -855,7 +953,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && !players[i].spectator - && players[i].kartstuff[k_position] == 1) + && players[i].position == 1) { // This player is first! Yay! @@ -873,37 +971,30 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) } } - if (mapobjectscale != FRACUNIT) - pdis = FixedDiv(pdis * FRACUNIT, mapobjectscale) / FRACUNIT; - - if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items - { - pdis = (15 * pdis) / 14; - } - - if (spbplace != -1 && player->kartstuff[k_position] == spbplace+1) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell + if (spbplace != -1 && player->position == spbplace+1) { + // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell pdis = (3 * pdis) / 2; spbrush = true; } + pdis = K_ScaleItemDistance(pdis, pingame, spbrush); + if (player->bot && player->botvars.rival) { // Rival has better odds :) pdis = (15 * pdis) / 14; } - pdis = ((28 + (8-pingame)) * pdis) / 28; // scale with player count - // SPECIAL CASE No. 1: // Fake Eggman items - if (player->kartstuff[k_roulettetype] == 2) + if (player->roulettetype == 2) { - player->kartstuff[k_eggmanexplode] = 4*TICRATE; + player->eggmanexplode = 4*TICRATE; //player->karthud[khud_itemblink] = TICRATE; //player->karthud[khud_itemblinkmode] = 1; - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->itemroulette = 0; + player->roulettetype = 0; if (P_IsDisplayPlayer(player) && !demo.freecam) S_StartSound(NULL, sfx_itrole); return; @@ -914,11 +1005,11 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) if (cv_kartdebugitem.value != 0 && !modeattacking) { K_KartGetItemResult(player, cv_kartdebugitem.value); - player->kartstuff[k_itemamount] = cv_kartdebugamount.value; + player->itemamount = cv_kartdebugamount.value; player->karthud[khud_itemblink] = TICRATE; player->karthud[khud_itemblinkmode] = 2; - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->itemroulette = 0; + player->roulettetype = 0; if (P_IsDisplayPlayer(player) && !demo.freecam) S_StartSound(NULL, sfx_dbgsal); return; @@ -970,8 +1061,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) } player->karthud[khud_itemblink] = TICRATE; - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->itemroulette = 0; + player->roulettetype = 0; return; } @@ -985,8 +1076,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) K_KartGetItemResult(player, KITEM_SUPERRING); player->karthud[khud_itemblink] = TICRATE; player->karthud[khud_itemblinkmode] = 1; - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->itemroulette = 0; + player->roulettetype = 0; if (P_IsDisplayPlayer(player)) S_StartSound(NULL, sfx_itrolm); return; @@ -995,17 +1086,17 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // SPECIAL CASE No. 5: // Force SPB onto 2nd if they get too far behind - if ((gametyperules & GTR_CIRCUIT) && player->kartstuff[k_position] == 2 && pdis > (DISTVAR*8) + if ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > SPBFORCEDIST && spbplace == -1 && !indirectitemcooldown && !dontforcespb && cv_selfpropelledbomb.value) { K_KartGetItemResult(player, KITEM_SPB); player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = (mashed ? 1 : 0); - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->karthud[khud_itemblinkmode] = 2; + player->itemroulette = 0; + player->roulettetype = 0; if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, (mashed ? sfx_itrolm : sfx_itrolf)); + S_StartSound(NULL, sfx_itrolk); return; } @@ -1018,7 +1109,14 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) useodds = K_FindUseodds(player, mashed, pdis, bestbumper, spbrush); for (i = 1; i < NUMKARTRESULTS; i++) - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, mashed, spbrush, player->bot, (player->bot && player->botvars.rival))); + { + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( + useodds, i, + player->distancetofinish, + mashed, + spbrush, player->bot, (player->bot && player->botvars.rival)) + ); + } // Award the player whatever power is rolled if (totalspawnchance > 0) @@ -1030,18 +1128,18 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) } else { - player->kartstuff[k_itemtype] = KITEM_SAD; - player->kartstuff[k_itemamount] = 1; + player->itemtype = KITEM_SAD; + player->itemamount = 1; } if (P_IsDisplayPlayer(player) && !demo.freecam) - S_StartSound(NULL, ((player->kartstuff[k_roulettetype] == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf))); + S_StartSound(NULL, ((player->roulettetype == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf))); player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = ((player->kartstuff[k_roulettetype] == 1) ? 2 : (mashed ? 1 : 0)); + player->karthud[khud_itemblinkmode] = ((player->roulettetype == 1) ? 2 : (mashed ? 1 : 0)); - player->kartstuff[k_itemroulette] = 0; // Since we're done, clear the roulette number - player->kartstuff[k_roulettetype] = 0; // This too + player->itemroulette = 0; // Since we're done, clear the roulette number + player->roulettetype = 0; // This too } //} @@ -1057,7 +1155,7 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) if (against && !P_MobjWasRemoved(against) && against->player && ((!P_PlayerInPain(against->player) && P_PlayerInPain(mobj->player)) // You're hurt - || (against->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD && mobj->player->kartstuff[k_itemtype] != KITEM_BUBBLESHIELD))) // They have a Bubble Shield + || (against->player->itemtype == KITEM_BUBBLESHIELD && mobj->player->itemtype != KITEM_BUBBLESHIELD))) // They have a Bubble Shield { weight = 0; // This player does not cause any bump action } @@ -1066,7 +1164,7 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) weight = (mobj->player->kartweight) * FRACUNIT; if (mobj->player->speed > K_GetKartSpeed(mobj->player, false)) weight += (mobj->player->speed - K_GetKartSpeed(mobj->player, false))/8; - if (mobj->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD) + if (mobj->player->itemtype == KITEM_BUBBLESHIELD) weight += 9*FRACUNIT; } @@ -1098,7 +1196,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) case MT_FALLINGROCK: if (against->player) { - if (against->player->kartstuff[k_invincibilitytimer] || against->player->kartstuff[k_growshrinktimer] > 0) + if (against->player->invincibilitytimer || against->player->growshrinktimer > 0) weight = 0; else weight = K_PlayerWeight(against, NULL); @@ -1124,16 +1222,137 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) return FixedMul(weight, mobj->scale); } -boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) +static void K_SpawnBumpForObjs(mobj_t *mobj1, mobj_t *mobj2) { - mobj_t *fx; + mobj_t *fx = P_SpawnMobj( + mobj1->x/2 + mobj2->x/2, + mobj1->y/2 + mobj2->y/2, + mobj1->z/2 + mobj2->z/2, + MT_BUMP + ); + fixed_t avgScale = (mobj1->scale + mobj2->scale) / 2; + + if (mobj1->eflags & MFE_VERTICALFLIP) + { + fx->eflags |= MFE_VERTICALFLIP; + } + else + { + fx->eflags &= ~MFE_VERTICALFLIP; + } + + P_SetScale(fx, (fx->destscale = avgScale)); + + if ((mobj1->player && mobj1->player->itemtype == KITEM_BUBBLESHIELD) + || (mobj2->player && mobj2->player->itemtype == KITEM_BUBBLESHIELD)) + { + S_StartSound(mobj1, sfx_s3k44); + } + else + { + S_StartSound(mobj1, sfx_s3k49); + } +} + +static void K_PlayerJustBumped(player_t *player) +{ + mobj_t *playerMobj = NULL; + + if (player == NULL) + { + return; + } + + playerMobj = player->mo; + + if (playerMobj == NULL || P_MobjWasRemoved(playerMobj)) + { + return; + } + + if (abs(player->rmomx) < playerMobj->scale && abs(player->rmomy) < playerMobj->scale) + { + // Because this is done during collision now, rmomx and rmomy need to be recalculated + // so that friction doesn't immediately decide to stop the player if they're at a standstill + player->rmomx = playerMobj->momx - player->cmomx; + player->rmomy = playerMobj->momy - player->cmomy; + } + + player->justbumped = bumptime; + player->spindash = 0; + + if (player->spinouttimer) + { + player->wipeoutslow = wipeoutslowtime+1; + player->spinouttimer = max(wipeoutslowtime+1, player->spinouttimer); + //player->spinouttype = KSPIN_WIPEOUT; // Enforce type + } +} + +static fixed_t K_GetBounceForce(mobj_t *mobj1, mobj_t *mobj2, fixed_t distx, fixed_t disty) +{ + const fixed_t forceMul = (4 * FRACUNIT) / 10; // Multiply by this value to make it feel like old bumps. + fixed_t momdifx, momdify; - fixed_t distx, disty; - fixed_t dot, force; + fixed_t dot; + fixed_t force = 0; + + momdifx = mobj1->momx - mobj2->momx; + momdify = mobj1->momy - mobj2->momy; + + if (distx == 0 && disty == 0) + { + // if there's no distance between the 2, they're directly on top of each other, don't run this + return 0; + } + + { // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision... + fixed_t dist = P_AproxDistance(distx, disty); + fixed_t nx, ny; + + dist = dist ? dist : 1; + + nx = FixedDiv(distx, dist); + ny = FixedDiv(disty, dist); + + distx = FixedMul(mobj1->radius + mobj2->radius, nx); + disty = FixedMul(mobj1->radius + mobj2->radius, ny); + + if (momdifx == 0 && momdify == 0) + { + // If there's no momentum difference, they're moving at exactly the same rate. Pretend they moved into each other. + momdifx = -nx; + momdify = -ny; + } + } + + dot = FixedMul(momdifx, distx) + FixedMul(momdify, disty); + + if (dot >= 0) + { + // They're moving away from each other + return 0; + } + + // Return the push force! + force = FixedDiv(dot, FixedMul(distx, distx) + FixedMul(disty, disty)); + + return FixedMul(force, forceMul); +} + +boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2) +{ + const fixed_t minBump = 25*mapobjectscale; + mobj_t *goombaBounce = NULL; + fixed_t distx, disty, dist; + fixed_t force; fixed_t mass1, mass2; - if (!mobj1 || !mobj2) + if ((!mobj1 || P_MobjWasRemoved(mobj1)) + || (!mobj2 || P_MobjWasRemoved(mobj2))) + { return false; + } // Don't bump when you're being reborn if ((mobj1->player && mobj1->player->playerstate != PST_LIVE) @@ -1148,164 +1367,174 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean sol INT32 flash; flash = K_GetKartFlashing(mobj1->player); - if (mobj1->player && mobj1->player->powers[pw_flashing] > 0 && mobj1->player->powers[pw_flashing] < flash) + if (mobj1->player && mobj1->player->flashing > 0 && mobj1->player->flashing < flash) { - if (mobj1->player->powers[pw_flashing] < flash-1) - mobj1->player->powers[pw_flashing]++; + if (mobj1->player->flashing < flash-1) + mobj1->player->flashing++; return false; } flash = K_GetKartFlashing(mobj2->player); - if (mobj2->player && mobj2->player->powers[pw_flashing] > 0 && mobj2->player->powers[pw_flashing] < flash) + if (mobj2->player && mobj2->player->flashing > 0 && mobj2->player->flashing < flash) { - if (mobj2->player->powers[pw_flashing] < flash-1) - mobj2->player->powers[pw_flashing]++; + if (mobj2->player->flashing < flash-1) + mobj2->player->flashing++; return false; } } // Don't bump if you've recently bumped - if (mobj1->player && mobj1->player->kartstuff[k_justbumped]) + if (mobj1->player && mobj1->player->justbumped) { - mobj1->player->kartstuff[k_justbumped] = bumptime; + mobj1->player->justbumped = bumptime; return false; } - if (mobj2->player && mobj2->player->kartstuff[k_justbumped]) + if (mobj2->player && mobj2->player->justbumped) + { + mobj2->player->justbumped = bumptime; + return false; + } + + // Adds the OTHER object's momentum times a bunch, for the best chance of getting the correct direction + distx = (mobj1->x + mobj2->momx) - (mobj2->x + mobj1->momx); + disty = (mobj1->y + mobj2->momy) - (mobj2->y + mobj1->momy); + + force = K_GetBounceForce(mobj1, mobj2, distx, disty); + + if (force == 0) { - mobj2->player->kartstuff[k_justbumped] = bumptime; return false; } mass1 = K_GetMobjWeight(mobj1, mobj2); + mass2 = K_GetMobjWeight(mobj2, mobj1); - if (solid == true && mass1 > 0) - mass2 = mass1; - else - mass2 = K_GetMobjWeight(mobj2, mobj1); - - momdifx = mobj1->momx - mobj2->momx; - momdify = mobj1->momy - mobj2->momy; - - // Adds the OTHER player's momentum times a bunch, for the best chance of getting the correct direction - distx = (mobj1->x + mobj2->momx*3) - (mobj2->x + mobj1->momx*3); - disty = (mobj1->y + mobj2->momy*3) - (mobj2->y + mobj1->momy*3); - - if (distx == 0 && disty == 0) + if ((P_IsObjectOnGround(mobj1) && mobj2->momz < 0) // Grounded + || (mass2 == 0 && mass1 > 0)) // The other party is immovable { - // if there's no distance between the 2, they're directly on top of each other, don't run this - return false; + goombaBounce = mobj2; + } + else if ((P_IsObjectOnGround(mobj2) && mobj1->momz < 0) // Grounded + || (mass1 == 0 && mass2 > 0)) // The other party is immovable + { + goombaBounce = mobj1; } - { // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision... - fixed_t dist = P_AproxDistance(distx, disty); - fixed_t nx, ny; - - dist = dist ? dist : 1; - - nx = FixedDiv(distx, dist); - ny = FixedDiv(disty, dist); - - distx = FixedMul(mobj1->radius+mobj2->radius, nx); - disty = FixedMul(mobj1->radius+mobj2->radius, ny); - - if (momdifx == 0 && momdify == 0) - { - // If there's no momentum difference, they're moving at exactly the same rate. Pretend they moved into each other. - momdifx = -nx; - momdify = -ny; - } + if (goombaBounce != NULL) + { + // Perform a Goomba Bounce by reversing your z momentum. + goombaBounce->momz = -goombaBounce->momz; } + else + { + // Trade z momentum values. + fixed_t newz = mobj1->momz; + mobj1->momz = mobj2->momz; + mobj2->momz = newz; + } + + // Multiply by force + distx = FixedMul(force, distx); + disty = FixedMul(force, disty); + dist = FixedHypot(distx, disty); // if the speed difference is less than this let's assume they're going proportionately faster from each other - if (P_AproxDistance(momdifx, momdify) < (25*mapobjectscale)) + if (dist < minBump) { - fixed_t momdiflength = P_AproxDistance(momdifx, momdify); - fixed_t normalisedx = FixedDiv(momdifx, momdiflength); - fixed_t normalisedy = FixedDiv(momdify, momdiflength); - momdifx = FixedMul((25*mapobjectscale), normalisedx); - momdify = FixedMul((25*mapobjectscale), normalisedy); - } + fixed_t normalisedx = FixedDiv(distx, dist); + fixed_t normalisedy = FixedDiv(disty, dist); - dot = FixedMul(momdifx, distx) + FixedMul(momdify, disty); - - if (dot >= 0) - { - // They're moving away from each other - return false; - } - - force = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty)); - - if (bounce == true && mass2 > 0) // Perform a Goomba Bounce. - mobj1->momz = -mobj1->momz; - else - { - fixed_t newz = mobj1->momz; - if (mass2 > 0) - mobj1->momz = mobj2->momz; - if (mass1 > 0 && solid == false) - mobj2->momz = newz; + distx = FixedMul(minBump, normalisedx); + disty = FixedMul(minBump, normalisedy); } if (mass2 > 0) { - mobj1->momx = mobj1->momx - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), force), distx); - mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), force), disty); + mobj1->momx = mobj1->momx - FixedMul(FixedDiv(2*mass2, mass1 + mass2), distx); + mobj1->momy = mobj1->momy - FixedMul(FixedDiv(2*mass2, mass1 + mass2), disty); } - if (mass1 > 0 && solid == false) + if (mass1 > 0) { - mobj2->momx = mobj2->momx - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), force), -distx); - mobj2->momy = mobj2->momy - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), force), -disty); + mobj2->momx = mobj2->momx - FixedMul(FixedDiv(2*mass1, mass1 + mass2), -distx); + mobj2->momy = mobj2->momy - FixedMul(FixedDiv(2*mass1, mass1 + mass2), -disty); } - // Do the bump fx when we've CONFIRMED we can bump. - if ((mobj1->player && mobj1->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD) || (mobj2->player && mobj2->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD)) - S_StartSound(mobj1, sfx_s3k44); - else - S_StartSound(mobj1, sfx_s3k49); + K_SpawnBumpForObjs(mobj1, mobj2); - fx = P_SpawnMobj(mobj1->x/2 + mobj2->x/2, mobj1->y/2 + mobj2->y/2, mobj1->z/2 + mobj2->z/2, MT_BUMP); - if (mobj1->eflags & MFE_VERTICALFLIP) - fx->eflags |= MFE_VERTICALFLIP; - else - fx->eflags &= ~MFE_VERTICALFLIP; - P_SetScale(fx, mobj1->scale); + K_PlayerJustBumped(mobj1->player); + K_PlayerJustBumped(mobj2->player); - // Because this is done during collision now, rmomx and rmomy need to be recalculated - // so that friction doesn't immediately decide to stop the player if they're at a standstill - // Also set justbumped here - if (mobj1->player) + return true; +} + +// K_KartBouncing, but simplified to act like P_BouncePlayerMove +boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj) +{ + const fixed_t minBump = 25*mapobjectscale; + fixed_t distx, disty, dist; + fixed_t force; + + if ((!bounceMobj || P_MobjWasRemoved(bounceMobj)) + || (!solidMobj || P_MobjWasRemoved(solidMobj))) { - mobj1->player->rmomx = mobj1->momx - mobj1->player->cmomx; - mobj1->player->rmomy = mobj1->momy - mobj1->player->cmomy; - mobj1->player->kartstuff[k_justbumped] = bumptime; - mobj1->player->kartstuff[k_spindash] = 0; - - if (mobj1->player->kartstuff[k_spinouttimer]) - { - mobj1->player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1; - mobj1->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj1->player->kartstuff[k_spinouttimer]); - //mobj1->player->kartstuff[k_spinouttype] = KSPIN_WIPEOUT; // Enforce type - } + return false; } - if (mobj2->player) + // Don't bump when you're being reborn + if (bounceMobj->player && bounceMobj->player->playerstate != PST_LIVE) + return false; + + if (bounceMobj->player && bounceMobj->player->respawn.state != RESPAWNST_NONE) + return false; + + // Don't bump if you've recently bumped + if (bounceMobj->player && bounceMobj->player->justbumped) { - mobj2->player->rmomx = mobj2->momx - mobj2->player->cmomx; - mobj2->player->rmomy = mobj2->momy - mobj2->player->cmomy; - mobj2->player->kartstuff[k_justbumped] = bumptime; - mobj2->player->kartstuff[k_spindash] = 0; - - if (mobj2->player->kartstuff[k_spinouttimer]) - { - mobj2->player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1; - mobj2->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj2->player->kartstuff[k_spinouttimer]); - //mobj2->player->kartstuff[k_spinouttype] = KSPIN_WIPEOUT; // Enforce type - } + bounceMobj->player->justbumped = bumptime; + return false; } + // Adds the OTHER object's momentum times a bunch, for the best chance of getting the correct direction + { + distx = (bounceMobj->x + solidMobj->momx) - (solidMobj->x + bounceMobj->momx); + disty = (bounceMobj->y + solidMobj->momy) - (solidMobj->y + bounceMobj->momy); + } + + force = K_GetBounceForce(bounceMobj, solidMobj, distx, disty); + + if (force == 0) + { + return false; + } + + // Multiply by force + distx = FixedMul(force, distx); + disty = FixedMul(force, disty); + dist = FixedHypot(distx, disty); + + { + // Normalize to the desired push value. + fixed_t normalisedx = FixedDiv(distx, dist); + fixed_t normalisedy = FixedDiv(disty, dist); + fixed_t bounceSpeed; + + bounceSpeed = FixedHypot(bounceMobj->momx, bounceMobj->momy); + bounceSpeed = FixedMul(bounceSpeed, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + bounceSpeed += minBump; + + distx = FixedMul(bounceSpeed, normalisedx); + disty = FixedMul(bounceSpeed, normalisedy); + } + + bounceMobj->momx = bounceMobj->momx - distx; + bounceMobj->momy = bounceMobj->momy - disty; + bounceMobj->momz = -bounceMobj->momz; + + K_SpawnBumpForObjs(bounceMobj, solidMobj); + K_PlayerJustBumped(bounceMobj->player); + return true; } @@ -1390,14 +1619,14 @@ static void K_UpdateOffroad(player_t *player) // If you are in offroad, a timer starts. if (offroadstrength) { - if (player->kartstuff[k_offroad] < offroadstrength) - player->kartstuff[k_offroad] += offroadstrength / TICRATE; + if (player->offroad < offroadstrength) + player->offroad += offroadstrength / TICRATE; - if (player->kartstuff[k_offroad] > offroadstrength) - player->kartstuff[k_offroad] = offroadstrength; + if (player->offroad > offroadstrength) + player->offroad = offroadstrength; } else - player->kartstuff[k_offroad] = 0; + player->offroad = 0; } static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t curdist, fixed_t maxdist, boolean transparent) @@ -1481,7 +1710,7 @@ static void K_UpdateDraft(player_t *player) UINT8 leniency; UINT8 i; - if (player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + if (player->itemtype == KITEM_FLAMESHIELD) { // Flame Shield gets infinite draft distance as its passive effect. draftdistance = 0; @@ -1527,7 +1756,7 @@ static void K_UpdateDraft(player_t *player) continue; // No tethering off of the guy who got the starting bonus :P - if (players[i].kartstuff[k_startboost] > 0) + if (players[i].startboost > 0) continue; #ifndef EASYDRAFTTEST @@ -1563,21 +1792,21 @@ static void K_UpdateDraft(player_t *player) continue; #endif - olddraft = player->kartstuff[k_draftpower]; + olddraft = player->draftpower; - player->kartstuff[k_draftleeway] = leniency; - player->kartstuff[k_lastdraft] = i; + player->draftleeway = leniency; + player->lastdraft = i; // Draft power is used later in K_GetKartBoostPower, ranging from 0 for normal speed and FRACUNIT for max draft speed. // How much this increments every tic biases toward acceleration! (min speed gets 1.5% per tic, max speed gets 0.5% per tic) - if (player->kartstuff[k_draftpower] < FRACUNIT) - player->kartstuff[k_draftpower] += (FRACUNIT/200) + ((9 - player->kartspeed) * ((3*FRACUNIT)/1600)); + if (player->draftpower < FRACUNIT) + player->draftpower += (FRACUNIT/200) + ((9 - player->kartspeed) * ((3*FRACUNIT)/1600)); - if (player->kartstuff[k_draftpower] > FRACUNIT) - player->kartstuff[k_draftpower] = FRACUNIT; + if (player->draftpower > FRACUNIT) + player->draftpower = FRACUNIT; // Play draft finish noise - if (olddraft < FRACUNIT && player->kartstuff[k_draftpower] >= FRACUNIT) + if (olddraft < FRACUNIT && player->draftpower >= FRACUNIT) S_StartSound(player->mo, sfx_cdfm62); // Spawn in the visual! @@ -1588,24 +1817,24 @@ static void K_UpdateDraft(player_t *player) } // No one to draft off of? Then you can knock that off. - if (player->kartstuff[k_draftleeway]) // Prevent small disruptions from stopping your draft. + if (player->draftleeway) // Prevent small disruptions from stopping your draft. { - player->kartstuff[k_draftleeway]--; - if (player->kartstuff[k_lastdraft] >= 0 - && player->kartstuff[k_lastdraft] < MAXPLAYERS - && playeringame[player->kartstuff[k_lastdraft]] - && !players[player->kartstuff[k_lastdraft]].spectator - && players[player->kartstuff[k_lastdraft]].mo) + player->draftleeway--; + if (player->lastdraft >= 0 + && player->lastdraft < MAXPLAYERS + && playeringame[player->lastdraft] + && !players[player->lastdraft].spectator + && players[player->lastdraft].mo) { - player_t *victim = &players[player->kartstuff[k_lastdraft]]; + player_t *victim = &players[player->lastdraft]; fixed_t dist = P_AproxDistance(P_AproxDistance(victim->mo->x - player->mo->x, victim->mo->y - player->mo->y), victim->mo->z - player->mo->z); K_DrawDraftCombiring(player, victim, dist, draftdistance, true); } } else // Remove draft speed boost. { - player->kartstuff[k_draftpower] = 0; - player->kartstuff[k_lastdraft] = -1; + player->draftpower = 0; + player->lastdraft = -1; } } @@ -1687,7 +1916,7 @@ void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master) K_FlipFromObject(mo, master); // visibility (usually for hyudoro) - mo->renderflags = (master->renderflags & RF_DONTDRAW); + mo->renderflags = (mo->renderflags & ~RF_DONTDRAW) | (master->renderflags & RF_DONTDRAW); } // same as above, but does not adjust Z height when flipping @@ -1698,7 +1927,7 @@ void K_GenericExtraFlagsNoZAdjust(mobj_t *mo, mobj_t *master) mo->flags2 = (mo->flags2 & ~MF2_OBJECTFLIP)|(master->flags2 & MF2_OBJECTFLIP); // visibility (usually for hyudoro) - mo->renderflags = (master->renderflags & RF_DONTDRAW); + mo->renderflags = (mo->renderflags & ~RF_DONTDRAW) | (master->renderflags & RF_DONTDRAW); } @@ -1717,13 +1946,13 @@ void K_SpawnDashDustRelease(player_t *player) if (!P_IsObjectOnGround(player->mo)) return; - if (!player->speed && !player->kartstuff[k_startboost] && !player->kartstuff[k_spindash]) + if (!player->speed && !player->startboost && !player->spindash) return; travelangle = player->mo->angle; - if (player->kartstuff[k_drift] || player->kartstuff[k_driftend]) - travelangle -= (ANGLE_45/5)*player->kartstuff[k_drift]; + if (player->drift || (player->pflags & PF_DRIFTEND)) + travelangle -= (ANGLE_45/5)*player->drift; for (i = 0; i < 2; i++) { @@ -1761,11 +1990,6 @@ static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the m sparks->renderflags |= RF_DONTDRAW; } -static fixed_t K_RandomFlip(fixed_t f) -{ - return ( ( leveltime & 1 ) ? f : -f ); -} - void K_SpawnDriftBoostClip(player_t *player) { mobj_t *clip; @@ -1790,7 +2014,7 @@ void K_SpawnDriftBoostClip(player_t *player) clip->momz += player->mo->momz; P_InstaThrust(clip, player->mo->angle + - K_RandomFlip(P_RandomRange(FRACUNIT/2, FRACUNIT)), + P_RandomFlip(P_RandomRange(FRACUNIT/2, FRACUNIT)), FixedMul(scale, player->speed)); } @@ -1824,7 +2048,7 @@ void K_SpawnNormalSpeedLines(player_t *player) K_MatchGenericExtraFlags(fast, player->mo); // Make it red when you have the eggman speed boost - if (player->kartstuff[k_eggmanexplode]) + if (player->eggmanexplode) { fast->color = SKINCOLOR_RED; fast->colorized = true; @@ -1849,8 +2073,8 @@ void K_SpawnInvincibilitySpeedLines(mobj_t *mo) fast->colorized = true; K_MatchGenericExtraFlags(fast, mo); P_SetMobjState(fast, S_KARTINVLINES1); - if (mo->player->kartstuff[k_invincibilitytimer] < 10*TICRATE) - fast->destscale = 6*((mo->player->kartstuff[k_invincibilitytimer]/TICRATE)*FRACUNIT)/8; + if (mo->player->invincibilitytimer < 10*TICRATE) + fast->destscale = 6*((mo->player->invincibilitytimer/TICRATE)*FRACUNIT)/8; } static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) @@ -1891,7 +2115,7 @@ static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) continue; } - if (p->spectator || p->kartstuff[k_hyudorotimer] > 0) + if (p->spectator || p->hyudorotimer > 0) { // Not playing / invisible continue; @@ -1970,8 +2194,9 @@ void K_KartMoveAnimation(player_t *player) SINT8 turndir = 0; SINT8 destGlanceDir = 0; - SINT8 drift = player->kartstuff[k_drift]; + SINT8 drift = player->drift; + // Uses turning over steering -- it's important to show player feedback immediately. if (player->cmd.turning < -minturn) { turndir = -1; @@ -1981,22 +2206,27 @@ void K_KartMoveAnimation(player_t *player) turndir = 1; } - if (lookback == true && drift == 0) + if (!lookback) + { + player->pflags &= ~PF_LOOKDOWN; + } + else if (drift == 0) { // Prioritize looking back frames over turning turndir = 0; } // Sliptides: drift -> lookback frames - if (abs(player->aizDriftTurn) >= ANGLE_90) + if (abs(player->aizdriftturn) >= ANGLE_90) { - destGlanceDir = -(2*intsign(player->aizDriftTurn)); + destGlanceDir = -(2*intsign(player->aizdriftturn)); player->glanceDir = destGlanceDir; drift = turndir = 0; + player->pflags &= ~PF_LOOKDOWN; } - else if (player->aizDriftTurn) + else if (player->aizdriftturn) { - drift = intsign(player->aizDriftTurn); + drift = intsign(player->aizdriftturn); turndir = 0; } else if (turndir == 0 && drift == 0) @@ -2007,6 +2237,7 @@ void K_KartMoveAnimation(player_t *player) if (lookback == true) { + statenum_t gainaxstate = S_GAINAX_TINY; if (destGlanceDir == 0) { if (player->glanceDir != 0) @@ -2031,6 +2262,20 @@ void K_KartMoveAnimation(player_t *player) { // Looking back AND glancing? Amplify the look! destGlanceDir *= 2; + if (player->itemamount && player->itemtype) + gainaxstate = S_GAINAX_HUGE; + else + gainaxstate = S_GAINAX_MID1; + } + + if (destGlanceDir && !(player->pflags & PF_LOOKDOWN)) + { + mobj_t *gainax = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GAINAX); + gainax->movedir = (destGlanceDir < 0) ? (ANGLE_270-ANG10) : (ANGLE_90+ANG10); + P_SetTarget(&gainax->target, player->mo); + P_SetMobjState(gainax, gainaxstate); + gainax->flags2 |= MF2_AMBUSH; + player->pflags |= PF_LOOKDOWN; } } else if (K_GetForwardMove(player) < 0 && destGlanceDir == 0) @@ -2286,6 +2531,9 @@ void K_KartMoveAnimation(player_t *player) player->glanceDir++; } + if (!player->glanceDir) + player->pflags &= ~PF_LOOKDOWN; + // Update lastspeed value -- we use to display slow driving frames instead of fast driving when slowing down. player->lastspeed = player->speed; player->lastmomz = player->mo->momz; @@ -2414,14 +2662,27 @@ void K_MomentumToFacing(player_t *player) boolean K_ApplyOffroad(player_t *player) { - if (player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_hyudorotimer] || player->kartstuff[k_sneakertimer]) + if (player->invincibilitytimer || player->hyudorotimer || player->sneakertimer) return false; return true; } boolean K_SlopeResistance(player_t *player) { - if (player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_sneakertimer] || player->kartstuff[k_tiregrease]) + if (player->invincibilitytimer || player->sneakertimer || player->tiregrease) + return true; + return false; +} + +boolean K_TripwirePass(player_t *player) +{ + if ( + player->invincibilitytimer || + player->sneakertimer || + player->growshrinktimer > 0 || + player->flamedash || + player->speed > 2 * K_GetKartSpeed(player, false) + ) return true; return false; } @@ -2463,17 +2724,17 @@ static void K_GetKartBoostPower(player_t *player) fixed_t speedboost = 0, accelboost = 0, handleboost = 0; UINT8 numboosts = 0; - if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow] == 1) // Slow down after you've been bumped + if (player->spinouttimer && player->wipeoutslow == 1) // Slow down after you've been bumped { - player->kartstuff[k_boostpower] = player->kartstuff[k_speedboost] = player->kartstuff[k_accelboost] = 0; + player->boostpower = player->speedboost = player->accelboost = 0; return; } // Offroad is separate, it's difficult to factor it in with a variable value anyway. - if (K_ApplyOffroad(player) && player->kartstuff[k_offroad] >= 0) - boostpower = FixedDiv(boostpower, FixedMul(player->kartstuff[k_offroad], K_GetKartGameSpeedScalar(gamespeed)) + FRACUNIT); + if (K_ApplyOffroad(player) && player->offroad >= 0) + boostpower = FixedDiv(boostpower, FixedMul(player->offroad, K_GetKartGameSpeedScalar(gamespeed)) + FRACUNIT); - if (player->kartstuff[k_bananadrag] > TICRATE) + if (player->bananadrag > TICRATE) boostpower = (4*boostpower)/5; // Note: Handling will ONLY stack when sliptiding! @@ -2482,34 +2743,34 @@ static void K_GetKartBoostPower(player_t *player) numboosts++; \ speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \ accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \ - if (player->kartstuff[k_aizdriftstrat]) \ + if (player->aizdriftstrat) \ handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))); \ else \ handleboost = max(h, handleboost); \ } - if (player->kartstuff[k_sneakertimer]) // Sneaker + if (player->sneakertimer) // Sneaker { UINT8 i; - for (i = 0; i < player->kartstuff[k_numsneakers]; i++) + for (i = 0; i < player->numsneakers; i++) { ADDBOOST(FRACUNIT/2, 8*FRACUNIT, sliptidehandling); // + 50% top speed, + 800% acceleration, +50% handling } } - if (player->kartstuff[k_invincibilitytimer]) // Invincibility + if (player->invincibilitytimer) // Invincibility { ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, sliptidehandling/2); // + 37.5% top speed, + 300% acceleration, +25% handling } - if (player->kartstuff[k_growshrinktimer] > 0) // Grow + if (player->growshrinktimer > 0) // Grow { ADDBOOST(0, 0, sliptidehandling/2); // + 0% top speed, + 0% acceleration, +25% handling } - if (player->kartstuff[k_flamedash]) // Flame Shield dash + if (player->flamedash) // Flame Shield dash { - fixed_t dash = K_FlameShieldDashVar(player->kartstuff[k_flamedash]); + fixed_t dash = K_FlameShieldDashVar(player->flamedash); ADDBOOST( dash, // + infinite top speed 3*FRACUNIT, // + 300% acceleration @@ -2517,10 +2778,10 @@ static void K_GetKartBoostPower(player_t *player) ); } - if (player->kartstuff[k_spindashboost]) // Spindash boost + if (player->spindashboost) // Spindash boost { const fixed_t MAXCHARGESPEED = K_GetSpindashChargeSpeed(player); - const fixed_t exponent = FixedMul(player->kartstuff[k_spindashspeed], player->kartstuff[k_spindashspeed]); + const fixed_t exponent = FixedMul(player->spindashspeed, player->spindashspeed); // character & charge dependent ADDBOOST( @@ -2530,50 +2791,62 @@ static void K_GetKartBoostPower(player_t *player) ); } - if (player->kartstuff[k_startboost]) // Startup Boost + if (player->startboost) // Startup Boost { ADDBOOST(FRACUNIT/2, 4*FRACUNIT, 0); // + 50% top speed, + 400% acceleration, +0% handling } - if (player->kartstuff[k_driftboost]) // Drift Boost + if (player->driftboost) // Drift Boost { - ADDBOOST(FRACUNIT/4, 4*FRACUNIT, 0); // + 25% top speed, + 400% acceleration, +0% handling + if (player->strongdriftboost) // Purple/Rainbow drift boost + { + ADDBOOST(FRACUNIT/3, 4*FRACUNIT, 0); // + 33% top speed, + 400% acceleration, +0% handling + } + else + { + ADDBOOST(FRACUNIT/4, 4*FRACUNIT, 0); // + 25% top speed, + 400% acceleration, +0% handling + } } - if (player->kartstuff[k_ringboost]) // Ring Boost + if (player->trickboost) // Trick pannel up-boost + { + ADDBOOST(player->trickboostpower, 5*FRACUNIT, 0); // % speed, 500% accel, 0% handling + } + + if (player->ringboost) // Ring Boost { ADDBOOST(FRACUNIT/5, 4*FRACUNIT, 0); // + 20% top speed, + 400% acceleration, +0% handling } - if (player->kartstuff[k_eggmanexplode]) // Ready-to-explode + if (player->eggmanexplode) // Ready-to-explode { ADDBOOST(3*FRACUNIT/20, FRACUNIT, 0); // + 15% top speed, + 100% acceleration, +0% handling } - if (player->kartstuff[k_draftpower] > 0) // Drafting + if (player->draftpower > 0) // Drafting { // 30% - 44%, each point of speed adds 1.75% fixed_t draftspeed = ((3*FRACUNIT)/10) + ((player->kartspeed-1) * ((7*FRACUNIT)/400)); - speedboost += FixedMul(draftspeed, player->kartstuff[k_draftpower]); // (Drafting suffers no boost stack penalty.) + speedboost += FixedMul(draftspeed, player->draftpower); // (Drafting suffers no boost stack penalty.) numboosts++; } - player->kartstuff[k_boostpower] = boostpower; + player->boostpower = boostpower; // value smoothing - if (speedboost > player->kartstuff[k_speedboost]) + if (speedboost > player->speedboost) { - player->kartstuff[k_speedboost] = speedboost; + player->speedboost = speedboost; } else { - player->kartstuff[k_speedboost] += (speedboost - player->kartstuff[k_speedboost]) / (TICRATE/2); + player->speedboost += (speedboost - player->speedboost) / (TICRATE/2); } - player->kartstuff[k_accelboost] = accelboost; - player->kartstuff[k_handleboost] = handleboost; + player->accelboost = accelboost; + player->handleboost = handleboost; - player->kartstuff[k_numboosts] = numboosts; + player->numboosts = numboosts; } // Returns kart speed from a stat. Boost power and scale are NOT taken into account, no player or object is necessary. @@ -2625,7 +2898,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player)); } - return FixedMul(finalspeed, player->kartstuff[k_boostpower]+player->kartstuff[k_speedboost]); + return FixedMul(finalspeed, player->boostpower+player->speedboost); } return finalspeed; @@ -2643,7 +2916,7 @@ fixed_t K_GetKartAccel(player_t *player) k_accel = FixedMul(k_accel, FRACUNIT + (sphereAdd * player->spheres)); } - return FixedMul(k_accel, (FRACUNIT + player->kartstuff[k_accelboost]) / 4); + return FixedMul(k_accel, (FRACUNIT + player->accelboost) / 4); } UINT16 K_GetKartFlashing(player_t *player) @@ -2675,17 +2948,17 @@ SINT8 K_GetForwardMove(player_t *player) { SINT8 forwardmove = player->cmd.forwardmove; - if ((player->pflags & PF_STASIS) || (player->pflags & PF_SLIDING)) + if ((player->pflags & PF_STASIS) || (player->carry == CR_SLIDING)) { return 0; } - if (player->kartstuff[k_sneakertimer] || player->kartstuff[k_spindashboost]) + if (player->sneakertimer || player->spindashboost) { return MAXPLMOVE; } - if (player->kartstuff[k_spinouttimer] || K_PlayerEBrake(player)) + if (player->spinouttimer || K_PlayerEBrake(player)) { return 0; } @@ -2700,22 +2973,20 @@ SINT8 K_GetForwardMove(player_t *player) return forwardmove; } -fixed_t K_3dKartMovement(player_t *player) +fixed_t K_GetNewSpeed(player_t *player) { const fixed_t accelmax = 4000; const fixed_t p_speed = K_GetKartSpeed(player, true); const fixed_t p_accel = K_GetKartAccel(player); + fixed_t newspeed, oldspeed, finalspeed; - fixed_t movemul = FRACUNIT; fixed_t orig = ORIG_FRICTION; - SINT8 forwardmove = K_GetForwardMove(player); if (K_PlayerUsesBotMovement(player)) { orig = K_BotFrictionRubberband(player, ORIG_FRICTION); } - // ACCELCODE!!!1!11! oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); // Don't calculate the acceleration as ever being above top speed if (oldspeed > p_speed) @@ -2723,6 +2994,17 @@ fixed_t K_3dKartMovement(player_t *player) newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), orig); finalspeed = newspeed - oldspeed; + + return finalspeed; +} + +fixed_t K_3dKartMovement(player_t *player) +{ + fixed_t finalspeed = K_GetNewSpeed(player); + + fixed_t movemul = FRACUNIT; + SINT8 forwardmove = K_GetForwardMove(player); + movemul = abs(forwardmove * FRACUNIT) / 50; // forwardmove is: @@ -2753,74 +3035,66 @@ angle_t K_MomentumAngle(mobj_t *mo) } } -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) +void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) { - boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1)); - boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2)); + if (mo == NULL || P_MobjWasRemoved(mo)) + { + return; + } - INT32 tics1 = tics; - INT32 tics2 = tics; + mo->hitlag += tics; + mo->hitlag = min(mo->hitlag, MAXHITLAGTICS); + + if (fromDamage == true) + { + // Dunno if this should flat-out &~ the flag out too. + // Decided it probably just just keep it since it's "adding" hitlag. + mo->eflags |= MFE_DAMAGEHITLAG; + } +} + +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage) +{ + INT32 finalTics = tics; if (tics <= 0) { return; } - if (mo1valid == true && mo2valid == true) + if ((mo1 && !P_MobjWasRemoved(mo1)) == true && (mo2 && !P_MobjWasRemoved(mo2)) == true) { - const INT32 mintics = tics; - const fixed_t ticaddfactor = mapobjectscale * 8; + const fixed_t speedTicFactor = (mapobjectscale * 8); + const INT32 angleTicFactor = ANGLE_22h; const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz); const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz); - const fixed_t speeddiff = mo2speed - mo1speed; + const fixed_t speedDiff = abs(mo2speed - mo1speed); - const fixed_t scalediff = mo2->scale - mo1->scale; + const fixed_t scaleDiff = abs(mo2->scale - mo1->scale); - const angle_t mo1angle = K_MomentumAngle(mo1); - const angle_t mo2angle = K_MomentumAngle(mo2); + angle_t mo1angle = K_MomentumAngle(mo1); + angle_t mo2angle = K_MomentumAngle(mo2); + INT32 angleDiff = 0; - angle_t anglediff = mo1angle - mo2angle; - fixed_t anglemul = FRACUNIT; - - if (anglediff > ANGLE_180) + if (mo1speed > 0 && mo2speed > 0) { - anglediff = InvAngle(anglediff); + // If either object is completely not moving, their speed doesn't matter. + angleDiff = AngleDelta(mo1angle, mo2angle); } - anglemul = FRACUNIT + (AngleFixed(anglediff) / 180); // x1.0 at 0, x1.5 at 90, x2.0 at 180 + // Add extra "damage" based on what was happening to the objects on impact. + finalTics += (FixedMul(speedDiff, FRACUNIT + scaleDiff) / speedTicFactor) + (angleDiff / angleTicFactor); - /* - CONS_Printf("anglemul: %f\n", FIXED_TO_FLOAT(anglemul)); - CONS_Printf("speeddiff: %f\n", FIXED_TO_FLOAT(speeddiff)); - CONS_Printf("scalediff: %f\n", FIXED_TO_FLOAT(scalediff)); - */ - - tics1 += FixedMul(speeddiff, FixedMul(anglemul, FRACUNIT + scalediff)) / ticaddfactor; - tics2 += FixedMul(-speeddiff, FixedMul(anglemul, FRACUNIT - scalediff)) / ticaddfactor; - - if (tics1 < mintics) + // This shouldn't happen anymore, but just in case something funky happens. + if (finalTics < tics) { - tics1 = mintics; - } - - if (tics2 < mintics) - { - tics2 = mintics; + finalTics = tics; } } - //CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2); - - if (mo1valid == true) - { - mo1->hitlag = max(tics1, mo1->hitlag); - } - - if (mo2valid == true) - { - mo2->hitlag = max(tics2, mo2->hitlag); - } + K_AddHitLag(mo1, finalTics, fromDamage); + K_AddHitLag(mo2, finalTics, fromDamage); } void K_DoInstashield(player_t *player) @@ -2828,10 +3102,10 @@ void K_DoInstashield(player_t *player) mobj_t *layera; mobj_t *layerb; - if (player->kartstuff[k_instashield] > 0) + if (player->instashield > 0) return; - player->kartstuff[k_instashield] = 15; // length of instashield animation + player->instashield = 15; // length of instashield animation S_StartSound(player->mo, sfx_cdpcm9); layera = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDA); @@ -2893,9 +3167,9 @@ void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 typ (void)inflictor; (void)source; - player->kartstuff[k_spinouttype] = type; + player->spinouttype = type; - if (( player->kartstuff[k_spinouttype] & KSPIN_THRUST )) + if (( player->spinouttype & KSPIN_THRUST )) { // At spinout, player speed is increased to 1/4 their regular speed, moving them forward if (player->speed < K_GetKartSpeed(player, true)/4) @@ -2903,7 +3177,7 @@ void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 typ S_StartSound(player->mo, sfx_slip); } - player->kartstuff[k_spinouttimer] = (3*TICRATE/2)+2; + player->spinouttimer = (3*TICRATE/2)+2; P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } @@ -2911,12 +3185,12 @@ static void K_RemoveGrowShrink(player_t *player) { if (player->mo && !P_MobjWasRemoved(player->mo)) { - if (player->kartstuff[k_growshrinktimer] > 0) // Play Shrink noise + if (player->growshrinktimer > 0) // Play Shrink noise S_StartSound(player->mo, sfx_kc59); - else if (player->kartstuff[k_growshrinktimer] < 0) // Play Grow noise + else if (player->growshrinktimer < 0) // Play Grow noise S_StartSound(player->mo, sfx_kc5a); - if (player->kartstuff[k_invincibilitytimer] == 0) + if (player->invincibilitytimer == 0) player->mo->color = player->skincolor; player->mo->scalespeed = mapobjectscale/TICRATE; @@ -2925,7 +3199,7 @@ static void K_RemoveGrowShrink(player_t *player) player->mo->destscale = (6*player->mo->destscale)/8; } - player->kartstuff[k_growshrinktimer] = 0; + player->growshrinktimer = 0; P_RestoreMusic(player); } @@ -2937,11 +3211,19 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) player->tumbleBounces = 1; - player->mo->momx = 2 * player->mo->momx / 3; - player->mo->momy = 2 * player->mo->momy / 3; + if (player->tripWireState == TRIP_PASSED) + { + player->tumbleHeight = 50; + } + else + { + player->mo->momx = 2 * player->mo->momx / 3; + player->mo->momy = 2 * player->mo->momy / 3; - player->tumbleHeight = 30; - player->tumbleSound = 0; + player->tumbleHeight = 30; + } + + player->pflags &= ~PF_TUMBLESOUND; if (inflictor && !P_MobjWasRemoved(inflictor)) { @@ -2970,15 +3252,15 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) static boolean K_LastTumbleBounceCondition(player_t *player) { - return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 40); + return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60); } static void K_HandleTumbleBounce(player_t *player) { fixed_t gravityadjust; player->tumbleBounces++; - player->tumbleHeight = (player->tumbleHeight * 4) / 5; - player->tumbleSound = 0; + player->tumbleHeight = (player->tumbleHeight * ((player->tumbleHeight > 100) ? 3 : 4)) / 5; + player->pflags &= ~PF_TUMBLESOUND; if (player->tumbleHeight < 10) { @@ -2990,18 +3272,18 @@ static void K_HandleTumbleBounce(player_t *player) { // Leave tumble state when below 40 height, and have bounced off the ground enough - if (player->tumbleLastBounce == true) + if (player->pflags & PF_TUMBLELASTBOUNCE) { // End tumble state player->tumbleBounces = 0; - player->tumbleLastBounce = false; // Reset for next time + player->pflags &= ~PF_TUMBLELASTBOUNCE; // Reset for next time return; } else { // One last bounce at the minimum height, to reset the animation player->tumbleHeight = 10; - player->tumbleLastBounce = true; + player->pflags |= PF_TUMBLELASTBOUNCE; player->mo->rollangle = 0; // p_user.c will stop rotating the player automatically } } @@ -3033,10 +3315,27 @@ static void K_HandleTumbleSound(player_t *player) momz = player->mo->momz * P_MobjFlip(player->mo); if (!K_LastTumbleBounceCondition(player) && - !player->tumbleSound && momz < -10*player->mo->scale) + !(player->pflags & PF_TUMBLESOUND) && momz < -10*player->mo->scale) { S_StartSound(player->mo, sfx_s3k51); - player->tumbleSound = 1; + player->pflags |= PF_TUMBLESOUND; + } +} + +void K_ApplyTripWire(player_t *player, tripwirestate_t state) +{ + if (state == TRIP_PASSED) + S_StartSound(player->mo, sfx_ssa015); + else if (state == TRIP_BLOCKED) + S_StartSound(player->mo, sfx_kc40); + + player->tripWireState = state; + K_AddHitLag(player->mo, 10, false); + + if (state == TRIP_PASSED && player->spinouttimer && + player->speed > 2* K_GetKartSpeed(player, false)) + { + K_TumblePlayer(player, NULL, NULL); } } @@ -3049,14 +3348,14 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A player->mo->momz = 18*mapobjectscale*P_MobjFlip(player->mo); // please stop forgetting mobjflip checks!!!! player->mo->momx = player->mo->momy = 0; - player->kartstuff[k_spinouttype] = KSPIN_EXPLOSION; - player->kartstuff[k_spinouttimer] = (3*TICRATE/2)+2; + player->spinouttype = KSPIN_EXPLOSION; + player->spinouttimer = (3*TICRATE/2)+2; if (inflictor && !P_MobjWasRemoved(inflictor)) { if (inflictor->type == MT_SPBEXPLOSION && inflictor->extravalue1) { - player->kartstuff[k_spinouttimer] = ((5*player->kartstuff[k_spinouttimer])/2)+1; + player->spinouttimer = ((5*player->spinouttimer)/2)+1; player->mo->momz *= 2; ringburst = 20; } @@ -3083,9 +3382,9 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) length += (4 * (source->player->kartweight - player->kartweight)); } - player->kartstuff[k_spinouttype] = KSPIN_STUNG; - player->kartstuff[k_spinouttimer] = length; - player->kartstuff[k_wipeoutslow] = min(length-1, wipeoutslowtime+1); + player->spinouttype = KSPIN_STUNG; + player->spinouttimer = length; + player->wipeoutslow = min(length-1, wipeoutslowtime+1); P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } @@ -3102,14 +3401,6 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers) if (player->bumpers > 0 && prevBumpers == 0) { - if (player->kartstuff[k_comebackmode] == 2) - { - mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE); - S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound); - } - - player->kartstuff[k_comebackmode] = 0; - if (netgame) { CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); @@ -3493,7 +3784,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I case MT_JAWZ: if (source && source->player) { - INT32 lasttarg = source->player->kartstuff[k_lastjawztarget]; + INT32 lasttarg = source->player->lastjawztarget; th->cvmem = source->player->skincolor; if ((lasttarg >= 0 && lasttarg < MAXPLAYERS) && playeringame[lasttarg] @@ -3537,7 +3828,11 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I UINT16 K_DriftSparkColor(player_t *player, INT32 charge) { - INT32 ds = K_GetKartDriftSparkValue(player); + const INT32 dsone = K_GetKartDriftSparkValueForStage(player, 1); + const INT32 dstwo = K_GetKartDriftSparkValueForStage(player, 2); + const INT32 dsthree = K_GetKartDriftSparkValueForStage(player, 3); + const INT32 dsfour = K_GetKartDriftSparkValueForStage(player, 4); + UINT16 color = SKINCOLOR_NONE; if (charge < 0) @@ -3545,10 +3840,10 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge) // Stage 0: Yellow color = SKINCOLOR_GOLD; } - else if (charge >= ds*4) + else if (charge >= dsfour) { - // Stage 3: Rainbow - if (charge <= (ds*4)+(32*3)) + // Stage 4: Rainbow + if (charge <= dsfour+(32*3)) { // transition color = SKINCOLOR_SILVER; @@ -3558,23 +3853,41 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge) color = K_RainbowColor(leveltime); } } - else if (charge >= ds*2) + else if (charge >= dsthree) + { + // Stage 3: Purple + if (charge <= dsthree+(16*3)) + { + // transition 1 + color = SKINCOLOR_TAFFY; + } + else if (charge <= dsthree+(32*3)) + { + // transition 2 + color = SKINCOLOR_MOONSET; + } + else + { + color = SKINCOLOR_PURPLE; + } + } + else if (charge >= dstwo) { // Stage 2: Blue - if (charge <= (ds*2)+(32*3)) + if (charge <= dstwo+(32*3)) { // transition - color = SKINCOLOR_PURPLE; + color = SKINCOLOR_NOVA; } else { color = SKINCOLOR_SAPPHIRE; } } - else if (charge >= ds) + else if (charge >= dsone) { // Stage 1: Red - if (charge <= (ds)+(32*3)) + if (charge <= dsone+(32*3)) { // transition color = SKINCOLOR_TANGERINE; @@ -3588,9 +3901,102 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge) return color; } +static void K_SpawnDriftElectricity(player_t *player) +{ + UINT8 i; + UINT16 color = K_DriftSparkColor(player, player->driftcharge); + mobj_t *mo = player->mo; + fixed_t vr = FixedDiv(mo->radius/3, mo->scale); // P_SpawnMobjFromMobj will rescale + fixed_t horizontalradius = FixedDiv(5*mo->radius/3, mo->scale); + angle_t verticalangle = K_MomentumAngle(mo) + ANGLE_180; // points away from the momentum angle + + for (i = 0; i < 2; i++) + { + // i == 0 is right, i == 1 is left + mobj_t *spark; + angle_t horizonatalangle = verticalangle + (i ? ANGLE_90 : ANGLE_270); + angle_t sparkangle = verticalangle + ANGLE_180; + fixed_t verticalradius = vr; // local version of the above so we can modify it + fixed_t scalefactor = 0; // positive values enlarge sparks, negative values shrink them + fixed_t x, y; + + if (player->drift == 0) + ; // idk what you're doing spawning drift sparks when you're not drifting but you do you + else + { + scalefactor = -(2*i - 1) * min(max(player->steering, -1), 1) * FRACUNIT; + if ((player->drift > 0) == !(i)) // inwards spark should be closer to the player + verticalradius = 0; + } + + x = P_ReturnThrustX(mo, verticalangle, verticalradius) + + P_ReturnThrustX(mo, horizonatalangle, horizontalradius); + y = P_ReturnThrustY(mo, verticalangle, verticalradius) + + P_ReturnThrustY(mo, horizonatalangle, horizontalradius); + spark = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRIFTELECTRICITY); + spark->angle = sparkangle; + spark->color = color; + K_GenericExtraFlagsNoZAdjust(spark, mo); + + spark->spritexscale += scalefactor/3; + spark->spriteyscale += scalefactor/8; + } +} + +void K_SpawnDriftElectricSparks(player_t *player) +{ + SINT8 hdir, vdir, i; + + mobj_t *mo = player->mo; + angle_t momangle = K_MomentumAngle(mo) + ANGLE_180; + fixed_t radius = 2 * FixedDiv(mo->radius, mo->scale); // P_SpawnMobjFromMobj will rescale + fixed_t x = P_ReturnThrustX(mo, momangle, radius); + fixed_t y = P_ReturnThrustY(mo, momangle, radius); + fixed_t z = FixedDiv(mo->height, 2 * mo->scale); // P_SpawnMobjFromMobj will rescale + + fixed_t sparkspeed = mobjinfo[MT_DRIFTELECTRICSPARK].speed; + fixed_t sparkradius = 2 * mobjinfo[MT_DRIFTELECTRICSPARK].radius; + UINT16 color = K_DriftSparkColor(player, player->driftcharge); + + // if the sparks are spawned from first blood rather than drift boost, color will be SKINCOLOR_NONE. ew! + if (color == SKINCOLOR_NONE) + color = SKINCOLOR_SILVER; + + for (hdir = -1; hdir <= 1; hdir += 2) + { + for (vdir = -1; vdir <= 1; vdir += 2) + { + fixed_t hspeed = FixedMul(hdir * sparkspeed, mo->scale); // P_InstaThrust treats speed as absolute + fixed_t vspeed = vdir * sparkspeed; // P_SetObjectMomZ scales speed with object scale + angle_t sparkangle = mo->angle + ANGLE_45; + + for (i = 0; i < 4; i++) + { + fixed_t xoff = P_ReturnThrustX(mo, sparkangle, sparkradius); + fixed_t yoff = P_ReturnThrustY(mo, sparkangle, sparkradius); + mobj_t *spark = P_SpawnMobjFromMobj(mo, x + xoff, y + yoff, z, MT_DRIFTELECTRICSPARK); + + spark->angle = sparkangle; + spark->color = color; + P_InstaThrust(spark, mo->angle + ANGLE_90, hspeed); + P_SetObjectMomZ(spark, vspeed, false); + spark->momx += mo->momx; // copy player speed + spark->momy += mo->momy; + + sparkangle += ANGLE_90; + } + } + } + S_StartSound(mo, sfx_s3k45); +} + static void K_SpawnDriftSparks(player_t *player) { - INT32 ds = K_GetKartDriftSparkValue(player); + const INT32 dsone = K_GetKartDriftSparkValueForStage(player, 1); + const INT32 dstwo = K_GetKartDriftSparkValueForStage(player, 2); + const INT32 dsthree = K_GetKartDriftSparkValueForStage(player, 3); + const INT32 dsfour = K_GetKartDriftSparkValueForStage(player, 4); + fixed_t newx; fixed_t newy; mobj_t *spark; @@ -3604,11 +4010,11 @@ static void K_SpawnDriftSparks(player_t *player) if (leveltime % 2 == 1) return; - if (!player->kartstuff[k_drift] - || (player->kartstuff[k_driftcharge] < ds && !(player->kartstuff[k_driftcharge] < 0))) + if (!player->drift + || (player->driftcharge < dsone && !(player->driftcharge < 0))) return; - travelangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift]; + travelangle = player->mo->angle-(ANGLE_45/5)*player->drift; for (i = 0; i < 2; i++) { @@ -3620,7 +4026,7 @@ static void K_SpawnDriftSparks(player_t *player) spark = P_SpawnMobj(newx, newy, player->mo->z, MT_DRIFTSPARK); P_SetTarget(&spark->target, player->mo); - spark->angle = travelangle-(ANGLE_45/5)*player->kartstuff[k_drift]; + spark->angle = travelangle-(ANGLE_45/5)*player->drift; spark->destscale = player->mo->scale; P_SetScale(spark, player->mo->scale); @@ -3628,20 +4034,20 @@ static void K_SpawnDriftSparks(player_t *player) spark->momy = player->mo->momy/2; //spark->momz = player->mo->momz/2; - spark->color = K_DriftSparkColor(player, player->kartstuff[k_driftcharge]); + spark->color = K_DriftSparkColor(player, player->driftcharge); - if (player->kartstuff[k_driftcharge] < 0) + if (player->driftcharge < 0) { // Stage 0: Yellow size = 0; } - else if (player->kartstuff[k_driftcharge] >= ds*4) + else if (player->driftcharge >= dsfour) { - // Stage 3: Rainbow + // Stage 4: Rainbow size = 2; trail = 2; - if (player->kartstuff[k_driftcharge] <= (ds*4)+(32*3)) + if (player->driftcharge <= (dsfour)+(32*3)) { // transition P_SetScale(spark, (spark->destscale = spark->scale*3/2)); @@ -3652,13 +4058,25 @@ static void K_SpawnDriftSparks(player_t *player) spark->colorized = true; } } - else if (player->kartstuff[k_driftcharge] >= ds*2) + else if (player->driftcharge >= dsthree) + { + // Stage 3: Purple + size = 2; + trail = 1; + + if (player->driftcharge <= dsthree+(32*3)) + { + // transition + P_SetScale(spark, (spark->destscale = spark->scale*3/2)); + } + } + else if (player->driftcharge >= dstwo) { // Stage 2: Blue size = 2; trail = 1; - if (player->kartstuff[k_driftcharge] <= (ds*2)+(32*3)) + if (player->driftcharge <= dstwo+(32*3)) { // transition P_SetScale(spark, (spark->destscale = spark->scale*3/2)); @@ -3669,37 +4087,37 @@ static void K_SpawnDriftSparks(player_t *player) // Stage 1: Red size = 1; - if (player->kartstuff[k_driftcharge] <= (ds)+(32*3)) + if (player->driftcharge <= dsone+(32*3)) { // transition P_SetScale(spark, (spark->destscale = spark->scale*2)); } } - if ((player->kartstuff[k_drift] > 0 && player->cmd.turning > 0) // Inward drifts - || (player->kartstuff[k_drift] < 0 && player->cmd.turning < 0)) + if ((player->drift > 0 && player->steering > 0) // Inward drifts + || (player->drift < 0 && player->steering < 0)) { - if ((player->kartstuff[k_drift] < 0 && (i & 1)) - || (player->kartstuff[k_drift] > 0 && !(i & 1))) + if ((player->drift < 0 && (i & 1)) + || (player->drift > 0 && !(i & 1))) { size++; } - else if ((player->kartstuff[k_drift] < 0 && !(i & 1)) - || (player->kartstuff[k_drift] > 0 && (i & 1))) + else if ((player->drift < 0 && !(i & 1)) + || (player->drift > 0 && (i & 1))) { size--; } } - else if ((player->kartstuff[k_drift] > 0 && player->cmd.turning < 0) // Outward drifts - || (player->kartstuff[k_drift] < 0 && player->cmd.turning > 0)) + else if ((player->drift > 0 && player->steering < 0) // Outward drifts + || (player->drift < 0 && player->steering > 0)) { - if ((player->kartstuff[k_drift] < 0 && (i & 1)) - || (player->kartstuff[k_drift] > 0 && !(i & 1))) + if ((player->drift < 0 && (i & 1)) + || (player->drift > 0 && !(i & 1))) { size--; } - else if ((player->kartstuff[k_drift] < 0 && !(i & 1)) - || (player->kartstuff[k_drift] > 0 && (i & 1))) + else if ((player->drift < 0 && !(i & 1)) + || (player->drift > 0 && (i & 1))) { size++; } @@ -3717,6 +4135,11 @@ static void K_SpawnDriftSparks(player_t *player) K_MatchGenericExtraFlags(spark, player->mo); } + + if (player->driftcharge >= dsthree) + { + K_SpawnDriftElectricity(player); + } } static void K_SpawnAIZDust(player_t *player) @@ -3743,11 +4166,11 @@ static void K_SpawnAIZDust(player_t *player) //S_StartSound(player->mo, sfx_s3k47); { - newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle - (player->kartstuff[k_aizdriftstrat]*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale)); - newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle - (player->kartstuff[k_aizdriftstrat]*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale)); + newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle - (player->aizdriftstrat*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale)); + newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle - (player->aizdriftstrat*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale)); spark = P_SpawnMobj(newx, newy, player->mo->z, MT_AIZDRIFTSTRAT); - spark->angle = travelangle+(player->kartstuff[k_aizdriftstrat]*ANGLE_90); + spark->angle = travelangle+(player->aizdriftstrat*ANGLE_90); P_SetScale(spark, (spark->destscale = (3*player->mo->scale)>>2)); spark->momx = (6*player->mo->momx)/5; @@ -3771,7 +4194,7 @@ void K_SpawnBoostTrail(player_t *player) I_Assert(!P_MobjWasRemoved(player->mo)); if (!P_IsObjectOnGround(player->mo) - || player->kartstuff[k_hyudorotimer] != 0 + || player->hyudorotimer != 0 || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)) return; @@ -3780,7 +4203,7 @@ void K_SpawnBoostTrail(player_t *player) else ground = player->mo->floorz; - if (player->kartstuff[k_drift] != 0) + if (player->drift != 0) travelangle = player->mo->angle; else travelangle = K_MomentumAngle(player->mo); @@ -3828,23 +4251,23 @@ void K_SpawnSparkleTrail(mobj_t *mo) INT32 i; UINT8 invanimnum; // Current sparkle animation number INT32 invtime;// Invincibility time left, in seconds - UINT8 index = 1; + UINT8 index = 0; fixed_t newx, newy, newz; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - if ((mo->player->kartstuff[k_sneakertimer] - || mo->player->kartstuff[k_ringboost] || mo->player->kartstuff[k_driftboost] - || mo->player->kartstuff[k_startboost] || mo->player->kartstuff[k_eggmanexplode])) + if ((mo->player->sneakertimer + || mo->player->ringboost || mo->player->driftboost + || mo->player->startboost || mo->player->eggmanexplode)) { return; } if (leveltime & 2) - index = 2; + index = 1; - invtime = mo->player->kartstuff[k_invincibilitytimer]/TICRATE+1; + invtime = mo->player->invincibilitytimer/TICRATE+1; //CONS_Printf("%d\n", index); @@ -3935,17 +4358,17 @@ void K_SpawnDraftDust(mobj_t *mo) ang = mo->player->drawangle; - if (mo->player->kartstuff[k_drift] != 0) + if (mo->player->drift != 0) { drifting = true; - ang += (mo->player->kartstuff[k_drift] * ((ANGLE_270 + ANGLE_22h) / 5)); // -112.5 doesn't work. I fucking HATE SRB2 angles - if (mo->player->kartstuff[k_drift] < 0) + ang += (mo->player->drift * ((ANGLE_270 + ANGLE_22h) / 5)); // -112.5 doesn't work. I fucking HATE SRB2 angles + if (mo->player->drift < 0) sign = 1; else sign = -1; } - foff = 5 - ((mo->player->kartstuff[k_draftleeway] * 5) / leniency); + foff = 5 - ((mo->player->draftleeway * 5) / leniency); // this shouldn't happen if (foff > 4) @@ -4056,11 +4479,11 @@ void K_DriftDustHandling(mobj_t *spawner) K_MatchGenericExtraFlags(dust, spawner); // Sparkle-y warning for when you're about to change drift sparks! - if (spawner->player && spawner->player->kartstuff[k_drift]) + if (spawner->player && spawner->player->drift) { INT32 driftval = K_GetKartDriftSparkValue(spawner->player); INT32 warntime = driftval/3; - INT32 dc = spawner->player->kartstuff[k_driftcharge]; + INT32 dc = spawner->player->driftcharge; UINT8 c = SKINCOLOR_NONE; boolean rainbow = false; @@ -4101,7 +4524,7 @@ static mobj_t *K_FindLastTrailMobj(player_t *player) return trail; } -static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow) +mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow) { mobj_t *mo; INT32 dir; @@ -4134,14 +4557,14 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map if (altthrow == 2) // Kitchen sink throwing { #if 0 - if (player->kartstuff[k_throwdir] == 1) + if (player->throwdir == 1) dir = 3; - else if (player->kartstuff[k_throwdir] == -1) + else if (player->throwdir == -1) dir = 1; else dir = 2; #else - if (player->kartstuff[k_throwdir] == 1) + if (player->throwdir == 1) dir = 2; else dir = 1; @@ -4149,9 +4572,9 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map } else { - if (player->kartstuff[k_throwdir] == 1) + if (player->throwdir == 1) dir = 2; - else if (player->kartstuff[k_throwdir] == -1) + else if (player->throwdir == -1) dir = -1; else dir = 1; @@ -4159,8 +4582,8 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map } else { - if (player->kartstuff[k_throwdir] != 0) - dir = player->kartstuff[k_throwdir]; + if (player->throwdir != 0) + dir = player->throwdir; else dir = defaultDir; } @@ -4204,7 +4627,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map } else { - player->kartstuff[k_bananadrag] = 0; // RESET timer, for multiple bananas + player->bananadrag = 0; // RESET timer, for multiple bananas if (dir > 0) { @@ -4360,12 +4783,17 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter) // Since we aren't using P_KillMobj, we need to clean up the hnext reference P_SetTarget(&mineOwner->hnext, NULL); - mineOwner->player->kartstuff[k_bananadrag] = 0; - mineOwner->player->kartstuff[k_itemheld] = 0; + mineOwner->player->bananadrag = 0; + mineOwner->player->pflags &= ~PF_ITEMOUT; - if (--mineOwner->player->kartstuff[k_itemamount] <= 0) + if (mineOwner->player->itemamount) { - mineOwner->player->kartstuff[k_itemtype] = KITEM_NONE; + mineOwner->player->itemamount--; + } + + if (!mineOwner->player->itemamount) + { + mineOwner->player->itemtype = KITEM_NONE; } P_RemoveMobj(origMine); @@ -4490,13 +4918,13 @@ static void K_DoHyudoroSteal(player_t *player) && player != &players[i] && !players[i].exiting && !players[i].spectator // Player in-game // Can steal from this player - && (gametype == GT_RACE //&& players[i].kartstuff[k_position] < player->kartstuff[k_position]) + && (gametype == GT_RACE //&& players[i].position < player->position) || ((gametyperules & GTR_BUMPERS) && players[i].bumpers > 0)) // Has an item - && (players[i].kartstuff[k_itemtype] - && players[i].kartstuff[k_itemamount] - && !players[i].kartstuff[k_itemheld] + && (players[i].itemtype + && players[i].itemamount + && !(players[i].pflags & PF_ITEMOUT) && !players[i].karthud[khud_itemblink])) { playerswappable[numplayers] = i; @@ -4509,18 +4937,18 @@ static void K_DoHyudoroSteal(player_t *player) if (sink && numplayers > 0 && cv_kitchensink.value) // BEHOLD THE KITCHEN SINK { - player->kartstuff[k_hyudorotimer] = hyu; - player->kartstuff[k_stealingtimer] = stealtime; + player->hyudorotimer = hyu; + player->stealingtimer = stealtime; - player->kartstuff[k_itemtype] = KITEM_KITCHENSINK; - player->kartstuff[k_itemamount] = 1; - player->kartstuff[k_itemheld] = 0; + player->itemtype = KITEM_KITCHENSINK; + player->itemamount = 1; + player->pflags &= ~PF_ITEMOUT; return; } - else if ((gametype == GT_RACE && player->kartstuff[k_position] == 1) || numplayers == 0) // No-one can be stolen from? Oh well... + else if ((gametype == GT_RACE && player->position == 1) || numplayers == 0) // No-one can be stolen from? Oh well... { - player->kartstuff[k_hyudorotimer] = hyu; - player->kartstuff[k_stealingtimer] = stealtime; + player->hyudorotimer = hyu; + player->stealingtimer = stealtime; return; } else if (numplayers == 1) // With just 2 players, we just need to set the other player to be the one to steal from @@ -4534,17 +4962,17 @@ static void K_DoHyudoroSteal(player_t *player) if (stealplayer > -1) // Now here's where we do the stealing, has to be done here because we still know the player we're stealing from { - player->kartstuff[k_hyudorotimer] = hyu; - player->kartstuff[k_stealingtimer] = stealtime; - players[stealplayer].kartstuff[k_stolentimer] = stealtime; + player->hyudorotimer = hyu; + player->stealingtimer = stealtime; + players[stealplayer].stealingtimer = -stealtime; - player->kartstuff[k_itemtype] = players[stealplayer].kartstuff[k_itemtype]; - player->kartstuff[k_itemamount] = players[stealplayer].kartstuff[k_itemamount]; - player->kartstuff[k_itemheld] = 0; + player->itemtype = players[stealplayer].itemtype; + player->itemamount = players[stealplayer].itemamount; + player->pflags &= ~PF_ITEMOUT; - players[stealplayer].kartstuff[k_itemtype] = KITEM_NONE; - players[stealplayer].kartstuff[k_itemamount] = 0; - players[stealplayer].kartstuff[k_itemheld] = 0; + players[stealplayer].itemtype = KITEM_NONE; + players[stealplayer].itemamount = 0; + players[stealplayer].pflags &= ~PF_ITEMOUT; if (P_IsDisplayPlayer(&players[stealplayer]) && !r_splitscreen) S_StartSound(NULL, sfx_s3k92); @@ -4555,13 +4983,13 @@ void K_DoSneaker(player_t *player, INT32 type) { const fixed_t intendedboost = FRACUNIT/2; - if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) + if (!player->floorboost || player->floorboost == 3) { const sfxenum_t normalsfx = sfx_cdfm01; const sfxenum_t smallsfx = sfx_cdfm40; sfxenum_t sfx = normalsfx; - if (player->kartstuff[k_numsneakers]) + if (player->numsneakers) { // Use a less annoying sound when stacking sneakers. sfx = smallsfx; @@ -4572,13 +5000,13 @@ void K_DoSneaker(player_t *player, INT32 type) S_StartSound(player->mo, sfx); K_SpawnDashDustRelease(player); - if (intendedboost > player->kartstuff[k_speedboost]) - player->karthud[khud_destboostcam] = FixedMul(FRACUNIT, FixedDiv((intendedboost - player->kartstuff[k_speedboost]), intendedboost)); + if (intendedboost > player->speedboost) + player->karthud[khud_destboostcam] = FixedMul(FRACUNIT, FixedDiv((intendedboost - player->speedboost), intendedboost)); - player->kartstuff[k_numsneakers]++; + player->numsneakers++; } - if (!player->kartstuff[k_sneakertimer]) + if (!player->sneakertimer) { if (type == 2) { @@ -4615,10 +5043,10 @@ void K_DoSneaker(player_t *player, INT32 type) } - player->kartstuff[k_sneakertimer] = sneakertime; + player->sneakertimer = sneakertime; // set angle for spun out players: - player->kartstuff[k_boostangle] = (INT32)player->mo->angle; + player->boostangle = (INT32)player->mo->angle; } static void K_DoShrink(player_t *user) @@ -4635,18 +5063,18 @@ static void K_DoShrink(player_t *user) continue; if (&players[i] == user) continue; - if (players[i].kartstuff[k_position] < user->kartstuff[k_position]) + if (players[i].position < user->position) { //P_FlashPal(&players[i], PAL_NUKE, 10); // Grow should get taken away. - if (players[i].kartstuff[k_growshrinktimer] > 0) + if (players[i].growshrinktimer > 0) K_RemoveGrowShrink(&players[i]); else { // Start shrinking! K_DropItems(&players[i]); - players[i].kartstuff[k_growshrinktimer] = -(15*TICRATE); + players[i].growshrinktimer = -(15*TICRATE); if (players[i].mo && !P_MobjWasRemoved(players[i].mo)) { @@ -4674,7 +5102,7 @@ static void K_DoShrink(player_t *user) { if (mobj->target && mobj->target->player) { - if (mobj->target->player->kartstuff[k_position] > user->kartstuff[k_position]) + if (mobj->target->player->position > user->position) continue; // this guy's behind us, don't take his stuff away! } } @@ -4715,16 +5143,19 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) if (mo->player) { - if (mo->player->kartstuff[k_sneakertimer]) + if (mo->player->sneakertimer) { thrust = FixedMul(thrust, 5*FRACUNIT/4); } - else if (mo->player->kartstuff[k_invincibilitytimer]) + else if (mo->player->invincibilitytimer) { thrust = FixedMul(thrust, 9*FRACUNIT/8); } - mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = 0; // Reset post-hitlag momentums. + mo->player->tricktime = 0; // Reset post-hitlag timer + // Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25) + mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100; + //CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT); } mo->momz = FixedMul(thrust, vscale); @@ -4814,7 +5245,7 @@ void K_UpdateHnextList(player_t *player, boolean clean) { nextwork = work->hnext; - if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount])) + if (!clean && (!work->movedir || work->movedir <= (UINT16)player->itemamount)) { continue; } @@ -4837,7 +5268,7 @@ void K_DropHnextList(player_t *player, boolean keepshields) INT32 flip; mobjtype_t type; boolean orbit, ponground, dropall = true; - INT32 shield = K_GetShieldFromItem(player->kartstuff[k_itemtype]); + INT32 shield = K_GetShieldFromItem(player->itemtype); if (work == NULL || P_MobjWasRemoved(work)) { @@ -4854,9 +5285,10 @@ void K_DropHnextList(player_t *player, boolean keepshields) K_DoThunderShield(player); } - player->kartstuff[k_curshield] = KSHIELD_NONE; - player->kartstuff[k_itemtype] = KITEM_NONE; - player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; + player->curshield = KSHIELD_NONE; + player->itemtype = KITEM_NONE; + player->itemamount = 0; + player->pflags &= ~PF_ITEMOUT; } nextwork = work->hnext; @@ -4978,17 +5410,18 @@ void K_DropHnextList(player_t *player, boolean keepshields) // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... P_SetTarget(&player->mo->hnext, NULL); - player->kartstuff[k_bananadrag] = 0; + player->bananadrag = 0; - if (player->kartstuff[k_eggmanheld]) + if (player->pflags & PF_EGGMANOUT) { - player->kartstuff[k_eggmanheld] = 0; + player->pflags &= ~PF_EGGMANOUT; } - else if (player->kartstuff[k_itemheld] - && (dropall || (--player->kartstuff[k_itemamount] <= 0))) + else if ((player->pflags & PF_ITEMOUT) + && (dropall || (--player->itemamount <= 0))) { - player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_itemtype] = KITEM_NONE; + player->itemamount = 0; + player->pflags &= ~PF_ITEMOUT; + player->itemtype = KITEM_NONE; } } @@ -5019,7 +5452,15 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 useodds = amount; for (i = 1; i < NUMKARTRESULTS; i++) - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, 0, false, false, false)); + { + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( + useodds, i, + UINT32_MAX, + 0, + false, false, false + ) + ); + } if (totalspawnchance > 0) { @@ -5109,12 +5550,12 @@ void K_DropItems(player_t *player) { K_DropHnextList(player, true); - if (player->mo && !P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount] > 0) + if (player->mo && !P_MobjWasRemoved(player->mo) && player->itemamount > 0) { mobj_t *drop = K_CreatePaperItem( player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, player->mo->angle + ANGLE_90, P_MobjFlip(player->mo), - player->kartstuff[k_itemtype], player->kartstuff[k_itemamount] + player->itemtype, player->itemamount ); K_FlipFromObject(drop, player->mo); @@ -5163,7 +5604,7 @@ void K_DropRocketSneaker(player_t *player) leftshoe = false; } P_SetTarget(&player->mo->hnext, NULL); - player->kartstuff[k_rocketsneakertimer] = 0; + player->rocketsneakertimer = 0; } void K_DropKitchenSink(player_t *player) @@ -5209,14 +5650,14 @@ void K_RepairOrbitChain(mobj_t *orbit) { prev = cur; cur = cur->hnext; - if (++num > orbit->target->player->kartstuff[k_itemamount]) + if (++num > orbit->target->player->itemamount) P_RemoveMobj(prev); else prev->movedir = num; } - if (orbit->target->player->kartstuff[k_itemamount] != num) - orbit->target->player->kartstuff[k_itemamount] = num; + if (orbit->target->player->itemamount != num) + orbit->target->player->itemamount = num; } } @@ -5359,13 +5800,14 @@ static void K_MoveHeldObjects(player_t *player) if (!player->mo->hnext) { - player->kartstuff[k_bananadrag] = 0; - if (player->kartstuff[k_eggmanheld]) - player->kartstuff[k_eggmanheld] = 0; - else if (player->kartstuff[k_itemheld]) + player->bananadrag = 0; + if (player->pflags & PF_EGGMANOUT) + player->pflags &= ~PF_EGGMANOUT; + else if (player->pflags & PF_ITEMOUT) { - player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_itemtype] = KITEM_NONE; + player->itemamount = 0; + player->pflags &= ~PF_ITEMOUT; + player->itemtype = KITEM_NONE; } return; } @@ -5374,13 +5816,14 @@ static void K_MoveHeldObjects(player_t *player) { // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... P_SetTarget(&player->mo->hnext, NULL); - player->kartstuff[k_bananadrag] = 0; - if (player->kartstuff[k_eggmanheld]) - player->kartstuff[k_eggmanheld] = 0; - else if (player->kartstuff[k_itemheld]) + player->bananadrag = 0; + if (player->pflags & PF_EGGMANOUT) + player->pflags &= ~PF_EGGMANOUT; + else if (player->pflags & PF_ITEMOUT) { - player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_itemtype] = KITEM_NONE; + player->itemamount = 0; + player->pflags &= ~PF_ITEMOUT; + player->itemtype = KITEM_NONE; } return; } @@ -5391,9 +5834,9 @@ static void K_MoveHeldObjects(player_t *player) case MT_JAWZ_SHIELD: { mobj_t *cur = player->mo->hnext; - fixed_t speed = ((8 - min(4, player->kartstuff[k_itemamount])) * cur->info->speed) / 7; + fixed_t speed = ((8 - min(4, player->itemamount)) * cur->info->speed) / 7; - player->kartstuff[k_bananadrag] = 0; // Just to make sure + player->bananadrag = 0; // Just to make sure while (cur && !P_MobjWasRemoved(cur)) { @@ -5473,7 +5916,7 @@ static void K_MoveHeldObjects(player_t *player) mobj_t *targ = player->mo; if (P_IsObjectOnGround(player->mo) && player->speed > 0) - player->kartstuff[k_bananadrag]++; + player->bananadrag++; while (cur && !P_MobjWasRemoved(cur)) { @@ -5529,7 +5972,7 @@ static void K_MoveHeldObjects(player_t *player) cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy); - /*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE + /*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->bananadrag > TICRATE && P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2))) { if (leveltime & 1) @@ -5570,7 +6013,7 @@ static void K_MoveHeldObjects(player_t *player) cur->flags &= ~MF_NOCLIPTHING; - if (player->kartstuff[k_rocketsneakertimer] <= TICRATE && (leveltime & 1)) + if (player->rocketsneakertimer <= TICRATE && (leveltime & 1)) cur->renderflags |= RF_DONTDRAW; else cur->renderflags &= ~RF_DONTDRAW; @@ -5580,7 +6023,7 @@ static void K_MoveHeldObjects(player_t *player) else P_SetMobjStateNF(cur, (vibrate ? S_ROCKETSNEAKER_RVIBRATE : S_ROCKETSNEAKER_R)); - if (!player->kartstuff[k_rocketsneakertimer] || cur->extravalue2 || !cur->health) + if (!player->rocketsneakertimer || cur->extravalue2 || !cur->health) { num = (num+1) % 2; cur = cur->hnext; @@ -5689,7 +6132,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) continue; // Invisible, don't bother - if (player->kartstuff[k_hyudorotimer]) + if (player->hyudorotimer) continue; // Find the angle, see who's got the best. @@ -5704,12 +6147,12 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) if (thisang > ANGLE_67h) continue; // Don't pay attention to people who aren't above your position - if (player->kartstuff[k_position] >= source->kartstuff[k_position]) + if (player->position >= source->position) continue; - if ((best == -1) || (player->kartstuff[k_position] > best)) + if ((best == -1) || (player->position > best)) { wtarg = player; - best = player->kartstuff[k_position]; + best = player->position; } } else @@ -5902,16 +6345,16 @@ static void K_UpdateInvincibilitySounds(player_t *player) { if (cv_kartinvinsfx.value) { - if (player->kartstuff[k_invincibilitytimer] > 0) // Prioritize invincibility + if (player->invincibilitytimer > 0) // Prioritize invincibility sfxnum = sfx_alarmi; - else if (player->kartstuff[k_growshrinktimer] > 0) + else if (player->growshrinktimer > 0) sfxnum = sfx_alarmg; } else { - if (player->kartstuff[k_invincibilitytimer] > 0) + if (player->invincibilitytimer > 0) sfxnum = sfx_kinvnc; - else if (player->kartstuff[k_growshrinktimer] > 0) + else if (player->growshrinktimer > 0) sfxnum = sfx_kgrow; } } @@ -5943,6 +6386,9 @@ void K_KartPlayerHUDUpdate(player_t *player) if (player->karthud[khud_tauntvoices]) player->karthud[khud_tauntvoices]--; + if (player->karthud[khud_trickcool]) + player->karthud[khud_trickcool]--; + if (!(player->pflags & PF_FAULT)) player->karthud[khud_fault] = 0; else if (player->karthud[khud_fault] > 0 && player->karthud[khud_fault] < 2*TICRATE) @@ -5951,10 +6397,10 @@ void K_KartPlayerHUDUpdate(player_t *player) if (gametype == GT_RACE) { // 0 is the fast spin animation, set at 30 tics of ring boost or higher! - if (player->kartstuff[k_ringboost] >= 30) + if (player->ringboost >= 30) player->karthud[khud_ringdelay] = 0; else - player->karthud[khud_ringdelay] = ((RINGANIM_DELAYMAX+1) * (30 - player->kartstuff[k_ringboost])) / 30; + player->karthud[khud_ringdelay] = ((RINGANIM_DELAYMAX+1) * (30 - player->ringboost)) / 30; if (player->karthud[khud_ringframe] == 0 && player->karthud[khud_ringdelay] > RINGANIM_DELAYMAX) { @@ -5975,7 +6421,7 @@ void K_KartPlayerHUDUpdate(player_t *player) } } - if (player->kartstuff[k_ringlock]) + if (player->pflags & PF_RINGLOCK) { UINT8 normalanim = (leveltime % 14); UINT8 debtanim = 14 + (leveltime % 2); @@ -6112,46 +6558,46 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_UpdateEngineSounds(player); // Thanks, VAda! // update boost angle if not spun out - if (!player->kartstuff[k_spinouttimer] && !player->kartstuff[k_wipeoutslow]) - player->kartstuff[k_boostangle] = (INT32)player->mo->angle; + if (!player->spinouttimer && !player->wipeoutslow) + player->boostangle = (INT32)player->mo->angle; K_GetKartBoostPower(player); // Special effect objects! if (player->mo && !player->spectator) { - if (player->kartstuff[k_dashpadcooldown]) // Twinkle Circuit afterimages + if (player->dashpadcooldown) // Twinkle Circuit afterimages { mobj_t *ghost; ghost = P_SpawnGhostMobj(player->mo); - ghost->fuse = player->kartstuff[k_dashpadcooldown]+1; - ghost->momx = player->mo->momx / (player->kartstuff[k_dashpadcooldown]+1); - ghost->momy = player->mo->momy / (player->kartstuff[k_dashpadcooldown]+1); - ghost->momz = player->mo->momz / (player->kartstuff[k_dashpadcooldown]+1); - player->kartstuff[k_dashpadcooldown]--; + ghost->fuse = player->dashpadcooldown+1; + ghost->momx = player->mo->momx / (player->dashpadcooldown+1); + ghost->momy = player->mo->momy / (player->dashpadcooldown+1); + ghost->momz = player->mo->momz / (player->dashpadcooldown+1); + player->dashpadcooldown--; } if (player->speed > 0) { // Speed lines - if (player->kartstuff[k_sneakertimer] || player->kartstuff[k_ringboost] - || player->kartstuff[k_driftboost] || player->kartstuff[k_startboost] - || player->kartstuff[k_eggmanexplode]) + if (player->sneakertimer || player->ringboost + || player->driftboost || player->startboost + || player->eggmanexplode || player->trickboost) { - if (player->kartstuff[k_invincibilitytimer]) + if (player->invincibilitytimer) K_SpawnInvincibilitySpeedLines(player->mo); else K_SpawnNormalSpeedLines(player); } - if (player->kartstuff[k_numboosts] > 0) // Boosting after images + if (player->numboosts > 0) // Boosting after images { mobj_t *ghost; ghost = P_SpawnGhostMobj(player->mo); - ghost->extravalue1 = player->kartstuff[k_numboosts]+1; + ghost->extravalue1 = player->numboosts+1; ghost->extravalue2 = (leveltime % ghost->extravalue1); ghost->fuse = ghost->extravalue1; - ghost->frame |= FF_FULLBRIGHT; + ghost->renderflags |= RF_FULLBRIGHT; ghost->colorized = true; //ghost->color = player->skincolor; //ghost->momx = (3*player->mo->momx)/4; @@ -6164,7 +6610,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (P_IsObjectOnGround(player->mo)) { // Offroad dust - if (player->kartstuff[k_boostpower] < FRACUNIT) + if (player->boostpower < FRACUNIT) { K_SpawnWipeoutTrail(player->mo, true); if (leveltime % 6 == 0) @@ -6172,7 +6618,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } // Draft dust - if (player->kartstuff[k_draftpower] >= FRACUNIT) + if (player->draftpower >= FRACUNIT) { K_SpawnDraftDust(player->mo); /*if (leveltime % 23 == 0 || !S_SoundPlaying(player->mo, sfx_s265)) @@ -6201,7 +6647,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) debtflag->renderflags = K_GetPlayerDontDrawFlag(player); } - if (player->kartstuff[k_springstars] && (leveltime & 1)) + if (player->springstars && (leveltime & 1)) { fixed_t randx = P_RandomRange(-40, 40) * player->mo->scale; fixed_t randy = P_RandomRange(-40, 40) * player->mo->scale; @@ -6212,7 +6658,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->mo->z + randz, MT_KARMAFIREWORK); - star->color = player->kartstuff[k_springcolor]; + star->color = player->springcolor; star->flags |= MF_NOGRAVITY; star->momx = player->mo->momx / 2; star->momy = player->mo->momy / 2; @@ -6221,24 +6667,24 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) star->scale = player->mo->scale; star->destscale = star->scale / 2; - player->kartstuff[k_springstars]--; + player->springstars--; } } if (player->playerstate == PST_DEAD || (player->respawn.state == RESPAWNST_MOVE)) // Ensure these are set correctly here { - player->mo->colorized = false; - player->mo->color = player->skincolor; + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; } - else if (player->kartstuff[k_eggmanexplode]) // You're gonna diiiiie + else if (player->eggmanexplode) // You're gonna diiiiie { - const INT32 flashtime = 4<<(player->kartstuff[k_eggmanexplode]/TICRATE); - if (player->kartstuff[k_eggmanexplode] == 1 || (player->kartstuff[k_eggmanexplode] % (flashtime/2) != 0)) + const INT32 flashtime = 4<<(player->eggmanexplode/TICRATE); + if (player->eggmanexplode == 1 || (player->eggmanexplode % (flashtime/2) != 0)) { - player->mo->colorized = false; - player->mo->color = player->skincolor; + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; } - else if (player->kartstuff[k_eggmanexplode] % flashtime == 0) + else if (player->eggmanexplode % flashtime == 0) { player->mo->colorized = true; player->mo->color = SKINCOLOR_BLACK; @@ -6249,53 +6695,34 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->mo->color = SKINCOLOR_CRIMSON; } } - else if (player->kartstuff[k_invincibilitytimer]) // setting players to use the star colormap and spawning afterimages + else if (player->invincibilitytimer) // setting players to use the star colormap and spawning afterimages { player->mo->colorized = true; } - else if (player->kartstuff[k_growshrinktimer]) // Ditto, for grow/shrink + else if (player->growshrinktimer) // Ditto, for grow/shrink { - if (player->kartstuff[k_growshrinktimer] % 5 == 0) + if (player->growshrinktimer % 5 == 0) { player->mo->colorized = true; - player->mo->color = (player->kartstuff[k_growshrinktimer] < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); + player->mo->color = (player->growshrinktimer < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); } else { - player->mo->colorized = false; - player->mo->color = player->skincolor; + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; } } - else if (player->kartstuff[k_killfield]) // You're gonna REALLY diiiiie - { - const INT32 flashtime = 4<<(4-(player->kartstuff[k_killfield]/TICRATE)); - if (player->kartstuff[k_killfield] == 1 || (player->kartstuff[k_killfield] % (flashtime/2) != 0)) - { - player->mo->colorized = false; - player->mo->color = player->skincolor; - } - else if (player->kartstuff[k_killfield] % flashtime == 0) - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_BYZANTIUM; - } - else - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_RUBY; - } - } - else if (player->kartstuff[k_ringboost] && (leveltime & 1)) // ring boosting + else if (player->ringboost && (leveltime & 1)) // ring boosting { player->mo->colorized = true; } else { - player->mo->colorized = false; + player->mo->colorized = (player->dye != 0); } - if (player->kartstuff[k_itemtype] == KITEM_NONE) - player->kartstuff[k_holdready] = 0; + if (player->itemtype == KITEM_NONE) + player->pflags &= ~PF_HOLDREADY; // DKR style camera for boosting if (player->karthud[khud_boostcam] != 0 || player->karthud[khud_destboostcam] != 0) @@ -6319,30 +6746,30 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->karthud[khud_timeovercam] = 0; // Make ABSOLUTELY SURE that your flashing tics don't get set WHILE you're still in hit animations. - if (player->kartstuff[k_spinouttimer] != 0 || player->kartstuff[k_wipeoutslow] != 0) + if (player->spinouttimer != 0 || player->wipeoutslow != 0) { - if (( player->kartstuff[k_spinouttype] & KSPIN_IFRAMES ) == 0) - player->powers[pw_flashing] = 0; + if (( player->spinouttype & KSPIN_IFRAMES ) == 0) + player->flashing = 0; else - player->powers[pw_flashing] = K_GetKartFlashing(player); + player->flashing = K_GetKartFlashing(player); } - if (player->kartstuff[k_spinouttimer]) + if (player->spinouttimer) { if ((P_IsObjectOnGround(player->mo) - || ( player->kartstuff[k_spinouttype] & KSPIN_AIRTIMER )) - && (!player->kartstuff[k_sneakertimer])) + || ( player->spinouttype & KSPIN_AIRTIMER )) + && (!player->sneakertimer)) { - player->kartstuff[k_spinouttimer]--; - if (player->kartstuff[k_wipeoutslow] > 1) - player->kartstuff[k_wipeoutslow]--; + player->spinouttimer--; + if (player->wipeoutslow > 1) + player->wipeoutslow--; } } else { - if (player->kartstuff[k_wipeoutslow] >= 1) + if (player->wipeoutslow >= 1) player->mo->friction = ORIG_FRICTION; - player->kartstuff[k_wipeoutslow] = 0; + player->wipeoutslow = 0; } if (player->rings > 20) @@ -6367,7 +6794,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->spheres < 0) player->spheres = 0; - if (comeback == false || !(gametyperules & GTR_KARMA) || player->eliminated == true) + if (comeback == false || !(gametyperules & GTR_KARMA) || (player->pflags & PF_ELIMINATED)) { player->karmadelay = comebacktime; } @@ -6378,100 +6805,105 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) comebackshowninfo = true; // client has already seen the message } - if (player->kartstuff[k_ringdelay]) - player->kartstuff[k_ringdelay]--; + if (player->ringdelay) + player->ringdelay--; if (P_PlayerInPain(player)) - player->kartstuff[k_ringboost] = 0; - else if (player->kartstuff[k_ringboost]) - player->kartstuff[k_ringboost]--; + player->ringboost = 0; + else if (player->ringboost) + player->ringboost--; - if (player->kartstuff[k_sneakertimer]) + if (player->sneakertimer) { - player->kartstuff[k_sneakertimer]--; + player->sneakertimer--; - if (player->kartstuff[k_sneakertimer] <= 0) + if (player->sneakertimer <= 0) { - player->kartstuff[k_numsneakers] = 0; + player->numsneakers = 0; } } - if (player->kartstuff[k_flamedash]) - player->kartstuff[k_flamedash]--; + if (player->trickboost) + player->trickboost--; - if (player->kartstuff[k_sneakertimer] && player->kartstuff[k_wipeoutslow] > 0 && player->kartstuff[k_wipeoutslow] < wipeoutslowtime+1) - player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1; + if (player->flamedash) + player->flamedash--; - if (player->kartstuff[k_floorboost]) - player->kartstuff[k_floorboost]--; + if (player->sneakertimer && player->wipeoutslow > 0 && player->wipeoutslow < wipeoutslowtime+1) + player->wipeoutslow = wipeoutslowtime+1; - if (player->kartstuff[k_driftboost]) - player->kartstuff[k_driftboost]--; + if (player->floorboost) + player->floorboost--; - if (player->kartstuff[k_startboost]) - player->kartstuff[k_startboost]--; + if (player->driftboost) + player->driftboost--; - if (player->kartstuff[k_spindashboost]) + if (player->strongdriftboost) + player->strongdriftboost--; + + if (player->startboost) + player->startboost--; + + if (player->spindashboost) { - player->kartstuff[k_spindashboost]--; + player->spindashboost--; - if (player->kartstuff[k_spindashboost] <= 0) + if (player->spindashboost <= 0) { - player->kartstuff[k_spindashspeed] = player->kartstuff[k_spindashboost] = 0; + player->spindashspeed = player->spindashboost = 0; } } - if (player->kartstuff[k_invincibilitytimer]) - player->kartstuff[k_invincibilitytimer]--; + if (player->invincibilitytimer) + player->invincibilitytimer--; - if ((player->respawn.state == RESPAWNST_NONE) && player->kartstuff[k_growshrinktimer] != 0) + if ((player->respawn.state == RESPAWNST_NONE) && player->growshrinktimer != 0) { - if (player->kartstuff[k_growshrinktimer] > 0) - player->kartstuff[k_growshrinktimer]--; - if (player->kartstuff[k_growshrinktimer] < 0) - player->kartstuff[k_growshrinktimer]++; + if (player->growshrinktimer > 0) + player->growshrinktimer--; + if (player->growshrinktimer < 0) + player->growshrinktimer++; // Back to normal - if (player->kartstuff[k_growshrinktimer] == 0) + if (player->growshrinktimer == 0) K_RemoveGrowShrink(player); } - if (player->kartstuff[k_superring]) + if (player->superring) { - if (player->kartstuff[k_superring] % 3 == 0) + if (player->superring % 3 == 0) { mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING); ring->extravalue1 = 1; // Ring collect animation timer ring->angle = player->mo->angle; // animation angle P_SetTarget(&ring->target, player->mo); // toucher for thinker - player->kartstuff[k_pickuprings]++; - if (player->kartstuff[k_superring] <= 3) + player->pickuprings++; + if (player->superring <= 3) ring->cvmem = 1; // play caching when collected } - player->kartstuff[k_superring]--; + player->superring--; } - if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0 - && player->kartstuff[k_rocketsneakertimer]) - player->kartstuff[k_rocketsneakertimer]--; + if (player->stealingtimer == 0 + && player->rocketsneakertimer) + player->rocketsneakertimer--; - if (player->kartstuff[k_hyudorotimer]) - player->kartstuff[k_hyudorotimer]--; + if (player->hyudorotimer) + player->hyudorotimer--; - if (player->kartstuff[k_sadtimer]) - player->kartstuff[k_sadtimer]--; + if (player->sadtimer) + player->sadtimer--; - if (player->kartstuff[k_stealingtimer]) - player->kartstuff[k_stealingtimer]--; + if (player->stealingtimer > 0) + player->stealingtimer--; + else if (player->stealingtimer < 0) + player->stealingtimer++; - if (player->kartstuff[k_stolentimer]) - player->kartstuff[k_stolentimer]--; + if (player->justbumped > 0) + player->justbumped--; - if (player->kartstuff[k_justbumped] > 0) - player->kartstuff[k_justbumped]--; - - if (player->kartstuff[k_tiregrease]) - player->kartstuff[k_tiregrease]--; + if (player->tiregrease) + player->tiregrease--; if (player->tumbleBounces > 0) { @@ -6489,12 +6921,15 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_KartPlayerHUDUpdate(player); - if ((gametyperules & GTR_WANTED) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) + if (battleovertime.enabled && !(player->pflags & PF_ELIMINATED) && player->bumpers <= 0 && player->karmadelay <= 0) { - player->kartstuff[k_wanted]++; + if (player->overtimekarma) + player->overtimekarma--; + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); } - if ((battleovertime.enabled >= 10*TICRATE) && (player->eliminated == false)) + if ((battleovertime.enabled >= 10*TICRATE) && !(player->pflags & PF_ELIMINATED)) { fixed_t distanceToBarrier = 0; @@ -6510,59 +6945,56 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } if (P_IsObjectOnGround(player->mo)) - player->kartstuff[k_waterskip] = 0; + player->waterskip = 0; - if (player->kartstuff[k_instashield]) - player->kartstuff[k_instashield]--; + if (player->instashield) + player->instashield--; - if (player->kartstuff[k_eggmanexplode]) + if (player->eggmanexplode) { if (player->spectator || (gametype == GT_BATTLE && !player->bumpers)) - player->kartstuff[k_eggmanexplode] = 0; + player->eggmanexplode = 0; else { - player->kartstuff[k_eggmanexplode]--; - if (player->kartstuff[k_eggmanexplode] <= 0) + player->eggmanexplode--; + if (player->eggmanexplode <= 0) { mobj_t *eggsexplode; - //player->powers[pw_flashing] = 0; + //player->flashing = 0; eggsexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SPBEXPLOSION); - if (player->kartstuff[k_eggmanblame] >= 0 - && player->kartstuff[k_eggmanblame] < MAXPLAYERS - && playeringame[player->kartstuff[k_eggmanblame]] - && !players[player->kartstuff[k_eggmanblame]].spectator - && players[player->kartstuff[k_eggmanblame]].mo) - P_SetTarget(&eggsexplode->target, players[player->kartstuff[k_eggmanblame]].mo); + if (player->eggmanblame >= 0 + && player->eggmanblame < MAXPLAYERS + && playeringame[player->eggmanblame] + && !players[player->eggmanblame].spectator + && players[player->eggmanblame].mo) + P_SetTarget(&eggsexplode->target, players[player->eggmanblame].mo); } } } - if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) + if (player->itemtype == KITEM_THUNDERSHIELD) { - if (RINGTOTAL(player) < 20 && !player->kartstuff[k_ringlock]) + if (RINGTOTAL(player) < 20 && !(player->pflags & PF_RINGLOCK)) K_LookForRings(player->mo); } - if (player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD) + if (player->itemtype == KITEM_BUBBLESHIELD) { - if (player->kartstuff[k_bubblecool]) - player->kartstuff[k_bubblecool]--; + if (player->bubblecool) + player->bubblecool--; } else { - player->kartstuff[k_bubbleblowup] = 0; - player->kartstuff[k_bubblecool] = 0; + player->bubbleblowup = 0; + player->bubblecool = 0; } - if (player->kartstuff[k_itemtype] != KITEM_FLAMESHIELD) + if (player->itemtype != KITEM_FLAMESHIELD) { - if (player->kartstuff[k_flamedash]) + if (player->flamedash) K_FlameDashLeftoverSmoke(player->mo); } - if (player->karmadelay) - player->kartstuff[k_comebackmode] = 0; - if (P_IsObjectOnGround(player->mo) && player->trickpanel != 0) { if (P_MobjFlip(player->mo) * player->mo->momz <= 0) @@ -6576,13 +7008,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // Only allow drifting while NOT trying to do an spindash input. if ((K_GetKartButtons(player) & BT_EBRAKEMASK) != BT_EBRAKEMASK) { - player->driftInput = true; + player->pflags |= PF_DRIFTINPUT; } // else, keep the previous value, because it might be brake-drifting. } else { - player->driftInput = false; + player->pflags &= ~PF_DRIFTINPUT; } // Roulette Code @@ -6591,19 +7023,22 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // Handle invincibility sfx K_UpdateInvincibilitySounds(player); // Also thanks, VAda! - // Plays the music after the starting countdown. - if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2))) + if (player->tripWireState != TRIP_NONE) { - S_ChangeMusic(mapmusname, mapmusflags, true); - S_ShowMusicCredit(); + if (player->tripWireState == TRIP_PASSED) + S_StartSound(player->mo, sfx_cdfm63); + else if (player->tripWireState == TRIP_BLOCKED) + S_StartSound(player->mo, sfx_kc4c); + + player->tripWireState = TRIP_NONE; } } void K_KartPlayerAfterThink(player_t *player) { - if (player->kartstuff[k_curshield] - || player->kartstuff[k_invincibilitytimer] - || (player->kartstuff[k_growshrinktimer] != 0 && player->kartstuff[k_growshrinktimer] % 5 == 4)) // 4 instead of 0 because this is afterthink! + if (player->curshield + || player->invincibilitytimer + || (player->growshrinktimer != 0 && player->growshrinktimer % 5 == 4)) // 4 instead of 0 because this is afterthink! { player->mo->frame |= FF_FULLBRIGHT; } @@ -6617,24 +7052,24 @@ void K_KartPlayerAfterThink(player_t *player) K_MoveHeldObjects(player); // Jawz reticule (seeking) - if (player->kartstuff[k_itemtype] == KITEM_JAWZ && player->kartstuff[k_itemheld]) + if (player->itemtype == KITEM_JAWZ && (player->pflags & PF_ITEMOUT)) { - INT32 lasttarg = player->kartstuff[k_lastjawztarget]; + INT32 lasttarg = player->lastjawztarget; player_t *targ; mobj_t *ret; - if (player->kartstuff[k_jawztargetdelay] && playeringame[lasttarg] && !players[lasttarg].spectator) + if (player->jawztargetdelay && playeringame[lasttarg] && !players[lasttarg].spectator) { targ = &players[lasttarg]; - player->kartstuff[k_jawztargetdelay]--; + player->jawztargetdelay--; } else targ = K_FindJawzTarget(player->mo, player); if (!targ || !targ->mo || P_MobjWasRemoved(targ->mo)) { - player->kartstuff[k_lastjawztarget] = -1; - player->kartstuff[k_jawztargetdelay] = 0; + player->lastjawztarget = -1; + player->jawztargetdelay = 0; return; } @@ -6651,14 +7086,14 @@ void K_KartPlayerAfterThink(player_t *player) else S_StartSound(targ->mo, sfx_s3k89); - player->kartstuff[k_lastjawztarget] = targ-players; - player->kartstuff[k_jawztargetdelay] = 5; + player->lastjawztarget = targ-players; + player->jawztargetdelay = 5; } } else { - player->kartstuff[k_lastjawztarget] = -1; - player->kartstuff[k_jawztargetdelay] = 0; + player->lastjawztarget = -1; + player->jawztargetdelay = 0; } } @@ -6794,7 +7229,7 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) } // Remove wrong way flag if we're using nextwaypoints - player->kartstuff[k_wrongway] = 0; + player->pflags &= ~PF_WRONGWAY; updaterespawn = true; } } @@ -6834,7 +7269,7 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) nextbestmomdelta = momdelta; // Set wrong way flag if we're using prevwaypoints - player->kartstuff[k_wrongway] = 1; + player->pflags |= PF_WRONGWAY; updaterespawn = false; } } @@ -7063,24 +7498,24 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer) INT16 basedrift, driftadjust; fixed_t driftweight = player->kartweight*14; // 12 - if (player->kartstuff[k_drift] == 0 || !P_IsObjectOnGround(player->mo)) + if (player->drift == 0 || !P_IsObjectOnGround(player->mo)) { // If they aren't drifting or on the ground, this doesn't apply return 0; } - if (player->kartstuff[k_driftend] != 0) + if (player->pflags & PF_DRIFTEND) { // Drift has ended and we are tweaking their angle back a bit - return -266*player->kartstuff[k_drift]; + return -266*player->drift; } - basedrift = (83 * player->kartstuff[k_drift]) - (((driftweight - 14) * player->kartstuff[k_drift]) / 5); // 415 - 303 - driftadjust = abs((252 - driftweight) * player->kartstuff[k_drift] / 5); + basedrift = (83 * player->drift) - (((driftweight - 14) * player->drift) / 5); // 415 - 303 + driftadjust = abs((252 - driftweight) * player->drift / 5); - if (player->kartstuff[k_tiregrease] > 0) // Buff drift-steering while in greasemode + if (player->tiregrease > 0) // Buff drift-steering while in greasemode { - basedrift += (basedrift / greasetics) * player->kartstuff[k_tiregrease]; + basedrift += (basedrift / greasetics) * player->tiregrease; } if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) @@ -7145,9 +7580,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return 0; } - if (player->trickpanel != 0) + if (player->trickpanel != 0 && player->trickpanel < 4) { - // No turning during trick panel + // No turning during trick panel unless you did the upwards trick (4) return 0; } @@ -7171,13 +7606,13 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) turnfixed = FixedMul(turnfixed, K_BotRubberband(player)); } - if (player->kartstuff[k_drift] != 0 && P_IsObjectOnGround(player->mo)) + if (player->drift != 0 && P_IsObjectOnGround(player->mo)) { fixed_t countersteer = FixedDiv(turnfixed, KART_FULLTURN*FRACUNIT); // If we're drifting we have a completely different turning value - if (player->kartstuff[k_driftend] != 0) + if (player->pflags & PF_DRIFTEND) { countersteer = FRACUNIT; } @@ -7185,9 +7620,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return K_GetKartDriftValue(player, countersteer); } - if (player->kartstuff[k_handleboost] > 0) + if (player->handleboost > 0) { - turnfixed = FixedMul(turnfixed, FRACUNIT + player->kartstuff[k_handleboost]); + turnfixed = FixedMul(turnfixed, FRACUNIT + player->handleboost); } if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) @@ -7206,10 +7641,32 @@ INT32 K_GetKartDriftSparkValue(player_t *player) return (26*4 + player->kartspeed*2 + (9 - player->kartweight))*8; } +INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage) +{ + fixed_t mul = FRACUNIT; + + // This code is function is pretty much useless now that the timing changes are linear but bleh. + switch (stage) + { + case 2: + mul = 2*FRACUNIT; // x2 + break; + case 3: + mul = 3*FRACUNIT; // x3 + break; + case 4: + mul = 4*FRACUNIT; // x4 + break; + } + + return (FixedMul(K_GetKartDriftSparkValue(player) * FRACUNIT, mul) / FRACUNIT); +} + /* Stage 1: red sparks Stage 2: blue sparks -Stage 3: big large rainbow sparks +Stage 3: purple sparks +Stage 4: big large rainbow sparks Stage 0: air failsafe */ void K_SpawnDriftBoostExplosion(player_t *player, int stage) @@ -7235,6 +7692,13 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage) break; case 3: + overlay->color = SKINCOLOR_PURPLE; + overlay->fuse = 48; + + S_StartSound(player->mo, sfx_kc5b); + break; + + case 4: overlay->color = SKINCOLOR_SILVER; overlay->fuse = 120; @@ -7255,9 +7719,10 @@ static void K_KartDrift(player_t *player, boolean onground) { const fixed_t minspeed = (10 * player->mo->scale); - const INT32 dsone = K_GetKartDriftSparkValue(player); - const INT32 dstwo = dsone*2; - const INT32 dsthree = dstwo*2; + const INT32 dsone = K_GetKartDriftSparkValueForStage(player, 1); + const INT32 dstwo = K_GetKartDriftSparkValueForStage(player, 2); + const INT32 dsthree = K_GetKartDriftSparkValueForStage(player, 3); + const INT32 dsfour = K_GetKartDriftSparkValueForStage(player, 4); const UINT16 buttons = K_GetKartButtons(player); @@ -7266,103 +7731,125 @@ static void K_KartDrift(player_t *player, boolean onground) // (This comment is extremely funny) // Drift Release (Moved here so you can't "chain" drifts) - if (player->kartstuff[k_drift] != -5 && player->kartstuff[k_drift] != 5) + if (player->drift != -5 && player->drift != 5) { - if (player->kartstuff[k_driftcharge] < 0 || player->kartstuff[k_driftcharge] >= dsone) + if (player->driftcharge < 0 || player->driftcharge >= dsone) { angle_t pushdir = K_MomentumAngle(player->mo); S_StartSound(player->mo, sfx_s23c); //K_SpawnDashDustRelease(player); - if (player->kartstuff[k_driftcharge] < 0) + if (player->driftcharge < 0) { // Stage 0: Yellow sparks if (!onground) P_Thrust(player->mo, pushdir, player->speed / 8); - if (player->kartstuff[k_driftboost] < 15) - player->kartstuff[k_driftboost] = 15; + if (player->driftboost < 15) + player->driftboost = 15; } - else if (player->kartstuff[k_driftcharge] >= dsone && player->kartstuff[k_driftcharge] < dstwo) + else if (player->driftcharge >= dsone && player->driftcharge < dstwo) { // Stage 1: Red sparks if (!onground) P_Thrust(player->mo, pushdir, player->speed / 4); - if (player->kartstuff[k_driftboost] < 20) - player->kartstuff[k_driftboost] = 20; + if (player->driftboost < 20) + player->driftboost = 20; K_SpawnDriftBoostExplosion(player, 1); } - else if (player->kartstuff[k_driftcharge] < dsthree) + else if (player->driftcharge < dsthree) { // Stage 2: Blue sparks if (!onground) P_Thrust(player->mo, pushdir, player->speed / 3); - if (player->kartstuff[k_driftboost] < 50) - player->kartstuff[k_driftboost] = 50; + if (player->driftboost < 50) + player->driftboost = 50; K_SpawnDriftBoostExplosion(player, 2); } - else if (player->kartstuff[k_driftcharge] >= dsthree) + else if (player->driftcharge < dsfour) { - // Stage 3: Rainbow sparks + // Stage 3: Purple sparks + if (!onground) + P_Thrust(player->mo, pushdir, ( 5 * player->speed ) / 12); + + if (player->driftboost < 85) + player->driftboost = 85; + if (player->strongdriftboost < 85) + player->strongdriftboost = 85; + + K_SpawnDriftBoostExplosion(player, 3); + K_SpawnDriftElectricSparks(player); + } + else if (player->driftcharge >= dsfour) + { + // Stage 4: Rainbow sparks if (!onground) P_Thrust(player->mo, pushdir, player->speed / 2); - if (player->kartstuff[k_driftboost] < 125) - player->kartstuff[k_driftboost] = 125; + if (player->driftboost < 125) + player->driftboost = 125; + if (player->strongdriftboost < 125) + player->strongdriftboost = 125; - K_SpawnDriftBoostExplosion(player, 3); + K_SpawnDriftBoostExplosion(player, 4); + K_SpawnDriftElectricSparks(player); } } // Remove charge - player->kartstuff[k_driftcharge] = 0; + player->driftcharge = 0; } // Drifting: left or right? - if ((player->cmd.turning > 0) && player->speed > minspeed && player->driftInput == true - && (player->kartstuff[k_drift] == 0 || player->kartstuff[k_driftend] == 1)) // && player->kartstuff[k_drift] != 1) - { - // Starting left drift - player->kartstuff[k_drift] = 1; - player->kartstuff[k_driftend] = player->kartstuff[k_driftcharge] = 0; - } - else if ((player->cmd.turning < 0) && player->speed > minspeed && player->driftInput == true - && (player->kartstuff[k_drift] == 0 || player->kartstuff[k_driftend] == 1)) // && player->kartstuff[k_drift] != -1) - { - // Starting right drift - player->kartstuff[k_drift] = -1; - player->kartstuff[k_driftend] = player->kartstuff[k_driftcharge] = 0; - } - else if (player->driftInput == false) // || player->kartstuff[k_turndir] == 0) + if (!(player->pflags & PF_DRIFTINPUT)) { // drift is not being performed so if we're just finishing set driftend and decrement counters - if (player->kartstuff[k_drift] > 0) + if (player->drift > 0) { - player->kartstuff[k_drift]--; - player->kartstuff[k_driftend] = 1; + player->drift--; + player->pflags |= PF_DRIFTEND; } - else if (player->kartstuff[k_drift] < 0) + else if (player->drift < 0) { - player->kartstuff[k_drift]++; - player->kartstuff[k_driftend] = 1; + player->drift++; + player->pflags |= PF_DRIFTEND; } else - player->kartstuff[k_driftend] = 0; + player->pflags &= ~PF_DRIFTEND; + } + else if (player->speed > minspeed + && (player->drift == 0 || (player->pflags & PF_DRIFTEND))) + { + // Uses turning over steering, since this is very binary. + // Using steering would cause a lot more "wrong drifts". + if (player->cmd.turning > 0) + { + // Starting left drift + player->drift = 1; + player->driftcharge = 0; + player->pflags &= ~PF_DRIFTEND; + } + else if (player->cmd.turning < 0) + { + // Starting right drift + player->drift = -1; + player->driftcharge = 0; + player->pflags &= ~PF_DRIFTEND; + } } if (P_PlayerInPain(player) || player->speed <= 0) { // Stop drifting - player->kartstuff[k_drift] = player->kartstuff[k_driftcharge] = 0; - player->kartstuff[k_aizdriftstrat] = player->kartstuff[k_brakedrift] = 0; - player->kartstuff[k_getsparks] = 0; + player->drift = player->driftcharge = player->aizdriftstrat = 0; + player->pflags &= ~(PF_BRAKEDRIFT|PF_GETSPARKS); } - else if (player->driftInput == true && player->kartstuff[k_drift] != 0) + else if ((player->pflags & PF_DRIFTINPUT) && player->drift != 0) { // Incease/decrease the drift value to continue drifting in that direction fixed_t driftadditive = 24; @@ -7370,53 +7857,53 @@ static void K_KartDrift(player_t *player, boolean onground) if (onground) { - if (player->kartstuff[k_drift] >= 1) // Drifting to the left + if (player->drift >= 1) // Drifting to the left { - player->kartstuff[k_drift]++; - if (player->kartstuff[k_drift] > 5) - player->kartstuff[k_drift] = 5; + player->drift++; + if (player->drift > 5) + player->drift = 5; - if (player->cmd.turning > 0) // Inward - driftadditive += abs(player->cmd.turning)/100; - if (player->cmd.turning < 0) // Outward - driftadditive -= abs(player->cmd.turning)/75; + if (player->steering > 0) // Inward + driftadditive += abs(player->steering)/100; + if (player->steering < 0) // Outward + driftadditive -= abs(player->steering)/75; } - else if (player->kartstuff[k_drift] <= -1) // Drifting to the right + else if (player->drift <= -1) // Drifting to the right { - player->kartstuff[k_drift]--; - if (player->kartstuff[k_drift] < -5) - player->kartstuff[k_drift] = -5; + player->drift--; + if (player->drift < -5) + player->drift = -5; - if (player->cmd.turning < 0) // Inward - driftadditive += abs(player->cmd.turning)/100; - if (player->cmd.turning > 0) // Outward - driftadditive -= abs(player->cmd.turning)/75; + if (player->steering < 0) // Inward + driftadditive += abs(player->steering)/100; + if (player->steering > 0) // Outward + driftadditive -= abs(player->steering)/75; } // Disable drift-sparks until you're going fast enough - if (player->kartstuff[k_getsparks] == 0 - || (player->kartstuff[k_offroad] && K_ApplyOffroad(player))) + if (!(player->pflags & PF_GETSPARKS) + || (player->offroad && K_ApplyOffroad(player))) driftadditive = 0; // Inbetween minspeed and minspeed*2, it'll keep your previous drift-spark state. if (player->speed > minspeed*2) { - player->kartstuff[k_getsparks] = 1; + player->pflags |= PF_GETSPARKS; - if (player->kartstuff[k_driftcharge] <= -1) + if (player->driftcharge <= -1) { - player->kartstuff[k_driftcharge] = dsone; // Back to red + player->driftcharge = dsone; // Back to red playsound = true; } } else if (player->speed <= minspeed) { - player->kartstuff[k_getsparks] = 0; + player->pflags &= ~PF_GETSPARKS; driftadditive = 0; - if (player->kartstuff[k_driftcharge] >= dsone) + if (player->driftcharge >= dsone) { - player->kartstuff[k_driftcharge] = -1; // Set yellow sparks + player->driftcharge = -1; // Set yellow sparks playsound = true; } } @@ -7427,15 +7914,15 @@ static void K_KartDrift(player_t *player, boolean onground) } // This spawns the drift sparks - if ((player->kartstuff[k_driftcharge] + driftadditive >= dsone) - || (player->kartstuff[k_driftcharge] < 0)) + if ((player->driftcharge + driftadditive >= dsone) + || (player->driftcharge < 0)) { K_SpawnDriftSparks(player); } - if ((player->kartstuff[k_driftcharge] < dsone && player->kartstuff[k_driftcharge]+driftadditive >= dsone) - || (player->kartstuff[k_driftcharge] < dstwo && player->kartstuff[k_driftcharge]+driftadditive >= dstwo) - || (player->kartstuff[k_driftcharge] < dsthree && player->kartstuff[k_driftcharge]+driftadditive >= dsthree)) + if ((player->driftcharge < dsone && player->driftcharge+driftadditive >= dsone) + || (player->driftcharge < dstwo && player->driftcharge+driftadditive >= dstwo) + || (player->driftcharge < dsthree && player->driftcharge+driftadditive >= dsthree)) { playsound = true; } @@ -7443,67 +7930,67 @@ static void K_KartDrift(player_t *player, boolean onground) // Sound whenever you get a different tier of sparks if (playsound && P_IsDisplayPlayer(player)) { - if (player->kartstuff[k_driftcharge] == -1) + if (player->driftcharge == -1) S_StartSoundAtVolume(player->mo, sfx_sploss, 192); // Yellow spark sound else S_StartSoundAtVolume(player->mo, sfx_s3ka2, 192); } - player->kartstuff[k_driftcharge] += driftadditive; - player->kartstuff[k_driftend] = 0; + player->driftcharge += driftadditive; + player->pflags &= ~PF_DRIFTEND; } - if ((player->kartstuff[k_handleboost] == 0) - || (!player->cmd.turning) - || (!player->kartstuff[k_aizdriftstrat]) - || (player->cmd.turning > 0) != (player->kartstuff[k_aizdriftstrat] > 0)) + if ((player->handleboost == 0) + || (!player->steering) + || (!player->aizdriftstrat) + || (player->steering > 0) != (player->aizdriftstrat > 0)) { - if (!player->kartstuff[k_drift]) - player->kartstuff[k_aizdriftstrat] = 0; + if (!player->drift) + player->aizdriftstrat = 0; else - player->kartstuff[k_aizdriftstrat] = ((player->kartstuff[k_drift] > 0) ? 1 : -1); + player->aizdriftstrat = ((player->drift > 0) ? 1 : -1); } - else if (player->kartstuff[k_aizdriftstrat] && !player->kartstuff[k_drift]) + else if (player->aizdriftstrat && !player->drift) { K_SpawnAIZDust(player); - if (abs(player->aizDriftTilt) < ANGLE_22h) + if (abs(player->aizdrifttilt) < ANGLE_22h) { - player->aizDriftTilt = - (abs(player->aizDriftTilt) + ANGLE_11hh / 4) * - player->kartstuff[k_aizdriftstrat]; + player->aizdrifttilt = + (abs(player->aizdrifttilt) + ANGLE_11hh / 4) * + player->aizdriftstrat; } - if (abs(player->aizDriftTurn) < ANGLE_112h) + if (abs(player->aizdriftturn) < ANGLE_112h) { - player->aizDriftTurn = - (abs(player->aizDriftTurn) + ANGLE_11hh) * - player->kartstuff[k_aizdriftstrat]; + player->aizdriftturn = + (abs(player->aizdriftturn) + ANGLE_11hh) * + player->aizdriftstrat; } } if (!K_Sliptiding(player)) { - player->aizDriftTilt -= player->aizDriftTilt / 4; - player->aizDriftTurn -= player->aizDriftTurn / 4; + player->aizdrifttilt -= player->aizdrifttilt / 4; + player->aizdriftturn -= player->aizdriftturn / 4; - if (abs(player->aizDriftTilt) < ANGLE_11hh / 4) - player->aizDriftTilt = 0; - if (abs(player->aizDriftTurn) < ANGLE_11hh) - player->aizDriftTurn = 0; + if (abs(player->aizdrifttilt) < ANGLE_11hh / 4) + player->aizdrifttilt = 0; + if (abs(player->aizdriftturn) < ANGLE_11hh) + player->aizdriftturn = 0; } - if (player->kartstuff[k_drift] + if (player->drift && ((buttons & BT_BRAKE) || !(buttons & BT_ACCELERATE)) && P_IsObjectOnGround(player->mo)) { - if (!player->kartstuff[k_brakedrift]) + if (!(player->pflags & PF_BRAKEDRIFT)) K_SpawnBrakeDriftSparks(player); - player->kartstuff[k_brakedrift] = 1; + player->pflags |= PF_BRAKEDRIFT; } else - player->kartstuff[k_brakedrift] = 0; + player->pflags &= ~PF_BRAKEDRIFT; } // // K_KartUpdatePosition @@ -7511,14 +7998,14 @@ static void K_KartDrift(player_t *player, boolean onground) void K_KartUpdatePosition(player_t *player) { fixed_t position = 1; - fixed_t oldposition = player->kartstuff[k_position]; + fixed_t oldposition = player->position; fixed_t i; if (player->spectator || !player->mo) { // Ensure these are reset for spectators - player->kartstuff[k_position] = 0; - player->kartstuff[k_positiondelay] = 0; + player->position = 0; + player->positiondelay = 0; return; } @@ -7551,7 +8038,7 @@ void K_KartUpdatePosition(player_t *player) if (player->exiting) // End of match standings { // Only score matters - if (players[i].marescore > player->marescore) + if (players[i].roundscore > player->roundscore) position++; } else @@ -7574,7 +8061,7 @@ void K_KartUpdatePosition(player_t *player) else if (players[i].bumpers == player->bumpers) { // Score is the second tier tie breaker - if (players[i].marescore > player->marescore) + if (players[i].roundscore > player->roundscore) { position++; } @@ -7588,9 +8075,9 @@ void K_KartUpdatePosition(player_t *player) oldposition = position; if (oldposition != position) // Changed places? - player->kartstuff[k_positiondelay] = 10; // Position number growth + player->positiondelay = 10; // Position number growth - player->kartstuff[k_position] = position; + player->position = position; } // @@ -7600,41 +8087,39 @@ void K_StripItems(player_t *player) { K_DropRocketSneaker(player); K_DropKitchenSink(player); - player->kartstuff[k_itemtype] = KITEM_NONE; - player->kartstuff[k_itemamount] = 0; - player->kartstuff[k_itemheld] = 0; + player->itemtype = KITEM_NONE; + player->itemamount = 0; + player->pflags &= ~(PF_ITEMOUT|PF_EGGMANOUT); - if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2) + if (!player->itemroulette || player->roulettetype != 2) { - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->itemroulette = 0; + player->roulettetype = 0; } - player->kartstuff[k_eggmanheld] = 0; - player->kartstuff[k_hyudorotimer] = 0; - player->kartstuff[k_stealingtimer] = 0; - player->kartstuff[k_stolentimer] = 0; + player->hyudorotimer = 0; + player->stealingtimer = 0; - player->kartstuff[k_curshield] = KSHIELD_NONE; - player->kartstuff[k_bananadrag] = 0; + player->curshield = KSHIELD_NONE; + player->bananadrag = 0; - player->kartstuff[k_sadtimer] = 0; + player->sadtimer = 0; K_UpdateHnextList(player, true); } void K_StripOther(player_t *player) { - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; + player->itemroulette = 0; + player->roulettetype = 0; - player->kartstuff[k_invincibilitytimer] = 0; + player->invincibilitytimer = 0; K_RemoveGrowShrink(player); - if (player->kartstuff[k_eggmanexplode]) + if (player->eggmanexplode) { - player->kartstuff[k_eggmanexplode] = 0; - player->kartstuff[k_eggmanblame] = -1; + player->eggmanexplode = 0; + player->eggmanblame = -1; } } @@ -7649,7 +8134,7 @@ static INT32 K_FlameShieldMax(player_t *player) { if (playeringame[i] && !players[i].spectator) numplayers++; - if (players[i].kartstuff[k_position] == 1) + if (players[i].position == 1) disttofinish = players[i].distancetofinish; } @@ -7657,7 +8142,7 @@ static INT32 K_FlameShieldMax(player_t *player) { return 16; // max when alone, for testing } - else if (player->kartstuff[k_position] == 1) + else if (player->position == 1) { return 0; // minimum for first } @@ -7671,18 +8156,21 @@ boolean K_PlayerEBrake(player_t *player) { return (K_GetKartButtons(player) & BT_EBRAKEMASK) == BT_EBRAKEMASK && P_IsObjectOnGround(player->mo) == true - && player->kartstuff[k_drift] == 0 - && player->kartstuff[k_spinouttimer] == 0 - && player->kartstuff[k_justbumped] == 0 - && player->kartstuff[k_spindash] >= 0 - && player->kartstuff[k_spindashboost] == 0 - && player->powers[pw_nocontrol] == 0; + && player->drift == 0 + && player->spinouttimer == 0 + && player->justbumped == 0 + && player->spindashboost == 0 + && player->nocontrol == 0; } SINT8 K_Sliptiding(player_t *player) { - const INT32 *p = player->kartstuff; - return p[k_drift] ? 0 : p[k_aizdriftstrat]; + return player->drift ? 0 : player->aizdriftstrat; +} + +INT32 K_StairJankFlip(INT32 value) +{ + return P_AltFlip(value, 2); } static void K_KartSpindashDust(mobj_t *parent) @@ -7749,15 +8237,15 @@ static void K_KartSpindash(player_t *player) if (player->mo->hitlag > 0 || P_PlayerInPain(player)) { - player->kartstuff[k_spindash] = 0; + player->spindash = 0; } - if (player->kartstuff[k_spindash] > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE)) != (BT_DRIFT|BT_BRAKE)) + if (player->spindash > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE)) != (BT_DRIFT|BT_BRAKE)) { - player->kartstuff[k_spindashspeed] = (player->kartstuff[k_spindash] * FRACUNIT) / MAXCHARGETIME; - player->kartstuff[k_spindashboost] = TICRATE; + player->spindashspeed = (player->spindash * FRACUNIT) / MAXCHARGETIME; + player->spindashboost = TICRATE; - if (!player->kartstuff[k_tiregrease]) + if (!player->tiregrease) { UINT8 i; for (i = 0; i < 2; i++) @@ -7770,30 +8258,30 @@ static void K_KartSpindash(player_t *player) } } - player->kartstuff[k_tiregrease] = 2*TICRATE; + player->tiregrease = 2*TICRATE; - player->kartstuff[k_spindash] = 0; + player->spindash = 0; S_StartSound(player->mo, sfx_s23c); } - if ((player->kartstuff[k_spindashboost] > 0) && (spawnWind == true)) + if ((player->spindashboost > 0) && (spawnWind == true)) { K_KartSpindashWind(player->mo); } - if (player->kartstuff[k_spindashboost] > (TICRATE/2)) + if (player->spindashboost > (TICRATE/2)) { K_KartSpindashDust(player->mo); } if (K_PlayerEBrake(player) == false) { - player->kartstuff[k_spindash] = 0; + player->spindash = 0; return; } - if (player->speed == 0 && cmd->turning != 0 && leveltime % 8 == 0) + if (player->speed == 0 && player->steering != 0 && leveltime % 8 == 0) { // Rubber burn turn sfx S_StartSound(player->mo, sfx_ruburn); @@ -7803,7 +8291,7 @@ static void K_KartSpindash(player_t *player) { if ((cmd->buttons & (BT_DRIFT|BT_BRAKE)) == (BT_DRIFT|BT_BRAKE)) { - INT16 chargetime = MAXCHARGETIME - ++player->kartstuff[k_spindash]; + INT16 chargetime = MAXCHARGETIME - ++player->spindash; boolean spawnOldEffect = true; if (chargetime <= (MAXCHARGETIME / 2)) @@ -7817,7 +8305,7 @@ static void K_KartSpindash(player_t *player) K_KartSpindashWind(player->mo); } - if (player->powers[pw_flashing] > 0 && (leveltime & 1) && player->kartstuff[k_hyudorotimer] == 0) + if (player->flashing > 0 && (leveltime & 1) && player->hyudorotimer == 0) { // Every frame that you're invisible from flashing, spill a ring. // Intentionally a lop-sided trade-off, so the game doesn't become @@ -7861,18 +8349,18 @@ static void K_AirFailsafe(player_t *player) if (player->speed > maxSpeed // Above the max speed that you're allowed to use this technique. || player->respawn.state != RESPAWNST_NONE) // Respawning, you don't need this AND drop dash :V { - player->airFailsafe = false; + player->pflags &= ~PF_AIRFAILSAFE; return; } if ((K_GetKartButtons(player) & BT_ACCELERATE) || K_GetForwardMove(player) != 0) { // Queue up later - player->airFailsafe = true; + player->pflags |= PF_AIRFAILSAFE; return; } - if (player->airFailsafe == true) + if (player->pflags & PF_AIRFAILSAFE) { // Push the player forward P_Thrust(player->mo, K_MomentumAngle(player->mo), thrustSpeed); @@ -7880,7 +8368,7 @@ static void K_AirFailsafe(player_t *player) S_StartSound(player->mo, sfx_s23c); K_SpawnDriftBoostExplosion(player, 0); - player->airFailsafe = false; + player->pflags &= ~PF_AIRFAILSAFE; } } @@ -7896,10 +8384,10 @@ void K_AdjustPlayerFriction(player_t *player) return; } - // Reduce friction after hitting a horizontal spring - if (player->kartstuff[k_tiregrease]) + // Reduce friction after hitting a spring + if (player->tiregrease) { - player->mo->friction += ((FRACUNIT - prevfriction) / greasetics) * player->kartstuff[k_tiregrease]; + player->mo->friction += ((FRACUNIT - prevfriction) / greasetics) * player->tiregrease; } /* @@ -7920,11 +8408,11 @@ void K_AdjustPlayerFriction(player_t *player) } // Wipeout slowdown - if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow]) + if (player->spinouttimer && player->wipeoutslow) { - if (player->kartstuff[k_offroad]) + if (player->offroad) player->mo->friction -= 4912; - if (player->kartstuff[k_wipeoutslow] == 1) + if (player->wipeoutslow == 1) player->mo->friction -= 9824; } @@ -7953,6 +8441,86 @@ void K_AdjustPlayerFriction(player_t *player) } } +// +// K_trickPanelTimingVisual +// Spawns the timing visual for trick panels depending on the given player's momz. +// If the player has tricked and is not in hitlag, this will send the half circles flying out. +// if you tumble, they'll fall off instead. +// + +#define RADIUSSCALING 6 +#define MINRADIUS 12 + +static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) +{ + + fixed_t pos, tx, ty, tz; + mobj_t *flame; + + angle_t hang = R_PointToAnglePlayer(player, player->mo->x, player->mo->y) + ANG1*90; // horizontal angle + angle_t vang = -FixedAngle(momz)*12 + (ANG1*45); // vertical angle dependant on momz, we want it to line up at 45 degrees at the perfect frame to trick at + fixed_t dist = FixedMul(max(MINRADIUS<mo->scale); // distance. + + UINT8 i; + + // Do you like trig? cool, me neither. + for (i=0; i < 2; i++) + { + pos = FixedMul(dist, FINESINE(vang>>ANGLETOFINESHIFT)); + tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); + ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); + tz = player->mo->z + player->mo->height/2 + FixedMul(dist, FINECOSINE(vang>>ANGLETOFINESHIFT)); + + // All coordinates set, spawn our fire, now. + flame = P_SpawnMobj(tx, ty, tz, MT_THOK); + + P_SetScale(flame, player->mo->scale); + + // Visuals + flame->sprite = SPR_TRCK; + flame->frame = i|FF_FULLBRIGHT; + + if (player->trickpanel <= 1 && !player->tumbleBounces) + flame->tics = 2; + else + { + flame->tics = TICRATE; + + if (player->trickpanel > 1) // we tricked + { + // Send the thing outwards via ghetto maths which involves redoing the whole 3d sphere again, witht the "vertical" angle shifted by 90 degrees. + // There's probably a simplier way to do this the way I want to but this works. + pos = FixedMul(48*player->mo->scale, FINESINE((vang +ANG1*90)>>ANGLETOFINESHIFT)); + tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); + ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); + tz = player->mo->z + player->mo->height/2 + FixedMul(48*player->mo->scale, FINECOSINE((vang +ANG1*90)>>ANGLETOFINESHIFT)); + + flame->momx = tx -player->mo->x; + flame->momy = ty -player->mo->y; + flame->momz = tz -(player->mo->z+player->mo->height/2); + } + else // we failed the trick, drop the half circles, it'll be funny I promise. + { + flame->flags &= ~MF_NOGRAVITY; + P_SetObjectMomZ(flame, 4<mo->x, player->mo->y, flame->x, flame->y), 8*mapobjectscale); + flame->momx += player->mo->momx; + flame->momy += player->mo->momy; + flame->momz += player->mo->momz; + } + } + + // make sure this is only drawn for our local player + flame->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player)); + + vang += FixedAngle(180<cmd; boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN)); - boolean HOLDING_ITEM = (player->kartstuff[k_itemheld] || player->kartstuff[k_eggmanheld]); - boolean NO_HYUDORO = (player->kartstuff[k_stolentimer] == 0 && player->kartstuff[k_stealingtimer] == 0); + boolean HOLDING_ITEM = (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)); + boolean NO_HYUDORO = (player->stealingtimer == 0); player->pflags &= ~PF_HITFINISHLINE; if (!player->exiting) { - if (player->kartstuff[k_oldposition] < player->kartstuff[k_position]) // But first, if you lost a place, + if (player->oldposition < player->position) // But first, if you lost a place, { - player->kartstuff[k_oldposition] = player->kartstuff[k_position]; // then the other player taunts. + player->oldposition = player->position; // then the other player taunts. K_RegularVoiceTimers(player); // and you can't for a bit } - else if (player->kartstuff[k_oldposition] > player->kartstuff[k_position]) // Otherwise, + else if (player->oldposition > player->position) // Otherwise, { K_PlayOvertakeSound(player->mo); // Say "YOU'RE TOO SLOW!" - player->kartstuff[k_oldposition] = player->kartstuff[k_position]; // Restore the old position, + player->oldposition = player->position; // Restore the old position, } } - if (player->kartstuff[k_positiondelay]) - player->kartstuff[k_positiondelay]--; + if (player->positiondelay) + player->positiondelay--; // Prevent ring misfire if (!(cmd->buttons & BT_ATTACK)) { - if (player->kartstuff[k_itemtype] == KITEM_NONE + if (player->itemtype == KITEM_NONE && NO_HYUDORO && !(HOLDING_ITEM - || player->kartstuff[k_itemamount] - || player->kartstuff[k_itemroulette] - || player->kartstuff[k_rocketsneakertimer] - || player->kartstuff[k_eggmanexplode])) - player->kartstuff[k_userings] = 1; + || player->itemamount + || player->itemroulette + || player->rocketsneakertimer + || player->eggmanexplode)) + player->pflags |= PF_USERINGS; else - player->kartstuff[k_userings] = 0; + player->pflags &= ~PF_USERINGS; } if ((player->pflags & PF_ATTACKDOWN) && !(cmd->buttons & BT_ATTACK)) @@ -8004,44 +8572,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player && player->mo && player->mo->health > 0 && !player->spectator && !P_PlayerInPain(player) && !mapreset && leveltime > introtime) { // First, the really specific, finicky items that function without the item being directly in your item slot. - // Karma item dropping - if (player->kartstuff[k_comebackmode]) - { - if (ATTACK_IS_DOWN) - { - mobj_t *newitem; - - if (player->kartstuff[k_comebackmode] == 1) - { - newitem = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RANDOMITEM); - newitem->threshold = 69; // selected "randomly". - } - else - { - newitem = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM); - if (player->kartstuff[k_eggmanblame] >= 0 - && player->kartstuff[k_eggmanblame] < MAXPLAYERS - && playeringame[player->kartstuff[k_eggmanblame]] - && !players[player->kartstuff[k_eggmanblame]].spectator - && players[player->kartstuff[k_eggmanblame]].mo) - P_SetTarget(&newitem->target, players[player->kartstuff[k_eggmanblame]].mo); - player->kartstuff[k_eggmanblame] = -1; - } - - newitem->flags2 = (player->mo->flags2 & MF2_OBJECTFLIP); - newitem->fuse = 15*TICRATE; // selected randomly. - - player->kartstuff[k_comebackmode] = 0; - player->karmadelay = comebacktime; - S_StartSound(player->mo, sfx_s254); - } - } - else { // Ring boosting - if (player->kartstuff[k_userings]) + if (player->pflags & PF_USERINGS) { - if ((player->pflags & PF_ATTACKDOWN) && !player->kartstuff[k_ringdelay] && player->rings > 0) + if ((player->pflags & PF_ATTACKDOWN) && !player->ringdelay && player->rings > 0) { mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING); P_SetMobjState(ring, S_FASTRING1); @@ -8050,73 +8585,73 @@ void K_MoveKartPlayer(player_t *player, boolean onground) ring->shadowscale = 0; P_SetTarget(&ring->target, player->mo); // user player->rings--; - player->kartstuff[k_ringdelay] = 3; + player->ringdelay = 3; } } // Other items else { // Eggman Monitor exploding - if (player->kartstuff[k_eggmanexplode]) + if (player->eggmanexplode) { - if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanexplode] <= 3*TICRATE && player->kartstuff[k_eggmanexplode] > 1) - player->kartstuff[k_eggmanexplode] = 1; + if (ATTACK_IS_DOWN && player->eggmanexplode <= 3*TICRATE && player->eggmanexplode > 1) + player->eggmanexplode = 1; } // Eggman Monitor throwing - else if (player->kartstuff[k_eggmanheld]) + else if (player->pflags & PF_EGGMANOUT) { if (ATTACK_IS_DOWN) { K_ThrowKartItem(player, false, MT_EGGMANITEM, -1, 0); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_eggmanheld] = 0; + player->pflags &= ~PF_EGGMANOUT; K_UpdateHnextList(player, true); } } // Rocket Sneaker usage - else if (player->kartstuff[k_rocketsneakertimer] > 1) + else if (player->rocketsneakertimer > 1) { if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO) { K_DoSneaker(player, 2); K_PlayBoostTaunt(player->mo); - player->kartstuff[k_rocketsneakertimer] -= 3*TICRATE; - if (player->kartstuff[k_rocketsneakertimer] < 1) - player->kartstuff[k_rocketsneakertimer] = 1; + if (player->rocketsneakertimer <= 3*TICRATE) + player->rocketsneakertimer = 1; + else + player->rocketsneakertimer -= 3*TICRATE; } } - else if (player->kartstuff[k_itemamount] <= 0) + else if (player->itemamount == 0) { - player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; + player->pflags &= ~PF_ITEMOUT; } else { - switch (player->kartstuff[k_itemtype]) + switch (player->itemtype) { case KITEM_SNEAKER: if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO) { K_DoSneaker(player, 1); K_PlayBoostTaunt(player->mo); - player->kartstuff[k_itemamount]--; + player->itemamount--; } break; case KITEM_ROCKETSNEAKER: if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO - && player->kartstuff[k_rocketsneakertimer] == 0) + && player->rocketsneakertimer == 0) { INT32 moloop; mobj_t *mo = NULL; mobj_t *prev = player->mo; K_PlayBoostTaunt(player->mo); - //player->kartstuff[k_itemheld] = 1; S_StartSound(player->mo, sfx_s3k3a); //K_DoSneaker(player, 2); - player->kartstuff[k_rocketsneakertimer] = (itemtime*3); - player->kartstuff[k_itemamount]--; + player->rocketsneakertimer = (itemtime*3); + player->itemamount--; K_UpdateHnextList(player, true); for (moloop = 0; moloop < 2; moloop++) @@ -8138,21 +8673,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_INVINCIBILITY: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) // Doesn't hold your item slot hostage normally, so you're free to waste it if you have multiple { - if (!player->kartstuff[k_invincibilitytimer]) + if (!player->invincibilitytimer) { mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INVULNFLASH); P_SetTarget(&overlay->target, player->mo); overlay->destscale = player->mo->scale; P_SetScale(overlay, player->mo->scale); } - player->kartstuff[k_invincibilitytimer] = itemtime+(2*TICRATE); // 10 seconds + player->invincibilitytimer = itemtime+(2*TICRATE); // 10 seconds if (P_IsLocalPlayer(player)) S_ChangeMusicSpecial("kinvnc"); if (! P_IsDisplayPlayer(player)) S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kinvnc)); P_RestoreMusic(player); K_PlayPowerGloatSound(player->mo); - player->kartstuff[k_itemamount]--; + player->itemamount--; } break; case KITEM_BANANA: @@ -8163,20 +8698,20 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mobj_t *prev = player->mo; //K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ITEMOUT; S_StartSound(player->mo, sfx_s254); - for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) + for (moloop = 0; moloop < player->itemamount; moloop++) { mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BANANA_SHIELD); if (!mo) { - player->kartstuff[k_itemamount] = moloop; + player->itemamount = moloop; break; } mo->flags |= MF_NOCLIPTHING; mo->threshold = 10; - mo->movecount = player->kartstuff[k_itemamount]; + mo->movecount = player->itemamount; mo->movedir = moloop+1; P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->hprev, prev); @@ -8184,11 +8719,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) prev = mo; } } - else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) // Banana x3 thrown + else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) // Banana x3 thrown { K_ThrowKartItem(player, false, MT_BANANA, -1, 0); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemamount]--; + player->itemamount--; K_UpdateHnextList(player, false); } break; @@ -8196,8 +8731,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { mobj_t *mo; - player->kartstuff[k_itemamount]--; - player->kartstuff[k_eggmanheld] = 1; + player->itemamount--; + player->pflags |= PF_EGGMANOUT; S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM_SHIELD); if (mo) @@ -8221,22 +8756,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mobj_t *prev = player->mo; //K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ITEMOUT; S_StartSound(player->mo, sfx_s3k3a); - for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) + for (moloop = 0; moloop < player->itemamount; moloop++) { - newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90; + newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->itemamount) * moloop) << FRACBITS) + ANGLE_90; mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ORBINAUT_SHIELD); if (!mo) { - player->kartstuff[k_itemamount] = moloop; + player->itemamount = moloop; break; } mo->flags |= MF_NOCLIPTHING; mo->angle = newangle; mo->threshold = 10; - mo->movecount = player->kartstuff[k_itemamount]; + mo->movecount = player->itemamount; mo->movedir = mo->lastlook = moloop+1; mo->color = player->skincolor; P_SetTarget(&mo->target, player->mo); @@ -8245,11 +8780,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) prev = mo; } } - else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) // Orbinaut x3 thrown + else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) // Orbinaut x3 thrown { K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemamount]--; + player->itemamount--; K_UpdateHnextList(player, false); } break; @@ -8262,22 +8797,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mobj_t *prev = player->mo; //K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ITEMOUT; S_StartSound(player->mo, sfx_s3k3a); - for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) + for (moloop = 0; moloop < player->itemamount; moloop++) { - newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90; + newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->itemamount) * moloop) << FRACBITS) + ANGLE_90; mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_JAWZ_SHIELD); if (!mo) { - player->kartstuff[k_itemamount] = moloop; + player->itemamount = moloop; break; } mo->flags |= MF_NOCLIPTHING; mo->angle = newangle; mo->threshold = 10; - mo->movecount = player->kartstuff[k_itemamount]; + mo->movecount = player->itemamount; mo->movedir = mo->lastlook = moloop+1; P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->hprev, prev); @@ -8285,14 +8820,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) prev = mo; } } - else if (ATTACK_IS_DOWN && HOLDING_ITEM && player->kartstuff[k_itemheld]) // Jawz thrown + else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->pflags & PF_ITEMOUT)) // Jawz thrown { - if (player->kartstuff[k_throwdir] == 1 || player->kartstuff[k_throwdir] == 0) + if (player->throwdir == 1 || player->throwdir == 0) K_ThrowKartItem(player, true, MT_JAWZ, 1, 0); - else if (player->kartstuff[k_throwdir] == -1) // Throwing backward gives you a dud that doesn't home in + else if (player->throwdir == -1) // Throwing backward gives you a dud that doesn't home in K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, 0); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemamount]--; + player->itemamount--; K_UpdateHnextList(player, false); } break; @@ -8300,7 +8835,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { mobj_t *mo; - player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ITEMOUT; S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD); if (mo) @@ -8313,19 +8848,19 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetTarget(&player->mo->hnext, mo); } } - else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) + else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) { K_ThrowKartItem(player, false, MT_SSMINE, 1, 1); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemamount]--; - player->kartstuff[k_itemheld] = 0; + player->itemamount--; + player->pflags &= ~PF_ITEMOUT; K_UpdateHnextList(player, true); } break; case KITEM_LANDMINE: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->kartstuff[k_itemamount]--; + player->itemamount--; K_ThrowLandMine(player); K_PlayAttackTaunt(player->mo); } @@ -8333,7 +8868,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_BALLHOG: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->kartstuff[k_itemamount]--; + player->itemamount--; K_ThrowKartItem(player, true, MT_BALLHOG, 1, 0); K_PlayAttackTaunt(player->mo); } @@ -8341,7 +8876,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_SPB: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->kartstuff[k_itemamount]--; + player->itemamount--; K_ThrowKartItem(player, true, MT_SPB, 1, 0); K_PlayAttackTaunt(player->mo); } @@ -8349,7 +8884,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_GROW: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - if (player->kartstuff[k_growshrinktimer] < 0) // If you're shrunk, then "grow" will just make you normal again. + if (player->growshrinktimer < 0) // If you're shrunk, then "grow" will just make you normal again. K_RemoveGrowShrink(player); else { @@ -8358,7 +8893,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->destscale = (3*mapobjectscale)/2; if (cv_kartdebugshrink.value && !modeattacking && !player->bot) player->mo->destscale = (6*player->mo->destscale)/8; - player->kartstuff[k_growshrinktimer] = itemtime+(4*TICRATE); // 12 seconds + player->growshrinktimer = itemtime+(4*TICRATE); // 12 seconds if (P_IsLocalPlayer(player)) S_ChangeMusicSpecial("kgrow"); if (! P_IsDisplayPlayer(player)) @@ -8366,84 +8901,87 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_RestoreMusic(player); S_StartSound(player->mo, sfx_kc5a); } - player->kartstuff[k_itemamount]--; + player->itemamount--; } break; case KITEM_SHRINK: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { K_DoShrink(player); - player->kartstuff[k_itemamount]--; + player->itemamount--; K_PlayPowerGloatSound(player->mo); } break; case KITEM_THUNDERSHIELD: - if (player->kartstuff[k_curshield] != KSHIELD_THUNDER) + if (player->curshield != KSHIELD_THUNDER) { mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetTarget(&shield->target, player->mo); S_StartSound(player->mo, sfx_s3k41); - player->kartstuff[k_curshield] = KSHIELD_THUNDER; + player->curshield = KSHIELD_THUNDER; } if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { K_DoThunderShield(player); - player->kartstuff[k_itemamount]--; + player->itemamount--; K_PlayAttackTaunt(player->mo); } break; case KITEM_BUBBLESHIELD: - if (player->kartstuff[k_curshield] != KSHIELD_BUBBLE) + if (player->curshield != KSHIELD_BUBBLE) { mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BUBBLESHIELD); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetTarget(&shield->target, player->mo); S_StartSound(player->mo, sfx_s3k3f); - player->kartstuff[k_curshield] = KSHIELD_BUBBLE; + player->curshield = KSHIELD_BUBBLE; } if (!HOLDING_ITEM && NO_HYUDORO) { - if ((cmd->buttons & BT_ATTACK) && player->kartstuff[k_holdready]) + if ((cmd->buttons & BT_ATTACK) && (player->pflags & PF_HOLDREADY)) { - if (player->kartstuff[k_bubbleblowup] == 0) + if (player->bubbleblowup == 0) S_StartSound(player->mo, sfx_s3k75); - player->kartstuff[k_bubbleblowup]++; - player->kartstuff[k_bubblecool] = player->kartstuff[k_bubbleblowup]*4; + player->bubbleblowup++; + player->bubblecool = player->bubbleblowup*4; - if (player->kartstuff[k_bubbleblowup] > bubbletime*2) + if (player->bubbleblowup > bubbletime*2) { - K_ThrowKartItem(player, (player->kartstuff[k_throwdir] > 0), MT_BUBBLESHIELDTRAP, -1, 0); + K_ThrowKartItem(player, (player->throwdir > 0), MT_BUBBLESHIELDTRAP, -1, 0); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_bubbleblowup] = 0; - player->kartstuff[k_bubblecool] = 0; - player->kartstuff[k_holdready] = 0; - player->kartstuff[k_itemamount]--; + player->bubbleblowup = 0; + player->bubblecool = 0; + player->pflags &= ~PF_HOLDREADY; + player->itemamount--; } } else { - if (player->kartstuff[k_bubbleblowup] > bubbletime) - player->kartstuff[k_bubbleblowup] = bubbletime; + if (player->bubbleblowup > bubbletime) + player->bubbleblowup = bubbletime; - if (player->kartstuff[k_bubbleblowup]) - player->kartstuff[k_bubbleblowup]--; + if (player->bubbleblowup) + player->bubbleblowup--; - player->kartstuff[k_holdready] = (player->kartstuff[k_bubblecool] ? 0 : 1); + if (player->bubblecool) + player->pflags &= ~PF_HOLDREADY; + else + player->pflags |= PF_HOLDREADY; } } break; case KITEM_FLAMESHIELD: - if (player->kartstuff[k_curshield] != KSHIELD_FLAME) + if (player->curshield != KSHIELD_FLAME) { mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FLAMESHIELD); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetTarget(&shield->target, player->mo); S_StartSound(player->mo, sfx_s3k3e); - player->kartstuff[k_curshield] = KSHIELD_FLAME; + player->curshield = KSHIELD_FLAME; } if (!HOLDING_ITEM && NO_HYUDORO) @@ -8451,26 +8989,23 @@ void K_MoveKartPlayer(player_t *player, boolean onground) INT32 destlen = K_FlameShieldMax(player); INT32 flamemax = 0; - if (player->kartstuff[k_flamelength] < destlen) - player->kartstuff[k_flamelength]++; // Can always go up! + if (player->flamelength < destlen) + player->flamelength++; // Can always go up! - flamemax = player->kartstuff[k_flamelength] * flameseg; + flamemax = player->flamelength * flameseg; if (flamemax > 0) flamemax += TICRATE; // leniency period - if ((cmd->buttons & BT_ATTACK) && player->kartstuff[k_holdready]) + if ((cmd->buttons & BT_ATTACK) && (player->pflags & PF_HOLDREADY)) { - if (player->kartstuff[k_flamemeter] < 0) - player->kartstuff[k_flamemeter] = 0; - - if (player->kartstuff[k_flamedash] == 0) + if (player->flamedash == 0) { S_StartSound(player->mo, sfx_s3k43); K_PlayBoostTaunt(player->mo); } - player->kartstuff[k_flamedash] += 2; - player->kartstuff[k_flamemeter] += 2; + player->flamedash += 2; + player->flamemeter += 2; if (!onground) { @@ -8480,44 +9015,44 @@ void K_MoveKartPlayer(player_t *player, boolean onground) ); } - if (player->kartstuff[k_flamemeter] > flamemax) + if (player->flamemeter > flamemax) { P_Thrust( player->mo, player->mo->angle, FixedMul((50*player->mo->scale), K_GetKartGameSpeedScalar(gamespeed)) ); - player->kartstuff[k_flamemeter] = 0; - player->kartstuff[k_flamelength] = 0; - player->kartstuff[k_holdready] = 0; - player->kartstuff[k_itemamount]--; + player->flamemeter = 0; + player->flamelength = 0; + player->pflags &= ~PF_HOLDREADY; + player->itemamount--; } } else { - player->kartstuff[k_holdready] = 1; + player->pflags |= PF_HOLDREADY; - if (player->kartstuff[k_flamemeter] > 0) - player->kartstuff[k_flamemeter]--; + if (player->flamemeter > 0) + player->flamemeter--; - if (player->kartstuff[k_flamelength] > destlen) + if (player->flamelength > destlen) { - player->kartstuff[k_flamelength]--; // Can ONLY go down if you're not using it + player->flamelength--; // Can ONLY go down if you're not using it - flamemax = player->kartstuff[k_flamelength] * flameseg; + flamemax = player->flamelength * flameseg; if (flamemax > 0) flamemax += TICRATE; // leniency period } - if (player->kartstuff[k_flamemeter] > flamemax) - player->kartstuff[k_flamemeter] = flamemax; + if (player->flamemeter > flamemax) + player->flamemeter = flamemax; } } break; case KITEM_HYUDORO: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->kartstuff[k_itemamount]--; + player->itemamount--; K_DoHyudoroSteal(player); // yes. yes they do. } break; @@ -8527,22 +9062,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayBoostTaunt(player->mo); K_DoPogoSpring(player->mo, 32<trickpanel = 1; - player->trickdelay = 1; - player->kartstuff[k_itemamount]--; + player->pflags |= PF_TRICKDELAY; + player->itemamount--; } break; case KITEM_SUPERRING: - if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO && player->superring < (UINT16_MAX - (10*3))) { - player->kartstuff[k_superring] += (10*3); - player->kartstuff[k_itemamount]--; + player->superring += (10*3); + player->itemamount--; } break; case KITEM_KITCHENSINK: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { mobj_t *mo; - player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ITEMOUT; S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SINK_SHIELD); if (mo) @@ -8555,21 +9090,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetTarget(&player->mo->hnext, mo); } } - else if (ATTACK_IS_DOWN && HOLDING_ITEM && player->kartstuff[k_itemheld]) // Sink thrown + else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->pflags & PF_ITEMOUT)) // Sink thrown { K_ThrowKartItem(player, false, MT_SINK, 1, 2); K_PlayAttackTaunt(player->mo); - player->kartstuff[k_itemamount]--; - player->kartstuff[k_itemheld] = 0; + player->itemamount--; + player->pflags &= ~PF_ITEMOUT; K_UpdateHnextList(player, true); } break; case KITEM_SAD: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO - && !player->kartstuff[k_sadtimer]) + && !player->sadtimer) { - player->kartstuff[k_sadtimer] = stealtime; - player->kartstuff[k_itemamount]--; + player->sadtimer = stealtime; + player->itemamount--; } break; default: @@ -8580,30 +9115,30 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } // No more! - if (!player->kartstuff[k_itemamount]) + if (!player->itemamount) { - player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_itemtype] = KITEM_NONE; + player->pflags &= ~PF_ITEMOUT; + player->itemtype = KITEM_NONE; } - if (K_GetShieldFromItem(player->kartstuff[k_itemtype]) == KSHIELD_NONE) + if (K_GetShieldFromItem(player->itemtype) == KSHIELD_NONE) { - player->kartstuff[k_curshield] = KSHIELD_NONE; // RESET shield type - player->kartstuff[k_bubbleblowup] = 0; - player->kartstuff[k_bubblecool] = 0; - player->kartstuff[k_flamelength] = 0; - player->kartstuff[k_flamemeter] = 0; + player->curshield = KSHIELD_NONE; // RESET shield type + player->bubbleblowup = 0; + player->bubblecool = 0; + player->flamelength = 0; + player->flamemeter = 0; } - if (spbplace == -1 || player->kartstuff[k_position] != spbplace) - player->kartstuff[k_ringlock] = 0; // reset ring lock + if (spbplace == -1 || player->position != spbplace) + player->pflags &= ~PF_RINGLOCK; // reset ring lock - if (player->kartstuff[k_itemtype] == KITEM_SPB - || player->kartstuff[k_itemtype] == KITEM_SHRINK - || player->kartstuff[k_growshrinktimer] < 0) + if (player->itemtype == KITEM_SPB + || player->itemtype == KITEM_SHRINK + || player->growshrinktimer < 0) indirectitemcooldown = 20*TICRATE; - if (player->kartstuff[k_hyudorotimer] > 0) + if (player->hyudorotimer > 0) { INT32 hyu = hyudorotime; @@ -8616,15 +9151,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else { - if (player->kartstuff[k_hyudorotimer] >= (TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyu-(TICRATE/2)) + if (player->hyudorotimer >= (TICRATE/2) && player->hyudorotimer <= hyu-(TICRATE/2)) player->mo->renderflags &= ~K_GetPlayerDontDrawFlag(player); else player->mo->renderflags &= ~RF_DONTDRAW; } - player->powers[pw_flashing] = player->kartstuff[k_hyudorotimer]; // We'll do this for now, let's people know about the invisible people through subtle hints + player->flashing = player->hyudorotimer; // We'll do this for now, let's people know about the invisible people through subtle hints } - else if (player->kartstuff[k_hyudorotimer] == 0) + else if (player->hyudorotimer == 0) { player->mo->renderflags &= ~RF_DONTDRAW; } @@ -8634,7 +9169,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_DropItems(player); //K_StripItems(player); K_StripOther(player); player->mo->renderflags |= RF_GHOSTLY; - player->powers[pw_flashing] = player->karmadelay; + player->flashing = player->karmadelay; } else if (gametype == GT_RACE || player->bumpers > 0) { @@ -8649,48 +9184,90 @@ void K_MoveKartPlayer(player_t *player, boolean onground) fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); + K_trickPanelTimingVisual(player, momz); + + // streaks: + if (momz*P_MobjFlip(player->mo) > 0) // only spawn those while you're going upwards relative to your current gravity + { + // these are all admittedly arbitrary numbers... + INT32 n; + INT32 maxlines = max(1, (momz/FRACUNIT)/16); + INT32 frequency = max(1, 5-(momz/FRACUNIT)/4); + fixed_t sx, sy, sz; + mobj_t *spdl; + + if (!(leveltime % frequency)) + { + for (n=0; n < maxlines; n++) + { + sx = player->mo->x + P_RandomRange(-24, 24)*player->mo->scale; + sy = player->mo->y + P_RandomRange(-24, 24)*player->mo->scale; + sz = player->mo->z + P_RandomRange(0, 48)*player->mo->scale; + + spdl = P_SpawnMobj(sx, sy, sz, MT_FASTLINE); + P_SetTarget(&spdl->target, player->mo); + spdl->angle = R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y); + spdl->rollangle = -ANG1*90*P_MobjFlip(player->mo); // angle them downwards relative to the player's gravity... + spdl->spriteyscale = player->trickboostpower+FRACUNIT; + spdl->momx = player->mo->momx; + spdl->momy = player->mo->momy; + } + + } + + } + + // We'll never need to go above that. + if (player->tricktime <= TRICKDELAY) + player->tricktime++; + // debug shit //CONS_Printf("%d\n", player->mo->momz / mapobjectscale); if (momz < -10*FRACUNIT) // :youfuckedup: { // tumble if you let your chance pass!! player->tumbleBounces = 1; - player->tumbleSound = 0; + player->pflags &= ~PF_TUMBLESOUND; player->tumbleHeight = 30; // Base tumble bounce height player->trickpanel = 0; + K_trickPanelTimingVisual(player, momz); // fail trick visual P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } - else if (player->trickdelay <= 0) // don't allow tricking at the same frame you tumble obv + else if (!(player->pflags & PF_TRICKDELAY)) // don't allow tricking at the same frame you tumble obv { + // "COOL" timing n shit. + if (cmd->turning || player->throwdir) + { + if (abs(momz) < FRACUNIT*99) // Let's use that as baseline for PERFECT trick. + { + player->karthud[khud_trickcool] = TICRATE; + } + } + + // Uses cmd->turning over steering intentionally. if (cmd->turning > 0) { P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + + K_trickPanelTimingVisual(player, momz); } else if (cmd->turning < 0) { P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2)); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 3; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + + K_trickPanelTimingVisual(player, momz); } - else if (player->kartstuff[k_throwdir] == 1) + else if (player->throwdir == 1) { if (player->mo->momz * P_MobjFlip(player->mo) > 0) { @@ -8698,17 +9275,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + + K_trickPanelTimingVisual(player, momz); } - else if (player->kartstuff[k_throwdir] == -1) + else if (player->throwdir == -1) { boolean relative = true; @@ -8720,40 +9294,37 @@ void K_MoveKartPlayer(player_t *player, boolean onground) relative = false; } + // Calculate speed boost decay: + // Base speed boost duration is 35 tics. + // At most, lose 3/4th of your boost. + player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); + //CONS_Printf("decay: %d\n", player->trickboostdecay); + P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); + player->trickpanel = 4; - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - - player->trickpanel = 3; player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + + K_trickPanelTimingVisual(player, momz); } } } - // After hitlag, we will get here and will be able to apply the desired momentums! - else if (player->trickmomx || player->trickmomy || player->trickmomz) + else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed! { - player->mo->momx = player->trickmomx; - player->mo->momy = player->trickmomy; - player->mo->momz = player->trickmomz; - - player->trickmomx = player->trickmomy = player->trickmomz = 0; + //CONS_Printf("apply boost\n"); + S_StartSound(player->mo, sfx_s23c); + K_SpawnDashDustRelease(player); + player->trickboost = TICRATE - player->trickboostdecay; + player->trickpanel = player->trickboostdecay = 0; } // Wait until we let go off the control stick to remove the delay - if (player->trickdelay > 0) + // buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying. + if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning && (player->tricktime >= TRICKDELAY)) { - player->trickdelay--; - - if ((player->kartstuff[k_throwdir] != 0 || cmd->turning != 0) && player->trickdelay <= 0) - { - // Don't allow a trick until you go back to neutral - player->trickdelay = 1; - } + player->pflags &= ~PF_TRICKDELAY; } } @@ -8766,7 +9337,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else { - player->airFailsafe = false; + player->pflags &= ~PF_AIRFAILSAFE; } // Play the starting countdown sounds @@ -8793,9 +9364,9 @@ void K_CheckSpectateStatus(void) if (!playeringame[i]) continue; if (players[i].spectator && (players[i].pflags & PF_WANTSTOJOIN)) - players[i].kartstuff[k_spectatewait]++; + players[i].spectatewait++; else - players[i].kartstuff[k_spectatewait] = 0; + players[i].spectatewait = 0; } // No one's allowed to join @@ -8843,11 +9414,11 @@ void K_CheckSpectateStatus(void) for (i = 0; i < numjoiners; i++) { UINT8 pos = 0; - INT32 ispecwait = players[oldrespawnlist[i]].kartstuff[k_spectatewait]; + INT32 ispecwait = players[oldrespawnlist[i]].spectatewait; for (j = 0; j < numjoiners; j++) { - INT32 jspecwait = players[oldrespawnlist[j]].kartstuff[k_spectatewait]; + INT32 jspecwait = players[oldrespawnlist[j]].spectatewait; if (j == i) continue; if (jspecwait > ispecwait) @@ -8876,4 +9447,46 @@ void K_CheckSpectateStatus(void) } } +UINT8 K_GetInvincibilityItemFrame(void) +{ + return ((leveltime % (7*3)) / 3); +} + +UINT8 K_GetOrbinautItemFrame(UINT8 count) +{ + return min(count - 1, 3); +} + +boolean K_IsSPBInGame(void) +{ + UINT8 i; + thinker_t *think; + + // is there an SPB chasing anyone? + if (spbplace != -1) + return true; + + // do any players have an SPB in their item slot? + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (players[i].itemtype == KITEM_SPB) + return true; + } + + // spbplace is still -1 until a fired SPB finds a target, so look for an in-map SPB just in case + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + if (((mobj_t *)think)->type == MT_SPB) + return true; + } + + return false; +} + //} diff --git a/src/k_kart.h b/src/k_kart.h index 09665d8ab..b8e74539b 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -19,6 +19,7 @@ Make sure this matches the actual number of states */ #define KART_NUMINVSPARKLESANIM 12 +#define MAXHITLAGTICS 18 //12 player_t *K_GetItemBoxPlayer(mobj_t *mobj); angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); @@ -34,10 +35,13 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value); extern consvar_t *KartItemCVars[NUMKARTRESULTS-1]; UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush); -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); +fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush); +UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush); +INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); INT32 K_GetShieldFromItem(INT32 item); fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against); -boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); +boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2); +boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj); void K_KartPainEnergyFling(player_t *player); void K_FlipFromObject(mobj_t *mo, mobj_t *master); void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master); @@ -52,7 +56,8 @@ void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); +void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage); void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); @@ -71,6 +76,7 @@ void K_SpawnSparkleTrail(mobj_t *mo); void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad); void K_SpawnDraftDust(mobj_t *mo); void K_DriftDustHandling(mobj_t *spawner); +mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow); 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); @@ -85,7 +91,10 @@ boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); void K_UpdateSteeringValue(player_t *player, INT16 destSteering); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT32 K_GetKartDriftSparkValue(player_t *player); +INT32 K_StairJankFlip(INT32 value); +INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage); void K_SpawnDriftBoostExplosion(player_t *player, int stage); +void K_SpawnDriftElectricSparks(player_t *player); void K_KartUpdatePosition(player_t *player); mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount); void K_DropItems(player_t *player); @@ -96,6 +105,8 @@ void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); boolean K_ApplyOffroad(player_t *player); boolean K_SlopeResistance(player_t *player); +boolean K_TripwirePass(player_t *player); +void K_ApplyTripWire(player_t *player, tripwirestate_t state); INT16 K_GetSpindashChargeTime(player_t *player); fixed_t K_GetSpindashChargeSpeed(player_t *player); fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); @@ -105,12 +116,16 @@ UINT16 K_GetKartFlashing(player_t *player); boolean K_KartKickstart(player_t *player); UINT16 K_GetKartButtons(player_t *player); SINT8 K_GetForwardMove(player_t *player); +fixed_t K_GetNewSpeed(player_t *player); fixed_t K_3dKartMovement(player_t *player); boolean K_PlayerEBrake(player_t *player); SINT8 K_Sliptiding(player_t *player); void K_AdjustPlayerFriction(player_t *player); void K_MoveKartPlayer(player_t *player, boolean onground); void K_CheckSpectateStatus(void); +UINT8 K_GetInvincibilityItemFrame(void); +UINT8 K_GetOrbinautItemFrame(UINT8 count); +boolean K_IsSPBInGame(void); // sound stuff for lua void K_PlayAttackTaunt(mobj_t *source); diff --git a/src/k_respawn.c b/src/k_respawn.c index 6018c2e54..2e93a57d8 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -113,7 +113,7 @@ static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint) void K_DoFault(player_t *player) { - player->powers[pw_nocontrol] = (starttime - leveltime) + 50; + player->nocontrol = (starttime - leveltime) + 50; if (!(player->pflags & PF_FAULT)) { S_StartSound(player->mo, sfx_s3k83); @@ -149,15 +149,18 @@ void K_DoIngameRespawn(player_t *player) if (leveltime < starttime) K_DoFault(player); - player->kartstuff[k_ringboost] = 0; - player->kartstuff[k_driftboost] = 0; + player->ringboost = 0; + player->driftboost = player->strongdriftboost = 0; // If player was tumbling, set variables so that they don't tumble like crazy after they're done respawning if (player->tumbleBounces > 0) { - player->tumbleBounces = TUMBLEBOUNCES-1; // Max # of bounces-1 (so you still tumble once) - player->tumbleLastBounce = false; // Still force them to bounce at least once for the funny - players->tumbleHeight = 20; // force tumble height + player->tumbleBounces = 0; // MAXBOUNCES-1; + player->pflags &= ~PF_TUMBLELASTBOUNCE; + //players->tumbleHeight = 20; + players->mo->rollangle = 0; + player->spinouttype = KSPIN_WIPEOUT; + player->spinouttimer = player->wipeoutslow = (3*TICRATE/2)+2; } P_ResetPlayer(player); @@ -273,6 +276,8 @@ void K_DoIngameRespawn(player_t *player) player->respawn.timer = RESPAWN_TIME; player->respawn.state = RESPAWNST_MOVE; + + player->respawn.airtimer = player->airtime; } /*-------------------------------------------------- @@ -315,8 +320,9 @@ size_t K_NextRespawnWaypointIndex(waypoint_t *waypoint) --------------------------------------------------*/ static void K_MovePlayerToRespawnPoint(player_t *player) { - const fixed_t realstepamt = (64 * mapobjectscale); - fixed_t stepamt = realstepamt; + const int airCompensation = 128; + fixed_t realstepamt = (64 * mapobjectscale); + fixed_t stepamt; vector3_t dest, step, laser; angle_t stepha, stepva; @@ -327,10 +333,17 @@ static void K_MovePlayerToRespawnPoint(player_t *player) waypoint_t *laserwp; boolean laserflip; + /* speed up if in the air for a long time */ + realstepamt += FixedMul(realstepamt, + (player->respawn.airtimer * FRACUNIT) + / airCompensation); + + stepamt = realstepamt; + player->mo->momx = player->mo->momy = player->mo->momz = 0; - player->powers[pw_flashing] = 2; - player->powers[pw_nocontrol] = max(2, player->powers[pw_nocontrol]); + player->flashing = 2; + player->nocontrol = max(2, player->nocontrol); if (leveltime % 8 == 0 && !mapreset) { @@ -589,7 +602,7 @@ static void K_MovePlayerToRespawnPoint(player_t *player) --------------------------------------------------*/ static void K_DropDashWait(player_t *player) { - if (player->powers[pw_nocontrol] == 0) + if (player->nocontrol == 0) player->respawn.timer--; if (leveltime % 8 == 0) @@ -656,7 +669,7 @@ static void K_HandleDropDash(player_t *player) { const UINT16 buttons = K_GetKartButtons(player); - if (player->kartstuff[k_growshrinktimer] < 0) + if (player->growshrinktimer < 0) { player->mo->scalespeed = mapobjectscale/TICRATE; player->mo->destscale = (6*mapobjectscale)/8; @@ -674,12 +687,12 @@ static void K_HandleDropDash(player_t *player) return; } - player->powers[pw_flashing] = K_GetKartFlashing(player); + player->flashing = K_GetKartFlashing(player); // The old behavior was stupid and prone to accidental usage. // Let's rip off Mania instead, and turn this into a Drop Dash! - if ((buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) + if ((buttons & BT_ACCELERATE) && !player->spinouttimer) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) { player->respawn.dropdash++; } @@ -707,7 +720,7 @@ static void K_HandleDropDash(player_t *player) if ((buttons & BT_ACCELERATE) && (player->respawn.dropdash >= TICRATE/4)) { S_StartSound(player->mo, sfx_s23c); - player->kartstuff[k_startboost] = 50; + player->startboost = 50; K_SpawnDashDustRelease(player); } diff --git a/src/k_respawn.h b/src/k_respawn.h index 5dd78ff1f..81ee16b77 100644 --- a/src/k_respawn.h +++ b/src/k_respawn.h @@ -17,9 +17,9 @@ #define RESPAWN_DIST 1024 #define RESPAWN_TIME 48 -#define RESPAWNST_NONE 0 -#define RESPAWNST_MOVE 1 -#define RESPAWNST_DROP 2 +#define RESPAWNST_NONE 0x00 +#define RESPAWNST_MOVE 0x01 +#define RESPAWNST_DROP 0x02 /*-------------------------------------------------- fixed_t K_RespawnOffset(player_t *player, boolean flip); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1397f6fcf..0ce78b6f9 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -170,7 +170,6 @@ static const struct { {META_PLAYER, "player_t"}, {META_TICCMD, "ticcmd_t"}, {META_SKIN, "skin_t"}, - {META_POWERS, "player_t.powers"}, {META_SOUNDSID, "skin_t.soundsid"}, {META_SKINSPRITES, "skin_t.sprites"}, {META_SKINSPRITESLIST, "skin_t.sprites[]"}, @@ -1245,17 +1244,6 @@ static int lib_pRestoreMusic(lua_State *L) return 1; } -static int lib_pSpawnShieldOrb(lua_State *L) -{ - player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - NOHUD - INLEVEL - if (!player) - return LUA_ErrInvalid(L, "player_t"); - P_SpawnShieldOrb(player); - return 0; -} - static int lib_pSpawnGhostMobj(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -1291,17 +1279,6 @@ static int lib_pGivePlayerLives(lua_State *L) return 0; } -static int lib_pResetScore(lua_State *L) -{ - player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - NOHUD - INLEVEL - if (!player) - return LUA_ErrInvalid(L, "player_t"); - P_ResetScore(player); - return 0; -} - static int lib_pMovePlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1376,18 +1353,6 @@ static int lib_pNukeEnemies(lua_State *L) return 0; } -static int lib_pSwitchShield(lua_State *L) -{ - player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - UINT16 shield = luaL_checkinteger(L, 2); - NOHUD - INLEVEL - if (!player) - return LUA_ErrInvalid(L, "player_t"); - P_SwitchShield(player, shield); - return 0; -} - // P_MAP /////////// @@ -2133,6 +2098,16 @@ static int lib_rPointToAngle(lua_State *L) return 1; } +static int lib_rPointToAnglePlayer(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + //HUDSAFE + lua_pushangle(L, R_PointToAnglePlayer(player, x, y)); + return 1; +} + static int lib_rPointToAngle2(lua_State *L) { fixed_t px2 = luaL_checkfixed(L, 1); @@ -3416,14 +3391,12 @@ static int lib_kKartBouncing(lua_State *L) { mobj_t *mobj1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mobj2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - boolean bounce = lua_optboolean(L, 3); - boolean solid = lua_optboolean(L, 4); NOHUD if (!mobj1) return LUA_ErrInvalid(L, "mobj_t"); if (!mobj2) return LUA_ErrInvalid(L, "mobj_t"); - K_KartBouncing(mobj1, mobj2, bounce, solid); + K_KartBouncing(mobj1, mobj2); return 0; } @@ -3847,18 +3820,15 @@ static luaL_Reg lib[] = { {"P_PlayJingle",lib_pPlayJingle}, {"P_PlayJingleMusic",lib_pPlayJingleMusic}, {"P_RestoreMusic",lib_pRestoreMusic}, - {"P_SpawnShieldOrb",lib_pSpawnShieldOrb}, {"P_SpawnGhostMobj",lib_pSpawnGhostMobj}, {"P_GivePlayerRings",lib_pGivePlayerRings}, {"P_GivePlayerLives",lib_pGivePlayerLives}, - {"P_ResetScore",lib_pResetScore}, {"P_MovePlayer",lib_pMovePlayer}, {"P_DoPlayerExit",lib_pDoPlayerExit}, {"P_InstaThrust",lib_pInstaThrust}, {"P_ReturnThrustX",lib_pReturnThrustX}, {"P_ReturnThrustY",lib_pReturnThrustY}, {"P_NukeEnemies",lib_pNukeEnemies}, - {"P_SwitchShield",lib_pSwitchShield}, // p_map {"P_CheckPosition",lib_pCheckPosition}, @@ -3914,6 +3884,7 @@ static luaL_Reg lib[] = { // r_defs {"R_PointToAngle",lib_rPointToAngle}, + {"R_PointToAnglePlayer", lib_rPointToAnglePlayer}, {"R_PointToAngle2",lib_rPointToAngle2}, {"R_PointToDist",lib_rPointToDist}, {"R_PointToDist2",lib_rPointToDist2}, diff --git a/src/lua_hook.h b/src/lua_hook.h index 022f6ad56..e44b60d75 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -114,8 +114,6 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to p void LUAh_IntermissionThinker(void); // Hook for Y_Ticker void LUAh_VoteThinker(void); // Hook for Y_VoteTicker -#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb -#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities #define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 926df78ca..75a84ed18 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -946,6 +946,24 @@ static int libd_drawString(lua_State *L) return 0; } +static int libd_drawTitleCardString(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); + boolean rightalign = lua_optboolean(L, 5); + INT32 timer = luaL_optinteger(L, 6, 0); + INT32 threshold = luaL_optinteger(L, 7, 0); + + flags &= ~V_PARAMMASK; // Don't let crashes happen. + + HUDONLY + V_DrawTitleCardString(x, y, str, flags, rightalign, timer, threshold); + return 0; +} + static int libd_drawKartString(lua_State *L) { fixed_t x = luaL_checkinteger(L, 1); @@ -960,6 +978,15 @@ static int libd_drawKartString(lua_State *L) return 0; } +static int libd_titleCardStringWidth(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + HUDONLY + + lua_pushinteger(L, V_TitleCardStringWidth(str)); + return 1; +} + static int libd_stringWidth(lua_State *L) { const char *str = luaL_checkstring(L, 1); @@ -1163,9 +1190,11 @@ static luaL_Reg lib_draw[] = { {"drawFill", libd_drawFill}, {"fadeScreen", libd_fadeScreen}, {"drawString", libd_drawString}, + {"drawTitleCardString", libd_drawTitleCardString}, {"drawKartString", libd_drawKartString}, // misc {"stringWidth", libd_stringWidth}, + {"titleCardStringWidth", libd_titleCardStringWidth}, // m_random {"RandomFixed",libd_RandomFixed}, {"RandomByte",libd_RandomByte}, diff --git a/src/lua_infolib.c b/src/lua_infolib.c index bbf640b85..880496770 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -41,6 +41,7 @@ enum sfxinfo_read { sfxinfor_singular, sfxinfor_priority, sfxinfor_flags, // "pitch" + sfxinfor_volume, sfxinfor_caption, sfxinfor_skinsound }; @@ -49,6 +50,7 @@ const char *const sfxinfo_ropt[] = { "singular", "priority", "flags", + "volume", "caption", "skinsound", NULL}; @@ -57,12 +59,14 @@ enum sfxinfo_write { sfxinfow_singular = 0, sfxinfow_priority, sfxinfow_flags, // "pitch" + sfxinfow_volume, sfxinfow_caption }; const char *const sfxinfo_wopt[] = { "singular", "priority", "flags", + "volume", "caption", NULL}; @@ -1328,6 +1332,9 @@ static int lib_setSfxInfo(lua_State *L) case sfxinfow_flags: info->pitch = (INT32)luaL_checkinteger(L, 3); break; + case sfxinfow_volume: + info->volume = (INT32)luaL_checkinteger(L, 3); + break; case sfxinfow_caption: strlcpy(info->caption, luaL_checkstring(L, 3), sizeof(info->caption)); break; @@ -1368,6 +1375,9 @@ static int sfxinfo_get(lua_State *L) case sfxinfor_flags: lua_pushinteger(L, sfx->pitch); return 1; + case sfxinfor_volume: + lua_pushinteger(L, sfx->volume); + return 1; case sfxinfor_caption: lua_pushstring(L, sfx->caption); return 1; @@ -1408,6 +1418,9 @@ static int sfxinfo_set(lua_State *L) case sfxinfow_flags: sfx->pitch = luaL_checkinteger(L, 1); break; + case sfxinfow_volume: + sfx->volume = luaL_checkinteger(L, 1); + break; case sfxinfow_caption: strlcpy(sfx->caption, luaL_checkstring(L, 1), sizeof(sfx->caption)); break; diff --git a/src/lua_libs.h b/src/lua_libs.h index 28404878e..c02964467 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -37,8 +37,6 @@ extern lua_State *gL; #define META_PLAYER "PLAYER_T*" #define META_TICCMD "TICCMD_T*" #define META_SKIN "SKIN_T*" -#define META_POWERS "PLAYER_T*POWERS" -#define META_KARTSTUFF "PLAYER_T*KARTSTUFF" #define META_KARTHUD "PLAYER_T*KARTHUD" #define META_RESPAWN "PLAYER_T*RESPAWN" #define META_COLLIDE "PLAYER_T*COLLIDE" diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 082a6dca3..f7c20ab64 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -128,7 +128,7 @@ static int lib_iterateDisplayplayers(lua_State *L) for (i++; i < MAXSPLITSCREENPLAYERS; i++) { - if (i > splitscreen || !playeringame[displayplayers[i]]) + if (i > r_splitscreen || !playeringame[displayplayers[i]]) return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers. LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER); @@ -147,7 +147,7 @@ static int lib_getDisplayplayers(lua_State *L) lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || i >= MAXSPLITSCREENPLAYERS) return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1); - if (i > splitscreen) + if (i > r_splitscreen) return 0; if (!playeringame[displayplayers[i]]) return 0; @@ -206,42 +206,172 @@ static int player_get(lua_State *L) lua_pushangle(L, plr->aiming); else if (fastcmp(field,"drawangle")) lua_pushangle(L, plr->drawangle); - else if (fastcmp(field,"rings")) - lua_pushinteger(L, plr->rings); - else if (fastcmp(field,"spheres")) - lua_pushinteger(L, plr->spheres); - else if (fastcmp(field,"powers")) - LUA_PushUserdata(L, plr->powers, META_POWERS); - else if (fastcmp(field,"kartstuff")) - LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); else if (fastcmp(field,"karthud")) LUA_PushUserdata(L, plr->karthud, META_KARTHUD); + else if (fastcmp(field,"nocontrol")) + lua_pushinteger(L, plr->nocontrol); + else if (fastcmp(field,"carry")) + lua_pushinteger(L, plr->carry); + else if (fastcmp(field,"dye")) + lua_pushinteger(L, plr->dye); + else if (fastcmp(field,"position")) + lua_pushinteger(L, plr->position); + else if (fastcmp(field,"oldposition")) + lua_pushinteger(L, plr->oldposition); + else if (fastcmp(field,"positiondelay")) + lua_pushinteger(L, plr->positiondelay); + else if (fastcmp(field,"distancetofinish")) + lua_pushinteger(L, plr->distancetofinish); else if (fastcmp(field,"airtime")) lua_pushinteger(L, plr->airtime); - else if (fastcmp(field,"driftInput")) - lua_pushboolean(L, plr->driftInput); - else if (fastcmp(field,"airFailsafe")) - lua_pushboolean(L, plr->airFailsafe); + else if (fastcmp(field,"flashing")) + lua_pushinteger(L, plr->flashing); + else if (fastcmp(field,"spinouttimer")) + lua_pushinteger(L, plr->spinouttimer); + else if (fastcmp(field,"instashield")) + lua_pushinteger(L, plr->instashield); + else if (fastcmp(field,"wipeoutslow")) + lua_pushinteger(L, plr->wipeoutslow); + else if (fastcmp(field,"justbumped")) + lua_pushinteger(L, plr->justbumped); else if (fastcmp(field,"tumbleBounces")) lua_pushinteger(L, plr->tumbleBounces); else if (fastcmp(field,"tumbleHeight")) lua_pushinteger(L, plr->tumbleHeight); - else if (fastcmp(field,"tumbleLastBounce")) - lua_pushboolean(L, plr->tumbleLastBounce); - else if (fastcmp(field,"tumbleSound")) - lua_pushboolean(L, plr->tumbleSound); + else if (fastcmp(field,"drift")) + lua_pushinteger(L, plr->drift); + else if (fastcmp(field,"driftcharge")) + lua_pushinteger(L, plr->driftcharge); + else if (fastcmp(field,"driftboost")) + lua_pushinteger(L, plr->driftboost); + else if (fastcmp(field,"strongdriftboost")) + lua_pushinteger(L, plr->strongdriftboost); + else if (fastcmp(field,"aizdriftstraft")) + lua_pushinteger(L, plr->aizdriftstrat); + else if (fastcmp(field,"aizdrifttilt")) + lua_pushinteger(L, plr->aizdrifttilt); + else if (fastcmp(field,"aizdriftturn")) + lua_pushinteger(L, plr->aizdriftturn); + else if (fastcmp(field,"offroad")) + lua_pushinteger(L, plr->offroad); + else if (fastcmp(field,"waterskip")) + lua_pushinteger(L, plr->waterskip); + else if (fastcmp(field,"tiregrease")) + lua_pushinteger(L, plr->tiregrease); + else if (fastcmp(field,"springstars")) + lua_pushinteger(L, plr->springstars); + else if (fastcmp(field,"springcolor")) + lua_pushinteger(L, plr->springcolor); + else if (fastcmp(field,"dashpadcooldown")) + lua_pushinteger(L, plr->dashpadcooldown); + else if (fastcmp(field,"spindash")) + lua_pushinteger(L, plr->spindash); + else if (fastcmp(field,"spindashspeed")) + lua_pushinteger(L, plr->spindashspeed); + else if (fastcmp(field,"spindashboost")) + lua_pushinteger(L, plr->spindashboost); + else if (fastcmp(field,"numboosts")) + lua_pushinteger(L, plr->numboosts); + else if (fastcmp(field,"boostpower")) + lua_pushinteger(L, plr->boostpower); + else if (fastcmp(field,"speedboost")) + lua_pushinteger(L, plr->speedboost); + else if (fastcmp(field,"accelboost")) + lua_pushinteger(L, plr->accelboost); + else if (fastcmp(field,"handleboost")) + lua_pushinteger(L, plr->handleboost); + else if (fastcmp(field,"boostangle")) + lua_pushinteger(L, plr->boostangle); + else if (fastcmp(field,"draftpower")) + lua_pushinteger(L, plr->draftpower); + else if (fastcmp(field,"draftleeway")) + lua_pushinteger(L, plr->draftleeway); + else if (fastcmp(field,"lastdraft")) + lua_pushinteger(L, plr->lastdraft); + else if (fastcmp(field,"itemroulette")) + lua_pushinteger(L, plr->itemroulette); + else if (fastcmp(field,"roulettetype")) + lua_pushinteger(L, plr->roulettetype); + else if (fastcmp(field,"itemtype")) + lua_pushinteger(L, plr->itemtype); + else if (fastcmp(field,"itemamount")) + lua_pushinteger(L, plr->itemamount); + else if (fastcmp(field,"throwdir")) + lua_pushinteger(L, plr->throwdir); + else if (fastcmp(field,"sadtimer")) + lua_pushinteger(L, plr->sadtimer); + else if (fastcmp(field,"rings")) + lua_pushinteger(L, plr->rings); + else if (fastcmp(field,"pickuprings")) + lua_pushinteger(L, plr->pickuprings); + else if (fastcmp(field,"ringdelay")) + lua_pushinteger(L, plr->ringdelay); + else if (fastcmp(field,"ringboost")) + lua_pushinteger(L, plr->ringboost); + else if (fastcmp(field,"sparkleanim")) + lua_pushinteger(L, plr->sparkleanim); + else if (fastcmp(field,"superring")) + lua_pushinteger(L, plr->superring); + else if (fastcmp(field,"curshield")) + lua_pushinteger(L, plr->curshield); + else if (fastcmp(field,"bubblecool")) + lua_pushinteger(L, plr->bubblecool); + else if (fastcmp(field,"bubbleblowup")) + lua_pushinteger(L, plr->bubbleblowup); + else if (fastcmp(field,"flamedash")) + lua_pushinteger(L, plr->flamedash); + else if (fastcmp(field,"flamemeter")) + lua_pushinteger(L, plr->flamemeter); + else if (fastcmp(field,"flamelength")) + lua_pushinteger(L, plr->flamelength); + else if (fastcmp(field,"hyudorotimer")) + lua_pushinteger(L, plr->hyudorotimer); + else if (fastcmp(field,"stealingtimer")) + lua_pushinteger(L, plr->stealingtimer); + else if (fastcmp(field,"sneakertimer")) + lua_pushinteger(L, plr->sneakertimer); + else if (fastcmp(field,"numsneakers")) + lua_pushinteger(L, plr->numsneakers); + else if (fastcmp(field,"floorboost")) + lua_pushinteger(L, plr->floorboost); + else if (fastcmp(field,"growshrinktimer")) + lua_pushinteger(L, plr->growshrinktimer); + else if (fastcmp(field,"rocketsneakertimer")) + lua_pushinteger(L, plr->rocketsneakertimer); + else if (fastcmp(field,"invincibilitytimer")) + lua_pushinteger(L, plr->invincibilitytimer); + else if (fastcmp(field,"eggmanexplode")) + lua_pushinteger(L, plr->eggmanexplode); + else if (fastcmp(field,"eggmanblame")) + lua_pushinteger(L, plr->eggmanblame); + else if (fastcmp(field,"bananadrag")) + lua_pushinteger(L, plr->bananadrag); + else if (fastcmp(field,"lastjawztarget")) + lua_pushinteger(L, plr->lastjawztarget); + else if (fastcmp(field,"jawztargetdelay")) + lua_pushinteger(L, plr->jawztargetdelay); else if (fastcmp(field,"glanceDir")) lua_pushinteger(L, plr->glanceDir); else if (fastcmp(field,"trickpanel")) lua_pushinteger(L, plr->trickpanel); - else if (fastcmp(field,"trickdelay")) - lua_pushinteger(L, plr->trickdelay); - else if (fastcmp(field,"trickmomx")) - lua_pushfixed(L, plr->trickmomx); - else if (fastcmp(field,"trickmomy")) - lua_pushfixed(L, plr->trickmomy); - else if (fastcmp(field,"trickmomz")) - lua_pushfixed(L, plr->trickmomz); + else if (fastcmp(field,"tricktime")) + lua_pushinteger(L, plr->tricktime); + else if (fastcmp(field,"trickboostpower")) + lua_pushfixed(L, plr->trickboostpower); + else if (fastcmp(field,"trickboostdecay")) + lua_pushinteger(L, plr->trickboostdecay); + else if (fastcmp(field,"trickboost")) + lua_pushinteger(L, plr->trickboost); + else if (fastcmp(field,"roundscore")) + plr->roundscore = luaL_checkinteger(L, 3); + else if (fastcmp(field,"emeralds")) + lua_pushinteger(L, plr->emeralds); + else if (fastcmp(field,"bumpers")) + lua_pushinteger(L, plr->bumpers); + else if (fastcmp(field,"karmadelay")) + lua_pushinteger(L, plr->karmadelay); + else if (fastcmp(field,"spheres")) + lua_pushinteger(L, plr->spheres); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) @@ -280,36 +410,16 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->followmobj, META_MOBJ); else if (fastcmp(field,"lives")) lua_pushinteger(L, plr->lives); - else if (fastcmp(field,"lostlife")) - lua_pushboolean(L, plr->lostlife); - else if (fastcmp(field,"continues")) - lua_pushinteger(L, plr->continues); else if (fastcmp(field,"xtralife")) lua_pushinteger(L, plr->xtralife); - else if (fastcmp(field,"gotcontinue")) - lua_pushinteger(L, plr->gotcontinue); else if (fastcmp(field,"speed")) lua_pushfixed(L, plr->speed); - else if (fastcmp(field,"secondjump")) - lua_pushinteger(L, plr->secondjump); - else if (fastcmp(field,"fly1")) - lua_pushinteger(L, plr->fly1); - else if (fastcmp(field,"scoreadd")) - lua_pushinteger(L, plr->scoreadd); - else if (fastcmp(field,"glidetime")) - lua_pushinteger(L, plr->glidetime); - else if (fastcmp(field,"climbing")) - lua_pushinteger(L, plr->climbing); + else if (fastcmp(field,"lastspeed")) + lua_pushfixed(L, plr->lastspeed); else if (fastcmp(field,"deadtimer")) lua_pushinteger(L, plr->deadtimer); else if (fastcmp(field,"exiting")) lua_pushinteger(L, plr->exiting); - else if (fastcmp(field,"homing")) - lua_pushinteger(L, plr->homing); - else if (fastcmp(field,"dashmode")) - lua_pushinteger(L, plr->dashmode); - else if (fastcmp(field,"skidtime")) - lua_pushinteger(L, plr->skidtime); else if (fastcmp(field,"cmomx")) lua_pushfixed(L, plr->cmomx); else if (fastcmp(field,"cmomy")) @@ -318,8 +428,6 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->rmomx); else if (fastcmp(field,"rmomy")) lua_pushfixed(L, plr->rmomy); - else if (fastcmp(field,"numboxes")) - lua_pushinteger(L, plr->numboxes); else if (fastcmp(field,"totalring")) lua_pushinteger(L, plr->totalring); else if (fastcmp(field,"realtime")) @@ -328,98 +436,14 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->laps); else if (fastcmp(field,"ctfteam")) lua_pushinteger(L, plr->ctfteam); - else if (fastcmp(field,"gotflag")) - lua_pushinteger(L, plr->gotflag); - else if (fastcmp(field,"weapondelay")) - lua_pushinteger(L, plr->weapondelay); - else if (fastcmp(field,"tossdelay")) - lua_pushinteger(L, plr->tossdelay); + else if (fastcmp(field,"checkskip")) + lua_pushinteger(L, plr->checkskip); else if (fastcmp(field,"starpostnum")) lua_pushinteger(L, plr->starpostnum); - else if (fastcmp(field,"angle_pos")) - lua_pushangle(L, plr->angle_pos); - else if (fastcmp(field,"old_angle_pos")) - lua_pushangle(L, plr->old_angle_pos); - else if (fastcmp(field,"axis1")) - LUA_PushUserdata(L, plr->axis1, META_MOBJ); - else if (fastcmp(field,"axis2")) - LUA_PushUserdata(L, plr->axis2, META_MOBJ); - else if (fastcmp(field,"bumpertime")) - lua_pushinteger(L, plr->bumpertime); - else if (fastcmp(field,"flyangle")) - lua_pushinteger(L, plr->flyangle); - else if (fastcmp(field,"drilltimer")) - lua_pushinteger(L, plr->drilltimer); - else if (fastcmp(field,"linkcount")) - lua_pushinteger(L, plr->linkcount); - else if (fastcmp(field,"linktimer")) - lua_pushinteger(L, plr->linktimer); - else if (fastcmp(field,"anotherflyangle")) - lua_pushinteger(L, plr->anotherflyangle); - else if (fastcmp(field,"nightstime")) - lua_pushinteger(L, plr->nightstime); - else if (fastcmp(field,"drillmeter")) - lua_pushinteger(L, plr->drillmeter); - else if (fastcmp(field,"drilldelay")) - lua_pushinteger(L, plr->drilldelay); - else if (fastcmp(field,"bonustime")) - lua_pushboolean(L, plr->bonustime); - else if (fastcmp(field,"capsule")) - LUA_PushUserdata(L, plr->capsule, META_MOBJ); - else if (fastcmp(field,"drone")) - LUA_PushUserdata(L, plr->drone, META_MOBJ); - else if (fastcmp(field,"oldscale")) - lua_pushfixed(L, plr->oldscale); - else if (fastcmp(field,"mare")) - lua_pushinteger(L, plr->mare); - else if (fastcmp(field,"marelap")) - lua_pushinteger(L, plr->marelap); - else if (fastcmp(field,"marebonuslap")) - lua_pushinteger(L, plr->marebonuslap); - else if (fastcmp(field,"marebegunat")) - lua_pushinteger(L, plr->marebegunat); - else if (fastcmp(field,"startedtime")) - lua_pushinteger(L, plr->startedtime); - else if (fastcmp(field,"finishedtime")) - lua_pushinteger(L, plr->finishedtime); - else if (fastcmp(field,"lapbegunat")) - lua_pushinteger(L, plr->lapbegunat); - else if (fastcmp(field,"lapstartedtime")) - lua_pushinteger(L, plr->lapstartedtime); - else if (fastcmp(field,"finishedspheres")) - lua_pushinteger(L, plr->finishedspheres); - else if (fastcmp(field,"finishedrings")) - lua_pushinteger(L, plr->finishedrings); - else if (fastcmp(field,"marescore")) - lua_pushinteger(L, plr->marescore); - else if (fastcmp(field,"lastmarescore")) - lua_pushinteger(L, plr->lastmarescore); - else if (fastcmp(field,"totalmarescore")) - lua_pushinteger(L, plr->totalmarescore); - else if (fastcmp(field,"lastmare")) - lua_pushinteger(L, plr->lastmare); - else if (fastcmp(field,"lastmarelap")) - lua_pushinteger(L, plr->lastmarelap); - else if (fastcmp(field,"lastmarebonuslap")) - lua_pushinteger(L, plr->lastmarebonuslap); - else if (fastcmp(field,"totalmarelap")) - lua_pushinteger(L, plr->totalmarelap); - else if (fastcmp(field,"totalmarebonuslap")) - lua_pushinteger(L, plr->totalmarebonuslap); - else if (fastcmp(field,"maxlink")) - lua_pushinteger(L, plr->maxlink); - else if (fastcmp(field,"texttimer")) - lua_pushinteger(L, plr->texttimer); - else if (fastcmp(field,"textvar")) - lua_pushinteger(L, plr->textvar); else if (fastcmp(field,"lastsidehit")) lua_pushinteger(L, plr->lastsidehit); else if (fastcmp(field,"lastlinehit")) lua_pushinteger(L, plr->lastlinehit); - else if (fastcmp(field,"losstime")) - lua_pushinteger(L, plr->losstime); - else if (fastcmp(field,"timeshit")) - lua_pushinteger(L, plr->timeshit); else if (fastcmp(field,"onconveyor")) lua_pushinteger(L, plr->onconveyor); else if (fastcmp(field,"awayviewmobj")) @@ -509,23 +533,17 @@ static int player_set(lua_State *L) } else if (fastcmp(field,"drawangle")) plr->drawangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"rings")) - plr->rings = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"spheres")) - plr->spheres = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"powers")) - return NOSET; else if (fastcmp(field,"pflags")) plr->pflags = luaL_checkinteger(L, 3); else if (fastcmp(field,"panim")) plr->panim = luaL_checkinteger(L, 3); else if (fastcmp(field,"flashcount")) - plr->flashcount = (UINT16)luaL_checkinteger(L, 3); + plr->flashcount = luaL_checkinteger(L, 3); else if (fastcmp(field,"flashpal")) - plr->flashpal = (UINT16)luaL_checkinteger(L, 3); + plr->flashpal = luaL_checkinteger(L, 3); else if (fastcmp(field,"skincolor")) { - UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); + UINT16 newcolor = luaL_checkinteger(L,3); if (newcolor >= numskincolors) return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); plr->skincolor = newcolor; @@ -535,40 +553,174 @@ static int player_set(lua_State *L) else if (fastcmp(field,"availabilities")) return NOSET; else if (fastcmp(field,"score")) - plr->score = (UINT32)luaL_checkinteger(L, 3); + plr->score = luaL_checkinteger(L, 3); // SRB2kart - else if (fastcmp(field,"kartstuff")) + else if (fastcmp(field,"nocontrol")) + plr->nocontrol = luaL_checkinteger(L, 3); + else if (fastcmp(field,"carry")) + plr->carry = luaL_checkinteger(L, 3); + else if (fastcmp(field,"dye")) + plr->dye = luaL_checkinteger(L, 3); + else if (fastcmp(field,"position")) + plr->position = luaL_checkinteger(L, 3); + else if (fastcmp(field,"oldposition")) + plr->oldposition = luaL_checkinteger(L, 3); + else if (fastcmp(field,"positiondelay")) + plr->positiondelay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"distancetofinish")) return NOSET; else if (fastcmp(field,"airtime")) - plr->airtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"driftInput")) - plr->driftInput = luaL_checkboolean(L, 3); - else if (fastcmp(field,"airFailsafe")) - plr->airFailsafe = luaL_checkboolean(L, 3); + plr->airtime = luaL_checkinteger(L, 3); + else if (fastcmp(field,"flashing")) + plr->flashing = luaL_checkinteger(L, 3); + else if (fastcmp(field,"spinouttimer")) + plr->spinouttimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"instashield")) + plr->instashield = luaL_checkinteger(L, 3); + else if (fastcmp(field,"wipeoutslow")) + plr->wipeoutslow = luaL_checkinteger(L, 3); + else if (fastcmp(field,"justbumped")) + plr->justbumped = luaL_checkinteger(L, 3); else if (fastcmp(field,"tumbleBounces")) - plr->tumbleBounces = (UINT8)luaL_checkinteger(L, 3); + plr->tumbleBounces = luaL_checkinteger(L, 3); else if (fastcmp(field,"tumbleHeight")) - plr->tumbleHeight = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"tumbleLastBounce")) - plr->tumbleLastBounce = luaL_checkboolean(L, 3); - else if (fastcmp(field,"tumbleSound")) - plr->tumbleSound = luaL_checkboolean(L, 3); + plr->tumbleHeight = luaL_checkinteger(L, 3); + else if (fastcmp(field,"drift")) + plr->drift = luaL_checkinteger(L, 3); + else if (fastcmp(field,"driftcharge")) + plr->driftcharge = luaL_checkinteger(L, 3); + else if (fastcmp(field,"driftboost")) + plr->driftboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"aizdriftstraft")) + plr->aizdriftstrat = luaL_checkinteger(L, 3); + else if (fastcmp(field,"aizdrifttilt")) + plr->aizdrifttilt = luaL_checkinteger(L, 3); + else if (fastcmp(field,"aizdriftturn")) + plr->aizdriftturn = luaL_checkinteger(L, 3); + else if (fastcmp(field,"offroad")) + plr->offroad = luaL_checkinteger(L, 3); + else if (fastcmp(field,"waterskip")) + plr->waterskip = luaL_checkinteger(L, 3); + else if (fastcmp(field,"tiregrease")) + plr->tiregrease = luaL_checkinteger(L, 3); + else if (fastcmp(field,"springstars")) + plr->springstars = luaL_checkinteger(L, 3); + else if (fastcmp(field,"springcolor")) + plr->springcolor = luaL_checkinteger(L, 3); + else if (fastcmp(field,"dashpadcooldown")) + plr->dashpadcooldown = luaL_checkinteger(L, 3); + else if (fastcmp(field,"spindash")) + plr->spindash = luaL_checkinteger(L, 3); + else if (fastcmp(field,"spindashspeed")) + plr->spindashspeed = luaL_checkinteger(L, 3); + else if (fastcmp(field,"spindashboost")) + plr->spindashboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"numboosts")) + plr->numboosts = luaL_checkinteger(L, 3); + else if (fastcmp(field,"boostpower")) + plr->boostpower = luaL_checkinteger(L, 3); + else if (fastcmp(field,"speedboost")) + plr->speedboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"accelboost")) + plr->accelboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"handleboost")) + plr->handleboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"boostangle")) + plr->boostangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"draftpower")) + plr->draftpower = luaL_checkinteger(L, 3); + else if (fastcmp(field,"draftleeway")) + plr->draftleeway = luaL_checkinteger(L, 3); + else if (fastcmp(field,"lastdraft")) + plr->lastdraft = luaL_checkinteger(L, 3); + else if (fastcmp(field,"itemroulette")) + plr->itemroulette = luaL_checkinteger(L, 3); + else if (fastcmp(field,"roulettetype")) + plr->roulettetype = luaL_checkinteger(L, 3); + else if (fastcmp(field,"itemtype")) + plr->itemtype = luaL_checkinteger(L, 3); + else if (fastcmp(field,"itemamount")) + plr->itemamount = luaL_checkinteger(L, 3); + else if (fastcmp(field,"throwdir")) + plr->throwdir = luaL_checkinteger(L, 3); + else if (fastcmp(field,"sadtimer")) + plr->sadtimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rings")) + plr->rings = luaL_checkinteger(L, 3); + else if (fastcmp(field,"pickuprings")) + plr->pickuprings = luaL_checkinteger(L, 3); + else if (fastcmp(field,"ringdelay")) + plr->ringdelay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"ringboost")) + plr->ringboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"sparkleanim")) + plr->sparkleanim = luaL_checkinteger(L, 3); + else if (fastcmp(field,"superring")) + plr->superring = luaL_checkinteger(L, 3); + else if (fastcmp(field,"curshield")) + plr->curshield = luaL_checkinteger(L, 3); + else if (fastcmp(field,"bubblecool")) + plr->bubblecool = luaL_checkinteger(L, 3); + else if (fastcmp(field,"bubbleblowup")) + plr->bubbleblowup = luaL_checkinteger(L, 3); + else if (fastcmp(field,"flamedash")) + plr->flamedash = luaL_checkinteger(L, 3); + else if (fastcmp(field,"flamemeter")) + plr->flamemeter = luaL_checkinteger(L, 3); + else if (fastcmp(field,"flamelength")) + plr->flamelength = luaL_checkinteger(L, 3); + else if (fastcmp(field,"hyudorotimer")) + plr->hyudorotimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"stealingtimer")) + plr->stealingtimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"sneakertimer")) + plr->sneakertimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"numsneakers")) + plr->numsneakers = luaL_checkinteger(L, 3); + else if (fastcmp(field,"floorboost")) + plr->floorboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"growshrinktimer")) + plr->growshrinktimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rocketsneakertimer")) + plr->rocketsneakertimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"invincibilitytimer")) + plr->invincibilitytimer = luaL_checkinteger(L, 3); + else if (fastcmp(field,"eggmanexplode")) + plr->eggmanexplode = luaL_checkinteger(L, 3); + else if (fastcmp(field,"eggmanblame")) + plr->eggmanblame = luaL_checkinteger(L, 3); + else if (fastcmp(field,"bananadrag")) + plr->bananadrag = luaL_checkinteger(L, 3); + else if (fastcmp(field,"lastjawztarget")) + plr->lastjawztarget = luaL_checkinteger(L, 3); + else if (fastcmp(field,"jawztargetdelay")) + plr->jawztargetdelay = luaL_checkinteger(L, 3); else if (fastcmp(field,"glanceDir")) - plr->glanceDir = (SINT8)luaL_checkinteger(L, 3); + plr->glanceDir = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickpanel")) plr->trickpanel = luaL_checkinteger(L, 3); - else if (fastcmp(field,"trickdelay")) - plr->trickdelay = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"trickmomx")) - plr->trickmomx = (fixed_t)luaL_checkfixed(L, 3); - else if (fastcmp(field,"trickmomy")) - plr->trickmomy = (fixed_t)luaL_checkfixed(L, 3); - else if (fastcmp(field,"trickmomz")) - plr->trickmomz = (fixed_t)luaL_checkfixed(L, 3); + else if (fastcmp(field,"tricktime")) + plr->tricktime = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickboostpower")) + plr->trickboostpower = luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickboostdecay")) + plr->trickboostdecay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickboost")) + plr->trickboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"roundscore")) + lua_pushinteger(L, plr->roundscore); + else if (fastcmp(field,"emeralds")) + plr->emeralds = luaL_checkinteger(L, 3); + else if (fastcmp(field,"bumpers")) + plr->bumpers = luaL_checkinteger(L, 3); + else if (fastcmp(field,"karmadelay")) + plr->karmadelay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"spheres")) + plr->spheres = luaL_checkinteger(L, 3); else if (fastcmp(field,"kartspeed")) - plr->kartspeed = (UINT8)luaL_checkinteger(L, 3); + plr->kartspeed = luaL_checkinteger(L, 3); else if (fastcmp(field,"kartweight")) - plr->kartweight = (UINT8)luaL_checkinteger(L, 3); + plr->kartweight = luaL_checkinteger(L, 3); else if (fastcmp(field,"followerskin")) plr->followerskin = luaL_checkinteger(L, 3); else if (fastcmp(field,"followercolor")) @@ -591,36 +743,16 @@ static int player_set(lua_State *L) } else if (fastcmp(field,"lives")) plr->lives = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lostlife")) - plr->lostlife = luaL_checkboolean(L, 3); - else if (fastcmp(field,"continues")) - plr->continues = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"xtralife")) plr->xtralife = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"gotcontinue")) - plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"speed")) plr->speed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"secondjump")) - plr->secondjump = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"fly1")) - plr->fly1 = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"scoreadd")) - plr->scoreadd = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"glidetime")) - plr->glidetime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"climbing")) - plr->climbing = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lastspeed")) + plr->lastspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"deadtimer")) plr->deadtimer = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"exiting")) plr->exiting = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"homing")) - plr->homing = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"dashmode")) - plr->dashmode = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"skidtime")) - plr->skidtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"cmomx")) plr->cmomx = luaL_checkfixed(L, 3); else if (fastcmp(field,"cmomy")) @@ -629,8 +761,6 @@ static int player_set(lua_State *L) plr->rmomx = luaL_checkfixed(L, 3); else if (fastcmp(field,"rmomy")) plr->rmomy = luaL_checkfixed(L, 3); - else if (fastcmp(field,"numboxes")) - plr->numboxes = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"totalring")) plr->totalring = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"realtime")) @@ -639,118 +769,14 @@ static int player_set(lua_State *L) plr->laps = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"ctfteam")) plr->ctfteam = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"gotflag")) - plr->gotflag = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"weapondelay")) - plr->weapondelay = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"tossdelay")) - plr->tossdelay = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"checkskip")) + plr->checkskip = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"starpostnum")) plr->starpostnum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"angle_pos")) - plr->angle_pos = luaL_checkangle(L, 3); - else if (fastcmp(field,"old_angle_pos")) - plr->old_angle_pos = luaL_checkangle(L, 3); - else if (fastcmp(field,"axis1")) - { - mobj_t *mo = NULL; - if (!lua_isnil(L, 3)) - mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - P_SetTarget(&plr->axis1, mo); - } - else if (fastcmp(field,"axis2")) - { - mobj_t *mo = NULL; - if (!lua_isnil(L, 3)) - mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - P_SetTarget(&plr->axis2, mo); - } - else if (fastcmp(field,"bumpertime")) - plr->bumpertime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"flyangle")) - plr->flyangle = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drilltimer")) - plr->drilltimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"linkcount")) - plr->linkcount = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"linktimer")) - plr->linktimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"anotherflyangle")) - plr->anotherflyangle = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"nightstime")) - plr->nightstime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drillmeter")) - plr->drillmeter = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drilldelay")) - plr->drilldelay = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"bonustime")) - plr->bonustime = luaL_checkboolean(L, 3); - else if (fastcmp(field,"capsule")) - { - mobj_t *mo = NULL; - if (!lua_isnil(L, 3)) - mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - P_SetTarget(&plr->capsule, mo); - } - else if (fastcmp(field,"drone")) - { - mobj_t *mo = NULL; - if (!lua_isnil(L, 3)) - mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - P_SetTarget(&plr->drone, mo); - } - else if (fastcmp(field,"oldscale")) - plr->oldscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"mare")) - plr->mare = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marelap")) - plr->marelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marebonuslap")) - plr->marebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marebegunat")) - plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"startedtime")) - plr->startedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedtime")) - plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lapbegunat")) - plr->lapbegunat = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lapstartedtime")) - plr->lapstartedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedspheres")) - plr->finishedspheres = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedrings")) - plr->finishedrings = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marescore")) - plr->marescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarescore")) - plr->lastmarescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarescore")) - plr->totalmarescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmare")) - plr->lastmare = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarelap")) - plr->lastmarelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarebonuslap")) - plr->lastmarebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarelap")) - plr->totalmarelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarebonuslap")) - plr->totalmarebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"maxlink")) - plr->maxlink = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"texttimer")) - plr->texttimer = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"textvar")) - plr->textvar = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastsidehit")) plr->lastsidehit = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastlinehit")) plr->lastlinehit = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"losstime")) - plr->losstime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"timeshit")) - plr->timeshit = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"onconveyor")) plr->onconveyor = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"awayviewmobj")) @@ -813,74 +839,6 @@ static int player_num(lua_State *L) return 1; } -// powers, p -> powers[p] -static int power_get(lua_State *L) -{ - UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS)); - powertype_t p = luaL_checkinteger(L, 2); - if (p >= NUMPOWERS) - return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p); - lua_pushinteger(L, powers[p]); - return 1; -} - -// powers, p, value -> powers[p] = value -static int power_set(lua_State *L) -{ - UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS)); - powertype_t p = luaL_checkinteger(L, 2); - UINT16 i = (UINT16)luaL_checkinteger(L, 3); - if (p >= NUMPOWERS) - return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)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 CMD building code!"); - powers[p] = i; - return 0; -} - -// #powers -> NUMPOWERS -static int power_len(lua_State *L) -{ - lua_pushinteger(L, NUMPOWERS); - return 1; -} - -// kartstuff, ks -> kartstuff[ks] -static int kartstuff_get(lua_State *L) -{ - INT32 *kartstuff = *((INT32 **)luaL_checkudata(L, 1, META_KARTSTUFF)); - kartstufftype_t ks = luaL_checkinteger(L, 2); - if (ks >= NUMKARTSTUFF) - return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks); - lua_pushinteger(L, kartstuff[ks]); - return 1; -} - -// kartstuff, ks, value -> kartstuff[ks] = value -static int kartstuff_set(lua_State *L) -{ - INT32 *kartstuff = *((INT32 **)luaL_checkudata(L, 1, META_KARTSTUFF)); - kartstufftype_t ks = luaL_checkinteger(L, 2); - INT32 i = (INT32)luaL_checkinteger(L, 3); - if (ks >= NUMKARTSTUFF) - 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; -} - -// #karthud -> NUMKARTSTUFF -static int kartstuff_len(lua_State *L) -{ - lua_pushinteger(L, NUMKARTSTUFF); - return 1; -} - // karthud, ks -> karthud[ks] static int karthud_get(lua_State *L) { @@ -892,7 +850,7 @@ static int karthud_get(lua_State *L) return 1; } -// karthud, ks, value -> kartstuff[ks] = value +// karthud, ks, value -> karthud[ks] = value static int karthud_set(lua_State *L) { INT32 *karthud = *((INT32 **)luaL_checkudata(L, 1, META_KARTHUD)); @@ -1063,28 +1021,6 @@ int LUA_PlayerLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); - luaL_newmetatable(L, META_POWERS); - lua_pushcfunction(L, power_get); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, power_set); - lua_setfield(L, -2, "__newindex"); - - lua_pushcfunction(L, power_len); - lua_setfield(L, -2, "__len"); - lua_pop(L,1); - - luaL_newmetatable(L, META_KARTSTUFF); - lua_pushcfunction(L, kartstuff_get); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, kartstuff_set); - lua_setfield(L, -2, "__newindex"); - - lua_pushcfunction(L, kartstuff_len); - lua_setfield(L, -2, "__len"); - lua_pop(L,1); - luaL_newmetatable(L, META_KARTHUD); lua_pushcfunction(L, karthud_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_script.c b/src/lua_script.c index 4d02ee413..94ba64767 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -178,7 +178,7 @@ int LUA_PushGlobals(lua_State *L, const char *word) lua_pushboolean(L, modeattacking); return 1; } else if (fastcmp(word,"splitscreen")) { - lua_pushboolean(L, splitscreen); + lua_pushinteger(L, splitscreen); return 1; } else if (fastcmp(word,"gamecomplete")) { lua_pushboolean(L, (gamecomplete != 0)); @@ -945,8 +945,7 @@ void LUA_InvalidatePlayer(player_t *player) if (!gL) return; LUA_InvalidateUserdata(player); - LUA_InvalidateUserdata(player->powers); - LUA_InvalidateUserdata(player->kartstuff); + LUA_InvalidateUserdata(player->karthud); LUA_InvalidateUserdata(&player->cmd); } diff --git a/src/m_cheat.c b/src/m_cheat.c index cc9552117..b45a7cbb6 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -317,20 +317,6 @@ void Command_CheatGod_f(void) G_SetGameModified(multiplayer, true); } -void Command_CheatNoTarget_f(void) -{ - player_t *plyr; - - REQUIRE_INLEVEL; - REQUIRE_SINGLEPLAYER; - - plyr = &players[consoleplayer]; - 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, true); -} - void Command_Scale_f(void) { const double scaled = atof(COM_Argv(1)); @@ -1147,7 +1133,7 @@ void OP_ObjectplaceMovement(player_t *player) mt = OP_CreateNewMapThing(player, (UINT16)spawnthing, ceiling); if (mt->type >= 600 && mt->type <= 609) // Placement patterns - P_SpawnItemPattern(mt, false); + P_SpawnItemPattern(mt); else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops P_SpawnHoop(mt); else @@ -1291,6 +1277,6 @@ void Command_ObjectPlace_f(void) players[0].mo->color = op_oldcolor; // This is necessary for recovery of dying players. - players[0].powers[pw_flashing] = K_GetKartFlashing(&players[0]); + players[0].flashing = K_GetKartFlashing(&players[0]); } } diff --git a/src/m_cheat.h b/src/m_cheat.h index de34d8a41..ec1a129cf 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -45,7 +45,6 @@ void OP_ObjectplaceMovement(player_t *player); // void Command_CheatNoClip_f(void); void Command_CheatGod_f(void); -void Command_CheatNoTarget_f(void); void Command_Savecheckpoint_f(void); void Command_Setrings_f(void); void Command_Setlives_f(void); diff --git a/src/p_enemy.c b/src/p_enemy.c index 8ef33a38e..9f5fc86d8 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -105,13 +105,8 @@ void A_Scream(mobj_t *actor); void A_Pain(mobj_t *actor); void A_Explode(mobj_t *actor); void A_BossDeath(mobj_t *actor); -void A_CustomPower(mobj_t *actor); void A_RingBox(mobj_t *actor); -void A_Invincibility(mobj_t *actor); -void A_SuperSneakers(mobj_t *actor); void A_AwardScore(mobj_t *actor); -void A_GiveShield(mobj_t *actor); -void A_GravityBox(mobj_t *actor); void A_ScoreRise(mobj_t *actor); void A_BunnyHop(mobj_t *actor); void A_BubbleSpawn(mobj_t *actor); @@ -326,6 +321,7 @@ void A_ReaperThinker(mobj_t *actor); void A_MementosTPParticles(mobj_t *actor); void A_FlameShieldPaper(mobj_t *actor); void A_InvincSparkleRotate(mobj_t *actor); +void A_SpawnItemCapsuleParts(mobj_t *actor); //for p_enemy.c @@ -742,9 +738,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if ((netgame || multiplayer) && player->spectator) continue; - if (player->pflags & PF_INVIS) - continue; // ignore notarget - if (!player->mo || P_MobjWasRemoved(player->mo)) continue; @@ -3442,7 +3435,7 @@ void A_BossDeath(mobj_t *mo) // make sure there is a player alive for victory for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && ((players[i].mo && players[i].mo->health) - || ((netgame || multiplayer) && (players[i].lives || players[i].continues)))) + || ((netgame || multiplayer) && players[i].lives))) break; if (i == MAXPLAYERS) @@ -3729,48 +3722,6 @@ bossjustdie: } } -// Function: A_CustomPower -// -// Description: Provides a custom powerup. Target (must be a player) is awarded the powerup. Reactiontime of the object is used as an index to the powers array. -// -// var1 = Power index # -// var2 = Power duration in tics -// -void A_CustomPower(mobj_t *actor) -{ - player_t *player; - INT32 locvar1 = var1; - INT32 locvar2 = var2; - boolean spawnshield = false; - - if (LUA_CallAction(A_CUSTOMPOWER, actor)) - return; - - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - if (locvar1 >= NUMPOWERS) - { - CONS_Debug(DBG_GAMELOGIC, "Power #%d out of range!\n", locvar1); - return; - } - - player = actor->target->player; - - if (locvar1 == pw_shield && player->powers[pw_shield] != locvar2) - spawnshield = true; - - player->powers[locvar1] = (UINT16)locvar2; - if (actor->info->seesound) - S_StartSound(player->mo, actor->info->seesound); - - if (spawnshield) //workaround for a bug - P_SpawnShieldOrb(player); -} - // Function: A_RingBox // // Description: Awards the player 10 rings. @@ -3798,70 +3749,6 @@ void A_RingBox(mobj_t *actor) S_StartSound(player->mo, actor->info->seesound); } -// Function: A_Invincibility -// -// Description: Awards the player invincibility. -// -// var1 = unused -// var2 = unused -// -void A_Invincibility(mobj_t *actor) -{ - player_t *player; - - if (LUA_CallAction(A_INVINCIBILITY, actor)) - return; - - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - player->powers[pw_invulnerability] = invulntics + 1; - - if (P_IsLocalPlayer(player) && !player->powers[pw_super]) - { - P_PlayJingle(player, JT_INV); - strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); - S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); - } -} - -// Function: A_SuperSneakers -// -// Description: Awards the player super sneakers. -// -// var1 = unused -// var2 = unused -// -void A_SuperSneakers(mobj_t *actor) -{ - player_t *player; - - if (LUA_CallAction(A_SUPERSNEAKERS, actor)) - return; - - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - actor->target->player->powers[pw_sneakers] = sneakertics + 1; - - if (P_IsLocalPlayer(player) && !player->powers[pw_super]) - { - if (S_SpeedMusic(0.0f)) - S_SpeedMusic(1.4f); - strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12); - S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]); - } -} - // Function: A_AwardScore // // Description: Adds a set amount of points to the player's score. @@ -3889,60 +3776,6 @@ void A_AwardScore(mobj_t *actor) S_StartSound(player->mo, actor->info->seesound); } -// Function: A_GiveShield -// -// Description: Awards the player a specified shield. -// -// var1 = Shield type (make with SH_ constants) -// var2 = unused -// -void A_GiveShield(mobj_t *actor) -{ - player_t *player; - UINT16 locvar1 = var1; - - if (LUA_CallAction(A_GIVESHIELD, actor)) - return; - - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, locvar1); - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_GravityBox -// -// Description: Awards the player gravity boots. -// -// var1 = unused -// var2 = unused -// -void A_GravityBox(mobj_t *actor) -{ - player_t *player; - - if (LUA_CallAction(A_GRAVITYBOX, actor)) - return; - - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - S_StartSound(player, actor->info->activesound); - - player->powers[pw_gravityboots] = (UINT16)(actor->info->reactiontime + 1); -} - // Function: A_ScoreRise // // Description: Makes the little score logos rise. Speed value sets speed. @@ -4173,13 +4006,13 @@ void A_AttractChase(mobj_t *actor) angle_t offset = FixedAngle(18<target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player, true) + 3; + actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3; S_StartSound(actor->target, sfx_s1b5); sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS); P_SetTarget(&sparkle->target, actor->target); - sparkle->angle = (actor->target->angle + (offset>>1)) + (offset * actor->target->player->kartstuff[k_sparkleanim]); - actor->target->player->kartstuff[k_sparkleanim] = (actor->target->player->kartstuff[k_sparkleanim]+1) % 20; + sparkle->angle = (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim); + actor->target->player->sparkleanim = (actor->target->player->sparkleanim+1) % 20; P_KillMobj(actor, actor->target, actor->target, DMG_NORMAL); return; @@ -4201,14 +4034,14 @@ void A_AttractChase(mobj_t *actor) if (actor->extravalue1 >= 16) { if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed - actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player, true) + 3; + actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3; if (actor->cvmem) // caching S_StartSound(actor->target, sfx_s1c5); else S_StartSound(actor->target, sfx_s227); - actor->target->player->kartstuff[k_pickuprings]--; + actor->target->player->pickuprings--; P_RemoveMobj(actor); return; } @@ -4257,9 +4090,9 @@ void A_AttractChase(mobj_t *actor) if (actor->tracer && actor->tracer->player && actor->tracer->health //&& P_CheckSight(actor, actor->tracer) - && actor->tracer->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD + && actor->tracer->player->itemtype == KITEM_THUNDERSHIELD && RINGTOTAL(actor->tracer->player) < 20 - && !actor->tracer->player->kartstuff[k_ringlock]) + && !(actor->tracer->player->pflags & PF_RINGLOCK)) { fixed_t dist; angle_t hang, vang; @@ -5852,7 +5685,7 @@ void A_MixUp(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE - && !players[i].exiting && !players[i].powers[pw_super]) + && !players[i].exiting) { if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators continue; @@ -5877,8 +5710,8 @@ void A_MixUp(mobj_t *actor) players[two].speed = transspeed; //set flags variables now but DON'T set them. - carry1 = players[one].powers[pw_carry]; - carry2 = players[two].powers[pw_carry]; + carry1 = players[one].carry; + carry2 = players[two].carry; x = players[one].mo->x; y = players[one].mo->y; @@ -5904,8 +5737,8 @@ void A_MixUp(mobj_t *actor) //carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for... //but not all of it! So we need to make sure they aren't set wrong or anything. - players[one].powers[pw_carry] = carry2; - players[two].powers[pw_carry] = carry1; + players[one].carry = carry2; + players[two].carry = carry1; teleported[one] = true; teleported[two] = true; @@ -5952,7 +5785,7 @@ void A_MixUp(mobj_t *actor) players[i].rmomx = players[i].rmomy = 1; players[i].cmomx = players[i].cmomy = 0; - transcarry[counter] = players[i].powers[pw_carry]; + transcarry[counter] = players[i].carry; transspeed[counter] = players[i].speed; transtracer[counter] = players[i].mo->tracer; @@ -6003,7 +5836,7 @@ void A_MixUp(mobj_t *actor) FRACUNIT, anglepos[teleportfrom][1], flags2[teleportfrom]); //...carry after. same reasoning. - players[i].powers[pw_carry] = transcarry[teleportfrom]; + players[i].carry = transcarry[teleportfrom]; teleported[i] = true; counter++; @@ -6555,7 +6388,7 @@ void A_Boss2PogoTarget(mobj_t *actor) if (LUA_CallAction(A_BOSS2POGOTARGET, actor)) return; - if (!actor->target || !(actor->target->flags & MF_SHOOTABLE) || (actor->target->player && actor->target->player->powers[pw_flashing]) + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE) || (actor->target->player && actor->target->player->flashing) || P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) >= FixedMul(512*FRACUNIT, actor->scale)) { // look for a new target @@ -6568,7 +6401,7 @@ void A_Boss2PogoTarget(mobj_t *actor) } // Target hit, retreat! - if ((actor->target->player && actor->target->player->powers[pw_flashing] > TICRATE) || actor->flags2 & MF2_FRET) + if ((actor->target->player && actor->target->player->flashing > TICRATE) || actor->flags2 & MF2_FRET) { UINT8 prandom = P_RandomByte(); actor->z++; // unstick from the floor @@ -6759,8 +6592,7 @@ void A_SparkFollow(mobj_t *actor) if (LUA_CallAction(A_SPARKFOLLOW, actor)) return; - if ((!actor->target || (actor->target->health <= 0)) - || (actor->target->player && !actor->target->player->powers[pw_super])) + if (!actor->target || (actor->target->health <= 0)) { P_RemoveMobj(actor); return; @@ -7697,7 +7529,7 @@ void A_FindTarget(mobj_t *actor) if (mo2->type == (mobjtype_t)locvar1) { - if (mo2->player && (mo2->player->spectator || mo2->player->pflags & PF_INVIS)) + if (mo2->player && mo2->player->spectator) continue; // Ignore spectators if ((mo2->player || mo2->flags & MF_ENEMY) && mo2->health <= 0) continue; // Ignore dead things @@ -7761,7 +7593,7 @@ void A_FindTracer(mobj_t *actor) if (mo2->type == (mobjtype_t)locvar1) { - if (mo2->player && (mo2->player->spectator || mo2->player->pflags & PF_INVIS)) + if (mo2->player && mo2->player->spectator) continue; // Ignore spectators if ((mo2->player || mo2->flags & MF_ENEMY) && mo2->health <= 0) continue; // Ignore dead things @@ -7903,7 +7735,7 @@ void A_Dye(mobj_t *actor) // What if it's a player? if (target->player) - target->player->powers[pw_dye] = color; + target->player->dye = color; if (!color) { @@ -9599,7 +9431,7 @@ void A_ForceWin(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && ((players[i].mo && players[i].mo->health) - || ((netgame || multiplayer) && (players[i].lives || players[i].continues)))) + || ((netgame || multiplayer) && players[i].lives))) break; } @@ -11213,7 +11045,7 @@ void A_FadeOverlay(mobj_t *actor) return; fade = P_SpawnGhostMobj(actor); - fade->frame = actor->frame; + fade->renderflags = actor->renderflags; if (!(locvar1 & 1)) { @@ -11790,7 +11622,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (players[i].mo->health <= 0) continue; - if (players[i].powers[pw_flashing]) + if (players[i].flashing) continue; if (actor->tracer == players[i].mo) // this was your tracer last time continue; @@ -11849,7 +11681,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (players[i].mo->health <= 0) continue; - if (players[i].powers[pw_flashing]) + if (players[i].flashing) continue; if (actor->tracer == players[i].mo) // this was your tracer last time continue; @@ -13474,7 +13306,7 @@ void A_ItemPop(mobj_t *actor) S_StartSound(remains, actor->info->deathsound); if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0)) - actor->target->player->kartstuff[k_itemroulette] = 1; + actor->target->player->itemroulette = 1; remains->flags2 &= ~MF2_AMBUSH; @@ -13797,9 +13629,9 @@ void A_SPBChase(mobj_t *actor) if (players[i].respawn.state != RESPAWNST_NONE) continue;*/ // respawning - if (players[i].kartstuff[k_position] < bestrank) + if (players[i].position < bestrank) { - bestrank = players[i].kartstuff[k_position]; + bestrank = players[i].position; player = &players[i]; } } @@ -13832,7 +13664,7 @@ void A_SPBChase(mobj_t *actor) fixed_t easiness = ((actor->tracer->player->kartspeed + (10-spark)) << FRACBITS) / 2; actor->lastlook = actor->tracer->player-players; // Save the player num for death scumming... - actor->tracer->player->kartstuff[k_ringlock] = 1; // set ring lock + actor->tracer->player->pflags |= PF_RINGLOCK; // set ring lock if (!P_IsObjectOnGround(actor->tracer)) { @@ -13850,12 +13682,12 @@ void A_SPBChase(mobj_t *actor) cy = actor->tracer->player->cmomy; // Switch targets if you're no longer 1st for long enough - if (actor->tracer->player->kartstuff[k_position] <= bestrank) + if (actor->tracer->player->position <= bestrank) actor->extravalue2 = 7*TICRATE; else if (actor->extravalue2-- <= 0) actor->extravalue1 = 0; // back to SEEKING - spbplace = actor->tracer->player->kartstuff[k_position]; + spbplace = actor->tracer->player->position; } dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z); @@ -13867,7 +13699,7 @@ void A_SPBChase(mobj_t *actor) wspeed = (3*defspeed)/2; if (wspeed < 20*actor->tracer->scale) wspeed = 20*actor->tracer->scale; - if (actor->tracer->player->pflags & PF_SLIDING) + if (actor->tracer->player->carry == CR_SLIDING) wspeed = actor->tracer->player->speed/2; // ^^^^ current section: These are annoying, and grand metropolis in particular needs this. @@ -13945,8 +13777,8 @@ void A_SPBChase(mobj_t *actor) && !players[actor->lastlook].spectator && !players[actor->lastlook].exiting) { - spbplace = players[actor->lastlook].kartstuff[k_position]; - players[actor->lastlook].kartstuff[k_ringlock] = 1; + spbplace = players[actor->lastlook].position; + players[actor->lastlook].pflags |= PF_RINGLOCK; if (actor->extravalue2-- <= 0 && players[actor->lastlook].mo) { P_SetTarget(&actor->tracer, players[actor->lastlook].mo); @@ -14175,7 +14007,7 @@ static inline boolean PIT_SSMineSearch(mobj_t *thing) if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner. return true; - if (thing->player && (thing->player->kartstuff[k_hyudorotimer] + if (thing->player && (thing->player->hyudorotimer || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay))) return true; @@ -14417,10 +14249,10 @@ void A_RandomShadowFrame(mobj_t *actor) // I have NO CLUE how to hardcode all of that fancy Linedef Executor shit so the fire spinout will be done by these entities directly. if (P_LookForPlayers(actor, false, false, 380<target && !actor->target->player->powers[pw_flashing] - && !actor->target->player->kartstuff[k_invincibilitytimer] - && !actor->target->player->kartstuff[k_growshrinktimer] - && !actor->target->player->kartstuff[k_spinouttimer] + if (actor->target && !actor->target->player->flashing + && !actor->target->player->invincibilitytimer + && !actor->target->player->growshrinktimer + && !actor->target->player->spinouttimer && P_IsObjectOnGround(actor->target) && actor->z == actor->target->z) { @@ -14462,10 +14294,10 @@ void A_RoamingShadowThinker(mobj_t *actor) if (P_LookForPlayers(actor, false, false, 256<target && !actor->target->player->powers[pw_flashing] - && !actor->target->player->kartstuff[k_invincibilitytimer] - && !actor->target->player->kartstuff[k_growshrinktimer] - && !actor->target->player->kartstuff[k_spinouttimer]) + if (actor->target && !actor->target->player->flashing + && !actor->target->player->invincibilitytimer + && !actor->target->player->growshrinktimer + && !actor->target->player->spinouttimer) { // send them flying and spawn the WIND! P_InstaThrust(actor->target, 0, 0); @@ -14703,10 +14535,10 @@ void A_ReaperThinker(mobj_t *actor) { if (P_LookForPlayers(actor, false, false, 1024<target == targetplayermo && actor->target && !actor->target->player->powers[pw_flashing] - && !actor->target->player->kartstuff[k_invincibilitytimer] - && !actor->target->player->kartstuff[k_growshrinktimer] - && !actor->target->player->kartstuff[k_spinouttimer])) + if (!(actor->target == targetplayermo && actor->target && !actor->target->player->flashing + && !actor->target->player->invincibilitytimer + && !actor->target->player->growshrinktimer + && !actor->target->player->spinouttimer)) P_SetTarget(&actor->target, actor->hnext); // if the above isn't correct, then we should go back to targetting waypoints or something. } @@ -14819,4 +14651,192 @@ void A_InvincSparkleRotate(mobj_t *actor) actor->momz = actor->target->momz; // Give momentum for eventual interp builds idk. actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose. -} \ No newline at end of file +} + +void P_RefreshItemCapsuleParts(mobj_t *mobj) +{ + UINT8 numNumbers = 0; + INT32 count = 0; + INT32 itemType = mobj->threshold; + mobj_t *part; + skincolornum_t color; + UINT32 newRenderFlags = 0; + boolean colorized; + + if (itemType < 1 || itemType >= NUMKARTITEMS) + itemType = KITEM_SAD; + + // update invincibility properties + if (itemType == KITEM_INVINCIBILITY) + { + mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_FULLBRIGHT; + mobj->colorized = true; + } + else + { + mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_SEMIBRIGHT; + mobj->color = SKINCOLOR_NONE; + mobj->colorized = false; + } + + // update cap colors + if (itemType == KITEM_SUPERRING) + { + color = SKINCOLOR_GOLD; + newRenderFlags |= RF_SEMIBRIGHT; + } + else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA)) + color = SKINCOLOR_SAPPHIRE; + else if (itemType == KITEM_SPB) + color = SKINCOLOR_JET; + else + color = SKINCOLOR_NONE; + + colorized = (color != SKINCOLOR_NONE); + part = mobj; + while (!P_MobjWasRemoved(part->hnext)) + { + part = part->hnext; + part->color = color; + part->colorized = colorized; + part->renderflags = (part->renderflags & ~RF_BRIGHTMASK) | newRenderFlags; + } + + // update inside item frame + part = mobj->tracer; + if (P_MobjWasRemoved(part)) + return; + + part->threshold = mobj->threshold; + part->movecount = mobj->movecount; + + switch (itemType) + { + case KITEM_ORBINAUT: + part->sprite = SPR_ITMO; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount); + break; + case KITEM_INVINCIBILITY: + part->sprite = SPR_ITMI; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame(); + break; + case KITEM_SAD: + part->sprite = SPR_ITEM; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE; + break; + default: + part->sprite = SPR_ITEM; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(itemType); + break; + } + + // update number frame + if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number + ; + else + { + switch (itemType) + { + case KITEM_ORBINAUT: // only display the number when the sprite no longer changes + if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount)) + count = mobj->movecount; + break; + case KITEM_SUPERRING: // always display the number, and multiply it by 5 + count = mobj->movecount * 5; + break; + case KITEM_SAD: // never display the number + case KITEM_SPB: + break; + default: + if (mobj->movecount > 1) + count = mobj->movecount; + break; + } + } + + while (count > 0) + { + if (P_MobjWasRemoved(part->tracer)) + { + P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY)); + P_SetTarget(&part->tracer->target, part); + P_SetMobjState(part->tracer, S_INVISIBLE); + part->tracer->spriteyoffset = 10*FRACUNIT; + part->tracer->spritexoffset = 13*numNumbers*FRACUNIT; + } + part = part->tracer; + part->sprite = SPR_ITMN; + part->frame = FF_FULLBRIGHT|(count % 10); + count /= 10; + numNumbers++; + } + + // delete any extra overlays (I guess in case the number changes?) + if (part->tracer) + { + P_RemoveMobj(part->tracer); + P_SetTarget(&part->tracer, NULL); + } +} + +#define CAPSULESIDES 5 +#define ANG_CAPSULE (UINT32_MAX / CAPSULESIDES) +#define ROTATIONSPEED (2*ANG2) +void A_SpawnItemCapsuleParts(mobj_t *actor) +{ + UINT8 i; + mobj_t *part; + fixed_t buttScale = 0; + statenum_t buttState = S_ITEMCAPSULE_BOTTOM_SIDE_AIR; + angle_t spin = ANGLE_MAX - ROTATIONSPEED; + + if (LUA_CallAction(A_SPAWNITEMCAPSULEPARTS, actor)) + return; + + if (P_IsObjectOnGround(actor)) + { + buttScale = 13*FRACUNIT/10; + buttState = S_ITEMCAPSULE_BOTTOM_SIDE_GROUND; + spin = 0; + } + + // inside item + part = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART); + P_SetTarget(&part->target, actor); + P_SetMobjState(part, S_ITEMICON); + part->movedir = ROTATIONSPEED; // rotation speed + part->extravalue1 = 175*FRACUNIT/100; // relative scale + part->flags2 |= MF2_CLASSICPUSH; // classicpush = centered horizontally + P_SetTarget(&actor->tracer, part); // pointer to this item, so we can modify its sprite/frame + + // capsule caps + part = actor; + for (i = 0; i < CAPSULESIDES; i++) + { + // a bottom side + P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART)); + P_SetTarget(&part->hnext->hprev, part); + part = part->hnext; + P_SetTarget(&part->target, actor); + P_SetMobjState(part, buttState); + part->angle = i * ANG_CAPSULE; + part->movedir = spin; // rotation speed + part->movefactor = 0; // z offset + part->extravalue1 = buttScale; // relative scale + + // a top side + P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART)); + P_SetTarget(&part->hnext->hprev, part); + part = part->hnext; + P_SetTarget(&part->target, actor); + P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE); + part->angle = i * ANG_CAPSULE; + part->movedir = spin; // rotation speed + part->movefactor = actor->info->height - part->info->height; // z offset + } + + P_RefreshItemCapsuleParts(actor); +} +#undef CAPSULESIDES +#undef ANG_CAPSULE +#undef ROTATIONSPEED diff --git a/src/p_floor.c b/src/p_floor.c index a427eabb0..7fdf01ebb 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1555,7 +1555,7 @@ void T_RaiseSector(raise_t *raise) continue; // Option to require spindashing. - if (raise->flags & RF_SPINDASH && !(thing->player->pflags & PF_STARTDASH)) + if ((raise->flags & RF_SPINDASH) && !thing->player->spindash) continue; if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector))) diff --git a/src/p_inter.c b/src/p_inter.c index 5077ef366..e5df84913 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -108,7 +108,7 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End) // boolean P_CanPickupItem(player_t *player, UINT8 weapon) { - if (player->exiting || mapreset || player->eliminated) + if (player->exiting || mapreset || (player->pflags & PF_ELIMINATED)) return false; #ifndef OTHERKARMAMODES @@ -122,29 +122,29 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (weapon == 2) { // Invulnerable - if (player->powers[pw_flashing] > 0) + if (player->flashing > 0) return false; // Already have fake - if (player->kartstuff[k_roulettetype] == 2 - || player->kartstuff[k_eggmanexplode]) + if (player->roulettetype == 2 + || player->eggmanexplode) return false; } else { // Item-specific timer going off - if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] - || player->kartstuff[k_rocketsneakertimer] - || player->kartstuff[k_eggmanexplode]) + if (player->stealingtimer + || player->rocketsneakertimer + || player->eggmanexplode) return false; // Item slot already taken up - if (player->kartstuff[k_itemroulette] - || (weapon != 3 && player->kartstuff[k_itemamount]) - || player->kartstuff[k_itemheld]) + if (player->itemroulette + || (weapon != 3 && player->itemamount) + || (player->pflags & PF_ITEMOUT)) return false; - if (weapon == 3 && K_GetShieldFromItem(player->kartstuff[k_itemtype]) != KSHIELD_NONE) + if (weapon == 3 && K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE) return false; // No stacking shields! } } @@ -243,16 +243,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_InstaThrust(player->mo, player->mo->angle, 20<kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) + if (!P_CanPickupItem(player, 3) || (player->itemamount && player->itemtype != special->threshold)) return; if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return; - player->kartstuff[k_itemtype] = special->threshold; - player->kartstuff[k_itemamount] += special->movecount; - if (player->kartstuff[k_itemamount] > 255) - player->kartstuff[k_itemamount] = 255; + player->itemtype = special->threshold; + if ((UINT16)(player->itemamount) + special->movecount > 255) + player->itemamount = 255; + else + player->itemamount += special->movecount; S_StartSound(special, special->info->deathsound); @@ -269,19 +270,39 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) { -#ifdef OTHERKARMAMODES - if (player->kartstuff[k_comebackmode] || player->karmadelay) - return; - player->kartstuff[k_comebackmode] = 1; -#else return; -#endif } special->momx = special->momy = special->momz = 0; P_SetTarget(&special->target, toucher); P_KillMobj(special, toucher, toucher, DMG_NORMAL); break; + case MT_ITEMCAPSULE: + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) + return; + + if (special->scale < special->extravalue1) // don't break it while it's respawning + return; + + switch (special->threshold) + { + case KITEM_SPB: + if (K_IsSPBInGame()) // don't spawn a second SPB + return; + break; + case KITEM_SUPERRING: + if (player->pflags & PF_RINGLOCK) // no cheaty rings + return; + break; + default: + if (!P_CanPickupItem(player, 1)) + return; + break; + } + + S_StartSound(toucher, special->info->deathsound); + P_KillMobj(special, toucher, toucher, DMG_NORMAL); + return; case MT_KARMAHITBOX: if (!special->target->player) return; @@ -298,113 +319,30 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->karmadelay > 0) return; -#ifdef OTHERKARMAMODES - if (!special->target->player->kartstuff[k_comebackmode]) { -#endif + mobj_t *boom; + + if (P_DamageMobj(toucher, special, special->target, 1, DMG_KARMA) == false) { - mobj_t *boom; - - if (P_DamageMobj(toucher, special, special->target, 1, DMG_KARMA) == false) - { - return; - } - - boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); - - boom->scale = special->target->scale; - boom->destscale = special->target->scale; - boom->momz = 5*FRACUNIT; - - if (special->target->color) - boom->color = special->target->color; - else - boom->color = SKINCOLOR_KETCHUP; - - S_StartSound(boom, special->info->attacksound); - - special->target->player->karthud[khud_yougotem] = 2*TICRATE; - special->target->player->karmadelay = comebacktime; - } -#ifdef OTHERKARMAMODES - } - else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1)) - { - mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE); - S_StartSound(poof, special->info->seesound); - - // Karma fireworks - for (i = 0; i < 5; i++) - { - mobj_t *firework = P_SpawnMobj(special->x, special->y, special->z, MT_KARMAFIREWORK); - firework->momx = (special->target->momx + toucher->momx) / 2; - firework->momy = (special->target->momy + toucher->momy) / 2; - firework->momz = (special->target->momz + toucher->momz) / 2; - P_Thrust(firework, FixedAngle((72*i)<scale); - P_SetObjectMomZ(firework, P_RandomRange(1,8)*special->scale, false); - firework->color = special->target->color; + return; } - special->target->player->kartstuff[k_comebackmode] = 0; - special->target->player->kartstuff[k_comebackpoints]++; + boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); - if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player, 1); - special->target->player->karmadelay = comebacktime; + boom->scale = special->target->scale; + boom->destscale = special->target->scale; + boom->momz = 5*FRACUNIT; - player->kartstuff[k_itemroulette] = 1; - player->kartstuff[k_roulettetype] = 1; - } - else if (special->target->player->kartstuff[k_comebackmode] == 2 && P_CanPickupItem(player, 2)) - { - mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE); - UINT8 ptadd = 1; // No WANTED bonus for tricking - - S_StartSound(poof, special->info->seesound); - - if (player->bumpers == 1) // If you have only one bumper left, and see if it's a 1v1 - { - INT32 numingame = 0; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].bumpers <= 0) - continue; - numingame++; - } - - if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a fake kill - ptadd++; - } - - special->target->player->kartstuff[k_comebackmode] = 0; - special->target->player->kartstuff[k_comebackpoints] += ptadd; - - if (ptadd > 1) - special->target->player->karthud[khud_yougotem] = 2*TICRATE; - - if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player, 1); - - special->target->player->karmadelay = comebacktime; - - K_DropItems(player); //K_StripItems(player); - //K_StripOther(player); - - player->kartstuff[k_itemroulette] = 1; - player->kartstuff[k_roulettetype] = 2; - - if (special->target->player->kartstuff[k_eggmanblame] >= 0 - && special->target->player->kartstuff[k_eggmanblame] < MAXPLAYERS - && playeringame[special->target->player->kartstuff[k_eggmanblame]] - && !players[special->target->player->kartstuff[k_eggmanblame]].spectator) - player->kartstuff[k_eggmanblame] = special->target->player->kartstuff[k_eggmanblame]; + if (special->target->color) + boom->color = special->target->color; else - player->kartstuff[k_eggmanblame] = -1; + boom->color = SKINCOLOR_KETCHUP; - special->target->player->kartstuff[k_eggmanblame] = -1; + S_StartSound(boom, special->info->attacksound); + + special->target->player->karthud[khud_yougotem] = 2*TICRATE; + special->target->player->karmadelay = comebacktime; } -#endif return; case MT_SPB: if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0)) @@ -420,7 +358,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *spbexplode; - if (player->kartstuff[k_bubbleblowup] > 0) + if (player->bubbleblowup > 0) { K_DropHnextList(player, false); special->extravalue1 = 2; // WAIT... @@ -452,7 +390,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (toucher->hitlag > 0) return; - player->powers[pw_emeralds] |= special->extravalue1; + player->emeralds |= special->extravalue1; K_CheckEmeralds(player); break; /* @@ -472,16 +410,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // kill - if (player->kartstuff[k_invincibilitytimer] > 0 - || player->kartstuff[k_growshrinktimer] > 0 - || player->kartstuff[k_flamedash] > 0) + if (player->invincibilitytimer > 0 + || player->growshrinktimer > 0 + || player->flamedash > 0) { P_KillMobj(special, toucher, toucher, DMG_NORMAL); return; } // no interaction - if (player->powers[pw_flashing] > 0 || player->kartstuff[k_hyudorotimer] > 0 || P_PlayerInPain(player)) + if (player->flashing > 0 || player->hyudorotimer > 0 || P_PlayerInPain(player)) return; // attach to player! @@ -492,8 +430,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; - player->kartstuff[k_itemroulette] = 1; - player->kartstuff[k_roulettetype] = 1; + player->itemroulette = 1; + player->roulettetype = 1; // Karma fireworks for (i = 0; i < 5; i++) @@ -545,7 +483,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // No picking up rings while SPB is targetting you - if (player->kartstuff[k_ringlock]) + if (player->pflags & PF_RINGLOCK) return; // Don't immediately pick up spilled rings @@ -564,7 +502,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->extravalue1 = 1; // Ring collect animation timer special->angle = R_PointToAngle2(toucher->x, toucher->y, special->x, special->y); // animation angle P_SetTarget(&special->target, toucher); // toucher for thinker - player->kartstuff[k_pickuprings]++; + player->pickuprings++; return; @@ -599,70 +537,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // CTF Flags case MT_REDFLAG: case MT_BLUEFLAG: - if (player->powers[pw_flashing] || player->tossdelay) - return; - if (!special->spawnpoint) - return; - if (special->fuse == 1) - return; -// if (special->momz > 0) -// return; - { - UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2; - const char *flagtext; - char flagcolor; - char plname[MAXPLAYERNAME+4]; - - if (special->type == MT_REDFLAG) - { - flagtext = M_GetText("Red flag"); - flagcolor = '\x85'; - } - else - { - flagtext = M_GetText("Blue flag"); - flagcolor = '\x84'; - } - snprintf(plname, sizeof(plname), "%s%s%s", - CTFTEAMCODE(player), - player_names[player - players], - CTFTEAMENDCODE(player)); - - if (player->ctfteam == flagteam) // Player is on the same team as the flag - { - // Ignore height, only check x/y for now - // avoids stupid problems with some flags constantly returning - if (special->x>>FRACBITS != special->spawnpoint->x - || special->y>>FRACBITS != special->spawnpoint->y) - { - special->fuse = 1; - special->flags2 |= MF2_JUSTATTACKED; - - if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam, false)) - { - CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); - - // The fuse code plays this sound effect - //if (players[consoleplayer].ctfteam == player->ctfteam) - // S_StartSound(NULL, sfx_hoop1); - } - } - } - else if (player->ctfteam) // Player is on the other team (and not a spectator) - { - UINT16 flagflag = (special->type == MT_REDFLAG) ? GF_REDFLAG : GF_BLUEFLAG; - mobj_t **flagmobj = (special->type == MT_REDFLAG) ? &redflag : &blueflag; - - if (player->powers[pw_super]) - return; - - player->gotflag |= flagflag; - CONS_Printf(M_GetText("%s picked up the %c%s%c!\n"), plname, flagcolor, flagtext, 0x80); - (*flagmobj) = NULL; - // code for dealing with abilities is handled elsewhere now - break; - } - } return; case MT_STARPOST: @@ -721,10 +595,9 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) // Player must have touched all previous starposts if (post->health - player->starpostnum > 1) { - // blatant reuse of a variable that's normally unused in circuit - if (!player->tossdelay) + if (!player->checkskip) S_StartSound(toucher, sfx_lose); - player->tossdelay = 3; + player->checkskip = 3; return; } @@ -883,7 +756,7 @@ void P_CheckPointLimit(void) if (!playeringame[i] || players[i].spectator) continue; - if ((UINT32)cv_pointlimit.value <= players[i].marescore) + if ((UINT32)cv_pointlimit.value <= players[i].roundscore) { for (i = 0; i < MAXPLAYERS; i++) // AAAAA nested loop using the same iteration variable ;; { @@ -929,7 +802,7 @@ boolean P_CheckRacers(void) numplayersingame++; - if (players[i].exiting || (players[i].pflags & PF_GAMETYPEOVER)) + if (players[i].exiting || (players[i].pflags & PF_NOCONTEST)) { numexiting++; } @@ -989,7 +862,7 @@ boolean P_CheckRacers(void) continue; } - if (players[i].exiting || (players[i].pflags & PF_GAMETYPEOVER)) + if (players[i].exiting || (players[i].pflags & PF_NOCONTEST)) { // You're done, you're free to go. continue; @@ -1095,45 +968,43 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; - //K_SetHitLagForObjects(target, inflictor, 15); + //K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true); // SRB2kart // I wish I knew a better way to do this if (target->target && target->target->player && target->target->player->mo) { - if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_EGGMANITEM_SHIELD) - target->target->player->kartstuff[k_eggmanheld] = 0; + if ((target->target->player->pflags & PF_EGGMANOUT) && target->type == MT_EGGMANITEM_SHIELD) + target->target->player->pflags &= ~PF_EGGMANOUT; - if (target->target->player->kartstuff[k_itemheld]) + if (target->target->player->pflags & PF_ITEMOUT) { - if ((target->type == MT_BANANA_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_BANANA) // trail items - || (target->type == MT_SSMINE_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_MINE) - || (target->type == MT_SINK_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_KITCHENSINK)) + if ((target->type == MT_BANANA_SHIELD && target->target->player->itemtype == KITEM_BANANA) // trail items + || (target->type == MT_SSMINE_SHIELD && target->target->player->itemtype == KITEM_MINE) + || (target->type == MT_SINK_SHIELD && target->target->player->itemtype == KITEM_KITCHENSINK)) { - if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->kartstuff[k_itemamount]) + if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->itemamount) { if (target->target->hnext) K_KillBananaChain(target->target->hnext, inflictor, source); - target->target->player->kartstuff[k_itemamount] = 0; + target->target->player->itemamount = 0; } - else - target->target->player->kartstuff[k_itemamount]--; + else if (target->target->player->itemamount) + target->target->player->itemamount--; } - else if ((target->type == MT_ORBINAUT_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) // orbit items - || (target->type == MT_JAWZ_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_JAWZ)) + else if ((target->type == MT_ORBINAUT_SHIELD && target->target->player->itemtype == KITEM_ORBINAUT) // orbit items + || (target->type == MT_JAWZ_SHIELD && target->target->player->itemtype == KITEM_JAWZ)) { - target->target->player->kartstuff[k_itemamount]--; + if (target->target->player->itemamount) + target->target->player->itemamount--; if (target->lastlook != 0) { K_RepairOrbitChain(target); } } - if (target->target->player->kartstuff[k_itemamount] < 0) - target->target->player->kartstuff[k_itemamount] = 0; - - if (!target->target->player->kartstuff[k_itemamount]) - target->target->player->kartstuff[k_itemheld] = 0; + if (!target->target->player->itemamount) + target->target->player->pflags &= ~PF_ITEMOUT; if (target->target->hnext == target) P_SetTarget(&target->target->hnext, NULL); @@ -1158,7 +1029,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget UINT8 i; P_SetTarget(&target->target, source); - source->player->numboxes++; for (i = 0; i < MAXPLAYERS; i++) { @@ -1385,6 +1255,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget kart->angle = target->angle; kart->color = target->color; kart->hitlag = target->hitlag; + kart->eflags |= MFE_DAMAGEHITLAG; P_SetObjectMomZ(kart, 6*FRACUNIT, false); kart->extravalue1 = target->player->kartweight; } @@ -1438,6 +1309,117 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } break; + case MT_ITEMCAPSULE: + { + UINT8 i; + mobj_t *attacker = inflictor ? inflictor : source; + mobj_t *part = target->hnext; + angle_t angle = FixedAngle(360*P_RandomFixed()); + INT16 spacing = (target->radius >> 1) / target->scale; + + // set respawn fuse + if (modeattacking) // no respawns + ; + else if (target->threshold == KITEM_SUPERRING) + target->fuse = 20*TICRATE; + else + target->fuse = 40*TICRATE; + + // burst effects + for (i = 0; i < 2; i++) + { + mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST); + blast->angle = angle + i*ANGLE_90; + P_SetScale(blast, 2*blast->scale/3); + blast->destscale = 2*blast->scale; + } + + // dust effects + for (i = 0; i < 10; i++) + { + mobj_t *puff = P_SpawnMobjFromMobj( + target, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(0, 4*spacing) * FRACUNIT, + MT_SPINDASHDUST + ); + + P_SetScale(puff, (puff->destscale *= 2)); + puff->momz = puff->scale * P_MobjFlip(puff); + + P_Thrust(puff, R_PointToAngle2(target->x, target->y, puff->x, puff->y), 3*puff->scale); + if (attacker) + { + puff->momx += attacker->momx; + puff->momy += attacker->momy; + puff->momz += attacker->momz; + } + } + + // remove inside item + if (target->tracer && !P_MobjWasRemoved(target->tracer)) + P_RemoveMobj(target->tracer); + + // bust capsule caps + while (part && !P_MobjWasRemoved(part)) + { + P_InstaThrust(part, part->angle + ANGLE_90, 6 * part->target->scale); + P_SetObjectMomZ(part, 6 * FRACUNIT, false); + part->fuse = TICRATE/2; + part->flags &= ~MF_NOGRAVITY; + + if (attacker) + { + part->momx += attacker->momx; + part->momy += attacker->momy; + part->momz += attacker->momz; + } + part = part->hnext; + } + + // give the player an item! + if (source && source->player) + { + player_t *player = source->player; + + // special behavior for ring capsules + if (target->threshold == KITEM_SUPERRING) + { + player->superring = min(player->superring + 5*target->movecount*3, UINT16_MAX); + break; + } + + // special behavior for SPB capsules + if (target->threshold == KITEM_SPB) + { + K_ThrowKartItem(player, true, MT_SPB, 1, 0); + break; + } + + if (target->threshold < 1 || target->threshold >= NUMKARTITEMS) // bruh moment prevention + { + player->itemtype = KITEM_SAD; + player->itemamount = 1; + } + else + { + player->itemtype = target->threshold; + if (K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE) // never give more than 1 shield + player->itemamount = 1; + else + player->itemamount = max(1, target->movecount); + } + player->karthud[khud_itemblink] = TICRATE; + player->karthud[khud_itemblinkmode] = 0; + player->itemroulette = 0; + player->roulettetype = 0; + if (P_IsDisplayPlayer(player)) + S_StartSound(NULL, sfx_itrolf); + } + break; + } + case MT_BATTLECAPSULE: { mobj_t *cur; @@ -1763,11 +1745,10 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, break; } - K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); - K_SetHitLagForObjects(player->mo, inflictor, 15); + K_DropEmeraldsFromPlayer(player, player->emeralds); + K_SetHitLagForObjects(player->mo, inflictor, MAXHITLAGTICS, true); - player->pflags &= ~PF_SLIDING; - player->powers[pw_carry] = CR_NONE; + player->carry = CR_NONE; player->mo->color = player->skincolor; player->mo->colorized = false; @@ -1797,7 +1778,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, } K_DestroyBumpers(player, player->bumpers); - player->eliminated = true; + player->pflags |= PF_ELIMINATED; } return true; @@ -1825,7 +1806,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player_t *player; boolean force = false; - INT32 laglength = 10; + INT32 laglength = 6; INT32 kinvextend = 0; if (objectplacing) @@ -1844,7 +1825,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (((damagetype & DMG_TYPEMASK) == DMG_STING) || ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1)) { - laglength = 5; + laglength = 2; } // Everything above here can't be forced. @@ -1922,7 +1903,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (gametyperules & GTR_BUMPERS) { - if ((player->bumpers <= 0 && player->karmadelay) || (player->kartstuff[k_comebackmode] == 1)) + if (player->bumpers <= 0 && player->karmadelay) { // No bumpers & in WAIT, can't be hurt K_DoInstashield(player); @@ -1939,7 +1920,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } - if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0) + if (player->invincibilitytimer > 0 || player->growshrinktimer > 0 || player->hyudorotimer > 0) { // Full invulnerability K_DoInstashield(player); @@ -1948,7 +1929,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (combo == false) { - if (player->powers[pw_flashing] > 0) + if (player->flashing > 0) { // Post-hit invincibility K_DoInstashield(player); @@ -1983,11 +1964,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source != player->mo && source->player) { // Extend the invincibility if the hit was a direct hit. - if (inflictor == source && source->player->kartstuff[k_invincibilitytimer]) + if (inflictor == source && source->player->invincibilitytimer) { - kinvextend = (source->player->kartstuff[k_invincibilitytimer])+5*TICRATE; - //CONS_Printf("extend k_invincibilitytimer for %s - old value %d new value %d\n", player_names[source->player - players], source->player->kartstuff[k_invincibilitytimer]/TICRATE, kinvextend/TICRATE); - source->player->kartstuff[k_invincibilitytimer] = kinvextend; + kinvextend = (source->player->invincibilitytimer)+5*TICRATE; + //CONS_Printf("extend k_invincibilitytimer for %s - old value %d new value %d\n", player_names[source->player - players], source->player->invincibilitytimer/TICRATE, kinvextend/TICRATE); + source->player->invincibilitytimer = kinvextend; } K_PlayHitEmSound(source); @@ -2000,12 +1981,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Destroy any remainder bumpers from the player for karma comeback damage K_DestroyBumpers(player, player->bumpers); } + else + { + source->player->overtimekarma += 5*TICRATE; + } if (damagetype & DMG_STEAL) { // Give them ALL of your emeralds instantly :) - source->player->powers[pw_emeralds] |= player->powers[pw_emeralds]; - player->powers[pw_emeralds] = 0; + source->player->emeralds |= player->emeralds; + player->emeralds = 0; K_CheckEmeralds(source->player); } } @@ -2017,13 +2002,15 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (!(damagetype & DMG_STEAL)) { // Drop all of your emeralds - K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + K_DropEmeraldsFromPlayer(player, player->emeralds); } } - player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; - player->kartstuff[k_driftboost] = 0; - player->kartstuff[k_ringboost] = 0; + player->sneakertimer = player->numsneakers = 0; + player->driftboost = player->strongdriftboost = 0; + player->ringboost = 0; + player->glanceDir = 0; + player->pflags &= ~PF_LOOKDOWN; switch (type) { @@ -2054,7 +2041,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (type != DMG_STING) { - player->powers[pw_flashing] = K_GetKartFlashing(player); + player->flashing = K_GetKartFlashing(player); } P_PlayRinglossSound(player->mo); @@ -2075,8 +2062,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_DropHnextList(player, false); } - player->kartstuff[k_instashield] = 15; - K_SetHitLagForObjects(target, inflictor, laglength); + player->instashield = 15; + K_SetHitLagForObjects(target, inflictor, laglength, true); return true; } } @@ -2098,7 +2085,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source->player && target) G_GhostAddHit((INT32) (source->player - players), target); - K_SetHitLagForObjects(target, inflictor, laglength); + K_SetHitLagForObjects(target, inflictor, laglength, true); if (target->health <= 0) { @@ -2106,7 +2093,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } - //K_SetHitLagForObjects(target, inflictor, laglength); + //K_SetHitLagForObjects(target, inflictor, laglength, true); if (player) P_ResetPlayer(target->player); @@ -2193,7 +2180,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) return; // Have a shield? You get hit, but don't lose your rings! - if (K_GetShieldFromItem(player->kartstuff[k_itemtype]) != KSHIELD_NONE) + if (K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE) return; // 20 is the maximum number of rings that can be taken from you at once - half the span of your counter diff --git a/src/p_local.h b/src/p_local.h index 7c71c7ebf..f97f31810 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -169,8 +169,6 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); boolean P_EndingMusic(player_t *player); -void P_SpawnShieldOrb(player_t *player); -void P_SwitchShield(player_t *player, UINT16 shieldtype); mobj_t *P_SpawnGhostMobj(mobj_t *mobj); INT32 P_GivePlayerRings(player_t *player, INT32 num_rings); void P_GivePlayerSpheres(player_t *player, INT32 num_spheres); @@ -178,11 +176,6 @@ void P_GivePlayerLives(player_t *player, INT32 numlives); UINT8 P_GetNextEmerald(void); void P_GiveEmerald(boolean spawnObj); void P_GiveFinishFlags(player_t *player); -#if 0 -void P_ResetScore(player_t *player); -#else -#define P_ResetScore(player) player->scoreadd = 0 -#endif boolean P_AutoPause(void); void P_ElementalFire(player_t *player, boolean cropcircle); @@ -287,7 +280,6 @@ boolean P_MobjWasRemoved(mobj_t *th); void P_RemoveSavegameMobj(mobj_t *th); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); -void P_RunShields(void); void P_RunOverlays(void); void P_HandleMinecartSegments(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj); @@ -373,6 +365,8 @@ void P_InternalFlickyBubble(mobj_t *actor); void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez); void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle); +void P_RefreshItemCapsuleParts(mobj_t *mobj); + // // P_MAP // @@ -404,6 +398,7 @@ void P_SetThingPosition(mobj_t *thing); void P_SetUnderlayPosition(mobj_t *thing); boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing); +boolean P_IsLineTripWire(const line_t *ld); boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y); boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); diff --git a/src/p_map.c b/src/p_map.c index ab4f13b82..42fa89b73 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -206,11 +206,14 @@ static void add_spechit(line_t *ld) numspechit++; } -static boolean P_SpecialIsLinedefCrossType(UINT16 ldspecial) +static boolean P_SpecialIsLinedefCrossType(line_t *ld) { boolean linedefcrossspecial = false; - switch (ldspecial) + if (P_IsLineTripWire(ld)) + return true; + + switch (ld->special) { case 2001: // Finish line case 2003: // Respawn line @@ -345,28 +348,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } } - if (object->player) - { - // Less friction when hitting horizontal springs - if (!vertispeed) - { - if (!object->player->kartstuff[k_tiregrease]) - { - UINT8 i; - for (i = 0; i < 2; i++) - { - mobj_t *grease; - grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); - P_SetTarget(&grease->target, object); - grease->angle = K_MomentumAngle(object); - grease->extravalue1 = i; - } - } - - object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS - } - } - // Horizontal speed is used as a minimum thrust, not a direct replacement finalSpeed = max(objectSpeed, finalSpeed); @@ -387,8 +368,24 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_ResetPlayer(object->player); - object->player->kartstuff[k_springstars] = max(vertispeed, horizspeed) / FRACUNIT / 2; - object->player->kartstuff[k_springcolor] = starcolor; + object->player->springstars = max(vertispeed, horizspeed) / FRACUNIT / 2; + object->player->springcolor = starcolor; + + // Less friction when hitting springs + if (!object->player->tiregrease) + { + UINT8 i; + for (i = 0; i < 2; i++) + { + mobj_t *grease; + grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); + P_SetTarget(&grease->target, object); + grease->angle = K_MomentumAngle(object); + grease->extravalue1 = i; + } + + object->player->tiregrease = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS + } } return true; @@ -427,8 +424,6 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) break; if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother break; - if (p && (p->climbing || p->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities! - break; object->momz += flipval*FixedMul(speed/4, spring->scale); @@ -450,7 +445,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (object->player) { object->player->trickpanel = 1; - object->player->trickdelay = 1; + object->player->pflags |= PF_TRICKDELAY; } K_DoPogoSpring(object, 32<player && thing->player->spectator)) return true; + // Ignore the collision if BOTH things are in hitlag. + if (thing->hitlag > 0 && tmthing->hitlag > 0) + return true; + if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING))) return true; @@ -699,8 +698,8 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // Bubble Shield reflect - if (((thing->type == MT_BUBBLESHIELD && thing->target->player && thing->target->player->kartstuff[k_bubbleblowup]) - || (thing->player && thing->player->kartstuff[k_bubbleblowup])) + if (((thing->type == MT_BUBBLESHIELD && thing->target->player && thing->target->player->bubbleblowup) + || (thing->player && thing->player->bubbleblowup)) && (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD || tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG || tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK @@ -724,8 +723,8 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetTarget(&tmthing, oldtmthing);*/ if (P_PlayerInPain(tmthing->player) - || tmthing->player->powers[pw_flashing] || tmthing->player->kartstuff[k_hyudorotimer] - || tmthing->player->kartstuff[k_justbumped] || tmthing->scale > thing->scale + (mapobjectscale/8)) + || tmthing->player->flashing || tmthing->player->hyudorotimer + || tmthing->player->justbumped || tmthing->scale > thing->scale + (mapobjectscale/8)) return true; // Player Damage @@ -757,8 +756,8 @@ static boolean PIT_CheckThing(mobj_t *thing) // no interaction return true; } - else if (((tmthing->type == MT_BUBBLESHIELD && tmthing->target->player && tmthing->target->player->kartstuff[k_bubbleblowup]) - || (tmthing->player && tmthing->player->kartstuff[k_bubbleblowup])) + else if (((tmthing->type == MT_BUBBLESHIELD && tmthing->target->player && tmthing->target->player->bubbleblowup) + || (tmthing->player && tmthing->player->bubbleblowup)) && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD || thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG || thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK @@ -782,8 +781,8 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetTarget(&tmthing, oldtmthing);*/ if (P_PlayerInPain(thing->player) - || thing->player->powers[pw_flashing] || thing->player->kartstuff[k_hyudorotimer] - || thing->player->kartstuff[k_justbumped] || thing->scale > tmthing->scale + (mapobjectscale/8)) + || thing->player->flashing || thing->player->hyudorotimer + || thing->player->justbumped || thing->scale > tmthing->scale + (mapobjectscale/8)) return true; // Player Damage @@ -1237,7 +1236,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->player->kartstuff[k_hyudorotimer] || tmthing->player->kartstuff[k_hyudorotimer]) + if (thing->player->hyudorotimer || tmthing->player->hyudorotimer) { return true; } @@ -1249,33 +1248,19 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } + // The bump has to happen last + if (P_IsObjectOnGround(thing) && tmthing->momz < 0 && tmthing->player->trickpanel) { - // The bump has to happen last - mobj_t *mo1 = tmthing; - mobj_t *mo2 = thing; - boolean zbounce = false; + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); + } + else if (P_IsObjectOnGround(tmthing) && thing->momz < 0 && thing->player->trickpanel) + { + P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); + } - if (P_IsObjectOnGround(thing) && tmthing->momz < 0) - { - zbounce = true; - mo1 = thing; - mo2 = tmthing; - - if (tmthing->player->trickpanel) - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); - } - else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) - { - zbounce = true; - - if (thing->player->trickpanel) - P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); - } - - if (K_KartBouncing(mo1, mo2, zbounce, false)) - { - K_PvPTouchDamage(mo1, mo2); - } + if (K_KartBouncing(tmthing, thing) == true) + { + K_PvPTouchDamage(tmthing, thing); } return true; @@ -1291,8 +1276,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (!thing->health) return true; // dead - if (tmthing->player->kartstuff[k_invincibilitytimer] > 0 - || tmthing->player->kartstuff[k_growshrinktimer] > 0) + if (tmthing->player->invincibilitytimer > 0 + || tmthing->player->growshrinktimer > 0) { if (thing->type == MT_BLUEROBRA_JOINT) P_KillMobj(thing->target, tmthing, tmthing, DMG_NORMAL); @@ -1302,8 +1287,8 @@ static boolean PIT_CheckThing(mobj_t *thing) } else { - K_KartBouncing(tmthing, thing, false, true); - return false; + K_KartSolidBounce(tmthing, thing); + return true; } } else if (thing->type == MT_SMK_PIPE) @@ -1317,15 +1302,15 @@ static boolean PIT_CheckThing(mobj_t *thing) if (!thing->health) return true; // dead - if (tmthing->player->kartstuff[k_invincibilitytimer] > 0 - || tmthing->player->kartstuff[k_growshrinktimer] > 0) + if (tmthing->player->invincibilitytimer > 0 + || tmthing->player->growshrinktimer > 0) { P_KillMobj(thing, tmthing, tmthing, DMG_NORMAL); return true; // kill } - K_KartBouncing(tmthing, thing, false, true); - return false; + K_KartSolidBounce(tmthing, thing); + return true; } else if (thing->type == MT_SMK_THWOMP) { @@ -1348,15 +1333,15 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // underneath // kill - if (tmthing->player->kartstuff[k_invincibilitytimer] > 0 - || tmthing->player->kartstuff[k_growshrinktimer] > 0) + if (tmthing->player->invincibilitytimer > 0 + || tmthing->player->growshrinktimer > 0) { P_KillMobj(thing, tmthing, tmthing, DMG_NORMAL); return true; } // no interaction - if (tmthing->player->powers[pw_flashing] > 0 || tmthing->player->kartstuff[k_hyudorotimer] > 0 || tmthing->player->kartstuff[k_spinouttimer] > 0) + if (tmthing->player->flashing > 0 || tmthing->player->hyudorotimer > 0 || tmthing->player->spinouttimer > 0) return true; // collide @@ -1364,12 +1349,13 @@ static boolean PIT_CheckThing(mobj_t *thing) P_DamageMobj(tmthing, thing, thing, 1, DMG_TUMBLE); else { - if (thing->flags2 & MF2_AMBUSH) + if ((K_KartSolidBounce(tmthing, thing) == true) && (thing->flags2 & MF2_AMBUSH)) + { P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT); - K_KartBouncing(tmthing, thing, false, true); + } } - return false; + return true; } else if (thing->type == MT_KART_LEFTOVER) { @@ -1379,12 +1365,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (P_IsObjectOnGround(thing) && tmthing->momz < 0) - K_KartBouncing(tmthing, thing, true, false); - else - K_KartBouncing(tmthing, thing, false, false); - - return false; + K_KartBouncing(tmthing, thing); + return true; } else if (thing->flags & MF_SOLID) { @@ -1394,12 +1376,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (P_IsObjectOnGround(thing) && tmthing->momz < 0) - K_KartBouncing(tmthing, thing, true, true); - else - K_KartBouncing(tmthing, thing, false, true); - - return false; + K_KartSolidBounce(tmthing, thing); + return true; } } @@ -1577,6 +1555,11 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) } } +boolean P_IsLineTripWire(const line_t *ld) +{ + return ld->tripwire; +} + // // PIT_CheckLine // Adjusts tmfloorz and tmceilingz as lines are contacted @@ -1691,7 +1674,7 @@ static boolean PIT_CheckLine(line_t *ld) tmdropoffz = lowfloor; // we've crossed the line - if (P_SpecialIsLinedefCrossType(ld->special)) + if (P_SpecialIsLinedefCrossType(ld)) { add_spechit(ld); } @@ -2252,7 +2235,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) #ifndef NOCLIPCAM if ((players[displayplayers[i]].pflags & PF_NOCLIP) || (leveltime < introtime)) // Noclipping player camera noclips too!! #else - if (!(players[displayplayers[i]].pflags & PF_GAMETYPEOVER)) // Time Over should not clip through walls + if (!(players[displayplayers[i]].pflags & PF_NOCONTEST)) // Time Over should not clip through walls #endif { floatok = true; @@ -2419,6 +2402,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t radius = thing->radius; fixed_t thingtop; fixed_t startingonground = P_IsObjectOnGround(thing); + fixed_t stairjank = 0; + pslope_t *oldslope = thing->standingslope; floatok = false; // reset this to 0 at the start of each trymove call as it's only used here @@ -2429,11 +2414,13 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (radius < mapobjectscale) radius = mapobjectscale; +#if 0 if (thing->hitlag > 0) { // Do not move during hitlag return false; } +#endif do { if (thing->flags & MF_NOCLIP) { @@ -2466,7 +2453,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); fixed_t maxstep = maxstepmove; - if (thing->player && thing->player->kartstuff[k_waterskip]) + if (thing->player && thing->player->waterskip) maxstep += maxstepmove; // Add some extra stepmove when waterskipping // If using type Section1:13, double the maxstep. @@ -2490,6 +2477,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (maxstep > 0) { + const boolean flipped = + (thing->eflags & MFE_VERTICALFLIP) != 0; + thingtop = thing->z + thing->height; // Step up @@ -2497,6 +2487,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { if (tmfloorstep <= maxstep) { + if (!flipped) + stairjank = tmfloorstep; + thing->z = thing->floorz = tmfloorz; thing->floorrover = tmfloorrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2510,6 +2503,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { if (tmceilingstep <= maxstep) { + if (flipped) + stairjank = tmceilingstep; + thing->z = ( thing->ceilingz = tmceilingz ) - thing->height; thing->ceilingrover = tmceilingrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2526,6 +2522,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep) { + if (flipped) + stairjank = (tmceilingz - thingtop); + thing->z = (thing->ceilingz = tmceilingz) - thing->height; thing->ceilingrover = tmceilingrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2533,6 +2532,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) { + if (!flipped) + stairjank = (thing->z - tmfloorz); + thing->z = thing->floorz = tmfloorz; thing->floorrover = tmfloorrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2619,6 +2621,28 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) else // don't set standingslope if you're not going to clip against it thing->standingslope = NULL; + /* FIXME: slope step down (even up) has some false + positives, so just ignore them entirely. */ + if (stairjank && !oldslope && !thing->standingslope && + thing->player && !thing->player->spectator) + { + /* use a shorter sound if not two tics have passed + * since the last step */ + S_StartSound(thing, thing->player->stairjank + >= 16 ? sfx_s23b : sfx_s268); + + if (!thing->player->stairjank) + { + mobj_t * spark = P_SpawnMobjFromMobj(thing, + 0, 0, 0, MT_JANKSPARK); + spark->fuse = 9; + spark->cusval = K_StairJankFlip(ANGLE_90); + P_SetTarget(&spark->target, thing); + } + + thing->player->stairjank = 17; + } + thing->x = x; thing->y = y; @@ -2644,10 +2668,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) oldside = P_PointOnLineSide(oldx, oldy, ld); if (side != oldside) { - if (ld->special) - { - P_CrossSpecialLine(ld, oldside, thing); - } + P_CrossSpecialLine(ld, oldside, thing); } } } @@ -2729,7 +2750,7 @@ static boolean PTR_GetSpecialLines(intercept_t *in) return true; } - if (P_SpecialIsLinedefCrossType(ld->special)) + if (P_SpecialIsLinedefCrossType(ld)) { add_spechit(ld); } @@ -2799,10 +2820,7 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_ oldside = P_PointOnLineSide(x, y, ld); if (side != oldside) { - if (ld->special) - { - P_CrossSpecialLine(ld, oldside, thing); - } + P_CrossSpecialLine(ld, oldside, thing); } } } @@ -3006,6 +3024,7 @@ static void P_PlayerHitBounceLine(line_t *ld) INT32 side; angle_t lineangle; fixed_t movelen; + fixed_t x, y; side = P_PointOnLineSide(slidemo->x, slidemo->y, ld); lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90; @@ -3020,8 +3039,19 @@ static void P_PlayerHitBounceLine(line_t *ld) if (slidemo->player && movelen < (15*mapobjectscale)) movelen = (15*mapobjectscale); - tmxmove += FixedMul(movelen, FINECOSINE(lineangle)); - tmymove += FixedMul(movelen, FINESINE(lineangle)); + x = FixedMul(movelen, FINECOSINE(lineangle)); + y = FixedMul(movelen, FINESINE(lineangle)); + + if (P_IsLineTripWire(ld)) + { + tmxmove = x * 4; + tmymove = y * 4; + } + else + { + tmxmove += x; + tmymove += y; + } } // @@ -3158,7 +3188,7 @@ static boolean PTR_SlideTraverse(intercept_t *in) P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); } - if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) + if (in->frac < bestslidefrac) { secondslidefrac = bestslidefrac; secondslideline = bestslideline; @@ -3659,6 +3689,11 @@ void P_BouncePlayerMove(mobj_t *mo) tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); } + if (P_IsLineTripWire(bestslideline)) + { + K_ApplyTripWire(mo->player, TRIP_BLOCKED); + } + else { mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); if (mo->eflags & MFE_VERTICALFLIP) @@ -3678,8 +3713,11 @@ void P_BouncePlayerMove(mobj_t *mo) mo->player->cmomx = tmxmove; mo->player->cmomy = tmymove; - if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) { - P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true); + if (!P_IsLineTripWire(bestslideline)) + { + if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) { + P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true); + } } } diff --git a/src/p_maputl.c b/src/p_maputl.c index 5cf2e81fe..2e21f5ee3 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -15,6 +15,7 @@ #include "doomdef.h" #include "doomstat.h" +#include "k_kart.h" #include "p_local.h" #include "r_main.h" #include "r_data.h" @@ -588,7 +589,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (mobj) { // Check for collision with front side's midtexture if Effect 4 is set - if (linedef->flags & ML_EFFECT4 + if ((linedef->flags & ML_EFFECT4 || (mobj->player && P_IsLineTripWire(linedef) && !K_TripwirePass(mobj->player))) && !linedef->polyobj // don't do anything for polyobjects! ...for now ) { side_t *side = &sides[linedef->sidenum[0]]; diff --git a/src/p_mobj.c b/src/p_mobj.c index 49165162d..2b2cfc251 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -191,7 +191,7 @@ static void P_CyclePlayerMobjState(mobj_t *mobj) // P_SetPlayerMobjState // Returns true if the mobj is still present. // -// Separate from P_SetMobjState because of the pw_flashing check and Super states +// Separate from P_SetMobjState because of the flashing check and Super states // boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) { @@ -285,7 +285,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if (skin) { - spr2 = P_GetSkinSprite2(skin, ((player->powers[pw_super] ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK, mobj->player); + spr2 = P_GetSkinSprite2(skin, st->frame & FF_FRAMEMASK, mobj->player); numframes = skin->sprites[spr2].numframes; } else @@ -1093,7 +1093,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (mo->player) { - if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be + if (mo->flags2 & MF2_OBJECTFLIP) { gravityadd = -gravityadd; mo->eflags ^= MFE_VERTICALFLIP; @@ -1104,12 +1104,12 @@ fixed_t P_GetMobjGravity(mobj_t *mo) P_PlayerFlip(mo); } - if (mo->player->kartstuff[k_waterskip]) + if (mo->player->waterskip) { gravityadd = (4*gravityadd)/3; } - if (mo->player->trickpanel == 2 || mo->player->trickpanel == 3) + if (mo->player->trickpanel >= 2) { gravityadd = (5*gravityadd)/2; } @@ -1657,8 +1657,6 @@ void P_XYMovement(mobj_t *mo) P_SlideMove(mo); - if (player) - player->powers[pw_pushing] = 3; xmove = ymove = 0; if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum @@ -1677,10 +1675,6 @@ void P_XYMovement(mobj_t *mo) transferslope->xydirection + (transferslope->zangle & ANGLE_180)); - if (player) - { - player->powers[pw_justlaunched] = 2; - } } } } @@ -1809,13 +1803,13 @@ void P_XYMovement(mobj_t *mo) if (mo->type == MT_FLINGRING || mo->type == MT_BALLHOG || mo->type == MT_BUBBLESHIELDTRAP) return; - if (player && (player->kartstuff[k_spinouttimer] && !player->kartstuff[k_wipeoutslow]) - && player->speed <= FixedDiv(20*mapobjectscale, player->kartstuff[k_offroad] + FRACUNIT)) + if (player && (player->spinouttimer && !player->wipeoutslow) + && player->speed <= FixedDiv(20*mapobjectscale, player->offroad + FRACUNIT)) return; //} if (((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) - && !(player && player->pflags & PF_SLIDING)) + && !(player && player->carry == CR_SLIDING)) return; // no friction when airborne P_XYFriction(mo, oldx, oldy); @@ -2723,7 +2717,7 @@ void P_PlayerZMovement(mobj_t *mo) mo->z = mo->floorz; // Get up if you fell. - if (mo->player->panim == PA_HURT && mo->player->kartstuff[k_spinouttimer] == 0 && mo->player->tumbleBounces == 0) + if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0 && mo->player->tumbleBounces == 0) P_SetPlayerMobjState(mo, S_KART_STILL); if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { @@ -2780,8 +2774,7 @@ void P_PlayerZMovement(mobj_t *mo) if (CheckForMarioBlocks) P_CheckMarioBlocks(mo); - if (!mo->player->climbing) - mo->momz = 0; + mo->momz = 0; } } } @@ -2953,7 +2946,7 @@ void P_MobjCheckWater(mobj_t *mobj) ffloor_t *rover; player_t *p = mobj->player; // Will just be null if not a player. fixed_t height = mobj->height; - boolean wasgroundpounding = (p && ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (p->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (p->pflags & PF_SHIELDABILITY)); + boolean wasgroundpounding = false; // Default if no water exists. mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; @@ -3013,30 +3006,6 @@ void P_MobjCheckWater(mobj_t *mobj) if (p && (p->spectator || p->playerstate != PST_LIVE)) return; - // Specific things for underwater players - if (p && (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER) - { - if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability]))) - { - boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC); - if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER) && !(mobj->eflags & MFE_TOUCHLAVA))) - { // Water removes electric and non-water fire shields... - P_FlashPal(p, - electric - ? PAL_WHITE - : PAL_NUKE, - 1); - p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK; - } - } - - if ((wasgroundpounding = ((mobj->eflags & MFE_GOOWATER) && wasgroundpounding))) - { - p->pflags &= ~PF_SHIELDABILITY; - mobj->momz >>= 1; - } - } - // The rest of this code only executes on a water state change. if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater) return; @@ -3089,9 +3058,9 @@ void P_MobjCheckWater(mobj_t *mobj) } // skipping stone! - if (p && p->kartstuff[k_waterskip] < 2 + if (p && p->waterskip < 2 && ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water. - || (p->speed > 20*mapobjectscale && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more! + || (p->speed > 20*mapobjectscale && p->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))) { @@ -3105,7 +3074,7 @@ void P_MobjCheckWater(mobj_t *mobj) else mobj->momz = FixedMul(hop, mobj->scale); - p->kartstuff[k_waterskip]++; + p->waterskip++; } } @@ -3390,7 +3359,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled dummy.z = thiscam->z; dummy.height = thiscam->height; - if ((player->pflags & PF_GAMETYPEOVER) && (gametyperules & GTR_CIRCUIT)) + if ((player->pflags & PF_NOCONTEST) && (gametyperules & GTR_CIRCUIT)) { player->karthud[khud_timeovercam] = (2*TICRATE)+1; } @@ -3556,7 +3525,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; // Zoom tube - if ((mobj->player->powers[pw_carry] == CR_ZOOMTUBE && mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + if ((mobj->player->carry == CR_ZOOMTUBE && mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) || mobj->player->respawn.state == RESPAWNST_MOVE) { P_HitSpecialLines(mobj, mobj->x, mobj->y, mobj->momx, mobj->momy); @@ -3574,7 +3543,6 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // Needed for gravity boots P_CheckGravity(mobj, false); - mobj->player->powers[pw_justlaunched] = 0; if (mobj->momx || mobj->momy) { P_XYMovement(mobj); @@ -3780,6 +3748,57 @@ static void P_RingThinker(mobj_t *mobj) P_CycleMobjState(mobj); } +static void P_ItemCapsulePartThinker(mobj_t *mobj) +{ + if (mobj->fuse > 0) // dead + { + mobj->fuse--; + if (mobj->fuse == 0) + { + P_RemoveMobj(mobj); + return; + } + mobj->renderflags ^= RF_DONTDRAW; + } + else // alive + { + mobj_t *target = mobj->target; + fixed_t targetScale, z; + + if (P_MobjWasRemoved(target)) + { + P_RemoveMobj(mobj); + return; + } + + // match the capsule's scale + if (mobj->extravalue1) + targetScale = FixedMul(mobj->extravalue1, target->scale); + else + targetScale = target->scale; + + if (mobj->scale != targetScale) + P_SetScale(mobj, mobj->destscale = targetScale); + + // find z position + K_GenericExtraFlagsNoZAdjust(mobj, target); + if (mobj->flags & MFE_VERTICALFLIP) + z = target->z + target->height - mobj->height - FixedMul(mobj->scale, mobj->movefactor); + else + z = target->z + FixedMul(mobj->scale, mobj->movefactor); + + // rotate & move to capsule + mobj->angle += mobj->movedir; + if (mobj->flags2 & MF2_CLASSICPUSH) // centered + P_TeleportMove(mobj, target->x, target->y, z); + else + P_TeleportMove(mobj, + target->x + P_ReturnThrustX(mobj, mobj->angle + ANGLE_90, mobj->radius), + target->y + P_ReturnThrustY(mobj, mobj->angle + ANGLE_90, mobj->radius), + z); + } +} + // // P_BossTargetPlayer // If closest is true, find the closest player. @@ -3813,7 +3832,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->pflags & PF_INVIS || player->bot || player->spectator) + if (player->bot || player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) @@ -3851,9 +3870,6 @@ boolean P_SupermanLook4Players(mobj_t *actor) { if (playeringame[c] && !players[c].spectator) { - if (players[c].pflags & PF_INVIS) - continue; // ignore notarget - if (!players[c].mo || players[c].bot) continue; @@ -4319,8 +4335,8 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) angle_t prevfa = (prevrot + mobj->friction) & FINEMASK; fa = (rot + mobj->friction) & FINEMASK; - if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing - dosound = true; + // completed a half-spin + dosound = ((prevfa > (FINEMASK/2)) != (fa > (FINEMASK/2))); unit_lengthways[0] = FixedMul(FINECOSINE(fa), radius); unit_lengthways[2] = FixedMul(FINESINE(fa), radius); @@ -4467,125 +4483,6 @@ cont: } } -static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) -{ - if (!thing->target || thing->target->health <= 0 || !thing->target->player - || (thing->target->player->powers[pw_shield] & SH_NOSTACK) == SH_NONE || thing->target->player->powers[pw_super] - || thing->target->player->powers[pw_invulnerability] > 1) - { - P_RemoveMobj(thing); - return false; - } - - // TODO: Make an MT_SHIELDORB which changes color/states to always match the appropriate shield, - // instead of having completely seperate mobjtypes. - if (!(shield & SH_FORCE)) - { // Regular shields check for themselves only - if ((shieldtype_t)(thing->target->player->powers[pw_shield] & SH_NOSTACK) != shield) - { - P_RemoveMobj(thing); - return false; - } - } - else if (!(thing->target->player->powers[pw_shield] & SH_FORCE)) - { // Force shields check for any force shield - P_RemoveMobj(thing); - return false; - } - - if (shield & SH_FORCE && thing->movecount != (thing->target->player->powers[pw_shield] & SH_FORCEHP)) - { - thing->movecount = (thing->target->player->powers[pw_shield] & SH_FORCEHP); - if (thing->movecount < 1) - { - if (thing->info->painstate) - P_SetMobjState(thing,thing->info->painstate); - else - thing->renderflags |= RF_GHOSTLY; - } - else - { - if (thing->info->painstate) - P_SetMobjState(thing,thing->info->spawnstate); - else - thing->renderflags &= ~(RF_TRANSMASK|RF_BRIGHTMASK); - } - } - - thing->flags |= MF_NOCLIPHEIGHT; - thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); - - P_SetScale(thing, thing->target->scale); - thing->destscale = thing->scale; - P_UnsetThingPosition(thing); - thing->x = thing->target->x; - thing->y = thing->target->y; - if (thing->eflags & MFE_VERTICALFLIP) - thing->z = thing->target->z + (thing->target->height - thing->height - FixedMul(2*FRACUNIT, thing->target->scale)); - else - thing->z = thing->target->z + FixedMul(2*FRACUNIT, thing->target->scale); - P_SetThingPosition(thing); - P_CheckPosition(thing, thing->x, thing->y); - - if (P_MobjWasRemoved(thing)) - return false; - -// if (thing->z < thing->floorz) -// thing->z = thing->floorz; - - return true; -} - -mobj_t *shields[MAXPLAYERS*2]; -INT32 numshields = 0; - -void P_RunShields(void) -{ - INT32 i; - - // run shields - for (i = 0; i < numshields; i++) - { - P_ShieldLook(shields[i], shields[i]->threshold); - P_SetTarget(&shields[i], NULL); - } - numshields = 0; -} - -static boolean P_AddShield(mobj_t *thing) -{ - shieldtype_t shield = thing->threshold; - - if (!thing->target || thing->target->health <= 0 || !thing->target->player - || (thing->target->player->powers[pw_shield] & SH_NOSTACK) == SH_NONE || thing->target->player->powers[pw_super] - || thing->target->player->powers[pw_invulnerability] > 1) - { - P_RemoveMobj(thing); - return false; - } - - if (!(shield & SH_FORCE)) - { // Regular shields check for themselves only - if ((shieldtype_t)(thing->target->player->powers[pw_shield] & SH_NOSTACK) != shield) - { - P_RemoveMobj(thing); - return false; - } - } - else if (!(thing->target->player->powers[pw_shield] & SH_FORCE)) - { // Force shields check for any force shield - P_RemoveMobj(thing); - return false; - } - - // Queue has been hit... why?!? - if (numshields >= MAXPLAYERS*2) - return P_ShieldLook(thing, thing->info->speed); - - P_SetTarget(&shields[numshields++], thing); - return true; -} - // Kartitem stuff. boolean P_IsKartItem(INT32 type) { @@ -5018,9 +4915,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (P_MobjWasRemoved(mobj)) return; - if ((mobj->flags2 & MF2_SHIELD) && !P_AddShield(mobj)) - return; - switch (mobj->type) { case MT_BOSSJUNK: @@ -5035,6 +4929,10 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_HIDDEN_SLING: P_MaceSceneryThink(mobj); break; + case MT_SMALLMACE: + case MT_BIGMACE: + P_SpawnGhostMobj(mobj)->tics = 8; + break; case MT_HOOP: if (mobj->fuse > 1) P_MoveHoop(mobj); @@ -5089,123 +4987,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) else P_AddOverlay(mobj); break; - case MT_PITY_ORB: - case MT_WHIRLWIND_ORB: - case MT_ARMAGEDDON_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - break; - case MT_ATTRACT_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (/*(mobj->target) -- the following is implicit by P_AddShield - && (mobj->target->player) - && */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY)) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - } - break; - case MT_ELEMENTAL_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL */ - && mobj->target->player->pflags & PF_SHIELDABILITY - && ((statenum_t)(mobj->tracer->state - states) < mobj->info->raisestate - || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - } - break; - case MT_FORCE_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (/* - && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_FORCE) - && */ (mobj->target->player->pflags & PF_SHIELDABILITY)) - { - mobj_t *whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST); // done here so the offset is correct - P_SetMobjState(whoosh, mobj->info->raisestate); - whoosh->destscale = whoosh->scale << 1; - whoosh->scalespeed = FixedMul(whoosh->scalespeed, whoosh->scale); - whoosh->height = 38*whoosh->scale; - whoosh->fuse = 10; - whoosh->flags |= MF_NOCLIPHEIGHT; - whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames - mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh - } - /* FALLTHRU */ - case MT_FLAMEAURA_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if ((statenum_t)(mobj->state - states) < mobj->info->painstate) - mobj->angle = mobj->target->angle; // implicitly okay because of P_AddShield - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_FLAMEAURA */ - && mobj->target->player->pflags & PF_SHIELDABILITY - && ((statenum_t)(mobj->tracer->state - states) < mobj->info->raisestate - || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - } - break; - case MT_BUBBLEWRAP_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP */ - ) - { - if (mobj->target->player->pflags & PF_SHIELDABILITY - && ((statenum_t)(mobj->state - states) < mobj->info->painstate - || (mobj->state->nextstate < mobj->info->painstate && mobj->tics == 1))) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - } - else if (mobj->target->eflags & MFE_JUSTHITFLOOR - && (statenum_t)(mobj->state - states) == mobj->info->painstate) - { - P_SetMobjState(mobj, mobj->info->painstate + 1); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate + 1); - mobj->tracer->tics++; - } - } - break; - case MT_THUNDERCOIN_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_THUNDERCOIN */ - && (mobj->target->player->pflags & PF_SHIELDABILITY)) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal spark - } - break; case MT_WATERDROP: P_SceneryCheckWater(mobj); if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) @@ -5658,7 +5439,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) } // Do this in an easy way - if (mobj->target->player->kartstuff[k_itemroulette]) + if (mobj->target->player->itemroulette) { mobj->tracer->color = mobj->target->player->skincolor; mobj->tracer->colorized = true; @@ -5671,17 +5452,17 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (!(mobj->renderflags & RF_DONTDRAW)) { - const INT32 numberdisplaymin = ((mobj->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2); + const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2); // Set it to use the correct states for its condition - if (mobj->target->player->kartstuff[k_itemroulette]) + if (mobj->target->player->itemroulette) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->kartstuff[k_itemroulette] % (13*3)) / 3) + 1); + mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->itemroulette % (13*3)) / 3) + 1); mobj->tracer->renderflags &= ~RF_DONTDRAW; } - else if (mobj->target->player->kartstuff[k_stolentimer] > 0) + else if (mobj->target->player->stealingtimer < 0) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); mobj->tracer->sprite = SPR_ITEM; @@ -5691,14 +5472,14 @@ static void P_MobjSceneryThink(mobj_t *mobj) else mobj->tracer->renderflags |= RF_DONTDRAW; } - else if ((mobj->target->player->kartstuff[k_stealingtimer] > 0) && (leveltime & 2)) + else if ((mobj->target->player->stealingtimer > 0) && (leveltime & 2)) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); mobj->tracer->sprite = SPR_ITEM; mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO; mobj->tracer->renderflags &= ~RF_DONTDRAW; } - else if (mobj->target->player->kartstuff[k_eggmanexplode] > 1) + else if (mobj->target->player->eggmanexplode > 1) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); mobj->tracer->sprite = SPR_ITEM; @@ -5708,9 +5489,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) else mobj->tracer->renderflags |= RF_DONTDRAW; } - else if (mobj->target->player->kartstuff[k_rocketsneakertimer] > 1) + else if (mobj->target->player->rocketsneakertimer > 1) { - //itembar = mobj->target->player->kartstuff[k_rocketsneakertimer]; -- not today satan + //itembar = mobj->target->player->rocketsneakertimer; -- not today satan P_SetMobjState(mobj, S_PLAYERARROW_BOX); mobj->tracer->sprite = SPR_ITEM; mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER; @@ -5719,19 +5500,19 @@ static void P_MobjSceneryThink(mobj_t *mobj) else mobj->tracer->renderflags |= RF_DONTDRAW; } - else if (mobj->target->player->kartstuff[k_itemtype] && mobj->target->player->kartstuff[k_itemamount] > 0) + else if (mobj->target->player->itemtype && mobj->target->player->itemamount > 0) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); - switch (mobj->target->player->kartstuff[k_itemtype]) + switch (mobj->target->player->itemtype) { case KITEM_ORBINAUT: mobj->tracer->sprite = SPR_ITMO; - mobj->tracer->frame = FF_FULLBRIGHT|(min(mobj->target->player->kartstuff[k_itemamount]-1, 3)); + mobj->tracer->frame = FF_FULLBRIGHT|K_GetOrbinautItemFrame(mobj->target->player->itemamount); break; case KITEM_INVINCIBILITY: mobj->tracer->sprite = SPR_ITMI; - mobj->tracer->frame = FF_FULLBRIGHT|((leveltime % (7*3)) / 3); + mobj->tracer->frame = FF_FULLBRIGHT|K_GetInvincibilityItemFrame(); break; case KITEM_SAD: mobj->tracer->sprite = SPR_ITEM; @@ -5739,11 +5520,11 @@ static void P_MobjSceneryThink(mobj_t *mobj) break; default: mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemtype]); + mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->itemtype); break; } - if (mobj->target->player->kartstuff[k_itemheld]) + if (mobj->target->player->pflags & PF_ITEMOUT) { if (leveltime & 1) mobj->tracer->renderflags &= ~RF_DONTDRAW; @@ -5761,8 +5542,8 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->tracer->destscale = scale; - if (mobj->target->player->kartstuff[k_itemamount] >= numberdisplaymin - && mobj->target->player->kartstuff[k_itemamount] <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V + if (mobj->target->player->itemamount >= numberdisplaymin + && mobj->target->player->itemamount <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V { mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); mobj_t *numx = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); @@ -5771,7 +5552,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(number, S_PLAYERARROW_NUMBER); P_SetScale(number, mobj->scale); number->destscale = scale; - number->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemamount]); + number->frame = FF_FULLBRIGHT|(mobj->target->player->itemamount); P_SetTarget(&numx->target, mobj); P_SetMobjState(numx, S_PLAYERARROW_X); @@ -5859,6 +5640,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite } break; + case MT_ITEMCAPSULE_PART: + P_ItemCapsulePartThinker(mobj); + break; case MT_BATTLECAPSULE_PIECE: if (mobj->extravalue2) mobj->frame |= FF_VERTICALFLIP; @@ -5872,6 +5656,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->renderflags ^= RF_DONTDRAW; break; case MT_SPINDASHWIND: + case MT_DRIFTELECTRICSPARK: mobj->renderflags ^= RF_DONTDRAW; break; case MT_VWREF: @@ -6332,11 +6117,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { case KITEM_ORBINAUT: mobj->sprite = SPR_ITMO; - mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(min(mobj->movecount-1, 3)); + mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount); break; case KITEM_INVINCIBILITY: mobj->sprite = SPR_ITMI; - mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|((leveltime % (7*3)) / 3); + mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame(); break; case KITEM_SAD: mobj->sprite = SPR_ITEM; @@ -6353,6 +6138,38 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; } + case MT_ITEMCAPSULE: + // scale the capsule + if (mobj->scale < mobj->extravalue1) + { + fixed_t oldHeight = mobj->height; + + if ((mobj->extravalue1 - mobj->scale) < mobj->scalespeed) + P_SetScale(mobj, mobj->destscale = mobj->extravalue1); + else + P_SetScale(mobj, mobj->destscale = mobj->scale + mobj->scalespeed); + + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->z -= (mobj->height - oldHeight); + } + + // update & animate capsule + if (!P_MobjWasRemoved(mobj->tracer)) + { + mobj_t *part = mobj->tracer; + + if (mobj->threshold != part->threshold + || mobj->movecount != part->movecount) // change the capsule properties if the item type or amount is updated + P_RefreshItemCapsuleParts(mobj); + + // animate invincibility capsules + if (mobj->threshold == KITEM_INVINCIBILITY) + { + mobj->color = K_RainbowColor(leveltime); + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame(); + } + } + break; case MT_ORBINAUT: { boolean grounded = P_IsObjectOnGround(mobj); @@ -6743,7 +6560,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } else if (mobj->fuse <= 32) mobj->color = SKINCOLOR_SAPPHIRE; - else if (mobj->fuse > 32) + else if (mobj->fuse <= 48) + mobj->color = SKINCOLOR_PURPLE; + else if (mobj->fuse > 48) mobj->color = K_RainbowColor( (SKINCOLOR_PURPLE - SKINCOLOR_PINK) // Smoothly transition into the other state + ((mobj->fuse - 32) * 2) // Make the color flashing slow down while it runs out @@ -6751,7 +6570,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) switch (mobj->extravalue1) { - case 3:/* rainbow boost */ + case 4:/* rainbow boost */ /* every 20 tics, bang! */ if (( 120 - mobj->fuse ) % 10 == 0) { @@ -6760,6 +6579,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; + case 3:/* purple boost */ + if ((mobj->fuse == 32)/* to blue*/ + || (mobj->fuse == 16))/* to red*/ + K_SpawnDriftBoostClip(mobj->target->player); + break; + case 2:/* blue boost */ if (mobj->fuse == 16)/* to red*/ K_SpawnDriftBoostClip(mobj->target->player); @@ -6779,12 +6604,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (p) { - if (p->kartstuff[k_driftboost] > mobj->movecount) + if (p->driftboost > mobj->movecount) { ; // reset animation } - mobj->movecount = p->kartstuff[k_driftboost]; + mobj->movecount = p->driftboost; } } break; @@ -6812,9 +6637,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (p) { - if (p->kartstuff[k_sneakertimer] > mobj->movecount) + if (p->sneakertimer > mobj->movecount) P_SetMobjState(mobj, S_BOOSTFLAME); - mobj->movecount = p->kartstuff[k_sneakertimer]; + mobj->movecount = p->sneakertimer; } } @@ -6843,7 +6668,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->colorized = mobj->target->colorized; break; case MT_INVULNFLASH: - if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_invincibilitytimer])) + if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->invincibilitytimer)) { P_RemoveMobj(mobj); return false; @@ -6852,7 +6677,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_BRAKEDRIFT: if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target)) - || !mobj->target->player->kartstuff[k_drift] || !mobj->target->player->kartstuff[k_brakedrift] + || !mobj->target->player->drift || !(mobj->target->player->pflags & PF_BRAKEDRIFT) || !((mobj->target->player->cmd.buttons & BT_BRAKE) || (K_GetKartButtons(mobj->target->player) & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting { @@ -6861,17 +6686,17 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } else { - UINT8 driftcolor = K_DriftSparkColor(mobj->target->player, mobj->target->player->kartstuff[k_driftcharge]); + UINT8 driftcolor = K_DriftSparkColor(mobj->target->player, mobj->target->player->driftcharge); fixed_t newx, newy; angle_t travelangle; - travelangle = mobj->target->angle - ((ANGLE_45/5)*mobj->target->player->kartstuff[k_drift]); + travelangle = mobj->target->angle - ((ANGLE_45/5)*mobj->target->player->drift); newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale); newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale); P_TeleportMove(mobj, newx, newy, mobj->target->z); - mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->kartstuff[k_drift]); + mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->drift); P_SetScale(mobj, (mobj->destscale = mobj->target->scale)); if (driftcolor != SKINCOLOR_NONE) @@ -6887,6 +6712,21 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->renderflags |= RF_DONTDRAW; } break; + case MT_JANKSPARK: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return false; + } + if (mobj->fuse == 1 && mobj->target->player && + mobj->target->player->stairjank >= 8) + { + mobj->fuse = 9; + } + P_TeleportMove(mobj, mobj->target->x, + mobj->target->y, mobj->target->z); + mobj->angle = mobj->target->angle + mobj->cusval; + break; case MT_PLAYERRETICULE: if (!mobj->target || !mobj->target->health) { @@ -6900,7 +6740,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) K_MatchGenericExtraFlags(mobj, mobj->target); /* FALLTHRU */ case MT_INSTASHIELDA: - if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield])) + if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->instashield)) { P_RemoveMobj(mobj); return false; @@ -6943,7 +6783,51 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), - mobj->z + mobj->target->height * P_MobjFlip(mobj)); + mobj->z + (mobj->target->height * P_MobjFlip(mobj))); + break; + case MT_GAINAX: + if (!mobj->target || P_MobjWasRemoved(mobj->target) // sanity + || !mobj->target->player // ditto + || !mobj->target->player->glanceDir // still glancing? + || mobj->target->player->aizdriftturn // only other circumstance where can glance + || ((K_GetKartButtons(mobj->target->player) & BT_LOOKBACK) != BT_LOOKBACK)) // it's a lookback indicator... + { + P_RemoveMobj(mobj); + return false; + } + + mobj->angle = mobj->target->player->drawangle; + mobj->z = mobj->target->z; + + K_MatchGenericExtraFlags(mobj, mobj->target); + mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW)|K_GetPlayerDontDrawFlag(mobj->target->player); + + P_TeleportMove(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)), + mobj->target->y + FixedMul(34 * mapobjectscale, FINESINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)), + mobj->z + (32 * mapobjectscale * P_MobjFlip(mobj))); + + { + statenum_t gainaxstate = mobj->state-states; + if (gainaxstate == S_GAINAX_TINY) + { + if (abs(mobj->target->player->glanceDir) > 1) + { + if (mobj->target->player->itemamount && mobj->target->player->itemtype) + gainaxstate = S_GAINAX_HUGE; + else + gainaxstate = S_GAINAX_MID1; + P_SetMobjState(mobj, gainaxstate); + } + } + else if (abs(mobj->target->player->glanceDir) <= 1) + { + if (mobj->flags2 & MF2_AMBUSH) + mobj->flags2 &= ~MF2_AMBUSH; + else + P_SetMobjState(mobj, S_GAINAX_TINY); + } + } + break; case MT_FLAMESHIELDPAPER: if (!mobj->target || P_MobjWasRemoved(mobj->target)) @@ -6971,7 +6855,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_TIREGREASE: if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player - || !mobj->target->player->kartstuff[k_tiregrease]) + || !mobj->target->player->tiregrease) { P_RemoveMobj(mobj); return false; @@ -6983,7 +6867,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) const angle_t off = FixedAngle(40*FRACUNIT); angle_t ang = K_MomentumAngle(mobj->target); fixed_t z; - UINT8 trans = (mobj->target->player->kartstuff[k_tiregrease] * (NUMTRANSMAPS+1)) / greasetics; + UINT8 trans = (mobj->target->player->tiregrease * (NUMTRANSMAPS+1)) / greasetics; if (trans > NUMTRANSMAPS) trans = NUMTRANSMAPS; @@ -7005,6 +6889,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) z); mobj->angle = ang; + if (!P_IsObjectOnGround(mobj->target)) + mobj->renderflags |= RF_DONTDRAW; + if (leveltime & 1) mobj->renderflags |= RF_DONTDRAW; @@ -7020,7 +6907,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { fixed_t destx, desty; if (!mobj->target || !mobj->target->health || !mobj->target->player - || mobj->target->player->kartstuff[k_curshield] != KSHIELD_THUNDER) + || mobj->target->player->curshield != KSHIELD_THUNDER) { P_RemoveMobj(mobj); return false; @@ -7061,7 +6948,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) statenum_t curstate; if (!mobj->target || !mobj->target->health || !mobj->target->player - || mobj->target->player->kartstuff[k_curshield] != KSHIELD_BUBBLE) + || mobj->target->player->curshield != KSHIELD_BUBBLE) { P_RemoveMobj(mobj); return false; @@ -7070,9 +6957,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) scale = (5*mobj->target->scale)>>2; curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states))); - if (mobj->target->player->kartstuff[k_bubbleblowup]) + if (mobj->target->player->bubbleblowup) { - INT32 blow = mobj->target->player->kartstuff[k_bubbleblowup]; + INT32 blow = mobj->target->player->bubbleblowup; if (blow > bubbletime) blow = bubbletime; @@ -7084,7 +6971,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) scale += (blow * (3*scale)) / bubbletime; mobj->frame = (states[S_BUBBLESHIELDBLOWUP].frame + mobj->extravalue1); - if ((mobj->target->player->kartstuff[k_bubbleblowup] > bubbletime) && (leveltime & 1)) + if ((mobj->target->player->bubbleblowup > bubbletime) && (leveltime & 1)) mobj->frame = (states[S_BUBBLESHIELDBLOWUP].frame + 5); if (mobj->extravalue1 < 4 && mobj->extravalue2 < blow && !mobj->cvmem && (leveltime & 1)) // Growing @@ -7149,14 +7036,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } else { - if (mobj->target->player->kartstuff[k_bubblecool] && ((curstate-S_BUBBLESHIELD1) & 1)) + if (mobj->target->player->bubblecool && ((curstate-S_BUBBLESHIELD1) & 1)) mobj->renderflags |= RF_GHOSTLY; else mobj->renderflags &= ~RF_GHOSTLYMASK; } } - mobj->extravalue2 = mobj->target->player->kartstuff[k_bubbleblowup]; + mobj->extravalue2 = mobj->target->player->bubbleblowup; P_SetScale(mobj, (mobj->destscale = scale)); if (!splitscreen /*&& rendermode != render_soft*/) @@ -7190,19 +7077,19 @@ static boolean P_MobjRegularThink(mobj_t *mobj) INT32 flamemax = 0; if (!mobj->target || !mobj->target->health || !mobj->target->player - || mobj->target->player->kartstuff[k_curshield] != KSHIELD_FLAME) + || mobj->target->player->curshield != KSHIELD_FLAME) { P_RemoveMobj(mobj); return false; } - flamemax = mobj->target->player->kartstuff[k_flamelength] * flameseg; + flamemax = mobj->target->player->flamelength * flameseg; P_SetScale(mobj, (mobj->destscale = (5*mobj->target->scale)>>2)); curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states))); - if (mobj->target->player->kartstuff[k_flamedash]) + if (mobj->target->player->flamedash) { if (!(curstate >= S_FLAMESHIELDDASH1 && curstate <= S_FLAMESHIELDDASH12)) P_SetMobjState(mobj, S_FLAMESHIELDDASH1); @@ -7221,7 +7108,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) UINT8 i; UINT8 nl = 2; - if (mobj->target->player->kartstuff[k_flamedash] > mobj->extravalue1) + if (mobj->target->player->flamedash > mobj->extravalue1) nl = 3; for (i = 0; i < nl; i++) @@ -7247,9 +7134,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_SetMobjState(mobj, S_FLAMESHIELD1); } - mobj->extravalue1 = mobj->target->player->kartstuff[k_flamedash]; + mobj->extravalue1 = mobj->target->player->flamedash; - if (mobj->target->player->kartstuff[k_flamemeter] > flamemax) + if (mobj->target->player->flamemeter > flamemax) { mobj_t *flash = P_SpawnMobj(mobj->x + mobj->target->momx, mobj->y + mobj->target->momy, mobj->z + mobj->target->momz, MT_THOK); P_SetMobjState(flash, S_FLAMESHIELDFLASH); @@ -7304,7 +7191,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_RemoveMobj(mobj); return false; } - if (mobj->target->player && !mobj->target->player->kartstuff[k_rocketsneakertimer]) + if (mobj->target->player && !mobj->target->player->rocketsneakertimer) { mobj->flags &= ~MF_NOGRAVITY; mobj->angle += ANGLE_45; @@ -7339,11 +7226,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->color = mobj->target->color; mobj->colorized = true; - // Give items an item-sized hitbox - if (mobj->target->player->kartstuff[k_comebackmode] == 1) - mobj->radius = 48*mobj->target->scale; - else - mobj->radius = 24*mobj->target->scale; + mobj->radius = 24*mobj->target->scale; mobj->height = 2*mobj->radius; if (mobj->target->player->karmadelay > 0) @@ -7357,17 +7240,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } else { - if (!mobj->target->player->kartstuff[k_comebackmode] - && (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20)) + if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20) P_SetMobjState(mobj, S_PLAYERBOMB1); - else if (mobj->target->player->kartstuff[k_comebackmode] == 1 - && (state < S_PLAYERITEM1 || state > S_PLAYERITEM12)) - P_SetMobjState(mobj, S_PLAYERITEM1); - else if (mobj->target->player->kartstuff[k_comebackmode] == 2 - && (state < S_PLAYERFAKE1 || state > S_PLAYERFAKE12)) - P_SetMobjState(mobj, S_PLAYERFAKE1); - if (mobj->target->player->powers[pw_flashing] && (leveltime & 1)) + if (mobj->target->player->flashing && (leveltime & 1)) mobj->renderflags |= RF_DONTDRAW; else mobj->renderflags &= ~RF_DONTDRAW; @@ -7937,7 +7813,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) player_t *player = mobj->target->player; mobj->extravalue1 = 1; - player->kartstuff[k_offroad] += 2<offroad += 2<mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius) @@ -7956,6 +7832,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; } + // Uses cmd.turning over steering intentionally. if (abs(player->cmd.turning) > 100) { INT32 lastsign = 0; @@ -8112,6 +7989,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; } + // Uses cmd.turning over steering intentionally. if (abs(player->cmd.turning) > 100) { INT32 lastsign = 0; @@ -8660,6 +8538,17 @@ static boolean P_FuseThink(mobj_t *mobj) P_RemoveMobj(mobj); // make sure they disappear return false; + case MT_ITEMCAPSULE: + if (mobj->spawnpoint) + P_SpawnMapThing(mobj->spawnpoint); + else + { + mobj_t *newMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + newMobj->threshold = mobj->threshold; + newMobj->movecount = mobj->movecount; + } + P_RemoveMobj(mobj); + return false; case MT_SMK_ICEBLOCK: { mobj_t *cur = mobj->hnext, *next; @@ -8727,7 +8616,7 @@ void P_MobjThinker(mobj_t *mobj) return; } - mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL); + mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG); tmfloorthing = tmhitthing = NULL; @@ -8747,17 +8636,29 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->type == MT_GHOST && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY! { - if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag + if (mobj->extravalue1 > 0) // Sonic Advance 2 mode { - if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - (2*mobj->fuse)/3) - // fade out when nearing the end of fuse... - mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - (2*mobj->fuse)/3) << FF_TRANSSHIFT); + if (mobj->extravalue2 >= 2) + { + if (mobj->extravalue2 == 2) // I don't know why the normal logic doesn't work for this. + mobj->renderflags ^= RF_DONTDRAW; + else + { + if (mobj->fuse == mobj->extravalue2) + mobj->renderflags &= ~RF_DONTDRAW; + else + mobj->renderflags |= RF_DONTDRAW; + } + } } else { - if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2) + INT32 dur = (mobj->flags2 & MF2_BOSSNOTRAP) + ? (2*mobj->fuse)/3 + : mobj->fuse/2; + if (((mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT) < ((NUMTRANSMAPS-1) - dur)) // fade out when nearing the end of fuse... - mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT); + mobj->renderflags = (mobj->renderflags & ~RF_TRANSMASK) | (((NUMTRANSMAPS-1) - dur) << RF_TRANSSHIFT); } } @@ -9085,21 +8986,6 @@ void P_SceneryThinker(mobj_t *mobj) } } - // Sonic Advance 2 flashing afterimages - if (mobj->type == MT_GHOST && mobj->fuse > 0 - && mobj->extravalue1 > 0 && mobj->extravalue2 >= 2) - { - if (mobj->extravalue2 == 2) // I don't know why the normal logic doesn't work for this. - mobj->renderflags ^= RF_DONTDRAW; - else - { - if (mobj->fuse == mobj->extravalue2) - mobj->renderflags &= ~RF_DONTDRAW; - else - mobj->renderflags |= RF_DONTDRAW; - } - } - // momentum movement if (mobj->momx || mobj->momy) { @@ -9146,7 +9032,7 @@ void P_SceneryThinker(mobj_t *mobj) if (!playeringame[mobj->threshold] || players[mobj->threshold].spectator) // focused on a valid player? return; - if (!(players[mobj->threshold].exiting) && !(players[mobj->threshold].pflags & PF_GAMETYPEOVER)) // not finished yet? + if (!(players[mobj->threshold].exiting) && !(players[mobj->threshold].pflags & PF_NOCONTEST)) // not finished yet? return; if (K_IsPlayerLosing(&players[mobj->threshold])) @@ -9233,6 +9119,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_FLOATINGITEM: case MT_BLUESPHERE: case MT_EMERALD: + case MT_ITEMCAPSULE: thing->shadowscale = FRACUNIT/2; break; case MT_DRIFTCLIP: @@ -9591,6 +9478,40 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->fuse = 100; break; // SRB2Kart + case MT_ITEMCAPSULE: + { + fixed_t oldHeight = mobj->height; + + // set default item & count +#if 0 // set to 1 to test capsules with random items, e.g. with objectplace + if (P_RandomChance(FRACUNIT/3)) + mobj->threshold = KITEM_SUPERRING; + else if (P_RandomChance(FRACUNIT/3)) + mobj->threshold = KITEM_SPB; + else if (P_RandomChance(FRACUNIT/3)) + mobj->threshold = KITEM_ORBINAUT; + else + mobj->threshold = P_RandomRange(1, NUMKARTITEMS - 1); + mobj->movecount = P_RandomChance(FRACUNIT/3) ? 1 : P_RandomKey(32) + 1; +#else + mobj->threshold = KITEM_SUPERRING; // default item is super ring + mobj->movecount = 1; +#endif + + // grounded/aerial properties + P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 0); + if (!P_IsObjectOnGround(mobj)) + mobj->flags |= MF_NOGRAVITY; + + // set starting scale + mobj->extravalue1 = mobj->scale; // this acts as the capsule's destscale; we're avoiding P_MobjScaleThink because we want aerial capsules not to scale from their center + mobj->scalespeed >>= 1; + P_SetScale(mobj, mobj->destscale = mapobjectscale >> 4); + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->z += (oldHeight - mobj->height); + + break; + } case MT_KARMAHITBOX: { const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->scale); @@ -10330,6 +10251,11 @@ void P_RespawnSpecials(void) pcount++; } +#if 0 // set to 1 to enable quick respawns for testing + if (true) + time = 5*TICRATE; + else +#endif if (gametyperules & GTR_SPHERES) { if (pcount > 2) @@ -10480,7 +10406,7 @@ void P_SpawnPlayer(INT32 playernum) } if (leveltime > introtime) - p->powers[pw_flashing] = K_GetKartFlashing(p); // Babysitting deterrent + p->flashing = K_GetKartFlashing(p); // Babysitting deterrent mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); (mobj->player = p)->mo = mobj; @@ -10499,7 +10425,6 @@ void P_SpawnPlayer(INT32 playernum) mobj->health = 1; p->playerstate = PST_LIVE; - p->bonustime = false; p->realtime = leveltime; p->followitem = skins[p->skin].followitem; @@ -10877,6 +10802,21 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) if (modifiedgame && !savemoddata) return false; // No cheating!! + break; + case MT_ITEMCAPSULE: + { + boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS); + + // don't spawn ring capsules in GTR_SPHERES gametypes + if (isRingCapsule && (gametyperules & GTR_SPHERES)) + return false; + + // in record attack, only spawn ring capsules + // (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not) + if (modeattacking + && (!(mthing->options & MTF_EXTRA) == !isRingCapsule)) + return false; + } break; default: break; @@ -11826,6 +11766,27 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean } break; } + case MT_ITEMCAPSULE: + { + // Angle = item type + if (mthing->angle > 0 && mthing->angle < NUMKARTITEMS) + mobj->threshold = mthing->angle; + + // Parameter = extra items (x5 for rings) + mobj->movecount += mthing->extrainfo; + + // Special = +16 items (+80 for rings) + if (mthing->options & MTF_OBJECTSPECIAL) + mobj->movecount += 16; + + // Ambush = double size (grounded) / half size (aerial) + if (!(mthing->options & MTF_AMBUSH) == !P_IsObjectOnGround(mobj)) + { + mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(64*FRACUNIT, mobj->info->radius)); // don't make them larger than the blockmap can handle + mobj->scalespeed <<= 1; + } + break; + } case MT_AAZTREE_HELPER: { fixed_t top = mobj->z; @@ -12286,7 +12247,7 @@ void P_SpawnHoop(mapthing_t *mthing) P_SpawnHoopInternal(mthing, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); } -static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) +static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) { mapthing_t dummything; mobj_t *mobj = NULL; @@ -12297,8 +12258,6 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numi angle_t angle = FixedAngle(fixedangle << FRACBITS); angle_t fineangle = (angle >> ANGLETOFINESHIFT) & FINEMASK; - (void)bonustime; - for (r = 0; r < numitemtypes; r++) { dummything = *mthing; @@ -12337,13 +12296,13 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numi } } -static void P_SpawnSingularItemRow(mapthing_t* mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) +static void P_SpawnSingularItemRow(mapthing_t* mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) { mobjtype_t itemtypes[1] = { itemtype }; - return P_SpawnItemRow(mthing, itemtypes, 1, numitems, horizontalspacing, verticalspacing, fixedangle, bonustime); + return P_SpawnItemRow(mthing, itemtypes, 1, numitems, horizontalspacing, verticalspacing, fixedangle); } -static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t size, boolean bonustime) +static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t size) { mapthing_t dummything; mobj_t* mobj = NULL; @@ -12355,8 +12314,6 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n INT32 i; TVector v, *res; - (void)bonustime; - for (i = 0; i < numitemtypes; i++) { dummything = *mthing; @@ -12401,22 +12358,22 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n } } -void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) +void P_SpawnItemPattern(mapthing_t *mthing) { switch (mthing->type) { // Special placement patterns case 600: // 5 vertical rings (yellow spring) - P_SpawnSingularItemRow(mthing, MT_RING, 5, 0, 64*FRACUNIT, 0, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 5, 0, 64*FRACUNIT, 0); return; case 601: // 5 vertical rings (red spring) - P_SpawnSingularItemRow(mthing, MT_RING, 5, 0, 128*FRACUNIT, 0, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 5, 0, 128*FRACUNIT, 0); return; case 602: // 5 diagonal rings (yellow spring) - P_SpawnSingularItemRow(mthing, MT_RING, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle); return; case 603: // 10 diagonal rings (red spring) - P_SpawnSingularItemRow(mthing, MT_RING, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle); return; case 604: // Circle of rings (8 items) case 605: // Circle of rings (16 items) @@ -12424,7 +12381,7 @@ void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) INT32 numitems = (mthing->type & 1) ? 16 : 8; fixed_t size = (mthing->type & 1) ? 192*FRACUNIT : 96*FRACUNIT; mobjtype_t itemtypes[1] = { MT_RING }; - P_SpawnItemCircle(mthing, itemtypes, 1, numitems, size, bonustime); + P_SpawnItemCircle(mthing, itemtypes, 1, numitems, size); return; } default: diff --git a/src/p_mobj.h b/src/p_mobj.h index f9b87db97..16055907b 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -247,6 +247,8 @@ typedef enum MFE_TRACERANGLE = 1<<11, // SRB2Kart: The mobj just hit & bounced off a wall, this is cleared on next frame MFE_JUSTBOUNCEDWALL = 1<<12, + // SRB2Kart: In damage hitlag (displays different visual efx) + MFE_DAMAGEHITLAG = 1<<13, // free: to and including 1<<15 } mobjeflag_t; @@ -487,7 +489,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt mobj_t *P_SpawnMapThing(mapthing_t *mthing); void P_SpawnHoop(mapthing_t *mthing); -void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime); +void P_SpawnItemPattern(mapthing_t *mthing); void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle); void P_SpawnPrecipitation(void); void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter); diff --git a/src/p_saveg.c b/src/p_saveg.c index 87646d225..ce1093061 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -73,7 +73,6 @@ static inline void P_ArchivePlayer(void) WRITEUINT8(save_p, numgameovers); WRITESINT8(save_p, pllives); WRITEUINT32(save_p, player->score); - WRITEINT32(save_p, player->continues); } static inline void P_UnArchivePlayer(void) @@ -84,7 +83,6 @@ static inline void P_UnArchivePlayer(void) savedata.numgameovers = READUINT8(save_p); savedata.lives = READSINT8(save_p); savedata.score = READUINT32(save_p); - savedata.continues = READINT32(save_p); } static void P_NetArchivePlayers(void) @@ -129,18 +127,15 @@ static void P_NetArchivePlayers(void) WRITEANGLE(save_p, players[i].aiming); WRITEANGLE(save_p, players[i].drawangle); WRITEANGLE(save_p, players[i].viewrollangle); + WRITEANGLE(save_p, players[i].tilt); WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); - WRITEINT16(save_p, players[i].rings); - WRITEINT16(save_p, players[i].spheres); - - for (j = 0; j < NUMPOWERS; j++) - WRITEUINT16(save_p, players[i].powers[j]); WRITEUINT8(save_p, players[i].playerstate); WRITEUINT32(save_p, players[i].pflags); WRITEUINT8(save_p, players[i].panim); WRITEUINT8(save_p, players[i].spectator); + WRITEUINT32(save_p, players[i].spectatewait); WRITEUINT16(save_p, players[i].flashpal); WRITEUINT16(save_p, players[i].flashcount); @@ -149,23 +144,12 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].skin); WRITEUINT32(save_p, players[i].availabilities); WRITEUINT32(save_p, players[i].score); - WRITEFIXED(save_p, players[i].dashspeed); WRITESINT8(save_p, players[i].lives); - WRITEUINT8(save_p, players[i].lostlife); - WRITESINT8(save_p, players[i].continues); WRITESINT8(save_p, players[i].xtralife); - WRITEUINT8(save_p, players[i].gotcontinue); WRITEFIXED(save_p, players[i].speed); - WRITEUINT8(save_p, players[i].secondjump); - WRITEUINT8(save_p, players[i].fly1); - WRITEUINT8(save_p, players[i].scoreadd); - WRITEUINT32(save_p, players[i].glidetime); - WRITEUINT8(save_p, players[i].climbing); + WRITEFIXED(save_p, players[i].lastspeed); WRITEINT32(save_p, players[i].deadtimer); WRITEUINT32(save_p, players[i].exiting); - WRITEUINT8(save_p, players[i].homing); - WRITEUINT32(save_p, players[i].dashmode); - WRITEUINT32(save_p, players[i].skidtime); //////////////////////////// // Conveyor Belt Movement // @@ -175,59 +159,14 @@ static void P_NetArchivePlayers(void) WRITEFIXED(save_p, players[i].rmomx); // "Real" momx (momx - cmomx) WRITEFIXED(save_p, players[i].rmomy); // "Real" momy (momy - cmomy) - ///////////////////// - // Race Mode Stuff // - ///////////////////// - WRITEINT16(save_p, players[i].numboxes); WRITEINT16(save_p, players[i].totalring); WRITEUINT32(save_p, players[i].realtime); WRITEUINT8(save_p, players[i].laps); WRITEINT32(save_p, players[i].starpostnum); - //////////////////// - // CTF Mode Stuff // - //////////////////// - WRITEINT32(save_p, players[i].ctfteam); - WRITEUINT16(save_p, players[i].gotflag); + WRITEUINT8(save_p, players[i].ctfteam); - WRITEINT32(save_p, players[i].weapondelay); - WRITEINT32(save_p, players[i].tossdelay); - - WRITEANGLE(save_p, players[i].angle_pos); - WRITEANGLE(save_p, players[i].old_angle_pos); - - WRITEINT32(save_p, players[i].flyangle); - WRITEUINT32(save_p, players[i].drilltimer); - WRITEINT32(save_p, players[i].linkcount); - WRITEUINT32(save_p, players[i].linktimer); - WRITEINT32(save_p, players[i].anotherflyangle); - WRITEUINT32(save_p, players[i].nightstime); - WRITEUINT32(save_p, players[i].bumpertime); - WRITEINT32(save_p, players[i].drillmeter); - WRITEUINT8(save_p, players[i].drilldelay); - WRITEUINT8(save_p, players[i].bonustime); - WRITEFIXED(save_p, players[i].oldscale); - WRITEUINT8(save_p, players[i].mare); - WRITEUINT8(save_p, players[i].marelap); - WRITEUINT8(save_p, players[i].marebonuslap); - WRITEUINT32(save_p, players[i].marebegunat); - WRITEUINT32(save_p, players[i].startedtime); - WRITEUINT32(save_p, players[i].finishedtime); - WRITEUINT32(save_p, players[i].lapbegunat); - WRITEUINT32(save_p, players[i].lapstartedtime); - WRITEINT16(save_p, players[i].finishedspheres); - WRITEINT16(save_p, players[i].finishedrings); - WRITEUINT32(save_p, players[i].marescore); - WRITEUINT32(save_p, players[i].lastmarescore); - WRITEUINT32(save_p, players[i].totalmarescore); - WRITEUINT8(save_p, players[i].lastmare); - WRITEUINT8(save_p, players[i].lastmarelap); - WRITEUINT8(save_p, players[i].lastmarebonuslap); - WRITEUINT8(save_p, players[i].totalmarelap); - WRITEUINT8(save_p, players[i].totalmarebonuslap); - WRITEINT32(save_p, players[i].maxlink); - WRITEUINT8(save_p, players[i].texttimer); - WRITEUINT8(save_p, players[i].textvar); + WRITEUINT8(save_p, players[i].checkskip); if (players[i].awayviewmobj) flags |= AWAYVIEW; @@ -241,10 +180,6 @@ static void P_NetArchivePlayers(void) WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastlinehit); - WRITEUINT32(save_p, players[i].losstime); - - WRITEUINT8(save_p, players[i].timeshit); - WRITEINT32(save_p, players[i].onconveyor); WRITEUINT32(save_p, players[i].jointime); @@ -274,32 +209,116 @@ static void P_NetArchivePlayers(void) if (flags & FOLLOWER) WRITEUINT32(save_p, players[i].follower->mobjnum); - for (j = 0; j < NUMKARTSTUFF; j++) - WRITEINT32(save_p, players[i].kartstuff[j]); + WRITEUINT16(save_p, players[i].nocontrol); + WRITEUINT8(save_p, players[i].carry); + WRITEUINT16(save_p, players[i].dye); + WRITEUINT8(save_p, players[i].position); + WRITEUINT8(save_p, players[i].oldposition); + WRITEUINT8(save_p, players[i].positiondelay); WRITEUINT32(save_p, players[i].distancetofinish); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); - WRITEUINT32(save_p, players[i].airtime); - WRITEUINT8(save_p, players[i].driftInput); - WRITEUINT8(save_p, players[i].airFailsafe); - - WRITEUINT8(save_p, players[i].trickpanel); - WRITEUINT8(save_p, players[i].trickdelay); - WRITEUINT32(save_p, players[i].trickmomx); - WRITEUINT32(save_p, players[i].trickmomy); - WRITEUINT32(save_p, players[i].trickmomz); - - WRITEUINT8(save_p, players[i].bumpers); - WRITEINT16(save_p, players[i].karmadelay); - WRITEUINT8(save_p, players[i].eliminated); + WRITEUINT8(save_p, players[i].startboost); + WRITEUINT16(save_p, players[i].flashing); + WRITEUINT16(save_p, players[i].spinouttimer); + WRITEUINT8(save_p, players[i].spinouttype); + WRITEUINT8(save_p, players[i].instashield); + WRITEUINT8(save_p, players[i].wipeoutslow); + WRITEUINT8(save_p, players[i].justbumped); WRITEUINT8(save_p, players[i].tumbleBounces); WRITEUINT16(save_p, players[i].tumbleHeight); - WRITEUINT8(save_p, players[i].tumbleLastBounce); - WRITEUINT8(save_p, players[i].tumbleSound); + + WRITESINT8(save_p, players[i].drift); + WRITEFIXED(save_p, players[i].driftcharge); + WRITEUINT8(save_p, players[i].driftboost); + WRITEUINT8(save_p, players[i].strongdriftboost); + + WRITESINT8(save_p, players[i].aizdriftstrat); + WRITEINT32(save_p, players[i].aizdrifttilt); + WRITEINT32(save_p, players[i].aizdriftturn); + + WRITEFIXED(save_p, players[i].offroad); + WRITEUINT8(save_p, players[i].waterskip); + + WRITEUINT16(save_p, players[i].tiregrease); + WRITEUINT16(save_p, players[i].springstars); + WRITEUINT16(save_p, players[i].springcolor); + WRITEUINT8(save_p, players[i].dashpadcooldown); + + WRITEUINT16(save_p, players[i].spindash); + WRITEFIXED(save_p, players[i].spindashspeed); + WRITEUINT8(save_p, players[i].spindashboost); + + WRITEUINT8(save_p, players[i].numboosts); + WRITEFIXED(save_p, players[i].boostpower); + WRITEFIXED(save_p, players[i].speedboost); + WRITEFIXED(save_p, players[i].accelboost); + WRITEFIXED(save_p, players[i].handleboost); + WRITEANGLE(save_p, players[i].boostangle); + + WRITEFIXED(save_p, players[i].draftpower); + WRITEUINT16(save_p, players[i].draftleeway); + WRITESINT8(save_p, players[i].lastdraft); + + WRITEUINT16(save_p, players[i].itemroulette); + WRITEUINT8(save_p, players[i].roulettetype); + + WRITESINT8(save_p, players[i].itemtype); + WRITEUINT8(save_p, players[i].itemamount); + WRITESINT8(save_p, players[i].throwdir); + + WRITEUINT8(save_p, players[i].sadtimer); + + WRITESINT8(save_p, players[i].rings); + WRITEUINT8(save_p, players[i].pickuprings); + WRITEUINT8(save_p, players[i].ringdelay); + WRITEUINT16(save_p, players[i].ringboost); + WRITEUINT8(save_p, players[i].sparkleanim); + WRITEUINT16(save_p, players[i].superring); + + WRITEUINT8(save_p, players[i].curshield); + WRITEUINT8(save_p, players[i].bubblecool); + WRITEUINT8(save_p, players[i].bubbleblowup); + WRITEUINT16(save_p, players[i].flamedash); + WRITEUINT16(save_p, players[i].flamemeter); + WRITEUINT8(save_p, players[i].flamelength); + + WRITEUINT16(save_p, players[i].hyudorotimer); + WRITESINT8(save_p, players[i].stealingtimer); + + WRITEUINT16(save_p, players[i].sneakertimer); + WRITEUINT8(save_p, players[i].numsneakers); + WRITEUINT8(save_p, players[i].floorboost); + + WRITEINT16(save_p, players[i].growshrinktimer); + WRITEUINT16(save_p, players[i].rocketsneakertimer); + WRITEUINT16(save_p, players[i].invincibilitytimer); + + WRITEUINT8(save_p, players[i].eggmanexplode); + WRITESINT8(save_p, players[i].eggmanblame); + + WRITEUINT8(save_p, players[i].bananadrag); + + WRITESINT8(save_p, players[i].lastjawztarget); + WRITEUINT8(save_p, players[i].jawztargetdelay); + + WRITEUINT8(save_p, players[i].trickpanel); + WRITEUINT8(save_p, players[i].tricktime); + WRITEUINT32(save_p, players[i].trickboostpower); + WRITEUINT8(save_p, players[i].trickboostdecay); + WRITEUINT8(save_p, players[i].trickboost); + + WRITEUINT32(save_p, players[i].roundscore); + WRITEUINT8(save_p, players[i].emeralds); + WRITEUINT8(save_p, players[i].bumpers); + WRITEINT16(save_p, players[i].karmadelay); + WRITEUINT32(save_p, players[i].overtimekarma); + WRITEINT16(save_p, players[i].spheres); WRITESINT8(save_p, players[i].glanceDir); + WRITEUINT8(save_p, players[i].tripWireState); WRITEUINT8(save_p, players[i].typing_timer); WRITEUINT8(save_p, players[i].typing_duration); @@ -314,6 +333,7 @@ static void P_NetArchivePlayers(void) WRITEFIXED(save_p, players[i].respawn.pointz); WRITEUINT8(save_p, players[i].respawn.flip); WRITEUINT32(save_p, players[i].respawn.timer); + WRITEUINT32(save_p, players[i].respawn.airtimer); WRITEUINT32(save_p, players[i].respawn.distanceleft); WRITEUINT32(save_p, players[i].respawn.dropdash); @@ -324,6 +344,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].botvars.itemdelay); WRITEUINT32(save_p, players[i].botvars.itemconfirm); WRITESINT8(save_p, players[i].botvars.turnconfirm); + WRITEUINT32(save_p, players[i].botvars.spindashconfirm); } } @@ -370,18 +391,15 @@ static void P_NetUnArchivePlayers(void) players[i].aiming = READANGLE(save_p); players[i].drawangle = READANGLE(save_p); players[i].viewrollangle = READANGLE(save_p); + players[i].tilt = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); - players[i].rings = READINT16(save_p); - players[i].spheres = READINT16(save_p); - - for (j = 0; j < NUMPOWERS; j++) - players[i].powers[j] = READUINT16(save_p); players[i].playerstate = READUINT8(save_p); players[i].pflags = READUINT32(save_p); players[i].panim = READUINT8(save_p); players[i].spectator = READUINT8(save_p); + players[i].spectatewait = READUINT32(save_p); players[i].flashpal = READUINT16(save_p); players[i].flashcount = READUINT16(save_p); @@ -390,23 +408,12 @@ static void P_NetUnArchivePlayers(void) players[i].skin = READINT32(save_p); players[i].availabilities = READUINT32(save_p); players[i].score = READUINT32(save_p); - players[i].dashspeed = READFIXED(save_p); // dashing speed players[i].lives = READSINT8(save_p); - players[i].lostlife = (boolean)READUINT8(save_p); - players[i].continues = READSINT8(save_p); // continues that player has acquired players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter - players[i].gotcontinue = READUINT8(save_p); // got continue from stage players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values) - players[i].secondjump = READUINT8(save_p); - players[i].fly1 = READUINT8(save_p); // Tails flying - players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus - players[i].glidetime = READUINT32(save_p); // Glide counter for thrust - players[i].climbing = READUINT8(save_p); // Climbing on the wall + players[i].lastspeed = READFIXED(save_p); players[i].deadtimer = READINT32(save_p); // End game if game over lasts too long players[i].exiting = READUINT32(save_p); // Exitlevel timer - players[i].homing = READUINT8(save_p); // Are you homing? - players[i].dashmode = READUINT32(save_p); // counter for dashmode ability - players[i].skidtime = READUINT32(save_p); // Skid timer //////////////////////////// // Conveyor Belt Movement // @@ -416,67 +423,18 @@ static void P_NetUnArchivePlayers(void) players[i].rmomx = READFIXED(save_p); // "Real" momx (momx - cmomx) players[i].rmomy = READFIXED(save_p); // "Real" momy (momy - cmomy) - ///////////////////// - // Race Mode Stuff // - ///////////////////// - players[i].numboxes = READINT16(save_p); // Number of item boxes obtained for Race Mode - players[i].totalring = READINT16(save_p); // Total number of rings obtained for Race Mode + players[i].totalring = READINT16(save_p); // Total number of rings obtained for GP players[i].realtime = READUINT32(save_p); // integer replacement for leveltime players[i].laps = READUINT8(save_p); // Number of laps (optional) players[i].starpostnum = READINT32(save_p); - //////////////////// - // CTF Mode Stuff // - //////////////////// - players[i].ctfteam = READINT32(save_p); // 1 == Red, 2 == Blue - players[i].gotflag = READUINT16(save_p); // 1 == Red, 2 == Blue Do you have the flag? + players[i].ctfteam = READUINT8(save_p); // 1 == Red, 2 == Blue - players[i].weapondelay = READINT32(save_p); - players[i].tossdelay = READINT32(save_p); - - players[i].angle_pos = READANGLE(save_p); - players[i].old_angle_pos = READANGLE(save_p); - - players[i].flyangle = READINT32(save_p); - players[i].drilltimer = READUINT32(save_p); - players[i].linkcount = READINT32(save_p); - players[i].linktimer = READUINT32(save_p); - players[i].anotherflyangle = READINT32(save_p); - players[i].nightstime = READUINT32(save_p); - players[i].bumpertime = READUINT32(save_p); - players[i].drillmeter = READINT32(save_p); - players[i].drilldelay = READUINT8(save_p); - players[i].bonustime = (boolean)READUINT8(save_p); - players[i].oldscale = READFIXED(save_p); - players[i].mare = READUINT8(save_p); - players[i].marelap = READUINT8(save_p); - players[i].marebonuslap = READUINT8(save_p); - players[i].marebegunat = READUINT32(save_p); - players[i].startedtime = READUINT32(save_p); - players[i].finishedtime = READUINT32(save_p); - players[i].lapbegunat = READUINT32(save_p); - players[i].lapstartedtime = READUINT32(save_p); - players[i].finishedspheres = READINT16(save_p); - players[i].finishedrings = READINT16(save_p); - players[i].marescore = READUINT32(save_p); - players[i].lastmarescore = READUINT32(save_p); - players[i].totalmarescore = READUINT32(save_p); - players[i].lastmare = READUINT8(save_p); - players[i].lastmarelap = READUINT8(save_p); - players[i].lastmarebonuslap = READUINT8(save_p); - players[i].totalmarelap = READUINT8(save_p); - players[i].totalmarebonuslap = READUINT8(save_p); - players[i].maxlink = READINT32(save_p); - players[i].texttimer = READUINT8(save_p); - players[i].textvar = READUINT8(save_p); + players[i].checkskip = READUINT8(save_p); players[i].lastsidehit = READINT16(save_p); players[i].lastlinehit = READINT16(save_p); - players[i].losstime = READUINT32(save_p); - - players[i].timeshit = READUINT8(save_p); - players[i].onconveyor = READINT32(save_p); players[i].jointime = READUINT32(save_p); @@ -507,32 +465,116 @@ static void P_NetUnArchivePlayers(void) if (flags & FOLLOWER) players[i].follower = (mobj_t *)(size_t)READUINT32(save_p); - for (j = 0; j < NUMKARTSTUFF; j++) - players[i].kartstuff[j] = READINT32(save_p); + players[i].nocontrol = READUINT16(save_p); + players[i].carry = READUINT8(save_p); + players[i].dye = READUINT16(save_p); + players[i].position = READUINT8(save_p); + players[i].oldposition = READUINT8(save_p); + players[i].positiondelay = READUINT8(save_p); players[i].distancetofinish = READUINT32(save_p); players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); - players[i].airtime = READUINT32(save_p); - players[i].driftInput = (boolean)READUINT8(save_p); - players[i].airFailsafe = (boolean)READUINT8(save_p); - - players[i].trickpanel = READUINT8(save_p); - players[i].trickdelay = READUINT8(save_p); - players[i].trickmomx = READUINT32(save_p); - players[i].trickmomy = READUINT32(save_p); - players[i].trickmomz = READUINT32(save_p); - - players[i].bumpers = READUINT8(save_p); - players[i].karmadelay = READINT16(save_p); - players[i].eliminated = (boolean)READUINT8(save_p); + players[i].startboost = READUINT8(save_p); + players[i].flashing = READUINT16(save_p); + players[i].spinouttimer = READUINT16(save_p); + players[i].spinouttype = READUINT8(save_p); + players[i].instashield = READUINT8(save_p); + players[i].wipeoutslow = READUINT8(save_p); + players[i].justbumped = READUINT8(save_p); players[i].tumbleBounces = READUINT8(save_p); players[i].tumbleHeight = READUINT16(save_p); - players[i].tumbleLastBounce = (boolean)READUINT8(save_p); - players[i].tumbleSound = (boolean)READUINT8(save_p); + + players[i].drift = READSINT8(save_p); + players[i].driftcharge = READFIXED(save_p); + players[i].driftboost = READUINT8(save_p); + players[i].strongdriftboost = READUINT8(save_p); + + players[i].aizdriftstrat = READSINT8(save_p); + players[i].aizdrifttilt = READINT32(save_p); + players[i].aizdriftturn = READINT32(save_p); + + players[i].offroad = READFIXED(save_p); + players[i].waterskip = READUINT8(save_p); + + players[i].tiregrease = READUINT16(save_p); + players[i].springstars = READUINT16(save_p); + players[i].springcolor = READUINT16(save_p); + players[i].dashpadcooldown = READUINT8(save_p); + + players[i].spindash = READUINT16(save_p); + players[i].spindashspeed = READFIXED(save_p); + players[i].spindashboost = READUINT8(save_p); + + players[i].numboosts = READUINT8(save_p); + players[i].boostpower = READFIXED(save_p); + players[i].speedboost = READFIXED(save_p); + players[i].accelboost = READFIXED(save_p); + players[i].handleboost = READFIXED(save_p); + players[i].boostangle = READANGLE(save_p); + + players[i].draftpower = READFIXED(save_p); + players[i].draftleeway = READUINT16(save_p); + players[i].lastdraft = READSINT8(save_p); + + players[i].itemroulette = READUINT16(save_p); + players[i].roulettetype = READUINT8(save_p); + + players[i].itemtype = READSINT8(save_p); + players[i].itemamount = READUINT8(save_p); + players[i].throwdir = READSINT8(save_p); + + players[i].sadtimer = READUINT8(save_p); + + players[i].rings = READSINT8(save_p); + players[i].pickuprings = READUINT8(save_p); + players[i].ringdelay = READUINT8(save_p); + players[i].ringboost = READUINT16(save_p); + players[i].sparkleanim = READUINT8(save_p); + players[i].superring = READUINT16(save_p); + + players[i].curshield = READUINT8(save_p); + players[i].bubblecool = READUINT8(save_p); + players[i].bubbleblowup = READUINT8(save_p); + players[i].flamedash = READUINT16(save_p); + players[i].flamemeter = READUINT16(save_p); + players[i].flamelength = READUINT8(save_p); + + players[i].hyudorotimer = READUINT16(save_p); + players[i].stealingtimer = READSINT8(save_p); + + players[i].sneakertimer = READUINT16(save_p); + players[i].numsneakers = READUINT8(save_p); + players[i].floorboost = READUINT8(save_p); + + players[i].growshrinktimer = READINT16(save_p); + players[i].rocketsneakertimer = READUINT16(save_p); + players[i].invincibilitytimer = READUINT16(save_p); + + players[i].eggmanexplode = READUINT8(save_p); + players[i].eggmanblame = READSINT8(save_p); + + players[i].bananadrag = READUINT8(save_p); + + players[i].lastjawztarget = READSINT8(save_p); + players[i].jawztargetdelay = READUINT8(save_p); + + players[i].trickpanel = READUINT8(save_p); + players[i].tricktime = READUINT8(save_p); + players[i].trickboostpower = READUINT32(save_p); + players[i].trickboostdecay = READUINT8(save_p); + players[i].trickboost = READUINT8(save_p); + + players[i].roundscore = READUINT32(save_p); + players[i].emeralds = READUINT8(save_p); + players[i].bumpers = READUINT8(save_p); + players[i].karmadelay = READINT16(save_p); + players[i].overtimekarma = READUINT32(save_p); + players[i].spheres = READINT16(save_p); players[i].glanceDir = READSINT8(save_p); + players[i].tripWireState = READUINT8(save_p); players[i].typing_timer = READUINT8(save_p); players[i].typing_duration = READUINT8(save_p); @@ -547,6 +589,7 @@ static void P_NetUnArchivePlayers(void) players[i].respawn.pointz = READFIXED(save_p); players[i].respawn.flip = (boolean)READUINT8(save_p); players[i].respawn.timer = READUINT32(save_p); + players[i].respawn.airtimer = READUINT32(save_p); players[i].respawn.distanceleft = READUINT32(save_p); players[i].respawn.dropdash = READUINT32(save_p); @@ -557,6 +600,7 @@ static void P_NetUnArchivePlayers(void) players[i].botvars.itemdelay = READUINT32(save_p); players[i].botvars.itemconfirm = READUINT32(save_p); players[i].botvars.turnconfirm = READSINT8(save_p); + players[i].botvars.spindashconfirm = READUINT32(save_p); //players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point } @@ -1921,7 +1965,9 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, slope->normal.z); } if (diff2 & MD2_HITLAG) + { WRITEINT32(save_p, mobj->hitlag); + } WRITEUINT32(save_p, mobj->mobjnum); } @@ -3013,7 +3059,9 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) slope->normal.z = READFIXED(save_p); } if (diff2 & MD2_HITLAG) + { mobj->hitlag = READINT32(save_p); + } if (diff & MD_REDFLAG) { diff --git a/src/p_saveg.h b/src/p_saveg.h index a938b4791..27865bf50 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -33,7 +33,6 @@ typedef struct UINT8 skin; INT32 score; INT32 lives; - INT32 continues; UINT16 emeralds; UINT8 numgameovers; } savedata_t; diff --git a/src/p_setup.c b/src/p_setup.c index 9ce5ca374..fab5429b8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -659,9 +659,7 @@ flatfound: levelflat->u.flat.baselumpnum = LUMPERROR; } -#ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); -#endif return ( numlevelflats++ ); } @@ -758,7 +756,7 @@ void P_ReloadRings(void) else if (mt->type >= 600 && mt->type <= 609) // Item patterns { mt->mobj = NULL; - P_SpawnItemPattern(mt, true); + P_SpawnItemPattern(mt); } } for (i = 0; i < numHoops; i++) @@ -867,7 +865,7 @@ static void P_SpawnMapThings(boolean spawnemblems) mt->mobj = NULL; if (mt->type >= 600 && mt->type <= 609) // item patterns - P_SpawnItemPattern(mt, false); + P_SpawnItemPattern(mt); else if (mt->type == 1705 || mt->type == 1713) // hoops P_SpawnHoop(mt); else // Everything else @@ -1046,6 +1044,8 @@ static void P_InitializeLinedef(line_t *ld) ld->validcount = 0; ld->polyobj = NULL; + ld->tripwire = false; + ld->text = NULL; ld->callcount = 0; @@ -1277,7 +1277,6 @@ static void P_LoadSidedefs(UINT8 *data) case 335: // Trigger linedef executor: Object dye - Each time case 336: // Trigger linedef executor: Object dye - Once case 425: // Calls P_SetMobjState on calling mobj - case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors case 461: // Spawns an object on the map based on texture offsets case 463: // Colorizes an object @@ -1939,11 +1938,23 @@ static void P_ProcessLinedefsAfterSidedefs(void) { size_t i = numlines; register line_t *ld = lines; + + const INT32 TEX_TRIPWIRE = R_TextureNumForName("TRIPWIRE"); + const INT32 TEX_4RIPWIRE = R_TextureNumForName("4RIPWIRE"); + for (; i--; ld++) { + INT32 midtexture = sides[ld->sidenum[0]].midtexture; + ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; + if (midtexture == TEX_TRIPWIRE || + midtexture == TEX_4RIPWIRE) + { + ld->tripwire = true; + } + switch (ld->special) { // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. @@ -3449,42 +3460,13 @@ static void P_InitLevelSettings(void) p++; if (grandprixinfo.gp == false) - { players[i].lives = 3; - players[i].xtralife = 0; - players[i].totalring = 0; - } - players[i].realtime = racecountdown = exitcountdown = 0; - curlap = bestlap = 0; // SRB2Kart - - players[i].lostlife = false; - players[i].gotcontinue = false; - - players[i].deadtimer = players[i].numboxes = players[i].laps = 0; - players[i].aiming = 0; - players[i].pflags &= ~PF_GAMETYPEOVER; + G_PlayerReborn(i, true); } racecountdown = exitcountdown = exitfadestarted = 0; - - for (i = 0; i < MAXPLAYERS; i++) - { - G_PlayerReborn(i, true); - - // obliteration station... - players[i].numboxes = players[i].totalring =\ - players[i].laps = players[i].marescore = players[i].lastmarescore =\ - players[i].mare = players[i].exiting = 0; - - players[i].drillmeter = 40*20; - - // hit these too - players[i].pflags &= ~(PF_GAMETYPEOVER); - - // Wipe follower from existence to avoid crashes - players[i].follower = NULL; - } + curlap = bestlap = 0; // SRB2Kart // SRB2Kart: map load variables if (grandprixinfo.gp == true) @@ -3759,10 +3741,10 @@ static void P_InitCamera(void) { UINT8 i; - for (i = 0; i <= splitscreen; i++) + for (i = 0; i <= r_splitscreen; i++) { - P_SetupCamera(i, &camera[i]); - displayplayers[i] = g_localplayers[i]; // Start with your OWN view, please! + //displayplayers[i] = g_localplayers[i]; // Start with your OWN view, please! + P_SetupCamera(displayplayers[i], &camera[i]); } } } @@ -4011,8 +3993,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) F_RunWipe(wipedefs[wipe_level_toblack], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false); } - if (!titlemapinaction) - wipegamestate = GS_LEVEL; + /*if (!titlemapinaction) + wipegamestate = GS_LEVEL;*/ // Close text prompt before freeing the old level F_EndTextPrompt(false, true); @@ -4044,7 +4026,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) if (!fromnetsave && savedata.lives > 0) { numgameovers = savedata.numgameovers; - players[consoleplayer].continues = savedata.continues; players[consoleplayer].lives = savedata.lives; players[consoleplayer].score = savedata.score; emeralds = savedata.emeralds; diff --git a/src/p_setup.h b/src/p_setup.h index 6caa453e4..0a7587ec0 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -116,7 +116,6 @@ void P_DeleteFlickies(INT16 i); // Needed for NiGHTS void P_ReloadRings(void); -void P_SwitchSpheresBonusMode(boolean bonustime); void P_DeleteGrades(INT16 i); void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext); UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare); diff --git a/src/p_slopes.c b/src/p_slopes.c index 80b1a79e1..d1e8f5f54 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -850,7 +850,9 @@ void P_SlopeLaunch(mobj_t *mo) mo->standingslope = NULL; if (mo->player) - mo->player->powers[pw_justlaunched] = 1; + { + mo->player->stairjank = 0; // fuck you + } } // @@ -895,9 +897,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) { thing->standingslope = slope; P_SetPitchRollFromSlope(thing, slope); - - if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) - thing->momz = -P_MobjFlip(thing); + thing->momz = -P_MobjFlip(thing); } return; } @@ -913,8 +913,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momy = mom.y; thing->standingslope = slope; P_SetPitchRollFromSlope(thing, slope); - if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) - thing->momz = -P_MobjFlip(thing); + thing->momz = -P_MobjFlip(thing); } } diff --git a/src/p_spec.c b/src/p_spec.c index 063d7e23e..07825759c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1552,7 +1552,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller case 336: // object dye - once { INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture; - UINT16 color = (actor->player ? actor->player->powers[pw_dye] : actor->color); + UINT16 color = (actor->player ? actor->player->dye : actor->color); boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false); if (invert ^ (triggercolor != color)) @@ -1872,7 +1872,7 @@ static void K_HandleLapIncrement(player_t *player) player->karthud[khud_laphand] = 3; else { - if (nump > 2 && player->kartstuff[k_position] == 1) // 1st place in 1v1 uses thumbs up + if (nump > 2 && player->position == 1) // 1st place in 1v1 uses thumbs up player->karthud[khud_laphand] = 1; else player->karthud[khud_laphand] = 2; @@ -1895,8 +1895,11 @@ static void K_HandleLapIncrement(player_t *player) if (rainbowstartavailable == true) { S_StartSound(player->mo, sfx_s23c); - player->kartstuff[k_startboost] = 125; - K_SpawnDriftBoostExplosion(player, 3); + player->startboost = 125; + + K_SpawnDriftBoostExplosion(player, 4); + K_SpawnDriftElectricSparks(player); + rainbowstartavailable = false; } @@ -1920,7 +1923,7 @@ static void K_HandleLapIncrement(player_t *player) } else { - if ((player->laps > (UINT8)(cv_numlaps.value)) && (player->kartstuff[k_position] == 1)) + if ((player->laps > (UINT8)(cv_numlaps.value)) && (player->position == 1)) { // opponent finished S_StartSound(NULL, sfx_s253); @@ -2011,10 +2014,16 @@ static void K_HandleLapDecrement(player_t *player) void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing) { // only used for the players currently - if (!(thing && thing->player && !thing->player->spectator && !(thing->player->pflags & PF_GAMETYPEOVER))) + if (!(thing && thing->player && !thing->player->spectator && !(thing->player->pflags & PF_NOCONTEST))) return; { player_t *player = thing->player; + + if (P_IsLineTripWire(line)) + { + K_ApplyTripWire(player, TRIP_PASSED); + } + switch (line->special) { case 2001: // Finish Line @@ -2779,27 +2788,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) mo->flags2 |= MF2_OBJECTFLIP; break; - case 434: // Custom Power - if (mo && mo->player) - { - mobj_t *dummy = P_SpawnMobj(mo->x, mo->y, mo->z, MT_NULL); - - var1 = sides[line->sidenum[0]].toptexture; //(line->dx>>FRACBITS)-1; - - if (line->sidenum[1] != 0xffff && line->flags & ML_BLOCKPLAYERS) // read power from back sidedef - var2 = sides[line->sidenum[1]].toptexture; - else if (line->flags & ML_NOCLIMB) // 'Infinite' - var2 = UINT16_MAX; - else - var2 = sides[line->sidenum[0]].textureoffset>>FRACBITS; - - P_SetTarget(&dummy->target, mo); - A_CustomPower(dummy); - - P_RemoveMobj(dummy); - } - break; - case 435: // Change scroller direction { scroll_t *scroller; @@ -2865,7 +2853,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) fractime = 1; //instantly wears off upon leaving if (line->flags & ML_NOCLIMB) fractime |= 1<<15; //more crazy &ing, as if music stuff wasn't enough - mo->player->powers[pw_nocontrol] = fractime; + mo->player->nocontrol = fractime; } break; @@ -3896,7 +3884,7 @@ void P_SetupSignExit(player_t *player) thinker_t *think; INT32 numfound = 0; - if (player->kartstuff[k_position] != 1) + if (player->position != 1) return; for (; node; node = node->m_thinglist_next) @@ -4538,7 +4526,7 @@ DoneSection2: } player->trickpanel = 1; - player->trickdelay = 1; + player->pflags |= PF_TRICKDELAY; K_DoPogoSpring(player->mo, upwards, 1); // Reduce speed @@ -4560,9 +4548,9 @@ DoneSection2: break; case 5: // Speed pad - if (player->kartstuff[k_floorboost] != 0) + if (player->floorboost != 0) { - player->kartstuff[k_floorboost] = 2; + player->floorboost = 2; break; } @@ -4594,9 +4582,9 @@ DoneSection2: P_InstaThrust(player->mo, lineangle, max(linespeed, 2*playerspeed)); - player->kartstuff[k_dashpadcooldown] = TICRATE/3; + player->dashpadcooldown = TICRATE/3; player->trickpanel = 0; - player->kartstuff[k_floorboost] = 2; + player->floorboost = 2; S_StartSound(player->mo, sfx_cdfm62); } break; @@ -4669,10 +4657,10 @@ DoneSection2: case 6: // SRB2kart 190117 - Sneaker Panel if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { - if (!player->kartstuff[k_floorboost]) - player->kartstuff[k_floorboost] = 3; + if (!player->floorboost) + player->floorboost = 3; else - player->kartstuff[k_floorboost] = 2; + player->floorboost = 2; K_DoSneaker(player, 0); } break; @@ -4688,10 +4676,7 @@ DoneSection2: mobj_t *waypoint = NULL; angle_t an; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) - break; - - if (player->powers[pw_ignorelatch] & (1<<15)) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->carry == CR_ZOOMTUBE) break; // Find line #3 tagged to this sector @@ -4731,10 +4716,8 @@ DoneSection2: break; // behind back P_SetTarget(&player->mo->tracer, waypoint); - player->powers[pw_carry] = CR_ZOOMTUBE; + player->carry = CR_ZOOMTUBE; player->speed = speed; - - player->pflags &= ~(PF_SLIDING); } break; @@ -4746,7 +4729,7 @@ DoneSection2: mobj_t *waypoint = NULL; angle_t an; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->carry == CR_ZOOMTUBE) break; // Find line #11 tagged to this sector @@ -4786,7 +4769,7 @@ DoneSection2: break; // behind back P_SetTarget(&player->mo->tracer, waypoint); - player->powers[pw_carry] = CR_ZOOMTUBE; + player->carry = CR_ZOOMTUBE; player->speed = speed; } break; @@ -8527,8 +8510,8 @@ void T_Pusher(pusher_t *p) continue; if (thing->player && (thing->state == &states[thing->info->painstate]) - && (thing->player->powers[pw_flashing] > (K_GetKartFlashing(thing->player)/4)*3 - && thing->player->powers[pw_flashing] <= K_GetKartFlashing(thing->player))) + && (thing->player->flashing > (K_GetKartFlashing(thing->player)/4)*3 + && thing->player->flashing <= K_GetKartFlashing(thing->player))) continue; inFOF = touching = moved = false; @@ -8656,11 +8639,11 @@ void T_Pusher(pusher_t *p) if (moved) { - if (p->slider && thing->player) + if (p->slider && thing->player && !thing->player->carry) { P_ResetPlayer (thing->player); - thing->player->pflags |= PF_SLIDING; + thing->player->carry = CR_SLIDING; thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); if (!demo.playback) diff --git a/src/p_tick.c b/src/p_tick.c index b79a1fa29..be82b9d40 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -36,6 +36,11 @@ tic_t leveltime; +INT32 P_AltFlip(INT32 n, tic_t tics) +{ + return leveltime % (2 * tics) < tics ? n : -(n); +} + // // THINKERS // All thinkers should be allocated by Z_Calloc @@ -355,7 +360,7 @@ static void P_DoAutobalanceTeams(void) INT32 i=0; INT32 red=0, blue=0; INT32 redarray[MAXPLAYERS], bluearray[MAXPLAYERS]; - INT32 redflagcarrier = 0, blueflagcarrier = 0; + //INT32 redflagcarrier = 0, blueflagcarrier = 0; INT32 totalred = 0, totalblue = 0; NetPacket.value.l = NetPacket.value.b = 0; @@ -375,29 +380,29 @@ static void P_DoAutobalanceTeams(void) { if (players[i].ctfteam == 1) { - if (!players[i].gotflag) + //if (!players[i].gotflag) { redarray[red] = i; //store the player's node. red++; } - else - redflagcarrier++; + /*else + redflagcarrier++;*/ } else { - if (!players[i].gotflag) + //if (!players[i].gotflag) { bluearray[blue] = i; //store the player's node. blue++; } - else - blueflagcarrier++; + /*else + blueflagcarrier++;*/ } } } - totalred = red + redflagcarrier; - totalblue = blue + blueflagcarrier; + totalred = red;// + redflagcarrier; + totalblue = blue;// + blueflagcarrier; if ((abs(totalred - totalblue) > max(1, (totalred + totalblue) / 8))) { @@ -603,13 +608,19 @@ void P_Ticker(boolean run) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); + // Plays the music after the starting countdown. + if (leveltime == (starttime + (TICRATE/2))) + { + S_ChangeMusic(mapmusname, mapmusflags, true); + S_ShowMusicCredit(); + } + ps_lua_thinkframe_time = I_GetPreciseTime(); LUAh_ThinkFrame(); ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time; } // Run shield positioning - P_RunShields(); P_RunOverlays(); P_UpdateSpecials(); @@ -772,7 +783,6 @@ void P_PreTicker(INT32 frames) LUAh_ThinkFrame(); // Run shield positioning - P_RunShields(); P_RunOverlays(); P_UpdateSpecials(); diff --git a/src/p_tick.h b/src/p_tick.h index 1fb88f3f2..e90f1be31 100644 --- a/src/p_tick.h +++ b/src/p_tick.h @@ -30,4 +30,8 @@ void P_DoTeamscrambling(void); void P_RemoveThinkerDelayed(thinker_t *thinker); //killed mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98 +// Negate the value for tics +INT32 P_AltFlip(INT32 value, tic_t tics); +#define P_RandomFlip(value) P_AltFlip(value, 1) + #endif diff --git a/src/p_user.c b/src/p_user.c index 0cba996ff..63bd09c96 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -338,7 +338,7 @@ void P_GiveEmerald(boolean spawnObj) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); // Make sure we're not being carried before our tracer is changed - players[i].powers[pw_carry] = CR_NONE; + players[i].carry = CR_NONE; P_SetTarget(&players[i].mo->tracer, emmo); @@ -386,19 +386,6 @@ void P_GiveFinishFlags(player_t *player) } } -#if 0 -// -// P_ResetScore -// -// This is called when your chain is reset. -void P_ResetScore(player_t *player) -{ - // Formally a host for Chaos mode behavior - - player->scoreadd = 0; -} -#endif - // // P_FindLowestLap // @@ -457,11 +444,11 @@ UINT8 P_FindHighestLap(void) // P_PlayerInPain // // Is player in pain?? -// Checks for painstate and pw_flashing, if both found return true +// Checks for painstate and flashing, if both found return true // boolean P_PlayerInPain(player_t *player) { - if (player->kartstuff[k_spinouttimer] || (player->tumbleBounces > 0) || (player->pflags & PF_FAULT)) + if (player->spinouttimer || (player->tumbleBounces > 0) || (player->pflags & PF_FAULT)) return true; return false; @@ -475,11 +462,12 @@ void P_ResetPlayer(player_t *player) { //player->pflags &= ~(PF_); - player->powers[pw_carry] = CR_NONE; + player->carry = CR_NONE; player->onconveyor = 0; - //player->kartstuff[k_drift] = player->kartstuff[k_driftcharge] = 0; + //player->drift = player->driftcharge = 0; player->trickpanel = 0; + player->glanceDir = 0; } // @@ -531,21 +519,17 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { - //UINT32 oldscore; - if (!((gametyperules & GTR_BUMPERS))) return; if (player->exiting) // srb2kart return; - //oldscore = player->score; - // Don't go above MAXSCORE. - if (player->marescore + amount < MAXSCORE) - player->marescore += amount; + if (player->roundscore + amount < MAXSCORE) + player->roundscore += amount; else - player->marescore = MAXSCORE; + player->roundscore = MAXSCORE; } // @@ -561,8 +545,6 @@ void P_PlayLivesJingle(player_t *player) else { P_PlayJingle(player, JT_1UP); - if (player) - player->powers[pw_extralife] = extralifetics + 1; strlcpy(S_sfx[sfx_None].caption, "One-up", 7); S_StartCaption(sfx_None, -1, extralifetics+1); } @@ -613,38 +595,38 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) switch(status) { case JT_1UP: // Extra life - result = (players[i].powers[pw_extralife] > 1); + result = false; //(players[i].powers[pw_extralife] > 1); break; case JT_SHOES: // Speed shoes - if (players[i].powers[pw_sneakers] > 1 && !players[i].powers[pw_super]) + /*if (players[i].powers[pw_sneakers] > 1 && !players[i].powers[pw_super]) { //strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12); //S_StartCaption(sfx_None, -1, players[i].powers[pw_sneakers]); result = true; } - else + else*/ result = false; break; case JT_INV: // Invincibility case JT_MINV: // Mario Invincibility - if (players[i].powers[pw_invulnerability] > 1) + /*if (players[i].powers[pw_invulnerability] > 1) { //strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); //S_StartCaption(sfx_None, -1, players[i].powers[pw_invulnerability]); result = true; } - else + else*/ result = false; break; case JT_DROWN: // Drowning - result = (players[i].powers[pw_underwater] && players[i].powers[pw_underwater] <= 11*TICRATE + 1); + result = false; //(players[i].powers[pw_underwater] && players[i].powers[pw_underwater] <= 11*TICRATE + 1); break; case JT_SUPER: // Super Sonic - result = (players[i].powers[pw_super]); + result = false; //(players[i].powers[pw_super]); break; case JT_GOVER: // Game Over @@ -653,7 +635,7 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) case JT_NIGHTSTIMEOUT: // NiGHTS Time Out (10 seconds) case JT_SSTIMEOUT: - result = (players[i].nightstime && players[i].nightstime <= 10*TICRATE); + result = false; //(players[i].nightstime && players[i].nightstime <= 10*TICRATE); break; case JT_OTHER: // Other state @@ -675,7 +657,7 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) void P_PlayRinglossSound(mobj_t *source) { - if (source->player && K_GetShieldFromItem(source->player->kartstuff[k_itemtype]) != KSHIELD_NONE) + if (source->player && K_GetShieldFromItem(source->player->itemtype) != KSHIELD_NONE) S_StartSound(source, sfx_s1a3); // Shield hit (no ring loss) else if (source->player && source->player->rings <= 0) S_StartSound(source, sfx_s1a6); // Ring debt (lessened ring loss) @@ -716,19 +698,19 @@ boolean P_EndingMusic(player_t *player) // Check for if this is valid or not if (r_splitscreen) { - if (!((players[displayplayers[0]].exiting || (players[displayplayers[0]].pflags & PF_GAMETYPEOVER)) - || (players[displayplayers[1]].exiting || (players[displayplayers[1]].pflags & PF_GAMETYPEOVER)) - || ((r_splitscreen < 2) && (players[displayplayers[2]].exiting || (players[displayplayers[2]].pflags & PF_GAMETYPEOVER))) - || ((r_splitscreen < 3) && (players[displayplayers[3]].exiting || (players[displayplayers[3]].pflags & PF_GAMETYPEOVER))))) + if (!((players[displayplayers[0]].exiting || (players[displayplayers[0]].pflags & PF_NOCONTEST)) + || (players[displayplayers[1]].exiting || (players[displayplayers[1]].pflags & PF_NOCONTEST)) + || ((r_splitscreen < 2) && (players[displayplayers[2]].exiting || (players[displayplayers[2]].pflags & PF_NOCONTEST))) + || ((r_splitscreen < 3) && (players[displayplayers[3]].exiting || (players[displayplayers[3]].pflags & PF_NOCONTEST))))) return false; bestlocalplayer = &players[displayplayers[0]]; - bestlocalpos = ((players[displayplayers[0]].pflags & PF_GAMETYPEOVER) ? MAXPLAYERS+1 : players[displayplayers[0]].kartstuff[k_position]); + bestlocalpos = ((players[displayplayers[0]].pflags & PF_NOCONTEST) ? MAXPLAYERS+1 : players[displayplayers[0]].position); #define setbests(p) \ - if (((players[p].pflags & PF_GAMETYPEOVER) ? MAXPLAYERS+1 : players[p].kartstuff[k_position]) < bestlocalpos) \ + if (((players[p].pflags & PF_NOCONTEST) ? MAXPLAYERS+1 : players[p].position) < bestlocalpos) \ { \ bestlocalplayer = &players[p]; \ - bestlocalpos = ((players[p].pflags & PF_GAMETYPEOVER) ? MAXPLAYERS+1 : players[p].kartstuff[k_position]); \ + bestlocalpos = ((players[p].pflags & PF_NOCONTEST) ? MAXPLAYERS+1 : players[p].position); \ } setbests(displayplayers[1]); if (r_splitscreen > 1) @@ -739,11 +721,11 @@ boolean P_EndingMusic(player_t *player) } else { - if (!(player->exiting || (player->pflags & PF_GAMETYPEOVER))) + if (!(player->exiting || (player->pflags & PF_NOCONTEST))) return false; bestlocalplayer = player; - bestlocalpos = ((player->pflags & PF_GAMETYPEOVER) ? MAXPLAYERS+1 : player->kartstuff[k_position]); + bestlocalpos = ((player->pflags & PF_NOCONTEST) ? MAXPLAYERS+1 : player->position); } if ((gametyperules & GTR_CIRCUIT) && bestlocalpos == MAXPLAYERS+1) @@ -814,10 +796,10 @@ void P_RestoreMusic(player_t *player) #define setbests(p) \ if (players[p].playerstate == PST_LIVE) \ { \ - if (players[p].kartstuff[k_invincibilitytimer] > bestlocaltimer) \ - { wantedmus = 1; bestlocaltimer = players[p].kartstuff[k_invincibilitytimer]; } \ - else if (players[p].kartstuff[k_growshrinktimer] > bestlocaltimer) \ - { wantedmus = 2; bestlocaltimer = players[p].kartstuff[k_growshrinktimer]; } \ + if (players[p].invincibilitytimer > bestlocaltimer) \ + { wantedmus = 1; bestlocaltimer = players[p].invincibilitytimer; } \ + else if (players[p].growshrinktimer > bestlocaltimer) \ + { wantedmus = 2; bestlocaltimer = players[p].growshrinktimer; } \ } setbests(displayplayers[0]); setbests(displayplayers[1]); @@ -831,9 +813,9 @@ void P_RestoreMusic(player_t *player) { if (player->playerstate == PST_LIVE) { - if (player->kartstuff[k_invincibilitytimer] > 1) + if (player->invincibilitytimer > 1) wantedmus = 1; - else if (player->kartstuff[k_growshrinktimer] > 1) + else if (player->growshrinktimer > 1) wantedmus = 2; } } @@ -897,7 +879,7 @@ boolean P_IsObjectInGoop(mobj_t *mo) // boolean P_IsObjectOnGround(mobj_t *mo) { - if (P_IsObjectInGoop(mo) && !(mo->player && mo->player->pflags & PF_BOUNCING)) + if (P_IsObjectInGoop(mo)) { /* // It's a crazy hack that checking if you're on the ground @@ -1104,170 +1086,6 @@ boolean P_IsDisplayPlayer(player_t *player) return false; } -// -// P_SpawnShieldOrb -// -// Spawns the shield orb on the player -// depending on which shield they are -// supposed to have. -// -void P_SpawnShieldOrb(player_t *player) -{ - mobjtype_t orbtype; - thinker_t *th; - mobj_t *shieldobj, *ov; - -#ifdef PARANOIA - if (!player->mo) - I_Error("P_SpawnShieldOrb: player->mo is NULL!\n"); -#endif - - // SRB2Kart - // TODO: Make our shields use this system - - if (LUAh_ShieldSpawn(player)) - return; - - if (player->powers[pw_shield] & SH_FORCE) - orbtype = MT_FORCE_ORB; - else switch (player->powers[pw_shield] & SH_NOSTACK) - { - case SH_WHIRLWIND: - orbtype = MT_WHIRLWIND_ORB; - break; - case SH_ATTRACT: - orbtype = MT_ATTRACT_ORB; - break; - case SH_ELEMENTAL: - orbtype = MT_ELEMENTAL_ORB; - break; - case SH_ARMAGEDDON: - orbtype = MT_ARMAGEDDON_ORB; - break; - case SH_PITY: - case SH_PINK: // PITY IN PINK - orbtype = MT_PITY_ORB; - break; - case SH_FLAMEAURA: - orbtype = MT_FLAMEAURA_ORB; - break; - case SH_BUBBLEWRAP: - orbtype = MT_BUBBLEWRAP_ORB; - break; - case SH_THUNDERCOIN: - orbtype = MT_THUNDERCOIN_ORB; - break; - default: - return; - } - - // blaze through the thinkers to see if an orb already exists! - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - shieldobj = (mobj_t *)th; - - if (shieldobj->type == orbtype && shieldobj->target == player->mo) - P_RemoveMobj(shieldobj); //kill the old one(s) - } - - shieldobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, orbtype); - shieldobj->flags2 |= MF2_SHIELD; - P_SetTarget(&shieldobj->target, player->mo); - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) - { - shieldobj->color = SKINCOLOR_PINK; - shieldobj->colorized = true; - } - else - shieldobj->color = (UINT16)shieldobj->info->painchance; - shieldobj->threshold = (player->powers[pw_shield] & SH_FORCE) ? SH_FORCE : (player->powers[pw_shield] & SH_NOSTACK); - - if (shieldobj->info->seestate) - { - ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); - P_SetTarget(&ov->target, shieldobj); - P_SetMobjState(ov, shieldobj->info->seestate); - P_SetTarget(&shieldobj->tracer, ov); - } - if (shieldobj->info->meleestate) - { - ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); - P_SetTarget(&ov->target, shieldobj); - P_SetMobjState(ov, shieldobj->info->meleestate); - } - if (shieldobj->info->missilestate) - { - ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); - P_SetTarget(&ov->target, shieldobj); - P_SetMobjState(ov, shieldobj->info->missilestate); - } - if (player->powers[pw_shield] & SH_FORCE) - { - //Copy and pasted from P_ShieldLook in p_mobj.c - shieldobj->movecount = (player->powers[pw_shield] & SH_FORCEHP); - if (shieldobj->movecount < 1) - { - if (shieldobj->info->painstate) - P_SetMobjState(shieldobj,shieldobj->info->painstate); - else - shieldobj->renderflags |= RF_GHOSTLY; - } - } -} - -// -// P_SwitchShield -// -// Handles the possibility of switching between -// the non-stack layer of shields thoroughly, -// then adds the desired one. -// -void P_SwitchShield(player_t *player, UINT16 shieldtype) -{ - boolean donthavealready; - - donthavealready = (shieldtype & SH_FORCE) - ? (!(player->powers[pw_shield] & SH_FORCE) || (player->powers[pw_shield] & SH_FORCEHP) < (shieldtype & ~SH_FORCE)) - : ((player->powers[pw_shield] & SH_NOSTACK) != shieldtype); - - if (donthavealready) - { - boolean stopshieldability = (shieldtype & SH_FORCE) - ? (!(player->powers[pw_shield] & SH_FORCE)) - : true; - - // Just in case. - if (stopshieldability && player->pflags & PF_SHIELDABILITY) - { - player->pflags &= ~(PF_SPINNING|PF_SHIELDABILITY); // They'll still have PF_THOKKED... - player->homing = 0; - } - - player->powers[pw_shield] = shieldtype|(player->powers[pw_shield] & SH_STACK); - P_SpawnShieldOrb(player); - - if (shieldtype & SH_PROTECTWATER) - { - if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) - { - player->powers[pw_underwater] = 0; - P_RestoreMusic(player); - } - else - player->powers[pw_underwater] = 0; - - if (player->powers[pw_spacetime] > 1) - { - player->powers[pw_spacetime] = 0; - P_RestoreMusic(player); - } - } - } -} - // // P_SpawnGhostMobj // @@ -1414,8 +1232,6 @@ void P_DoPlayerExit(player_t *player) } } - player->powers[pw_underwater] = 0; - player->powers[pw_spacetime] = 0; player->karthud[khud_cardanimation] = 0; // srb2kart: reset battle animation if (player == &players[consoleplayer]) @@ -1779,19 +1595,16 @@ static void P_CheckQuicksand(player_t *player) // static void P_CheckInvincibilityTimer(player_t *player) { - if (!player->powers[pw_invulnerability] && !player->kartstuff[k_invincibilitytimer]) + if (!player->invincibilitytimer) return; player->mo->color = (UINT16)(SKINCOLOR_PINK + (leveltime % (numskincolors - SKINCOLOR_PINK))); // Resume normal music stuff. - if (player->powers[pw_invulnerability] == 1 || player->kartstuff[k_invincibilitytimer] == 1) + if (player->invincibilitytimer == 1) { - if (!player->powers[pw_super]) - { - player->mo->color = player->skincolor; - G_GhostAddColor((INT32) (player - players), GHC_NORMAL); - } + player->mo->color = player->skincolor; + G_GhostAddColor((INT32) (player - players), GHC_NORMAL); P_RestoreMusic(player); } @@ -1809,12 +1622,12 @@ static void P_DoBubbleBreath(player_t *player) fixed_t z = player->mo->z; mobj_t *bubble = NULL; - if (!(player->mo->eflags & MFE_UNDERWATER) || (player->powers[pw_shield] & SH_PROTECTWATER) || player->spectator) + if (!(player->mo->eflags & MFE_UNDERWATER) || player->spectator) return; if (player->charflags & SF_MACHINE) { - if (player->powers[pw_underwater] && P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256)) + if (P_RandomChance(FRACUNIT/5)) { fixed_t r = player->mo->radius>>FRACBITS; x += (P_RandomRange(r, -r)<mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); - if (player->kartstuff[k_drift] != 0) - movepushangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift]; - else if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_wipeoutslow]) // if spun out, use the boost angle - movepushangle = (angle_t)player->kartstuff[k_boostangle]; + if (player->stairjank > 8 && leveltime & 3) + { + movepushangle = K_MomentumAngle(player->mo); + } + else if (player->drift != 0) + { + movepushangle = player->mo->angle - (ANGLE_45/5) * player->drift; + } + else if (player->spinouttimer || player->wipeoutslow) // if spun out, use the boost angle + { + movepushangle = (angle_t)player->boostangle; + } else + { movepushangle = player->mo->angle; + } // cmomx/cmomy stands for the conveyor belt speed. if (player->onconveyor == 2) // Wind/Current @@ -1943,7 +1766,7 @@ static void P_3dMovement(player_t *player) //{ SRB2kart 220217 - Toaster Code for misplaced thrust #if 0 - if (!player->kartstuff[k_drift]) // Not Drifting + if (!player->drift) // Not Drifting { angle_t difference = dangle/2; boolean reverse = (dangle >= ANGLE_90); @@ -2166,7 +1989,7 @@ void P_MovePlayer(player_t *player) runspd = FixedMul(runspd, player->mo->movefactor); // Control relinquishing stuff! - if (player->powers[pw_nocontrol]) + if (player->nocontrol) player->pflags |= PF_STASIS; // note: don't unset stasis here @@ -2200,7 +2023,7 @@ void P_MovePlayer(player_t *player) UINT8 rollSpeed = max(1, min(8, player->tumbleHeight / 10)); - if (player->tumbleLastBounce == true) + if (player->pflags & PF_TUMBLELASTBOUNCE) spinSpeed = 2; P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); @@ -2208,7 +2031,7 @@ void P_MovePlayer(player_t *player) player->mo->rollangle -= (ANGLE_11hh * rollSpeed); - if (player->tumbleLastBounce == true) + if (player->pflags & PF_TUMBLELASTBOUNCE) { if (abs((signed)(player->mo->angle - player->drawangle)) < ANGLE_22h) player->drawangle = player->mo->angle; @@ -2217,15 +2040,17 @@ void P_MovePlayer(player_t *player) player->mo->rollangle = 0; } } - else if (player->pflags & PF_SLIDING) + else if (player->carry == CR_SLIDING) { P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); player->drawangle -= ANGLE_22h; player->mo->rollangle = 0; + player->glanceDir = 0; + player->pflags &= ~PF_LOOKDOWN; } - else if ((player->pflags & PF_FAULT) || (player->kartstuff[k_spinouttimer] > 0)) + else if ((player->pflags & PF_FAULT) || (player->spinouttimer > 0)) { - UINT16 speed = ((player->pflags & PF_FAULT) ? player->powers[pw_nocontrol] : player->kartstuff[k_spinouttimer])/8; + UINT16 speed = ((player->pflags & PF_FAULT) ? player->nocontrol : player->spinouttimer)/8; if (speed > 8) speed = 8; else if (speed < 1) @@ -2240,17 +2065,6 @@ void P_MovePlayer(player_t *player) player->mo->rollangle = 0; } - /*else if (player->pflags & PF_FAULT) -- v1 fault - { - P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); - - if (((player->powers[pw_nocontrol] + 5) % 20) < 10) - player->drawangle += ANGLE_11hh; - else - player->drawangle -= ANGLE_11hh; - - player->mo->rollangle = 0; - }*/ else { K_KartMoveAnimation(player); @@ -2259,7 +2073,7 @@ void P_MovePlayer(player_t *player) { player->drawangle += ANGLE_22h; } - else if (player->trickpanel == 3) + else if (player->trickpanel >= 3) { player->drawangle -= ANGLE_22h; } @@ -2267,13 +2081,13 @@ void P_MovePlayer(player_t *player) { player->drawangle = player->mo->angle; - if (player->aizDriftTurn) + if (player->aizdriftturn) { - player->drawangle += player->aizDriftTurn; + player->drawangle += player->aizdriftturn; } - else if (player->kartstuff[k_drift] != 0) + else if (player->drift != 0) { - INT32 a = (ANGLE_45 / 5) * player->kartstuff[k_drift]; + INT32 a = (ANGLE_45 / 5) * player->drift; player->drawangle += a; } } @@ -2287,13 +2101,13 @@ void P_MovePlayer(player_t *player) // Drifting sound // Start looping the sound now. - if (leveltime % 50 == 0 && onground && player->kartstuff[k_drift] != 0) + if (leveltime % 50 == 0 && onground && player->drift != 0) S_StartSound(player->mo, sfx_drift); // Leveltime being 50 might take a while at times. We'll start it up once, isntantly. - else if (!S_SoundPlaying(player->mo, sfx_drift) && onground && player->kartstuff[k_drift] != 0) + else if (!S_SoundPlaying(player->mo, sfx_drift) && onground && player->drift != 0) S_StartSound(player->mo, sfx_drift); // Ok, we'll stop now. - else if (player->kartstuff[k_drift] == 0) + else if (player->drift == 0) S_StopSoundByID(player->mo, sfx_drift); K_MoveKartPlayer(player, onground); @@ -2303,38 +2117,10 @@ void P_MovePlayer(player_t *player) //GAMEPLAY STUFF// ////////////////// - // If you're running fast enough, you can create splashes as you run in shallow water. -#if 0 - if (!player->climbing - && ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop) + if (((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop) || (player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height >= player->mo->waterbottom && player->mo->z <= player->mo->waterbottom)) - && (player->speed > runspd || (player->pflags & PF_STARTDASH)) - && leveltime % (TICRATE/7) == 0 && player->mo->momz == 0 && !(player->pflags & PF_SLIDING) && !player->spectator) - { - mobjtype_t splishtype = (player->mo->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH; - mobj_t *water = P_SpawnMobj(player->mo->x - P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius), player->mo->y - P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius), - ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[splishtype].height, player->mo->scale) : player->mo->watertop), splishtype); - if (player->mo->eflags & MFE_GOOWATER) - S_StartSound(water, sfx_ghit); - else if (player->mo->eflags & MFE_TOUCHLAVA) - S_StartSound(water, sfx_splash); - else - S_StartSound(water, sfx_wslap); - if (player->mo->eflags & MFE_VERTICALFLIP) - { - water->flags2 |= MF2_OBJECTFLIP; - water->eflags |= MFE_VERTICALFLIP; - } - water->destscale = player->mo->scale; - P_SetScale(water, player->mo->scale); - } -#endif - - if (!player->climbing - && ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop) - || (player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height >= player->mo->waterbottom && player->mo->z <= player->mo->waterbottom)) - && (player->speed > runspd || (player->pflags & PF_STARTDASH)) - && player->mo->momz == 0 && !(player->pflags & PF_SLIDING) && !player->spectator) + && (player->speed > runspd) + && player->mo->momz == 0 && player->carry != CR_SLIDING && !player->spectator) { fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, K_GetKartSpeed(player, false) - runspd), mapobjectscale); fixed_t playerTopSpeed = K_GetKartSpeed(player, false); @@ -2418,14 +2204,14 @@ void P_MovePlayer(player_t *player) //////////////////////////// // SRB2kart - Drifting smoke and fire - if ((player->kartstuff[k_sneakertimer] || player->kartstuff[k_flamedash]) + if ((player->sneakertimer || player->flamedash) && onground && (leveltime & 1)) K_SpawnBoostTrail(player); - if (player->kartstuff[k_invincibilitytimer] > 0) + if (player->invincibilitytimer > 0) K_SpawnSparkleTrail(player->mo); - if (player->kartstuff[k_wipeoutslow] > 1 && (leveltime & 1)) + if (player->wipeoutslow > 1 && (leveltime & 1)) K_SpawnWipeoutTrail(player->mo, false); K_DriftDustHandling(player->mo); @@ -2478,7 +2264,7 @@ static void P_DoZoomTube(player_t *player) else reverse = true; - player->powers[pw_flashing] = 1; + player->flashing = 1; speed = abs(player->speed); @@ -2536,7 +2322,7 @@ static void P_DoZoomTube(player_t *player) else { P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly. - player->powers[pw_carry] = CR_NONE; + player->carry = CR_NONE; CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); } @@ -2686,7 +2472,7 @@ static void P_DeathThink(player_t *player) if (player->deadtimer < INT32_MAX) player->deadtimer++; - if ((player->pflags & PF_GAMETYPEOVER) && (gametyperules & GTR_CIRCUIT)) + if ((player->pflags & PF_NOCONTEST) && (gametyperules & GTR_CIRCUIT)) { player->karthud[khud_timeovercam]++; @@ -2701,13 +2487,13 @@ static void P_DeathThink(player_t *player) K_KartPlayerHUDUpdate(player); - if (player->lives > 0 && !(player->pflags & PF_GAMETYPEOVER) && player->deadtimer > TICRATE) + if (player->lives > 0 && !(player->pflags & PF_NOCONTEST) && player->deadtimer > TICRATE) { player->playerstate = PST_REBORN; } // Keep time rolling - if (!(exitcountdown && !racecountdown) && !(player->exiting || mapreset) && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock) + if (!(exitcountdown && !racecountdown) && !(player->exiting || mapreset) && !(player->pflags & PF_NOCONTEST) && !stoppedclock) { if (leveltime >= starttime) { @@ -3135,7 +2921,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall || (leveltime < introtime)); // Kart intro cam #endif - if ((player->pflags & PF_GAMETYPEOVER) && (gametyperules & GTR_CIRCUIT)) // 1 for momentum keep, 2 for turnaround + if ((player->pflags & PF_NOCONTEST) && (gametyperules & GTR_CIRCUIT)) // 1 for momentum keep, 2 for turnaround timeover = (player->karthud[khud_timeovercam] > 2*TICRATE ? 2 : 1); else timeover = 0; @@ -3221,6 +3007,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else lookbackdelay[num]--; } + else if (player->respawn.state != RESPAWNST_NONE) + { + camspeed = 3*FRACUNIT/4; + } lookbackdown = (lookbackdelay[num] == MAXLOOKBACKDELAY) != lookbackactive[num]; lookbackactive[num] = (lookbackdelay[num] == MAXLOOKBACKDELAY); #undef MAXLOOKBACKDELAY @@ -3329,11 +3119,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall pan = xpan = ypan = 0; else { - if (player->kartstuff[k_drift] != 0) + if (player->drift != 0) { fixed_t panmax = (dist/5); INT32 driftval = K_GetKartDriftSparkValue(player); - INT32 dc = player->kartstuff[k_driftcharge]; + INT32 dc = player->driftcharge; if (dc > driftval || dc < 0) dc = driftval; @@ -3342,7 +3132,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (pan > panmax) pan = panmax; - if (player->kartstuff[k_drift] < 0) + if (player->drift < 0) pan *= -1; } else @@ -3677,7 +3467,7 @@ boolean P_SpectatorJoinGame(player_t *player) { if (P_IsLocalPlayer(player)) CONS_Printf(M_GetText("Server does not allow team change.\n")); - //player->powers[pw_flashing] = TICRATE + 1; //to prevent message spam. + //player->flashing = TICRATE + 1; //to prevent message spam. } // Team changing in Team Match and CTF // Pressing fire assigns you to a team that needs players if allowed. @@ -3719,7 +3509,7 @@ boolean P_SpectatorJoinGame(player_t *player) } player->spectator = false; player->pflags &= ~PF_WANTSTOJOIN; - player->kartstuff[k_spectatewait] = 0; + player->spectatewait = 0; player->ctfteam = changeto; player->playerstate = PST_REBORN; @@ -3749,7 +3539,7 @@ boolean P_SpectatorJoinGame(player_t *player) } player->spectator = false; player->pflags &= ~PF_WANTSTOJOIN; - player->kartstuff[k_spectatewait] = 0; + player->spectatewait = 0; player->playerstate = PST_REBORN; //Reset away view @@ -3880,7 +3670,7 @@ static void P_CalcPostImg(player_t *player) void P_DoTimeOver(player_t *player) { - if (player->pflags & PF_GAMETYPEOVER) + if (player->pflags & PF_NOCONTEST) { // NO! Don't do this! return; @@ -3896,7 +3686,7 @@ void P_DoTimeOver(player_t *player) CON_LogMessage(va(M_GetText("%s ran out of time.\n"), player_names[player-players])); } - player->pflags |= PF_GAMETYPEOVER; + player->pflags |= PF_NOCONTEST; if (G_GametypeUsesLives()) { @@ -4184,7 +3974,7 @@ static void P_HandleFollower(player_t *player) player->follower->renderflags = player->mo->renderflags; // Make the follower invisible if we no contest'd rather than removing it. No one will notice the diff seriously. - if (player->pflags & PF_GAMETYPEOVER) + if (player->pflags & PF_NOCONTEST) player->follower->renderflags |= RF_DONTDRAW; if (player->speed && (player->follower->momx || player->follower->momy)) @@ -4223,7 +4013,7 @@ static void P_HandleFollower(player_t *player) // handle follower animations. Could probably be better... // hurt or dead - if (player->kartstuff[k_spinouttimer] || player->mo->state == &states[S_KART_SPINOUT] || player->mo->health <= 0) + if (player->spinouttimer || player->mo->state == &states[S_KART_SPINOUT] || player->mo->health <= 0) { player->follower->movecount = 0; // cancel hit confirm. player->follower->angle = player->drawangle; // spin out @@ -4345,12 +4135,18 @@ DoABarrelRoll (player_t *player) fixed_t smoothing; + if (player->respawn.state != RESPAWNST_NONE) + { + player->tilt = 0; + return; + } + if (player->exiting) { return; } - slope = InvAngle(R_GetPitchRollAngle(player->mo)); + slope = InvAngle(R_GetPitchRollAngle(player->mo, player)); if (AbsAngle(slope) < ANGLE_11hh) { @@ -4435,15 +4231,15 @@ void P_PlayerThink(player_t *player) // to allow items to be thrown forward or backward. if (cmd->buttons & BT_FORWARD) { - player->kartstuff[k_throwdir] = 1; + player->throwdir = 1; } else if (cmd->buttons & BT_BACKWARD) { - player->kartstuff[k_throwdir] = -1; + player->throwdir = -1; } else { - player->kartstuff[k_throwdir] = 0; + player->throwdir = 0; } // Accessibility - kickstart your acceleration @@ -4475,7 +4271,7 @@ void P_PlayerThink(player_t *player) { if (playeringame[i] && !players[i].spectator) { - if (!players[i].exiting && !(players[i].pflags & PF_GAMETYPEOVER) && players[i].lives > 0) + if (!players[i].exiting && !(players[i].pflags & PF_NOCONTEST) && players[i].lives > 0) break; } } @@ -4496,7 +4292,7 @@ void P_PlayerThink(player_t *player) // If you've hit the countdown and you haven't made // it to the exit, you're a goner! - if (racecountdown == 1 && !player->spectator && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && player->lives > 0) + if (racecountdown == 1 && !player->spectator && !player->exiting && !(player->pflags & PF_NOCONTEST) && player->lives > 0) { P_DoTimeOver(player); @@ -4566,11 +4362,11 @@ void P_PlayerThink(player_t *player) // SRB2kart 010217 if (leveltime < introtime) { - player->powers[pw_nocontrol] = 2; + player->nocontrol = 2; } // Synchronizes the "real" amount of time spent in the level. - if (!(exitcountdown && !racecountdown) && !(player->exiting || mapreset) && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock) + if (!(exitcountdown && !racecountdown) && !(player->exiting || mapreset) && !(player->pflags & PF_NOCONTEST) && !stoppedclock) { if (leveltime >= starttime) { @@ -4591,20 +4387,14 @@ void P_PlayerThink(player_t *player) } } - if ((netgame || multiplayer) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) + if ((netgame || multiplayer) && player->spectator && cmd->buttons & BT_ATTACK && !player->flashing) { player->pflags ^= PF_WANTSTOJOIN; - player->powers[pw_flashing] = TICRATE/2 + 1; + player->flashing = TICRATE/2 + 1; /*if (P_SpectatorJoinGame(player)) return; // player->mo was removed.*/ } - if (player->linktimer && !player->powers[pw_nights_linkfreeze]) - { - if (--player->linktimer <= 0) // Link timer - player->linkcount = 0; - } - if (player->respawn.state != RESPAWNST_NONE) { K_RespawnChecker(player); @@ -4626,7 +4416,6 @@ void P_PlayerThink(player_t *player) { P_DoZoomTube(player); player->rmomx = player->rmomy = 0; - P_ResetScore(player); } else { @@ -4649,42 +4438,6 @@ void P_PlayerThink(player_t *player) P_DoBubbleBreath(player); // Spawn Sonic's bubbles P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles -#if 1 - // "Blur" a bit when you have speed shoes and are going fast enough - if ((player->powers[pw_super] || player->powers[pw_sneakers]) - && (player->speed + abs(player->mo->momz)) > FixedMul(20*FRACUNIT,player->mo->scale)) - { - UINT8 i; - mobj_t *gmobj = P_SpawnGhostMobj(player->mo); - - gmobj->fuse = 2; - if (gmobj->tracer) - gmobj->tracer->fuse = 2; - if (leveltime & 1) - { - gmobj->frame &= ~FF_TRANSMASK; - gmobj->frame |= tr_trans70<tracer) - { - gmobj->tracer->frame &= ~FF_TRANSMASK; - gmobj->tracer->frame |= tr_trans70<renderflags |= RF_DONTDRAW; - break; - } - } - } -#endif - // check for buttons if (cmd->buttons & BT_ACCELERATE) player->pflags |= PF_ACCELDOWN; @@ -4696,36 +4449,34 @@ void P_PlayerThink(player_t *player) else player->pflags &= ~PF_BRAKEDOWN; + // PF_LOOKDOWN handled in K_KartMoveAnimation + // Counters, time dependent power ups. // Time Bonus & Ring Bonus count settings // Strength counts up to diminish fade. - if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && + if (player->flashing && player->flashing < UINT16_MAX && (player->spectator || !P_PlayerInPain(player))) { - player->powers[pw_flashing]--; + player->flashing--; } - if (player->powers[pw_nocontrol] && player->powers[pw_nocontrol] < UINT16_MAX) + if (player->nocontrol && player->nocontrol < UINT16_MAX) { - if (!(--player->powers[pw_nocontrol])) + if (!(--player->nocontrol)) player->pflags &= ~PF_FAULT; } else - player->powers[pw_nocontrol] = 0; - - //pw_super acts as a timer now - if (player->powers[pw_super]) - player->powers[pw_super]++; + player->nocontrol = 0; // Flash player after being hit. - if (!(player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should. - || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. + if (!(player->hyudorotimer // SRB2kart - fixes Hyudoro not flashing when it should. + || player->growshrinktimer > 0 // Grow doesn't flash either. || (player->respawn.state != RESPAWNST_NONE) // Respawn timer (for drop dash effect) - || (player->pflags & PF_GAMETYPEOVER) // NO CONTEST explosion + || (player->pflags & PF_NOCONTEST) // NO CONTEST explosion || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay))) { - if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing(player) + if (player->flashing > 0 && player->flashing < K_GetKartFlashing(player) && (leveltime & 1)) player->mo->renderflags |= RF_DONTDRAW; else @@ -4790,12 +4541,18 @@ void P_PlayerThink(player_t *player) player->typing_duration = 0; } - player->pflags &= ~PF_SLIDING; + if (player->stairjank > 0) + { + player->stairjank--; + } K_KartPlayerThink(player, cmd); // SRB2kart DoABarrelRoll(player); + if (player->carry == CR_SLIDING) + player->carry = CR_NONE; + LUAh_PlayerThink(player); } @@ -4845,9 +4602,6 @@ void P_PlayerAfterThink(player_t *player) return; } - if (player->pflags & PF_SLIDING) - P_SetPlayerMobjState(player->mo, player->mo->info->painstate); - if (thiscam) { if (!thiscam->chase) // bob view only if looking through the player's eyes @@ -4880,12 +4634,6 @@ void P_PlayerAfterThink(player_t *player) K_KartPlayerAfterThink(player); - if (player->powers[pw_dye]) - { - player->mo->colorized = true; - player->mo->color = player->powers[pw_dye]; - } - if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) { P_RemoveMobj(player->followmobj); @@ -4964,5 +4712,5 @@ void P_ForceLocalAngle(player_t *player, angle_t angle) boolean P_PlayerFullbright(player_t *player) { - return (player->kartstuff[k_invincibilitytimer] > 0); + return (player->invincibilitytimer > 0); } diff --git a/src/r_defs.h b/src/r_defs.h index 41b0cdaab..7decdfeab 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -420,6 +420,8 @@ typedef struct line_s size_t validcount; // if == validcount, already checked polyobj_t *polyobj; // Belongs to a polyobject? + boolean tripwire; + char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 } line_t; diff --git a/src/r_draw.c b/src/r_draw.c index 565d4a1fa..4adfb6663 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -141,7 +141,9 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) #define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6) -#define TT_CACHE_SIZE (MAXSKINS + 7) +#define HITLAG_TT_CACHE_INDEX (MAXSKINS + 7) +#define TT_CACHE_SIZE (MAXSKINS + 8) + #define SKIN_RAMP_LENGTH 16 #define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 @@ -160,6 +162,7 @@ static INT32 SkinToCacheIndex(INT32 skinnum) case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX; case TC_BLINK: return BLINK_TT_CACHE_INDEX; case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX; + case TC_HITLAG: return HITLAG_TT_CACHE_INDEX; default: break; } @@ -177,6 +180,7 @@ static INT32 CacheIndexToSkin(INT32 ttc) case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW; case BLINK_TT_CACHE_INDEX: return TC_BLINK; case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE; + case HITLAG_TT_CACHE_INDEX: return TC_HITLAG; default: break; } diff --git a/src/r_draw.h b/src/r_draw.h index 687448c98..646eb5ec8 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -119,6 +119,7 @@ enum TC_RAINBOW, // For single colour TC_BLINK, // For item blinking, according to kart TC_DASHMODE, // For Metal Sonic's dashmode + TC_HITLAG, // Damage hitlag effect TC_DEFAULT }; diff --git a/src/r_main.c b/src/r_main.c index 5f145bd76..dfc11ab4a 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -318,18 +318,35 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) angle_t R_PointToAngle(fixed_t x, fixed_t y) { - return (y -= viewy, (x -= viewx) || y) ? - x >= 0 ? - y >= 0 ? - (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 - ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1 - x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 - ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 - y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3 - ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2 - (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 - ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5 - 0; + return R_PointToAngle2(viewx, viewy, x, y); +} + +// Similar to R_PointToAngle, but requires an additional player_t argument. +// If this player is a local displayplayer, this will base off the calculations off of their camera instead, otherwise use viewx/viewy as usual. +// Yes this is kinda ghetto. +angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y) +{ + fixed_t refx = viewx, refy = viewy; + camera_t *cam = NULL; + UINT8 i; + + for (i = 0; i < r_splitscreen; i++) + { + if (player == &players[displayplayers[i]]) + { + cam = &camera[i]; + break; + } + } + + // use whatever cam we found's coordinates. + if (cam != NULL) + { + refx = cam->x; + refy = cam->y; + } + + return R_PointToAngle2(refx, refy, x, y); } // This version uses 64-bit variables to avoid overflows with large values. diff --git a/src/r_main.h b/src/r_main.h index 49e028149..5208b52a3 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -63,6 +63,7 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node); INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line); angle_t R_PointToAngle(fixed_t x, fixed_t y); +angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y); angle_t R_PointToAngle64(INT64 x, INT64 y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); diff --git a/src/r_patch.h b/src/r_patch.h index c6d222617..601144a1d 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -15,6 +15,7 @@ #include "r_defs.h" #include "r_picformats.h" #include "doomdef.h" +#include "d_player.h" // Patch functions patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest); @@ -38,9 +39,10 @@ patch_t *Patch_GetRotatedSprite( size_t frame, size_t spriteangle, boolean flip, boolean adjustfeet, void *info, INT32 rotationangle); + INT32 R_GetRollAngle(angle_t rollangle); -angle_t R_GetPitchRollAngle(mobj_t *mobj); -angle_t R_SpriteRotationAngle(mobj_t *mobj); +angle_t R_GetPitchRollAngle(mobj_t *mobj, player_t *viewPlayer); +angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer); #endif #endif // __R_PATCH__ diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index 6149bab24..3744dfce2 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -15,14 +15,15 @@ #include "w_wad.h" #include "r_main.h" // R_PointToAngle #include "k_kart.h" // K_Sliptiding +#include "p_tick.h" #ifdef ROTSPRITE fixed_t rollcosang[ROTANGLES]; fixed_t rollsinang[ROTANGLES]; -angle_t R_GetPitchRollAngle(mobj_t *mobj) +angle_t R_GetPitchRollAngle(mobj_t *mobj, player_t *viewPlayer) { - angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y); + angle_t viewingAngle = R_PointToAnglePlayer(viewPlayer, mobj->x, mobj->y); fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT); fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT); @@ -32,16 +33,14 @@ angle_t R_GetPitchRollAngle(mobj_t *mobj) return rollOrPitch; } -angle_t R_SpriteRotationAngle(mobj_t *mobj) +static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer) { - angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y); - angle_t angleDelta = (viewingAngle - mobj->angle); + angle_t viewingAngle = R_PointToAnglePlayer(viewPlayer, player->mo->x, player->mo->y); + angle_t angleDelta = (viewingAngle - player->mo->angle); - angle_t sliptideLift = mobj->player - ? mobj->player->aizDriftTilt : 0; + angle_t sliptideLift = player->aizdrifttilt; - angle_t rollOrPitch = R_GetPitchRollAngle(mobj); - angle_t rollAngle = (rollOrPitch + mobj->rollangle); + angle_t rollAngle = 0; if (sliptideLift) { @@ -52,6 +51,25 @@ angle_t R_SpriteRotationAngle(mobj_t *mobj) FixedMul(sliptideLift, FINECOSINE(angleDelta >> ANGLETOFINESHIFT)); } + if (player->stairjank) + { + rollAngle += K_StairJankFlip(ANGLE_11hh / 2 / + (17 / player->stairjank)); + } + + return rollAngle; +} + +angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer) +{ + angle_t rollOrPitch = R_GetPitchRollAngle(mobj, viewPlayer); + angle_t rollAngle = (rollOrPitch + mobj->rollangle); + + if (mobj->player) + { + rollAngle += R_PlayerSpriteRotation(mobj->player, viewPlayer); + } + return rollAngle; } diff --git a/src/r_segs.c b/src/r_segs.c index 8d056a295..5c9538e34 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -162,7 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) return; transtable = R_GetLinedefTransTable(ldef); - if (ldef->special == 910) + if (ldef->special == 910 || P_IsLineTripWire(ldef)) { if (transtable == NUMTRANSMAPS) transtable = 0; diff --git a/src/r_textures.c b/src/r_textures.c index e8d79981a..9716724b5 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -1611,9 +1611,7 @@ INT32 R_CheckTextureNumForName(const char *name) Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache); strncpy(tidcache[tidcachelen-1].name, name, 8); tidcache[tidcachelen-1].name[8] = '\0'; -#ifndef ZDEBUG CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name); -#endif tidcache[tidcachelen-1].id = i; return i; } diff --git a/src/r_things.c b/src/r_things.c index bb848a679..defd02a5f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -484,9 +484,7 @@ void R_AddSpriteDefs(UINT16 wadnum) #endif // if a new sprite was added (not just replaced) addsprites++; -#ifndef ZDEBUG CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", sprnames[i], wadnum); -#endif } } @@ -739,7 +737,11 @@ boolean R_SpriteIsFlashing(vissprite_t *vis) UINT8 *R_GetSpriteTranslation(vissprite_t *vis) { - if (R_SpriteIsFlashing(vis)) // Bosses "flash" + if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG)) + { + return R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE); + } + else if (R_SpriteIsFlashing(vis)) // Bosses "flash" { if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized) return R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); @@ -1434,7 +1436,7 @@ static void R_ProjectSprite(mobj_t *thing) #endif // hitlag vibrating - if (thing->hitlag > 0) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) { fixed_t mul = thing->hitlag * (FRACUNIT / 10); @@ -1576,7 +1578,7 @@ static void R_ProjectSprite(mobj_t *thing) patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE); #ifdef ROTSPRITE - spriterotangle = R_SpriteRotationAngle(thing); + spriterotangle = R_SpriteRotationAngle(thing, NULL); if (spriterotangle && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) diff --git a/src/s_sound.c b/src/s_sound.c index 3c7957624..7e44bb207 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -35,7 +35,7 @@ // 3D Sound Interface #include "hardware/hw3sound.h" #else -static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo); +static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo); #endif CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {MAX_VOLUME, "MAX"}, {0, NULL}}; @@ -183,8 +183,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo) // channel number to use INT32 cnum; - channel_t *c; - // Find an open channel for (cnum = 0; cnum < numofchannels; cnum++) { @@ -196,7 +194,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo) else if (sfxinfo == channels[cnum].sfxinfo && (sfxinfo->pitch & SF_NOMULTIPLESOUND)) { return -1; - break; } else if (sfxinfo == channels[cnum].sfxinfo && sfxinfo->singularity == true) { @@ -240,12 +237,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo) } } - c = &channels[cnum]; - - // channel is decided to be cnum. - c->sfxinfo = sfxinfo; - c->origin = origin; - return cnum; } @@ -501,24 +492,37 @@ void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan) closedcaptions[set].b = 2; // bob } +static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume) +{ + fixed_t root = INT32_MAX; + + if (r_splitscreen == 0) + { + return volume; + } + + root = FixedSqrt((r_splitscreen + 1) * (FRACUNIT/3)); + + return FixedDiv( + volume * FRACUNIT, + root + ) / FRACUNIT; +} + void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) { - const INT32 initial_volume = volume; - INT32 sep, pitch, priority, cnum; - const sfxenum_t actual_id = sfx_id; - sfxinfo_t *sfx; - const boolean reverse = (stereoreverse.value ^ encoremode); const mobj_t *origin = (const mobj_t *)origin_p; + const sfxenum_t actual_id = sfx_id; + const boolean reverse = (stereoreverse.value ^ encoremode); + const INT32 initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume); - listener_t listener = {0,0,0,0}; - listener_t listener2 = {0,0,0,0}; - listener_t listener3 = {0,0,0,0}; - listener_t listener4 = {0,0,0,0}; + sfxinfo_t *sfx; + INT32 sep, pitch, priority, cnum; + boolean anyListeners = false; + INT32 i; - mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo; - mobj_t *listenmobj2 = NULL; - mobj_t *listenmobj3 = NULL; - mobj_t *listenmobj4 = NULL; + listener_t listener[MAXSPLITSCREENPLAYERS]; + mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; if (S_SoundDisabled() || !sound_started) return; @@ -527,27 +531,30 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) if (sfx_id == sfx_None) return; - if (players[displayplayers[0]].awayviewtics) - listenmobj = players[displayplayers[0]].awayviewmobj; - - if (r_splitscreen) + for (i = 0; i <= r_splitscreen; i++) { - listenmobj2 = players[displayplayers[1]].mo; - if (players[displayplayers[1]].awayviewtics) - listenmobj2 = players[displayplayers[1]].awayviewmobj; + player_t *player = &players[displayplayers[i]]; - if (r_splitscreen > 1) + memset(&listener[i], 0, sizeof (listener[i])); + listenmobj[i] = NULL; + + if (!player) { - listenmobj3 = players[displayplayers[2]].mo; - if (players[displayplayers[2]].awayviewtics) - listenmobj3 = players[displayplayers[2]].awayviewmobj; + continue; + } - if (r_splitscreen > 2) - { - listenmobj4 = players[displayplayers[3]].mo; - if (players[displayplayers[3]].awayviewtics) - listenmobj4 = players[displayplayers[3]].awayviewmobj; - } + if (i == 0 && democam.soundmobj) + { + continue; + } + + if (player->awayviewtics) + { + listenmobj[i] = player->awayviewmobj; + } + else + { + listenmobj[i] = player->mo; } } @@ -559,75 +566,37 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) }; #endif - if (camera[0].chase && !players[displayplayers[0]].awayviewtics) + for (i = 0; i <= r_splitscreen; i++) { - listener.x = camera[0].x; - listener.y = camera[0].y; - listener.z = camera[0].z; - listener.angle = camera[0].angle; + player_t *player = &players[displayplayers[i]]; + + if (!player) + { + continue; + } + + if (camera[i].chase && !player->awayviewtics) + { + listener[i].x = camera[i].x; + listener[i].y = camera[i].y; + listener[i].z = camera[i].z; + listener[i].angle = camera[i].angle; + anyListeners = true; + } + else if (listenmobj[i]) + { + listener[i].x = listenmobj[i]->x; + listener[i].y = listenmobj[i]->y; + listener[i].z = listenmobj[i]->z; + listener[i].angle = listenmobj[i]->angle; + anyListeners = true; + } } - else if (listenmobj) + + if (origin && anyListeners == false) { - listener.x = listenmobj->x; - listener.y = listenmobj->y; - listener.z = listenmobj->z; - listener.angle = listenmobj->angle; - } - else if (origin) + // If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound? return; - - if (listenmobj2) - { - if (camera[1].chase && !players[displayplayers[1]].awayviewtics) - { - listener2.x = camera[1].x; - listener2.y = camera[1].y; - listener2.z = camera[1].z; - listener2.angle = camera[1].angle; - } - else - { - listener2.x = listenmobj2->x; - listener2.y = listenmobj2->y; - listener2.z = listenmobj2->z; - listener2.angle = listenmobj2->angle; - } - } - - if (listenmobj3) - { - if (camera[2].chase && !players[displayplayers[2]].awayviewtics) - { - listener3.x = camera[2].x; - listener3.y = camera[2].y; - listener3.z = camera[2].z; - listener3.angle = camera[2].angle; - } - else - { - listener3.x = listenmobj3->x; - listener3.y = listenmobj3->y; - listener3.z = listenmobj3->z; - listener3.angle = listenmobj3->angle; - } - } - - if (listenmobj4) - { - if (camera[3].chase && !players[displayplayers[3]].awayviewtics) - { - listener4.x = camera[3].x; - listener4.y = camera[3].y; - listener4.z = camera[3].z; - listener4.angle = camera[3].angle; - } - else - { - listener4.x = listenmobj4->x; - listener4.y = listenmobj4->y; - listener4.z = listenmobj4->z; - listener4.angle = listenmobj4->angle; - } } // check for bogus sound # @@ -647,36 +616,40 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) pitch = NORM_PITCH; priority = NORM_PRIORITY; - if (r_splitscreen && origin) - volume = FixedDiv(volume<>FRACBITS; - - if (r_splitscreen && listenmobj2) // Copy the sound for the split player + for (i = r_splitscreen; i >= 0; i--) { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj2) + // Copy the sound for the splitscreen players! + if (listenmobj[i] == NULL && i != 0) { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx); + continue; + } + + // Check to see if it is audible, and if not, modify the params + if (origin && origin != listenmobj[i]) + { + boolean rc = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx); if (!rc) - goto dontplay; // Maybe the other player can hear it... + { + continue; // Maybe the other player can hear it... + } - if (origin->x == listener2.x && origin->y == listener2.y) + if (origin->x == listener[i].x && origin->y == listener[i].y) + { sep = NORM_SEP; + } } - else if (!origin) - // Do not play origin-less sounds for the second player. + else if (i > 0 && !origin) + { + // Do not play origin-less sounds for the splitscreen players. // The first player will be able to hear it just fine, // we really don't want it playing twice. - goto dontplay; + continue; + } else + { sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; // If there's no free channels, it's not gonna be free for player 1, either. + } // This is supposed to handle the loading/caching. // For some odd reason, the caching is done nearly @@ -685,191 +658,43 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // cache data if necessary // NOTE: set sfx->data NULL sfx->lump -1 to force a reload if (!sfx->data) + { sfx->data = I_GetSfx(sfx); + } // increase the usefulness if (sfx->usefulness++ < 0) + { sfx->usefulness = -1; + } // Avoid channel reverse if surround if (reverse #ifdef SURROUND && sep != SURROUND_SEP #endif - ) - sep = (~sep) & 255; - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); - } - -dontplay: - - if (r_splitscreen > 1 && listenmobj3) // Copy the sound for the third player - { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj3) + ) { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - goto dontplay3; // Maybe the other player can hear it... - - if (origin->x == listener3.x && origin->y == listener3.y) - sep = NORM_SEP; + sep = (~sep) & 255; } - else if (!origin) - // Do not play origin-less sounds for the second player. - // The first player will be able to hear it just fine, - // we really don't want it playing twice. - goto dontplay3; - else - sep = NORM_SEP; - // try to find a channel + // At this point it is determined that a sound can and should be played, so find a free channel to play it on cnum = S_getChannel(origin, sfx); if (cnum < 0) - return; // If there's no free channels, it's not gonna be free for player 1, either. - - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - - // cache data if necessary - // NOTE: set sfx->data NULL sfx->lump -1 to force a reload - if (!sfx->data) - sfx->data = I_GetSfx(sfx); - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = -1; - - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); - } - -dontplay3: - - if (r_splitscreen > 2 && listenmobj4) // Copy the sound for the split player - { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj4) { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - goto dontplay4; // Maybe the other player can hear it... - - if (origin->x == listener4.x && origin->y == listener4.y) - sep = NORM_SEP; + return; // If there's no free channels, there won't be any for anymore players either } - else if (!origin) - // Do not play origin-less sounds for the second player. - // The first player will be able to hear it just fine, - // we really don't want it playing twice. - goto dontplay4; - else - sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; // If there's no free channels, it's not gonna be free for player 1, either. - - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - - // cache data if necessary - // NOTE: set sfx->data NULL sfx->lump -1 to force a reload - if (!sfx->data) - sfx->data = I_GetSfx(sfx); - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = -1; - - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; // Handle closed caption input. S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); + // Now that we know we are going to play a sound, fill out this info + channels[cnum].sfxinfo = sfx; + channels[cnum].origin = origin; + channels[cnum].volume = initial_volume; + channels[cnum].handle = I_StartSound(sfx_id, S_GetSoundVolume(sfx, volume), sep, pitch, priority, cnum); } - -dontplay4: - - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj) - { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - return; - - if (origin->x == listener.x && origin->y == listener.y) - sep = NORM_SEP; - } - else - sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; - - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - - // cache data if necessary - // NOTE: set sfx->data NULL sfx->lump -1 to force a reload - if (!sfx->data) - sfx->data = I_GetSfx(sfx); - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = -1; - - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; - - // Handle closed caption input. - S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].volume = initial_volume; - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); } void S_StartSound(const void *origin, sfxenum_t sfx_id) @@ -920,23 +745,13 @@ static INT32 actualdigmusicvolume; void S_UpdateSounds(void) { - INT32 audible, cnum, volume, sep, pitch; + INT32 cnum, volume, sep, pitch; + boolean audible = false; channel_t *c; + INT32 i; - listener_t listener; - listener_t listener2; - listener_t listener3; - listener_t listener4; - - mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo; - mobj_t *listenmobj2 = NULL; - mobj_t *listenmobj3 = NULL; - mobj_t *listenmobj4 = NULL; - - memset(&listener, 0, sizeof(listener_t)); - memset(&listener2, 0, sizeof(listener_t)); - memset(&listener3, 0, sizeof(listener_t)); - memset(&listener4, 0, sizeof(listener_t)); + listener_t listener[MAXSPLITSCREENPLAYERS]; + mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; // Update sound/music volumes, if changed manually at console if (actualsfxvolume != cv_soundvolume.value * USER_VOLUME_SCALE) @@ -949,7 +764,7 @@ void S_UpdateSounds(void) { #ifndef NOMUMBLE // Stop Mumble cutting out. I'm sick of it. - I_UpdateMumble(NULL, listener); + I_UpdateMumble(NULL, listener[0]); #endif goto notinlevel; @@ -958,47 +773,35 @@ void S_UpdateSounds(void) if (dedicated || sound_disabled) return; - if (players[displayplayers[0]].awayviewtics) - listenmobj = players[displayplayers[0]].awayviewmobj; - - if (r_splitscreen) + for (i = 0; i <= r_splitscreen; i++) { - listenmobj2 = players[displayplayers[1]].mo; - if (players[displayplayers[1]].awayviewtics) - listenmobj2 = players[displayplayers[1]].awayviewmobj; + player_t *player = &players[displayplayers[i]]; - if (r_splitscreen > 1) + memset(&listener[i], 0, sizeof (listener[i])); + listenmobj[i] = NULL; + + if (!player) { - listenmobj3 = players[displayplayers[2]].mo; - if (players[displayplayers[2]].awayviewtics) - listenmobj3 = players[displayplayers[2]].awayviewmobj; + continue; + } - if (r_splitscreen > 2) - { - listenmobj4 = players[displayplayers[3]].mo; - if (players[displayplayers[3]].awayviewtics) - listenmobj4 = players[displayplayers[3]].awayviewmobj; - } + if (i == 0 && democam.soundmobj) + { + continue; + } + + if (player->awayviewtics) + { + listenmobj[i] = player->awayviewmobj; + } + else + { + listenmobj[i] = player->mo; } } - if (camera[0].chase && !players[displayplayers[0]].awayviewtics) - { - listener.x = camera[0].x; - listener.y = camera[0].y; - listener.z = camera[0].z; - listener.angle = camera[0].angle; - } - else if (listenmobj) - { - listener.x = listenmobj->x; - listener.y = listenmobj->y; - listener.z = listenmobj->z; - listener.angle = listenmobj->angle; - } - #ifndef NOMUMBLE - I_UpdateMumble(players[consoleplayer].mo, listener); + I_UpdateMumble(players[consoleplayer].mo, listener[0]); #endif #ifdef HW3SOUND @@ -1009,57 +812,28 @@ void S_UpdateSounds(void) } #endif - if (listenmobj2) + for (i = 0; i <= r_splitscreen; i++) { - if (camera[1].chase && !players[displayplayers[1]].awayviewtics) - { - listener2.x = camera[1].x; - listener2.y = camera[1].y; - listener2.z = camera[1].z; - listener2.angle = camera[1].angle; - } - else - { - listener2.x = listenmobj2->x; - listener2.y = listenmobj2->y; - listener2.z = listenmobj2->z; - listener2.angle = listenmobj2->angle; - } - } + player_t *player = &players[displayplayers[i]]; - if (listenmobj3) - { - if (camera[2].chase && !players[displayplayers[2]].awayviewtics) + if (!player) { - listener3.x = camera[2].x; - listener3.y = camera[2].y; - listener3.z = camera[2].z; - listener3.angle = camera[2].angle; + continue; } - else - { - listener3.x = listenmobj3->x; - listener3.y = listenmobj3->y; - listener3.z = listenmobj3->z; - listener3.angle = listenmobj3->angle; - } - } - if (listenmobj4) - { - if (camera[3].chase && !players[displayplayers[3]].awayviewtics) + if (camera[i].chase && !player->awayviewtics) { - listener4.x = camera[3].x; - listener4.y = camera[3].y; - listener4.z = camera[3].z; - listener4.angle = camera[3].angle; + listener[i].x = camera[i].x; + listener[i].y = camera[i].y; + listener[i].z = camera[i].z; + listener[i].angle = camera[i].angle; } - else + else if (listenmobj[i]) { - listener4.x = listenmobj4->x; - listener4.y = listenmobj4->y; - listener4.z = listenmobj4->z; - listener4.angle = listenmobj4->angle; + listener[i].x = listenmobj[i]->x; + listener[i].y = listenmobj[i]->y; + listener[i].z = listenmobj[i]->z; + listener[i].angle = listenmobj[i]->angle; } } @@ -1076,86 +850,56 @@ void S_UpdateSounds(void) pitch = NORM_PITCH; sep = NORM_SEP; - if (r_splitscreen && c->origin) - volume = FixedDiv(volume<>FRACBITS; - // check non-local sounds for distance clipping // or modify their params - if (c->origin && ((c->origin != players[displayplayers[0]].mo) - || (r_splitscreen && c->origin != players[displayplayers[1]].mo) - || (r_splitscreen > 1 && c->origin != players[displayplayers[2]].mo) - || (r_splitscreen > 2 && c->origin != players[displayplayers[3]].mo))) + if (c->origin) { - // Whomever is closer gets the sound, but only in splitscreen. - if (r_splitscreen) + boolean itsUs = false; + + for (i = 0; i <= r_splitscreen; i++) + { + if (c->origin == players[displayplayers[i]].mo) + { + itsUs = true; + break; + } + } + + if (itsUs == false) { const mobj_t *soundmobj = c->origin; - fixed_t recdist = -1; - INT32 i, p = -1; + fixed_t recdist = INT32_MAX; + UINT8 p = 0; for (i = 0; i <= r_splitscreen; i++) { - fixed_t thisdist = -1; + fixed_t thisdist = INT32_MAX; - if (i == 0 && listenmobj) - thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); - else if (i == 1 && listenmobj2) - thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y); - else if (i == 2 && listenmobj3) - thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y); - else if (i == 3 && listenmobj4) - thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y); - else + if (!listenmobj[i]) + { continue; + } - if (recdist == -1 || (thisdist != -1 && thisdist < recdist)) + thisdist = P_AproxDistance(listener[i].x - soundmobj->x, listener[i].y - soundmobj->y); + + if (thisdist < recdist) { recdist = thisdist; p = i; } } - if (p != -1) + if (listenmobj[p]) { - if (p == 1) - { - // Player 2 gets the sound - audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else if (p == 2) - { - // Player 3 gets the sound - audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else if (p == 3) - { - // Player 4 gets the sound - audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else - { - // Player 1 gets the sound - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - - if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); - else - S_StopChannel(cnum); + audible = S_AdjustSoundParams( + listenmobj[p], c->origin, + &volume, &sep, &pitch, + c->sfxinfo + ); } - } - else if (listenmobj && !r_splitscreen) - { - // In the case of a single player, he or she always should get updated sound. - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, - c->sfxinfo); if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); + I_UpdateSoundParams(c->handle, S_GetSoundVolume(c->sfxinfo, volume), sep, pitch); else S_StopChannel(cnum); } @@ -1267,60 +1011,53 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t return FixedDiv(approx_dist, mapobjectscale); // approx_dist } +INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume) +{ + if (sfx->volume > 0) + return (volume * sfx->volume) / 100; + + return volume; +} + // // Changes volume, stereo-separation, and pitch variables // from the norm of a sound effect to be played. // If the sound is not audible, returns a 0. // Otherwise, modifies parameters and returns 1. // -INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, +boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo) { + const boolean reverse = (stereoreverse.value ^ encoremode); + fixed_t approx_dist; angle_t angle; listener_t listensource; - - const boolean reverse = (stereoreverse.value ^ encoremode); + INT32 i; (void)pitch; + if (!listener) return false; - if (listener == players[displayplayers[0]].mo && camera[0].chase) + // Init listensource with default listener + listensource.x = listener->x; + listensource.y = listener->y; + listensource.z = listener->z; + listensource.angle = listener->angle; + + for (i = 0; i <= r_splitscreen; i++) { - listensource.x = camera[0].x; - listensource.y = camera[0].y; - listensource.z = camera[0].z; - listensource.angle = camera[0].angle; - } - else if (r_splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase) - { - listensource.x = camera[1].x; - listensource.y = camera[1].y; - listensource.z = camera[1].z; - listensource.angle = camera[1].angle; - } - else if (r_splitscreen > 1 && listener == players[displayplayers[2]].mo && camera[2].chase) - { - listensource.x = camera[2].x; - listensource.y = camera[2].y; - listensource.z = camera[2].z; - listensource.angle = camera[2].angle; - } - else if (r_splitscreen > 2 && listener == players[displayplayers[3]].mo && camera[3].chase) - { - listensource.x = camera[3].x; - listensource.y = camera[3].y; - listensource.z = camera[3].z; - listensource.angle = camera[3].angle; - } - else - { - listensource.x = listener->x; - listensource.y = listener->y; - listensource.z = listener->z; - listensource.angle = listener->angle; + // If listener is a chasecam player, use the camera instead + if (listener == players[displayplayers[i]].mo && camera[i].chase) + { + listensource.x = camera[i].x; + listensource.y = camera[i].y; + listensource.z = camera[i].z; + listensource.angle = camera[i].angle; + break; + } } if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case @@ -1370,7 +1107,7 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v approx_dist = FixedDiv(approx_dist,2*FRACUNIT); if (approx_dist > S_CLIPPING_DIST) - return 0; + return false; // angle of source to listener angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y); @@ -1405,9 +1142,6 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v *vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR; } - if (r_splitscreen) - *vol = FixedDiv((*vol)<>FRACBITS; - return (*vol > 0); } diff --git a/src/s_sound.h b/src/s_sound.h index 80a53fb3e..816a90fb5 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -295,6 +295,8 @@ void S_UpdateClosedCaptions(void); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); +INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume); + void S_SetSfxVolume(INT32 volume); void S_SetMusicVolume(INT32 digvolume); #define S_SetDigMusicVolume S_SetMusicVolume diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index 92d6a5184..65ff383ed 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -21,46 +21,25 @@ if(${SRB2_CONFIG_SDL2_USEMIXER}) endif() if(${SDL2_MIXER_FOUND}) set(SRB2_HAVE_MIXER ON) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) + target_sources(SRB2SDL2 PRIVATE mixer_sound.c) else() message(WARNING "You specified that SDL2_mixer is available, but it was not found. Falling back to sdl sound.") - set(SRB2_SDL2_SOUNDIMPL sdl_sound.c) + target_sources(SRB2SDL2 PRIVATE sdl_sound.c) endif() elseif(${MIXERX_FOUND}) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) + target_sources(SRB2SDL2 PRIVATE mixer_sound.c) else() - set(SRB2_SDL2_SOUNDIMPL sdl_sound.c) + target_sources(SRB2SDL2 PRIVATE sdl_sound.c) endif() -set(SRB2_SDL2_SOURCES - dosstr.c - endtxt.c - hwsym_sdl.c - i_main.c - i_net.c - i_system.c - i_ttf.c - i_video.c - #IMG_xpm.c - ogl_sdl.c +target_sourcefile(c) - ${SRB2_SDL2_SOUNDIMPL} -) - -set(SRB2_SDL2_HEADERS - endtxt.h - hwsym_sdl.h - i_ttf.h - ogl_sdl.h - sdlmain.h -) +target_sources(SRB2SDL2 PRIVATE ogl_sdl.c) if(${SRB2_CONFIG_HAVE_THREADS}) - set(SRB2_SDL2_SOURCES ${SRB2_SDL2_SOURCES} i_threads.c) + target_sources(SRB2SDL2 PRIVATE i_threads.c) endif() -source_group("Interface Code" FILES ${SRB2_SDL2_SOURCES} ${SRB2_SDL2_HEADERS}) - # Dependency if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) set(SDL2_FOUND ON) @@ -76,83 +55,29 @@ else() endif() if(${SDL2_FOUND}) - set(SRB2_SDL2_TOTAL_SOURCES - ${SRB2_CORE_SOURCES} - ${SRB2_CORE_HEADERS} - ${SRB2_DISCORDRPC_SOURCES} - ${SRB2_DISCORDRPC_HEADERS} - ${SRB2_PNG_SOURCES} - ${SRB2_PNG_HEADERS} - ${SRB2_CORE_RENDER_SOURCES} - ${SRB2_CORE_GAME_SOURCES} - ${SRB2_LUA_SOURCES} - ${SRB2_LUA_HEADERS} - ${SRB2_BLUA_SOURCES} - ${SRB2_BLUA_HEADERS} - ${SRB2_SDL2_SOURCES} - ${SRB2_SDL2_HEADERS} - ) - - source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS} - ${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS}) - source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) - source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) - source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) - source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) - source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) - source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) - - - if(${SRB2_CONFIG_HWRENDER}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_HWRENDER_SOURCES} - ${SRB2_HWRENDER_HEADERS} - ${SRB2_R_OPENGL_SOURCES} - ${SRB2_R_OPENGL_HEADERS} - ) - - source_group("Hardware" FILES ${SRB2_HWRENDER_SOURCES} ${SRB2_HWRENDER_HEADERS}) - source_group("Hardware\\OpenGL Renderer" FILES ${SRB2_R_OPENGL_SOURCES} ${SRB2_R_OPENGL_HEADERS}) - endif() - if(${SRB2_USEASM}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_NASM_SOURCES} - ) - if(MSVC) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_NASM_OBJECTS} - ) - set_source_files_properties(${SRB2_NASM_OBJECTS} PROPERTIES GENERATED ON) - else() - list(APPEND SRB2_SDL2_TOTAL_SOURCES ${SRB2_ASM_SOURCES}) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") - endif() + set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) + set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") endif() if(${CMAKE_SYSTEM} MATCHES Windows) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${CMAKE_SOURCE_DIR}/src/win32/win_dbg.c - ${CMAKE_SOURCE_DIR}/src/win32/Srb2win.rc - ) + target_sources(SRB2SDL2 PRIVATE + ../win32/win_dbg.c + ../win32/Srb2win.rc) endif() if(${CMAKE_SYSTEM} MATCHES Darwin) set(MACOSX_BUNDLE_ICON_FILE Srb2mac.icns) set_source_files_properties(macosx/Srb2mac.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - set(SRB2_SDL2_MAC_SOURCES + target_sources(SRB2SDL2 PRIVATE macosx/mac_alert.c macosx/mac_alert.h macosx/mac_resources.c macosx/mac_resources.h macosx/Srb2mac.icns ) - source_group("Interface Code\\OSX Compatibility" FILES ${SRB2_SDL2_MAC_SOURCES}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} ${SRB2_SDL2_MAC_SOURCES}) endif() - add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) if(${CMAKE_SYSTEM} MATCHES Windows) set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2win) elseif(${CMAKE_SYSTEM} MATCHES Linux) @@ -211,18 +136,6 @@ if(${SDL2_FOUND}) set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT}) set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM) endif() - - if(MSVC) - # using assembler with msvc doesn't work, must do it manually - foreach(ASMFILE ${SRB2_NASM_SOURCES}) - get_filename_component(ASMFILE_NAME ${ASMFILE} NAME_WE) - set(ASMFILE_NAME ${ASMFILE_NAME}.obj) - add_custom_command(TARGET SRB2SDL2 PRE_LINK - COMMAND ${ASM_ASSEMBLER_TEMP} ARGS -f ${ASM_ASSEMBLER_OBJFORMAT} -o ${CMAKE_CURRENT_BINARY_DIR}/${ASMFILE_NAME} ${ASMFILE} - COMMENT "assemble ${ASMFILE_NAME}." - ) - endforeach() - endif() endif() set_target_properties(SRB2SDL2 PROPERTIES VERSION ${SRB2_VERSION}) @@ -236,31 +149,6 @@ if(${SDL2_FOUND}) ) endif() - if(MSVC) - if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) - set(SDL2_MAIN_FOUND ON) - if(${SRB2_SYSTEM_BITS} EQUAL 64) - set(SDL2_MAIN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/include/SDL2) - set(SDL2_MAIN_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/lib -lSDL2main") - else() # 32-bit - set(SDL2_MAIN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/include/SDL2) - set(SDL2_MAIN_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/lib -lSDL2main") - endif() - else() - find_package(SDL2_MAIN REQUIRED) - endif() - target_link_libraries(SRB2SDL2 PRIVATE - ${SDL2_MAIN_LIBRARIES} - ) - target_compile_options(SRB2SDL2 PRIVATE - /Umain - /D_CRT_SECURE_NO_WARNINGS # something about string functions. - /D_CRT_NONSTDC_NO_DEPRECATE - /DSDLMAIN - /D_WINSOCK_DEPRECATED_NO_WARNINGS # Don't care - ) - endif() - target_include_directories(SRB2SDL2 PRIVATE ${SDL2_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIRS} diff --git a/src/sdl/MakeNIX.cfg b/src/sdl/MakeNIX.cfg deleted file mode 100644 index 6998a03ad..000000000 --- a/src/sdl/MakeNIX.cfg +++ /dev/null @@ -1,74 +0,0 @@ -# -# sdl/makeNIX.cfg for SRB2/?nix -# - -#Valgrind support -ifdef VALGRIND -VALGRIND_PKGCONFIG?=valgrind -VALGRIND_CFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --cflags) -VALGRIND_LDFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --libs) -ZDEBUG=1 -LIBS+=$(VALGRIND_LDFLAGS) -ifdef GCC46 -WFLAGS+=-Wno-error=unused-but-set-variable -WFLAGS+=-Wno-unused-but-set-variable -endif -endif - -# -#here is GNU/Linux and other -# - - OPTS=-DUNIXCOMMON - - #LDFLAGS = -L/usr/local/lib - LIBS=-lm -ifdef LINUX - LIBS+=-lrt -ifdef NOTERMIOS - OPTS+=-DNOTERMIOS -endif -endif - -ifdef LINUX64 - OPTS+=-DLINUX64 -endif - -# -#here is Solaris -# -ifdef SOLARIS - NOIPX=1 - NOASM=1 - OPTS+=-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP - OPTS+=-I/usr/local/include -I/opt/sfw/include - LDFLAGS+=-L/opt/sfw/lib - LIBS+=-lsocket -lnsl -endif - -# -#here is FreeBSD -# -ifdef FREEBSD - OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include - SDL_CONFIG?=sdl11-config - LDFLAGS+=-L/usr/X11R6/lib - LIBS+=-lipx -lkvm -endif - -# -#here is Mac OS X -# -ifdef MACOSX - OBJS+=$(OBJDIR)/mac_resources.o - OBJS+=$(OBJDIR)/mac_alert.o - LIBS+=-framework CoreFoundation -endif - -ifndef NOHW - OPTS+=-I/usr/X11R6/include - LDFLAGS+=-L/usr/X11R6/lib -endif - - # name of the exefile - EXENAME?=lsdl2srb2kart diff --git a/src/sdl/Makefile.cfg b/src/sdl/Makefile.cfg deleted file mode 100644 index 45d0d6ba7..000000000 --- a/src/sdl/Makefile.cfg +++ /dev/null @@ -1,125 +0,0 @@ -# -# sdl/makefile.cfg for SRB2/SDL -# - -# -#SDL...., *looks at Alam*, THIS IS A MESS! -# - -ifdef UNIXCOMMON -include sdl/MakeNIX.cfg -endif - -ifdef PANDORA -include sdl/SRB2Pandora/Makefile.cfg -endif #ifdef PANDORA - -ifdef CYGWIN32 -include sdl/MakeCYG.cfg -endif #ifdef CYGWIN32 - -ifdef SDL_PKGCONFIG -SDL_CFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --cflags) -SDL_LDFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --libs) -else -ifdef PREFIX - SDL_CONFIG?=$(PREFIX)-sdl2-config -else - SDL_CONFIG?=sdl2-config -endif - -ifdef STATIC - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --static-libs) -else - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --libs) -endif -endif - - - #use the x86 asm code -ifndef CYGWIN32 -ifndef NOASM - USEASM=1 -endif -endif - - OBJS+=$(OBJDIR)/i_video.o $(OBJDIR)/dosstr.o $(OBJDIR)/endtxt.o $(OBJDIR)/hwsym_sdl.o - - OPTS+=-DDIRECTFULLSCREEN -DHAVE_SDL - -ifndef NOHW - OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o -endif - -ifdef NOMIXER - i_sound_o=$(OBJDIR)/sdl_sound.o -else - i_sound_o=$(OBJDIR)/mixer_sound.o - OPTS+=-DHAVE_MIXER -ifdef HAVE_MIXERX - OPTS+=-DHAVE_MIXERX - SDL_LDFLAGS+=-lSDL2_mixer_ext -else - SDL_LDFLAGS+=-lSDL2_mixer -endif -endif - -ifndef NOTHREADS - OPTS+=-DHAVE_THREADS - OBJS+=$(OBJDIR)/i_threads.o -endif - -ifdef SDL_TTF - OPTS+=-DHAVE_TTF - SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz - OBJS+=$(OBJDIR)/i_ttf.o -endif - -ifdef SDL_IMAGE - OPTS+=-DHAVE_IMAGE - SDL_LDFLAGS+=-lSDL2_image -endif - -ifdef SDL_NET - OPTS+=-DHAVE_SDLNET - SDL_LDFLAGS+=-lSDL2_net -endif - -ifdef MINGW -ifndef NOSDLMAIN - SDLMAIN=1 -endif -endif - -ifdef SDLMAIN - OPTS+=-DSDLMAIN -else -ifdef MINGW - SDL_CFLAGS+=-Umain - SDL_LDFLAGS+=-mconsole -endif -endif - -ifndef NOHW -ifdef OPENAL -ifdef MINGW - LIBS:=-lopenal32 $(LIBS) -else - LIBS:=-lopenal $(LIBS) -endif -else -ifdef MINGW -ifdef DS3D - LIBS:=-ldsound -luuid $(LIBS) -endif -endif -endif -endif - -CFLAGS+=$(SDL_CFLAGS) -LIBS:=$(SDL_LDFLAGS) $(LIBS) -ifdef STATIC - LIBS+=$(shell $(SDL_CONFIG) --static-libs) -endif diff --git a/src/sdl/Sourcefile b/src/sdl/Sourcefile new file mode 100644 index 000000000..82d5ce073 --- /dev/null +++ b/src/sdl/Sourcefile @@ -0,0 +1,7 @@ +i_net.c +i_system.c +i_main.c +i_video.c +dosstr.c +endtxt.c +hwsym_sdl.c diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index ea5a12f3d..4a135c136 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -9,7 +9,7 @@ /// \file /// \brief SDL Mixer interface for sound -#ifdef HAVE_LIBGME +#ifdef HAVE_GME #ifdef HAVE_ZLIB #ifndef _MSC_VER #ifndef _LARGEFILE64_SOURCE @@ -27,7 +27,7 @@ #include #endif // HAVE_ZLIB -#endif // HAVE_LIBGME +#endif // HAVE_GME #include "../doomdef.h" #include "../doomstat.h" // menuactive @@ -79,11 +79,11 @@ write netcode into the sound code, OKAY? #define MUS_MODPLUG MUS_MODPLUG_UNUSED #endif -#ifdef HAVE_LIBGME +#ifdef HAVE_GME #include "gme/gme.h" #define GME_TREBLE 5.0f #define GME_BASS 1.0f -#endif // HAVE_LIBGME +#endif // HAVE_GME static UINT16 BUFFERSIZE = 2048; static UINT16 SAMPLERATE = 44100; @@ -123,7 +123,7 @@ static INT32 fading_id; static void (*fading_callback)(void); static boolean fading_nocleanup; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME static Music_Emu *gme; static UINT16 current_track; #endif @@ -157,7 +157,7 @@ static void var_cleanup(void) internal_volume = 100; } -#if defined (HAVE_LIBGME) && defined (HAVE_ZLIB) +#if defined (HAVE_GME) && defined (HAVE_ZLIB) static const char* get_zlib_error(int zErr) { switch (zErr) @@ -250,7 +250,7 @@ void I_ShutdownSound(void) SDL_QuitSubSystem(SDL_INIT_AUDIO); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) gme_delete(gme); #endif @@ -394,7 +394,7 @@ void *I_GetSfx(sfxinfo_t *sfx) void *lump; Mix_Chunk *chunk; SDL_RWops *rw; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME Music_Emu *emu; gme_info_t *info; #endif @@ -414,7 +414,7 @@ void *I_GetSfx(sfxinfo_t *sfx) } // Not a doom sound? Try something else. -#ifdef HAVE_LIBGME +#ifdef HAVE_GME // VGZ format if (((UINT8 *)lump)[0] == 0x1F && ((UINT8 *)lump)[1] == 0x8B) @@ -700,7 +700,7 @@ static UINT32 music_fade(UINT32 interval, void *param) } } -#ifdef HAVE_LIBGME +#ifdef HAVE_GME static void mix_gme(void *udata, Uint8 *stream, int len) { int i; @@ -760,7 +760,7 @@ void I_ShutdownMusic(void) musictype_t I_SongType(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) return MU_GME; else @@ -791,7 +791,7 @@ musictype_t I_SongType(void) boolean I_SongPlaying(void) { return ( -#ifdef HAVE_LIBGME +#ifdef HAVE_GME (I_SongType() == MU_GME && gme) || #endif #ifdef HAVE_OPENMPT @@ -814,7 +814,7 @@ boolean I_SetSongSpeed(float speed) { if (speed > 250.0f) speed = 250.0f; //limit speed up to 250x -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { SDL_LockAudio(); @@ -856,7 +856,7 @@ UINT32 I_GetSongLength(void) { INT32 length; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_info_t *info; @@ -926,7 +926,7 @@ boolean I_SetSongLoopPoint(UINT32 looppoint) UINT32 I_GetSongLoopPoint(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { INT32 looppoint; @@ -955,7 +955,7 @@ UINT32 I_GetSongLoopPoint(void) boolean I_SetSongPosition(UINT32 position) { UINT32 length; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { // this is unstable, so fail silently @@ -1020,7 +1020,7 @@ boolean I_SetSongPosition(UINT32 position) UINT32 I_GetSongPosition(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { INT32 position = gme_tell(gme); @@ -1105,7 +1105,7 @@ boolean I_LoadSong(char *data, size_t len) SDL_RWops *rw; if (music -#ifdef HAVE_LIBGME +#ifdef HAVE_GME || gme #endif #ifdef HAVE_OPENMPT @@ -1117,7 +1117,7 @@ boolean I_LoadSong(char *data, size_t len) // always do this whether or not a music already exists var_cleanup(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if ((UINT8)data[0] == 0x1F && (UINT8)data[1] == 0x8B) { @@ -1244,7 +1244,7 @@ void I_UnloadSong(void) { I_StopSong(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_delete(gme); @@ -1267,7 +1267,7 @@ void I_UnloadSong(void) boolean I_PlaySong(boolean looping) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; @@ -1333,7 +1333,7 @@ void I_StopSong(void) if (!fading_nocleanup) I_StopFadingSong(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { Mix_HookMusic(NULL, NULL); @@ -1395,7 +1395,7 @@ void I_SetMusicVolume(int volume) boolean I_SetSongTrack(int track) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME // If the specified track is within the number of tracks playing, then change it if (gme) { diff --git a/src/sounds.c b/src/sounds.c index dc777a088..e9a13da77 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -87,7 +87,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"fire", false, 8, 32, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, {"grind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic grinding"}, {"laser", true, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Laser hum"}, - {"mswing", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging mace"}, + {"mswing", false, 16, 65, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging mace"}, {"pstart", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"}, {"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"}, {"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001 @@ -630,8 +630,8 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kc7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, // ditto {"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, {"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, // ditto - {"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, - {"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, // ditto + {"s3kc9s", false, 64, 65, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, + {"s3kc9l", false, 64, 65, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, // ditto {"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, {"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto {"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, @@ -837,6 +837,209 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + // Mean Bean Machine sounds + {"mbs41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbs72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"mbv97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + + // SegaSonic Arcade sounds + {"ssa001", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa002", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa003", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa004", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa005", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa006", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa007", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa008", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa009", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa010", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa011", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa012", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa013", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa014", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa015", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa016", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa017", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa018", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa019", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa020", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa021", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa022", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa023", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa024", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa025", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa026", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa027", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa028", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa029", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa030", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa031", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa032", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa033", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa034", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa035", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa036", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa037", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa038", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa039", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa040", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa041", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa042", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa043", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa044", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa045", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa046", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa047", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa048", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa049", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa050", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa051", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa052", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa053", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa054", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa055", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa056", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa057", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa058", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa059", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa060", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa061", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa062", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa063", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa064", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa065", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa066", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa067", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa068", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa069", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa070", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa071", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa072", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa073", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa074", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa075", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa076", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa077", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa078", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa079", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa080", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa081", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa082", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa083", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa084", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa085", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa086", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa087", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa088", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa089", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa090", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa091", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa092", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa093", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa094", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa095", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa096", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa097", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa098", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa099", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa100", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa101", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa102", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa103", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa104", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa105", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa106", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa107", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa108", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa109", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa110", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa111", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa112", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa113", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa114", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa115", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa116", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa117", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa118", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa119", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa120", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa121", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa122", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa123", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa124", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa125", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa126", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa127", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa128", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa129", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa130", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + // SRB2kart {"slip", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Spinout {"screec", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Tight turning screech @@ -895,6 +1098,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // :shitsfree: {"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Debug notification {"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang + {"itcaps", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, "Item capsule"}, // SRB2Kart - Engine sounds // Engine class A diff --git a/src/sounds.h b/src/sounds.h index 51155c7c3..9abf99117 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -901,6 +901,209 @@ typedef enum sfx_kc6d, sfx_kc6e, + // Mean Bean Machine sounds + sfx_mbs41, + sfx_mbs42, + sfx_mbs43, + sfx_mbs44, + sfx_mbs45, + sfx_mbs46, + sfx_mbs47, + sfx_mbs48, + sfx_mbs49, + sfx_mbs4a, + sfx_mbs4b, + sfx_mbs4c, + sfx_mbs4d, + sfx_mbs4e, + sfx_mbs4f, + sfx_mbs50, + sfx_mbs51, + sfx_mbs52, + sfx_mbs53, + sfx_mbs54, + sfx_mbs55, + sfx_mbs56, + sfx_mbs57, + sfx_mbs58, + sfx_mbs59, + sfx_mbs5a, + sfx_mbs5b, + sfx_mbs5c, + sfx_mbs5d, + sfx_mbs5e, + sfx_mbs5f, + sfx_mbs60, + sfx_mbs61, + sfx_mbs62, + sfx_mbs63, + sfx_mbs64, + sfx_mbs67, + sfx_mbs68, + sfx_mbs69, + sfx_mbs6a, + sfx_mbs6b, + sfx_mbs6d, + sfx_mbs6e, + sfx_mbs70, + sfx_mbs71, + sfx_mbs72, + sfx_mbv81, + sfx_mbv82, + sfx_mbv83, + sfx_mbv84, + sfx_mbv85, + sfx_mbv86, + sfx_mbv87, + sfx_mbv88, + sfx_mbv89, + sfx_mbv8a, + sfx_mbv8b, + sfx_mbv8c, + sfx_mbv8d, + sfx_mbv8e, + sfx_mbv8f, + sfx_mbv90, + sfx_mbv91, + sfx_mbv92, + sfx_mbv93, + sfx_mbv94, + sfx_mbv95, + sfx_mbv96, + sfx_mbv97, + + // SegaSonic Arcade sounds + sfx_ssa001, + sfx_ssa002, + sfx_ssa003, + sfx_ssa004, + sfx_ssa005, + sfx_ssa006, + sfx_ssa007, + sfx_ssa008, + sfx_ssa009, + sfx_ssa010, + sfx_ssa011, + sfx_ssa012, + sfx_ssa013, + sfx_ssa014, + sfx_ssa015, + sfx_ssa016, + sfx_ssa017, + sfx_ssa018, + sfx_ssa019, + sfx_ssa020, + sfx_ssa021, + sfx_ssa022, + sfx_ssa023, + sfx_ssa024, + sfx_ssa025, + sfx_ssa026, + sfx_ssa027, + sfx_ssa028, + sfx_ssa029, + sfx_ssa030, + sfx_ssa031, + sfx_ssa032, + sfx_ssa033, + sfx_ssa034, + sfx_ssa035, + sfx_ssa036, + sfx_ssa037, + sfx_ssa038, + sfx_ssa039, + sfx_ssa040, + sfx_ssa041, + sfx_ssa042, + sfx_ssa043, + sfx_ssa044, + sfx_ssa045, + sfx_ssa046, + sfx_ssa047, + sfx_ssa048, + sfx_ssa049, + sfx_ssa050, + sfx_ssa051, + sfx_ssa052, + sfx_ssa053, + sfx_ssa054, + sfx_ssa055, + sfx_ssa056, + sfx_ssa057, + sfx_ssa058, + sfx_ssa059, + sfx_ssa060, + sfx_ssa061, + sfx_ssa062, + sfx_ssa063, + sfx_ssa064, + sfx_ssa065, + sfx_ssa066, + sfx_ssa067, + sfx_ssa068, + sfx_ssa069, + sfx_ssa070, + sfx_ssa071, + sfx_ssa072, + sfx_ssa073, + sfx_ssa074, + sfx_ssa075, + sfx_ssa076, + sfx_ssa077, + sfx_ssa078, + sfx_ssa079, + sfx_ssa080, + sfx_ssa081, + sfx_ssa082, + sfx_ssa083, + sfx_ssa084, + sfx_ssa085, + sfx_ssa086, + sfx_ssa087, + sfx_ssa088, + sfx_ssa089, + sfx_ssa090, + sfx_ssa091, + sfx_ssa092, + sfx_ssa093, + sfx_ssa094, + sfx_ssa095, + sfx_ssa096, + sfx_ssa097, + sfx_ssa098, + sfx_ssa099, + sfx_ssa100, + sfx_ssa101, + sfx_ssa102, + sfx_ssa103, + sfx_ssa104, + sfx_ssa105, + sfx_ssa106, + sfx_ssa107, + sfx_ssa108, + sfx_ssa109, + sfx_ssa110, + sfx_ssa111, + sfx_ssa112, + sfx_ssa113, + sfx_ssa114, + sfx_ssa115, + sfx_ssa116, + sfx_ssa117, + sfx_ssa118, + sfx_ssa119, + sfx_ssa120, + sfx_ssa121, + sfx_ssa122, + sfx_ssa123, + sfx_ssa124, + sfx_ssa125, + sfx_ssa126, + sfx_ssa127, + sfx_ssa128, + sfx_ssa129, + sfx_ssa130, + // SRB2kart sfx_slip, sfx_screec, @@ -959,6 +1162,7 @@ typedef enum sfx_itfree, sfx_dbgsal, sfx_cock, + sfx_itcaps, // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight diff --git a/src/st_stuff.c b/src/st_stuff.c index aa7a39259..ee03a07a4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -31,6 +31,7 @@ #include "m_misc.h" // moviemode #include "m_anigif.h" // cv_gif_downscale #include "p_setup.h" // NiGHTS grading +#include "k_grandprix.h" // we need to know grandprix status for titlecards //random index #include "m_random.h" @@ -622,23 +623,97 @@ static void ST_drawDebugInfo(void) V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); } -static patch_t *lt_patches[3]; -static INT32 lt_scroll = 0; -static INT32 lt_mom = 0; -static INT32 lt_zigzag = 0; - tic_t lt_ticker = 0, lt_lasttic = 0; tic_t lt_exitticker = 0, lt_endtime = 0; +// SRB2KART: HUD shit for new titlecards: +static patch_t *tcchev1; +static patch_t *tcchev2; + +static patch_t *tcol1; +static patch_t *tcol2; + +static patch_t *tcroundbar; +static patch_t *tcround; + +static patch_t *tccircletop; +static patch_t *tccirclebottom; +static patch_t *tccirclebg; + +static patch_t *tcbanner; +static patch_t *tcbanner2; + +static patch_t *tcroundnum[10]; +static patch_t *tcactnum[10]; +static patch_t *tcact; + +// some coordinates define to make my life easier.... +#define FINAL_ROUNDX (24) +#define FINAL_EGGY (160) +#define FINAL_ROUNDY (16) +#define FINAL_BANNERY (160) + +INT32 chev1x, chev1y, chev2x, chev2y, chevtflag; +INT32 roundx, roundy; +INT32 bannerx, bannery; + +INT32 roundnumx, roundnumy; +INT32 eggx1, eggx2, eggy1, eggy2; + +// These are all arbitrary values found by trial and error trying to align the hud lmao. +// But they'll work. +#define BASE_CHEV1X (252) +#define BASE_CHEV1Y (60) +#define BASE_CHEV2X (65) +#define BASE_CHEV2Y (135) + +#define TTANIMTHRESHOLD (TICRATE) +#define TTANIMSTART (TTANIMTHRESHOLD-16) +#define TTANIMENDTHRESHOLD (TICRATE*3) +#define TTANIMEND (TICRATE*4) + // // Load the graphics for the title card. // Don't let LJ see this // static void ST_cacheLevelTitle(void) { - lt_patches[0] = (patch_t *)W_CachePatchName("LTACTBLU", PU_HUDGFX); - lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGZAG", PU_HUDGFX); - lt_patches[2] = (patch_t *)W_CachePatchName("LTZZTEXT", PU_HUDGFX); + UINT8 i; + char buf[9]; + + // SRB2KART + tcchev1 = (patch_t *)W_CachePatchName("TCCHEV1W", PU_HUDGFX); + tcchev2 = (patch_t *)W_CachePatchName("TCCHEV2W", PU_HUDGFX); + + tcol1 = (patch_t *)W_CachePatchName("TCCHOL1", PU_HUDGFX); + tcol2 = (patch_t *)W_CachePatchName("TCCHOL2", PU_HUDGFX); + + tcroundbar = (patch_t *)W_CachePatchName("TCBB0", PU_HUDGFX); + tcround = (patch_t *)W_CachePatchName("TCROUND", PU_HUDGFX); + + tccircletop = (patch_t *)W_CachePatchName("TCSN1", PU_HUDGFX); + tccirclebottom =(patch_t *)W_CachePatchName("TCSN2", PU_HUDGFX); + tccirclebg = (patch_t *)W_CachePatchName("TCEG3", PU_HUDGFX); + + tcbanner = (patch_t *)W_CachePatchName("TCBSKA0", PU_HUDGFX); + tcbanner2 = (patch_t *)W_CachePatchName("TCBC0", PU_HUDGFX); + + tcact = (patch_t *)W_CachePatchName("TT_ACT", PU_HUDGFX); + + // Cache round # + for (i=1; i < 11; i++) + { + sprintf(buf, "TT_RND%d", i); + tcroundnum[i-1] = (patch_t *)W_CachePatchName(buf, PU_HUDGFX); + } + + // Cache act # + for (i=0; i < 10; i++) + { + sprintf(buf, "TT_ACT%d", i); + tcactnum[i] = (patch_t *)W_CachePatchName(buf, PU_HUDGFX); + } + } // @@ -649,12 +724,28 @@ void ST_startTitleCard(void) // cache every HUD patch used ST_cacheLevelTitle(); + // Set most elements to start off-screen, ST_runTitleCard will have them slide in afterwards + chev1x = BASE_CHEV1X +350; // start off-screen + chev1y = BASE_CHEV1Y; + chev2x = BASE_CHEV2X -350; // start off-screen + chev2y = BASE_CHEV2Y; + chevtflag = 0; + + roundx = -999; + roundy = -999; + + roundnumx = -999; + roundnumy = -999; + eggx1 = -999; + eggx2 = -999; + eggy1 = -999; + eggy2 = -999; + + bannery = 300; + // initialize HUD variables lt_ticker = lt_exitticker = lt_lasttic = 0; - lt_endtime = 2*TICRATE + (10*NEWTICRATERATIO); - lt_scroll = BASEVIDWIDTH * FRACUNIT; - lt_zigzag = -((lt_patches[1])->width * FRACUNIT); - lt_mom = 0; + lt_endtime = 4*TICRATE; // + (10*NEWTICRATERATIO); } // @@ -679,6 +770,8 @@ void ST_preDrawTitleCard(void) void ST_runTitleCard(void) { boolean run = !(paused || P_AutoPause()); + INT32 auxticker; + boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); // check whether we're in grandprix if (!G_IsTitleCardAvailable()) return; @@ -690,35 +783,137 @@ void ST_runTitleCard(void) { // tick lt_ticker++; + + // SRB2KART + // side Zig-Zag positions... + + // TITLECARD START + if (lt_ticker < TTANIMSTART) + { + chev1x = max(BASE_CHEV1X, (BASE_CHEV1X +350) - (INT32)(lt_ticker)*50); + chev2x = min(BASE_CHEV2X, (BASE_CHEV2X -350) + (INT32)(lt_ticker)*50); + } + + // OPEN ZIG-ZAGS 1 SECOND IN + if (lt_ticker > TTANIMTHRESHOLD) + { + auxticker = (INT32)(lt_ticker) - TTANIMTHRESHOLD; + + chev1x = min(320, BASE_CHEV1X + auxticker*16); + chev1y = max(0, BASE_CHEV1Y - auxticker*16); + + chev2x = max(0, BASE_CHEV2X - auxticker*16); + chev2y = min(200, BASE_CHEV2Y + auxticker*16); + + // translucent fade after opening up. + chevtflag = min(5, ((auxticker)/5)) << V_ALPHASHIFT; + + + // OPEN ZIG-ZAG: END OF ANIMATION (they leave the screen borders) + if (lt_ticker > TTANIMENDTHRESHOLD) + { + auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD; + + chev1x += auxticker*16; + chev1y -= auxticker*16; + + chev2x -= auxticker*16; + chev2y += auxticker*16; + } + } + + // ROUND BAR + EGG + + eggy1 = FINAL_EGGY; // Make sure to reset that each call so that Y position doesn't go bonkers + + // SLIDE BAR IN, SLIDE "ROUND" DOWNWARDS + if (lt_ticker <= TTANIMTHRESHOLD) + { + INT32 interptimer = (INT32)lt_ticker - TTANIMSTART; + // INT32 because tic_t is unsigned and we want this to be potentially negative + + if (interptimer >= 0) + { + INT32 interpdiff = ((TTANIMTHRESHOLD-TTANIMSTART) - interptimer); + interpdiff *= interpdiff; // interpdiff^2 + + roundx = FINAL_ROUNDX - interpdiff; + roundy = FINAL_ROUNDY - interpdiff; + eggy1 = FINAL_EGGY + interpdiff; + + } + } + // SLIDE BAR OUT, SLIDE "ROUND" DOWNWARDS FASTER + else if (lt_ticker >= TTANIMENDTHRESHOLD) + { + auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD; + + roundx = FINAL_ROUNDX - auxticker*24; + roundy = FINAL_ROUNDY + auxticker*48; + eggy1 = FINAL_EGGY + auxticker*48; + } + + // follow the round bar. + eggx1 = roundx + tcroundbar->width/2; + + // initially, both halves are on the same coordinates. + eggx2 = eggx1; + eggy2 = eggy1; + // same for the background (duh) + roundnumx = eggx1; + roundnumy = eggy1; + + // split both halves of the egg, but only do that in grand prix! + if (gp && lt_ticker > TTANIMTHRESHOLD + TICRATE/2) + { + auxticker = (INT32)lt_ticker - (TTANIMTHRESHOLD + TICRATE/2); + + eggx1 -= auxticker*12; + eggy1 -= auxticker*12; + + eggx2 += auxticker*12; + eggy2 += auxticker*12; + + } + + + // SCROLLING BOTTOM BANNER + + // SLIDE BANNER UPWARDS WITH A FUNNY BOUNCE (this requires trig :death:) + if (lt_ticker < TTANIMTHRESHOLD) + { + INT32 costimer = (INT32)lt_ticker - TTANIMSTART; + // INT32 because tic_t is unsigned and we want this to be potentially negative + + if (costimer > 0) + { + // For this animation, we're going to do a tiny bit of stupid trigonometry. + // Admittedly all of this is going to look like magic numbers, and honestly? They are. + + // start at angle 355 (where y = ~230 with our params) + // and go to angle 131 (where y = ~160 with our params) + + UINT8 basey = 190; + UINT8 amplitude = 45; + fixed_t ang = (355 - costimer*14)*FRACUNIT; + + bannery = basey + (amplitude * FINECOSINE(FixedAngle(ang)>>ANGLETOFINESHIFT)) / FRACUNIT; + } + } + // SLIDE BANNER DOWNWARDS OUT OF THE SCREEN AT THE END + else if (lt_ticker >= TTANIMENDTHRESHOLD) + { + auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD; + bannery = FINAL_BANNERY + auxticker*16; + } + + // No matter the circumstances, scroll the banner... + bannerx = -(lt_ticker%(tcbanner->width)); + + + // used for hud slidein if (lt_ticker >= lt_endtime) lt_exitticker++; - - // scroll to screen (level title) - if (!lt_exitticker) - { - if (abs(lt_scroll) > FRACUNIT) - lt_scroll -= (lt_scroll>>2); - else - lt_scroll = 0; - } - // scroll away from screen (level title) - else - { - lt_mom -= FRACUNIT*6; - lt_scroll += lt_mom; - } - - // scroll to screen (zigzag) - if (!lt_exitticker) - { - if (abs(lt_zigzag) > FRACUNIT) - lt_zigzag -= (lt_zigzag>>2); - else - lt_zigzag = 0; - } - // scroll away from screen (zigzag) - else - lt_zigzag += lt_mom; } } @@ -729,25 +924,17 @@ void ST_runTitleCard(void) void ST_drawTitleCard(void) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; - char *subttl = mapheaderinfo[gamemap-1]->subttl; char *zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; - INT32 lvlttlxpos, ttlnumxpos, zonexpos; - INT32 subttlxpos = BASEVIDWIDTH/2; - INT32 ttlscroll = FixedInt(lt_scroll); -#ifdef TITLEPATCHES - INT32 zzticker; - patch_t *actpat, *zigzag, *zztext; - UINT8 colornum; - const UINT8 *colormap; + boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); - if (players[g_localplayers[0]].skincolor) - colornum = players[g_localplayers[0]].skincolor; - else - colornum = cv_playercolor[0].value; + INT32 acttimer; + fixed_t actscale; + angle_t fakeangle; - colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); -#endif + INT32 bx = bannerx; // We need to make a copy of that otherwise pausing will cause problems. + + UINT8 i; if (!G_IsTitleCardAvailable()) return; @@ -761,95 +948,118 @@ void ST_drawTitleCard(void) if ((lt_ticker-lt_lasttic) > 1) lt_ticker = lt_lasttic+1; - ST_cacheLevelTitle(); + // Avoid HOMs while drawing the start of the titlecard + if (lt_ticker < TTANIMSTART) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); -#ifdef TITLEPATCHES - actpat = lt_patches[0]; - zigzag = lt_patches[1]; - zztext = lt_patches[2]; -#endif + // Background zig-zags + V_DrawFixedPatch((chev1x)*FRACUNIT, (chev1y)*FRACUNIT, FRACUNIT, chevtflag, tcchev1, NULL); + V_DrawFixedPatch((chev2x)*FRACUNIT, (chev2y)*FRACUNIT, FRACUNIT, chevtflag, tcchev2, NULL); - lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)); - if (actnum > 0) - lvlttlxpos -= V_LevelNameWidth(va("%d", actnum)); + // Draw ROUND bar, scroll it downwards. + V_DrawFixedPatch(roundx*FRACUNIT, ((-32) + (lt_ticker%32))*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, tcroundbar, NULL); + // Draw ROUND text + if (gp) + V_DrawFixedPatch((roundx+10)*FRACUNIT, roundy*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, tcround, NULL); - zonexpos = ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl); - if (zonttl[0]) - zonexpos -= V_LevelNameWidth(zonttl); // SRB2kart - else - zonexpos -= V_LevelNameWidth(M_GetText("Zone")); + // round num background + V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccirclebg, NULL); - ttlnumxpos++; - - if (lvlttlxpos < 0) - lvlttlxpos = 0; - -#ifdef TITLEPATCHES - if (!splitscreen || (splitscreen && stplyr == &players[displayplayers[0]])) + // Scrolling banner, we'll draw 3 of those back to back. + for (i=0; i < 3; i++) { - zzticker = lt_ticker; - V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); - V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); - V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); - V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); + V_DrawFixedPatch((bannerx + bx)*FRACUNIT, (bannery)*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tcbanner, NULL); + bx += tcbanner->width; } -#endif - if (actnum) + // If possible, draw round number + if (gp && grandprixinfo.roundnum > 0 && grandprixinfo.roundnum < 11) // Check boundaries JUST IN CASE. + V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tcroundnum[grandprixinfo.roundnum-1], NULL); + + // Draw both halves of the egg + V_DrawFixedPatch(eggx1*FRACUNIT, eggy1*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccircletop, NULL); + V_DrawFixedPatch(eggx2*FRACUNIT, eggy2*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccirclebottom, NULL); + + // Now the level name. + V_DrawTitleCardString((actnum) ? 265 : 280, 60, lvlttl, V_SNAPTORIGHT, true, lt_ticker, TTANIMENDTHRESHOLD); + + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + V_DrawTitleCardString((actnum) ? 265 : 280, 60+32, strlen(zonttl) ? zonttl : "ZONE", V_SNAPTORIGHT, true, lt_ticker - strlen(lvlttl), TTANIMENDTHRESHOLD); + + // the act has a similar graphic animation, but we'll handle it here since it's only like 2 graphics lmfao. + if (actnum && actnum < 10) { -#ifdef TITLEPATCHES - if (!splitscreen) + + // compute delay before the act should appear. + acttimer = lt_ticker - strlen(lvlttl); + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + acttimer -= strlen((strlen(zonttl)) ? (zonttl) : ("ZONE")); + + actscale = 0; + fakeangle = 0; + + if (acttimer >= 0) { - if (actnum > 9) // slightly offset the act diamond for two-digit act numbers - V_DrawMappedPatch(ttlnumxpos + (V_LevelNameWidth(va("%d", actnum))/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); - else - V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); - } -#endif - V_DrawLevelTitle(ttlnumxpos + ttlscroll, 104, 0, va("%d", actnum)); - } - V_DrawLevelTitle(lvlttlxpos - ttlscroll, 80, 0, lvlttl); - if (zonttl[0]) - V_DrawLevelTitle(zonexpos + ttlscroll, 104, 0, zonttl); - else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - V_DrawLevelTitle(zonexpos + ttlscroll, 104, 0, M_GetText("Zone")); - V_DrawCenteredString(subttlxpos - ttlscroll, 135, 0|V_ALLOWLOWERCASE, subttl); + if (acttimer < TTANIMENDTHRESHOLD) // spin in + { + fakeangle = min(360 + 90, acttimer*41) * ANG1; + actscale = FINESINE(fakeangle>>ANGLETOFINESHIFT); + } + else // spin out + { + // Make letters disappear... + acttimer -= TTANIMENDTHRESHOLD; + + fakeangle = max(0, (360+90) - acttimer*41)*ANG1; + actscale = FINESINE(fakeangle>>ANGLETOFINESHIFT); + } + + if (actscale) + { + // draw the top: + V_DrawStretchyFixedPatch(286*FRACUNIT, 76*FRACUNIT, abs(actscale), FRACUNIT, V_SNAPTORIGHT|(actscale < 0 ? V_FLIP : 0), tcact, NULL); + V_DrawStretchyFixedPatch(286*FRACUNIT, 123*FRACUNIT, abs(actscale), FRACUNIT, V_SNAPTORIGHT|(actscale < 0 ? V_FLIP : 0), tcactnum[actnum], NULL); + } + } + } lt_lasttic = lt_ticker; luahook: LUAh_TitleCardHUD(stplyr); + } +// Clear defined coordinates, we don't need them anymore +#undef FINAL_ROUNDX +#undef FINAL_EGGY +#undef FINAL_ROUNDY +#undef FINAL_BANNERY + +#undef BASE_CHEV1X +#undef BASE_CHEV1Y +#undef BASE_CHEV2X +#undef BASE_CHEV2Y + +#undef TTANIMTHRESHOLD +#undef TTANIMSTART +#undef TTANIMENDTHRESHOLD +#undef TTANIMEND + // // Drawer for G_PreLevelTitleCard. // void ST_preLevelTitleCardDrawer(void) { V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - ST_drawWipeTitleCard(); + + ST_drawTitleCard(); I_OsPolling(); I_UpdateNoBlit(); } -// -// Draw the title card while on a wipe. -// Also used in G_PreLevelTitleCard. -// -void ST_drawWipeTitleCard(void) -{ - UINT8 i; - - for (i = 0; i <= r_splitscreen; i++) - { - stplyr = &players[displayplayers[i]]; - ST_preDrawTitleCard(); - ST_drawTitleCard(); - } -} - // // Draw the status bar overlay, customisable: the user chooses which // kind of information to overlay @@ -909,7 +1119,7 @@ static void ST_overlayDrawer(void) { const char *itemtxt = M_GetText("Item - Join Game"); - if (stplyr->powers[pw_flashing]) + if (stplyr->flashing) itemtxt = M_GetText("Item - . . ."); else if (stplyr->pflags & PF_WANTSTOJOIN) itemtxt = M_GetText("Item - Cancel Join"); diff --git a/src/st_stuff.h b/src/st_stuff.h index cc771c053..a17f72c1f 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -64,7 +64,6 @@ void ST_runTitleCard(void); void ST_drawTitleCard(void); void ST_preDrawTitleCard(void); void ST_preLevelTitleCardDrawer(void); -void ST_drawWipeTitleCard(void); extern tic_t lt_ticker, lt_lasttic; extern tic_t lt_exitticker, lt_endtime; diff --git a/src/v_video.c b/src/v_video.c index 85adeb4eb..5bd7ba733 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1676,6 +1676,149 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UI V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/2, flags, fontv[HU_FONT].font[c], colormap); } +// V_TitleCardStringWidth +// Get the string's width using the titlecard font. +INT32 V_TitleCardStringWidth(const char *str) +{ + INT32 xoffs = 0; + const char *ch = str; + char c; + patch_t *pp; + + for (;;ch++) + { + if (!*ch) + break; + + if (*ch == '\n') + { + xoffs = 0; + continue; + } + + c = *ch; + c = toupper(c); + c -= LT_FONTSTART; + + // check if character exists, if not, it's a space. + if (c < 0 || c >= LT_FONTSIZE || !tc_font[0][(INT32)c]) + { + xoffs += 10; + continue; + } + + pp = tc_font[1][(INT32)c]; + + xoffs += pp->width-5; + } + + return xoffs; +} + +// V_DrawTitleCardScreen. +// see v_video.h's prototype for more information. +// +void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boolean alignright, INT32 timer, INT32 threshold) +{ + + INT32 xoffs = 0; + INT32 yoffs = 0; + INT32 i = 0; + + // per-letter variables + fixed_t scalex; + fixed_t offs; + INT32 let_time; + INT32 flipflag; + angle_t fakeang; + + const char *ch = str; + char c; + patch_t *pp; + patch_t *ol; + + x -= 2; // Account for patch width... + + if (alignright) + x -= V_TitleCardStringWidth(str); + + + for (;;ch++, i++) + { + + scalex = FRACUNIT; + offs = 0; + let_time = timer - i; + flipflag = 0; + + if (!*ch) + break; + + if (*ch == '\n') + { + xoffs = x; + yoffs += 32; + + continue; + } + + c = *ch; + + c = toupper(c); + c -= LT_FONTSTART; + + // check if character exists, if not, it's a space. + if (c < 0 || c >= LT_FONTSIZE || !tc_font[1][(INT32)c]) + { + xoffs += 10; + continue; + } + + ol = tc_font[0][(INT32)c]; + pp = tc_font[1][(INT32)c]; + + if (timer) + { + + // make letters appear + if (!threshold || let_time < threshold) + { + if (let_time <= 0) + return; // No reason to continue drawing, none of the next letters will be drawn either. + + // otherwise; scalex must start at 0 + // let's have each letter do 4 spins (360*4 + 90 = 1530 "degrees") + fakeang = min(360 + 90, let_time*41) * ANG1; + scalex = FINESINE(fakeang>>ANGLETOFINESHIFT); + } + else if (let_time > threshold) + { + // Make letters disappear... + let_time -= threshold; + + fakeang = max(0, (360+90) - let_time*41)*ANG1; + scalex = FINESINE(fakeang>>ANGLETOFINESHIFT); + } + + // Because of how our patches are offset, we need to counter the displacement caused by changing the scale with an offset of our own. + offs = ((FRACUNIT-scalex)*pp->width)/2; + } + + // And now, we just need to draw the stuff. + flipflag = (scalex < 0) ? V_FLIP : 0; + + if (scalex && ol && pp) + { + //CONS_Printf("%d\n", (INT32)c); + V_DrawStretchyFixedPatch((x + xoffs)*FRACUNIT + offs, (y+yoffs)*FRACUNIT, abs(scalex), FRACUNIT, flags|flipflag, ol, NULL); + V_DrawStretchyFixedPatch((x + xoffs)*FRACUNIT + offs, (y+yoffs)*FRACUNIT, abs(scalex), FRACUNIT, flags|flipflag, pp, NULL); + } + + xoffs += pp->width -5; + } +} + + // Precompile a wordwrapped string to any given width. // This is a muuuch better method than V_WORDWRAP. char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) diff --git a/src/v_video.h b/src/v_video.h index 08a279fd0..da4506c9a 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -262,6 +262,16 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st #define V_DrawThinStringAtFixed( x,y,option,string ) \ V__DrawOneScaleString (x,y,FRACUNIT,option,TINY_FONT,string) +// Draws a titlecard font string. +// timer: when the letters start appearing (leave to 0 to disable) +// threshold: when the letters start disappearing (leave to 0 to disable) (both are INT32 in case you supply negative values...) +// NOTE: This function ignores most conventional string flags (V_RETURN8, V_ALLOWLOWERCASE ...) +// NOTE: This font only works with uppercase letters. +void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boolean alignright, INT32 timer, INT32 threshold); + +// returns thr width of a string drawn using the above function. +INT32 V_TitleCardStringWidth(const char *str); + // Draw tall nums, used for menu, HUD, intermission void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg deleted file mode 100644 index 85ee0d6b5..000000000 --- a/src/win32/Makefile.cfg +++ /dev/null @@ -1,161 +0,0 @@ -# -# win32/Makefile.cfg for SRB2/Minwgw -# - -# -#Mingw, if you don't know, that's Win32/Win64 -# - -ifdef MINGW64 - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86_64/mingw -lopenmpt -endif -ifndef NOMIXERX - HAVE_MIXERX=1 - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDLMixerX/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -else - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif -else - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win32 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86/mingw -lopenmpt -endif -ifndef NOMIXERX - HAVE_MIXERX=1 - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDLMixerX/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -else - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDL2_mixer/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif -endif - -ifndef NOASM - USEASM=1 -endif - -ifndef NONET -ifndef MINGW64 #miniupnc is broken with MINGW64 - HAVE_MINIUPNPC=1 -endif -endif - -ifndef NO_DISCORDRPC - HAVE_DISCORDRPC=1 -endif - - OPTS=-DSTDC_HEADERS - -ifndef GCC44 - #OPTS+=-mms-bitfields -endif - - LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 -ifdef MINGW64 - LIBS+=-lws2_32 -else -ifdef NO_IPV6 - LIBS+=-lwsock32 -else - LIBS+=-lws2_32 -endif -endif - -ifndef MINGW64 - CPPFLAGS+=-I../libs/drmingw/include - LDFLAGS+=-L../libs/drmingw/lib/win32 - LIBS+=-lmgwhelp -lexchndl -endif - - # name of the exefile - EXENAME?=srb2kart.exe - -ifdef SDL - i_system_o+=$(OBJDIR)/SRB2.res - #i_main_o+=$(OBJDIR)/win_dbg.o -ifndef NOHW - OPTS+=-DUSE_WGL_SWAP -endif -endif - - -ZLIB_CFLAGS?=-I../libs/zlib -ifdef MINGW64 -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz64 -else -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz32 -endif - -ifndef NOPNG -ifndef PNG_CONFIG - PNG_CFLAGS?=-I../libs/libpng-src -ifdef MINGW64 - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64 -else - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32 -endif #MINGW64 -endif #PNG_CONFIG -endif #NOPNG - -ifdef GETTEXT -ifndef CCBS - MSGFMT?=../libs/gettext/bin32/msgfmt.exe -endif -ifdef MINGW64 - CPPFLAGS+=-I../libs/gettext/include64 - LDFLAGS+=-L../libs/gettext/lib64 - LIBS+=-lmingwex -else - CPPFLAGS+=-I../libs/gettext/include32 - LDFLAGS+=-L../libs/gettext/lib32 - STATIC_GETTEXT=1 -endif #MINGW64 -ifdef STATIC_GETTEXT - LIBS+=-lasprintf -lintl -else - LIBS+=-lintl.dll -endif #STATIC_GETTEXT -endif #GETTEXT - -ifdef HAVE_MINIUPNPC - CPPFLAGS+=-I../libs/ -DSTATIC_MINIUPNPC -ifdef MINGW64 - LDFLAGS+=-L../libs/miniupnpc/mingw64 -else - LDFLAGS+=-L../libs/miniupnpc/mingw32 -endif #MINGW64 -endif - -ifndef NOCURL - CURL_CFLAGS+=-I../libs/curl/include -ifdef MINGW64 - CURL_LDFLAGS+=-L../libs/curl/lib64 -lcurl -else - CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl -endif #MINGW64 -endif - -ifdef HAVE_DISCORDRPC -ifdef MINGW64 - CPPFLAGS+=-I../libs/discord-rpc/win64-dynamic/include - LDFLAGS+=-L../libs/discord-rpc/win64-dynamic/lib -else - CPPFLAGS+=-I../libs/discord-rpc/win32-dynamic/include - LDFLAGS+=-L../libs/discord-rpc/win32-dynamic/lib -endif - LIBS+=-ldiscord-rpc -endif - -ifndef MINGW64 - LDFLAGS+=-Wl,--large-address-aware -endif diff --git a/src/y_inter.c b/src/y_inter.c index e9c3fcf51..68a6019ad 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -165,7 +165,7 @@ static void Y_UnloadVoteData(void); // static void Y_CompareTime(INT32 i) { - UINT32 val = ((players[i].pflags & PF_GAMETYPEOVER || players[i].realtime == UINT32_MAX) + UINT32 val = ((players[i].pflags & PF_NOCONTEST || players[i].realtime == UINT32_MAX) ? (UINT32_MAX-1) : players[i].realtime); if (!(val < data.val[data.numplayers])) @@ -177,11 +177,11 @@ static void Y_CompareTime(INT32 i) static void Y_CompareScore(INT32 i) { - UINT32 val = ((players[i].pflags & PF_GAMETYPEOVER) - ? (UINT32_MAX-1) : players[i].marescore); + UINT32 val = ((players[i].pflags & PF_NOCONTEST) + ? (UINT32_MAX-1) : players[i].roundscore); if (!(data.val[data.numplayers] == UINT32_MAX - || (!(players[i].pflags & PF_GAMETYPEOVER) && val > data.val[data.numplayers]))) + || (!(players[i].pflags & PF_NOCONTEST) && val > data.val[data.numplayers]))) return; data.val[data.numplayers] = val; @@ -310,7 +310,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) if ((powertype == PWRLV_DISABLED) && (!rankingsmode) - && !(players[i].pflags & PF_GAMETYPEOVER) + && !(players[i].pflags & PF_NOCONTEST) && (data.pos[data.numplayers] < (numplayersingame + numgriefers))) { // Online rank is handled further below in this file. diff --git a/src/z_zone.c b/src/z_zone.c index d7da17e51..3a541f3a6 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -47,10 +47,6 @@ static boolean Z_calloc = false; #define ZONEID 0xa441d13d -#ifdef ZDEBUG -//#define ZDEBUG2 -#endif - struct memblock_s; typedef struct @@ -76,10 +72,8 @@ typedef struct memblock_s size_t size; // including the header and blocks size_t realsize; // size of real data only -#ifdef ZDEBUG const char *ownerfile; INT32 ownerline; -#endif struct memblock_s *next, *prev; } ATTRPACK memblock_t; @@ -91,9 +85,7 @@ static memblock_t head; // Function prototypes // static void Command_Memfree_f(void); -#ifdef ZDEBUG static void Command_Memdump_f(void); -#endif // -------------------------- // Zone memory initialisation @@ -117,10 +109,7 @@ void Z_Init(void) // Note: This allocates memory. Watch out. COM_AddCommand("memfree", Command_Memfree_f); - -#ifdef ZDEBUG COM_AddCommand("memdump", Command_Memdump_f); -#endif } @@ -137,12 +126,8 @@ void Z_Init(void) * \return A pointer to the memblock_t for the given memory. * \sa Z_Free, Z_ReallocAlign */ -#ifdef ZDEBUG #define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) -#else -static memblock_t *Ptr2Memblock(void *ptr, const char* func) -#endif { memhdr_t *hdr; memblock_t *block; @@ -150,8 +135,8 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func) if (ptr == NULL) return NULL; -#ifdef ZDEBUG2 - CONS_Printf("%s %s:%d\n", func, file, line); +#ifdef ZDEBUG + CONS_Debug(DBG_MEMORY, "%s %s:%d\n", func, file, line); #endif hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); @@ -163,20 +148,12 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func) #ifdef VALGRIND_MEMPOOL_EXISTS if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) { -#ifdef ZDEBUG I_Error("%s: bad memblock from %s:%d", func, file, line); -#else - I_Error("%s: bad memblock", func); -#endif } #endif if (hdr->id != ZONEID) { -#ifdef ZDEBUG I_Error("%s: wrong id from %s:%d", func, file, line); -#else - I_Error("%s: wrong id", func); -#endif } block = hdr->block; #ifdef VALGRIND_MAKE_MEM_NOACCESS @@ -192,31 +169,24 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func) * assumed to have been allocated with Z_Malloc/Z_Calloc. * \sa Z_FreeTags */ -#ifdef ZDEBUG void Z_Free2(void *ptr, const char *file, INT32 line) -#else -void Z_Free(void *ptr) -#endif { memblock_t *block; if (ptr == NULL) return; -#ifdef ZDEBUG2 +/* +// Sal: There's a print exactly like this just below? +#ifdef ZDEBUG CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line); #endif +*/ -#ifdef ZDEBUG block = Ptr2Memblock2(ptr, "Z_Free", file, line); -#else - block = Ptr2Memblock(ptr, "Z_Free"); -#endif -#ifdef ZDEBUG // Write every Z_Free call to a debug file. CONS_Debug(DBG_MEMORY, "Z_Free at %s:%d\n", file, line); -#endif // anything that isn't by lua gets passed to lua just in case. if (block->tag != PU_LUA) @@ -280,12 +250,8 @@ static void *xm(size_t size) * \note You can pass Z_Malloc() a NULL user if the tag is less than PU_PURGELEVEL. * \sa Z_CallocAlign, Z_ReallocAlign */ -#ifdef ZDEBUG void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) -#else -void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) -#endif { size_t extrabytes = (1<hdr = hdr; block->tag = tag; block->user = NULL; -#ifdef ZDEBUG block->ownerline = line; block->ownerfile = file; -#endif block->size = blocksize; block->realsize = size; @@ -375,20 +339,12 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) * \note You can pass Z_Calloc() a NULL user if the tag is less than PU_PURGELEVEL. * \sa Z_MallocAlign, Z_ReallocAlign */ -#ifdef ZDEBUG void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) -#else -void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) -#endif { #ifdef VALGRIND_MEMPOOL_ALLOC Z_calloc = true; #endif -#ifdef ZDEBUG return memset(Z_Malloc2 (size, tag, user, alignbits, file, line), 0, size); -#else - return memset(Z_MallocAlign(size, tag, user, alignbits ), 0, size); -#endif } /** The Z_ReallocAlign function. @@ -407,17 +363,13 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) * \note You can pass Z_Realloc() a NULL user if the tag is less than PU_PURGELEVEL. * \sa Z_MallocAlign, Z_CallocAlign */ -#ifdef ZDEBUG void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) -#else -void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) -#endif { void *rez; memblock_t *block; size_t copysize; -#ifdef ZDEBUG2 +#ifdef ZDEBUG CONS_Debug(DBG_MEMORY, "Z_Realloc %s:%d\n", file, line); #endif @@ -429,29 +381,17 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb if (!ptr) { -#ifdef ZDEBUG return Z_Calloc2(size, tag, user, alignbits, file , line); -#else - return Z_CallocAlign(size, tag, user, alignbits); -#endif } -#ifdef ZDEBUG block = Ptr2Memblock2(ptr, "Z_Realloc", file, line); -#else - block = Ptr2Memblock(ptr, "Z_Realloc"); -#endif if (block == NULL) return NULL; -#ifdef ZDEBUG // Write every Z_Realloc call to a debug file. DEBFILE(va("Z_Realloc at %s:%d\n", file, line)); rez = Z_Malloc2(size, tag, user, alignbits, file, line); -#else - rez = Z_MallocAlign(size, tag, user, alignbits); -#endif if (size < block->realsize) copysize = size; @@ -460,11 +400,7 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb M_Memcpy(rez, ptr, copysize); -#ifdef ZDEBUG Z_Free2(ptr, file, line); -#else - Z_Free(ptr); -#endif // Need to set the user in case the old block had the same one, in // which case the Z_Free will just have NULLed it out. @@ -569,7 +505,7 @@ void Z_CheckHeap(INT32 i) blocknumon++; hdr = block->hdr; given = (UINT8 *)hdr + sizeof *hdr; -#ifdef ZDEBUG2 +#ifdef ZDEBUG CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n", blocknumon, block->ownerfile, block->ownerline); #endif @@ -577,51 +513,35 @@ void Z_CheckHeap(INT32 i) if (!VALGRIND_MEMPOOL_EXISTS(block)) { I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG "(owned by %s:%d)" -#endif - " should not exist", i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); + " should not exist", i, blocknumon, + block->ownerfile, block->ownerline + ); } #endif if (block->user != NULL && *(block->user) != given) { I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG "(owned by %s:%d)" -#endif - " doesn't have a proper user", i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); + " doesn't have a proper user", i, blocknumon, + block->ownerfile, block->ownerline + ); } if (block->next->prev != block) { I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG "(owned by %s:%d)" -#endif - " lacks proper backlink", i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); + " lacks proper backlink", i, blocknumon, + block->ownerfile, block->ownerline + ); } if (block->prev->next != block) { I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG "(owned by %s:%d)" -#endif - " lacks proper forward link", i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); + " lacks proper forward link", i, blocknumon, + block->ownerfile, block->ownerline + ); } #ifdef VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); @@ -629,27 +549,19 @@ void Z_CheckHeap(INT32 i) if (hdr->block != block) { I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG "(owned by %s:%d)" -#endif " doesn't have linkback from allocated memory", - i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); + i, blocknumon, + block->ownerfile, block->ownerline + ); } if (hdr->id != ZONEID) { I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG "(owned by %s:%d)" -#endif - " have the wrong ID", i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); + " have the wrong ID", i, blocknumon, + block->ownerfile, block->ownerline + ); } #ifdef VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); @@ -828,11 +740,9 @@ static void Command_Memfree_f(void) CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); } -#ifdef ZDEBUG /** The function called by the "memdump" console command. * Prints zone memory debugging information (i.e. tag, size, location in code allocated). * Can be all memory allocated in game, or between a set of tags (if -min/-max args used). - * This command is available only if ZDEBUG is enabled. */ static void Command_Memdump_f(void) { @@ -853,7 +763,6 @@ static void Command_Memdump_f(void) CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline); } } -#endif /** Creates a copy of a string. * diff --git a/src/z_zone.h b/src/z_zone.h index 049a39475..94cf244cf 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -79,12 +79,8 @@ void Z_Init(void); // // Zone memory allocation // -// enable ZDEBUG to get the file + line the functions were called from -// for ZZ_Alloc, see doomdef.h -// // Z_Free and alloc with alignment -#ifdef ZDEBUG #define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) #define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) #define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) @@ -93,12 +89,6 @@ void Z_Free2(void *ptr, const char *file, INT32 line); void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2); -#else -void Z_Free(void *ptr); -void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2); -#endif // Alloc with no alignment #define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) @@ -106,7 +96,7 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb #define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) // Free all memory by tag -// these don't give line numbers for ZDEBUG currently though +// these don't give line numbers currently though // (perhaps this should be changed in future?) #define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) void Z_FreeTags(INT32 lowtag, INT32 hightag);