mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 20:11:12 +00:00
Merge branch 'master' into update-libs
This commit is contained in:
commit
95a2ef4021
129 changed files with 16985 additions and 2909 deletions
9
.gitattributes
vendored
9
.gitattributes
vendored
|
@ -1,3 +1,12 @@
|
|||
#Source code
|
||||
/src/*.c text=auto
|
||||
/src/*.h text=auto
|
||||
/src/*.s text=auto
|
||||
/src/*.m text=auto
|
||||
/src/*.xpm text=auto
|
||||
/src/Makefile text=auto
|
||||
/src/Make*.cfg text=auto
|
||||
/src/CMakeLists.txt text=auto
|
||||
# Windows EOL
|
||||
*.cs -crlf -whitespace
|
||||
*.mk -crlf -whitespace
|
||||
|
|
|
@ -13,11 +13,10 @@ set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer"
|
|||
CACHE STRING "Path to directory that contains all asset files for the installer.")
|
||||
|
||||
set(SRB2_ASSET_HASHED
|
||||
"srb2.srb;\
|
||||
"srb2.pk3;\
|
||||
player.dta;\
|
||||
rings.dta;\
|
||||
zones.dta;\
|
||||
patch.dta"
|
||||
zones.pk3;\
|
||||
patch.pk3"
|
||||
CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!"
|
||||
)
|
||||
|
||||
|
|
6482
extras/conf/SRB2-22.cfg
Normal file
6482
extras/conf/SRB2-22.cfg
Normal file
File diff suppressed because it is too large
Load diff
91
libs/SDL2/test/Makefile.os2
Normal file
91
libs/SDL2/test/Makefile.os2
Normal file
|
@ -0,0 +1,91 @@
|
|||
BINPATH = .
|
||||
|
||||
TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe &
|
||||
testdrawchessboard.exe testdropfile.exe testerror.exe testfile.exe &
|
||||
testfilesystem.exe testgamecontroller.exe testgesture.exe &
|
||||
testhittesting.exe testhotplug.exe testiconv.exe testime.exe &
|
||||
testintersections.exe testjoystick.exe testkeys.exe testloadso.exe &
|
||||
testlock.exe testmessage.exe testoverlay2.exe testplatform.exe &
|
||||
testpower.exe testsensor.exe testrelative.exe testrendercopyex.exe &
|
||||
testrendertarget.exe testrumble.exe testscale.exe testsem.exe &
|
||||
testshader.exe testshape.exe testsprite2.exe testspriteminimal.exe &
|
||||
teststreaming.exe testthread.exe testtimer.exe testver.exe &
|
||||
testviewport.exe testwm2.exe torturethread.exe checkkeys.exe &
|
||||
controllermap.exe testhaptic.exe testqsort.exe testresample.exe &
|
||||
testaudioinfo.exe testaudiocapture.exe loopwave.exe loopwavequeue.exe &
|
||||
testyuv.exe testgl2.exe testvulkan.exe testautomation.exe
|
||||
|
||||
# SDL2test.lib sources (../src/test)
|
||||
|
||||
CSRCS = SDL_test_assert.c SDL_test_common.c SDL_test_compare.c &
|
||||
SDL_test_crc32.c SDL_test_font.c SDL_test_fuzzer.c SDL_test_harness.c &
|
||||
SDL_test_imageBlit.c SDL_test_imageBlitBlend.c SDL_test_imageFace.c &
|
||||
SDL_test_imagePrimitives.c SDL_test_imagePrimitivesBlend.c &
|
||||
SDL_test_log.c SDL_test_md5.c SDL_test_random.c SDL_test_memory.c
|
||||
TESTLIB = SDL2test.lib
|
||||
|
||||
# testautomation sources
|
||||
|
||||
TASRCS = testautomation.c testautomation_audio.c testautomation_clipboard.c &
|
||||
testautomation_events.c testautomation_hints.c &
|
||||
testautomation_keyboard.c testautomation_main.c &
|
||||
testautomation_mouse.c testautomation_pixels.c &
|
||||
testautomation_platform.c testautomation_rect.c &
|
||||
testautomation_render.c testautomation_rwops.c &
|
||||
testautomation_sdltest.c testautomation_stdlib.c &
|
||||
testautomation_surface.c testautomation_syswm.c &
|
||||
testautomation_timer.c testautomation_video.c
|
||||
|
||||
OBJS = $(TARGETS:.exe=.obj)
|
||||
COBJS = $(CSRCS:.c=.obj)
|
||||
TAOBJS = $(TASRCS:.c=.obj)
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
INCPATH = -I$(%WATCOM)/h/os2 -I$(%WATCOM)/h -I../include
|
||||
|
||||
CFLAGS = $(INCPATH) -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei
|
||||
|
||||
LIBPATH = ..
|
||||
LIBS = SDL2.lib $(TESTLIB)
|
||||
|
||||
#CFLAGS+= -DHAVE_SDL_TTF
|
||||
#LIBS_TTF = SDL2ttf.lib
|
||||
|
||||
.c: ../src/test
|
||||
|
||||
$(TESTLIB): $(COBJS)
|
||||
wlib -q -b -n $@ $(COBJS)
|
||||
|
||||
.obj.exe:
|
||||
@%make $(TESTLIB)
|
||||
wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@
|
||||
|
||||
.c.obj:
|
||||
wcc386 $(CFLAGS) -wcd=107 -fo=$^@ $<
|
||||
|
||||
# specials
|
||||
testautomation.exe: $(TAOBJS)
|
||||
@%make $(TESTLIB)
|
||||
wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@
|
||||
|
||||
testoverlay2.exe: testoverlay2.obj testyuv_cvt.obj
|
||||
@%make $(TESTLIB)
|
||||
wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@
|
||||
|
||||
testyuv.exe: testyuv.obj testyuv_cvt.obj
|
||||
@%make $(TESTLIB)
|
||||
wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@
|
||||
|
||||
testime.exe: testime.obj
|
||||
@%make $(TESTLIB)
|
||||
wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS) $(LIBS_TTF)} op q op el file {$<} name $@
|
||||
|
||||
clean: .SYMBOLIC
|
||||
@echo * Clean tests in $(BINPATH)
|
||||
@if exist *.obj rm *.obj
|
||||
@if exist *.err rm *.err
|
||||
|
||||
distclean: .SYMBOLIC clean
|
||||
@if exist *.exe rm *.exe
|
||||
@if exist $(TESTLIB) rm $(TESTLIB)
|
200
libs/SDL2/test/configure.ac
Normal file
200
libs/SDL2/test/configure.ac
Normal file
|
@ -0,0 +1,200 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(README)
|
||||
|
||||
dnl Detect the canonical build and host environments
|
||||
AC_CONFIG_AUX_DIRS($srcdir/../build-scripts)
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
dnl Check for tools
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
dnl Check for compiler environment
|
||||
|
||||
AC_C_CONST
|
||||
|
||||
dnl We only care about this for building testnative at the moment, so these
|
||||
dnl values shouldn't be considered absolute truth.
|
||||
dnl (Haiku, for example, sets none of these.)
|
||||
ISUNIX="false"
|
||||
ISWINDOWS="false"
|
||||
ISMACOSX="false"
|
||||
|
||||
dnl Figure out which math library to use
|
||||
case "$host" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
ISWINDOWS="true"
|
||||
EXE=".exe"
|
||||
MATHLIB=""
|
||||
SYS_GL_LIBS="-lopengl32"
|
||||
;;
|
||||
*-*-haiku*)
|
||||
EXE=""
|
||||
MATHLIB=""
|
||||
SYS_GL_LIBS="-lGL"
|
||||
;;
|
||||
*-*-darwin* )
|
||||
ISMACOSX="true"
|
||||
EXE=""
|
||||
MATHLIB=""
|
||||
SYS_GL_LIBS="-Wl,-framework,OpenGL"
|
||||
;;
|
||||
*-*-aix*)
|
||||
ISUNIX="true"
|
||||
EXE=""
|
||||
if test x$ac_cv_prog_gcc = xyes; then
|
||||
CFLAGS="-mthreads"
|
||||
fi
|
||||
SYS_GL_LIBS=""
|
||||
;;
|
||||
*-*-mint*)
|
||||
EXE=""
|
||||
MATHLIB=""
|
||||
AC_PATH_PROG(OSMESA_CONFIG, osmesa-config, no)
|
||||
if test "x$OSMESA_CONFIG" = "xyes"; then
|
||||
OSMESA_CFLAGS=`$OSMESA_CONFIG --cflags`
|
||||
OSMESA_LIBS=`$OSMESA_CONFIG --libs`
|
||||
CFLAGS="$CFLAGS $OSMESA_CFLAGS"
|
||||
SYS_GL_LIBS="$OSMESA_LIBS"
|
||||
else
|
||||
SYS_GL_LIBS="-lOSMesa"
|
||||
fi
|
||||
;;
|
||||
*-*-qnx*)
|
||||
EXE=""
|
||||
MATHLIB=""
|
||||
SYS_GL_LIBS="-lGLES_CM"
|
||||
;;
|
||||
*-*-emscripten* )
|
||||
dnl This should really be .js, but we need to specify extra flags when compiling to js
|
||||
EXE=".bc"
|
||||
MATHLIB=""
|
||||
SYS_GL_LIBS=""
|
||||
;;
|
||||
*)
|
||||
dnl Oh well, call it Unix...
|
||||
ISUNIX="true"
|
||||
EXE=""
|
||||
MATHLIB="-lm"
|
||||
SYS_GL_LIBS="-lGL"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXE)
|
||||
AC_SUBST(MATHLIB)
|
||||
AC_SUBST(ISMACOSX)
|
||||
AC_SUBST(ISWINDOWS)
|
||||
AC_SUBST(ISUNIX)
|
||||
|
||||
dnl Check for SDL
|
||||
SDL_VERSION=2.0.0
|
||||
AM_PATH_SDL2($SDL_VERSION,
|
||||
:,
|
||||
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
|
||||
)
|
||||
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||
LIBS="$LIBS -lSDL2_test $SDL_LIBS"
|
||||
|
||||
dnl Check for X11 path, needed for OpenGL on some systems
|
||||
AC_PATH_X
|
||||
if test x$have_x = xyes; then
|
||||
if test x$ac_x_includes = xno || test "x$ac_x_includes" = xNone || test "x$ac_x_includes" = x; then
|
||||
:
|
||||
else
|
||||
CFLAGS="$CFLAGS -I$ac_x_includes"
|
||||
fi
|
||||
if test x$ac_x_libraries = xno || test "x$ac_x_libraries" = xNone; then
|
||||
:
|
||||
else
|
||||
if test "x$ac_x_libraries" = x; then
|
||||
XPATH=""
|
||||
XLIB="-lX11"
|
||||
else
|
||||
XPATH="-L$ac_x_libraries"
|
||||
XLIB="-L$ac_x_libraries -lX11"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Check for OpenGL
|
||||
AC_MSG_CHECKING(for OpenGL support)
|
||||
have_opengl=no
|
||||
AC_TRY_COMPILE([
|
||||
#include "SDL_opengl.h"
|
||||
],[
|
||||
],[
|
||||
have_opengl=yes
|
||||
])
|
||||
AC_MSG_RESULT($have_opengl)
|
||||
|
||||
dnl Check for OpenGL ES
|
||||
AC_MSG_CHECKING(for OpenGL ES support)
|
||||
have_opengles=no
|
||||
AC_TRY_COMPILE([
|
||||
#if defined (__IPHONEOS__)
|
||||
#include <OpenGLES/ES1/gl.h>
|
||||
#else
|
||||
#include <GLES/gl.h>
|
||||
#endif /* __QNXNTO__ */
|
||||
],[
|
||||
],[
|
||||
have_opengles=yes
|
||||
])
|
||||
AC_MSG_RESULT($have_opengles)
|
||||
|
||||
dnl Check for OpenGL ES2
|
||||
AC_MSG_CHECKING(for OpenGL ES2 support)
|
||||
have_opengles2=no
|
||||
AC_TRY_COMPILE([
|
||||
#if defined (__IPHONEOS__)
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#else
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
],[
|
||||
],[
|
||||
have_opengles2=yes
|
||||
])
|
||||
AC_MSG_RESULT($have_opengles2)
|
||||
|
||||
GLLIB=""
|
||||
GLESLIB=""
|
||||
GLES2LIB=""
|
||||
OPENGLES1_TARGETS="UNUSED"
|
||||
OPENGLES2_TARGETS="UNUSED"
|
||||
OPENGL_TARGETS="UNUSED"
|
||||
if test x$have_opengles = xyes; then
|
||||
CFLAGS="$CFLAGS -DHAVE_OPENGLES"
|
||||
GLESLIB="$XPATH -lGLESv1_CM"
|
||||
OPENGLES1_TARGETS="TARGETS"
|
||||
fi
|
||||
if test x$have_opengles2 = xyes; then
|
||||
CFLAGS="$CFLAGS -DHAVE_OPENGLES2"
|
||||
#GLES2LIB="$XPATH -lGLESv2"
|
||||
OPENGLES2_TARGETS="TARGETS"
|
||||
fi
|
||||
if test x$have_opengl = xyes; then
|
||||
CFLAGS="$CFLAGS -DHAVE_OPENGL"
|
||||
GLLIB="$XPATH $SYS_GL_LIBS"
|
||||
OPENGL_TARGETS="TARGETS"
|
||||
fi
|
||||
|
||||
AC_SUBST(OPENGLES1_TARGETS)
|
||||
AC_SUBST(OPENGLES2_TARGETS)
|
||||
AC_SUBST(OPENGL_TARGETS)
|
||||
AC_SUBST(GLLIB)
|
||||
AC_SUBST(GLESLIB)
|
||||
AC_SUBST(GLES2LIB)
|
||||
AC_SUBST(XLIB)
|
||||
|
||||
dnl Check for SDL_ttf
|
||||
AC_CHECK_LIB(SDL2_ttf, TTF_Init, have_SDL_ttf=yes)
|
||||
if test x$have_SDL_ttf = xyes; then
|
||||
CFLAGS="$CFLAGS -DHAVE_SDL_TTF"
|
||||
SDL_TTF_LIB="-lSDL2_ttf"
|
||||
fi
|
||||
AC_SUBST(SDL_TTF_LIB)
|
||||
|
||||
dnl Finally create all the generated files
|
||||
AC_OUTPUT([Makefile])
|
|
@ -1,6 +1,6 @@
|
|||
# libopenmpt mingw-w64 binary info
|
||||
|
||||
Current built version as of 2019/05/23 is 0.4.4+r11531.pkg
|
||||
Current built version as of 2019/09/27 is 0.4.7+r12088.pkg
|
||||
|
||||
* mingw binaries (.dll): `bin/[x86 or x86_64]/mingw`
|
||||
* mingw import libraries (.dll.a): `lib/[x86 or x86_64]/mingw`
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,6 +5,44 @@ Changelog {#changelog}
|
|||
For fully detailed change log, please see the source repository directly. This
|
||||
is just a high-level summary.
|
||||
|
||||
### libopenmpt 0.4.7 (2019-09-23)
|
||||
|
||||
* [**Bug**] Compilation fix for various platforms that do not provide
|
||||
`std::aligned_alloc` in C++17 mode. The problematic dependency has been
|
||||
removed. This should fix build problems on MinGW, OpenBSD, Haiku, and others
|
||||
for good.
|
||||
|
||||
* J2B: Ignore notes with non-existing instrument (fixes Ending.j2b).
|
||||
|
||||
* mpg123: Update to v1.25.13 (2019-08-24).
|
||||
* ogg: Update to v1.3.4. (2019-08-31).
|
||||
* flac: Update to v1.3.3. (2019-08-04).
|
||||
|
||||
### libopenmpt 0.4.6 (2019-08-10)
|
||||
|
||||
* [**Bug**] Compilation fix for OpenBSD.
|
||||
* [**Bug**] Compilation fix for NO_PLUGINS being defined.
|
||||
|
||||
* in_openmpt: Correct documentation. `openmpt-mpg123.dll` must be placed into
|
||||
the Winamp directory.
|
||||
|
||||
* Detect IT files unpacked with early UNMO3 versions.
|
||||
|
||||
* mpg123: Update to v1.25.11 (2019-07-18).
|
||||
* minimp3: Update to commit 977514a6dfc4960d819a103f43b358e58ac6c28f
|
||||
(2019-07-24).
|
||||
* miniz: Update to v2.1.0 (2019-05-05).
|
||||
* stb_vorbis: Update to v1.17 (2019-08-09).
|
||||
|
||||
### libopenmpt 0.4.5 (2019-05-27)
|
||||
|
||||
* [**Sec**] Possible crash during playback due out-of-bounds read in XM and
|
||||
MT2 files (r11608).
|
||||
|
||||
* Breaking out of a sustain loop through Note-Off sometimes didn't continue in
|
||||
the regular sample loop.
|
||||
* Seeking did not stop notes playing with XM Key Off (Kxx) effect.
|
||||
|
||||
### libopenmpt 0.4.4 (2019-04-07)
|
||||
|
||||
* [**Bug**] Channel VU meters were swapped.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
/*! \brief libopenmpt minor version number */
|
||||
#define OPENMPT_API_VERSION_MINOR 4
|
||||
/*! \brief libopenmpt patch version number */
|
||||
#define OPENMPT_API_VERSION_PATCH 4
|
||||
#define OPENMPT_API_VERSION_PATCH 7
|
||||
/*! \brief libopenmpt pre-release tag */
|
||||
#define OPENMPT_API_VERSION_PREREL ""
|
||||
/*! \brief libopenmpt pre-release flag */
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
srb2.png
BIN
srb2.png
Binary file not shown.
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 25 KiB |
|
@ -86,10 +86,7 @@
|
|||
D_DIR?=../bin/Resources
|
||||
D_FILES=$(D_DIR)/srb2.pk3 \
|
||||
$(D_DIR)/player.dta \
|
||||
$(D_DIR)/rings.wpn \
|
||||
$(D_DIR)/drill.dta \
|
||||
$(D_DIR)/soar.dta \
|
||||
$(D_DIR)/zones.dta \
|
||||
$(D_DIR)/zones.pk3 \
|
||||
$(D_DIR)/music.dta \
|
||||
|
||||
PKG_CONFIG?=pkg-config
|
||||
|
|
61
src/am_map.c
61
src/am_map.c
|
@ -62,7 +62,7 @@ static const UINT8 NOCLIMBYELLOWS = (11*16);
|
|||
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
|
||||
#define THINGCOLORS GREENS
|
||||
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
|
||||
#define XHAIRCOLORS GRAYS
|
||||
#define XHAIRCOLORS DWHITE
|
||||
|
||||
// controls
|
||||
#define AM_PANUPKEY KEY_UPARROW
|
||||
|
@ -111,11 +111,6 @@ typedef struct
|
|||
mpoint_t a, b;
|
||||
} mline_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t slp, islp;
|
||||
} islope_t;
|
||||
|
||||
//
|
||||
// The vector graphics for the automap.
|
||||
// A line drawing of the player pointing right,
|
||||
|
@ -137,16 +132,14 @@ static const mline_t player_arrow[] = {
|
|||
#undef R
|
||||
#define NUMPLYRLINES (sizeof (player_arrow)/sizeof (mline_t))
|
||||
|
||||
#if 0
|
||||
#define R (FRACUNIT)
|
||||
static mline_t triangle_guy[] = {
|
||||
{ { (fixed_t)-.867f*R, (fixed_t)-.5f*R }, { (fixed_t) .867f*R, (fixed_t)-.5f*R } },
|
||||
{ { (fixed_t) .867f*R, (fixed_t)-.5f*R }, { (fixed_t) 0, (fixed_t) R } },
|
||||
{ { (fixed_t) 0, (fixed_t) R }, { (fixed_t)-.867f*R, (fixed_t)-.5f*R } }
|
||||
static const mline_t cross_mark[] =
|
||||
{
|
||||
{ { -R, 0 }, { R, 0} },
|
||||
{ { 0, -R }, { 0, R } },
|
||||
};
|
||||
#undef R
|
||||
#define NUMTRIANGLEGUYLINES (sizeof (triangle_guy)/sizeof (mline_t))
|
||||
#endif
|
||||
#define NUMCROSSMARKLINES (sizeof(cross_mark)/sizeof(mline_t))
|
||||
|
||||
#define R (FRACUNIT)
|
||||
static const mline_t thintriangle_guy[] = {
|
||||
|
@ -206,7 +199,7 @@ static fixed_t scale_ftom;
|
|||
|
||||
static player_t *plr; // the player represented by an arrow
|
||||
|
||||
static INT32 followplayer = true; // specifies whether to follow the player around
|
||||
static boolean followplayer = true; // specifies whether to follow the player around
|
||||
|
||||
// function for drawing lines, depends on rendermode
|
||||
typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color);
|
||||
|
@ -816,17 +809,18 @@ static void AM_drawGrid(INT32 color)
|
|||
fixed_t x, y;
|
||||
fixed_t start, end;
|
||||
mline_t ml;
|
||||
fixed_t gridsize = (MAPBLOCKUNITS<<MAPBITS);
|
||||
|
||||
// Figure out start of vertical gridlines
|
||||
start = m_x;
|
||||
if ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS))
|
||||
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS));
|
||||
if ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize)
|
||||
start += gridsize - ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize);
|
||||
end = m_x + m_w;
|
||||
|
||||
// draw vertical gridlines
|
||||
ml.a.y = m_y;
|
||||
ml.b.y = m_y + m_h;
|
||||
for (x = start; x < end; x += (MAPBLOCKUNITS<<FRACBITS))
|
||||
for (x = start; x < end; x += gridsize)
|
||||
{
|
||||
ml.a.x = x;
|
||||
ml.b.x = x;
|
||||
|
@ -835,14 +829,14 @@ static void AM_drawGrid(INT32 color)
|
|||
|
||||
// Figure out start of horizontal gridlines
|
||||
start = m_y;
|
||||
if ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS))
|
||||
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS));
|
||||
if ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize)
|
||||
start += gridsize - ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize);
|
||||
end = m_y + m_h;
|
||||
|
||||
// draw horizontal gridlines
|
||||
ml.a.x = m_x;
|
||||
ml.b.x = m_x + m_w;
|
||||
for (y = start; y < end; y += (MAPBLOCKUNITS<<FRACBITS))
|
||||
for (y = start; y < end; y += gridsize)
|
||||
{
|
||||
ml.a.y = y;
|
||||
ml.b.y = y;
|
||||
|
@ -1039,7 +1033,7 @@ static inline void AM_drawPlayers(void)
|
|||
|
||||
if (!multiplayer)
|
||||
{
|
||||
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
|
||||
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 16<<FRACBITS, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1047,7 @@ static inline void AM_drawPlayers(void)
|
|||
if (p->skincolor > 0)
|
||||
color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8];
|
||||
|
||||
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, p->mo->angle, color, p->mo->x, p->mo->y);
|
||||
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 16<<FRACBITS, p->mo->angle, color, p->mo->x, p->mo->y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1073,13 +1067,30 @@ static inline void AM_drawThings(UINT8 colors)
|
|||
}
|
||||
}
|
||||
|
||||
/** Draws the crosshair, actually just a dot in software mode.
|
||||
/** Draws the crosshair.
|
||||
*
|
||||
* \param color Color for the crosshair.
|
||||
*/
|
||||
static inline void AM_drawCrosshair(UINT8 color)
|
||||
{
|
||||
V_DrawFill(f_w/2 + f_x, f_h/2 + f_y, 1, 1, color|V_NOSCALESTART);
|
||||
const fixed_t scale = 4<<FRACBITS;
|
||||
size_t i;
|
||||
fline_t fl;
|
||||
|
||||
for (i = 0; i < NUMCROSSMARKLINES; i++)
|
||||
{
|
||||
fl.a.x = FixedMul(cross_mark[i].a.x, scale) >> FRACBITS;
|
||||
fl.a.y = FixedMul(cross_mark[i].a.y, scale) >> FRACBITS;
|
||||
fl.b.x = FixedMul(cross_mark[i].b.x, scale) >> FRACBITS;
|
||||
fl.b.y = FixedMul(cross_mark[i].b.y, scale) >> FRACBITS;
|
||||
|
||||
fl.a.x += f_x + (f_w / 2);
|
||||
fl.a.y += f_y + (f_h / 2);
|
||||
fl.b.x += f_x + (f_w / 2);
|
||||
fl.b.y += f_y + (f_h / 2);
|
||||
|
||||
AM_drawFline(&fl, color);
|
||||
}
|
||||
}
|
||||
|
||||
/** Draws the automap.
|
||||
|
@ -1095,5 +1106,5 @@ void AM_Drawer(void)
|
|||
AM_drawPlayers();
|
||||
AM_drawThings(THINGCOLORS);
|
||||
|
||||
AM_drawCrosshair(XHAIRCOLORS);
|
||||
if (!followplayer) AM_drawCrosshair(XHAIRCOLORS);
|
||||
}
|
||||
|
|
|
@ -26,11 +26,6 @@ typedef struct
|
|||
fpoint_t a, b;
|
||||
} fline_t;
|
||||
|
||||
// Used by ST StatusBar stuff.
|
||||
#define AM_MSGHEADER (('a'<<24)+('m'<<16))
|
||||
#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
|
||||
#define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
|
||||
|
||||
extern boolean am_recalc; // true if screen size changes
|
||||
extern boolean automapactive; // In AutoMap mode?
|
||||
|
||||
|
|
14
src/b_bot.c
14
src/b_bot.c
|
@ -140,6 +140,9 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin)
|
||||
{
|
||||
// don't try to do stuff if your sonic is in a minecart or something
|
||||
if (players[consoleplayer].powers[pw_carry])
|
||||
return;
|
||||
// Turn the virtual keypresses into ticcmd_t.
|
||||
if (twodlevel || mo->flags2 & MF2_TWOD) {
|
||||
if (players[consoleplayer].climbing
|
||||
|
@ -218,7 +221,12 @@ boolean B_CheckRespawn(player_t *player)
|
|||
return false;
|
||||
|
||||
// Low ceiling, do not want!
|
||||
if (sonic->ceilingz - sonic->z < 2*sonic->height)
|
||||
if (sonic->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (sonic->z - sonic->floorz < (sonic->player->exiting ? 5 : 2)*sonic->height)
|
||||
return false;
|
||||
}
|
||||
else if (sonic->ceilingz - sonic->z < (sonic->player->exiting ? 6 : 3)*sonic->height)
|
||||
return false;
|
||||
|
||||
// If you're dead, wait a few seconds to respawn.
|
||||
|
@ -252,11 +260,11 @@ void B_RespawnBot(INT32 playernum)
|
|||
y = sonic->y;
|
||||
if (sonic->eflags & MFE_VERTICALFLIP) {
|
||||
tails->eflags |= MFE_VERTICALFLIP;
|
||||
z = sonic->z - FixedMul(512*FRACUNIT,sonic->scale);
|
||||
z = sonic->z - (512*sonic->scale);
|
||||
if (z < sonic->floorz)
|
||||
z = sonic->floorz;
|
||||
} else {
|
||||
z = sonic->z + sonic->height + FixedMul(512*FRACUNIT,sonic->scale);
|
||||
z = sonic->z + sonic->height + (512*sonic->scale);
|
||||
if (z > sonic->ceilingz - sonic->height)
|
||||
z = sonic->ceilingz - sonic->height;
|
||||
}
|
||||
|
|
252
src/command.c
252
src/command.c
|
@ -49,6 +49,7 @@ static void COM_Exec_f(void);
|
|||
static void COM_Wait_f(void);
|
||||
static void COM_Help_f(void);
|
||||
static void COM_Toggle_f(void);
|
||||
static void COM_Add_f(void);
|
||||
|
||||
static void CV_EnforceExecVersion(void);
|
||||
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
|
||||
|
@ -291,6 +292,7 @@ void COM_Init(void)
|
|||
COM_AddCommand("wait", COM_Wait_f);
|
||||
COM_AddCommand("help", COM_Help_f);
|
||||
COM_AddCommand("toggle", COM_Toggle_f);
|
||||
COM_AddCommand("add", COM_Add_f);
|
||||
RegisterNetXCmd(XD_NETVAR, Got_NetVar);
|
||||
}
|
||||
|
||||
|
@ -709,15 +711,21 @@ static void COM_Help_f(void)
|
|||
|
||||
if (COM_Argc() > 1)
|
||||
{
|
||||
cvar = CV_FindVar(COM_Argv(1));
|
||||
const char *help = COM_Argv(1);
|
||||
cvar = CV_FindVar(help);
|
||||
if (cvar)
|
||||
{
|
||||
CONS_Printf(M_GetText("Variable %s:\n"), cvar->name);
|
||||
boolean floatmode = false;
|
||||
const char *cvalue = NULL;
|
||||
CONS_Printf("\x82""Variable %s:\n", cvar->name);
|
||||
CONS_Printf(M_GetText(" flags :"));
|
||||
if (cvar->flags & CV_SAVE)
|
||||
CONS_Printf("AUTOSAVE ");
|
||||
if (cvar->flags & CV_FLOAT)
|
||||
{
|
||||
CONS_Printf("FLOAT ");
|
||||
floatmode = true;
|
||||
}
|
||||
if (cvar->flags & CV_NETVAR)
|
||||
CONS_Printf("NETVAR ");
|
||||
if (cvar->flags & CV_CALL)
|
||||
|
@ -727,59 +735,113 @@ static void COM_Help_f(void)
|
|||
CONS_Printf("\n");
|
||||
if (cvar->PossibleValue)
|
||||
{
|
||||
if (stricmp(cvar->PossibleValue[0].strvalue, "MIN") == 0)
|
||||
{
|
||||
for (i = 1; cvar->PossibleValue[i].strvalue != NULL; i++)
|
||||
if (!stricmp(cvar->PossibleValue[i].strvalue, "MAX"))
|
||||
break;
|
||||
CONS_Printf(M_GetText(" range from %d to %d\n"), cvar->PossibleValue[0].value,
|
||||
cvar->PossibleValue[i].value);
|
||||
CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value);
|
||||
}
|
||||
CONS_Printf(" Possible values:\n");
|
||||
if (cvar->PossibleValue == CV_YesNo)
|
||||
CONS_Printf(" Yes or No (On or Off, 1 or 0)\n");
|
||||
else if (cvar->PossibleValue == CV_OnOff)
|
||||
CONS_Printf(" On or Off (Yes or No, 1 or 0)\n");
|
||||
else
|
||||
{
|
||||
const char *cvalue = NULL;
|
||||
CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name);
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
if (!stricmp(cvar->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
if (floatmode)
|
||||
CONS_Printf(" range from %f to %f\n", FIXED_TO_FLOAT(cvar->PossibleValue[MINVAL].value),
|
||||
FIXED_TO_FLOAT(cvar->PossibleValue[MAXVAL].value));
|
||||
else
|
||||
CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[MINVAL].value,
|
||||
cvar->PossibleValue[MAXVAL].value);
|
||||
i = MAXVAL+1;
|
||||
}
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
|
||||
//CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name);
|
||||
while (cvar->PossibleValue[i].strvalue)
|
||||
{
|
||||
if (floatmode)
|
||||
CONS_Printf(" %-2f : %s\n", FIXED_TO_FLOAT(cvar->PossibleValue[i].value),
|
||||
cvar->PossibleValue[i].strvalue);
|
||||
else
|
||||
CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value,
|
||||
cvar->PossibleValue[i].strvalue);
|
||||
if (cvar->PossibleValue[i].value == cvar->value)
|
||||
cvalue = cvar->PossibleValue[i].strvalue;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cvalue)
|
||||
CONS_Printf(M_GetText(" Current value: %s\n"), cvalue);
|
||||
CONS_Printf(" Current value: %s\n", cvalue);
|
||||
else if (cvar->string)
|
||||
CONS_Printf(" Current value: %s\n", cvar->string);
|
||||
else
|
||||
CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value);
|
||||
}
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value);
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("No help for this command/variable\n"));
|
||||
CONS_Printf(" Current value: %d\n", cvar->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (cmd = com_commands; cmd; cmd = cmd->next)
|
||||
{
|
||||
if (strcmp(cmd->name, help))
|
||||
continue;
|
||||
|
||||
CONS_Printf("\x82""Command %s:\n", cmd->name);
|
||||
CONS_Printf(" help is not available for commands");
|
||||
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or try typing <name> without arguments\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CONS_Printf("No exact match, searching...\n");
|
||||
|
||||
// variables
|
||||
CONS_Printf("\x82""Variables:\n");
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if ((cvar->flags & CV_NOSHOWHELP) || (!strstr(cvar->name, help)))
|
||||
continue;
|
||||
CONS_Printf("%s ", cvar->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
// commands
|
||||
CONS_Printf("\x82%s", M_GetText("Commands\n"));
|
||||
CONS_Printf("\x82""\nCommands:\n");
|
||||
for (cmd = com_commands; cmd; cmd = cmd->next)
|
||||
{
|
||||
if (!strstr(cmd->name, help))
|
||||
continue;
|
||||
CONS_Printf("%s ",cmd->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help <command or variable>\n");
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "\x87Total : %d\n", i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// variables
|
||||
CONS_Printf("\x82""Variables:\n");
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if (cvar->flags & CV_NOSHOWHELP)
|
||||
continue;
|
||||
CONS_Printf("%s ", cvar->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
// commands
|
||||
CONS_Printf("\x82""\nCommands:\n");
|
||||
for (cmd = com_commands; cmd; cmd = cmd->next)
|
||||
{
|
||||
CONS_Printf("%s ",cmd->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
// variables
|
||||
CONS_Printf("\n\x82%s", M_GetText("Variables\n"));
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if (!(cvar->flags & CV_NOSHOWHELP))
|
||||
CONS_Printf("%s ", cvar->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
CONS_Printf("\n\x82%s", M_GetText("Read help file for more or type help <command or variable>\n"));
|
||||
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help <command or variable>\n");
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "\x82Total : %d\n", i);
|
||||
}
|
||||
|
@ -816,6 +878,30 @@ static void COM_Toggle_f(void)
|
|||
CV_AddValue(cvar, +1);
|
||||
}
|
||||
|
||||
/** Command variant of CV_AddValue
|
||||
*/
|
||||
static void COM_Add_f(void)
|
||||
{
|
||||
consvar_t *cvar;
|
||||
|
||||
if (COM_Argc() != 3)
|
||||
{
|
||||
CONS_Printf(M_GetText("Add <cvar_name> <value>: Add to the value of a cvar. Negative values work too!\n"));
|
||||
return;
|
||||
}
|
||||
cvar = CV_FindVar(COM_Argv(1));
|
||||
if (!cvar)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("%s is not a cvar\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (( cvar->flags & CV_FLOAT ))
|
||||
CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2))));
|
||||
else
|
||||
CV_AddValue(cvar, atoi(COM_Argv(2)));
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// VARIABLE SIZE BUFFERS
|
||||
// =========================================================================
|
||||
|
@ -1123,32 +1209,42 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
|
||||
if (var->PossibleValue[0].strvalue && !stricmp(var->PossibleValue[0].strvalue, "MIN")) // bounded cvar
|
||||
{
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
INT32 i;
|
||||
// search for maximum
|
||||
for (i = 1; var->PossibleValue[i].strvalue; i++)
|
||||
if (!stricmp(var->PossibleValue[i].strvalue, "MAX"))
|
||||
break;
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[i].strvalue)
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
I_Error("Bounded cvar \"%s\" without maximum!\n", var->name);
|
||||
#endif
|
||||
|
||||
if ((v != INT32_MIN && v < var->PossibleValue[0].value) || !stricmp(valstr, "MIN"))
|
||||
// search for other
|
||||
for (i = MAXVAL+1; var->PossibleValue[i].strvalue; i++)
|
||||
if (v == var->PossibleValue[i].value || !stricmp(var->PossibleValue[i].strvalue, valstr))
|
||||
{
|
||||
v = var->PossibleValue[0].value;
|
||||
valstr = var->PossibleValue[0].strvalue;
|
||||
var->value = var->PossibleValue[i].value;
|
||||
var->string = var->PossibleValue[i].strvalue;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
if ((v != INT32_MIN && v < var->PossibleValue[MINVAL].value) || !stricmp(valstr, "MIN"))
|
||||
{
|
||||
v = var->PossibleValue[MINVAL].value;
|
||||
valstr = var->PossibleValue[MINVAL].strvalue;
|
||||
override = true;
|
||||
overrideval = v;
|
||||
}
|
||||
else if ((v != INT32_MIN && v > var->PossibleValue[i].value) || !stricmp(valstr, "MAX"))
|
||||
else if ((v != INT32_MIN && v > var->PossibleValue[MAXVAL].value) || !stricmp(valstr, "MAX"))
|
||||
{
|
||||
v = var->PossibleValue[i].value;
|
||||
valstr = var->PossibleValue[i].strvalue;
|
||||
v = var->PossibleValue[MAXVAL].value;
|
||||
valstr = var->PossibleValue[MAXVAL].strvalue;
|
||||
override = true;
|
||||
overrideval = v;
|
||||
}
|
||||
if (v == INT32_MIN)
|
||||
goto badinput;
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1515,6 +1611,9 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
{
|
||||
INT32 newvalue, max;
|
||||
|
||||
if (!increment)
|
||||
return;
|
||||
|
||||
// count pointlimit better
|
||||
if (var == &cv_pointlimit && (gametype == GT_MATCH))
|
||||
increment *= 50;
|
||||
|
@ -1538,13 +1637,11 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
|
||||
if (var->PossibleValue)
|
||||
{
|
||||
#define MINVAL 0
|
||||
if (var == &cv_nextmap)
|
||||
{
|
||||
// Special case for the nextmap variable, used only directly from the menu
|
||||
INT32 oldvalue = var->value - 1, gt;
|
||||
gt = cv_newgametype.value;
|
||||
if (increment != 0) // Going up!
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
|
@ -1575,21 +1672,58 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
else if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
// search the next to last
|
||||
for (max = 0; var->PossibleValue[max+1].strvalue; max++)
|
||||
;
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
I_Error("Bounded cvar \"%s\" without maximum!\n", var->name);
|
||||
#endif
|
||||
|
||||
if (newvalue < var->PossibleValue[MINVAL].value) // add the max+1
|
||||
newvalue += var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1;
|
||||
|
||||
newvalue = var->PossibleValue[MINVAL].value + (newvalue - var->PossibleValue[MINVAL].value)
|
||||
% (var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1);
|
||||
|
||||
CV_SetValue(var, newvalue);
|
||||
#undef MINVAL
|
||||
if (newvalue < var->PossibleValue[MINVAL].value || newvalue > var->PossibleValue[MAXVAL].value)
|
||||
{
|
||||
INT32 currentindice = -1, newindice;
|
||||
for (max = MAXVAL+1; var->PossibleValue[max].strvalue; max++)
|
||||
{
|
||||
if (var->PossibleValue[max].value == newvalue)
|
||||
{
|
||||
increment = 0;
|
||||
currentindice = max;
|
||||
}
|
||||
else if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
}
|
||||
|
||||
if (increment)
|
||||
{
|
||||
increment = (increment > 0) ? 1 : -1;
|
||||
if (currentindice == -1 && max != MAXVAL+1)
|
||||
newindice = ((increment > 0) ? MAXVAL : max) + increment;
|
||||
else
|
||||
newindice = currentindice + increment;
|
||||
|
||||
if (newindice >= max || newindice <= MAXVAL)
|
||||
{
|
||||
if (var == &cv_pointlimit && (gametype == GT_MATCH) && increment > 0)
|
||||
CV_SetValue(var, 50);
|
||||
else
|
||||
{
|
||||
newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value;
|
||||
CV_SetValue(var, newvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Set(var, var->PossibleValue[newindice].strvalue);
|
||||
}
|
||||
else
|
||||
CV_Set(var, var->PossibleValue[currentindice].strvalue);
|
||||
}
|
||||
else
|
||||
CV_SetValue(var, newvalue);
|
||||
}
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
else
|
||||
{
|
||||
INT32 currentindice = -1, newindice;
|
||||
|
@ -1599,8 +1733,6 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
|
||||
max--;
|
||||
|
||||
if (var == &cv_chooseskin)
|
||||
{
|
||||
// Special case for the chooseskin variable, used only directly from the menu
|
||||
|
@ -1632,7 +1764,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
var->value);
|
||||
#endif
|
||||
|
||||
newindice = (currentindice + increment + max + 1) % (max+1);
|
||||
newindice = (currentindice + increment + max) % max;
|
||||
CV_Set(var, var->PossibleValue[newindice].strvalue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#define ASSET_HASH_SRB2_PK3 "${SRB2_ASSET_srb2.pk3_HASH}"
|
||||
#define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}"
|
||||
#define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}"
|
||||
#define ASSET_HASH_ZONES_PK3 "${SRB2_ASSET_zones.pk3_HASH}"
|
||||
#ifdef USE_PATCH_DTA
|
||||
#define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}"
|
||||
#endif
|
||||
|
@ -30,7 +30,7 @@
|
|||
* Last updated 2018 / ?? / ?? - v2.2 - patch.pk3
|
||||
*/
|
||||
#define ASSET_HASH_SRB2_PK3 "c1b9577687f8a795104aef4600720ea7"
|
||||
#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60"
|
||||
#define ASSET_HASH_ZONES_PK3 "303838c6c534d9540288360fa49cca60"
|
||||
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
|
||||
#ifdef USE_PATCH_DTA
|
||||
#define ASSET_HASH_PATCH_PK3 "dbbf8bc6121618ee3be2d5b14650429b"
|
||||
|
|
|
@ -175,11 +175,11 @@ static void CONS_Clear_f(void)
|
|||
|
||||
// Choose english keymap
|
||||
//
|
||||
static void CONS_English_f(void)
|
||||
/*static void CONS_English_f(void)
|
||||
{
|
||||
shiftxform = english_shiftxform;
|
||||
CONS_Printf(M_GetText("%s keymap.\n"), M_GetText("English"));
|
||||
}
|
||||
}*/
|
||||
|
||||
static char *bindtable[NUMINPUTS];
|
||||
|
||||
|
@ -394,7 +394,7 @@ void CON_Init(void)
|
|||
// register our commands
|
||||
//
|
||||
COM_AddCommand("cls", CONS_Clear_f);
|
||||
COM_AddCommand("english", CONS_English_f);
|
||||
//COM_AddCommand("english", CONS_English_f);
|
||||
// set console full screen for game startup MAKE SURE VID_Init() done !!!
|
||||
con_destlines = vid.height;
|
||||
con_curlines = vid.height;
|
||||
|
|
126
src/d_clisrv.c
126
src/d_clisrv.c
|
@ -83,11 +83,9 @@ tic_t jointimeout = (10*TICRATE);
|
|||
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
|
||||
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
|
||||
|
||||
#ifdef NEWPING
|
||||
UINT16 pingmeasurecount = 1;
|
||||
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
|
||||
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
|
||||
#endif
|
||||
SINT8 nodetoplayer[MAXNETNODES];
|
||||
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
|
||||
UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen
|
||||
|
@ -621,6 +619,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->friction = LONG(players[i].mo->friction);
|
||||
rsp->movefactor = LONG(players[i].mo->movefactor);
|
||||
|
||||
rsp->sprite = (spritenum_t)LONG(players[i].mo->sprite);
|
||||
rsp->frame = LONG(players[i].mo->frame);
|
||||
rsp->sprite2 = players[i].mo->sprite2;
|
||||
rsp->anim_duration = SHORT(players[i].mo->anim_duration);
|
||||
rsp->tics = LONG(players[i].mo->tics);
|
||||
rsp->statenum = (statenum_t)LONG(players[i].mo->state-states); // :(
|
||||
rsp->eflags = (UINT16)SHORT(players[i].mo->eflags);
|
||||
|
@ -767,8 +769,17 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].mo->momy = LONG(rsp->momy);
|
||||
players[i].mo->momz = LONG(rsp->momz);
|
||||
players[i].mo->movefactor = LONG(rsp->movefactor);
|
||||
|
||||
// Don't use P_SetMobjStateNF to restore state, write/read all the values manually!
|
||||
// This should stop those stupid console errors, hopefully.
|
||||
// -- Monster Iestyn
|
||||
players[i].mo->sprite = (spritenum_t)LONG(rsp->sprite);
|
||||
players[i].mo->frame = LONG(rsp->frame);
|
||||
players[i].mo->sprite2 = rsp->sprite2;
|
||||
players[i].mo->anim_duration = SHORT(rsp->anim_duration);
|
||||
players[i].mo->tics = LONG(rsp->tics);
|
||||
P_SetMobjStateNF(players[i].mo, LONG(rsp->statenum));
|
||||
players[i].mo->state = &states[LONG(rsp->statenum)];
|
||||
|
||||
players[i].mo->x = LONG(rsp->x);
|
||||
players[i].mo->y = LONG(rsp->y);
|
||||
players[i].mo->z = LONG(rsp->z);
|
||||
|
@ -1253,7 +1264,8 @@ static boolean CL_SendJoin(void)
|
|||
netbuffer->u.clientcfg.localplayers = localplayers;
|
||||
netbuffer->u.clientcfg.version = VERSION;
|
||||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
|
||||
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
|
||||
strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME);
|
||||
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
||||
|
@ -1312,33 +1324,13 @@ static void SV_SendPlayerInfo(INT32 node)
|
|||
continue;
|
||||
}
|
||||
|
||||
netbuffer->u.playerinfo[i].node = (UINT8)playernode[i];
|
||||
netbuffer->u.playerinfo[i].node = i;
|
||||
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
|
||||
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
//fetch IP address
|
||||
{
|
||||
const char *claddress;
|
||||
UINT32 numericaddress[4];
|
||||
|
||||
//No, don't do that, you fuckface.
|
||||
memset(netbuffer->u.playerinfo[i].address, 0, 4);
|
||||
if (playernode[i] == 0)
|
||||
{
|
||||
//127.0.0.1
|
||||
netbuffer->u.playerinfo[i].address[0] = 127;
|
||||
netbuffer->u.playerinfo[i].address[3] = 1;
|
||||
}
|
||||
else if (playernode[i] > 0 && I_GetNodeAddress && (claddress = I_GetNodeAddress(playernode[i])) != NULL)
|
||||
{
|
||||
if (sscanf(claddress, "%d.%d.%d.%d", &numericaddress[0], &numericaddress[1], &numericaddress[2], &numericaddress[3]) < 4)
|
||||
goto badaddress;
|
||||
netbuffer->u.playerinfo[i].address[0] = (UINT8)numericaddress[0];
|
||||
netbuffer->u.playerinfo[i].address[1] = (UINT8)numericaddress[1];
|
||||
netbuffer->u.playerinfo[i].address[2] = (UINT8)numericaddress[2];
|
||||
netbuffer->u.playerinfo[i].address[3] = (UINT8)numericaddress[3];
|
||||
}
|
||||
}
|
||||
badaddress:
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
|
@ -2417,7 +2409,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
// the remaining players.
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
{
|
||||
INT32 i, count, increment, spheres;
|
||||
INT32 i, count, sincrement, spheres, rincrement, rings;
|
||||
|
||||
for (i = 0, count = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -2427,18 +2419,35 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
|
||||
count--;
|
||||
spheres = players[playernum].spheres;
|
||||
increment = spheres/count;
|
||||
rings = players[playernum].rings;
|
||||
sincrement = spheres/count;
|
||||
rincrement = rings/count;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && i != playernum)
|
||||
{
|
||||
if (spheres < increment)
|
||||
if (spheres < 2*sincrement)
|
||||
{
|
||||
P_GivePlayerSpheres(&players[i], spheres);
|
||||
spheres = 0;
|
||||
}
|
||||
else
|
||||
P_GivePlayerSpheres(&players[i], increment);
|
||||
{
|
||||
P_GivePlayerSpheres(&players[i], sincrement);
|
||||
spheres -= sincrement;
|
||||
}
|
||||
|
||||
spheres -= increment;
|
||||
if (rings < 2*rincrement)
|
||||
{
|
||||
P_GivePlayerRings(&players[i], rings);
|
||||
rings = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
P_GivePlayerRings(&players[i], rincrement);
|
||||
rings -= rincrement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2853,12 +2862,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
#ifdef NEWPING
|
||||
case KICK_MSG_PING_HIGH:
|
||||
HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false);
|
||||
kickreason = KR_PINGLIMIT;
|
||||
break;
|
||||
#endif
|
||||
case KICK_MSG_CON_FAIL:
|
||||
HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false);
|
||||
kickreason = KR_SYNCH;
|
||||
|
@ -2931,10 +2938,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
D_StartTitle();
|
||||
if (msg == KICK_MSG_CON_FAIL)
|
||||
M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
#ifdef NEWPING
|
||||
else if (msg == KICK_MSG_PING_HIGH)
|
||||
M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
#endif
|
||||
else if (msg == KICK_MSG_BANNED)
|
||||
M_StartMessage(M_GetText("You have been banned by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
else if (msg == KICK_MSG_CUSTOM_KICK)
|
||||
|
@ -2952,7 +2957,7 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, N
|
|||
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}};
|
||||
consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
||||
|
@ -3182,6 +3187,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
if (!splitscreen && !botingame)
|
||||
CL_ClearPlayer(newplayernum);
|
||||
playeringame[newplayernum] = true;
|
||||
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
||||
G_AddPlayer(newplayernum);
|
||||
if (newplayernum+1 > doomcom->numslots)
|
||||
doomcom->numslots = (INT16)(newplayernum+1);
|
||||
|
@ -3214,10 +3220,10 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
const char *address;
|
||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
|
||||
HU_AddChatText(va("\x82*Player %d has joined the game (node %d) (%s)", newplayernum+1, node, address), false); // merge join notification + IP to avoid clogging console/chat.
|
||||
HU_AddChatText(va("\x82*%s has joined the game (node %d) (%s)", player_names[newplayernum], node, address), false); // merge join notification + IP to avoid clogging console/chat.
|
||||
}
|
||||
else
|
||||
HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false); // if you don't wanna see the join address.
|
||||
HU_AddChatText(va("\x82*%s has joined the game (node %d)", player_names[newplayernum], node), false); // if you don't wanna see the join address.
|
||||
}
|
||||
|
||||
if (server && multiplayer && motd[0] != '\0')
|
||||
|
@ -3228,10 +3234,11 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
#endif
|
||||
}
|
||||
|
||||
static boolean SV_AddWaitingPlayers(void)
|
||||
static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
||||
{
|
||||
INT32 node, n, newplayer = false;
|
||||
UINT8 buf[2];
|
||||
UINT8 buf[2 + MAXPLAYERNAME];
|
||||
UINT8 *p;
|
||||
UINT8 newplayernum = 0;
|
||||
|
||||
// What is the reason for this? Why can't newplayernum always be 0?
|
||||
|
@ -3314,18 +3321,23 @@ static boolean SV_AddWaitingPlayers(void)
|
|||
|
||||
playernode[newplayernum] = (UINT8)node;
|
||||
|
||||
p = buf + 2;
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = newplayernum;
|
||||
if (playerpernode[node] < 1)
|
||||
{
|
||||
nodetoplayer[node] = newplayernum;
|
||||
WRITESTRINGN(p, name, MAXPLAYERNAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodetoplayer2[node] = newplayernum;
|
||||
buf[1] |= 0x80;
|
||||
WRITESTRINGN(p, name2, MAXPLAYERNAME);
|
||||
}
|
||||
playerpernode[node]++;
|
||||
|
||||
SendNetXCmd(XD_ADDPLAYER, &buf, 2);
|
||||
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
||||
|
||||
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
|
@ -3387,7 +3399,7 @@ boolean SV_SpawnServer(void)
|
|||
else doomcom->numslots = 1;
|
||||
}
|
||||
|
||||
return SV_AddWaitingPlayers();
|
||||
return SV_AddWaitingPlayers(cv_playername.zstring, cv_playername2.zstring);
|
||||
}
|
||||
|
||||
void SV_StopServer(void)
|
||||
|
@ -3458,6 +3470,9 @@ static size_t TotalTextCmdPerTic(tic_t tic)
|
|||
*/
|
||||
static void HandleConnect(SINT8 node)
|
||||
{
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||
INT32 i;
|
||||
|
||||
if (bannednode && bannednode[node])
|
||||
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server"));
|
||||
else if (netbuffer->u.clientcfg.version != VERSION
|
||||
|
@ -3477,6 +3492,16 @@ static void HandleConnect(SINT8 node)
|
|||
boolean newnode = false;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
||||
{
|
||||
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
||||
if (!EnsurePlayerNameIsGood(names[i], -1))
|
||||
{
|
||||
SV_SendRefuse(node, "Bad player name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// client authorised to join
|
||||
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
|
||||
if (!nodeingame[node])
|
||||
|
@ -3517,7 +3542,7 @@ static void HandleConnect(SINT8 node)
|
|||
SV_SendSaveGame(node); // send a complete game state
|
||||
DEBFILE("send savegame\n");
|
||||
}
|
||||
SV_AddWaitingPlayers();
|
||||
SV_AddWaitingPlayers(names[0], names[1]);
|
||||
player_joining = true;
|
||||
}
|
||||
#else
|
||||
|
@ -3824,7 +3849,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
break;
|
||||
|
||||
// Ignore tics from those not synched
|
||||
if (resynch_inprogress[node])
|
||||
if (resynch_inprogress[node] && nettics[node] == gametic)
|
||||
break;
|
||||
|
||||
// To save bytes, only the low byte of tic numbers are sent
|
||||
|
@ -4158,7 +4183,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
resynch_local_inprogress = true;
|
||||
CL_AcknowledgeResynch(&netbuffer->u.resynchpak);
|
||||
break;
|
||||
#ifdef NEWPING
|
||||
case PT_PING:
|
||||
// Only accept PT_PING from the server.
|
||||
if (node != servernode)
|
||||
|
@ -4186,7 +4210,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
case PT_SERVERCFG:
|
||||
break;
|
||||
case PT_FILEFRAGMENT:
|
||||
|
@ -4682,7 +4705,7 @@ void TryRunTics(tic_t realtics)
|
|||
if (player_joining)
|
||||
return;
|
||||
|
||||
if (neededtic > gametic)
|
||||
if (neededtic > gametic && !resynch_local_inprogress)
|
||||
{
|
||||
if (advancedemo)
|
||||
D_StartTitle();
|
||||
|
@ -4700,7 +4723,6 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NEWPING
|
||||
static inline void PingUpdate(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -4758,7 +4780,6 @@ static inline void PingUpdate(void)
|
|||
|
||||
pingmeasurecount = 1; //Reset count
|
||||
}
|
||||
#endif
|
||||
|
||||
void NetUpdate(void)
|
||||
{
|
||||
|
@ -4783,7 +4804,6 @@ void NetUpdate(void)
|
|||
|
||||
gametime = nowtime;
|
||||
|
||||
#ifdef NEWPING
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 255))
|
||||
|
@ -4794,7 +4814,6 @@ void NetUpdate(void)
|
|||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (client)
|
||||
maketic = neededtic;
|
||||
|
@ -4835,10 +4854,15 @@ void NetUpdate(void)
|
|||
|
||||
for (i = 0; i < MAXNETNODES; ++i)
|
||||
if (resynch_inprogress[i])
|
||||
{
|
||||
if (!nodeingame[i] || nettics[i] == gametic)
|
||||
{
|
||||
SV_SendResynch(i);
|
||||
counts = -666;
|
||||
}
|
||||
else
|
||||
counts = 0; // Let the client catch up with the server
|
||||
}
|
||||
|
||||
// Do not make tics while resynching
|
||||
if (counts != -666)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "d_ticcmd.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
|
||||
|
@ -73,9 +74,7 @@ typedef enum
|
|||
|
||||
PT_LOGIN, // Login attempt from the client.
|
||||
|
||||
#ifdef NEWPING
|
||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||
#endif
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
|
@ -265,6 +264,10 @@ typedef struct
|
|||
fixed_t friction;
|
||||
fixed_t movefactor;
|
||||
|
||||
spritenum_t sprite;
|
||||
UINT32 frame;
|
||||
UINT8 sprite2;
|
||||
UINT16 anim_duration;
|
||||
INT32 tics;
|
||||
statenum_t statenum;
|
||||
UINT32 flags;
|
||||
|
@ -322,6 +325,7 @@ typedef struct
|
|||
UINT8 subversion; // Contains build version
|
||||
UINT8 localplayers;
|
||||
UINT8 mode;
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
|
@ -421,9 +425,7 @@ typedef struct
|
|||
msaskinfo_pak msaskinfo; // 22 bytes
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE)
|
||||
#ifdef NEWPING
|
||||
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
|
||||
#endif
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
||||
|
@ -457,9 +459,7 @@ extern consvar_t cv_playbackspeed;
|
|||
#define KICK_MSG_PLAYER_QUIT 3
|
||||
#define KICK_MSG_TIMEOUT 4
|
||||
#define KICK_MSG_BANNED 5
|
||||
#ifdef NEWPING
|
||||
#define KICK_MSG_PING_HIGH 6
|
||||
#endif
|
||||
#define KICK_MSG_CUSTOM_KICK 7
|
||||
#define KICK_MSG_CUSTOM_BAN 8
|
||||
|
||||
|
@ -484,11 +484,9 @@ extern SINT8 servernode;
|
|||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
extern tic_t jointimeout;
|
||||
#ifdef NEWPING
|
||||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
|
|
39
src/d_main.c
39
src/d_main.c
|
@ -129,6 +129,7 @@ char srb2home[256] = ".";
|
|||
char srb2path[256] = ".";
|
||||
boolean usehome = true;
|
||||
const char *pandf = "%s" PATHSEP "%s";
|
||||
static char addonsdir[MAX_WADPATH];
|
||||
|
||||
//
|
||||
// EVENT HANDLING
|
||||
|
@ -358,7 +359,7 @@ static void D_Display(void)
|
|||
|
||||
// clean up border stuff
|
||||
// see if the border needs to be initially drawn
|
||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide))
|
||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
|
||||
{
|
||||
// draw the view directly
|
||||
|
||||
|
@ -716,6 +717,7 @@ void D_StartTitle(void)
|
|||
botskin = 0;
|
||||
cv_debug = 0;
|
||||
emeralds = 0;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
lastmaploaded = 0;
|
||||
|
||||
// In case someone exits out at the same time they start a time attack run,
|
||||
|
@ -850,7 +852,7 @@ static void IdentifyVersion(void)
|
|||
// checking in D_SRB2Main
|
||||
|
||||
// Add the maps
|
||||
D_AddFile(va(pandf,srb2waddir,"zones.dta"));
|
||||
D_AddFile(va(pandf,srb2waddir,"zones.pk3"));
|
||||
|
||||
// Add the players
|
||||
D_AddFile(va(pandf,srb2waddir, "player.dta"));
|
||||
|
@ -1038,7 +1040,6 @@ void D_SRB2Main(void)
|
|||
// can't use sprintf since there is %u in savegamename
|
||||
strcatbf(savegamename, srb2home, PATHSEP);
|
||||
|
||||
I_mkdir(srb2home, 0700);
|
||||
#else
|
||||
snprintf(srb2home, sizeof srb2home, "%s", userhome);
|
||||
snprintf(downloaddir, sizeof downloaddir, "%s", userhome);
|
||||
|
@ -1055,6 +1056,10 @@ void D_SRB2Main(void)
|
|||
configfile[sizeof configfile - 1] = '\0';
|
||||
}
|
||||
|
||||
// Create addons dir
|
||||
snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons");
|
||||
I_mkdir(addonsdir, 0755);
|
||||
|
||||
// rand() needs seeded regardless of password
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
|
@ -1140,10 +1145,10 @@ void D_SRB2Main(void)
|
|||
|
||||
// Check MD5s of autoloaded files
|
||||
W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_PK3); // srb2.pk3
|
||||
W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_DTA); // zones.dta
|
||||
W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_PK3); // zones.pk3
|
||||
W_VerifyFileMD5(mainwads++, ASSET_HASH_PLAYER_DTA); // player.dta
|
||||
#ifdef USE_PATCH_DTA
|
||||
W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.dta
|
||||
W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.pk3
|
||||
#endif
|
||||
// don't check music.dta because people like to modify it, and it doesn't matter if they do
|
||||
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
||||
|
@ -1152,7 +1157,7 @@ void D_SRB2Main(void)
|
|||
#else
|
||||
|
||||
mainwads++; // srb2.pk3
|
||||
mainwads++; // zones.dta
|
||||
mainwads++; // zones.pk3
|
||||
mainwads++; // player.dta
|
||||
#ifdef USE_PATCH_DTA
|
||||
mainwads++; // patch.dta
|
||||
|
@ -1239,14 +1244,21 @@ void D_SRB2Main(void)
|
|||
sound_disabled = true;
|
||||
midi_disabled = digital_disabled = true;
|
||||
}
|
||||
if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic
|
||||
{
|
||||
sound_disabled = true;
|
||||
digital_disabled = true;
|
||||
midi_disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
|
||||
}
|
||||
if (M_CheckParm("-nosound"))
|
||||
sound_disabled = true;
|
||||
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
|
||||
midi_disabled = digital_disabled = true;
|
||||
{
|
||||
digital_disabled = true;
|
||||
midi_disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (M_CheckParm("-nomidimusic"))
|
||||
|
@ -1254,9 +1266,18 @@ void D_SRB2Main(void)
|
|||
if (M_CheckParm("-nodigmusic"))
|
||||
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||
}
|
||||
}
|
||||
if (!( sound_disabled && digital_disabled
|
||||
#ifndef NO_MIDI
|
||||
&& midi_disabled
|
||||
#endif
|
||||
))
|
||||
{
|
||||
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
S_InitSfxChannels(cv_soundvolume.value);
|
||||
}
|
||||
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
|
121
src/d_net.c
121
src/d_net.c
|
@ -185,22 +185,10 @@ typedef struct
|
|||
UINT8 nextacknum;
|
||||
|
||||
UINT8 flags;
|
||||
#ifndef NEWPING
|
||||
// jacobson tcp timeout evaluation algorithm (Karn variation)
|
||||
fixed_t ping;
|
||||
fixed_t varping;
|
||||
INT32 timeout; // computed with ping and varping
|
||||
#endif
|
||||
} node_t;
|
||||
|
||||
static node_t nodes[MAXNETNODES];
|
||||
#ifndef NEWPING
|
||||
#define PINGDEFAULT ((200*TICRATE*FRACUNIT)/1000)
|
||||
#define VARPINGDEFAULT ((50*TICRATE*FRACUNIT)/1000)
|
||||
#define TIMEOUT(p,v) (p+4*v+FRACUNIT/2)>>FRACBITS;
|
||||
#else
|
||||
#define NODETIMEOUT 14 //What the above boiled down to...
|
||||
#endif
|
||||
#define NODETIMEOUT 14
|
||||
|
||||
#ifndef NONET
|
||||
// return <0 if a < b (mod 256)
|
||||
|
@ -320,19 +308,7 @@ static UINT8 GetAcktosend(INT32 node)
|
|||
static void RemoveAck(INT32 i)
|
||||
{
|
||||
INT32 node = ackpak[i].destinationnode;
|
||||
#ifndef NEWPING
|
||||
fixed_t trueping = (I_GetTime() - ackpak[i].senttime)<<FRACBITS;
|
||||
if (ackpak[i].resentnum)
|
||||
{
|
||||
// +FRACUNIT/2 for round
|
||||
nodes[node].ping = (nodes[node].ping*7 + trueping)/8;
|
||||
nodes[node].varping = (nodes[node].varping*7 + abs(nodes[node].ping-trueping))/8;
|
||||
nodes[node].timeout = TIMEOUT(nodes[node].ping,nodes[node].varping);
|
||||
}
|
||||
DEBFILE(va("Remove ack %d trueping %d ping %f var %f timeout %d\n",ackpak[i].acknum,trueping>>FRACBITS,(double)FIXED_TO_FLOAT(nodes[node].ping),(double)FIXED_TO_FLOAT(nodes[node].varping),nodes[node].timeout));
|
||||
#else
|
||||
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
|
||||
#endif
|
||||
ackpak[i].acknum = 0;
|
||||
if (nodes[node].flags & NF_CLOSE)
|
||||
Net_CloseConnection(node);
|
||||
|
@ -519,11 +495,7 @@ void Net_AckTicker(void)
|
|||
{
|
||||
const INT32 nodei = ackpak[i].destinationnode;
|
||||
node_t *node = &nodes[nodei];
|
||||
#ifdef NEWPING
|
||||
if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
|
||||
#else
|
||||
if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime())
|
||||
#endif
|
||||
{
|
||||
if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE))
|
||||
{
|
||||
|
@ -534,13 +506,8 @@ void Net_AckTicker(void)
|
|||
ackpak[i].acknum = 0;
|
||||
continue;
|
||||
}
|
||||
#ifdef NEWPING
|
||||
DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
|
||||
NODETIMEOUT, I_GetTime()));
|
||||
#else
|
||||
DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
|
||||
node->timeout, I_GetTime()));
|
||||
#endif
|
||||
M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length);
|
||||
ackpak[i].senttime = I_GetTime();
|
||||
ackpak[i].resentnum++;
|
||||
|
@ -658,11 +625,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
|
|||
static void InitNode(node_t *node)
|
||||
{
|
||||
node->acktosend_head = node->acktosend_tail = 0;
|
||||
#ifndef NEWPING
|
||||
node->ping = PINGDEFAULT;
|
||||
node->varping = VARPINGDEFAULT;
|
||||
node->timeout = TIMEOUT(node->ping, node->varping);
|
||||
#endif
|
||||
node->firstacktosend = 0;
|
||||
node->nextacknum = 1;
|
||||
node->remotefirstack = 0;
|
||||
|
@ -843,9 +805,7 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"CLIENTJOIN",
|
||||
"NODETIMEOUT",
|
||||
"RESYNCHING",
|
||||
#ifdef NEWPING
|
||||
"PING"
|
||||
#endif
|
||||
};
|
||||
|
||||
static void DebugPrintpacket(const char *header)
|
||||
|
@ -1384,30 +1344,73 @@ boolean D_CheckNetGame(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct pingcell
|
||||
{
|
||||
INT32 num;
|
||||
INT32 ms;
|
||||
};
|
||||
|
||||
static int pingcellcmp(const void *va, const void *vb)
|
||||
{
|
||||
const struct pingcell *a, *b;
|
||||
a = va;
|
||||
b = vb;
|
||||
return ( a->ms - b->ms );
|
||||
}
|
||||
|
||||
/*
|
||||
New ping command formatted nicely to present ping in
|
||||
ascending order. And with equally spaced columns.
|
||||
The caller's ping is presented at the bottom too, for
|
||||
convenience.
|
||||
*/
|
||||
|
||||
void Command_Ping_f(void)
|
||||
{
|
||||
#ifndef NEWPING
|
||||
if(server)
|
||||
{
|
||||
#endif
|
||||
struct pingcell pingv[MAXPLAYERS];
|
||||
INT32 pingc;
|
||||
|
||||
int name_width = 0;
|
||||
int ms_width = 0;
|
||||
|
||||
int n;
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXPLAYERS;i++)
|
||||
|
||||
pingc = 0;
|
||||
for (i = 1; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i])
|
||||
{
|
||||
#ifndef NEWPING
|
||||
const INT32 node = playernode[i];
|
||||
if (playeringame[i] && node != 0)
|
||||
CONS_Printf(M_GetText("%.2d : %s\n %d tics, %d ms.\n"), i, player_names[i],
|
||||
GetLag(node), G_TicsToMilliseconds(GetLag(node)));
|
||||
#else
|
||||
if (playeringame[i] && i != 0)
|
||||
CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]);
|
||||
#endif
|
||||
n = strlen(player_names[i]);
|
||||
if (n > name_width)
|
||||
name_width = n;
|
||||
|
||||
n = playerpingtable[i];
|
||||
if (n > ms_width)
|
||||
ms_width = n;
|
||||
|
||||
pingv[pingc].num = i;
|
||||
pingv[pingc].ms = playerpingtable[i];
|
||||
pingc++;
|
||||
}
|
||||
#ifndef NEWPING
|
||||
|
||||
if (ms_width < 10) ms_width = 1;
|
||||
else if (ms_width < 100) ms_width = 2;
|
||||
else ms_width = 3;
|
||||
|
||||
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
|
||||
|
||||
for (i = 0; i < pingc; ++i)
|
||||
{
|
||||
CONS_Printf("%02d : %-*s %*d ms\n",
|
||||
pingv[i].num,
|
||||
name_width, player_names[pingv[i].num],
|
||||
ms_width, pingv[i].ms);
|
||||
}
|
||||
|
||||
if (!server && playeringame[consoleplayer])
|
||||
{
|
||||
CONS_Printf("\nYour ping is %d ms\n", playerpingtable[consoleplayer]);
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void D_CloseConnection(void)
|
||||
|
|
|
@ -74,6 +74,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum);
|
|||
static void PointLimit_OnChange(void);
|
||||
static void TimeLimit_OnChange(void);
|
||||
static void NumLaps_OnChange(void);
|
||||
static void BaseNumLaps_OnChange(void);
|
||||
static void Mute_OnChange(void);
|
||||
|
||||
static void Hidetime_OnChange(void);
|
||||
|
@ -210,7 +211,7 @@ consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, N
|
|||
|
||||
consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||
consvar_t cv_respawntime = {"respawndelay", "3", CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_competitionboxes = {"competitionboxes", "Mystery", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -246,20 +247,20 @@ INT32 cv_debug;
|
|||
consvar_t cv_usemouse = {"use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||
consvar_t cv_usejoystick = {"use_gamepad", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||
consvar_t cv_usejoystick2 = {"use_gamepad2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||
I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL};
|
||||
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
|
||||
#ifdef LJOYSTICK
|
||||
consvar_t cv_joyport = {"joyport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_joyport2 = {"joyport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: for later
|
||||
consvar_t cv_joyport = {"padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_joyport2 = {"padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: for later
|
||||
#endif
|
||||
consvar_t cv_joyscale = {"joyscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_joyscale2 = {"joyscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_joyscale = {"padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_joyscale2 = {"padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2, 0, NULL, NULL, 0, 0, NULL};
|
||||
#else
|
||||
consvar_t cv_joyscale = {"joyscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
|
||||
consvar_t cv_joyscale2 = {"joyscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
|
||||
consvar_t cv_joyscale = {"padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
|
||||
consvar_t cv_joyscale2 = {"padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
|
||||
#endif
|
||||
#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)
|
||||
consvar_t cv_mouse2port = {"mouse2port", "/dev/gpmdata", CV_SAVE, mouse2port_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -315,16 +316,17 @@ consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0,
|
|||
static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}};
|
||||
consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_pointlimit = {"pointlimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
||||
PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = {"timelimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
|
||||
TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {50, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t,
|
||||
NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// 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};
|
||||
|
@ -340,9 +342,7 @@ static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE
|
|||
consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
#ifdef NEWPING
|
||||
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
// Intermission time Tails 04-19-2002
|
||||
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -363,7 +363,7 @@ consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL
|
|||
consvar_t cv_pause = {"pausepermission", "Server", CV_NETVAR, pause_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sleep = {"cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT16 gametype = GT_COOP;
|
||||
boolean splitscreen = false;
|
||||
|
@ -497,7 +497,7 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_friendlyfire);
|
||||
CV_RegisterVar(&cv_pointlimit);
|
||||
CV_RegisterVar(&cv_numlaps);
|
||||
CV_RegisterVar(&cv_usemapnumlaps);
|
||||
CV_RegisterVar(&cv_basenumlaps);
|
||||
|
||||
CV_RegisterVar(&cv_hazardlog);
|
||||
|
||||
|
@ -573,9 +573,7 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_skipmapcheck);
|
||||
CV_RegisterVar(&cv_sleep);
|
||||
#ifdef NEWPING
|
||||
CV_RegisterVar(&cv_maxping);
|
||||
#endif
|
||||
|
||||
#ifdef SEENAMES
|
||||
CV_RegisterVar(&cv_allowseenames);
|
||||
|
@ -637,6 +635,8 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_screenshot_folder);
|
||||
CV_RegisterVar(&cv_screenshot_colorprofile);
|
||||
CV_RegisterVar(&cv_moviemode);
|
||||
CV_RegisterVar(&cv_movie_option);
|
||||
CV_RegisterVar(&cv_movie_folder);
|
||||
// PNG variables
|
||||
CV_RegisterVar(&cv_zlib_level);
|
||||
CV_RegisterVar(&cv_zlib_memory);
|
||||
|
@ -738,6 +738,8 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_chasefreelook);
|
||||
CV_RegisterVar(&cv_chasefreelook2);
|
||||
CV_RegisterVar(&cv_tutorialprompt);
|
||||
CV_RegisterVar(&cv_showfocuslost);
|
||||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_sideaxis);
|
||||
|
@ -877,7 +879,7 @@ void D_RegisterClientCommands(void)
|
|||
* \sa CleanupPlayerName, SetPlayerName, Got_NameAndColor
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static boolean IsNameGood(char *name, INT32 playernum)
|
||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
|
||||
{
|
||||
INT32 ix;
|
||||
|
||||
|
@ -918,14 +920,14 @@ static boolean IsNameGood(char *name, INT32 playernum)
|
|||
if (len > 1)
|
||||
{
|
||||
name[len-1] = '\0';
|
||||
if (!IsNameGood (name, playernum))
|
||||
if (!EnsurePlayerNameIsGood (name, playernum))
|
||||
return false;
|
||||
}
|
||||
else if (len == 1) // Agh!
|
||||
{
|
||||
// Last ditch effort...
|
||||
sprintf(name, "%d", M_RandomKey(10));
|
||||
if (!IsNameGood (name, playernum))
|
||||
if (!EnsurePlayerNameIsGood (name, playernum))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -1054,12 +1056,12 @@ static void CleanupPlayerName(INT32 playernum, const char *newname)
|
|||
* \param newname New name for that player. Should be good, but won't
|
||||
* necessarily be if the client is maliciously modified or
|
||||
* buggy.
|
||||
* \sa CleanupPlayerName, IsNameGood
|
||||
* \sa CleanupPlayerName, EnsurePlayerNameIsGood
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static void SetPlayerName(INT32 playernum, char *newname)
|
||||
{
|
||||
if (IsNameGood(newname, playernum))
|
||||
if (EnsurePlayerNameIsGood(newname, playernum))
|
||||
{
|
||||
if (strcasecmp(newname, player_names[playernum]) != 0)
|
||||
{
|
||||
|
@ -1184,12 +1186,12 @@ static void SendNameAndColor(void)
|
|||
&& !strcmp(cv_skin.string, skins[players[consoleplayer].skin].name))
|
||||
return;
|
||||
|
||||
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
||||
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (!netgame)
|
||||
{
|
||||
|
@ -1302,12 +1304,12 @@ static void SendNameAndColor2(void)
|
|||
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue);
|
||||
}
|
||||
|
||||
players[secondplaya].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
||||
players[secondplaya].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (botingame)
|
||||
{
|
||||
|
@ -1690,7 +1692,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
// Kick bot from special stages
|
||||
if (botskin)
|
||||
{
|
||||
if (G_IsSpecialStage(mapnum))
|
||||
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
|
||||
{
|
||||
if (botingame)
|
||||
{
|
||||
|
@ -1916,7 +1918,10 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
precache = false;
|
||||
|
||||
if (resetplayer && !FLS)
|
||||
{
|
||||
emeralds = 0;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
|
@ -2027,8 +2032,6 @@ static void Command_Suicide(void)
|
|||
UINT8 buf[4];
|
||||
UINT8 *cp = buf;
|
||||
|
||||
WRITEINT32(cp, consoleplayer);
|
||||
|
||||
if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
|
||||
{
|
||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||
|
@ -2048,6 +2051,7 @@ static void Command_Suicide(void)
|
|||
return;
|
||||
}
|
||||
|
||||
WRITEINT32(cp, consoleplayer);
|
||||
SendNetXCmd(XD_SUICIDE, &buf, 4);
|
||||
}
|
||||
|
||||
|
@ -2714,14 +2718,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
// Clear player score and rings if a spectator.
|
||||
if (players[playernum].spectator)
|
||||
{
|
||||
players[playernum].score = players[playernum].rings = 0;
|
||||
if (players[playernum].mo)
|
||||
players[playernum].mo->health = 1;
|
||||
}
|
||||
|
||||
// In tag, check to see if you still have a game.
|
||||
if (G_TagGametype())
|
||||
P_CheckSurvivors();
|
||||
|
@ -3608,7 +3604,7 @@ static void CoopLives_OnChange(void)
|
|||
{
|
||||
case 0:
|
||||
CONS_Printf(M_GetText("Players can now respawn indefinitely.\n"));
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
CONS_Printf(M_GetText("Lives are now per-player.\n"));
|
||||
return;
|
||||
|
@ -4111,6 +4107,7 @@ void Command_ExitGame_f(void)
|
|||
botskin = 0;
|
||||
cv_debug = 0;
|
||||
emeralds = 0;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
|
||||
if (dirmenu)
|
||||
closefilemenu(true);
|
||||
|
@ -4467,3 +4464,14 @@ static void Command_ShowTime_f(void)
|
|||
|
||||
CONS_Printf(M_GetText("The current time is %f.\nThe timelimit is %f\n"), (double)leveltime/TICRATE, (double)timelimitintics/TICRATE);
|
||||
}
|
||||
|
||||
static void BaseNumLaps_OnChange(void)
|
||||
{
|
||||
if (gametype == GT_RACE)
|
||||
{
|
||||
if (cv_basenumlaps.value)
|
||||
CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n"));
|
||||
else
|
||||
CONS_Printf(M_GetText("Number of laps will be changed to %d next round.\n"), cv_basenumlaps.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ extern consvar_t cv_friendlyfire;
|
|||
extern consvar_t cv_pointlimit;
|
||||
extern consvar_t cv_timelimit;
|
||||
extern consvar_t cv_numlaps;
|
||||
extern consvar_t cv_usemapnumlaps;
|
||||
extern consvar_t cv_basenumlaps;
|
||||
extern UINT32 timelimitintics;
|
||||
extern consvar_t cv_allowexitlevel;
|
||||
|
||||
|
@ -107,9 +107,7 @@ extern consvar_t cv_ringslinger, cv_soundtest;
|
|||
|
||||
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
|
||||
|
||||
#ifdef NEWPING
|
||||
extern consvar_t cv_maxping;
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_skipmapcheck;
|
||||
|
||||
|
@ -190,6 +188,7 @@ typedef union {
|
|||
// add game commands, needs cleanup
|
||||
void D_RegisterServerCommands(void);
|
||||
void D_RegisterClientCommands(void);
|
||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
||||
void D_SendPlayerConfig(void);
|
||||
void Command_ExitGame_f(void);
|
||||
void Command_Retry_f(void);
|
||||
|
|
|
@ -752,11 +752,9 @@ void Got_Filetxpak(void)
|
|||
nameonly(filename);
|
||||
|
||||
if (!(strcmp(filename, "srb2.pk3")
|
||||
&& strcmp(filename, "srb2.srb")
|
||||
&& strcmp(filename, "srb2.wad")
|
||||
&& strcmp(filename, "zones.dta")
|
||||
&& strcmp(filename, "zones.pk3")
|
||||
&& strcmp(filename, "player.dta")
|
||||
&& strcmp(filename, "patch.dta")
|
||||
&& strcmp(filename, "patch.pk3")
|
||||
&& strcmp(filename, "music.dta")
|
||||
))
|
||||
I_Error("Tried to download \"%s\"", filename);
|
||||
|
|
|
@ -234,7 +234,9 @@ typedef enum
|
|||
CR_ZOOMTUBE,
|
||||
CR_ROPEHANG,
|
||||
CR_MACESPIN,
|
||||
CR_MINECART
|
||||
CR_MINECART,
|
||||
CR_ROLLOUT,
|
||||
CR_PTERABYTE
|
||||
} carrytype_t; // pw_carry
|
||||
|
||||
// Player powers. (don't edit this comment)
|
||||
|
@ -250,6 +252,8 @@ typedef enum
|
|||
pw_spacetime, // In space, no one can hear you spin!
|
||||
pw_extralife, // Extra Life timer
|
||||
pw_pushing,
|
||||
pw_justsprung,
|
||||
pw_noautobrake,
|
||||
|
||||
pw_super, // Are you super?
|
||||
pw_gravityboots, // gravity boots
|
||||
|
@ -509,6 +513,10 @@ typedef struct player_s
|
|||
#endif
|
||||
} player_t;
|
||||
|
||||
// Values for dashmode
|
||||
#define DASHMODE_THRESHOLD (3*TICRATE)
|
||||
#define DASHMODE_MAX (DASHMODE_THRESHOLD + 3)
|
||||
|
||||
// Value for infinite lives
|
||||
#define INFLIVES 0x7F
|
||||
|
||||
|
|
331
src/dehacked.c
331
src/dehacked.c
|
@ -313,7 +313,13 @@ static boolean findFreeSlot(INT32 *num)
|
|||
if (*num >= MAXSKINS)
|
||||
return false;
|
||||
|
||||
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||
// Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||
description[*num].picname[0] = '\0';
|
||||
description[*num].nametag[0] = '\0';
|
||||
description[*num].displayname[0] = '\0';
|
||||
description[*num].oppositecolor = SKINCOLOR_NONE;
|
||||
description[*num].tagtextcolor = SKINCOLOR_NONE;
|
||||
description[*num].tagoutlinecolor = SKINCOLOR_NONE;
|
||||
|
||||
// Found one! ^_^
|
||||
return (description[*num].used = true);
|
||||
|
@ -326,9 +332,16 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *displayname = ZZ_Alloc(MAXLINELEN+1);
|
||||
INT32 i;
|
||||
boolean slotfound = false;
|
||||
|
||||
#define SLOTFOUND \
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) \
|
||||
goto done;
|
||||
|
||||
displayname[MAXLINELEN] = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
|
@ -336,6 +349,17 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
char *tmp;
|
||||
if (s[i] == '=')
|
||||
{
|
||||
tmp = &s[i+2];
|
||||
strncpy(displayname, tmp, SKINNAMESIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
|
@ -346,8 +370,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
{
|
||||
char *playertext = NULL;
|
||||
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
SLOTFOUND
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
|
@ -395,11 +418,54 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
|
||||
if (fastcmp(word, "PICNAME"))
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
|
||||
SLOTFOUND
|
||||
strncpy(description[num].picname, word2, 8);
|
||||
}
|
||||
// new character select
|
||||
else if (fastcmp(word, "DISPLAYNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
// replace '#' with line breaks
|
||||
// (also remove any '\n')
|
||||
{
|
||||
char *cur = NULL;
|
||||
|
||||
// remove '\n'
|
||||
cur = strchr(displayname, '\n');
|
||||
if (cur)
|
||||
*cur = '\0';
|
||||
|
||||
// turn '#' into '\n'
|
||||
cur = strchr(displayname, '#');
|
||||
while (cur)
|
||||
{
|
||||
*cur = '\n';
|
||||
cur = strchr(cur, '#');
|
||||
}
|
||||
}
|
||||
// copy final string
|
||||
strncpy(description[num].displayname, displayname, SKINNAMESIZE);
|
||||
}
|
||||
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].oppositecolor = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
strncpy(description[num].nametag, word2, 8);
|
||||
}
|
||||
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].tagtextcolor = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].tagoutlinecolor = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "STATUS"))
|
||||
{
|
||||
/*
|
||||
|
@ -417,9 +483,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
else if (fastcmp(word, "SKINNAME"))
|
||||
{
|
||||
// Send to free slot.
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
|
||||
SLOTFOUND
|
||||
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
|
||||
strlwr(description[num].skinname);
|
||||
}
|
||||
|
@ -427,8 +491,9 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
deh_warning("readPlayer %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
#undef SLOTFOUND
|
||||
done:
|
||||
Z_Free(displayname);
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
|
@ -2325,6 +2390,7 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_Boss1Spikeballs}, "A_BOSS1SPIKEBALLS"},
|
||||
{{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"},
|
||||
{{A_Boss3Path}, "A_BOSS3PATH"},
|
||||
{{A_Boss3ShockThink}, "A_BOSS3SHOCKTHINK"},
|
||||
{{A_LinedefExecute}, "A_LINEDEFEXECUTE"},
|
||||
{{A_PlaySeeSound}, "A_PLAYSEESOUND"},
|
||||
{{A_PlayAttackSound}, "A_PLAYATTACKSOUND"},
|
||||
|
@ -2431,6 +2497,7 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"},
|
||||
{{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"},
|
||||
{{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"},
|
||||
{{A_Boss5MakeJunk}, "A_BOSS5MAKEJUNK"},
|
||||
{{A_LookForBetter}, "A_LOOKFORBETTER"},
|
||||
{{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"},
|
||||
{{A_DustDevilThink}, "A_DUSTDEVILTHINK"},
|
||||
|
@ -2445,6 +2512,14 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_SaloonDoorSpawn}, "A_SALOONDOORSPAWN"},
|
||||
{{A_MinecartSparkThink}, "A_MINECARTSPARKTHINK"},
|
||||
{{A_ModuloToState}, "A_MODULOTOSTATE"},
|
||||
{{A_LavafallRocks}, "A_LAVAFALLROCKS"},
|
||||
{{A_LavafallLava}, "A_LAVAFALLLAVA"},
|
||||
{{A_FallingLavaCheck}, "A_FALLINGLAVACHECK"},
|
||||
{{A_FireShrink}, "A_FIRESHRINK"},
|
||||
{{A_SpawnPterabytes}, "A_SPAWNPTERABYTES"},
|
||||
{{A_PterabyteHover}, "A_PTERABYTEHOVER"},
|
||||
{{A_RolloutSpawn}, "A_ROLLOUTSPAWN"},
|
||||
{{A_RolloutRock}, "A_ROLLOUTROCK"},
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
// This NULL entry must be the last in the list
|
||||
|
@ -4183,6 +4258,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// CA_GLIDEANDCLIMB
|
||||
"S_PLAY_GLIDE",
|
||||
"S_PLAY_GLIDE_LANDING",
|
||||
"S_PLAY_CLING",
|
||||
"S_PLAY_CLIMB",
|
||||
|
||||
|
@ -4282,6 +4358,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_TAILSOVERLAY_GASP",
|
||||
"S_TAILSOVERLAY_EDGE",
|
||||
|
||||
// [:
|
||||
"S_JETFUMEFLASH",
|
||||
|
||||
// Blue Crawla
|
||||
"S_POSS_STND",
|
||||
"S_POSS_RUN1",
|
||||
|
@ -4430,6 +4509,21 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_CRUSHCLAW_WAIT",
|
||||
"S_CRUSHCHAIN",
|
||||
|
||||
// Banpyura
|
||||
"S_BANPYURA_ROAM1",
|
||||
"S_BANPYURA_ROAM2",
|
||||
"S_BANPYURA_ROAM3",
|
||||
"S_BANPYURA_ROAM4",
|
||||
"S_BANPYURA_ROAMPAUSE",
|
||||
"S_CDIAG1",
|
||||
"S_CDIAG2",
|
||||
"S_CDIAG3",
|
||||
"S_CDIAG4",
|
||||
"S_CDIAG5",
|
||||
"S_CDIAG6",
|
||||
"S_CDIAG7",
|
||||
"S_CDIAG8",
|
||||
|
||||
// Jet Jaw
|
||||
"S_JETJAW_ROAM1",
|
||||
"S_JETJAW_ROAM2",
|
||||
|
@ -4616,6 +4710,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_CANARIVOREGAS_7",
|
||||
"S_CANARIVOREGAS_8",
|
||||
|
||||
// Pyre Fly
|
||||
"S_PYREFLY_FLY",
|
||||
"S_PYREFLY_BURN",
|
||||
"S_PYREFIRE1",
|
||||
"S_PYREFIRE2",
|
||||
|
||||
// Pterabyte
|
||||
"S_PTERABYTESPAWNER",
|
||||
"S_PTERABYTEWAYPOINT",
|
||||
"S_PTERABYTE_FLY1",
|
||||
"S_PTERABYTE_FLY2",
|
||||
"S_PTERABYTE_FLY3",
|
||||
"S_PTERABYTE_FLY4",
|
||||
"S_PTERABYTE_SWOOPDOWN",
|
||||
"S_PTERABYTE_SWOOPUP",
|
||||
|
||||
// Boss Explosion
|
||||
"S_BOSSEXPLODE",
|
||||
|
||||
|
@ -4742,6 +4852,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BOSSSEBH1",
|
||||
"S_BOSSSEBH2",
|
||||
|
||||
// Boss 3 Shockwave
|
||||
|
||||
"S_SHOCKWAVE1",
|
||||
"S_SHOCKWAVE2",
|
||||
|
||||
// Boss 4
|
||||
"S_EGGMOBILE4_STND",
|
||||
"S_EGGMOBILE4_LATK1",
|
||||
|
@ -4784,6 +4899,25 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_EGGROBOJET",
|
||||
|
||||
// Boss 5
|
||||
"S_FANG_SETUP",
|
||||
"S_FANG_INTRO0",
|
||||
"S_FANG_INTRO1",
|
||||
"S_FANG_INTRO2",
|
||||
"S_FANG_INTRO3",
|
||||
"S_FANG_INTRO4",
|
||||
"S_FANG_INTRO5",
|
||||
"S_FANG_INTRO6",
|
||||
"S_FANG_INTRO7",
|
||||
"S_FANG_INTRO8",
|
||||
"S_FANG_INTRO9",
|
||||
"S_FANG_INTRO10",
|
||||
"S_FANG_INTRO11",
|
||||
"S_FANG_INTRO12",
|
||||
"S_FANG_CLONE1",
|
||||
"S_FANG_CLONE2",
|
||||
"S_FANG_CLONE3",
|
||||
"S_FANG_CLONE4",
|
||||
"S_FANG_IDLE0",
|
||||
"S_FANG_IDLE1",
|
||||
"S_FANG_IDLE2",
|
||||
"S_FANG_IDLE3",
|
||||
|
@ -4855,6 +4989,26 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FANG_FLEEBOUNCE2",
|
||||
"S_FANG_KO",
|
||||
|
||||
"S_BROKENROBOTRANDOM",
|
||||
"S_BROKENROBOTA",
|
||||
"S_BROKENROBOTB",
|
||||
"S_BROKENROBOTC",
|
||||
"S_BROKENROBOTD",
|
||||
"S_BROKENROBOTE",
|
||||
"S_BROKENROBOTF",
|
||||
|
||||
"S_ALART1",
|
||||
"S_ALART2",
|
||||
|
||||
"S_VWREF",
|
||||
"S_VWREB",
|
||||
|
||||
"S_PROJECTORLIGHT1",
|
||||
"S_PROJECTORLIGHT2",
|
||||
"S_PROJECTORLIGHT3",
|
||||
"S_PROJECTORLIGHT4",
|
||||
"S_PROJECTORLIGHT5",
|
||||
|
||||
"S_FBOMB1",
|
||||
"S_FBOMB2",
|
||||
"S_FBOMB_EXPL1",
|
||||
|
@ -5578,14 +5732,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_DRIPC1",
|
||||
"S_DRIPC2",
|
||||
|
||||
// Coral 1
|
||||
// Coral
|
||||
"S_CORAL1",
|
||||
|
||||
// Coral 2
|
||||
"S_CORAL2",
|
||||
|
||||
// Coral 3
|
||||
"S_CORAL3",
|
||||
"S_CORAL4",
|
||||
"S_CORAL5",
|
||||
|
||||
// Blue Crystal
|
||||
"S_BLUECRYSTAL1",
|
||||
|
@ -5593,6 +5745,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
// Kelp,
|
||||
"S_KELP",
|
||||
|
||||
// Animated algae
|
||||
"S_ANIMALGAETOP1",
|
||||
"S_ANIMALGAETOP2",
|
||||
"S_ANIMALGAESEG",
|
||||
|
||||
// DSZ Stalagmites
|
||||
"S_DSZSTALAGMITE",
|
||||
"S_DSZ2STALAGMITE",
|
||||
|
@ -5737,6 +5894,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_CACTI7",
|
||||
"S_CACTI8",
|
||||
"S_CACTI9",
|
||||
"S_CACTI10",
|
||||
"S_CACTI11",
|
||||
"S_CACTITINYSEG",
|
||||
"S_CACTISMALLSEG",
|
||||
|
||||
// Warning signs sprites
|
||||
"S_ARIDSIGN_CAUTION",
|
||||
|
@ -5808,7 +5969,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// Saloon door
|
||||
"S_SALOONDOOR",
|
||||
"S_SALOONDOORTHINKER",
|
||||
"S_SALOONDOORCENTER",
|
||||
|
||||
// Train cameo
|
||||
"S_TRAINCAMEOSPAWNER_1",
|
||||
|
@ -5829,6 +5990,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FLAMEJETFLAME1",
|
||||
"S_FLAMEJETFLAME2",
|
||||
"S_FLAMEJETFLAME3",
|
||||
"S_FLAMEJETFLAME4",
|
||||
"S_FLAMEJETFLAME5",
|
||||
"S_FLAMEJETFLAME6",
|
||||
"S_FLAMEJETFLAME7",
|
||||
"S_FLAMEJETFLAME8",
|
||||
"S_FLAMEJETFLAME9",
|
||||
|
||||
// Spinning flame jets
|
||||
"S_FJSPINAXISA1", // Counter-clockwise
|
||||
|
@ -5841,6 +6008,28 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FLAMEJETFLAMEB2",
|
||||
"S_FLAMEJETFLAMEB3",
|
||||
|
||||
// Lavafall
|
||||
"S_LAVAFALL_DORMANT",
|
||||
"S_LAVAFALL_TELL",
|
||||
"S_LAVAFALL_SHOOT",
|
||||
"S_LAVAFALL_LAVA1",
|
||||
"S_LAVAFALL_LAVA2",
|
||||
"S_LAVAFALL_LAVA3",
|
||||
"S_LAVAFALLROCK",
|
||||
|
||||
// Rollout Rock
|
||||
"S_ROLLOUTSPAWN",
|
||||
"S_ROLLOUTROCK",
|
||||
|
||||
// RVZ scenery
|
||||
"S_BIGFERNLEAF",
|
||||
"S_BIGFERN1",
|
||||
"S_BIGFERN2",
|
||||
"S_JUNGLEPALM",
|
||||
"S_TORCHFLOWER",
|
||||
"S_WALLVINE_LONG",
|
||||
"S_WALLVINE_SHORT",
|
||||
|
||||
// Trapgoyles
|
||||
"S_TRAPGOYLE",
|
||||
"S_TRAPGOYLE_CHECK",
|
||||
|
@ -5872,6 +6061,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_TARGET_RESPAWN",
|
||||
"S_TARGET_ALLDONE",
|
||||
|
||||
// ATZ's green flame
|
||||
"S_GREENFLAME",
|
||||
|
||||
// Stalagmites
|
||||
"S_STG0",
|
||||
"S_STG1",
|
||||
|
@ -5892,6 +6084,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_LAMPPOST1", // normal
|
||||
"S_LAMPPOST2", // with snow
|
||||
"S_HANGSTAR",
|
||||
"S_MISTLETOE",
|
||||
// Xmas GFZ bushes
|
||||
"S_XMASBLUEBERRYBUSH",
|
||||
"S_XMASBERRYBUSH",
|
||||
|
@ -5899,6 +6092,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
// FHZ
|
||||
"S_FHZICE1",
|
||||
"S_FHZICE2",
|
||||
"S_ROSY_IDLE1",
|
||||
"S_ROSY_IDLE2",
|
||||
"S_ROSY_IDLE3",
|
||||
"S_ROSY_IDLE4",
|
||||
"S_ROSY_JUMP",
|
||||
"S_ROSY_WALK",
|
||||
"S_ROSY_HUG",
|
||||
"S_ROSY_PAIN",
|
||||
"S_ROSY_STND",
|
||||
"S_ROSY_UNHAPPY",
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -6550,6 +6753,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BHORIZ7",
|
||||
"S_BHORIZ8",
|
||||
|
||||
"S_BOOSTERSOUND",
|
||||
"S_YELLOWBOOSTERROLLER",
|
||||
"S_YELLOWBOOSTERSEG_LEFT",
|
||||
"S_YELLOWBOOSTERSEG_RIGHT",
|
||||
"S_YELLOWBOOSTERSEG_FACE",
|
||||
"S_REDBOOSTERROLLER",
|
||||
"S_REDBOOSTERSEG_LEFT",
|
||||
"S_REDBOOSTERSEG_RIGHT",
|
||||
"S_REDBOOSTERSEG_FACE",
|
||||
|
||||
// Rain
|
||||
"S_RAIN1",
|
||||
"S_RAINRETURN",
|
||||
|
@ -6570,6 +6783,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_SPLISH8",
|
||||
"S_SPLISH9",
|
||||
|
||||
// Lava splish
|
||||
"S_LAVASPLISH",
|
||||
|
||||
// added water splash
|
||||
"S_SPLASH1",
|
||||
"S_SPLASH2",
|
||||
|
@ -7181,6 +7397,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_THOK", // Thok! mobj
|
||||
"MT_PLAYER",
|
||||
"MT_TAILSOVERLAY", // c:
|
||||
"MT_METALJETFUME", // [:
|
||||
|
||||
// Enemies
|
||||
"MT_BLUECRAWLA", // Crawla (Blue)
|
||||
|
@ -7199,6 +7416,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_CRUSHSTACEAN", // Crushstacean
|
||||
"MT_CRUSHCLAW", // Big meaty claw
|
||||
"MT_CRUSHCHAIN", // Chain
|
||||
"MT_BANPYURA", // Banpyura
|
||||
"MT_BANPSPRING", // Banpyura spring
|
||||
"MT_JETJAW", // Jet Jaw
|
||||
"MT_SNAILER", // Snailer
|
||||
"MT_VULTURE", // BASH
|
||||
|
@ -7220,6 +7439,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_UNIBALL", // Unidus Ball
|
||||
"MT_CANARIVORE", // Canarivore
|
||||
"MT_CANARIVORE_GAS", // Canarivore gas
|
||||
"MT_PYREFLY", // Pyre Fly
|
||||
"MT_PYREFLY_FIRE", // Pyre Fly fire
|
||||
"MT_PTERABYTESPAWNER", // Pterabyte spawner
|
||||
"MT_PTERABYTEWAYPOINT", // Pterabyte waypoint
|
||||
"MT_PTERABYTE", // Pterabyte
|
||||
|
||||
// Generic Boss Items
|
||||
"MT_BOSSEXPLODE",
|
||||
|
@ -7246,7 +7470,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
// Boss 3
|
||||
"MT_EGGMOBILE3",
|
||||
"MT_FAKEMOBILE",
|
||||
"MT_SHOCK",
|
||||
"MT_SHOCKWAVE",
|
||||
|
||||
// Boss 4
|
||||
"MT_EGGMOBILE4",
|
||||
|
@ -7257,6 +7481,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
|
||||
// Boss 5
|
||||
"MT_FANG",
|
||||
"MT_BROKENROBOT",
|
||||
"MT_VWREF",
|
||||
"MT_VWREB",
|
||||
"MT_PROJECTORLIGHT",
|
||||
"MT_FBOMB",
|
||||
"MT_TNTDUST", // also used by barrel
|
||||
"MT_FSGNA",
|
||||
|
@ -7327,6 +7555,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_REDHORIZ",
|
||||
"MT_BLUEHORIZ",
|
||||
|
||||
"MT_BOOSTERSEG",
|
||||
"MT_BOOSTERROLLER",
|
||||
"MT_YELLOWBOOSTER",
|
||||
"MT_REDBOOSTER",
|
||||
|
||||
// Interactive Objects
|
||||
"MT_BUBBLES", // Bubble source
|
||||
"MT_SIGN", // Level end sign
|
||||
|
@ -7455,11 +7688,15 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SEAWEED", // DSZ Seaweed
|
||||
"MT_WATERDRIP", // Dripping Water source
|
||||
"MT_WATERDROP", // Water drop from dripping water
|
||||
"MT_CORAL1", // Coral 1
|
||||
"MT_CORAL2", // Coral 2
|
||||
"MT_CORAL3", // Coral 3
|
||||
"MT_CORAL1", // Coral
|
||||
"MT_CORAL2",
|
||||
"MT_CORAL3",
|
||||
"MT_CORAL4",
|
||||
"MT_CORAL5",
|
||||
"MT_BLUECRYSTAL", // Blue Crystal
|
||||
"MT_KELP", // Kelp
|
||||
"MT_ANIMALGAETOP", // Animated algae top
|
||||
"MT_ANIMALGAESEG", // Animated algae segment
|
||||
"MT_DSZSTALAGMITE", // Deep Sea 1 Stalagmite
|
||||
"MT_DSZ2STALAGMITE", // Deep Sea 2 Stalagmite
|
||||
"MT_LIGHTBEAM", // DSZ Light beam
|
||||
|
@ -7519,6 +7756,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_CACTI7",
|
||||
"MT_CACTI8",
|
||||
"MT_CACTI9",
|
||||
"MT_CACTI10",
|
||||
"MT_CACTI11",
|
||||
"MT_CACTITINYSEG",
|
||||
"MT_CACTISMALLSEG",
|
||||
"MT_ARIDSIGN_CAUTION",
|
||||
"MT_ARIDSIGN_CACTI",
|
||||
"MT_ARIDSIGN_SHARPTURN",
|
||||
|
@ -7536,7 +7777,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_MINECARTSIDEMARK",
|
||||
"MT_MINECARTSPARK",
|
||||
"MT_SALOONDOOR",
|
||||
"MT_SALOONDOORTHINKER",
|
||||
"MT_SALOONDOORCENTER",
|
||||
"MT_TRAINCAMEOSPAWNER",
|
||||
"MT_TRAINSEG",
|
||||
"MT_TRAINDUSTSPAWNER",
|
||||
|
@ -7553,6 +7794,20 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
|
||||
"MT_FLAMEJETFLAMEB", // Blade's flame
|
||||
|
||||
"MT_LAVAFALL",
|
||||
"MT_LAVAFALL_LAVA",
|
||||
"MT_LAVAFALLROCK",
|
||||
|
||||
"MT_ROLLOUTSPAWN",
|
||||
"MT_ROLLOUTROCK",
|
||||
|
||||
"MT_BIGFERNLEAF",
|
||||
"MT_BIGFERN",
|
||||
"MT_JUNGLEPALM",
|
||||
"MT_TORCHFLOWER",
|
||||
"MT_WALLVINE_LONG",
|
||||
"MT_WALLVINE_SHORT",
|
||||
|
||||
// Dark City Scenery
|
||||
|
||||
// Egg Rock Scenery
|
||||
|
@ -7563,6 +7818,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_TRAPGOYLEDOWN",
|
||||
"MT_TRAPGOYLELONG",
|
||||
"MT_TARGET",
|
||||
"MT_GREENFLAME",
|
||||
|
||||
// Stalagmites
|
||||
"MT_STALAGMITE0",
|
||||
|
@ -7584,6 +7840,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_LAMPPOST1", // normal
|
||||
"MT_LAMPPOST2", // with snow
|
||||
"MT_HANGSTAR",
|
||||
"MT_MISTLETOE",
|
||||
// Xmas GFZ bushes
|
||||
"MT_XMASBLUEBERRYBUSH",
|
||||
"MT_XMASBERRYBUSH",
|
||||
|
@ -7591,6 +7848,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
// FHZ
|
||||
"MT_FHZICE1",
|
||||
"MT_FHZICE2",
|
||||
"MT_ROSY",
|
||||
"MT_CDLHRT",
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -7719,6 +7978,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_RAIN", // Rain
|
||||
"MT_SNOWFLAKE", // Snowflake
|
||||
"MT_SPLISH", // Water splish!
|
||||
"MT_LAVASPLISH", // Lava splish!
|
||||
"MT_SMOKE",
|
||||
"MT_SMALLBUBBLE", // small bubble
|
||||
"MT_MEDIUMBUBBLE", // medium bubble
|
||||
|
@ -8204,6 +8464,8 @@ static const char *const POWERS_LIST[] = {
|
|||
"SPACETIME", // In space, no one can hear you spin!
|
||||
"EXTRALIFE", // Extra Life timer
|
||||
"PUSHING",
|
||||
"JUSTSPRUNG",
|
||||
"NOAUTOBRAKE",
|
||||
|
||||
"SUPER", // Are you super?
|
||||
"GRAVITYBOOTS", // gravity boots
|
||||
|
@ -8544,6 +8806,8 @@ struct {
|
|||
{"CR_ROPEHANG",CR_ROPEHANG},
|
||||
{"CR_MACESPIN",CR_MACESPIN},
|
||||
{"CR_MINECART",CR_MINECART},
|
||||
{"CR_ROLLOUT", CR_ROLLOUT},
|
||||
{"CR_PTERABYTE",CR_PTERABYTE},
|
||||
|
||||
// Ring weapons (ringweapons_t)
|
||||
// Useful for A_GiveWeapon
|
||||
|
@ -8765,9 +9029,9 @@ struct {
|
|||
{"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top.
|
||||
{"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
|
||||
{"FF_INTANGABLEFLATS",FF_INTANGABLEFLATS}, ///< Both flats are intangable, but the sides are still solid.
|
||||
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles.
|
||||
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball.
|
||||
{"FF_ONLYKNUX",FF_ONLYKNUX}, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock.
|
||||
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
|
||||
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
|
||||
{"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
{"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats
|
||||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
@ -8898,6 +9162,7 @@ struct {
|
|||
{"V_OFFSET",V_OFFSET},
|
||||
{"V_ALLOWLOWERCASE",V_ALLOWLOWERCASE},
|
||||
{"V_FLIP",V_FLIP},
|
||||
{"V_CENTERNAMETAG",V_CENTERNAMETAG},
|
||||
{"V_SNAPTOTOP",V_SNAPTOTOP},
|
||||
{"V_SNAPTOBOTTOM",V_SNAPTOBOTTOM},
|
||||
{"V_SNAPTOLEFT",V_SNAPTOLEFT},
|
||||
|
@ -8931,6 +9196,7 @@ struct {
|
|||
{"TC_ALLWHITE",TC_ALLWHITE},
|
||||
{"TC_RAINBOW",TC_RAINBOW},
|
||||
{"TC_BLINK",TC_BLINK},
|
||||
{"TC_DASHMODE",TC_DASHMODE},
|
||||
#endif
|
||||
|
||||
{NULL,0}
|
||||
|
@ -9917,6 +10183,23 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"mapmusposition")) {
|
||||
lua_pushinteger(L, mapmusposition);
|
||||
return 1;
|
||||
// local player variables, by popular request
|
||||
} else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1)
|
||||
if (consoleplayer < 0 || !playeringame[consoleplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1)
|
||||
if (displayplayer < 0 || !playeringame[displayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[displayplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen
|
||||
if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER);
|
||||
return 1;
|
||||
// end local player variables
|
||||
} else if (fastcmp(word,"server")) {
|
||||
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
||||
return 0;
|
||||
|
|
|
@ -506,13 +506,20 @@ INT32 I_GetKey(void);
|
|||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
// Max gamepad/joysticks that can be detected/used.
|
||||
#define MAX_JOYSTICKS 4
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
|
||||
// Floating point comparison epsilons from float.h
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON 1.1920928955078125e-7f
|
||||
#endif
|
||||
|
||||
#ifndef DBL_EPSILON
|
||||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#define DBL_EPSILON 2.2204460492503131e-16l
|
||||
#endif
|
||||
|
||||
// An assert-type mechanism.
|
||||
|
@ -558,9 +565,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// Polyobject fake flat code
|
||||
#define POLYOBJECTS_PLANES
|
||||
|
||||
/// Improved way of dealing with ping values and a ping limit.
|
||||
#define NEWPING
|
||||
|
||||
/// See name of player in your crosshair
|
||||
#define SEENAMES
|
||||
|
||||
|
|
|
@ -420,6 +420,10 @@ extern UINT16 emeralds;
|
|||
#define EMERALD7 64
|
||||
#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7))
|
||||
|
||||
// yes, even in non HAVE_BLUA
|
||||
#define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8
|
||||
extern INT32 luabanks[NUM_LUABANKS];
|
||||
|
||||
extern INT32 nummaprings; //keep track of spawned rings/coins
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
|
@ -429,6 +433,7 @@ typedef struct
|
|||
tic_t time; ///< Time in which the level was finished.
|
||||
UINT32 score; ///< Score when the level was finished.
|
||||
UINT16 rings; ///< Rings when the level was finished.
|
||||
boolean gotperfect; ///< Got perfect bonus?
|
||||
} recorddata_t;
|
||||
|
||||
/** Setup for one NiGHTS map.
|
||||
|
|
264
src/f_finale.c
264
src/f_finale.c
|
@ -75,6 +75,7 @@ INT32 curbgcolor;
|
|||
INT32 curbgxspeed;
|
||||
INT32 curbgyspeed;
|
||||
boolean curbghide;
|
||||
boolean hidetitlemap; // WARNING: set to false by M_SetupNextMenu and M_ClearMenus
|
||||
|
||||
static UINT8 curDemo = 0;
|
||||
static UINT32 demoDelayLeft;
|
||||
|
@ -637,6 +638,7 @@ static void F_IntroDrawScene(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
menuanimtimer = animtimer; // Reusing this variable for the intro to fix the scrolling sky, better than changing the function around.
|
||||
F_SkyScroll(80*4, 0, "TITLESKY");
|
||||
if (timetonext == 6)
|
||||
{
|
||||
|
@ -1584,15 +1586,15 @@ void F_StartEnding(void)
|
|||
UINT8 skinnum = players[consoleplayer].skin;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 7)
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= (XTRA_ENDING+2)+1)
|
||||
{
|
||||
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
// character head, skin specific
|
||||
sprframe = &sprdef->spriteframes[4];
|
||||
sprframe = &sprdef->spriteframes[XTRA_ENDING];
|
||||
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
sprframe = &sprdef->spriteframes[5];
|
||||
sprframe = &sprdef->spriteframes[XTRA_ENDING+1];
|
||||
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
sprframe = &sprdef->spriteframes[6];
|
||||
sprframe = &sprdef->spriteframes[XTRA_ENDING+2];
|
||||
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
}
|
||||
else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this)
|
||||
|
@ -2097,12 +2099,12 @@ void F_InitMenuPresValues(void)
|
|||
curfadevalue = 16;
|
||||
curhidepics = hidetitlepics;
|
||||
curbgcolor = -1;
|
||||
curbgxspeed = titlescrollxspeed;
|
||||
curbgyspeed = titlescrollyspeed;
|
||||
curbghide = true;
|
||||
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
||||
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 22 : titlescrollyspeed;
|
||||
curbghide = (gamestate == GS_TIMEATTACK) ? false : true;
|
||||
|
||||
// Find current presentation values
|
||||
M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY");
|
||||
M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY");
|
||||
M_SetMenuCurFadeValue(16);
|
||||
M_SetMenuCurHideTitlePics();
|
||||
}
|
||||
|
@ -2465,6 +2467,11 @@ void F_TitleDemoTicker(void)
|
|||
// ==========
|
||||
// CONTINUE
|
||||
// ==========
|
||||
|
||||
static skin_t *contskins[2];
|
||||
static UINT8 cont_spr2[2][6];
|
||||
static UINT8 *contcolormaps[2];
|
||||
|
||||
void F_StartContinue(void)
|
||||
{
|
||||
I_Assert(!netgame && !multiplayer);
|
||||
|
@ -2488,7 +2495,44 @@ void F_StartContinue(void)
|
|||
S_ChangeMusicInternal("_conti", false);
|
||||
S_StopSounds();
|
||||
|
||||
timetonext = TICRATE*11;
|
||||
contskins[0] = &skins[players[consoleplayer].skin];
|
||||
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL);
|
||||
cont_spr2[0][2] = contskins[0]->contangle & 7;
|
||||
contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
|
||||
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
|
||||
cont_spr2[0][5] = max(1, contskins[0]->contspeed);
|
||||
|
||||
if (botskin)
|
||||
{
|
||||
INT32 secondplaya;
|
||||
|
||||
if (secondarydisplayplayer != consoleplayer)
|
||||
secondplaya = secondarydisplayplayer;
|
||||
else // HACK
|
||||
secondplaya = 1;
|
||||
|
||||
contskins[1] = &skins[players[secondplaya].skin];
|
||||
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL);
|
||||
cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7;
|
||||
contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE);
|
||||
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
|
||||
if (cont_spr2[1][0] == SPR2_CNT4)
|
||||
cont_spr2[1][5] = 4; // sorry, this one is hardcoded
|
||||
else
|
||||
cont_spr2[1][5] = max(1, contskins[1]->contspeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
contskins[1] = NULL;
|
||||
contcolormaps[1] = NULL;
|
||||
cont_spr2[1][0] = cont_spr2[1][2] = cont_spr2[1][4] = cont_spr2[1][5] = 0;
|
||||
}
|
||||
|
||||
cont_spr2[0][1] = cont_spr2[0][3] =\
|
||||
cont_spr2[1][1] = cont_spr2[1][3] = 0;
|
||||
|
||||
timetonext = (11*TICRATE)+11;
|
||||
continuetime = 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2497,47 +2541,198 @@ void F_StartContinue(void)
|
|||
//
|
||||
void F_ContinueDrawer(void)
|
||||
{
|
||||
patch_t *contsonic;
|
||||
INT32 i, x = (BASEVIDWIDTH/2) + 4, ncontinues = players[consoleplayer].continues;
|
||||
if (ncontinues > 20)
|
||||
ncontinues = 20;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
patch_t *patch;
|
||||
INT32 i, x = (BASEVIDWIDTH>>1), ncontinues = players[consoleplayer].continues;
|
||||
char numbuf[9] = "CONTNUM*";
|
||||
tic_t timeleft = (timetonext/TICRATE);
|
||||
INT32 offsx = 0, offsy = 0, lift[2] = {0, 0};
|
||||
|
||||
if (imcontinuing)
|
||||
contsonic = W_CachePatchName("CONT2", PU_CACHE);
|
||||
else
|
||||
contsonic = W_CachePatchName("CONT1", PU_CACHE);
|
||||
if (continuetime >= 3*TICRATE)
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 100, 0, "CONTINUE?");
|
||||
|
||||
// Draw a Sonic!
|
||||
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(contsonic->width))/2, 32, 0, contsonic);
|
||||
if (timetonext >= (11*TICRATE)+10)
|
||||
return;
|
||||
|
||||
// Draw the continue markers! Show continues minus one.
|
||||
x -= ncontinues * 6;
|
||||
V_DrawLevelTitle(x - (V_LevelNameWidth("CONTINUE")>>1), 16, 0, "CONTINUE");
|
||||
|
||||
// Two stars...
|
||||
patch = W_CachePatchName("CONTSTAR", PU_CACHE);
|
||||
V_DrawScaledPatch(x-32, 160, 0, patch);
|
||||
V_DrawScaledPatch(x+32, 160, 0, patch);
|
||||
|
||||
// Time left!
|
||||
if (timeleft > 9)
|
||||
{
|
||||
numbuf[7] = '1';
|
||||
V_DrawScaledPatch(x - 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
|
||||
numbuf[7] = '0';
|
||||
V_DrawScaledPatch(x + 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
|
||||
}
|
||||
else
|
||||
{
|
||||
numbuf[7] = '0'+timeleft;
|
||||
V_DrawScaledPatch(x, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
|
||||
}
|
||||
|
||||
// Draw the continue markers! Show continues.
|
||||
if (ncontinues > 10)
|
||||
{
|
||||
if (!(continuetime & 1) || continuetime > 17)
|
||||
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
||||
V_DrawScaledPatch(x+12, 68-2, 0, stlivex);
|
||||
V_DrawRightAlignedString(x+36, 69-5, 0,
|
||||
va("%d",(imcontinuing ? ncontinues-1 : ncontinues)));
|
||||
}
|
||||
else
|
||||
{
|
||||
x += (ncontinues/2) * 30;
|
||||
if (!(ncontinues & 1))
|
||||
x -= 15;
|
||||
for (i = 0; i < ncontinues; ++i)
|
||||
V_DrawContinueIcon(x + (i*12), 140, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
||||
{
|
||||
if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17))
|
||||
continue;
|
||||
V_DrawContinueIcon(x - (i*30), 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
||||
}
|
||||
x = BASEVIDWIDTH>>1;
|
||||
}
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 168, 0, va("\x82*\x80" " %02d " "\x82*\x80", timetonext/TICRATE));
|
||||
// Spotlight
|
||||
V_DrawScaledPatch(x, 140, 0, W_CachePatchName("CONTSPOT", PU_CACHE));
|
||||
|
||||
// warping laser
|
||||
if (continuetime)
|
||||
{
|
||||
INT32 w = min(continuetime, 28), brightness = (continuetime>>1) & 7;
|
||||
if (brightness > 3)
|
||||
brightness = 8-brightness;
|
||||
V_DrawFadeFill(x-w, 0, w<<1, 140, 0, 0, (3+brightness));
|
||||
}
|
||||
|
||||
if (contskins[1])
|
||||
{
|
||||
if (continuetime > 15)
|
||||
{
|
||||
angle_t work = FixedAngle((10*(continuetime-15))<<FRACBITS)>>ANGLETOFINESHIFT;
|
||||
offsy = FINESINE(work)<<1;
|
||||
offsx = (27*FINECOSINE(work))>>1;
|
||||
}
|
||||
else
|
||||
offsx = 27<<(FRACBITS-1);
|
||||
lift[1] = continuetime-10;
|
||||
if (lift[1] < 0)
|
||||
lift[1] = 0;
|
||||
else if (lift[1] > TICRATE+5)
|
||||
lift[1] = TICRATE+5;
|
||||
}
|
||||
|
||||
lift[0] = continuetime-5;
|
||||
if (lift[0] < 0)
|
||||
lift[0] = 0;
|
||||
else if (lift[0] > TICRATE+5)
|
||||
lift[0] = TICRATE+5;
|
||||
|
||||
#define drawchar(dx, dy, n) {\
|
||||
sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\
|
||||
sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\
|
||||
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_CACHE);\
|
||||
V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);\
|
||||
}
|
||||
|
||||
if (offsy < 0)
|
||||
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
|
||||
if (contskins[1])
|
||||
drawchar((BASEVIDWIDTH<<(FRACBITS-1))+offsx, ((140-lift[1])<<FRACBITS)+offsy, 1);
|
||||
if (offsy >= 0)
|
||||
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
|
||||
|
||||
#undef drawchar
|
||||
|
||||
if (timetonext > (11*TICRATE))
|
||||
V_DrawFadeScreen(31, timetonext-(11*TICRATE));
|
||||
if (continuetime > ((3*TICRATE) - 10))
|
||||
V_DrawFadeScreen(0, (continuetime - ((3*TICRATE) - 10)));
|
||||
}
|
||||
|
||||
void F_ContinueTicker(void)
|
||||
{
|
||||
if (!imcontinuing)
|
||||
{
|
||||
// note the setup to prevent 2x reloading
|
||||
if (timetonext >= 0)
|
||||
timetonext--;
|
||||
if (timetonext == 0)
|
||||
if (timetonext > 0)
|
||||
{
|
||||
if (!(--timetonext))
|
||||
{
|
||||
Command_ExitGame_f();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// note the setup to prevent 2x reloading
|
||||
if (continuetime >= 0)
|
||||
continuetime--;
|
||||
if (continuetime == 0)
|
||||
if (++continuetime == 3*TICRATE)
|
||||
{
|
||||
G_Continue();
|
||||
return;
|
||||
}
|
||||
|
||||
if (continuetime > 5 && ((continuetime & 1) || continuetime > TICRATE) && (++cont_spr2[0][2]) >= 8)
|
||||
cont_spr2[0][2] = 0;
|
||||
|
||||
if (continuetime > 10 && (!(continuetime & 1) || continuetime > TICRATE+5) && (++cont_spr2[1][2]) >= 8)
|
||||
cont_spr2[1][2] = 0;
|
||||
|
||||
if (continuetime == (3*TICRATE)-10)
|
||||
S_StartSound(NULL, sfx_cdfm56); // or 31
|
||||
else if (continuetime == 5)
|
||||
{
|
||||
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT2, NULL);
|
||||
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
|
||||
cont_spr2[0][1] = cont_spr2[0][3] = 0;
|
||||
cont_spr2[0][5] = 2;
|
||||
}
|
||||
else if (continuetime == TICRATE)
|
||||
{
|
||||
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT3, NULL);
|
||||
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
|
||||
cont_spr2[0][1] = cont_spr2[0][3] = 0;
|
||||
}
|
||||
else if (contskins[1])
|
||||
{
|
||||
if (continuetime == 10)
|
||||
{
|
||||
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT2, NULL);
|
||||
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
|
||||
cont_spr2[1][1] = cont_spr2[1][3] = 0;
|
||||
cont_spr2[1][5] = 2;
|
||||
}
|
||||
else if (continuetime == TICRATE+5)
|
||||
{
|
||||
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT3, NULL);
|
||||
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
|
||||
cont_spr2[1][1] = cont_spr2[1][3] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((++cont_spr2[0][3]) >= cont_spr2[0][5])
|
||||
{
|
||||
cont_spr2[0][3] = 0;
|
||||
if (++cont_spr2[0][1] >= cont_spr2[0][4])
|
||||
cont_spr2[0][1] = 0;
|
||||
}
|
||||
|
||||
if (contskins[1] && (++cont_spr2[1][3]) >= cont_spr2[1][5])
|
||||
{
|
||||
cont_spr2[1][3] = 0;
|
||||
if (++cont_spr2[1][1] >= cont_spr2[1][4])
|
||||
cont_spr2[1][1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2568,8 +2763,9 @@ boolean F_ContinueResponder(event_t *event)
|
|||
|
||||
keypressed = true;
|
||||
imcontinuing = true;
|
||||
continuetime = TICRATE;
|
||||
S_StartSound(NULL, sfx_itemup);
|
||||
S_StartSound(NULL, sfx_kc6b);
|
||||
I_FadeSong(0, MUSICRATE, &S_StopMusic);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ extern INT32 curbgcolor;
|
|||
extern INT32 curbgxspeed;
|
||||
extern INT32 curbgyspeed;
|
||||
extern boolean curbghide;
|
||||
extern boolean hidetitlemap;
|
||||
|
||||
#define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0])
|
||||
|
||||
|
|
|
@ -751,7 +751,7 @@ boolean preparefilemenu(boolean samedepth)
|
|||
}
|
||||
else if (ext == EXT_TXT)
|
||||
{
|
||||
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
|
||||
if (!strncmp(dent->d_name, "log-", 4) || !strcmp(dent->d_name, "errorlog.txt"))
|
||||
ext |= EXT_LOADED;
|
||||
}
|
||||
|
||||
|
|
258
src/g_game.c
258
src/g_game.c
|
@ -172,6 +172,7 @@ static boolean retrying = false;
|
|||
UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
|
||||
|
||||
UINT16 emeralds;
|
||||
INT32 luabanks[NUM_LUABANKS]; // yes, even in non HAVE_BLUA
|
||||
UINT32 token; // Number of tokens collected in a level
|
||||
UINT32 tokenlist; // List of tokens collected
|
||||
boolean gottoken; // Did you get a token? Used for end of act
|
||||
|
@ -215,7 +216,7 @@ UINT16 spacetimetics = 11*TICRATE + (TICRATE/2);
|
|||
UINT16 extralifetics = 4*TICRATE;
|
||||
UINT16 nightslinktics = 2*TICRATE;
|
||||
|
||||
INT32 gameovertics = 15*TICRATE;
|
||||
INT32 gameovertics = 11*TICRATE;
|
||||
|
||||
UINT8 ammoremovaltics = 2*TICRATE;
|
||||
|
||||
|
@ -360,6 +361,8 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
|
|||
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
|
||||
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Pause game upon window losing focus
|
||||
consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -885,6 +888,7 @@ static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
|
|||
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
||||
{
|
||||
boolean forcestrafe = false;
|
||||
boolean forcefullinput = false;
|
||||
INT32 tspeed, forward, side, axis, altaxis, i;
|
||||
const INT32 speed = 1;
|
||||
// these ones used for multiple conditions
|
||||
|
@ -960,8 +964,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
}
|
||||
if (twodlevel
|
||||
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|
||||
|| (!demoplayback && (player->climbing
|
||||
|| (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
|| (!demoplayback && (player->pflags & PF_SLIDING)))
|
||||
forcefullinput = true;
|
||||
if (twodlevel
|
||||
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|
||||
|| (!demoplayback && ((player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
|| (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))))) // Analog
|
||||
forcestrafe = true;
|
||||
if (forcestrafe)
|
||||
|
@ -1142,8 +1149,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
if (!mouseaiming && cv_mousemove.value)
|
||||
forward += mousey;
|
||||
|
||||
if ((!demoplayback && (player->climbing
|
||||
|| (player->pflags & PF_SLIDING)))) // Analog for mouse
|
||||
if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse
|
||||
side += mousex*2;
|
||||
else if (cv_analog.value)
|
||||
{
|
||||
|
@ -1171,11 +1177,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
|
||||
// No additional acceleration when moving forward/backward and strafing simultaneously.
|
||||
// do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this.
|
||||
// 9-18-2017: ALSO, only do this when using keys to move. Gamepad analog sticks get severely gimped by this
|
||||
if (!forcestrafe && (((movefkey || movebkey) && side) || ((strafelkey || straferkey) && forward)))
|
||||
if (!forcefullinput && forward && side)
|
||||
{
|
||||
forward = FixedMul(forward, 3*FRACUNIT/4);
|
||||
side = FixedMul(side, 3*FRACUNIT/4);
|
||||
angle_t angle = R_PointToAngle2(0, 0, side << FRACBITS, forward << FRACBITS);
|
||||
INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE));
|
||||
INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE));
|
||||
forward = max(min(forward, maxforward), -maxforward);
|
||||
side = max(min(side, maxside), -maxside);
|
||||
}
|
||||
|
||||
//Silly hack to make 2d mode *somewhat* playable with no chasecam.
|
||||
|
@ -1211,6 +1219,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
||||
{
|
||||
boolean forcestrafe = false;
|
||||
boolean forcefullinput = false;
|
||||
INT32 tspeed, forward, side, axis, altaxis, i;
|
||||
const INT32 speed = 1;
|
||||
// these ones used for multiple conditions
|
||||
|
@ -1282,6 +1291,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
if (turnleft)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
|
||||
}
|
||||
if (twodlevel
|
||||
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|
||||
|| (!demoplayback && (player->pflags & PF_SLIDING)))
|
||||
forcefullinput = true;
|
||||
if (twodlevel
|
||||
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|
||||
|| player->climbing
|
||||
|
@ -1492,11 +1505,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
|
||||
// No additional acceleration when moving forward/backward and strafing simultaneously.
|
||||
// do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this.
|
||||
// 9-18-2017: ALSO, only do this when using keys to move. Gamepad analog sticks get severely gimped by this
|
||||
if (!forcestrafe && (((movefkey || movebkey) && side) || ((strafelkey || straferkey) && forward)))
|
||||
if (!forcefullinput && forward && side)
|
||||
{
|
||||
forward = FixedMul(forward, 3*FRACUNIT/4);
|
||||
side = FixedMul(side, 3*FRACUNIT/4);
|
||||
angle_t angle = R_PointToAngle2(0, 0, side << FRACBITS, forward << FRACBITS);
|
||||
INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE));
|
||||
INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE));
|
||||
forward = max(min(forward, maxforward), -maxforward);
|
||||
side = max(min(side, maxside), -maxside);
|
||||
}
|
||||
|
||||
//Silly hack to make 2d mode *somewhat* playable with no chasecam.
|
||||
|
@ -1698,65 +1713,6 @@ static INT32 camtoggledelay, camtoggledelay2 = 0;
|
|||
//
|
||||
boolean G_Responder(event_t *ev)
|
||||
{
|
||||
// allow spy mode changes even during the demo
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
|
||||
{
|
||||
if (splitscreen || !netgame)
|
||||
displayplayer = consoleplayer;
|
||||
else
|
||||
{
|
||||
// spy mode
|
||||
do
|
||||
{
|
||||
displayplayer++;
|
||||
if (displayplayer == MAXPLAYERS)
|
||||
displayplayer = 0;
|
||||
|
||||
if (!playeringame[displayplayer])
|
||||
continue;
|
||||
|
||||
if (players[displayplayer].spectator)
|
||||
continue;
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[consoleplayer].ctfteam
|
||||
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
|
||||
continue;
|
||||
}
|
||||
else if (gametype == GT_HIDEANDSEEK)
|
||||
{
|
||||
if (players[consoleplayer].pflags & PF_TAGIT)
|
||||
continue;
|
||||
}
|
||||
// Other Tag-based gametypes?
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator
|
||||
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
|
||||
continue;
|
||||
}
|
||||
else if (G_GametypeHasSpectators() && G_RingSlingerGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
} while (displayplayer != consoleplayer);
|
||||
|
||||
// change statusbar also if playing back demo
|
||||
if (singledemo)
|
||||
ST_changeDemoView();
|
||||
|
||||
// tell who's the view
|
||||
CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// any other key pops up menu if in demos
|
||||
if (gameaction == ga_nothing && !singledemo &&
|
||||
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
|
||||
|
@ -1833,6 +1789,65 @@ boolean G_Responder(event_t *ev)
|
|||
if (HU_Responder(ev))
|
||||
return true; // chat ate the event
|
||||
|
||||
// allow spy mode changes even during the demo
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
|
||||
{
|
||||
if (splitscreen || !netgame)
|
||||
displayplayer = consoleplayer;
|
||||
else
|
||||
{
|
||||
// spy mode
|
||||
do
|
||||
{
|
||||
displayplayer++;
|
||||
if (displayplayer == MAXPLAYERS)
|
||||
displayplayer = 0;
|
||||
|
||||
if (!playeringame[displayplayer])
|
||||
continue;
|
||||
|
||||
if (players[displayplayer].spectator)
|
||||
continue;
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[consoleplayer].ctfteam
|
||||
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
|
||||
continue;
|
||||
}
|
||||
else if (gametype == GT_HIDEANDSEEK)
|
||||
{
|
||||
if (players[consoleplayer].pflags & PF_TAGIT)
|
||||
continue;
|
||||
}
|
||||
// Other Tag-based gametypes?
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator
|
||||
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
|
||||
continue;
|
||||
}
|
||||
else if (G_GametypeHasSpectators() && G_RingSlingerGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
} while (displayplayer != consoleplayer);
|
||||
|
||||
// change statusbar also if playing back demo
|
||||
if (singledemo)
|
||||
ST_changeDemoView();
|
||||
|
||||
// tell who's the view
|
||||
CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// update keys current state
|
||||
G_MapEventsToControls(ev);
|
||||
|
||||
|
@ -2099,7 +2114,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
|
|||
// G_PlayerReborn
|
||||
// Called after a player dies. Almost everything is cleared and initialized.
|
||||
//
|
||||
void G_PlayerReborn(INT32 player)
|
||||
void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||
{
|
||||
player_t *p;
|
||||
INT32 score;
|
||||
|
@ -2147,6 +2162,8 @@ void G_PlayerReborn(INT32 player)
|
|||
boolean outofcoop;
|
||||
INT16 bot;
|
||||
SINT8 pity;
|
||||
INT16 rings;
|
||||
INT16 spheres;
|
||||
|
||||
score = players[player].score;
|
||||
lives = players[player].lives;
|
||||
|
@ -2202,6 +2219,17 @@ void G_PlayerReborn(INT32 player)
|
|||
bot = players[player].bot;
|
||||
pity = players[player].pity;
|
||||
|
||||
if (betweenmaps || !G_IsSpecialStage(gamemap))
|
||||
{
|
||||
rings = (ultimatemode ? 0 : mapheaderinfo[gamemap-1]->startrings);
|
||||
spheres = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rings = players[player].rings;
|
||||
spheres = players[player].spheres;
|
||||
}
|
||||
|
||||
p = &players[player];
|
||||
memset(p, 0, sizeof (*p));
|
||||
|
||||
|
@ -2256,6 +2284,8 @@ void G_PlayerReborn(INT32 player)
|
|||
if (bot)
|
||||
p->bot = 1; // reset to AI-controlled
|
||||
p->pity = pity;
|
||||
p->rings = rings;
|
||||
p->spheres = spheres;
|
||||
|
||||
// Don't do anything immediately
|
||||
p->pflags |= PF_USEDOWN;
|
||||
|
@ -2263,12 +2293,33 @@ void G_PlayerReborn(INT32 player)
|
|||
p->pflags |= PF_JUMPDOWN;
|
||||
|
||||
p->playerstate = PST_LIVE;
|
||||
p->rings = p->spheres = 0; // 0 rings
|
||||
p->panim = PA_IDLE; // standing animation
|
||||
|
||||
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
|
||||
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
|
||||
|
||||
// Check to make sure their color didn't change somehow...
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_redteam);
|
||||
else if (p == &players[secondarydisplayplayer])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_redteam);
|
||||
}
|
||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_blueteam);
|
||||
else if (p == &players[secondarydisplayplayer])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
|
||||
}
|
||||
}
|
||||
|
||||
if (betweenmaps)
|
||||
return;
|
||||
|
||||
if (p-players == consoleplayer)
|
||||
{
|
||||
if (mapmusflags & MUSIC_RELOADRESET)
|
||||
|
@ -2288,9 +2339,6 @@ void G_PlayerReborn(INT32 player)
|
|||
if (gametype == GT_COOP)
|
||||
P_FindEmerald(); // scan for emeralds to hunt for
|
||||
|
||||
// Reset Nights score and max link to 0 on death
|
||||
p->marescore = p->maxlink = 0;
|
||||
|
||||
// If NiGHTS, find lowest mare to start with.
|
||||
p->mare = P_FindLowestMare();
|
||||
|
||||
|
@ -2298,27 +2346,6 @@ void G_PlayerReborn(INT32 player)
|
|||
|
||||
if (p->mare == 255)
|
||||
p->mare = 0;
|
||||
|
||||
p->marelap = p->marebonuslap = 0;
|
||||
|
||||
// Check to make sure their color didn't change somehow...
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_redteam);
|
||||
else if (p == &players[secondarydisplayplayer])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_redteam);
|
||||
}
|
||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_blueteam);
|
||||
else if (p == &players[secondarydisplayplayer])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2374,8 +2401,6 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
|||
|
||||
P_SpawnPlayer(playernum);
|
||||
|
||||
players[playernum].rings = mapheaderinfo[gamemap-1]->startrings;
|
||||
|
||||
if (starpost) //Don't even bother with looking for a place to spawn.
|
||||
{
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
|
@ -2598,7 +2623,7 @@ void G_DoReborn(INT32 playernum)
|
|||
|
||||
if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP))
|
||||
resetlevel = true;
|
||||
else if (gametype == GT_COOP && (netgame || multiplayer))
|
||||
else if (gametype == GT_COOP && (netgame || multiplayer) && !G_IsSpecialStage(gamemap))
|
||||
{
|
||||
boolean notgameover = true;
|
||||
|
||||
|
@ -3316,6 +3341,7 @@ void G_LoadGameData(void)
|
|||
UINT32 recscore;
|
||||
tic_t rectime;
|
||||
UINT16 recrings;
|
||||
boolean gotperf;
|
||||
|
||||
UINT8 recmares;
|
||||
INT32 curmare;
|
||||
|
@ -3408,6 +3434,7 @@ void G_LoadGameData(void)
|
|||
recscore = READUINT32(save_p);
|
||||
rectime = (tic_t)READUINT32(save_p);
|
||||
recrings = READUINT16(save_p);
|
||||
gotperf = (boolean)READUINT8(save_p);
|
||||
|
||||
if (recrings > 10000 || recscore > MAXSCORE)
|
||||
goto datacorrupt;
|
||||
|
@ -3419,6 +3446,9 @@ void G_LoadGameData(void)
|
|||
mainrecords[i]->time = rectime;
|
||||
mainrecords[i]->rings = recrings;
|
||||
}
|
||||
|
||||
if (gotperf)
|
||||
mainrecords[i]->gotperfect = gotperf;
|
||||
}
|
||||
|
||||
// Nights records
|
||||
|
@ -3550,12 +3580,14 @@ void G_SaveGameData(void)
|
|||
WRITEUINT32(save_p, mainrecords[i]->score);
|
||||
WRITEUINT32(save_p, mainrecords[i]->time);
|
||||
WRITEUINT16(save_p, mainrecords[i]->rings);
|
||||
WRITEUINT8(save_p, mainrecords[i]->gotperfect);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT16(save_p, 0);
|
||||
WRITEUINT8(save_p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3788,7 +3820,29 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
|
||||
// File end marker check
|
||||
CHECKPOS
|
||||
if (READUINT8(save_p) != 0x1d) BADSAVE;
|
||||
switch (READUINT8(save_p))
|
||||
{
|
||||
case 0xb7:
|
||||
{
|
||||
UINT8 i, banksinuse;
|
||||
CHECKPOS
|
||||
banksinuse = READUINT8(save_p);
|
||||
CHECKPOS
|
||||
if (banksinuse > NUM_LUABANKS)
|
||||
BADSAVE
|
||||
for (i = 0; i < banksinuse; i++)
|
||||
{
|
||||
(void)READINT32(save_p);
|
||||
CHECKPOS
|
||||
}
|
||||
if (READUINT8(save_p) != 0x1d)
|
||||
BADSAVE
|
||||
}
|
||||
case 0x1d:
|
||||
break;
|
||||
default:
|
||||
BADSAVE
|
||||
}
|
||||
|
||||
// done
|
||||
saved = FIL_WriteFile(backup, savebuffer, length);
|
||||
|
|
|
@ -59,6 +59,8 @@ extern boolean pausebreakkey;
|
|||
|
||||
extern boolean promptactive;
|
||||
|
||||
extern consvar_t cv_pauseifunfocused;
|
||||
|
||||
// used in game menu
|
||||
extern consvar_t cv_tutorialprompt;
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
||||
|
@ -100,7 +102,7 @@ extern INT32 localaiming, localaiming2; // should be an angle_t but signed
|
|||
//
|
||||
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo);
|
||||
void G_DoReborn(INT32 playernum);
|
||||
void G_PlayerReborn(INT32 player);
|
||||
void G_PlayerReborn(INT32 player, boolean betweenmaps);
|
||||
void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer,
|
||||
boolean skipprecutscene, boolean FLS);
|
||||
char *G_BuildMapTitle(INT32 mapnum);
|
||||
|
|
|
@ -709,8 +709,8 @@ void G_DefineDefaultControls(void)
|
|||
|
||||
for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0)
|
||||
{
|
||||
gamecontroldefault[i][gc_weaponnext ][0] = 'e';
|
||||
gamecontroldefault[i][gc_weaponprev ][0] = 'q';
|
||||
gamecontroldefault[i][gc_weaponnext ][0] = KEY_MOUSEWHEELUP+0;
|
||||
gamecontroldefault[i][gc_weaponprev ][0] = KEY_MOUSEWHEELDOWN+0;
|
||||
gamecontroldefault[i][gc_wepslot1 ][0] = '1';
|
||||
gamecontroldefault[i][gc_wepslot2 ][0] = '2';
|
||||
gamecontroldefault[i][gc_wepslot3 ][0] = '3';
|
||||
|
|
|
@ -201,7 +201,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
|||
// (do not accept hit with the extensions)
|
||||
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
|
||||
frac = num / den;
|
||||
if (frac < 0.0 || frac > 1.0)
|
||||
if (frac < 0.0l || frac > 1.0l)
|
||||
return NULL;
|
||||
|
||||
// now get the frac along the BSP line
|
||||
|
|
|
@ -149,7 +149,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
|
@ -159,7 +159,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
||||
break;
|
||||
|
@ -263,7 +263,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
|
@ -273,7 +273,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
||||
break;
|
||||
|
@ -694,7 +694,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
|
|||
realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength);
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
#endif
|
||||
HWR_DrawTexturePatchInCache(&grtex->mipmap,
|
||||
blockwidth, blockheight,
|
||||
|
@ -724,6 +724,13 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
|
|||
{
|
||||
INT32 newwidth, newheight;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
// lump is a png so convert it
|
||||
size_t len = W_LumpLengthPwad(grPatch->wadnum, grPatch->lumpnum);
|
||||
if ((patch != NULL) && R_IsLumpPNG((const UINT8 *)patch, len))
|
||||
patch = R_PNGToPatch((const UINT8 *)patch, len, NULL, true);
|
||||
#endif
|
||||
|
||||
// don't do it twice (like a cache)
|
||||
if (grMipmap->width == 0)
|
||||
{
|
||||
|
@ -926,7 +933,7 @@ static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
|||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)patch, lumplength))
|
||||
patch = R_PNGToPatch((UINT8 *)patch, lumplength);
|
||||
patch = R_PNGToPatch((UINT8 *)patch, lumplength, NULL, false);
|
||||
#endif
|
||||
|
||||
grMipmap->width = (UINT16)SHORT(patch->width);
|
||||
|
|
|
@ -61,9 +61,6 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
|
|||
// ==========================================================================
|
||||
|
||||
// Constants
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
#define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360
|
||||
|
||||
void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/;
|
||||
|
|
|
@ -162,6 +162,8 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_TURR
|
||||
&lspr[NOLIGHT], // SPR_SHRP
|
||||
&lspr[NOLIGHT], // SPR_CRAB
|
||||
&lspr[NOLIGHT], // SPR_CR2B
|
||||
&lspr[NOLIGHT], // SPR_CSPR
|
||||
&lspr[NOLIGHT], // SPR_JJAW
|
||||
&lspr[NOLIGHT], // SPR_SNLR
|
||||
&lspr[NOLIGHT], // SPR_VLTR
|
||||
|
@ -180,6 +182,8 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_UNID
|
||||
&lspr[NOLIGHT], // SPR_CANA
|
||||
&lspr[NOLIGHT], // SPR_CANG
|
||||
&lspr[NOLIGHT], // SPR_PYRE
|
||||
&lspr[NOLIGHT], // SPR_PTER
|
||||
|
||||
// Generic Boos Items
|
||||
&lspr[JETLIGHT_L], // SPR_JETF // Boss jet fumes
|
||||
|
@ -197,6 +201,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_EGGO
|
||||
&lspr[NOLIGHT], // SPR_SEBH
|
||||
&lspr[NOLIGHT], // SPR_FAKE
|
||||
&lspr[LBLUESHINE_L],// SPR_SHCK
|
||||
|
||||
// Boss 4 (Castle Eggman)
|
||||
&lspr[NOLIGHT], // SPR_EGGP
|
||||
|
@ -204,11 +209,15 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_EGR1
|
||||
|
||||
// Boss 5 (Arid Canyon)
|
||||
&lspr[NOLIGHT], //SPR_FANG // replaces EGGQ
|
||||
&lspr[NOLIGHT], //SPR_FBOM
|
||||
&lspr[NOLIGHT], //SPR_FSGN
|
||||
&lspr[REDBALL_L], //SPR_BARX // bomb explosion (also used by barrel)
|
||||
&lspr[NOLIGHT], //SPR_BARD // bomb dust (also used by barrel)
|
||||
&lspr[NOLIGHT], // SPR_FANG // replaces EGGQ
|
||||
&lspr[NOLIGHT], // SPR_BRKN
|
||||
&lspr[NOLIGHT], // SPR_WHAT
|
||||
&lspr[INVINCIBLE_L], // SPR_VWRE
|
||||
&lspr[INVINCIBLE_L], // SPR_PROJ
|
||||
&lspr[NOLIGHT], // SPR_FBOM
|
||||
&lspr[NOLIGHT], // SPR_FSGN
|
||||
&lspr[REDBALL_L], // SPR_BARX // bomb explosion (also used by barrel)
|
||||
&lspr[NOLIGHT], // SPR_BARD // bomb dust (also used by barrel)
|
||||
|
||||
// Boss 6 (Red Volcano)
|
||||
&lspr[NOLIGHT], // SPR_EEGR
|
||||
|
@ -255,6 +264,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_WSPB
|
||||
&lspr[NOLIGHT], // SPR_STPT
|
||||
&lspr[NOLIGHT], // SPR_BMNE
|
||||
&lspr[NOLIGHT], // SPR_PUMI
|
||||
|
||||
// Monitor Boxes
|
||||
&lspr[NOLIGHT], // SPR_MSTV
|
||||
|
@ -372,6 +382,10 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
// Red Volcano Scenery
|
||||
&lspr[REDBALL_L], // SPR_FLME
|
||||
&lspr[REDBALL_L], // SPR_DFLM
|
||||
&lspr[NOLIGHT], // SPR_LFAL
|
||||
&lspr[NOLIGHT], // SPR_JPLA
|
||||
&lspr[NOLIGHT], // SPR_TFLO
|
||||
&lspr[NOLIGHT], // SPR_WVIN
|
||||
|
||||
// Dark City Scenery
|
||||
|
||||
|
@ -383,7 +397,9 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_XMS3
|
||||
&lspr[NOLIGHT], // SPR_XMS4
|
||||
&lspr[NOLIGHT], // SPR_XMS5
|
||||
&lspr[NOLIGHT], // SPR_XMS6
|
||||
&lspr[NOLIGHT], // SPR_FHZI
|
||||
&lspr[NOLIGHT], // SPR_ROSY
|
||||
|
||||
// Halloween Scenery
|
||||
&lspr[RINGLIGHT_L], // SPR_PUMK
|
||||
|
@ -391,6 +407,11 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SHRM
|
||||
&lspr[NOLIGHT], // SPR_HHZM
|
||||
|
||||
// Azure Temple Scenery
|
||||
&lspr[NOLIGHT], // SPR_BGAR
|
||||
&lspr[NOLIGHT], // SPR_RCRY
|
||||
&lspr[GREENBALL_L], // SPR_CFLM
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
&lspr[NOLIGHT], // SPR_BSZ1
|
||||
&lspr[NOLIGHT], // SPR_BSZ2
|
||||
|
@ -410,7 +431,6 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
// Misc Scenery
|
||||
&lspr[NOLIGHT], // SPR_STLG
|
||||
&lspr[NOLIGHT], // SPR_DBAL
|
||||
&lspr[NOLIGHT], // SPR_RCRY
|
||||
|
||||
// Powerup Indicators
|
||||
&lspr[NOLIGHT], // SPR_ARMA
|
||||
|
@ -464,11 +484,14 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SSWY
|
||||
&lspr[NOLIGHT], // SPR_SSWR
|
||||
&lspr[NOLIGHT], // SPR_SSWB
|
||||
&lspr[NOLIGHT], // SPR_BSTY
|
||||
&lspr[NOLIGHT], // SPR_BSTR
|
||||
|
||||
// Environmental Effects
|
||||
&lspr[NOLIGHT], // SPR_RAIN
|
||||
&lspr[NOLIGHT], // SPR_SNO1
|
||||
&lspr[NOLIGHT], // SPR_SPLH
|
||||
&lspr[NOLIGHT], // SPR_LSPL
|
||||
&lspr[NOLIGHT], // SPR_SPLA
|
||||
&lspr[NOLIGHT], // SPR_SMOK
|
||||
&lspr[NOLIGHT], // SPR_BUBL
|
||||
|
|
|
@ -5454,7 +5454,7 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
#ifdef HWPRECIP
|
||||
precipmobj_t *precipthing;
|
||||
#endif
|
||||
fixed_t approx_dist, limit_dist;
|
||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
||||
|
||||
// BSP is traversed by subsector.
|
||||
// A sector might have been split into several
|
||||
|
@ -5471,7 +5471,9 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
|
||||
// Handle all things in sector.
|
||||
// If a limit exists, handle things a tiny bit different.
|
||||
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS))
|
||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
if (limit_dist || hoop_limit_dist)
|
||||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
@ -5480,8 +5482,16 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (approx_dist > limit_dist)
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
continue;
|
||||
}
|
||||
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
|
@ -5711,6 +5721,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
||||
{
|
||||
// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
|
||||
if (thing->tracer->sprite == SPR_NULL || thing->tracer->flags2 & MF2_DONTDRAW)
|
||||
return;
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
vis = HWR_NewVisSprite();
|
||||
vis->x1 = x1;
|
||||
|
@ -5724,7 +5741,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->z2 = z2;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
|
||||
if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
|
||||
{
|
||||
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
|
||||
vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../d_main.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../fastcmp.h"
|
||||
|
@ -70,6 +71,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef errno
|
||||
#include "errno.h"
|
||||
#endif
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
float avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
{-0.525731f, 0.000000f, 0.850651f},
|
||||
|
@ -294,7 +299,8 @@ static md2_model_t *md2_readModel(const char *filename)
|
|||
if (model == NULL)
|
||||
return 0;
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
file = fopen(va("%s"PATHSEP"%s", srb2home, filename), "rb");
|
||||
if (!file)
|
||||
{
|
||||
free(model);
|
||||
|
@ -523,7 +529,8 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
|
|||
#endif
|
||||
#endif
|
||||
png_FILE_p png_FILE;
|
||||
char *pngfilename = va("md2/%s", filename);
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
char *pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
|
||||
|
||||
FIL_ForceExtension(pngfilename, ".png");
|
||||
png_FILE = fopen(pngfilename, "rb");
|
||||
|
@ -651,7 +658,8 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
|
|||
size_t pw, ph, size, ptr = 0;
|
||||
INT32 ch, rep;
|
||||
FILE *file;
|
||||
char *pcxfilename = va("md2/%s", filename);
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
char *pcxfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
|
||||
|
||||
FIL_ForceExtension(pcxfilename, ".pcx");
|
||||
file = fopen(pcxfilename, "rb");
|
||||
|
@ -845,11 +853,12 @@ void HWR_InitMD2(void)
|
|||
}
|
||||
|
||||
// read the md2.dat file
|
||||
f = fopen("md2.dat", "rt");
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
CONS_Printf("%s", M_GetText("Error while loading md2.dat\n"));
|
||||
CONS_Printf("%s %s\n", M_GetText("Error while loading md2.dat:"), strerror(errno));
|
||||
nomd2s = true;
|
||||
return;
|
||||
}
|
||||
|
@ -911,7 +920,8 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
|
|||
CONS_Printf("AddPlayerMD2()...\n");
|
||||
|
||||
// read the md2.dat file
|
||||
f = fopen("md2.dat", "rt");
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
|
@ -956,7 +966,8 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
|
|||
return;
|
||||
|
||||
// Read the md2.dat file
|
||||
f = fopen("md2.dat", "rt");
|
||||
//Filename checking fixed ~Monster Iestyn and Golden
|
||||
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
|
@ -1202,7 +1213,7 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p
|
|||
if (!md2 || !skin)
|
||||
return 0;
|
||||
|
||||
if ((unsigned)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!(md2->model->spr2frames[spr2*2 + 1])
|
||||
|
@ -1266,6 +1277,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
|
||||
// MD2 colormap fix
|
||||
// colormap test
|
||||
if (spr->mobj->subsector)
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
|
@ -1297,6 +1309,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
else
|
||||
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
|
||||
}
|
||||
else
|
||||
Surf.FlatColor.rgba = 0xFFFFFFFF;
|
||||
|
||||
// Look at HWR_ProjectSprite for more
|
||||
{
|
||||
|
|
|
@ -1427,7 +1427,6 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf,
|
|||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
}
|
||||
|
||||
// PRBoom sky dome
|
||||
typedef struct vbo_vertex_s
|
||||
{
|
||||
float x, y, z;
|
||||
|
@ -1456,62 +1455,59 @@ typedef struct
|
|||
static int rows, columns;
|
||||
static boolean yflip;
|
||||
static int texw, texh;
|
||||
static float yMult, yAdd;
|
||||
static boolean foglayer;
|
||||
static float delta = 0.0f;
|
||||
|
||||
static int gl_sky_detail = 16;
|
||||
|
||||
static INT32 lasttex = -1;
|
||||
|
||||
static RGBA_t SkyColor;
|
||||
|
||||
#define MAP_COEFF 128.0f
|
||||
#define MAP_SCALE (MAP_COEFF*(float)FRACUNIT)
|
||||
|
||||
static void SkyVertex(vbo_vertex_t *vbo, int r, int c)
|
||||
{
|
||||
static fixed_t scale = 10000 << FRACBITS;
|
||||
static angle_t maxSideAngle = ANGLE_180 / 3;
|
||||
const float radians = (M_PIl / 180.0f);
|
||||
const float scale = 10000.0f;
|
||||
const float maxSideAngle = 60.0f;
|
||||
|
||||
angle_t topAngle = (angle_t)(c / (float)columns * ANGLE_MAX);
|
||||
angle_t sideAngle = maxSideAngle * (rows - r) / rows;
|
||||
fixed_t height = FINESINE(sideAngle>>ANGLETOFINESHIFT);
|
||||
fixed_t realRadius = FixedMul(scale, FINECOSINE(sideAngle>>ANGLETOFINESHIFT));
|
||||
fixed_t x = FixedMul(realRadius, FINECOSINE(topAngle>>ANGLETOFINESHIFT));
|
||||
fixed_t y = (!yflip) ? FixedMul(scale, height) : FixedMul(scale, height) * -1;
|
||||
fixed_t z = FixedMul(realRadius, FINESINE(topAngle>>ANGLETOFINESHIFT));
|
||||
float timesRepeat;
|
||||
|
||||
timesRepeat = (short)(4 * (256.0f / texw));
|
||||
if (timesRepeat == 0.0f)
|
||||
float topAngle = (c / (float)columns * 360.0f);
|
||||
float sideAngle = (maxSideAngle * (rows - r) / rows);
|
||||
float height = sin(sideAngle * radians);
|
||||
float realRadius = scale * cos(sideAngle * radians);
|
||||
float x = realRadius * cos(topAngle * radians);
|
||||
float y = (!yflip) ? scale * height : -scale * height;
|
||||
float z = realRadius * sin(topAngle * radians);
|
||||
float timesRepeat = (4 * (256.0f / texw));
|
||||
if (fpclassify(timesRepeat) == FP_ZERO)
|
||||
timesRepeat = 1.0f;
|
||||
|
||||
if (!foglayer)
|
||||
{
|
||||
boolean flip = yflip;
|
||||
vbo->r = 255;
|
||||
vbo->g = 255;
|
||||
vbo->b = 255;
|
||||
vbo->a = (r == 0 ? 0 : 255);
|
||||
|
||||
// Flip Y coordinate anyway for the top part of the hemisphere
|
||||
if (r <= 1)
|
||||
flip = !flip;
|
||||
|
||||
// And the texture coordinates.
|
||||
vbo->u = (-timesRepeat * c / (float)columns);
|
||||
if (!flip) // Flipped Y is for the lower hemisphere.
|
||||
vbo->v = (r / (float)rows) * 1.f * yMult + yAdd;
|
||||
if (!yflip) // Flipped Y is for the lower hemisphere.
|
||||
vbo->v = (r / (float)rows) + 0.5f;
|
||||
else
|
||||
vbo->v = ((rows-r)/(float)rows) * 1.f * yMult + yAdd;
|
||||
vbo->v = 1.0f + ((rows - r) / (float)rows) + 0.5f;
|
||||
}
|
||||
|
||||
if (r != 4)
|
||||
{
|
||||
y += 300.0f;
|
||||
}
|
||||
|
||||
// And finally the vertex.
|
||||
vbo->x = (float)x/(float)MAP_SCALE;
|
||||
vbo->y = (float)y/(float)MAP_SCALE + delta;
|
||||
vbo->z = (float)z/(float)MAP_SCALE;
|
||||
vbo->x = x;
|
||||
vbo->y = y + delta;
|
||||
vbo->z = z;
|
||||
}
|
||||
|
||||
GLSkyVBO sky_vbo;
|
||||
static GLSkyVBO sky_vbo;
|
||||
|
||||
static void gld_BuildSky(int row_count, int col_count)
|
||||
{
|
||||
|
@ -1542,10 +1538,7 @@ static void gld_BuildSky(int row_count, int col_count)
|
|||
vertex_p = &vbo->data[0];
|
||||
vbo->loopcount = 0;
|
||||
|
||||
memset(&SkyColor, 0xFF, sizeof(SkyColor));
|
||||
|
||||
// Why not?
|
||||
for (yflip = false; yflip <= true; yflip++)
|
||||
for (yflip = 0; yflip < 2; yflip++)
|
||||
{
|
||||
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN;
|
||||
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
|
||||
|
@ -1553,21 +1546,14 @@ static void gld_BuildSky(int row_count, int col_count)
|
|||
vbo->loops[vbo->loopcount].use_texture = false;
|
||||
vbo->loopcount++;
|
||||
|
||||
yAdd = 0.5f;
|
||||
yMult = 1.0f;
|
||||
/*if (yflip == 0)
|
||||
SkyColor = &sky->CeilingSkyColor[vbo_idx];
|
||||
else
|
||||
SkyColor = &sky->FloorSkyColor[vbo_idx];*/
|
||||
|
||||
delta = 0.0f;
|
||||
foglayer = true;
|
||||
for (c = 0; c < col_count; c++)
|
||||
{
|
||||
SkyVertex(vertex_p, 1, c);
|
||||
vertex_p->r = SkyColor.s.red;
|
||||
vertex_p->g = SkyColor.s.green;
|
||||
vertex_p->b = SkyColor.s.blue;
|
||||
vertex_p->r = 255;
|
||||
vertex_p->g = 255;
|
||||
vertex_p->b = 255;
|
||||
vertex_p->a = 255;
|
||||
vertex_p++;
|
||||
}
|
||||
|
@ -1580,7 +1566,7 @@ static void gld_BuildSky(int row_count, int col_count)
|
|||
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP;
|
||||
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
|
||||
vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2;
|
||||
vbo->loops[vbo->loopcount].use_texture = true; //(r > 1) ? true : false;
|
||||
vbo->loops[vbo->loopcount].use_texture = true;
|
||||
vbo->loopcount++;
|
||||
|
||||
for (c = 0; c <= col_count; c++)
|
||||
|
@ -1592,12 +1578,18 @@ static void gld_BuildSky(int row_count, int col_count)
|
|||
}
|
||||
}
|
||||
|
||||
static void RenderDomeForReal(INT32 skytexture)
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void RenderDome(INT32 skytexture)
|
||||
{
|
||||
int i, j;
|
||||
GLSkyVBO *vbo = &sky_vbo;
|
||||
|
||||
pglRotatef(270.f, 0.f, 1.f, 0.f);
|
||||
pglRotatef(270.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
rows = 4;
|
||||
columns = 4 * gl_sky_detail;
|
||||
|
@ -1636,8 +1628,6 @@ static void RenderDomeForReal(INT32 skytexture)
|
|||
}
|
||||
|
||||
pglScalef(1.0f, 1.0f, 1.0f);
|
||||
|
||||
// current color is undefined after glDrawArrays
|
||||
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
@ -1645,12 +1635,9 @@ EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture
|
|||
{
|
||||
SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
SetTransform(&transform);
|
||||
|
||||
texw = texture_width;
|
||||
texh = texture_height;
|
||||
RenderDomeForReal(tex);
|
||||
|
||||
// HWR_DrawSkyBackground left no blend flags after rendering the sky
|
||||
RenderDome(tex);
|
||||
SetBlend(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,10 @@ patch_t *lt_font[LT_FONTSIZE];
|
|||
patch_t *cred_font[CRED_FONTSIZE];
|
||||
patch_t *ttlnum[20]; // act numbers (0-19)
|
||||
|
||||
// Name tag fonts
|
||||
patch_t *ntb_font[NT_FONTSIZE];
|
||||
patch_t *nto_font[NT_FONTSIZE];
|
||||
|
||||
static player_t *plr;
|
||||
boolean chat_on; // entering a chat message?
|
||||
static char w_chat[HU_MAXMSGLEN];
|
||||
|
@ -246,6 +250,32 @@ void HU_LoadGraphics(void)
|
|||
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// cache the base name tag font for entire game execution
|
||||
j = NT_FONTSTART;
|
||||
for (i = 0; i < NT_FONTSIZE; i++)
|
||||
{
|
||||
sprintf(buffer, "NTFNT%.3d", j);
|
||||
j++;
|
||||
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
ntb_font[i] = NULL;
|
||||
else
|
||||
ntb_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// cache the outline name tag font for entire game execution
|
||||
j = NT_FONTSTART;
|
||||
for (i = 0; i < NT_FONTSIZE; i++)
|
||||
{
|
||||
sprintf(buffer, "NTFNO%.3d", j);
|
||||
j++;
|
||||
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
nto_font[i] = NULL;
|
||||
else
|
||||
nto_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// cache the crosshairs, don't bother to know which one is being used,
|
||||
// just cache all 3, they're so small anyway.
|
||||
for (i = 0; i < HU_CROSSHAIRS; i++)
|
||||
|
|
|
@ -35,6 +35,12 @@
|
|||
#define CRED_FONTEND 'Z' // the last font character
|
||||
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)
|
||||
|
||||
// Name tag font
|
||||
// Used by base and outline font set
|
||||
#define NT_FONTSTART '!' // the first font character
|
||||
#define NT_FONTEND 'Z' // the last font character
|
||||
#define NT_FONTSIZE (NT_FONTEND - NT_FONTSTART + 1)
|
||||
|
||||
#define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
|
||||
|
||||
extern char *shiftxform; // english translation shift table
|
||||
|
@ -77,6 +83,8 @@ extern patch_t *tallnum[10];
|
|||
extern patch_t *nightsnum[10];
|
||||
extern patch_t *lt_font[LT_FONTSIZE];
|
||||
extern patch_t *cred_font[CRED_FONTSIZE];
|
||||
extern patch_t *ntb_font[NT_FONTSIZE];
|
||||
extern patch_t *nto_font[NT_FONTSIZE];
|
||||
extern patch_t *ttlnum[20];
|
||||
extern patch_t *emeraldpics[3][8];
|
||||
extern patch_t *rflagico;
|
||||
|
|
36
src/i_tcp.c
36
src/i_tcp.c
|
@ -776,6 +776,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
#endif
|
||||
#endif
|
||||
mysockaddr_t straddr;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
|
||||
if (s == (SOCKET_TYPE)ERRSOCKET)
|
||||
return (SOCKET_TYPE)ERRSOCKET;
|
||||
|
@ -869,12 +871,16 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||
}
|
||||
|
||||
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
||||
else
|
||||
current_port = (UINT16)ntohs(sin.sin_port);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static boolean UDP_Socket(void)
|
||||
{
|
||||
const char *sock_port = NULL;
|
||||
size_t s;
|
||||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
|
@ -896,20 +902,11 @@ static boolean UDP_Socket(void)
|
|||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
if (M_CheckParm("-clientport"))
|
||||
{
|
||||
if (!M_IsNextParm())
|
||||
I_Error("syntax: -clientport <portnum>");
|
||||
sock_port = M_GetNextParm();
|
||||
}
|
||||
else
|
||||
sock_port = port_name;
|
||||
|
||||
if (M_CheckParm("-bindaddr"))
|
||||
{
|
||||
while (M_IsNextParm())
|
||||
{
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -930,7 +927,7 @@ static boolean UDP_Socket(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gaie = I_getaddrinfo("0.0.0.0", sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -945,8 +942,8 @@ static boolean UDP_Socket(void)
|
|||
#ifdef HAVE_MINIUPNPC
|
||||
if (UPNP_support)
|
||||
{
|
||||
I_UPnP_rem(sock_port, "UDP");
|
||||
I_UPnP_add(NULL, sock_port, "UDP");
|
||||
I_UPnP_rem(port_name, "UDP");
|
||||
I_UPnP_add(NULL, port_name, "UDP");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -963,7 +960,7 @@ static boolean UDP_Socket(void)
|
|||
{
|
||||
while (M_IsNextParm())
|
||||
{
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -984,7 +981,7 @@ static boolean UDP_Socket(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gaie = I_getaddrinfo("::", sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo("::", port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -1260,7 +1257,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
int gaie;
|
||||
|
||||
if (!port || !port[0])
|
||||
port = port_name;
|
||||
port = DEFAULTPORT;
|
||||
|
||||
DEBFILE(va("Creating new node: %s@%s\n", address, port));
|
||||
|
||||
|
@ -1424,14 +1421,15 @@ boolean I_InitTcpNetwork(void)
|
|||
if (!I_InitTcpDriver())
|
||||
return false;
|
||||
|
||||
if (M_CheckParm("-udpport"))
|
||||
if (M_CheckParm("-port"))
|
||||
// Combined -udpport and -clientport into -port
|
||||
// As it was really redundant having two seperate parms that does the same thing
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
strcpy(port_name, M_GetNextParm());
|
||||
else
|
||||
strcpy(port_name, "0");
|
||||
}
|
||||
current_port = (UINT16)atoi(port_name);
|
||||
|
||||
// parse network game options,
|
||||
if (M_CheckParm("-server") || dedicated)
|
||||
|
|
1512
src/info.c
1512
src/info.c
File diff suppressed because it is too large
Load diff
289
src/info.h
289
src/info.h
|
@ -138,6 +138,7 @@ void A_SetReactionTime();
|
|||
void A_Boss1Spikeballs();
|
||||
void A_Boss3TakeDamage();
|
||||
void A_Boss3Path();
|
||||
void A_Boss3ShockThink();
|
||||
void A_LinedefExecute();
|
||||
void A_PlaySeeSound();
|
||||
void A_PlayAttackSound();
|
||||
|
@ -252,6 +253,7 @@ void A_Boss5CheckOnGround();
|
|||
void A_Boss5CheckFalling();
|
||||
void A_Boss5PinchShot();
|
||||
void A_Boss5MakeItRain();
|
||||
void A_Boss5MakeJunk();
|
||||
void A_LookForBetter();
|
||||
void A_Boss5BombExplode();
|
||||
void A_DustDevilThink();
|
||||
|
@ -266,6 +268,14 @@ void A_SnapperThinker();
|
|||
void A_SaloonDoorSpawn();
|
||||
void A_MinecartSparkThink();
|
||||
void A_ModuloToState();
|
||||
void A_LavafallRocks();
|
||||
void A_LavafallLava();
|
||||
void A_FallingLavaCheck();
|
||||
void A_FireShrink();
|
||||
void A_SpawnPterabytes();
|
||||
void A_PterabyteHover();
|
||||
void A_RolloutSpawn();
|
||||
void A_RolloutRock();
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 512
|
||||
|
@ -296,6 +306,8 @@ typedef enum sprite
|
|||
SPR_TURR, // Pop-Up Turret
|
||||
SPR_SHRP, // Sharp
|
||||
SPR_CRAB, // Crushstacean
|
||||
SPR_CR2B, // Banpyura
|
||||
SPR_CSPR, // Banpyura spring
|
||||
SPR_JJAW, // Jet Jaw
|
||||
SPR_SNLR, // Snailer
|
||||
SPR_VLTR, // BASH
|
||||
|
@ -314,6 +326,8 @@ typedef enum sprite
|
|||
SPR_UNID, // Unidus
|
||||
SPR_CANA, // Canarivore
|
||||
SPR_CANG, // Canarivore gas
|
||||
SPR_PYRE, // Pyre Fly
|
||||
SPR_PTER, // Pterabyte
|
||||
|
||||
// Generic Boss Items
|
||||
SPR_JETF, // Boss jet fumes
|
||||
|
@ -331,6 +345,7 @@ typedef enum sprite
|
|||
SPR_EGGO, // Boss 3
|
||||
SPR_SEBH, // Boss 3 Junk
|
||||
SPR_FAKE, // Boss 3 Fakemobile
|
||||
SPR_SHCK, // Boss 3 Shockwave
|
||||
|
||||
// Boss 4 (Castle Eggman)
|
||||
SPR_EGGP,
|
||||
|
@ -339,6 +354,10 @@ typedef enum sprite
|
|||
|
||||
// Boss 5 (Arid Canyon)
|
||||
SPR_FANG, // replaces EGGQ
|
||||
SPR_BRKN,
|
||||
SPR_WHAT,
|
||||
SPR_VWRE,
|
||||
SPR_PROJ, // projector light
|
||||
SPR_FBOM,
|
||||
SPR_FSGN,
|
||||
SPR_BARX, // bomb explosion (also used by barrel)
|
||||
|
@ -390,6 +409,7 @@ typedef enum sprite
|
|||
SPR_WSPB, // Wall spike base
|
||||
SPR_STPT, // Starpost
|
||||
SPR_BMNE, // Big floating mine
|
||||
SPR_PUMI, // Rollout Rock
|
||||
|
||||
// Monitor Boxes
|
||||
SPR_MSTV, // MiSc TV sprites
|
||||
|
@ -458,11 +478,11 @@ typedef enum sprite
|
|||
SPR_GARG, // Deep Sea Gargoyle
|
||||
SPR_SEWE, // Deep Sea Seaweed
|
||||
SPR_DRIP, // Dripping water
|
||||
SPR_CRL1, // Coral 1
|
||||
SPR_CRL2, // Coral 2
|
||||
SPR_CRL3, // Coral 3
|
||||
SPR_CORL, // Coral
|
||||
SPR_BCRY, // Blue Crystal
|
||||
SPR_KELP, // Kelp
|
||||
SPR_ALGA, // Animated algae top
|
||||
SPR_ALGB, // Animated algae segment
|
||||
SPR_DSTG, // DSZ Stalagmites
|
||||
SPR_LIBE, // DSZ Light beam
|
||||
|
||||
|
@ -492,7 +512,7 @@ typedef enum sprite
|
|||
// Arid Canyon Scenery
|
||||
SPR_BTBL, // Big tumbleweed
|
||||
SPR_STBL, // Small tumbleweed
|
||||
SPR_CACT, // Cacti sprites
|
||||
SPR_CACT, // Cacti
|
||||
SPR_WWSG, // Caution Sign
|
||||
SPR_WWS2, // Cacti Sign
|
||||
SPR_WWS3, // Sharp Turn Sign
|
||||
|
@ -504,7 +524,6 @@ typedef enum sprite
|
|||
SPR_ADST, // Arid dust
|
||||
SPR_MCRT, // Minecart
|
||||
SPR_MCSP, // Minecart spark
|
||||
SPR_NON2, // Saloon door thinker
|
||||
SPR_SALD, // Saloon door
|
||||
SPR_TRAE, // Train cameo locomotive
|
||||
SPR_TRAI, // Train cameo wagon
|
||||
|
@ -513,6 +532,10 @@ typedef enum sprite
|
|||
// Red Volcano Scenery
|
||||
SPR_FLME, // Flame jet
|
||||
SPR_DFLM, // Blade's flame
|
||||
SPR_LFAL, // Lavafall
|
||||
SPR_JPLA, // Jungle palm
|
||||
SPR_TFLO, // Torch flower
|
||||
SPR_WVIN, // Wall vines
|
||||
|
||||
// Dark City Scenery
|
||||
|
||||
|
@ -524,7 +547,9 @@ typedef enum sprite
|
|||
SPR_XMS3, // Snowman
|
||||
SPR_XMS4, // Lamppost
|
||||
SPR_XMS5, // Hanging Star
|
||||
SPR_XMS6, // Mistletoe
|
||||
SPR_FHZI, // FHZ Ice
|
||||
SPR_ROSY,
|
||||
|
||||
// Halloween Scenery
|
||||
SPR_PUMK, // Pumpkins
|
||||
|
@ -532,6 +557,11 @@ typedef enum sprite
|
|||
SPR_SHRM, // Mushroom
|
||||
SPR_HHZM, // Misc
|
||||
|
||||
// Azure Temple Scenery
|
||||
SPR_BGAR, // ATZ Gargoyles
|
||||
SPR_RCRY, // ATZ Red Crystal (Target)
|
||||
SPR_CFLM, // Green torch flame
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
SPR_BSZ1, // Tall flowers
|
||||
SPR_BSZ2, // Medium flowers
|
||||
|
@ -551,7 +581,6 @@ typedef enum sprite
|
|||
// Misc Scenery
|
||||
SPR_STLG, // Stalagmites
|
||||
SPR_DBAL, // Disco
|
||||
SPR_RCRY, // ATZ Red Crystal (Target)
|
||||
|
||||
// Powerup Indicators
|
||||
SPR_ARMA, // Armageddon Shield Orb
|
||||
|
@ -605,11 +634,14 @@ typedef enum sprite
|
|||
SPR_SSWY, // Yellow Side Spring
|
||||
SPR_SSWR, // Red Side Spring
|
||||
SPR_SSWB, // Blue Side Spring
|
||||
SPR_BSTY, // Yellow Booster
|
||||
SPR_BSTR, // Red Booster
|
||||
|
||||
// Environmental Effects
|
||||
SPR_RAIN, // Rain
|
||||
SPR_SNO1, // Snowflake
|
||||
SPR_SPLH, // Water Splish
|
||||
SPR_LSPL, // Lava Splish
|
||||
SPR_SPLA, // Water Splash
|
||||
SPR_SMOK,
|
||||
SPR_BUBL, // Bubble
|
||||
|
@ -764,6 +796,7 @@ typedef enum playersprite
|
|||
SPR2_TIRE, // tired
|
||||
|
||||
SPR2_GLID, // glide
|
||||
SPR2_LAND, // landing after glide/bounce
|
||||
SPR2_CLNG, // cling
|
||||
SPR2_CLMB, // climb
|
||||
|
||||
|
@ -771,7 +804,6 @@ typedef enum playersprite
|
|||
SPR2_FRUN, // float run
|
||||
|
||||
SPR2_BNCE, // bounce
|
||||
SPR2_BLND, // bounce landing
|
||||
|
||||
SPR2_FIRE, // fire
|
||||
|
||||
|
@ -832,15 +864,27 @@ typedef enum playersprite
|
|||
SPR2_TALA,
|
||||
SPR2_TALB,
|
||||
|
||||
SPR2_CNT1, // continue disappointment
|
||||
SPR2_CNT2, // continue lift
|
||||
SPR2_CNT3, // continue spin
|
||||
SPR2_CNT4, // continue "soooooooniiic!" tugging
|
||||
|
||||
SPR2_SIGN, // end sign head
|
||||
SPR2_LIFE, // life monitor icon
|
||||
SPR2_XTRA, // stuff that isn't in-game - keep this last in the list
|
||||
|
||||
SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?"
|
||||
|
||||
SPR2_FIRSTFREESLOT,
|
||||
SPR2_LASTFREESLOT = 0x7f,
|
||||
NUMPLAYERSPRITES
|
||||
} playersprite_t;
|
||||
|
||||
// SPR2_XTRA
|
||||
#define XTRA_LIFEPIC 0 // Life icon patch
|
||||
#define XTRA_CHARSEL 1 // Character select picture
|
||||
#define XTRA_CONTINUE 2 // Continue icon
|
||||
#define XTRA_ENDING 3 // Ending finale patches
|
||||
|
||||
typedef enum state
|
||||
{
|
||||
S_NULL,
|
||||
|
@ -887,6 +931,7 @@ typedef enum state
|
|||
|
||||
// CA_GLIDEANDCLIMB
|
||||
S_PLAY_GLIDE,
|
||||
S_PLAY_GLIDE_LANDING,
|
||||
S_PLAY_CLING,
|
||||
S_PLAY_CLIMB,
|
||||
|
||||
|
@ -986,6 +1031,9 @@ typedef enum state
|
|||
S_TAILSOVERLAY_GASP,
|
||||
S_TAILSOVERLAY_EDGE,
|
||||
|
||||
// [:
|
||||
S_JETFUMEFLASH,
|
||||
|
||||
// Blue Crawla
|
||||
S_POSS_STND,
|
||||
S_POSS_RUN1,
|
||||
|
@ -1134,6 +1182,21 @@ typedef enum state
|
|||
S_CRUSHCLAW_WAIT,
|
||||
S_CRUSHCHAIN,
|
||||
|
||||
// Banpyura
|
||||
S_BANPYURA_ROAM1,
|
||||
S_BANPYURA_ROAM2,
|
||||
S_BANPYURA_ROAM3,
|
||||
S_BANPYURA_ROAM4,
|
||||
S_BANPYURA_ROAMPAUSE,
|
||||
S_CDIAG1,
|
||||
S_CDIAG2,
|
||||
S_CDIAG3,
|
||||
S_CDIAG4,
|
||||
S_CDIAG5,
|
||||
S_CDIAG6,
|
||||
S_CDIAG7,
|
||||
S_CDIAG8,
|
||||
|
||||
// Jet Jaw
|
||||
S_JETJAW_ROAM1,
|
||||
S_JETJAW_ROAM2,
|
||||
|
@ -1320,6 +1383,22 @@ typedef enum state
|
|||
S_CANARIVOREGAS_7,
|
||||
S_CANARIVOREGAS_8,
|
||||
|
||||
// Pyre Fly
|
||||
S_PYREFLY_FLY,
|
||||
S_PYREFLY_BURN,
|
||||
S_PYREFIRE1,
|
||||
S_PYREFIRE2,
|
||||
|
||||
// Pterabyte
|
||||
S_PTERABYTESPAWNER,
|
||||
S_PTERABYTEWAYPOINT,
|
||||
S_PTERABYTE_FLY1,
|
||||
S_PTERABYTE_FLY2,
|
||||
S_PTERABYTE_FLY3,
|
||||
S_PTERABYTE_FLY4,
|
||||
S_PTERABYTE_SWOOPDOWN,
|
||||
S_PTERABYTE_SWOOPUP,
|
||||
|
||||
// Boss Explosion
|
||||
S_BOSSEXPLODE,
|
||||
|
||||
|
@ -1447,6 +1526,10 @@ typedef enum state
|
|||
S_BOSSSEBH1,
|
||||
S_BOSSSEBH2,
|
||||
|
||||
// Boss 3 Shockwave
|
||||
S_SHOCKWAVE1,
|
||||
S_SHOCKWAVE2,
|
||||
|
||||
// Boss 4
|
||||
S_EGGMOBILE4_STND,
|
||||
S_EGGMOBILE4_LATK1,
|
||||
|
@ -1489,6 +1572,25 @@ typedef enum state
|
|||
S_EGGROBOJET,
|
||||
|
||||
// Boss 5
|
||||
S_FANG_SETUP,
|
||||
S_FANG_INTRO0,
|
||||
S_FANG_INTRO1,
|
||||
S_FANG_INTRO2,
|
||||
S_FANG_INTRO3,
|
||||
S_FANG_INTRO4,
|
||||
S_FANG_INTRO5,
|
||||
S_FANG_INTRO6,
|
||||
S_FANG_INTRO7,
|
||||
S_FANG_INTRO8,
|
||||
S_FANG_INTRO9,
|
||||
S_FANG_INTRO10,
|
||||
S_FANG_INTRO11,
|
||||
S_FANG_INTRO12,
|
||||
S_FANG_CLONE1,
|
||||
S_FANG_CLONE2,
|
||||
S_FANG_CLONE3,
|
||||
S_FANG_CLONE4,
|
||||
S_FANG_IDLE0,
|
||||
S_FANG_IDLE1,
|
||||
S_FANG_IDLE2,
|
||||
S_FANG_IDLE3,
|
||||
|
@ -1560,6 +1662,26 @@ typedef enum state
|
|||
S_FANG_FLEEBOUNCE2,
|
||||
S_FANG_KO,
|
||||
|
||||
S_BROKENROBOTRANDOM,
|
||||
S_BROKENROBOTA,
|
||||
S_BROKENROBOTB,
|
||||
S_BROKENROBOTC,
|
||||
S_BROKENROBOTD,
|
||||
S_BROKENROBOTE,
|
||||
S_BROKENROBOTF,
|
||||
|
||||
S_ALART1,
|
||||
S_ALART2,
|
||||
|
||||
S_VWREF,
|
||||
S_VWREB,
|
||||
|
||||
S_PROJECTORLIGHT1,
|
||||
S_PROJECTORLIGHT2,
|
||||
S_PROJECTORLIGHT3,
|
||||
S_PROJECTORLIGHT4,
|
||||
S_PROJECTORLIGHT5,
|
||||
|
||||
S_FBOMB1,
|
||||
S_FBOMB2,
|
||||
S_FBOMB_EXPL1,
|
||||
|
@ -2283,14 +2405,12 @@ typedef enum state
|
|||
S_DRIPC1,
|
||||
S_DRIPC2,
|
||||
|
||||
// Coral 1
|
||||
// Coral
|
||||
S_CORAL1,
|
||||
|
||||
// Coral 2
|
||||
S_CORAL2,
|
||||
|
||||
// Coral 3
|
||||
S_CORAL3,
|
||||
S_CORAL4,
|
||||
S_CORAL5,
|
||||
|
||||
// Blue Crystal
|
||||
S_BLUECRYSTAL1,
|
||||
|
@ -2298,6 +2418,11 @@ typedef enum state
|
|||
// Kelp,
|
||||
S_KELP,
|
||||
|
||||
// Animated algae
|
||||
S_ANIMALGAETOP1,
|
||||
S_ANIMALGAETOP2,
|
||||
S_ANIMALGAESEG,
|
||||
|
||||
// DSZ Stalagmites
|
||||
S_DSZSTALAGMITE,
|
||||
S_DSZ2STALAGMITE,
|
||||
|
@ -2432,7 +2557,7 @@ typedef enum state
|
|||
S_LITTLETUMBLEWEED_ROLL7,
|
||||
S_LITTLETUMBLEWEED_ROLL8,
|
||||
|
||||
// Cacti Sprites
|
||||
// Cacti
|
||||
S_CACTI1,
|
||||
S_CACTI2,
|
||||
S_CACTI3,
|
||||
|
@ -2442,8 +2567,12 @@ typedef enum state
|
|||
S_CACTI7,
|
||||
S_CACTI8,
|
||||
S_CACTI9,
|
||||
S_CACTI10,
|
||||
S_CACTI11,
|
||||
S_CACTITINYSEG,
|
||||
S_CACTISMALLSEG,
|
||||
|
||||
// Warning signs sprites
|
||||
// Warning signs
|
||||
S_ARIDSIGN_CAUTION,
|
||||
S_ARIDSIGN_CACTI,
|
||||
S_ARIDSIGN_SHARPTURN,
|
||||
|
@ -2513,7 +2642,7 @@ typedef enum state
|
|||
|
||||
// Saloon door
|
||||
S_SALOONDOOR,
|
||||
S_SALOONDOORTHINKER,
|
||||
S_SALOONDOORCENTER,
|
||||
|
||||
// Train cameo
|
||||
S_TRAINCAMEOSPAWNER_1,
|
||||
|
@ -2534,6 +2663,12 @@ typedef enum state
|
|||
S_FLAMEJETFLAME1,
|
||||
S_FLAMEJETFLAME2,
|
||||
S_FLAMEJETFLAME3,
|
||||
S_FLAMEJETFLAME4,
|
||||
S_FLAMEJETFLAME5,
|
||||
S_FLAMEJETFLAME6,
|
||||
S_FLAMEJETFLAME7,
|
||||
S_FLAMEJETFLAME8,
|
||||
S_FLAMEJETFLAME9,
|
||||
|
||||
// Spinning flame jets
|
||||
S_FJSPINAXISA1, // Counter-clockwise
|
||||
|
@ -2546,6 +2681,28 @@ typedef enum state
|
|||
S_FLAMEJETFLAMEB2,
|
||||
S_FLAMEJETFLAMEB3,
|
||||
|
||||
// Lavafall
|
||||
S_LAVAFALL_DORMANT,
|
||||
S_LAVAFALL_TELL,
|
||||
S_LAVAFALL_SHOOT,
|
||||
S_LAVAFALL_LAVA1,
|
||||
S_LAVAFALL_LAVA2,
|
||||
S_LAVAFALL_LAVA3,
|
||||
S_LAVAFALLROCK,
|
||||
|
||||
// Rollout Rock
|
||||
S_ROLLOUTSPAWN,
|
||||
S_ROLLOUTROCK,
|
||||
|
||||
// RVZ scenery
|
||||
S_BIGFERNLEAF,
|
||||
S_BIGFERN1,
|
||||
S_BIGFERN2,
|
||||
S_JUNGLEPALM,
|
||||
S_TORCHFLOWER,
|
||||
S_WALLVINE_LONG,
|
||||
S_WALLVINE_SHORT,
|
||||
|
||||
// Trapgoyles
|
||||
S_TRAPGOYLE,
|
||||
S_TRAPGOYLE_CHECK,
|
||||
|
@ -2577,6 +2734,9 @@ typedef enum state
|
|||
S_TARGET_RESPAWN,
|
||||
S_TARGET_ALLDONE,
|
||||
|
||||
// ATZ's green flame
|
||||
S_GREENFLAME,
|
||||
|
||||
// Stalagmites
|
||||
S_STG0,
|
||||
S_STG1,
|
||||
|
@ -2597,6 +2757,7 @@ typedef enum state
|
|||
S_LAMPPOST1, // normal
|
||||
S_LAMPPOST2, // with snow
|
||||
S_HANGSTAR,
|
||||
S_MISTLETOE,
|
||||
// Xmas GFZ bushes
|
||||
S_XMASBLUEBERRYBUSH,
|
||||
S_XMASBERRYBUSH,
|
||||
|
@ -2604,6 +2765,16 @@ typedef enum state
|
|||
// FHZ
|
||||
S_FHZICE1,
|
||||
S_FHZICE2,
|
||||
S_ROSY_IDLE1,
|
||||
S_ROSY_IDLE2,
|
||||
S_ROSY_IDLE3,
|
||||
S_ROSY_IDLE4,
|
||||
S_ROSY_JUMP,
|
||||
S_ROSY_WALK,
|
||||
S_ROSY_HUG,
|
||||
S_ROSY_PAIN,
|
||||
S_ROSY_STND,
|
||||
S_ROSY_UNHAPPY,
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -3255,6 +3426,17 @@ typedef enum state
|
|||
S_BHORIZ7,
|
||||
S_BHORIZ8,
|
||||
|
||||
// Booster
|
||||
S_BOOSTERSOUND,
|
||||
S_YELLOWBOOSTERROLLER,
|
||||
S_YELLOWBOOSTERSEG_LEFT,
|
||||
S_YELLOWBOOSTERSEG_RIGHT,
|
||||
S_YELLOWBOOSTERSEG_FACE,
|
||||
S_REDBOOSTERROLLER,
|
||||
S_REDBOOSTERSEG_LEFT,
|
||||
S_REDBOOSTERSEG_RIGHT,
|
||||
S_REDBOOSTERSEG_FACE,
|
||||
|
||||
// Rain
|
||||
S_RAIN1,
|
||||
S_RAINRETURN,
|
||||
|
@ -3275,6 +3457,9 @@ typedef enum state
|
|||
S_SPLISH8,
|
||||
S_SPLISH9,
|
||||
|
||||
// Lava Splish
|
||||
S_LAVASPLISH,
|
||||
|
||||
// added water splash
|
||||
S_SPLASH1,
|
||||
S_SPLASH2,
|
||||
|
@ -3908,6 +4093,7 @@ typedef enum mobj_type
|
|||
MT_THOK, // Thok! mobj
|
||||
MT_PLAYER,
|
||||
MT_TAILSOVERLAY, // c:
|
||||
MT_METALJETFUME,
|
||||
|
||||
// Enemies
|
||||
MT_BLUECRAWLA, // Crawla (Blue)
|
||||
|
@ -3926,6 +4112,8 @@ typedef enum mobj_type
|
|||
MT_CRUSHSTACEAN, // Crushstacean
|
||||
MT_CRUSHCLAW, // Big meaty claw
|
||||
MT_CRUSHCHAIN, // Chain
|
||||
MT_BANPYURA, // Banpyura
|
||||
MT_BANPSPRING, // Banpyura spring
|
||||
MT_JETJAW, // Jet Jaw
|
||||
MT_SNAILER, // Snailer
|
||||
MT_VULTURE, // BASH
|
||||
|
@ -3947,6 +4135,11 @@ typedef enum mobj_type
|
|||
MT_UNIBALL, // Unidus Ball
|
||||
MT_CANARIVORE, // Canarivore
|
||||
MT_CANARIVORE_GAS, // Canarivore gas
|
||||
MT_PYREFLY, // Pyre Fly
|
||||
MT_PYREFLY_FIRE, // Pyre Fly fire
|
||||
MT_PTERABYTESPAWNER, // Pterabyte spawner
|
||||
MT_PTERABYTEWAYPOINT, // Pterabyte waypoint
|
||||
MT_PTERABYTE, // Pterabyte
|
||||
|
||||
// Generic Boss Items
|
||||
MT_BOSSEXPLODE,
|
||||
|
@ -3973,7 +4166,7 @@ typedef enum mobj_type
|
|||
// Boss 3
|
||||
MT_EGGMOBILE3,
|
||||
MT_FAKEMOBILE,
|
||||
MT_SHOCK,
|
||||
MT_SHOCKWAVE,
|
||||
|
||||
// Boss 4
|
||||
MT_EGGMOBILE4,
|
||||
|
@ -3984,6 +4177,10 @@ typedef enum mobj_type
|
|||
|
||||
// Boss 5
|
||||
MT_FANG,
|
||||
MT_BROKENROBOT,
|
||||
MT_VWREF,
|
||||
MT_VWREB,
|
||||
MT_PROJECTORLIGHT,
|
||||
MT_FBOMB,
|
||||
MT_TNTDUST, // also used by barrel
|
||||
MT_FSGNA,
|
||||
|
@ -4054,6 +4251,11 @@ typedef enum mobj_type
|
|||
MT_REDHORIZ,
|
||||
MT_BLUEHORIZ,
|
||||
|
||||
MT_BOOSTERSEG,
|
||||
MT_BOOSTERROLLER,
|
||||
MT_YELLOWBOOSTER,
|
||||
MT_REDBOOSTER,
|
||||
|
||||
// Interactive Objects
|
||||
MT_BUBBLES, // Bubble source
|
||||
MT_SIGN, // Level end sign
|
||||
|
@ -4182,11 +4384,15 @@ typedef enum mobj_type
|
|||
MT_SEAWEED, // DSZ Seaweed
|
||||
MT_WATERDRIP, // Dripping Water source
|
||||
MT_WATERDROP, // Water drop from dripping water
|
||||
MT_CORAL1, // Coral 1
|
||||
MT_CORAL2, // Coral 2
|
||||
MT_CORAL3, // Coral 3
|
||||
MT_CORAL1, // Coral
|
||||
MT_CORAL2,
|
||||
MT_CORAL3,
|
||||
MT_CORAL4,
|
||||
MT_CORAL5,
|
||||
MT_BLUECRYSTAL, // Blue Crystal
|
||||
MT_KELP, // Kelp
|
||||
MT_ANIMALGAETOP, // Animated algae top
|
||||
MT_ANIMALGAESEG, // Animated algae segment
|
||||
MT_DSZSTALAGMITE, // Deep Sea 1 Stalagmite
|
||||
MT_DSZ2STALAGMITE, // Deep Sea 2 Stalagmite
|
||||
MT_LIGHTBEAM, // DSZ Light beam
|
||||
|
@ -4237,15 +4443,19 @@ typedef enum mobj_type
|
|||
// Arid Canyon Scenery
|
||||
MT_BIGTUMBLEWEED,
|
||||
MT_LITTLETUMBLEWEED,
|
||||
MT_CACTI1,
|
||||
MT_CACTI2,
|
||||
MT_CACTI3,
|
||||
MT_CACTI4,
|
||||
MT_CACTI5, // Harmful Cactus 1
|
||||
MT_CACTI6, // Harmful Cactus 2
|
||||
MT_CACTI7, // Harmful Cactus 3
|
||||
MT_CACTI8, // Harmful Cactus 4
|
||||
MT_CACTI9, // Harmful Cactus 5
|
||||
MT_CACTI1, // Tiny Red Flower Cactus
|
||||
MT_CACTI2, // Small Red Flower Cactus
|
||||
MT_CACTI3, // Tiny Blue Flower Cactus
|
||||
MT_CACTI4, // Small Blue Flower Cactus
|
||||
MT_CACTI5, // Prickly Pear
|
||||
MT_CACTI6, // Barrel Cactus
|
||||
MT_CACTI7, // Tall Barrel Cactus
|
||||
MT_CACTI8, // Armed Cactus
|
||||
MT_CACTI9, // Ball Cactus
|
||||
MT_CACTI10, // Tiny Cactus
|
||||
MT_CACTI11, // Small Cactus
|
||||
MT_CACTITINYSEG, // Tiny Cactus Segment
|
||||
MT_CACTISMALLSEG, // Small Cactus Segment
|
||||
MT_ARIDSIGN_CAUTION, // Caution Sign
|
||||
MT_ARIDSIGN_CACTI, // Cacti Sign
|
||||
MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign
|
||||
|
@ -4263,7 +4473,7 @@ typedef enum mobj_type
|
|||
MT_MINECARTSIDEMARK,
|
||||
MT_MINECARTSPARK,
|
||||
MT_SALOONDOOR,
|
||||
MT_SALOONDOORTHINKER,
|
||||
MT_SALOONDOORCENTER,
|
||||
MT_TRAINCAMEOSPAWNER,
|
||||
MT_TRAINSEG,
|
||||
MT_TRAINDUSTSPAWNER,
|
||||
|
@ -4280,6 +4490,20 @@ typedef enum mobj_type
|
|||
|
||||
MT_FLAMEJETFLAMEB, // Blade's flame
|
||||
|
||||
MT_LAVAFALL,
|
||||
MT_LAVAFALL_LAVA,
|
||||
MT_LAVAFALLROCK,
|
||||
|
||||
MT_ROLLOUTSPAWN,
|
||||
MT_ROLLOUTROCK,
|
||||
|
||||
MT_BIGFERNLEAF,
|
||||
MT_BIGFERN,
|
||||
MT_JUNGLEPALM,
|
||||
MT_TORCHFLOWER,
|
||||
MT_WALLVINE_LONG,
|
||||
MT_WALLVINE_SHORT,
|
||||
|
||||
// Dark City Scenery
|
||||
|
||||
// Egg Rock Scenery
|
||||
|
@ -4290,6 +4514,7 @@ typedef enum mobj_type
|
|||
MT_TRAPGOYLEDOWN,
|
||||
MT_TRAPGOYLELONG,
|
||||
MT_TARGET, // AKA Red Crystal
|
||||
MT_GREENFLAME,
|
||||
|
||||
// Stalagmites
|
||||
MT_STALAGMITE0,
|
||||
|
@ -4311,6 +4536,7 @@ typedef enum mobj_type
|
|||
MT_LAMPPOST1, // normal
|
||||
MT_LAMPPOST2, // with snow
|
||||
MT_HANGSTAR,
|
||||
MT_MISTLETOE,
|
||||
// Xmas GFZ bushes
|
||||
MT_XMASBLUEBERRYBUSH,
|
||||
MT_XMASBERRYBUSH,
|
||||
|
@ -4318,6 +4544,8 @@ typedef enum mobj_type
|
|||
// FHZ
|
||||
MT_FHZICE1,
|
||||
MT_FHZICE2,
|
||||
MT_ROSY,
|
||||
MT_CDLHRT,
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -4446,6 +4674,7 @@ typedef enum mobj_type
|
|||
MT_RAIN, // Rain
|
||||
MT_SNOWFLAKE, // Snowflake
|
||||
MT_SPLISH, // Water splish!
|
||||
MT_LAVASPLISH, // Lava splish!
|
||||
MT_SMOKE,
|
||||
MT_SMALLBUBBLE, // small bubble
|
||||
MT_MEDIUMBUBBLE, // medium bubble
|
||||
|
|
|
@ -182,6 +182,8 @@ static const struct {
|
|||
{META_CAMERA, "camera_t"},
|
||||
|
||||
{META_ACTION, "action"},
|
||||
|
||||
{META_LUABANKS, "luabanks[]"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -228,6 +230,18 @@ static int lib_isPlayerAdmin(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_reserveLuabanks(lua_State *L)
|
||||
{
|
||||
static boolean reserved = false;
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "luabanks[] cannot be reserved from within a hook or coroutine!");
|
||||
if (reserved)
|
||||
return luaL_error(L, "luabanks[] has already been reserved! Only one savedata-enabled mod at a time may use this feature.");
|
||||
reserved = true;
|
||||
LUA_PushUserdata(L, &luabanks, META_LUABANKS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// M_RANDOM
|
||||
//////////////
|
||||
|
||||
|
@ -802,15 +816,12 @@ static int lib_pCheckDeathPitCollide(lua_State *L)
|
|||
|
||||
static int lib_pCheckSolidLava(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
|
||||
//HUDSAFE
|
||||
INLEVEL
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
if (!rover)
|
||||
return LUA_ErrInvalid(L, "ffloor_t");
|
||||
lua_pushboolean(L, P_CheckSolidLava(mo, rover));
|
||||
lua_pushboolean(L, P_CheckSolidLava(rover));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2736,6 +2747,7 @@ static luaL_Reg lib[] = {
|
|||
{"chatprintf", lib_chatprintf},
|
||||
{"userdataType", lib_userdataType},
|
||||
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
||||
{"reserveLuabanks", lib_reserveLuabanks},
|
||||
|
||||
// m_random
|
||||
{"P_RandomFixed",lib_pRandomFixed},
|
||||
|
|
|
@ -50,6 +50,7 @@ enum hook {
|
|||
hook_FollowMobj,
|
||||
hook_PlayerCanDamage,
|
||||
hook_PlayerQuit,
|
||||
hook_IntermissionThinker,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -91,5 +92,6 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnM
|
|||
boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following
|
||||
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"FollowMobj",
|
||||
"PlayerCanDamage",
|
||||
"PlayerQuit",
|
||||
"IntermissionThinker",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1322,4 +1323,27 @@ void LUAh_PlayerQuit(player_t *plr, int reason)
|
|||
lua_settop(gL, 0);
|
||||
}
|
||||
|
||||
// Hook for Y_Ticker
|
||||
void LUAh_IntermissionThinker(void)
|
||||
{
|
||||
hook_p hookp;
|
||||
if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8))))
|
||||
return;
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type != hook_IntermissionThinker)
|
||||
continue;
|
||||
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
if (lua_pcall(gL, 0, 0, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -637,6 +637,68 @@ static int libd_drawString(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawNameTag(lua_State *L)
|
||||
{
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
const char *str;
|
||||
INT32 flags;
|
||||
UINT8 basecolor;
|
||||
UINT8 outlinecolor;
|
||||
UINT8 *basecolormap = NULL;
|
||||
UINT8 *outlinecolormap = NULL;
|
||||
|
||||
HUDONLY
|
||||
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
str = luaL_checkstring(L, 3);
|
||||
flags = luaL_optinteger(L, 4, 0);
|
||||
basecolor = luaL_optinteger(L, 5, SKINCOLOR_BLUE);
|
||||
outlinecolor = luaL_optinteger(L, 6, SKINCOLOR_ORANGE);
|
||||
if (basecolor != SKINCOLOR_NONE)
|
||||
basecolormap = R_GetTranslationColormap(TC_DEFAULT, basecolor, GTC_CACHE);
|
||||
if (outlinecolor != SKINCOLOR_NONE)
|
||||
outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
V_DrawNameTag(x, y, flags, FRACUNIT, basecolormap, outlinecolormap, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawScaledNameTag(lua_State *L)
|
||||
{
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
const char *str;
|
||||
INT32 flags;
|
||||
fixed_t scale;
|
||||
UINT8 basecolor;
|
||||
UINT8 outlinecolor;
|
||||
UINT8 *basecolormap = NULL;
|
||||
UINT8 *outlinecolormap = NULL;
|
||||
|
||||
HUDONLY
|
||||
|
||||
x = luaL_checkfixed(L, 1);
|
||||
y = luaL_checkfixed(L, 2);
|
||||
str = luaL_checkstring(L, 3);
|
||||
flags = luaL_optinteger(L, 4, 0);
|
||||
scale = luaL_optinteger(L, 5, FRACUNIT);
|
||||
if (scale < 0)
|
||||
return luaL_error(L, "negative scale");
|
||||
basecolor = luaL_optinteger(L, 6, SKINCOLOR_BLUE);
|
||||
outlinecolor = luaL_optinteger(L, 7, SKINCOLOR_ORANGE);
|
||||
if (basecolor != SKINCOLOR_NONE)
|
||||
basecolormap = R_GetTranslationColormap(TC_DEFAULT, basecolor, GTC_CACHE);
|
||||
if (outlinecolor != SKINCOLOR_NONE)
|
||||
outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
V_DrawNameTag(FixedInt(x), FixedInt(y), flags, scale, basecolormap, outlinecolormap, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_stringWidth(lua_State *L)
|
||||
{
|
||||
const char *str = luaL_checkstring(L, 1);
|
||||
|
@ -659,6 +721,13 @@ static int libd_stringWidth(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int libd_nameTagWidth(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, V_NameTagWidth(luaL_checkstring(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_getColormap(lua_State *L)
|
||||
{
|
||||
INT32 skinnum = TC_DEFAULT;
|
||||
|
@ -837,9 +906,12 @@ static luaL_Reg lib_draw[] = {
|
|||
{"drawPaddedNum", libd_drawPaddedNum},
|
||||
{"drawFill", libd_drawFill},
|
||||
{"drawString", libd_drawString},
|
||||
{"drawNameTag", libd_drawNameTag},
|
||||
{"drawScaledNameTag", libd_drawScaledNameTag},
|
||||
{"fadeScreen", libd_fadeScreen},
|
||||
// misc
|
||||
{"stringWidth", libd_stringWidth},
|
||||
{"nameTagWidth", libd_nameTagWidth},
|
||||
// m_random
|
||||
{"RandomFixed",libd_RandomFixed},
|
||||
{"RandomByte",libd_RandomByte},
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "p_mobj.h"
|
||||
#include "p_local.h"
|
||||
#include "z_zone.h"
|
||||
#include "doomstat.h" // luabanks[]
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
@ -146,7 +147,7 @@ static int lib_getSpr2default(lua_State *L)
|
|||
return luaL_error(L, "spr2defaults[] invalid index");
|
||||
|
||||
if (i >= free_spr2)
|
||||
return 0;
|
||||
return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, 0, free_spr2-1);
|
||||
|
||||
lua_pushinteger(L, spr2defaults[i]);
|
||||
return 1;
|
||||
|
@ -1026,6 +1027,61 @@ static int sfxinfo_num(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
//////////////
|
||||
// LUABANKS //
|
||||
//////////////
|
||||
|
||||
static int lib_getluabanks(lua_State *L)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
lua_remove(L, 1); // don't care about luabanks[] dummy userdata.
|
||||
|
||||
if (lua_isnumber(L, 1))
|
||||
i = lua_tonumber(L, 1);
|
||||
else
|
||||
return luaL_error(L, "luabanks[] invalid index");
|
||||
|
||||
if (i >= NUM_LUABANKS)
|
||||
luaL_error(L, "luabanks[] index %d out of range (%d - %d)", i, 0, NUM_LUABANKS-1);
|
||||
|
||||
lua_pushinteger(L, luabanks[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_setluabanks(lua_State *L)
|
||||
{
|
||||
UINT8 i;
|
||||
INT32 j = 0;
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter luabanks[] in HUD rendering code!");
|
||||
|
||||
lua_remove(L, 1); // don't care about luabanks[] dummy userdata.
|
||||
|
||||
if (lua_isnumber(L, 1))
|
||||
i = lua_tonumber(L, 1);
|
||||
else
|
||||
return luaL_error(L, "luabanks[] invalid index");
|
||||
|
||||
if (i >= NUM_LUABANKS)
|
||||
luaL_error(L, "luabanks[] index %d out of range (%d - %d)", i, 0, NUM_LUABANKS-1);
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
j = lua_tonumber(L, 2);
|
||||
else
|
||||
return luaL_error(L, "luabanks[] invalid set");
|
||||
|
||||
luabanks[i] = j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_luabankslen(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUM_LUABANKS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//
|
||||
// Now push all these functions into the Lua state!
|
||||
|
@ -1147,6 +1203,18 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "S_sfx");
|
||||
lua_setglobal(L, "sfxinfo");
|
||||
|
||||
luaL_newmetatable(L, META_LUABANKS);
|
||||
lua_pushcfunction(L, lib_getluabanks);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_setluabanks);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, lib_luabankslen);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ extern lua_State *gL;
|
|||
|
||||
#define META_ACTION "ACTIONF_T*"
|
||||
|
||||
#define META_LUABANKS "LUABANKS[]*"
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg);
|
||||
|
||||
int LUA_EnumLib(lua_State *L);
|
||||
|
|
|
@ -411,37 +411,53 @@ static int sector_iterate(lua_State *L)
|
|||
|
||||
// sector.lines, i -> sector.lines[i]
|
||||
// sector.lines.valid, for validity checking
|
||||
//
|
||||
// 25/9/19 Monster Iestyn
|
||||
// Modified this and _num to use triple pointers, to allow for a new hack of mine involving offsetof
|
||||
// this way we don't need to check frontsector or backsector of line #0 in the array
|
||||
//
|
||||
static int sectorlines_get(lua_State *L)
|
||||
{
|
||||
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
size_t i;
|
||||
size_t numoflines = 0;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
int field = luaL_checkoption(L, 2, NULL, valid_opt);
|
||||
if (!seclines)
|
||||
if (!seclines || !(*seclines))
|
||||
{
|
||||
if (field == 0) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed sector_t doesn't exist anymore.");
|
||||
return luaL_error(L, "accessed sector_t.lines doesn't exist anymore.");
|
||||
} else if (field == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* a snip from sector_t struct in r_defs.h, for reference
|
||||
size_t linecount;
|
||||
struct line_s **lines; // [linecount] size
|
||||
*/
|
||||
// get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result
|
||||
// we need this to determine the array's actual size, and therefore also the maximum value allowed as an index
|
||||
// this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy
|
||||
numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
|
||||
/* OLD HACK
|
||||
// check first linedef to figure which of its sectors owns this sector->lines pointer
|
||||
// then check that sector's linecount to get a maximum index
|
||||
//if (!seclines[0])
|
||||
//if (!(*seclines)[0])
|
||||
//return luaL_error(L, "no lines found!"); // no first linedef?????
|
||||
if (seclines[0]->frontsector->lines == seclines)
|
||||
numoflines = seclines[0]->frontsector->linecount;
|
||||
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
|
||||
numoflines = seclines[0]->backsector->linecount;
|
||||
if ((*seclines)[0]->frontsector->lines == *seclines)
|
||||
numoflines = (*seclines)[0]->frontsector->linecount;
|
||||
else if ((*seclines)[0]->backsector && *seclines[0]->backsector->lines == *seclines) // check backsector exists first
|
||||
numoflines = (*seclines)[0]->backsector->linecount;
|
||||
//if neither sector has it then ???
|
||||
*/
|
||||
|
||||
if (!numoflines)
|
||||
return luaL_error(L, "no lines found!");
|
||||
|
@ -449,23 +465,21 @@ static int sectorlines_get(lua_State *L)
|
|||
i = (size_t)lua_tointeger(L, 2);
|
||||
if (i >= numoflines)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, seclines[i], META_LINE);
|
||||
LUA_PushUserdata(L, (*seclines)[i], META_LINE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// #(sector.lines) -> sector.linecount
|
||||
static int sectorlines_num(lua_State *L)
|
||||
{
|
||||
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
size_t numoflines = 0;
|
||||
// check first linedef to figure which of its sectors owns this sector->lines pointer
|
||||
// then check that sector's linecount to get a maximum index
|
||||
//if (!seclines[0])
|
||||
//return luaL_error(L, "no lines found!"); // no first linedef?????
|
||||
if (seclines[0]->frontsector->lines == seclines)
|
||||
numoflines = seclines[0]->frontsector->linecount;
|
||||
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
|
||||
numoflines = seclines[0]->backsector->linecount;
|
||||
//if neither sector has it then ???
|
||||
|
||||
if (!seclines || !(*seclines))
|
||||
return luaL_error(L, "accessed sector_t.lines doesn't exist anymore.");
|
||||
|
||||
// see comments in the _get function above
|
||||
numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
lua_pushinteger(L, numoflines);
|
||||
return 1;
|
||||
}
|
||||
|
@ -543,7 +557,7 @@ static int sector_get(lua_State *L)
|
|||
LUA_PushUserdata(L, §ors[sector->camsec], META_SECTOR);
|
||||
return 1;
|
||||
case sector_lines: // lines
|
||||
LUA_PushUserdata(L, sector->lines, META_SECTORLINES);
|
||||
LUA_PushUserdata(L, §or->lines, META_SECTORLINES); // push the address of the "lines" member in the struct, to allow our hacks in sectorlines_get/_num to work
|
||||
return 1;
|
||||
case sector_ffloors: // ffloors
|
||||
lua_pushcfunction(L, lib_iterateSectorFFloors);
|
||||
|
@ -579,6 +593,7 @@ static int sector_set(lua_State *L)
|
|||
case sector_thinglist: // thinglist
|
||||
case sector_heightsec: // heightsec
|
||||
case sector_camsec: // camsec
|
||||
case sector_lines: // lines
|
||||
case sector_ffloors: // ffloors
|
||||
#ifdef ESLOPE
|
||||
case sector_fslope: // f_slope
|
||||
|
|
|
@ -164,6 +164,8 @@ static int mobj_get(lua_State *L)
|
|||
enum mobj_e field = Lua_optoption(L, 2, NULL, mobj_opt);
|
||||
lua_settop(L, 2);
|
||||
|
||||
INLEVEL
|
||||
|
||||
if (!mo) {
|
||||
if (field == mobj_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
|
@ -409,6 +411,8 @@ static int mobj_set(lua_State *L)
|
|||
enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt);
|
||||
lua_settop(L, 3);
|
||||
|
||||
INLEVEL
|
||||
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
//return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'.");
|
||||
|
@ -52,7 +51,6 @@ static int lib_getPlayer(lua_State *L)
|
|||
{
|
||||
const char *field;
|
||||
// i -> players[i]
|
||||
INLEVEL
|
||||
if (lua_type(L, 2) == LUA_TNUMBER)
|
||||
{
|
||||
lua_Integer i = luaL_checkinteger(L, 2);
|
||||
|
|
|
@ -431,7 +431,7 @@ void LUA_InvalidateLevel(void)
|
|||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(§ors[i]);
|
||||
LUA_InvalidateUserdata(sectors[i].lines);
|
||||
LUA_InvalidateUserdata(§ors[i].lines);
|
||||
if (sectors[i].ffloors)
|
||||
{
|
||||
for (rover = sectors[i].ffloors; rover; rover = rover->next)
|
||||
|
@ -1121,7 +1121,7 @@ void LUA_Archive(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
if (!playeringame[i] && i > 0) // dedicated servers...
|
||||
continue;
|
||||
// all players in game will be archived, even if they just add a 0.
|
||||
ArchiveExtVars(&players[i], "player");
|
||||
|
@ -1157,7 +1157,7 @@ void LUA_UnArchive(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
if (!playeringame[i] && i > 0) // dedicated servers...
|
||||
continue;
|
||||
UnArchiveExtVars(&players[i]);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ enum skin {
|
|||
skin_supercolor,
|
||||
skin_prefoppositecolor,
|
||||
skin_highresscale,
|
||||
skin_contspeed,
|
||||
skin_contangle,
|
||||
skin_soundsid,
|
||||
skin_availability
|
||||
};
|
||||
|
@ -88,6 +90,8 @@ static const char *const skin_opt[] = {
|
|||
"supercolor",
|
||||
"prefoppositecolor",
|
||||
"highresscale",
|
||||
"contspeed",
|
||||
"contangle",
|
||||
"soundsid",
|
||||
"availability",
|
||||
NULL};
|
||||
|
@ -199,6 +203,12 @@ static int skin_get(lua_State *L)
|
|||
case skin_highresscale:
|
||||
lua_pushinteger(L, skin->highresscale);
|
||||
break;
|
||||
case skin_contspeed:
|
||||
lua_pushinteger(L, skin->contspeed);
|
||||
break;
|
||||
case skin_contangle:
|
||||
lua_pushinteger(L, skin->contangle);
|
||||
break;
|
||||
case skin_soundsid:
|
||||
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
|
||||
break;
|
||||
|
|
28
src/m_cond.c
28
src/m_cond.c
|
@ -528,12 +528,22 @@ skincolors_t M_GetEmblemColor(emblem_t *em)
|
|||
return em->color;
|
||||
}
|
||||
|
||||
const char *M_GetEmblemPatch(emblem_t *em)
|
||||
const char *M_GetEmblemPatch(emblem_t *em, boolean big)
|
||||
{
|
||||
static char pnamebuf[7] = "GOTITn";
|
||||
static char pnamebuf[7];
|
||||
|
||||
if (!big)
|
||||
strcpy(pnamebuf, "GOTITn");
|
||||
else
|
||||
strcpy(pnamebuf, "EMBMn0");
|
||||
|
||||
I_Assert(em->sprite >= 'A' && em->sprite <= 'Z');
|
||||
|
||||
if (!big)
|
||||
pnamebuf[5] = em->sprite;
|
||||
else
|
||||
pnamebuf[4] = em->sprite;
|
||||
|
||||
return pnamebuf;
|
||||
}
|
||||
|
||||
|
@ -544,11 +554,21 @@ skincolors_t M_GetExtraEmblemColor(extraemblem_t *em)
|
|||
return em->color;
|
||||
}
|
||||
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em)
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big)
|
||||
{
|
||||
static char pnamebuf[7] = "GOTITn";
|
||||
static char pnamebuf[7];
|
||||
|
||||
if (!big)
|
||||
strcpy(pnamebuf, "GOTITn");
|
||||
else
|
||||
strcpy(pnamebuf, "EMBMn0");
|
||||
|
||||
I_Assert(em->sprite >= 'A' && em->sprite <= 'Z');
|
||||
|
||||
if (!big)
|
||||
pnamebuf[5] = em->sprite;
|
||||
else
|
||||
pnamebuf[4] = em->sprite;
|
||||
|
||||
return pnamebuf;
|
||||
}
|
||||
|
|
|
@ -171,9 +171,9 @@ INT32 M_CountEmblems(void);
|
|||
// Emblem shit
|
||||
emblem_t *M_GetLevelEmblems(INT32 mapnum);
|
||||
skincolors_t M_GetEmblemColor(emblem_t *em);
|
||||
const char *M_GetEmblemPatch(emblem_t *em);
|
||||
const char *M_GetEmblemPatch(emblem_t *em, boolean big);
|
||||
skincolors_t M_GetExtraEmblemColor(extraemblem_t *em);
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em);
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big);
|
||||
|
||||
// If you're looking to compare stats for unlocks or what not, use these
|
||||
// They stop checking upon reaching the target number so they
|
||||
|
|
1302
src/m_menu.c
1302
src/m_menu.c
File diff suppressed because it is too large
Load diff
26
src/m_menu.h
26
src/m_menu.h
|
@ -63,6 +63,7 @@ typedef enum
|
|||
MN_MP_CONNECT,
|
||||
MN_MP_ROOM,
|
||||
MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
||||
MN_MP_SERVER_OPTIONS,
|
||||
|
||||
// Options
|
||||
MN_OP_MAIN,
|
||||
|
@ -72,10 +73,12 @@ typedef enum
|
|||
MN_OP_P1MOUSE,
|
||||
MN_OP_P1JOYSTICK,
|
||||
MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2
|
||||
MN_OP_P1CAMERA,
|
||||
|
||||
MN_OP_P2CONTROLS,
|
||||
MN_OP_P2MOUSE,
|
||||
MN_OP_P2JOYSTICK,
|
||||
MN_OP_P2CAMERA,
|
||||
|
||||
MN_OP_VIDEO,
|
||||
MN_OP_VIDEOMODE,
|
||||
|
@ -101,6 +104,7 @@ typedef enum
|
|||
MN_SR_LEVELSELECT,
|
||||
MN_SR_UNLOCKCHECKLIST,
|
||||
MN_SR_EMBLEMHINT,
|
||||
MN_SR_PLAYER,
|
||||
|
||||
// Addons (Part of MISC, but let's make it our own)
|
||||
MN_AD_MAIN,
|
||||
|
@ -206,7 +210,6 @@ void M_QuitResponse(INT32 ch);
|
|||
// Determines whether to show a level in the list (platter version does not need to be exposed)
|
||||
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||
|
||||
|
||||
// flags for items in the menu
|
||||
// menu handle (what we do when key is pressed
|
||||
#define IT_TYPE 14 // (2+4+8)
|
||||
|
@ -242,6 +245,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
#define IT_CV_NOPRINT 1536
|
||||
#define IT_CV_NOMOD 2048
|
||||
#define IT_CV_INVISSLIDER 2560
|
||||
#define IT_CV_INTEGERSTEP 4096 // if IT_CV_NORMAL and cvar is CV_FLOAT, modify it by 1 instead of 0.0625
|
||||
#define IT_CV_FLOATSLIDER 4608 // IT_CV_SLIDER, value modified by 0.0625 instead of 1 (for CV_FLOAT cvars)
|
||||
|
||||
//call/submenu specific
|
||||
// There used to be a lot more here but ...
|
||||
|
@ -309,6 +314,10 @@ extern menu_t *currentMenu;
|
|||
extern menu_t MainDef;
|
||||
extern menu_t SP_LoadDef;
|
||||
|
||||
// Call upon joystick hotplug
|
||||
void M_SetupJoystickMenu(INT32 choice);
|
||||
extern menu_t OP_JoystickSetDef;
|
||||
|
||||
// Stuff for customizing the player select screen
|
||||
typedef struct
|
||||
{
|
||||
|
@ -316,9 +325,18 @@ typedef struct
|
|||
char notes[441];
|
||||
char picname[8];
|
||||
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
|
||||
patch_t *pic;
|
||||
patch_t *charpic;
|
||||
UINT8 prev;
|
||||
UINT8 next;
|
||||
|
||||
// new character select
|
||||
char displayname[SKINNAMESIZE+1];
|
||||
SINT8 skinnum[2];
|
||||
UINT8 oppositecolor;
|
||||
char nametag[8];
|
||||
patch_t *namepic;
|
||||
UINT8 tagtextcolor;
|
||||
UINT8 tagoutlinecolor;
|
||||
} description_t;
|
||||
|
||||
// level select platter
|
||||
|
@ -367,6 +385,7 @@ typedef struct
|
|||
|
||||
extern description_t description[MAXSKINS];
|
||||
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||
extern CV_PossibleValue_t gametype_cons_t[];
|
||||
|
||||
|
@ -397,6 +416,9 @@ void Screenshot_option_Onchange(void);
|
|||
// Addons menu updating
|
||||
void Addons_option_Onchange(void);
|
||||
|
||||
// Moviemode menu updating
|
||||
void Moviemode_option_Onchange(void);
|
||||
|
||||
// These defines make it a little easier to make menus
|
||||
#define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\
|
||||
{\
|
||||
|
|
46
src/m_misc.c
46
src/m_misc.c
|
@ -108,6 +108,9 @@ consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAV
|
|||
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
|
||||
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_movie_option = {"movie_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Moviemode_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_movie_folder = {"movie_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t zlib_mem_level_t[] = {
|
||||
{1, "(Min Memory) 1"},
|
||||
{2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"},
|
||||
|
@ -194,7 +197,7 @@ INT32 M_MapNumber(char first, char second)
|
|||
// ==========================================================================
|
||||
|
||||
// some libcs has no access function, make our own
|
||||
#if defined (_WIN32_WCE)
|
||||
#if 0
|
||||
int access(const char *path, int amode)
|
||||
{
|
||||
int accesshandle = -1;
|
||||
|
@ -1124,19 +1127,25 @@ static inline moviemode_t M_StartMovieGIF(const char *pathname)
|
|||
void M_StartMovie(void)
|
||||
{
|
||||
#if NUMSCREENS > 2
|
||||
const char *pathname = ".";
|
||||
char pathname[MAX_WADPATH];
|
||||
|
||||
if (moviemode)
|
||||
return;
|
||||
|
||||
if (cv_screenshot_option.value == 0)
|
||||
pathname = usehome ? srb2home : srb2path;
|
||||
else if (cv_screenshot_option.value == 1)
|
||||
pathname = srb2home;
|
||||
else if (cv_screenshot_option.value == 2)
|
||||
pathname = srb2path;
|
||||
else if (cv_screenshot_option.value == 3 && *cv_screenshot_folder.string != '\0')
|
||||
pathname = cv_screenshot_folder.string;
|
||||
if (cv_movie_option.value == 0)
|
||||
strcpy(pathname, usehome ? srb2home : srb2path);
|
||||
else if (cv_movie_option.value == 1)
|
||||
strcpy(pathname, srb2home);
|
||||
else if (cv_movie_option.value == 2)
|
||||
strcpy(pathname, srb2path);
|
||||
else if (cv_movie_option.value == 3 && *cv_movie_folder.string != '\0')
|
||||
strcpy(pathname, cv_movie_folder.string);
|
||||
|
||||
if (cv_movie_option.value != 3)
|
||||
{
|
||||
strcat(pathname, PATHSEP"movies"PATHSEP);
|
||||
I_mkdir(pathname, 0755);
|
||||
}
|
||||
|
||||
if (rendermode == render_none)
|
||||
I_Error("Can't make a movie without a render system\n");
|
||||
|
@ -1474,7 +1483,8 @@ void M_ScreenShot(void)
|
|||
void M_DoScreenShot(void)
|
||||
{
|
||||
#if NUMSCREENS > 2
|
||||
const char *freename = NULL, *pathname = ".";
|
||||
const char *freename = NULL;
|
||||
char pathname[MAX_WADPATH];
|
||||
boolean ret = false;
|
||||
UINT8 *linear = NULL;
|
||||
|
||||
|
@ -1486,13 +1496,19 @@ void M_DoScreenShot(void)
|
|||
return;
|
||||
|
||||
if (cv_screenshot_option.value == 0)
|
||||
pathname = usehome ? srb2home : srb2path;
|
||||
strcpy(pathname, usehome ? srb2home : srb2path);
|
||||
else if (cv_screenshot_option.value == 1)
|
||||
pathname = srb2home;
|
||||
strcpy(pathname, srb2home);
|
||||
else if (cv_screenshot_option.value == 2)
|
||||
pathname = srb2path;
|
||||
strcpy(pathname, srb2path);
|
||||
else if (cv_screenshot_option.value == 3 && *cv_screenshot_folder.string != '\0')
|
||||
pathname = cv_screenshot_folder.string;
|
||||
strcpy(pathname, cv_screenshot_folder.string);
|
||||
|
||||
if (cv_screenshot_option.value != 3)
|
||||
{
|
||||
strcat(pathname, PATHSEP"screenshots"PATHSEP);
|
||||
I_mkdir(pathname, 0755);
|
||||
}
|
||||
|
||||
#ifdef USE_PNG
|
||||
freename = Newsnapshotfile(pathname,"png");
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef enum {
|
|||
extern moviemode_t moviemode;
|
||||
|
||||
extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_colorprofile;
|
||||
extern consvar_t cv_moviemode;
|
||||
extern consvar_t cv_moviemode, cv_movie_folder, cv_movie_option;
|
||||
extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits;
|
||||
extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa;
|
||||
extern consvar_t cv_apng_delay;
|
||||
|
|
42
src/m_swap.h
42
src/m_swap.h
|
@ -14,29 +14,39 @@
|
|||
#ifndef __M_SWAP__
|
||||
#define __M_SWAP__
|
||||
|
||||
#include "endian.h"
|
||||
|
||||
// Endianess handling.
|
||||
// WAD files are stored little endian.
|
||||
#include "endian.h"
|
||||
|
||||
// Little to big endian
|
||||
#ifdef SRB2_BIG_ENDIAN
|
||||
|
||||
#define SHORT(x) ((INT16)(\
|
||||
(((UINT16)(x) & (UINT16)0x00ffU) << 8) \
|
||||
| \
|
||||
(((UINT16)(x) & (UINT16)0xff00U) >> 8))) \
|
||||
#define SHORT(x) ((INT16)(\
|
||||
(((UINT16)(x) & (UINT16)0x00ffU) << 8) \
|
||||
| \
|
||||
(((UINT16)(x) & (UINT16)0xff00U) >> 8))) \
|
||||
|
||||
#define LONG(x) ((INT32)(\
|
||||
(((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x00ff0000UL) >> 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0xff000000UL) >> 24)))
|
||||
#define LONG(x) ((INT32)(\
|
||||
(((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0x00ff0000UL) >> 8) \
|
||||
| \
|
||||
(((UINT32)(x) & (UINT32)0xff000000UL) >> 24)))
|
||||
|
||||
#else
|
||||
#define SHORT(x) ((INT16)(x))
|
||||
#define LONG(x) ((INT32)(x))
|
||||
#define SHORT(x) ((INT16)(x))
|
||||
#define LONG(x) ((INT32)(x))
|
||||
#endif
|
||||
|
||||
// Big to little endian
|
||||
#ifdef SRB2_LITTLE_ENDIAN
|
||||
#define BIGENDIAN_LONG(x) ((INT32)(((x)>>24)&0xff)|(((x)<<8)&0xff0000)|(((x)>>8)&0xff00)|(((x)<<24)&0xff000000))
|
||||
#define BIGENDIAN_SHORT(x) ((INT16)(((x)>>8)|((x)<<8)))
|
||||
#else
|
||||
#define BIGENDIAN_LONG(x) ((INT32)(x))
|
||||
#define BIGENDIAN_SHORT(x) ((INT16)(x))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
591
src/p_enemy.c
591
src/p_enemy.c
|
@ -170,6 +170,7 @@ void A_SetReactionTime(mobj_t *actor);
|
|||
void A_Boss1Spikeballs(mobj_t *actor);
|
||||
void A_Boss3TakeDamage(mobj_t *actor);
|
||||
void A_Boss3Path(mobj_t *actor);
|
||||
void A_Boss3ShockThink(mobj_t *actor);
|
||||
void A_LinedefExecute(mobj_t *actor);
|
||||
void A_PlaySeeSound(mobj_t *actor);
|
||||
void A_PlayAttackSound(mobj_t *actor);
|
||||
|
@ -282,6 +283,7 @@ void A_Boss5CheckOnGround(mobj_t *actor);
|
|||
void A_Boss5CheckFalling(mobj_t *actor);
|
||||
void A_Boss5PinchShot(mobj_t *actor);
|
||||
void A_Boss5MakeItRain(mobj_t *actor);
|
||||
void A_Boss5MakeJunk(mobj_t *actor);
|
||||
void A_LookForBetter(mobj_t *actor);
|
||||
void A_Boss5BombExplode(mobj_t *actor);
|
||||
void A_DustDevilThink(mobj_t *actor);
|
||||
|
@ -296,6 +298,14 @@ void A_SnapperThinker(mobj_t *actor);
|
|||
void A_SaloonDoorSpawn(mobj_t *actor);
|
||||
void A_MinecartSparkThink(mobj_t *actor);
|
||||
void A_ModuloToState(mobj_t *actor);
|
||||
void A_LavafallRocks(mobj_t *actor);
|
||||
void A_LavafallLava(mobj_t *actor);
|
||||
void A_FallingLavaCheck(mobj_t *actor);
|
||||
void A_FireShrink(mobj_t *actor);
|
||||
void A_SpawnPterabytes(mobj_t *actor);
|
||||
void A_PterabyteHover(mobj_t *actor);
|
||||
void A_RolloutSpawn(mobj_t *actor);
|
||||
void A_RolloutRock(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
|
@ -2017,6 +2027,7 @@ void A_CrushstaceanWalk(mobj_t *actor)
|
|||
|| (actor->reactiontime-- <= 0))
|
||||
{
|
||||
actor->flags2 ^= MF2_AMBUSH;
|
||||
P_SetTarget(&actor->target, NULL);
|
||||
P_SetMobjState(actor, locvar2);
|
||||
actor->reactiontime = actor->info->reactiontime;
|
||||
}
|
||||
|
@ -2077,7 +2088,7 @@ void A_CrushclawAim(mobj_t *actor)
|
|||
return; // there is only one step and it is crab
|
||||
}
|
||||
|
||||
if (crab->target || P_LookForPlayers(crab, true, false, 600*crab->scale))
|
||||
if (crab->target || P_LookForPlayers(crab, true, false, actor->info->speed*crab->scale))
|
||||
ang = R_PointToAngle2(crab->x, crab->y, crab->target->x, crab->target->y);
|
||||
else
|
||||
ang = crab->angle + ((crab->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);
|
||||
|
@ -2160,7 +2171,7 @@ void A_CrushclawLaunch(mobj_t *actor)
|
|||
UINT8 i = 0;
|
||||
for (i = 0; (i < CSEGS); i++)
|
||||
{
|
||||
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate);
|
||||
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, (mobjtype_t)actor->info->raisestate);
|
||||
P_SetTarget(&prevchain->target, newchain);
|
||||
prevchain = newchain;
|
||||
}
|
||||
|
@ -3027,10 +3038,15 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
if (!actor->target)
|
||||
return;
|
||||
|
||||
if (actor->state->tics > 1)
|
||||
dur = actor->tics;
|
||||
else
|
||||
{
|
||||
if ((upperend & 1) && (actor->extravalue2 > 1))
|
||||
actor->extravalue2--;
|
||||
|
||||
dur = actor->extravalue2;
|
||||
}
|
||||
|
||||
switch (locvar2)
|
||||
{
|
||||
|
@ -3076,22 +3092,14 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);
|
||||
if (mobjinfo[locvar1].seesound)
|
||||
S_StartSound(actor, mobjinfo[locvar1].seesound);
|
||||
if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
||||
{
|
||||
|
||||
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
|
||||
point->angle = actor->angle;
|
||||
point->fuse = dur+1;
|
||||
P_SetTarget(&point->target, actor->target);
|
||||
P_SetTarget(&actor->target, point);
|
||||
}
|
||||
}
|
||||
/* -- the following was relevant when the MT_EGGMOBILE_TARGET was allowed to move left and right from its path
|
||||
else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
||||
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/
|
||||
|
||||
/*if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)
|
||||
angle = FixedAngle(FixedDiv(dur*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT);
|
||||
else*/
|
||||
angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y));
|
||||
|
||||
point = P_SpawnMobj(x, y, z, locvar1);
|
||||
|
@ -4028,13 +4036,17 @@ bossjustdie:
|
|||
}
|
||||
case MT_FANG:
|
||||
{
|
||||
if (mo->flags2 & MF2_SLIDEPUSH)
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return;
|
||||
}
|
||||
if (mo->tracer)
|
||||
{
|
||||
var1 = var2 = 0;
|
||||
A_Boss5Jump(mo);
|
||||
mo->momx = ((16 - 1)*mo->momx)/16;
|
||||
mo->momy = ((16 - 1)*mo->momy)/16;
|
||||
if (!(mo->flags2 & MF2_AMBUSH))
|
||||
{
|
||||
const fixed_t time = FixedHypot(mo->tracer->x - mo->x, mo->tracer->y - mo->y)/FixedHypot(mo->momx, mo->momy);
|
||||
const fixed_t speed = 64*FRACUNIT;
|
||||
|
@ -5340,20 +5352,22 @@ static mobj_t *minus;
|
|||
|
||||
static boolean PIT_MinusCarry(mobj_t *thing)
|
||||
{
|
||||
if (minus->tracer)
|
||||
return true;
|
||||
|
||||
if (minus->type == thing->type)
|
||||
return true;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE) || !(thing->flags & MF_ENEMY))
|
||||
if (!(thing->flags & (MF_PUSHABLE|MF_ENEMY)))
|
||||
return true;
|
||||
|
||||
if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius * 3)
|
||||
if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3)
|
||||
return true;
|
||||
|
||||
if (abs(thing->z - minus->z) > minus->height)
|
||||
return true;
|
||||
|
||||
P_SetTarget(&minus->tracer, thing);
|
||||
minus->tracer->flags &= ~MF_PUSHABLE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5417,6 +5431,9 @@ void A_MinusDigging(mobj_t *actor)
|
|||
A_Chase(actor);
|
||||
|
||||
// Carry over shit, maybe
|
||||
if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
|
||||
if (!actor->tracer)
|
||||
{
|
||||
fixed_t radius = 3*actor->radius;
|
||||
|
@ -5466,7 +5483,6 @@ void A_MinusPopup(mobj_t *actor)
|
|||
else
|
||||
actor->momz = 10*FRACUNIT;
|
||||
|
||||
actor->flags |= MF_SPECIAL|MF_SHOOTABLE;
|
||||
S_StartSound(actor, sfx_s3k82);
|
||||
for (i = 1; i <= num; i++)
|
||||
{
|
||||
|
@ -5479,6 +5495,7 @@ void A_MinusPopup(mobj_t *actor)
|
|||
if (actor->tracer)
|
||||
P_DamageMobj(actor->tracer, actor, actor, 1, 0);
|
||||
|
||||
actor->flags = (actor->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE;
|
||||
}
|
||||
|
||||
// Function: A_MinusCheck
|
||||
|
@ -8079,6 +8096,57 @@ void A_Boss3Path(mobj_t *actor)
|
|||
}
|
||||
}
|
||||
|
||||
// Function: A_Boss3ShockThink
|
||||
//
|
||||
// Description: Inserts new interstitial shockwave objects when the space between others spreads too much.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_Boss3ShockThink(mobj_t *actor)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_Boss3ShockThink", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->momx || actor->momy)
|
||||
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy) + ANGLE_90;
|
||||
|
||||
if (actor->hnext && !P_MobjWasRemoved(actor->hnext))
|
||||
{
|
||||
mobj_t *snext = actor->hnext;
|
||||
mobj_t *snew;
|
||||
fixed_t x0, y0, x1, y1;
|
||||
|
||||
// Break the link if movements are too different
|
||||
if (FixedHypot(snext->momx - actor->momx, snext->momy - actor->momy) > 12*actor->scale)
|
||||
{
|
||||
P_SetTarget(&actor->hnext, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check distance between shockwave objects to determine whether interstitial ones should be spawned
|
||||
x0 = actor->x;
|
||||
y0 = actor->y;
|
||||
x1 = snext->x;
|
||||
y1 = snext->y;
|
||||
if (FixedHypot(x1 - x0, y1 - y0) > 2*actor->radius)
|
||||
{
|
||||
snew = P_SpawnMobj((x0 + x1) >> 1, (y0 + y1) >> 1, (actor->z + snext->z) >> 1, actor->type);
|
||||
snew->momx = (actor->momx + snext->momx) >> 1;
|
||||
snew->momy = (actor->momy + snext->momy) >> 1;
|
||||
snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed?
|
||||
snew->angle = (actor->angle + snext->angle) >> 1;
|
||||
P_SetTarget(&snew->target, actor->target);
|
||||
snew->fuse = actor->fuse;
|
||||
|
||||
P_SetTarget(&actor->hnext, snew);
|
||||
P_SetTarget(&snew->hnext, snext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_LinedefExecute
|
||||
//
|
||||
// Description: Object's location is used to set the calling sector. The tag used is var1. Optionally, if var2 is set, the actor's angle (multiplied by var2) is added to the tag number as well.
|
||||
|
@ -8354,8 +8422,8 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
|
|||
//
|
||||
// var1 = sound # to play
|
||||
// var2:
|
||||
// 0 = Play sound without an origin
|
||||
// 1 = Play sound using calling object as origin
|
||||
// lower 16 bits = If 1, play sound using calling object as origin. If 0, play sound without an origin
|
||||
// upper 16 bits = If 1, do not play sound during preticker.
|
||||
//
|
||||
void A_PlaySound(mobj_t *actor)
|
||||
{
|
||||
|
@ -8366,7 +8434,10 @@ void A_PlaySound(mobj_t *actor)
|
|||
return;
|
||||
#endif
|
||||
|
||||
S_StartSound(locvar2 ? actor : NULL, locvar1);
|
||||
if (leveltime < 2 && (locvar2 >> 16))
|
||||
return;
|
||||
|
||||
S_StartSound((locvar2 & 65535) ? actor : NULL, locvar1);
|
||||
}
|
||||
|
||||
// Function: A_FindTarget
|
||||
|
@ -12143,7 +12214,7 @@ void A_MineExplode(mobj_t *actor)
|
|||
#undef dist
|
||||
|
||||
if (actor->watertop != INT32_MAX)
|
||||
P_SpawnMobj(actor->x, actor->y, actor->watertop, MT_SPLISH);
|
||||
P_SpawnMobj(actor->x, actor->y, actor->watertop, (actor->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12183,7 +12254,6 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
mobj_t *work;
|
||||
fixed_t workz;
|
||||
fixed_t workh;
|
||||
SINT8 dir;
|
||||
angle_t ang;
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
|
@ -12197,23 +12267,17 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
P_AdjustMobjFloorZ_FFloors(actor, actor->subsector->sector, 2);
|
||||
|
||||
if (actor->flags2 & MF2_OBJECTFLIP)
|
||||
{
|
||||
workz = actor->ceilingz - (actor->z + actor->height);
|
||||
dir = -1;
|
||||
}
|
||||
workz = (actor->z + actor->height) - actor->ceilingz;
|
||||
else
|
||||
{
|
||||
workz = actor->floorz - actor->z;
|
||||
dir = 1;
|
||||
}
|
||||
|
||||
if (locvar2)
|
||||
{
|
||||
workh = FixedMul(mobjinfo[locvar2].height, actor->scale);
|
||||
if (actor->flags2 & MF2_OBJECTFLIP)
|
||||
workz -= workh;
|
||||
workz += workh;
|
||||
work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar2);
|
||||
workz += dir*workh;
|
||||
workz += workh;
|
||||
}
|
||||
|
||||
if (!locvar1)
|
||||
|
@ -12222,21 +12286,18 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
if (!(workh = FixedMul(mobjinfo[locvar1].height, actor->scale)))
|
||||
return;
|
||||
|
||||
if (actor->flags2 & MF2_OBJECTFLIP)
|
||||
workz -= workh;
|
||||
|
||||
ang = actor->angle + ANGLE_45;
|
||||
while (dir*workz < 0)
|
||||
while (workz < 0)
|
||||
{
|
||||
work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1);
|
||||
if (work)
|
||||
work->angle = ang;
|
||||
ang += ANGLE_90;
|
||||
workz += dir*workh;
|
||||
workz += workh;
|
||||
}
|
||||
|
||||
if (workz != 0)
|
||||
actor->z += workz;
|
||||
actor->z += P_MobjFlip(actor)*workz;
|
||||
}
|
||||
|
||||
// Function: A_SpawnParticleRelative
|
||||
|
@ -12978,6 +13039,100 @@ void A_Boss5MakeItRain(mobj_t *actor)
|
|||
actor->extravalue2 = 0;
|
||||
}
|
||||
|
||||
// Function: A_Boss5MakeJunk
|
||||
//
|
||||
// Description: Make a mess.
|
||||
//
|
||||
// var1 = state # to set on MT_BROKENROBOT (if 0 do nothing, if -1 go to if colorized)
|
||||
// var2 = mode (-1 = spin, 0 = make 1, & 1 make 8, & 2 alart mode)
|
||||
//
|
||||
void A_Boss5MakeJunk(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
mobj_t *broked;
|
||||
angle_t ang;
|
||||
INT32 i = ((locvar2 & 1) ? 8 : 1);
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_Boss5MakeJunk", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (locvar1 < 0 && (actor->flags2 & MF2_SLIDEPUSH)) // this entire action is a hack, don't judge me
|
||||
{
|
||||
INT32 curextravalue2 = actor->extravalue2;
|
||||
P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_PROJECTORLIGHT);
|
||||
actor->z += P_MobjFlip(actor)*actor->height;
|
||||
actor->flags |= MF_NOGRAVITY;
|
||||
S_StartSound(actor, sfx_vwre);
|
||||
actor->extravalue2 = 49;
|
||||
P_SetMobjState(actor, -locvar1);
|
||||
actor->extravalue2 = curextravalue2;
|
||||
actor->angle -= FixedAngle((49*45)<<FRACBITS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (locvar2 == -1)
|
||||
{
|
||||
INT32 trans = (10*actor->extravalue2)/50;
|
||||
if (trans > 9)
|
||||
trans = 9;
|
||||
if (trans < 0)
|
||||
trans = 0;
|
||||
if (!(actor->extravalue2 & 1))
|
||||
{
|
||||
if (actor->extravalue2 > 10)
|
||||
{
|
||||
mobj_t *front = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_VWREF);
|
||||
broked = P_SpawnMobjFromMobj(front, 0, 0, 0, MT_VWREB);
|
||||
front->z = broked->z = front->z - broked->height;
|
||||
P_SetObjectMomZ(front, (4<<FRACBITS), false);
|
||||
broked->momz = front->momz;
|
||||
broked->fuse = front->fuse = (actor->height+(2*front->height))/front->momz;
|
||||
}
|
||||
if (!(actor->colorized = !actor->colorized))
|
||||
actor->frame |= FF_FULLBRIGHT;
|
||||
}
|
||||
actor->angle += ANGLE_45;
|
||||
actor->frame = (actor->frame & ~FF_TRANSMASK)|(trans<<FF_TRANSSHIFT);
|
||||
return;
|
||||
}
|
||||
|
||||
ang = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
|
||||
while (i--)
|
||||
{
|
||||
broked = P_SpawnMobjFromMobj(actor, 0, 0, FRACUNIT, MT_BROKENROBOT);
|
||||
if (locvar2 & 2)
|
||||
broked->fuse = TICRATE;
|
||||
else
|
||||
broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3;
|
||||
broked->angle = ang;
|
||||
P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale);
|
||||
P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))<<FRACBITS, false);
|
||||
if (locvar1 > 0)
|
||||
P_SetMobjState(broked, locvar1);
|
||||
if (!P_MobjWasRemoved(broked))
|
||||
P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
|
||||
ang += ANGLE_45;
|
||||
}
|
||||
|
||||
if (locvar2 & 2)
|
||||
{
|
||||
broked = P_SpawnMobjFromMobj(actor, 0, 0, 64<<FRACBITS, MT_GHOST);
|
||||
S_StartSound(broked, sfx_alart);
|
||||
broked->fuse = states[S_FANG_INTRO12].tics+10;
|
||||
P_SetMobjState(broked, S_ALART1);
|
||||
}
|
||||
else if (locvar2 & 1)
|
||||
{
|
||||
broked->z += broked->momz;
|
||||
S_StartSound(actor, sfx_s3kccs);
|
||||
actor->flags &= ~MF_NOCLIPTHING;
|
||||
}
|
||||
else
|
||||
S_StartSound(actor, sfx_s3kd3s);
|
||||
}
|
||||
|
||||
// Function: A_LookForBetter
|
||||
//
|
||||
// Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer.
|
||||
|
@ -13104,11 +13259,14 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
|
|||
if (dustdevil->height - pos > thresh)
|
||||
{
|
||||
fixed_t dist = FixedHypot(thing->x - dustdevil->x, thing->y - dustdevil->y);
|
||||
fixed_t dragamount = 6 * FRACUNIT;
|
||||
fixed_t dragamount = player->speed;
|
||||
fixed_t x, y;
|
||||
|
||||
if (player->powers[pw_nocontrol] == 0)
|
||||
{
|
||||
P_ResetPlayer(player);
|
||||
A_PlayActiveSound(dustdevil);
|
||||
}
|
||||
player->powers[pw_nocontrol] = 2;
|
||||
player->drawangle += ANG20;
|
||||
P_SetPlayerMobjState(thing, S_PLAY_PAIN);
|
||||
|
@ -13304,6 +13462,13 @@ void A_TNTExplode(mobj_t *actor)
|
|||
if (LUA_CallAction("A_TNTExplode", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->tracer)
|
||||
{
|
||||
P_SetTarget(&actor->tracer->tracer, NULL);
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
}
|
||||
|
||||
P_UnsetThingPosition(actor);
|
||||
if (sector_list)
|
||||
{
|
||||
|
@ -13517,8 +13682,6 @@ void A_KillSegments(mobj_t *actor)
|
|||
static void P_SnapperLegPlace(mobj_t *mo)
|
||||
{
|
||||
mobj_t *seg = mo->tracer;
|
||||
fixed_t x0 = mo->x;
|
||||
fixed_t y0 = mo->y;
|
||||
angle_t a = mo->angle;
|
||||
angle_t fa = (a >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FINECOSINE(fa);
|
||||
|
@ -13533,7 +13696,8 @@ static void P_SnapperLegPlace(mobj_t *mo)
|
|||
fixed_t rad = mo->radius;
|
||||
INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU
|
||||
|
||||
P_TeleportMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, mo->z + mo->height/3);
|
||||
seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3);
|
||||
P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true);
|
||||
seg->angle = a;
|
||||
|
||||
// Move as many legs as available.
|
||||
|
@ -13553,13 +13717,14 @@ static void P_SnapperLegPlace(mobj_t *mo)
|
|||
{
|
||||
x = c*o2 + s*o1;
|
||||
y = s*o2 - c*o1;
|
||||
P_TryMove(seg, x0 + x, y0 + y, true);
|
||||
seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0));
|
||||
P_TryMove(seg, mo->x + x, mo->y + y, true);
|
||||
P_SetMobjState(seg, seg->info->raisestate);
|
||||
}
|
||||
else
|
||||
P_SetMobjState(seg, seg->info->spawnstate);
|
||||
|
||||
seg->angle = R_PointToAngle2(x0, y0, seg->x, seg->y);
|
||||
seg->angle = R_PointToAngle2(mo->x, mo->y, seg->x, seg->y);
|
||||
|
||||
seg = seg->tracer;
|
||||
} while (seg);
|
||||
|
@ -13587,14 +13752,14 @@ void A_SnapperSpawn(mobj_t *actor)
|
|||
#endif
|
||||
|
||||
// It spawns 1 head.
|
||||
seg = P_SpawnMobj(actor->x, actor->y, actor->z, headtype);
|
||||
seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, headtype);
|
||||
P_SetTarget(&ptr->tracer, seg);
|
||||
ptr = seg;
|
||||
|
||||
// It spawns 4 legs which will be handled in the thinker function.
|
||||
for (i = 1; i <= 4; i++)
|
||||
{
|
||||
seg = P_SpawnMobj(actor->x, actor->y, actor->z, legtype);
|
||||
seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, legtype);
|
||||
P_SetTarget(&ptr->tracer, seg);
|
||||
ptr = seg;
|
||||
|
||||
|
@ -13742,51 +13907,43 @@ void A_SnapperThinker(mobj_t *actor)
|
|||
//
|
||||
// Description: Spawns a saloon door.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
// var1 = mobjtype for sides
|
||||
// var2 = distance sides should be placed apart
|
||||
//
|
||||
void A_SaloonDoorSpawn(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
angle_t ang = actor->angle;
|
||||
angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FINECOSINE(fa);
|
||||
fixed_t s = FINESINE(fa);
|
||||
INT32 d = 48;
|
||||
fixed_t x = actor->x;
|
||||
fixed_t y = actor->y;
|
||||
fixed_t z = actor->z;
|
||||
fixed_t c = FINECOSINE(fa)*locvar2;
|
||||
fixed_t s = FINESINE(fa)*locvar2;
|
||||
mobj_t *door;
|
||||
mobjflag2_t ambush = (actor->flags & MF2_AMBUSH);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SaloonDoorSpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
//Front
|
||||
door = P_SpawnMobj(x + c*d, y + s*d, z, MT_SALOONDOOR);
|
||||
if (!locvar1)
|
||||
return;
|
||||
|
||||
// One door...
|
||||
if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return;
|
||||
door->angle = ang + ANGLE_180;
|
||||
door->extravalue1 = AngleFixed(door->angle); // Origin angle
|
||||
door->extravalue2 = 0; // Angular speed
|
||||
P_SetTarget(&door->tracer, actor); // Origin door
|
||||
door->flags2 |= ambush; // Can be opened by normal players?
|
||||
|
||||
// Origin angle
|
||||
door->extravalue1 = AngleFixed(door->angle);
|
||||
|
||||
// Angular speed
|
||||
door->extravalue2 = 0;
|
||||
|
||||
// Origin door
|
||||
P_SetTarget(&door->tracer, actor);
|
||||
|
||||
//Back
|
||||
door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR);
|
||||
// ...two door!
|
||||
if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return;
|
||||
door->angle = ang;
|
||||
|
||||
// Origin angle
|
||||
door->extravalue1 = AngleFixed(door->angle);
|
||||
|
||||
// Angular speed
|
||||
door->extravalue2 = 0;
|
||||
|
||||
// Origin door
|
||||
P_SetTarget(&door->tracer, actor);
|
||||
door->extravalue1 = AngleFixed(door->angle); // Origin angle
|
||||
door->extravalue2 = 0; // Angular speed
|
||||
P_SetTarget(&door->tracer, actor); // Origin door
|
||||
door->flags2 |= ambush; // Can be opened by normal players?
|
||||
}
|
||||
|
||||
// Function: A_MinecartSparkThink
|
||||
|
@ -13847,3 +14004,289 @@ void A_ModuloToState(mobj_t *actor)
|
|||
P_SetMobjState(actor, (locvar2));
|
||||
modulothing++;
|
||||
}
|
||||
|
||||
// Function: A_LavafallRocks
|
||||
//
|
||||
// Description: Spawn random rock particles.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_LavafallRocks(mobj_t *actor)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_LavafallRocks", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Don't spawn rocks unless a player is relatively close by.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i] && players[i].mo
|
||||
&& P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (1600 << FRACBITS))
|
||||
break; // Stop looking.
|
||||
|
||||
if (i < MAXPLAYERS)
|
||||
{
|
||||
angle_t fa = (FixedAngle(P_RandomKey(360) << FRACBITS) >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t offset = P_RandomRange(4, 12) << FRACBITS;
|
||||
fixed_t xoffs = FixedMul(FINECOSINE(fa), actor->radius + offset);
|
||||
fixed_t yoffs = FixedMul(FINESINE(fa), actor->radius + offset);
|
||||
P_SpawnMobjFromMobj(actor, xoffs, yoffs, 0, MT_LAVAFALLROCK);
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_LavafallLava
|
||||
//
|
||||
// Description: Spawn lava from lavafall.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_LavafallLava(mobj_t *actor)
|
||||
{
|
||||
mobj_t *lavafall;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_LavafallLava", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ((40 - actor->fuse) % (2*(actor->scale >> FRACBITS)))
|
||||
return;
|
||||
|
||||
lavafall = P_SpawnMobjFromMobj(actor, 0, 0, -8*FRACUNIT, MT_LAVAFALL_LAVA);
|
||||
lavafall->momz = -P_MobjFlip(actor)*25*FRACUNIT;
|
||||
}
|
||||
|
||||
// Function: A_FallingLavaCheck
|
||||
//
|
||||
// Description: If actor hits the ground or a water surface, enter the death animation.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_FallingLavaCheck(mobj_t *actor)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_FallingLavaCheck", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->eflags & MFE_TOUCHWATER || P_IsObjectOnGround(actor))
|
||||
{
|
||||
actor->flags = MF_NOGRAVITY|MF_NOCLIPTHING;
|
||||
actor->momz = 0;
|
||||
if (actor->eflags & MFE_TOUCHWATER)
|
||||
actor->z = (actor->eflags & MFE_VERTICALFLIP) ? actor->waterbottom : actor->watertop;
|
||||
P_SetMobjState(actor, actor->info->deathstate);
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_FireShrink
|
||||
//
|
||||
// Description: Shrink the actor down to the specified scale at the specified speed.
|
||||
//
|
||||
// var1 = Scale to shrink to
|
||||
// var2 = Shrinking speed
|
||||
//
|
||||
void A_FireShrink(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_FireShrink", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
actor->destscale = locvar1;
|
||||
actor->scalespeed = FRACUNIT/locvar2;
|
||||
}
|
||||
|
||||
// Function: A_SpawnPterabytes
|
||||
//
|
||||
// Description: Spawn Pterabytes around the actor in a circle.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_SpawnPterabytes(mobj_t *actor)
|
||||
{
|
||||
mobj_t *waypoint, *ptera;
|
||||
fixed_t c, s;
|
||||
fixed_t rad = 280*FRACUNIT;
|
||||
angle_t ang = 0;
|
||||
angle_t interval, fa;
|
||||
UINT8 amount = 1;
|
||||
UINT8 i;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SpawnPterabytes", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->spawnpoint)
|
||||
amount = actor->spawnpoint->extrainfo + 1;
|
||||
|
||||
interval = FixedAngle(FRACUNIT*360/amount);
|
||||
|
||||
for (i = 0; i < amount; i++)
|
||||
{
|
||||
fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
c = FINECOSINE(fa);
|
||||
s = FINESINE(fa);
|
||||
waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT);
|
||||
waypoint->angle = ang + ANGLE_90;
|
||||
P_SetTarget(&waypoint->tracer, actor);
|
||||
ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE);
|
||||
ptera->angle = waypoint->angle;
|
||||
P_SetTarget(&ptera->tracer, waypoint);
|
||||
ptera->extravalue1 = 0;
|
||||
ang += interval;
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_PterabyteHover
|
||||
//
|
||||
// Description: Hover in a circular fashion, bobbing up and down slightly.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_PterabyteHover(mobj_t *actor)
|
||||
{
|
||||
angle_t ang, fa;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_PterabyteHover", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
P_InstaThrust(actor, actor->angle, actor->info->speed);
|
||||
actor->angle += ANG1;
|
||||
actor->extravalue1 = (actor->extravalue1 + 3) % 360;
|
||||
ang = actor->extravalue1*ANG1;
|
||||
fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
actor->z += FINESINE(fa);
|
||||
}
|
||||
// Function: A_RolloutSpawn
|
||||
//
|
||||
// Description: Spawns a new Rollout Rock when the currently spawned rock is destroyed or moves far enough away.
|
||||
//
|
||||
// var1 = Distance currently spawned rock should travel before spawning a new one
|
||||
// var2 = Object type to spawn
|
||||
//
|
||||
void A_RolloutSpawn(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_RolloutSpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!(actor->target)
|
||||
|| P_MobjWasRemoved(actor->target)
|
||||
|| P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1)
|
||||
{
|
||||
actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2);
|
||||
actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH;
|
||||
actor->target->eflags |= (actor->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
if (actor->target->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
actor->target->color = SKINCOLOR_SUPERRUST3;
|
||||
actor->target->colorized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_RolloutRock
|
||||
//
|
||||
// Description: Thinker for Rollout Rock.
|
||||
//
|
||||
// var1 = Drag
|
||||
// var2 = Vertical bobbing speed factor
|
||||
//
|
||||
void A_RolloutRock(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through
|
||||
fixed_t pi = (22*FRACUNIT/7);
|
||||
fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame
|
||||
fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale);
|
||||
boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_RolloutRock", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves
|
||||
|
||||
if (actor->threshold)
|
||||
actor->threshold--;
|
||||
|
||||
if (inwater && !(actor->flags2 & MF2_AMBUSH)) // buoyancy in water (or lava)
|
||||
{
|
||||
UINT8 flip = P_MobjFlip(actor);
|
||||
fixed_t prevmomz = actor->momz;
|
||||
actor->momz = FixedMul(actor->momz, locvar2);
|
||||
actor->momz += flip * FixedMul(locvar2, actor->scale);
|
||||
if (flip*prevmomz < 0 && flip*actor->momz >= 0 && !actor->threshold)
|
||||
{
|
||||
if (actor->eflags & MFE_UNDERWATER)
|
||||
S_StartSound(actor, sfx_splash);
|
||||
else if (!actor->threshold)
|
||||
S_StartSound(actor, sfx_splish);
|
||||
actor->threshold = max((topspeed - speed) >> FRACBITS, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (speed > topspeed) // cap speed
|
||||
{
|
||||
actor->momx = FixedMul(FixedDiv(actor->momx, speed), topspeed);
|
||||
actor->momy = FixedMul(FixedDiv(actor->momy, speed), topspeed);
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(actor) || inwater) // apply drag to speed (compensates for lack of friction but also works in liquids)
|
||||
{
|
||||
actor->momx = FixedMul(actor->momx, locvar1);
|
||||
actor->momy = FixedMul(actor->momy, locvar1);
|
||||
}
|
||||
|
||||
speed = P_AproxDistance(actor->momx, actor->momy); // recalculate speed for visual rolling
|
||||
|
||||
if (speed < actor->scale >> 1) // stop moving if speed is insignificant
|
||||
{
|
||||
actor->momx = 0;
|
||||
actor->momy = 0;
|
||||
}
|
||||
else if (speed > actor->scale)
|
||||
{
|
||||
actor->movecount = 1; // rock has moved; fuse should be set so we don't have a trillion rocks lying around
|
||||
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); // set rock's angle to movement direction
|
||||
actor->movefactor += speed;
|
||||
if (actor->movefactor > circumference / maxframes) // if distance moved is enough to change frame, change it!
|
||||
{
|
||||
actor->reactiontime++;
|
||||
actor->reactiontime %= maxframes;
|
||||
actor->movefactor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
actor->frame = actor->reactiontime % maxframes; // set frame
|
||||
|
||||
if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear
|
||||
actor->fuse = 0;
|
||||
else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse
|
||||
actor->fuse = actor->info->painchance;
|
||||
|
||||
if (actor->fuse && actor->fuse < 2*TICRATE)
|
||||
actor->flags2 ^= MF2_DONTDRAW;
|
||||
|
||||
}
|
||||
|
|
|
@ -1778,6 +1778,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
|
|||
case MT_RAIN:
|
||||
case MT_SNOWFLAKE:
|
||||
case MT_SPLISH:
|
||||
case MT_LAVASPLISH:
|
||||
case MT_SMOKE:
|
||||
case MT_SMALLBUBBLE:
|
||||
case MT_MEDIUMBUBBLE:
|
||||
|
@ -2424,7 +2425,7 @@ void T_RaiseSector(levelspecthink_t *raise)
|
|||
mobj_t *thing;
|
||||
sector_t *sector;
|
||||
INT32 i;
|
||||
boolean playeronme = false;
|
||||
boolean playeronme = false, active = false;
|
||||
fixed_t ceilingdestination, floordestination;
|
||||
result_e res = 0;
|
||||
|
||||
|
@ -2459,7 +2460,52 @@ void T_RaiseSector(levelspecthink_t *raise)
|
|||
}
|
||||
}
|
||||
|
||||
if (raise->vars[9]) // Dynamically Sinking Platform^tm
|
||||
{
|
||||
#define shaketime 10
|
||||
if (raise->vars[11] > shaketime) // State: moving
|
||||
{
|
||||
if (playeronme) // If player is standing on the platform, accelerate
|
||||
{
|
||||
raise->vars[10] += (FRACUNIT >> 5);
|
||||
}
|
||||
else // otherwise, decelerate until inflection
|
||||
{
|
||||
raise->vars[10] -= FRACUNIT >> 3;
|
||||
if (raise->vars[10] <= 0) // inflection!
|
||||
{
|
||||
raise->vars[10] = 0;
|
||||
raise->vars[11] = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese)
|
||||
}
|
||||
}
|
||||
active = raise->vars[10] > 0;
|
||||
}
|
||||
else // State: shaking
|
||||
{
|
||||
if (playeronme || raise->vars[11])
|
||||
{
|
||||
active = true;
|
||||
if (++raise->vars[11] > shaketime)
|
||||
{
|
||||
if (playeronme)
|
||||
raise->vars[10] = FRACUNIT >> 5;
|
||||
else
|
||||
raise->vars[10] = FRACUNIT << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
raise->vars[10] = ((shaketime/2) - raise->vars[11]) << FRACBITS;
|
||||
if (raise->vars[10] < -raise->vars[2]/2)
|
||||
raise->vars[10] = -raise->vars[2]/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef shaketime
|
||||
}
|
||||
else // Air bobbing platform (not a Dynamically Sinking Platform^tm)
|
||||
active = playeronme;
|
||||
|
||||
if (active)
|
||||
{
|
||||
raise->vars[3] = raise->vars[2];
|
||||
|
||||
|
@ -2553,6 +2599,8 @@ void T_RaiseSector(levelspecthink_t *raise)
|
|||
raise->vars[3] = origspeed;
|
||||
}
|
||||
|
||||
raise->vars[3] += raise->vars[10];
|
||||
|
||||
res = T_MovePlane
|
||||
(
|
||||
raise->sector, // sector
|
||||
|
|
|
@ -428,7 +428,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|| special->state == &states[S_FANG_BOUNCE4]
|
||||
|| special->state == &states[S_FANG_PINCHBOUNCE3]
|
||||
|| special->state == &states[S_FANG_PINCHBOUNCE4])
|
||||
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > -(special->height/4))
|
||||
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > (special->height/4))
|
||||
{
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
P_SetTarget(&special->tracer, toucher);
|
||||
|
@ -450,12 +450,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case MT_PYREFLY:
|
||||
if (special->extravalue2 == 2 && P_DamageMobj(player->mo, special, special, 1, DMG_FIRE))
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (P_PlayerCanDamage(player, special)) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
if (special->type == MT_PTERABYTE && special->target == player->mo && special->extravalue1 == 1)
|
||||
return; // Can't hurt a Pterabyte if it's trying to pick you up
|
||||
|
||||
if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1))
|
||||
{
|
||||
if (elementalpierce == 2)
|
||||
|
@ -471,13 +477,29 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
toucher->momy = -toucher->momy;
|
||||
if (player->charability == CA_FLY && player->panim == PA_ABILITY)
|
||||
toucher->momz = -toucher->momz/2;
|
||||
else if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher))
|
||||
{
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
|
||||
toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3);
|
||||
toucher->momx = 7*toucher->momx>>3;
|
||||
toucher->momy = 7*toucher->momy>>3;
|
||||
}
|
||||
else if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
|
||||
&& player->panim == PA_DASH)
|
||||
P_DoPlayerPain(player, special, special);
|
||||
}
|
||||
P_DamageMobj(special, toucher, toucher, 1, 0);
|
||||
if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)
|
||||
P_TwinSpinRejuvenate(player, player->thokitem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (special->type == MT_PTERABYTE && special->target == player->mo)
|
||||
return; // Don't hurt the player you're trying to grab
|
||||
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1074,7 +1096,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (player->exiting)
|
||||
return;
|
||||
|
||||
if (player->bumpertime < TICRATE/4)
|
||||
if (player->bumpertime <= (TICRATE/2)-5)
|
||||
{
|
||||
S_StartSound(toucher, special->info->seesound);
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
|
@ -1482,8 +1504,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_SetMobjState(mo2, mo2->info->painstate);
|
||||
}
|
||||
}
|
||||
|
||||
S_StartSound(toucher, special->info->painsound);
|
||||
return;
|
||||
|
||||
case MT_FAKEMOBILE:
|
||||
|
@ -1509,10 +1529,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
toucher->momx = P_ReturnThrustX(special, angle, touchspeed);
|
||||
toucher->momy = P_ReturnThrustY(special, angle, touchspeed);
|
||||
toucher->momz = -toucher->momz;
|
||||
if (player->pflags & PF_GLIDING)
|
||||
if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher))
|
||||
{
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
|
||||
toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3);
|
||||
toucher->momx = 7*toucher->momx>>3;
|
||||
toucher->momy = 7*toucher->momy>>3;
|
||||
}
|
||||
player->homing = 0;
|
||||
|
||||
|
@ -1557,10 +1580,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
toucher->momx = P_ReturnThrustX(special, special->angle, touchspeed);
|
||||
toucher->momy = P_ReturnThrustY(special, special->angle, touchspeed);
|
||||
toucher->momz = -toucher->momz;
|
||||
if (player->pflags & PF_GLIDING)
|
||||
if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher))
|
||||
{
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
|
||||
toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3);
|
||||
toucher->momx = 7*toucher->momx>>3;
|
||||
toucher->momy = 7*toucher->momy>>3;
|
||||
}
|
||||
player->homing = 0;
|
||||
|
||||
|
@ -1595,6 +1621,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
// Buenos Dias Mandy
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_STUN);
|
||||
player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
P_ResetPlayer(player);
|
||||
player->drawangle = special->angle + ANGLE_180;
|
||||
P_InstaThrust(toucher, special->angle, FixedMul(3*special->info->speed, special->scale/2));
|
||||
toucher->z += P_MobjFlip(toucher);
|
||||
|
@ -1700,13 +1727,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
if (mariomode)
|
||||
return;
|
||||
if (special->state-states != S_EXTRALARGEBUBBLE)
|
||||
return; // Don't grab the bubble during its spawn animation
|
||||
else if (toucher->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (special->z+special->height < toucher->z + toucher->height / 3
|
||||
if (special->z+special->height < toucher->z
|
||||
|| special->z+special->height > toucher->z + (toucher->height*2/3))
|
||||
return; // Only go in the mouth
|
||||
}
|
||||
else if (special->z < toucher->z + toucher->height / 3
|
||||
else if (special->z < toucher->z
|
||||
|| special->z > toucher->z + (toucher->height*2/3))
|
||||
return; // Only go in the mouth
|
||||
|
||||
|
@ -1762,7 +1791,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
case MT_MINECARTSPAWNER:
|
||||
if (!special->fuse || player->powers[pw_carry] != CR_MINECART)
|
||||
if (!player->bot && (special->fuse < TICRATE || player->powers[pw_carry] != CR_MINECART))
|
||||
{
|
||||
mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART);
|
||||
P_SetTarget(&mcart->target, toucher);
|
||||
|
@ -1772,7 +1801,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_ResetPlayer(player);
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
player->powers[pw_carry] = CR_MINECART;
|
||||
toucher->player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
P_SetTarget(&toucher->tracer, mcart);
|
||||
toucher->momx = toucher->momy = toucher->momz = 0;
|
||||
|
||||
|
@ -2454,6 +2483,28 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
|
||||
P_SetThingPosition(target);
|
||||
|
||||
if (target->player->powers[pw_super])
|
||||
{
|
||||
target->player->powers[pw_super] = 0;
|
||||
if (P_IsLocalPlayer(target->player))
|
||||
{
|
||||
music_stack_noposition = true; // HACK: Do not reposition next music
|
||||
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
|
||||
}
|
||||
P_RestoreMusic(target->player);
|
||||
|
||||
if (gametype != GT_COOP)
|
||||
{
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[target->player-players]));
|
||||
}
|
||||
}
|
||||
|
||||
target->color = target->player->skincolor;
|
||||
target->colorized = false;
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
|
||||
if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0))
|
||||
;
|
||||
else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != INFLIVES)
|
||||
|
@ -2481,8 +2532,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
else if (P_IsLocalPlayer(target->player))
|
||||
gameovermus = true;
|
||||
|
||||
if (gameovermus)
|
||||
P_PlayJingle(target->player, JT_GOVER); // Yousa dead now, Okieday? Tails 03-14-2000
|
||||
if (gameovermus) // Yousa dead now, Okieday? Tails 03-14-2000
|
||||
S_ChangeMusicEx("_gover", 0, 0, 0, (2*MUSICRATE) - (MUSICRATE/25), 0); // 1.96 seconds
|
||||
//P_PlayJingle(target->player, JT_GOVER); // can't be used because incompatible with track fadeout
|
||||
|
||||
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers)
|
||||
{
|
||||
|
@ -2598,6 +2650,14 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
}
|
||||
break;
|
||||
|
||||
case MT_BANPYURA:
|
||||
if (target->tracer)
|
||||
{
|
||||
S_StopSound(target->tracer);
|
||||
P_KillMobj(target->tracer, inflictor, source, damagetype);
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_EGGSHIELD:
|
||||
P_SetObjectMomZ(target, 4*target->scale, false);
|
||||
P_InstaThrust(target, target->angle, 3*target->scale);
|
||||
|
@ -3404,7 +3464,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
|
||||
// Spectator handling
|
||||
if (netgame)
|
||||
if (multiplayer)
|
||||
{
|
||||
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
|
||||
return false;
|
||||
|
@ -3436,7 +3496,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
|
||||
// Make sure that boxes cannot be popped by enemies, red rings, etc.
|
||||
if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot) || (inflictor && !inflictor->player)))
|
||||
if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot)
|
||||
|| (inflictor && inflictor->type >= MT_REDRING && inflictor->type <= MT_GRENADERING)))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3518,7 +3579,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return true;
|
||||
}
|
||||
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
if (G_IsSpecialStage(gamemap) && !(damagetype & DMG_DEATHMASK))
|
||||
{
|
||||
P_SpecialStageDamage(player, inflictor, source);
|
||||
return true;
|
||||
|
@ -3542,10 +3603,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
// Instant-Death
|
||||
if (damagetype & DMG_DEATHMASK)
|
||||
{
|
||||
P_KillPlayer(player, source, damage);
|
||||
player->rings = player->spheres = 0;
|
||||
}
|
||||
else if (metalrecording)
|
||||
{
|
||||
if (!inflictor)
|
||||
|
@ -3580,7 +3638,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
|
||||
return true;
|
||||
#endif
|
||||
else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield
|
||||
else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield
|
||||
{
|
||||
P_ShieldDamage(player, inflictor, source, damage, damagetype);
|
||||
damage = 0;
|
||||
|
|
|
@ -115,10 +115,10 @@ typedef struct camera_s
|
|||
|
||||
extern camera_t camera, camera2;
|
||||
extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height;
|
||||
extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed;
|
||||
extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_orbit, cv_cam_adjust;
|
||||
|
||||
extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height;
|
||||
extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed;
|
||||
extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_orbit, cv_cam2_adjust;
|
||||
|
||||
extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
|
||||
extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
|
||||
|
@ -303,7 +303,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
|
|||
|
||||
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
||||
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
||||
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
|
||||
boolean P_CheckSolidLava(ffloor_t *rover);
|
||||
void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype);
|
||||
|
||||
mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type);
|
||||
|
|
338
src/p_map.c
338
src/p_map.c
|
@ -124,6 +124,7 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
|||
// Positive spring modes are minor variants of vanilla spring behaviour.
|
||||
// 1 = launch players in jump
|
||||
// 2 = don't modify player at all, just add momentum
|
||||
// 3 = speed-booster mode (force onto ground, MF_AMBUSH causes auto-spin)
|
||||
// Negative spring modes are mildly-related gimmicks with customisation.
|
||||
// -1 = pinball bumper
|
||||
// Any other spring mode defaults to standard vanilla spring behaviour,
|
||||
|
@ -151,7 +152,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
if (object->player)
|
||||
{
|
||||
if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY)
|
||||
if (spring->info->painchance == 3)
|
||||
;
|
||||
else if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY)
|
||||
strong = 1;
|
||||
else if (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2)
|
||||
strong = 2;
|
||||
|
@ -208,7 +211,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
{
|
||||
angle_t nightsangle = 0;
|
||||
|
||||
if (object->player->bumpertime >= TICRATE/4)
|
||||
if (object->player->bumpertime > (TICRATE/2)-5)
|
||||
return false;
|
||||
|
||||
if ((object->player->pflags & PF_TRANSFERTOCLOSEST) && object->player->axis1 && object->player->axis2)
|
||||
|
@ -286,7 +289,27 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
if (spring->info->painchance != 2)
|
||||
{
|
||||
if (object->player)
|
||||
{
|
||||
object->player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
#ifndef SPRINGSPIN
|
||||
object->player->powers[pw_justsprung] = 5;
|
||||
if (horizspeed)
|
||||
object->player->powers[pw_noautobrake] = ((horizspeed*TICRATE)>>(FRACBITS+3))/9; // TICRATE at 72*FRACUNIT
|
||||
else if (P_MobjFlip(object) == P_MobjFlip(spring))
|
||||
object->player->powers[pw_justsprung] |= (1<<15);
|
||||
#else
|
||||
object->player->powers[pw_justsprung] = 15;
|
||||
if (horizspeed)
|
||||
object->player->powers[pw_noautobrake] = ((horizspeed*TICRATE)>>(FRACBITS+3))/9; // TICRATE at 72*FRACUNIT
|
||||
else
|
||||
{
|
||||
if (abs(object->player->rmomx) > object->scale || abs(object->player->rmomy) > object->scale)
|
||||
object->player->drawangle = R_PointToAngle2(0, 0, object->player->rmomx, object->player->rmomy);
|
||||
if (P_MobjFlip(object) == P_MobjFlip(spring))
|
||||
object->player->powers[pw_justsprung] |= (1<<15);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA
|
||||
{
|
||||
|
@ -321,6 +344,14 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
// Set position!
|
||||
P_TryMove(object, spring->x + offx, spring->y + offy, true);
|
||||
|
||||
if ((spring->info->painchance == 3))
|
||||
{
|
||||
object->z = spring->z;
|
||||
if (spring->eflags & MFE_VERTICALFLIP)
|
||||
object->z -= object->height;
|
||||
object->momz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,10 +375,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
if (horizspeed)
|
||||
{
|
||||
object->player->drawangle = spring->angle;
|
||||
if (vertispeed || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0))
|
||||
{
|
||||
object->angle = spring->angle;
|
||||
object->angle = object->player->drawangle = spring->angle;
|
||||
|
||||
if (!demoplayback || P_AnalogMove(object->player))
|
||||
{
|
||||
|
@ -357,13 +385,26 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
localangle2 = spring->angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (object->player->pflags & PF_GLIDING)
|
||||
P_SetPlayerMobjState(object, S_PLAY_FALL);
|
||||
if ((spring->info->painchance == 3))
|
||||
{
|
||||
if (!(pflags = (object->player->pflags & PF_SPINNING)) &&
|
||||
(((object->player->charability2 == CA2_SPINDASH) && (object->player->cmd.buttons & BT_USE))
|
||||
|| (spring->flags2 & MF2_AMBUSH)))
|
||||
{
|
||||
pflags = PF_SPINNING;
|
||||
P_SetPlayerMobjState(object, S_PLAY_ROLL);
|
||||
S_StartSound(object, sfx_spin);
|
||||
}
|
||||
else
|
||||
P_SetPlayerMobjState(object, S_PLAY_ROLL);
|
||||
}
|
||||
else
|
||||
pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these.
|
||||
secondjump = object->player->secondjump;
|
||||
washoming = object->player->homing;
|
||||
if (object->player->pflags & PF_GLIDING)
|
||||
P_SetPlayerMobjState(object, S_PLAY_FALL);
|
||||
P_ResetPlayer(object->player);
|
||||
|
||||
if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities.
|
||||
|
@ -371,7 +412,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
object->player->pflags |= P_GetJumpFlags(object->player);
|
||||
P_SetPlayerMobjState(object, S_PLAY_JUMP);
|
||||
}
|
||||
else if ((spring->info->painchance == 2) || (pflags & PF_BOUNCING)) // Adding momentum only.
|
||||
else if ((spring->info->painchance == 2) || ((spring->info->painchance != 3) && (pflags & PF_BOUNCING))) // Adding momentum only.
|
||||
{
|
||||
object->player->pflags |= (pflags &~ PF_STARTJUMP);
|
||||
object->player->secondjump = secondjump;
|
||||
|
@ -385,6 +426,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
object->player->pflags |= pflags;
|
||||
object->player->secondjump = secondjump;
|
||||
}
|
||||
else if (object->player->dashmode >= 3*TICRATE)
|
||||
P_SetPlayerMobjState(object, S_PLAY_DASH);
|
||||
else if (P_IsObjectOnGround(object) && horizspeed >= FixedMul(object->player->runspeed, object->scale))
|
||||
P_SetPlayerMobjState(object, S_PLAY_RUN);
|
||||
else
|
||||
P_SetPlayerMobjState(object, S_PLAY_WALK);
|
||||
}
|
||||
|
@ -493,6 +538,42 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
}
|
||||
|
||||
static void P_DoPterabyteCarry(player_t *player, mobj_t *ptera)
|
||||
{
|
||||
if (player->powers[pw_carry] && players->powers[pw_carry] != CR_ROLLOUT)
|
||||
return;
|
||||
if (ptera->extravalue1 != 1)
|
||||
return; // Not swooping
|
||||
if (ptera->target != player->mo)
|
||||
return; // Not swooping for you!
|
||||
|
||||
if (player->spectator)
|
||||
return;
|
||||
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) != (ptera->eflags & MFE_VERTICALFLIP))
|
||||
return; // Both should be in same gravity
|
||||
|
||||
if (ptera->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (ptera->ceilingz - (ptera->z + ptera->height) < player->mo->height - FixedMul(2*FRACUNIT, player->mo->scale))
|
||||
return;
|
||||
}
|
||||
else if (ptera->z - ptera->floorz < player->mo->height - FixedMul(2*FRACUNIT, player->mo->scale))
|
||||
return; // No room to pick up this guy!
|
||||
|
||||
P_ResetPlayer(player);
|
||||
P_SetTarget(&player->mo->tracer, ptera);
|
||||
player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
player->powers[pw_carry] = CR_PTERABYTE;
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x = ptera->x;
|
||||
player->mo->y = ptera->y;
|
||||
P_SetThingPosition(player->mo);
|
||||
ptera->movefactor = 3*TICRATE;
|
||||
ptera->watertop = ptera->waterbottom = ptera->cusval = 0;
|
||||
}
|
||||
|
||||
static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
||||
{
|
||||
INT32 p;
|
||||
|
@ -607,6 +688,34 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole)
|
|||
P_SetTarget(&pole->tracer, NULL);
|
||||
}
|
||||
|
||||
static void P_PlayerBarrelCollide(mobj_t *toucher, mobj_t *barrel)
|
||||
{
|
||||
if (toucher->momz < 0)
|
||||
{
|
||||
if (toucher->z + toucher->momz > barrel->z + barrel->height)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (toucher->z > barrel->z + barrel->height)
|
||||
return;
|
||||
}
|
||||
|
||||
if (toucher->momz > 0)
|
||||
{
|
||||
if (toucher->z + toucher->height + toucher->momz < barrel->z)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (toucher->z + toucher->height < barrel->z)
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_PlayerCanDamage(toucher->player, barrel))
|
||||
P_DamageMobj(barrel, toucher, toucher, 1, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// PIT_CheckThing
|
||||
//
|
||||
|
@ -749,7 +858,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
|
||||
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
|
||||
return true;
|
||||
|
||||
// Don't collide with your buddies while NiGHTS-flying.
|
||||
|
@ -857,6 +966,15 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (tmthing->type == MT_LAVAFALL_LAVA && (thing->type == MT_RING || thing->type == MT_REDTEAMRING || thing->type == MT_BLUETEAMRING || thing->type == MT_FLINGRING))
|
||||
{
|
||||
//height check
|
||||
if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height || !(thing->health))
|
||||
return true;
|
||||
|
||||
P_KillMobj(thing, tmthing, tmthing, DMG_FIRE);
|
||||
}
|
||||
|
||||
if (tmthing->type == MT_MINECART)
|
||||
{
|
||||
//height check
|
||||
|
@ -875,12 +993,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_SALOONDOOR && tmthing->player)
|
||||
{
|
||||
if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health)
|
||||
mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing;
|
||||
if ((thing->flags & MF2_AMBUSH) || ref != tmthing)
|
||||
{
|
||||
fixed_t dx = tmthing->tracer->momx;
|
||||
fixed_t dy = tmthing->tracer->momy;
|
||||
fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT);
|
||||
angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle;
|
||||
fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT);
|
||||
angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle;
|
||||
fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
S_StartSound(tmthing, thing->info->activesound);
|
||||
thing->extravalue2 += 2*FixedMul(s, dm)/3;
|
||||
|
@ -888,40 +1005,72 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
if (thing->type == MT_SALOONDOORCENTER && tmthing->player)
|
||||
{
|
||||
if ((thing->flags & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (thing->type == MT_ROLLOUTROCK && tmthing->player && tmthing->health)
|
||||
{
|
||||
if (tmthing->player->powers[pw_carry] == CR_ROLLOUT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((thing->flags & MF_PUSHABLE) // not carrying a player
|
||||
&& (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something
|
||||
&& ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP))
|
||||
&& (P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < (thing->radius))
|
||||
&& (P_MobjFlip(tmthing)*tmthing->momz <= 0)
|
||||
&& ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2))
|
||||
|| (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2))))
|
||||
{
|
||||
thing->flags &= ~MF_PUSHABLE; // prevent riding player from applying pushable movement logic
|
||||
thing->flags2 &= ~MF2_DONTDRAW; // don't leave the rock invisible if it was flashing prior to boarding
|
||||
P_SetTarget(&thing->tracer, tmthing);
|
||||
P_ResetPlayer(tmthing->player);
|
||||
P_SetPlayerMobjState(tmthing, S_PLAY_WALK);
|
||||
tmthing->player->powers[pw_carry] = CR_ROLLOUT;
|
||||
P_SetTarget(&tmthing->tracer, thing);
|
||||
P_SetObjectMomZ(thing, tmthing->momz, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (tmthing->type == MT_ROLLOUTROCK)
|
||||
{
|
||||
if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height || !thing->health)
|
||||
return true;
|
||||
|
||||
if (thing == tmthing->tracer) // don't collide with rider
|
||||
return true;
|
||||
|
||||
if (thing->flags & MF_SPRING) // bounce on springs
|
||||
{
|
||||
P_DoSpring(thing, tmthing);
|
||||
return true;
|
||||
}
|
||||
else if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) == (MF_MONITOR|MF_SHOOTABLE) && !(tmthing->flags & MF_PUSHABLE)) // pop monitors while carrying a player
|
||||
{
|
||||
P_KillMobj(thing, tmthing, tmthing->tracer, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (thing->type == tmthing->type // bounce against other rollout rocks
|
||||
&& (tmthing->momx || tmthing->momy || thing->momx || thing->momy))
|
||||
{
|
||||
fixed_t tempmomx = thing->momx, tempmomy = thing->momy;
|
||||
thing->momx = tmthing->momx;
|
||||
thing->momy = tmthing->momy;
|
||||
tmthing->momx = tempmomx;
|
||||
tmthing->momy = tempmomy;
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->type == MT_PTERABYTE && tmthing->player)
|
||||
P_DoPterabyteCarry(tmthing->player, thing);
|
||||
|
||||
if (thing->type == MT_TNTBARREL && tmthing->player)
|
||||
{
|
||||
if (tmthing->momz < 0)
|
||||
{
|
||||
if (tmthing->z + tmthing->momz > thing->z + thing->height)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tmthing->momz > 0)
|
||||
{
|
||||
if (tmthing->z + tmthing->height + tmthing->momz < thing->z)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmthing->z + tmthing->height < thing->z)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((tmthing->player->pflags & (PF_SPINNING | PF_GLIDING))
|
||||
|| ((tmthing->player->pflags & PF_JUMPED)
|
||||
&& (!(tmthing->player->pflags & PF_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 || tmthing->player->pflags & PF_BOUNCING)
|
||||
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height / 2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|
||||
|| (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY)))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
}
|
||||
P_PlayerBarrelCollide(tmthing, thing);
|
||||
|
||||
if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE)
|
||||
{
|
||||
|
@ -1022,7 +1171,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // underneath
|
||||
if (tmthing->flags & MF_SHOOTABLE && thing->health > 0)
|
||||
{
|
||||
UINT8 damagetype = (thing->info->mass & 0xFF);
|
||||
UINT32 damagetype = (thing->info->mass & 0xFF);
|
||||
if (!damagetype && thing->flags & MF_FIRE) // BURN!
|
||||
damagetype = DMG_FIRE;
|
||||
if (P_DamageMobj(tmthing, thing, thing, 1, damagetype) && (damagetype = (thing->info->mass>>8)))
|
||||
|
@ -1039,7 +1188,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // underneath
|
||||
if (thing->flags & MF_SHOOTABLE && tmthing->health > 0)
|
||||
{
|
||||
UINT8 damagetype = (tmthing->info->mass & 0xFF);
|
||||
UINT32 damagetype = (tmthing->info->mass & 0xFF);
|
||||
if (!damagetype && tmthing->flags & MF_FIRE) // BURN!
|
||||
damagetype = DMG_FIRE;
|
||||
if (P_DamageMobj(thing, tmthing, tmthing, 1, damagetype) && (damagetype = (tmthing->info->mass>>8)))
|
||||
|
@ -1563,8 +1712,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
if ((!tmthing->player) && (thing->player))
|
||||
; // no solid thing should ever be able to step up onto a player
|
||||
if ((tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM) && (thing->player))
|
||||
; // springs and gas jets should never be able to step up onto a player
|
||||
// z checking at last
|
||||
// Treat noclip things as non-solid!
|
||||
else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID
|
||||
|
@ -1967,7 +2116,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (thing->player && (P_CheckSolidLava(thing, rover) || P_CanRunOnWater(thing->player, rover)))
|
||||
if (thing->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(thing->player, rover)))
|
||||
;
|
||||
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
|
||||
;
|
||||
|
@ -2632,8 +2781,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
// HACK TO FIX DSZ2: apply only if slopes are involved
|
||||
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||
{
|
||||
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
||||
thing->ceilingrover = tmceilingrover;
|
||||
|
@ -2648,8 +2796,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
// HACK TO FIX DSZ2: apply only if slopes are involved
|
||||
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||
{
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->floorrover = tmfloorrover;
|
||||
|
@ -2884,11 +3031,8 @@ static boolean P_ThingHeightClip(mobj_t *thing)
|
|||
thing->z = thing->ceilingz - thing->height;
|
||||
}
|
||||
|
||||
if (thing->z != oldz)
|
||||
{
|
||||
if (thing->player)
|
||||
if (P_MobjFlip(thing)*(thing->z - oldz) > 0 && thing->player)
|
||||
P_PlayerHitFloor(thing->player, !onfloor);
|
||||
}
|
||||
|
||||
// debug: be sure it falls to the floor
|
||||
thing->eflags &= ~MFE_ONGROUND;
|
||||
|
@ -3202,7 +3346,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
|
|||
&& glidesector->sector->ceilingpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|
||||
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz)
|
||||
|| (player->mo->z >= ceilingz))
|
||||
floorclimb = true;
|
||||
}
|
||||
|
@ -3340,13 +3484,13 @@ isblocking:
|
|||
&& canclimb)
|
||||
{
|
||||
slidemo->angle = climbangle;
|
||||
if (!demoplayback || P_AnalogMove(slidemo->player))
|
||||
/*if (!demoplayback || P_AnalogMove(slidemo->player))
|
||||
{
|
||||
if (slidemo->player == &players[consoleplayer])
|
||||
localangle = slidemo->angle;
|
||||
else if (slidemo->player == &players[secondarydisplayplayer])
|
||||
localangle2 = slidemo->angle;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!slidemo->player->climbing)
|
||||
{
|
||||
|
@ -3485,6 +3629,64 @@ stairstep:
|
|||
goto retry;
|
||||
}
|
||||
|
||||
static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_SWIMMABLE))
|
||||
continue;
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 3)
|
||||
continue;
|
||||
|
||||
if (rover->master->flags & ML_BLOCKMONSTERS)
|
||||
continue;
|
||||
|
||||
topheight =
|
||||
#ifdef ESLOPE
|
||||
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
|
||||
#endif
|
||||
*rover->topheight;
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (topheight < mo->z - mo->height)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (topheight < mo->z)
|
||||
continue;
|
||||
}
|
||||
|
||||
bottomheight =
|
||||
#ifdef ESLOPE
|
||||
*rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) :
|
||||
#endif
|
||||
*rover->bottomheight;
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (bottomheight > mo->z)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bottomheight > mo->z + mo->height)
|
||||
continue;
|
||||
}
|
||||
|
||||
P_DamageMobj(mo, NULL, NULL, 1, DMG_FIRE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_SlideMove
|
||||
// The momx / momy move is bad, so try to slide
|
||||
|
@ -3645,6 +3847,12 @@ retry:
|
|||
P_PathTraverse(leadx, traily, leadx + mo->momx, traily + mo->momy,
|
||||
PT_ADDLINES, PTR_SlideTraverse);
|
||||
|
||||
if (bestslideline && mo->player && bestslideline->sidenum[1] != 0xffff)
|
||||
{
|
||||
sector_t *sec = P_PointOnLineSide(mo->x, mo->y, bestslideline) ? bestslideline->frontsector : bestslideline->backsector;
|
||||
P_CheckLavaWall(mo, sec);
|
||||
}
|
||||
|
||||
// Some walls are bouncy even if you're not
|
||||
if (bestslideline && bestslideline->flags & ML_BOUNCY)
|
||||
{
|
||||
|
|
|
@ -662,7 +662,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
|
||||
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
|
||||
;
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||
|
@ -674,7 +674,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
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
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
{
|
||||
if (bottomheight < opentop) {
|
||||
opentop = bottomheight;
|
||||
|
@ -687,7 +687,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = bottomheight;
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
{
|
||||
if (topheight > openbottom) {
|
||||
openbottom = topheight;
|
||||
|
@ -708,7 +708,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
|
||||
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
|
||||
;
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||
|
@ -720,7 +720,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
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
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
{
|
||||
if (bottomheight < opentop) {
|
||||
opentop = bottomheight;
|
||||
|
@ -733,7 +733,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = bottomheight;
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
{
|
||||
if (topheight > openbottom) {
|
||||
openbottom = topheight;
|
||||
|
|
857
src/p_mobj.c
857
src/p_mobj.c
File diff suppressed because it is too large
Load diff
10
src/p_mobj.h
10
src/p_mobj.h
|
@ -233,15 +233,17 @@ typedef enum
|
|||
MFE_VERTICALFLIP = 1<<5,
|
||||
// Goo water
|
||||
MFE_GOOWATER = 1<<6,
|
||||
// The mobj is touching a lava block
|
||||
MFE_TOUCHLAVA = 1<<7,
|
||||
// Mobj was already pushed this tic
|
||||
MFE_PUSHED = 1<<7,
|
||||
MFE_PUSHED = 1<<8,
|
||||
// Mobj was already sprung this tic
|
||||
MFE_SPRUNG = 1<<8,
|
||||
MFE_SPRUNG = 1<<9,
|
||||
// Platform movement
|
||||
MFE_APPLYPMOMZ = 1<<9,
|
||||
MFE_APPLYPMOMZ = 1<<10,
|
||||
// Compute and trigger on mobj angle relative to tracer
|
||||
// See Linedef Exec 457 (Track mobj angle to point)
|
||||
MFE_TRACERANGLE = 1<<10,
|
||||
MFE_TRACERANGLE = 1<<11,
|
||||
// free: to and including 1<<15
|
||||
} mobjeflag_t;
|
||||
|
||||
|
|
|
@ -3618,7 +3618,7 @@ static void P_NetUnArchiveThinkers(void)
|
|||
{
|
||||
executor_t *delay = NULL;
|
||||
UINT32 mobjnum;
|
||||
for (currentthinker = thlist[i].next; currentthinker != &thlist[i];
|
||||
for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN];
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 != (actionf_p1)T_ExecutorDelay)
|
||||
|
@ -4119,12 +4119,54 @@ static inline boolean P_NetUnArchiveMisc(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline void P_ArchiveLuabanksAndConsistency(void)
|
||||
{
|
||||
UINT8 i, banksinuse = NUM_LUABANKS;
|
||||
|
||||
while (banksinuse && !luabanks[banksinuse-1])
|
||||
banksinuse--; // get the last used bank
|
||||
|
||||
if (banksinuse)
|
||||
{
|
||||
WRITEUINT8(save_p, 0xb7); // luabanks marker
|
||||
WRITEUINT8(save_p, banksinuse);
|
||||
for (i = 0; i < banksinuse; i++)
|
||||
WRITEINT32(save_p, luabanks[i]);
|
||||
}
|
||||
|
||||
WRITEUINT8(save_p, 0x1d); // consistency marker
|
||||
}
|
||||
|
||||
static inline boolean P_UnArchiveLuabanksAndConsistency(void)
|
||||
{
|
||||
switch (READUINT8(save_p))
|
||||
{
|
||||
case 0xb7:
|
||||
{
|
||||
UINT8 i, banksinuse = READUINT8(save_p);
|
||||
if (banksinuse > NUM_LUABANKS)
|
||||
return false;
|
||||
for (i = 0; i < banksinuse; i++)
|
||||
luabanks[i] = READINT32(save_p);
|
||||
if (READUINT8(save_p) != 0x1d)
|
||||
return false;
|
||||
}
|
||||
case 0x1d:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void P_SaveGame(void)
|
||||
{
|
||||
P_ArchiveMisc();
|
||||
P_ArchivePlayer();
|
||||
|
||||
WRITEUINT8(save_p, 0x1d); // consistency marker
|
||||
// yes, even in non HAVE_BLUA
|
||||
P_ArchiveLuabanksAndConsistency();
|
||||
}
|
||||
|
||||
void P_SaveNetGame(void)
|
||||
|
@ -4163,7 +4205,7 @@ void P_SaveNetGame(void)
|
|||
LUA_Archive();
|
||||
#endif
|
||||
|
||||
WRITEUINT8(save_p, 0x1d); // consistency marker
|
||||
P_ArchiveLuabanksAndConsistency();
|
||||
}
|
||||
|
||||
boolean P_LoadGame(INT16 mapoverride)
|
||||
|
@ -4175,8 +4217,7 @@ boolean P_LoadGame(INT16 mapoverride)
|
|||
P_UnArchiveSPGame(mapoverride);
|
||||
P_UnArchivePlayer();
|
||||
|
||||
// Savegame end marker
|
||||
if (READUINT8(save_p) != 0x1d)
|
||||
if (!P_UnArchiveLuabanksAndConsistency())
|
||||
return false;
|
||||
|
||||
// Only do this after confirming savegame is ok
|
||||
|
@ -4217,5 +4258,5 @@ boolean P_LoadNetGame(void)
|
|||
// precipitation when loading a netgame save. Instead, precip has to be spawned here.
|
||||
// This is done in P_NetUnArchiveSpecials now.
|
||||
|
||||
return READUINT8(save_p) == 0x1d;
|
||||
return P_UnArchiveLuabanksAndConsistency();
|
||||
}
|
||||
|
|
|
@ -2246,6 +2246,8 @@ static void P_LevelInitStuff(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
G_PlayerReborn(i, true);
|
||||
|
||||
if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0))
|
||||
{
|
||||
// In Co-Op, replenish a user's lives if they are depleted.
|
||||
|
@ -2253,41 +2255,18 @@ static void P_LevelInitStuff(void)
|
|||
}
|
||||
|
||||
// obliteration station...
|
||||
players[i].rings = players[i].spheres =\
|
||||
players[i].xtralife = players[i].deadtimer =\
|
||||
players[i].numboxes = players[i].totalring =\
|
||||
players[i].laps = players[i].aiming =\
|
||||
players[i].losstime = players[i].timeshit =\
|
||||
players[i].marescore = players[i].lastmarescore =\
|
||||
players[i].maxlink = players[i].startedtime =\
|
||||
players[i].finishedtime = players[i].finishedspheres =\
|
||||
players[i].finishedrings = players[i].lastmare =\
|
||||
players[i].lastmarelap = players[i].lastmarebonuslap =\
|
||||
players[i].totalmarelap = players[i].totalmarebonuslap =\
|
||||
players[i].marebegunat = players[i].textvar =\
|
||||
players[i].texttimer = players[i].linkcount =\
|
||||
players[i].linktimer = players[i].flyangle =\
|
||||
players[i].anotherflyangle = players[i].nightstime =\
|
||||
players[i].oldscale = players[i].mare = players[i].marelap =\
|
||||
players[i].marebonuslap = players[i].lapbegunat =\
|
||||
players[i].lapstartedtime = players[i].totalmarescore =\
|
||||
players[i].realtime = players[i].exiting = 0;
|
||||
players[i].laps = players[i].marescore = players[i].lastmarescore =\
|
||||
players[i].mare = players[i].exiting = 0;
|
||||
|
||||
// i guess this could be part of the above but i feel mildly uncomfortable implicitly casting
|
||||
players[i].gotcontinue = false;
|
||||
|
||||
// aha, the first evidence this shouldn't be a memset!
|
||||
players[i].drillmeter = 40*20;
|
||||
|
||||
P_ResetPlayer(&players[i]);
|
||||
// hit these too
|
||||
players[i].pflags &= ~(PF_GAMETYPEOVER|PF_TRANSFERTOCLOSEST);
|
||||
|
||||
// unset ALL the pointers. P_SetTarget isn't needed here because if this
|
||||
// function is being called we're just going to clobber the data anyways
|
||||
players[i].mo = players[i].followmobj = players[i].awayviewmobj =\
|
||||
players[i].capsule = players[i].axis1 = players[i].axis2 = players[i].drone = NULL;
|
||||
players[i].pflags &= ~(PF_GAMETYPEOVER);
|
||||
}
|
||||
|
||||
if (botingame)
|
||||
CV_SetValue(&cv_analog2, true);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2627,7 +2606,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
boolean loadedbm = false;
|
||||
sector_t *ss;
|
||||
boolean chase;
|
||||
|
||||
levelloading = true;
|
||||
|
||||
// This is needed. Don't touch.
|
||||
|
@ -3068,8 +3046,11 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n"));
|
||||
|
||||
}
|
||||
else if (gametype == GT_RACE && server && cv_usemapnumlaps.value)
|
||||
CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps);
|
||||
else if (gametype == GT_RACE && server)
|
||||
CV_StealthSetValue(&cv_numlaps,
|
||||
(cv_basenumlaps.value)
|
||||
? cv_basenumlaps.value
|
||||
: mapheaderinfo[gamemap - 1]->numlaps);
|
||||
|
||||
// ===========
|
||||
// landing point for netgames.
|
||||
|
|
201
src/p_spec.c
201
src/p_spec.c
|
@ -2718,6 +2718,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
|
||||
{
|
||||
if (line->flags & ML_EFFECT5) // Repeat Midtexture
|
||||
|
@ -2758,7 +2759,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
// play the sound from nowhere, but only if display player triggered it
|
||||
|
@ -2784,6 +2786,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
S_StartSound(mo, sfxnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 415: // Run a script
|
||||
|
@ -4174,27 +4177,12 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
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 != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
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
|
||||
|
@ -4234,27 +4222,12 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
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 != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
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
|
||||
|
@ -4304,26 +4277,11 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == top));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottom));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top)
|
||||
return false;
|
||||
}
|
||||
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 != bottom)
|
||||
return false;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom)
|
||||
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top)))
|
||||
return false;
|
||||
}
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4345,10 +4303,10 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
|||
//
|
||||
static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
|
||||
else
|
||||
return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR);
|
||||
boolean floorallowed = ((sec->flags & SF_FLIPSPECIAL_FLOOR) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == P_GetSpecialBottomZ(mo, sec, sec)));
|
||||
boolean ceilingallowed = ((sec->flags & SF_FLIPSPECIAL_CEILING) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == P_GetSpecialTopZ(mo, sec, sec)));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
return (floorallowed || ceilingallowed);
|
||||
}
|
||||
|
||||
/** Applies a sector special to a player.
|
||||
|
@ -5312,27 +5270,12 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
if (((rover->flags & FF_BLOCKPLAYER) && mo->player)
|
||||
|| ((rover->flags & FF_BLOCKOTHERS) && !mo->player))
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight)
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
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 != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight)
|
||||
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight)))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Water and intangible FOFs
|
||||
|
@ -5374,27 +5317,12 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
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 != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
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
|
||||
|
@ -5450,40 +5378,18 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
}
|
||||
|
||||
if (!(po->flags & POF_TESTHEIGHT)) // Don't do height checking
|
||||
{
|
||||
}
|
||||
;
|
||||
else if (po->flags & POF_SOLID)
|
||||
{
|
||||
boolean floorallowed = ((polysec->flags & SF_FLIPSPECIAL_FLOOR) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == polysec->ceilingheight));
|
||||
boolean ceilingallowed = ((polysec->flags & SF_FLIPSPECIAL_CEILING) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == polysec->floorheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((polysec->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(polysec->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != polysec->ceilingheight)
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((polysec->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(polysec->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|| player->mo->z + player->mo->height != polysec->floorheight)
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (polysec->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == polysec->floorheight)
|
||||
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == polysec->ceilingheight)))
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Water and DEATH FOG!!! heh
|
||||
|
@ -5580,17 +5486,13 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
|
|||
f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector);
|
||||
c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector);
|
||||
|
||||
// Only go further if on the ground
|
||||
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint)
|
||||
return;
|
||||
|
||||
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint)
|
||||
return;
|
||||
|
||||
if ((sector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
&& player->mo->z != f_affectpoint
|
||||
&& player->mo->z + player->mo->height != c_affectpoint)
|
||||
{
|
||||
boolean floorallowed = ((sector->flags & SF_FLIPSPECIAL_FLOOR) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == f_affectpoint));
|
||||
boolean ceilingallowed = ((sector->flags & SF_FLIPSPECIAL_CEILING) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == c_affectpoint));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
return;
|
||||
}
|
||||
|
||||
P_ProcessSpecialSector(player, sector, NULL);
|
||||
}
|
||||
|
@ -6085,8 +5987,6 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
|
|||
* to the lowest nearby height if not
|
||||
* there already.
|
||||
*
|
||||
* Replaces the old "AirBob".
|
||||
*
|
||||
* \param sec Control sector.
|
||||
* \param actionsector Target sector.
|
||||
* \param sourceline Control linedef.
|
||||
|
@ -6131,8 +6031,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline)
|
|||
raise->sourceline = sourceline;
|
||||
}
|
||||
|
||||
// Function to maintain backwards compatibility
|
||||
static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust)
|
||||
static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic)
|
||||
{
|
||||
levelspecthink_t *airbob;
|
||||
|
||||
|
@ -6170,6 +6069,8 @@ static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust)
|
|||
airbob->vars[4] = airbob->vars[5]
|
||||
- (sec->ceilingheight - sec->floorheight);
|
||||
|
||||
airbob->vars[9] = dynamic ? 1 : 0;
|
||||
|
||||
airbob->sourceline = sourceline;
|
||||
}
|
||||
|
||||
|
@ -6683,6 +6584,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
|
||||
if (lines[i].flags & ML_EFFECT3)
|
||||
sectors[s].flags |= SF_TRIGGERSPECIAL_TOUCH;
|
||||
if (lines[i].flags & ML_EFFECT2)
|
||||
sectors[s].flags |= SF_TRIGGERSPECIAL_HEADBUMP;
|
||||
|
||||
if (lines[i].flags & ML_EFFECT1)
|
||||
sectors[s].flags |= SF_INVERTPRECIP;
|
||||
|
||||
if (lines[i].frontsector && GETSECSPECIAL(lines[i].frontsector->special, 4) == 12)
|
||||
sectors[s].camsec = sides[*lines[i].sidenum].sector-sectors;
|
||||
|
@ -6987,11 +6893,16 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 151: // Adjustable air bobbing platform
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151));
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false);
|
||||
break;
|
||||
case 152: // Adjustable air bobbing platform in reverse
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
case 153: // Dynamic Sinking Platform
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, false, true);
|
||||
break;
|
||||
|
||||
case 160: // Float/bob platform
|
||||
|
@ -7042,14 +6953,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
|
||||
case 177: // Air bobbing platform that will crumble and bob on
|
||||
// the water when it falls and hits, then never return
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
|
||||
case 178: // Crumbling platform that will float when it hits water
|
||||
|
@ -7063,7 +6974,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 180: // Air bobbing platform that will crumble
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
|
||||
case 190: // Rising Platform FOF (solid, opaque, shadows)
|
||||
|
@ -7171,21 +7082,21 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 252: // Shatter block (breaks when touched)
|
||||
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER;
|
||||
ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
ffloorflags |= FF_SOLID|FF_SHATTERBOTTOM;
|
||||
ffloorflags |= FF_BLOCKPLAYER|FF_SHATTERBOTTOM;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
case 253: // Translucent shatter block (see 76)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_TRANSLUCENT, secthinkers);
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_TRANSLUCENT, secthinkers);
|
||||
break;
|
||||
|
||||
case 254: // Bustable block
|
||||
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
ffloorflags |= FF_ONLYKNUX;
|
||||
ffloorflags |= FF_STRONGBUST;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
|
|
@ -482,7 +482,7 @@ static inline void P_DoSpecialStageStuff(void)
|
|||
countspheres += players[i].spheres;
|
||||
|
||||
// If in water, deplete timer 6x as fast.
|
||||
if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
|
||||
if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(players[i].powers[pw_shield] & SH_PROTECTWATER))
|
||||
players[i].nightstime -= 5;
|
||||
if (--players[i].nightstime > 6)
|
||||
{
|
||||
|
|
1256
src/p_user.c
1256
src/p_user.c
File diff suppressed because it is too large
Load diff
486
src/r_data.c
486
src/r_data.c
|
@ -23,6 +23,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "p_setup.h" // levelflats
|
||||
#include "v_video.h" // pMasterPalette
|
||||
#include "byteptr.h"
|
||||
#include "dehacked.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -34,7 +35,7 @@
|
|||
#endif
|
||||
|
||||
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
|
||||
#ifdef _WIN32_WCE
|
||||
#if 0
|
||||
#define AVOID_ERRNO
|
||||
#else
|
||||
#include <errno.h>
|
||||
|
@ -241,7 +242,7 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
|
|||
}
|
||||
}
|
||||
|
||||
RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
|
||||
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
|
||||
{
|
||||
RGBA_t output;
|
||||
if (style == AST_TRANSLUCENT)
|
||||
|
@ -261,6 +262,9 @@ RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
|
|||
// if there's no pixel in here
|
||||
if (!background.rgba)
|
||||
output.s.alpha = foreground.s.alpha;
|
||||
else
|
||||
output.s.alpha = 0xFF;
|
||||
return output.rgba;
|
||||
}
|
||||
#define clamp(c) max(min(c, 0xFF), 0x00);
|
||||
else
|
||||
|
@ -298,30 +302,38 @@ RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
|
|||
}
|
||||
// just copy the pixel
|
||||
else if (style == AST_COPY)
|
||||
return background;
|
||||
output.rgba = foreground.rgba;
|
||||
|
||||
output.s.alpha = 0xFF;
|
||||
return output.rgba;
|
||||
}
|
||||
#undef clamp
|
||||
// unimplemented blend modes return the background pixel
|
||||
output = background;
|
||||
output.s.alpha = 0xFF;
|
||||
return output;
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha)
|
||||
{
|
||||
if ((style == AST_TRANSLUCENT) && (alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency?
|
||||
// Alpha style set to translucent?
|
||||
if (style == AST_TRANSLUCENT)
|
||||
{
|
||||
// Is the alpha small enough for translucency?
|
||||
if (alpha <= (10*255/11))
|
||||
{
|
||||
UINT8 *mytransmap;
|
||||
if (alpha < 255/11) // Is the patch way too translucent? Don't render then.
|
||||
// Is the patch way too translucent? Don't blend then.
|
||||
if (alpha < 255/11)
|
||||
return background;
|
||||
// The equation's not exact but it works as intended. I'll call it a day for now.
|
||||
mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
|
||||
if (background != 0xFF)
|
||||
return *(mytransmap + (background<<8) + foreground);
|
||||
}
|
||||
else // just copy the pixel
|
||||
return foreground;
|
||||
}
|
||||
// just copy the pixel
|
||||
else if (style == AST_COPY)
|
||||
return background;
|
||||
return foreground;
|
||||
// use ASTBlendPixel for all other blend modes
|
||||
// and find the nearest colour in the palette
|
||||
else if (style != AST_TRANSLUCENT)
|
||||
|
@ -329,7 +341,7 @@ UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 al
|
|||
RGBA_t texel;
|
||||
RGBA_t bg = V_GetColor(background);
|
||||
RGBA_t fg = V_GetColor(foreground);
|
||||
texel = ASTBlendPixel(bg, fg, style, alpha);
|
||||
texel.rgba = ASTBlendPixel(bg, fg, style, alpha);
|
||||
return NearestColor(texel.s.red, texel.s.green, texel.s.blue);
|
||||
}
|
||||
// fallback if all above fails, somehow
|
||||
|
@ -374,7 +386,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
|
|||
if (count > 0)
|
||||
{
|
||||
for (; dest < cache + position + count; source++, dest++)
|
||||
if (*dest != 0xFF)
|
||||
if (*source != 0xFF)
|
||||
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
|
||||
|
@ -383,7 +395,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
|
|||
}
|
||||
|
||||
//
|
||||
// R_DrawTransColumnInCache
|
||||
// R_DrawBlendFlippedColumnInCache
|
||||
// Similar to the one above except that the column is inverted.
|
||||
//
|
||||
static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
||||
|
@ -418,7 +430,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
|
|||
if (count > 0)
|
||||
{
|
||||
for (; dest < cache + position + count; --source, dest++)
|
||||
if (*dest != 0xFF)
|
||||
if (*source != 0xFF)
|
||||
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
|
||||
|
@ -471,12 +483,12 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
wadnum = patch->wad;
|
||||
lumpnum = patch->lump;
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); // can't use W_CachePatchNumPwad because OpenGL
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
{
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength);
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
goto multipatch;
|
||||
}
|
||||
#endif
|
||||
|
@ -545,7 +557,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
texturememory += blocksize;
|
||||
block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]);
|
||||
|
||||
memset(block, 0xFF, blocksize+1); // Transparency hack
|
||||
memset(block, TRANSPARENTPIXEL, blocksize+1); // Transparency hack
|
||||
|
||||
// columns lookup table
|
||||
colofs = (UINT32 *)(void *)block;
|
||||
|
@ -569,7 +581,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength);
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
#endif
|
||||
|
||||
x1 = patch->originx;
|
||||
|
@ -2508,7 +2520,11 @@ void R_PrecacheLevel(void)
|
|||
"spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10));
|
||||
}
|
||||
|
||||
// https://github.com/coelckers/prboom-plus/blob/master/prboom2/src/r_patch.c#L350
|
||||
//
|
||||
// R_CheckIfPatch
|
||||
//
|
||||
// Returns true if the lump is a valid patch.
|
||||
//
|
||||
boolean R_CheckIfPatch(lumpnum_t lump)
|
||||
{
|
||||
size_t size;
|
||||
|
@ -2553,6 +2569,71 @@ boolean R_CheckIfPatch(lumpnum_t lump)
|
|||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// R_TextureToFlat
|
||||
//
|
||||
// Convert a texture to a flat.
|
||||
//
|
||||
void R_TextureToFlat(size_t tex, UINT8 *flat)
|
||||
{
|
||||
texture_t *texture = textures[tex];
|
||||
|
||||
fixed_t col, ofs;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest, *deststop;
|
||||
UINT8 *source;
|
||||
|
||||
// yea
|
||||
R_CheckTextureCache(tex);
|
||||
|
||||
desttop = flat;
|
||||
deststop = desttop + (texture->width * texture->height);
|
||||
|
||||
for (col = 0; col < texture->width; col++, desttop++)
|
||||
{
|
||||
// no post_t info
|
||||
if (!texture->holes)
|
||||
{
|
||||
column = (column_t *)(R_GetColumn(tex, col));
|
||||
source = (UINT8 *)(column);
|
||||
dest = desttop;
|
||||
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3);
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
dest = desttop + (topdelta * texture->width);
|
||||
source = (UINT8 *)column + 3;
|
||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_PatchToFlat
|
||||
//
|
||||
// Convert a patch to a flat.
|
||||
//
|
||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat)
|
||||
{
|
||||
fixed_t col, ofs;
|
||||
|
@ -2587,8 +2668,125 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_FlatToPatch
|
||||
//
|
||||
// Convert a flat to a patch.
|
||||
//
|
||||
static unsigned char imgbuf[1<<26];
|
||||
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency)
|
||||
{
|
||||
UINT32 x, y;
|
||||
UINT8 *img;
|
||||
UINT8 *imgptr = imgbuf;
|
||||
UINT8 *colpointers, *startofspan;
|
||||
size_t size = 0;
|
||||
|
||||
// Write image size and offset
|
||||
WRITEINT16(imgptr, width);
|
||||
WRITEINT16(imgptr, height);
|
||||
WRITEINT16(imgptr, leftoffset);
|
||||
WRITEINT16(imgptr, topoffset);
|
||||
|
||||
// Leave placeholder to column pointers
|
||||
colpointers = imgptr;
|
||||
imgptr += width*4;
|
||||
|
||||
// Write columns
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int lastStartY = 0;
|
||||
int spanSize = 0;
|
||||
startofspan = NULL;
|
||||
|
||||
// Write column pointer
|
||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
||||
|
||||
// Write pixels
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
UINT8 paletteIndex = raw[((y * width) + x)];
|
||||
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
|
||||
|
||||
// End span if we have a transparent pixel
|
||||
if (!opaque)
|
||||
{
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
startofspan = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start new column if we need to
|
||||
if (!startofspan || spanSize == 255)
|
||||
{
|
||||
int writeY = y;
|
||||
|
||||
// If we reached the span size limit, finish the previous span
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
if (y > 254)
|
||||
{
|
||||
// Make sure we're aligned to 254
|
||||
if (lastStartY < 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
lastStartY = 254;
|
||||
}
|
||||
|
||||
// Write stopgap empty spans if needed
|
||||
writeY = y - lastStartY;
|
||||
|
||||
while (writeY > 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
writeY -= 254;
|
||||
}
|
||||
}
|
||||
|
||||
startofspan = imgptr;
|
||||
WRITEUINT8(imgptr, writeY);
|
||||
imgptr += 2;
|
||||
spanSize = 0;
|
||||
|
||||
lastStartY = y;
|
||||
}
|
||||
|
||||
// Write the pixel
|
||||
WRITEUINT8(imgptr, paletteIndex);
|
||||
spanSize++;
|
||||
startofspan[1] = spanSize;
|
||||
}
|
||||
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
WRITEUINT8(imgptr, 0xFF);
|
||||
}
|
||||
|
||||
size = imgptr-imgbuf;
|
||||
img = Z_Malloc(size, PU_STATIC, NULL);
|
||||
memcpy(img, imgbuf, size);
|
||||
|
||||
Z_Free(raw);
|
||||
|
||||
if (destsize != NULL)
|
||||
*destsize = size;
|
||||
return (patch_t *)img;
|
||||
}
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
boolean R_IsLumpPNG(UINT8 *d, size_t s)
|
||||
//
|
||||
// R_IsLumpPNG
|
||||
//
|
||||
// Returns true if the lump is a valid PNG.
|
||||
//
|
||||
boolean R_IsLumpPNG(const UINT8 *d, size_t s)
|
||||
{
|
||||
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
||||
return false;
|
||||
|
@ -2599,21 +2797,49 @@ boolean R_IsLumpPNG(UINT8 *d, size_t s)
|
|||
}
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
|
||||
#if PNG_LIBPNG_VER_DLLNUM < 14
|
||||
typedef PNG_CONST png_byte *png_const_bytep;
|
||||
#endif
|
||||
typedef struct {
|
||||
png_bytep buffer;
|
||||
png_const_bytep buffer;
|
||||
png_uint_32 bufsize;
|
||||
png_uint_32 current_pos;
|
||||
} png_ioread;
|
||||
} png_io_t;
|
||||
|
||||
static void PNG_IOReader(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_ioread *f = png_get_io_ptr(png_ptr);
|
||||
png_io_t *f = png_get_io_ptr(png_ptr);
|
||||
if (length > (f->bufsize - f->current_pos))
|
||||
png_error(png_ptr, "PNG_IOReader: buffer overrun");
|
||||
memcpy(data, f->buffer + f->current_pos, length);
|
||||
f->current_pos += length;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[4];
|
||||
void *data;
|
||||
size_t size;
|
||||
} png_chunk_t;
|
||||
|
||||
static png_byte *chunkname = NULL;
|
||||
static png_chunk_t chunk;
|
||||
|
||||
static int PNG_ChunkReader(png_structp png_ptr, png_unknown_chunkp chonk)
|
||||
{
|
||||
(void)png_ptr;
|
||||
if (!memcmp(chonk->name, chunkname, 4))
|
||||
{
|
||||
memcpy(chunk.name, chonk->name, 4);
|
||||
chunk.size = chonk->size;
|
||||
chunk.data = Z_Malloc(chunk.size, PU_STATIC, NULL);
|
||||
memcpy(chunk.data, chonk->data, chunk.size);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PNG_error(png_structp PNG, png_const_charp pngtext)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "libpng error at %p: %s", PNG, pngtext);
|
||||
|
@ -2625,7 +2851,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
|
|||
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
|
||||
}
|
||||
|
||||
static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
||||
static png_bytep *PNG_Read(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop png_info_ptr;
|
||||
|
@ -2638,11 +2864,13 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
png_ioread png_io;
|
||||
png_io_t png_io;
|
||||
png_bytep *row_pointers;
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||
PNG_error, PNG_warn);
|
||||
png_byte grAb_chunk[5] = {'g', 'r', 'A', 'b', (png_byte)'\0'};
|
||||
png_voidp *user_chunk_ptr;
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
|
||||
if (!png_ptr)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "PNG_Load: Error on initialize libpng\n");
|
||||
|
@ -2672,19 +2900,24 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
|||
#endif
|
||||
|
||||
// set our own read_function
|
||||
png_io.buffer = (png_bytep)png;
|
||||
png_io.buffer = (png_const_bytep)png;
|
||||
png_io.bufsize = size;
|
||||
png_io.current_pos = 0;
|
||||
png_set_read_fn(png_ptr, &png_io, PNG_IOReader);
|
||||
|
||||
memset(&chunk, 0x00, sizeof(png_chunk_t));
|
||||
chunkname = grAb_chunk; // I want to read a grAb chunk
|
||||
|
||||
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
|
||||
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, PNG_ChunkReader);
|
||||
png_set_keep_unknown_chunks(png_ptr, 2, chunkname, 1);
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
png_set_user_limits(png_ptr, 2048, 2048);
|
||||
#endif
|
||||
|
||||
png_read_info(png_ptr, png_info_ptr);
|
||||
|
||||
png_get_IHDR(png_ptr, png_info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
NULL, NULL, NULL);
|
||||
png_get_IHDR(png_ptr, png_info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
|
||||
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
@ -2712,7 +2945,24 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
|||
for (y = 0; y < height; y++)
|
||||
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, png_info_ptr));
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
// Read grAB chunk
|
||||
if ((topoffset || leftoffset) && (chunk.data != NULL))
|
||||
{
|
||||
INT32 *offsets = (INT32 *)chunk.data;
|
||||
// read left offset
|
||||
if (leftoffset != NULL)
|
||||
*leftoffset = (INT16)BIGENDIAN_LONG(*offsets);
|
||||
offsets++;
|
||||
// read top offset
|
||||
if (topoffset != NULL)
|
||||
*topoffset = (INT16)BIGENDIAN_LONG(*offsets);
|
||||
}
|
||||
|
||||
// bye
|
||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
|
||||
if (chunk.data)
|
||||
Z_Free(chunk.data);
|
||||
|
||||
*w = (INT32)width;
|
||||
*h = (INT32)height;
|
||||
|
@ -2720,11 +2970,11 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
|||
}
|
||||
|
||||
// Convert a PNG to a raw image.
|
||||
static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
||||
static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
|
||||
{
|
||||
UINT8 *flat;
|
||||
png_uint_32 x, y;
|
||||
png_bytep *row_pointers = PNG_Read(png, w, h, size);
|
||||
png_bytep *row_pointers = PNG_Read(png, w, h, topoffset, leftoffset, size);
|
||||
png_uint_32 width = *w, height = *h;
|
||||
|
||||
if (!row_pointers)
|
||||
|
@ -2748,121 +2998,31 @@ static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
|
|||
return flat;
|
||||
}
|
||||
|
||||
//
|
||||
// R_PNGToFlat
|
||||
//
|
||||
// Convert a PNG to a flat.
|
||||
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size)
|
||||
//
|
||||
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size)
|
||||
{
|
||||
return PNG_RawConvert(png, &levelflat->width, &levelflat->height, size);
|
||||
return PNG_RawConvert(png, width, height, NULL, NULL, size);
|
||||
}
|
||||
|
||||
//
|
||||
// R_PNGToPatch
|
||||
//
|
||||
// Convert a PNG to a patch.
|
||||
static unsigned char imgbuf[1<<26];
|
||||
patch_t *R_PNGToPatch(UINT8 *png, size_t size)
|
||||
//
|
||||
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency)
|
||||
{
|
||||
UINT16 width, height;
|
||||
UINT8 *raw = PNG_RawConvert(png, &width, &height, size);
|
||||
|
||||
UINT32 x, y;
|
||||
UINT8 *img;
|
||||
UINT8 *imgptr = imgbuf;
|
||||
UINT8 *colpointers, *startofspan;
|
||||
|
||||
#define WRITE8(buf, a) ({*buf = (a); buf++;})
|
||||
#define WRITE16(buf, a) ({*buf = (a)&255; buf++; *buf = (a)>>8; buf++;})
|
||||
#define WRITE32(buf, a) ({WRITE16(buf, (a)&65535); WRITE16(buf, (a)>>16);})
|
||||
INT16 topoffset = 0, leftoffset = 0;
|
||||
UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size);
|
||||
|
||||
if (!raw)
|
||||
I_Error("R_PNGToPatch: conversion failed");
|
||||
|
||||
// Write image size and offset
|
||||
WRITE16(imgptr, width);
|
||||
WRITE16(imgptr, height);
|
||||
// no offsets
|
||||
WRITE16(imgptr, 0);
|
||||
WRITE16(imgptr, 0);
|
||||
|
||||
// Leave placeholder to column pointers
|
||||
colpointers = imgptr;
|
||||
imgptr += width*4;
|
||||
|
||||
// Write columns
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int lastStartY = 0;
|
||||
int spanSize = 0;
|
||||
startofspan = NULL;
|
||||
|
||||
//printf("%d ", x);
|
||||
// Write column pointer (@TODO may be wrong)
|
||||
WRITE32(colpointers, imgptr - imgbuf);
|
||||
|
||||
// Write pixels
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
UINT8 paletteIndex = raw[((y * width) + x)];
|
||||
|
||||
// Start new column if we need to
|
||||
if (!startofspan || spanSize == 255)
|
||||
{
|
||||
int writeY = y;
|
||||
|
||||
// If we reached the span size limit, finish the previous span
|
||||
if (startofspan)
|
||||
WRITE8(imgptr, 0);
|
||||
|
||||
if (y > 254)
|
||||
{
|
||||
// Make sure we're aligned to 254
|
||||
if (lastStartY < 254)
|
||||
{
|
||||
WRITE8(imgptr, 254);
|
||||
WRITE8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
lastStartY = 254;
|
||||
}
|
||||
|
||||
// Write stopgap empty spans if needed
|
||||
writeY = y - lastStartY;
|
||||
|
||||
while (writeY > 254)
|
||||
{
|
||||
WRITE8(imgptr, 254);
|
||||
WRITE8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
writeY -= 254;
|
||||
}
|
||||
}
|
||||
|
||||
startofspan = imgptr;
|
||||
WRITE8(imgptr, writeY);///@TODO calculate starting y pos
|
||||
imgptr += 2;
|
||||
spanSize = 0;
|
||||
|
||||
lastStartY = y;
|
||||
}
|
||||
|
||||
// Write the pixel
|
||||
WRITE8(imgptr, paletteIndex);
|
||||
spanSize++;
|
||||
startofspan[1] = spanSize;
|
||||
}
|
||||
|
||||
if (startofspan)
|
||||
WRITE8(imgptr, 0);
|
||||
|
||||
WRITE8(imgptr, 0xFF);
|
||||
}
|
||||
|
||||
#undef WRITE8
|
||||
#undef WRITE16
|
||||
#undef WRITE32
|
||||
|
||||
size = imgptr-imgbuf;
|
||||
img = malloc(size);
|
||||
memcpy(img, imgbuf, size);
|
||||
|
||||
Z_Free(raw);
|
||||
|
||||
return (patch_t *)img;
|
||||
return R_FlatToPatch(raw, width, height, leftoffset, topoffset, destsize, transparency);
|
||||
}
|
||||
|
||||
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
|
||||
|
@ -2877,7 +3037,7 @@ boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
png_ioread png_io;
|
||||
png_io_t png_io;
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||
PNG_error, PNG_warn);
|
||||
|
@ -2933,53 +3093,3 @@ boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void R_TextureToFlat(size_t tex, UINT8 *flat)
|
||||
{
|
||||
texture_t *texture = textures[tex];
|
||||
|
||||
fixed_t col, ofs;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest, *deststop;
|
||||
UINT8 *source;
|
||||
|
||||
desttop = flat;
|
||||
deststop = desttop + (texture->width * texture->height);
|
||||
|
||||
for (col = 0; col < texture->width; col++, desttop++)
|
||||
{
|
||||
column = (column_t *)R_GetColumn(tex, col);
|
||||
if (!texture->holes)
|
||||
{
|
||||
dest = desttop;
|
||||
source = (UINT8 *)(column);
|
||||
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
dest = desttop + (topdelta * texture->width);
|
||||
source = (UINT8 *)(column) + 3;
|
||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
src/r_data.h
13
src/r_data.h
|
@ -25,7 +25,7 @@
|
|||
// Possible alpha types for a patch.
|
||||
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
|
||||
|
||||
RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
|
||||
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
|
||||
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha);
|
||||
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
|
@ -159,16 +159,15 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
|||
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||
|
||||
boolean R_CheckIfPatch(lumpnum_t lump);
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
|
||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
|
||||
void R_TextureToFlat(size_t tex, UINT8 *flat);
|
||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
|
||||
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
boolean R_IsLumpPNG(UINT8 *d, size_t s);
|
||||
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
|
||||
|
||||
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size);
|
||||
patch_t *R_PNGToPatch(UINT8 *png, size_t size);
|
||||
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size);
|
||||
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency);
|
||||
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
|
||||
#endif
|
||||
|
||||
|
|
17
src/r_defs.h
17
src/r_defs.h
|
@ -139,9 +139,9 @@ typedef enum
|
|||
FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top.
|
||||
FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
|
||||
FF_INTANGABLEFLATS = 0x6000000, ///< Both flats are intangable, but the sides are still solid.
|
||||
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles.
|
||||
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball.
|
||||
FF_ONLYKNUX = 0x20000000, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock.
|
||||
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
|
||||
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
|
||||
FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
FF_RIPPLE = 0x40000000, ///< Ripple the flats
|
||||
FF_COLORMAPONLY = 0x80000000, ///< Only copy the colormap, not the lightlevel
|
||||
FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
@ -263,10 +263,15 @@ typedef struct pslope_s
|
|||
|
||||
typedef enum
|
||||
{
|
||||
// flipspecial - planes with effect
|
||||
SF_FLIPSPECIAL_FLOOR = 1,
|
||||
SF_FLIPSPECIAL_CEILING = 2,
|
||||
SF_FLIPSPECIAL_BOTH = 3,
|
||||
SF_TRIGGERSPECIAL_TOUCH = 4,
|
||||
SF_FLIPSPECIAL_CEILING = 1<<1,
|
||||
SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
|
||||
// triggerspecial - conditions under which plane touch causes effect
|
||||
SF_TRIGGERSPECIAL_TOUCH = 1<<2,
|
||||
SF_TRIGGERSPECIAL_HEADBUMP = 1<<3,
|
||||
// invertprecip - inverts presence of precipitation
|
||||
SF_INVERTPRECIP = 1<<4,
|
||||
} sectorflags_t;
|
||||
|
||||
//
|
||||
|
|
38
src/r_draw.c
38
src/r_draw.c
|
@ -130,10 +130,11 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
|
|||
#define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
|
||||
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
|
||||
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
|
||||
#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
|
||||
#define DEFAULT_STARTTRANSCOLOR 96
|
||||
#define NUM_PALETTE_ENTRIES 256
|
||||
|
||||
static UINT8** translationtablecache[MAXSKINS + 6] = {NULL};
|
||||
static UINT8** translationtablecache[MAXSKINS + 7] = {NULL};
|
||||
|
||||
const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = {
|
||||
// {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE
|
||||
|
@ -569,6 +570,40 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
|
|||
dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i];
|
||||
dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0;
|
||||
}
|
||||
else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
|
||||
{
|
||||
// greens -> ketchups
|
||||
dest_colormap[96] = dest_colormap[97] = 48;
|
||||
dest_colormap[98] = 49;
|
||||
dest_colormap[99] = 51;
|
||||
dest_colormap[100] = 52;
|
||||
dest_colormap[101] = dest_colormap[102] = 54;
|
||||
dest_colormap[103] = 34;
|
||||
dest_colormap[104] = 37;
|
||||
dest_colormap[105] = 39;
|
||||
dest_colormap[106] = 41;
|
||||
for (i = 0; i < 5; i++)
|
||||
dest_colormap[107 + i] = 43 + i;
|
||||
|
||||
// reds -> steel blues
|
||||
dest_colormap[32] = 146;
|
||||
dest_colormap[33] = 147;
|
||||
dest_colormap[34] = dest_colormap[35] = 170;
|
||||
dest_colormap[36] = 171;
|
||||
dest_colormap[37] = dest_colormap[38] = 172;
|
||||
dest_colormap[39] = dest_colormap[40] = dest_colormap[41] = 173;
|
||||
dest_colormap[42] = dest_colormap[43] = dest_colormap[44] = 174;
|
||||
dest_colormap[45] = dest_colormap[46] = dest_colormap[47] = 175;
|
||||
dest_colormap[71] = 139;
|
||||
|
||||
// steel blues -> oranges
|
||||
dest_colormap[170] = 52;
|
||||
dest_colormap[171] = 54;
|
||||
dest_colormap[172] = 56;
|
||||
dest_colormap[173] = 42;
|
||||
dest_colormap[174] = 45;
|
||||
dest_colormap[175] = 47;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (color == SKINCOLOR_NONE)
|
||||
|
@ -628,6 +663,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags)
|
|||
case TC_ALLWHITE: skintableindex = ALLWHITE_TT_CACHE_INDEX; break;
|
||||
case TC_RAINBOW: skintableindex = RAINBOW_TT_CACHE_INDEX; break;
|
||||
case TC_BLINK: skintableindex = BLINK_TT_CACHE_INDEX; break;
|
||||
case TC_DASHMODE: skintableindex = DASHMODE_TT_CACHE_INDEX; break;
|
||||
default: skintableindex = skinnum; break;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ extern lumpnum_t viewborderlump[8];
|
|||
#define TC_ALLWHITE -4 // For Cy-Brak-demon
|
||||
#define TC_RAINBOW -5 // For single colour
|
||||
#define TC_BLINK -6 // For item blinking, according to kart
|
||||
#define TC_DASHMODE -7 // For Metal Sonic's dashmode
|
||||
|
||||
// Initialize color translation tables, for player rendering etc.
|
||||
void R_InitTranslationTables(void);
|
||||
|
|
|
@ -1182,6 +1182,8 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_cam_speed);
|
||||
CV_RegisterVar(&cv_cam_rotate);
|
||||
CV_RegisterVar(&cv_cam_rotspeed);
|
||||
CV_RegisterVar(&cv_cam_orbit);
|
||||
CV_RegisterVar(&cv_cam_adjust);
|
||||
|
||||
CV_RegisterVar(&cv_cam2_dist);
|
||||
CV_RegisterVar(&cv_cam2_still);
|
||||
|
@ -1189,6 +1191,8 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_cam2_speed);
|
||||
CV_RegisterVar(&cv_cam2_rotate);
|
||||
CV_RegisterVar(&cv_cam2_rotspeed);
|
||||
CV_RegisterVar(&cv_cam2_orbit);
|
||||
CV_RegisterVar(&cv_cam2_adjust);
|
||||
|
||||
CV_RegisterVar(&cv_showhud);
|
||||
CV_RegisterVar(&cv_translucenthud);
|
||||
|
|
106
src/r_plane.c
106
src/r_plane.c
|
@ -44,6 +44,9 @@
|
|||
// Quincunx antialiasing of flats!
|
||||
//#define QUINCUNX
|
||||
|
||||
// good night sweet prince
|
||||
#define SHITPLANESPARENCY
|
||||
|
||||
//SoM: 3/23/2000: Use Boom visplane hashing.
|
||||
|
||||
visplane_t *visplanes[MAXVISPLANES];
|
||||
|
@ -650,17 +653,33 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckPowersOfTwo
|
||||
//
|
||||
// Self-explanatory?
|
||||
//
|
||||
boolean R_CheckPowersOfTwo(void)
|
||||
{
|
||||
if (ds_flatwidth & (ds_flatwidth - 1))
|
||||
boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1)));
|
||||
boolean hpow2 = (!(ds_flatheight & (ds_flatheight - 1)));
|
||||
|
||||
// Initially, the flat isn't powers-of-two-sized.
|
||||
ds_powersoftwo = false;
|
||||
else if (ds_flatheight & (ds_flatheight - 1))
|
||||
ds_powersoftwo = false;
|
||||
else if (ds_flatwidth == ds_flatheight)
|
||||
|
||||
// But if the width and height are powers of two,
|
||||
// and are EQUAL, then it's okay :]
|
||||
if ((ds_flatwidth == ds_flatheight) && (wpow2 && hpow2))
|
||||
ds_powersoftwo = true;
|
||||
|
||||
// Just return ds_powersoftwo.
|
||||
return ds_powersoftwo;
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckFlatLength
|
||||
//
|
||||
// Determine the flat's dimensions from the lump length.
|
||||
//
|
||||
void R_CheckFlatLength(size_t size)
|
||||
{
|
||||
switch (size)
|
||||
|
@ -717,7 +736,24 @@ void R_CheckFlatLength(size_t size)
|
|||
}
|
||||
}
|
||||
|
||||
static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
|
||||
//
|
||||
// R_GenerateFlat
|
||||
//
|
||||
// Generate a flat from specified width and height.
|
||||
//
|
||||
static UINT8 *R_GenerateFlat(UINT16 width, UINT16 height)
|
||||
{
|
||||
UINT8 *flat = Z_Malloc(width * height, PU_LEVEL, NULL);
|
||||
memset(flat, TRANSPARENTPIXEL, width * height);
|
||||
return flat;
|
||||
}
|
||||
|
||||
//
|
||||
// R_GetTextureFlat
|
||||
//
|
||||
// Convert a texture or patch to a flat.
|
||||
//
|
||||
static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
|
||||
{
|
||||
UINT8 *flat;
|
||||
textureflat_t *texflat = &texflats[levelflat->texturenum];
|
||||
|
@ -741,14 +777,14 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
// If the texture changed, or the patch doesn't exist, convert either of them to a flat.
|
||||
if (levelflat->flatpatch == NULL || texturechanged)
|
||||
{
|
||||
// Level texture
|
||||
if (leveltexture)
|
||||
{
|
||||
texture_t *texture = textures[levelflat->texturenum];
|
||||
texflat->width = ds_flatwidth = texture->width;
|
||||
texflat->height = ds_flatheight = texture->height;
|
||||
|
||||
texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
|
||||
memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
|
||||
texflat->flat = R_GenerateFlat(ds_flatwidth, ds_flatheight);
|
||||
R_TextureToFlat(levelflat->texturenum, texflat->flat);
|
||||
flat = texflat->flat;
|
||||
|
||||
|
@ -756,13 +792,14 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
levelflat->width = ds_flatwidth;
|
||||
levelflat->height = ds_flatheight;
|
||||
}
|
||||
// Patch (never happens yet)
|
||||
else
|
||||
{
|
||||
patch = (patch_t *)ds_source;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (ispng)
|
||||
{
|
||||
levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum));
|
||||
levelflat->flatpatch = R_PNGToFlat(&levelflat->width, &levelflat->height, ds_source, W_LumpLength(levelflat->lumpnum));
|
||||
levelflat->topoffset = levelflat->leftoffset = 0;
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
|
@ -776,8 +813,7 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
levelflat->topoffset = patch->topoffset * FRACUNIT;
|
||||
levelflat->leftoffset = patch->leftoffset * FRACUNIT;
|
||||
|
||||
levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
|
||||
memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
|
||||
levelflat->flatpatch = R_GenerateFlat(ds_flatwidth, ds_flatheight);
|
||||
R_PatchToFlat(patch, levelflat->flatpatch);
|
||||
}
|
||||
flat = levelflat->flatpatch;
|
||||
|
@ -788,10 +824,10 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
flat = levelflat->flatpatch;
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
}
|
||||
|
||||
xoffs += levelflat->leftoffset;
|
||||
yoffs += levelflat->topoffset;
|
||||
}
|
||||
|
||||
levelflat->lasttexturenum = levelflat->texturenum;
|
||||
return flat;
|
||||
|
@ -806,6 +842,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
size_t size;
|
||||
ffloor_t *rover;
|
||||
levelflat_t *levelflat;
|
||||
boolean rawflat = false;
|
||||
|
||||
if (!(pl->minx <= pl->maxx))
|
||||
return;
|
||||
|
@ -834,7 +871,11 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunc = splatfunc;
|
||||
|
||||
#ifdef SHITPLANESPARENCY
|
||||
if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
@ -888,7 +929,11 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunc = splatfunc;
|
||||
|
||||
#ifdef SHITPLANESPARENCY
|
||||
if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
@ -956,18 +1001,19 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
// Check if the flat is actually a wall texture.
|
||||
if (levelflat->texturenum != 0 && levelflat->texturenum != -1)
|
||||
flat = R_GetPatchFlat(levelflat, true, false);
|
||||
flat = R_GetTextureFlat(levelflat, true, false);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
// Maybe it's a PNG?!
|
||||
else if (R_IsLumpPNG(ds_source, size))
|
||||
flat = R_GetPatchFlat(levelflat, false, true);
|
||||
flat = R_GetTextureFlat(levelflat, false, true);
|
||||
#endif
|
||||
// Maybe it's just a patch, then?
|
||||
else if (R_CheckIfPatch(levelflat->lumpnum))
|
||||
flat = R_GetPatchFlat(levelflat, false, false);
|
||||
flat = R_GetTextureFlat(levelflat, false, false);
|
||||
// It's a raw flat.
|
||||
else
|
||||
{
|
||||
rawflat = true;
|
||||
R_CheckFlatLength(size);
|
||||
flat = ds_source;
|
||||
}
|
||||
|
@ -978,8 +1024,11 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
if (ds_source == NULL)
|
||||
return;
|
||||
|
||||
// Check if the flat has dimensions that are powers-of-two numbers.
|
||||
if (R_CheckPowersOfTwo())
|
||||
// Raw flats always have dimensions that are powers-of-two numbers.
|
||||
if (rawflat)
|
||||
ds_powersoftwo = true;
|
||||
// Otherwise, check if this texture or patch has such dimensions.
|
||||
else if (R_CheckPowersOfTwo())
|
||||
{
|
||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
if (spanfunc == basespanfunc)
|
||||
|
@ -1064,7 +1113,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
|
||||
zeroheight = FIXED_TO_FLOAT(temp);
|
||||
|
||||
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
|
||||
#define ANG2RAD(angle) ((float)((angle)*M_PIl)/ANGLE_180)
|
||||
|
||||
// p is the texture origin in view space
|
||||
// Don't add in the offsets at this stage, because doing so can result in
|
||||
|
@ -1116,26 +1165,27 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
ds_sz.z *= focallengthf;
|
||||
|
||||
// Premultiply the texture vectors with the scale factors
|
||||
#define SFMULT 65536.f
|
||||
if (ds_powersoftwo)
|
||||
{
|
||||
#define SFMULT 65536.f*(1<<nflatshiftup)
|
||||
ds_su.x *= (SFMULT * (1<<nflatshiftup));
|
||||
ds_su.y *= (SFMULT * (1<<nflatshiftup));
|
||||
ds_su.z *= (SFMULT * (1<<nflatshiftup));
|
||||
ds_sv.x *= (SFMULT * (1<<nflatshiftup));
|
||||
ds_sv.y *= (SFMULT * (1<<nflatshiftup));
|
||||
ds_sv.z *= (SFMULT * (1<<nflatshiftup));
|
||||
}
|
||||
else
|
||||
{
|
||||
// I'm essentially multiplying the vectors by FRACUNIT...
|
||||
ds_su.x *= SFMULT;
|
||||
ds_su.y *= SFMULT;
|
||||
ds_su.z *= SFMULT;
|
||||
ds_sv.x *= SFMULT;
|
||||
ds_sv.y *= SFMULT;
|
||||
ds_sv.z *= SFMULT;
|
||||
}
|
||||
#undef SFMULT
|
||||
}
|
||||
else
|
||||
{
|
||||
ds_su.x *= 65536.f;
|
||||
ds_su.y *= 65536.f;
|
||||
ds_su.z *= 65536.f;
|
||||
ds_sv.x *= 65536.f;
|
||||
ds_sv.y *= 65536.f;
|
||||
ds_sv.z *= 65536.f;
|
||||
}
|
||||
|
||||
if (spanfunc == R_DrawTranslucentSpan_8)
|
||||
spanfunc = R_DrawTiltedTranslucentSpan_8;
|
||||
|
|
|
@ -254,6 +254,19 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
// store sprite info in lookup tables
|
||||
//FIXME : numspritelumps do not duplicate sprite replacements
|
||||
W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof (patch_t), 0);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
{
|
||||
patch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
|
||||
size_t len = W_LumpLengthPwad(wadnum, l);
|
||||
// lump is a png so convert it
|
||||
if (R_IsLumpPNG((UINT8 *)png, len))
|
||||
{
|
||||
png = R_PNGToPatch((UINT8 *)png, len, NULL, true);
|
||||
M_Memcpy(&patch, png, sizeof(INT16)*4);
|
||||
}
|
||||
Z_Free(png);
|
||||
}
|
||||
#endif
|
||||
spritecachedinfo[numspritelumps].width = SHORT(patch.width)<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].offset = SHORT(patch.leftoffset)<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].topoffset = SHORT(patch.topoffset)<<FRACBITS;
|
||||
|
@ -701,7 +714,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
INT32 texturecolumn;
|
||||
#endif
|
||||
fixed_t frac;
|
||||
patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE);
|
||||
patch_t *patch = W_CachePatchNum(vis->patch, PU_CACHE);
|
||||
fixed_t this_scale = vis->mobj->scale;
|
||||
INT32 x1, x2;
|
||||
INT64 overflow_test;
|
||||
|
@ -740,6 +753,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
dc_transmap = vis->transmap;
|
||||
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
|
||||
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
|
||||
else if (!(vis->cut & SC_PRECIP)
|
||||
&& vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
}
|
||||
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
|
||||
{
|
||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||
|
@ -761,6 +781,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
// New colormap stuff for skins Tails 06-07-2002
|
||||
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
|
||||
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
|
||||
else if (!(vis->cut & SC_PRECIP)
|
||||
&& vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
}
|
||||
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||
{
|
||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||
|
@ -870,7 +897,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
INT64 overflow_test;
|
||||
|
||||
//Fab : R_InitSprites now sets a wad lump number
|
||||
patch = W_CacheLumpNum(vis->patch, PU_CACHE);
|
||||
patch = W_CachePatchNum(vis->patch, PU_CACHE);
|
||||
if (!patch)
|
||||
return;
|
||||
|
||||
|
@ -1217,7 +1244,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
range = 1;
|
||||
|
||||
scalestep = (yscale2 - yscale)/range;
|
||||
scalestep = (yscale2 - yscale)/range ?: 1;
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
@ -1624,7 +1651,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
mobj_t *thing;
|
||||
precipmobj_t *precipthing; // Tails 08-25-2002
|
||||
INT32 lightnum;
|
||||
fixed_t approx_dist, limit_dist;
|
||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
@ -1655,7 +1682,9 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
|
||||
// Handle all things in sector.
|
||||
// If a limit exists, handle things a tiny bit different.
|
||||
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS))
|
||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
if (limit_dist || hoop_limit_dist)
|
||||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
@ -1664,8 +1693,16 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (approx_dist > limit_dist)
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
continue;
|
||||
}
|
||||
|
||||
R_ProjectSprite(thing);
|
||||
}
|
||||
|
@ -2511,7 +2548,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
if (!skin)
|
||||
return 0;
|
||||
|
||||
if ((unsigned)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!(skin->sprites[spr2].numframes)
|
||||
|
@ -2603,6 +2640,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
|
|||
skin->followitem = 0;
|
||||
|
||||
skin->highresscale = FRACUNIT;
|
||||
skin->contspeed = 17;
|
||||
skin->contangle = 0;
|
||||
|
||||
skin->availability = 0;
|
||||
|
||||
|
@ -2771,9 +2810,9 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin not found\n"));
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin not found\n", playernum, player_names[playernum]);
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
||||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||
}
|
||||
|
||||
|
@ -2869,6 +2908,8 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski
|
|||
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
|
||||
R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[sprite2], wadnum, *lump, *lastlump);
|
||||
|
||||
if (skin->sprites[0].numframes == 0)
|
||||
I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]);
|
||||
}
|
||||
|
||||
// returns whether found appropriate property
|
||||
|
@ -2907,6 +2948,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
|||
GETINT(thrustfactor)
|
||||
GETINT(accelstart)
|
||||
GETINT(acceleration)
|
||||
GETINT(contspeed)
|
||||
GETINT(contangle)
|
||||
#undef GETINT
|
||||
|
||||
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue