diff --git a/.travis.yml b/.travis.yml
index f1996215b..e5dbb58e4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,19 +2,199 @@ language: c
sudo: required
dist: trusty
-env:
-- CFLAGS=-Wall -W -Werror
-
-os:
- - linux
- - osx
-
-compiler:
- - gcc
- - clang
+matrix:
+ include:
+ - os: linux
+ addons:
+ apt:
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-4.4
+ compiler: gcc-4.4
+ #gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
+ - os: linux
+ addons:
+ apt:
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-4.6
+ compiler: gcc-4.6
+ #gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
+ - os: linux
+ addons:
+ apt:
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-4.7
+ compiler: gcc-4.7
+ #gcc-4.7
+ - os: linux
+ compiler: gcc
+ #gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-4.8
+ compiler: gcc-4.8
+ #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-4.9
+ compiler: gcc-4.9
+ #gcc-4.9 (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-5
+ compiler: gcc-5
+ #gcc-5 (Ubuntu 5.3.0-3ubuntu1~14.04) 5.3.0 20151204
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - gcc-6
+ compiler: gcc-6
+ env: WFLAGS="-Wno-tautological-compare"
+ #gcc-6 (Ubuntu 6.1.1-3ubuntu11~14.04.1) 6.1.1 20160511
+ - os: linux
+ compiler: clang
+ #clang version 3.5.0 (tags/RELEASE_350/final)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.5
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - clang-3.5
+ compiler: clang-3.5
+ #Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.6
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - clang-3.6
+ compiler: clang-3.6
+ #Ubuntu clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.7
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - clang-3.7
+ compiler: clang-3.7
+ #Ubuntu clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.8
+ - ubuntu-toolchain-r-test
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - p7zip-full
+ - clang-3.8
+ compiler: clang-3.8
+ #clang version 3.8.1-svn271127-1~exp1 (branches/release_38)
+# - os: osx
+# osx_image: beta-xcode6.1
+# #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
+# - os: osx
+# osx_image: beta-xcode6.2
+# compiler: gcc
+# #Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
+## - os: osx
+## osx_image: beta-xcode6.3
+## #I think xcode.6.3 VM is broken, it does not boot
+# - os: osx
+# osx_image: xcode6.4
+# #Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
+# - os: osx
+# osx_image: xcode7
+# #Apple LLVM version 7.0.0 (clang-700.0.72)
+# - os: osx
+# osx_image: xcode7.1
+# #Apple LLVM version 7.0.0 (clang-700.1.76)
+# - os: osx
+# osx_image: xcode7.2
+# #Apple LLVM version 7.0.2 (clang-700.1.81)
+ - os: osx
+ osx_image: xcode7.3
+ #Apple LLVM version 7.3.0 (clang-703.0.31)
+ allow_failures:
+ - compiler: clang-3.5
+ - compiler: clang-3.6
+ - compiler: clang-3.7
+ - compiler: clang-3.8
cache:
- apt: true
+ apt: true
ccache: true
directories:
- $HOME/srb2_cache
@@ -33,11 +213,14 @@ before_script:
- 7z x $HOME/srb2_cache/SRB2-v2115-assets-2.7z -oassets
- mkdir build
- cd build
- - cmake ..
+ - export CFLAGS="-Wall -W -Werror $WFLAGS"
+ - export CCACHE_COMPRESS=true
+ - cmake .. -DCMAKE_BUILD_TYPE=Release
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2_mixer game-music-emu p7zip ; fi
+ - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2_mixer game-music-emu p7zip; fi
+ - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake||true; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.4.dmg; hdiutil attach SDL2-2.0.4.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
- mkdir -p $HOME/srb2_cache
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..eb06156b4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+# Sonic Robo Blast 2
+
+[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2)
+[![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2)
+
+[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/).
+
+## Dependencies
+- NASM (x86 builds only)
+- SDL2 (Linux/OS X only)
+- SDL2-Mixer (Linux/OS X only)
+- libupnp (Linux/OS X only)
+- libgme (Linux/OS X only)
+
+Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at your own risk.
+
+## Compiling
+
+See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling)
+
+## Disclaimer
+Sonic Team Junior is in no way affiliated with SEGA or Sonic Team. We do not claim ownership of any of SEGA's intellectual property used in SRB2.
diff --git a/SRB2.cbp b/SRB2.cbp
index 43696ee2e..99a712264 100644
--- a/SRB2.cbp
+++ b/SRB2.cbp
@@ -2815,6 +2815,39 @@ HW3SOUND for 3D hardware sound support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/appveyor.yml b/appveyor.yml
index fd949dbb3..e0ee99c61 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 2.1.14.{branch}-{build}
+version: 2.1.16.{branch}-{build}
os: MinGW
environment:
@@ -75,6 +75,9 @@ deploy:
folder: appveyor
application:
active_mode: false
+ on:
+ branch: master
+ appveyor_repo_tag: true
on_finish:
diff --git a/readme.txt b/readme.txt
deleted file mode 100644
index c1898d491..000000000
--- a/readme.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-Here it is! SRB2 v2.1.14 source code!
-(why do we keep the version number up to date
- when everything else in this file is hilariously old?
- - Inuyasha)
-
-
-Win32 with Visual C (6SP6+Processor Pack OR 7)
-~~~
-
-2 VC++ 6.0 project files are included:
-
-Win32/DirectX/FMOD
-src\win32\wLegacy.dsw
-You'll need FMOD to compile this version (www.fmod.org)
-or
-Win32/SDL/SDL_mixer
-src\sdl\Win32SDL.dsp
-You'll need SDL and SDL_mixer for this version (www.libsdl.org)
-
-Both needs NASM (http://sourceforge.net/projects/nasm)
-For PNG screenshot, libPNG, and Zlib (from http://gnuwin32.sourceforge.net/)
-
-No warranty, support, etc. of any kind is offered,
-just plain old as is.
-Some bits of code are still really scary.
-Go nuts!
-
-
-Win32 with Dev-C++ (http://bloodshed.net/ free!)
-~~~
-2 Dev-C++ project files are included:
-
-Win32/DirectX/FMOD
-src\win32\SRB2.dev
-or
-Win32/SDL/SDL_mixer
-src\sdl\Win32SDL.dev
-You'll need SDL and SDL_mixer for this version (www.libsdl.org)
-libPNG and Zlib (from http://gnuwin32.sourceforge.net/)
-Note there are precompiled libpng.a and libz.a for Mingw
-
-you will need NASM for both SDL/SDL_mixer and DirectX/FMOD
-and you need DirectX 6 (or up) Dev-Paks to compile DirectX version
-
-GNU/Linux
-~~~
-
-Dependencies:
- SDL 1.2.7 or better (from libsdl.org)
- SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
- Nasm (use NOASM=1 if you don't have it or have an non-i386 system, I think)
- libPNG 1.2.7
- Zlib 1.2.3
- The Xiph.org libogg and libvorbis libraries
- The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
- installation, so you needn't worry, most likely)
- GCC 3.x toolchain and binutils
- GNU Make
-
-Build instructions:
-
-make -C src LINUX=1
-
-Build instructions (64 bit):
-
-make -C src LINUX64=1
-
-Build instructions to build for Wii Linux/SRB2Wii on a PowerPC system,
-follow cross-compiling instructions for cross-compiling on a x86 system:
-
-make -C src LINUX=1 WIILINUX=1
-
-Build instructions to build for Pandora (Linux) on a ARM system,
-follow cross-compiling instructions for cross-compiling on a x86 system:
-
-make -C src PANDORA=1
-
-Solaris
-~~~
-
-Dependencies:
- SDL 1.2.5 or better (from libsdl.org)
- SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
- libPNG 1.2.7
- Zlib 1.2.3
- The Xiph.org libogg and libvorbis libraries
- The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
- installation, so you needn't worry, most likely)
- GCC 3.x toolchain and binutils
- GNU Make
-
- You can get all these programs/libraries from the Companion CD (except SDL_mixer and OpenGL)
-
-Build instructions:
-
-gmake -C src SOLARIS=1
-
-FreeBSD
-~~~
-
-Dependencies:
- SDL 1.2.7 or better (from libsdl.org)
- SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
- Nasm (use NOASM=1 if you don't have it or have an non-i386 system, I think)
- libPNG 1.2.7
- Zlib 1.2.3
- The Xiph.org libogg and libvorbis libraries
- The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
- installation, so you needn't worry, most likely)
- GCC 3.x toolchain and binutils
- GNU Make
-
-Build instructions:
-
-gmake -C src FREEBSD=1
-
-DJGPP/DOS
-~~~
-
-Dependencies:
- Allegro 3.12 game programming library, (from
- http://alleg.sourceforge.net/index.html)
- Nasm (use NOASM=1 if you don't have it)
- libsocket (from http://homepages.nildram.co.uk/~phekda/richdawe/lsck/) or
- Watt-32 (from http://www.bgnett.no/~giva/)
- GCC 3.x toolchain and binutils
- GNU Make
-
-Build instructions:
-
-make -C src # to link with Watt-32, add WATTCP=1
- # for remote debugging over the COM port, add RDB=1
-
-Notes:
- use tools\djgpp\all313.diff to update Allegro to a "more usable" version ;)
- Example: E:\djgpp\allegro>patch -p# < D:\SRB2Code\1.1\srb2\tools\djgpp\all313.diff
-
-Windows CE
-~~~
-
-Dependencies:
- SDL 1.27
-
-Build instructions:
-
-use src\SDL\WinCE\SRB2CE.vcw
-
--------------------------------------------------------------------------------
-
-binaries will turn in up in bin/
-
-note: read the src/makefile for more options
-
-- Sonic Team Junior
-http://www.srb2.org
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 035b46556..ba354c289 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,6 +22,7 @@ set(SRB2_CORE_SOURCES
i_tcp.c
info.c
lzf.c
+ m_aatree.c
m_anigif.c
m_argv.c
m_bbox.c
@@ -83,6 +84,7 @@ set(SRB2_CORE_HEADERS
info.h
keys.h
lzf.h
+ m_aatree.h
m_anigif.h
m_argv.h
m_bbox.h
diff --git a/src/Makefile b/src/Makefile
index f43e3c24d..ce4b569ee 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -189,6 +189,10 @@ ifdef FREEBSD
UNIXCOMMON=1
endif
+ifdef MACOSX
+UNIXCOMMON=1
+endif
+
ifdef NDS
NOPNG=1
NONET=1
@@ -366,7 +370,12 @@ ifdef DEBUGMODE
# build with debugging information
WINDRESFLAGS = -D_DEBUG
- CFLAGS+=-O0 -Wall -DPARANOIA -DRANGECHECK
+ifdef GCC48
+ CFLAGS+=-Og
+else
+ CFLAGS+=-O0
+endif
+ CFLAGS+= -Wall -DPARANOIA -DRANGECHECK
else
@@ -424,6 +433,7 @@ OBJS:=$(i_main_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 \
@@ -588,11 +598,15 @@ ifndef WINDOWSHELL
-$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt
endif
endif
+
+# mac os x lsdlsrb2 does not like objcopy
+ifndef MACOSX
ifndef PSP
$(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME)
$(OBJCOPY) --strip-debug $(BIN)/$(EXENAME)
-$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME)
endif
+endif
ifndef NOUPX
-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
endif
@@ -740,6 +754,11 @@ $(OBJDIR)/%.o: %.c
$(OBJDIR)/%.o: $(INTERFACE)/%.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
+ifdef MACOSX
+$(OBJDIR)/%.o: sdl/macosx/%.c
+ $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
+endif
+
$(OBJDIR)/%.o: hardware/%.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
diff --git a/src/Makefile.cfg b/src/Makefile.cfg
index 347efa5e4..72404becc 100644
--- a/src/Makefile.cfg
+++ b/src/Makefile.cfg
@@ -406,6 +406,15 @@ else
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
+
OBJDUMP_OPTS?=--wide --source --line-numbers
LD=$(CC)
diff --git a/src/am_map.c b/src/am_map.c
index 90f815729..b28cecf11 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -999,7 +999,7 @@ static inline void AM_drawWalls(void)
static mline_t l;
#ifdef ESLOPE
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
- fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
+ fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends
#endif
for (i = 0; i < numlines; i++)
diff --git a/src/b_bot.c b/src/b_bot.c
index c59c084e9..0f2c80d55 100644
--- a/src/b_bot.c
+++ b/src/b_bot.c
@@ -41,12 +41,13 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
return;
#endif
- if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
+ if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC)
{
+ boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC);
dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y);
- if (sonic->player->cmd.buttons & BT_JUMP && sonic->player->pflags & (PF_JUMPED|PF_MACESPIN|PF_ITEMHANG))
+ if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant)
cmd->buttons |= BT_JUMP;
- if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
+ if (isrelevant)
{
cmd->forwardmove = sonic->player->cmd.forwardmove;
cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16;
@@ -211,8 +212,9 @@ boolean B_CheckRespawn(player_t *player)
// Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us.
- if (sonic->player->pflags & (PF_ROPEHANG|PF_GLIDING|PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_NIGHTSMODE)
- || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK))
+ if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_NIGHTSMODE)
+ || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)
+ || (sonic->player->powers[pw_carry]))
return false;
// Low ceiling, do not want!
diff --git a/src/blua/lcode.c b/src/blua/lcode.c
index 743a094a8..5c7fed454 100644
--- a/src/blua/lcode.c
+++ b/src/blua/lcode.c
@@ -270,6 +270,7 @@ static int boolK (FuncState *fs, int b) {
static int nilK (FuncState *fs) {
TValue k, v;
+ setbvalue(&v, 0);
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
sethvalue(fs->L, &k, fs->h);
diff --git a/src/blua/ltablib.c b/src/blua/ltablib.c
index 2e50ce0ae..2dd157155 100644
--- a/src/blua/ltablib.c
+++ b/src/blua/ltablib.c
@@ -137,7 +137,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for "
LUA_QL("concat"), luaL_typename(L, -1), i);
- luaL_addvalue(b);
+ luaL_addvalue(b);
}
diff --git a/src/blua/lvm.c b/src/blua/lvm.c
index a921d4437..b654613f4 100644
--- a/src/blua/lvm.c
+++ b/src/blua/lvm.c
@@ -732,7 +732,8 @@ void luaV_execute (lua_State *L, int nexeccalls) {
luaG_runerror(L, LUA_QL("for") " limit must be a number");
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number");
- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
+ if (ra && pstep)
+ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i));
continue;
}
diff --git a/src/command.c b/src/command.c
index 84d777acf..6534fed3d 100644
--- a/src/command.c
+++ b/src/command.c
@@ -966,9 +966,11 @@ void CV_RegisterVar(consvar_t *variable)
// check net variables
if (variable->flags & CV_NETVAR)
{
+ const consvar_t *netvar;
variable->netid = CV_ComputeNetid(variable->name);
- if (CV_FindNetVar(variable->netid))
- I_Error("Variables %s and %s have same netid\n", variable->name, CV_FindNetVar(variable->netid)->name);
+ netvar = CV_FindNetVar(variable->netid);
+ if (netvar)
+ I_Error("Variables %s and %s have same netid\n", variable->name, netvar->name);
}
// link the variable in
@@ -1159,7 +1161,16 @@ found:
var->value = (INT32)(d * FRACUNIT);
}
else
- var->value = atoi(var->string);
+ {
+ if (var == &cv_forceskin)
+ {
+ var->value = R_SkinAvailable(var->string);
+ if (!R_SkinUnlock(var->value))
+ var->value = -1;
+ }
+ else
+ var->value = atoi(var->string);
+ }
finish:
// See the note above.
@@ -1383,6 +1394,30 @@ void CV_StealthSet(consvar_t *var, const char *value)
CV_SetCVar(var, value, true);
}
+/** Sets a numeric value to a variable, sometimes calling its callback
+ * function.
+ *
+ * \param var The variable.
+ * \param value The numeric value, converted to a string before setting.
+ * \param stealth Do we call the callback function or not?
+ */
+static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth)
+{
+ char val[32];
+
+ if (var == &cv_forceskin) // Special handling.
+ {
+ if ((value < 0) || (value >= numskins))
+ sprintf(val, "None");
+ else
+ sprintf(val, "%s", skins[value].name);
+ }
+ else
+ sprintf(val, "%d", value);
+
+ CV_SetCVar(var, val, stealth);
+}
+
/** Sets a numeric value to a variable without calling its callback
* function.
*
@@ -1392,10 +1427,7 @@ void CV_StealthSet(consvar_t *var, const char *value)
*/
void CV_StealthSetValue(consvar_t *var, INT32 value)
{
- char val[32];
-
- sprintf(val, "%d", value);
- CV_SetCVar(var, val, true);
+ CV_SetValueMaybeStealth(var, value, true);
}
// New wrapper for what used to be CV_Set()
@@ -1413,10 +1445,7 @@ void CV_Set(consvar_t *var, const char *value)
*/
void CV_SetValue(consvar_t *var, INT32 value)
{
- char val[32];
-
- sprintf(val, "%d", value);
- CV_SetCVar(var, val, false);
+ CV_SetValueMaybeStealth(var, value, false);
}
/** Adds a value to a console variable.
@@ -1436,7 +1465,23 @@ void CV_AddValue(consvar_t *var, INT32 increment)
// count pointlimit better
if (var == &cv_pointlimit && (gametype == GT_MATCH))
increment *= 50;
- newvalue = var->value + increment;
+
+ if (var == &cv_forceskin) // Special handling.
+ {
+ INT32 oldvalue = var->value;
+ newvalue = oldvalue;
+ do
+ {
+ newvalue += increment;
+ if (newvalue < -1)
+ newvalue = (numskins - 1);
+ else if (newvalue >= numskins)
+ newvalue = -1;
+ } while ((oldvalue != newvalue)
+ && !(R_SkinUnlock(newvalue)));
+ }
+ else
+ newvalue = var->value + increment;
if (var->PossibleValue)
{
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 5378b2b9f..7ea95cfb8 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -506,6 +506,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->skin = LONG(players[i].skin);
// Just in case Lua does something like
// modify these at runtime
+ rsp->camerascale = (fixed_t)LONG(players[i].camerascale);
+ rsp->shieldscale = (fixed_t)LONG(players[i].shieldscale);
rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
rsp->runspeed = (fixed_t)LONG(players[i].runspeed);
rsp->thrustfactor = players[i].thrustfactor;
@@ -521,6 +523,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->mindash = (fixed_t)LONG(players[i].mindash);
rsp->maxdash = (fixed_t)LONG(players[i].maxdash);
rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor);
+ rsp->playerheight = (fixed_t)LONG(players[i].height);
+ rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight);
rsp->speed = (fixed_t)LONG(players[i].speed);
rsp->jumping = players[i].jumping;
@@ -531,6 +535,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->deadtimer = players[i].deadtimer;
rsp->exiting = (tic_t)LONG(players[i].exiting);
rsp->homing = players[i].homing;
+ rsp->dashmode = (tic_t)LONG(players[i].dashmode);
rsp->skidtime = (tic_t)LONG(players[i].skidtime);
rsp->cmomx = (fixed_t)LONG(players[i].cmomx);
rsp->cmomy = (fixed_t)LONG(players[i].cmomy);
@@ -549,7 +554,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->maxlink = LONG(players[i].maxlink);
rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed);
- rsp->dashtime = LONG(players[i].dashtime);
rsp->angle_pos = (angle_t)LONG(players[i].angle_pos);
rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos);
rsp->bumpertime = (tic_t)LONG(players[i].bumpertime);
@@ -631,6 +635,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].skin = LONG(rsp->skin);
// Just in case Lua does something like
// modify these at runtime
+ players[i].camerascale = (fixed_t)LONG(rsp->camerascale);
+ players[i].shieldscale = (fixed_t)LONG(rsp->shieldscale);
players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed);
players[i].runspeed = (fixed_t)LONG(rsp->runspeed);
players[i].thrustfactor = rsp->thrustfactor;
@@ -646,6 +652,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].mindash = (fixed_t)LONG(rsp->mindash);
players[i].maxdash = (fixed_t)LONG(rsp->maxdash);
players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor);
+ players[i].height = (fixed_t)LONG(rsp->playerheight);
+ players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight);
players[i].speed = (fixed_t)LONG(rsp->speed);
players[i].jumping = rsp->jumping;
@@ -656,6 +664,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].deadtimer = rsp->deadtimer;
players[i].exiting = (tic_t)LONG(rsp->exiting);
players[i].homing = rsp->homing;
+ players[i].dashmode = (tic_t)LONG(rsp->dashmode);
players[i].skidtime = (tic_t)LONG(rsp->skidtime);
players[i].cmomx = (fixed_t)LONG(rsp->cmomx);
players[i].cmomy = (fixed_t)LONG(rsp->cmomy);
@@ -674,7 +683,6 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].maxlink = LONG(rsp->maxlink);
players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed);
- players[i].dashtime = LONG(rsp->dashtime);
players[i].angle_pos = (angle_t)LONG(rsp->angle_pos);
players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos);
players[i].bumpertime = (tic_t)LONG(rsp->bumpertime);
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index b0cd7d2cc..21ef3a46b 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -166,6 +166,8 @@ typedef struct
INT32 skin;
// Just in case Lua does something like
// modify these at runtime
+ fixed_t camerascale;
+ fixed_t shieldscale;
fixed_t normalspeed;
fixed_t runspeed;
UINT8 thrustfactor;
@@ -181,6 +183,8 @@ typedef struct
fixed_t mindash;
fixed_t maxdash;
fixed_t jumpfactor;
+ fixed_t playerheight;
+ fixed_t playerspinheight;
fixed_t speed;
UINT8 jumping;
@@ -191,6 +195,7 @@ typedef struct
INT32 deadtimer;
tic_t exiting;
UINT8 homing;
+ tic_t dashmode;
tic_t skidtime;
fixed_t cmomx;
fixed_t cmomy;
@@ -209,7 +214,6 @@ typedef struct
INT32 maxlink;
fixed_t dashspeed;
- INT32 dashtime;
angle_t angle_pos;
angle_t old_angle_pos;
tic_t bumpertime;
diff --git a/src/d_main.c b/src/d_main.c
index ce602a39a..2ac72a9da 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1060,10 +1060,11 @@ void D_SRB2Main(void)
if (M_CheckParm("-warp") && M_IsNextParm())
{
const char *word = M_GetNextParm();
- if (fastncmp(word, "MAP", 3))
+ char ch; // use this with sscanf to catch non-digits with
+ if (fastncmp(word, "MAP", 3)) // MAPxx name
pstartmap = M_MapNumber(word[3], word[4]);
- else
- pstartmap = atoi(word);
+ else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number
+ I_Error("Cannot warp to map %s (invalid map name)\n", word);
// Don't check if lump exists just yet because the wads haven't been loaded!
// Just do a basic range check here.
if (pstartmap < 1 || pstartmap > NUMMAPS)
diff --git a/src/d_main.h b/src/d_main.h
index 88387a579..6dc273b15 100644
--- a/src/d_main.h
+++ b/src/d_main.h
@@ -41,7 +41,7 @@ void D_SRB2Main(void);
// Called by IO functions when input is detected.
void D_PostEvent(const event_t *ev);
#ifndef DOXYGEN
-void D_PostEvent_end(void); // delimiter for locking memory
+FUNCMATH void D_PostEvent_end(void); // delimiter for locking memory
#endif
void D_ProcessEvents(void);
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 47f80d8ef..784d07bca 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -332,7 +332,7 @@ consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0,
// log elemental hazards -- not a netvar, is local to current player
consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
-consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_forceskin = {"forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -1092,7 +1092,7 @@ static void SendNameAndColor(void)
SetPlayerSkinByNum(consoleplayer, 0);
CV_StealthSet(&cv_skin, skins[0].name);
}
- else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1)
+ else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUnlock(foundskin))
{
boolean notsame;
@@ -1139,7 +1139,7 @@ static void SendNameAndColor(void)
// check if player has the skin loaded (cv_skin may have
// the name of a skin that was available in the previous game)
cv_skin.value = R_SkinAvailable(cv_skin.string);
- if (cv_skin.value < 0)
+ if ((cv_skin.value < 0) || !R_SkinUnlock(cv_skin.value))
{
CV_StealthSet(&cv_skin, DEFAULTSKIN);
cv_skin.value = 0;
@@ -1217,7 +1217,7 @@ static void SendNameAndColor2(void)
SetPlayerSkinByNum(secondplaya, forcedskin);
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
}
- else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1)
+ else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUnlock(foundskin))
{
boolean notsame;
@@ -2598,11 +2598,13 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
memset(dest, 0, 16);
#else
XBOXSTATIC char tmpbuf[256];
+ const size_t sl = strlen(salt);
- if (len > 256-strlen(salt))
- len = 256-strlen(salt);
+ if (len > 256-sl)
+ len = 256-sl;
memcpy(tmpbuf, buffer, len);
- strcpy(&tmpbuf[len], salt);
+ memmove(&tmpbuf[len], salt, sl);
+ //strcpy(&tmpbuf[len], salt);
len += strlen(salt);
if (len < 256)
memset(&tmpbuf[len],0,256-len);
@@ -4000,17 +4002,10 @@ static void Command_Archivetest_f(void)
*/
static void ForceSkin_OnChange(void)
{
- if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins))
+ if ((server || adminplayer == consoleplayer) && ((cv_forceskin.value == -1 && stricmp(cv_forceskin.string, "None")) || !(R_SkinUnlock(cv_forceskin.value))))
{
- if (cv_forceskin.value == -2)
- CV_SetValue(&cv_forceskin, numskins-1);
- else
- {
- // hack because I can't restrict this and still allow added skins to be used with forceskin.
- if (!menuactive)
- CONS_Printf(M_GetText("Valid skin numbers are 0 to %d (-1 disables)\n"), numskins - 1);
- CV_SetValue(&cv_forceskin, -1);
- }
+ CONS_Printf("Please provide a valid skin name (\"None\" disables).\n");
+ CV_SetValue(&cv_forceskin, -1);
return;
}
@@ -4022,7 +4017,7 @@ static void ForceSkin_OnChange(void)
CONS_Printf("The server has lifted the forced skin restrictions.\n");
else
{
- CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
+ CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].realname);
ForceAllSkins(cv_forceskin.value);
}
}
diff --git a/src/d_player.h b/src/d_player.h
index ec4e1ee86..49f6cfade 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -39,6 +39,12 @@ typedef enum
SF_NOSKID = 1<<4, // No skid particles etc
SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust
SF_RUNONWATER = 1<<6, // Run on top of water FOFs?
+ SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_SPIN, falling states used, and player height is full when jumping?
+ SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping?
+ SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability?
+ SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc.
+ SF_MACHINE = 1<<10, // Beep boop. Are you a robot?
+ // free up to and including 1<<31
} skinflags_t;
//Primary and secondary skin abilities
@@ -57,7 +63,9 @@ typedef enum
CA_FALLSWITCH,
CA_JUMPBOOST,
CA_AIRDRILL,
- CA_JUMPTHOK
+ CA_JUMPTHOK,
+ CA_DASHMODE,
+ CA_TWINSPIN
} charability_t;
//Secondary skin abilities
@@ -65,7 +73,8 @@ typedef enum
{
CA2_NONE=0,
CA2_SPINDASH,
- CA2_MULTIABILITY
+ CA2_MULTIABILITY,
+ CA2_MELEE
} charability2_t;
//
@@ -120,40 +129,31 @@ typedef enum
// Are you gliding?
PF_GLIDING = 1<<16,
- // Tails pickup!
- PF_CARRIED = 1<<17,
-
// Sliding (usually in water) like Labyrinth/Oil Ocean
- PF_SLIDING = 1<<18,
-
- // Hanging on a rope
- PF_ROPEHANG = 1<<19,
-
- // Hanging on an item of some kind - zipline, chain, etc. (->tracer)
- PF_ITEMHANG = 1<<20,
-
- // On the mace chain spinning around (->tracer)
- PF_MACESPIN = 1<<21,
+ PF_SLIDING = 1<<17,
/*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode?
- PF_NIGHTSMODE = 1<<22,
- PF_TRANSFERTOCLOSEST = 1<<23,
+ PF_NIGHTSMODE = 1<<18,
+ PF_TRANSFERTOCLOSEST = 1<<19,
// Spill rings after falling
- PF_NIGHTSFALL = 1<<24,
- PF_DRILLING = 1<<25,
- PF_SKIDDOWN = 1<<26,
+ PF_NIGHTSFALL = 1<<20,
+ PF_DRILLING = 1<<21,
+ PF_SKIDDOWN = 1<<22,
/*** TAG STUFF ***/
- PF_TAGGED = 1<<27, // Player has been tagged and awaits the next round in hide and seek.
- PF_TAGIT = 1<<28, // The player is it! For Tag Mode
+ PF_TAGGED = 1<<23, // Player has been tagged and awaits the next round in hide and seek.
+ PF_TAGIT = 1<<24, // The player is it! For Tag Mode
/*** misc ***/
- PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs
- PF_ANALOGMODE = 1<<30, // Analog mode?
+ PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs
+ PF_ANALOGMODE = 1<<26, // Analog mode?
- // free: 1<<30 and 1<<31
+ // Can carry another player?
+ PF_CANCARRY = 1<<27
+
+ // free up to and including 1<<31
} pflags_t;
typedef enum
@@ -164,11 +164,14 @@ typedef enum
PA_EDGE,
PA_WALK,
PA_RUN,
+ PA_PEEL,
PA_PAIN,
PA_ROLL,
+ PA_JUMP,
PA_SPRING,
PA_FALL,
PA_ABILITY,
+ PA_ABILITY2,
PA_RIDE
} panim_t;
@@ -193,7 +196,20 @@ typedef enum
SH_STACK = SH_FIREFLOWER,
SH_NOSTACK = ~SH_STACK
-} shieldtype_t;
+} shieldtype_t; // pw_shield
+
+typedef enum
+{
+ CR_NONE = 0,
+ // The generic case is suitable for most objects.
+ CR_GENERIC,
+ // Tails carry.
+ CR_PLAYER,
+ // Specific level gimmicks.
+ CR_ZOOMTUBE,
+ CR_ROPEHANG,
+ CR_MACESPIN
+} carrytype_t; // pw_carry
// Player powers. (don't edit this comment)
typedef enum
@@ -202,6 +218,7 @@ typedef enum
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!
@@ -265,6 +282,8 @@ typedef struct player_s
playerstate_t playerstate;
// Determine POV, including viewpoint bobbing during movement.
+ fixed_t camerascale;
+ fixed_t shieldscale;
// Focal origin above r.z
fixed_t viewz;
// Base height above floor for viewz.
@@ -306,7 +325,6 @@ typedef struct player_s
UINT32 score; // player score
fixed_t dashspeed; // dashing speed
- INT32 dashtime; // tics dashing, used for rev sound
fixed_t normalspeed; // Normal ground
fixed_t runspeed; // Speed you break into the run animation
@@ -331,6 +349,9 @@ typedef struct player_s
fixed_t jumpfactor; // How high can the player jump?
+ fixed_t height; // Bounding box changes.
+ fixed_t spinheight;
+
SINT8 lives;
SINT8 continues; // continues that player has acquired
@@ -349,6 +370,7 @@ typedef struct player_s
tic_t exiting; // Exitlevel timer
UINT8 homing; // Are you homing?
+ tic_t dashmode; // counter for dashmode ability
tic_t skidtime; // Skid timer
diff --git a/src/dehacked.c b/src/dehacked.c
index 023a872cf..7c8afeecc 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -430,16 +430,20 @@ static void readAnimTex(MYFILE *f, INT32 num)
}
*/
-static boolean findFreeSlot(INT32 *num)
+static boolean findFreeSlot(INT32 *num, UINT16 wadnum)
{
// Send the character select entry to a free slot.
- while (*num < 32 && PlayerMenu[*num].status != IT_DISABLED)
+ while (*num < 32 && (!(PlayerMenu[*num].status & IT_DISABLED) || description[*num].wadnum == wadnum)) // Will kill hidden characters from other files, but that's okay.
*num = *num+1;
// No more free slots. :(
if (*num >= 32)
return false;
+ PlayerMenu[*num].status = IT_CALL;
+ description[*num].wadnum = wadnum;
+ description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
+
// Found one! ^_^
return true;
}
@@ -473,9 +477,8 @@ static void readPlayer(MYFILE *f, INT32 num)
{
char *playertext = NULL;
- if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
+ if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done;
- PlayerMenu[num].status = IT_CALL;
for (i = 0; i < MAXLINELEN-3; i++)
{
@@ -521,34 +524,12 @@ static void readPlayer(MYFILE *f, INT32 num)
word2[strlen(word2)-1] = '\0';
i = atoi(word2);
- /*if (fastcmp(word, "PLAYERNAME"))
+ if (fastcmp(word, "PICNAME"))
{
- if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
- goto done;
- DEH_WriteUndoline(word, description[num].text, UNDO_NONE);
- strlcpy(description[num].text, word2, sizeof (description[num].text));
- for (word2 = description[num].text; *word2; word2++)
- if (*word2 == '_')
- *word2 = ' ';
- PlayerMenu[num].text = description[num].text;
- }*/
-/* else if (fastcmp(word, "MENUPOSITION"))
- { // Make sure you make MENUPOSITION the first thing under CHARACTER if you're using it!
- // This is to manually choose a slot and overwrite existing characters! It is NOT necessary for most individual character wads!!
-#ifdef DELFILE
- if (disableundo)
-#endif
- {
- slotfound = true;
- num = i;
- }
- } */
- /*else*/ if (fastcmp(word, "PICNAME"))
- {
- if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
+ if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done;
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
- PlayerMenu[num].status = IT_CALL;
+
strncpy(description[num].picname, word2, 8);
}
else if (fastcmp(word, "STATUS"))
@@ -563,13 +544,10 @@ static void readPlayer(MYFILE *f, INT32 num)
You MAY disable previous entries if you so desire...
But try to enable something that's already enabled and you will be sent to a free slot.
- Because of this, you are allowed to edit any previous entrys you like, but only if you
+ Because of this, you are allowed to edit any previous entries you like, but only if you
signal that you are purposely doing so by disabling and then reenabling the slot.
-
- ... Or use MENUPOSITION first, that works too. Hell, you could edit multiple character
- slots in a single section that way, due to how SOC editing works.
*/
- if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num)) == false)
+ if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done;
DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE);
PlayerMenu[num].status = (INT16)i;
@@ -577,10 +555,9 @@ static void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "SKINNAME"))
{
// Send to free slot.
- if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
+ if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done;
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
- PlayerMenu[num].status = IT_CALL;
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
strlwr(description[num].skinname);
@@ -673,6 +650,22 @@ static void readfreeslots(MYFILE *f)
break;
}
}
+ else if (fastcmp(type, "SPR2"))
+ {
+ // Search if we already have an SPR2 by that name...
+ for (i = SPR2_FIRSTFREESLOT; i < (int)free_spr2; i++)
+ if (memcmp(spr2names[i],word,4) == 0)
+ break;
+ // We found it? (Two mods using the same SPR2 name?) Then don't allocate another one.
+ if (i < (int)free_spr2)
+ continue;
+ // Copy in the spr2 name and increment free_spr2.
+ if (free_spr2 < NUMPLAYERSPRITES) {
+ strncpy(spr2names[free_spr2],word,4);
+ spr2names[free_spr2++][4] = 0;
+ } else
+ CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+ }
else
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
}
@@ -1666,6 +1659,9 @@ static actionpointer_t actionpointers[] =
{{A_Pain}, "A_PAIN"},
{{A_Fall}, "A_FALL"},
{{A_MonitorPop}, "A_MONITORPOP"},
+ {{A_GoldMonitorPop}, "A_GOLDMONITORPOP"},
+ {{A_GoldMonitorRestore}, "A_GOLDMONITORRESTORE"},
+ {{A_GoldMonitorSparkle}, "A_GOLDMONITORSPARKLE"},
{{A_Look}, "A_LOOK"},
{{A_Chase}, "A_CHASE"},
{{A_FaceStabChase}, "A_FACESTABCHASE"},
@@ -3794,6 +3790,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_WAIT",
"S_PLAY_WALK",
"S_PLAY_RUN",
+ "S_PLAY_PEEL",
"S_PLAY_PAIN",
"S_PLAY_DEAD",
"S_PLAY_DRWN",
@@ -3806,8 +3803,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_EDGE",
"S_PLAY_RIDE",
- // CA_FLY
+ // CA_FLY/SWIM
"S_PLAY_FLY",
+ "S_PLAY_SWIM",
"S_PLAY_FLY_TIRED",
// CA_GLIDEANDCLIMB
@@ -3815,10 +3813,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_CLING",
"S_PLAY_CLIMB",
+ // CA_TWINSPIN
+ "S_PLAY_TWINSPIN",
+
+ // CA2_MELEE
+ "S_PLAY_MELEE",
+ "S_PLAY_MELEE_FINISH",
+
// SF_SUPERANIMS
"S_PLAY_SUPER_STND",
"S_PLAY_SUPER_WALK",
"S_PLAY_SUPER_RUN",
+ "S_PLAY_SUPER_PEEL",
"S_PLAY_SUPER_PAIN",
"S_PLAY_SUPER_STUN",
"S_PLAY_SUPER_DEAD",
@@ -3856,6 +3862,50 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Level end sign (uses player sprite)
"S_PLAY_SIGN",
+ // NiGHTS character (uses player sprite)
+ "S_PLAY_NIGHTS_TRANS",
+ "S_PLAY_NIGHTS_TRANS2",
+ "S_PLAY_NIGHTS_TRANS3",
+ "S_PLAY_NIGHTS_TRANS4",
+ "S_PLAY_NIGHTS_TRANS5",
+ "S_PLAY_NIGHTS_TRANS6",
+ "S_PLAY_NIGHTS_TRANS7",
+ "S_PLAY_NIGHTS_TRANS8",
+ "S_PLAY_NIGHTS_TRANS9",
+
+ "S_PLAY_NIGHTS_STAND",
+ "S_PLAY_NIGHTS_FLOAT",
+ "S_PLAY_NIGHTS_PAIN",
+ "S_PLAY_NIGHTS_PULL",
+ "S_PLAY_NIGHTS_ATTACK",
+
+ "S_PLAY_NIGHTS_FLY0",
+ "S_PLAY_NIGHTS_DRILL0",
+ "S_PLAY_NIGHTS_FLY1",
+ "S_PLAY_NIGHTS_DRILL1",
+ "S_PLAY_NIGHTS_FLY2",
+ "S_PLAY_NIGHTS_DRILL2",
+ "S_PLAY_NIGHTS_FLY3",
+ "S_PLAY_NIGHTS_DRILL3",
+ "S_PLAY_NIGHTS_FLY4",
+ "S_PLAY_NIGHTS_DRILL4",
+ "S_PLAY_NIGHTS_FLY5",
+ "S_PLAY_NIGHTS_DRILL5",
+ "S_PLAY_NIGHTS_FLY6",
+ "S_PLAY_NIGHTS_DRILL6",
+ "S_PLAY_NIGHTS_FLY7",
+ "S_PLAY_NIGHTS_DRILL7",
+ "S_PLAY_NIGHTS_FLY8",
+ "S_PLAY_NIGHTS_DRILL8",
+ "S_PLAY_NIGHTS_FLY9",
+ "S_PLAY_NIGHTS_DRILL9",
+ "S_PLAY_NIGHTS_FLYA",
+ "S_PLAY_NIGHTS_DRILLA",
+ "S_PLAY_NIGHTS_FLYB",
+ "S_PLAY_NIGHTS_DRILLB",
+ "S_PLAY_NIGHTS_FLYC",
+ "S_PLAY_NIGHTS_DRILLC",
+
// Blue Crawla
"S_POSS_STND",
"S_POSS_RUN1",
@@ -4706,6 +4756,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Bubble Source
"S_BUBBLES1",
"S_BUBBLES2",
+ "S_BUBBLES3",
+ "S_BUBBLES4",
// Level End Sign
"S_SIGN1",
@@ -4820,170 +4872,114 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_CANNONLAUNCHER2",
"S_CANNONLAUNCHER3",
- // Super Ring Box
- "S_SUPERRINGBOX",
- "S_SUPERRINGBOX1",
- "S_SUPERRINGBOX2",
- "S_SUPERRINGBOX3",
- "S_SUPERRINGBOX4",
- "S_SUPERRINGBOX5",
- "S_SUPERRINGBOX6",
+ // Monitor Miscellany
+ "S_BOXSPARKLE1",
+ "S_BOXSPARKLE2",
+ "S_BOXSPARKLE3",
- // Red Team Ring Box
- "S_REDRINGBOX",
- "S_REDRINGBOX1",
+ "S_BOX_FLICKER",
+ "S_BOX_POP1",
+ "S_BOX_POP2",
- // Blue Team Ring Box
- "S_BLUERINGBOX",
- "S_BLUERINGBOX1",
+ "S_GOLDBOX_FLICKER",
+ "S_GOLDBOX_OFF1",
+ "S_GOLDBOX_OFF2",
+ "S_GOLDBOX_OFF3",
+ "S_GOLDBOX_OFF4",
+ "S_GOLDBOX_OFF5",
+ "S_GOLDBOX_OFF6",
+ "S_GOLDBOX_OFF7",
- // Super Sneakers Box
- "S_SHTV",
- "S_SHTV1",
- "S_SHTV2",
- "S_SHTV3",
- "S_SHTV4",
- "S_SHTV5",
- "S_SHTV6",
+ // Monitor States (one per box)
+ "S_MYSTERY_BOX",
+ "S_RING_BOX",
+ "S_PITY_BOX",
+ "S_ATTRACT_BOX",
+ "S_FORCE_BOX",
+ "S_ARMAGEDDON_BOX",
+ "S_WHIRLWIND_BOX",
+ "S_ELEMENTAL_BOX",
+ "S_SNEAKERS_BOX",
+ "S_INVULN_BOX",
+ "S_1UP_BOX",
+ "S_EGGMAN_BOX",
+ "S_MIXUP_BOX",
+ "S_GRAVITY_BOX",
+ "S_RECYCLER_BOX",
+ "S_SCORE1K_BOX",
+ "S_SCORE10K_BOX",
- // Invincibility Box
- "S_PINV",
- "S_PINV1",
- "S_PINV2",
- "S_PINV3",
- "S_PINV4",
- "S_PINV5",
- "S_PINV6",
+ // Gold Repeat Monitor States (one per box)
+ "S_PITY_GOLDBOX",
+ "S_ATTRACT_GOLDBOX",
+ "S_FORCE_GOLDBOX",
+ "S_ARMAGEDDON_GOLDBOX",
+ "S_WHIRLWIND_GOLDBOX",
+ "S_ELEMENTAL_GOLDBOX",
+ "S_SNEAKERS_GOLDBOX",
+ "S_INVULN_GOLDBOX",
+ "S_EGGMAN_GOLDBOX",
+ "S_GRAVITY_GOLDBOX",
- // 1-Up Box
- "S_PRUP",
- "S_PRUP1",
- "S_PRUP2",
- "S_PRUP3",
- "S_PRUP4",
- "S_PRUP5",
- "S_PRUP6",
+ // Team Ring Boxes (these are special)
+ "S_RING_REDBOX1",
+ "S_RING_REDBOX2",
+ "S_REDBOX_POP1",
+ "S_REDBOX_POP2",
- // Ring Shield Box
- "S_YLTV",
- "S_YLTV1",
- "S_YLTV2",
- "S_YLTV3",
- "S_YLTV4",
- "S_YLTV5",
- "S_YLTV6",
+ "S_RING_BLUEBOX1",
+ "S_RING_BLUEBOX2",
+ "S_BLUEBOX_POP1",
+ "S_BLUEBOX_POP2",
- // Force Shield Box
- "S_BLTV1",
- "S_BLTV2",
- "S_BLTV3",
- "S_BLTV4",
- "S_BLTV5",
- "S_BLTV6",
- "S_BLTV7",
+ // Box Icons -- 2 states each, animation and action
+ "S_RING_ICON1",
+ "S_RING_ICON2",
- // Bomb Shield Box
- "S_BKTV1",
- "S_BKTV2",
- "S_BKTV3",
- "S_BKTV4",
- "S_BKTV5",
- "S_BKTV6",
- "S_BKTV7",
+ "S_PITY_ICON1",
+ "S_PITY_ICON2",
- // Jump Shield Box
- "S_WHTV1",
- "S_WHTV2",
- "S_WHTV3",
- "S_WHTV4",
- "S_WHTV5",
- "S_WHTV6",
- "S_WHTV7",
+ "S_ATTRACT_ICON1",
+ "S_ATTRACT_ICON2",
- // Water Shield Box
- "S_GRTV",
- "S_GRTV1",
- "S_GRTV2",
- "S_GRTV3",
- "S_GRTV4",
- "S_GRTV5",
- "S_GRTV6",
+ "S_FORCE_ICON1",
+ "S_FORCE_ICON2",
- // Pity Shield Box
- "S_PITV1",
- "S_PITV2",
- "S_PITV3",
- "S_PITV4",
- "S_PITV5",
- "S_PITV6",
- "S_PITV7",
+ "S_ARMAGEDDON_ICON1",
+ "S_ARMAGEDDON_ICON2",
- // Eggman Box
- "S_EGGTV1",
- "S_EGGTV2",
- "S_EGGTV3",
- "S_EGGTV4",
- "S_EGGTV5",
- "S_EGGTV6",
- "S_EGGTV7",
+ "S_WHIRLWIND_ICON1",
+ "S_WHIRLWIND_ICON2",
- // Teleport Box
- "S_MIXUPBOX1",
- "S_MIXUPBOX2",
- "S_MIXUPBOX3",
- "S_MIXUPBOX4",
- "S_MIXUPBOX5",
- "S_MIXUPBOX6",
- "S_MIXUPBOX7",
+ "S_ELEMENTAL_ICON1",
+ "S_ELEMENTAL_ICON2",
- // Recycler Box
- "S_RECYCLETV1",
- "S_RECYCLETV2",
- "S_RECYCLETV3",
- "S_RECYCLETV4",
- "S_RECYCLETV5",
- "S_RECYCLETV6",
- "S_RECYCLETV7",
+ "S_SNEAKERS_ICON1",
+ "S_SNEAKERS_ICON2",
- // Question Box
- "S_RANDOMBOX1",
- "S_RANDOMBOX2",
- "S_RANDOMBOX3",
+ "S_INVULN_ICON1",
+ "S_INVULN_ICON2",
- // Gravity Boots Box
- "S_GBTV1",
- "S_GBTV2",
- "S_GBTV3",
- "S_GBTV4",
- "S_GBTV5",
- "S_GBTV6",
- "S_GBTV7",
+ "S_1UP_ICON1",
+ "S_1UP_ICON2",
- // Score boxes
- "S_SCORETVA1",
- "S_SCORETVA2",
- "S_SCORETVA3",
- "S_SCORETVA4",
- "S_SCORETVA5",
- "S_SCORETVA6",
- "S_SCORETVA7",
- "S_SCORETVB1",
- "S_SCORETVB2",
- "S_SCORETVB3",
- "S_SCORETVB4",
- "S_SCORETVB5",
- "S_SCORETVB6",
- "S_SCORETVB7",
+ "S_EGGMAN_ICON1",
+ "S_EGGMAN_ICON2",
- // Monitor Explosion
- "S_MONITOREXPLOSION1",
- "S_MONITOREXPLOSION2",
+ "S_MIXUP_ICON1",
+ "S_MIXUP_ICON2",
- "S_REDMONITOREXPLOSION1",
- "S_REDMONITOREXPLOSION2",
+ "S_GRAVITY_ICON1",
+ "S_GRAVITY_ICON2",
- "S_BLUEMONITOREXPLOSION1",
- "S_BLUEMONITOREXPLOSION2",
+ "S_RECYCLER_ICON1",
+ "S_RECYCLER_ICON2",
+
+ "S_SCORE1K_ICON1",
+ "S_SCORE1K_ICON2",
+
+ "S_SCORE10K_ICON1",
+ "S_SCORE10K_ICON2",
"S_ROCKET",
@@ -5497,6 +5493,36 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_RDIAG7",
"S_RDIAG8",
+ // Yellow Side Spring
+ "S_YHORIZ1",
+ "S_YHORIZ2",
+ "S_YHORIZ3",
+ "S_YHORIZ4",
+ "S_YHORIZ5",
+ "S_YHORIZ6",
+ "S_YHORIZ7",
+ "S_YHORIZ8",
+
+ // Red Side Spring
+ "S_RHORIZ1",
+ "S_RHORIZ2",
+ "S_RHORIZ3",
+ "S_RHORIZ4",
+ "S_RHORIZ5",
+ "S_RHORIZ6",
+ "S_RHORIZ7",
+ "S_RHORIZ8",
+
+ // Blue Side Spring
+ "S_BHORIZ1",
+ "S_BHORIZ2",
+ "S_BHORIZ3",
+ "S_BHORIZ4",
+ "S_BHORIZ5",
+ "S_BHORIZ6",
+ "S_BHORIZ7",
+ "S_BHORIZ8",
+
// Rain
"S_RAIN1",
"S_RAINRETURN",
@@ -5531,14 +5557,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Bubbles
"S_SMALLBUBBLE",
- "S_SMALLBUBBLE1",
"S_MEDIUMBUBBLE",
- "S_MEDIUMBUBBLE1",
- "S_LARGEBUBBLE",
+ "S_LARGEBUBBLE1",
+ "S_LARGEBUBBLE2",
"S_EXTRALARGEBUBBLE", // breathable
"S_POP1", // Extra Large bubble goes POP!
+ "S_WATERZAP",
+
"S_FOG1",
"S_FOG2",
"S_FOG3",
@@ -5580,6 +5607,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FOUR1",
"S_FIVE1",
+ "S_ZERO2",
+ "S_ONE2",
+ "S_TWO2",
+ "S_THREE2",
+ "S_FOUR2",
+ "S_FIVE2",
+
// Tag Sign
"S_TTAG1",
@@ -5812,93 +5846,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_NIGHTSGOAL3",
"S_NIGHTSGOAL4",
- "S_NIGHTSFLY1A",
- "S_NIGHTSFLY1B",
- "S_NIGHTSDRILL1A",
- "S_NIGHTSDRILL1B",
- "S_NIGHTSDRILL1C",
- "S_NIGHTSDRILL1D",
- "S_NIGHTSFLY2A",
- "S_NIGHTSFLY2B",
- "S_NIGHTSDRILL2A",
- "S_NIGHTSDRILL2B",
- "S_NIGHTSDRILL2C",
- "S_NIGHTSDRILL2D",
- "S_NIGHTSFLY3A",
- "S_NIGHTSFLY3B",
- "S_NIGHTSDRILL3A",
- "S_NIGHTSDRILL3B",
- "S_NIGHTSDRILL3C",
- "S_NIGHTSDRILL3D",
- "S_NIGHTSFLY4A",
- "S_NIGHTSFLY4B",
- "S_NIGHTSDRILL4A",
- "S_NIGHTSDRILL4B",
- "S_NIGHTSDRILL4C",
- "S_NIGHTSDRILL4D",
- "S_NIGHTSFLY5A",
- "S_NIGHTSFLY5B",
- "S_NIGHTSDRILL5A",
- "S_NIGHTSDRILL5B",
- "S_NIGHTSDRILL5C",
- "S_NIGHTSDRILL5D",
- "S_NIGHTSFLY6A",
- "S_NIGHTSFLY6B",
- "S_NIGHTSDRILL6A",
- "S_NIGHTSDRILL6B",
- "S_NIGHTSDRILL6C",
- "S_NIGHTSDRILL6D",
- "S_NIGHTSFLY7A",
- "S_NIGHTSFLY7B",
- "S_NIGHTSDRILL7A",
- "S_NIGHTSDRILL7B",
- "S_NIGHTSDRILL7C",
- "S_NIGHTSDRILL7D",
- "S_NIGHTSFLY8A",
- "S_NIGHTSFLY8B",
- "S_NIGHTSDRILL8A",
- "S_NIGHTSDRILL8B",
- "S_NIGHTSDRILL8C",
- "S_NIGHTSDRILL8D",
- "S_NIGHTSFLY9A",
- "S_NIGHTSFLY9B",
- "S_NIGHTSDRILL9A",
- "S_NIGHTSDRILL9B",
- "S_NIGHTSDRILL9C",
- "S_NIGHTSDRILL9D",
- "S_NIGHTSHURT1",
- "S_NIGHTSHURT2",
- "S_NIGHTSHURT3",
- "S_NIGHTSHURT4",
- "S_NIGHTSHURT5",
- "S_NIGHTSHURT6",
- "S_NIGHTSHURT7",
- "S_NIGHTSHURT8",
- "S_NIGHTSHURT9",
- "S_NIGHTSHURT10",
- "S_NIGHTSHURT11",
- "S_NIGHTSHURT12",
- "S_NIGHTSHURT13",
- "S_NIGHTSHURT14",
- "S_NIGHTSHURT15",
- "S_NIGHTSHURT16",
- "S_NIGHTSHURT17",
- "S_NIGHTSHURT18",
- "S_NIGHTSHURT19",
- "S_NIGHTSHURT20",
- "S_NIGHTSHURT21",
- "S_NIGHTSHURT22",
- "S_NIGHTSHURT23",
- "S_NIGHTSHURT24",
- "S_NIGHTSHURT25",
- "S_NIGHTSHURT26",
- "S_NIGHTSHURT27",
- "S_NIGHTSHURT28",
- "S_NIGHTSHURT29",
- "S_NIGHTSHURT30",
- "S_NIGHTSHURT31",
- "S_NIGHTSHURT32",
-
"S_NIGHTSPARKLE1",
"S_NIGHTSPARKLE2",
"S_NIGHTSPARKLE3",
@@ -5995,16 +5942,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_CRUMBLE1",
"S_CRUMBLE2",
- "S_SUPERTRANS1",
- "S_SUPERTRANS2",
- "S_SUPERTRANS3",
- "S_SUPERTRANS4",
- "S_SUPERTRANS5",
- "S_SUPERTRANS6",
- "S_SUPERTRANS7",
- "S_SUPERTRANS8",
- "S_SUPERTRANS9",
-
// Spark
"S_SPRK1",
"S_SPRK2",
@@ -6254,6 +6191,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_REDSPRING",
"MT_YELLOWDIAG", // Yellow Diagonal Spring
"MT_REDDIAG", // Red Diagonal Spring
+ "MT_YELLOWHORIZ", // Yellow Side Spring
+ "MT_REDHORIZ", // Red Side Spring
+ "MT_BLUEHORIZ", // Blue Side Spring
// Interactive Objects
"MT_BUBBLES", // Bubble source
@@ -6267,47 +6207,61 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_BIGAIRMINE",
"MT_CANNONLAUNCHER",
- // Monitor Boxes
- "MT_SUPERRINGBOX",
- "MT_REDRINGBOX",
- "MT_BLUERINGBOX",
- "MT_SNEAKERTV",
- "MT_INV",
- "MT_PRUP", // 1up Box
- "MT_YELLOWTV", // Attract shield TV
- "MT_BLUETV", // Force shield TV
- "MT_BLACKTV", // Bomb shield TV
- "MT_WHITETV", // Jump shield TV
- "MT_GREENTV", // Elemental shield TV
- "MT_PITYTV", // Pity shield TV
- "MT_EGGMANBOX",
- "MT_MIXUPBOX",
- "MT_RECYCLETV",
- "MT_RECYCLEICO",
- "MT_QUESTIONBOX",
- "MT_GRAVITYBOX",
- "MT_SCORETVSMALL",
- "MT_SCORETVLARGE",
-
// Monitor miscellany
- "MT_MONITOREXPLOSION",
- "MT_REDMONITOREXPLOSION",
- "MT_BLUEMONITOREXPLOSION",
- "MT_RINGICO",
- "MT_SHOESICO",
- "MT_INVCICO",
- "MT_1UPICO",
- "MT_YSHIELDICO",
- "MT_BSHIELDICO",
- "MT_KSHIELDICO",
- "MT_WSHIELDICO",
- "MT_GSHIELDICO",
- "MT_PITYSHIELDICO",
- "MT_EGGMANICO",
- "MT_MIXUPICO",
- "MT_GRAVITYICO",
- "MT_SCOREICOSMALL",
- "MT_SCOREICOLARGE",
+ "MT_BOXSPARKLE",
+
+ // Monitor boxes -- regular
+ "MT_RING_BOX",
+ "MT_PITY_BOX",
+ "MT_ATTRACT_BOX",
+ "MT_FORCE_BOX",
+ "MT_ARMAGEDDON_BOX",
+ "MT_WHIRLWIND_BOX",
+ "MT_ELEMENTAL_BOX",
+ "MT_SNEAKERS_BOX",
+ "MT_INVULN_BOX",
+ "MT_1UP_BOX",
+ "MT_EGGMAN_BOX",
+ "MT_MIXUP_BOX",
+ "MT_MYSTERY_BOX",
+ "MT_GRAVITY_BOX",
+ "MT_RECYCLER_BOX",
+ "MT_SCORE1K_BOX",
+ "MT_SCORE10K_BOX",
+
+ // Monitor boxes -- repeating (big) boxes
+ "MT_PITY_GOLDBOX",
+ "MT_ATTRACT_GOLDBOX",
+ "MT_FORCE_GOLDBOX",
+ "MT_ARMAGEDDON_GOLDBOX",
+ "MT_WHIRLWIND_GOLDBOX",
+ "MT_ELEMENTAL_GOLDBOX",
+ "MT_SNEAKERS_GOLDBOX",
+ "MT_INVULN_GOLDBOX",
+ "MT_EGGMAN_GOLDBOX",
+ "MT_GRAVITY_GOLDBOX",
+
+ // Monitor boxes -- special
+ "MT_RING_REDBOX",
+ "MT_RING_BLUEBOX",
+
+ // Monitor icons
+ "MT_RING_ICON",
+ "MT_PITY_ICON",
+ "MT_ATTRACT_ICON",
+ "MT_FORCE_ICON",
+ "MT_ARMAGEDDON_ICON",
+ "MT_WHIRLWIND_ICON",
+ "MT_ELEMENTAL_ICON",
+ "MT_SNEAKERS_ICON",
+ "MT_INVULN_ICON",
+ "MT_1UP_ICON",
+ "MT_EGGMAN_ICON",
+ "MT_MIXUP_ICON",
+ "MT_GRAVITY_ICON",
+ "MT_RECYCLER_ICON",
+ "MT_SCORE1K_ICON",
+ "MT_SCORE10K_ICON",
// Projectiles
"MT_ROCKET",
@@ -6485,6 +6439,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SMALLBUBBLE", // small bubble
"MT_MEDIUMBUBBLE", // medium bubble
"MT_EXTRALARGEBUBBLE", // extra large bubble
+ "MT_WATERZAP",
"MT_TFOG",
"MT_SEED",
"MT_PARTICLE",
@@ -6557,7 +6512,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_AXISTRANSFERLINE",
"MT_NIGHTSDRONE",
"MT_NIGHTSGOAL",
- "MT_NIGHTSCHAR",
"MT_NIGHTSPARKLE",
"MT_NIGHTSLOOPHELPER",
"MT_NIGHTSBUMPER", // NiGHTS Bumper
@@ -6714,12 +6668,14 @@ static const char *const MOBJEFLAG_LIST[] = {
NULL
};
+#ifdef HAVE_BLUA
static const char *const MAPTHINGFLAG_LIST[4] = {
NULL,
"OBJECTFLIP", // Reverse gravity flag for objects.
"OBJECTSPECIAL", // Special flag used with certain objects.
"AMBUSH" // Deaf monsters/do not react to sound.
};
+#endif
static const char *const PLAYERFLAG_LIST[] = {
// Flip camera angle with gravity flip prefrence.
@@ -6756,21 +6712,9 @@ static const char *const PLAYERFLAG_LIST[] = {
// Are you gliding?
"GLIDING",
- // Tails pickup!
- "CARRIED",
-
// Sliding (usually in water) like Labyrinth/Oil Ocean
"SLIDING",
- // Hanging on a rope
- "ROPEHANG",
-
- // Hanging on an item of some kind - zipline, chain, etc. (->tracer)
- "ITEMHANG",
-
- // On the mace chain spinning around (->tracer)
- "MACESPIN",
-
/*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode?
"NIGHTSMODE",
@@ -6792,6 +6736,7 @@ static const char *const PLAYERFLAG_LIST[] = {
NULL // stop loop here.
};
+#ifdef HAVE_BLUA
// Linedef flags
static const char *const ML_LIST[16] = {
"IMPASSIBLE",
@@ -6811,6 +6756,7 @@ static const char *const ML_LIST[16] = {
"BOUNCY",
"TFERLINE"
};
+#endif
// This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors
@@ -6845,24 +6791,61 @@ static const char *COLOR_ENUMS[] = {
"MAGENTA", // SKINCOLOR_MAGENTA
"PINK", // SKINCOLOR_PINK
"ROSY", // SKINCOLOR_ROSY
+
// Super special awesome Super flashing colors!
- "SUPER1", // SKINCOLOR_SUPER1
- "SUPER2", // SKINCOLOR_SUPER2,
- "SUPER3", // SKINCOLOR_SUPER3,
- "SUPER4", // SKINCOLOR_SUPER4,
- "SUPER5", // SKINCOLOR_SUPER5,
- // Super Tails
- "TSUPER1", // SKINCOLOR_TSUPER1,
- "TSUPER2", // SKINCOLOR_TSUPER2,
- "TSUPER3", // SKINCOLOR_TSUPER3,
- "TSUPER4", // SKINCOLOR_TSUPER4,
- "TSUPER5", // SKINCOLOR_TSUPER5,
- // Super Knuckles
- "KSUPER1", // SKINCOLOR_KSUPER1,
- "KSUPER2", // SKINCOLOR_KSUPER2,
- "KSUPER3", // SKINCOLOR_KSUPER3,
- "KSUPER4", // SKINCOLOR_KSUPER4,
- "KSUPER5" // SKINCOLOR_KSUPER5,
+ "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1
+ "SUPERSILVER2", // SKINCOLOR_SUPERSILVER2,
+ "SUPERSILVER3", // SKINCOLOR_SUPERSILVER3,
+ "SUPERSILVER4", // SKINCOLOR_SUPERSILVER4,
+ "SUPERSILVER5", // SKINCOLOR_SUPERSILVER5,
+
+ "SUPERRED1", // SKINCOLOR_SUPERRED1
+ "SUPERRED2", // SKINCOLOR_SUPERRED2,
+ "SUPERRED3", // SKINCOLOR_SUPERRED3,
+ "SUPERRED4", // SKINCOLOR_SUPERRED4,
+ "SUPERRED5", // SKINCOLOR_SUPERRED5,
+
+ "SUPERORANGE1", // SKINCOLOR_SUPERORANGE1
+ "SUPERORANGE2", // SKINCOLOR_SUPERORANGE2,
+ "SUPERORANGE3", // SKINCOLOR_SUPERORANGE3,
+ "SUPERORANGE4", // SKINCOLOR_SUPERORANGE4,
+ "SUPERORANGE5", // SKINCOLOR_SUPERORANGE5,
+
+ "SUPERGOLD1", // SKINCOLOR_SUPERGOLD1
+ "SUPERGOLD2", // SKINCOLOR_SUPERGOLD2,
+ "SUPERGOLD3", // SKINCOLOR_SUPERGOLD3,
+ "SUPERGOLD4", // SKINCOLOR_SUPERGOLD4,
+ "SUPERGOLD5", // SKINCOLOR_SUPERGOLD5,
+
+ "SUPERPERIDOT1", // SKINCOLOR_SUPERPERIDOT1
+ "SUPERPERIDOT2", // SKINCOLOR_SUPERPERIDOT2,
+ "SUPERPERIDOT3", // SKINCOLOR_SUPERPERIDOT3,
+ "SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4,
+ "SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5,
+
+ "SUPERCYAN1", // SKINCOLOR_SUPERCYAN1
+ "SUPERCYAN2", // SKINCOLOR_SUPERCYAN2,
+ "SUPERCYAN3", // SKINCOLOR_SUPERCYAN3,
+ "SUPERCYAN4", // SKINCOLOR_SUPERCYAN4,
+ "SUPERCYAN5", // SKINCOLOR_SUPERCYAN5,
+
+ "SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1,
+ "SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2,
+ "SUPERPURPLE3", // SKINCOLOR_SUPERPURPLE3,
+ "SUPERPURPLE4", // SKINCOLOR_SUPERPURPLE4,
+ "SUPERPURPLE5", // SKINCOLOR_SUPERPURPLE5,
+
+ "SUPERRUST1", // SKINCOLOR_SUPERRUST1
+ "SUPERRUST2", // SKINCOLOR_SUPERRUST2,
+ "SUPERRUST3", // SKINCOLOR_SUPERRUST3,
+ "SUPERRUST4", // SKINCOLOR_SUPERRUST4,
+ "SUPERRUST5", // SKINCOLOR_SUPERRUST5,
+
+ "SUPERTAN1", // SKINCOLOR_SUPERTAN1
+ "SUPERTAN2", // SKINCOLOR_SUPERTAN2,
+ "SUPERTAN3", // SKINCOLOR_SUPERTAN3,
+ "SUPERTAN4", // SKINCOLOR_SUPERTAN4,
+ "SUPERTAN5" // SKINCOLOR_SUPERTAN5,
};
static const char *const POWERS_LIST[] = {
@@ -6870,6 +6853,7 @@ static const char *const POWERS_LIST[] = {
"SNEAKERS",
"FLASHING",
"SHIELD",
+ "CARRY",
"TAILSFLY", // tails flying
"UNDERWATER", // underwater timer
"SPACETIME", // In space, no one can hear you spin!
@@ -6989,6 +6973,8 @@ struct {
// Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK},
+ {"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE},
+ {"FF_MIDDLESTARTCHANCE",FF_MIDDLESTARTCHANCE},
{"FF_ANIMATE",FF_ANIMATE},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK},
@@ -7103,6 +7089,14 @@ struct {
{"SH_STACK",SH_STACK},
{"SH_NOSTACK",SH_NOSTACK},
+ // Carrying
+ {"CR_NONE",CR_NONE},
+ {"CR_GENERIC",CR_GENERIC},
+ {"CR_PLAYER",CR_PLAYER},
+ {"CR_ZOOMTUBE",CR_ZOOMTUBE},
+ {"CR_ROPEHANG",CR_ROPEHANG},
+ {"CR_MACESPIN",CR_MACESPIN},
+
// Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon
{"RW_AUTO",RW_AUTO},
@@ -7120,6 +7114,11 @@ struct {
{"SF_NOSKID",SF_NOSKID},
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
{"SF_RUNONWATER",SF_RUNONWATER},
+ {"SF_NOJUMPSPIN",SF_NOJUMPSPIN},
+ {"SF_NOJUMPDAMAGE",SF_NOJUMPDAMAGE},
+ {"SF_STOMPDAMAGE",SF_STOMPDAMAGE},
+ {"SF_MARIODAMAGE",SF_MARIODAMAGE},
+ {"SF_MACHINE",SF_MACHINE},
// Character abilities!
// Primary
@@ -7137,10 +7136,13 @@ struct {
{"CA_JUMPBOOST",CA_JUMPBOOST},
{"CA_AIRDRILL",CA_AIRDRILL},
{"CA_JUMPTHOK",CA_JUMPTHOK},
+ {"CA_DASHMODE",CA_DASHMODE},
+ {"CA_TWINSPIN",CA_TWINSPIN},
// Secondary
{"CA2_NONE",CA2_NONE}, // now slot 0!
{"CA2_SPINDASH",CA2_SPINDASH},
{"CA2_MULTIABILITY",CA2_MULTIABILITY},
+ {"CA2_MELEE",CA2_MELEE},
// Sound flags
{"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE},
@@ -7203,11 +7205,14 @@ struct {
{"PA_EDGE",PA_EDGE},
{"PA_WALK",PA_WALK},
{"PA_RUN",PA_RUN},
+ {"PA_PEEL",PA_PEEL},
{"PA_PAIN",PA_PAIN},
{"PA_ROLL",PA_ROLL},
+ {"PA_JUMP",PA_JUMP},
{"PA_SPRING",PA_SPRING},
{"PA_FALL",PA_FALL},
{"PA_ABILITY",PA_ABILITY},
+ {"PA_ABILITY2",PA_ABILITY2},
{"PA_RIDE",PA_RIDE},
// Current weapon
@@ -7783,7 +7788,7 @@ fixed_t get_number(const char *word)
#endif
}
-void DEH_Check(void)
+void FUNCMATH DEH_Check(void)
{
#if defined(_DEBUG) || defined(PARANOIA)
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
@@ -7848,7 +7853,7 @@ static inline int lib_freeslot(lua_State *L)
lua_pushinteger(L, sfx);
r++;
} else
- return r;
+ CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
}
else if (fastcmp(type, "SPR"))
{
@@ -7875,7 +7880,7 @@ static inline int lib_freeslot(lua_State *L)
break;
}
if (j > SPR_LASTFREESLOT)
- return r;
+ CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
}
else if (fastcmp(type, "S"))
{
@@ -7890,7 +7895,7 @@ static inline int lib_freeslot(lua_State *L)
break;
}
if (i == NUMSTATEFREESLOTS)
- return r;
+ CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
}
else if (fastcmp(type, "MT"))
{
@@ -7905,7 +7910,26 @@ static inline int lib_freeslot(lua_State *L)
break;
}
if (i == NUMMOBJFREESLOTS)
- return r;
+ CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
+ }
+ else if (fastcmp(type, "SPR2"))
+ {
+ // Search if we already have an SPR2 by that name...
+ enum playersprite i;
+ for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++)
+ if (memcmp(spr2names[i],word,4) == 0)
+ break;
+ // We don't, so allocate a new one.
+ if (i >= free_spr2) {
+ if (free_spr2 < NUMPLAYERSPRITES)
+ {
+ CONS_Printf("Sprite SPR2_%s allocated.\n",word);
+ strncpy(spr2names[free_spr2],word,4);
+ spr2names[free_spr2++][4] = 0;
+ } else
+ CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+ }
+ r++;
}
Z_Free(s);
lua_remove(L, 1);
@@ -8072,7 +8096,7 @@ static inline int lib_getenum(lua_State *L)
}
else if (fastncmp("SPR2_",word,4)) {
p = word+5;
- for (i = 0; i < NUMPLAYERSPRITES; i++)
+ for (i = 0; i < (fixed_t)free_spr2; i++)
if (!spr2names[i][4])
{
// special 3-char cases, e.g. SPR2_RUN
@@ -8318,6 +8342,9 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"VERSIONSTRING")) {
lua_pushstring(L, VERSIONSTRING);
return 1;
+ } else if (fastcmp(word, "token")) {
+ lua_pushinteger(L, token);
+ return 1;
}
return 0;
diff --git a/src/doomdata.h b/src/doomdata.h
index e916a151f..033cc71b3 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -207,7 +207,7 @@ typedef struct
#define ZSHIFT 4
-extern const char *Color_Names[MAXSKINCOLORS];
+extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS];
extern const UINT8 Color_Opposite[MAXSKINCOLORS*2];
#define NUMMAPS 1035
diff --git a/src/doomdef.h b/src/doomdef.h
index 70ec8c0d1..3f504d25f 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -60,6 +60,7 @@
#endif
#ifdef _WINDOWS
+#define NONET
#if !defined (HWRENDER) && !defined (NOHW)
#define HWRENDER
#endif
@@ -158,7 +159,7 @@ extern FILE *logstream;
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
-//#define USE_PATCH_DTA
+#define USE_PATCH_DTA
// Modification options
// If you want to take advantage of the Master Server's ability to force clients to update
@@ -213,7 +214,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
-#define MODVERSION 20
+#define MODVERSION 21
// =========================================================================
@@ -257,32 +258,69 @@ typedef enum
SKINCOLOR_MAGENTA,
SKINCOLOR_PINK,
SKINCOLOR_ROSY,
+ //SKINCOLOR_?
+ //SKINCOLOR_?
- // Careful! MAXSKINCOLORS cannot be greater than 0x20!
+ // Careful! MAXSKINCOLORS cannot be greater than 0x20! Two slots left...
MAXSKINCOLORS,
// Super special awesome Super flashing colors!
- SKINCOLOR_SUPER1 = MAXSKINCOLORS,
- SKINCOLOR_SUPER2,
- SKINCOLOR_SUPER3,
- SKINCOLOR_SUPER4,
- SKINCOLOR_SUPER5,
+ SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS,
+ SKINCOLOR_SUPERSILVER2,
+ SKINCOLOR_SUPERSILVER3,
+ SKINCOLOR_SUPERSILVER4,
+ SKINCOLOR_SUPERSILVER5,
- // Super Tails
- SKINCOLOR_TSUPER1,
- SKINCOLOR_TSUPER2,
- SKINCOLOR_TSUPER3,
- SKINCOLOR_TSUPER4,
- SKINCOLOR_TSUPER5,
+ SKINCOLOR_SUPERRED1,
+ SKINCOLOR_SUPERRED2,
+ SKINCOLOR_SUPERRED3,
+ SKINCOLOR_SUPERRED4,
+ SKINCOLOR_SUPERRED5,
- // Super Knuckles
- SKINCOLOR_KSUPER1,
- SKINCOLOR_KSUPER2,
- SKINCOLOR_KSUPER3,
- SKINCOLOR_KSUPER4,
- SKINCOLOR_KSUPER5,
+ SKINCOLOR_SUPERORANGE1,
+ SKINCOLOR_SUPERORANGE2,
+ SKINCOLOR_SUPERORANGE3,
+ SKINCOLOR_SUPERORANGE4,
+ SKINCOLOR_SUPERORANGE5,
- MAXTRANSLATIONS
+ SKINCOLOR_SUPERGOLD1,
+ SKINCOLOR_SUPERGOLD2,
+ SKINCOLOR_SUPERGOLD3,
+ SKINCOLOR_SUPERGOLD4,
+ SKINCOLOR_SUPERGOLD5,
+
+ SKINCOLOR_SUPERPERIDOT1,
+ SKINCOLOR_SUPERPERIDOT2,
+ SKINCOLOR_SUPERPERIDOT3,
+ SKINCOLOR_SUPERPERIDOT4,
+ SKINCOLOR_SUPERPERIDOT5,
+
+ SKINCOLOR_SUPERCYAN1,
+ SKINCOLOR_SUPERCYAN2,
+ SKINCOLOR_SUPERCYAN3,
+ SKINCOLOR_SUPERCYAN4,
+ SKINCOLOR_SUPERCYAN5,
+
+ SKINCOLOR_SUPERPURPLE1,
+ SKINCOLOR_SUPERPURPLE2,
+ SKINCOLOR_SUPERPURPLE3,
+ SKINCOLOR_SUPERPURPLE4,
+ SKINCOLOR_SUPERPURPLE5,
+
+ SKINCOLOR_SUPERRUST1,
+ SKINCOLOR_SUPERRUST2,
+ SKINCOLOR_SUPERRUST3,
+ SKINCOLOR_SUPERRUST4,
+ SKINCOLOR_SUPERRUST5,
+
+ SKINCOLOR_SUPERTAN1,
+ SKINCOLOR_SUPERTAN2,
+ SKINCOLOR_SUPERTAN3,
+ SKINCOLOR_SUPERTAN4,
+ SKINCOLOR_SUPERTAN5,
+
+ MAXTRANSLATIONS,
+ NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5)
} skincolors_t;
// State updates, number of tics / second.
@@ -435,6 +473,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
+#ifdef ESLOPE
+/// Backwards compatibility with SRB2CB's slope linedef types.
+/// \note A simple shim that prints a warning.
+#define ESLOPE_TYPESHIM
+#endif
+
/// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE
diff --git a/src/doomtype.h b/src/doomtype.h
index 2d9d36328..a711b466d 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -92,7 +92,7 @@ typedef long ssize_t;
#endif
#ifdef __APPLE_CC__
-#define DIRECTFULLSCREEN
+#define DIRECTFULLSCREEN 1
#define DEBUG_LOG
#define NOIPX
#endif
diff --git a/src/f_finale.c b/src/f_finale.c
index 68b23528d..81c530e6a 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -1727,6 +1727,7 @@ static void F_AdvanceToNextScene(void)
void F_EndCutScene(void)
{
+ cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
if (runningprecutscene)
{
if (server)
@@ -1743,7 +1744,6 @@ void F_EndCutScene(void)
else
Y_EndGame();
}
- cutsceneover = true;
}
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer)
diff --git a/src/f_finale.h b/src/f_finale.h
index 8ee02bdf3..1f23643be 100644
--- a/src/f_finale.h
+++ b/src/f_finale.h
@@ -35,7 +35,7 @@ void F_CutsceneTicker(void);
void F_TitleDemoTicker(void);
// Called by main loop.
-void F_GameEndDrawer(void);
+FUNCMATH void F_GameEndDrawer(void);
void F_IntroDrawer(void);
void F_TitleScreenDrawer(void);
diff --git a/src/g_game.c b/src/g_game.c
index 8dba4f78a..c5488e0b7 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -712,6 +712,10 @@ void G_SetGameModified(boolean silent)
if (!silent)
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n"));
+
+ // If in record attack recording, cancel it.
+ if (modeattacking)
+ M_EndModeAttackRun();
}
/** Builds an original game map name from a map number.
@@ -2044,6 +2048,8 @@ void G_PlayerReborn(INT32 player)
INT32 score;
INT32 lives;
INT32 continues;
+ fixed_t camerascale;
+ fixed_t shieldscale;
UINT8 charability;
UINT8 charability2;
fixed_t normalspeed;
@@ -2067,6 +2073,8 @@ void G_PlayerReborn(INT32 player)
INT32 starpostnum;
INT32 starpostangle;
fixed_t jumpfactor;
+ fixed_t height;
+ fixed_t spinheight;
INT32 exiting;
INT16 numboxes;
INT16 totalring;
@@ -2098,6 +2106,8 @@ void G_PlayerReborn(INT32 player)
skincolor = players[player].skincolor;
skin = players[player].skin;
+ camerascale = players[player].camerascale;
+ shieldscale = players[player].shieldscale;
charability = players[player].charability;
charability2 = players[player].charability2;
normalspeed = players[player].normalspeed;
@@ -2114,6 +2124,8 @@ void G_PlayerReborn(INT32 player)
starpostnum = players[player].starpostnum;
starpostangle = players[player].starpostangle;
jumpfactor = players[player].jumpfactor;
+ height = players[player].height;
+ spinheight = players[player].spinheight;
thokitem = players[player].thokitem;
spinitem = players[player].spinitem;
revitem = players[player].revitem;
@@ -2139,6 +2151,8 @@ void G_PlayerReborn(INT32 player)
// save player config truth reborn
p->skincolor = skincolor;
p->skin = skin;
+ p->camerascale = camerascale;
+ p->shieldscale = shieldscale;
p->charability = charability;
p->charability2 = charability2;
p->normalspeed = normalspeed;
@@ -2161,6 +2175,8 @@ void G_PlayerReborn(INT32 player)
p->starpostnum = starpostnum;
p->starpostangle = starpostangle;
p->jumpfactor = jumpfactor;
+ p->height = height;
+ p->spinheight = spinheight;
p->exiting = exiting;
p->numboxes = numboxes;
@@ -4346,12 +4362,18 @@ void G_GhostTicker(void)
// Tick ghost colors (Super and Mario Invincibility flashing)
switch(g->color)
{
- case GHC_SUPER: // Super Sonic (P_DoSuperStuff)
- g->mo->color = SKINCOLOR_SUPER1;
+ case GHC_SUPER: // Super (P_DoSuperStuff)
+ if (g->mo->skin)
+ {
+ skin_t *skin = (skin_t *)g->mo->skin;
+ g->mo->color = skin->supercolor;
+ }
+ else
+ g->mo->color = SKINCOLOR_SUPERGOLD1;
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
- g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS);
+ g->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours
break;
default:
break;
@@ -4687,6 +4709,8 @@ void G_BeginRecording(void)
demo_p += 16;
// Stats
+ WRITEUINT8(demo_p,player->camerascale>>FRACBITS);
+ WRITEUINT8(demo_p,player->shieldscale>>FRACBITS);
WRITEUINT8(demo_p,player->charability);
WRITEUINT8(demo_p,player->charability2);
WRITEUINT8(demo_p,player->actionspd>>FRACBITS);
@@ -4697,6 +4721,8 @@ void G_BeginRecording(void)
WRITEUINT8(demo_p,player->thrustfactor);
WRITEUINT8(demo_p,player->accelstart);
WRITEUINT8(demo_p,player->acceleration);
+ WRITEUINT8(demo_p,player->height>>FRACBITS);
+ WRITEUINT8(demo_p,player->spinheight>>FRACBITS);
// Trying to convert it back to % causes demo desync due to precision loss.
// Don't do it.
@@ -4927,7 +4953,7 @@ void G_DoPlayDemo(char *defdemoname)
char skin[17],color[17],*n,*pdemoname;
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration;
UINT32 randseed;
- fixed_t actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor;
+ fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
char msg[1024];
skin[16] = '\0';
@@ -5063,6 +5089,8 @@ void G_DoPlayDemo(char *defdemoname)
M_Memcpy(color,demo_p,16);
demo_p += 16;
+ camerascale = (fixed_t)READUINT8(demo_p)<f_slope && FOFsector->floorheight == fixedheight)
+ if (FOFsector->f_slope && !isceiling)
slope = FOFsector->f_slope;
- else if (FOFsector->c_slope && FOFsector->ceilingheight == fixedheight)
+ else if (FOFsector->c_slope && isceiling)
slope = FOFsector->c_slope;
}
else
{
- // Use fixedheight to determine whether to check floor or ceiling because I hate my life
- if (gr_frontsector->f_slope && gr_frontsector->floorheight == fixedheight)
+ if (gr_frontsector->f_slope && !isceiling)
slope = gr_frontsector->f_slope;
- else if (gr_frontsector->c_slope && gr_frontsector->ceilingheight == fixedheight)
+ else if (gr_frontsector->c_slope && isceiling)
slope = gr_frontsector->c_slope;
}
@@ -638,12 +637,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
if (FOFsector != NULL)
{
-#ifdef ESLOPE
- if ((slope && slope == FOFsector->f_slope)
- || fixedheight == FOFsector->floorheight) // it's a floor
-#else
- if (fixedheight == FOFsector->floorheight) // it's a floor
-#endif
+ if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
@@ -658,12 +652,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
}
else if (gr_frontsector)
{
-#ifdef ESLOPE
- if ((slope && slope == gr_frontsector->f_slope)
- || fixedheight == gr_frontsector->floorheight) // it's a floor
-#else
- if (fixedheight < dup_viewz) // it's a floor
-#endif
+ if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
@@ -1675,9 +1664,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
else
{
// Skewed by bottom
- wallVerts[0].t = (texturevpegtop + worldhigh - worldtop) * grTex->scaleY;
- wallVerts[2].t = wallVerts[3].t - (worldhighslope - worldhigh) * grTex->scaleY;
- wallVerts[1].t = wallVerts[2].t - (worldhighslope - worldtopslope) * grTex->scaleY;
+ wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
+ wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
+ wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
}
#endif
}
@@ -1719,12 +1708,12 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
if (!(gr_linedef->flags & ML_DONTPEGBOTTOM))
texturevpegbottom = 0;
else if (gr_linedef->flags & ML_EFFECT1)
- texturevpegbottom = worldtop - worldlow;
+ texturevpegbottom = worldbottom - worldlow;
else
- texturevpegbottom = gr_frontsector->ceilingheight - gr_backsector->floorheight;
+ texturevpegbottom = gr_frontsector->floorheight - gr_backsector->floorheight;
#else
if (gr_linedef->flags & ML_DONTPEGBOTTOM)
- texturevpegbottom = worldtop - worldlow;
+ texturevpegbottom = worldbottom - worldlow;
else
texturevpegbottom = 0;
#endif
@@ -1752,9 +1741,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
else if (gr_linedef->flags & ML_DONTPEGBOTTOM)
{
// Skewed by bottom
- wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
- wallVerts[2].t = wallVerts[3].t - (worldlowslope - worldlow) * grTex->scaleY;
- wallVerts[1].t = wallVerts[2].t - (worldbottomslope - worldlowslope) * grTex->scaleY;
+ wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
+ //wallVerts[3].t = wallVerts[0].t - (worldlow - worldbottom) * grTex->scaleY; // no need, [3] is already this
+ wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY;
}
else
{
@@ -2892,15 +2881,57 @@ static void HWR_AddLine(seg_t * line)
gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true);
- // Closed door.
- if (gr_backsector->ceilingheight <= gr_frontsector->floorheight ||
- gr_backsector->floorheight >= gr_frontsector->ceilingheight)
- goto clipsolid;
+#ifdef ESLOPE
+ if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope)
+ {
+ fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
+ fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
+ fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
- // Window.
- if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight ||
- gr_backsector->floorheight != gr_frontsector->floorheight)
- goto clippass;
+ v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x);
+ v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y);
+ v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x);
+ v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y);
+#define SLOPEPARAMS(slope, end1, end2, normalheight) \
+ if (slope) { \
+ end1 = P_GetZAt(slope, v1x, v1y); \
+ end2 = P_GetZAt(slope, v2x, v2y); \
+ } else \
+ end1 = end2 = normalheight;
+
+ SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector->floorheight)
+ SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight)
+ SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight)
+ SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight)
+#undef SLOPEPARAMS
+
+ // Closed door.
+ if ((backc1 <= frontf1 && backc2 <= frontf2)
+ || (backf1 >= frontc1 && backf2 >= frontc2))
+ {
+ goto clipsolid;
+ }
+
+ // Window.
+ if (backc1 != frontc1 || backc2 != frontc2
+ || backf1 != frontf1 || backf2 != frontf2)
+ {
+ goto clippass;
+ }
+ }
+ else
+#endif
+ {
+ // Closed door.
+ if (gr_backsector->ceilingheight <= gr_frontsector->floorheight ||
+ gr_backsector->floorheight >= gr_frontsector->ceilingheight)
+ goto clipsolid;
+
+ // Window.
+ if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight ||
+ gr_backsector->floorheight != gr_frontsector->floorheight)
+ goto clippass;
+ }
// Reject empty lines used for triggers and special events.
// Identical floor and ceiling on both sides,
@@ -3069,7 +3100,7 @@ static inline void HWR_AddPolyObjectSegs(void)
}
#ifdef POLYOBJECTS_PLANES
-static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight,
+static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap)
{
@@ -3153,7 +3184,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight
if (FOFsector != NULL)
{
- if (fixedheight == FOFsector->floorheight) // it's a floor
+ if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
@@ -3168,7 +3199,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight
}
else if (gr_frontsector)
{
- if (fixedheight < dup_viewz) // it's a floor
+ if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
@@ -3261,13 +3292,13 @@ static void HWR_AddPolyObjectPlanes(void)
{
FSurfaceInfo Surf;
FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
- HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], polyobjsector->floorheight,
+ HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
}
else
{
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum);
- HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->floorheight, PF_Occlude,
+ HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL);
}
@@ -3283,13 +3314,13 @@ static void HWR_AddPolyObjectPlanes(void)
FBITFIELD blendmode;
memset(&Surf, 0x00, sizeof(Surf));
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
- HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], polyobjsector->ceilingheight,
+ HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
}
else
{
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum);
- HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->ceilingheight, PF_Occlude,
+ HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL);
}
@@ -3443,7 +3474,7 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount)
{
HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum);
- HWR_RenderPlane(gr_frontsector, &extrasubsectors[num],
+ HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false,
// Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
// We now return you to your regularly scheduled rendering.
@@ -3465,7 +3496,7 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount)
{
HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum);
- HWR_RenderPlane(NULL, &extrasubsectors[num],
+ HWR_RenderPlane(NULL, &extrasubsectors[num], true,
// Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
// We now return you to your regularly scheduled rendering.
@@ -3534,6 +3565,7 @@ static void HWR_Subsector(size_t num)
HWR_AddTransparentFloor(0,
&extrasubsectors[num],
+ false,
*rover->bottomheight,
*gr_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture,
@@ -3551,6 +3583,7 @@ static void HWR_Subsector(size_t num)
#else
HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum,
&extrasubsectors[num],
+ false,
*rover->bottomheight,
*gr_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
@@ -3561,7 +3594,7 @@ static void HWR_Subsector(size_t num)
{
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
- HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
+ HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
}
}
@@ -3595,6 +3628,7 @@ static void HWR_Subsector(size_t num)
HWR_AddTransparentFloor(0,
&extrasubsectors[num],
+ true,
*rover->topheight,
*gr_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture,
@@ -3612,6 +3646,7 @@ static void HWR_Subsector(size_t num)
#else
HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum,
&extrasubsectors[num],
+ true,
*rover->topheight,
*gr_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
@@ -3623,7 +3658,7 @@ static void HWR_Subsector(size_t num)
{
HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
- HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
+ HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
}
}
@@ -4487,7 +4522,8 @@ static void HWR_SortVisSprites(void)
// Fix first and last. ds still points to the last one after the loop
dsfirst->prev = &unsorted;
unsorted.next = dsfirst;
- ds->next = &unsorted;
+ if (ds)
+ ds->next = &unsorted;
unsorted.prev = ds;
// pull the vissprites out by scale
@@ -4510,10 +4546,13 @@ static void HWR_SortVisSprites(void)
best = ds;
}
}
- best->next->prev = best->prev;
- best->prev->next = best->next;
- best->next = &gr_vsprsortedhead;
- best->prev = gr_vsprsortedhead.prev;
+ if (best)
+ {
+ best->next->prev = best->prev;
+ best->prev->next = best->next;
+ best->next = &gr_vsprsortedhead;
+ best->prev = gr_vsprsortedhead.prev;
+ }
gr_vsprsortedhead.prev->next = best;
gr_vsprsortedhead.prev = best;
}
@@ -4546,6 +4585,7 @@ static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIE
typedef struct
{
extrasubsector_t *xsub;
+ boolean isceiling;
fixed_t fixedheight;
INT32 lightlevel;
lumpnum_t lumpnum;
@@ -4563,6 +4603,7 @@ static planeinfo_t *planeinfo = NULL;
typedef struct
{
polyobj_t *polysector;
+ boolean isceiling;
fixed_t fixedheight;
INT32 lightlevel;
lumpnum_t lumpnum;
@@ -4598,7 +4639,7 @@ static INT32 drawcount = 0;
#define MAX_TRANSPARENTFLOOR 512
// This will likely turn into a copy of HWR_Add3DWater and replace it.
-void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub,
+void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap)
{
static size_t allocedplanes = 0;
@@ -4613,6 +4654,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub,
Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo);
}
+ planeinfo[numplanes].isceiling = isceiling;
planeinfo[numplanes].fixedheight = fixedheight;
planeinfo[numplanes].lightlevel = lightlevel;
planeinfo[numplanes].lumpnum = lumpnum;
@@ -4623,12 +4665,13 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub,
planeinfo[numplanes].fogplane = fogplane;
planeinfo[numplanes].planecolormap = planecolormap;
planeinfo[numplanes].drawcount = drawcount++;
+
numplanes++;
}
// Adding this for now until I can create extrasubsector info for polyobjects
// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane
-void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
+void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap)
{
static size_t allocedpolyplanes = 0;
@@ -4643,6 +4686,7 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
Z_Realloc(polyplaneinfo, allocedpolyplanes * sizeof (*polyplaneinfo), PU_LEVEL, &polyplaneinfo);
}
+ polyplaneinfo[numpolyplanes].isceiling = isceiling;
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
polyplaneinfo[numpolyplanes].lumpnum = lumpnum;
@@ -4808,7 +4852,7 @@ static void HWR_CreateDrawNodes(void)
if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture))
HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum);
- HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
+ HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
}
else if (sortnode[sortindex[i]].polyplane)
@@ -4818,7 +4862,7 @@ static void HWR_CreateDrawNodes(void)
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum);
- HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
+ HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
}
else if (sortnode[sortindex[i]].wall)
@@ -5050,22 +5094,29 @@ static void HWR_ProjectSprite(mobj_t *thing)
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
#endif
- if (sprframe->rotate)
- {
- // choose a different rotation based on player view
- ang = R_PointToAngle(thing->x, thing->y); // uses viewx,viewy
- rot = (ang-thing->angle+ANGLE_202h)>>29;
- //Fab: lumpid is the index for spritewidth,spriteoffset... tables
- lumpoff = sprframe->lumpid[rot];
- flip = sprframe->flip & (1<rotate == SRF_SINGLE)
{
// use single rotation for all views
rot = 0; //Fab: for vis->patch below
lumpoff = sprframe->lumpid[0]; //Fab: see note above
flip = sprframe->flip; // Will only be 0x00 or 0xFF
}
+ else
+ {
+ // choose a different rotation based on player view
+ ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
+
+ if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
+ rot = 6; // F7 slot
+ else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
+ rot = 2; // F3 slot
+ else // Normal behaviour
+ rot = (ang+ANGLE_202h)>>29;
+
+ //Fab: lumpid is the index for spritewidth,spriteoffset... tables
+ lumpoff = sprframe->lumpid[rot];
+ flip = sprframe->flip & (1<skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
@@ -5279,7 +5330,7 @@ static void HWR_DrawSkyBackground(player_t *player)
// 0--1
(void)player;
- HWR_GetTexture(skytexture);
+ HWR_GetTexture(texturetranslation[skytexture]);
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
// because it's called just after clearing the screen
@@ -5299,7 +5350,7 @@ static void HWR_DrawSkyBackground(player_t *player)
angle = (dup_viewangle + gr_xtoviewangle[0]);
- dimensionmultiply = ((float)textures[skytexture]->width/256.0f);
+ dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply));
v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply));
@@ -5308,7 +5359,7 @@ static void HWR_DrawSkyBackground(player_t *player)
angle = aimingangle;
aspectratio = (float)vid.width/(float)vid.height;
- dimensionmultiply = ((float)textures[skytexture]->height/(128.0f*aspectratio));
+ dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
// Middle of the sky should always be at angle 0
@@ -6115,7 +6166,7 @@ static void HWR_Render3DWater(void)
for (i = 0; i < numfloors; i++)
{
HWR_GetFlat(planeinfo[i].lumpnum);
- HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].lumpnum,
+ HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].isceiling, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].lumpnum,
planeinfo[i].FOFSector, planeinfo[i].alpha, planeinfo[i].fogplane, planeinfo[i].planecolormap);
}
numfloors = 0;
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index 6628d1317..fa4699810 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -1035,32 +1035,151 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
case SKINCOLOR_ROSY:
blendcolor = V_GetColor(202);
break;
- case SKINCOLOR_SUPER1:
+
+ case SKINCOLOR_SUPERSILVER1: // Super silver
+ blendcolor = V_GetColor(0);
+ break;
+ case SKINCOLOR_SUPERSILVER2:
+ blendcolor = V_GetColor(2);
+ break;
+ case SKINCOLOR_SUPERSILVER3:
+ blendcolor = V_GetColor(4);
+ break;
+ case SKINCOLOR_SUPERSILVER4:
+ blendcolor = V_GetColor(7);
+ break;
+ case SKINCOLOR_SUPERSILVER5:
+ blendcolor = V_GetColor(10);
+ break;
+
+ case SKINCOLOR_SUPERRED1: // Super red
+ blendcolor = V_GetColor(208);
+ break;
+ case SKINCOLOR_SUPERRED2:
+ blendcolor = V_GetColor(210);
+ break;
+ case SKINCOLOR_SUPERRED3:
+ blendcolor = V_GetColor(32);
+ break;
+ case SKINCOLOR_SUPERRED4:
+ blendcolor = V_GetColor(33);
+ break;
+ case SKINCOLOR_SUPERRED5:
+ blendcolor = V_GetColor(35);
+ break;
+
+ case SKINCOLOR_SUPERORANGE1: // Super orange
+ blendcolor = V_GetColor(208);
+ break;
+ case SKINCOLOR_SUPERORANGE2:
+ blendcolor = V_GetColor(48);
+ break;
+ case SKINCOLOR_SUPERORANGE3:
+ blendcolor = V_GetColor(50);
+ break;
+ case SKINCOLOR_SUPERORANGE4:
+ blendcolor = V_GetColor(54);
+ break;
+ case SKINCOLOR_SUPERORANGE5:
+ blendcolor = V_GetColor(58);
+ break;
+
+ case SKINCOLOR_SUPERGOLD1: // Super gold
blendcolor = V_GetColor(80);
break;
- case SKINCOLOR_SUPER2:
+ case SKINCOLOR_SUPERGOLD2:
blendcolor = V_GetColor(83);
break;
- case SKINCOLOR_SUPER3:
+ case SKINCOLOR_SUPERGOLD3:
blendcolor = V_GetColor(73);
break;
- case SKINCOLOR_SUPER4:
+ case SKINCOLOR_SUPERGOLD4:
blendcolor = V_GetColor(64);
break;
- case SKINCOLOR_SUPER5:
+ case SKINCOLOR_SUPERGOLD5:
blendcolor = V_GetColor(67);
break;
- case SKINCOLOR_TSUPER1:
- case SKINCOLOR_TSUPER2:
- case SKINCOLOR_TSUPER3:
- case SKINCOLOR_TSUPER4:
- case SKINCOLOR_TSUPER5:
- case SKINCOLOR_KSUPER1:
- case SKINCOLOR_KSUPER2:
- case SKINCOLOR_KSUPER3:
- case SKINCOLOR_KSUPER4:
- case SKINCOLOR_KSUPER5:
+ case SKINCOLOR_SUPERPERIDOT1: // Super peridot
+ blendcolor = V_GetColor(88);
+ break;
+ case SKINCOLOR_SUPERPERIDOT2:
+ blendcolor = V_GetColor(188);
+ break;
+ case SKINCOLOR_SUPERPERIDOT3:
+ blendcolor = V_GetColor(189);
+ break;
+ case SKINCOLOR_SUPERPERIDOT4:
+ blendcolor = V_GetColor(190);
+ break;
+ case SKINCOLOR_SUPERPERIDOT5:
+ blendcolor = V_GetColor(191);
+ break;
+
+ case SKINCOLOR_SUPERCYAN1: // Super cyan
+ blendcolor = V_GetColor(128);
+ break;
+ case SKINCOLOR_SUPERCYAN2:
+ blendcolor = V_GetColor(131);
+ break;
+ case SKINCOLOR_SUPERCYAN3:
+ blendcolor = V_GetColor(133);
+ break;
+ case SKINCOLOR_SUPERCYAN4:
+ blendcolor = V_GetColor(134);
+ break;
+ case SKINCOLOR_SUPERCYAN5:
+ blendcolor = V_GetColor(136);
+ break;
+
+ case SKINCOLOR_SUPERPURPLE1: // Super purple
+ blendcolor = V_GetColor(144);
+ break;
+ case SKINCOLOR_SUPERPURPLE2:
+ blendcolor = V_GetColor(162);
+ break;
+ case SKINCOLOR_SUPERPURPLE3:
+ blendcolor = V_GetColor(164);
+ break;
+ case SKINCOLOR_SUPERPURPLE4:
+ blendcolor = V_GetColor(166);
+ break;
+ case SKINCOLOR_SUPERPURPLE5:
+ blendcolor = V_GetColor(168);
+ break;
+
+ case SKINCOLOR_SUPERRUST1: // Super rust
+ blendcolor = V_GetColor(51);
+ break;
+ case SKINCOLOR_SUPERRUST2:
+ blendcolor = V_GetColor(54);
+ break;
+ case SKINCOLOR_SUPERRUST3:
+ blendcolor = V_GetColor(68);
+ break;
+ case SKINCOLOR_SUPERRUST4:
+ blendcolor = V_GetColor(70);
+ break;
+ case SKINCOLOR_SUPERRUST5:
+ blendcolor = V_GetColor(234);
+ break;
+
+ case SKINCOLOR_SUPERTAN1: // Super tan
+ blendcolor = V_GetColor(80);
+ break;
+ case SKINCOLOR_SUPERTAN2:
+ blendcolor = V_GetColor(82);
+ break;
+ case SKINCOLOR_SUPERTAN3:
+ blendcolor = V_GetColor(84);
+ break;
+ case SKINCOLOR_SUPERTAN4:
+ blendcolor = V_GetColor(87);
+ break;
+ case SKINCOLOR_SUPERTAN5:
+ blendcolor = V_GetColor(247);
+ break;
+
default:
blendcolor = V_GetColor(255);
break;
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 1a81fe796..54dd94854 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -1836,10 +1836,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
}
}
-// -----------------+
-// HWRAPI DrawMD2 : Draw an MD2 model with glcommands
-// -----------------+
-EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
+static inline void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
{
INT32 val, count, pindex;
GLfloat s, t;
@@ -1931,7 +1928,7 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
// Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?!
- if (color[3] < 255)
+ if (color && color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglDepthMask(GL_FALSE);
@@ -2007,11 +2004,20 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d
pglDisable(GL_CULL_FACE);
}
+// -----------------+
+// HWRAPI DrawMD2 : Draw an MD2 model with glcommands
+// -----------------+
+EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
+{
+ DrawMD2Ex(gl_cmd_buffer, frame, duration, tics, nextframe, pos, scale, flipped, color);
+}
+
EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale)
{
- DrawMD2i(gl_cmd_buffer, frame, 0, 0, NULL, pos, scale, false, NULL);
+ DrawMD2Ex(gl_cmd_buffer, frame, 0, 0, NULL, pos, scale, false, NULL);
}
+
// -----------------+
// SetTransform :
// -----------------+
diff --git a/src/hu_stuff.h b/src/hu_stuff.h
index f0dd40096..7b22f33f1 100644
--- a/src/hu_stuff.h
+++ b/src/hu_stuff.h
@@ -87,7 +87,7 @@ void HU_Init(void);
void HU_LoadGraphics(void);
// reset heads up when consoleplayer respawns.
-void HU_Start(void);
+FUNCMATH void HU_Start(void);
boolean HU_Responder(event_t *ev);
diff --git a/src/i_tcp.c b/src/i_tcp.c
index 89e59c8b8..f6212458b 100644
--- a/src/i_tcp.c
+++ b/src/i_tcp.c
@@ -56,7 +56,9 @@
//#define NONET
#endif
-#ifndef NONET
+#ifdef NONET
+#undef HAVE_MINIUPNPC
+#else
#ifdef USE_WINSOCK1
#include
#elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__)
@@ -466,7 +468,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
UINT32 bitmask = INADDR_NONE;
if (mask && mask < 32)
- bitmask = htonl(-1 << (32 - mask));
+ bitmask = htonl((UINT32)(-1) << (32 - mask));
if (b->any.sa_family == AF_INET)
return (a->ip4.sin_addr.s_addr & bitmask) == (b->ip4.sin_addr.s_addr & bitmask)
diff --git a/src/info.c b/src/info.c
index dc71ad163..884217611 100644
--- a/src/info.c
+++ b/src/info.c
@@ -25,35 +25,360 @@
#endif
// Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c!
+// For the sake of constant merge conflicts, let's spread this out
char sprnames[NUMSPRITES + 1][5] =
{
- "NULL","UNKN","THOK","PLAY","POSS","SPOS","FISH","BUZZ","RBUZ","JETB",
- "JETW","JETG","CCOM","DETN","SKIM","TRET","TURR","SHRP","JJAW","SNLR",
- "VLTR","PNTY","ARCH","CBFS","SPSH","ESHI","GSNP","MNUS","SSHL","UNID",
- "BBUZ","JETF","EGGM","EGGN","TNKA","TNKB","SPNK","GOOP","EGGO","PRPL",
- "FAKE","EGGP","EFIR","EGGQ","EGGR","BRAK","BGOO","BMSL","EGGT","RCKT",
- "ELEC","TARG","NPLM","MNPL","METL","MSCF","MSCB","RING","TRNG","EMMY",
- "TOKE","RFLG","BFLG","NWNG","EMBM","CEMG","EMER","FANS","BUBL","SIGN",
- "STEM","SPIK","SFLM","USPK","STPT","BMNE","SRBX","RRBX","BRBX","SHTV",
- "PINV","YLTV","BLTV","BKTV","WHTV","GRTV","ELTV","EGGB","MIXU","RECY",
- "QUES","GBTV","PRUP","PTTV","MTEX","MISL","TORP","ENRG","MINE","JBUL",
- "TRLS","CBLL","AROW","CFIR","FWR1","FWR2","FWR3","FWR4","BUS1","BUS2",
- "THZP","ALRM","GARG","SEWE","DRIP","CRL1","CRL2","CRL3","BCRY","CHAN",
- "FLAM","ESTA","SMCH","BMCH","SMCE","BMCE","BTBL","STBL","CACT","FLME",
- "DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6",
- "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN",
- "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC",
- "COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","RAIN","SNO1","SPLH",
- "SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL",
- "SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE",
- "RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE",
- "TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM",
- "KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL",
- "NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2",
- "BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH",
- "ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG",
- "GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI",
- "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO",
+ "NULL", // invisible object
+ "UNKN",
+
+ "THOK", // Thok! mobj
+ "PLAY",
+
+ // Enemies
+ "POSS",
+ "SPOS",
+ "FISH", // Greenflower Fish
+ "BUZZ", // Buzz (Gold)
+ "RBUZ", // Buzz (Red)
+ "JETB", // Jetty-Syn Bomber
+ "JETW", // Jetty-Syn Water Bomber
+ "JETG", // Jetty-Syn Gunner
+ "CCOM", // Crawla Commander
+ "DETN", // Deton
+ "SKIM", // Skim mine dropper
+ "TRET",
+ "TURR", // Pop-Up Turret
+ "SHRP", // Sharp
+ "JJAW", // Jet Jaw
+ "SNLR", // Snailer
+ "VLTR", // Vulture
+ "PNTY", // Pointy
+ "ARCH", // Robo-Hood
+ "CBFS", // CastleBot FaceStabber (Egg Knight?)
+ "SPSH", // Egg Guard
+ "ESHI", // Egg Shield for Egg Guard
+ "GSNP", // Green Snapper
+ "MNUS", // Minus
+ "SSHL", // Spring Shell
+ "UNID", // Unidus
+ "BBUZ", // AquaBuzz, for Azure Temple
+
+ // Generic Boss Items
+ "JETF", // Boss jet fumes
+
+ // Boss 1 (Greenflower)
+ "EGGM",
+
+ // Boss 2 (Techno Hill)
+ "EGGN", // Boss 2
+ "TNKA", // Boss 2 Tank 1
+ "TNKB", // Boss 2 Tank 2
+ "SPNK", // Boss 2 Spigot
+ "GOOP", // Boss 2 Goop
+
+ // Boss 3 (Deep Sea)
+ "EGGO", // Boss 3
+ "PRPL", // Boss 3 Propeller
+ "FAKE", // Boss 3 Fakemobile
+
+ // Boss 4 (Castle Eggman)
+ "EGGP",
+ "EFIR", // Boss 4 jet flame
+
+ // Boss 5 (Arid Canyon)
+ "EGGQ",
+
+ // Boss 6 (Red Volcano)
+ "EGGR",
+
+ // Boss 7 (Dark City)
+ "BRAK",
+ "BGOO", // Goop
+ "BMSL",
+
+ // Boss 8 (Egg Rock)
+ "EGGT",
+
+ // Cy-Brak-Demon; uses "BRAK" as well, but has some extras
+ "RCKT", // Rockets!
+ "ELEC", // Electricity!
+ "TARG", // Targeting reticules!
+ "NPLM", // Big napalm bombs!
+ "MNPL", // Mini napalm bombs!
+
+ // Metal Sonic
+ "METL",
+ "MSCF",
+ "MSCB",
+
+ // Collectible Items
+ "RING",
+ "TRNG", // Team Rings
+ "EMMY", // emerald test
+ "TOKE", // Special Stage Token
+ "RFLG", // Red CTF Flag
+ "BFLG", // Blue CTF Flag
+ "NWNG", // NiGHTS Wing collectable item.
+ "EMBM", // Emblem
+ "CEMG", // Chaos Emeralds
+ "EMER", // Emerald Hunt
+
+ // Interactive Objects
+ "FANS",
+ "BBLS", // water bubble source
+ "SIGN", // Level end sign
+ "STEM", // Steam riser
+ "SPIK", // Spike Ball
+ "SFLM", // Spin fire
+ "USPK", // Floor spike
+ "STPT", // Starpost
+ "BMNE", // Big floating mine
+
+ // Monitor Boxes
+ "MSTV", // MiSc TV sprites
+ "XLTV", // eXtra Large TV sprites
+
+ "TRRI", // Red team: 10 RIngs
+ "TBRI", // Blue team: 10 RIngs
+
+ "TVRI", // 10 RIng
+ "TVPI", // PIty shield
+ "TVAT", // ATtraction shield
+ "TVFO", // FOrce shield
+ "TVAR", // ARmageddon shield
+ "TVWW", // WhirlWind shield
+ "TVEL", // ELemental shield
+ "TVSS", // Super Sneakers
+ "TVIV", // InVincibility
+ "TV1U", // 1Up
+ "TV1P", // 1uP (textless)
+ "TVEG", // EGgman
+ "TVMX", // MiXup
+ "TVMY", // MYstery
+ "TVGV", // GraVity boots
+ "TVRC", // ReCycler
+ "TV1K", // 1,000 points (1 K)
+ "TVTK", // 10,000 points (Ten K)
+
+ // Projectiles
+ "MISL",
+ "TORP", // Torpedo
+ "ENRG", // Energy ball
+ "MINE", // Skim mine
+ "JBUL", // Jetty-Syn Bullet
+ "TRLS",
+ "CBLL", // Cannonball
+ "AROW", // Arrow
+ "CFIR", // Colored fire of various sorts
+
+ // Greenflower Scenery
+ "FWR1",
+ "FWR2", // GFZ Sunflower
+ "FWR3", // GFZ budding flower
+ "FWR4",
+ "BUS1", // GFZ Bush w/ berries
+ "BUS2", // GFZ Bush w/o berries
+
+ // Techno Hill Scenery
+ "THZP", // Techno Hill Zone Plant
+ "ALRM", // THZ2 Alarm
+
+ // Deep Sea Scenery
+ "GARG", // Deep Sea Gargoyle
+ "SEWE", // Deep Sea Seaweed
+ "DRIP", // Dripping water
+ "CRL1", // Coral 1
+ "CRL2", // Coral 2
+ "CRL3", // Coral 3
+ "BCRY", // Blue Crystal
+
+ // Castle Eggman Scenery
+ "CHAN", // CEZ Chain
+ "FLAM", // Flame
+ "ESTA", // Eggman esta una estatua!
+ "SMCH", // Small Mace Chain
+ "BMCH", // Big Mace Chain
+ "SMCE", // Small Mace
+ "BMCE", // Big Mace
+
+ // Arid Canyon Scenery
+ "BTBL", // Big tumbleweed
+ "STBL", // Small tumbleweed
+ "CACT", // Cacti sprites
+
+ // Red Volcano Scenery
+ "FLME", // Flame jet
+ "DFLM", // Blade's flame
+
+ // Dark City Scenery
+
+ // Egg Rock Scenery
+
+ // Christmas Scenery
+ "XMS1",
+ "XMS2",
+ "XMS3",
+
+ // Botanic Serenity Scenery
+ "BSZ1", // Tall flowers
+ "BSZ2", // Medium flowers
+ "BSZ3", // Small flowers
+ "BSZ4", // Tulip
+ "BSZ5", // Cluster of Tulips
+ "BSZ6", // Bush
+ "BSZ7", // Vine
+ "BSZ8", // Misc things
+
+ // Misc Scenery
+ "STLG", // Stalagmites
+ "DBAL", // Disco
+ "RCRY", // ATZ Red Crystal (Target)
+
+ // Powerup Indicators
+ "ARMA", // Armageddon Shield Orb
+ "ARMF", // Armageddon Shield Ring, Front
+ "ARMB", // Armageddon Shield Ring, Back
+ "WIND", // Whirlwind Shield Orb
+ "MAGN", // Attract Shield Orb
+ "ELEM", // Elemental Shield Orb and Fire
+ "FORC", // Force Shield Orb
+ "PITY", // Pity Shield Orb
+ "IVSP", // invincibility sparkles
+ "SSPK", // Super Sonic Spark
+
+ "GOAL", // Special Stage goal (here because lol NiGHTS)
+
+ // Freed Animals
+ "BIRD", // Birdie freed!
+ "BUNY", // Bunny freed!
+ "MOUS", // Mouse
+ "CHIC", // Chicken
+ "COWZ", // Cow
+ "RBRD", // Red Birdie in Bubble
+
+ // Springs
+ "SPRY", // yellow spring
+ "SPRR", // red spring
+ "SPRB", // Blue springs
+ "YSPR", // Yellow Diagonal Spring
+ "RSPR", // Red Diagonal Spring
+ "SSWY", // Yellow Side Spring
+ "SSWR", // Red Side Spring
+ "SSWB", // Blue Side Spring
+
+ // Environmental Effects
+ "RAIN", // Rain
+ "SNO1", // Snowflake
+ "SPLH", // Water Splish
+ "SPLA", // Water Splash
+ "SMOK",
+ "BUBL", // Bubble
+ "WZAP",
+ "TFOG", // Teleport Fog
+ "SEED", // Sonic CD flower seed
+ "PRTL", // Particle (for fans, etc.)
+
+ // Game Indicators
+ "SCOR", // Score logo
+ "DRWN", // Drowning Timer
+ "TTAG", // Tag Sign
+ "GFLG", // Got Flag sign
+
+ // Ring Weapons
+ "RRNG", // Red Ring
+ "RNGB", // Bounce Ring
+ "RNGR", // Rail Ring
+ "RNGI", // Infinity Ring
+ "RNGA", // Automatic Ring
+ "RNGE", // Explosion Ring
+ "RNGS", // Scatter Ring
+ "RNGG", // Grenade Ring
+
+ "PIKB", // Bounce Ring Pickup
+ "PIKR", // Rail Ring Pickup
+ "PIKA", // Automatic Ring Pickup
+ "PIKE", // Explosion Ring Pickup
+ "PIKS", // Scatter Ring Pickup
+ "PIKG", // Grenade Ring Pickup
+
+ "TAUT", // Thrown Automatic Ring
+ "TGRE", // Thrown Grenade Ring
+ "TSCR", // Thrown Scatter Ring
+
+ // Mario-specific stuff
+ "COIN",
+ "CPRK",
+ "GOOM",
+ "BGOM",
+ "FFWR",
+ "FBLL",
+ "SHLL",
+ "PUMA",
+ "HAMM",
+ "KOOP",
+ "BFLM",
+ "MAXE",
+ "MUS1",
+ "MUS2",
+ "TOAD",
+
+ // NiGHTS Stuff
+ "NDRN", // NiGHTS drone
+ "NSPK", // NiGHTS sparkle
+ "NBMP", // NiGHTS Bumper
+ "HOOP", // NiGHTS hoop sprite
+ "NSCR", // NiGHTS score sprite
+ "NPRU", // Nights Powerups
+ "CAPS", // Capsule thingy for NiGHTS
+
+ // Debris
+ "SPRK", // spark
+ "BOM1", // Robot Explosion
+ "BOM2", // Boss Explosion 1
+ "BOM3", // Boss Explosion 2
+ "BOM4", // Underwater Explosion
+
+ // Crumbly rocks
+ "ROIA",
+ "ROIB",
+ "ROIC",
+ "ROID",
+ "ROIE",
+ "ROIF",
+ "ROIG",
+ "ROIH",
+ "ROII",
+ "ROIJ",
+ "ROIK",
+ "ROIL",
+ "ROIM",
+ "ROIN",
+ "ROIO",
+ "ROIP",
+
+ // Blue Spheres
+ "BBAL",
+
+ // Gravity Well Objects
+ "GWLG",
+ "GWLR",
+
+ // SRB1 Sprites
+ "SRBA",
+ "SRBB",
+ "SRBC",
+ "SRBD",
+ "SRBE",
+ "SRBF",
+ "SRBG",
+ "SRBH",
+ "SRBI",
+ "SRBJ",
+ "SRBK",
+ "SRBL",
+ "SRBM",
+ "SRBN",
+ "SRBO",
};
char spr2names[NUMPLAYERSPRITES][5] =
@@ -62,6 +387,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
"WAIT",
"WALK",
"RUN_",
+ "PEEL",
"PAIN",
"DEAD",
"DRWN",
@@ -78,18 +404,24 @@ char spr2names[NUMPLAYERSPRITES][5] =
"LIFE",
"FLY_",
+ "SWIM",
"TIRE",
"GLID",
"CLNG",
"CLMB",
+ "TWIN",
+
+ "MLEE",
+
"TRNS",
"SSTD",
"SWLK",
"SRUN",
+ "SPEE",
"SPAN",
- "SMSL",
+ "SSTN",
"SDTH",
"SDRN",
"SSPN",
@@ -99,8 +431,44 @@ char spr2names[NUMPLAYERSPRITES][5] =
"SFAL",
"SEDG",
"SRID",
- "SFLT"
+ "SFLT",
+
+ "NTRN",
+ "NSTD",
+ "NFLT",
+ "NPAN",
+ "NPUL",
+ "NATK",
+
+ "NGT0",
+ "NGT1",
+ "NGT2",
+ "NGT3",
+ "NGT4",
+ "NGT5",
+ "NGT6",
+ "NGT7",
+ "NGT8",
+ "NGT9",
+ "NGTA",
+ "NGTB",
+ "NGTC",
+
+ "DRL0",
+ "DRL1",
+ "DRL2",
+ "DRL3",
+ "DRL4",
+ "DRL5",
+ "DRL6",
+ "DRL7",
+ "DRL8",
+ "DRL9",
+ "DRLA",
+ "DRLB",
+ "DRLC"
};
+enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
state_t states[NUMSTATES] =
@@ -132,6 +500,7 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT
{SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
{SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
+ {SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL
{SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN
{SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD
{SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN
@@ -144,21 +513,30 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE
{SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE
- // Tails abilities
+ // CA_FLY/CA_SWIM
{SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
+ {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
{SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED
- // Knuckles abilities
+ // CA_GLIDEANDCLIMB
{SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
{SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
- // Super Sonic
+ // CA_TWINSPIN
+ {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN
+
+ // CA2_MELEE
+ {SPR_PLAY, SPR2_MLEE|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_MELEE_FINISH, 0, S_PLAY_MELEE}, // S_PLAY_MELEE
+ {SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH
+
+ // SF_SUPERANIMS
{SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND
{SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
{SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN
+ {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL
{SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN
- {SPR_PLAY, SPR2_SMSL, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN
+ {SPR_PLAY, SPR2_SSTN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN
{SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD
{SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN
{SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
@@ -170,16 +548,16 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE
{SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT
- // Transforming into Super
+ // SF_SUPER
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
- {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
- {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
- {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
- {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
- {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
- {SPR_PLAY, SPR2_TRNS, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
@@ -188,11 +566,57 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2
{SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1
{SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2
- {SPR_PLAY, SPR2_LIFE, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
+ {SPR_PLAY, SPR2_LIFE, 20, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
// Level end sign (uses player sprite)
{SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
+ // NiGHTS Player, transforming
+ {SPR_PLAY, SPR2_NTRN, 4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS
+ {SPR_PLAY, SPR2_NTRN, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2
+ {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3
+ {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4
+ {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5
+ {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6
+ {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7
+ {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8
+ {SPR_PLAY, SPR2_NTRN, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9
+
+ // NiGHTS Player, Stand, Floating, Pain, Pull and Attack
+ {SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND
+ {SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT
+ {SPR_PLAY, SPR2_NPAN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_PAIN}, // S_PLAY_NIGHTS_PAIN
+ {SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL
+ {SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK
+
+ // NiGHTS Player, Flying and Drilling
+ {SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0
+ {SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0
+ {SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1
+ {SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1
+ {SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2
+ {SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2
+ {SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3
+ {SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3
+ {SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4
+ {SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4
+ {SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5
+ {SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5
+ {SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6
+ {SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6
+ {SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7
+ {SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7
+ {SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8
+ {SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8
+ {SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9
+ {SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9
+ {SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA
+ {SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA
+ {SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB
+ {SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB
+ {SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC
+ {SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC
+
// Blue Crawla
{SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND
{SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1
@@ -1045,8 +1469,10 @@ state_t states[NUMSTATES] =
{SPR_FANS, 4, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN}, // S_FAN5
// Bubble Source
- {SPR_BUBL, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1
- {SPR_BUBL, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES2
+ {SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1
+ {SPR_BBLS, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES3}, // S_BUBBLES2
+ {SPR_BBLS, 2, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES4}, // S_BUBBLES3
+ {SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4
// Level End Sign
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1
@@ -1161,172 +1587,116 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 1, {A_LobShot}, MT_CANNONBALL, 4*TICRATE, S_CANNONLAUNCHER3}, // S_CANNONLAUNCHER2
{SPR_NULL, 0, 2, {A_SetRandomTics}, TICRATE/2, 3*TICRATE, S_CANNONLAUNCHER1}, // S_CANNONLAUNCHER3
- // Super Ring Box
- {SPR_SRBX, 0, 2, {NULL}, 0, 0, S_SUPERRINGBOX1}, // S_SUPERRINGBOX
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SUPERRINGBOX}, // S_SUPERRINGBOX1
- {SPR_SRBX, 1, 4, {A_MonitorPop}, 0, 0, S_SUPERRINGBOX3}, // S_SUPERRINGBOX2
- {SPR_YLTV, 2, 4, {NULL}, 0, 0, S_SUPERRINGBOX4}, // S_SUPERRINGBOX3
- {SPR_YLTV, 3, 4, {NULL}, 0, 0, S_SUPERRINGBOX5}, // S_SUPERRINGBOX4
- {SPR_YLTV, 4, 4, {NULL}, 0, 0, S_SUPERRINGBOX6}, // S_SUPERRINGBOX5
- {SPR_SRBX, 1, 18, {A_RingBox}, 0, 0, S_NULL}, // S_SUPERRINGBOX6
+ // Monitor Miscellany
+ {SPR_NSPK, FF_TRANS40, 20, {NULL}, 0, 0, S_BOXSPARKLE2}, // S_BOXSPARKLE1
+ {SPR_NSPK, FF_TRANS60, 10, {NULL}, 0, 0, S_BOXSPARKLE3}, // S_BOXSPARKLE2
+ {SPR_NSPK, FF_TRANS80, 5, {NULL}, 0, 0, S_NULL}, // S_BOXSPARKLE3
- // Red Team Ring Box
- {SPR_RRBX, 0, 2, {NULL}, 0, 0, S_REDRINGBOX1}, // S_REDRINGBOX
- {SPR_RRBX, 1, 1, {NULL}, 0, 0, S_REDRINGBOX}, // S_REDRINGBOX1
+ {SPR_MSTV, 0, 1, {NULL}, 0, 0, S_SPAWNSTATE}, // S_BOX_FLICKER
+ {SPR_MSTV, 0, 4, {A_MonitorPop}, 0, 0, S_BOX_POP2}, // S_BOX_POP1
+ {SPR_MSTV, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BOX_POP2
- // Blue Team Ring Box
- {SPR_BRBX, 0, 2, {NULL}, 0, 0, S_BLUERINGBOX1}, // S_BLUERINGBOX
- {SPR_BRBX, 1, 1, {NULL}, 0, 0, S_BLUERINGBOX}, // S_BLUERINGBOX1
+ {SPR_XLTV, 0, 1, {NULL}, 0, 0, S_SPAWNSTATE}, // S_GOLDBOX_FLICKER
+ {SPR_XLTV, 1, 89, {A_GoldMonitorPop}, 0, 0, S_GOLDBOX_OFF2}, // S_GOLDBOX_OFF1
+ {SPR_XLTV, 2, 4, {A_PlayAttackSound}, 0, 0, S_GOLDBOX_OFF3}, // S_GOLDBOX_OFF2
+ {SPR_XLTV, 3, 4, {NULL}, 0, 0, S_GOLDBOX_OFF4}, // S_GOLDBOX_OFF3
+ {SPR_XLTV, 4, 4, {NULL}, 0, 0, S_GOLDBOX_OFF5}, // S_GOLDBOX_OFF4
+ {SPR_XLTV, 5, 2, {NULL}, 0, 0, S_GOLDBOX_OFF6}, // S_GOLDBOX_OFF5
+ {SPR_XLTV, 6, 2, {NULL}, 0, 0, S_GOLDBOX_OFF7}, // S_GOLDBOX_OFF6
+ {SPR_XLTV, 6, 0, {A_GoldMonitorRestore}, 0, 0, S_SPAWNSTATE}, // S_GOLDBOX_OFF7
- // Super Sneakers Box
- {SPR_SHTV, 0, 2, {NULL}, 0, 0, S_SHTV1}, // S_SHTV
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SHTV}, // S_SHTV1
- {SPR_SHTV, 1, 4, {A_MonitorPop}, 0, 0, S_SHTV3}, // S_SHTV2
- {SPR_YLTV, 2, 4, {NULL}, 0, 0, S_SHTV4}, // S_SHTV3
- {SPR_YLTV, 3, 4, {NULL}, 0, 0, S_SHTV5}, // S_SHTV4
- {SPR_YLTV, 4, 4, {NULL}, 0, 0, S_SHTV6}, // S_SHTV5
- {SPR_SHTV, 1, 18, {A_SuperSneakers}, 0, 0, S_NULL}, // S_SHTV6
+ // Monitor States (one per box)
+ {SPR_TVMY, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_MYSTERY_BOX
+ {SPR_TVRI, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_RING_BOX
+ {SPR_TVPI, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_PITY_BOX
+ {SPR_TVAT, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_ATTRACT_BOX
+ {SPR_TVFO, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_FORCE_BOX
+ {SPR_TVAR, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_ARMAGEDDON_BOX
+ {SPR_TVWW, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_WHIRLWIND_BOX
+ {SPR_TVEL, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_ELEMENTAL_BOX
+ {SPR_TVSS, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_SNEAKERS_BOX
+ {SPR_TVIV, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_INVULN_BOX
+ {SPR_TV1U, 0, 2, {A_1upThinker}, 0, 0, S_BOX_FLICKER}, // S_1UP_BOX
+ {SPR_TVEG, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_EGGMAN_BOX
+ {SPR_TVMX, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_MIXUP_BOX
+ {SPR_TVGV, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_GRAVITY_BOX
+ {SPR_TVRC, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_RECYCLER_BOX
+ {SPR_TV1K, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_SCORE1K_BOX
+ {SPR_TVTK, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_SCORE10K_BOX
- // Invincibility Box
- {SPR_PINV, 0, 2, {NULL}, 0, 0, S_PINV1}, // S_PINV
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_PINV}, // S_PINV1
- {SPR_PINV, 1, 4, {A_MonitorPop}, 0, 0, S_PINV3}, // S_PINV2
- {SPR_PINV, 2, 4, {NULL}, 0, 0, S_PINV4}, // S_PINV3
- {SPR_PINV, 3, 4, {NULL}, 0, 0, S_PINV5}, // S_PINV4
- {SPR_PINV, 4, 4, {NULL}, 0, 0, S_PINV6}, // S_PINV5
- {SPR_PINV, 1, 18, {A_Invincibility}, 0, 0, S_NULL}, // S_PINV6
+ // Gold Repeat Monitor States (one per box)
+ {SPR_TVPI, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_PITY_GOLDBOX
+ {SPR_TVAT, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_ATTRACT_GOLDBOX
+ {SPR_TVFO, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_FORCE_GOLDBOX
+ {SPR_TVAR, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_ARMAGEDDON_GOLDBOX
+ {SPR_TVWW, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_WHIRLWIND_GOLDBOX
+ {SPR_TVEL, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_ELEMENTAL_GOLDBOX
+ {SPR_TVSS, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_SNEAKERS_GOLDBOX
+ {SPR_TVIV, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_INVULN_GOLDBOX
+ {SPR_TVEG, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_EGGMAN_GOLDBOX
+ {SPR_TVGV, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_GRAVITY_GOLDBOX
- // 1up Box
- {SPR_PRUP, 2, 2, {A_1upThinker}, 0, 0, S_PRUP1}, // S_PRUP
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_PRUP}, // S_PRUP1
- {SPR_PRUP, 3, 4, {A_MonitorPop}, 0, 0, S_PRUP3}, // S_PRUP2
- {SPR_PINV, 2, 4, {NULL}, 0, 0, S_PRUP4}, // S_PRUP3
- {SPR_PINV, 3, 4, {NULL}, 0, 0, S_PRUP5}, // S_PRUP4
- {SPR_PINV, 4, 4, {NULL}, 0, 0, S_PRUP6}, // S_PRUP5
- {SPR_PRUP, 3, 18, {A_ExtraLife}, 0, 0, S_NULL}, // S_PRUP6
+ // Team Ring Boxes (these are special)
+ {SPR_TRRI, 0, 2, {NULL}, 0, 0, S_RING_REDBOX2}, // S_RING_REDBOX1
+ {SPR_TRRI, 1, 1, {NULL}, 0, 0, S_RING_REDBOX1}, // S_RING_REDBOX2
+ {SPR_TRRI, 1, 4, {A_MonitorPop}, 0, 0, S_REDBOX_POP2}, // S_REDBOX_POP1
+ {SPR_TRRI, 2, -1, {NULL}, 0, 0, S_NULL}, // S_REDBOX_POP2
- // Ring Shield Box
- {SPR_YLTV, 0, 2, {NULL}, 0, 0, S_YLTV1}, // S_YLTV
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_YLTV}, // S_YLTV1
- {SPR_YLTV, 1, 4, {A_MonitorPop}, 0, 0, S_YLTV3}, // S_YLTV2
- {SPR_YLTV, 2, 4, {NULL}, 0, 0, S_YLTV4}, // S_YLTV3
- {SPR_YLTV, 3, 4, {NULL}, 0, 0, S_YLTV5}, // S_YLTV4
- {SPR_YLTV, 4, 4, {NULL}, 0, 0, S_YLTV6}, // S_YLTV5
- {SPR_YLTV, 1, 18, {A_RingShield},0, 0, S_NULL}, // S_YLTV6
+ {SPR_TBRI, 0, 2, {NULL}, 0, 0, S_RING_BLUEBOX2}, // S_RING_BLUEBOX1
+ {SPR_TBRI, 1, 1, {NULL}, 0, 0, S_RING_BLUEBOX1}, // S_RING_BLUEBOX2
+ {SPR_TBRI, 1, 4, {A_MonitorPop}, 0, 0, S_BLUEBOX_POP2}, // S_BLUEBOX_POP1
+ {SPR_TBRI, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBOX_POP2
- // Force Shield Box
- {SPR_BLTV, 0, 2, {NULL}, 0, 0, S_BLTV2}, // S_BLTV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_BLTV1}, // S_BLTV2
- {SPR_BLTV, 1, 4, {A_MonitorPop}, 0, 0, S_BLTV4}, // S_BLTV3
- {SPR_BLTV, 2, 4, {NULL}, 0, 0, S_BLTV5}, // S_BLTV4
- {SPR_BLTV, 3, 4, {NULL}, 0, 0, S_BLTV6}, // S_BLTV5
- {SPR_BLTV, 4, 4, {NULL}, 0, 0, S_BLTV7}, // S_BLTV6
- {SPR_BLTV, 1, 18, {A_ForceShield}, 0, 0, S_NULL}, // S_BLTV7
+ // 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
- // Bomb Shield Box
- {SPR_BKTV, 0, 2, {NULL}, 0, 0, S_BKTV2}, // S_BKTV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_BKTV1}, // S_BKTV2
- {SPR_BKTV, 1, 4, {A_MonitorPop}, 0, 0, S_BKTV4}, // S_BKTV3
- {SPR_BKTV, 2, 4, {NULL}, 0, 0, S_BKTV5}, // S_BKTV4
- {SPR_BKTV, 3, 4, {NULL}, 0, 0, S_BKTV6}, // S_BKTV5
- {SPR_BKTV, 4, 4, {NULL}, 0, 0, S_BKTV7}, // S_BKTV6
- {SPR_BKTV, 1, 18, {A_BombShield}, 0, 0, S_NULL}, // S_BKTV7
+ {SPR_TVPI, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_PITY_ICON2}, // S_PITY_ICON1
+ {SPR_TVPI, 2, 18, {A_PityShield}, 0, 0, S_NULL}, // S_PITY_ICON2
- // Jump Shield Box
- {SPR_WHTV, 0, 2, {NULL}, 0, 0, S_WHTV2}, // S_WHTV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_WHTV1}, // S_WHTV2
- {SPR_WHTV, 1, 4, {A_MonitorPop}, 0, 0, S_WHTV4}, // S_WHTV3
- {SPR_WHTV, 2, 4, {NULL}, 0, 0, S_WHTV5}, // S_WHTV4
- {SPR_WHTV, 3, 4, {NULL}, 0, 0, S_WHTV6}, // S_WHTV5
- {SPR_WHTV, 4, 4, {NULL}, 0, 0, S_WHTV7}, // S_WHTV6
- {SPR_WHTV, 1, 18, {A_JumpShield}, 0, 0, S_NULL}, // S_WHTV7
+ {SPR_TVAT, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ATTRACT_ICON2}, // S_ATTRACT_ICON1
+ {SPR_TVAT, 2, 18, {A_RingShield},0, 0, S_NULL}, // S_ATTRACT_ICON2
- // Elemental Shield Box
- {SPR_ELTV, 0, 2, {NULL}, 0, 0, S_GRTV1}, // S_GRTV
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_GRTV}, // S_GRTV1
- {SPR_ELTV, 1, 4, {A_MonitorPop}, 0, 0, S_GRTV3}, // S_GRTV2
- {SPR_ELTV, 2, 4, {NULL}, 0, 0, S_GRTV4}, // S_GRTV3
- {SPR_ELTV, 3, 4, {NULL}, 0, 0, S_GRTV5}, // S_GRTV4
- {SPR_ELTV, 4, 4, {NULL}, 0, 0, S_GRTV6}, // S_GRTV5
- {SPR_ELTV, 1, 18, {A_WaterShield}, 0, 0, S_NULL}, // S_GRTV6
+ {SPR_TVFO, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FORCE_ICON2}, // S_FORCE_ICON1
+ {SPR_TVFO, 2, 18, {A_ForceShield}, 0, 0, S_NULL}, // S_FORCE_ICON2
- // Pity Shield Box
- {SPR_GRTV, 0, 2, {NULL}, 0, 0, S_PITV2}, // S_PITV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_PITV1}, // S_PITV2
- {SPR_GRTV, 1, 4, {A_MonitorPop}, 0, 0, S_PITV4}, // S_PITV3
- {SPR_GRTV, 2, 4, {NULL}, 0, 0, S_PITV5}, // S_PITV4
- {SPR_GRTV, 3, 4, {NULL}, 0, 0, S_PITV6}, // S_PITV5
- {SPR_GRTV, 4, 4, {NULL}, 0, 0, S_PITV7}, // S_PITV6
- {SPR_GRTV, 1, 18, {A_PityShield}, 0, 0, S_NULL}, // S_PITV7
+ {SPR_TVAR, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ARMAGEDDON_ICON2}, // S_ARMAGEDDON_ICON1
+ {SPR_TVAR, 2, 18, {A_BombShield}, 0, 0, S_NULL}, // S_ARMAGEDDON_ICON2
- // Eggman Box
- {SPR_EGGB, 0, 2, {NULL}, 0, 0, S_EGGTV2}, // S_EGGTV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_EGGTV1}, // S_EGGTV2
- {SPR_EGGB, 1, 4, {A_MonitorPop}, 0, 0, S_EGGTV4}, // S_EGGTV3
- {SPR_BKTV, 2, 4, {NULL}, 0, 0, S_EGGTV5}, // S_EGGTV4
- {SPR_BKTV, 3, 4, {NULL}, 0, 0, S_EGGTV6}, // S_EGGTV5
- {SPR_BKTV, 4, 4, {NULL}, 0, 0, S_EGGTV7}, // S_EGGTV6
- {SPR_EGGB, 1, 18, {A_EggmanBox}, 0, 0, S_NULL}, // S_EGGTV7
+ {SPR_TVWW, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_WHIRLWIND_ICON2}, // S_WHIRLWIND_ICON1
+ {SPR_TVWW, 2, 18, {A_JumpShield}, 0, 0, S_NULL}, // S_WHIRLWIND_ICON2
- // Teleport Box
- {SPR_MIXU, 0, 2, {NULL}, 0, 0, S_MIXUPBOX2}, // S_MIXUPBOX1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_MIXUPBOX1}, // S_MIXUPBOX2
- {SPR_MIXU, 1, 4, {A_MonitorPop}, 0, 0, S_MIXUPBOX4}, // S_MIXUPBOX3
- {SPR_WHTV, 2, 4, {NULL}, 0, 0, S_MIXUPBOX5}, // S_MIXUPBOX4
- {SPR_WHTV, 3, 4, {NULL}, 0, 0, S_MIXUPBOX6}, // S_MIXUPBOX5
- {SPR_WHTV, 4, 4, {NULL}, 0, 0, S_MIXUPBOX7}, // S_MIXUPBOX6
- {SPR_MIXU, 1, 18, {A_MixUp}, 0, 0, S_NULL}, // S_MIXUPBOX7
+ {SPR_TVEL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ELEMENTAL_ICON2}, // S_ELEMENTAL_ICON1
+ {SPR_TVEL, 2, 18, {A_WaterShield}, 0, 0, S_NULL}, // S_ELEMENTAL_ICON2
- // Recycler Box
- {SPR_RECY, 0, 2, {NULL}, 0, 0, S_RECYCLETV2}, // S_RECYCLETV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_RECYCLETV1}, // S_RECYCLETV2
- {SPR_RECY, 1, 4, {A_MonitorPop}, 0, 0, S_RECYCLETV4}, // S_RECYCLETV3
- {SPR_GRTV, 2, 4, {NULL}, 0, 0, S_RECYCLETV5}, // S_RECYCLETV4
- {SPR_GRTV, 3, 4, {NULL}, 0, 0, S_RECYCLETV6}, // S_RECYCLETV5
- {SPR_GRTV, 4, 4, {NULL}, 0, 0, S_RECYCLETV7}, // S_RECYCLETV6
- {SPR_RECY, 1, 18, {A_RecyclePowers}, 0, 0, S_NULL}, // S_RECYCLETV7
+ {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
- // Question Box
- {SPR_QUES, 0, 2, {NULL}, 0, 0, S_RANDOMBOX2}, // S_RANDOMBOX1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_RANDOMBOX1}, // S_RANDOMBOX2
- {SPR_QUES, 0, 1, {A_MonitorPop}, 0, 0, S_NULL}, // S_RANDOMBOX3
+ {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
- // Gravity Boots Box
- {SPR_GBTV, 0, 2, {NULL}, 0, 0, S_GBTV2}, // S_GBTV1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_GBTV1}, // S_GBTV2
- {SPR_GBTV, 1, 4, {A_MonitorPop}, 0, 0, S_GBTV4}, // S_GBTV3
- {SPR_BLTV, 2, 4, {NULL}, 0, 0, S_GBTV5}, // S_GBTV4
- {SPR_BLTV, 3, 4, {NULL}, 0, 0, S_GBTV6}, // S_GBTV5
- {SPR_BLTV, 4, 4, {NULL}, 0, 0, S_GBTV7}, // S_GBTV6
- {SPR_GBTV, 1, 18, {A_GravityBox}, 0, 0, S_NULL}, // S_GBTV7
+ {SPR_TV1U, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_1UP_ICON2}, // S_1UP_ICON1
+ {SPR_TV1U, 2, 18, {A_ExtraLife}, 0, 0, S_NULL}, // S_1UP_ICON2
- // Score Box (1k)
- {SPR_PTTV, 0, 2, {NULL}, 0, 0, S_SCORETVA2}, // S_SCORETVA1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SCORETVA1}, // S_SCORETVA2
- {SPR_PTTV, 1, 4, {A_MonitorPop}, 0, 0, S_SCORETVA4}, // S_SCORETVA3
- {SPR_PTTV, 2, 4, {NULL}, 0, 0, S_SCORETVA5}, // S_SCORETVA4
- {SPR_PTTV, 3, 4, {NULL}, 0, 0, S_SCORETVA6}, // S_SCORETVA5
- {SPR_PTTV, 4, 4, {NULL}, 0, 0, S_SCORETVA7}, // S_SCORETVA6
- {SPR_PTTV, 1, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORETVA7
+ {SPR_TVEG, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_EGGMAN_ICON2}, // S_EGGMAN_ICON1
+ {SPR_TVEG, 2, 18, {A_EggmanBox}, 0, 0, S_NULL}, // S_EGGMAN_ICON2
- // Score Box (10k)
- {SPR_PTTV, 5, 2, {NULL}, 0, 0, S_SCORETVB2}, // S_SCORETVB1
- {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SCORETVB1}, // S_SCORETVB2
- {SPR_PTTV, 6, 4, {A_MonitorPop}, 0, 0, S_SCORETVB4}, // S_SCORETVB3
- {SPR_PTTV, 7, 4, {NULL}, 0, 0, S_SCORETVB5}, // S_SCORETVB4
- {SPR_PTTV, 8, 4, {NULL}, 0, 0, S_SCORETVB6}, // S_SCORETVB5
- {SPR_PTTV, 9, 4, {NULL}, 0, 0, S_SCORETVB7}, // S_SCORETVB6
- {SPR_PTTV, 6, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORETVB7
+ {SPR_TVMX, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_MIXUP_ICON2}, // S_MIXUP_ICON1
+ {SPR_TVMX, 2, 18, {A_MixUp}, 0, 0, S_NULL}, // S_MIXUP_ICON2
- // Monitor Explosion
- {SPR_MTEX, 0, 4, {NULL}, 0, 0, S_MONITOREXPLOSION2}, // S_MONITOREXPLOSION1
- {SPR_MTEX, 1, -1, {NULL}, 0, 0, S_NULL}, // S_MONITOREXPLOSION2
+ {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_RRBX, 1, 4, {NULL}, 0, 0, S_REDMONITOREXPLOSION2}, // S_REDMONITOREXPLOSION1
- {SPR_RRBX, 2, -1, {NULL}, 0, 0, S_NULL}, // S_REDMONITOREXPLOSION2
+ {SPR_TVRC, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_RECYCLER_ICON2}, // S_RECYCLER_ICON1
+ {SPR_TVRC, 2, 18, {A_RecyclePowers}, 0, 0, S_NULL}, // S_RECYCLER_ICON2
- {SPR_BRBX, 1, 4, {NULL}, 0, 0, S_BLUEMONITOREXPLOSION2}, // S_BLUEMONITOREXPLOSION1
- {SPR_BRBX, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEMONITOREXPLOSION2
+ {SPR_TV1K, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SCORE1K_ICON2}, // S_SCORE1K_ICON1
+ {SPR_TV1K, 2, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORE1K_ICON2
+
+ {SPR_TVTK, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SCORE10K_ICON2}, // S_SCORE10K_ICON1
+ {SPR_TVTK, 2, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORE10K_ICON2
+
+ // ---
{SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET
@@ -1850,6 +2220,36 @@ state_t states[NUMSTATES] =
{SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG8}, // S_RDIAG7
{SPR_RSPR, 1, 1, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG8
+ // Yellow Side Spring
+ {SPR_SSWY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YHORIZ1
+ {SPR_SSWY, 1, 1, {A_Pain}, 0, 0, S_YHORIZ3}, // S_YHORIZ2
+ {SPR_SSWY, 2, 1, {NULL}, 0, 0, S_YHORIZ4}, // S_YHORIZ3
+ {SPR_SSWY, 3, 1, {NULL}, 0, 0, S_YHORIZ5}, // S_YHORIZ4
+ {SPR_SSWY, 4, 1, {NULL}, 0, 0, S_YHORIZ6}, // S_YHORIZ5
+ {SPR_SSWY, 3, 1, {NULL}, 0, 0, S_YHORIZ7}, // S_YHORIZ6
+ {SPR_SSWY, 2, 1, {NULL}, 0, 0, S_YHORIZ8}, // S_YHORIZ7
+ {SPR_SSWY, 1, 1, {NULL}, 0, 0, S_YHORIZ1}, // S_YHORIZ8
+
+ // Red Side Spring
+ {SPR_SSWR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RHORIZ1
+ {SPR_SSWR, 1, 1, {A_Pain}, 0, 0, S_RHORIZ3}, // S_RHORIZ2
+ {SPR_SSWR, 2, 1, {NULL}, 0, 0, S_RHORIZ4}, // S_RHORIZ3
+ {SPR_SSWR, 3, 1, {NULL}, 0, 0, S_RHORIZ5}, // S_RHORIZ4
+ {SPR_SSWR, 4, 1, {NULL}, 0, 0, S_RHORIZ6}, // S_RHORIZ5
+ {SPR_SSWR, 3, 1, {NULL}, 0, 0, S_RHORIZ7}, // S_RHORIZ6
+ {SPR_SSWR, 2, 1, {NULL}, 0, 0, S_RHORIZ8}, // S_RHORIZ7
+ {SPR_SSWR, 1, 1, {NULL}, 0, 0, S_RHORIZ1}, // S_RHORIZ8
+
+ // Blue Side Spring
+ {SPR_SSWB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BHORIZ1
+ {SPR_SSWB, 1, 1, {A_Pain}, 0, 0, S_BHORIZ3}, // S_BHORIZ2
+ {SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ4}, // S_BHORIZ3
+ {SPR_SSWB, 3, 1, {NULL}, 0, 0, S_BHORIZ5}, // S_BHORIZ4
+ {SPR_SSWB, 4, 1, {NULL}, 0, 0, S_BHORIZ6}, // S_BHORIZ5
+ {SPR_SSWB, 3, 1, {NULL}, 0, 0, S_BHORIZ7}, // S_BHORIZ6
+ {SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ8}, // S_BHORIZ7
+ {SPR_SSWB, 1, 1, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ8
+
// Rain
{SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1
{SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN
@@ -1883,17 +2283,18 @@ state_t states[NUMSTATES] =
{SPR_SMOK, FF_TRANS50|4, 8, {NULL}, 0, 0, S_NULL}, // S_SMOKE5
// Bubbles
- {SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE1}, // S_SMALLBUBBLE
- {SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE1
- {SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE1}, // S_MEDIUMBUBBLE
- {SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE1
+ {SPR_BUBL, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE
+ {SPR_BUBL, FF_TRANS50|1, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE
// Extra Large Bubble (breathable)
- {SPR_BUBN, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE
- {SPR_BUBM, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE
+ {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|2, 8, {A_BubbleRise}, 0, 1024, S_LARGEBUBBLE2}, // S_LARGEBUBBLE1
+ {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|3, 8, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE2
+ {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|4, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE
// Extra Large Bubble goes POP!
- {SPR_POPP, 0, 16, {NULL}, 0, 0, S_NULL}, // S_POP1
+ {SPR_BUBL, 5, 16, {NULL}, 0, 0, S_NULL}, // S_POP1
+
+ {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_MIDDLESTARTCHANCE, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2
@@ -1937,6 +2338,13 @@ state_t states[NUMSTATES] =
{SPR_DRWN, 4, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR1
{SPR_DRWN, 5, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE1
+ {SPR_DRWN, 6, 40, {NULL}, 0, 0, S_NULL}, // S_ZERO2
+ {SPR_DRWN, 7, 40, {NULL}, 0, 0, S_NULL}, // S_ONE2
+ {SPR_DRWN, 8, 40, {NULL}, 0, 0, S_NULL}, // S_TWO2
+ {SPR_DRWN, 9, 40, {NULL}, 0, 0, S_NULL}, // S_THREE2
+ {SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2
+ {SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2
+
{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1
// CTF Sign
@@ -2209,96 +2617,6 @@ state_t states[NUMSTATES] =
{SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3
{SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4
- // Nights Player, Flying and Drilling
- {SPR_SUPE, 0, 1, {NULL}, 0, 0, S_NIGHTSFLY1B}, // S_NIGHTSFLY1A
- {SPR_SUPE, 1, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSFLY1B
- {SPR_NDRL, 0, 2, {NULL}, 0, 0, S_NIGHTSDRILL1B}, // S_NIGHTSDRILL1A
- {SPR_NDRL, 1, 2, {NULL}, 0, 0, S_NIGHTSDRILL1C}, // S_NIGHTSDRILL1B
- {SPR_NDRL, 2, 2, {NULL}, 0, 0, S_NIGHTSDRILL1D}, // S_NIGHTSDRILL1C
- {SPR_NDRL, 3, 2, {NULL}, 0, 0, S_NIGHTSDRILL1A}, // S_NIGHTSDRILL1D
- {SPR_SUPE, 2, 1, {NULL}, 0, 0, S_NIGHTSFLY2B}, // S_NIGHTSFLY2A
- {SPR_SUPE, 3, 1, {NULL}, 0, 0, S_NIGHTSFLY2A}, // S_NIGHTSFLY2B
- {SPR_NDRL, 4, 2, {NULL}, 0, 0, S_NIGHTSDRILL2B}, // S_NIGHTSDRILL2A
- {SPR_NDRL, 5, 2, {NULL}, 0, 0, S_NIGHTSDRILL2C}, // S_NIGHTSDRILL2B
- {SPR_NDRL, 6, 2, {NULL}, 0, 0, S_NIGHTSDRILL2D}, // S_NIGHTSDRILL2C
- {SPR_NDRL, 7, 2, {NULL}, 0, 0, S_NIGHTSDRILL2A}, // S_NIGHTSDRILL2D
- {SPR_SUPE, 4, 1, {NULL}, 0, 0, S_NIGHTSFLY3B}, // S_NIGHTSFLY3A
- {SPR_SUPE, 5, 1, {NULL}, 0, 0, S_NIGHTSFLY3A}, // S_NIGHTSFLY3B
- {SPR_NDRL, 8, 2, {NULL}, 0, 0, S_NIGHTSDRILL3B}, // S_NIGHTSDRILL3A
- {SPR_NDRL, 9, 2, {NULL}, 0, 0, S_NIGHTSDRILL3C}, // S_NIGHTSDRILL3B
- {SPR_NDRL, 10, 2, {NULL}, 0, 0, S_NIGHTSDRILL3D}, // S_NIGHTSDRILL3C
- {SPR_NDRL, 11, 2, {NULL}, 0, 0, S_NIGHTSDRILL3A}, // S_NIGHTSDRILL3D
- {SPR_SUPE, 6, 1, {NULL}, 0, 0, S_NIGHTSFLY4B}, // S_NIGHTSFLY4A
- {SPR_SUPE, 7, 1, {NULL}, 0, 0, S_NIGHTSFLY4A}, // S_NIGHTSFLY4B
- {SPR_NDRL, 12, 2, {NULL}, 0, 0, S_NIGHTSDRILL4B}, // S_NIGHTSDRILL4A
- {SPR_NDRL, 13, 2, {NULL}, 0, 0, S_NIGHTSDRILL4C}, // S_NIGHTSDRILL4B
- {SPR_NDRL, 14, 2, {NULL}, 0, 0, S_NIGHTSDRILL4D}, // S_NIGHTSDRILL4C
- {SPR_NDRL, 15, 2, {NULL}, 0, 0, S_NIGHTSDRILL4A}, // S_NIGHTSDRILL4D
- {SPR_SUPE, 8, 1, {NULL}, 0, 0, S_NIGHTSFLY5B}, // S_NIGHTSFLY5A
- {SPR_SUPE, 9, 1, {NULL}, 0, 0, S_NIGHTSFLY5A}, // S_NIGHTSFLY5B
- {SPR_NDRL, 16, 2, {NULL}, 0, 0, S_NIGHTSDRILL5B}, // S_NIGHTSDRILL5A
- {SPR_NDRL, 17, 2, {NULL}, 0, 0, S_NIGHTSDRILL5C}, // S_NIGHTSDRILL5B
- {SPR_NDRL, 18, 2, {NULL}, 0, 0, S_NIGHTSDRILL5D}, // S_NIGHTSDRILL5C
- {SPR_NDRL, 19, 2, {NULL}, 0, 0, S_NIGHTSDRILL5A}, // S_NIGHTSDRILL5D
- {SPR_SUPE, 10, 1, {NULL}, 0, 0, S_NIGHTSFLY6B}, // S_NIGHTSFLY6A
- {SPR_SUPE, 11, 1, {NULL}, 0, 0, S_NIGHTSFLY6A}, // S_NIGHTSFLY6B
- {SPR_NDRL, 20, 2, {NULL}, 0, 0, S_NIGHTSDRILL6B}, // S_NIGHTSDRILL6A
- {SPR_NDRL, 21, 2, {NULL}, 0, 0, S_NIGHTSDRILL6C}, // S_NIGHTSDRILL6B
- {SPR_NDRL, 22, 2, {NULL}, 0, 0, S_NIGHTSDRILL6D}, // S_NIGHTSDRILL6C
- {SPR_NDRL, 23, 2, {NULL}, 0, 0, S_NIGHTSDRILL6A}, // S_NIGHTSDRILL6D
- {SPR_SUPE, 12, 1, {NULL}, 0, 0, S_NIGHTSFLY7B}, // S_NIGHTSFLY7A
- {SPR_SUPE, 13, 1, {NULL}, 0, 0, S_NIGHTSFLY7A}, // S_NIGHTSFLY7B
- {SPR_NDRL, 24, 2, {NULL}, 0, 0, S_NIGHTSDRILL7B}, // S_NIGHTSDRILL7A
- {SPR_NDRL, 25, 2, {NULL}, 0, 0, S_NIGHTSDRILL7C}, // S_NIGHTSDRILL7B
- {SPR_NDRL, 26, 2, {NULL}, 0, 0, S_NIGHTSDRILL7D}, // S_NIGHTSDRILL7C
- {SPR_NDRL, 27, 2, {NULL}, 0, 0, S_NIGHTSDRILL7A}, // S_NIGHTSDRILL7D
- {SPR_SUPE, 14, 1, {NULL}, 0, 0, S_NIGHTSFLY8B}, // S_NIGHTSFLY8A
- {SPR_SUPE, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY8A}, // S_NIGHTSFLY8B
- {SPR_NDRL, 28, 2, {NULL}, 0, 0, S_NIGHTSDRILL8B}, // S_NIGHTSDRILL8A
- {SPR_NDRL, 29, 2, {NULL}, 0, 0, S_NIGHTSDRILL8C}, // S_NIGHTSDRILL8B
- {SPR_NDRL, 30, 2, {NULL}, 0, 0, S_NIGHTSDRILL8D}, // S_NIGHTSDRILL8C
- {SPR_NDRL, 31, 2, {NULL}, 0, 0, S_NIGHTSDRILL8A}, // S_NIGHTSDRILL8D
- {SPR_SUPE, 16, 1, {NULL}, 0, 0, S_NIGHTSFLY9B}, // S_NIGHTSFLY9A
- {SPR_SUPE, 17, 1, {NULL}, 0, 0, S_NIGHTSFLY9A}, // S_NIGHTSFLY9B
- {SPR_NDRL, 32, 2, {NULL}, 0, 0, S_NIGHTSDRILL9B}, // S_NIGHTSDRILL9A
- {SPR_NDRL, 33, 2, {NULL}, 0, 0, S_NIGHTSDRILL9C}, // S_NIGHTSDRILL9B
- {SPR_NDRL, 34, 2, {NULL}, 0, 0, S_NIGHTSDRILL9D}, // S_NIGHTSDRILL9C
- {SPR_NDRL, 35, 2, {NULL}, 0, 0, S_NIGHTSDRILL9A}, // S_NIGHTSDRILL9D
-
- // Nights Player, Falling
- {SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT2}, // S_NIGHTSHURT1
- {SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT3}, // S_NIGHTSHURT2
- {SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT4}, // S_NIGHTSHURT3
- {SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT5}, // S_NIGHTSHURT4
- {SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT6}, // S_NIGHTSHURT5
- {SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT7}, // S_NIGHTSHURT6
- {SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT8}, // S_NIGHTSHURT7
- {SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT9}, // S_NIGHTSHURT8
- {SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT10}, // S_NIGHTSHURT9
- {SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT11}, // S_NIGHTSHURT10
- {SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT12}, // S_NIGHTSHURT11
- {SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT13}, // S_NIGHTSHURT12
- {SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT14}, // S_NIGHTSHURT13
- {SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT15}, // S_NIGHTSHURT14
- {SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT16}, // S_NIGHTSHURT15
- {SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSHURT17}, // S_NIGHTSHURT16
- {SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT18}, // S_NIGHTSHURT17
- {SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT19}, // S_NIGHTSHURT18
- {SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT20}, // S_NIGHTSHURT19
- {SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT21}, // S_NIGHTSHURT20
- {SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT22}, // S_NIGHTSHURT21
- {SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT23}, // S_NIGHTSHURT22
- {SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT24}, // S_NIGHTSHURT23
- {SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT25}, // S_NIGHTSHURT24
- {SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT26}, // S_NIGHTSHURT25
- {SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT27}, // S_NIGHTSHURT26
- {SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT28}, // S_NIGHTSHURT27
- {SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT29}, // S_NIGHTSHURT28
- {SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT30}, // S_NIGHTSHURT29
- {SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT31}, // S_NIGHTSHURT30
- {SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT32}, // S_NIGHTSHURT31
- {SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSHURT32
-
// Nights Sparkle
{SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1
{SPR_NSPK, FF_FULLBRIGHT|1, 7, {NULL}, 0, 0, S_NIGHTSPARKLE3}, // S_NIGHTSPARKLE2
@@ -2401,16 +2719,6 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2}, // S_CRUMBLE1
{SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2
- {SPR_SUPT, 0, 4, {A_Scream}, 0, 0, S_SUPERTRANS2}, // S_SUPERTRANS1
- {SPR_SUPT, 1, 4, {NULL}, 0, 0, S_SUPERTRANS3}, // S_SUPERTRANS2
- {SPR_SUPT, FF_FULLBRIGHT|2, 4, {NULL}, 0, 0, S_SUPERTRANS4}, // S_SUPERTRANS3
- {SPR_SUPT, 3, 3, {NULL}, 0, 0, S_SUPERTRANS5}, // S_SUPERTRANS4
- {SPR_SUPT, 4, 3, {NULL}, 0, 0, S_SUPERTRANS6}, // S_SUPERTRANS5
- {SPR_SUPT, 5, 3, {NULL}, 0, 0, S_SUPERTRANS7}, // S_SUPERTRANS6
- {SPR_SUPT, 6, 3, {NULL}, 0, 0, S_SUPERTRANS8}, // S_SUPERTRANS7
- {SPR_SUPT, 7, 3, {NULL}, 0, 0, S_SUPERTRANS9}, // S_SUPERTRANS8
- {SPR_SUPT, 8, 16, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_SUPERTRANS9
-
// Spark
{SPR_SPRK, FF_TRANS40 , 1, {NULL}, 0, 0, S_SPRK2}, // S_SPRK1
{SPR_SPRK, FF_TRANS50|1, 1, {NULL}, 0, 0, S_SPRK3}, // S_SPRK2
@@ -2637,7 +2945,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MT_THOK, // damage
sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE, // flags
- (statenum_t)MT_THOK // raisestate
+ (statenum_t)MT_NULL // raisestate
},
{ // MT_BLUECRAWLA
@@ -5281,6 +5589,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_RDIAG2 // raisestate
},
+ { // MT_YELLOWHORIZ
+ 558, // doomednum
+ S_YHORIZ1, // spawnstate
+ 1, // spawnhealth
+ S_YHORIZ2, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_NULL, // painstate
+ 0, // painchance
+ sfx_spring, // 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
+ 16*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
+ S_YHORIZ2 // raisestate
+ },
+
+ { // MT_REDHORIZ
+ 559, // doomednum
+ S_RHORIZ1, // spawnstate
+ 1, // spawnhealth
+ S_RHORIZ2, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_NULL, // painstate
+ 0, // painchance
+ sfx_spring, // 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
+ 64*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
+ S_RHORIZ2 // raisestate
+ },
+
+ { // MT_BLUEHORIZ
+ 560, // doomednum
+ S_BHORIZ1, // spawnstate
+ 1, // spawnhealth
+ S_BHORIZ2, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_NULL, // painstate
+ 0, // painchance
+ sfx_spring, // 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
+ 4*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
+ S_BHORIZ2 // raisestate
+ },
+
{ // MT_BUBBLES
500, // doomednum
S_BUBBLES1, // spawnstate
@@ -5551,417 +5940,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_SUPERRINGBOX
- 400, // doomednum
- S_SUPERRINGBOX, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_SUPERRINGBOX, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_SUPERRINGBOX2,// deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_RINGICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_REDRINGBOX
- 414, // doomednum
- S_REDRINGBOX, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_REDRINGBOX, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_SUPERRINGBOX2,// deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_REDMONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_RINGICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_BLUERINGBOX
- 415, // doomednum
- S_BLUERINGBOX, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_BLUERINGBOX, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_SUPERRINGBOX2,// deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_BLUEMONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_RINGICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_SNEAKERTV
- 407, // doomednum
- S_SHTV, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_SHTV, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_SHTV2, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_SHOESICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_INV
- 408, // doomednum
- S_PINV, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_PINV, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_PINV2, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_INVCICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- // 1-up box
- { // MT_PRUP
- 409, // doomednum
- S_PRUP, // spawnstate
- 1, // spawnhealth
- S_PLAY_BOX1, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_PRUP, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_PRUP2, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_1UPICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_RUNSPAWNFUNC, // flags
- S_NULL // raisestate
- },
-
- { // MT_YELLOWTV
- 402, // doomednum
- S_YLTV, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_YLTV, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_YLTV2, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_YSHIELDICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_BLUETV
- 403, // doomednum
- S_BLTV1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_BLTV1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_BLTV3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_BSHIELDICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- // bomb shield box
- { // MT_BLACKTV
- 404, // doomednum
- S_BKTV1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_BKTV1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_BKTV3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_KSHIELDICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- // jump shield box
- { // MT_WHITETV
- 405, // doomednum
- S_WHTV1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_WHTV1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_WHTV3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_WSHIELDICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_GREENTV
- 406, // doomednum
- S_GRTV, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_GRTV, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_GRTV2, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_GSHIELDICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_PITYTV
- 401, // doomednum
- S_PITV1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_PITV1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_PITV3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_PITYSHIELDICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_EGGMANBOX
- 410, // doomednum
- S_EGGTV1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_EGGTV1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_EGGTV3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_EGGMANICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_MIXUPBOX
- 411, // doomednum
- S_MIXUPBOX1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_MIXUPBOX1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_MIXUPBOX3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_MIXUPICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_RECYCLETV
- 416, // doomednum
- S_RECYCLETV1, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 8, // reactiontime
- sfx_None, // attacksound
- S_RECYCLETV1, // painstate
- 0, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_RECYCLETV3, // deathstate
- S_NULL, // xdeathstate
- sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
- 16*FRACUNIT, // radius
- 32*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- MT_RECYCLEICO, // damage
- sfx_None, // activesound
- MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
- S_NULL // raisestate
- },
-
- { // MT_RECYCLEICO
+ { // MT_BOXSPARKLE
-1, // doomednum
- S_RECYCLETV3, // spawnstate
+ S_BOXSPARKLE1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -5974,210 +5955,804 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
- sfx_None, // deathsound
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
+ sfx_pop, // deathsound
+ 3*FRACUNIT, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
0, // display offset
100, // mass
- 62*FRACUNIT, // damage
+ 0, // damage
sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ MF_NOGRAVITY|MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
- { // MT_QUESTIONBOX
+ { // MT_RING_BOX
+ 400, // doomednum
+ S_RING_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_RING_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_RING_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_PITY_BOX
+ 401, // doomednum
+ S_PITY_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_PITY_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_PITY_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ATTRACT_BOX
+ 402, // doomednum
+ S_ATTRACT_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_ATTRACT_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_ATTRACT_ICON,// damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_FORCE_BOX
+ 403, // doomednum
+ S_FORCE_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_FORCE_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_FORCE_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ARMAGEDDON_BOX
+ 404, // doomednum
+ S_ARMAGEDDON_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_ARMAGEDDON_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_ARMAGEDDON_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_WHIRLWIND_BOX
+ 405, // doomednum
+ S_WHIRLWIND_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_WHIRLWIND_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_WHIRLWIND_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ELEMENTAL_BOX
+ 406, // doomednum
+ S_ELEMENTAL_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_ELEMENTAL_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_ELEMENTAL_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_SNEAKERS_BOX
+ 407, // doomednum
+ S_SNEAKERS_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_SNEAKERS_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_SNEAKERS_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_INVULN_BOX
+ 408, // doomednum
+ S_INVULN_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_INVULN_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_INVULN_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_1UP_BOX
+ 409, // doomednum
+ S_1UP_BOX, // spawnstate
+ 1, // spawnhealth
+ S_PLAY_BOX1, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_1UP_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_1UP_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_EGGMAN_BOX
+ 410, // doomednum
+ S_EGGMAN_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_EGGMAN_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_EGGMAN_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_MIXUP_BOX
+ 411, // doomednum
+ S_MIXUP_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_MIXUP_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_MIXUP_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_MYSTERY_BOX
412, // doomednum
- S_RANDOMBOX1, // spawnstate
+ S_MYSTERY_BOX, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
- S_RANDOMBOX1, // painstate
+ S_MYSTERY_BOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_RANDOMBOX3, // deathstate
+ S_BOX_POP1, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
+ 0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
- 0, // damage
+ MT_UNKNOWN, // damage
sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
S_NULL // raisestate
},
- { // MT_GRAVITYBOX
+ { // MT_GRAVITY_BOX
413, // doomednum
- S_GBTV1, // spawnstate
+ S_GRAVITY_BOX, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
- S_GBTV1, // painstate
+ S_GRAVITY_BOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_GBTV3, // deathstate
+ S_BOX_POP1, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
+ 0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
- MT_GRAVITYICO, // damage
- sfx_cgot, // activesound
+ MT_GRAVITY_ICON, // damage
+ sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
S_NULL // raisestate
},
- { // MT_SCORETVSMALL
+ { // MT_RECYCLER_BOX
+ 416, // doomednum
+ S_RECYCLER_BOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_RECYCLER_BOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 1, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_RECYCLER_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_SCORE1K_BOX
418, // doomednum
- S_SCORETVA1, // spawnstate
+ S_SCORE1K_BOX, // spawnstate
1, // spawnhealth
S_NULL, // seestate
- sfx_token, // seesound
+ sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
- S_SCORETVA1, // painstate
+ S_SCORE1K_BOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_SCORETVA3, // deathstate
+ S_BOX_POP1, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
+ 0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
- MT_SCOREICOSMALL, // damage
+ MT_SCORE1K_ICON, // damage
sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
S_NULL // raisestate
},
- { // MT_SCORETVLARGE
+ { // MT_SCORE10K_BOX
419, // doomednum
- S_SCORETVB1, // spawnstate
+ S_SCORE10K_BOX, // spawnstate
1, // spawnhealth
S_NULL, // seestate
- sfx_token, // seesound
+ sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
- S_SCORETVB1, // painstate
+ S_SCORE10K_BOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_SCORETVB3, // deathstate
+ S_BOX_POP1, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
- MT_MONITOREXPLOSION, // speed
+ 0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
- MT_SCOREICOLARGE, // damage
+ MT_SCORE10K_ICON, // damage
sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
S_NULL // raisestate
},
- { // MT_MONITOREXPLOSION
- -1, // doomednum
- S_MONITOREXPLOSION1, // spawnstate
- 0, // spawnhealth
+ { // MT_PITY_GOLDBOX
+ 431, // doomednum
+ S_PITY_GOLDBOX, // spawnstate
+ 1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
- sfx_None, // attacksound
- S_XPLD1, // painstate
+ sfx_monton, // attacksound
+ S_PITY_GOLDBOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_NULL, // deathstate
+ S_GOLDBOX_OFF1, // deathstate
S_NULL, // xdeathstate
- sfx_None, // deathsound
+ sfx_pop, // deathsound
0, // speed
- 8*FRACUNIT, // radius
- 8*FRACUNIT, // height
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
0, // display offset
- MT_EXPLODE, // mass
- 0, // damage
+ 100, // mass
+ MT_PITY_ICON, // damage
sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate
},
- { // MT_REDMONITOREXPLOSION
- -1, // doomednum
- S_REDMONITOREXPLOSION1, // spawnstate
- 0, // spawnhealth
+ { // MT_ATTRACT_GOLDBOX
+ 432, // doomednum
+ S_ATTRACT_GOLDBOX, // spawnstate
+ 1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
- sfx_None, // attacksound
- S_XPLD1, // painstate
+ sfx_monton, // attacksound
+ S_ATTRACT_GOLDBOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_NULL, // deathstate
+ S_GOLDBOX_OFF1, // deathstate
S_NULL, // xdeathstate
- sfx_None, // deathsound
+ sfx_pop, // deathsound
0, // speed
- 8*FRACUNIT, // radius
- 8*FRACUNIT, // height
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
0, // display offset
- MT_EXPLODE, // mass
- 0, // damage
+ 100, // mass
+ MT_ATTRACT_ICON,// damage
sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate
},
- { // MT_BLUEMONITOREXPLOSION
- -1, // doomednum
- S_BLUEMONITOREXPLOSION1, // spawnstate
- 0, // spawnhealth
+ { // MT_FORCE_GOLDBOX
+ 433, // doomednum
+ S_FORCE_GOLDBOX, // spawnstate
+ 1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
- sfx_None, // attacksound
- S_XPLD1, // painstate
+ sfx_monton, // attacksound
+ S_FORCE_GOLDBOX, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
- S_NULL, // deathstate
+ S_GOLDBOX_OFF1, // deathstate
S_NULL, // xdeathstate
- sfx_None, // deathsound
+ sfx_pop, // deathsound
0, // speed
- 8*FRACUNIT, // radius
- 8*FRACUNIT, // height
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
0, // display offset
- MT_EXPLODE, // mass
- 0, // damage
+ 100, // mass
+ MT_FORCE_ICON, // damage
sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate
},
- { // MT_RINGICO
+ { // MT_ARMAGEDDON_GOLDBOX
+ 434, // doomednum
+ S_ARMAGEDDON_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_ARMAGEDDON_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_ARMAGEDDON_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_WHIRLWIND_GOLDBOX
+ 435, // doomednum
+ S_WHIRLWIND_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_WHIRLWIND_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_WHIRLWIND_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ELEMENTAL_GOLDBOX
+ 436, // doomednum
+ S_ELEMENTAL_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_ELEMENTAL_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_ELEMENTAL_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_SNEAKERS_GOLDBOX
+ 437, // doomednum
+ S_SNEAKERS_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_SNEAKERS_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_SNEAKERS_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_INVULN_GOLDBOX
+ 438, // doomednum
+ S_INVULN_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_INVULN_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_INVULN_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_EGGMAN_GOLDBOX
+ 440, // doomednum
+ S_EGGMAN_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_EGGMAN_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_EGGMAN_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_GRAVITY_GOLDBOX
+ 443, // doomednum
+ S_GRAVITY_GOLDBOX, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_monton, // attacksound
+ S_GRAVITY_GOLDBOX, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_GOLDBOX_OFF1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 36*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_GRAVITY_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_RING_REDBOX
+ 414, // doomednum
+ S_RING_REDBOX1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_RING_REDBOX1, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_REDBOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_RING_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_RING_BLUEBOX
+ 415, // doomednum
+ S_RING_BLUEBOX1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_None, // seesound
+ 8, // reactiontime
+ sfx_None, // attacksound
+ S_RING_BLUEBOX1, // painstate
+ 0, // painchance
+ sfx_None, // painsound
+ S_NULL, // meleestate
+ S_NULL, // missilestate
+ S_BLUEBOX_POP1, // deathstate
+ S_NULL, // xdeathstate
+ sfx_pop, // deathsound
+ 0, // speed
+ 16*FRACUNIT, // radius
+ 32*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ MT_RING_ICON, // damage
+ sfx_None, // activesound
+ MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_RING_ICON
-1, // doomednum
- S_SUPERRINGBOX2, // spawnstate
+ S_RING_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_itemup, // seesound
@@ -6202,9 +6777,171 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_SHOESICO
+ { // MT_PITY_ICON
-1, // doomednum
- S_SHTV2, // spawnstate
+ S_PITY_ICON1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_shield, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ATTRACT_ICON
+ -1, // doomednum
+ S_ATTRACT_ICON1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_shield, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_FORCE_ICON
+ -1, // doomednum
+ S_FORCE_ICON1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_shield, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ARMAGEDDON_ICON
+ -1, // doomednum
+ S_ARMAGEDDON_ICON1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_shield, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_WHIRLWIND_ICON
+ -1, // doomednum
+ S_WHIRLWIND_ICON1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_shield, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_ELEMENTAL_ICON
+ -1, // doomednum
+ S_ELEMENTAL_ICON1, // spawnstate
+ 1, // spawnhealth
+ S_NULL, // seestate
+ sfx_shield, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_SNEAKERS_ICON
+ -1, // doomednum
+ S_SNEAKERS_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -6229,9 +6966,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_INVCICO
+ { // MT_INVULN_ICON
-1, // doomednum
- S_PINV2, // spawnstate
+ S_INVULN_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -6256,9 +6993,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_1UPICO
+ { // MT_1UP_ICON
-1, // doomednum
- S_PRUP2, // spawnstate
+ S_1UP_ICON1, // spawnstate
1, // spawnhealth
S_PLAY_ICON1, // seestate
sfx_None, // seesound
@@ -6283,172 +7020,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_YSHIELDICO
+ { // MT_EGGMAN_ICON
-1, // doomednum
- S_YLTV2, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_shield, // 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
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- 62*FRACUNIT, // damage
- sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
- S_NULL // raisestate
- },
-
- { // MT_BSHIELDICO
- -1, // doomednum
- S_BLTV3, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_shield, // 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
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- 62*FRACUNIT, // damage
- sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
- S_NULL // raisestate
- },
-
- { // MT_KSHIELDICO
- -1, // doomednum
- S_BKTV3, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_shield, // 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
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- 62*FRACUNIT, // damage
- sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
- S_NULL // raisestate
- },
-
- { // MT_WSHIELDICO
- -1, // doomednum
- S_WHTV3, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_shield, // 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
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- 62*FRACUNIT, // damage
- sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
- S_NULL // raisestate
- },
-
- { // MT_GSHIELDICO
- -1, // doomednum
- S_GRTV2, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_shield, // 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
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- 62*FRACUNIT, // damage
- sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
- S_NULL // raisestate
- },
-
-
- { // MT_PITYSHIELDICO
- -1, // doomednum
- S_PITV3, // spawnstate
- 1, // spawnhealth
- S_NULL, // seestate
- sfx_shield, // 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
- 2*FRACUNIT, // speed
- 8*FRACUNIT, // radius
- 14*FRACUNIT, // height
- 0, // display offset
- 100, // mass
- 62*FRACUNIT, // damage
- sfx_None, // activesound
- MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
- S_NULL // raisestate
- },
-
- { // MT_EGGMANICO
- -1, // doomednum
- S_EGGTV3, // spawnstate
+ S_EGGMAN_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -6473,9 +7047,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_MIXUPICO
+ { // MT_MIXUP_ICON
-1, // doomednum
- S_MIXUPBOX3, // spawnstate
+ S_MIXUP_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -6500,9 +7074,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_GRAVITYICO
+ { // MT_GRAVITY_ICON
-1, // doomednum
- S_GBTV3, // spawnstate
+ S_GRAVITY_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -6527,9 +7101,36 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_SCOREICOSMALL
+ { // MT_RECYCLER_ICON
-1, // doomednum
- S_SCORETVA3, // spawnstate
+ S_RECYCLER_ICON1, // spawnstate
+ 1, // 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
+ 2*FRACUNIT, // speed
+ 8*FRACUNIT, // radius
+ 14*FRACUNIT, // height
+ 0, // display offset
+ 100, // mass
+ 62*FRACUNIT, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags
+ S_NULL // raisestate
+ },
+
+ { // MT_SCORE1K_ICON
+ -1, // doomednum
+ S_SCORE1K_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_token, // seesound
@@ -6554,9 +7155,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_SCOREICOLARGE
+ { // MT_SCORE10K_ICON
-1, // doomednum
- S_SCORETVB3, // spawnstate
+ S_SCORE10K_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_token, // seesound
@@ -10367,7 +10968,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EXTRALARGEBUBBLE
-1, // doomednum
- S_LARGEBUBBLE, // spawnstate
+ S_LARGEBUBBLE1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@@ -10382,8 +10983,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_gasp, // deathsound
8, // speed
- 8*FRACUNIT, // radius
- 12*FRACUNIT, // height
+ 23*FRACUNIT, // radius
+ 43*FRACUNIT, // height
0, // display offset
16, // mass
0, // damage
@@ -10392,6 +10993,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
+ { // MT_WATERZAP
+ -1, // doomednum
+ S_WATERZAP, // 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
+ 4*FRACUNIT, // radius
+ 4*FRACUNIT, // height
+ 0, // display offset
+ 16, // mass
+ 0, // damage
+ sfx_None, // activesound
+ MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
+ S_NULL // raisestate
+ },
+
{ // MT_TFOG
-1, // doomednum
S_FOG1, // spawnstate
@@ -12020,33 +12648,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
- { // MT_NIGHTSCHAR
- -1, // doomednum
- S_NIGHTSFLY1A, // spawnstate
- 1000, // spawnhealth
- S_NULL, // seestate
- sfx_None, // seesound
- 0, // reactiontime
- sfx_None, // attacksound
- S_NIGHTSFLY1A, // painstate
- 255, // painchance
- sfx_None, // painsound
- S_NULL, // meleestate
- S_NULL, // missilestate
- S_NIGHTSFLY1A, // deathstate
- S_NULL, // xdeathstate
- sfx_None, // deathsound
- 0, // speed
- 16*FRACUNIT, // radius
- 48*FRACUNIT, // height
- 0, // display offset
- 1000, // mass
- 0, // damage
- sfx_None, // activesound
- MF_NOCLIP|MF_NOGRAVITY, // flags
- S_NULL // raisestate
- },
-
{ // MT_NIGHTSPARKLE
-1, // doomednum
S_NIGHTSPARKLE1,// spawnstate
diff --git a/src/info.h b/src/info.h
index 46fdde46b..8f9e473aa 100644
--- a/src/info.h
+++ b/src/info.h
@@ -28,6 +28,9 @@ void A_Explode();
void A_Pain();
void A_Fall();
void A_MonitorPop();
+void A_GoldMonitorPop();
+void A_GoldMonitorRestore();
+void A_GoldMonitorSparkle();
void A_Look();
void A_Chase();
void A_FaceStabChase();
@@ -314,7 +317,7 @@ typedef enum sprite
// Interactive Objects
SPR_FANS,
- SPR_BUBL, // water bubble source
+ SPR_BBLS, // water bubble source
SPR_SIGN, // Level end sign
SPR_STEM, // Steam riser
SPR_SPIK, // Spike Ball
@@ -324,27 +327,30 @@ typedef enum sprite
SPR_BMNE, // Big floating mine
// Monitor Boxes
- SPR_SRBX,
- SPR_RRBX,
- SPR_BRBX,
- SPR_SHTV,
- SPR_PINV,
- SPR_YLTV,
- SPR_BLTV, // Force shield
- SPR_BKTV, // Bomb shield TV
- SPR_WHTV, // Jump shield TV
- SPR_GRTV, // Pity shield TV
- SPR_ELTV, // Elemental shield TV
- SPR_EGGB, // Eggman box
- SPR_MIXU, // Player mixing monitor
- SPR_RECY, // Recycler (power mixing) monitor
- SPR_QUES, // Random monitor
- SPR_GBTV, // Gravity boots TV
- SPR_PRUP, // 1up
- SPR_PTTV, // Score TVs
+ SPR_MSTV, // MiSc TV sprites
+ SPR_XLTV, // eXtra Large TV sprites
- // Monitor Miscellany
- SPR_MTEX, // Exploding monitor
+ SPR_TRRI, // Red team: 10 RIngs
+ SPR_TBRI, // Blue team: 10 RIngs
+
+ SPR_TVRI, // 10 RIng
+ SPR_TVPI, // PIty shield
+ SPR_TVAT, // ATtraction shield
+ SPR_TVFO, // FOrce shield
+ SPR_TVAR, // ARmageddon shield
+ SPR_TVWW, // WhirlWind shield
+ SPR_TVEL, // ELemental shield
+ SPR_TVSS, // Super Sneakers
+ SPR_TVIV, // InVincibility
+ SPR_TV1U, // 1Up
+ SPR_TV1P, // 1uP (textless)
+ SPR_TVEG, // EGgman
+ SPR_TVMX, // MiXup
+ SPR_TVMY, // MYstery
+ SPR_TVGV, // GraVity boots
+ SPR_TVRC, // ReCycler
+ SPR_TV1K, // 1,000 points (1 K)
+ SPR_TVTK, // 10,000 points (Ten K)
// Projectiles
SPR_MISL,
@@ -448,6 +454,9 @@ typedef enum sprite
SPR_SPRB, // Blue springs
SPR_YSPR, // Yellow Diagonal Spring
SPR_RSPR, // Red Diagonal Spring
+ SPR_SSWY, // Yellow Side Spring
+ SPR_SSWR, // Red Side Spring
+ SPR_SSWB, // Blue Side Spring
// Environmental Effects
SPR_RAIN, // Rain
@@ -455,11 +464,8 @@ typedef enum sprite
SPR_SPLH, // Water Splish
SPR_SPLA, // Water Splash
SPR_SMOK,
- SPR_BUBP, // Small bubble
- SPR_BUBO, // Medium bubble
- SPR_BUBN, // Large bubble
- SPR_BUBM, // Extra Large (would you like fries with that?) bubble
- SPR_POPP, // Extra Large bubble goes POP!
+ SPR_BUBL, // Bubble
+ SPR_WZAP,
SPR_TFOG, // Teleport Fog
SPR_SEED, // Sonic CD flower seed
SPR_PRTL, // Particle (for fans, etc.)
@@ -510,16 +516,12 @@ typedef enum sprite
// NiGHTS Stuff
SPR_NDRN, // NiGHTS drone
- SPR_SUPE, // NiGHTS character flying
- SPR_SUPZ, // NiGHTS hurt
- SPR_NDRL, // NiGHTS character drilling
SPR_NSPK, // NiGHTS sparkle
SPR_NBMP, // NiGHTS Bumper
SPR_HOOP, // NiGHTS hoop sprite
SPR_NSCR, // NiGHTS score sprite
SPR_NPRU, // Nights Powerups
SPR_CAPS, // Capsule thingy for NiGHTS
- SPR_SUPT, // Super Sonic Transformation (NiGHTS)
// Debris
SPR_SPRK, // spark
@@ -575,17 +577,21 @@ typedef enum sprite
NUMSPRITES
} spritenum_t;
+// Make sure to be conscious of FF_FRAMEMASK whenever you change this table.
+// Currently, FF_FRAMEMASK is 0x1ff, or 511 - and NUMSPRITEFREESLOTS is 256.
+// Since this is zero-based, there can be at most 256 different SPR2_'s without changing that.
enum playersprite
{
SPR2_STND = 0,
SPR2_WAIT,
SPR2_WALK,
SPR2_RUN ,
+ SPR2_PEEL,
SPR2_PAIN,
SPR2_DEAD,
- SPR2_DRWN,
+ SPR2_DRWN, // drown
SPR2_SPIN,
- SPR2_DASH,
+ SPR2_DASH, // spindash charge
SPR2_GASP,
SPR2_JUMP,
SPR2_SPNG, // spring
@@ -593,33 +599,78 @@ enum playersprite
SPR2_EDGE,
SPR2_RIDE,
- SPR2_SIGN,
- SPR2_LIFE,
+ SPR2_SIGN, // end sign head
+ SPR2_LIFE, // life monitor icon
SPR2_FLY ,
- SPR2_TIRE,
+ SPR2_SWIM,
+ SPR2_TIRE, // tired
- SPR2_GLID,
- SPR2_CLNG,
- SPR2_CLMB,
+ SPR2_GLID, // glide
+ SPR2_CLNG, // cling
+ SPR2_CLMB, // climb
- SPR2_TRNS,
- SPR2_SSTD,
- SPR2_SWLK,
- SPR2_SRUN,
- SPR2_SPAN,
- SPR2_SMSL,
- SPR2_SDTH,
- SPR2_SDRN,
- SPR2_SSPN,
- SPR2_SGSP,
- SPR2_SJMP,
- SPR2_SSPG,
- SPR2_SFAL,
- SPR2_SEDG,
- SPR2_SRID,
- SPR2_SFLT,
+ SPR2_TWIN, // twinspin
+ SPR2_MLEE, // melee
+
+ SPR2_TRNS, // super transformation
+ SPR2_SSTD, // super stand
+ SPR2_SWLK, // super walk
+ SPR2_SRUN, // super run
+ SPR2_SPEE, // super peelout
+ SPR2_SPAN, // super pain
+ SPR2_SSTN, // super stun
+ SPR2_SDTH, // super death
+ SPR2_SDRN, // super drown
+ SPR2_SSPN, // super spin
+ SPR2_SGSP, // super gasp
+ SPR2_SJMP, // super jump
+ SPR2_SSPG, // super spring
+ SPR2_SFAL, // super fall
+ SPR2_SEDG, // super edge
+ SPR2_SRID, // super ride
+ SPR2_SFLT, // super float
+
+ SPR2_NTRN, // NiGHTS transformation
+ SPR2_NSTD, // NiGHTS stand
+ SPR2_NFLT, // NiGHTS float
+ SPR2_NPAN, // NiGHTS pain
+ SPR2_NPUL, // NiGHTS pull
+ SPR2_NATK, // NiGHTS attack
+
+ // NiGHTS flight.
+ SPR2_NGT0,
+ SPR2_NGT1,
+ SPR2_NGT2,
+ SPR2_NGT3,
+ SPR2_NGT4,
+ SPR2_NGT5,
+ SPR2_NGT6,
+ SPR2_NGT7,
+ SPR2_NGT8,
+ SPR2_NGT9,
+ SPR2_NGTA,
+ SPR2_NGTB,
+ SPR2_NGTC,
+
+ // NiGHTS drill.
+ SPR2_DRL0,
+ SPR2_DRL1,
+ SPR2_DRL2,
+ SPR2_DRL3,
+ SPR2_DRL4,
+ SPR2_DRL5,
+ SPR2_DRL6,
+ SPR2_DRL7,
+ SPR2_DRL8,
+ SPR2_DRL9,
+ SPR2_DRLA,
+ SPR2_DRLB,
+ SPR2_DRLC,
+
+ SPR2_FIRSTFREESLOT,
+ SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
NUMPLAYERSPRITES
};
@@ -645,20 +696,22 @@ typedef enum state
S_PLAY_WAIT,
S_PLAY_WALK,
S_PLAY_RUN,
+ S_PLAY_PEEL,
S_PLAY_PAIN,
S_PLAY_DEAD,
S_PLAY_DRWN,
S_PLAY_SPIN,
S_PLAY_DASH,
S_PLAY_GASP,
- S_PLAY_JUMP, // spin jump (todo: make jump separate from spring up for non-spin chars too?)
+ S_PLAY_JUMP, // spin jump
S_PLAY_SPRING,
S_PLAY_FALL,
S_PLAY_EDGE,
S_PLAY_RIDE,
- // CA_FLY
+ // CA_FLY/SWIM
S_PLAY_FLY,
+ S_PLAY_SWIM,
S_PLAY_FLY_TIRED,
// CA_GLIDEANDCLIMB
@@ -666,10 +719,18 @@ typedef enum state
S_PLAY_CLING,
S_PLAY_CLIMB,
+ // CA_TWINSPIN
+ S_PLAY_TWINSPIN,
+
+ // CA2_MELEE
+ S_PLAY_MELEE,
+ S_PLAY_MELEE_FINISH,
+
// SF_SUPERANIMS
S_PLAY_SUPER_STND,
S_PLAY_SUPER_WALK,
S_PLAY_SUPER_RUN,
+ S_PLAY_SUPER_PEEL,
S_PLAY_SUPER_PAIN,
S_PLAY_SUPER_STUN,
S_PLAY_SUPER_DEAD,
@@ -707,6 +768,50 @@ typedef enum state
// Level end sign overlay (uses player sprite)
S_PLAY_SIGN,
+ // NiGHTS character (uses player sprite)
+ S_PLAY_NIGHTS_TRANS,
+ S_PLAY_NIGHTS_TRANS2,
+ S_PLAY_NIGHTS_TRANS3,
+ S_PLAY_NIGHTS_TRANS4,
+ S_PLAY_NIGHTS_TRANS5,
+ S_PLAY_NIGHTS_TRANS6,
+ S_PLAY_NIGHTS_TRANS7,
+ S_PLAY_NIGHTS_TRANS8,
+ S_PLAY_NIGHTS_TRANS9,
+
+ S_PLAY_NIGHTS_STAND,
+ S_PLAY_NIGHTS_FLOAT,
+ S_PLAY_NIGHTS_PAIN,
+ S_PLAY_NIGHTS_PULL,
+ S_PLAY_NIGHTS_ATTACK,
+
+ S_PLAY_NIGHTS_FLY0,
+ S_PLAY_NIGHTS_DRILL0,
+ S_PLAY_NIGHTS_FLY1,
+ S_PLAY_NIGHTS_DRILL1,
+ S_PLAY_NIGHTS_FLY2,
+ S_PLAY_NIGHTS_DRILL2,
+ S_PLAY_NIGHTS_FLY3,
+ S_PLAY_NIGHTS_DRILL3,
+ S_PLAY_NIGHTS_FLY4,
+ S_PLAY_NIGHTS_DRILL4,
+ S_PLAY_NIGHTS_FLY5,
+ S_PLAY_NIGHTS_DRILL5,
+ S_PLAY_NIGHTS_FLY6,
+ S_PLAY_NIGHTS_DRILL6,
+ S_PLAY_NIGHTS_FLY7,
+ S_PLAY_NIGHTS_DRILL7,
+ S_PLAY_NIGHTS_FLY8,
+ S_PLAY_NIGHTS_DRILL8,
+ S_PLAY_NIGHTS_FLY9,
+ S_PLAY_NIGHTS_DRILL9,
+ S_PLAY_NIGHTS_FLYA,
+ S_PLAY_NIGHTS_DRILLA,
+ S_PLAY_NIGHTS_FLYB,
+ S_PLAY_NIGHTS_DRILLB,
+ S_PLAY_NIGHTS_FLYC,
+ S_PLAY_NIGHTS_DRILLC,
+
// Blue Crawla
S_POSS_STND,
S_POSS_RUN1,
@@ -1557,6 +1662,8 @@ typedef enum state
// Bubble Source
S_BUBBLES1,
S_BUBBLES2,
+ S_BUBBLES3,
+ S_BUBBLES4,
// Level End Sign
S_SIGN1,
@@ -1671,170 +1778,116 @@ typedef enum state
S_CANNONLAUNCHER2,
S_CANNONLAUNCHER3,
- // Super Ring Box
- S_SUPERRINGBOX,
- S_SUPERRINGBOX1,
- S_SUPERRINGBOX2,
- S_SUPERRINGBOX3,
- S_SUPERRINGBOX4,
- S_SUPERRINGBOX5,
- S_SUPERRINGBOX6,
+ // Monitor Miscellany
+ S_BOXSPARKLE1,
+ S_BOXSPARKLE2,
+ S_BOXSPARKLE3,
- // Red Team Ring Box
- S_REDRINGBOX,
- S_REDRINGBOX1,
+ S_BOX_FLICKER,
+ S_BOX_POP1,
+ S_BOX_POP2,
- // Blue Team Ring Box
- S_BLUERINGBOX,
- S_BLUERINGBOX1,
+ S_GOLDBOX_FLICKER,
+ S_GOLDBOX_OFF1,
+ S_GOLDBOX_OFF2,
+ S_GOLDBOX_OFF3,
+ S_GOLDBOX_OFF4,
+ S_GOLDBOX_OFF5,
+ S_GOLDBOX_OFF6,
+ S_GOLDBOX_OFF7,
- // Super Sneakers Box
- S_SHTV,
- S_SHTV1,
- S_SHTV2,
- S_SHTV3,
- S_SHTV4,
- S_SHTV5,
- S_SHTV6,
+ // Monitor States (one per box)
+ S_MYSTERY_BOX,
+ S_RING_BOX,
+ S_PITY_BOX,
+ S_ATTRACT_BOX,
+ S_FORCE_BOX,
+ S_ARMAGEDDON_BOX,
+ S_WHIRLWIND_BOX,
+ S_ELEMENTAL_BOX,
+ S_SNEAKERS_BOX,
+ S_INVULN_BOX,
+ S_1UP_BOX,
+ S_EGGMAN_BOX,
+ S_MIXUP_BOX,
+ S_GRAVITY_BOX,
+ S_RECYCLER_BOX,
+ S_SCORE1K_BOX,
+ S_SCORE10K_BOX,
- // Invincibility Box
- S_PINV,
- S_PINV1,
- S_PINV2,
- S_PINV3,
- S_PINV4,
- S_PINV5,
- S_PINV6,
+ // Gold Repeat Monitor States (one per box)
+ S_PITY_GOLDBOX,
+ S_ATTRACT_GOLDBOX,
+ S_FORCE_GOLDBOX,
+ S_ARMAGEDDON_GOLDBOX,
+ S_WHIRLWIND_GOLDBOX,
+ S_ELEMENTAL_GOLDBOX,
+ S_SNEAKERS_GOLDBOX,
+ S_INVULN_GOLDBOX,
+ S_EGGMAN_GOLDBOX,
+ S_GRAVITY_GOLDBOX,
- // 1up Box
- S_PRUP,
- S_PRUP1,
- S_PRUP2,
- S_PRUP3,
- S_PRUP4,
- S_PRUP5,
- S_PRUP6,
+ // Team Ring Boxes (these are special)
+ S_RING_REDBOX1,
+ S_RING_REDBOX2,
+ S_REDBOX_POP1,
+ S_REDBOX_POP2,
- // Ring Shield Box
- S_YLTV,
- S_YLTV1,
- S_YLTV2,
- S_YLTV3,
- S_YLTV4,
- S_YLTV5,
- S_YLTV6,
+ S_RING_BLUEBOX1,
+ S_RING_BLUEBOX2,
+ S_BLUEBOX_POP1,
+ S_BLUEBOX_POP2,
- // Force Shield Box
- S_BLTV1,
- S_BLTV2,
- S_BLTV3,
- S_BLTV4,
- S_BLTV5,
- S_BLTV6,
- S_BLTV7,
+ // Box Icons -- 2 states each, animation and action
+ S_RING_ICON1,
+ S_RING_ICON2,
- // Bomb Shield Box
- S_BKTV1,
- S_BKTV2,
- S_BKTV3,
- S_BKTV4,
- S_BKTV5,
- S_BKTV6,
- S_BKTV7,
+ S_PITY_ICON1,
+ S_PITY_ICON2,
- // Jump Shield Box
- S_WHTV1,
- S_WHTV2,
- S_WHTV3,
- S_WHTV4,
- S_WHTV5,
- S_WHTV6,
- S_WHTV7,
+ S_ATTRACT_ICON1,
+ S_ATTRACT_ICON2,
- // Water Shield Box
- S_GRTV,
- S_GRTV1,
- S_GRTV2,
- S_GRTV3,
- S_GRTV4,
- S_GRTV5,
- S_GRTV6,
+ S_FORCE_ICON1,
+ S_FORCE_ICON2,
- // Pity Shield Box
- S_PITV1,
- S_PITV2,
- S_PITV3,
- S_PITV4,
- S_PITV5,
- S_PITV6,
- S_PITV7,
+ S_ARMAGEDDON_ICON1,
+ S_ARMAGEDDON_ICON2,
- // Eggman Box
- S_EGGTV1,
- S_EGGTV2,
- S_EGGTV3,
- S_EGGTV4,
- S_EGGTV5,
- S_EGGTV6,
- S_EGGTV7,
+ S_WHIRLWIND_ICON1,
+ S_WHIRLWIND_ICON2,
- // Teleport Box
- S_MIXUPBOX1,
- S_MIXUPBOX2,
- S_MIXUPBOX3,
- S_MIXUPBOX4,
- S_MIXUPBOX5,
- S_MIXUPBOX6,
- S_MIXUPBOX7,
+ S_ELEMENTAL_ICON1,
+ S_ELEMENTAL_ICON2,
- // Recycler Box
- S_RECYCLETV1,
- S_RECYCLETV2,
- S_RECYCLETV3,
- S_RECYCLETV4,
- S_RECYCLETV5,
- S_RECYCLETV6,
- S_RECYCLETV7,
+ S_SNEAKERS_ICON1,
+ S_SNEAKERS_ICON2,
- // Question Box
- S_RANDOMBOX1,
- S_RANDOMBOX2,
- S_RANDOMBOX3,
+ S_INVULN_ICON1,
+ S_INVULN_ICON2,
- // Gravity Boots Box
- S_GBTV1,
- S_GBTV2,
- S_GBTV3,
- S_GBTV4,
- S_GBTV5,
- S_GBTV6,
- S_GBTV7,
+ S_1UP_ICON1,
+ S_1UP_ICON2,
- // Score boxes
- S_SCORETVA1,
- S_SCORETVA2,
- S_SCORETVA3,
- S_SCORETVA4,
- S_SCORETVA5,
- S_SCORETVA6,
- S_SCORETVA7,
- S_SCORETVB1,
- S_SCORETVB2,
- S_SCORETVB3,
- S_SCORETVB4,
- S_SCORETVB5,
- S_SCORETVB6,
- S_SCORETVB7,
+ S_EGGMAN_ICON1,
+ S_EGGMAN_ICON2,
- // Monitor Explosion
- S_MONITOREXPLOSION1,
- S_MONITOREXPLOSION2,
+ S_MIXUP_ICON1,
+ S_MIXUP_ICON2,
- S_REDMONITOREXPLOSION1,
- S_REDMONITOREXPLOSION2,
+ S_GRAVITY_ICON1,
+ S_GRAVITY_ICON2,
- S_BLUEMONITOREXPLOSION1,
- S_BLUEMONITOREXPLOSION2,
+ S_RECYCLER_ICON1,
+ S_RECYCLER_ICON2,
+
+ S_SCORE1K_ICON1,
+ S_SCORE1K_ICON2,
+
+ S_SCORE10K_ICON1,
+ S_SCORE10K_ICON2,
+
+ // ---
S_ROCKET,
@@ -2348,6 +2401,36 @@ typedef enum state
S_RDIAG7,
S_RDIAG8,
+ // Yellow Side Spring
+ S_YHORIZ1,
+ S_YHORIZ2,
+ S_YHORIZ3,
+ S_YHORIZ4,
+ S_YHORIZ5,
+ S_YHORIZ6,
+ S_YHORIZ7,
+ S_YHORIZ8,
+
+ // Red Side Spring
+ S_RHORIZ1,
+ S_RHORIZ2,
+ S_RHORIZ3,
+ S_RHORIZ4,
+ S_RHORIZ5,
+ S_RHORIZ6,
+ S_RHORIZ7,
+ S_RHORIZ8,
+
+ // Blue Side Spring
+ S_BHORIZ1,
+ S_BHORIZ2,
+ S_BHORIZ3,
+ S_BHORIZ4,
+ S_BHORIZ5,
+ S_BHORIZ6,
+ S_BHORIZ7,
+ S_BHORIZ8,
+
// Rain
S_RAIN1,
S_RAINRETURN,
@@ -2382,14 +2465,15 @@ typedef enum state
// Bubbles
S_SMALLBUBBLE,
- S_SMALLBUBBLE1,
S_MEDIUMBUBBLE,
- S_MEDIUMBUBBLE1,
- S_LARGEBUBBLE,
+ S_LARGEBUBBLE1,
+ S_LARGEBUBBLE2,
S_EXTRALARGEBUBBLE, // breathable
S_POP1, // Extra Large bubble goes POP!
+ S_WATERZAP,
+
S_FOG1,
S_FOG2,
S_FOG3,
@@ -2431,6 +2515,13 @@ typedef enum state
S_FOUR1,
S_FIVE1,
+ S_ZERO2,
+ S_ONE2,
+ S_TWO2,
+ S_THREE2,
+ S_FOUR2,
+ S_FIVE2,
+
// Tag Sign
S_TTAG1,
@@ -2663,93 +2754,6 @@ typedef enum state
S_NIGHTSGOAL3,
S_NIGHTSGOAL4,
- S_NIGHTSFLY1A,
- S_NIGHTSFLY1B,
- S_NIGHTSDRILL1A,
- S_NIGHTSDRILL1B,
- S_NIGHTSDRILL1C,
- S_NIGHTSDRILL1D,
- S_NIGHTSFLY2A,
- S_NIGHTSFLY2B,
- S_NIGHTSDRILL2A,
- S_NIGHTSDRILL2B,
- S_NIGHTSDRILL2C,
- S_NIGHTSDRILL2D,
- S_NIGHTSFLY3A,
- S_NIGHTSFLY3B,
- S_NIGHTSDRILL3A,
- S_NIGHTSDRILL3B,
- S_NIGHTSDRILL3C,
- S_NIGHTSDRILL3D,
- S_NIGHTSFLY4A,
- S_NIGHTSFLY4B,
- S_NIGHTSDRILL4A,
- S_NIGHTSDRILL4B,
- S_NIGHTSDRILL4C,
- S_NIGHTSDRILL4D,
- S_NIGHTSFLY5A,
- S_NIGHTSFLY5B,
- S_NIGHTSDRILL5A,
- S_NIGHTSDRILL5B,
- S_NIGHTSDRILL5C,
- S_NIGHTSDRILL5D,
- S_NIGHTSFLY6A,
- S_NIGHTSFLY6B,
- S_NIGHTSDRILL6A,
- S_NIGHTSDRILL6B,
- S_NIGHTSDRILL6C,
- S_NIGHTSDRILL6D,
- S_NIGHTSFLY7A,
- S_NIGHTSFLY7B,
- S_NIGHTSDRILL7A,
- S_NIGHTSDRILL7B,
- S_NIGHTSDRILL7C,
- S_NIGHTSDRILL7D,
- S_NIGHTSFLY8A,
- S_NIGHTSFLY8B,
- S_NIGHTSDRILL8A,
- S_NIGHTSDRILL8B,
- S_NIGHTSDRILL8C,
- S_NIGHTSDRILL8D,
- S_NIGHTSFLY9A,
- S_NIGHTSFLY9B,
- S_NIGHTSDRILL9A,
- S_NIGHTSDRILL9B,
- S_NIGHTSDRILL9C,
- S_NIGHTSDRILL9D,
- S_NIGHTSHURT1,
- S_NIGHTSHURT2,
- S_NIGHTSHURT3,
- S_NIGHTSHURT4,
- S_NIGHTSHURT5,
- S_NIGHTSHURT6,
- S_NIGHTSHURT7,
- S_NIGHTSHURT8,
- S_NIGHTSHURT9,
- S_NIGHTSHURT10,
- S_NIGHTSHURT11,
- S_NIGHTSHURT12,
- S_NIGHTSHURT13,
- S_NIGHTSHURT14,
- S_NIGHTSHURT15,
- S_NIGHTSHURT16,
- S_NIGHTSHURT17,
- S_NIGHTSHURT18,
- S_NIGHTSHURT19,
- S_NIGHTSHURT20,
- S_NIGHTSHURT21,
- S_NIGHTSHURT22,
- S_NIGHTSHURT23,
- S_NIGHTSHURT24,
- S_NIGHTSHURT25,
- S_NIGHTSHURT26,
- S_NIGHTSHURT27,
- S_NIGHTSHURT28,
- S_NIGHTSHURT29,
- S_NIGHTSHURT30,
- S_NIGHTSHURT31,
- S_NIGHTSHURT32,
-
S_NIGHTSPARKLE1,
S_NIGHTSPARKLE2,
S_NIGHTSPARKLE3,
@@ -2846,16 +2850,6 @@ typedef enum state
S_CRUMBLE1,
S_CRUMBLE2,
- S_SUPERTRANS1,
- S_SUPERTRANS2,
- S_SUPERTRANS3,
- S_SUPERTRANS4,
- S_SUPERTRANS5,
- S_SUPERTRANS6,
- S_SUPERTRANS7,
- S_SUPERTRANS8,
- S_SUPERTRANS9,
-
// Spark
S_SPRK1,
S_SPRK2,
@@ -2993,8 +2987,9 @@ typedef struct
extern state_t states[NUMSTATES];
extern char sprnames[NUMSPRITES + 1][5];
-char spr2names[NUMPLAYERSPRITES][5];
+extern char spr2names[NUMPLAYERSPRITES][5];
extern state_t *astate;
+extern enum playersprite free_spr2;
typedef enum mobj_type
{
@@ -3123,6 +3118,9 @@ typedef enum mobj_type
MT_REDSPRING,
MT_YELLOWDIAG, // Yellow Diagonal Spring
MT_REDDIAG, // Red Diagonal Spring
+ MT_YELLOWHORIZ, // Yellow Side Spring
+ MT_REDHORIZ, // Red Side Spring
+ MT_BLUEHORIZ, // Blue Side Spring
// Interactive Objects
MT_BUBBLES, // Bubble source
@@ -3136,47 +3134,61 @@ typedef enum mobj_type
MT_BIGAIRMINE,
MT_CANNONLAUNCHER,
- // Monitor Boxes
- MT_SUPERRINGBOX,
- MT_REDRINGBOX,
- MT_BLUERINGBOX,
- MT_SNEAKERTV,
- MT_INV,
- MT_PRUP, // 1up Box
- MT_YELLOWTV,
- MT_BLUETV,
- MT_BLACKTV, // Bomb shield TV
- MT_WHITETV, // Jump shield TV
- MT_GREENTV,
- MT_PITYTV, // Pity Shield TV
- MT_EGGMANBOX,
- MT_MIXUPBOX,
- MT_RECYCLETV,
- MT_RECYCLEICO,
- MT_QUESTIONBOX,
- MT_GRAVITYBOX,
- MT_SCORETVSMALL,
- MT_SCORETVLARGE,
-
// Monitor miscellany
- MT_MONITOREXPLOSION,
- MT_REDMONITOREXPLOSION,
- MT_BLUEMONITOREXPLOSION,
- MT_RINGICO,
- MT_SHOESICO,
- MT_INVCICO,
- MT_1UPICO,
- MT_YSHIELDICO,
- MT_BSHIELDICO,
- MT_KSHIELDICO,
- MT_WSHIELDICO,
- MT_GSHIELDICO,
- MT_PITYSHIELDICO,
- MT_EGGMANICO,
- MT_MIXUPICO,
- MT_GRAVITYICO,
- MT_SCOREICOSMALL,
- MT_SCOREICOLARGE,
+ MT_BOXSPARKLE,
+
+ // Monitor boxes -- regular
+ MT_RING_BOX,
+ MT_PITY_BOX,
+ MT_ATTRACT_BOX,
+ MT_FORCE_BOX,
+ MT_ARMAGEDDON_BOX,
+ MT_WHIRLWIND_BOX,
+ MT_ELEMENTAL_BOX,
+ MT_SNEAKERS_BOX,
+ MT_INVULN_BOX,
+ MT_1UP_BOX,
+ MT_EGGMAN_BOX,
+ MT_MIXUP_BOX,
+ MT_MYSTERY_BOX,
+ MT_GRAVITY_BOX,
+ MT_RECYCLER_BOX,
+ MT_SCORE1K_BOX,
+ MT_SCORE10K_BOX,
+
+ // Monitor boxes -- repeating (big) boxes
+ MT_PITY_GOLDBOX,
+ MT_ATTRACT_GOLDBOX,
+ MT_FORCE_GOLDBOX,
+ MT_ARMAGEDDON_GOLDBOX,
+ MT_WHIRLWIND_GOLDBOX,
+ MT_ELEMENTAL_GOLDBOX,
+ MT_SNEAKERS_GOLDBOX,
+ MT_INVULN_GOLDBOX,
+ MT_EGGMAN_GOLDBOX,
+ MT_GRAVITY_GOLDBOX,
+
+ // Monitor boxes -- special
+ MT_RING_REDBOX,
+ MT_RING_BLUEBOX,
+
+ // Monitor icons
+ MT_RING_ICON,
+ MT_PITY_ICON,
+ MT_ATTRACT_ICON,
+ MT_FORCE_ICON,
+ MT_ARMAGEDDON_ICON,
+ MT_WHIRLWIND_ICON,
+ MT_ELEMENTAL_ICON,
+ MT_SNEAKERS_ICON,
+ MT_INVULN_ICON,
+ MT_1UP_ICON,
+ MT_EGGMAN_ICON,
+ MT_MIXUP_ICON,
+ MT_GRAVITY_ICON,
+ MT_RECYCLER_ICON,
+ MT_SCORE1K_ICON,
+ MT_SCORE10K_ICON,
// Projectiles
MT_ROCKET,
@@ -3354,6 +3366,7 @@ typedef enum mobj_type
MT_SMALLBUBBLE, // small bubble
MT_MEDIUMBUBBLE, // medium bubble
MT_EXTRALARGEBUBBLE, // extra large bubble
+ MT_WATERZAP,
MT_TFOG,
MT_SEED,
MT_PARTICLE,
@@ -3426,7 +3439,6 @@ typedef enum mobj_type
MT_AXISTRANSFERLINE,
MT_NIGHTSDRONE,
MT_NIGHTSGOAL,
- MT_NIGHTSCHAR,
MT_NIGHTSPARKLE,
MT_NIGHTSLOOPHELPER,
MT_NIGHTSBUMPER, // NiGHTS Bumper
diff --git a/src/locale/en.po b/src/locale/en.po
index 2665082a2..069930b81 100644
--- a/src/locale/en.po
+++ b/src/locale/en.po
@@ -1377,11 +1377,6 @@ msgstr ""
msgid "modifiedgame is false, you can unlock secrets\n"
msgstr ""
-#: d_netcmd.c:4599
-#, c-format
-msgid "Valid skin numbers are 0 to %d (-1 disables)\n"
-msgstr ""
-
#: d_netcmd.c:4617 d_netcmd.c:4629
msgid "You may not change your name when chat is muted.\n"
msgstr ""
diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot
index 37d14f8b7..ced13bbe6 100644
--- a/src/locale/srb2.pot
+++ b/src/locale/srb2.pot
@@ -1362,11 +1362,6 @@ msgstr ""
msgid "No CHEAT-marked variables are changed -- Cheats are disabled.\n"
msgstr ""
-#: d_netcmd.c:4439
-#, c-format
-msgid "Valid skin numbers are 0 to %d (-1 disables)\n"
-msgstr ""
-
#: d_netcmd.c:4457 d_netcmd.c:4469
msgid "You may not change your name when chat is muted.\n"
msgstr ""
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index fcc388534..5d0eac718 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -429,6 +429,16 @@ static int lib_pMobjFlip(lua_State *L)
return 1;
}
+static int lib_pGetMobjGravity(lua_State *L)
+{
+ mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+ //HUDSAFE
+ if (!mobj)
+ return LUA_ErrInvalid(L, "mobj_t");
+ lua_pushfixed(L, P_GetMobjGravity(mobj));
+ return 1;
+}
+
static int lib_pWeaponOrPanel(lua_State *L)
{
mobjtype_t type = luaL_checkinteger(L, 1);
@@ -2034,6 +2044,7 @@ static luaL_Reg lib[] = {
{"P_SPMAngle",lib_pSPMAngle},
{"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile},
{"P_MobjFlip",lib_pMobjFlip},
+ {"P_GetMobjGravity",lib_pGetMobjGravity},
{"P_WeaponOrPanel",lib_pWeaponOrPanel},
{"P_FlashPal",lib_pFlashPal},
{"P_GetClosestAxis",lib_pGetClosestAxis},
diff --git a/src/lua_hook.h b/src/lua_hook.h
index d2ce0d826..97d447d2e 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -69,7 +69,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8
#define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type
#define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping)
#define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping)
-#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinDash (Spin button effect)
+#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinAbility (Spin button effect)
#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air))
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
diff --git a/src/lua_hud.h b/src/lua_hud.h
index 799ce2fbf..ba0a1d894 100644
--- a/src/lua_hud.h
+++ b/src/lua_hud.h
@@ -18,6 +18,9 @@ enum hud {
hud_time,
hud_rings,
hud_lives,
+ // Match / CTF / Tag / Ringslinger
+ hud_weaponrings,
+ hud_powerstones,
// NiGHTS mode
hud_nightslink,
hud_nightsdrill,
diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c
index 31549afa7..7aadd9c0e 100644
--- a/src/lua_hudlib.c
+++ b/src/lua_hudlib.c
@@ -44,6 +44,9 @@ static const char *const hud_disable_options[] = {
"rings",
"lives",
+ "weaponrings",
+ "powerstones",
+
"nightslink",
"nightsdrill",
"nightsrings",
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index 3260e377e..4f7fdaa26 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -105,7 +105,7 @@ static int lib_getSpr2name(lua_State *L)
if (lua_isnumber(L, 1))
{
i = lua_tonumber(L, 1);
- if (i > NUMPLAYERSPRITES)
+ if (i >= free_spr2)
return 0;
lua_pushlstring(L, spr2names[i], 4);
return 1;
@@ -113,7 +113,7 @@ static int lib_getSpr2name(lua_State *L)
else if (lua_isstring(L, 1))
{
const char *name = lua_tostring(L, 1);
- for (i = 0; i < NUMPLAYERSPRITES; i++)
+ for (i = 0; i < free_spr2; i++)
if (fastcmp(name, spr2names[i]))
{
lua_pushinteger(L, i);
@@ -125,7 +125,7 @@ static int lib_getSpr2name(lua_State *L)
static int lib_spr2namelen(lua_State *L)
{
- lua_pushinteger(L, NUMPLAYERSPRITES);
+ lua_pushinteger(L, free_spr2);
return 1;
}
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 8577bcb02..29f1c6ff0 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -108,6 +108,10 @@ static int player_get(lua_State *L)
LUA_PushUserdata(L, &plr->cmd, META_TICCMD);
else if (fastcmp(field,"playerstate"))
lua_pushinteger(L, plr->playerstate);
+ else if (fastcmp(field,"camerascale"))
+ lua_pushfixed(L, plr->camerascale);
+ else if (fastcmp(field,"shieldscale"))
+ lua_pushfixed(L, plr->shieldscale);
else if (fastcmp(field,"viewz"))
lua_pushfixed(L, plr->viewz);
else if (fastcmp(field,"viewheight"))
@@ -142,8 +146,6 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->score);
else if (fastcmp(field,"dashspeed"))
lua_pushfixed(L, plr->dashspeed);
- else if (fastcmp(field,"dashtime"))
- lua_pushinteger(L, plr->dashtime);
else if (fastcmp(field,"normalspeed"))
lua_pushfixed(L, plr->normalspeed);
else if (fastcmp(field,"runspeed"))
@@ -174,6 +176,10 @@ static int player_get(lua_State *L)
lua_pushfixed(L, plr->maxdash);
else if (fastcmp(field,"jumpfactor"))
lua_pushfixed(L, plr->jumpfactor);
+ else if (fastcmp(field,"height"))
+ lua_pushfixed(L, plr->height);
+ else if (fastcmp(field,"spinheight"))
+ lua_pushfixed(L, plr->spinheight);
else if (fastcmp(field,"lives"))
lua_pushinteger(L, plr->lives);
else if (fastcmp(field,"continues"))
@@ -202,6 +208,8 @@ static int player_get(lua_State *L)
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"))
@@ -355,6 +363,10 @@ static int player_set(lua_State *L)
return NOSET;
else if (fastcmp(field,"playerstate"))
plr->playerstate = luaL_checkinteger(L, 3);
+ else if (fastcmp(field,"camerascale"))
+ plr->camerascale = luaL_checkfixed(L, 3);
+ else if (fastcmp(field,"shieldscale"))
+ plr->shieldscale = luaL_checkfixed(L, 3);
else if (fastcmp(field,"viewz"))
plr->viewz = luaL_checkfixed(L, 3);
else if (fastcmp(field,"viewheight"))
@@ -399,8 +411,6 @@ static int player_set(lua_State *L)
plr->score = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"dashspeed"))
plr->dashspeed = luaL_checkfixed(L, 3);
- else if (fastcmp(field,"dashtime"))
- plr->dashtime = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"normalspeed"))
plr->normalspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"runspeed"))
@@ -431,6 +441,10 @@ static int player_set(lua_State *L)
plr->maxdash = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"jumpfactor"))
plr->jumpfactor = (INT32)luaL_checkinteger(L, 3);
+ else if (fastcmp(field,"height"))
+ plr->height = luaL_checkfixed(L, 3);
+ else if (fastcmp(field,"spinheight"))
+ plr->spinheight = luaL_checkfixed(L, 3);
else if (fastcmp(field,"lives"))
plr->lives = (SINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"continues"))
@@ -459,6 +473,8 @@ static int player_set(lua_State *L)
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"))
diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c
index 28d5fed23..f93513c49 100644
--- a/src/lua_skinlib.c
+++ b/src/lua_skinlib.c
@@ -44,10 +44,18 @@ enum skin {
skin_accelstart,
skin_acceleration,
skin_jumpfactor,
+ skin_radius,
+ skin_height,
+ skin_spinheight,
+ skin_shieldscale,
+ skin_camerascale,
skin_starttranscolor,
skin_prefcolor,
+ skin_supercolor,
+ skin_prefoppositecolor,
skin_highresscale,
- skin_soundsid
+ skin_soundsid,
+ skin_availability
};
static const char *const skin_opt[] = {
"valid",
@@ -74,10 +82,18 @@ static const char *const skin_opt[] = {
"accelstart",
"acceleration",
"jumpfactor",
+ "radius",
+ "height",
+ "spinheight",
+ "shieldscale",
+ "camerascale",
"starttranscolor",
"prefcolor",
+ "supercolor",
+ "prefoppositecolor",
"highresscale",
"soundsid",
+ "availability",
NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field])
@@ -173,18 +189,42 @@ static int skin_get(lua_State *L)
case skin_jumpfactor:
lua_pushfixed(L, skin->jumpfactor);
break;
+ case skin_radius:
+ lua_pushfixed(L, skin->radius);
+ break;
+ case skin_height:
+ lua_pushfixed(L, skin->height);
+ break;
+ case skin_spinheight:
+ lua_pushfixed(L, skin->spinheight);
+ break;
+ case skin_shieldscale:
+ lua_pushfixed(L, skin->shieldscale);
+ break;
+ case skin_camerascale:
+ lua_pushfixed(L, skin->camerascale);
+ break;
case skin_starttranscolor:
lua_pushinteger(L, skin->starttranscolor);
break;
case skin_prefcolor:
lua_pushinteger(L, skin->prefcolor);
break;
+ case skin_supercolor:
+ lua_pushinteger(L, skin->supercolor);
+ break;
+ case skin_prefoppositecolor:
+ lua_pushinteger(L, skin->prefoppositecolor);
+ break;
case skin_highresscale:
lua_pushinteger(L, skin->highresscale);
break;
case skin_soundsid:
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
break;
+ case skin_availability:
+ lua_pushinteger(L, skin->availability);
+ break;
}
return 1;
}
diff --git a/src/lzf.c b/src/lzf.c
index 33a1b2dcd..272174f30 100644
--- a/src/lzf.c
+++ b/src/lzf.c
@@ -59,7 +59,11 @@
* Unconditionally aligning does not cost very much, so do it if unsure
*/
#ifndef STRICT_ALIGN
-# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) || defined (__clang__)
+#if !(defined(__i386) || defined (__amd64)) || defined (__clang__)
+#define STRICT_ALIGN 1
+#else
+#define STRICT_ALIGN 0
+#endif
#endif
/*
diff --git a/src/m_aatree.c b/src/m_aatree.c
new file mode 100644
index 000000000..6cb3a32cb
--- /dev/null
+++ b/src/m_aatree.c
@@ -0,0 +1,167 @@
+// SONIC ROBO BLAST 2
+//-----------------------------------------------------------------------------
+// Copyright (C) 1993-1996 by id Software, Inc.
+// Copyright (C) 1998-2000 by DooM Legacy Team.
+// Copyright (C) 1999-2016 by Sonic Team Junior.
+//
+// This program is free software distributed under the
+// terms of the GNU General Public License, version 2.
+// See the 'LICENSE' file for more details.
+//-----------------------------------------------------------------------------
+/// \file m_aatree.h
+/// \brief AA trees code
+
+#include "m_aatree.h"
+#include "z_zone.h"
+
+// A partial implementation of AA trees,
+// according to the algorithms given on Wikipedia.
+// http://en.wikipedia.org/wiki/AA_tree
+
+typedef struct aatree_node_s
+{
+ INT32 level;
+ INT32 key;
+ void* value;
+
+ struct aatree_node_s *left, *right;
+} aatree_node_t;
+
+struct aatree_s
+{
+ aatree_node_t *root;
+ UINT32 flags;
+};
+
+aatree_t *M_AATreeAlloc(UINT32 flags)
+{
+ aatree_t *aatree = Z_Malloc(sizeof (aatree_t), PU_STATIC, NULL);
+ aatree->root = NULL;
+ aatree->flags = flags;
+ return aatree;
+}
+
+static void M_AATreeFree_Node(aatree_node_t *node)
+{
+ if (node->left) M_AATreeFree_Node(node->left);
+ if (node->right) M_AATreeFree_Node(node->right);
+ Z_Free(node);
+}
+
+void M_AATreeFree(aatree_t *aatree)
+{
+ if (aatree->root)
+ M_AATreeFree_Node(aatree->root);
+
+ Z_Free(aatree);
+}
+
+static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
+{
+ if (node && node->left && node->left->level == node->level)
+ {
+ // Not allowed: horizontal left-link. Reverse the
+ // horizontal link and hook the orphan back in.
+ aatree_node_t *oldleft = node->left;
+ node->left = oldleft->right;
+ oldleft->right = node;
+
+ return oldleft;
+ }
+
+ // No change needed.
+ return node;
+}
+
+static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
+{
+ if (node && node->right && node->right->right && node->level == node->right->right->level)
+ {
+ // Not allowed: two consecutive horizontal right-links.
+ // The middle one becomes the new root at this point,
+ // with suitable adjustments below.
+
+ aatree_node_t *oldright = node->right;
+ node->right = oldright->left;
+ oldright->left = node;
+ oldright->level++;
+
+ return oldright;
+ }
+
+ // No change needed.
+ return node;
+}
+
+static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32 key, void* value)
+{
+ if (!node)
+ {
+ // Nothing here, so just add where we are
+
+ node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
+ node->level = 1;
+ node->key = key;
+ if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
+ else node->value = value;
+ node->left = node->right = NULL;
+ }
+ else
+ {
+ if (key < node->key)
+ node->left = M_AATreeSet_Node(node->left, flags, key, value);
+ else if (key > node->key)
+ node->right = M_AATreeSet_Node(node->right, flags, key, value);
+ else
+ {
+ if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
+ else node->value = value;
+ }
+
+ node = M_AATreeSkew(node);
+ node = M_AATreeSplit(node);
+ }
+
+ return node;
+}
+
+void M_AATreeSet(aatree_t *aatree, INT32 key, void* value)
+{
+ aatree->root = M_AATreeSet_Node(aatree->root, aatree->flags, key, value);
+}
+
+// Caveat: we don't distinguish between nodes that don't exists
+// and nodes with value == NULL.
+static void *M_AATreeGet_Node(aatree_node_t *node, INT32 key)
+{
+ if (node)
+ {
+ if (node->key == key)
+ return node->value;
+ else if(node->key < key)
+ return M_AATreeGet_Node(node->right, key);
+ else
+ return M_AATreeGet_Node(node->left, key);
+ }
+
+ return NULL;
+}
+
+void *M_AATreeGet(aatree_t *aatree, INT32 key)
+{
+ return M_AATreeGet_Node(aatree->root, key);
+}
+
+
+static void M_AATreeIterate_Node(aatree_node_t *node, aatree_iter_t callback)
+{
+ if (node->left) M_AATreeIterate_Node(node->left, callback);
+ callback(node->key, node->value);
+ if (node->right) M_AATreeIterate_Node(node->right, callback);
+}
+
+void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback)
+{
+ if (aatree->root)
+ M_AATreeIterate_Node(aatree->root, callback);
+}
diff --git a/src/m_aatree.h b/src/m_aatree.h
new file mode 100644
index 000000000..c9077b974
--- /dev/null
+++ b/src/m_aatree.h
@@ -0,0 +1,31 @@
+// SONIC ROBO BLAST 2
+//-----------------------------------------------------------------------------
+// Copyright (C) 1993-1996 by id Software, Inc.
+// Copyright (C) 1998-2000 by DooM Legacy Team.
+// Copyright (C) 1999-2016 by Sonic Team Junior.
+//
+// This program is free software distributed under the
+// terms of the GNU General Public License, version 2.
+// See the 'LICENSE' file for more details.
+//-----------------------------------------------------------------------------
+/// \file m_aatree.h
+/// \brief AA trees code
+
+#ifndef __M_AATREE__
+#define __M_AATREE__
+
+#include "doomtype.h"
+
+// Flags for AA trees.
+#define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields
+
+typedef struct aatree_s aatree_t;
+typedef void (*aatree_iter_t)(INT32 key, void *value);
+
+aatree_t *M_AATreeAlloc(UINT32 flags);
+void M_AATreeFree(aatree_t *aatree);
+void M_AATreeSet(aatree_t *aatree, INT32 key, void* value);
+void *M_AATreeGet(aatree_t *aatree, INT32 key);
+void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback);
+
+#endif
\ No newline at end of file
diff --git a/src/m_menu.c b/src/m_menu.c
index afda79911..ca45290a7 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -110,38 +110,38 @@ const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003
description_t description[32] =
{
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""},
- {"???", "", ""}
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0},
+ {"???", "", "", 0, 0, 0}
};
static char *char_notes = NULL;
static fixed_t char_scroll = 0;
@@ -170,6 +170,7 @@ static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games
INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002
+static boolean lastdirection = true; // toaster - Only You Can Prevent Hacks - true is for forward, false is for backwards
static INT16 skullAnimCounter = 10; // skull animation counter
static boolean setupcontrols_secondaryplayer;
@@ -705,7 +706,7 @@ static menuitem_t SP_TimeAttackMenu[] =
{IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100},
{IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110},
{IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120},
- {IT_WHITESTRING|IT_CALL, NULL, "Start", M_ChooseTimeAttack, 130},
+ {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseTimeAttack, 130},
};
enum
@@ -797,7 +798,7 @@ static menuitem_t SP_NightsAttackMenu[] =
{IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 108},
{IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 118},
{IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 128},
- {IT_WHITESTRING|IT_CALL, NULL, "Start", M_ChooseNightsAttack, 138},
+ {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseNightsAttack, 138},
};
enum
@@ -1342,7 +1343,7 @@ static menuitem_t OP_NetgameOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Sudden Death", &cv_suddendeath, 90},
{IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 98},
- {IT_STRING | IT_CVAR, NULL, "Force Skin #", &cv_forceskin, 114},
+ {IT_STRING | IT_CVAR, NULL, "Force Skin", &cv_forceskin, 114},
{IT_STRING | IT_CVAR, NULL, "Restrict skin changes", &cv_restrictskinchange, 122},
{IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 138},
@@ -2036,6 +2037,7 @@ static boolean M_ChangeStringCvar(INT32 choice)
static void M_NextOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
+ lastdirection = true;
do
{
@@ -2049,6 +2051,7 @@ static void M_NextOpt(void)
static void M_PrevOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
+ lastdirection = false;
do
{
@@ -3426,9 +3429,9 @@ static void M_PatchSkinNameTable(void)
for (j = 0; j < MAXSKINS; j++)
{
- if (skins[j].name[0] != '\0')
+ if (skins[j].name[0] != '\0' && R_SkinUnlock(j))
{
- skins_cons_t[j].strvalue = skins[j].name;
+ skins_cons_t[j].strvalue = skins[j].realname;
skins_cons_t[j].value = j+1;
}
else
@@ -3702,6 +3705,11 @@ static void M_DrawMessageMenu(void)
mlines = currentMenu->lastOn>>8;
max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8);
+
+ // hack: draw RA background in RA menus
+ if (gamestate == GS_TIMEATTACK)
+ V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
+
M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines);
while (*(msg+start))
@@ -4310,9 +4318,9 @@ static void M_SinglePlayerMenu(INT32 choice)
{
(void)choice;
SP_MainMenu[sprecordattack].status =
- (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET;
+ (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
SP_MainMenu[spnightsmode].status =
- (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET;
+ (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
M_SetupNextMenu(&SP_MainDef);
}
@@ -4768,14 +4776,63 @@ void M_ForceSaveSlotSelected(INT32 sslot)
static void M_SetupChoosePlayer(INT32 choice)
{
+ INT32 skinnum;
+ UINT8 i;
+ UINT8 firstvalid = 255;
+ UINT8 lastvalid = 0;
+ char *name;
(void)choice;
- if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')
+ if (PlayerMenu[0].status & (IT_DYBIGSPACE)) // Correcting a hack that may be made below.
+ PlayerMenu[0].status = (IT_DISABLED|(PlayerMenu[0].status & IT_CENTER));
+
+ for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
{
- M_ChoosePlayer(0); //oh for crying out loud just get STARTED, it doesn't matter!
+ if (PlayerMenu[i].status != IT_DISABLED) // If the character's disabled through SOC, there's nothing we can do for it.
+ {
+ name = strtok(Z_StrDup(description[i].skinname), "&");
+ skinnum = R_SkinAvailable(name);
+ if ((skinnum != -1) && (R_SkinUnlock(skinnum)))
+ {
+ // Handling order.
+ if (firstvalid == 255)
+ firstvalid = i;
+ else
+ {
+ description[i].prev = lastvalid;
+ description[lastvalid].next = i;
+ }
+ lastvalid = i;
+
+ // Handling visibility.
+ if (PlayerMenu[i].status & (IT_DISABLED|IT_CENTER))
+ PlayerMenu[i].status = IT_CALL;
+ if (description[i].picname[0] == '\0')
+ strncpy(description[i].picname, skins[skinnum].charsel, 8);
+ }
+ else // Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
+ PlayerMenu[i].status = (IT_DISABLED|IT_CENTER);
+ Z_Free(name);
+ }
+ }
+
+ if ((firstvalid != 255)
+ && !(mapheaderinfo[startmap-1]
+ && (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')
+ )
+ )
+ { // One last bit of order we can't do in the iteration above.
+ description[firstvalid].prev = lastvalid;
+ description[lastvalid].next = firstvalid;
+ }
+ else // We're being forced into a specific character, so might as well.
+ {
+ PlayerMenu[0].status = (IT_CALL|IT_DYBIGSPACE|(PlayerMenu[0].status & IT_CENTER)); // This is a hack to make a non-IT_CALL character in slot 0 not softlock the game. IT_DYBIGSPACE is a dummy flag, whilst IT_CENTER is preserved.
+ M_ChoosePlayer(0);
return;
}
+
if (Playing() == false)
{
S_StopMusic();
@@ -4794,8 +4851,9 @@ static void M_DrawSetupChoosePlayerMenu(void)
{
const INT32 my = 24;
patch_t *patch;
- INT32 i, o, j;
- char *picname;
+ INT32 i, o;
+ UINT8 prev, next;
+ boolean loophack = false;
// Black BG
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
@@ -4804,91 +4862,76 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Character select profile images!1
M_DrawTextBox(0, my, 16, 20);
- if (abs(itemOn*128*FRACUNIT - char_scroll) > 256*FRACUNIT)
- char_scroll = itemOn*128*FRACUNIT;
- else if (itemOn*128*FRACUNIT - char_scroll > 128*FRACUNIT)
- char_scroll += 48*FRACUNIT;
- else if (itemOn*128*FRACUNIT - char_scroll < -128*FRACUNIT)
- char_scroll -= 48*FRACUNIT;
- else if (itemOn*128*FRACUNIT > char_scroll+16*FRACUNIT)
- char_scroll += 16*FRACUNIT;
- else if (itemOn*128*FRACUNIT < char_scroll-16*FRACUNIT)
- char_scroll -= 16*FRACUNIT;
+ i = (itemOn*128 - (char_scroll / FRACUNIT));
+
+ if (!char_notes)
+ {
+ if (i) // turns out this and the preceding check is better then (abs(i) > 128)
+ {
+ o = (lastdirection) ? -1 : 1;
+ char_scroll = (itemOn + o)*128*FRACUNIT;
+ i = -o*128;
+ }
+ char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes);
+ }
+
+ if (abs(i) > 1)
+ char_scroll += i*FRACUNIT>>2;
else // close enough.
char_scroll = itemOn*128*FRACUNIT; // just be exact now.
- i = (char_scroll+16*FRACUNIT)/(128*FRACUNIT);
- o = ((char_scroll/FRACUNIT)+16)%128;
- // prev character
- if (i-1 >= 0 && PlayerMenu[i-1].status != IT_DISABLED
- && o < 32)
+ o = ((char_scroll / FRACUNIT) + 16);
+
+ if (o < 0) // This hack is to prevent visual glitches when looping from the last character to the 1st character.
+ loophack = true;
+
+ if (loophack)
+ o += 128;
+
+ i = (o / 128);
+ o = (o % 128);
+
+ if (loophack)
+ i = description[i].prev;
+
+ // Get prev character...
+ prev = description[i].prev;
+
+ if (prev != i) // If there's more than one character available...
{
- picname = description[i-1].picname;
- if (picname[0] == '\0')
+ // Let's get the next character now.
+ next = description[i].next;
+
+ // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two
+ if (o < 32) // (prev != i) was previously a part of this, but we don't need to check again after above.
{
- picname = strtok(Z_StrDup(description[i-1].skinname), "&");
- for (j = 0; j < numskins; j++)
- if (stricmp(skins[j].name, picname) == 0)
- {
- Z_Free(picname);
- picname = skins[j].charsel;
- break;
- }
- if (j == numskins) // AAAAAAAAAA
- picname = skins[0].charsel;
+ patch = W_CachePatchName(description[prev].picname, PU_CACHE);
+ if (SHORT(patch->width) >= 256)
+ V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height));
+ else
+ V_DrawCroppedPatch(8<height) - 32 + o, SHORT(patch->width), SHORT(patch->height));
+ W_UnlockCachedPatch(patch);
}
- patch = W_CachePatchName(picname, PU_CACHE);
- if (SHORT(patch->width) >= 256)
- V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height));
- else
- V_DrawCroppedPatch(8<height) - 32 + o, SHORT(patch->width), SHORT(patch->height));
- W_UnlockCachedPatch(patch);
+
+ // Draw next character if it's visible and its number isn't less than the current one or there's more than two
+ if (o < 128) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true.
+ {
+ patch = W_CachePatchName(description[next].picname, PU_CACHE);
+ if (SHORT(patch->width) >= 256)
+ V_DrawCroppedPatch(8<width), o*2);
+ else
+ V_DrawCroppedPatch(8<width), o);
+ W_UnlockCachedPatch(patch);
+ }
+
+ // current character
+ if (PlayerMenu[i].status & IT_DISABLED) // Prevent flickering.
+ i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly.
}
- // next character
- if (i+1 < currentMenu->numitems && PlayerMenu[i+1].status != IT_DISABLED
- && o < 128)
+ if (!(PlayerMenu[i].status & IT_DISABLED))
{
- picname = description[i+1].picname;
- if (picname[0] == '\0')
- {
- picname = strtok(Z_StrDup(description[i+1].skinname), "&");
- for (j = 0; j < numskins; j++)
- if (stricmp(skins[j].name, picname) == 0)
- {
- Z_Free(picname);
- picname = skins[j].charsel;
- break;
- }
- if (j == numskins) // AAAAAAAAAA
- picname = skins[0].charsel;
- }
- patch = W_CachePatchName(picname, PU_CACHE);
- if (SHORT(patch->width) >= 256)
- V_DrawCroppedPatch(8<width), o*2);
- else
- V_DrawCroppedPatch(8<width), o);
- W_UnlockCachedPatch(patch);
- }
-
- // current character
- if (i < currentMenu->numitems && PlayerMenu[i].status != IT_DISABLED)
- {
- picname = description[i].picname;
- if (picname[0] == '\0')
- {
- picname = strtok(Z_StrDup(description[i].skinname), "&");
- for (j = 0; j < numskins; j++)
- if (stricmp(skins[j].name, picname) == 0)
- {
- Z_Free(picname);
- picname = skins[j].charsel;
- break;
- }
- if (j == numskins) // AAAAAAAAAA
- picname = skins[0].charsel;
- }
- patch = W_CachePatchName(picname, PU_CACHE);
+ patch = W_CachePatchName(description[i].picname, PU_CACHE);
if (o >= 0 && o <= 32)
{
if (SHORT(patch->width) >= 256)
@@ -4911,8 +4954,6 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Character description
M_DrawTextBox(136, my, 21, 20);
- if (!char_notes)
- char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes);
V_DrawString(146, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes);
}
@@ -4923,8 +4964,8 @@ static void M_ChoosePlayer(INT32 choice)
INT32 skinnum;
boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
- // skip this if forcecharacter
- if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] == '\0')
+ // skip this if forcecharacter or no characters available
+ if (!(PlayerMenu[choice].status & IT_DYBIGSPACE))
{
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu
@@ -6470,6 +6511,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
static void M_HandleSetupMultiPlayer(INT32 choice)
{
size_t l;
+ INT32 prev_setupm_fakeskin;
boolean exitmenu = false; // exit to previous menu and send name change
switch (choice)
@@ -6488,7 +6530,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (itemOn == 2) //player skin
{
S_StartSound(NULL,sfx_menu1); // Tails
- setupm_fakeskin--;
+ prev_setupm_fakeskin = setupm_fakeskin;
+ do
+ {
+ setupm_fakeskin--;
+ if (setupm_fakeskin < 0)
+ setupm_fakeskin = numskins-1;
+ }
+ while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin)));
}
else if (itemOn == 1) // player color
{
@@ -6501,7 +6550,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (itemOn == 2) //player skin
{
S_StartSound(NULL,sfx_menu1); // Tails
- setupm_fakeskin++;
+ prev_setupm_fakeskin = setupm_fakeskin;
+ do
+ {
+ setupm_fakeskin++;
+ if (setupm_fakeskin > numskins-1)
+ setupm_fakeskin = 0;
+ }
+ while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin)));
}
else if (itemOn == 1) // player color
{
@@ -6535,12 +6591,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
}
- // check skin
- if (setupm_fakeskin < 0)
- setupm_fakeskin = numskins-1;
- if (setupm_fakeskin > numskins-1)
- setupm_fakeskin = 0;
-
// check color
if (setupm_fakecolor < 1)
setupm_fakecolor = MAXSKINCOLORS-1;
@@ -7424,7 +7474,7 @@ static void M_HandleFogColor(INT32 choice)
l = strlen(temp);
for (i = 0; i < l; i++)
cv_grfogcolor.zstring[5 - i] = temp[l - i];
- cv_grfogcolor.zstring[5] = (char)choice;
+ cv_grfogcolor.zstring[5] = (char)choice;
}
break;
}
diff --git a/src/m_menu.h b/src/m_menu.h
index 2ff1cea90..9cac52ed5 100644
--- a/src/m_menu.h
+++ b/src/m_menu.h
@@ -79,7 +79,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_SUBMENU 6 // go to sub menu
#define IT_CVAR 8 // handle as a cvar
#define IT_SPACE 10 // no handling
-#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message
+#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message)
#define IT_DISPLAY (48+64+128) // 16+32+64+128
#define IT_NOTHING 0 // space
@@ -177,6 +177,9 @@ typedef struct
char notes[441];
char picname[8];
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
+ UINT16 wadnum; // for duplicate characters
+ UINT8 prev;
+ UINT8 next;
} description_t;
// mode descriptions for video mode menu
diff --git a/src/m_misc.c b/src/m_misc.c
index 64054d4f9..457214e33 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -2323,158 +2323,3 @@ void M_SetupMemcpy(void)
M_Memcpy = cpu_cpy;
#endif
}
-
-
-// A partial implementation of AA trees,
-// according to the algorithms given on Wikipedia.
-// http://en.wikipedia.org/wiki/AA_tree
-
-
-
-typedef struct aatree_node_s
-{
- INT32 level;
- INT32 key;
- void* value;
-
- struct aatree_node_s *left, *right;
-} aatree_node_t;
-
-struct aatree_s
-{
- aatree_node_t *root;
- UINT32 flags;
-};
-
-aatree_t *M_AATreeAlloc(UINT32 flags)
-{
- aatree_t *aatree = Z_Malloc(sizeof (aatree_t), PU_STATIC, NULL);
- aatree->root = NULL;
- aatree->flags = flags;
- return aatree;
-}
-
-static void M_AATreeFree_Node(aatree_node_t *node)
-{
- if (node->left) M_AATreeFree_Node(node->left);
- if (node->right) M_AATreeFree_Node(node->right);
- Z_Free(node);
-}
-
-void M_AATreeFree(aatree_t *aatree)
-{
- if (aatree->root)
- M_AATreeFree_Node(aatree->root);
-
- Z_Free(aatree);
-}
-
-static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
-{
- if (node && node->left && node->left->level == node->level)
- {
- // Not allowed: horizontal left-link. Reverse the
- // horizontal link and hook the orphan back in.
- aatree_node_t *oldleft = node->left;
- node->left = oldleft->right;
- oldleft->right = node;
-
- return oldleft;
- }
-
- // No change needed.
- return node;
-}
-
-static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
-{
- if (node && node->right && node->right->right && node->level == node->right->right->level)
- {
- // Not allowed: two consecutive horizontal right-links.
- // The middle one becomes the new root at this point,
- // with suitable adjustments below.
-
- aatree_node_t *oldright = node->right;
- node->right = oldright->left;
- oldright->left = node;
- oldright->level++;
-
- return oldright;
- }
-
- // No change needed.
- return node;
-}
-
-static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32 key, void* value)
-{
- if (!node)
- {
- // Nothing here, so just add where we are
-
- node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
- node->level = 1;
- node->key = key;
- if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
- else node->value = value;
- node->left = node->right = NULL;
- }
- else
- {
- if (key < node->key)
- node->left = M_AATreeSet_Node(node->left, flags, key, value);
- else if (key > node->key)
- node->right = M_AATreeSet_Node(node->right, flags, key, value);
- else
- {
- if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
- else node->value = value;
- }
-
- node = M_AATreeSkew(node);
- node = M_AATreeSplit(node);
- }
-
- return node;
-}
-
-void M_AATreeSet(aatree_t *aatree, INT32 key, void* value)
-{
- aatree->root = M_AATreeSet_Node(aatree->root, aatree->flags, key, value);
-}
-
-// Caveat: we don't distinguish between nodes that don't exists
-// and nodes with value == NULL.
-static void *M_AATreeGet_Node(aatree_node_t *node, INT32 key)
-{
- if (node)
- {
- if (node->key == key)
- return node->value;
- else if(node->key < key)
- return M_AATreeGet_Node(node->right, key);
- else
- return M_AATreeGet_Node(node->left, key);
- }
-
- return NULL;
-}
-
-void *M_AATreeGet(aatree_t *aatree, INT32 key)
-{
- return M_AATreeGet_Node(aatree->root, key);
-}
-
-
-static void M_AATreeIterate_Node(aatree_node_t *node, aatree_iter_t callback)
-{
- if (node->left) M_AATreeIterate_Node(node->left, callback);
- callback(node->key, node->value);
- if (node->right) M_AATreeIterate_Node(node->right, callback);
-}
-
-void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback)
-{
- if (aatree->root)
- M_AATreeIterate_Node(aatree->root, callback);
-}
diff --git a/src/m_misc.h b/src/m_misc.h
index fa1f3b33c..dc540dc16 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -96,19 +96,6 @@ void M_SetupMemcpy(void);
// counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
-// Flags for AA trees.
-#define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields
-
-typedef struct aatree_s aatree_t;
-typedef void (*aatree_iter_t)(INT32 key, void *value);
-
-aatree_t *M_AATreeAlloc(UINT32 flags);
-void M_AATreeFree(aatree_t *aatree);
-void M_AATreeSet(aatree_t *aatree, INT32 key, void* value);
-void *M_AATreeGet(aatree_t *aatree, INT32 key);
-void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback);
-
-// Nasty cyclic dependency workaround. This must come after aatree stuff.
#include "w_wad.h"
extern char configfile[MAX_WADPATH];
diff --git a/src/p_enemy.c b/src/p_enemy.c
index f687afe84..b804f88a1 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -86,6 +86,9 @@ void A_Scream(mobj_t *actor);
void A_Pain(mobj_t *actor);
void A_1upThinker(mobj_t *actor);
void A_MonitorPop(mobj_t *actor);
+void A_GoldMonitorPop(mobj_t *actor);
+void A_GoldMonitorRestore(mobj_t *actor);
+void A_GoldMonitorSparkle(mobj_t *actor);
void A_Explode(mobj_t *actor);
void A_BossDeath(mobj_t *actor);
void A_CustomPower(mobj_t *actor);
@@ -818,6 +821,32 @@ static int P_RecycleCompare(const void *p1, const void *p2)
}
#endif
+// Handles random monitor weights via console.
+static mobjtype_t P_DoRandomBoxChances(void)
+{
+ mobjtype_t spawnchance[256];
+ INT32 numchoices = 0, i = 0;
+
+#define QUESTIONBOXCHANCES(type, cvar) \
+for (i = cvar.value; i; --i) spawnchance[numchoices++] = type
+ QUESTIONBOXCHANCES(MT_RING_ICON, cv_superring);
+ QUESTIONBOXCHANCES(MT_SNEAKERS_ICON, cv_supersneakers);
+ QUESTIONBOXCHANCES(MT_INVULN_ICON, cv_invincibility);
+ QUESTIONBOXCHANCES(MT_WHIRLWIND_ICON, cv_jumpshield);
+ QUESTIONBOXCHANCES(MT_ELEMENTAL_ICON, cv_watershield);
+ QUESTIONBOXCHANCES(MT_ATTRACT_ICON, cv_ringshield);
+ QUESTIONBOXCHANCES(MT_FORCE_ICON, cv_forceshield);
+ QUESTIONBOXCHANCES(MT_ARMAGEDDON_ICON, cv_bombshield);
+ QUESTIONBOXCHANCES(MT_1UP_ICON, cv_1up);
+ QUESTIONBOXCHANCES(MT_EGGMAN_ICON, cv_eggmanbox);
+ QUESTIONBOXCHANCES(MT_MIXUP_ICON, cv_teleporters);
+ QUESTIONBOXCHANCES(MT_RECYCLER_ICON, cv_recycler);
+#undef QUESTIONBOXCHANCES
+
+ if (numchoices == 0) return MT_NULL;
+ return spawnchance[P_RandomKey(numchoices)];
+}
+
//
// ACTION ROUTINES
//
@@ -2510,7 +2539,6 @@ void A_1upThinker(mobj_t *actor)
if (closestplayer == -1 || skins[players[closestplayer].skin].sprites[SPR2_LIFE].numframes == 0)
{ // Closest player not found (no players in game?? may be empty dedicated server!), or does not have correct sprite.
- actor->frame = 0;
if (actor->tracer) {
P_RemoveMobj(actor->tracer);
actor->tracer = NULL;
@@ -2518,11 +2546,19 @@ void A_1upThinker(mobj_t *actor)
return;
}
+ // We're using the overlay, so use the overlay 1up box (no text)
+ actor->sprite = SPR_TV1P;
+
if (!actor->tracer)
{
P_SetTarget(&actor->tracer, P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY));
P_SetTarget(&actor->tracer->target, actor);
P_SetMobjState(actor->tracer, actor->info->seestate);
+
+ // The overlay is going to be one tic early turning off and on
+ // because it's going to get its thinker run the frame we spawned it.
+ // So make it take one tic longer if it just spawned.
+ ++actor->tracer->tics;
}
actor->tracer->color = players[closestplayer].mo->color;
@@ -2538,139 +2574,200 @@ void A_1upThinker(mobj_t *actor)
//
void A_MonitorPop(mobj_t *actor)
{
- mobj_t *remains;
- mobjtype_t explode;
mobjtype_t item = 0;
- mobjtype_t newbox;
+ mobj_t *newmobj;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_MonitorPop", actor))
return;
#endif
- // de-solidify
+ // Spawn the "pop" explosion.
+ if (actor->info->deathsound)
+ S_StartSound(actor, actor->info->deathsound);
+ P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_EXPLODE);
+
+ // We're dead now. De-solidify.
actor->health = 0;
P_UnsetThingPosition(actor);
actor->flags &= ~MF_SOLID;
actor->flags |= MF_NOCLIP;
P_SetThingPosition(actor);
- // Monitor explosion
- explode = mobjinfo[actor->info->speed].mass;
- remains = P_SpawnMobj(actor->x, actor->y,
- ((actor->eflags & MFE_VERTICALFLIP) ? (actor->z + 3*(actor->height/4) - FixedMul(mobjinfo[explode].height, actor->scale)) : (actor->z + actor->height/4)), explode);
- if (actor->eflags & MFE_VERTICALFLIP)
+ if (actor->info->damage == MT_UNKNOWN)
{
- remains->eflags |= MFE_VERTICALFLIP;
- remains->flags2 |= MF2_OBJECTFLIP;
- }
- remains->destscale = actor->destscale;
- P_SetScale(remains, actor->scale);
+ // MT_UNKNOWN is random. Because it's unknown to us... get it?
+ item = P_DoRandomBoxChances();
- remains = P_SpawnMobj(actor->x, actor->y,
- ((actor->eflags & MFE_VERTICALFLIP) ? (actor->z + actor->height - FixedMul(mobjinfo[actor->info->speed].height, actor->scale)) : actor->z),
- actor->info->speed);
- remains->type = actor->type; // Transfer type information
- P_UnsetThingPosition(remains);
- if (sector_list)
- {
- P_DelSeclist(sector_list);
- sector_list = NULL;
- }
- P_SetThingPosition(remains);
- remains->destscale = actor->destscale;
- P_SetScale(remains, actor->scale);
- remains->flags = actor->flags; // Transfer flags
- remains->flags2 = actor->flags2; // Transfer flags2
- remains->fuse = actor->fuse; // Transfer respawn timer
- remains->threshold = 68;
- remains->skin = NULL;
-
- P_SetTarget(&tmthing, remains);
-
- if (actor->info->deathsound)
- S_StartSound(remains, actor->info->deathsound);
-
- switch (actor->type)
- {
- case MT_QUESTIONBOX: // Random!
+ if (item == MT_NULL)
{
- mobjtype_t spawnchance[256];
- INT32 numchoices = 0, i = 0;
-
-#define QUESTIONBOXCHANCES(type, cvar) \
-for (i = cvar.value; i; --i) spawnchance[numchoices++] = type
-
- QUESTIONBOXCHANCES(MT_SUPERRINGBOX, cv_superring);
- QUESTIONBOXCHANCES(MT_SNEAKERTV, cv_supersneakers);
- QUESTIONBOXCHANCES(MT_INV, cv_invincibility);
- QUESTIONBOXCHANCES(MT_WHITETV, cv_jumpshield);
- QUESTIONBOXCHANCES(MT_GREENTV, cv_watershield);
- QUESTIONBOXCHANCES(MT_YELLOWTV, cv_ringshield);
- QUESTIONBOXCHANCES(MT_BLUETV, cv_forceshield);
- QUESTIONBOXCHANCES(MT_BLACKTV, cv_bombshield);
- QUESTIONBOXCHANCES(MT_PRUP, cv_1up);
- QUESTIONBOXCHANCES(MT_EGGMANBOX, cv_eggmanbox);
- QUESTIONBOXCHANCES(MT_MIXUPBOX, cv_teleporters);
- QUESTIONBOXCHANCES(MT_RECYCLETV, cv_recycler);
-
-#undef QUESTIONBOXCHANCES
-
- if (numchoices == 0)
- {
- CONS_Alert(CONS_WARNING, M_GetText("All monitors turned off.\n"));
- return;
- }
-
- newbox = spawnchance[P_RandomKey(numchoices)];
- item = mobjinfo[newbox].damage;
-
- remains->flags &= ~MF_AMBUSH;
- break;
- }
- default:
- item = actor->info->damage;
- break;
- }
-
- if (item != 0)
- {
- mobj_t *newmobj;
-
- if (actor->eflags & MFE_VERTICALFLIP)
- {
- newmobj = P_SpawnMobj(actor->x, actor->y, actor->z + actor->height - FixedMul(13*FRACUNIT + mobjinfo[item].height, actor->scale), item);
- newmobj->eflags |= MFE_VERTICALFLIP;
- }
- else
- newmobj = P_SpawnMobj(actor->x, actor->y, actor->z + FixedMul(13*FRACUNIT, actor->scale), item);
-
- newmobj->destscale = actor->destscale;
- P_SetScale(newmobj, actor->scale);
- P_SetTarget(&newmobj->target, actor->target); // Transfer target
- if (item == MT_1UPICO && newmobj->target->player)
- {
- if (actor->tracer) // Remove the old lives icon.
- P_RemoveMobj(actor->tracer);
-
- if (!newmobj->target->skin || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0)
- newmobj->frame -= 2; // No lives icon for this player, use the default.
- else
- { // Spawn the lives icon.
- remains = P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_OVERLAY);
- P_SetTarget(&remains->target, newmobj);
- P_SetTarget(&newmobj->tracer, remains);
-
- remains->color = newmobj->target->player->mo->color;
- remains->skin = &skins[newmobj->target->player->skin];
- P_SetMobjState(remains, newmobj->info->seestate);
- }
+ CONS_Alert(CONS_WARNING, M_GetText("All monitors turned off.\n"));
+ return;
}
}
else
- CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_MonitorPop\n");
+ item = actor->info->damage;
- P_RemoveMobj(actor);
+ if (item == 0)
+ {
+ CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_MonitorPop\n");
+ return;
+ }
+
+ newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 13*FRACUNIT, item);
+ P_SetTarget(&newmobj->target, actor->target); // Transfer target
+
+ if (item == MT_1UP_ICON)
+ {
+ if (actor->tracer) // Remove the old lives icon.
+ P_RemoveMobj(actor->tracer);
+
+ if (!newmobj->target
+ || !newmobj->target->player
+ || !newmobj->target->skin
+ || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0)
+ {} // No lives icon for this player, use the default.
+ else
+ { // Spawn the lives icon.
+ mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY);
+ P_SetTarget(&livesico->target, newmobj);
+ P_SetTarget(&newmobj->tracer, livesico);
+
+ livesico->color = newmobj->target->player->mo->color;
+ livesico->skin = &skins[newmobj->target->player->skin];
+ P_SetMobjState(livesico, newmobj->info->seestate);
+
+ // We're using the overlay, so use the overlay 1up sprite (no text)
+ newmobj->sprite = SPR_TV1P;
+ }
+ }
+}
+
+// Function: A_GoldMonitorPop
+//
+// Description: Used by repeating monitors when they turn off. They don't really pop, but, you know...
+//
+// var1 = unused
+// var2 = unused
+//
+void A_GoldMonitorPop(mobj_t *actor)
+{
+ mobjtype_t item = 0;
+ mobj_t *newmobj;
+
+#ifdef HAVE_BLUA
+ if (LUA_CallAction("A_GoldMonitorPop", actor))
+ return;
+#endif
+
+ // Don't spawn the "pop" explosion, because the monitor isn't broken.
+ if (actor->info->deathsound)
+ S_StartSound(actor, actor->info->deathsound);
+ //P_SpawnMobjFromMobj(actor, 0, 0, actor.height/4, MT_EXPLODE);
+
+ // Remove our flags for a bit.
+ // Players can now stand on top of us.
+ P_UnsetThingPosition(actor);
+ actor->flags &= ~(MF_MONITOR|MF_SHOOTABLE);
+ actor->flags2 |= MF2_STANDONME;
+ P_SetThingPosition(actor);
+
+ // Don't count this box in statistics. Sorry.
+ if (actor->target && actor->target->player)
+ --actor->target->player->numboxes;
+ actor->fuse = 0; // Don't let the monitor code screw us up.
+
+ if (actor->info->damage == MT_UNKNOWN)
+ {
+ // MT_UNKNOWN is random. Because it's unknown to us... get it?
+ item = P_DoRandomBoxChances();
+
+ if (item == MT_NULL)
+ {
+ CONS_Alert(CONS_WARNING, M_GetText("All monitors turned off.\n"));
+ return;
+ }
+ }
+ else
+ item = actor->info->damage;
+
+ if (item == 0)
+ {
+ CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_GoldMonitorPop\n");
+ return;
+ }
+
+ // Note: the icon spawns 1 fracunit higher
+ newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 14*FRACUNIT, item);
+ P_SetTarget(&newmobj->target, actor->target); // Transfer target
+
+ if (item == MT_1UP_ICON)
+ {
+ if (actor->tracer) // Remove the old lives icon.
+ P_RemoveMobj(actor->tracer);
+
+ if (!newmobj->target
+ || !newmobj->target->player
+ || !newmobj->target->skin
+ || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0)
+ {} // No lives icon for this player, use the default.
+ else
+ { // Spawn the lives icon.
+ mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY);
+ P_SetTarget(&livesico->target, newmobj);
+ P_SetTarget(&newmobj->tracer, livesico);
+
+ livesico->color = newmobj->target->player->mo->color;
+ livesico->skin = &skins[newmobj->target->player->skin];
+ P_SetMobjState(livesico, newmobj->info->seestate);
+
+ // We're using the overlay, so use the overlay 1up sprite (no text)
+ newmobj->sprite = SPR_TV1P;
+ }
+ }
+}
+
+// Function: A_GoldMonitorRestore
+//
+// Description: A repeating monitor is coming back to life. Reset monitor flags, etc.
+//
+// var1 = unused
+// var2 = unused
+//
+void A_GoldMonitorRestore(mobj_t *actor)
+{
+#ifdef HAVE_BLUA
+ if (LUA_CallAction("A_GoldMonitorRestore", actor))
+ return;
+#endif
+
+ actor->flags |= MF_MONITOR|MF_SHOOTABLE;
+ actor->flags2 &= ~MF2_STANDONME;
+ actor->health = 1; // Just in case.
+}
+
+// Function: A_GoldMonitorSparkle
+//
+// Description: Spawns the little sparkly effect around big monitors. Looks pretty, doesn't it?
+//
+// var1 = unused
+// var2 = unused
+//
+void A_GoldMonitorSparkle(mobj_t *actor)
+{
+ fixed_t i, ngangle, xofs, yofs;
+
+#ifdef HAVE_BLUA
+ if (LUA_CallAction("A_GoldMonitorSparkle", actor))
+ return;
+#endif
+
+ ngangle = FixedAngle(((leveltime * 21) % 360) << FRACBITS);
+ xofs = FINESINE((ngangle>>ANGLETOFINESHIFT) & FINEMASK) * (actor->radius>>FRACBITS);
+ yofs = FINECOSINE((ngangle>>ANGLETOFINESHIFT) & FINEMASK) * (actor->radius>>FRACBITS);
+
+ for (i = FRACUNIT*2; i <= FRACUNIT*3; i += FRACUNIT/2)
+ P_SetObjectMomZ(P_SpawnMobjFromMobj(actor, xofs, yofs, 0, MT_BOXSPARKLE), i, false);
}
// Function: A_Explode
@@ -3151,8 +3248,11 @@ void A_ExtraLife(mobj_t *actor)
player = actor->target->player;
- if (actor->type == MT_1UPICO && !actor->tracer)
- actor->frame -= 2; // No lives icon for this player, use the default.
+ if (actor->type == MT_1UP_ICON && actor->tracer)
+ {
+ // We're using the overlay, so use the overlay 1up sprite (no text)
+ actor->sprite = SPR_TV1P;
+ }
if (ultimatemode) //I don't THINK so!
{
@@ -3949,6 +4049,7 @@ void A_UnsetSolidSteam(mobj_t *actor)
void A_SignPlayer(mobj_t *actor)
{
mobj_t *ov;
+ skin_t *skin;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_SignPlayer", actor))
return;
@@ -3959,15 +4060,35 @@ void A_SignPlayer(mobj_t *actor)
if (!actor->target->player)
return;
- // Set the sign to be an appropriate background color for this player's skincolor.
- actor->color = Color_Opposite[actor->target->player->skincolor*2];
- actor->frame += Color_Opposite[actor->target->player->skincolor*2+1];
+ skin = &skins[actor->target->player->skin];
+
+ if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
+ {
+ actor->color = skin->prefoppositecolor;
+ /*
+ If you're here from the comment above Color_Opposite,
+ the following line is the one which is dependent on the
+ array being symmetrical. It gets the opposite of the
+ opposite of your desired colour just so it can get the
+ brightness frame for the End Sign. It's not a great
+ design choice, but it's constant time array access and
+ the idea that the colours should be OPPOSITES is kind
+ of in the name. If you have a better idea, feel free
+ to let me know. ~toast 2016/07/20
+ */
+ actor->frame += Color_Opposite[Color_Opposite[skin->prefoppositecolor*2]*2+1];
+ }
+ else // Set the sign to be an appropriate background color for this player's skincolor.
+ {
+ actor->color = Color_Opposite[actor->target->player->skincolor*2];
+ actor->frame += Color_Opposite[actor->target->player->skincolor*2+1];
+ }
// spawn an overlay of the player's face.
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
P_SetTarget(&ov->target, actor);
ov->color = actor->target->player->skincolor;
- ov->skin = &skins[actor->target->player->skin];
+ ov->skin = skin;
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
}
@@ -5407,8 +5528,8 @@ void A_MixUp(mobj_t *actor)
// Zoom tube stuff
mobj_t *tempthing = NULL; //tracer
- pflags_t flags1,flags2; //player pflags
- INT32 transspeed; //player speed
+ UINT16 carry1,carry2; //carry
+ INT32 transspeed; //player speed
// Starpost stuff
INT16 starpostx, starposty, starpostz;
@@ -5445,8 +5566,8 @@ void A_MixUp(mobj_t *actor)
players[two].speed = transspeed;
//set flags variables now but DON'T set them.
- flags1 = (players[one].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG));
- flags2 = (players[two].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG));
+ carry1 = (players[one].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[one].powers[pw_carry]);
+ carry2 = (players[two].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[two].powers[pw_carry]);
x = players[one].mo->x;
y = players[one].mo->y;
@@ -5471,12 +5592,10 @@ void A_MixUp(mobj_t *actor)
starpostnum, starposttime, starpostangle,
mflags2);
- //flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for...
- //but not all of them! So we need to make sure they aren't set wrong or anything.
- players[one].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
- players[one].pflags |= flags2;
- players[two].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
- players[two].pflags |= flags1;
+ //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;
teleported[one] = true;
teleported[two] = true;
@@ -5488,8 +5607,9 @@ void A_MixUp(mobj_t *actor)
INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0;
// Zoom tube stuff
- mobj_t *transtracer[MAXPLAYERS]; //tracer
- pflags_t transflag[MAXPLAYERS]; //player pflags
+ mobj_t *transtracer[MAXPLAYERS]; //tracer
+ //pflags_t transflag[MAXPLAYERS]; //cyan pink white pink cyan
+ UINT16 transcarry[MAXPLAYERS]; //player carry
INT32 transspeed[MAXPLAYERS]; //player speed
// Star post stuff
@@ -5523,7 +5643,7 @@ void A_MixUp(mobj_t *actor)
players[i].rmomx = players[i].rmomy = 1;
players[i].cmomx = players[i].cmomy = 0;
- transflag[counter] = (players[i].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG));
+ transcarry[counter] = (players[i].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[i].powers[pw_carry]);
transspeed[counter] = players[i].speed;
transtracer[counter] = players[i].mo->tracer;
@@ -5575,9 +5695,8 @@ void A_MixUp(mobj_t *actor)
starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom],
flags2[teleportfrom]);
- //...flags after. same reasoning.
- players[i].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
- players[i].pflags |= transflag[teleportfrom];
+ //...carry after. same reasoning.
+ players[i].powers[pw_carry] = transcarry[teleportfrom];
teleported[i] = true;
counter++;
@@ -6144,7 +6263,7 @@ void A_Boss7Chase(mobj_t *actor)
if (actor->health <= actor->info->damage
&& actor->target
&& actor->target->player
- && (actor->target->player->pflags & PF_ITEMHANG))
+ && (actor->target->player->powers[pw_carry] == CR_GENERIC))
{
A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
@@ -8018,7 +8137,7 @@ void A_OrbitNights(mobj_t* actor)
#endif
if (!actor->target || !actor->target->player ||
- !actor->target->tracer || !actor->target->player->nightstime
+ !(actor->target->player->pflags & PF_NIGHTSMODE) || !actor->target->player->nightstime
// Also remove this object if they no longer have a NiGHTS helper
|| (ishelper && !actor->target->player->powers[pw_nights_helper]))
{
@@ -8037,14 +8156,23 @@ void A_OrbitNights(mobj_t* actor)
const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale));
const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale));
- actor->x = actor->target->tracer->x + fc;
- actor->y = actor->target->tracer->y + fs;
- actor->z = actor->target->tracer->z + fh + FixedMul(16*FRACUNIT, actor->scale);
+ actor->x = actor->target->x + fc;
+ actor->y = actor->target->y + fs;
+ actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale);
// Semi-lazy hack
actor->angle = (angle_t)actor->extravalue1 + ANGLE_90;
}
P_SetThingPosition(actor);
+
+ if (ishelper) // Flash a helper that's about to be removed.
+ {
+ if ((actor->target->player->powers[pw_nights_helper] < TICRATE)
+ && (actor->target->player->powers[pw_nights_helper] & 1))
+ actor->flags2 |= MF2_DONTDRAW;
+ else
+ actor->flags2 &= ~MF2_DONTDRAW;
+ }
}
}
diff --git a/src/p_floor.c b/src/p_floor.c
index af6274f28..8f51698cc 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -1163,7 +1163,7 @@ void T_SpikeSector(levelspecthink_t *spikes)
node = spikes->sector->touching_thinglist; // things touching this sector
- for (; node; node = node->m_snext)
+ for (; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
if (!thing->player)
@@ -1314,7 +1314,7 @@ void T_BridgeThinker(levelspecthink_t *bridge)
controlsec = §ors[k];
// Is a player standing on me?
- for (node = sector->touching_thinglist; node; node = node->m_snext)
+ for (node = sector->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
@@ -1737,7 +1737,7 @@ wegotit:
static mobj_t *SearchMarioNode(msecnode_t *node)
{
mobj_t *thing = NULL;
- for (; node; node = node->m_snext)
+ for (; node; node = node->m_thinglist_next)
{
// Things which should NEVER be ejected from a MarioBlock, by type.
switch (node->m_thing->type)
@@ -2009,7 +2009,7 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
&& thing->z < upperbound && thing->z+thing->height > lowerbound)
return;
- node = node->m_snext;
+ node = node->m_thinglist_next;
}
}
}
@@ -2027,7 +2027,7 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
&& thing->z < upperbound && thing->z+thing->height > lowerbound)
return;
- node = node->m_snext;
+ node = node->m_thinglist_next;
}
}
}
@@ -2306,7 +2306,7 @@ void T_RaiseSector(levelspecthink_t *raise)
sector = §ors[i];
// Is a player standing on me?
- for (node = sector->touching_thinglist; node; node = node->m_snext)
+ for (node = sector->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
diff --git a/src/p_inter.c b/src/p_inter.c
index dee2aa824..b151819e3 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -367,7 +367,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
- || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
+ || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
+ || (player->pflags & (PF_SPINNING|PF_GLIDING))
+ || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
+ || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{
if (P_MobjFlip(toucher)*toucher->momz < 0)
@@ -410,7 +413,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_DamageMobj(toucher, special, special, 1, 0);
}
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
- || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
+ || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
+ || (player->pflags & (PF_SPINNING|PF_GLIDING))
+ || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
+ || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{
if (P_MobjFlip(toucher)*toucher->momz < 0)
@@ -717,16 +723,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages.
{
// only allow the player with the emerald in-hand to leave.
- if (toucher->tracer && toucher->tracer->target
- && toucher->tracer->target->type == MT_GOTEMERALD)
+ if (toucher->tracer
+ && toucher->tracer->type == MT_GOTEMERALD)
{
}
else // Make sure that SOMEONE has the emerald, at least!
{
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].playerstate == PST_LIVE
- && players[i].mo->tracer && players[i].mo->tracer->target
- && players[i].mo->tracer->target->type == MT_GOTEMERALD)
+ && players[i].mo->tracer
+ && players[i].mo->tracer->type == MT_GOTEMERALD)
return;
// Well no one has an emerald, so exit anyway!
}
@@ -1312,10 +1318,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->powers[pw_ingoop] = 2;
- if (player->pflags & PF_ITEMHANG)
+ if (player->powers[pw_carry] == CR_GENERIC)
{
P_SetTarget(&toucher->tracer, NULL);
- player->pflags &= ~PF_ITEMHANG;
+ player->powers[pw_carry] = CR_NONE;
}
P_ResetPlayer(player);
@@ -1367,7 +1373,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, special->info->painsound);
return;
}
- else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
+ else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
+ || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE))
+ || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
+ || (player->pflags & (PF_SPINNING|PF_GLIDING))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{
// Shatter the shield!
@@ -1397,7 +1406,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_BIGMACECHAIN:
// Is this the last link in the chain?
if (toucher->momz > 0 || !(special->flags & MF_AMBUSH)
- || (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN))
+ || (player->powers[pw_carry]))
return;
if (toucher->z > special->z + special->height/2)
@@ -1414,12 +1423,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING))
{
- player->pflags |= PF_MACESPIN;
+ player->powers[pw_carry] = CR_MACESPIN;
S_StartSound(toucher, sfx_spin);
P_SetPlayerMobjState(toucher, S_PLAY_SPIN);
}
else
- player->pflags |= PF_ITEMHANG;
+ player->powers[pw_carry] = CR_GENERIC;
// Can't jump first frame
player->pflags |= PF_JUMPSTASIS;
@@ -1654,8 +1663,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
}
else switch (source->type)
{
- case MT_EGGMANICO:
- case MT_EGGMANBOX:
+ case MT_EGGMAN_ICON:
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
break;
case MT_SPIKE:
@@ -2325,7 +2333,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->momx = target->momy = target->momz = 0;
if (damagetype == DMG_DROWNED) // drowned
{
- S_StartSound(target, sfx_drown);
+ target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack.
+ if (target->player->charflags & SF_MACHINE)
+ S_StartSound(target, sfx_fizzle);
+ else
+ S_StartSound(target, sfx_drown);
// Don't jump up when drowning
}
else
@@ -2544,7 +2556,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
}
player->powers[pw_flashing] = flashingtics;
- P_SetMobjState(target->tracer, S_NIGHTSHURT1);
+ P_SetPlayerMobjState(target, S_PLAY_NIGHTS_PAIN);
S_StartSound(target, sfx_nghurt);
if (oldnightstime > 10*TICRATE
@@ -2671,7 +2683,9 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
{
- player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE);
+ player->pflags &= ~(PF_SLIDING|PF_NIGHTSMODE);
+
+ player->powers[pw_carry] = CR_NONE;
// Burst weapons and emeralds in Match/CTF only
if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF))
@@ -2946,10 +2960,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!force)
{
// Special case for team ring boxes
- if (target->type == MT_REDRINGBOX && !(source->player->ctfteam == 1))
+ if (target->type == MT_RING_REDBOX && !(source->player->ctfteam == 1))
return false;
- if (target->type == MT_BLUERINGBOX && !(source->player->ctfteam == 2))
+ if (target->type == MT_RING_BLUEBOX && !(source->player->ctfteam == 2))
return false;
}
@@ -3736,7 +3750,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
// Flag text
{
char plname[MAXPLAYERNAME+4];
- char *flagtext;
+ const char *flagtext;
char flagcolor;
snprintf(plname, sizeof(plname), "%s%s%s",
diff --git a/src/p_local.h b/src/p_local.h
index f90ad2fab..71f7fda5b 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -62,6 +62,9 @@
#define mariomode (maptol & TOL_MARIO)
#define twodlevel (maptol & TOL_2D)
+#define P_GetPlayerHeight(player) FixedMul(player->height, player->mo->scale)
+#define P_GetPlayerSpinHeight(player) FixedMul(player->spinheight, player->mo->scale)
+
//
// P_TICK
//
@@ -119,8 +122,6 @@ extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed;
extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
-fixed_t P_GetPlayerHeight(player_t *player);
-fixed_t P_GetPlayerSpinHeight(player_t *player);
INT32 P_GetPlayerControlDirection(player_t *player);
void P_AddPlayerScore(player_t *player, UINT32 amount);
void P_StealPlayerScore(player_t *player, UINT32 amount);
@@ -241,6 +242,8 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
boolean P_CheckDeathPitCollide(mobj_t *mo);
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
+mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type);
+
mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type);
mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z);
mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z);
@@ -252,7 +255,8 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype
#endif
void P_ColorTeamMissile(mobj_t *missile, player_t *source);
SINT8 P_MobjFlip(mobj_t *mobj);
-boolean P_WeaponOrPanel(mobjtype_t type);
+fixed_t P_GetMobjGravity(mobj_t *mo);
+FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled);
diff --git a/src/p_map.c b/src/p_map.c
index 668ba19c2..f00cacef6 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -129,6 +129,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
return false;
}
+#ifdef ESLOPE
+ object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you.
+#endif
+
object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
@@ -207,7 +211,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring
{
- if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL)
+ if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL))
object->player->pflags = pflags;
else
P_SetPlayerMobjState(object, S_PLAY_WALK);
@@ -232,20 +236,24 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
return;
- // is object below thruster's position? if not, calculate distance between their bottoms
+ // is object's top below thruster's position? if not, calculate distance between their bottoms
if (spring->eflags & MFE_VERTICALFLIP)
{
- if (object->z + object->height > spring->z + spring->height)
+ if (object->z > spring->z + spring->height)
return;
zdist = (spring->z + spring->height) - (object->z + object->height);
}
else
{
- if (object->z < spring->z)
+ if (object->z + object->height < spring->z)
return;
zdist = object->z - spring->z;
}
+#ifdef ESLOPE
+ object->standingslope = NULL; // No launching off at silly angles for you.
+#endif
+
switch (spring->type)
{
case MT_FAN: // fan
@@ -294,12 +302,17 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
INT32 p;
fixed_t zdist; // z distance between the two players' bottoms
- if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo)
+ if (tails->powers[pw_carry])
return;
- if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo)
+ if (sonic->powers[pw_carry])
return;
- if (!tails->powers[pw_tailsfly] && !(tails->charability == CA_FLY && tails->mo->state-states == S_PLAY_FLY_TIRED))
+ if (tails->spectator)
+ return;
+ if (sonic->spectator)
+ return;
+
+ if (!(tails->pflags & PF_CANCARRY))
return;
if (tails->bot == 1)
@@ -308,10 +321,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if (sonic->pflags & PF_NIGHTSMODE)
return;
- if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT
- && !(sonic->pflags & PF_ROPEHANG))
- return; // don't steal players from zoomtubes!
-
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
return; // Both should be in same gravity
@@ -326,47 +335,43 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
// Search in case another player is already being carried by this fox.
for (p = 0; p < MAXPLAYERS; p++)
if (playeringame[p] && players[p].mo
- && players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo)
+ && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo)
return;
+ // Why block opposing teams from tailsflying each other?
+ // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
+ /*
+ if (gametype == GT_RACE || gametype == GT_COMPETITION
+ || (netgame && (tails->spectator || sonic->spectator))
+ || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
+ || (gametype == GT_MATCH)
+ || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
+ return; */
+
if (tails->mo->eflags & MFE_VERTICALFLIP)
zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height);
else
zdist = tails->mo->z - sonic->mo->z;
- if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale)
+ if (zdist <= sonic->mo->height + sonic->mo->scale // FixedMul(FRACUNIT, sonic->mo->scale), but scale == FRACUNIT by default
&& zdist > sonic->mo->height*2/3
&& P_MobjFlip(tails->mo)*sonic->mo->momz <= 0)
{
- // Why block opposing teams from tailsflying each other?
- // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
- /*
- if (gametype == GT_RACE || gametype == GT_COMPETITION
- || (netgame && (tails->spectator || sonic->spectator))
- || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
- || (gametype == GT_MATCH)
- || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
- sonic->pflags &= ~PF_CARRIED; */
- if (tails->spectator || sonic->spectator)
- sonic->pflags &= ~PF_CARRIED;
- else
- {
- if (sonic-players == consoleplayer && botingame)
- CV_SetValue(&cv_analog2, false);
- P_ResetPlayer(sonic);
- P_SetTarget(&sonic->mo->tracer, tails->mo);
- sonic->pflags |= PF_CARRIED;
- S_StartSound(sonic->mo, sfx_s3k4a);
- P_UnsetThingPosition(sonic->mo);
- sonic->mo->x = tails->mo->x;
- sonic->mo->y = tails->mo->y;
- P_SetThingPosition(sonic->mo);
- }
+ if (sonic-players == consoleplayer && botingame)
+ CV_SetValue(&cv_analog2, false);
+ P_ResetPlayer(sonic);
+ P_SetTarget(&sonic->mo->tracer, tails->mo);
+ sonic->powers[pw_carry] = CR_PLAYER;
+ S_StartSound(sonic->mo, sfx_s3k4a);
+ P_UnsetThingPosition(sonic->mo);
+ sonic->mo->x = tails->mo->x;
+ sonic->mo->y = tails->mo->y;
+ P_SetThingPosition(sonic->mo);
}
else {
if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
- sonic->pflags &= ~PF_CARRIED;
+ sonic->powers[pw_carry] = CR_NONE;
}
}
@@ -435,7 +440,42 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // underneath
if (thing->type == MT_SPIKE)
{
- S_StartSound(tmthing, thing->info->deathsound);
+ if (thing->flags & MF_SOLID)
+ S_StartSound(tmthing, thing->info->deathsound);
+ for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
+ if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
+ P_KillMobj(thing, tmthing, tmthing, 0);
+ }
+ else
+ {
+ thing->health = 0;
+ P_KillMobj(thing, tmthing, tmthing, 0);
+ }
+ return true;
+ }
+
+ // CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
+ if ((tmthing->player)
+ && (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
+ && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
+ || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
+ || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
+ && (thing->type == MT_SPIKE))))
+ {
+ if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
+ return true;
+ blockdist = thing->radius + tmthing->radius;
+ if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
+ return true; // didn't hit it
+ // see if it went over / under
+ if (tmthing->z > thing->z + thing->height)
+ return true; // overhead
+ if (tmthing->z + tmthing->height < thing->z)
+ return true; // underneath
+ if (thing->type == MT_SPIKE)
+ {
+ if (thing->flags & MF_SOLID)
+ S_StartSound(tmthing, thing->info->deathsound);
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
P_KillMobj(thing, tmthing, tmthing, 0);
@@ -623,7 +663,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player
&& thing->player->ctfteam == tmthing->target->player->ctfteam
- && thing->player->pflags & PF_CARRIED && thing->tracer == tmthing->target)
+ && thing->player->powers[pw_carry] == CR_PLAYER && thing->tracer == tmthing->target)
return true; // Don't give rings to your carry player by accident.
if (thing->type == MT_EGGSHIELD)
@@ -666,7 +706,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& tmthing->target != thing)
{
// Hop on the missile for a ride!
- thing->player->pflags |= PF_ITEMHANG;
+ thing->player->powers[pw_carry] = CR_GENERIC;
thing->player->pflags &= ~PF_JUMPED;
P_SetTarget(&thing->tracer, tmthing);
P_SetTarget(&tmthing->target, thing); // Set owner to the player
@@ -685,7 +725,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
- else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->pflags & PF_ITEMHANG) || (thing->player->pflags & PF_JUMPED)))
+ else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->powers[pw_carry] == CR_GENERIC) || (thing->player->pflags & PF_JUMPED)))
{
// Ignore
}
@@ -886,7 +926,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (thing->player) {
if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
- thing->player->pflags &= ~PF_CARRIED;
+ if (thing->player->powers[pw_carry] == CR_PLAYER)
+ thing->player->powers[pw_carry] = CR_NONE;
}
if (thing->player)
@@ -938,7 +979,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{
if (thing->flags & MF_MONITOR
- && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
+ && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
+ || ((tmthing->player->pflags & PF_JUMPED)
+ && !(tmthing->player->charflags & SF_NOJUMPDAMAGE
+ && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
+ || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
+ || ((tmthing->player->charflags & SF_STOMPDAMAGE)
+ && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))))
{
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
@@ -960,8 +1007,15 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
// unless it's a CTF team monitor and you're on the wrong team
- else if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)
- && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
+ else if (thing->flags & MF_MONITOR && tmthing->player
+ && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
+ || ((tmthing->player->pflags & PF_JUMPED)
+ && !(tmthing->player->charflags & SF_NOJUMPDAMAGE
+ && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
+ || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
+ || ((tmthing->player->charflags & SF_STOMPDAMAGE)
+ && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))
+ && !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2)))
;
// z checking at last
// Treat noclip things as non-solid!
@@ -1155,7 +1209,7 @@ static boolean PIT_CheckLine(line_t *ld)
}
// set openrange, opentop, openbottom
- P_LineOpening(ld);
+ P_LineOpening(ld, tmthing);
// adjust floor / ceiling heights
if (opentop < tmceilingz)
@@ -1273,7 +1327,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
- if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
+ if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER) && !(thing->flags & MF_NOGRAVITY))
{
// If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
@@ -1972,8 +2026,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
}
// Ramp test
- if (thing->player && maxstep > 0
- && !(P_PlayerTouchingSectorSpecial(thing->player, 1, 14) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14))
+ if (maxstep > 0 && !(
+ thing->player && (
+ P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
+ || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
+ )
+ )
{
// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
// step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more.
@@ -2433,6 +2491,8 @@ isblocking:
//
// P_IsClimbingValid
//
+// Unlike P_DoClimbing, don't use when up against a one-sided linedef.
+//
static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{
fixed_t platx, platy;
@@ -2581,7 +2641,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
}
// set openrange, opentop, openbottom
- P_LineOpening(li);
+ P_LineOpening(li, slidemo);
if (openrange < slidemo->height)
goto isblocking; // doesn't fit
@@ -2657,6 +2717,7 @@ isblocking:
// see about climbing on the wall
if (!(checkline->flags & ML_NOCLIMB))
{
+ boolean canclimb;
angle_t climbangle, climbline;
INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li);
@@ -2667,9 +2728,11 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1));
+ canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true);
+
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
- && P_IsClimbingValid(slidemo->player, climbangle))
+ && canclimb)
{
slidemo->angle = climbangle;
if (!demoplayback || P_AnalogMove(slidemo->player))
@@ -3368,7 +3431,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
for (i = 0; i < sector->numattached; i++)
{
sec = §ors[sector->attached[i]];
- for (n = sec->touching_thinglist; n; n = n->m_snext)
+ for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false;
sec->moved = true;
@@ -3380,7 +3443,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do
{
- for (n = sec->touching_thinglist; n; n = n->m_snext)
+ for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
if (!n->visited)
{
n->visited = true;
@@ -3401,12 +3464,12 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
// Mark all things invalid
sector->moved = true;
- for (n = sector->touching_thinglist; n; n = n->m_snext)
+ for (n = sector->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false;
do
{
- for (n = sector->touching_thinglist; n; n = n->m_snext) // go through list
+ for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list
if (!n->visited) // unprocessed thing found
{
n->visited = true; // mark thing as processed
@@ -3430,7 +3493,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
for (i = 0; i < sector->numattached; i++)
{
sec = §ors[sector->attached[i]];
- for (n = sec->touching_thinglist; n; n = n->m_snext)
+ for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false;
sec->moved = true;
@@ -3442,7 +3505,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do
{
- for (n = sec->touching_thinglist; n; n = n->m_snext)
+ for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
if (!n->visited)
{
n->visited = true;
@@ -3460,12 +3523,12 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
// Mark all things invalid
sector->moved = true;
- for (n = sector->touching_thinglist; n; n = n->m_snext)
+ for (n = sector->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false;
do
{
- for (n = sector->touching_thinglist; n; n = n->m_snext) // go through list
+ for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list
if (!n->visited) // unprocessed thing found
{
n->visited = true; // mark thing as processed
@@ -3505,7 +3568,7 @@ static msecnode_t *P_GetSecnode(void)
if (headsecnode)
{
node = headsecnode;
- headsecnode = headsecnode->m_snext;
+ headsecnode = headsecnode->m_thinglist_next;
}
else
node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL);
@@ -3519,7 +3582,7 @@ static mprecipsecnode_t *P_GetPrecipSecnode(void)
if (headprecipsecnode)
{
node = headprecipsecnode;
- headprecipsecnode = headprecipsecnode->m_snext;
+ headprecipsecnode = headprecipsecnode->m_thinglist_next;
}
else
node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL);
@@ -3530,14 +3593,14 @@ static mprecipsecnode_t *P_GetPrecipSecnode(void)
static inline void P_PutSecnode(msecnode_t *node)
{
- node->m_snext = headsecnode;
+ node->m_thinglist_next = headsecnode;
headsecnode = node;
}
// Tails 08-25-2002
static inline void P_PutPrecipSecnode(mprecipsecnode_t *node)
{
- node->m_snext = headprecipsecnode;
+ node->m_thinglist_next = headprecipsecnode;
headprecipsecnode = node;
}
@@ -3558,7 +3621,7 @@ static msecnode_t *P_AddSecnode(sector_t *s, mobj_t *thing, msecnode_t *nextnode
node->m_thing = thing; // Yes. Setting m_thing says 'keep it'.
return nextnode;
}
- node = node->m_tnext;
+ node = node->m_sectorlist_next;
}
// Couldn't find an existing node for this sector. Add one at the head
@@ -3571,17 +3634,17 @@ static msecnode_t *P_AddSecnode(sector_t *s, mobj_t *thing, msecnode_t *nextnode
node->m_sector = s; // sector
node->m_thing = thing; // mobj
- node->m_tprev = NULL; // prev node on Thing thread
- node->m_tnext = nextnode; // next node on Thing thread
+ node->m_sectorlist_prev = NULL; // prev node on Thing thread
+ node->m_sectorlist_next = nextnode; // next node on Thing thread
if (nextnode)
- nextnode->m_tprev = node; // set back link on Thing
+ nextnode->m_sectorlist_prev = node; // set back link on Thing
// Add new node at head of sector thread starting at s->touching_thinglist
- node->m_sprev = NULL; // prev node on sector thread
- node->m_snext = s->touching_thinglist; // next node on sector thread
+ node->m_thinglist_prev = NULL; // prev node on sector thread
+ node->m_thinglist_next = s->touching_thinglist; // next node on sector thread
if (s->touching_thinglist)
- node->m_snext->m_sprev = node;
+ node->m_thinglist_next->m_thinglist_prev = node;
s->touching_thinglist = node;
return node;
}
@@ -3599,7 +3662,7 @@ static mprecipsecnode_t *P_AddPrecipSecnode(sector_t *s, precipmobj_t *thing, mp
node->m_thing = thing; // Yes. Setting m_thing says 'keep it'.
return nextnode;
}
- node = node->m_tnext;
+ node = node->m_sectorlist_next;
}
// Couldn't find an existing node for this sector. Add one at the head
@@ -3612,17 +3675,17 @@ static mprecipsecnode_t *P_AddPrecipSecnode(sector_t *s, precipmobj_t *thing, mp
node->m_sector = s; // sector
node->m_thing = thing; // mobj
- node->m_tprev = NULL; // prev node on Thing thread
- node->m_tnext = nextnode; // next node on Thing thread
+ node->m_sectorlist_prev = NULL; // prev node on Thing thread
+ node->m_sectorlist_next = nextnode; // next node on Thing thread
if (nextnode)
- nextnode->m_tprev = node; // set back link on Thing
+ nextnode->m_sectorlist_prev = node; // set back link on Thing
// Add new node at head of sector thread starting at s->touching_thinglist
- node->m_sprev = NULL; // prev node on sector thread
- node->m_snext = s->touching_preciplist; // next node on sector thread
+ node->m_thinglist_prev = NULL; // prev node on sector thread
+ node->m_thinglist_next = s->touching_preciplist; // next node on sector thread
if (s->touching_preciplist)
- node->m_snext->m_sprev = node;
+ node->m_thinglist_next->m_thinglist_prev = node;
s->touching_preciplist = node;
return node;
}
@@ -3644,24 +3707,24 @@ static msecnode_t *P_DelSecnode(msecnode_t *node)
// Unlink from the Thing thread. The Thing thread begins at
// sector_list and not from mobj_t->touching_sectorlist.
- tp = node->m_tprev;
- tn = node->m_tnext;
+ tp = node->m_sectorlist_prev;
+ tn = node->m_sectorlist_next;
if (tp)
- tp->m_tnext = tn;
+ tp->m_sectorlist_next = tn;
if (tn)
- tn->m_tprev = tp;
+ tn->m_sectorlist_prev = tp;
// Unlink from the sector thread. This thread begins at
// sector_t->touching_thinglist.
- sp = node->m_sprev;
- sn = node->m_snext;
+ sp = node->m_thinglist_prev;
+ sn = node->m_thinglist_next;
if (sp)
- sp->m_snext = sn;
+ sp->m_thinglist_next = sn;
else
node->m_sector->touching_thinglist = sn;
if (sn)
- sn->m_sprev = sp;
+ sn->m_thinglist_prev = sp;
// Return this node to the freelist
@@ -3683,24 +3746,24 @@ static mprecipsecnode_t *P_DelPrecipSecnode(mprecipsecnode_t *node)
// Unlink from the Thing thread. The Thing thread begins at
// sector_list and not from mobj_t->touching_sectorlist.
- tp = node->m_tprev;
- tn = node->m_tnext;
+ tp = node->m_sectorlist_prev;
+ tn = node->m_sectorlist_next;
if (tp)
- tp->m_tnext = tn;
+ tp->m_sectorlist_next = tn;
if (tn)
- tn->m_tprev = tp;
+ tn->m_sectorlist_prev = tp;
// Unlink from the sector thread. This thread begins at
// sector_t->touching_thinglist.
- sp = node->m_sprev;
- sn = node->m_snext;
+ sp = node->m_thinglist_prev;
+ sn = node->m_thinglist_next;
if (sp)
- sp->m_snext = sn;
+ sp->m_thinglist_next = sn;
else
node->m_sector->touching_preciplist = sn;
if (sn)
- sn->m_sprev = sp;
+ sn->m_thinglist_prev = sp;
// Return this node to the freelist
@@ -3815,7 +3878,7 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
while (node)
{
node->m_thing = NULL;
- node = node->m_tnext;
+ node = node->m_sectorlist_next;
}
P_SetTarget(&tmthing, thing);
@@ -3853,11 +3916,11 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
if (!node->m_thing)
{
if (node == sector_list)
- sector_list = node->m_tnext;
+ sector_list = node->m_sectorlist_next;
node = P_DelSecnode(node);
}
else
- node = node->m_tnext;
+ node = node->m_sectorlist_next;
}
/* cph -
@@ -3898,7 +3961,7 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
while (node)
{
node->m_thing = NULL;
- node = node->m_tnext;
+ node = node->m_sectorlist_next;
}
tmprecipthing = thing;
@@ -3932,11 +3995,11 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
if (!node->m_thing)
{
if (node == precipsector_list)
- precipsector_list = node->m_tnext;
+ precipsector_list = node->m_sectorlist_next;
node = P_DelPrecipSecnode(node);
}
else
- node = node->m_tnext;
+ node = node->m_sectorlist_next;
}
/* cph -
diff --git a/src/p_maputl.c b/src/p_maputl.c
index c3a6fa842..fea8530a1 100644
--- a/src/p_maputl.c
+++ b/src/p_maputl.c
@@ -489,7 +489,7 @@ void P_CameraLineOpening(line_t *linedef)
}
}
-void P_LineOpening(line_t *linedef)
+void P_LineOpening(line_t *linedef, mobj_t *mobj)
{
sector_t *front, *back;
@@ -520,8 +520,8 @@ void P_LineOpening(line_t *linedef)
{ // Set open and high/low values here
fixed_t frontheight, backheight;
- frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef);
- backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef);
+ frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
+ backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
if (frontheight < backheight)
{
@@ -540,8 +540,8 @@ void P_LineOpening(line_t *linedef)
#endif
}
- frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef);
- backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef);
+ frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
+ backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
if (frontheight > backheight)
{
@@ -561,12 +561,14 @@ void P_LineOpening(line_t *linedef)
}
}
- if (tmthing)
+ if (mobj)
{
- fixed_t thingtop = tmthing->z + tmthing->height;
+ fixed_t thingtop = mobj->z + mobj->height;
// Check for collision with front side's midtexture if Effect 4 is set
- if (linedef->flags & ML_EFFECT4) {
+ if (linedef->flags & ML_EFFECT4
+ && !linedef->polyobj // don't do anything for polyobjects! ...for now
+ ) {
side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight;
fixed_t texmid, delta1, delta2;
@@ -575,30 +577,38 @@ void P_LineOpening(line_t *linedef)
texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries
-#ifdef POLYOBJECTS
+#if 0 // #ifdef POLYOBJECTS
+ // don't remove this code unless solid midtextures
+ // on non-solid polyobjects should NEVER happen in the future
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
- if (linedef->flags & ML_DONTPEGBOTTOM) {
+ if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
+ texbottom = back->floorheight + side->rowoffset;
+ textop = back->ceilingheight + side->rowoffset;
+ } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
texbottom = back->floorheight + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1);
} else {
- textop = back->ceilingheight - side->rowoffset;
+ textop = back->ceilingheight + side->rowoffset;
texbottom = textop - texheight*(side->repeatcnt+1);
}
} else
#endif
{
- if (linedef->flags & ML_DONTPEGBOTTOM) {
+ if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
+ texbottom = openbottom + side->rowoffset;
+ textop = opentop + side->rowoffset;
+ } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
texbottom = openbottom + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1);
} else {
- textop = opentop - side->rowoffset;
+ textop = opentop + side->rowoffset;
texbottom = textop - texheight*(side->repeatcnt+1);
}
}
texmid = texbottom+(textop-texbottom)/2;
- delta1 = abs(tmthing->z - texmid);
+ delta1 = abs(mobj->z - texmid);
delta2 = abs(thingtop - texmid);
if (delta1 > delta2) { // Below
@@ -636,16 +646,16 @@ void P_LineOpening(line_t *linedef)
if (!(rover->flags & FF_EXISTS))
continue;
- if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover)))
+ if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
;
- else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player)
- || (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
+ else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
+ || (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
- topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef);
- bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef);
+ topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
+ bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
- delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
+ delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
@@ -680,16 +690,16 @@ void P_LineOpening(line_t *linedef)
if (!(rover->flags & FF_EXISTS))
continue;
- if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover)))
+ if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
;
- else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player)
- || (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
+ else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
+ || (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
- topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef);
- bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef);
+ topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
+ bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
- delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
+ delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
@@ -723,7 +733,7 @@ void P_LineOpening(line_t *linedef)
{
const sector_t *polysec = linedef->backsector;
- delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
+ delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
lowestceiling = polysec->floorheight;
diff --git a/src/p_maputl.h b/src/p_maputl.h
index c160bfa28..3d74e927b 100644
--- a/src/p_maputl.h
+++ b/src/p_maputl.h
@@ -59,7 +59,7 @@ extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
extern pslope_t *opentopslope, *openbottomslope;
#endif
-void P_LineOpening(line_t *plinedef);
+void P_LineOpening(line_t *plinedef, mobj_t *mobj);
boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *));
boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *));
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 9be9dc85a..c69bf474d 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -163,6 +163,16 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state);
#endif
+ // Catch falling for nojumpspin
+ if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0))
+ return P_SetPlayerMobjState(mobj, S_PLAY_FALL);
+
+ // Catch swimming versus flying
+ if (state == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER)
+ return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM);
+ else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
+ return P_SetPlayerMobjState(player->mo, S_PLAY_FLY);
+
// Catch state changes for Super Sonic
if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS))
{
@@ -175,6 +185,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_WALK);
case S_PLAY_RUN:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_RUN);
+ case S_PLAY_PEEL:
+ return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PEEL);
case S_PLAY_PAIN:
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PAIN);
case S_PLAY_DEAD:
@@ -231,18 +243,24 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
case S_PLAY_SUPER_RUN:
player->panim = PA_RUN;
break;
+ case S_PLAY_PEEL:
+ case S_PLAY_SUPER_PEEL:
+ player->panim = PA_PEEL;
+ break;
case S_PLAY_PAIN:
case S_PLAY_SUPER_PAIN:
case S_PLAY_SUPER_STUN:
player->panim = PA_PAIN;
break;
case S_PLAY_SPIN:
- case S_PLAY_DASH:
- case S_PLAY_JUMP:
+ //case S_PLAY_DASH: -- everyone can ROLL thanks to zoom tubes...
case S_PLAY_SUPER_SPIN:
- case S_PLAY_SUPER_JUMP:
player->panim = PA_ROLL;
break;
+ case S_PLAY_JUMP:
+ case S_PLAY_SUPER_JUMP:
+ player->panim = PA_JUMP;
+ break;
case S_PLAY_SPRING:
case S_PLAY_SUPER_SPRING:
player->panim = PA_SPRING;
@@ -252,9 +270,16 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
player->panim = PA_FALL;
break;
case S_PLAY_FLY:
+ case S_PLAY_SWIM:
case S_PLAY_GLIDE:
+ case S_PLAY_TWINSPIN:
player->panim = PA_ABILITY;
break;
+ case S_PLAY_DASH: // ...but the act of SPINDASHING is charability2 specific.
+ case S_PLAY_MELEE:
+ case S_PLAY_MELEE_FINISH:
+ player->panim = PA_ABILITY2;
+ break;
case S_PLAY_RIDE:
case S_PLAY_SUPER_RIDE:
player->panim = PA_RIDE;
@@ -285,15 +310,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
// Adjust the player's animation speed to match their velocity.
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
{
- fixed_t speed = FixedDiv(player->speed, mobj->scale);
- if (player->panim == PA_ROLL)
- {
- if (speed > 16<tics = 1;
- else
- mobj->tics = 2;
- }
- else if (player->panim == PA_FALL)
+ fixed_t speed;// = FixedDiv(player->speed, mobj->scale);
+ if (player->panim == PA_FALL)
{
speed = FixedDiv(abs(mobj->momz), mobj->scale);
if (speed < 10<tics = 1;
}
- else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying.
+ else if (player->panim == PA_ABILITY2 && player->charability2 == CA2_SPINDASH)
{
- if (player->panim == PA_WALK)
+ fixed_t step = (player->maxdash - player->mindash)/4;
+ speed = (player->dashspeed - player->mindash);
+ if (speed > 3*step)
+ mobj->tics = 1;
+ else if (speed > step)
+ mobj->tics = 2;
+ else
+ mobj->tics = 3;
+ }
+ else
+ {
+ speed = FixedDiv(player->speed, mobj->scale);
+ if (player->panim == PA_ROLL || player->panim == PA_JUMP)
{
- if (speed > 12<tics = 2;
- else if (speed > 6<tics = 3;
- else
- mobj->tics = 4;
- }
- else if (player->panim == PA_RUN)
- {
- if (speed > 52< 16<tics = 1;
else
mobj->tics = 2;
}
+ else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying.
+ {
+ if (player->panim == PA_WALK)
+ {
+ if (speed > 12<tics = 2;
+ else if (speed > 6<tics = 3;
+ else
+ mobj->tics = 4;
+ }
+ else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL))
+ {
+ if (speed > 52<tics = 1;
+ else
+ mobj->tics = 2;
+ }
+ }
}
}
+ mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
+
// Player animations
if (st->sprite == SPR_PLAY)
{
+ skin_t *skin = ((skin_t *)mobj->skin);
boolean noalt = false;
UINT8 spr2 = st->frame & FF_FRAMEMASK;
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
- mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
+ UINT8 numframes;
- while (((skin_t *)mobj->skin)->sprites[spr2].numframes <= 0
+ while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0)
&& spr2 != SPR2_STND)
{
switch(spr2)
{
+ case SPR2_PEEL:
+ spr2 = SPR2_RUN;
+ break;
case SPR2_RUN:
spr2 = SPR2_WALK;
break;
@@ -352,7 +398,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
spr2 = SPR2_SPNG;
break;
case SPR2_JUMP:
- spr2 = SPR2_SPIN;
+ spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN;
break;
case SPR2_SPNG: // spring
spr2 = SPR2_FALL;
@@ -367,23 +413,29 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
case SPR2_FLY:
spr2 = SPR2_SPNG;
break;
- case SPR2_TIRE:
+ case SPR2_SWIM:
spr2 = SPR2_FLY;
break;
+ case SPR2_TIRE:
+ spr2 = (player->charability == CA_FLY) ? SPR2_FLY : SPR2_SWIM;
+ break;
case SPR2_GLID:
spr2 = SPR2_FLY;
break;
case SPR2_CLMB:
- spr2 = SPR2_WALK;
+ spr2 = SPR2_SPIN;
break;
case SPR2_CLNG:
spr2 = SPR2_CLMB;
break;
- case SPR2_SIGN:
- case SPR2_LIFE:
- noalt = true;
+ case SPR2_TWIN:
+ spr2 = SPR2_SPIN;
+ break;
+
+ case SPR2_MLEE:
+ spr2 = SPR2_TWIN;
break;
// Super sprites fallback to regular sprites
@@ -393,10 +445,13 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
case SPR2_SRUN:
spr2 = SPR2_RUN;
break;
+ case SPR2_SPEE:
+ spr2 = SPR2_PEEL;
+ break;
case SPR2_SPAN:
spr2 = SPR2_PAIN;
break;
- case SPR2_SMSL:
+ case SPR2_SSTN:
spr2 = SPR2_SPAN;
break;
case SPR2_SDTH:
@@ -412,7 +467,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
spr2 = SPR2_GASP;
break;
case SPR2_SJMP:
- spr2 = SPR2_JUMP;
+ spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN;
break;
case SPR2_SSPG:
spr2 = SPR2_SPNG;
@@ -430,6 +485,87 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
spr2 = SPR2_SWLK;
break;
+ // NiGHTS sprites.
+ case SPR2_NTRN:
+ spr2 = SPR2_TRNS;
+ break;
+ case SPR2_NSTD:
+ spr2 = SPR2_SSTD;
+ break;
+ case SPR2_NFLT:
+ spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice.
+ break;
+ case SPR2_NPUL:
+ spr2 = SPR2_NFLT;
+ break;
+ case SPR2_NPAN:
+ spr2 = SPR2_NPUL;
+ break;
+ case SPR2_NATK:
+ spr2 = SPR2_SSPN;
+ break;
+ /*case SPR2_NGT0:
+ spr2 = SPR2_STND;
+ break;*/
+ case SPR2_NGT1:
+ case SPR2_NGT7:
+ case SPR2_DRL0:
+ spr2 = SPR2_NGT0;
+ break;
+ case SPR2_NGT2:
+ case SPR2_DRL1:
+ spr2 = SPR2_NGT1;
+ break;
+ case SPR2_NGT3:
+ case SPR2_DRL2:
+ spr2 = SPR2_NGT2;
+ break;
+ case SPR2_NGT4:
+ case SPR2_DRL3:
+ spr2 = SPR2_NGT3;
+ break;
+ case SPR2_NGT5:
+ case SPR2_DRL4:
+ spr2 = SPR2_NGT4;
+ break;
+ case SPR2_NGT6:
+ case SPR2_DRL5:
+ spr2 = SPR2_NGT5;
+ break;
+ case SPR2_DRL6:
+ spr2 = SPR2_NGT6;
+ break;
+ case SPR2_NGT8:
+ case SPR2_DRL7:
+ spr2 = SPR2_NGT7;
+ break;
+ case SPR2_NGT9:
+ case SPR2_DRL8:
+ spr2 = SPR2_NGT8;
+ break;
+ case SPR2_NGTA:
+ case SPR2_DRL9:
+ spr2 = SPR2_NGT9;
+ break;
+ case SPR2_NGTB:
+ case SPR2_DRLA:
+ spr2 = SPR2_NGTA;
+ break;
+ case SPR2_NGTC:
+ case SPR2_DRLB:
+ spr2 = SPR2_NGTB;
+ break;
+ case SPR2_DRLC:
+ spr2 = SPR2_NGTC;
+ break;
+
+
+ // Sprites for non-player objects? There's nothing we can do.
+ case SPR2_SIGN:
+ case SPR2_LIFE:
+ noalt = true;
+ break;
+
// Dunno? Just go to standing then.
default:
spr2 = SPR2_STND;
@@ -439,24 +575,54 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
break;
}
+ if (!skin)
+ {
+ frame = 0;
+ numframes = 0;
+ }
+
if (mobj->sprite != SPR_PLAY)
{
mobj->sprite = SPR_PLAY;
frame = 0;
}
else if (mobj->sprite2 != spr2)
- frame = 0;
+ {
+ if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2))
+ frame = numframes/2;
+ else
+ frame = 0;
+ }
+
+ if (frame >= numframes)
+ {
+ if (st->frame & FF_SPR2ENDSTATE) // no frame advancement
+ {
+ if (st->var1 == S_NULL)
+ frame--;
+ else
+ {
+ if (mobj->frame & FF_FRAMEMASK)
+ mobj->frame--;
+ return P_SetPlayerMobjState(mobj, st->var1);
+ }
+ }
+ else
+ frame = 0;
+ }
mobj->sprite2 = spr2;
- if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes)
- frame = 0;
mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
+ if (mobj->color >= MAXSKINCOLORS && mobj->color < MAXTRANSLATIONS) // Super colours? Super bright!
+ mobj->frame |= FF_FULLBRIGHT;
}
// Regular sprites
else
{
mobj->sprite = st->sprite;
mobj->frame = st->frame;
+ if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE))
+ mobj->frame += P_RandomKey(st->var1+1);
}
// Modified handling.
@@ -528,18 +694,41 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
// Player animations
if (st->sprite == SPR_PLAY)
{
+ skin_t *skin = ((skin_t *)mobj->skin);
UINT8 spr2 = st->frame & FF_FRAMEMASK;
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
+ UINT8 numframes;
+
+ if (skin)
+ numframes = skin->sprites[spr2].numframes;
+ else
+ {
+ frame = 0;
+ numframes = 0;
+ }
+
if (mobj->sprite != SPR_PLAY)
{
mobj->sprite = SPR_PLAY;
frame = 0;
}
else if (mobj->sprite2 != spr2)
- frame = 0;
+ {
+ if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2))
+ frame = numframes/2;
+ else
+ frame = 0;
+ }
+
+ if (frame >= numframes)
+ {
+ if (st->frame & FF_SPR2ENDSTATE)
+ return P_SetPlayerMobjState(mobj, st->var1); // Differs from P_SetPlayerMobjState - allows object to be removed via S_NULL
+ else
+ frame = 0;
+ }
+
mobj->sprite2 = spr2;
- if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes)
- frame = 0;
mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
}
// Regular sprites
@@ -547,6 +736,8 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
{
mobj->sprite = st->sprite;
mobj->frame = st->frame;
+ if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE))
+ mobj->frame += P_RandomKey(st->var1+1);
}
// Modified handling.
@@ -1425,13 +1616,12 @@ static void P_PlayerFlip(mobj_t *mo)
}
//
-// P_CheckGravity
+// P_GetMobjGravity
//
-// Checks the current gravity state
-// of the object. If affect is true,
-// a gravity force will be applied.
+// Returns the current gravity
+// value of the object.
//
-void P_CheckGravity(mobj_t *mo, boolean affect)
+fixed_t P_GetMobjGravity(mobj_t *mo)
{
fixed_t gravityadd = 0;
boolean no3dfloorgrav = true; // Custom gravity
@@ -1452,25 +1642,23 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
- if (!(rover->flags & FF_EXISTS))
+ if (!(rover->flags & FF_EXISTS) || !P_InsideANonSolidFFloor(mo, rover)) // P_InsideANonSolidFFloor checks for FF_EXISTS itself, but let's not always call this function
continue;
- if (P_InsideANonSolidFFloor(mo, rover))
- {
- if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER))
- goopgravity = true;
- if (rover->master->frontsector->gravity)
- {
- gravityadd = -FixedMul(gravity,
- (FixedDiv(*rover->master->frontsector->gravity>>FRACBITS, 1000)));
+ if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER))
+ goopgravity = true;
- if (rover->master->frontsector->verticalflip && gravityadd > 0)
- mo->eflags |= MFE_VERTICALFLIP;
+ if (!(rover->master->frontsector->gravity))
+ continue;
- no3dfloorgrav = false;
- break;
- }
- }
+ gravityadd = -FixedMul(gravity,
+ (FixedDiv(*rover->master->frontsector->gravity>>FRACBITS, 1000)));
+
+ if (rover->master->frontsector->verticalflip && gravityadd > 0)
+ mo->eflags |= MFE_VERTICALFLIP;
+
+ no3dfloorgrav = false;
+ break;
}
}
@@ -1490,33 +1678,22 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (mo->eflags & MFE_UNDERWATER && !goopgravity)
gravityadd = gravityadd/3;
- if (!mo->momz) // mobj at stop, no floor, so feel the push of gravity!
- gravityadd <<= 1;
-
if (mo->player)
{
- if (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
- || mo->state-states == S_PLAY_FLY_TIRED))
- gravityadd = gravityadd/3; // less gravity while flying
- if (mo->player->pflags & PF_GLIDING)
- gravityadd = gravityadd/3; // less gravity while gliding
- if (mo->player->climbing)
- gravityadd = 0;
- if (mo->player->pflags & PF_NIGHTSMODE)
+ if ((mo->player->pflags & PF_GLIDING)
+ || (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
+ || mo->state-states == S_PLAY_FLY_TIRED)))
+ gravityadd = gravityadd/3; // less gravity while flying/gliding
+ if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE))
gravityadd = 0;
+ 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
{
- UINT8 bits = 0;
- if (mo->flags2 & MF2_OBJECTFLIP)
- bits ^= 1;
- if (mo->player->powers[pw_gravityboots])
- bits ^= 1;
- if (bits & 1)
- {
- gravityadd = -gravityadd;
- mo->eflags ^= MFE_VERTICALFLIP;
- }
+ gravityadd = -gravityadd;
+ mo->eflags ^= MFE_VERTICALFLIP;
}
+ if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way
+ P_PlayerFlip(mo);
}
else
{
@@ -1524,10 +1701,10 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (mo->flags2 & MF2_OBJECTFLIP)
{
mo->eflags |= MFE_VERTICALFLIP;
- if (gravityadd < 0) // Don't sink, only rise up
- gravityadd *= -1;
if (mo->z + mo->height >= mo->ceilingz)
gravityadd = 0;
+ else if (gravityadd < 0) // Don't sink, only rise up
+ gravityadd *= -1;
}
else //Otherwise, sort through the other exceptions.
{
@@ -1573,11 +1750,27 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (goopgravity)
gravityadd = -gravityadd/5;
- if (affect)
- mo->momz += FixedMul(gravityadd, mo->scale);
+ gravityadd = FixedMul(gravityadd, mo->scale);
- if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip)
- P_PlayerFlip(mo);
+ return gravityadd;
+}
+
+//
+// P_CheckGravity
+//
+// Checks the current gravity state
+// of the object. If affect is true,
+// a gravity force will be applied.
+//
+void P_CheckGravity(mobj_t *mo, boolean affect)
+{
+ fixed_t gravityadd = P_GetMobjGravity(mo);
+
+ if (!mo->momz) // mobj at stop, no floor, so feel the push of gravity!
+ gravityadd <<= 1;
+
+ if (affect)
+ mo->momz += gravityadd;
if (mo->type == MT_SKIM && mo->z + mo->momz <= mo->watertop && mo->z >= mo->watertop)
{
@@ -1653,7 +1846,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
&& (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))
#ifdef ESLOPE
- && !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
+ && !(player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && (abs(player->mo->standingslope->zdelta) >= FRACUNIT/2))
#endif
)
{
@@ -1703,7 +1896,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
mo->y += mo->momy;
P_SetThingPosition(mo);
- for (node = mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (!node->m_sector)
break;
@@ -1711,6 +1904,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
if (node->m_sector->ffloors)
{
ffloor_t *rover;
+ fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
@@ -1723,37 +1917,39 @@ static void P_PushableCheckBustables(mobj_t *mo)
if (!rover->master->frontsector->crumblestate)
{
+ topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
+ bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
// Height checks
if (rover->flags & FF_SHATTERBOTTOM)
{
- if (mo->z+mo->momz + mo->height < *rover->bottomheight)
+ if (mo->z+mo->momz + mo->height < bottomheight)
continue;
- if (mo->z+mo->height > *rover->bottomheight)
+ if (mo->z+mo->height > bottomheight)
continue;
}
else if (rover->flags & FF_SPINBUST)
{
- if (mo->z+mo->momz > *rover->topheight)
+ if (mo->z+mo->momz > topheight)
continue;
- if (mo->z+mo->height < *rover->bottomheight)
+ if (mo->z+mo->height < bottomheight)
continue;
}
else if (rover->flags & FF_SHATTER)
{
- if (mo->z+mo->momz > *rover->topheight)
+ if (mo->z+mo->momz > topheight)
continue;
- if (mo->z+mo->momz + mo->height < *rover->bottomheight)
+ if (mo->z+mo->momz + mo->height < bottomheight)
continue;
}
else
{
- if (mo->z >= *rover->topheight)
+ if (mo->z >= topheight)
continue;
- if (mo->z+mo->height < *rover->bottomheight)
+ if (mo->z+mo->height < bottomheight)
continue;
}
@@ -1808,8 +2004,6 @@ void P_XYMovement(mobj_t *mo)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
- moved = true;
-
// if it's stopped
if (!mo->momx && !mo->momy)
{
@@ -1866,9 +2060,9 @@ void P_XYMovement(mobj_t *mo)
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
{
// blocked move
+ moved = false;
if (player) {
- moved = false;
if (player->bot)
B_MoveBlocked(player);
}
@@ -1973,7 +2167,7 @@ void P_XYMovement(mobj_t *mo)
else
mo->momx = mo->momy = 0;
}
- else if (player)
+ else
moved = true;
if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;;
@@ -2186,12 +2380,14 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
- && !(rover->flags & FF_REVERSEPLATFORM))
+ && !(rover->flags & FF_REVERSEPLATFORM)
+ && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
{
mo->floorz = topheight;
}
if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
- && !(rover->flags & FF_PLATFORM))
+ && !(rover->flags & FF_PLATFORM)
+ && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
{
mo->ceilingz = bottomheight;
}
@@ -2325,16 +2521,6 @@ static boolean P_ZMovement(mobj_t *mo)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
-#ifdef ESLOPE
- if (mo->standingslope)
- {
- if (mo->flags & MF_NOCLIPHEIGHT)
- mo->standingslope = NULL;
- else if (!P_IsObjectOnGround(mo))
- P_SlopeLaunch(mo);
- }
-#endif
-
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
@@ -2349,6 +2535,16 @@ static boolean P_ZMovement(mobj_t *mo)
}
mo->z += mo->momz;
+#ifdef ESLOPE
+ if (mo->standingslope)
+ {
+ if (mo->flags & MF_NOCLIPHEIGHT)
+ mo->standingslope = NULL;
+ else if (!P_IsObjectOnGround(mo))
+ P_SlopeLaunch(mo);
+ }
+#endif
+
switch (mo->type)
{
case MT_THROWNBOUNCE:
@@ -2418,6 +2614,7 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_BLUETEAMRING:
case MT_FLINGRING:
case MT_FLINGCOIN:
+ case MT_FLINGEMERALD:
// Remove flinged stuff from death pits.
if (P_CheckDeathPitCollide(mo))
{
@@ -2449,7 +2646,6 @@ static boolean P_ZMovement(mobj_t *mo)
if (!(mo->momx || mo->momy || mo->momz))
return true;
break;
- case MT_FLINGEMERALD:
case MT_NIGHTSWING:
if (!(mo->momx || mo->momy || mo->momz))
return true;
@@ -2531,14 +2727,17 @@ static boolean P_ZMovement(mobj_t *mo)
mo->z = mo->floorz;
#ifdef ESLOPE
- P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
- if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) {
- mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
+ if (mo->standingslope) // You're still on the ground; why are we here?
+ {
+ mo->momz = 0;
+ return true;
+ }
- // Reverse quantizing might could use its own function later
- mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle;
- P_QuantizeMomentumToSlope(&mom, mo->standingslope);
- mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle;
+ P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
+ if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
+ {
+ mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
+ P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
}
#endif
@@ -2691,7 +2890,7 @@ static boolean P_ZMovement(mobj_t *mo)
mom.z = tmfloorthing->momz;
#ifdef ESLOPE
- if (mo->standingslope) {
+ if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above.
P_QuantizeMomentumToSlope(&mom, mo->standingslope);
}
#endif
@@ -2876,7 +3075,7 @@ static void P_PlayerZMovement(mobj_t *mo)
msecnode_t *node;
boolean stopmovecut = false;
- for (node = mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
sector_t *sec = node->m_sector;
subsector_t *newsubsec;
@@ -2948,12 +3147,19 @@ static void P_PlayerZMovement(mobj_t *mo)
mo->player->skidtime = TICRATE;
mo->tics = -1;
}
+ else if (mo->player->charability2 == CA2_MELEE && mo->player->panim == PA_ABILITY2)
+ {
+ P_InstaThrust(mo, mo->angle, 0);
+ P_SetPlayerMobjState(mo, S_PLAY_STND);
+ }
else if (mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN)
|| mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED)
{
if (mo->player->cmomx || mo->player->cmomy)
{
- if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
+ if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL)
+ P_SetPlayerMobjState(mo, S_PLAY_PEEL);
+ else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
P_SetPlayerMobjState(mo, S_PLAY_RUN);
else if ((mo->player->rmomx || mo->player->rmomy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
P_SetPlayerMobjState(mo, S_PLAY_WALK);
@@ -2962,6 +3168,8 @@ static void P_PlayerZMovement(mobj_t *mo)
}
else
{
+ if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL)
+ P_SetPlayerMobjState(mo, S_PLAY_PEEL);
if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
P_SetPlayerMobjState(mo, S_PLAY_RUN);
else if ((mo->momx || mo->momy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
@@ -2978,8 +3186,7 @@ static void P_PlayerZMovement(mobj_t *mo)
if (!(mo->player->pflags & PF_GLIDING))
mo->player->pflags &= ~PF_JUMPED;
- mo->player->pflags &= ~PF_THOKKED;
- //mo->player->pflags &= ~PF_GLIDING;
+ mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
mo->player->jumping = 0;
mo->player->secondjump = 0;
mo->player->glidetime = 0;
@@ -3053,7 +3260,7 @@ nightsdone:
if (CheckForMarioBlocks && !(netgame && mo->player->spectator)) // Only let the player punch
{
// Search the touching sectors, from side-to-side...
- for (node = mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
ffloor_t *rover;
if (!node->m_sector->ffloors)
@@ -3242,7 +3449,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{
if (!(player->pflags & PF_NIGHTSMODE) && !player->homing
- && (((player->charability == CA_SWIM) || player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
+ && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
&& !(player->pflags & PF_SLIDING)
&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
@@ -3261,10 +3468,11 @@ void P_MobjCheckWater(mobj_t *mobj)
boolean waterwasnotset = (mobj->watertop == INT32_MAX);
boolean wasinwater = (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER;
boolean wasingoo = (mobj->eflags & MFE_GOOWATER) == MFE_GOOWATER;
- fixed_t thingtop = mobj->z + mobj->height; // especially for players, infotable height does not neccessarily match actual height
+ fixed_t thingtop = mobj->z + mobj->height;
sector_t *sector = mobj->subsector->sector;
ffloor_t *rover;
player_t *p = mobj->player; // Will just be null if not a player.
+ fixed_t height = (p ? P_GetPlayerHeight(p) : mobj->height); // for players, calculation height does not necessarily match actual height for gameplay reasons (spin, etc)
// Default if no water exists.
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
@@ -3293,14 +3501,14 @@ void P_MobjCheckWater(mobj_t *mobj)
if (mobj->eflags & MFE_VERTICALFLIP)
{
- if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale))
+ if (topheight < (thingtop - (height>>1))
|| bottomheight > thingtop)
continue;
}
else
{
if (topheight < mobj->z
- || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale)))
+ || bottomheight > (mobj->z + (height>>1)))
continue;
}
@@ -3309,16 +3517,16 @@ void P_MobjCheckWater(mobj_t *mobj)
mobj->waterbottom = bottomheight;
// Just touching the water?
- if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight)
- || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight))
+ if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - height < bottomheight)
+ || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + height > topheight))
{
mobj->eflags |= MFE_TOUCHWATER;
if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY))
mobj->eflags |= MFE_GOOWATER;
}
// Actually in the water?
- if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight)
- || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight))
+ if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - (height>>1) > bottomheight)
+ || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + (height>>1) < topheight))
{
mobj->eflags |= MFE_UNDERWATER;
if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY))
@@ -3326,6 +3534,10 @@ void P_MobjCheckWater(mobj_t *mobj)
}
}
+ // Spectators and dead players don't get to do any of the things after this.
+ if (p && (p->spectator || p->playerstate != PST_LIVE))
+ return;
+
// Specific things for underwater players
if (p && (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER)
{
@@ -3358,10 +3570,6 @@ void P_MobjCheckWater(mobj_t *mobj)
if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
return;
- // Spectators and dead players also don't count.
- if (p && (p->spectator || p->playerstate != PST_LIVE))
- return;
-
if ((p) // Players
|| (mobj->flags & MF_PUSHABLE) // Pushables
|| ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still
@@ -3369,10 +3577,8 @@ void P_MobjCheckWater(mobj_t *mobj)
{
// Check to make sure you didn't just cross into a sector to jump out of
// that has shallower water than the block you were originally in.
- if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= FixedMul(mobj->info->height, mobj->scale)>>1)
- return;
-
- if ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= FixedMul(mobj->info->height, mobj->scale)>>1)
+ if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1)
+ || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1))
return;
if ((mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water.
@@ -3384,8 +3590,8 @@ void P_MobjCheckWater(mobj_t *mobj)
if (P_MobjFlip(mobj)*mobj->momz < 0)
{
- if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz <= mobj->waterbottom)
- || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz >= mobj->watertop))
+ if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz <= mobj->waterbottom)
+ || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz >= mobj->watertop))
{
// Spawn a splash
mobj_t *splish;
@@ -3418,8 +3624,8 @@ void P_MobjCheckWater(mobj_t *mobj)
}
else if (P_MobjFlip(mobj)*mobj->momz > 0)
{
- if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz > mobj->waterbottom)
- || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz < mobj->watertop))
+ if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz > mobj->waterbottom)
+ || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz < mobj->watertop))
&& !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
{
// Spawn a splash
@@ -3524,10 +3730,10 @@ static void P_SceneryCheckWater(mobj_t *mobj)
#endif
if (topheight <= mobj->z
- || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale)))
+ || bottomheight > (mobj->z + (mobj->height>>1)))
continue;
- if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)
+ if (mobj->z + mobj->height > topheight)
mobj->eflags |= MFE_TOUCHWATER;
else
mobj->eflags &= ~MFE_TOUCHWATER;
@@ -3536,7 +3742,7 @@ static void P_SceneryCheckWater(mobj_t *mobj)
mobj->watertop = topheight;
mobj->waterbottom = bottomheight;
- if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight)
+ if (mobj->z + (mobj->height>>1) < topheight)
mobj->eflags |= MFE_UNDERWATER;
else
mobj->eflags &= ~MFE_UNDERWATER;
@@ -3789,20 +3995,23 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
// Zoom tube
- if (mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT)
+ if (mobj->tracer)
{
- P_UnsetThingPosition(mobj);
- mobj->x += mobj->momx;
- mobj->y += mobj->momy;
- mobj->z += mobj->momz;
- P_SetThingPosition(mobj);
- P_CheckPosition(mobj, mobj->x, mobj->y);
- goto animonly;
- }
- else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer)
- {
- P_CheckPosition(mobj, mobj->x, mobj->y);
- goto animonly;
+ if (mobj->player->powers[pw_carry] == CR_ZOOMTUBE || mobj->player->powers[pw_carry] == CR_ROPEHANG)
+ {
+ P_UnsetThingPosition(mobj);
+ mobj->x += mobj->momx;
+ mobj->y += mobj->momy;
+ mobj->z += mobj->momz;
+ P_SetThingPosition(mobj);
+ P_CheckPosition(mobj, mobj->x, mobj->y);
+ goto animonly;
+ }
+ else if (mobj->player->powers[pw_carry] == CR_MACESPIN)
+ {
+ P_CheckPosition(mobj, mobj->x, mobj->y);
+ goto animonly;
+ }
}
// Needed for gravity boots
@@ -3821,7 +4030,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
if (!(netgame && mobj->player->spectator))
{
// Crumbling platforms
- for (node = mobj->touching_sectorlist; node; node = node->m_snext)
+ for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next)
{
fixed_t topheight, bottomheight;
ffloor_t *rover;
@@ -3846,7 +4055,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
{
boolean thereiswater = false;
- for (node = mobj->touching_sectorlist; node; node = node->m_snext)
+ for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector->ffloors)
{
@@ -3867,7 +4076,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
}
if (thereiswater)
{
- for (node = mobj->touching_sectorlist; node; node = node->m_snext)
+ for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector->ffloors)
{
@@ -3980,7 +4189,7 @@ void P_RecalcPrecipInSector(sector_t *sector)
sector->moved = true; // Recalc lighting and things too, maybe
- for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_snext)
+ for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_thinglist_next)
CalculatePrecipFloor(psecnode->m_thing);
}
@@ -5970,8 +6179,8 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
mobj->scale = newscale;
- mobj->radius = FixedMul(mobj->info->radius, newscale);
- mobj->height = FixedMul(mobj->info->height, newscale);
+ mobj->radius = FixedMul(FixedDiv(mobj->radius, oldscale), newscale);
+ mobj->height = FixedMul(FixedDiv(mobj->height, oldscale), newscale);
player = mobj->player;
@@ -5979,7 +6188,6 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
{
G_GhostAddScale(newscale);
player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it!
- player->dashspeed = FixedMul(FixedDiv(player->dashspeed, oldscale), newscale); // Prevents the player from having to re-charge up spindash if the player grew in size
}
}
@@ -6091,7 +6299,7 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
thing->flags |= MF_NOCLIPHEIGHT;
thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP);
- P_SetScale(thing, thing->target->scale);
+ P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale));
P_UnsetThingPosition(thing);
thing->x = thing->target->x;
thing->y = thing->target->y;
@@ -6802,7 +7010,22 @@ void P_MobjThinker(mobj_t *mobj)
}
}
else // Apply gravity to fall downwards.
- P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true);
+ {
+ if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE))
+ {
+ fixed_t r = mobj->radius>>FRACBITS;
+ mobj_t *explosion = P_SpawnMobj(
+ mobj->x + (P_RandomRange(r, -r)<y + (P_RandomRange(r, -r)<z + (P_RandomKey(mobj->height>>FRACBITS)<movedir == DMG_DROWNED)
+ P_SetObjectMomZ(mobj, -FRACUNIT/2, true); // slower fall from drowning
+ else
+ P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true);
+ }
}
break;
default:
@@ -7089,6 +7312,7 @@ void P_MobjThinker(mobj_t *mobj)
{
mobj->flags &= ~MF_NOGRAVITY;
P_SetMobjState(mobj, S_NIGHTSDRONE1);
+ mobj->flags2 |= MF2_DONTDRAW;
}
}
else if (mobj->tracer && mobj->tracer->player)
@@ -7362,9 +7586,60 @@ void P_MobjThinker(mobj_t *mobj)
mobj_t *flagmo, *newmobj;
#ifdef HAVE_BLUA
- if (!LUAh_MobjFuse(mobj) && !P_MobjWasRemoved(mobj))
+ if (LUAh_MobjFuse(mobj) || P_MobjWasRemoved(mobj))
+ ;
+ else
#endif
- switch (mobj->type)
+ if (mobj->info->flags & MF_MONITOR)
+ {
+ // Special case for ALL monitors.
+ // If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM.
+ if (mobj->info->speed != 0 && (mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX))
+ {
+ mobjtype_t spawnchance[64];
+ INT32 numchoices = 0, i = 0;
+
+// This define should make it a lot easier to organize and change monitor weights
+#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \
+for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type
+
+ // Type SRM WRM
+ SETMONITORCHANCES(MT_SNEAKERS_BOX, 0, 10); // Super Sneakers
+ SETMONITORCHANCES(MT_INVULN_BOX, 2, 0); // Invincibility
+ SETMONITORCHANCES(MT_WHIRLWIND_BOX, 3, 8); // Whirlwind Shield
+ SETMONITORCHANCES(MT_ELEMENTAL_BOX, 3, 8); // Elemental Shield
+ SETMONITORCHANCES(MT_ATTRACT_BOX, 2, 0); // Attraction Shield
+ SETMONITORCHANCES(MT_FORCE_BOX, 3, 3); // Force Shield
+ SETMONITORCHANCES(MT_ARMAGEDDON_BOX, 2, 0); // Armageddon Shield
+ SETMONITORCHANCES(MT_MIXUP_BOX, 0, 1); // Teleporters
+ SETMONITORCHANCES(MT_RECYCLER_BOX, 0, 1); // Recycler
+ SETMONITORCHANCES(MT_1UP_BOX, 1, 1); // 1-Up
+ // =======================================
+ // Total 16 32
+
+#undef SETMONITORCHANCES
+
+ i = P_RandomKey(numchoices); // Gotta love those random numbers!
+ newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]);
+
+ // If the monitor respawns randomly, transfer the flag.
+ if (mobj->flags & MF_AMBUSH)
+ newmobj->flags |= MF_AMBUSH;
+
+ // Transfer flags2 (strongbox, objectflip)
+ newmobj->flags2 = mobj->flags2;
+ }
+ else
+ {
+ newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type);
+
+ // Transfer flags2 (strongbox, objectflip)
+ newmobj->flags2 = mobj->flags2;
+ }
+ P_RemoveMobj(mobj); // make sure they disappear
+ return;
+ }
+ else switch (mobj->type)
{
// gargoyle and snowman handled in P_PushableThinker, not here
case MT_THROWNGRENADE:
@@ -7423,68 +7698,6 @@ void P_MobjThinker(mobj_t *mobj)
}
P_RemoveMobj(mobj);
return;
- case MT_YELLOWTV: // Ring shield box
- case MT_BLUETV: // Force shield box
- case MT_GREENTV: // Water shield box
- case MT_BLACKTV: // Bomb shield box
- case MT_WHITETV: // Jump shield box
- case MT_SNEAKERTV: // Super Sneaker box
- case MT_SUPERRINGBOX: // 10-Ring box
- case MT_REDRINGBOX: // Red Team 10-Ring box
- case MT_BLUERINGBOX: // Blue Team 10-Ring box
- case MT_INV: // Invincibility box
- case MT_MIXUPBOX: // Teleporter Mixup box
- case MT_RECYCLETV: // Recycler box
- case MT_SCORETVSMALL:
- case MT_SCORETVLARGE:
- case MT_PRUP: // 1up!
- case MT_EGGMANBOX: // Eggman box
- case MT_GRAVITYBOX: // Gravity box
- case MT_QUESTIONBOX:
- if ((mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX)
- {
- mobjtype_t spawnchance[64];
- INT32 numchoices = 0, i = 0;
-
-// This define should make it a lot easier to organize and change monitor weights
-#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \
-for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type
-
- // Type SRM WRM
- SETMONITORCHANCES(MT_SNEAKERTV, 0, 10); // Super Sneakers
- SETMONITORCHANCES(MT_INV, 2, 0); // Invincibility
- SETMONITORCHANCES(MT_WHITETV, 3, 8); // Whirlwind Shield
- SETMONITORCHANCES(MT_GREENTV, 3, 8); // Elemental Shield
- SETMONITORCHANCES(MT_YELLOWTV, 2, 0); // Attraction Shield
- SETMONITORCHANCES(MT_BLUETV, 3, 3); // Force Shield
- SETMONITORCHANCES(MT_BLACKTV, 2, 0); // Armageddon Shield
- SETMONITORCHANCES(MT_MIXUPBOX, 0, 1); // Teleporters
- SETMONITORCHANCES(MT_RECYCLETV, 0, 1); // Recycler
- SETMONITORCHANCES(MT_PRUP, 1, 1); // 1-Up
- // ======================================
- // Total 16 32
-
-#undef SETMONITORCHANCES
-
- i = P_RandomKey(numchoices); // Gotta love those random numbers!
- newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]);
-
- // If the monitor respawns randomly, transfer the flag.
- if (mobj->flags & MF_AMBUSH)
- newmobj->flags |= MF_AMBUSH;
-
- // Transfer flags2 (strongbox, objectflip)
- newmobj->flags2 = mobj->flags2;
- }
- else
- {
- newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type);
-
- // Transfer flags2 (strongbox, objectflip)
- newmobj->flags2 = mobj->flags2;
- }
- P_RemoveMobj(mobj); // make sure they disappear
- return;
case MT_METALSONIC_BATTLE:
break; // don't remove
case MT_SPIKE:
@@ -7501,6 +7714,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
default:
P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL.
break;
+ // Looking for monitors? They moved to a special condition above.
}
if (P_MobjWasRemoved(mobj))
return;
@@ -8600,6 +8814,10 @@ void P_SpawnPlayer(INT32 playernum)
P_SetScale(mobj, mobj->destscale);
P_FlashPal(p, 0, 0); // Resets
+ // Set bounds accurately.
+ mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale);
+ mobj->height = P_GetPlayerHeight(p);
+
// Spawn with a pity shield if necessary.
P_DoPityCheck(p);
}
@@ -8948,36 +9166,37 @@ void P_SpawnMapThing(mapthing_t *mthing)
if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS))
return;
- // Set powerup boxes to user settings for competition.
- if (gametype == GT_COMPETITION)
+ // Altering monitor spawns via cvars
+ // If MF_GRENADEBOUNCE is set in the monitor's info,
+ // skip this step. (Used for gold monitors)
+ // Yeah, this is a dirty hack.
+ if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR)
{
- if ((mobjinfo[i].flags & MF_MONITOR) && cv_competitionboxes.value) // not Normal
+ if (gametype == GT_COMPETITION)
{
+ // Set powerup boxes to user settings for competition.
if (cv_competitionboxes.value == 1) // Random
- i = MT_QUESTIONBOX;
+ i = MT_MYSTERY_BOX;
else if (cv_competitionboxes.value == 2) // Teleports
- i = MT_MIXUPBOX;
+ i = MT_MIXUP_BOX;
else if (cv_competitionboxes.value == 3) // None
return; // Don't spawn!
+ // default case: normal
}
- }
-
- // Set powerup boxes to user settings for other netplay modes
- else if (gametype != GT_COOP)
- {
- if ((mobjinfo[i].flags & MF_MONITOR) && cv_matchboxes.value) // not Normal
+ // Set powerup boxes to user settings for other netplay modes
+ else if (gametype != GT_COOP)
{
if (cv_matchboxes.value == 1) // Random
- i = MT_QUESTIONBOX;
- else if (cv_matchboxes.value == 3) // Don't spawn
- return;
- else // cv_matchboxes.value == 2, Non-Random
+ i = MT_MYSTERY_BOX;
+ else if (cv_matchboxes.value == 2) // Non-Random
{
- if (i == MT_QUESTIONBOX)
+ if (i == MT_MYSTERY_BOX)
return; // don't spawn in Non-Random
-
mthing->options &= ~(MTF_AMBUSH|MTF_OBJECTSPECIAL); // no random respawning!
}
+ else if (cv_matchboxes.value == 3) // Don't spawn
+ return;
+ // default case: normal
}
}
@@ -8985,8 +9204,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
{
if (i == MT_BLUETEAMRING || i == MT_REDTEAMRING)
i = MT_RING;
- else if (i == MT_BLUERINGBOX || i == MT_REDRINGBOX)
- i = MT_SUPERRINGBOX;
+ else if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX)
+ i = MT_RING_BOX;
else if (i == MT_BLUEFLAG || i == MT_REDFLAG)
return; // No flags in non-CTF modes!
}
@@ -9013,23 +9232,27 @@ void P_SpawnMapThing(mapthing_t *mthing)
return; /// \todo
// 1UPs -->> Score TVs
- else if (i == MT_PRUP) // 1UP
+ else if (i == MT_1UP_BOX) // 1UP
{
// Either or, doesn't matter which.
if (mthing->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL))
- i = MT_SCORETVLARGE; // 10,000
+ i = MT_SCORE10K_BOX; // 10,000
else
- i = MT_SCORETVSMALL; // 1,000
+ i = MT_SCORE1K_BOX; // 1,000
}
}
if (ultimatemode)
{
- if (i == MT_PITYTV || i == MT_GREENTV || i == MT_YELLOWTV || i == MT_BLUETV || i == MT_BLACKTV || i == MT_WHITETV)
+ if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX
+ || i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX)
return; // No shields in Ultimate mode
- if (i == MT_SUPERRINGBOX && !G_IsSpecialStage(gamemap))
+ if (i == MT_RING_BOX && !G_IsSpecialStage(gamemap))
return; // No rings in Ultimate mode (except special stages)
+
+ // Don't include the gold repeating boxes here please.
+ // They're likely facets of the level's design and therefore required to progress.
}
if (i == MT_EMMY && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
@@ -9452,7 +9675,7 @@ ML_NOCLIMB : Direction not controllable
}
//count 10 ring boxes into the number of rings equation too.
- if (i == MT_SUPERRINGBOX)
+ if (i == MT_RING_BOX)
nummaprings += 10;
if (i == MT_BIGTUMBLEWEED || i == MT_LITTLETUMBLEWEED)
@@ -9531,16 +9754,11 @@ ML_NOCLIMB : Direction not controllable
mobj->flags2 |= MF2_STANDONME;
}
- if (mobj->flags & MF_MONITOR)
+ if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0)
{
// flag for strong/weak random boxes
- if (mthing->type == mobjinfo[MT_SUPERRINGBOX].doomednum || mthing->type == mobjinfo[MT_PRUP].doomednum ||
- mthing->type == mobjinfo[MT_SNEAKERTV].doomednum || mthing->type == mobjinfo[MT_INV].doomednum ||
- mthing->type == mobjinfo[MT_WHITETV].doomednum || mthing->type == mobjinfo[MT_GREENTV].doomednum ||
- mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum ||
- mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum ||
- mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum)
- mobj->flags |= MF_AMBUSH;
+ // any monitor with nonzero speed is allowed to respawn like this
+ mobj->flags |= MF_AMBUSH;
}
else if (mthing->type != mobjinfo[MT_AXIS].doomednum &&
@@ -9553,14 +9771,12 @@ ML_NOCLIMB : Direction not controllable
if (mthing->options & MTF_OBJECTSPECIAL)
{
- // flag for strong/weak random boxes
- if (mthing->type == mobjinfo[MT_SUPERRINGBOX].doomednum || mthing->type == mobjinfo[MT_PRUP].doomednum ||
- mthing->type == mobjinfo[MT_SNEAKERTV].doomednum || mthing->type == mobjinfo[MT_INV].doomednum ||
- mthing->type == mobjinfo[MT_WHITETV].doomednum || mthing->type == mobjinfo[MT_GREENTV].doomednum ||
- mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum ||
- mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum ||
- mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum)
- mobj->flags2 |= MF2_STRONGBOX;
+ if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0)
+ {
+ // flag for strong/weak random boxes
+ // any monitor with nonzero speed is allowed to respawn like this
+ mobj->flags2 |= MF2_STRONGBOX;
+ }
// Requires you to be in bonus time to activate
if (mobj->flags & MF_NIGHTSITEM)
@@ -10553,3 +10769,35 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration)
pl->flashcount = duration;
pl->flashpal = type;
}
+
+//
+// P_SpawnMobjFromMobj
+// Spawns an object with offsets relative to the position of another object.
+// Scale, gravity flip, etc. is taken into account automatically.
+//
+mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type)
+{
+ mobj_t *newmobj;
+
+ xofs = FixedMul(xofs, mobj->scale);
+ yofs = FixedMul(yofs, mobj->scale);
+ zofs = FixedMul(zofs, mobj->scale);
+
+ newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type);
+ if (!newmobj)
+ return NULL;
+
+ if (mobj->eflags & MFE_VERTICALFLIP)
+ {
+ fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale);
+
+ newmobj->eflags |= MFE_VERTICALFLIP;
+ newmobj->flags2 |= MF2_OBJECTFLIP;
+ newmobj->z = mobj->z + mobj->height - zofs - elementheight;
+ }
+
+ newmobj->destscale = mobj->destscale;
+ P_SetScale(newmobj, mobj->scale);
+ return newmobj;
+}
+
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 7ec301349..bb702b209 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -442,7 +442,7 @@ boolean P_SupermanLook4Players(mobj_t *actor);
void P_DestroyRobots(void);
void P_SnowThinker(precipmobj_t *mobj);
void P_RainThinker(precipmobj_t *mobj);
-void P_NullPrecipThinker(precipmobj_t *mobj);
+FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj);
void P_RemovePrecipMobj(precipmobj_t *mobj);
void P_SetScale(mobj_t *mobj, fixed_t newscale);
void P_XYMovement(mobj_t *mo);
diff --git a/src/p_pspr.h b/src/p_pspr.h
index 2fb232e73..9420796ff 100644
--- a/src/p_pspr.h
+++ b/src/p_pspr.h
@@ -35,8 +35,12 @@
#pragma interface
#endif
-/// \brief Frame flags: only the frame number
-#define FF_FRAMEMASK 0x3fff
+/// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range)
+#define FF_FRAMEMASK 0x1ff
+/// \brief Frame flags: A change of state at the end of Sprite2 animation
+#define FF_SPR2ENDSTATE 0x1000
+/// \brief Frame flags: 50% of starting in middle of animation (Sprite2 and FF_ANIMATE)
+#define FF_MIDDLESTARTCHANCE 0x2000
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright
diff --git a/src/p_saveg.c b/src/p_saveg.c
index e463b1ba4..8d792067f 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -147,7 +147,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].score);
WRITEFIXED(save_p, players[i].dashspeed);
- WRITEINT32(save_p, players[i].dashtime);
WRITESINT8(save_p, players[i].lives);
WRITESINT8(save_p, players[i].continues);
WRITESINT8(save_p, players[i].xtralife);
@@ -162,6 +161,7 @@ static void P_NetArchivePlayers(void)
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);
////////////////////////////
@@ -259,6 +259,9 @@ static void P_NetArchivePlayers(void)
if (flags & AWAYVIEW)
WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum);
+ WRITEFIXED(save_p, players[i].camerascale);
+ WRITEFIXED(save_p, players[i].shieldscale);
+
WRITEUINT8(save_p, players[i].charability);
WRITEUINT8(save_p, players[i].charability2);
WRITEUINT32(save_p, players[i].charflags);
@@ -274,6 +277,8 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].accelstart);
WRITEUINT8(save_p, players[i].acceleration);
WRITEFIXED(save_p, players[i].jumpfactor);
+ WRITEFIXED(save_p, players[i].height);
+ WRITEFIXED(save_p, players[i].spinheight);
}
}
@@ -322,7 +327,6 @@ static void P_NetUnArchivePlayers(void)
players[i].score = READUINT32(save_p);
players[i].dashspeed = READFIXED(save_p); // dashing speed
- players[i].dashtime = READINT32(save_p); // dashing speed
players[i].lives = READSINT8(save_p);
players[i].continues = READSINT8(save_p); // continues that player has acquired
players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter
@@ -337,6 +341,7 @@ static void P_NetUnArchivePlayers(void)
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
////////////////////////////
@@ -424,6 +429,9 @@ static void P_NetUnArchivePlayers(void)
players[i].viewheight = cv_viewheight.value<lines = Z_Calloc(sector->linecount * sizeof(line_t*), PU_LEVEL, NULL);
+ if (sector->linecount == 0) // no lines found?
+ {
+ sector->lines = NULL;
+ CONS_Debug(DBG_SETUP, "P_GroupLines: sector %s has no lines\n", sizeu1(i));
+ }
+ else
+ {
+ sector->lines = Z_Calloc(sector->linecount * sizeof(line_t*), PU_LEVEL, NULL);
- // zero the count, since we'll later use this to track how many we've recorded
- sector->linecount = 0;
+ // zero the count, since we'll later use this to track how many we've recorded
+ sector->linecount = 0;
+ }
}
// iterate through lines, assigning them to sectors' linebuffers,
@@ -1952,11 +1960,14 @@ static void P_GroupLines(void)
{
M_ClearBox(bbox);
- for (j = 0; j < sector->linecount; j++)
+ if (sector->linecount != 0)
{
- li = sector->lines[j];
- M_AddToBox(bbox, li->v1->x, li->v1->y);
- M_AddToBox(bbox, li->v2->x, li->v2->y);
+ for (j = 0; j < sector->linecount; j++)
+ {
+ li = sector->lines[j];
+ M_AddToBox(bbox, li->v1->x, li->v1->y);
+ M_AddToBox(bbox, li->v2->x, li->v2->y);
+ }
}
// set the degenmobj_t to the middle of the bounding box
@@ -1966,6 +1977,35 @@ static void P_GroupLines(void)
}
}
+//
+// P_LoadReject
+//
+// Detect if the REJECT lump is valid,
+// if not, rejectmatrix will be NULL
+static void P_LoadReject(lumpnum_t lumpnum)
+{
+ size_t count;
+ const char *lumpname = W_CheckNameForNum(lumpnum);
+
+ // Check if the lump exists, and if it's named "REJECT"
+ if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0)
+ {
+ rejectmatrix = NULL;
+ CONS_Debug(DBG_SETUP, "P_LoadReject: No valid REJECT lump found\n");
+ return;
+ }
+
+ count = W_LumpLength(lumpnum);
+
+ if (!count) // zero length, someone probably used ZDBSP
+ {
+ rejectmatrix = NULL;
+ CONS_Debug(DBG_SETUP, "P_LoadReject: REJECT lump has size 0, will not be loaded\n");
+ }
+ else
+ rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL);
+}
+
#if 0
static char *levellumps[] =
{
@@ -2575,7 +2615,7 @@ boolean P_SetupLevel(boolean skipprecip)
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
- rejectmatrix = W_CacheLumpNum(lastloadedmaplumpnum + ML_REJECT, PU_LEVEL);
+ P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
P_GroupLines();
numdmstarts = numredctfstarts = numbluectfstarts = 0;
diff --git a/src/p_sight.c b/src/p_sight.c
index 14c1c945f..bd6ab4d73 100644
--- a/src/p_sight.c
+++ b/src/p_sight.c
@@ -325,9 +325,12 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
s2 = t2->subsector->sector;
pnum = (s1-sectors)*numsectors + (s2-sectors);
- // Check in REJECT table.
- if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
- return false;
+ if (rejectmatrix != NULL)
+ {
+ // Check in REJECT table.
+ if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
+ return false;
+ }
// killough 11/98: shortcut for melee situations
// same subsector? obviously visible
diff --git a/src/p_slopes.c b/src/p_slopes.c
index 6393ca4b5..d939fee98 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -199,7 +199,6 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
// Find furthest vertex from the reference line. It, along with the two ends
// of the line, will define the plane.
- // SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep
for(i = 0; i < sector->linecount; i++)
{
line_t *li = sector->lines[i];
@@ -231,7 +230,6 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
//
// Creates one or more slopes based on the given line type and front/back
// sectors.
-// Kalaron: Check if dynamic slopes need recalculation
//
void P_SpawnSlope_Line(int linenum)
{
@@ -276,7 +274,6 @@ void P_SpawnSlope_Line(int linenum)
ny = -FixedDiv(line->dx, len);
}
- // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF
origin.x = line->v1->x + (line->v2->x - line->v1->x)/2;
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
@@ -327,7 +324,7 @@ void P_SpawnSlope_Line(int linenum)
// fslope->normal is a 3D line perpendicular to the 3D vector
// Sync the linedata of the line that started this slope
- // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ // TODO: Anything special for control sector based slopes later?
fslope->sourceline = line;
// To find the real highz/lowz of a slope, you need to check all the vertexes
@@ -379,7 +376,7 @@ void P_SpawnSlope_Line(int linenum)
cslope->refpos = 2;
// Sync the linedata of the line that started this slope
- // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ // TODO: Anything special for control sector based slopes later?
cslope->sourceline = line;
// Remember the way the slope is formed
@@ -445,7 +442,7 @@ void P_SpawnSlope_Line(int linenum)
fslope->refpos = 3;
// Sync the linedata of the line that started this slope
- // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ // TODO: Anything special for control sector based slopes later?
fslope->sourceline = line;
// Remember the way the slope is formed
@@ -488,7 +485,7 @@ void P_SpawnSlope_Line(int linenum)
cslope->refpos = 4;
// Sync the linedata of the line that started this slope
- // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ // TODO: Anything special for control sector based slopes later?
cslope->sourceline = line;
// Remember the way the slope is formed
@@ -554,16 +551,11 @@ static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
ret->vertices[2] = mt;
}
- if (!ret->vertices[0])
- CONS_Printf("PANIC 0\n");
- if (!ret->vertices[1])
- CONS_Printf("PANIC 1\n");
- if (!ret->vertices[2])
- CONS_Printf("PANIC 2\n");
-
// Now set heights for each vertex, because they haven't been set yet
for (i = 0; i < 3; i++) {
mt = ret->vertices[i];
+ if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?)
+ I_Error("P_NewVertexSlope: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1);
if (mt->extrainfo)
mt->z = mt->options;
else
@@ -623,265 +615,10 @@ pslope_t *P_SlopeById(UINT16 id)
return ret;
}
-#ifdef SPRINGCLEAN
-#include "byteptr.h"
-
-#include "p_setup.h"
-#include "p_local.h"
-
-//==========================================================================
-//
-// P_SetSlopesFromVertexHeights
-//
-//==========================================================================
-void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum)
-{
- mapthing_t *mt;
- boolean vt_found = false;
- size_t i, j, k, l, q;
-
- //size_t i;
- //mapthing_t *mt;
- char *data;
- char *datastart;
-
- // SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10
- // anything else seems to make a map not load properly,
- // but this hard-coded value MUST have some reason for being what it is
- size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short));
- mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL);
- fixed_t x, y;
- sector_t *sector;
- // Spawn axis points first so they are
- // at the front of the list for fast searching.
- data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
- mt = smapthings;
- for (i = 0; i < snummapthings; i++, mt++)
- {
- mt->x = READINT16(data);
- mt->y = READINT16(data);
- mt->angle = READINT16(data);
- mt->type = READINT16(data);
- mt->options = READINT16(data);
- // mt->z hasn't been set yet!
- //mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types
-
- //mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!!
- x = mt->x*FRACUNIT;
- y = mt->y*FRACUNIT;
- sector = R_PointInSubsector(x, y)->sector;
- // Z for objects
-#ifdef ESLOPE
- if (sector->f_slope)
- mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS);
- else
-#endif
- mt->z = (short)(sector->floorheight>>FRACBITS);
-
- mt->z = mt->z + (mt->options >> ZSHIFT);
-
- if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ
- {
- for(l = 0; l < numvertexes; l++)
- {
- if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT)
- {
- if (mt->type == THING_VertexFloorZ)
- {
- vertexes[l].z = mt->z*FRACUNIT;
- //I_Error("Z value: %i", vertexes[l].z/FRACUNIT);
-
- }
- else
- {
- vertexes[l].z = mt->z*FRACUNIT; // celing floor
- }
- vt_found = true;
- }
- }
- //mt->type = 0; // VPHYSICS: Dynamic slopes
-
-
-
-
-
-
- if (vt_found)
- {
- for (k = 0; k < numsectors; k++)
- {
- sector_t *sec = §ors[k];
- if (sec->linecount != 3) continue; // only works with triangular sectors
-
- v3float_t vt1, vt2, vt3; // cross = ret->normalf
- v3float_t vec1, vec2;
-
- int vi1, vi2, vi3;
-
- vi1 = (int)(sec->lines[0]->v1 - vertexes);
- vi2 = (int)(sec->lines[0]->v2 - vertexes);
- vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)?
- (int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes);
-
- //if (vertexes[vi1].z)
- // I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT);
- //if (vertexes[vi2].z)
- // I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT);
- //if (vertexes[vi3].z)
- // I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT);
-
- //I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z);
-
- //I_Error("%i, %i, %i", mt->x, mt->y, mt->z);
- //P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING);
-
- // TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the
- // triangle sector to setup the real vertex slopes
- // Check for the vertexes of all sectors
- for(q = 0; q < numvertexes; q++)
- {
- if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT)
- {
- //I_Error("yeah %i", vertexes[q].z);
- P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING);
-#if 0
- if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
- && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
- && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
- P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING);
- else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
- && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
- && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
- P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV);
- else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)
- && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
- && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z))
- P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1);
- else
-#endif
- continue;
- }
- }
-
- vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x);
- vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y);
- vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x);
- vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y);
- vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x);
- vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y);
-
- for(j = 0; j < 2; j++)
- {
-
- fixed_t z3;
- //I_Error("Lo hicimos");
-
- vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight);
- vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight);
- z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height
- vt3.z = FIXED_TO_FLOAT(z3);
-
- if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0)
- {
- vec1.x = vt2.x - vt3.x;
- vec1.y = vt2.y - vt3.y;
- vec1.z = vt2.z - vt3.z;
-
- vec2.x = vt1.x - vt3.x;
- vec2.y = vt1.y - vt3.y;
- vec2.z = vt1.z - vt3.z;
- }
- else
- {
- vec1.x = vt1.x - vt3.x;
- vec1.y = vt1.y - vt3.y;
- vec1.z = vt1.z - vt3.z;
-
- vec2.x = vt2.x - vt3.x;
- vec2.y = vt2.y - vt3.y;
- vec2.z = vt2.z - vt3.z;
- }
-
-
- pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
- memset(ret, 0, sizeof(*ret));
-
- {
- M_CrossProduct3f(&ret->normalf, &vec1, &vec2);
-
- // Cross product length
- float len = (float)sqrt(ret->normalf.x * ret->normalf.x +
- ret->normalf.y * ret->normalf.y +
- ret->normalf.z * ret->normalf.z);
-
- if (len == 0)
- {
- // Only happens when all vertices in this sector are on the same line.
- // Let's just ignore this case.
- //CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16));
- return;
- }
- // cross/len
- ret->normalf.x /= len;
- ret->normalf.y /= len;
- ret->normalf.z /= len;
-
- // ZDoom cross = ret->normalf
- // Fix backward normals
- if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1))
- {
- // cross = -cross
- ret->normalf.x = -ret->normalf.x;
- ret->normalf.y = -ret->normalf.x;
- ret->normalf.z = -ret->normalf.x;
- }
- }
-
- secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL);
-
- srcplane->a = FLOAT_TO_FIXED (ret->normalf.x);
- srcplane->b = FLOAT_TO_FIXED (ret->normalf.y);
- srcplane->c = FLOAT_TO_FIXED (ret->normalf.z);
- //srcplane->ic = FixedDiv(FRACUNIT, srcplane->c);
- srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x,
- srcplane->b, vertexes[vi3].y,
- srcplane->c, z3);
-
- if (j == 0)
- {
- sec->f_slope = ret;
- sec->f_slope->secplane = *srcplane;
- }
- else if (j == 1)
- {
- sec->c_slope = ret;
- sec->c_slope->secplane = *srcplane;
- }
- }
- }
- }
-
-
-
-
-
-
-
-
- }
- }
- Z_Free(datastart);
-
-
-
-
-}
-#endif
-
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
void P_ResetDynamicSlopes(void) {
size_t i;
-#if 1 // Rewrite old specials to new ones, and give a console warning
+#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
boolean warned = false;
#endif
@@ -894,7 +631,7 @@ void P_ResetDynamicSlopes(void) {
{
switch (lines[i].special)
{
-#if 1 // Rewrite old specials to new ones, and give a console warning
+#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
case 386:
case 387:
@@ -1018,7 +755,11 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
// When given a vector, rotates it and aligns it to a slope
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
{
- vector3_t axis;
+ vector3_t axis; // Fuck you, C90.
+
+ if (slope->flags & SL_NOPHYSICS)
+ return; // No physics, no quantizing.
+
axis.x = -slope->d.y;
axis.y = slope->d.x;
axis.z = 0;
@@ -1026,24 +767,38 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT);
}
+//
+// P_ReverseQuantizeMomentumToSlope
+//
+// When given a vector, rotates and aligns it to a flat surface (from being relative to a given slope)
+void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
+{
+ slope->zangle = InvAngle(slope->zangle);
+ P_QuantizeMomentumToSlope(momentum, slope);
+ slope->zangle = InvAngle(slope->zangle);
+}
+
//
// P_SlopeLaunch
//
// Handles slope ejection for objects
void P_SlopeLaunch(mobj_t *mo)
{
- // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
- // vertical launch given from slopes while increasing the horizontal launch
- // given. Good for SRB2's gravity and horizontal speeds.
- vector3_t slopemom;
- slopemom.x = mo->momx;
- slopemom.y = mo->momy;
- slopemom.z = mo->momz*2;
- P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
+ if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching.
+ {
+ // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
+ // vertical launch given from slopes while increasing the horizontal launch
+ // given. Good for SRB2's gravity and horizontal speeds.
+ vector3_t slopemom;
+ slopemom.x = mo->momx;
+ slopemom.y = mo->momy;
+ slopemom.z = mo->momz*2;
+ P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
- mo->momx = slopemom.x;
- mo->momy = slopemom.y;
- mo->momz = slopemom.z/2;
+ mo->momx = slopemom.x;
+ mo->momy = slopemom.y;
+ mo->momz = slopemom.z/2;
+ }
//CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL;
@@ -1052,17 +807,21 @@ void P_SlopeLaunch(mobj_t *mo)
// Function to help handle landing on slopes
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
{
- vector3_t mom;
+ vector3_t mom; // Ditto.
+
+ if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated.
+ if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
+ thing->momz = -P_MobjFlip(thing);
+ thing->standingslope = slope;
+ }
+ return;
+ }
+
mom.x = thing->momx;
mom.y = thing->momy;
mom.z = thing->momz*2;
- //CONS_Printf("langing on slope\n");
-
- // Reverse quantizing might could use its own function later
- slope->zangle = ANGLE_MAX-slope->zangle;
- P_QuantizeMomentumToSlope(&mom, slope);
- slope->zangle = ANGLE_MAX-slope->zangle;
+ P_ReverseQuantizeMomentumToSlope(&mom, slope);
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
thing->momx = mom.x;
@@ -1082,6 +841,9 @@ void P_ButteredSlope(mobj_t *mo)
if (!mo->standingslope)
return;
+ if (mo->standingslope->flags & SL_NOPHYSICS)
+ return; // No physics, no butter.
+
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
return; // don't slide down slopes if you can't touch them or you're not affected by gravity
@@ -1106,8 +868,6 @@ void P_ButteredSlope(mobj_t *mo)
mult = FINECOSINE(angle >> ANGLETOFINESHIFT);
}
- //CONS_Printf("%d\n", mult);
-
thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8);
}
@@ -1115,10 +875,11 @@ void P_ButteredSlope(mobj_t *mo)
thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16);
// This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
- // Multiply by gravity
- thrust = FixedMul(thrust, gravity); // TODO account for per-sector gravity etc
- // Multiply by scale (gravity strength depends on mobj scale)
- thrust = FixedMul(thrust, mo->scale);
+ // Let's get the gravity strength for the object...
+ thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo)));
+
+ // ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same).
+ thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION));
P_Thrust(mo, mo->standingslope->xydirection, thrust);
}
diff --git a/src/p_slopes.h b/src/p_slopes.h
index 80921a84b..de38f1d9e 100644
--- a/src/p_slopes.h
+++ b/src/p_slopes.h
@@ -21,26 +21,6 @@ void P_RunDynamicSlopes(void);
// sectors.
void P_SpawnSlope_Line(int linenum);
-#ifdef SPRINGCLEAN
-// Loads just map objects that make slopes,
-// terrain affecting objects have to be spawned first
-void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum);
-
-typedef enum
-{
- THING_SlopeFloorPointLine = 9500,
- THING_SlopeCeilingPointLine = 9501,
- THING_SetFloorSlope = 9502,
- THING_SetCeilingSlope = 9503,
- THING_CopyFloorPlane = 9510,
- THING_CopyCeilingPlane = 9511,
- THING_VavoomFloor=1500,
- THING_VavoomCeiling=1501,
- THING_VertexFloorZ=1504,
- THING_VertexCeilingZ=1505,
-} slopething_e;
-#endif
-
//
// P_CopySectorSlope
//
@@ -55,6 +35,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
// Lots of physics-based bullshit
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
+void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_SlopeLaunch(mobj_t *mo);
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
void P_ButteredSlope(mobj_t *mo);
diff --git a/src/p_spec.c b/src/p_spec.c
index d6b0bfc5f..ca34425f2 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -1188,7 +1188,12 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start)
{
start++;
- while (lines[start].special != special)
+ // This redundant check stops the compiler from complaining about function expansion
+ // elsewhere for some reason and everything is awful
+ if (start >= (INT32)numlines)
+ return -1;
+
+ while (start < (INT32)numlines && lines[start].special != special)
start++;
if (start >= (INT32)numlines)
@@ -1642,7 +1647,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
mo = node->m_thing;
if (mo->flags & MF_PUSHABLE)
numpush++;
- node = node->m_snext;
+ node = node->m_thinglist_next;
}
if (triggerline->flags & ML_NOCLIMB) // Need at least or more
@@ -2435,10 +2440,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (rover->master->frontsector->tag != line->tag)
continue;
- if (mo->z > *rover->topheight)
+ if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
continue;
- if (mo->z + mo->height < *rover->bottomheight)
+ if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
continue;
foundit = true;
@@ -3145,7 +3150,7 @@ void P_SetupSignExit(player_t *player)
thinker_t *think;
INT32 numfound = 0;
- for (; node; node = node->m_snext)
+ for (; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
if (thing->type != MT_SIGN)
@@ -3228,8 +3233,8 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
if (GETSECSPECIAL(rover->master->frontsector->special, 4) != specialnum)
continue;
- if (mo->z <= *rover->topheight
- && mo->z >= *rover->bottomheight)
+ if (mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector)
+ && mo->z >= P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
return true;
}
}
@@ -3263,12 +3268,17 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
// Hmm.. maybe there's a FOF that has it...
for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
+
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
continue;
if (!(rover->flags & FF_EXISTS))
continue;
+ topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
+ bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
+
// Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER)
{
@@ -3276,27 +3286,27 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
- if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight)
+ if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
continue;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(player->mo->eflags & MFE_VERTICALFLIP)
- || player->mo->z + player->mo->height != *rover->bottomheight)
+ || player->mo->z + player->mo->height != bottomheight)
continue;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
- if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight)
- || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight)))
+ if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight)
+ || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight)))
continue;
}
}
else
{
// Water and DEATH FOG!!! heh
- if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight)
+ if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight)
continue;
}
@@ -3304,7 +3314,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
return rover->master->frontsector;
}
- for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (GETSECSPECIAL(node->m_sector->special, section) == number)
{
@@ -3318,12 +3328,17 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
// Hmm.. maybe there's a FOF that has it...
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
+
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
continue;
if (!(rover->flags & FF_EXISTS))
continue;
+ topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
+ bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
+
// Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER)
{
@@ -3331,27 +3346,27 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
- if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight)
+ if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
continue;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(player->mo->eflags & MFE_VERTICALFLIP)
- || player->mo->z + player->mo->height != *rover->bottomheight)
+ || player->mo->z + player->mo->height != bottomheight)
continue;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
- if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight)
- || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight)))
+ if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight)
+ || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight)))
continue;
}
}
else
{
// Water and DEATH FOG!!! heh
- if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight)
+ if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight)
continue;
}
@@ -3872,7 +3887,7 @@ DoneSection2:
mobj_t *mo2;
angle_t an;
- if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
+ if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE)
break;
// Find line #3 tagged to this sector
@@ -3921,10 +3936,10 @@ DoneSection2:
break; // behind back
P_SetTarget(&player->mo->tracer, waypoint);
+ player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed;
player->pflags |= PF_SPINNING;
- player->pflags &= ~PF_JUMPED;
- player->pflags &= ~PF_GLIDING;
+ player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0;
if (player->mo->state-states != S_PLAY_SPIN)
@@ -3945,7 +3960,7 @@ DoneSection2:
mobj_t *mo2;
angle_t an;
- if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
+ if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE)
break;
// Find line #3 tagged to this sector
@@ -3995,9 +4010,10 @@ DoneSection2:
break; // behind back
P_SetTarget(&player->mo->tracer, waypoint);
+ player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed;
player->pflags |= PF_SPINNING;
- player->pflags &= ~PF_JUMPED;
+ player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
if (player->mo->state-states != S_PLAY_SPIN)
{
@@ -4067,7 +4083,7 @@ DoneSection2:
vertex_t v1, v2, resulthigh, resultlow;
mobj_t *highest = NULL;
- if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
+ if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG)
break;
if (player->mo->momz > 0)
@@ -4288,6 +4304,7 @@ DoneSection2:
}
P_SetTarget(&player->mo->tracer, closest);
+ player->powers[pw_carry] = CR_ROPEHANG;
// Option for static ropes.
if (lines[lineindex].flags & ML_NOCLIMB)
@@ -4295,13 +4312,9 @@ DoneSection2:
else
player->speed = speed;
- player->pflags |= PF_ROPEHANG;
-
S_StartSound(player->mo, sfx_s3k4a);
- player->pflags &= ~PF_JUMPED;
- player->pflags &= ~PF_GLIDING;
- player->pflags &= ~PF_SLIDING;
+ player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0;
P_SetThingPosition(player->mo);
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
@@ -4334,12 +4347,17 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
for (rover = sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
+
if (!rover->master->frontsector->special)
continue;
if (!(rover->flags & FF_EXISTS))
continue;
+ topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, sector);
+ bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, sector);
+
// Check the 3D floor's type...
if (((rover->flags & FF_BLOCKPLAYER) && mo->player)
|| ((rover->flags & FF_BLOCKOTHERS) && !mo->player))
@@ -4348,27 +4366,27 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
- if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight)
+ if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight)
continue;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(mo->eflags & MFE_VERTICALFLIP)
- || mo->z + mo->height != *rover->bottomheight)
+ || mo->z + mo->height != bottomheight)
continue;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
- if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight)
- || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight)))
+ if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight)
+ || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight)))
continue;
}
}
else
{
// Water and intangible FOFs
- if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight)
+ if (mo->z > topheight || (mo->z + mo->height) < bottomheight)
continue;
}
@@ -4390,12 +4408,17 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
for (rover = sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
+
if (!rover->master->frontsector->special)
continue;
if (!(rover->flags & FF_EXISTS))
continue;
+ topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector);
+ bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector);
+
// Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER)
{
@@ -4403,27 +4426,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
- if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))
+ if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
continue;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(player->mo->eflags & MFE_VERTICALFLIP)
- || player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
+ || player->mo->z + player->mo->height != bottomheight)
continue;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
- if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
- || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))))
+ if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight)
+ || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight)))
continue;
}
}
else
{
// Water and DEATH FOG!!! heh
- if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
+ if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight)
continue;
}
@@ -4636,7 +4659,7 @@ void P_PlayerInSpecialSector(player_t *player)
P_RunSpecialSectorCheck(player, sector);
// Iterate through touching_sectorlist
- for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
sector = node->m_sector;
@@ -5275,11 +5298,19 @@ void T_LaserFlash(laserthink_t *flash)
sourcesec = ffloor->master->frontsector; // Less to type!
+#ifdef ESLOPE
+ top = (*ffloor->t_slope) ? P_GetZAt(*ffloor->t_slope, sector->soundorg.x, sector->soundorg.y)
+ : *ffloor->topheight;
+ bottom = (*ffloor->b_slope) ? P_GetZAt(*ffloor->b_slope, sector->soundorg.x, sector->soundorg.y)
+ : *ffloor->bottomheight;
+ sector->soundorg.z = (top + bottom)/2;
+#else
sector->soundorg.z = (*ffloor->topheight + *ffloor->bottomheight)/2;
+#endif
S_StartSound(§or->soundorg, sfx_laser);
// Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough*
- for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_snext)
+ for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next)
{
thing = node->m_thing;
@@ -6550,7 +6581,7 @@ void T_Scroll(scroll_t *s)
sector_t *psec;
psec = sectors + sect;
- for (node = psec->touching_thinglist; node; node = node->m_snext)
+ for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
@@ -6572,7 +6603,7 @@ void T_Scroll(scroll_t *s)
if (!is3dblock)
{
- for (node = sec->touching_thinglist; node; node = node->m_snext)
+ for (node = sec->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
@@ -6613,7 +6644,7 @@ void T_Scroll(scroll_t *s)
sector_t *psec;
psec = sectors + sect;
- for (node = psec->touching_thinglist; node; node = node->m_snext)
+ for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
@@ -6635,7 +6666,7 @@ void T_Scroll(scroll_t *s)
if (!is3dblock)
{
- for (node = sec->touching_thinglist; node; node = node->m_snext)
+ for (node = sec->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
@@ -6874,6 +6905,11 @@ void T_Disappear(disappear_t *d)
if (!(lines[d->sourceline].flags & ML_NOCLIMB))
{
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ sectors[s].soundorg.z = P_GetZAt(*rover->t_slope, sectors[s].soundorg.x, sectors[s].soundorg.y);
+ else
+#endif
sectors[s].soundorg.z = *rover->topheight;
S_StartSound(§ors[s].soundorg, sfx_appear);
}
@@ -6980,7 +7016,7 @@ void T_Friction(friction_t *f)
{
if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec))
{
- node = node->m_snext;
+ node = node->m_thinglist_next;
continue;
}
@@ -6998,7 +7034,7 @@ void T_Friction(friction_t *f)
thing->movefactor = f->movefactor;
}
}
- node = node->m_snext;
+ node = node->m_thinglist_next;
}
}
@@ -7125,7 +7161,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
if (thing->eflags & MFE_PUSHED)
return false;
- if (thing->player && thing->player->pflags & PF_ROPEHANG)
+ if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
return false;
// Allow this to affect pushable objects at some point?
@@ -7338,7 +7374,7 @@ void T_Pusher(pusher_t *p)
// constant pushers p_wind and p_current
node = sec->touching_thinglist; // things touching this sector
- for (; node; node = node->m_snext)
+ for (; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
if (thing->flags & (MF_NOGRAVITY | MF_NOCLIP)
@@ -7358,7 +7394,7 @@ void T_Pusher(pusher_t *p)
if (thing->eflags & MFE_PUSHED)
continue;
- if (thing->player && thing->player->pflags & PF_ROPEHANG)
+ if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics))
diff --git a/src/p_telept.c b/src/p_telept.c
index 4921040b4..671accb0f 100644
--- a/src/p_telept.c
+++ b/src/p_telept.c
@@ -160,9 +160,9 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
INT32 p;
// Search for any players you might be carrying, so you can get them off before they end up being taken with you!
for (p = 0; p < MAXPLAYERS; p++)
- if (playeringame[p] && players[p].mo && players[p].pflags & PF_CARRIED && players[p].mo->tracer == thing)
+ if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing)
{
- players[p].pflags &= ~PF_CARRIED;
+ players[p].powers[pw_carry] = CR_NONE;
break;
}
thing->player->cmomx = thing->player->cmomy = 0;
diff --git a/src/p_user.c b/src/p_user.c
index d790c6923..50bad7731 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -576,9 +576,6 @@ static void P_DeNightserizePlayer(player_t *player)
player->pflags &= ~PF_NIGHTSMODE;
- //if (player->mo->tracer)
- //P_RemoveMobj(player->mo->tracer);
-
player->powers[pw_underwater] = 0;
player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
player->secondjump = 0;
@@ -592,7 +589,8 @@ static void P_DeNightserizePlayer(player_t *player)
player->mo->flags &= ~MF_NOGRAVITY;
- player->mo->flags2 &= ~MF2_DONTDRAW;
+ player->mo->skin = &skins[player->skin];
+ player->mo->color = player->skincolor;
// Restore aiming angle
if (player == &players[consoleplayer])
@@ -603,8 +601,6 @@ static void P_DeNightserizePlayer(player_t *player)
// If you screwed up, kiss your score goodbye.
player->marescore = 0;
- if (player->mo->tracer)
- P_RemoveMobj(player->mo->tracer);
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
player->pflags |= PF_NIGHTSFALL;
@@ -638,6 +634,7 @@ static void P_DeNightserizePlayer(player_t *player)
// Restore from drowning music
P_RestoreMusic(player);
}
+
//
// P_NightserizePlayer
//
@@ -651,13 +648,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
return;
if (!(player->pflags & PF_NIGHTSMODE))
- {
- P_SetTarget(&player->mo->tracer, P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NIGHTSCHAR));
- player->mo->tracer->destscale = player->mo->scale;
- P_SetScale(player->mo->tracer, player->mo->scale);
- player->mo->tracer->eflags = (player->mo->tracer->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
- player->mo->height = player->mo->tracer->height;
- }
+ player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox.
player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING);
player->homing = 0;
@@ -670,13 +661,17 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->mo->flags |= MF_NOGRAVITY;
- player->mo->flags2 |= MF2_DONTDRAW;
+ if (skins[player->skin].sprites[SPR2_NGT0].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
+ {
+ player->mo->skin = &skins[DEFAULTNIGHTSSKIN];
+ player->mo->color = ((skin_t *)(player->mo->skin))->prefcolor;
+ }
player->nightstime = player->startedtime = nighttime*TICRATE;
player->bonustime = false;
P_RestoreMusic(player);
- P_SetMobjState(player->mo->tracer, S_SUPERTRANS1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS);
if (gametype == GT_RACE || gametype == GT_COMPETITION)
{
@@ -845,7 +840,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
P_InstaThrust(player->mo, ang, fallbackspeed);
- if (player->pflags & PF_ROPEHANG)
+ if (player->powers[pw_carry] == CR_ROPEHANG)
P_SetTarget(&player->mo->tracer, NULL);
// Point penalty for hitting a hazard during tag.
@@ -872,7 +867,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
// Useful when you want to kill everything the player is doing.
void P_ResetPlayer(player_t *player)
{
- player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED);
+ player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CANCARRY);
+ player->powers[pw_carry] = CR_NONE;
player->jumping = 0;
player->secondjump = 0;
player->glidetime = 0;
@@ -1323,28 +1319,6 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative)
mo->momz = value;
}
-//
-// P_GetPlayerHeight
-//
-// Returns the height
-// of the player.
-//
-fixed_t P_GetPlayerHeight(player_t *player)
-{
- return FixedMul(player->mo->info->height, player->mo->scale);
-}
-
-//
-// P_GetPlayerSpinHeight
-//
-// Returns the 'spin height'
-// of the player.
-//
-fixed_t P_GetPlayerSpinHeight(player_t *player)
-{
- return FixedMul(FixedMul(player->mo->info->height, player->mo->scale),2*FRACUNIT/3);
-}
-
//
// P_IsLocalPlayer
//
@@ -1712,7 +1686,7 @@ static void P_CheckBustableBlocks(player_t *player)
player->mo->y += player->mo->momy;
P_SetThingPosition(player->mo);
- for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (!node->m_sector)
break;
@@ -1720,6 +1694,7 @@ static void P_CheckBustableBlocks(player_t *player)
if (node->m_sector->ffloors)
{
ffloor_t *rover;
+ fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
@@ -1733,54 +1708,70 @@ static void P_CheckBustableBlocks(player_t *player)
continue;
// if it's not an FF_SHATTER, you must be spinning (and not jumping)
- // or have Knuckles's abilities (or Super Sonic)
- // ...or are drilling in NiGHTS (or Metal Sonic)
+ // or be super
+ // or have CA_GLIDEANDCLIMB
+ // or be in dashmode with CA_DASHMODE
+ // or be using CA_TWINSPIN
+ // or be using CA2_MELEE
+ // or are drilling in NiGHTS
+ // or are recording for Metal Sonic
if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST)
&& !((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
- && (player->charability != CA_GLIDEANDCLIMB && !player->powers[pw_super])
- && !(player->pflags & PF_DRILLING) && !metalrecording)
+ && !(player->powers[pw_super])
+ && !(player->charability == CA_GLIDEANDCLIMB)
+ && !((player->charability == CA_DASHMODE) && (player->dashmode >= 3*TICRATE))
+ && !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
+ && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
+ && !(player->pflags & PF_DRILLING)
+ && !metalrecording)
continue;
- // Only Knuckles can break this rock...
- if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) && !(player->charability == CA_GLIDEANDCLIMB))
+ // Only players with CA_GLIDEANDCLIMB, or CA_TWINSPIN/CA2_MELEE users can break this rock...
+ if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX)
+ && !(player->charability == CA_GLIDEANDCLIMB
+ || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
+ || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)))
continue;
+ topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+ bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+
// Height checks
if (rover->flags & FF_SHATTERBOTTOM)
{
- if (player->mo->z+player->mo->momz + player->mo->height < *rover->bottomheight)
+ if (player->mo->z+player->mo->momz + player->mo->height < bottomheight)
continue;
- if (player->mo->z+player->mo->height > *rover->bottomheight)
+ if (player->mo->z+player->mo->height > bottomheight)
continue;
}
else if (rover->flags & FF_SPINBUST)
{
- if (player->mo->z+player->mo->momz > *rover->topheight)
+ if (player->mo->z+player->mo->momz > topheight)
continue;
- if (player->mo->z + player->mo->height < *rover->bottomheight)
+ if (player->mo->z + player->mo->height < bottomheight)
continue;
}
else if (rover->flags & FF_SHATTER)
{
- if (player->mo->z + player->mo->momz > *rover->topheight)
+ if (player->mo->z + player->mo->momz > topheight)
continue;
- if (player->mo->z+player->mo->momz + player->mo->height < *rover->bottomheight)
+ if (player->mo->z+player->mo->momz + player->mo->height < bottomheight)
continue;
}
else
{
- if (player->mo->z >= *rover->topheight)
+ if (player->mo->z >= topheight)
continue;
- if (player->mo->z + player->mo->height < *rover->bottomheight)
+ if (player->mo->z + player->mo->height < bottomheight)
continue;
}
// Impede the player's fall a bit
- if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= *rover->topheight)
+ if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight)
player->mo->momz >>= 1;
else if (rover->flags & FF_SHATTER)
{
@@ -1829,7 +1820,7 @@ static void P_CheckBouncySectors(player_t *player)
player->mo->z += player->mo->momz;
P_SetThingPosition(player->mo);
- for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (!node->m_sector)
break;
@@ -1879,12 +1870,8 @@ static void P_CheckBouncySectors(player_t *player)
momentum.y = player->mo->momy;
momentum.z = player->mo->momz*2;
- if (slope) {
- // Reverse quantizing might could use its own function later
- slope->zangle = ANGLE_MAX-slope->zangle;
- P_QuantizeMomentumToSlope(&momentum, slope);
- slope->zangle = ANGLE_MAX-slope->zangle;
- }
+ if (slope)
+ P_ReverseQuantizeMomentumToSlope(&momentum, slope);
newmom = momentum.z = -FixedMul(momentum.z,linedist)/2;
#else
@@ -2023,66 +2010,50 @@ static void P_CheckSneakerAndLivesTimer(player_t *player)
//
static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
{
- fixed_t height;
- mobj_t *numbermobj = NULL;
+ tic_t timeleft = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater];
- if (player->mo->eflags & MFE_VERTICALFLIP)
- height = player->mo->z - FixedMul(8*FRACUNIT - mobjinfo[MT_DROWNNUMBERS].height, player->mo->scale);
- else
- height = player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale);
+ if ((timeleft == 11*TICRATE + 1) // 5
+ || (timeleft == 9*TICRATE + 1) // 4
+ || (timeleft == 7*TICRATE + 1) // 3
+ || (timeleft == 5*TICRATE + 1) // 2
+ || (timeleft == 3*TICRATE + 1) // 1
+ || (timeleft == 1*TICRATE + 1) // 0
+ ) {
+ fixed_t height = (player->mo->eflags & MFE_VERTICALFLIP)
+ ? player->mo->z - FixedMul(8*FRACUNIT - mobjinfo[MT_DROWNNUMBERS].height, player->mo->scale)
+ : player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale);
- if (player->powers[pw_underwater] == 11*TICRATE + 1 || player->powers[pw_spacetime] == 11*TICRATE + 1)
- {
- numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
- P_SetMobjState(numbermobj, numbermobj->info->spawnstate+5);
- }
- else if (player->powers[pw_underwater] == 9*TICRATE + 1 || player->powers[pw_spacetime] == 9*TICRATE + 1)
- {
- numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
- P_SetMobjState(numbermobj, numbermobj->info->spawnstate+4);
- }
- else if (player->powers[pw_underwater] == 7*TICRATE + 1 || player->powers[pw_spacetime] == 7*TICRATE + 1)
- {
- numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
- P_SetMobjState(numbermobj, numbermobj->info->spawnstate+3);
- }
- else if (player->powers[pw_underwater] == 5*TICRATE + 1 || player->powers[pw_spacetime] == 5*TICRATE + 1)
- {
- numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
- P_SetMobjState(numbermobj, numbermobj->info->spawnstate+2);
- }
- else if (player->powers[pw_underwater] == 3*TICRATE + 1 || player->powers[pw_spacetime] == 3*TICRATE + 1)
- {
- numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
- P_SetMobjState(numbermobj, numbermobj->info->spawnstate+1);
- }
- else if (player->powers[pw_underwater] == 1*TICRATE + 1 || player->powers[pw_spacetime] == 1*TICRATE + 1)
- {
- numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
- //P_SetMobjState(numbermobj, numbermobj->info->spawnstate+0);
- }
- // Underwater timer runs out
- else if (player->powers[pw_underwater] == 1)
- {
- if ((netgame || multiplayer) && P_IsLocalPlayer(player))
- S_ChangeMusic(mapmusname, mapmusflags, true);
- P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED);
- }
- else if (player->powers[pw_spacetime] == 1)
- {
- if ((netgame || multiplayer) && P_IsLocalPlayer(player))
- S_ChangeMusic(mapmusname, mapmusflags, true);
- P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN);
- }
+ mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
+
+ timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be (((timeleft - 1)/TICRATE) - 1)/2, but integer division rounds down for us
+
+ if (player->charflags & SF_MACHINE)
+ {
+ S_StartSound(player->mo, sfx_buzz1);
+ timeleft += 6;
+ }
+ else
+ S_StartSound(player->mo, sfx_dwnind);
+
+ if (timeleft) // Don't waste time setting the state if the time is 0.
+ P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft);
- if (numbermobj)
- {
P_SetTarget(&numbermobj->target, player->mo);
numbermobj->threshold = 40;
- S_StartSound(player->mo, sfx_dwnind);
numbermobj->destscale = player->mo->scale;
P_SetScale(numbermobj, player->mo->scale);
}
+ // Underwater timer runs out
+ else if (timeleft == 1)
+ {
+ if ((netgame || multiplayer) && P_IsLocalPlayer(player))
+ S_ChangeMusic(mapmusname, mapmusflags, true);
+
+ if (player->powers[pw_spacetime] == 1)
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN);
+ else
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED);
+ }
if (!(player->mo->eflags & MFE_UNDERWATER) && player->powers[pw_underwater])
{
@@ -2101,19 +2072,17 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
// Underwater audio cues
if (P_IsLocalPlayer(player) && !player->bot)
{
+ if ((player->powers[pw_underwater] == 25*TICRATE + 1)
+ || (player->powers[pw_underwater] == 20*TICRATE + 1)
+ || (player->powers[pw_underwater] == 15*TICRATE + 1))
+ S_StartSound(NULL, sfx_wtrdng);
+
if (player->powers[pw_underwater] == 11*TICRATE + 1
&& player == &players[consoleplayer])
{
S_StopMusic();
S_ChangeMusicInternal("drown", false);
}
-
- if (player->powers[pw_underwater] == 25*TICRATE + 1)
- S_StartSound(NULL, sfx_wtrdng);
- else if (player->powers[pw_underwater] == 20*TICRATE + 1)
- S_StartSound(NULL, sfx_wtrdng);
- else if (player->powers[pw_underwater] == 15*TICRATE + 1)
- S_StartSound(NULL, sfx_wtrdng);
}
if (player->exiting)
@@ -2136,7 +2105,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
return;
if (mariomode && !player->powers[pw_super])
- player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
+ player->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours
else if (leveltime % (TICRATE/7) == 0)
{
mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
@@ -2183,21 +2152,39 @@ static void P_CheckInvincibilityTimer(player_t *player)
//
static void P_DoBubbleBreath(player_t *player)
{
- fixed_t zh;
+ fixed_t x = player->mo->x;
+ fixed_t y = player->mo->y;
+ fixed_t z = player->mo->z;
mobj_t *bubble = NULL;
- if (player->mo->eflags & MFE_VERTICALFLIP)
- zh = player->mo->z + player->mo->height - FixedDiv(player->mo->height,5*(FRACUNIT/4));
- else
- zh = player->mo->z + FixedDiv(player->mo->height,5*(FRACUNIT/4));
-
if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator)
return;
- if (P_RandomChance(FRACUNIT/16))
- bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE);
- else if (P_RandomChance(3*FRACUNIT/256))
- bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE);
+ if (player->charflags & SF_MACHINE)
+ {
+ if (P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256))
+ {
+ fixed_t r = player->mo->radius>>FRACBITS;
+ x += (P_RandomRange(r, -r)<mo->height>>FRACBITS)<mo->eflags & MFE_VERTICALFLIP)
+ z += player->mo->height - FixedDiv(player->mo->height,5*(FRACUNIT/4));
+ else
+ z += FixedDiv(player->mo->height,5*(FRACUNIT/4));
+
+ if (P_RandomChance(FRACUNIT/16))
+ bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE);
+ else if (P_RandomChance(3*FRACUNIT/256))
+ bubble = P_SpawnMobj(x, y, z, MT_MEDIUMBUBBLE);
+ }
+
if (bubble)
{
bubble->threshold = 42;
@@ -2302,313 +2289,315 @@ static void P_DoClimbing(player_t *player)
fixed_t platy;
subsector_t *glidesector;
boolean climb = true;
+ boolean onesided = ((player->lastsidehit != -1 && player->lastlinehit != -1) && !(lines[player->lastlinehit].backsector));
platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
- if (glidesector->sector != player->mo->subsector->sector)
+ if (onesided || glidesector->sector != player->mo->subsector->sector)
{
- boolean floorclimb;
- boolean thrust;
- boolean boostup;
- boolean skyclimber;
+ boolean floorclimb = false;
+ boolean thrust = false;
+ boolean boostup = false;
+ boolean skyclimber = false;
fixed_t floorheight, ceilingheight; // ESLOPE
- thrust = false;
- floorclimb = false;
- boostup = false;
- skyclimber = false;
-#ifdef ESLOPE
- floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y)
- : glidesector->sector->floorheight;
- ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y)
- : glidesector->sector->ceilingheight;
-#else
- floorheight = glidesector->sector->floorheight;
- ceilingheight = glidesector->sector->ceilingheight;
-#endif
-
- if (glidesector->sector->ffloors)
- {
- ffloor_t *rover;
- fixed_t topheight, bottomheight; // ESLOPE
-
- for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
- {
- if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
- continue;
-
- floorclimb = true;
-
-#ifdef ESLOPE
- bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
- topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
-#else
- bottomheight = *rover->bottomheight;
- topheight = *rover->topheight;
-#endif
-
- // Only supports rovers that are moving like an 'elevator', not just the top or bottom.
- if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
- {
- if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
- && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
- || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
- && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
- {
- if (cmd->forwardmove != 0)
- player->mo->momz += rover->master->frontsector->floorspeed;
- else
- {
- player->mo->momz = rover->master->frontsector->floorspeed;
- climb = false;
- }
- }
- }
-
- // Gravity is flipped, so the comments are, too.
- if (player->mo->eflags & MFE_VERTICALFLIP)
- {
- // Trying to climb down past the bottom of the FOF
- if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
- {
- fixed_t bottomheight2;
- ffloor_t *roverbelow;
- boolean foundfof = false;
- floorclimb = true;
- boostup = false;
-
- // Is there a FOF directly below this one that we can move onto?
- for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
- {
- if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP))
- continue;
-
- if (roverbelow == rover)
- continue;
-
-#ifdef ESLOPE
- bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight;
-#else
- bottomheight2 = *roverbelow->bottomheight;
-#endif
-
- if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
- foundfof = true;
- }
-
- if (!foundfof)
- player->mo->momz = 0;
- }
-
- // Below the FOF
- if (topheight <= player->mo->z)
- {
- floorclimb = false;
- boostup = false;
- thrust = false;
- }
-
- // Above the FOF
- if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
- {
- floorclimb = false;
- thrust = true;
- boostup = true;
- }
- }
- else
- {
- // Trying to climb down past the bottom of a FOF
- if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
- {
- fixed_t topheight2;
- ffloor_t *roverbelow;
- boolean foundfof = false;
- floorclimb = true;
- boostup = false;
-
- // Is there a FOF directly below this one that we can move onto?
- for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
- {
- if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP))
- continue;
-
- if (roverbelow == rover)
- continue;
-
-#ifdef ESLOPE
- topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight;
-#else
- topheight2 = *roverbelow->topheight;
-#endif
-
- if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
- foundfof = true;
- }
-
- if (!foundfof)
- player->mo->momz = 0;
- }
-
- // Below the FOF
- if (bottomheight >= player->mo->z + player->mo->height)
- {
- floorclimb = false;
- boostup = false;
- thrust = false;
- }
-
- // Above the FOF
- if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
- {
- floorclimb = false;
- thrust = true;
- boostup = true;
- }
- }
-
- if (floorclimb)
- {
- if (rover->flags & FF_CRUMBLE && !(netgame && player->spectator))
- EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN));
- break;
- }
- }
- }
-
- // Gravity is flipped, so are comments.
- if (player->mo->eflags & MFE_VERTICALFLIP)
- {
- // Trying to climb down past the upper texture area
- if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
- {
- boolean foundfof = false;
- floorclimb = true;
-
- // Is there a FOF directly below that we can move onto?
- if (glidesector->sector->ffloors)
- {
- fixed_t bottomheight;
- ffloor_t *rover;
- for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
- {
- if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
- continue;
-
-#ifdef ESLOPE
- bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
-#else
- bottomheight = *rover->bottomheight;
-#endif
-
- if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
- {
- foundfof = true;
- break;
- }
- }
- }
-
- if (!foundfof)
- player->mo->momz = 0;
- }
-
- // Reached the top of the lower texture area
- if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
- && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
- {
- thrust = true;
- boostup = true;
- // Play climb-up animation here
- }
- }
+ if (onesided)
+ floorclimb = true;
else
{
- // Trying to climb down past the upper texture area
- if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
+#ifdef ESLOPE
+ floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y)
+ : glidesector->sector->floorheight;
+ ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y)
+ : glidesector->sector->ceilingheight;
+#else
+ floorheight = glidesector->sector->floorheight;
+ ceilingheight = glidesector->sector->ceilingheight;
+#endif
+
+ if (glidesector->sector->ffloors)
{
- boolean foundfof = false;
- floorclimb = true;
+ ffloor_t *rover;
+ fixed_t topheight, bottomheight; // ESLOPE
- // Is there a FOF directly below that we can move onto?
- if (glidesector->sector->ffloors)
+ for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
- ffloor_t *rover;
- for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
- {
- if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
- continue;
+ if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
+ continue;
- if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ floorclimb = true;
+
+#ifdef ESLOPE
+ bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
+ topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
+#else
+ bottomheight = *rover->bottomheight;
+ topheight = *rover->topheight;
+#endif
+
+ // Only supports rovers that are moving like an 'elevator', not just the top or bottom.
+ if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
+ {
+ if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
+ && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
+ || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
+ && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{
- foundfof = true;
- break;
+ if (cmd->forwardmove != 0)
+ player->mo->momz += rover->master->frontsector->floorspeed;
+ else
+ {
+ player->mo->momz = rover->master->frontsector->floorspeed;
+ climb = false;
+ }
}
}
- }
- if (!foundfof)
- player->mo->momz = 0;
+ // Gravity is flipped, so the comments are, too.
+ if (player->mo->eflags & MFE_VERTICALFLIP)
+ {
+ // Trying to climb down past the bottom of the FOF
+ if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
+ {
+ fixed_t bottomheight2;
+ ffloor_t *roverbelow;
+ boolean foundfof = false;
+ floorclimb = true;
+ boostup = false;
+
+ // Is there a FOF directly below this one that we can move onto?
+ for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
+ {
+ if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP))
+ continue;
+
+ if (roverbelow == rover)
+ continue;
+
+#ifdef ESLOPE
+ bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight;
+#else
+ bottomheight2 = *roverbelow->bottomheight;
+#endif
+
+ if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
+ foundfof = true;
+ }
+
+ if (!foundfof)
+ player->mo->momz = 0;
+ }
+
+ // Below the FOF
+ if (topheight <= player->mo->z)
+ {
+ floorclimb = false;
+ boostup = false;
+ thrust = false;
+ }
+
+ // Above the FOF
+ if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
+ {
+ floorclimb = false;
+ thrust = true;
+ boostup = true;
+ }
+ }
+ else
+ {
+ // Trying to climb down past the bottom of a FOF
+ if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
+ {
+ fixed_t topheight2;
+ ffloor_t *roverbelow;
+ boolean foundfof = false;
+ floorclimb = true;
+ boostup = false;
+
+ // Is there a FOF directly below this one that we can move onto?
+ for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
+ {
+ if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP))
+ continue;
+
+ if (roverbelow == rover)
+ continue;
+
+#ifdef ESLOPE
+ topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight;
+#else
+ topheight2 = *roverbelow->topheight;
+#endif
+
+ if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ foundfof = true;
+ }
+
+ if (!foundfof)
+ player->mo->momz = 0;
+ }
+
+ // Below the FOF
+ if (bottomheight >= player->mo->z + player->mo->height)
+ {
+ floorclimb = false;
+ boostup = false;
+ thrust = false;
+ }
+
+ // Above the FOF
+ if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
+ {
+ floorclimb = false;
+ thrust = true;
+ boostup = true;
+ }
+ }
+
+ if (floorclimb)
+ {
+ if (rover->flags & FF_CRUMBLE && !(netgame && player->spectator))
+ EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN));
+ break;
+ }
+ }
}
- // Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
- if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ // Gravity is flipped, so are comments.
+ if (player->mo->eflags & MFE_VERTICALFLIP)
+ {
+ // Trying to climb down past the upper texture area
+ if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
+ {
+ boolean foundfof = false;
+ floorclimb = true;
+
+ // Is there a FOF directly below that we can move onto?
+ if (glidesector->sector->ffloors)
+ {
+ fixed_t bottomheight;
+ ffloor_t *rover;
+ for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
+ {
+ if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
+ continue;
+
+#ifdef ESLOPE
+ bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
+#else
+ bottomheight = *rover->bottomheight;
+#endif
+
+ if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
+ {
+ foundfof = true;
+ break;
+ }
+ }
+ }
+
+ if (!foundfof)
+ player->mo->momz = 0;
+ }
+
+ // Reached the top of the lower texture area
+ if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
+ && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
+ {
+ thrust = true;
+ boostup = true;
+ // Play climb-up animation here
+ }
+ }
+ else
+ {
+ // Trying to climb down past the upper texture area
+ if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
+ {
+ boolean foundfof = false;
+ floorclimb = true;
+
+ // Is there a FOF directly below that we can move onto?
+ if (glidesector->sector->ffloors)
+ {
+ ffloor_t *rover;
+ for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
+ {
+ if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
+ continue;
+
+ if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ {
+ foundfof = true;
+ break;
+ }
+ }
+ }
+
+ if (!foundfof)
+ player->mo->momz = 0;
+ }
+
+ // Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
+ if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ {
+ floorclimb = true;
+ thrust = false;
+ boostup = false;
+ }
+
+ // Reached the top of the lower texture area
+ if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
+ && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
+ {
+ thrust = true;
+ boostup = true;
+ // Play climb-up animation here
+ }
+ }
+
+ // Trying to climb on the sky
+ if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
+ {
+ skyclimber = true;
+ }
+
+ // Climbing on the lower texture area?
+ if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight)
+ || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight))
{
floorclimb = true;
- thrust = false;
- boostup = false;
- }
- // Reached the top of the lower texture area
- if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
- && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
- {
- thrust = true;
- boostup = true;
- // Play climb-up animation here
- }
- }
-
- // Trying to climb on the sky
- if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
- {
- skyclimber = true;
- }
-
- // Climbing on the lower texture area?
- if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight)
- || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight))
- {
- floorclimb = true;
-
- if (glidesector->sector->floorspeed)
- {
- if (cmd->forwardmove != 0)
- player->mo->momz += glidesector->sector->floorspeed;
- else
+ if (glidesector->sector->floorspeed)
{
- player->mo->momz = glidesector->sector->floorspeed;
- climb = false;
+ if (cmd->forwardmove != 0)
+ player->mo->momz += glidesector->sector->floorspeed;
+ else
+ {
+ player->mo->momz = glidesector->sector->floorspeed;
+ climb = false;
+ }
}
}
- }
- // Climbing on the upper texture area?
- else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight)
- || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight))
- {
- floorclimb = true;
-
- if (glidesector->sector->ceilspeed)
+ // Climbing on the upper texture area?
+ else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight)
+ || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight))
{
- if (cmd->forwardmove != 0)
- player->mo->momz += glidesector->sector->ceilspeed;
- else
+ floorclimb = true;
+
+ if (glidesector->sector->ceilspeed)
{
- player->mo->momz = glidesector->sector->ceilspeed;
- climb = false;
+ if (cmd->forwardmove != 0)
+ player->mo->momz += glidesector->sector->ceilspeed;
+ else
+ {
+ player->mo->momz = glidesector->sector->ceilspeed;
+ climb = false;
+ }
}
}
}
@@ -2871,94 +2860,20 @@ static boolean PIT_CheckSolidsTeeter(mobj_t *thing)
//
static void P_DoTeeter(player_t *player)
{
- msecnode_t *node;
boolean teeter = false;
boolean roverfloor; // solid 3d floors?
- boolean checkedforteeter = false;
+ fixed_t floorheight, ceilingheight;
+ fixed_t topheight, bottomheight; // for 3d floor usage
const fixed_t tiptop = FixedMul(MAXSTEPMOVE, player->mo->scale); // Distance you have to be above the ground in order to teeter.
- for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
+ if (player->mo->standingslope && player->mo->standingslope->zdelta >= (FRACUNIT/2)) // Always teeter if the slope is too steep.
+ teeter = true;
+ else // Let's do some checks...
{
- // Ledge teetering. Check if any nearby sectors are low enough from your current one.
- checkedforteeter = true;
- roverfloor = false;
- if (node->m_sector->ffloors)
- {
- ffloor_t *rover;
- for (rover = node->m_sector->ffloors; rover; rover = rover->next)
- {
- if (!(rover->flags & FF_EXISTS)) continue;
-
- if (P_CheckSolidLava(player->mo, rover))
- ;
- else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
- continue; // intangible 3d floor
-
- if (player->mo->eflags & MFE_VERTICALFLIP)
- {
- if (*rover->bottomheight > node->m_sector->ceilingheight) // Above the ceiling
- continue;
-
- if (*rover->bottomheight > player->mo->z + player->mo->height + tiptop
- || (*rover->topheight < player->mo->z
- && player->mo->z + player->mo->height < node->m_sector->ceilingheight - tiptop))
- {
- teeter = true;
- roverfloor = true;
- }
- else
- {
- teeter = false;
- roverfloor = true;
- break;
- }
- }
- else
- {
- if (*rover->topheight < node->m_sector->floorheight) // Below the floor
- continue;
-
- if (*rover->topheight < player->mo->z - tiptop
- || (*rover->bottomheight > player->mo->z + player->mo->height
- && player->mo->z > node->m_sector->floorheight + tiptop))
- {
- teeter = true;
- roverfloor = true;
- }
- else
- {
- teeter = false;
- roverfloor = true;
- break;
- }
- }
- }
- }
-
- if (!teeter && !roverfloor)
- {
- if (player->mo->eflags & MFE_VERTICALFLIP)
- {
- if (node->m_sector->ceilingheight > player->mo->z + player->mo->height + tiptop)
- teeter = true;
- }
- else
- {
- if (node->m_sector->floorheight < player->mo->z - tiptop)
- teeter = true;
- }
- }
- }
-
- if (checkedforteeter && !teeter) // Backup code
- {
- subsector_t *subsec[4]; // changed abcd into array instead
UINT8 i;
-
- subsec[0] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale));
- subsec[1] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale));
- subsec[2] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
- subsec[3] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
+ sector_t *sec;
+ fixed_t highestceilingheight = INT32_MIN;
+ fixed_t lowestfloorheight = INT32_MAX;
teeter = false;
roverfloor = false;
@@ -2966,13 +2881,43 @@ static void P_DoTeeter(player_t *player)
{
ffloor_t *rover;
- if (!(subsec[i]->sector->ffloors))
+#define xsign ((i & 1) ? -1 : 1) // 0 -> 1 | 1 -> -1 | 2 -> 1 | 3 -> -1
+#define ysign ((i & 2) ? 1 : -1) // 0 -> 1 | 1 -> 1 | 2 -> -1 | 3 -> -1
+ fixed_t checkx = player->mo->x + (xsign*FixedMul(5*FRACUNIT, player->mo->scale));
+ fixed_t checky = player->mo->y + (ysign*FixedMul(5*FRACUNIT, player->mo->scale));
+#undef xsign
+#undef ysign
+
+ sec = R_PointInSubsector(checkx, checky)->sector;
+
+ ceilingheight = sec->ceilingheight;
+ floorheight = sec->floorheight;
+#ifdef ESLOPE
+ if (sec->c_slope)
+ ceilingheight = P_GetZAt(sec->c_slope, checkx, checky);
+ if (sec->f_slope)
+ floorheight = P_GetZAt(sec->f_slope, checkx, checky);
+#endif
+ highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight;
+ lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight;
+
+ if (!(sec->ffloors))
continue; // move on to the next subsector
- for (rover = subsec[i]->sector->ffloors; rover; rover = rover->next)
+ for (rover = sec->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS)) continue;
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
+#endif
+
if (P_CheckSolidLava(player->mo, rover))
;
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
@@ -2980,12 +2925,12 @@ static void P_DoTeeter(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
- if (*rover->bottomheight > subsec[i]->sector->ceilingheight) // Above the ceiling
+ if (bottomheight > ceilingheight) // Above the ceiling
continue;
- if (*rover->bottomheight > player->mo->z + player->mo->height + tiptop
- || (*rover->topheight < player->mo->z
- && player->mo->z + player->mo->height < subsec[i]->sector->ceilingheight - tiptop))
+ if (bottomheight > player->mo->z + player->mo->height + tiptop
+ || (topheight < player->mo->z
+ && player->mo->z + player->mo->height < ceilingheight - tiptop))
{
teeter = true;
roverfloor = true;
@@ -2999,12 +2944,12 @@ static void P_DoTeeter(player_t *player)
}
else
{
- if (*rover->topheight < subsec[i]->sector->floorheight) // Below the floor
+ if (topheight < floorheight) // Below the floor
continue;
- if (*rover->topheight < player->mo->z - tiptop
- || (*rover->bottomheight > player->mo->z + player->mo->height
- && player->mo->z > subsec[i]->sector->floorheight + tiptop))
+ if (topheight < player->mo->z - tiptop
+ || (bottomheight > player->mo->z + player->mo->height
+ && player->mo->z > floorheight + tiptop))
{
teeter = true;
roverfloor = true;
@@ -3022,18 +2967,12 @@ static void P_DoTeeter(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
- if (!teeter && !roverfloor && (subsec[0]->sector->ceilingheight > player->mo->ceilingz + tiptop
- || subsec[1]->sector->ceilingheight > player->mo->ceilingz + tiptop
- || subsec[2]->sector->ceilingheight > player->mo->ceilingz + tiptop
- || subsec[3]->sector->ceilingheight > player->mo->ceilingz + tiptop))
+ if (!teeter && !roverfloor && (highestceilingheight > player->mo->ceilingz + tiptop))
teeter = true;
}
else
{
- if (!teeter && !roverfloor && (subsec[0]->sector->floorheight < player->mo->floorz - tiptop
- || subsec[1]->sector->floorheight < player->mo->floorz - tiptop
- || subsec[2]->sector->floorheight < player->mo->floorz - tiptop
- || subsec[3]->sector->floorheight < player->mo->floorz - tiptop))
+ if (!teeter && !roverfloor && (lowestfloorheight < player->mo->floorz - tiptop))
teeter = true;
}
}
@@ -3169,7 +3108,7 @@ teeterdone:
if (player->panim == PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_EDGE);
}
- else if (checkedforteeter && player->panim == PA_EDGE)
+ else if (player->panim == PA_EDGE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
@@ -3445,16 +3384,11 @@ static void P_DoSuperStuff(player_t *player)
if ((leveltime % TICRATE == 0) && !(player->exiting))
player->rings--;
- // future todo: a skin option for this, and possibly more colors
- switch (player->skin)
- {
- case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break;
- case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break;
- default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break;
- }
- player->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
+ player->mo->color = (player->pflags & PF_GODMODE && cv_debug == 0)
+ ? (SKINCOLOR_SUPERSILVER1 + 5*((leveltime >> 1) % 7)) // A wholesome easter egg.
+ : skins[player->skin].supercolor + (unsigned)abs( ( (signed)(leveltime >> 1) % 9) - 4); // This is where super flashing is handled.
- if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
+ if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->powers[pw_carry])
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
{
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
@@ -3506,6 +3440,9 @@ static void P_DoSuperStuff(player_t *player)
case S_PLAY_SUPER_RUN:
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
break;
+ case S_PLAY_SUPER_PEEL:
+ P_SetPlayerMobjState(player->mo, S_PLAY_PEEL);
+ break;
case S_PLAY_SUPER_PAIN:
P_SetPlayerMobjState(player->mo, S_PLAY_PAIN);
break;
@@ -3613,22 +3550,22 @@ void P_DoJump(player_t *player, boolean soundandstate)
return;
// Jump this high.
- if (player->pflags & PF_CARRIED)
+ if (player->powers[pw_carry] == CR_PLAYER)
{
player->mo->momz = 9*FRACUNIT;
- player->pflags &= ~PF_CARRIED;
+ player->powers[pw_carry] = CR_NONE;
if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true);
}
- else if (player->pflags & PF_ITEMHANG)
+ else if (player->powers[pw_carry] == CR_GENERIC)
{
player->mo->momz = 9*FRACUNIT;
- player->pflags &= ~PF_ITEMHANG;
+ player->powers[pw_carry] = CR_NONE;
}
- else if (player->pflags & PF_ROPEHANG)
+ else if (player->powers[pw_carry] == CR_ROPEHANG)
{
player->mo->momz = 12*FRACUNIT;
- player->pflags &= ~PF_ROPEHANG;
+ player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
else if (player->mo->eflags & MFE_GOOWATER)
@@ -3666,13 +3603,10 @@ void P_DoJump(player_t *player, boolean soundandstate)
}
}
else if (player->charability2 == CA2_MULTIABILITY &&
- (player->charability == CA_DOUBLEJUMP || player->charability == CA_FLOAT || player->charability == CA_SLOWFALL))
+ (player->charability == CA_FLOAT || player->charability == CA_SLOWFALL))
{
// Multiability exceptions, since some abilities cannot effectively use it and need a boost.
- if (player->charability == CA_DOUBLEJUMP)
- player->mo->momz = 23*(FRACUNIT/2); // Increased jump height instead of infinite jumps.
- else if (player->charability == CA_FLOAT || player->charability == CA_SLOWFALL)
- player->mo->momz = 12*FRACUNIT; // Increased jump height due to ineffective repeat.
+ player->mo->momz = 12*FRACUNIT; // Increased jump height due to ineffective repeat.
}
else
{
@@ -3698,6 +3632,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
if (twodlevel || (player->mo->flags2 & MF2_TWOD))
factor += player->jumpfactor / 10;
+ if (player->charability2 == CA2_MULTIABILITY && player->charability == CA_DOUBLEJUMP)
+ factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time
+
P_SetObjectMomZ(player->mo, FixedMul(factor, player->mo->momz), false); // Custom height
// set just an eensy above the ground
@@ -3726,19 +3663,16 @@ void P_DoJump(player_t *player, boolean soundandstate)
if (!player->spectator)
S_StartSound(player->mo, sfx_jump); // Play jump sound!
- if (!(player->charability2 == CA2_SPINDASH))
- P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
- else
- P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
+ P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
}
//
-// P_DoSpinDash
+// P_DoSpinAbility
//
// Player spindash handling
//
-static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
+static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{
if (player->pflags & PF_STASIS)
return;
@@ -3757,43 +3691,45 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
{
if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)
#ifdef ESLOPE
- && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+ && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{
player->mo->momx = player->cmomx;
player->mo->momy = player->cmomy;
player->pflags |= PF_STARTDASH|PF_SPINNING;
- player->dashspeed = FixedMul(FRACUNIT, player->mo->scale);
- player->dashtime = 0;
+ player->dashspeed = player->mindash;
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
player->pflags |= PF_USEDOWN;
+ if (!player->spectator)
+ S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh.
}
else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH))
{
- player->dashspeed += FixedMul(FRACUNIT, player->mo->scale);
-
- if (!(player->dashtime++ % 5))
+ if (player->dashspeed < player->maxdash)
{
- if (!player->spectator && player->dashspeed < FixedMul(player->maxdash, player->mo->scale))
- S_StartSound(player->mo, sfx_spndsh); // Make the rev sound!
-
- // Now spawn the color thok circle.
- if (player->mo->sprite2 != SPR2_DASH)
- {
- P_SpawnSpinMobj(player, player->revitem);
- if (demorecording)
- G_GhostAddRev();
- }
+#define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash)
+ fixed_t soundcalculation = chargecalculation;
+ player->dashspeed += FRACUNIT;
+ if (!player->spectator && soundcalculation != chargecalculation)
+ S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh.
+#undef chargecalculation
+ }
+ if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle.
+ {
+ P_SpawnSpinMobj(player, player->revitem);
+ if (demorecording)
+ G_GhostAddRev();
}
}
+
// If not moving up or down, and travelling faster than a speed of four while not holding
// down the spin button and not spinning.
// AKA Just go into a spin on the ground, you idiot. ;)
else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20))
&& !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<mo->scale)
#ifdef ESLOPE
- || (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
+ || (player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
#endif
) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
{
@@ -3809,7 +3745,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale)
#ifdef ESLOPE
- && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+ && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{
@@ -3826,26 +3762,59 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
}
// Catapult the player from a spindash rev!
- if (onground && !(player->pflags & PF_USEDOWN) && player->dashspeed && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING))
+ if (onground && !(player->pflags & PF_USEDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING))
{
+ player->pflags &= ~PF_STARTDASH;
if (player->powers[pw_ingoop])
player->dashspeed = 0;
- player->pflags &= ~PF_STARTDASH;
if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE))
{
- P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
- P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!!
+ if (player->dashspeed)
+ {
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
+ P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->dashspeed, player->mo->scale)); // catapult forward ho!!
+ }
+ else
+ {
+ P_SetPlayerMobjState(player->mo, S_PLAY_STND);
+ player->pflags &= ~PF_SPINNING;
+ }
+
if (!player->spectator)
S_StartSound(player->mo, sfx_zoom);
}
+
player->dashspeed = 0;
}
- if (onground && player->pflags & PF_STARTDASH && player->mo->state-states != S_PLAY_DASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
+ if (onground && player->pflags & PF_STARTDASH)
+ {
+ if (player->mo->state-states != S_PLAY_DASH)
+ P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
+ }
else if (onground && player->pflags & PF_SPINNING && !(player->panim == PA_ROLL))
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
+
+ // Melee attack
+ if ((player->charability2 == CA2_MELEE) && !(player->panim == PA_ABILITY2) && !player->exiting
+ && !P_PlayerInPain(player) && (cmd->buttons & BT_USE) && player->speed < FixedMul(10<mo->scale)
+ && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN)
+#ifdef ESLOPE
+ && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+#endif
+ )
+ {
+ P_ResetPlayer(player);
+ player->mo->z += P_MobjFlip(player->mo);
+ player->mo->momx = player->cmomx = 0;
+ player->mo->momy = player->cmomy = 0;
+ P_SetObjectMomZ(player->mo, player->mindash, false);
+ P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->maxdash, player->mo->scale));
+ P_SetPlayerMobjState(player->mo, S_PLAY_MELEE);
+ player->pflags |= PF_USEDOWN;
+ S_StartSound(player->mo, sfx_s3k8b);
+ }
}
//
@@ -3933,9 +3902,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPDOWN) && !player->exiting && !P_PlayerInPain(player))
{
- if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG))
+ if (player->mo->tracer && player->powers[pw_carry] == CR_MACESPIN)
{}
- else if (player->pflags & PF_MACESPIN && player->mo->tracer)
+ else if (onground || player->climbing || (player->mo->tracer && player->powers[pw_carry]))
{}
else if (!(player->pflags & PF_SLIDING) && ((gametype != GT_CTF) || (!player->gotflag)))
{
@@ -4008,19 +3977,19 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->secondjump = 0;
player->pflags &= ~PF_THOKKED;
}
+ else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer)
+ {
+ player->powers[pw_carry] = CR_NONE;
+ player->powers[pw_flashing] = TICRATE/4;
+ }
else
// can't jump while in air, can't jump while jumping
- if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG))
+ if (onground || player->climbing || player->powers[pw_carry])
{
P_DoJump(player, true);
player->secondjump = 0;
player->pflags &= ~PF_THOKKED;
}
- else if (player->pflags & PF_MACESPIN && player->mo->tracer)
- {
- player->pflags &= ~PF_MACESPIN;
- player->powers[pw_flashing] = TICRATE/4;
- }
else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag))
;
else if (P_SuperReady(player))
@@ -4039,19 +4008,26 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
case CA_THOK:
case CA_HOMINGTHOK:
case CA_JUMPTHOK: // Credit goes to CZ64 and Sryder13 for the original
+ case CA_DASHMODE: // Credit goes to Iceman404
// Now it's Sonic's abilities turn!
// THOK!
if (!(player->pflags & PF_THOKKED) || (player->charability2 == CA2_MULTIABILITY))
{
// Catapult the player
fixed_t actionspd = player->actionspd;
+
+ if (player->charability == CA_DASHMODE)
+ actionspd = max(player->normalspeed, FixedDiv(player->speed, player->mo->scale));
+
if (player->mo->eflags & MFE_UNDERWATER)
actionspd >>= 1;
+
if ((player->charability == CA_JUMPTHOK) && !(player->pflags & PF_THOKKED))
{
player->pflags &= ~PF_JUMPED;
P_DoJump(player, false);
}
+
P_InstaThrust(player->mo, player->mo->angle, FixedMul(actionspd, player->mo->scale));
if (maptol & TOL_2D)
@@ -4085,7 +4061,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break;
case CA_FLY:
- case CA_SWIM: // Swim
+ case CA_SWIM:
// If currently in the air from a jump, and you pressed the
// button again and have the ability to fly, do so!
if (player->charability == CA_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
@@ -4097,13 +4073,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer
player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH);
- player->pflags |= PF_THOKKED;
+ player->pflags |= (PF_THOKKED|PF_CANCARRY);
}
break;
case CA_GLIDEANDCLIMB:
// Now Knuckles-type abilities are checked.
- // If you can turn super and aren't already,
- // and you don't have a shield, do it!
if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY)
{
INT32 glidespeed = player->actionspd;
@@ -4117,14 +4091,17 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
}
break;
case CA_DOUBLEJUMP: // Double-Jump
- if (!(player->pflags & PF_THOKKED))
+ if (!(player->pflags & PF_THOKKED) || ((player->charability2 == CA2_MULTIABILITY) && (player->secondjump < (player->actionspd >> FRACBITS))))
{
- player->pflags &= ~PF_JUMPED;
- P_DoJump(player, true);
-
// Allow infinite double jumping if super.
if (!player->powers[pw_super])
player->pflags |= PF_THOKKED;
+ else
+ player->secondjump = 0;
+
+ player->pflags &= ~PF_JUMPED;
+ P_DoJump(player, true);
+ player->secondjump++;
}
break;
case CA_FLOAT: // Float
@@ -4148,7 +4125,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->pflags |= PF_THOKKED;
}
break;
-
case CA_AIRDRILL:
if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY)
{
@@ -4157,6 +4133,15 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
S_StartSound(player->mo, sfx_spndsh);
}
break;
+ case CA_TWINSPIN:
+ if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY)
+ {
+ player->pflags |= PF_THOKKED;
+ S_StartSound(player->mo, sfx_s3k42);
+ player->mo->frame = 0;
+ P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
+ }
+ break;
default:
break;
}
@@ -4778,7 +4763,7 @@ static void P_3dMovement(player_t *player)
#ifdef ESLOPE
if ((totalthrust.x || totalthrust.y)
- && player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
+ && player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
// Factor thrust to slope, but only for the part pushing up it!
// The rest is unaffected.
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
@@ -4962,14 +4947,29 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
if (player->exiting)
return;
- // You're welcome, Rob. (Now with slightly less horrendous hacking -Red
- player->mo->tracer->flags &= ~MF_NOCLIP;
- player->mo->tracer->z = player->mo->z;
- if (!P_TryMove(player->mo->tracer, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)) {
- player->mo->tracer->flags |= MF_NOCLIP;
- return;
+ /*
+ In some ways worse, in some ways better.
+ I did the following this way because the player object has to deal with touchspecials too, not just solids.
+ There were all sorts of fun bugs when the player got to touch the goal a frame earlier than it should've.
+ Technically, we lose out on being blocked by MF_SOLID objects, but official stages don't use them on the track.
+ I know we probably could've kept around MT_NIGHTSCHAR in some fashion, having an invisible hitbox following the
+ player around... but I'd already removed all its references, restructured the way the chaos emerald follows
+ the player around to fill the player->mo->tracer gap left behind, and NiGHTS is a lag magnet (lagnet?)
+ enough as it is... so whatever.
+ ~toast
+ */
+ {
+ fixed_t prevx = player->mo->x;
+ fixed_t prevy = player->mo->y;
+ boolean notallowed;
+ player->mo->flags |= MF_NOCLIPTHING; // player = NULL; // YIKES
+ notallowed = (!(P_TryMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)));
+ P_TeleportMove(player->mo, prevx, prevy, player->mo->z);
+ player->mo->flags &= ~MF_NOCLIPTHING; // player = player; // unyikes
+ if (notallowed)
+ return;
}
- player->mo->tracer->flags |= MF_NOCLIP;
+
{
const INT32 sequence = player->mo->target->threshold;
mobj_t *transfer1 = NULL;
@@ -5359,10 +5359,6 @@ static void P_DoNiGHTSCapsule(player_t *player)
{
INT32 i;
- if ((player->pflags & PF_NIGHTSMODE) && (player->mo->tracer->state < &states[S_NIGHTSHURT1]
- || player->mo->tracer->state > &states[S_NIGHTSHURT32]))
- P_SetMobjState(player->mo->tracer, S_NIGHTSHURT1);
-
if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT)
{
P_UnsetThingPosition(player->mo);
@@ -5400,6 +5396,20 @@ static void P_DoNiGHTSCapsule(player_t *player)
else if (player->mo->z < player->capsule->z+(player->capsule->height/3))
player->mo->momz = 2*FRACUNIT;
+ if (player->pflags & PF_NIGHTSMODE)
+ {
+ if (player->mo->momx || player->mo->momy || player->mo->momz)
+ {
+ if (player->mo->state != &states[S_PLAY_NIGHTS_PULL])
+ P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_PULL);
+ }
+ else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK])
+ {
+ S_StartSound(player->mo, sfx_spin);
+ P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_ATTACK);
+ }
+ }
+
if (G_IsSpecialStage(gamemap))
{ // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here!
for (i = 0; i < MAXPLAYERS; i++)
@@ -5426,7 +5436,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<capsule->health <= 0)
{
@@ -5464,13 +5474,13 @@ static void P_DoNiGHTSCapsule(player_t *player)
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
}*/
- if (player->mo->tracer)
+ if (player->pflags & PF_NIGHTSMODE)
{
// Only give it to ONE person, and THAT player has to get to the goal!
emmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->info->height, MT_GOTEMERALD);
P_SetTarget(&emmo->target, player->mo);
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
- P_SetTarget(&player->mo->tracer->target, emmo);
+ P_SetTarget(&player->mo->tracer, emmo);
}
// Okay, we're doing this down here because we're handling time weirdly for co-op special stages
@@ -5529,7 +5539,8 @@ static void P_NiGHTSMovement(player_t *player)
ticcmd_t *cmd = &player->cmd;
INT32 thrustfactor;
INT32 i;
- statenum_t flystate = S_NIGHTSFLY1A;
+ statenum_t flystate;
+ UINT16 visangle;
player->pflags &= ~PF_DRILLING;
@@ -5548,7 +5559,7 @@ static void P_NiGHTSMovement(player_t *player)
player->drillmeter = TICRATE/10;
}
- if (!player->mo->tracer)
+ if (!(player->pflags & PF_NIGHTSMODE))
{
P_DeNightserizePlayer(player);
return;
@@ -5563,13 +5574,14 @@ static void P_NiGHTSMovement(player_t *player)
&& (players[i].capsule && players[i].capsule->reactiontime))
capsule = true;
if (!capsule
- && !(player->mo->tracer->state >= &states[S_SUPERTRANS1]
- && player->mo->tracer->state <= &states[S_SUPERTRANS9])
+ && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+ && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9])
&& !player->exiting)
player->nightstime--;
}
else if (gametype != GT_RACE && gametype != GT_COMPETITION
- && !(player->mo->tracer->state >= &states[S_SUPERTRANS1] && player->mo->tracer->state <= &states[S_SUPERTRANS9])
+ && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+ && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9])
&& !(player->capsule && player->capsule->reactiontime)
&& !player->exiting)
player->nightstime--;
@@ -5654,8 +5666,6 @@ static void P_NiGHTSMovement(player_t *player)
radius = player->mo->target->radius;
player->mo->flags |= MF_NOGRAVITY;
- player->mo->flags2 |= MF2_DONTDRAW;
- P_SetScale(player->mo->tracer, player->mo->scale);
if (player->mo->eflags & MFE_VERTICALFLIP)
cmd->forwardmove = (SINT8)(-cmd->forwardmove);
@@ -5710,28 +5720,25 @@ static void P_NiGHTSMovement(player_t *player)
return;
}
- if (player->mo->tracer->state >= &states[S_SUPERTRANS1]
- && player->mo->tracer->state <= &states[S_SUPERTRANS9])
+ if (player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+ && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9])
{
player->mo->momx = player->mo->momy = player->mo->momz = 0;
return;
}
- if (player->exiting > 0 && player->exiting < 2*TICRATE)
+ if (player->exiting > 0) // && player->exiting < 2*TICRATE)
{
player->mo->momx = player->mo->momy = 0;
if (gametype != GT_RACE && gametype != GT_COMPETITION)
- P_SetObjectMomZ(player->mo, 30*FRACUNIT, false);
+ P_SetObjectMomZ(player->mo, FRACUNIT/2, true);
- player->mo->tracer->angle += ANGLE_11hh;
+ if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL6])
+ P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL6);
- if (!(player->mo->tracer->state >= &states[S_NIGHTSDRONE1]
- && player->mo->tracer->state <= &states[S_NIGHTSDRONE2]))
- P_SetMobjState(player->mo->tracer, S_NIGHTSDRONE1);
-
- player->mo->tracer->flags |= MF_NOCLIPHEIGHT;
player->mo->flags |= MF_NOCLIPHEIGHT;
+
return;
}
@@ -5997,74 +6004,41 @@ static void P_NiGHTSMovement(player_t *player)
// NiGHTS flying state
// Yep, I just ripped out almost 1000 lines of code.
- if ((player->anotherflyangle >= 12 && player->anotherflyangle <= 33) // +x +y
- || (player->anotherflyangle >= 147 && player->anotherflyangle <= 168)) // -x +y
- flystate = S_NIGHTSFLY2A;
- else if ((player->anotherflyangle >= 34 && player->anotherflyangle <= 56) // +x +y
- || (player->anotherflyangle >= 124 && player->anotherflyangle <= 146)) // -x +y
- flystate = S_NIGHTSFLY3A;
- else if ((player->anotherflyangle >= 57 && player->anotherflyangle <= 79) // +x +y
- || (player->anotherflyangle >= 102 && player->anotherflyangle <= 123)) // -x +y
- flystate = S_NIGHTSFLY4A;
- else if (player->anotherflyangle >= 80 && player->anotherflyangle <= 101)
- flystate = S_NIGHTSFLY5A;
- else if ((player->anotherflyangle >= 192 && player->anotherflyangle <= 213) // -x -y
- || (player->anotherflyangle >= 327 && player->anotherflyangle <= 348)) // +x -y
- flystate = S_NIGHTSFLY6A;
- else if ((player->anotherflyangle >= 214 && player->anotherflyangle <= 236) // -x -y
- || (player->anotherflyangle >= 305 && player->anotherflyangle <= 326)) // +x -y
- flystate = S_NIGHTSFLY7A;
- else if ((player->anotherflyangle >= 237 && player->anotherflyangle <= 258) // -x -y
- || (player->anotherflyangle >= 282 && player->anotherflyangle <= 304)) // +x -y
- flystate = S_NIGHTSFLY8A;
- else if (player->anotherflyangle >= 259 && player->anotherflyangle <= 281)
- flystate = S_NIGHTSFLY9A;
+ // (and then toast revamped the entire thing again to be better, but not by much)
+ if (still)
+ flystate = (P_IsObjectOnGround(player->mo)) ? S_PLAY_NIGHTS_STAND : S_PLAY_NIGHTS_FLOAT;
else
- flystate = S_NIGHTSFLY1A;
-
- if (player->mo->eflags & MFE_VERTICALFLIP)
{
- if (flystate >= S_NIGHTSFLY2A && flystate <= S_NIGHTSFLY5A)
- flystate += 24; // shift to S_NIGHTSFLY6A
- else if (flystate >= S_NIGHTSFLY6A && flystate <= S_NIGHTSFLY9A)
- flystate -= 24; // shift to S_NIGHTSFLY2A
- }
+ visangle = ((player->anotherflyangle + 7) % 360)/15;
+ if (visangle > 18) // Over 270 degrees.
+ visangle = 30 - visangle;
+ else if (visangle > 12) // Over 180 degrees.
+ visangle -= 6;
+ else if (visangle > 6) // Over 90 degrees.
+ visangle = 12 - visangle;
- if (player->pflags & PF_DRILLING)
- {
- const statenum_t drillstate = flystate + 2;
-
- if (!(player->mo->tracer->state >= &states[drillstate]
- && player->mo->tracer->state <= &states[drillstate+4]))
+ if (player->mo->eflags & MFE_VERTICALFLIP && visangle) // S_PLAY_NIGHTS_FLY0 stays the same, even in reverse gravity
{
- if (!(player->mo->tracer->state >= &states[S_NIGHTSFLY1A]
- && player->mo->tracer->state <= &states[S_NIGHTSFLY9B]))
- {
- const INT32 framenum = player->mo->tracer->state->frame & 3;
-
- if (framenum == 3) // Drilld special case
- P_SetMobjStateNF(player->mo->tracer, drillstate);
- else
- P_SetMobjStateNF(player->mo->tracer, drillstate+framenum+1);
- }
+ if (visangle > 6)
+ visangle -= 6; // shift to S_PLAY_NIGHTS_FLY1-6
else
- P_SetMobjStateNF(player->mo->tracer, drillstate);
+ visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C
}
+
+ flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_FLY0-C - the *2 is to skip over drill states
+
+ if (player->pflags & PF_DRILLING)
+ flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C
}
- else
- P_SetMobjStateNF(player->mo->tracer, leveltime & 1 ? flystate : flystate+1);
+
+ if (player->mo->state != &states[flystate])
+ P_SetPlayerMobjState(player->mo, flystate);
if (player == &players[consoleplayer])
localangle = player->mo->angle;
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
- if (still)
- {
- P_SetMobjStateNF(player->mo->tracer, S_NIGHTSDRONE1);
- player->mo->tracer->angle = player->mo->angle;
- }
-
// Check for crushing in our new location
if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
&& !(player->mo->flags & MF_NOCLIP))
@@ -6088,8 +6062,6 @@ static void P_NiGHTSMovement(player_t *player)
else if (player == &players[secondarydisplayplayer])
localaiming2 = movingangle;
- player->mo->tracer->angle = player->mo->angle;
-
if ((player->pflags & PF_DRILLING) && !player->bumpertime)
{
if (firstdrill)
@@ -6394,6 +6366,15 @@ static void P_MovePlayer(player_t *player)
// Locate the capsule for this mare.
else if (maptol & TOL_NIGHTS)
{
+ if ((player->pflags & PF_NIGHTSMODE)
+ && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+ && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6] // NOT 9 - it's 6 when the player turns their supercolor.
+ && !(player->exiting)))
+ {
+ skin_t *skin = ((skin_t *)(player->mo->skin));
+ player->mo->color = (skin->flags & SF_SUPER) ? skin->supercolor + (unsigned)abs(((signed)(leveltime >> 1) % 9) - 4) : player->mo->color; // This is where super flashing is handled.
+ }
+
if (!player->capsule && !player->bonustime)
{
thinker_t *th;
@@ -6476,9 +6457,12 @@ static void P_MovePlayer(player_t *player)
if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && !onground))
{
+ // If the player is in dashmode, here's their peelout.
+ if (player->charability == CA_DASHMODE && player->dashmode >= 3*TICRATE && player->panim == PA_RUN && !player->skidtime && (onground || player->powers[pw_super]))
+ P_SetPlayerMobjState (player->mo, S_PLAY_PEEL);
// If the player is moving fast enough,
// break into a run!
- if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || player->powers[pw_super]))
+ else if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || player->powers[pw_super]))
P_SetPlayerMobjState (player->mo, S_PLAY_RUN);
// Super floating at slow speeds has its own special animation.
@@ -6490,6 +6474,11 @@ static void P_MovePlayer(player_t *player)
P_SetPlayerMobjState (player->mo, S_PLAY_WALK);
}
+ // If your peelout animation is playing, and you're
+ // going too slow, switch back to the run.
+ if (player->charability == CA_DASHMODE && player->panim == PA_PEEL && player->dashmode < 3*TICRATE)
+ P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
+
// If your running animation is playing, and you're
// going too slow, switch back to the walking frames.
if (player->panim == PA_RUN && player->speed < runspd)
@@ -6500,11 +6489,13 @@ static void P_MovePlayer(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
}
- // If Springing, but travelling DOWNWARD, change back!
- if (player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0)
+ // If Springing (or nojumpspinning), but travelling DOWNWARD, change back! (nojumpspin also turns to fall once PF_THOKKED is added.)
+ if ((player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0)
+ || ((((player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED) && player->panim == PA_JUMP))
+ && (P_MobjFlip(player->mo)*player->mo->momz < 0)))
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
- // If Springing but on the ground, change back!
- else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz)
+ // If doing an air animation but on the ground, change back!
+ else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE || player->panim == PA_JUMP) && !player->mo->momz)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
// If you are stopped and are still walking, stand still!
@@ -6527,24 +6518,15 @@ static void P_MovePlayer(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
- // Cap the speed limit on a spindash
- // Up the 60*FRACUNIT number to boost faster, you speed demon you!
- if (player->dashspeed > FixedMul(player->maxdash, player->mo->scale))
- player->dashspeed = FixedMul(player->maxdash, player->mo->scale);
- else if (player->dashspeed > 0 && player->dashspeed < FixedMul(player->mindash, player->mo->scale))
- player->dashspeed = FixedMul(player->mindash, player->mo->scale);
-
- if (!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding?
+ if ((!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding?
+ && (player->pflags & PF_GLIDING || player->climbing))
{
- if (player->pflags & PF_GLIDING || player->climbing)
+ if (onground)
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
+ else
{
- if (onground)
- P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
- else
- {
- player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
- }
+ player->pflags |= PF_JUMPED;
+ P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
player->pflags &= ~PF_GLIDING;
player->glidetime = 0;
@@ -6635,7 +6617,7 @@ static void P_MovePlayer(player_t *player)
&& (player->speed > runspd || (player->pflags & PF_STARTDASH))
&& leveltime % (TICRATE/7) == 0 && player->mo->momz == 0 && !(player->pflags & PF_SLIDING) && !player->spectator)
{
- mobj_t *water = P_SpawnMobj(player->mo->x, player->mo->y,
+ 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[MT_SPLISH].height, player->mo->scale) : player->mo->watertop), MT_SPLISH);
if (player->mo->eflags & MFE_GOOWATER)
S_StartSound(water, sfx_ghit);
@@ -6765,7 +6747,7 @@ static void P_MovePlayer(player_t *player)
&& !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
P_ElementalFireTrail(player);
- P_DoSpinDash(player, cmd);
+ P_DoSpinAbility(player, cmd);
// jumping
P_DoJumpStuff(player, cmd);
@@ -6820,8 +6802,8 @@ static void P_MovePlayer(player_t *player)
#endif
}
// Otherwise, face the direction you're travelling.
- else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL
- || (player->mo->state-states == S_PLAY_FLY || player->mo->state-states == S_PLAY_FLY_TIRED))
+ else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_PEEL || player->panim == PA_ROLL || player->panim == PA_JUMP
+ || (player->panim == PA_ABILITY && player->mo->state-states == S_PLAY_GLIDE))
player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
// Update the local angle control.
@@ -6864,7 +6846,7 @@ static void P_MovePlayer(player_t *player)
if (player->skin == 0 && player->powers[pw_super] && player->speed > FixedMul(5<mo->scale)
&& P_MobjFlip(player->mo)*player->mo->momz <= 0)
{
- if (player->panim == PA_ROLL || player->mo->state-states == S_PLAY_PAIN || player->panim == PA_WALK)
+ if (player->panim == PA_ROLL || player->panim == PA_JUMP || player->mo->state-states == S_PLAY_PAIN || player->panim == PA_WALK)
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_FLOAT);
player->mo->momz = 0;
@@ -6930,7 +6912,7 @@ static void P_MovePlayer(player_t *player)
// Check for teeter!
if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER)
- && player->panim == PA_IDLE && !(player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG)))
+ && player->panim == PA_IDLE && !(player->powers[pw_carry]))
P_DoTeeter(player);
// Toss a flag
@@ -6951,7 +6933,8 @@ static void P_MovePlayer(player_t *player)
// Less height while spinning. Good for spinning under things...?
if ((player->mo->state == &states[player->mo->info->painstate] || player->mo->state == &states[S_PLAY_SUPER_PAIN])
- || (player->charability2 == CA2_SPINDASH && (player->pflags & (PF_SPINNING|PF_JUMPED)))
+ || (!(player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED))
+ || (player->pflags & PF_SPINNING)
|| player->powers[pw_tailsfly] || player->pflags & PF_GLIDING
|| (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
player->mo->height = P_GetPlayerSpinHeight(player);
@@ -7026,6 +7009,7 @@ static void P_MovePlayer(player_t *player)
msecnode_t *node; // only place it's being used in P_MovePlayer now
fixed_t oldx;
fixed_t oldy;
+ fixed_t floorz, ceilingz;
oldx = player->mo->x;
oldy = player->mo->y;
@@ -7035,7 +7019,7 @@ static void P_MovePlayer(player_t *player)
player->mo->y += player->mo->momy;
P_SetThingPosition(player->mo);
- for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
+ for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (!node->m_sector)
break;
@@ -7043,31 +7027,34 @@ static void P_MovePlayer(player_t *player)
if (node->m_sector->ffloors)
{
ffloor_t *rover;
+ fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
- if (!(rover->flags & FF_EXISTS)) continue;
+ if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
+ continue;
- if ((rover->flags & FF_BLOCKPLAYER))
+ topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+ bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+ if (topheight > player->mo->z && bottomheight < player->mo->z)
{
- if (*rover->topheight > player->mo->z && *rover->bottomheight < player->mo->z)
- {
- P_ResetPlayer(player);
- S_StartSound(player->mo, sfx_s3k4a);
- player->climbing = 5;
- player->mo->momx = player->mo->momy = player->mo->momz = 0;
- break;
- }
+ P_ResetPlayer(player);
+ S_StartSound(player->mo, sfx_s3k4a);
+ player->climbing = 5;
+ player->mo->momx = player->mo->momy = player->mo->momz = 0;
+ break;
}
}
}
- if (player->mo->z+player->mo->height > node->m_sector->ceilingheight
+ floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
+ ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
+
+ if (player->mo->z+player->mo->height > ceilingz
&& node->m_sector->ceilingpic == skyflatnum)
continue;
- if (node->m_sector->floorheight > player->mo->z
- || node->m_sector->ceilingheight < player->mo->z)
+ if (floorz > player->mo->z || ceilingz < player->mo->z)
{
P_ResetPlayer(player);
S_StartSound(player->mo, sfx_s3k4a);
@@ -7100,7 +7087,6 @@ static void P_DoZoomTube(player_t *player)
mobj_t *waypoint = NULL;
fixed_t dist;
boolean reverse;
- fixed_t speedx,speedy,speedz;
player->mo->height = P_GetPlayerSpinHeight(player);
@@ -7121,17 +7107,17 @@ static void P_DoZoomTube(player_t *player)
if (dist < 1)
dist = 1;
- speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
- speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
- speedz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed));
+ player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
+ player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
+ player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed));
// Calculate the distance between the player and the waypoint
// 'dist' already equals this.
- // Will the player be FURTHER away if the momx/momy/momz is added to
- // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors)
- if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - player->mo->z - speedz)>>FRACBITS)
+ // Will the player go past the waypoint?
+ if (speed > dist)
{
+ speed -= dist;
// If further away, set XYZ of player to waypoint location
P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x;
@@ -7171,6 +7157,8 @@ static void P_DoZoomTube(player_t *player)
{
CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
+ P_SetTarget(&player->mo->tracer, waypoint);
+
// calculate MOMX/MOMY/MOMZ for next waypoint
// change angle
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y);
@@ -7189,33 +7177,15 @@ static void P_DoZoomTube(player_t *player)
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed));
-
- P_SetTarget(&player->mo->tracer, waypoint);
}
else
{
- P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly.
+ P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly.
+ player->powers[pw_carry] = CR_NONE;
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n");
}
}
- else
- {
- player->mo->momx = speedx;
- player->mo->momy = speedy;
- player->mo->momz = speedz;
- }
-
- // change angle
- if (player->mo->tracer)
- {
- player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y);
-
- if (player == &players[consoleplayer])
- localangle = player->mo->angle;
- else if (player == &players[secondarydisplayplayer])
- localangle2 = player->mo->angle;
- }
}
//
@@ -7232,24 +7202,10 @@ static void P_DoRopeHang(player_t *player)
mobj_t *mo2;
mobj_t *waypoint = NULL;
fixed_t dist;
- fixed_t speedx,speedy,speedz;
fixed_t playerz;
player->mo->height = P_GetPlayerHeight(player);
- if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope
- {
- P_SetTarget(&player->mo->tracer, NULL);
-
- player->pflags |= PF_JUMPED;
- player->pflags &= ~PF_ROPEHANG;
-
- if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
- && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
- return;
- }
-
// Play the 'clink' sound only if the player is moving.
if (!(leveltime & 7) && player->speed)
S_StartSound(player->mo, sfx_s3k55);
@@ -7266,9 +7222,22 @@ static void P_DoRopeHang(player_t *player)
if (dist < 1)
dist = 1;
- speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
- speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
- speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
+ player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
+ player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
+ player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
+
+ if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope
+ {
+ P_SetTarget(&player->mo->tracer, NULL);
+
+ player->pflags |= PF_JUMPED;
+ player->powers[pw_carry] = CR_NONE;
+
+ if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
+ && !(player->panim == PA_JUMP))
+ P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
+ return;
+ }
// If not allowed to move, we're done here.
if (!speed)
@@ -7277,15 +7246,16 @@ static void P_DoRopeHang(player_t *player)
// Calculate the distance between the player and the waypoint
// 'dist' already equals this.
- // Will the player be FURTHER away if the momx/momy/momz is added to
- // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors)
- if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - playerz - speedz)>>FRACBITS)
+ // Will the player go past the waypoint?
+ if (speed > dist)
{
+ speed -= dist;
// If further away, set XYZ of player to waypoint location
P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x;
player->mo->y = player->mo->tracer->y;
player->mo->z = player->mo->tracer->z - player->mo->height;
+ playerz = player->mo->tracer->z;
P_SetThingPosition(player->mo);
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n");
@@ -7341,6 +7311,8 @@ static void P_DoRopeHang(player_t *player)
{
CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
+ P_SetTarget(&player->mo->tracer, waypoint);
+
// calculate MOMX/MOMY/MOMZ for next waypoint
// change slope
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz);
@@ -7351,32 +7323,24 @@ static void P_DoRopeHang(player_t *player)
player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed));
player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed));
player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed));
-
- P_SetTarget(&player->mo->tracer, waypoint);
}
else
{
if (player->mo->tracer->flags & MF_SLIDEME)
{
player->pflags |= PF_JUMPED;
- player->pflags &= ~PF_ROPEHANG;
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
- && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
+ && !(player->panim == PA_JUMP))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
P_SetTarget(&player->mo->tracer, NULL);
+ player->powers[pw_carry] = CR_NONE;
CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n");
}
}
- else
- {
- player->mo->momx = speedx;
- player->mo->momy = speedy;
- player->mo->momz = speedz;
- }
}
#if 0
@@ -7941,16 +7905,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
camspeed = cv_cam_speed.value;
camstill = cv_cam_still.value;
camrotate = cv_cam_rotate.value;
- camdist = FixedMul(cv_cam_dist.value, mo->scale);
- camheight = FixedMul(cv_cam_height.value, mo->scale);
+ camdist = FixedMul(cv_cam_dist.value, FixedMul(player->camerascale, mo->scale));
+ camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale, mo->scale));
}
else // Camera 2
{
camspeed = cv_cam2_speed.value;
camstill = cv_cam2_still.value;
camrotate = cv_cam2_rotate.value;
- camdist = FixedMul(cv_cam2_dist.value, mo->scale);
- camheight = FixedMul(cv_cam2_height.value, mo->scale);
+ camdist = FixedMul(cv_cam2_dist.value, FixedMul(player->camerascale, mo->scale));
+ camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale, mo->scale));
}
#ifdef REDSANALOG
@@ -8060,7 +8024,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{
dist = camdist;
- if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG)))
+ if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] && player->powers[pw_carry] != CR_PLAYER))
dist <<= 1;
}
@@ -8370,7 +8334,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player));
else
angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player));
- if (player->playerstate != PST_DEAD && !(player->pflags & PF_NIGHTSMODE && player->exiting))
+ if (player->playerstate != PST_DEAD)
angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;'
if (twodlevel || (mo->flags2 & MF2_TWOD) || !camstill) // Keep the view still...
@@ -8634,7 +8598,7 @@ void P_DoPityCheck(player_t *player)
if ((player->pity >= 3 || player->pity < 0) && player->powers[pw_shield] == SH_NONE)
{
if (player->pity > 0)
- S_StartSound(player->mo, mobjinfo[MT_PITYSHIELDICO].seesound);
+ S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound);
player->pity = 0;
player->powers[pw_shield] = SH_PITY;
@@ -8704,7 +8668,7 @@ void P_PlayerThink(player_t *player)
if (player->panim != PA_ABILITY)
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
}
- else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH)
+ else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_JUMP && !(player->charflags & SF_NOJUMPSPIN))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
if (player->flashcount)
@@ -8930,9 +8894,9 @@ void P_PlayerThink(player_t *player)
// for a bit after a teleport.
if (player->mo->reactiontime)
player->mo->reactiontime--;
- else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
+ else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE))
{
- if (player->pflags & PF_ROPEHANG)
+ if (player->powers[pw_carry] == CR_ROPEHANG)
{
if (!P_AnalogMove(player))
player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */);
@@ -8945,10 +8909,10 @@ void P_PlayerThink(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
P_DoJumpStuff(player, &player->cmd);
}
- else
+ else //if (player->powers[pw_carry] == CR_ZOOMTUBE)
{
P_DoZoomTube(player);
- if (!(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
+ if (!(player->panim == PA_ROLL))
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
player->rmomx = player->rmomy = 0; // no actual momentum from your controls
@@ -9007,19 +8971,6 @@ void P_PlayerThink(player_t *player)
else
player->pflags &= ~PF_USEDOWN;
}
- else if (player->mo->tracer) // match tracer's position with yours when NiGHTS
- {
- P_UnsetThingPosition(player->mo->tracer);
- player->mo->tracer->x = player->mo->x;
- player->mo->tracer->y = player->mo->y;
- if (player->mo->eflags & MFE_VERTICALFLIP)
- player->mo->tracer->z = player->mo->z + player->mo->height - player->mo->tracer->height;
- else
- player->mo->tracer->z = player->mo->z;
- player->mo->tracer->floorz = player->mo->floorz;
- player->mo->tracer->ceilingz = player->mo->ceilingz;
- P_SetThingPosition(player->mo->tracer);
- }
// Counters, time dependent power ups.
// Time Bonus & Ring Bonus count settings
@@ -9116,23 +9067,56 @@ void P_PlayerThink(player_t *player)
player->losstime--;
// Flash player after being hit.
- if (!(player->pflags & PF_NIGHTSMODE))
- {
- if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1))
- player->mo->flags2 |= MF2_DONTDRAW;
- else
- player->mo->flags2 &= ~MF2_DONTDRAW;
- }
- else if (player->mo->tracer)
- {
- if (player->powers[pw_flashing] & 1)
- player->mo->tracer->flags2 |= MF2_DONTDRAW;
- else
- player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
- }
+ if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1))
+ player->mo->flags2 |= MF2_DONTDRAW;
+ else
+ player->mo->flags2 &= ~MF2_DONTDRAW;
player->pflags &= ~PF_SLIDING;
+#define dashmode player->dashmode
+ // Dash mode ability for Metal Sonic
+ if ((player->charability == CA_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho.
+ {
+ if (player->speed >= FixedMul(player->runspeed, player->mo->scale) || (player->pflags & PF_STARTDASH))
+ {
+ dashmode++; // Counter. Adds 1 to dash mode per tic in top speed.
+ if (dashmode == 3*TICRATE) // This isn't in the ">=" equation because it'd cause the sound to play infinitely.
+ S_StartSound(player->mo, sfx_s3ka2); // If the player enters dashmode, play this sound on the the tic it starts.
+ }
+ else if (!(player->pflags & PF_SPINNING))
+ {
+ if (dashmode > 3)
+ dashmode -= 3; // Rather than lose it all, it gently counts back down!
+ else
+ dashmode = 0;
+ }
+
+ if (dashmode < 3*TICRATE) // Exits Dash Mode if you drop below speed/dash counter tics. Not in the above block so it doesn't keep disabling in midair.
+ {
+ player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode.
+ player->jumpfactor = skins[player->skin].jumpfactor;
+ }
+ else if (P_IsObjectOnGround(player->mo)) // Activate dash mode if we're on the ground.
+ {
+ if (player->normalspeed < skins[player->skin].actionspd) // If the player normalspeed is not currently at actionspd in dash mode, add speed each tic
+ player->normalspeed = player->normalspeed + 1*FRACUNIT/5; // Enter Dash Mode smoothly.
+
+ if (player->jumpfactor < FixedMul(skins[player->skin].jumpfactor, 5*FRACUNIT/4)) // Boost jump height.
+ player->jumpfactor = player->jumpfactor + 1*FRACUNIT/300;
+ }
+
+ dashmode = min(dashmode, 3*TICRATE + 3);
+
+ if (player->normalspeed >= skins[player->skin].actionspd)
+ {
+ mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages
+ ghost->fuse = 2; // Makes the images fade quickly
+ }
+ }
+ else
+ dashmode = 0;
+#undef dashmode
/*
// Colormap verification
{
@@ -9328,19 +9312,17 @@ void P_PlayerAfterThink(player_t *player)
else if (player->pflags & PF_SLIDING)
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
else if (player->pflags & PF_JUMPED
- && ((!player->powers[pw_super] && player->panim != PA_ROLL)
+ && ((!player->powers[pw_super] && player->panim != PA_JUMP)
|| player->mo->state == &states[player->mo->info->painstate])
- && player->charability2 == CA2_SPINDASH)
+ && !(player->charflags & SF_NOJUMPSPIN))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
- if (player->pflags & PF_CARRIED && player->mo->tracer)
+ if (player->powers[pw_carry] == CR_PLAYER && player->mo->tracer)
{
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
- if (player->mo->tracer->player
- && player->mo->tracer->state-states != S_PLAY_FLY
- && player->mo->tracer->state-states != S_PLAY_FLY_TIRED)
- player->pflags &= ~PF_CARRIED;
+ if (player->mo->tracer->player && !(player->mo->tracer->player->pflags & PF_CANCARRY))
+ player->powers[pw_carry] = CR_NONE;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
@@ -9348,7 +9330,7 @@ void P_PlayerAfterThink(player_t *player)
&& (player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame
player->mo->z = player->mo->tracer->z + player->mo->tracer->height + FixedMul(FRACUNIT, player->mo->scale);
else
- player->pflags &= ~PF_CARRIED;
+ player->powers[pw_carry] = CR_NONE;
}
else
{
@@ -9356,11 +9338,11 @@ void P_PlayerAfterThink(player_t *player)
&& !(player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame
player->mo->z = player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
else
- player->pflags &= ~PF_CARRIED;
+ player->powers[pw_carry] = CR_NONE;
}
if (player->mo->tracer->health <= 0)
- player->pflags &= ~PF_CARRIED;
+ player->powers[pw_carry] = CR_NONE;
else
{
P_TryMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, true);
@@ -9383,14 +9365,14 @@ void P_PlayerAfterThink(player_t *player)
}
if (P_AproxDistance(player->mo->x - player->mo->tracer->x, player->mo->y - player->mo->tracer->y) > player->mo->radius)
- player->pflags &= ~PF_CARRIED;
+ player->powers[pw_carry] = CR_NONE;
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if (player-players == consoleplayer && botingame)
- CV_SetValue(&cv_analog2, !(player->pflags & PF_CARRIED));
+ CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER));
}
- else if (player->pflags & PF_ITEMHANG && player->mo->tracer)
+ else if (player->powers[pw_carry] == CR_GENERIC && player->mo->tracer)
{
// tracer is what you're hanging onto
P_UnsetThingPosition(player->mo);
@@ -9418,12 +9400,12 @@ void P_PlayerAfterThink(player_t *player)
if (player->mo->z <= player->mo->floorz
|| player->mo->tracer->health <= 0)
{
- player->pflags &= ~PF_ITEMHANG;
+ player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
}
}
- else if (player->pflags & PF_MACESPIN && player->mo->tracer && player->mo->tracer->target)
+ else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->target)
{
player->mo->height = P_GetPlayerSpinHeight(player);
// tracer is what you're hanging onto....
diff --git a/src/r_data.h b/src/r_data.h
index 4a37f82c3..69a2882af 100644
--- a/src/r_data.h
+++ b/src/r_data.h
@@ -30,7 +30,7 @@ typedef struct
{
// Block origin (always UL), which has already accounted for the internal origin of the patch.
INT16 originx, originy;
- INT16 wad, lump;
+ UINT16 wad, lump;
} texpatch_t;
// A maptexturedef_t describes a rectangular texture,
diff --git a/src/r_defs.h b/src/r_defs.h
index 848708164..9109ac7c3 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -500,10 +500,10 @@ typedef struct subsector_s
// Sector list node showing all sectors an object appears in.
//
// There are two threads that flow through these nodes. The first thread
-// starts at touching_thinglist in a sector_t and flows through the m_snext
+// starts at touching_thinglist in a sector_t and flows through the m_thinglist_next
// links to find all mobjs that are entirely or partially in the sector.
// The second thread starts at touching_sectorlist in an mobj_t and flows
-// through the m_tnext links to find all sectors a thing touches. This is
+// through the m_sectorlist_next links to find all sectors a thing touches. This is
// useful when applying friction or push effects to sectors. These effects
// can be done as thinkers that act upon all objects touching their sectors.
// As an mobj moves through the world, these nodes are created and
@@ -515,10 +515,10 @@ typedef struct msecnode_s
{
sector_t *m_sector; // a sector containing this object
struct mobj_s *m_thing; // this object
- struct msecnode_s *m_tprev; // prev msecnode_t for this thing
- struct msecnode_s *m_tnext; // next msecnode_t for this thing
- struct msecnode_s *m_sprev; // prev msecnode_t for this sector
- struct msecnode_s *m_snext; // next msecnode_t for this sector
+ struct msecnode_s *m_sectorlist_prev; // prev msecnode_t for this thing
+ struct msecnode_s *m_sectorlist_next; // next msecnode_t for this thing
+ struct msecnode_s *m_thinglist_prev; // prev msecnode_t for this sector
+ struct msecnode_s *m_thinglist_next; // next msecnode_t for this sector
boolean visited; // used in search algorithms
} msecnode_t;
@@ -526,10 +526,10 @@ typedef struct mprecipsecnode_s
{
sector_t *m_sector; // a sector containing this object
struct precipmobj_s *m_thing; // this object
- struct mprecipsecnode_s *m_tprev; // prev msecnode_t for this thing
- struct mprecipsecnode_s *m_tnext; // next msecnode_t for this thing
- struct mprecipsecnode_s *m_sprev; // prev msecnode_t for this sector
- struct mprecipsecnode_s *m_snext; // next msecnode_t for this sector
+ struct mprecipsecnode_s *m_sectorlist_prev; // prev msecnode_t for this thing
+ struct mprecipsecnode_s *m_sectorlist_next; // next msecnode_t for this thing
+ struct mprecipsecnode_s *m_thinglist_prev; // prev msecnode_t for this sector
+ struct mprecipsecnode_s *m_thinglist_next; // next msecnode_t for this sector
boolean visited; // used in search algorithms
} mprecipsecnode_t;
@@ -729,23 +729,36 @@ typedef struct
#pragma pack()
#endif
+typedef enum
+{
+ SRF_SINGLE = 0, // 0-angle for all rotations
+ SRF_3D = 1, // Angles 1-8
+ SRF_LEFT = 2, // Left side uses single patch
+ SRF_RIGHT = 4, // Right side uses single patch
+ SRF_2D = SRF_LEFT|SRF_RIGHT, // 6
+ SRF_NONE = 0xff // Initial value
+} spriterotateflags_t; // SRF's up!
+
//
// Sprites are patches with a special naming convention so they can be
// recognized by R_InitSprites.
// The base name is NNNNFx or NNNNFxFx, with x indicating the rotation,
-// x = 0, 1-7.
+// x = 0, 1-8, L/R
// The sprite and frame specified by a thing_t is range checked at run time.
// A sprite is a patch_t that is assumed to represent a three dimensional
// object and may have multiple rotations predrawn.
// Horizontal flipping is used to save space, thus NNNNF2F5 defines a mirrored patch.
// Some sprites will only have one picture used for all views: NNNNF0
+// Some sprites will take the entirety of the left side: NNNNFL
+// Or the right side: NNNNFR
+// Or both, mirrored: NNNNFLFR
//
typedef struct
{
// If false use 0 for any position.
// Note: as eight entries are available, we might as well insert the same
// name eight times.
- UINT8 rotate;
+ UINT8 rotate; // see spriterotateflags_t above
// Lump to use for view angles 0-7.
lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump
diff --git a/src/r_draw.c b/src/r_draw.c
index d6a1ee7ae..2c1f18826 100644
--- a/src/r_draw.c
+++ b/src/r_draw.c
@@ -135,7 +135,7 @@ static UINT8** translationtablecache[MAXSKINS + 4] = {NULL};
// See also the enum skincolors_t
// TODO Callum: Can this be translated?
-const char *Color_Names[MAXSKINCOLORS] =
+const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] =
{
"None", // SKINCOLOR_NONE
"White", // SKINCOLOR_WHITE
@@ -166,9 +166,23 @@ const char *Color_Names[MAXSKINCOLORS] =
"Lavender", // SKINCOLOR_LAVENDER
"Magenta", // SKINCOLOR_MAGENTA
"Pink", // SKINCOLOR_PINK
- "Rosy" // SKINCOLOR_ROSY
+ "Rosy", // SKINCOLOR_ROSY
+ // Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName.
+ "Silver", // SKINCOLOR_SUPERSILVER1
+ "Red", // SKINCOLOR_SUPERRED1
+ "Orange", // SKINCOLOR_SUPERORANGE1
+ "Gold", // SKINCOLOR_SUPERGOLD1
+ "Peridot", // SKINCOLOR_SUPERPERIDOT1
+ "Cyan", // SKINCOLOR_SUPERCYAN1
+ "Purple", // SKINCOLOR_SUPERPURPLE1
+ "Rust", // SKINCOLOR_SUPERRUST1
+ "Tan" // SKINCOLOR_SUPERTAN1
};
+/*
+A word of warning: If the following array is non-symmetrical,
+A_SignPlayer's prefoppositecolor behaviour will break.
+*/
const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
{
SKINCOLOR_NONE,8, // SKINCOLOR_NONE
@@ -183,7 +197,7 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto
SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE
SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto
- SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto
+ SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto
SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto
SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto
SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS
@@ -196,11 +210,11 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE
SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto
SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto
- SKINCOLOR_PERIDOT,8, // SKINCOLOR_PURPLE - ditto
+ SKINCOLOR_PERIDOT,10, // SKINCOLOR_PURPLE - ditto
SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto
SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto
SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto
- SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto
+ SKINCOLOR_AQUA,14 // SKINCOLOR_ROSY - ditto
};
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
@@ -569,49 +583,186 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
break;
// Super colors, from lightest to darkest!
- case SKINCOLOR_SUPER1:
- // Super White
+
+ // Super silvers.
+ case SKINCOLOR_SUPERSILVER1:
+ for (i = 0; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)1;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(i-12);
+ break;
+
+ case SKINCOLOR_SUPERSILVER2:
+ for (i = 0; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(i);
+ dest_colormap[starttranscolor + (i++)] = (UINT8)2;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)3;
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)4;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(i-9);
+ break;
+
+ case SKINCOLOR_SUPERSILVER3:
+ dest_colormap[starttranscolor] = (UINT8)1;
+ for (i = 1; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)2;
+ for (; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)3;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)4;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-12)*2));
+ break;
+
+ case SKINCOLOR_SUPERSILVER4:
+ dest_colormap[starttranscolor] = (UINT8)2;
+ for (i = 1; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)3;
+ for (; i < 9; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)4;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-9)*2));
+ break;
+
+ case SKINCOLOR_SUPERSILVER5:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)3;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)4;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-8)*2));
+ break;
+
+ // Super reds.
+ case SKINCOLOR_SUPERRED1:
+ for (i = 0; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-10) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERRED2:
+ for (i = 0; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-3) / 3));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-12) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERRED3:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-2) >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-8) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERRED4:
+ dest_colormap[starttranscolor] = (UINT8)0;
+ for (i = 1; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(208 + (i >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-6) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERRED5:
+ dest_colormap[starttranscolor] = (UINT8)208;
+ for (i = 1; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(209 + (i >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-4) >> 1));
+ break;
+
+ // Super oranges.
+ case SKINCOLOR_SUPERORANGE1:
+ for (i = 0; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ dest_colormap[starttranscolor + (i++)] = (UINT8)208;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-11));
+ break;
+
+ case SKINCOLOR_SUPERORANGE2:
+ for (i = 0; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)208;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-6) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERORANGE3:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)208;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-4) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERORANGE4:
+ dest_colormap[starttranscolor] = (UINT8)0;
+ dest_colormap[starttranscolor + 1] = (UINT8)208;
+ for (i = 2; i < 13; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-2));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-13));
+ break;
+
+ case SKINCOLOR_SUPERORANGE5:
+ dest_colormap[starttranscolor] = (UINT8)208;
+ for (i = 1; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-12));
+ break;
+
+ // Super golds.
+ case SKINCOLOR_SUPERGOLD1:
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0; // True white
for (; i < 12; i++) // White-yellow fade
- dest_colormap[starttranscolor + i] = (UINT8)(80);
+ dest_colormap[starttranscolor + i] = (UINT8)80;
for (; i < 15; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12));
- dest_colormap[starttranscolor + 15] = (UINT8)(72);
+ dest_colormap[starttranscolor + 15] = (UINT8)72;
break;
- case SKINCOLOR_SUPER2:
- // Super Bright
+ case SKINCOLOR_SUPERGOLD2:
dest_colormap[starttranscolor] = (UINT8)(0);
for (i = 1; i < 4; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1));
for (; i < 6; i++) // Yellow
- dest_colormap[starttranscolor + i] = (UINT8)(83);
+ dest_colormap[starttranscolor + i] = (UINT8)83;
for (; i < 8; i++) // Yellow
- dest_colormap[starttranscolor + i] = (UINT8)(72);
+ dest_colormap[starttranscolor + i] = (UINT8)72;
for (; i < 14; i++) // Yellow
- dest_colormap[starttranscolor + i] = (UINT8)(73);
+ dest_colormap[starttranscolor + i] = (UINT8)73;
for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14));
break;
- case SKINCOLOR_SUPER3:
- // Super Yellow
+ case SKINCOLOR_SUPERGOLD3:
for (i = 0; i < 2; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(81 + i);
for (; i < 4; i++)
- dest_colormap[starttranscolor + i] = (UINT8)(83);
+ dest_colormap[starttranscolor + i] = (UINT8)83;
for (; i < 6; i++) // Yellow
- dest_colormap[starttranscolor + i] = (UINT8)(72);
+ dest_colormap[starttranscolor + i] = (UINT8)72;
for (; i < 12; i++) // Yellow
- dest_colormap[starttranscolor + i] = (UINT8)(73);
+ dest_colormap[starttranscolor + i] = (UINT8)73;
for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12));
break;
- case SKINCOLOR_SUPER4:
- // "The SSNTails"
- dest_colormap[starttranscolor] = 83; // Golden shine
+ case SKINCOLOR_SUPERGOLD4: // "The SSNTails"
+ dest_colormap[starttranscolor] = (UINT8)83; // Golden shine
for (i = 1; i < 3; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 9; i++) // Yellow
@@ -620,30 +771,310 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9));
break;
- case SKINCOLOR_SUPER5:
- // Golden Delicious
+ case SKINCOLOR_SUPERGOLD5: // Golden Delicious
for (i = 0; i < 2; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73);
- for (; i < 15; i++) // With a fine golden finish! :3
+ for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8));
- dest_colormap[starttranscolor + 15] = (UINT8)63;
break;
- // Super Tails and Knuckles, who really should be dummied out by now
- case SKINCOLOR_TSUPER1:
- case SKINCOLOR_TSUPER2:
- case SKINCOLOR_TSUPER3:
- case SKINCOLOR_TSUPER4:
- case SKINCOLOR_TSUPER5:
- case SKINCOLOR_KSUPER1:
- case SKINCOLOR_KSUPER2:
- case SKINCOLOR_KSUPER3:
- case SKINCOLOR_KSUPER4:
- case SKINCOLOR_KSUPER5:
- for (i = 0; i < SKIN_RAMP_LENGTH; i++)
- dest_colormap[starttranscolor + i] = 0xFF;
+ // Super peridots. (nyeheheheh)
+ case SKINCOLOR_SUPERPERIDOT1:
+ for (i = 0; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 13; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)88;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)188;
+ break;
+
+ case SKINCOLOR_SUPERPERIDOT2:
+ dest_colormap[starttranscolor] = (UINT8)(0);
+ for (i = 1; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)88;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)188;
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)189;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)190;
+ break;
+
+ case SKINCOLOR_SUPERPERIDOT3:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)88;
+ for (; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)188;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)189;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-12) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERPERIDOT4:
+ dest_colormap[starttranscolor] = (UINT8)88;
+ for (i = 1; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)188;
+ for (; i < 9; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)189;
+ for (; i < 13; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-9) >> 1));
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)94;
+ dest_colormap[starttranscolor + i] = (UINT8)95;
+ break;
+
+ case SKINCOLOR_SUPERPERIDOT5:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)188;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)189;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-8) >> 1));
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)94;
+ dest_colormap[starttranscolor + (i++)] = (UINT8)95;
+ dest_colormap[starttranscolor + i] = (UINT8)119;
+ break;
+
+ // Super cyans.
+ case SKINCOLOR_SUPERCYAN1:
+ for (i = 0; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)128;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(129 + (i-12));
+ break;
+
+ case SKINCOLOR_SUPERCYAN2:
+ dest_colormap[starttranscolor] = (UINT8)0;
+ for (i = 1; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(128 + (i-1));
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-4) >> 1));
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)133;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)134;
+ break;
+
+ case SKINCOLOR_SUPERCYAN3:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(129 + i);
+ for (; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-2) >> 1));
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)133;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-12) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERCYAN4:
+ dest_colormap[starttranscolor] = (UINT8)131;
+ for (i = 1; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)132;
+ for (; i < 9; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)133;
+ for (; i < 13; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-9) >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-13));
+ break;
+
+ case SKINCOLOR_SUPERCYAN5:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)132;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)133;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-8) >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-12));
+ break;
+
+ // Super purples.
+ case SKINCOLOR_SUPERPURPLE1:
+ for (i = 0; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)144;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-12));
+ break;
+
+ case SKINCOLOR_SUPERPURPLE2:
+ dest_colormap[starttranscolor] = (UINT8)0;
+ dest_colormap[starttranscolor + 1] = (UINT8)144;
+ for (i = 2; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-2));
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-4) >> 1));
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)164;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)165;
+ break;
+
+ case SKINCOLOR_SUPERPURPLE3:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(160 + i);
+ for (; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-2) >> 1));
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)164;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-12) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERPURPLE4:
+ dest_colormap[starttranscolor] = (UINT8)162;
+ for (i = 1; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)163;
+ for (; i < 9; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)164;
+ for (; i < 13; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-9) >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-13));
+ break;
+
+ case SKINCOLOR_SUPERPURPLE5:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)163;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)164;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-8) >> 1));
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-12));
+ dest_colormap[starttranscolor + i] = (UINT8)253;
+ break;
+
+ // Super rusts.
+ case SKINCOLOR_SUPERRUST1:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 5; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)208;
+ for (; i < 7; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)48;
+ for (; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-7));
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(55 + ((i-10)*3));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11));
+ break;
+
+ case SKINCOLOR_SUPERRUST2:
+ for (i = 0; i < 4; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)48;
+ for (; i < 9; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-4));
+ for (; i < 11; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(56 + ((i-9)*2));
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11));
+ dest_colormap[starttranscolor + i] = (UINT8)71;
+ break;
+
+ case SKINCOLOR_SUPERRUST3:
+ dest_colormap[starttranscolor] = (UINT8)49;
+ for (i = 1; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)50;
+ for (; i < 5; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(51 + (i-3));
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(54 + (i-5));
+ dest_colormap[starttranscolor + (i++)] = (UINT8)58;
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-7) >> 1));
+ dest_colormap[starttranscolor + i] = (UINT8)46;
+ break;
+
+ case SKINCOLOR_SUPERRUST4:
+ dest_colormap[starttranscolor] = (UINT8)83;
+ dest_colormap[starttranscolor + 1] = (UINT8)72;
+ for (i = 2; i < 6; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-2));
+ for (; i < 14; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-6) >> 1));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)46;
+ break;
+
+ case SKINCOLOR_SUPERRUST5:
+ for (i = 0; i < 3; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(64 + i);
+ for (; i < 7; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(67 + ((i-3) >> 1));
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(233 + (i-7));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(238 + ((i-12) >> 1));
+ break;
+
+ // Super tans.
+ case SKINCOLOR_SUPERTAN1:
+ for (i = 0; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)0;
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-10) >> 1));
+ break;
+
+ case SKINCOLOR_SUPERTAN2:
+ dest_colormap[starttranscolor] = (UINT8)0;
+ for (i = 1; i < 7; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-1) >> 1));
+ dest_colormap[starttranscolor + (i++)] = (UINT8)82;
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)84;
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-12));
+ dest_colormap[starttranscolor + i] = (UINT8)245;
+ break;
+
+ case SKINCOLOR_SUPERTAN3:
+ dest_colormap[starttranscolor] = (UINT8)80;
+ for (i = 1; i < 5; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(81 + ((i-1) >> 1));
+ dest_colormap[starttranscolor + (i++)] = (UINT8)82;
+ for (; i < 10; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)84;
+ for (; i < 13; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-10));
+ for (; i < 16; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-13)*2));
+ break;
+
+ case SKINCOLOR_SUPERTAN4:
+ dest_colormap[starttranscolor] = (UINT8)81;
+ for (i = 1; i < 5; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)82;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)84;
+ for (; i < 11; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-8));
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-11)*2));
+ dest_colormap[starttranscolor + i] = (UINT8)237;
+ break;
+
+ case SKINCOLOR_SUPERTAN5:
+ for (i = 0; i < 2; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)82;
+ for (; i < 5; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)84;
+ for (; i < 8; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-5));
+ for (; i < 12; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(245 + (i-8));
+ for (; i < 15; i++)
+ dest_colormap[starttranscolor + i] = (UINT8)(237 + (i-12));
+ dest_colormap[starttranscolor + i] = (UINT8)239;
break;
default:
@@ -727,6 +1158,17 @@ UINT8 R_GetColorByName(const char *name)
return 0;
}
+UINT8 R_GetSuperColorByName(const char *name)
+{
+ UINT8 color; /* = (UINT8)atoi(name); -- This isn't relevant to S_SKIN, which is the only way it's accessible right now. Let's simplify things.
+ if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5))
+ return color;*/
+ for (color = 0; color < NUMSUPERCOLORS; color++)
+ if (!stricmp(Color_Names[color + MAXSKINCOLORS], name))
+ return ((color*5) + MAXSKINCOLORS);
+ return 0;
+}
+
// ==========================================================================
// COMMON DRAWER FOR 8 AND 16 BIT COLOR MODES
// ==========================================================================
diff --git a/src/r_draw.h b/src/r_draw.h
index 6d85bd6a5..60c3c9db6 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -111,6 +111,7 @@ void R_InitTranslationTables(void);
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags);
void R_FlushTranslationColormapCache(void);
UINT8 R_GetColorByName(const char *name);
+UINT8 R_GetSuperColorByName(const char *name);
// Custom player skin translation
void R_InitViewBuffer(INT32 width, INT32 height);
diff --git a/src/r_draw8.c b/src/r_draw8.c
index 7bfe5c79b..c1b7da11b 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -874,9 +874,9 @@ void R_DrawTiltedSplat_8(void)
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
- val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- *dest = val;
+ *dest = colormap[val];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
@@ -913,9 +913,9 @@ void R_DrawTiltedSplat_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
- val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- *dest = val;
+ *dest = colormap[val];
dest++;
u += stepu;
v += stepv;
@@ -931,9 +931,9 @@ void R_DrawTiltedSplat_8(void)
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
- val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- *dest = val;
+ *dest = colormap[val];
}
else
{
@@ -954,9 +954,9 @@ void R_DrawTiltedSplat_8(void)
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
- val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- *dest = val;
+ *dest = colormap[val];
dest++;
u += stepu;
v += stepv;
@@ -1124,49 +1124,49 @@ void R_DrawTranslucentSplat_8 (void)
// need!
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[0])];
+ dest[0] = colormap[*(ds_transmap + (val << 8) + dest[0])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[1])];
+ dest[1] = colormap[*(ds_transmap + (val << 8) + dest[1])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[2])];
+ dest[2] = colormap[*(ds_transmap + (val << 8) + dest[2])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[3])];
+ dest[3] = colormap[*(ds_transmap + (val << 8) + dest[3])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[4])];
+ dest[4] = colormap[*(ds_transmap + (val << 8) + dest[4])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[5])];
+ dest[5] = colormap[*(ds_transmap + (val << 8) + dest[5])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[6])];
+ dest[6] = colormap[*(ds_transmap + (val << 8) + dest[6])];
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[7])];
+ dest[7] = colormap[*(ds_transmap + (val << 8) + dest[7])];
xposition += xstep;
yposition += ystep;
@@ -1175,9 +1175,9 @@ void R_DrawTranslucentSplat_8 (void)
}
while (count--)
{
- val =colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
+ val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
- *dest = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dest)];
+ *dest = colormap[*(ds_transmap + (val << 8) + *dest)];
dest++;
xposition += xstep;
@@ -1363,7 +1363,19 @@ void R_DrawColumnShadowed_8(void)
height = dc_lightlist[i].height >> LIGHTSCALESHIFT;
if (solid)
+ {
bheight = dc_lightlist[i].botheight >> LIGHTSCALESHIFT;
+ if (bheight < height)
+ {
+ // confounded slopes sometimes allow partial invertedness,
+ // even including cases where the top and bottom heights
+ // should actually be the same!
+ // swap the height values as a workaround for this quirk
+ INT32 temp = height;
+ height = bheight;
+ bheight = temp;
+ }
+ }
if (height <= dc_yl)
{
dc_colormap = dc_lightlist[i].rcolormap;
diff --git a/src/r_main.c b/src/r_main.c
index f625b29b6..79ee803e1 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -771,7 +771,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y)
}
//
-// R_IsPointInSubsector, same as above but returns 0 if not in subsector
+// R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t
//
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
{
@@ -919,9 +919,9 @@ void R_SkyboxFrame(player_t *player)
}
}
if (mh->skybox_scalez > 0)
- viewz += player->awayviewmobj->z / mh->skybox_scalez;
+ viewz += (player->awayviewmobj->z + 20*FRACUNIT) / mh->skybox_scalez;
else if (mh->skybox_scalez < 0)
- viewz += player->awayviewmobj->z * -mh->skybox_scalez;
+ viewz += (player->awayviewmobj->z + 20*FRACUNIT) * -mh->skybox_scalez;
}
else if (thiscam->chase)
{
@@ -966,9 +966,9 @@ void R_SkyboxFrame(player_t *player)
}
}
if (mh->skybox_scalez > 0)
- viewz += thiscam->z / mh->skybox_scalez;
+ viewz += (thiscam->z + (thiscam->height>>1)) / mh->skybox_scalez;
else if (mh->skybox_scalez < 0)
- viewz += thiscam->z * -mh->skybox_scalez;
+ viewz += (thiscam->z + (thiscam->height>>1)) * -mh->skybox_scalez;
}
else
{
@@ -1324,6 +1324,7 @@ void R_RenderPlayerView(player_t *player)
#endif
R_RenderBSPNode((INT32)numnodes - 1);
+ R_ClipSprites();
R_DrawPlanes();
#ifdef FLOORSPLATS
R_DrawVisibleFloorSplats();
diff --git a/src/r_plane.c b/src/r_plane.c
index 19007d88f..ad30f4247 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -711,7 +711,7 @@ void R_DrawPlanes(void)
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
dc_x = x;
dc_source =
- R_GetColumn(skytexture,
+ R_GetColumn(texturetranslation[skytexture],
angle);
wallcolfunc();
}
diff --git a/src/r_plane.h b/src/r_plane.h
index 8730bcefd..ec1940716 100644
--- a/src/r_plane.h
+++ b/src/r_plane.h
@@ -87,7 +87,7 @@ extern lighttable_t **planezlight;
extern fixed_t *yslope;
extern fixed_t distscale[MAXVIDWIDTH];
-void R_InitPlanes(void);
+FUNCMATH void R_InitPlanes(void);
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
void R_ClearPlanes(void);
diff --git a/src/r_segs.c b/src/r_segs.c
index 11b4c8aef..cb78743b6 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -1453,34 +1453,45 @@ static void R_RenderSegLoop (void)
frontscale[rw_x] = rw_scale;
// draw the wall tiers
- if (midtexture && yl <= yh && yh < vid.height && yh > 0)
+ if (midtexture)
{
// single sided line
- dc_yl = yl;
- dc_yh = yh;
- dc_texturemid = rw_midtexturemid;
- dc_source = R_GetColumn(midtexture,texturecolumn);
- dc_texheight = textureheight[midtexture]>>FRACBITS;
+ if (yl <= yh && yh >= 0 && yl < viewheight)
+ {
+ dc_yl = yl;
+ dc_yh = yh;
+ dc_texturemid = rw_midtexturemid;
+ dc_source = R_GetColumn(midtexture,texturecolumn);
+ dc_texheight = textureheight[midtexture]>>FRACBITS;
- //profile stuff ---------------------------------------------------------
+ //profile stuff ---------------------------------------------------------
#ifdef TIMING
- ProfZeroTimer();
+ ProfZeroTimer();
#endif
- colfunc();
+ colfunc();
#ifdef TIMING
- RDMSR(0x10,&mycount);
- mytotal += mycount; //64bit add
+ RDMSR(0x10,&mycount);
+ mytotal += mycount; //64bit add
- if (nombre--==0)
- I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
- (INT32)mytotal);
+ if (nombre--==0)
+ I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
+ (INT32)mytotal);
#endif
- //profile stuff ---------------------------------------------------------
+ //profile stuff ---------------------------------------------------------
- // dont draw anything more for this column, since
- // a midtexture blocks the view
- ceilingclip[rw_x] = (INT16)viewheight;
- floorclip[rw_x] = -1;
+ // dont draw anything more for this column, since
+ // a midtexture blocks the view
+ ceilingclip[rw_x] = (INT16)viewheight;
+ floorclip[rw_x] = -1;
+ }
+ else
+ {
+ // note: don't use min/max macros, since casting from INT32 to INT16 is involved here
+ if (markceiling)
+ ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
+ if (markfloor)
+ floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
+ }
}
else
{
@@ -1494,21 +1505,28 @@ static void R_RenderSegLoop (void)
if (mid >= floorclip[rw_x])
mid = floorclip[rw_x]-1;
- if (mid >= yl && yh < vid.height && yh > 0)
+ if (mid >= yl) // back ceiling lower than front ceiling ?
{
- dc_yl = yl;
- dc_yh = mid;
- dc_texturemid = rw_toptexturemid;
- dc_source = R_GetColumn(toptexture,texturecolumn);
- dc_texheight = textureheight[toptexture]>>FRACBITS;
- colfunc();
- ceilingclip[rw_x] = (INT16)mid;
+ if (yl >= viewheight) // entirely off bottom of screen
+ ceilingclip[rw_x] = (INT16)viewheight;
+ else if (mid >= 0) // safe to draw top texture
+ {
+ dc_yl = yl;
+ dc_yh = mid;
+ dc_texturemid = rw_toptexturemid;
+ dc_source = R_GetColumn(toptexture,texturecolumn);
+ dc_texheight = textureheight[toptexture]>>FRACBITS;
+ colfunc();
+ ceilingclip[rw_x] = (INT16)mid;
+ }
+ else // entirely off top of screen
+ ceilingclip[rw_x] = -1;
}
else
- ceilingclip[rw_x] = (INT16)((INT16)yl - 1);
+ ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
}
else if (markceiling) // no top wall
- ceilingclip[rw_x] = (INT16)((INT16)yl - 1);
+ ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
if (bottomtexture)
{
@@ -1520,22 +1538,29 @@ static void R_RenderSegLoop (void)
if (mid <= ceilingclip[rw_x])
mid = ceilingclip[rw_x]+1;
- if (mid <= yh && yh < vid.height && yh > 0)
+ if (mid <= yh) // back floor higher than front floor ?
{
- dc_yl = mid;
- dc_yh = yh;
- dc_texturemid = rw_bottomtexturemid;
- dc_source = R_GetColumn(bottomtexture,
- texturecolumn);
- dc_texheight = textureheight[bottomtexture]>>FRACBITS;
- colfunc();
- floorclip[rw_x] = (INT16)mid;
+ if (yh < 0) // entirely off top of screen
+ floorclip[rw_x] = -1;
+ else if (mid < viewheight) // safe to draw bottom texture
+ {
+ dc_yl = mid;
+ dc_yh = yh;
+ dc_texturemid = rw_bottomtexturemid;
+ dc_source = R_GetColumn(bottomtexture,
+ texturecolumn);
+ dc_texheight = textureheight[bottomtexture]>>FRACBITS;
+ colfunc();
+ floorclip[rw_x] = (INT16)mid;
+ }
+ else // entirely off bottom of screen
+ floorclip[rw_x] = (INT16)viewheight;
}
else
- floorclip[rw_x] = (INT16)((INT16)yh + 1);
+ floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
}
else if (markfloor) // no bottom wall
- floorclip[rw_x] = (INT16)((INT16)yh + 1);
+ floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
}
if (maskedtexture || numthicksides)
@@ -1858,12 +1883,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true;
#ifdef ESLOPE
- if (!(linedef->flags & ML_EFFECT1)) {
+ if (linedef->flags & ML_EFFECT2) {
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz;
else
- rw_midtexturemid = frontsector->ceilingheight;
+ rw_midtexturemid = frontsector->ceilingheight - viewz;
}
+ else
#endif
if (linedef->flags & ML_DONTPEGBOTTOM)
{
@@ -2482,6 +2508,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef ESLOPE
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
+#ifdef POLYOBJECTS
+ if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up
+ rw_midtextureslide = rw_midtexturebackslide = 0;
+ if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
+ rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
+ else
+ rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz;
+ } else
+#endif
// Set midtexture starting height
if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0;
diff --git a/src/r_splats.h b/src/r_splats.h
index 349d8fa7a..c0ba6881c 100644
--- a/src/r_splats.h
+++ b/src/r_splats.h
@@ -63,7 +63,11 @@ typedef struct floorsplat_s
fixed_t P_SegLength(seg_t *seg);
// call at P_SetupLevel()
+#if !(defined (WALLSPLATS) || defined (FLOORSPLATS))
+FUNCMATH void R_ClearLevelSplats(void);
+#else
void R_ClearLevelSplats(void);
+#endif
#ifdef WALLSPLATS
void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top,
diff --git a/src/r_things.c b/src/r_things.c
index 4b3f289df..f9f0f756c 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -18,6 +18,7 @@
#include "st_stuff.h"
#include "w_wad.h"
#include "z_zone.h"
+#include "m_menu.h" // character select
#include "m_misc.h"
#include "i_video.h" // rendermode
#include "r_things.h"
@@ -28,6 +29,7 @@
#include "dehacked.h" // get_number (for thok)
#include "d_netfil.h" // blargh. for nameonly().
#include "m_cheat.h" // objectplace
+#include "m_cond.h"
#ifdef HWRENDER
#include "hardware/hw_md2.h"
#endif
@@ -100,7 +102,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
lumppat <<= 16;
lumppat += lump;
- if (frame >= 64 || rotation > 8)
+ if (frame >= 64 || !(R_ValidSpriteAngle(rotation)))
I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat));
if (maxframe ==(size_t)-1 || frame > maxframe)
@@ -109,31 +111,72 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
if (rotation == 0)
{
// the lump should be used for all rotations
- if (sprtemp[frame].rotate == 0)
+ if (sprtemp[frame].rotate == SRF_SINGLE)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn);
-
- if (sprtemp[frame].rotate == 1)
+ else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message.
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn);
- sprtemp[frame].rotate = 0;
+ sprtemp[frame].rotate = SRF_SINGLE;
for (r = 0; r < 8; r++)
{
sprtemp[frame].lumppat[r] = lumppat;
sprtemp[frame].lumpid[r] = lumpid;
}
- sprtemp[frame].flip = flipped ? UINT8_MAX : 0;
+ sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary
+ return;
+ }
+
+ if (rotation == ROT_L || rotation == ROT_R)
+ {
+ UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0);
+
+ // the lump should be used for half of all rotations
+ if (sprtemp[frame].rotate == SRF_SINGLE)
+ CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn);
+ else if (sprtemp[frame].rotate == SRF_3D)
+ CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn);
+ else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L))
+ CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn);
+ else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R))
+ CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn);
+
+ if (sprtemp[frame].rotate == SRF_NONE)
+ sprtemp[frame].rotate = SRF_SINGLE;
+
+ sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT);
+ if (sprtemp[frame].rotate == (SRF_3D|SRF_2D))
+ sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen.
+
+ for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too.
+ {
+ sprtemp[frame].lumppat[r + rightfactor] = lumppat;
+ sprtemp[frame].lumpid[r + rightfactor] = lumpid;
+ }
+
+ if (flipped)
+ sprtemp[frame].flip |= (0x0F< 3) // Right side
+ sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover
+ else // if (rotation <= 3) // Left side
+ sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover
+
if (sprtemp[frame].lumppat[rotation] != LUMPERROR)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation);
@@ -195,7 +238,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
frame = R_Char2Frame(lumpinfo[l].name[4]);
rotation = (UINT8)(lumpinfo[l].name[5] - '0');
- if (frame >= 64 || rotation > 8) // Give an actual NAME error -_-...
+ if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-...
{
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l));
continue;
@@ -278,22 +321,29 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
{
switch (sprtemp[frame].rotate)
{
- case 0xff:
+ case SRF_NONE:
// no rotations were found for that frame at all
- I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame));
+ I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame));
break;
- case 0:
+ case SRF_SINGLE:
// only the first rotation is needed
break;
- case 1:
+ case SRF_2D: // both Left and Right rotations
+ // we test to see whether the left and right slots are present
+ if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR))
+ I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
+ sprname, R_Frame2Char(frame));
+ break;
+
+ default:
// must have all 8 frames
for (rotation = 0; rotation < 8; rotation++)
// we test the patch lump, or the id lump whatever
// if it was not loaded the two are LUMPERROR
if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
- I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations",
+ I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
sprname, R_Frame2Char(frame));
break;
}
@@ -1138,22 +1188,29 @@ static void R_ProjectSprite(mobj_t *thing)
I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite);
#endif
- if (sprframe->rotate)
- {
- // choose a different rotation based on player view
- ang = R_PointToAngle (thing->x, thing->y);
- rot = (ang-thing->angle+ANGLE_202h)>>29;
- //Fab: lumpid is the index for spritewidth,spriteoffset... tables
- lump = sprframe->lumpid[rot];
- flip = sprframe->flip & (1<rotate == SRF_SINGLE)
{
// use single rotation for all views
rot = 0; //Fab: for vis->patch below
lump = sprframe->lumpid[0]; //Fab: see note above
flip = sprframe->flip; // Will only be 0x00 or 0xFF
}
+ else
+ {
+ // choose a different rotation based on player view
+ ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
+
+ if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
+ rot = 6; // F7 slot
+ else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
+ rot = 2; // F3 slot
+ else // Normal behaviour
+ rot = (ang+ANGLE_202h)>>29;
+
+ //Fab: lumpid is the index for spritewidth,spriteoffset... tables
+ lump = sprframe->lumpid[rot];
+ flip = sprframe->flip & (1<prev = &unsorted;
unsorted.next = dsfirst;
- ds->next = &unsorted;
+ if (ds)
+ ds->next = &unsorted;
unsorted.prev = ds;
// pull the vissprites out by scale
@@ -2285,6 +2343,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->starttranscolor = 96;
skin->prefcolor = SKINCOLOR_GREEN;
+ skin->supercolor = SKINCOLOR_SUPERGOLD1;
+ skin->prefoppositecolor = 0; // use tables
skin->normalspeed = 36<runspeed = 28<jumpfactor = FRACUNIT;
skin->actionspd = 30<mindash = 15<maxdash = 90<maxdash = 70<radius = mobjinfo[MT_PLAYER].radius;
+ skin->height = mobjinfo[MT_PLAYER].height;
+ skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3);
+
+ skin->shieldscale = FRACUNIT;
+ skin->camerascale = FRACUNIT;
skin->thokitem = -1;
skin->spinitem = -1;
@@ -2305,6 +2372,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->highresscale = FRACUNIT>>1;
+ skin->availability = 0;
+
for (i = 0; i < sfx_skinsoundslot0; i++)
if (S_sfx[i].skinsound != -1)
skin->soundsid[S_sfx[i].skinsound] = i;
@@ -2329,6 +2398,19 @@ void R_InitSkins(void)
numskins = 0;
}
+// returns true if available in circumstances, otherwise nope
+// warning don't use with an invalid skinnum other than -1 which always returns true
+boolean R_SkinUnlock(INT32 skinnum)
+{
+ return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
+ || (!skins[skinnum].availability)
+ || (unlockables[skins[skinnum].availability - 1].unlocked)
+ || (modeattacking) // If you have someone else's run you might as well take a look
+ || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1.
+ || (netgame && !(server || adminplayer == consoleplayer) && (cv_forceskin.value == skinnum)) // Force 2.
+ );
+}
+
// returns true if the skin name is found (loaded from pwad)
// warning return -1 if not found
INT32 R_SkinAvailable(const char *name)
@@ -2337,6 +2419,7 @@ INT32 R_SkinAvailable(const char *name)
for (i = 0; i < numskins; i++)
{
+ // search in the skin list
if (stricmp(skins[i].name,name)==0)
return i;
}
@@ -2346,17 +2429,13 @@ INT32 R_SkinAvailable(const char *name)
// network code calls this when a 'skin change' is received
void SetPlayerSkin(INT32 playernum, const char *skinname)
{
- INT32 i;
+ INT32 i = R_SkinAvailable(skinname);
player_t *player = &players[playernum];
- for (i = 0; i < numskins; i++)
+ if ((i != -1) && (!P_IsLocalPlayer(player) || R_SkinUnlock(i)))
{
- // search in the skin list
- if (stricmp(skins[i].name, skinname) == 0)
- {
- SetPlayerSkinByNum(playernum, i);
- return;
- }
+ SetPlayerSkinByNum(playernum, i);
+ return;
}
if (P_IsLocalPlayer(player))
@@ -2373,12 +2452,15 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
{
player_t *player = &players[playernum];
skin_t *skin = &skins[skinnum];
+ UINT8 newcolor = 0;
- if (skinnum >= 0 && skinnum < numskins) // Make sure it exists!
+ if ((skinnum >= 0 && skinnum < numskins) // Make sure it exists!
+ && (!P_IsLocalPlayer(player) || R_SkinUnlock(skinnum))) // ...but is it allowed? We must always allow external players to change skin. The server should vet that...
{
player->skin = skinnum;
- if (player->mo)
- player->mo->skin = skin;
+
+ player->camerascale = skin->camerascale;
+ player->shieldscale = skin->shieldscale;
player->charability = (UINT8)skin->ability;
player->charability2 = (UINT8)skin->ability2;
@@ -2401,21 +2483,35 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->jumpfactor = skin->jumpfactor;
+ player->height = skin->height;
+ player->spinheight = skin->spinheight;
+
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
{
if (playernum == consoleplayer)
CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
else if (playernum == secondarydisplayplayer)
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
- player->skincolor = skin->prefcolor;
- if (player->mo)
- player->mo->color = player->skincolor;
+ player->skincolor = newcolor = skin->prefcolor;
}
if (player->mo)
+ {
+ if ((player->pflags & PF_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
+ {
+ skin = &skins[DEFAULTNIGHTSSKIN];
+ newcolor = ((skin->flags & SF_SUPER) ? skin->supercolor : skin->prefcolor);
+ }
+ player->mo->skin = skin;
+ if (newcolor)
+ player->mo->color = newcolor;
P_SetScale(player->mo, player->mo->scale);
+ player->mo->radius = FixedMul(skin->radius, player->mo->scale);
+ }
return;
}
+ else if (skinnum >= 0 && skinnum < numskins)
+ skinnum = 255; // Cheeky emulation.
if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum);
@@ -2510,15 +2606,12 @@ void R_AddSkins(UINT16 wadnum)
if (!stricmp(stoken, "name"))
{
- // the skin name must uniquely identify a single skin
- // I'm lazy so if name is already used I leave the 'skin x'
- // default skin name set in Sk_SetDefaultValue
- if (R_SkinAvailable(value) == -1)
- {
+ INT32 skinnum = R_SkinAvailable(value);
+ strlwr(value);
+ if (skinnum == -1)
STRBUFCPY(skin->name, value);
- strlwr(skin->name);
- }
- // I'm not lazy, so if the name is already used I make the name 'namex'
+ // the skin name must uniquely identify a single skin
+ // if the name is already used I make the name 'namex'
// using the default skin name's number set above
else
{
@@ -2529,11 +2622,9 @@ void R_AddSkins(UINT16 wadnum)
"%s%d", value, numskins);
value2[stringspace - 1] = '\0';
if (R_SkinAvailable(value2) == -1)
- {
- STRBUFCPY(skin->name,
- value2);
- strlwr(skin->name);
- }
+ // I'm lazy so if NEW name is already used I leave the 'skin x'
+ // default skin name set in Sk_SetDefaultValue
+ STRBUFCPY(skin->name, value2);
Z_Free(value2);
}
@@ -2601,13 +2692,18 @@ void R_AddSkins(UINT16 wadnum)
FULLPROCESS(revitem)
#undef FULLPROCESS
-#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<field = atoi(value)<field = atoi(value);
GETINT(thrustfactor)
@@ -2615,20 +2711,75 @@ void R_AddSkins(UINT16 wadnum)
GETINT(acceleration)
#undef GETINT
+ else if (!stricmp(stoken, "availability"))
+ {
+ skin->availability = atoi(value);
+ if (skin->availability >= MAXUNLOCKABLES)
+ skin->availability = 0;
+ if (skin->availability)
+ STRBUFCPY(unlockables[skin->availability - 1].name, skin->realname);
+ }
+
// custom translation table
else if (!stricmp(stoken, "startcolor"))
skin->starttranscolor = atoi(value);
- else if (!stricmp(stoken, "prefcolor"))
- skin->prefcolor = R_GetColorByName(value);
- else if (!stricmp(stoken, "jumpfactor"))
- skin->jumpfactor = FLOAT_TO_FIXED(atof(value));
- else if (!stricmp(stoken, "highresscale"))
- skin->highresscale = FLOAT_TO_FIXED(atof(value));
- else
+#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
+ GETSKINCOLOR(prefcolor)
+ GETSKINCOLOR(prefoppositecolor)
+#undef GETSKINCOLOR
+ else if (!stricmp(stoken, "supercolor"))
+ skin->supercolor = R_GetSuperColorByName(value);
+
+#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value));
+ GETFLOAT(jumpfactor)
+ GETFLOAT(highresscale)
+ GETFLOAT(shieldscale)
+ GETFLOAT(camerascale)
+#undef GETFLOAT
+
+#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \
+ strupr(value); \
+ if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \
+ skin->flags |= (SF_##field); \
+ else \
+ skin->flags &= ~(SF_##field); \
+}
+ // parameters for individual character flags
+ // these are uppercase so they can be concatenated with SF_
+ // 1, true, yes are all valid values
+ GETFLAG(SUPER)
+ GETFLAG(SUPERANIMS)
+ GETFLAG(SUPERSPIN)
+ GETFLAG(HIRES)
+ GETFLAG(NOSKID)
+ GETFLAG(NOSPEEDADJUST)
+ GETFLAG(RUNONWATER)
+ GETFLAG(NOJUMPSPIN)
+ GETFLAG(NOJUMPDAMAGE)
+ GETFLAG(STOMPDAMAGE)
+ GETFLAG(MARIODAMAGE)
+ GETFLAG(MACHINE)
+#undef GETFLAG
+
+ else // let's check if it's a sound, otherwise error out
{
- INT32 found = false;
+ boolean found = false;
sfxenum_t i;
+ size_t stokenadjust;
+
+ // Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.)
+ if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS*
+ stokenadjust = 2;
+ else // sfx_*
+ stokenadjust = 4;
+
+ // Remove the prefix. (We can affect this directly since we're not going to use it again.)
+ if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS*
+ value += 2;
+ else // sfx_*
+ value += 4;
+
// copy name of sounds that are remapped
// for this skin
for (i = 0; i < sfx_skinsoundslot0; i++)
@@ -2637,15 +2788,15 @@ void R_AddSkins(UINT16 wadnum)
continue;
if (S_sfx[i].skinsound != -1
&& !stricmp(S_sfx[i].name,
- stoken + 2))
+ stoken + stokenadjust))
{
skin->soundsid[S_sfx[i].skinsound] =
- S_AddSoundFx(value+2, S_sfx[i].singularity, S_sfx[i].pitch, true);
+ S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true);
found = true;
}
}
if (!found)
- CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump# %d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
+ CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
}
next_token:
stoken = strtok(NULL, "\r\n= ");
@@ -2666,13 +2817,14 @@ next_token:
if (z < lastlump) lastlump = z;
// load all sprite sets we are aware of.
- for (sprite2 = 0; sprite2 < NUMPLAYERSPRITES; sprite2++)
+ for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
}
R_FlushTranslationColormapCache();
- CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
+ if (!skin->availability) // Safe to print...
+ CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
#ifdef SKINVALUES
skin_cons_t[numskins].value = numskins;
skin_cons_t[numskins].strvalue = skin->name;
diff --git a/src/r_things.h b/src/r_things.h
index 3fce5f3fd..ffe34e293 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -17,6 +17,10 @@
#include "sounds.h"
#include "r_plane.h"
+// "Left" and "Right" character symbols for additional rotation functionality
+#define ROT_L ('L' - '0')
+#define ROT_R ('R' - '0')
+
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
// Fab: this is a hack : should allocate the lookup tables per sprite
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
@@ -25,6 +29,8 @@
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
+#define DEFAULTNIGHTSSKIN 0
+
// Constant arrays used for psprite clipping
// and initializing clipping.
extern INT16 negonearray[MAXVIDWIDTH];
@@ -93,15 +99,27 @@ typedef struct
fixed_t jumpfactor; // multiple of standard jump height
+ fixed_t radius; // Bounding box changes.
+ fixed_t height;
+ fixed_t spinheight;
+
+ fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size
+ fixed_t camerascale;
+
// Definable color translation table
UINT8 starttranscolor;
UINT8 prefcolor;
+ UINT8 supercolor;
+ UINT8 prefoppositecolor; // if 0 use tables instead
+
fixed_t highresscale; // scale of highres, default is 0.5
// specific sounds per skin
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
spritedef_t sprites[NUMPLAYERSPRITES];
+
+ UINT8 availability; // lock?
} skin_t;
// -----------
@@ -184,6 +202,7 @@ extern skin_t skins[MAXSKINS + 1];
void SetPlayerSkin(INT32 playernum,const char *skinname);
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
+boolean R_SkinUnlock(INT32 skinnum);
INT32 R_SkinAvailable(const char *name);
void R_AddSkins(UINT16 wadnum);
@@ -230,4 +249,9 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
#endif
}
+FUNCMATH FUNCINLINE static ATTRINLINE boolean R_ValidSpriteAngle(UINT8 rotation)
+{
+ return ((rotation <= 8) || (rotation == ROT_L) || (rotation == ROT_R));
+}
+
#endif //__R_THINGS__
diff --git a/src/s_sound.h b/src/s_sound.h
index bcc7979a1..39ec769a6 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -119,7 +119,7 @@ void S_ResumeAudio(void);
//
void S_UpdateSounds(void);
-fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
+FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
void S_SetDigMusicVolume(INT32 volume);
void S_SetMIDIMusicVolume(INT32 volume);
diff --git a/src/screen.c b/src/screen.c
index 3834f72d5..376586c5d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -69,6 +69,13 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N
consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
+
+#ifdef DIRECTFULLSCREEN
+static FUNCMATH void SCR_ChangeFullscreen (void);
+#else
+static void SCR_ChangeFullscreen (void);
+#endif
+
consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL};
// =========================================================================
diff --git a/src/screen.h b/src/screen.h
index bdf8e5a7d..2dff4590e 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -175,9 +175,7 @@ void SCR_SetDefaultMode (void);
void SCR_Startup (void);
-void SCR_ChangeFullscreen (void);
-
-boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
+FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency
void SCR_DisplayTicRate(void);
diff --git a/src/sdl/MakeNIX.cfg b/src/sdl/MakeNIX.cfg
index f5c9b2075..1a0b54210 100644
--- a/src/sdl/MakeNIX.cfg
+++ b/src/sdl/MakeNIX.cfg
@@ -56,6 +56,15 @@ ifdef FREEBSD
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
+
#
#here is GP2x (arm-gp2x-linux)
#
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index d12a7efbf..820192649 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -167,6 +167,7 @@
+
@@ -308,6 +309,7 @@
+
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index 9396b4823..d04007dd7 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj.filters
+++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters
@@ -294,6 +294,9 @@
M_Misc
+
+ M_Misc
+
M_Misc
@@ -666,6 +669,9 @@
M_Misc
+
+ M_Misc
+
M_Misc
diff --git a/src/sdl/i_cdmus.c b/src/sdl/i_cdmus.c
index f3f703667..3105f5122 100644
--- a/src/sdl/i_cdmus.c
+++ b/src/sdl/i_cdmus.c
@@ -12,25 +12,25 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL
consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
-void I_InitCD(void){}
+FUNCMATH void I_InitCD(void){}
-void I_StopCD(void){}
+FUNCMATH void I_StopCD(void){}
-void I_PauseCD(void){}
+FUNCMATH void I_PauseCD(void){}
-void I_ResumeCD(void){}
+FUNCMATH void I_ResumeCD(void){}
-void I_ShutdownCD(void){}
+FUNCMATH void I_ShutdownCD(void){}
-void I_UpdateCD(void){}
+FUNCMATH void I_UpdateCD(void){}
-void I_PlayCD(UINT8 track, UINT8 looping)
+FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping)
{
(void)track;
(void)looping;
}
-boolean I_SetVolumeCD(int volume)
+FUNCMATH boolean I_SetVolumeCD(int volume)
{
(void)volume;
return false;
diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c
index 74b61339b..25fccb9f9 100644
--- a/src/sdl/i_main.c
+++ b/src/sdl/i_main.c
@@ -144,10 +144,8 @@ void XBoxStartup()
myargv = NULL;
#else
#ifdef FORCESDLMAIN
-FUNCNORETURN
int SDL_main(int argc, char **argv)
#else
-FUNCNORETURN
int main(int argc, char **argv)
#endif
{
@@ -216,12 +214,14 @@ int main(int argc, char **argv)
#if defined (_WIN32) && !defined (_XBOX)
#ifndef _WIN32_WCE
{
+#if 0 // just load the DLL
p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent");
if ((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent())
#ifdef BUGTRAP
&& !InitBugTrap()
#endif
)
+#endif
{
LoadLibraryA("exchndl.dll");
}
@@ -245,8 +245,6 @@ int main(int argc, char **argv)
#endif
// return to OS
-#ifndef __GNUC__
return 0;
-#endif
}
#endif
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 0212e620b..ea8ade8c1 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -2049,14 +2049,14 @@ void I_StartupMouse2(void)
//
// I_Tactile
//
-void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
+FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
{
// UNUSED.
(void)pFFType;
(void)FFEffect;
}
-void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
+FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
{
// UNUSED.
(void)pFFType;
@@ -2067,7 +2067,7 @@ void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
*/
static ticcmd_t emptycmd;
-ticcmd_t *I_BaseTiccmd(void)
+FUNCMATH ticcmd_t *I_BaseTiccmd(void)
{
return &emptycmd;
}
@@ -2076,7 +2076,7 @@ ticcmd_t *I_BaseTiccmd(void)
*/
static ticcmd_t emptycmd2;
-ticcmd_t *I_BaseTiccmd2(void)
+FUNCMATH ticcmd_t *I_BaseTiccmd2(void)
{
return &emptycmd2;
}
@@ -2179,7 +2179,7 @@ tic_t I_GetTime (void)
//
//I_StartupTimer
//
-void I_StartupTimer(void)
+FUNCMATH void I_StartupTimer(void)
{
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX)
// for win2k time bug
@@ -2313,11 +2313,11 @@ void I_WaitVBL(INT32 count)
SDL_Delay(count);
}
-void I_BeginRead(void)
+FUNCMATH void I_BeginRead(void)
{
}
-void I_EndRead(void)
+FUNCMATH void I_EndRead(void)
{
}
@@ -3067,5 +3067,5 @@ const CPUInfoFlags *I_CPUInfo(void)
}
// note CPUAFFINITY code used to reside here
-void I_RegisterSysCommands(void) {}
+FUNCMATH void I_RegisterSysCommands(void) {}
#endif
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index b5168dad5..71baca510 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -1346,7 +1346,7 @@ void I_SetPalette(RGBA_t *palette)
}
// return number of fullscreen + X11 modes
-INT32 VID_NumModes(void)
+FUNCMATH INT32 VID_NumModes(void)
{
if (USE_FULLSCREEN && numVidModes != -1)
return numVidModes - firstEntry;
@@ -1354,7 +1354,7 @@ INT32 VID_NumModes(void)
return MAXWINMODES;
}
-const char *VID_GetModeName(INT32 modeNum)
+FUNCMATH const char *VID_GetModeName(INT32 modeNum)
{
#if 0
if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes
@@ -1384,7 +1384,7 @@ const char *VID_GetModeName(INT32 modeNum)
return &vidModeName[modeNum][0];
}
-INT32 VID_GetModeForSize(INT32 w, INT32 h)
+FUNCMATH INT32 VID_GetModeForSize(INT32 w, INT32 h)
{
int i;
for (i = 0; i < MAXWINMODES; i++)
diff --git a/src/sdl/macosx/mac_alert.c b/src/sdl/macosx/mac_alert.c
index 455e36509..2a139041a 100644
--- a/src/sdl/macosx/mac_alert.c
+++ b/src/sdl/macosx/mac_alert.c
@@ -25,19 +25,38 @@
#include "mac_alert.h"
#include
+#define CFSTRINGIFY(x) CFStringCreateWithCString(NULL, x, kCFStringEncodingASCII)
+
int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3)
{
CFOptionFlags results;
- CFUserNotificationDisplayAlert(0,
- kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag,
- NULL, NULL, NULL,
- CFStringCreateWithCString(NULL, title, kCFStringEncodingASCII),
- CFStringCreateWithCString(NULL, message, kCFStringEncodingASCII),
- button1 != NULL ? CFStringCreateWithCString(NULL, button1, kCFStringEncodingASCII) : NULL,
- button2 != NULL ? CFStringCreateWithCString(NULL, button2, kCFStringEncodingASCII) : NULL,
- button3 != NULL ? CFStringCreateWithCString(NULL, button3, kCFStringEncodingASCII) : NULL,
- &results);
+ CFStringRef cf_title = CFSTRINGIFY(title);
+ CFStringRef cf_message = CFSTRINGIFY(message);
+ CFStringRef cf_button1 = NULL;
+ CFStringRef cf_button2 = NULL;
+ CFStringRef cf_button3 = NULL;
+
+ if (button1 != NULL)
+ cf_button1 = CFSTRINGIFY(button1);
+ if (button2 != NULL)
+ cf_button2 = CFSTRINGIFY(button2);
+ if (button3 != NULL)
+ cf_button3 = CFSTRINGIFY(button3);
+
+ CFOptionFlags alert_flags = kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag;
+
+ CFUserNotificationDisplayAlert(0, alert_flags, NULL, NULL, NULL, cf_title, cf_message,
+ cf_button1, cf_button2, cf_button3, &results);
+
+ if (cf_button1 != NULL)
+ CFRelease(cf_button1);
+ if (cf_button2 != NULL)
+ CFRelease(cf_button2);
+ if (cf_button3 != NULL)
+ CFRelease(cf_button3);
+ CFRelease(cf_message);
+ CFRelease(cf_title);
return (int)results;
}
diff --git a/src/sdl/macosx/mac_resources.c b/src/sdl/macosx/mac_resources.c
index dacc8014b..d67b92580 100644
--- a/src/sdl/macosx/mac_resources.c
+++ b/src/sdl/macosx/mac_resources.c
@@ -9,23 +9,29 @@ void OSX_GetResourcesPath(char * buffer)
mainBundle = CFBundleGetMainBundle();
if (mainBundle)
{
+ const int BUF_SIZE = 256; // because we somehow always know that
+
CFURLRef appUrlRef = CFBundleCopyBundleURL(mainBundle);
- CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
- CFStringRef resources = CFStringCreateWithCString(kCFAllocatorMalloc, "/Contents/Resources", kCFStringEncodingASCII);
- const void* rawarray[2] = {macPath, resources};
- CFArrayRef array = CFArrayCreate(kCFAllocatorMalloc, rawarray, 2, NULL);
- CFStringRef separator = CFStringCreateWithCString(kCFAllocatorMalloc, "", kCFStringEncodingASCII);
- CFStringRef fullPath = CFStringCreateByCombiningStrings(kCFAllocatorMalloc, array, separator);
- const char * path = CFStringGetCStringPtr(fullPath, kCFStringEncodingASCII);
- strcpy(buffer, path);
- CFRelease(fullPath);
- path = NULL;
- CFRelease(array);
- CFRelease(resources);
+ CFStringRef macPath;
+ if (appUrlRef != NULL)
+ macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
+ else
+ macPath = NULL;
+
+ const char* rawPath;
+
+ if (macPath != NULL)
+ rawPath = CFStringGetCStringPtr(macPath, kCFStringEncodingASCII);
+ else
+ rawPath = NULL;
+
+ if (rawPath != NULL && (CFStringGetLength(macPath) + strlen("/Contents/Resources") < BUF_SIZE))
+ {
+ strcpy(buffer, rawPath);
+ strcat(buffer, "/Contents/Resources");
+ }
+
CFRelease(macPath);
CFRelease(appUrlRef);
- //CFRelease(mainBundle);
- CFRelease(separator);
}
-
-}
\ No newline at end of file
+}
diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c
index faebca6b4..4a46813c1 100644
--- a/src/sdl/mixer_sound.c
+++ b/src/sdl/mixer_sound.c
@@ -126,7 +126,7 @@ void I_ShutdownSound(void)
#endif
}
-void I_UpdateSound(void)
+FUNCMATH void I_UpdateSound(void)
{
}
@@ -464,7 +464,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
}
#endif
-void I_InitMusic(void)
+FUNCMATH void I_InitMusic(void)
{
}
@@ -769,7 +769,7 @@ boolean I_SetSongTrack(int track)
// MIDI Music
//
-void I_InitMIDIMusic(void)
+FUNCMATH void I_InitMIDIMusic(void)
{
}
diff --git a/src/sounds.c b/src/sounds.c
index 8ad42ac9f..75ee1358c 100644
--- a/src/sounds.c
+++ b/src/sounds.c
@@ -159,6 +159,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"lvpass", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mindig", false, 8, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"mixup", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
+ {"monton", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"pogo" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"pop" , false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"rail1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
diff --git a/src/sounds.h b/src/sounds.h
index 565d41b56..532c61da6 100644
--- a/src/sounds.h
+++ b/src/sounds.h
@@ -222,6 +222,7 @@ typedef enum
sfx_lvpass,
sfx_mindig,
sfx_mixup,
+ sfx_monton,
sfx_pogo,
sfx_pop,
sfx_rail1,
diff --git a/src/st_stuff.c b/src/st_stuff.c
index e0d085497..1d5b42c60 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -565,7 +565,7 @@ static void ST_drawDebugInfo(void)
{
V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
- V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, FixedMul(stplyr->maxdash,stplyr->mo->scale)>>FRACBITS));
+ V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, stplyr->maxdash>>FRACBITS));
V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
// Flags
@@ -890,11 +890,19 @@ static void ST_drawFirstPersonHUD(void)
V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p);
}
-// [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold
-static skincolors_t linkColor[14] =
+// 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold
+/*#define NUMLINKCOLORS 14
+static skincolors_t linkColor[NUMLINKCOLORS] =
{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE,
- SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED,
- SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};
+ SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED,
+ SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/
+
+// 2.2+: (unix time 1470866042) Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot
+#define NUMLINKCOLORS 13
+static skincolors_t linkColor[NUMLINKCOLORS] =
+{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL,
+ SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE,
+ SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};
static void ST_drawNightsRecords(void)
{
@@ -974,7 +982,7 @@ static void ST_drawNiGHTSHUD(void)
if (cv_debug & DBG_NIGHTSBASIC)
minlink = 0;
- // Cheap hack: don't display when the score is showing
+ // Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional)
if (stplyr->texttimer && stplyr->textvar == 4)
minlink = INT32_MAX;
@@ -994,7 +1002,7 @@ static void ST_drawNiGHTSHUD(void)
#endif
stplyr->linkcount > minlink)
{
- skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % (sizeof(linkColor) / sizeof(skincolors_t))];
+ skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % NUMLINKCOLORS];
if (stplyr->powers[pw_nights_linkfreeze])
colornum = SKINCOLOR_WHITE;
@@ -1299,7 +1307,7 @@ static void ST_drawNiGHTSHUD(void)
nightsnum, SKINCOLOR_RED);
else
ST_DrawNightsOverlayNum(160 + numbersize, STRINGY(12), SPLITFLAGS(V_SNAPTOTOP), realnightstime,
- nightsnum, SKINCOLOR_SUPER4);
+ nightsnum, SKINCOLOR_SUPERGOLD4);
// Show exact time in debug
if (cv_debug & DBG_NIGHTSBASIC)
@@ -1385,6 +1393,10 @@ static void ST_drawMatchHUD(void)
if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT))
return;
+#ifdef HAVE_BLUA
+ if (LUA_HudEnabled(hud_weaponrings)) {
+#endif
+
if (stplyr->powers[pw_infinityring])
ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring);
else if (stplyr->rings > 0)
@@ -1408,6 +1420,12 @@ static void ST_drawMatchHUD(void)
offset += 20;
ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring);
+#ifdef HAVE_BLUA
+ }
+
+ if (LUA_HudEnabled(hud_powerstones)) {
+#endif
+
// Power Stones collected
offset = 136; // Used for Y now
@@ -1439,6 +1457,10 @@ static void ST_drawMatchHUD(void)
if (stplyr->powers[pw_emeralds] & EMERALD7)
V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]);
+
+#ifdef HAVE_BLUA
+ }
+#endif
}
static inline void ST_drawRaceHUD(void)
diff --git a/src/st_stuff.h b/src/st_stuff.h
index 6fafca404..c11559d2b 100644
--- a/src/st_stuff.h
+++ b/src/st_stuff.h
@@ -24,7 +24,7 @@
//
// Called by main loop.
-void ST_Ticker(void);
+FUNCMATH void ST_Ticker(void);
// Called by main loop.
void ST_Drawer(void);
diff --git a/src/tables.h b/src/tables.h
index 0e4853cb9..e05b81845 100644
--- a/src/tables.h
+++ b/src/tables.h
@@ -82,7 +82,7 @@ typedef UINT32 angle_t;
extern angle_t tantoangle[SLOPERANGE+1];
// Utility function, called by R_PointToAngle.
-unsigned SlopeDiv(unsigned num, unsigned den);
+FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den);
// 360 - angle_t(ANGLE_45) = ANGLE_315
FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a)
diff --git a/src/w_wad.c b/src/w_wad.c
index 40fea5223..aeaad3ced 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -475,11 +475,11 @@ UINT16 W_LoadWadFile(const char *filename)
//
CONS_Printf(M_GetText("Added file %s (%u lumps)\n"), filename, numlumps);
wadfiles[numwadfiles] = wadfile;
- W_LoadDehackedLumps(numwadfiles);
+ numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded
+ W_LoadDehackedLumps(numwadfiles-1);
W_InvalidateLumpnumCache();
- numwadfiles++;
return wadfile->numlumps;
}
diff --git a/src/w_wad.h b/src/w_wad.h
index c13f69338..b03e376bf 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -54,10 +54,8 @@ typedef struct
#define lumpcache_t void *
-// Annoying cyclic dependency workaround: this inlcusion must come after
-// the definition of MAX_WADPATH.
#ifdef HWRENDER
-#include "m_misc.h"
+#include "m_aatree.h"
#endif
typedef struct wadfile_s
diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj
index 1e9d8241e..064f75d7d 100644
--- a/src/win32/Srb2win-vc10.vcxproj
+++ b/src/win32/Srb2win-vc10.vcxproj
@@ -145,6 +145,7 @@
+
@@ -300,6 +301,7 @@
+
diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters
index 3f5b84bfb..b2647ea1c 100644
--- a/src/win32/Srb2win-vc10.vcxproj.filters
+++ b/src/win32/Srb2win-vc10.vcxproj.filters
@@ -255,6 +255,9 @@
LUA
+
+ M_Misc
+
M_Misc
@@ -662,6 +665,9 @@
M_Misc
+
+ M_Misc
+
M_Misc
diff --git a/src/win32/win_main.c b/src/win32/win_main.c
index 9c9a20e75..663eddbd4 100644
--- a/src/win32/win_main.c
+++ b/src/win32/win_main.c
@@ -644,13 +644,16 @@ int WINAPI WinMain (HINSTANCE hInstance,
{
int Result = -1;
+#if 0
// Win95 and NT <4 don't have this, so link at runtime.
p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"),"IsDebuggerPresent");
+#endif
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
+#if 0
#ifdef BUGTRAP
// Try BugTrap first.
if((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) && InitBugTrap())
@@ -660,6 +663,7 @@ int WINAPI WinMain (HINSTANCE hInstance,
#endif
// Try Dr MinGW's exception handler.
if (!pfnIsDebuggerPresent || !pfnIsDebuggerPresent())
+#endif
LoadLibraryA("exchndl.dll");
prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo);