mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-17 10:11:02 +00:00
Merge remote-tracking branch 'refs/remotes/origin/master' into save-mode
This commit is contained in:
commit
0b05b10bdb
129 changed files with 7979 additions and 4429 deletions
63
.circleci/config.yml
Normal file
63
.circleci/config.yml
Normal file
|
@ -0,0 +1,63 @@
|
|||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
working_directory: /root/SRB2
|
||||
docker:
|
||||
- image: debian:jessie
|
||||
environment:
|
||||
CC: ccache gcc -m32
|
||||
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
||||
LIBGME_CFLAGS: -I/usr/include
|
||||
LIBGME_LDFLAGS: -lgme
|
||||
CCACHE_COMPRESS: true
|
||||
WFLAGS: -Wno-unsuffixed-float-constants
|
||||
GCC49: true
|
||||
#- image: ubuntu:trusty
|
||||
# environment:
|
||||
# CC: ccache gcc -m32
|
||||
# PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
||||
# LIBGME_CFLAGS: -I/usr/include
|
||||
# LIBGME_LDFLAGS: -lgme
|
||||
# CCACHE_COMPRESS: true
|
||||
# WFLAGS: -Wno-unsuffixed-float-constants
|
||||
# GCC48: true
|
||||
steps:
|
||||
- run:
|
||||
name: Add i386 arch
|
||||
command: dpkg --add-architecture i386
|
||||
- run:
|
||||
name: Update APT listing
|
||||
command: apt-get -qq update
|
||||
- run:
|
||||
name: Support S3 upload
|
||||
command: apt-get -qq -y install ca-certificates
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-SRB2-APT
|
||||
- run:
|
||||
name: Install SDK
|
||||
command: apt-get -qq -y install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx
|
||||
- save_cache:
|
||||
key: v1-SRB2-APT
|
||||
paths:
|
||||
- /var/cache/apt/archives
|
||||
- checkout
|
||||
- run:
|
||||
name: Clean build
|
||||
command: make -C src LINUX=1 clean
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-SRB2-{{ .Branch }}-{{ checksum "objs/Linux/SDL/Release/depend.dep" }}
|
||||
- run:
|
||||
name: Compile
|
||||
command: make -C src LINUX=1 ERRORMODE=1 -k
|
||||
- store_artifacts:
|
||||
path: /root/SRB2/bin/Linux/Release/
|
||||
destination: bin
|
||||
- save_cache:
|
||||
key: v1-SRB2-{{ .Branch }}-{{ checksum "objs/Linux/SDL/Release/depend.dep" }}
|
||||
paths:
|
||||
- /root/.ccache
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(SRB2
|
||||
VERSION 2.1.17
|
||||
VERSION 2.1.19
|
||||
LANGUAGES C)
|
||||
|
||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2)
|
||||
[![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2)
|
||||
[![CircleCI](https://circleci.com/gh/STJr/SRB2/tree/master.svg?style=svg)](https://circleci.com/gh/STJr/SRB2/tree/master)
|
||||
|
||||
[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/).
|
||||
|
||||
|
|
37
appveyor.yml
37
appveyor.yml
|
@ -1,4 +1,4 @@
|
|||
version: 2.1.17.{branch}-{build}
|
||||
version: 2.1.19.{branch}-{build}
|
||||
os: MinGW
|
||||
|
||||
environment:
|
||||
|
@ -47,7 +47,7 @@ before_build:
|
|||
- upx -V
|
||||
- ccache -V
|
||||
- ccache -s
|
||||
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1
|
||||
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1 NOOBJDUMP=1
|
||||
|
||||
build_script:
|
||||
- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
|
||||
|
@ -58,26 +58,29 @@ after_build:
|
|||
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
|
||||
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
||||
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
|
||||
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
|
||||
- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
|
||||
- appveyor PushArtifact %BUILD_ARCHIVE%
|
||||
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
|
||||
- appveyor PushArtifact %BUILDSARCHIVE%
|
||||
|
||||
test: off
|
||||
|
||||
deploy:
|
||||
- provider: FTP
|
||||
protocol: ftps
|
||||
host:
|
||||
secure: NsLJEPIBvmwCOj8Tg8RoRQ==
|
||||
username:
|
||||
secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
|
||||
password:
|
||||
secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
|
||||
folder: appveyor
|
||||
application:
|
||||
active_mode: false
|
||||
on:
|
||||
branch: master
|
||||
appveyor_repo_tag: true
|
||||
#deploy:
|
||||
# - provider: FTP
|
||||
# protocol: ftps
|
||||
# host:
|
||||
# secure: NsLJEPIBvmwCOj8Tg8RoRQ==
|
||||
# username:
|
||||
# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
|
||||
# password:
|
||||
# secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
|
||||
# folder: appveyor
|
||||
# application:
|
||||
# active_mode: false
|
||||
# on:
|
||||
# branch: master
|
||||
# appveyor_repo_tag: true
|
||||
|
||||
|
||||
on_finish:
|
||||
|
|
6
bin/Mingw/Debug/.gitignore
vendored
6
bin/Mingw/Debug/.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
/srb2sdl.exe
|
||||
/srb2win.exe
|
||||
/r_opengl.dll
|
||||
*.exe
|
||||
*.mo
|
||||
r_opengl.dll
|
||||
|
|
6
bin/Mingw/Release/.gitignore
vendored
6
bin/Mingw/Release/.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
/srb2sdl.exe
|
||||
/srb2win.exe
|
||||
/r_opengl.dll
|
||||
*.exe
|
||||
*.mo
|
||||
r_opengl.dll
|
||||
|
|
8
objs/.gitignore
vendored
Normal file
8
objs/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
#All folders
|
||||
SRB2.res
|
||||
depend.dep
|
||||
depend.ped
|
||||
*.o
|
||||
#VC9 folder only
|
||||
/VC9/Win32
|
||||
/VC9/x64
|
3
objs/DC/SDL/Debug/.gitignore
vendored
3
objs/DC/SDL/Debug/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.dep
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
3
objs/DC/SDL/Release/.gitignore
vendored
3
objs/DC/SDL/Release/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.dep
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/Linux/SDL/Debug/.gitignore
vendored
4
objs/Linux/SDL/Debug/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/Linux/SDL/Release/.gitignore
vendored
4
objs/Linux/SDL/Release/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/Linux64/SDL/Debug/.gitignore
vendored
4
objs/Linux64/SDL/Debug/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/Linux64/SDL/Release/.gitignore
vendored
4
objs/Linux64/SDL/Release/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw/Debug/.gitignore
vendored
5
objs/Mingw/Debug/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw/Release/.gitignore
vendored
5
objs/Mingw/Release/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw/SDL/Debug/.gitignore
vendored
5
objs/Mingw/SDL/Debug/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw/SDL/Release/.gitignore
vendored
5
objs/Mingw/SDL/Release/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw64/Debug/.gitignore
vendored
5
objs/Mingw64/Debug/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw64/Release/.gitignore
vendored
5
objs/Mingw64/Release/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw64/SDL/Debug/.gitignore
vendored
5
objs/Mingw64/SDL/Debug/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
5
objs/Mingw64/SDL/Release/.gitignore
vendored
5
objs/Mingw64/SDL/Release/.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/SRB2.res
|
||||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/PS3/SDL/Debug/.gitignore
vendored
4
objs/PS3/SDL/Debug/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/PS3/SDL/Release/.gitignore
vendored
4
objs/PS3/SDL/Release/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
3
objs/PSP/SDL/Release/.gitignore
vendored
3
objs/PSP/SDL/Release/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.dep
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
3
objs/SDL/Release/.gitignore
vendored
3
objs/SDL/Release/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.ped
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
2
objs/VC/.gitignore
vendored
2
objs/VC/.gitignore
vendored
|
@ -0,0 +1,2 @@
|
|||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
4
objs/VC9/.gitignore
vendored
4
objs/VC9/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/Win32
|
||||
/x64
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/Wii/SDL/Debug/.gitignore
vendored
4
objs/Wii/SDL/Debug/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/Wii/SDL/Release/.gitignore
vendored
4
objs/Wii/SDL/Release/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
3
objs/WinCE/SDL/Release/.gitignore
vendored
3
objs/WinCE/SDL/Release/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.dep
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
3
objs/djgppdos/Debug/.gitignore
vendored
3
objs/djgppdos/Debug/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.dep
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
3
objs/djgppdos/Release/.gitignore
vendored
3
objs/djgppdos/Release/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/depend.dep
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/nds/Debug/.gitignore
vendored
4
objs/nds/Debug/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
4
objs/nds/Release/.gitignore
vendored
4
objs/nds/Release/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/depend.dep
|
||||
/*.o
|
||||
# DON'T REMOVE
|
||||
# This keeps the folder from disappearing
|
||||
|
|
|
@ -511,13 +511,11 @@ OBJS:=$(i_main_o) \
|
|||
# For reference, this is the command I use to build a srb2.pot file from the source code.
|
||||
# (The listed source files are the ones containing translated strings).
|
||||
# FILES=""; for file in `find ./ | grep "\.c" | grep -v svn`; do [ "`grep "M_GetText(" $file`" ] && FILES="$FILES $file"; done; xgettext -d srb2 -o locale/srb2.pot -kM_GetText -F --no-wrap $FILES
|
||||
ifndef NOGETTEXT
|
||||
ifdef GETTEXT
|
||||
POS:=$(BIN)/en.mo
|
||||
|
||||
OPTS+=-DGETTEXT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef DJGPPDOS
|
||||
all: pre-build $(BIN)/$(EXENAME)
|
||||
|
|
|
@ -283,9 +283,6 @@ else
|
|||
ifdef LINUX
|
||||
NASMFORMAT=elf -DLINUX
|
||||
SDL=1
|
||||
ifndef NOGETTEXT
|
||||
GETTEXT=1
|
||||
endif
|
||||
ifdef LINUX64
|
||||
OBJDIR:=$(OBJDIR)/Linux64
|
||||
BIN:=$(BIN)/Linux64
|
||||
|
@ -321,9 +318,6 @@ else
|
|||
ifdef MINGW64
|
||||
INTERFACE=win32
|
||||
#NASMFORMAT=win64
|
||||
ifndef NOGETTEXT
|
||||
#GETTEXT=1
|
||||
endif
|
||||
OBJDIR:=$(OBJDIR)/Mingw64
|
||||
BIN:=$(BIN)/Mingw64
|
||||
else
|
||||
|
@ -354,9 +348,6 @@ else
|
|||
ifdef MINGW
|
||||
INTERFACE=win32
|
||||
NASMFORMAT=win32
|
||||
ifndef NOGETTEXT
|
||||
GETTEXT=1
|
||||
endif
|
||||
OBJDIR:=$(OBJDIR)/Mingw
|
||||
BIN:=$(BIN)/Mingw
|
||||
else
|
||||
|
|
|
@ -212,7 +212,7 @@ boolean B_CheckRespawn(player_t *player)
|
|||
|
||||
// Check if Sonic is busy first.
|
||||
// If he's doing any of these things, he probably doesn't want to see us.
|
||||
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_NIGHTSMODE)
|
||||
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)
|
||||
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)
|
||||
|| (sonic->player->powers[pw_carry]))
|
||||
return false;
|
||||
|
|
|
@ -1165,7 +1165,7 @@ found:
|
|||
if (var == &cv_forceskin)
|
||||
{
|
||||
var->value = R_SkinAvailable(var->string);
|
||||
if (!R_SkinUnlock(var->value))
|
||||
if (!R_SkinUsable(-1, var->value))
|
||||
var->value = -1;
|
||||
}
|
||||
else
|
||||
|
@ -1361,6 +1361,16 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
|||
return;
|
||||
}
|
||||
|
||||
if (var == &cv_forceskin)
|
||||
{
|
||||
INT32 skin = R_SkinAvailable(value);
|
||||
if ((stricmp(value, "None")) && ((skin == -1) || !R_SkinUsable(-1, skin)))
|
||||
{
|
||||
CONS_Printf("Please provide a valid skin name (\"None\" disables).\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Only add to netcmd buffer if in a netgame, otherwise, just change it.
|
||||
if (netgame || multiplayer)
|
||||
{
|
||||
|
@ -1478,7 +1488,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
else if (newvalue >= numskins)
|
||||
newvalue = -1;
|
||||
} while ((oldvalue != newvalue)
|
||||
&& !(R_SkinUnlock(newvalue)));
|
||||
&& !(R_SkinUsable(-1, newvalue)));
|
||||
}
|
||||
else
|
||||
newvalue = var->value + increment;
|
||||
|
@ -1551,34 +1561,27 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
if (var == &cv_chooseskin)
|
||||
{
|
||||
// Special case for the chooseskin variable, used only directly from the menu
|
||||
if (increment > 0) // Going up!
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
if (increment > 0) // Going up!
|
||||
{
|
||||
newvalue++;
|
||||
if (newvalue == MAXSKINS)
|
||||
newvalue = 0;
|
||||
} while (var->PossibleValue[newvalue].strvalue == NULL);
|
||||
var->value = newvalue + 1;
|
||||
var->string = var->PossibleValue[newvalue].strvalue;
|
||||
var->func();
|
||||
return;
|
||||
}
|
||||
else if (increment < 0) // Going down!
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
}
|
||||
else if (increment < 0) // Going down!
|
||||
{
|
||||
newvalue--;
|
||||
if (newvalue == -1)
|
||||
newvalue = MAXSKINS-1;
|
||||
} while (var->PossibleValue[newvalue].strvalue == NULL);
|
||||
var->value = newvalue + 1;
|
||||
var->string = var->PossibleValue[newvalue].strvalue;
|
||||
var->func();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (var->PossibleValue[newvalue].strvalue == NULL);
|
||||
|
||||
var->value = newvalue + 1;
|
||||
var->string = var->PossibleValue[newvalue].strvalue;
|
||||
var->func();
|
||||
return;
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
if (currentindice == -1)
|
||||
|
|
|
@ -1394,32 +1394,32 @@ static void CON_DrawInput(void)
|
|||
if (input_sel < c)
|
||||
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART);
|
||||
for (i = 0; i < 3; ++i, x += charwidth)
|
||||
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
|
||||
}
|
||||
else
|
||||
V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
|
||||
|
||||
for (cend = c + clen; c < cend; ++c, x += charwidth)
|
||||
{
|
||||
if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c))
|
||||
{
|
||||
V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART);
|
||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, true);
|
||||
}
|
||||
else
|
||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
|
||||
if (c == input_cur && con_tick >= 4)
|
||||
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
}
|
||||
if (cend == input_cur && con_tick >= 4)
|
||||
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
if (rellip)
|
||||
{
|
||||
if (input_sel > cend)
|
||||
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART);
|
||||
for (i = 0; i < 3; ++i, x += charwidth)
|
||||
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1465,11 +1465,11 @@ static void CON_DrawHudlines(void)
|
|||
else
|
||||
{
|
||||
//charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
}
|
||||
}
|
||||
|
||||
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
y += charheight;
|
||||
}
|
||||
|
||||
|
@ -1607,7 +1607,7 @@ static void CON_DrawConsole(void)
|
|||
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
|
||||
p++;
|
||||
}
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
190
src/d_clisrv.c
190
src/d_clisrv.c
|
@ -528,6 +528,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
|
||||
rsp->skincolor = players[i].skincolor;
|
||||
rsp->skin = LONG(players[i].skin);
|
||||
rsp->availabilities = LONG(players[i].availabilities);
|
||||
// Just in case Lua does something like
|
||||
// modify these at runtime
|
||||
rsp->camerascale = (fixed_t)LONG(players[i].camerascale);
|
||||
|
@ -551,7 +552,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight);
|
||||
|
||||
rsp->speed = (fixed_t)LONG(players[i].speed);
|
||||
rsp->jumping = players[i].jumping;
|
||||
rsp->secondjump = players[i].secondjump;
|
||||
rsp->fly1 = players[i].fly1;
|
||||
rsp->glidetime = (tic_t)LONG(players[i].glidetime);
|
||||
|
@ -657,6 +657,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
|
||||
players[i].skincolor = rsp->skincolor;
|
||||
players[i].skin = LONG(rsp->skin);
|
||||
players[i].availabilities = LONG(rsp->availabilities);
|
||||
// Just in case Lua does something like
|
||||
// modify these at runtime
|
||||
players[i].camerascale = (fixed_t)LONG(rsp->camerascale);
|
||||
|
@ -680,7 +681,6 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight);
|
||||
|
||||
players[i].speed = (fixed_t)LONG(rsp->speed);
|
||||
players[i].jumping = rsp->jumping;
|
||||
players[i].secondjump = rsp->secondjump;
|
||||
players[i].fly1 = rsp->fly1;
|
||||
players[i].glidetime = (tic_t)LONG(rsp->glidetime);
|
||||
|
@ -1364,6 +1364,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
// which is nice and easy for us to detect
|
||||
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
|
||||
memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
|
||||
memset(netbuffer->u.servercfg.playeravailabilities, 0xFF, sizeof(netbuffer->u.servercfg.playeravailabilities));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -1371,6 +1372,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
continue;
|
||||
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
|
||||
netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor;
|
||||
netbuffer->u.servercfg.playeravailabilities[i] = (UINT32)LONG(players[i].availabilities);
|
||||
}
|
||||
|
||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||
|
@ -1561,8 +1563,6 @@ static void CL_LoadReceivedSavegame(void)
|
|||
automapactive = false;
|
||||
|
||||
// load a base level
|
||||
playerdeadview = false;
|
||||
|
||||
if (P_LoadNetGame())
|
||||
{
|
||||
const INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||
|
@ -1740,9 +1740,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
{
|
||||
#ifndef NONET
|
||||
INT32 i;
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
// serverlist is updated by GetPacket function
|
||||
if (serverlistcount > 0)
|
||||
{
|
||||
|
@ -1776,7 +1774,20 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
serverlist[i].info.fileneeded);
|
||||
CONS_Printf(M_GetText("Checking files...\n"));
|
||||
i = CL_CheckFiles();
|
||||
if (i == 2) // cannot join for some reason
|
||||
if (i == 3) // too many files
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have too many WAD files loaded\n"
|
||||
"to add ones the server is using.\n"
|
||||
"Please restart SRB2 before connecting.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
else if (i == 2) // cannot join for some reason
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
|
@ -2308,12 +2319,7 @@ static void ResetNode(INT32 node);
|
|||
void CL_ClearPlayer(INT32 playernum)
|
||||
{
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
// Don't leave a NiGHTS ghost!
|
||||
if ((players[playernum].pflags & PF_NIGHTSMODE) && players[playernum].mo->tracer)
|
||||
P_RemoveMobj(players[playernum].mo->tracer);
|
||||
P_RemoveMobj(players[playernum].mo);
|
||||
}
|
||||
memset(&players[playernum], 0, sizeof (player_t));
|
||||
}
|
||||
|
||||
|
@ -2521,12 +2527,18 @@ static void Command_Nodes(void)
|
|||
|
||||
static void Command_Ban(void)
|
||||
{
|
||||
if (COM_Argc() == 1)
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame) // Don't kick Tails in splitscreen!
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server || adminplayer == consoleplayer)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
|
@ -2536,9 +2548,10 @@ static void Command_Ban(void)
|
|||
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
else
|
||||
WRITEUINT8(p, pn);
|
||||
if (I_Ban && !I_Ban(node))
|
||||
|
||||
WRITEUINT8(p, pn);
|
||||
|
||||
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||
|
@ -2546,7 +2559,8 @@ static void Command_Ban(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
Ban_Add(COM_Argv(2));
|
||||
if (server) // only the server is allowed to do this right now
|
||||
Ban_Add(COM_Argv(2));
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
|
@ -2579,21 +2593,27 @@ static void Command_Ban(void)
|
|||
|
||||
static void Command_Kick(void)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
UINT8 *p = buf;
|
||||
|
||||
if (COM_Argc() == 1)
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame) // Don't kick Tails in splitscreen!
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server || adminplayer == consoleplayer)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
UINT8 *p = buf;
|
||||
const SINT8 pn = nametonum(COM_Argv(1));
|
||||
WRITESINT8(p, pn);
|
||||
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
|
||||
// Special case if we are trying to kick a player who is downloading the game state:
|
||||
// trigger a timeout instead of kicking them, because a kick would only
|
||||
// take effect after they have finished downloading
|
||||
|
@ -2602,6 +2622,9 @@ static void Command_Kick(void)
|
|||
Net_ConnectionTimeout(playernode[pn]);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITESINT8(p, pn);
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||
|
@ -2703,12 +2726,14 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
|
||||
// If a verified admin banned someone, the server needs to know about it.
|
||||
// If the playernum isn't zero (the server) then the server needs to record the ban.
|
||||
if (server && playernum && msg == KICK_MSG_BANNED)
|
||||
if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN))
|
||||
{
|
||||
if (I_Ban && !I_Ban(playernode[(INT32)pnum]))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||
}
|
||||
#ifndef NONET
|
||||
else
|
||||
Ban_Add(reason);
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
|
@ -3406,17 +3431,42 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
if (node != servernode)
|
||||
DEBFILE(va("Received packet from unknown host %d\n", node));
|
||||
|
||||
// macro for packets that should only be sent by the server
|
||||
// if it is NOT from the server, bail out and close the connection!
|
||||
#define SERVERONLY \
|
||||
if (node != servernode) \
|
||||
{ \
|
||||
Net_CloseConnection(node); \
|
||||
break; \
|
||||
}
|
||||
switch (netbuffer->packettype)
|
||||
{
|
||||
case PT_ASKINFOVIAMS:
|
||||
#if 0
|
||||
if (server && serverrunning)
|
||||
{
|
||||
INT32 clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
||||
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
|
||||
SV_SendPlayerInfo(clientnode); // Send extra info
|
||||
Net_CloseConnection(clientnode);
|
||||
// Don't close connection to MS.
|
||||
INT32 clientnode;
|
||||
if (ms_RoomId < 0) // ignore if we're not actually on the MS right now
|
||||
{
|
||||
Net_CloseConnection(node); // and yes, close connection
|
||||
return;
|
||||
}
|
||||
clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
||||
if (clientnode != -1)
|
||||
{
|
||||
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
|
||||
SV_SendPlayerInfo(clientnode); // Send extra info
|
||||
Net_CloseConnection(clientnode);
|
||||
// Don't close connection to MS...
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // ...unless the IP address is not valid
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // you're not supposed to get it, so ignore it
|
||||
#else
|
||||
Net_CloseConnection(node);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PT_ASKINFO:
|
||||
|
@ -3424,8 +3474,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
{
|
||||
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
||||
SV_SendPlayerInfo(node); // Send extra info
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
Net_CloseConnection(node);
|
||||
break;
|
||||
|
||||
case PT_SERVERREFUSE: // Negative response of client join request
|
||||
|
@ -3434,6 +3484,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
SERVERONLY
|
||||
if (cl_mode == CL_WAITJOINRESPONSE)
|
||||
{
|
||||
// Save the reason so it can be displayed after quitting the netgame
|
||||
|
@ -3465,6 +3516,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
SERVERONLY
|
||||
/// \note how would this happen? and is it doing the right thing if it does?
|
||||
if (cl_mode != CL_WAITJOINRESPONSE)
|
||||
break;
|
||||
|
@ -3497,10 +3549,12 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
if (netbuffer->u.servercfg.playerskins[j] == 0xFF
|
||||
&& netbuffer->u.servercfg.playercolor[j] == 0xFF)
|
||||
&& netbuffer->u.servercfg.playercolor[j] == 0xFF
|
||||
&& netbuffer->u.servercfg.playeravailabilities[j] == 0xFFFFFFFF)
|
||||
continue; // not in game
|
||||
|
||||
playeringame[j] = true;
|
||||
players[j].availabilities = (UINT32)LONG(netbuffer->u.servercfg.playeravailabilities[j]);
|
||||
SetPlayerSkinByNum(j, (INT32)netbuffer->u.servercfg.playerskins[j]);
|
||||
players[j].skincolor = netbuffer->u.servercfg.playercolor[j];
|
||||
}
|
||||
|
@ -3528,13 +3582,18 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
else
|
||||
Got_Filetxpak();
|
||||
SERVERONLY
|
||||
Got_Filetxpak();
|
||||
break;
|
||||
|
||||
case PT_REQUESTFILE:
|
||||
if (server)
|
||||
Got_RequestFilePak(node);
|
||||
{
|
||||
if (!cv_downloading.value || !Got_RequestFilePak(node))
|
||||
Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // nope
|
||||
break;
|
||||
|
||||
case PT_NODETIMEOUT:
|
||||
|
@ -3557,6 +3616,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
break; // Ignore it
|
||||
|
||||
}
|
||||
#undef SERVERONLY
|
||||
}
|
||||
|
||||
/** Handles a packet received from a node that is in game
|
||||
|
@ -3589,6 +3649,8 @@ FILESTAMP
|
|||
{
|
||||
// -------------------------------------------- SERVER RECEIVE ----------
|
||||
case PT_RESYNCHGET:
|
||||
if (client)
|
||||
break;
|
||||
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
|
||||
break;
|
||||
case PT_CLIENTCMD:
|
||||
|
@ -3655,7 +3717,8 @@ FILESTAMP
|
|||
}
|
||||
|
||||
// Splitscreen cmd
|
||||
if (netbuffer->packettype == PT_CLIENT2CMD && nodetoplayer2[node] >= 0)
|
||||
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||
&& nodetoplayer2[node] >= 0)
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
|
@ -3714,6 +3777,27 @@ FILESTAMP
|
|||
tic_t tic = maketic;
|
||||
UINT8 *textcmd;
|
||||
|
||||
// ignore if the textcmd has a reported size of zero
|
||||
// this shouldn't be sent at all
|
||||
if (!netbuffer->u.textcmd[0])
|
||||
{
|
||||
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore if the textcmd size var is actually larger than it should be
|
||||
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
||||
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
||||
{
|
||||
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
||||
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
break;
|
||||
}
|
||||
|
||||
// check if tic that we are making isn't too large else we cannot send it :(
|
||||
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
||||
j = software_MAXPACKETLENGTH
|
||||
|
@ -3907,7 +3991,7 @@ FILESTAMP
|
|||
if (client)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
|
||||
}
|
||||
|
@ -3917,6 +4001,21 @@ FILESTAMP
|
|||
case PT_SERVERCFG:
|
||||
break;
|
||||
case PT_FILEFRAGMENT:
|
||||
// Only accept PT_FILEFRAGMENT from the server.
|
||||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[2];
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (client)
|
||||
Got_Filetxpak();
|
||||
break;
|
||||
|
@ -4450,8 +4549,8 @@ static inline void PingUpdate(void)
|
|||
}
|
||||
|
||||
//send out our ping packets
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i])
|
||||
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
||||
|
||||
pingmeasurecount = 1; //Reset count
|
||||
|
@ -4481,20 +4580,15 @@ void NetUpdate(void)
|
|||
|
||||
gametime = nowtime;
|
||||
|
||||
if (!(gametime % 255) && netgame && server)
|
||||
{
|
||||
#ifdef NEWPING
|
||||
PingUpdate();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NEWPING
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 255))
|
||||
PingUpdate();
|
||||
// update node latency values so we can take an average later.
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(i));
|
||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -172,6 +172,7 @@ typedef struct
|
|||
|
||||
UINT8 skincolor;
|
||||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
// Just in case Lua does something like
|
||||
// modify these at runtime
|
||||
fixed_t camerascale;
|
||||
|
@ -195,7 +196,6 @@ typedef struct
|
|||
fixed_t playerspinheight;
|
||||
|
||||
fixed_t speed;
|
||||
UINT8 jumping;
|
||||
UINT8 secondjump;
|
||||
UINT8 fly1;
|
||||
tic_t glidetime;
|
||||
|
@ -284,6 +284,7 @@ typedef struct
|
|||
// 0xFF == not in game; else player skin num
|
||||
UINT8 playerskins[MAXPLAYERS];
|
||||
UINT8 playercolor[MAXPLAYERS];
|
||||
UINT32 playeravailabilities[MAXPLAYERS];
|
||||
|
||||
UINT8 gametype;
|
||||
UINT8 modifiedgame;
|
||||
|
|
69
src/d_main.c
69
src/d_main.c
|
@ -107,8 +107,6 @@ UINT8 window_notinfocus = false;
|
|||
//
|
||||
// DEMO LOOP
|
||||
//
|
||||
//static INT32 demosequence;
|
||||
static const char *pagename = "MAP1PIC";
|
||||
static char *startupwadfiles[MAX_WADFILES];
|
||||
|
||||
boolean devparm = false; // started game with -devparm
|
||||
|
@ -720,9 +718,7 @@ void D_StartTitle(void)
|
|||
maptol = 0;
|
||||
|
||||
gameaction = ga_nothing;
|
||||
playerdeadview = false;
|
||||
displayplayer = consoleplayer = 0;
|
||||
//demosequence = -1;
|
||||
gametype = GT_COOP;
|
||||
paused = false;
|
||||
advancedemo = false;
|
||||
|
@ -887,27 +883,10 @@ static void IdentifyVersion(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
// Just print the nice red titlebar like the original SRB2 for DOS.
|
||||
/* ======================================================================== */
|
||||
#ifdef PC_DOS
|
||||
static inline void D_Titlebar(char *title1, char *title2)
|
||||
{
|
||||
// SRB2 banner
|
||||
clrscr();
|
||||
textattr((BLUE<<4)+WHITE);
|
||||
clreol();
|
||||
cputs(title1);
|
||||
|
||||
// standard srb2 banner
|
||||
textattr((RED<<4)+WHITE);
|
||||
clreol();
|
||||
gotoxy((80-strlen(title2))/2, 2);
|
||||
cputs(title2);
|
||||
normvideo();
|
||||
gotoxy(1,3);
|
||||
}
|
||||
#endif
|
||||
/* ======================================================================== */
|
||||
// Code for printing SRB2's title bar in DOS
|
||||
/* ======================================================================== */
|
||||
|
||||
//
|
||||
// Center the title string, then add the date and time of compilation.
|
||||
|
@ -936,6 +915,31 @@ static inline void D_MakeTitleString(char *s)
|
|||
strcpy(s, temp);
|
||||
}
|
||||
|
||||
static inline void D_Titlebar(void)
|
||||
{
|
||||
char title1[82]; // srb2 title banner
|
||||
char title2[82];
|
||||
|
||||
strcpy(title1, "Sonic Robo Blast 2");
|
||||
strcpy(title2, "Sonic Robo Blast 2");
|
||||
|
||||
D_MakeTitleString(title1);
|
||||
|
||||
// SRB2 banner
|
||||
clrscr();
|
||||
textattr((BLUE<<4)+WHITE);
|
||||
clreol();
|
||||
cputs(title1);
|
||||
|
||||
// standard srb2 banner
|
||||
textattr((RED<<4)+WHITE);
|
||||
clreol();
|
||||
gotoxy((80-strlen(title2))/2, 2);
|
||||
cputs(title2);
|
||||
normvideo();
|
||||
gotoxy(1,3);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// D_SRB2Main
|
||||
|
@ -943,8 +947,6 @@ static inline void D_MakeTitleString(char *s)
|
|||
void D_SRB2Main(void)
|
||||
{
|
||||
INT32 p;
|
||||
char srb2[82]; // srb2 title banner
|
||||
char title[82];
|
||||
|
||||
INT32 pstartmap = 1;
|
||||
boolean autostart = false;
|
||||
|
@ -987,20 +989,8 @@ void D_SRB2Main(void)
|
|||
dedicated = M_CheckParm("-dedicated") != 0;
|
||||
#endif
|
||||
|
||||
strcpy(title, "Sonic Robo Blast 2");
|
||||
strcpy(srb2, "Sonic Robo Blast 2");
|
||||
D_MakeTitleString(srb2);
|
||||
|
||||
#ifdef PC_DOS
|
||||
D_Titlebar(srb2, title);
|
||||
#endif
|
||||
|
||||
#if defined (__OS2__) && !defined (HAVE_SDL)
|
||||
// set PM window title
|
||||
snprintf(pmData->title, sizeof (pmData->title),
|
||||
"Sonic Robo Blast 2" VERSIONSTRING ": %s",
|
||||
title);
|
||||
pmData->title[sizeof (pmData->title) - 1] = '\0';
|
||||
D_Titlebar();
|
||||
#endif
|
||||
|
||||
if (devparm)
|
||||
|
@ -1400,7 +1390,6 @@ void D_SRB2Main(void)
|
|||
|
||||
if (dedicated && server)
|
||||
{
|
||||
pagename = "TITLESKY";
|
||||
levelstarttic = gametic;
|
||||
G_SetGamestate(GS_LEVEL);
|
||||
if (!P_SetupLevel(false))
|
||||
|
|
|
@ -34,7 +34,7 @@ void D_SRB2Loop(void) FUNCNORETURN;
|
|||
// D_SRB2Main()
|
||||
// Not a globally visible function, just included for source reference,
|
||||
// calls all startup code, parses command line options.
|
||||
// If not overrided by user input, calls N_AdvanceDemo.
|
||||
// If not overrided by user input, calls D_AdvanceDemo.
|
||||
//
|
||||
void D_SRB2Main(void);
|
||||
|
||||
|
@ -51,9 +51,6 @@ const char *D_Home(void);
|
|||
//
|
||||
// BASE LEVEL
|
||||
//
|
||||
void D_PageTicker(void);
|
||||
// pagename is lumpname of a 320x200 patch to fill the screen
|
||||
void D_PageDrawer(const char *pagename);
|
||||
void D_AdvanceDemo(void);
|
||||
void D_StartTitle(void);
|
||||
|
||||
|
|
15
src/d_net.c
15
src/d_net.c
|
@ -49,7 +49,9 @@ doomcom_t *doomcom = NULL;
|
|||
/// \brief network packet data, points inside doomcom
|
||||
doomdata_t *netbuffer = NULL;
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
FILE *debugfile = NULL; // put some net info in a file during the game
|
||||
#endif
|
||||
|
||||
#define MAXREBOUND 8
|
||||
static doomdata_t reboundstore[MAXREBOUND];
|
||||
|
@ -711,11 +713,24 @@ void Net_CloseConnection(INT32 node)
|
|||
#else
|
||||
INT32 i;
|
||||
boolean forceclose = (node & FORCECLOSE) != 0;
|
||||
|
||||
if (node == -1)
|
||||
{
|
||||
DEBFILE(M_GetText("Net_CloseConnection: node -1 detected!\n"));
|
||||
return; // nope, just ignore it
|
||||
}
|
||||
|
||||
node &= ~FORCECLOSE;
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
if (node < 0 || node >= MAXNETNODES) // prevent invalid nodes from crashing the game
|
||||
{
|
||||
DEBFILE(va(M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node));
|
||||
return;
|
||||
}
|
||||
|
||||
nodes[node].flags |= NF_CLOSE;
|
||||
|
||||
// try to Send ack back (two army problem)
|
||||
|
|
176
src/d_netcmd.c
176
src/d_netcmd.c
|
@ -189,14 +189,13 @@ static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2
|
|||
|
||||
static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Teleports"},
|
||||
static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, //{2, "Teleports"},
|
||||
{3, "None"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"},
|
||||
{3, "None"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t match_scoring_cons_t[] = {{0, "Normal"}, {1, "Classic"}, {0, NULL}};
|
||||
static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {0, NULL}};
|
||||
|
@ -311,7 +310,6 @@ consvar_t cv_friendlyfire = {"friendlyfire", "Off", CV_NETVAR, CV_OnOff, NULL, 0
|
|||
consvar_t cv_itemfinder = {"itemfinder", "Off", CV_CALL, CV_OnOff, ItemFinder_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Scoring type options
|
||||
consvar_t cv_match_scoring = {"matchscoring", "Normal", CV_NETVAR|CV_CHEAT, match_scoring_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -485,7 +483,6 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_itemrespawntime);
|
||||
CV_RegisterVar(&cv_itemrespawn);
|
||||
CV_RegisterVar(&cv_flagtime);
|
||||
CV_RegisterVar(&cv_suddendeath);
|
||||
|
||||
// misc
|
||||
CV_RegisterVar(&cv_friendlyfire);
|
||||
|
@ -533,7 +530,6 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_startinglives);
|
||||
CV_RegisterVar(&cv_countdowntime);
|
||||
CV_RegisterVar(&cv_runscripts);
|
||||
CV_RegisterVar(&cv_match_scoring);
|
||||
CV_RegisterVar(&cv_overtime);
|
||||
CV_RegisterVar(&cv_pause);
|
||||
CV_RegisterVar(&cv_mute);
|
||||
|
@ -616,6 +612,7 @@ void D_RegisterClientCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_screenshot_option);
|
||||
CV_RegisterVar(&cv_screenshot_folder);
|
||||
CV_RegisterVar(&cv_screenshot_colorprofile);
|
||||
CV_RegisterVar(&cv_moviemode);
|
||||
// PNG variables
|
||||
CV_RegisterVar(&cv_zlib_level);
|
||||
|
@ -673,7 +670,29 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_resetmusic);
|
||||
|
||||
// FIXME: not to be here.. but needs be done for config loading
|
||||
CV_RegisterVar(&cv_usegamma);
|
||||
CV_RegisterVar(&cv_globalgamma);
|
||||
CV_RegisterVar(&cv_globalsaturation);
|
||||
|
||||
CV_RegisterVar(&cv_rhue);
|
||||
CV_RegisterVar(&cv_yhue);
|
||||
CV_RegisterVar(&cv_ghue);
|
||||
CV_RegisterVar(&cv_chue);
|
||||
CV_RegisterVar(&cv_bhue);
|
||||
CV_RegisterVar(&cv_mhue);
|
||||
|
||||
CV_RegisterVar(&cv_rgamma);
|
||||
CV_RegisterVar(&cv_ygamma);
|
||||
CV_RegisterVar(&cv_ggamma);
|
||||
CV_RegisterVar(&cv_cgamma);
|
||||
CV_RegisterVar(&cv_bgamma);
|
||||
CV_RegisterVar(&cv_mgamma);
|
||||
|
||||
CV_RegisterVar(&cv_rsaturation);
|
||||
CV_RegisterVar(&cv_ysaturation);
|
||||
CV_RegisterVar(&cv_gsaturation);
|
||||
CV_RegisterVar(&cv_csaturation);
|
||||
CV_RegisterVar(&cv_bsaturation);
|
||||
CV_RegisterVar(&cv_msaturation);
|
||||
|
||||
// m_menu.c
|
||||
CV_RegisterVar(&cv_crosshair);
|
||||
|
@ -731,6 +750,7 @@ void D_RegisterClientCommands(void)
|
|||
|
||||
// s_sound.c
|
||||
CV_RegisterVar(&cv_soundvolume);
|
||||
CV_RegisterVar(&cv_closedcaptioning);
|
||||
CV_RegisterVar(&cv_digmusicvolume);
|
||||
CV_RegisterVar(&cv_midimusicvolume);
|
||||
CV_RegisterVar(&cv_numChannels);
|
||||
|
@ -1011,7 +1031,7 @@ UINT8 CanChangeSkin(INT32 playernum)
|
|||
return true;
|
||||
|
||||
// Force skin in effect.
|
||||
if (client && (cv_forceskin.value != -1) && !(adminplayer == playernum && serverplayer == -1))
|
||||
if ((cv_forceskin.value != -1) || (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'))
|
||||
return false;
|
||||
|
||||
// Can change skin in intermission and whatnot.
|
||||
|
@ -1109,6 +1129,8 @@ static void SendNameAndColor(void)
|
|||
if (!Playing())
|
||||
return;
|
||||
|
||||
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (!netgame)
|
||||
{
|
||||
|
@ -1127,7 +1149,7 @@ static void SendNameAndColor(void)
|
|||
SetPlayerSkinByNum(consoleplayer, 0);
|
||||
CV_StealthSet(&cv_skin, skins[0].name);
|
||||
}
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUnlock(foundskin))
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin))
|
||||
{
|
||||
boolean notsame;
|
||||
|
||||
|
@ -1174,7 +1196,7 @@ static void SendNameAndColor(void)
|
|||
// check if player has the skin loaded (cv_skin may have
|
||||
// the name of a skin that was available in the previous game)
|
||||
cv_skin.value = R_SkinAvailable(cv_skin.string);
|
||||
if ((cv_skin.value < 0) || !R_SkinUnlock(cv_skin.value))
|
||||
if ((cv_skin.value < 0) || !R_SkinUsable(consoleplayer, cv_skin.value))
|
||||
{
|
||||
CV_StealthSet(&cv_skin, DEFAULTSKIN);
|
||||
cv_skin.value = 0;
|
||||
|
@ -1182,6 +1204,7 @@ static void SendNameAndColor(void)
|
|||
|
||||
// Finally write out the complete packet and send it off.
|
||||
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME);
|
||||
WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities);
|
||||
WRITEUINT8(p, (UINT8)cv_playercolor.value);
|
||||
WRITEUINT8(p, (UINT8)cv_skin.value);
|
||||
SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf);
|
||||
|
@ -1224,6 +1247,8 @@ static void SendNameAndColor2(void)
|
|||
if (!Playing())
|
||||
return;
|
||||
|
||||
players[secondplaya].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (botingame)
|
||||
{
|
||||
|
@ -1252,7 +1277,7 @@ static void SendNameAndColor2(void)
|
|||
SetPlayerSkinByNum(secondplaya, forcedskin);
|
||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
||||
}
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUnlock(foundskin))
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUsable(secondplaya, foundskin))
|
||||
{
|
||||
boolean notsame;
|
||||
|
||||
|
@ -1307,6 +1332,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
#endif
|
||||
|
||||
READSTRINGN(*cp, name, MAXPLAYERNAME);
|
||||
p->availabilities = READUINT32(*cp);
|
||||
color = READUINT8(*cp);
|
||||
skin = READUINT8(*cp);
|
||||
|
||||
|
@ -1323,6 +1349,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
|
||||
{
|
||||
boolean kick = false;
|
||||
INT32 s;
|
||||
|
||||
// team colors
|
||||
if (G_GametypeHasTeams())
|
||||
|
@ -1337,6 +1364,16 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
if (!p->skincolor)
|
||||
kick = true;
|
||||
|
||||
// availabilities
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
{
|
||||
if (!skins[s].availability && (p->availabilities & (1 << s)))
|
||||
{
|
||||
kick = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (kick)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[2];
|
||||
|
@ -1532,10 +1569,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
// The supplied data are assumed to be good.
|
||||
I_Assert(delay >= 0 && delay <= 2);
|
||||
|
||||
if (mapnum != -1)
|
||||
CV_SetValue(&cv_nextmap, mapnum);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
|
||||
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
|
||||
|
||||
if (netgame || multiplayer)
|
||||
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
|
||||
FLS = false;
|
||||
|
||||
if (delay != 2)
|
||||
|
@ -1569,8 +1609,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
mapchangepending = 0;
|
||||
// spawn the server if needed
|
||||
// reset players if there is a new one
|
||||
if (!(adminplayer == consoleplayer) && SV_SpawnServer())
|
||||
buf[0] &= ~(1<<1);
|
||||
if (!(adminplayer == consoleplayer))
|
||||
{
|
||||
if (SV_SpawnServer())
|
||||
buf[0] &= ~(1<<1);
|
||||
if (!Playing()) // you failed to start a server somehow, so cancel the map change
|
||||
return;
|
||||
}
|
||||
|
||||
// Kick bot from special stages
|
||||
if (botskin)
|
||||
|
@ -1701,9 +1746,19 @@ static void Command_Map_f(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Prevent warping to locked levels
|
||||
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
|
||||
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
|
||||
// lives hell.
|
||||
if (!dedicated && M_MapLocked(newmapnum))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// don't use a gametype the map doesn't support
|
||||
if (cv_debug || COM_CheckParm("-force") || cv_skipmapcheck.value)
|
||||
; // The player wants us to trek on anyway. Do so.
|
||||
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
|
||||
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
|
||||
// Alternatively, bail if the map header is completely missing anyway.
|
||||
else if (!mapheaderinfo[newmapnum-1]
|
||||
|
@ -1722,19 +1777,10 @@ static void Command_Map_f(void)
|
|||
CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring);
|
||||
return;
|
||||
}
|
||||
else
|
||||
fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP)));
|
||||
|
||||
// Prevent warping to locked levels
|
||||
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
|
||||
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
|
||||
// lives hell.
|
||||
if (!dedicated && M_MapLocked(newmapnum))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
fromlevelselect = false;
|
||||
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, false);
|
||||
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
|
||||
}
|
||||
|
||||
/** Receives a map command and changes the map.
|
||||
|
@ -1800,17 +1846,14 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
if (demoplayback && !timingdemo)
|
||||
precache = false;
|
||||
|
||||
if (resetplayer)
|
||||
{
|
||||
if (!FLS || (netgame || multiplayer))
|
||||
emeralds = 0;
|
||||
}
|
||||
if (resetplayer && !FLS)
|
||||
emeralds = 0;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_MapChange();
|
||||
#endif
|
||||
|
||||
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene);
|
||||
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS);
|
||||
if (demoplayback && !timingdemo)
|
||||
precache = true;
|
||||
CON_ToggleOff();
|
||||
|
@ -2116,7 +2159,7 @@ static void Command_Teamchange_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cv_allowteamchange.value && !NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
|
||||
if (!cv_allowteamchange.value && NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n"));
|
||||
return;
|
||||
|
@ -2213,7 +2256,7 @@ static void Command_Teamchange2_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cv_allowteamchange.value && !NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
|
||||
if (!cv_allowteamchange.value && NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n"));
|
||||
return;
|
||||
|
@ -2967,6 +3010,7 @@ static void Command_Addfile(void)
|
|||
XBOXSTATIC char buf[256];
|
||||
char *buf_p = buf;
|
||||
INT32 i;
|
||||
int musiconly; // W_VerifyNMUSlumps isn't boolean
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
|
@ -2981,7 +3025,9 @@ static void Command_Addfile(void)
|
|||
if (!isprint(fn[i]) || fn[i] == ';')
|
||||
return;
|
||||
|
||||
if (!W_VerifyNMUSlumps(fn))
|
||||
musiconly = W_VerifyNMUSlumps(fn);
|
||||
|
||||
if (!musiconly)
|
||||
{
|
||||
// ... But only so long as they contain nothing more then music and sprites.
|
||||
if (netgame && !(server || adminplayer == consoleplayer))
|
||||
|
@ -2993,7 +3039,7 @@ static void Command_Addfile(void)
|
|||
}
|
||||
|
||||
// Add file on your client directly if it is trivial, or you aren't in a netgame.
|
||||
if (!(netgame || multiplayer) || W_VerifyNMUSlumps(fn))
|
||||
if (!(netgame || multiplayer) || musiconly)
|
||||
{
|
||||
P_AddWadFile(fn, NULL);
|
||||
return;
|
||||
|
@ -3013,9 +3059,7 @@ static void Command_Addfile(void)
|
|||
#else
|
||||
FILE *fhandle;
|
||||
|
||||
fhandle = fopen(fn, "rb");
|
||||
|
||||
if (fhandle)
|
||||
if ((fhandle = W_OpenWadFile(&fn, true)) != NULL)
|
||||
{
|
||||
tic_t t = I_GetTime();
|
||||
CONS_Debug(DBG_SETUP, "Making MD5 for %s\n",fn);
|
||||
|
@ -3023,11 +3067,8 @@ static void Command_Addfile(void)
|
|||
CONS_Debug(DBG_SETUP, "MD5 calc for %s took %f second\n", fn, (float)(I_GetTime() - t)/TICRATE);
|
||||
fclose(fhandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("File %s not found.\n"), fn);
|
||||
else // file not found
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
WRITEMEM(buf_p, md5sum, 16);
|
||||
}
|
||||
|
@ -3080,7 +3121,13 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
filestatus_t ncs = FS_NOTFOUND;
|
||||
UINT8 md5sum[16];
|
||||
boolean kick = false;
|
||||
boolean toomany = false;
|
||||
INT32 i;
|
||||
size_t packetsize = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
READSTRINGN(*cp, filename, 240);
|
||||
READMEM(*cp, md5sum, 16);
|
||||
|
@ -3106,13 +3153,25 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
|
||||
if (ncs != FS_FOUND)
|
||||
packetsize += nameonlylength(filename) + 22;
|
||||
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
toomany = true;
|
||||
else
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
||||
if (ncs != FS_FOUND || toomany)
|
||||
{
|
||||
char message[256];
|
||||
|
||||
if (ncs == FS_NOTFOUND)
|
||||
if (toomany)
|
||||
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
|
||||
else if (ncs == FS_NOTFOUND)
|
||||
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
|
||||
else if (ncs == FS_MD5SUMBAD)
|
||||
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
|
||||
|
@ -3182,10 +3241,15 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
||||
if (ncs != FS_FOUND)
|
||||
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL))
|
||||
{
|
||||
Command_ExitGame_f();
|
||||
if (ncs == FS_NOTFOUND)
|
||||
if (ncs == FS_FOUND)
|
||||
{
|
||||
CONS_Printf(M_GetText("The server tried to add %s,\nbut you have too many files added.\nRestart the game to clear loaded files\nand play on this server."), filename);
|
||||
M_StartMessage(va("The server added a file \n(%s)\nbut you have too many files added.\nRestart the game to clear loaded files.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
||||
}
|
||||
else if (ncs == FS_NOTFOUND)
|
||||
{
|
||||
CONS_Printf(M_GetText("The server tried to add %s,\nbut you don't have this file.\nYou need to find it in order\nto play on this server."), filename);
|
||||
M_StartMessage(va("The server added a file \n(%s)\nthat you do not have.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
||||
|
@ -3203,7 +3267,6 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
P_AddWadFile(filename, NULL);
|
||||
G_SetGameModified(true);
|
||||
}
|
||||
|
||||
|
@ -4042,13 +4105,6 @@ static void Command_Archivetest_f(void)
|
|||
*/
|
||||
static void ForceSkin_OnChange(void)
|
||||
{
|
||||
if ((server || adminplayer == consoleplayer) && ((cv_forceskin.value == -1 && stricmp(cv_forceskin.string, "None")) || !(R_SkinUnlock(cv_forceskin.value))))
|
||||
{
|
||||
CONS_Printf("Please provide a valid skin name (\"None\" disables).\n");
|
||||
CV_SetValue(&cv_forceskin, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOT in SP, silly!
|
||||
if (!(netgame || multiplayer))
|
||||
return;
|
||||
|
@ -4057,7 +4113,7 @@ static void ForceSkin_OnChange(void)
|
|||
CONS_Printf("The server has lifted the forced skin restrictions.\n");
|
||||
else
|
||||
{
|
||||
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].realname);
|
||||
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
|
||||
ForceAllSkins(cv_forceskin.value);
|
||||
}
|
||||
}
|
||||
|
@ -4095,7 +4151,8 @@ static void Skin_OnChange(void)
|
|||
if (!Playing())
|
||||
return; // do whatever you want
|
||||
|
||||
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
|
||||
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
|
||||
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
||||
{
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
return;
|
||||
|
@ -4138,8 +4195,7 @@ static void Color_OnChange(void)
|
|||
if (!Playing())
|
||||
return; // do whatever you want
|
||||
|
||||
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
|
||||
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING))
|
||||
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
|
||||
{
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
return;
|
||||
|
|
|
@ -20,6 +20,12 @@
|
|||
// console vars
|
||||
extern consvar_t cv_playername;
|
||||
extern consvar_t cv_playercolor;
|
||||
extern consvar_t cv_skin;
|
||||
// secondary splitscreen player
|
||||
extern consvar_t cv_playername2;
|
||||
extern consvar_t cv_playercolor2;
|
||||
extern consvar_t cv_skin2;
|
||||
|
||||
#ifdef SEENAMES
|
||||
extern consvar_t cv_seenames, cv_allowseenames;
|
||||
#endif
|
||||
|
@ -32,7 +38,6 @@ extern consvar_t cv_joyport2;
|
|||
#endif
|
||||
extern consvar_t cv_joyscale;
|
||||
extern consvar_t cv_joyscale2;
|
||||
extern consvar_t cv_controlperkey;
|
||||
|
||||
// splitscreen with second mouse
|
||||
extern consvar_t cv_mouse2port;
|
||||
|
@ -40,25 +45,12 @@ extern consvar_t cv_usemouse2;
|
|||
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON)
|
||||
extern consvar_t cv_mouse2opt;
|
||||
#endif
|
||||
extern consvar_t cv_invertmouse2;
|
||||
extern consvar_t cv_alwaysfreelook2;
|
||||
extern consvar_t cv_mousemove2;
|
||||
extern consvar_t cv_mousesens2;
|
||||
extern consvar_t cv_mouseysens2;
|
||||
|
||||
// normally in p_mobj but the .h is not read
|
||||
extern consvar_t cv_itemrespawntime;
|
||||
extern consvar_t cv_itemrespawn;
|
||||
|
||||
extern consvar_t cv_flagtime;
|
||||
extern consvar_t cv_suddendeath;
|
||||
|
||||
extern consvar_t cv_skin;
|
||||
|
||||
// secondary splitscreen player
|
||||
extern consvar_t cv_playername2;
|
||||
extern consvar_t cv_playercolor2;
|
||||
extern consvar_t cv_skin2;
|
||||
|
||||
extern consvar_t cv_touchtag;
|
||||
extern consvar_t cv_hidetime;
|
||||
|
@ -77,9 +69,6 @@ extern consvar_t cv_autobalance;
|
|||
extern consvar_t cv_teamscramble;
|
||||
extern consvar_t cv_scrambleonchange;
|
||||
|
||||
extern consvar_t cv_useranalog, cv_useranalog2;
|
||||
extern consvar_t cv_analog, cv_analog2;
|
||||
|
||||
extern consvar_t cv_netstat;
|
||||
#ifdef WALLSPLATS
|
||||
extern consvar_t cv_splats;
|
||||
|
@ -101,7 +90,6 @@ extern consvar_t cv_recycler;
|
|||
extern consvar_t cv_itemfinder;
|
||||
|
||||
extern consvar_t cv_inttime, cv_advancemap, cv_playersforexit;
|
||||
extern consvar_t cv_match_scoring;
|
||||
extern consvar_t cv_overtime;
|
||||
extern consvar_t cv_startinglives;
|
||||
|
||||
|
@ -120,17 +108,7 @@ extern consvar_t cv_maxping;
|
|||
|
||||
extern consvar_t cv_skipmapcheck;
|
||||
|
||||
extern consvar_t cv_sleep, cv_screenshot_option, cv_screenshot_folder;
|
||||
|
||||
extern consvar_t cv_moviemode;
|
||||
|
||||
extern consvar_t cv_zlib_level, cv_zlib_memory, cv_zlib_strategy;
|
||||
|
||||
extern consvar_t cv_zlib_window_bits, cv_zlib_levela, cv_zlib_memorya;
|
||||
|
||||
extern consvar_t cv_zlib_strategya, cv_zlib_window_bitsa;
|
||||
|
||||
extern consvar_t cv_apng_delay;
|
||||
extern consvar_t cv_sleep;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -211,7 +189,6 @@ void Command_ExitGame_f(void);
|
|||
void Command_Retry_f(void);
|
||||
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
||||
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
|
||||
void ObjectPlace_OnChange(void);
|
||||
void ItemFinder_OnChange(void);
|
||||
void D_SetPassword(const char *pw);
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
||||
// Prototypes
|
||||
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
||||
|
||||
// Sender structure
|
||||
typedef struct filetx_s
|
||||
|
@ -303,7 +304,8 @@ boolean CL_SendRequestFile(void)
|
|||
}
|
||||
|
||||
// get request filepak and put it on the send queue
|
||||
void Got_RequestFilePak(INT32 node)
|
||||
// returns false if a requested file was not found or cannot be sent
|
||||
boolean Got_RequestFilePak(INT32 node)
|
||||
{
|
||||
char wad[MAX_WADPATH+1];
|
||||
UINT8 *p = netbuffer->u.textcmd;
|
||||
|
@ -314,8 +316,13 @@ void Got_RequestFilePak(INT32 node)
|
|||
if (id == 0xFF)
|
||||
break;
|
||||
READSTRINGN(p, wad, MAX_WADPATH);
|
||||
SV_SendFile(node, wad, id);
|
||||
if (!SV_SendFile(node, wad, id))
|
||||
{
|
||||
SV_AbortSendFiles(node);
|
||||
return false; // don't read the rest of the files
|
||||
}
|
||||
}
|
||||
return true; // no problems with any files
|
||||
}
|
||||
|
||||
/** Checks if the files needed aren't already loaded or on the disk
|
||||
|
@ -330,6 +337,12 @@ INT32 CL_CheckFiles(void)
|
|||
INT32 i, j;
|
||||
char wadfilename[MAX_WADPATH];
|
||||
INT32 ret = 1;
|
||||
size_t packetsize = 0;
|
||||
size_t filestoget = 0;
|
||||
serverinfo_pak *dummycheck = NULL;
|
||||
|
||||
// Shut the compiler up.
|
||||
(void)dummycheck;
|
||||
|
||||
// if (M_CheckParm("-nofiles"))
|
||||
// return 1;
|
||||
|
@ -378,6 +391,10 @@ INT32 CL_CheckFiles(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||
|
||||
for (i = 1; i < fileneedednum; i++)
|
||||
{
|
||||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||
|
@ -397,6 +414,14 @@ INT32 CL_CheckFiles(void)
|
|||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
||||
continue;
|
||||
|
||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||
|
||||
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||
return 3;
|
||||
|
||||
filestoget++;
|
||||
|
||||
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
||||
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
||||
if (fileneeded[i].status != FS_FOUND)
|
||||
|
@ -480,7 +505,7 @@ static INT32 filestosend = 0;
|
|||
* \sa SV_SendRam
|
||||
*
|
||||
*/
|
||||
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||
{
|
||||
filetx_t **q; // A pointer to the "next" field of the last file in the list
|
||||
filetx_t *p; // The new file request
|
||||
|
@ -488,7 +513,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
char wadfilename[MAX_WADPATH];
|
||||
|
||||
if (cv_noticedownload.value)
|
||||
CONS_Printf("Sending file \"%s\" to node %d\n", filename, node);
|
||||
CONS_Printf("Sending file \"%s\" to node %d (%s)\n", filename, node, I_GetNodeAddress(node));
|
||||
|
||||
// Find the last file in the list and set a pointer to its "next" field
|
||||
q = &transfer[node].txlist;
|
||||
|
@ -537,7 +562,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
free(p->id.filename);
|
||||
free(p);
|
||||
*q = NULL;
|
||||
return;
|
||||
return false; // cancel the rest of the requests
|
||||
}
|
||||
|
||||
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
|
||||
|
@ -549,7 +574,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
free(p->id.filename);
|
||||
free(p);
|
||||
*q = NULL;
|
||||
return;
|
||||
return false; // cancel the rest of the requests
|
||||
}
|
||||
|
||||
DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node));
|
||||
|
@ -557,6 +582,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
|||
p->fileid = fileid;
|
||||
p->next = NULL; // End of list
|
||||
filestosend++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Adds a memory block to the file list for a node
|
||||
|
|
|
@ -69,7 +69,7 @@ boolean SV_SendingFile(INT32 node);
|
|||
|
||||
boolean CL_CheckDownloadable(void);
|
||||
boolean CL_SendRequestFile(void);
|
||||
void Got_RequestFilePak(INT32 node);
|
||||
boolean Got_RequestFilePak(INT32 node);
|
||||
|
||||
void SV_AbortSendFiles(INT32 node);
|
||||
void CloseNetFile(void);
|
||||
|
|
|
@ -32,19 +32,21 @@
|
|||
// Extra abilities/settings for skins (combinable stuff)
|
||||
typedef enum
|
||||
{
|
||||
SF_SUPER = 1, // Can turn super in singleplayer/co-op mode.
|
||||
SF_SUPERANIMS = 1<<1, // If super, use the super sonic animations
|
||||
SF_SUPERSPIN = 1<<2, // Should spin frames be played while super?
|
||||
SF_HIRES = 1<<3, // Draw the sprite 2x as small?
|
||||
SF_SUPER = 1, // Can turn super in singleplayer/co-op mode?
|
||||
SF_NOSUPERSPIN = 1<<1, // Should spin frames be played while super?
|
||||
SF_NOSPINDASHDUST = 1<<2, // Spawn dust particles when charging a spindash?
|
||||
SF_HIRES = 1<<3, // Draw the sprite at different size?
|
||||
SF_NOSKID = 1<<4, // No skid particles etc
|
||||
SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust
|
||||
SF_RUNONWATER = 1<<6, // Run on top of water FOFs?
|
||||
SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_SPIN, falling states used, and player height is full when jumping?
|
||||
SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_ROLL, falling states used, and player height is full when jumping?
|
||||
SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping?
|
||||
SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability?
|
||||
SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc.
|
||||
SF_MACHINE = 1<<10, // Beep boop. Are you a robot?
|
||||
SF_NOSPINDASHDUST = 1<<11, // Don't spawn dust particles when charging a spindash
|
||||
SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase?
|
||||
SF_FASTEDGE = 1<<12, // Faster edge teeter?
|
||||
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
|
||||
// free up to and including 1<<31
|
||||
} skinflags_t;
|
||||
|
||||
|
@ -65,7 +67,7 @@ typedef enum
|
|||
CA_JUMPBOOST,
|
||||
CA_AIRDRILL,
|
||||
CA_JUMPTHOK,
|
||||
CA_DASHMODE,
|
||||
CA_BOUNCE,
|
||||
CA_TWINSPIN
|
||||
} charability_t;
|
||||
|
||||
|
@ -74,7 +76,7 @@ typedef enum
|
|||
{
|
||||
CA2_NONE=0,
|
||||
CA2_SPINDASH,
|
||||
CA2_MULTIABILITY,
|
||||
CA2_GUNSLINGER,
|
||||
CA2_MELEE
|
||||
} charability2_t;
|
||||
|
||||
|
@ -118,10 +120,8 @@ typedef enum
|
|||
// Did you get a time-over?
|
||||
PF_TIMEOVER = 1<<10,
|
||||
|
||||
// Ready for Super?
|
||||
PF_SUPERREADY = 1<<11,
|
||||
|
||||
// Character action status
|
||||
PF_STARTJUMP = 1<<11,
|
||||
PF_JUMPED = 1<<12,
|
||||
PF_SPINNING = 1<<13,
|
||||
PF_STARTDASH = 1<<14,
|
||||
|
@ -133,12 +133,11 @@ typedef enum
|
|||
// Sliding (usually in water) like Labyrinth/Oil Ocean
|
||||
PF_SLIDING = 1<<17,
|
||||
|
||||
/*** NIGHTS STUFF ***/
|
||||
// Is the player in NiGHTS mode?
|
||||
PF_NIGHTSMODE = 1<<18,
|
||||
PF_TRANSFERTOCLOSEST = 1<<19,
|
||||
// Bouncing
|
||||
PF_BOUNCING = 1<<18,
|
||||
|
||||
// Spill rings after falling
|
||||
/*** NIGHTS STUFF ***/
|
||||
PF_TRANSFERTOCLOSEST = 1<<19,
|
||||
PF_NIGHTSFALL = 1<<20,
|
||||
PF_DRILLING = 1<<21,
|
||||
PF_SKIDDOWN = 1<<22,
|
||||
|
@ -157,10 +156,10 @@ typedef enum
|
|||
// Used shield ability
|
||||
PF_SHIELDABILITY = 1<<28,
|
||||
|
||||
// Force jump damage?
|
||||
PF_FORCEJUMPDAMAGE = 1<<29
|
||||
// Jump damage?
|
||||
PF_NOJUMPDAMAGE = 1<<29,
|
||||
|
||||
// free up to and including 1<<31
|
||||
// up to 1<<31 is free
|
||||
} pflags_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -171,7 +170,7 @@ typedef enum
|
|||
PA_EDGE,
|
||||
PA_WALK,
|
||||
PA_RUN,
|
||||
PA_PEEL,
|
||||
PA_DASH,
|
||||
PA_PAIN,
|
||||
PA_ROLL,
|
||||
PA_JUMP,
|
||||
|
@ -223,6 +222,10 @@ typedef enum
|
|||
CR_GENERIC,
|
||||
// Tails carry.
|
||||
CR_PLAYER,
|
||||
// NiGHTS mode. Not technically a CARRYING, but doesn't stack with any of the others, so might as well go here.
|
||||
CR_NIGHTSMODE,
|
||||
// Old Brak sucks hard, but this gimmick could be used for something better, so we might as well continue supporting it.
|
||||
CR_BRAKGOOP,
|
||||
// Specific level gimmicks.
|
||||
CR_ZOOMTUBE,
|
||||
CR_ROPEHANG,
|
||||
|
@ -262,9 +265,7 @@ typedef enum
|
|||
pw_nights_helper,
|
||||
pw_nights_linkfreeze,
|
||||
|
||||
//for linedef exec 427
|
||||
pw_nocontrol,
|
||||
pw_ingoop, // In goop
|
||||
pw_nocontrol, //for linedef exec 427
|
||||
|
||||
NUMPOWERS
|
||||
} powertype_t;
|
||||
|
@ -340,6 +341,7 @@ typedef struct player_s
|
|||
UINT8 skincolor;
|
||||
|
||||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
|
||||
UINT32 score; // player score
|
||||
fixed_t dashspeed; // dashing speed
|
||||
|
@ -377,7 +379,6 @@ typedef struct player_s
|
|||
UINT8 gotcontinue; // Got continue from this stage?
|
||||
|
||||
fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values)
|
||||
UINT8 jumping; // Holding down jump button
|
||||
UINT8 secondjump; // Jump counter
|
||||
|
||||
UINT8 fly1; // Tails flying
|
||||
|
|
565
src/dehacked.c
565
src/dehacked.c
|
@ -382,72 +382,20 @@ static void clear_levels(void)
|
|||
P_AllocMapHeader(gamemap-1);
|
||||
}
|
||||
|
||||
/*
|
||||
// Edits an animated texture slot on the array
|
||||
// Tails 12-27-2003
|
||||
static void readAnimTex(MYFILE *f, INT32 num)
|
||||
{
|
||||
char s[MAXLINELEN];
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
|
||||
do {
|
||||
if (myfgets(s, sizeof s, f) != NULL)
|
||||
{
|
||||
if (s[0] == '\n') break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
// set the value in the appropriate field
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
|
||||
i = atoi(word2);
|
||||
|
||||
if (fastcmp(word, "START"))
|
||||
strncpy(harddefs[num].startname, word2, 8);
|
||||
if (fastcmp(word, "END"))
|
||||
strncpy(harddefs[num].endname, word2, 8);
|
||||
else if (fastcmp(word, "SPEED")) harddefs[num].speed = i;
|
||||
else if (fastcmp(word, "ISTEXTURE")) harddefs[num].istexture = i;
|
||||
|
||||
else deh_warning("readAnimTex %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (s[0] != '\n' && !myfeof(f)); //finish when the line is empty
|
||||
}
|
||||
*/
|
||||
|
||||
static boolean findFreeSlot(INT32 *num, UINT16 wadnum)
|
||||
static boolean findFreeSlot(INT32 *num)
|
||||
{
|
||||
// Send the character select entry to a free slot.
|
||||
while (*num < 32 && (!(PlayerMenu[*num].status & IT_DISABLED) || description[*num].wadnum == wadnum)) // Will kill hidden characters from other files, but that's okay.
|
||||
while (*num < 32 && (description[*num].used))
|
||||
*num = *num+1;
|
||||
|
||||
// No more free slots. :(
|
||||
if (*num >= 32)
|
||||
return false;
|
||||
|
||||
PlayerMenu[*num].status = IT_CALL;
|
||||
description[*num].wadnum = wadnum;
|
||||
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||
|
||||
// Found one! ^_^
|
||||
return true;
|
||||
return (description[*num].used = true);
|
||||
}
|
||||
|
||||
// Reads a player.
|
||||
|
@ -479,7 +427,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
{
|
||||
char *playertext = NULL;
|
||||
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
|
@ -528,7 +476,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
|
||||
if (fastcmp(word, "PICNAME"))
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
|
||||
|
||||
|
@ -536,12 +484,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
}
|
||||
else if (fastcmp(word, "STATUS"))
|
||||
{
|
||||
// Limit the status to only IT_DISABLED and IT_CALL
|
||||
if (i)
|
||||
i = IT_CALL;
|
||||
else
|
||||
i = IT_DISABLED;
|
||||
|
||||
/*
|
||||
You MAY disable previous entries if you so desire...
|
||||
But try to enable something that's already enabled and you will be sent to a free slot.
|
||||
|
@ -549,15 +491,15 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
Because of this, you are allowed to edit any previous entries you like, but only if you
|
||||
signal that you are purposely doing so by disabling and then reenabling the slot.
|
||||
*/
|
||||
if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
|
||||
if (i && !slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE);
|
||||
PlayerMenu[num].status = (INT16)i;
|
||||
DEH_WriteUndoline(word, va("%d", description[num].used), UNDO_NONE);
|
||||
description[num].used = (!!i);
|
||||
}
|
||||
else if (fastcmp(word, "SKINNAME"))
|
||||
{
|
||||
// Send to free slot.
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
|
||||
|
||||
|
@ -1211,6 +1153,12 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
|
||||
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
|
||||
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once
|
||||
}
|
||||
else if (fastcmp(word, "SELECTHEADING"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->selectheading, word2,
|
||||
sizeof(mapheaderinfo[num-1]->selectheading), va("Level header %d: selectheading", num));
|
||||
}
|
||||
else if (fastcmp(word, "SCRIPTNAME"))
|
||||
{
|
||||
|
@ -1430,6 +1378,13 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
else
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_NOVISITNEEDED;
|
||||
}
|
||||
else if (fastcmp(word, "WIDEICON"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_WIDEICON;
|
||||
else
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_WIDEICON;
|
||||
}
|
||||
else
|
||||
deh_warning("Level header %d: unknown word '%s'", num, word);
|
||||
}
|
||||
|
@ -2113,10 +2068,11 @@ static void readframe(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||
static void readsound(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 value;
|
||||
|
||||
|
@ -2130,8 +2086,8 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
|||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
value = searchvalue(s);
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
|
@ -2139,21 +2095,16 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
|||
else
|
||||
break;
|
||||
|
||||
/* if (fastcmp(word, "OFFSET"))
|
||||
word2 = strtok(NULL, " ");
|
||||
if (word2)
|
||||
value = atoi(word2);
|
||||
else
|
||||
{
|
||||
value -= 150360;
|
||||
if (value <= 64)
|
||||
value /= 8;
|
||||
else if (value <= 260)
|
||||
value = (value+4)/8;
|
||||
else
|
||||
value = (value+8)/8;
|
||||
if (value >= -1 && value < sfx_freeslot0 - 1)
|
||||
S_sfx[num].name = savesfxnames[value+1];
|
||||
else
|
||||
deh_warning("Sound %d: offset out of bounds", num);
|
||||
deh_warning("No value for token %s", word);
|
||||
continue;
|
||||
}
|
||||
else */if (fastcmp(word, "SINGULAR"))
|
||||
|
||||
if (fastcmp(word, "SINGULAR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||
S_sfx[num].singularity = value;
|
||||
|
@ -2168,14 +2119,17 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
|||
DEH_WriteUndoline(word, va("%d", S_sfx[num].pitch), UNDO_NONE);
|
||||
S_sfx[num].pitch = value;
|
||||
}
|
||||
else if (fastcmp(word, "CAPTION") || fastcmp(word, "DESCRIPTION"))
|
||||
{
|
||||
deh_strlcpy(S_sfx[num].caption, word2,
|
||||
sizeof(S_sfx[num].caption), va("Sound effect %d: caption", num));
|
||||
}
|
||||
else
|
||||
deh_warning("Sound %d : unknown word '%s'",num,word);
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
Z_Free(s);
|
||||
|
||||
(void)savesfxnames;
|
||||
}
|
||||
|
||||
/** Checks if a game data file name for a mod is good.
|
||||
|
@ -2461,6 +2415,7 @@ static void readunlockable(MYFILE *f, INT32 num)
|
|||
DEH_WriteUndoline("VAR", va("%d", unlockables[num].variable), UNDO_NONE);
|
||||
|
||||
memset(&unlockables[num], 0, sizeof(unlockable_t));
|
||||
unlockables[num].objective[0] = '/';
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -2802,190 +2757,6 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readtexture(MYFILE *f, const char *name)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 i, j, value;
|
||||
UINT16 width = 0, height = 0;
|
||||
INT16 patchcount = 0;
|
||||
texture_t *texture;
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
value = searchvalue(s);
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
// Width of the texture.
|
||||
if (fastcmp(word, "WIDTH"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", width), UNDO_NONE);
|
||||
width = SHORT((UINT16)value);
|
||||
}
|
||||
// Height of the texture.
|
||||
else if (fastcmp(word, "HEIGHT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", height), UNDO_NONE);
|
||||
height = SHORT((UINT16)value);
|
||||
}
|
||||
// Number of patches the texture has.
|
||||
else if (fastcmp(word, "NUMPATCHES"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", patchcount), UNDO_NONE);
|
||||
patchcount = SHORT((UINT16)value);
|
||||
}
|
||||
else
|
||||
deh_warning("readtexture: unknown word '%s'", word);
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
// Error checking.
|
||||
if (!width)
|
||||
I_Error("Texture %s has no width!\n", name);
|
||||
|
||||
if (!height)
|
||||
I_Error("Texture %s has no height!\n", name);
|
||||
|
||||
if (!patchcount)
|
||||
I_Error("Texture %s has no patches!\n", name);
|
||||
|
||||
// Allocate memory for the texture, and fill in information.
|
||||
texture = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * SHORT(patchcount)), PU_STATIC, NULL);
|
||||
M_Memcpy(texture->name, name, sizeof(texture->name));
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->patchcount = patchcount;
|
||||
texture->holes = false;
|
||||
// Fill out the texture patches, to allow them to be detected
|
||||
// accurately by readpatch.
|
||||
for (i = 0; i < patchcount; i++)
|
||||
{
|
||||
texture->patches[i].originx = 0;
|
||||
texture->patches[i].originy = 0;
|
||||
texture->patches[i].wad = UINT16_MAX;
|
||||
texture->patches[i].lump = UINT16_MAX;
|
||||
}
|
||||
|
||||
// Jump to the next empty texture entry.
|
||||
i = 0;
|
||||
while (textures[i])
|
||||
i++;
|
||||
|
||||
// Fill the global texture buffer entries.
|
||||
j = 1;
|
||||
while (j << 1 <= texture->width)
|
||||
j <<= 1;
|
||||
|
||||
textures[i] = texture;
|
||||
texturewidthmask[i] = j - 1;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
|
||||
// Clean up.
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 i = 0, j = 0, value;
|
||||
texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0, 255, AST_COPY};
|
||||
|
||||
// Jump to the texture this patch belongs to, which,
|
||||
// coincidentally, is always the last one on the buffer cache.
|
||||
while (textures[i+1])
|
||||
i++;
|
||||
|
||||
// Jump to the next empty patch entry.
|
||||
while (memcmp(&(textures[i]->patches[j]), &patch, sizeof(patch)))
|
||||
j++;
|
||||
|
||||
patch.wad = wad;
|
||||
// Set the texture number, but only if the lump exists.
|
||||
if ((patch.lump = W_CheckNumForNamePwad(name, wad, 0)) == INT16_MAX)
|
||||
I_Error("readpatch: Missing patch in texture %s", textures[i]->name);
|
||||
|
||||
// note: undoing this patch will be done by other means
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
value = searchvalue(s);
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
// X position of the patch in the texture.
|
||||
if (fastcmp(word, "X"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE);
|
||||
patch.originx = (INT16)value;
|
||||
}
|
||||
// Y position of the patch in the texture.
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE);
|
||||
patch.originy = (INT16)value;
|
||||
}
|
||||
else
|
||||
deh_warning("readpatch: unknown word '%s'", word);
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
// Error checking.
|
||||
/* // Irrelevant. Origins cannot be unsigned.
|
||||
if (patch.originx == UINT16_MAX)
|
||||
I_Error("Patch %s on texture %s has no X position!\n", name, textures[i]->name);
|
||||
|
||||
if (patch.originy == UINT16_MAX)
|
||||
I_Error("Patch %s on texture %s has no Y position!\n", name, textures[i]->name);
|
||||
*/
|
||||
|
||||
// Set the patch as that patch number.
|
||||
textures[i]->patches[j] = patch;
|
||||
|
||||
// Clean up.
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readmaincfg(MYFILE *f)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
@ -3396,30 +3167,17 @@ static void ignorelines(MYFILE *f)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
static void DEH_LoadDehackedFile(MYFILE *f)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
// do a copy of this for cross references probleme
|
||||
//XBOXSTATIC actionf_t saveactions[NUMSTATES];
|
||||
//XBOXSTATIC const char *savesprnames[NUMSPRITES];
|
||||
XBOXSTATIC const char *savesfxnames[NUMSFX];
|
||||
|
||||
if (!deh_loaded)
|
||||
initfreeslots();
|
||||
|
||||
deh_num_warning = 0;
|
||||
// save values for cross reference
|
||||
/*
|
||||
for (i = 0; i < NUMSTATES; i++)
|
||||
saveactions[i] = states[i].action;
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
savesprnames[i] = sprnames[i];
|
||||
*/
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
savesfxnames[i] = S_sfx[i].name;
|
||||
|
||||
gamedataadded = false;
|
||||
|
||||
|
@ -3496,19 +3254,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
i = atoi(word2);
|
||||
if (fastcmp(word, "TEXTURE"))
|
||||
{
|
||||
// Read texture from spec file.
|
||||
readtexture(f, word2);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "PATCH"))
|
||||
{
|
||||
// Read patch from spec file.
|
||||
readpatch(f, word2, wad);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_mobjtype(word2); // find a thing by name
|
||||
|
@ -3521,10 +3267,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
/* else if (fastcmp(word, "ANIMTEX"))
|
||||
{
|
||||
readAnimTex(f, i);
|
||||
}*/
|
||||
else if (fastcmp(word, "LIGHT"))
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
|
@ -3596,61 +3338,19 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
// <Callum> Added translations to this just in case its re-enabled
|
||||
/* else if (fastcmp(word, "POINTER"))
|
||||
{
|
||||
word = strtok(NULL, " "); // get frame
|
||||
word = strtok(NULL, ")");
|
||||
if (word)
|
||||
{
|
||||
i = atoi(word);
|
||||
if (i < NUMSTATES && i >= 0)
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
states[i].action = saveactions[searchvalue(s)];
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Pointer: Frame %d doesn't exist", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
||||
}*/
|
||||
else if (fastcmp(word, "SOUND"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_sfx(word2); // find a sound by name
|
||||
if (i < NUMSFX && i >= 0)
|
||||
readsound(f, i, savesfxnames);
|
||||
if (i < NUMSFX && i > 0)
|
||||
readsound(f, i);
|
||||
else
|
||||
{
|
||||
deh_warning("Sound %d out of range (0 - %d)", i, NUMSFX-1);
|
||||
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
/* else if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
if (i < NUMSPRITES && i >= 0)
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
INT32 k;
|
||||
k = (searchvalue(s) - 151328)/8;
|
||||
if (k >= 0 && k < NUMSPRITES)
|
||||
sprnames[i] = savesprnames[k];
|
||||
else
|
||||
{
|
||||
deh_warning("Sprite %d: offset out of bounds", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("Sprite %d doesn't exist",i);
|
||||
}*/
|
||||
else if (fastcmp(word, "HUDITEM"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
|
@ -3737,7 +3437,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// no undo support for this insanity yet
|
||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
// Last I heard this crashes the game if you try to use it
|
||||
// so this is disabled for now
|
||||
// -- Monster Iestyn
|
||||
/* else if (fastcmp(word, "SRB2"))
|
||||
{
|
||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||
if (ver != PATCHVERSION)
|
||||
|
@ -3748,6 +3451,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// Unless you REALLY want to piss people off,
|
||||
// define a custom gamedata /before/ doing this!!
|
||||
// (then again, modifiedgame will prevent game data saving anyway)
|
||||
*/
|
||||
else if (fastcmp(word, "CLEAR"))
|
||||
{
|
||||
boolean clearall = (fastcmp(word2, "ALL"));
|
||||
|
@ -3821,7 +3525,7 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
|||
W_ReadLumpPwad(wad, lump, f.data);
|
||||
f.curpos = f.data;
|
||||
f.data[f.size] = 0;
|
||||
DEH_LoadDehackedFile(&f, wad);
|
||||
DEH_LoadDehackedFile(&f);
|
||||
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
||||
Z_Free(f.data);
|
||||
}
|
||||
|
@ -3924,12 +3628,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PLAY_WAIT",
|
||||
"S_PLAY_WALK",
|
||||
"S_PLAY_RUN",
|
||||
"S_PLAY_PEEL",
|
||||
"S_PLAY_DASH",
|
||||
"S_PLAY_PAIN",
|
||||
"S_PLAY_STUN",
|
||||
"S_PLAY_DEAD",
|
||||
"S_PLAY_DRWN",
|
||||
"S_PLAY_SPIN",
|
||||
"S_PLAY_DASH",
|
||||
"S_PLAY_ROLL",
|
||||
"S_PLAY_GASP",
|
||||
"S_PLAY_JUMP",
|
||||
"S_PLAY_SPRING",
|
||||
|
@ -3937,6 +3641,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PLAY_EDGE",
|
||||
"S_PLAY_RIDE",
|
||||
|
||||
// CA2_SPINDASH
|
||||
"S_PLAY_SPINDASH",
|
||||
|
||||
// CA_FLY/SWIM
|
||||
"S_PLAY_FLY",
|
||||
"S_PLAY_SWIM",
|
||||
|
@ -3947,30 +3654,25 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PLAY_CLING",
|
||||
"S_PLAY_CLIMB",
|
||||
|
||||
// CA_FLOAT/CA_SLOWFALL
|
||||
"S_PLAY_FLOAT",
|
||||
"S_PLAY_FLOAT_RUN",
|
||||
|
||||
// CA_BOUNCE
|
||||
"S_PLAY_BOUNCE",
|
||||
"S_PLAY_BOUNCE_LANDING",
|
||||
|
||||
// CA2_GUNSLINGER
|
||||
"S_PLAY_FIRE",
|
||||
"S_PLAY_FIRE_FINISH",
|
||||
|
||||
// CA_TWINSPIN
|
||||
"S_PLAY_TWINSPIN",
|
||||
|
||||
// CA2_MELEE
|
||||
"S_PLAY_MELEE",
|
||||
"S_PLAY_MELEE_FINISH",
|
||||
|
||||
// SF_SUPERANIMS
|
||||
"S_PLAY_SUPER_STND",
|
||||
"S_PLAY_SUPER_WALK",
|
||||
"S_PLAY_SUPER_RUN",
|
||||
"S_PLAY_SUPER_PEEL",
|
||||
"S_PLAY_SUPER_PAIN",
|
||||
"S_PLAY_SUPER_STUN",
|
||||
"S_PLAY_SUPER_DEAD",
|
||||
"S_PLAY_SUPER_DRWN",
|
||||
"S_PLAY_SUPER_SPIN",
|
||||
"S_PLAY_SUPER_GASP",
|
||||
"S_PLAY_SUPER_JUMP",
|
||||
"S_PLAY_SUPER_SPRING",
|
||||
"S_PLAY_SUPER_FALL",
|
||||
"S_PLAY_SUPER_EDGE",
|
||||
"S_PLAY_SUPER_RIDE",
|
||||
"S_PLAY_SUPER_FLOAT",
|
||||
"S_PLAY_MELEE_LANDING",
|
||||
|
||||
// SF_SUPER
|
||||
"S_PLAY_SUPERTRANS1",
|
||||
|
@ -4009,7 +3711,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
"S_PLAY_NIGHTS_STAND",
|
||||
"S_PLAY_NIGHTS_FLOAT",
|
||||
"S_PLAY_NIGHTS_PAIN",
|
||||
"S_PLAY_NIGHTS_STUN",
|
||||
"S_PLAY_NIGHTS_PULL",
|
||||
"S_PLAY_NIGHTS_ATTACK",
|
||||
|
||||
|
@ -4831,12 +4533,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
// Individual Team Rings
|
||||
"S_TEAMRING",
|
||||
|
||||
// Special Stage Token
|
||||
"S_EMMY",
|
||||
|
||||
// Special Stage Token
|
||||
"S_TOKEN",
|
||||
"S_MOVINGTOKEN",
|
||||
|
||||
// CTF Flags
|
||||
"S_REDFLAG",
|
||||
|
@ -4987,6 +4685,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_SPIKED1",
|
||||
"S_SPIKED2",
|
||||
|
||||
// Wall spikes
|
||||
"S_WALLSPIKE1",
|
||||
"S_WALLSPIKE2",
|
||||
"S_WALLSPIKE3",
|
||||
"S_WALLSPIKE4",
|
||||
"S_WALLSPIKE5",
|
||||
"S_WALLSPIKE6",
|
||||
"S_WALLSPIKEBASE",
|
||||
|
||||
// Starpost
|
||||
"S_STARPOST_IDLE",
|
||||
"S_STARPOST_FLASH",
|
||||
|
@ -5173,6 +4880,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_DEMONFIRE5",
|
||||
"S_DEMONFIRE6",
|
||||
|
||||
// GFZ flowers
|
||||
"S_GFZFLOWERA",
|
||||
"S_GFZFLOWERB",
|
||||
"S_GFZFLOWERC",
|
||||
|
@ -5180,6 +4888,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BERRYBUSH",
|
||||
"S_BUSH",
|
||||
|
||||
// Trees (both GFZ and misc)
|
||||
"S_GFZTREE",
|
||||
"S_GFZBERRYTREE",
|
||||
"S_GFZCHERRYTREE",
|
||||
"S_CHECKERTREE",
|
||||
"S_CHECKERSUNSETTREE",
|
||||
"S_FHZTREE", // Frozen Hillside
|
||||
"S_FHZPINKTREE",
|
||||
"S_POLYGONTREE",
|
||||
"S_BUSHTREE",
|
||||
"S_BUSHREDTREE",
|
||||
|
||||
// THZ Plant
|
||||
"S_THZFLOWERA",
|
||||
"S_THZFLOWERB",
|
||||
|
@ -5189,6 +4909,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// Deep Sea Gargoyle
|
||||
"S_GARGOYLE",
|
||||
"S_BIGGARGOYLE",
|
||||
|
||||
// DSZ Seaweed
|
||||
"S_SEAWEED1",
|
||||
|
@ -5347,7 +5068,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
// Xmas-specific stuff
|
||||
"S_XMASPOLE",
|
||||
"S_CANDYCANE",
|
||||
"S_SNOWMAN",
|
||||
"S_SNOWMAN", // normal
|
||||
"S_SNOWMANHAT", // with hat + scarf
|
||||
"S_LAMPPOST1", // normal
|
||||
"S_LAMPPOST2", // with snow
|
||||
"S_HANGSTAR",
|
||||
// Xmas GFZ bushes
|
||||
"S_XMASBERRYBUSH",
|
||||
"S_XMASBUSH",
|
||||
|
||||
// Botanic Serenity's loads of scenery states
|
||||
"S_BSZTALLFLOWER_RED",
|
||||
|
@ -5539,10 +5267,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PITY4",
|
||||
"S_PITY5",
|
||||
"S_PITY6",
|
||||
"S_PITY7",
|
||||
"S_PITY8",
|
||||
"S_PITY9",
|
||||
"S_PITY10",
|
||||
|
||||
"S_FIRS1",
|
||||
"S_FIRS2",
|
||||
|
@ -5934,14 +5658,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FOUR2",
|
||||
"S_FIVE2",
|
||||
|
||||
"S_LOCKON1",
|
||||
"S_LOCKON2",
|
||||
|
||||
// Tag Sign
|
||||
"S_TTAG1",
|
||||
"S_TTAG",
|
||||
|
||||
// Got Flag Sign
|
||||
"S_GOTFLAG1",
|
||||
"S_GOTFLAG2",
|
||||
"S_GOTFLAG3",
|
||||
"S_GOTFLAG4",
|
||||
"S_GOTFLAG",
|
||||
"S_GOTREDFLAG",
|
||||
"S_GOTBLUEFLAG",
|
||||
|
||||
"S_CORK",
|
||||
|
||||
// Red Ring
|
||||
"S_RRNG1",
|
||||
|
@ -6424,8 +6152,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BLUEBALL", // Blue sphere replacement for special stages
|
||||
"MT_REDTEAMRING", //Rings collectable by red team.
|
||||
"MT_BLUETEAMRING", //Rings collectable by blue team.
|
||||
"MT_EMMY", // emerald token for special stage
|
||||
"MT_TOKEN", // Special Stage Token (uncollectible part)
|
||||
"MT_TOKEN", // Special Stage Token
|
||||
"MT_REDFLAG", // Red CTF Flag
|
||||
"MT_BLUEFLAG", // Blue CTF Flag
|
||||
"MT_EMBLEM",
|
||||
|
@ -6459,6 +6186,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SPECIALSPIKEBALL",
|
||||
"MT_SPINFIRE",
|
||||
"MT_SPIKE",
|
||||
"MT_WALLSPIKE",
|
||||
"MT_WALLSPIKEBASE",
|
||||
"MT_STARPOST",
|
||||
"MT_BIGMINE",
|
||||
"MT_BIGAIRMINE",
|
||||
|
@ -6549,6 +6278,17 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_GFZFLOWER3",
|
||||
"MT_BERRYBUSH",
|
||||
"MT_BUSH",
|
||||
// Trees (both GFZ and misc)
|
||||
"MT_GFZTREE",
|
||||
"MT_GFZBERRYTREE",
|
||||
"MT_GFZCHERRYTREE",
|
||||
"MT_CHECKERTREE",
|
||||
"MT_CHECKERSUNSETTREE",
|
||||
"MT_FHZTREE", // Frozen Hillside
|
||||
"MT_FHZPINKTREE",
|
||||
"MT_POLYGONTREE",
|
||||
"MT_BUSHTREE",
|
||||
"MT_BUSHREDTREE",
|
||||
|
||||
// Techno Hill Scenery
|
||||
"MT_THZFLOWER1",
|
||||
|
@ -6557,6 +6297,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
|
||||
// Deep Sea Scenery
|
||||
"MT_GARGOYLE", // Deep Sea Gargoyle
|
||||
"MT_BIGGARGOYLE", // Deep Sea Gargoyle (Big)
|
||||
"MT_SEAWEED", // DSZ Seaweed
|
||||
"MT_WATERDRIP", // Dripping Water source
|
||||
"MT_WATERDROP", // Water drop from dripping water
|
||||
|
@ -6625,7 +6366,14 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
// Christmas Scenery
|
||||
"MT_XMASPOLE",
|
||||
"MT_CANDYCANE",
|
||||
"MT_SNOWMAN",
|
||||
"MT_SNOWMAN", // normal
|
||||
"MT_SNOWMANHAT", // with hat + scarf
|
||||
"MT_LAMPPOST1", // normal
|
||||
"MT_LAMPPOST2", // with snow
|
||||
"MT_HANGSTAR",
|
||||
// Xmas GFZ bushes
|
||||
"MT_XMASBERRYBUSH",
|
||||
"MT_XMASBUSH",
|
||||
|
||||
// Botanic Serenity
|
||||
"MT_BSZTALLFLOWER_RED",
|
||||
|
@ -6732,9 +6480,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SCORE", // score logo
|
||||
"MT_DROWNNUMBERS", // Drowning Timer
|
||||
"MT_GOTEMERALD", // Chaos Emerald (intangible)
|
||||
"MT_LOCKON", // Target
|
||||
"MT_TAG", // Tag Sign
|
||||
"MT_GOTFLAG", // Got Flag sign
|
||||
"MT_GOTFLAG2", // Got Flag sign
|
||||
|
||||
// Ambient Sounds
|
||||
"MT_AWATERA", // Ambient Water Sound 1
|
||||
|
@ -6748,6 +6496,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_RANDOMAMBIENT",
|
||||
"MT_RANDOMAMBIENT2",
|
||||
|
||||
"MT_CORK",
|
||||
|
||||
// Ring Weapons
|
||||
"MT_REDRING",
|
||||
"MT_BOUNCERING",
|
||||
|
@ -6971,10 +6721,8 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
// Did you get a time-over?
|
||||
"TIMEOVER",
|
||||
|
||||
// Ready for Super?
|
||||
"SUPERREADY",
|
||||
|
||||
// Character action status
|
||||
"STARTJUMP",
|
||||
"JUMPED",
|
||||
"SPINNING",
|
||||
"STARTDASH",
|
||||
|
@ -6986,12 +6734,11 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
// Sliding (usually in water) like Labyrinth/Oil Ocean
|
||||
"SLIDING",
|
||||
|
||||
/*** NIGHTS STUFF ***/
|
||||
// Is the player in NiGHTS mode?
|
||||
"NIGHTSMODE",
|
||||
"TRANSFERTOCLOSEST",
|
||||
// Bouncing
|
||||
"BOUNCING",
|
||||
|
||||
// Spill rings after falling
|
||||
/*** NIGHTS STUFF ***/
|
||||
"TRANSFERTOCLOSEST",
|
||||
"NIGHTSFALL",
|
||||
"DRILLING",
|
||||
"SKIDDOWN",
|
||||
|
@ -7005,7 +6752,7 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
"ANALOGMODE", // Analog mode?
|
||||
"CANCARRY", // Can carry?
|
||||
"SHIELDABILITY", // Thokked with shield ability
|
||||
"FORCEJUMPDAMAGE", // Force jump damage
|
||||
"NOJUMPDAMAGE", // No jump damage
|
||||
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
@ -7154,8 +6901,7 @@ static const char *const POWERS_LIST[] = {
|
|||
"NIGHTS_LINKFREEZE",
|
||||
|
||||
//for linedef exec 427
|
||||
"NOCONTROL",
|
||||
"INGOOP" // In goop
|
||||
"NOCONTROL"
|
||||
};
|
||||
|
||||
static const char *const HUDITEMS_LIST[] = {
|
||||
|
@ -7247,14 +6993,15 @@ struct {
|
|||
|
||||
// Frame settings
|
||||
{"FF_FRAMEMASK",FF_FRAMEMASK},
|
||||
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
|
||||
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
|
||||
{"FF_SPR2SUPER",FF_SPR2SUPER},
|
||||
{"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE},
|
||||
{"FF_SPR2MIDSTART",FF_SPR2MIDSTART},
|
||||
{"FF_ANIMATE",FF_ANIMATE},
|
||||
{"FF_RANDOMANIM",FF_RANDOMANIM},
|
||||
{"FF_GLOBALANIM",FF_GLOBALANIM},
|
||||
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
|
||||
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
|
||||
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
|
||||
{"FF_TRANSMASK",FF_TRANSMASK},
|
||||
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
|
||||
// new preshifted translucency (used in source)
|
||||
|
@ -7317,6 +7064,7 @@ struct {
|
|||
{"LF2_RECORDATTACK",LF2_RECORDATTACK},
|
||||
{"LF2_NIGHTSATTACK",LF2_NIGHTSATTACK},
|
||||
{"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED},
|
||||
{"LF2_WIDEICON",LF2_WIDEICON},
|
||||
|
||||
// NiGHTS grades
|
||||
{"GRADE_F",GRADE_F},
|
||||
|
@ -7378,6 +7126,8 @@ struct {
|
|||
{"CR_NONE",CR_NONE},
|
||||
{"CR_GENERIC",CR_GENERIC},
|
||||
{"CR_PLAYER",CR_PLAYER},
|
||||
{"CR_NIGHTSMODE",CR_NIGHTSMODE},
|
||||
{"CR_BRAKGOOP",CR_BRAKGOOP},
|
||||
{"CR_ZOOMTUBE",CR_ZOOMTUBE},
|
||||
{"CR_ROPEHANG",CR_ROPEHANG},
|
||||
{"CR_MACESPIN",CR_MACESPIN},
|
||||
|
@ -7393,8 +7143,8 @@ struct {
|
|||
|
||||
// Character flags (skinflags_t)
|
||||
{"SF_SUPER",SF_SUPER},
|
||||
{"SF_SUPERANIMS",SF_SUPERANIMS},
|
||||
{"SF_SUPERSPIN",SF_SUPERSPIN},
|
||||
{"SF_NOSUPERSPIN",SF_NOSUPERSPIN},
|
||||
{"SF_NOSPINDASHDUST",SF_NOSPINDASHDUST},
|
||||
{"SF_HIRES",SF_HIRES},
|
||||
{"SF_NOSKID",SF_NOSKID},
|
||||
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
|
||||
|
@ -7404,7 +7154,9 @@ struct {
|
|||
{"SF_STOMPDAMAGE",SF_STOMPDAMAGE},
|
||||
{"SF_MARIODAMAGE",SF_MARIODAMAGE},
|
||||
{"SF_MACHINE",SF_MACHINE},
|
||||
{"SF_NOSPINDASHDUST",SF_NOSPINDASHDUST},
|
||||
{"SF_DASHMODE",SF_DASHMODE},
|
||||
{"SF_FASTEDGE",SF_FASTEDGE},
|
||||
{"SF_MULTIABILITY",SF_MULTIABILITY},
|
||||
|
||||
// Character abilities!
|
||||
// Primary
|
||||
|
@ -7422,12 +7174,12 @@ struct {
|
|||
{"CA_JUMPBOOST",CA_JUMPBOOST},
|
||||
{"CA_AIRDRILL",CA_AIRDRILL},
|
||||
{"CA_JUMPTHOK",CA_JUMPTHOK},
|
||||
{"CA_DASHMODE",CA_DASHMODE},
|
||||
{"CA_BOUNCE",CA_BOUNCE},
|
||||
{"CA_TWINSPIN",CA_TWINSPIN},
|
||||
// Secondary
|
||||
{"CA2_NONE",CA2_NONE}, // now slot 0!
|
||||
{"CA2_SPINDASH",CA2_SPINDASH},
|
||||
{"CA2_MULTIABILITY",CA2_MULTIABILITY},
|
||||
{"CA2_GUNSLINGER",CA2_GUNSLINGER},
|
||||
{"CA2_MELEE",CA2_MELEE},
|
||||
|
||||
// Sound flags
|
||||
|
@ -7496,7 +7248,7 @@ struct {
|
|||
{"PA_EDGE",PA_EDGE},
|
||||
{"PA_WALK",PA_WALK},
|
||||
{"PA_RUN",PA_RUN},
|
||||
{"PA_PEEL",PA_PEEL},
|
||||
{"PA_DASH",PA_DASH},
|
||||
{"PA_PAIN",PA_PAIN},
|
||||
{"PA_ROLL",PA_ROLL},
|
||||
{"PA_JUMP",PA_JUMP},
|
||||
|
@ -7685,6 +7437,7 @@ struct {
|
|||
{"V_70TRANS",V_70TRANS},
|
||||
{"V_80TRANS",V_80TRANS},
|
||||
{"V_90TRANS",V_90TRANS},
|
||||
{"V_STATIC",V_STATIC},
|
||||
{"V_HUDTRANSHALF",V_HUDTRANSHALF},
|
||||
{"V_HUDTRANS",V_HUDTRANS},
|
||||
{"V_HUDTRANSDOUBLE",V_HUDTRANSDOUBLE},
|
||||
|
|
|
@ -90,6 +90,10 @@ static unsigned long nombre = NEWTICRATE*10;
|
|||
static void I_BlitScreenVesa1(void); //see later
|
||||
void I_FinishUpdate (void)
|
||||
{
|
||||
// draw captions if enabled
|
||||
if (cv_closedcaptioning.value)
|
||||
SCR_ClosedCaptions();
|
||||
|
||||
// draw FPS if enabled
|
||||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
|
|
@ -214,7 +214,7 @@ extern FILE *logstream;
|
|||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||
// Only set it higher, not lower, obviously.
|
||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||
#define MODVERSION 22
|
||||
#define MODVERSION 24
|
||||
|
||||
// =========================================================================
|
||||
|
||||
|
@ -222,7 +222,7 @@ extern FILE *logstream;
|
|||
// NOTE: it needs more than this to increase the number of players...
|
||||
|
||||
#define MAXPLAYERS 32
|
||||
#define MAXSKINS MAXPLAYERS
|
||||
#define MAXSKINS 32
|
||||
#define PLAYERSMASK (MAXPLAYERS-1)
|
||||
#define MAXPLAYERNAME 21
|
||||
|
||||
|
@ -543,4 +543,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
|
||||
//#define PAPER_COLLISIONCORRECTION
|
||||
|
||||
/// Hudname padding.
|
||||
#define SKINNAMEPADDING
|
||||
|
||||
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
|
||||
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
|
||||
//#define SECTORSPECIALSAFTERTHINK
|
||||
|
||||
#endif // __DOOMDEF__
|
||||
|
|
|
@ -242,6 +242,8 @@ typedef struct
|
|||
UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below
|
||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
|
||||
|
||||
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
|
||||
|
||||
// Freed animals stuff.
|
||||
UINT8 numFlickies; ///< Internal. For freed flicky support.
|
||||
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
|
||||
|
@ -268,6 +270,7 @@ typedef struct
|
|||
#define LF2_RECORDATTACK 4 ///< Show this map in Time Attack
|
||||
#define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu
|
||||
#define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level
|
||||
#define LF2_WIDEICON 32 ///< If you're in a circumstance where it fits, use a wide map icon
|
||||
|
||||
extern mapheader_t* mapheaderinfo[NUMMAPS];
|
||||
|
||||
|
@ -312,7 +315,7 @@ enum GameType
|
|||
|
||||
NUMGAMETYPES
|
||||
};
|
||||
// If you alter this list, update gametype_cons_t in m_menu.c
|
||||
// If you alter this list, update dehacked.c, and gametype_cons_t and MISC_ChangeGameTypeMenu in m_menu.c
|
||||
|
||||
extern tic_t totalplaytime;
|
||||
|
||||
|
@ -377,6 +380,7 @@ nightsdata_t ntemprecords;
|
|||
|
||||
extern UINT32 token; ///< Number of tokens collected in a level
|
||||
extern UINT32 tokenlist; ///< List of tokens collected
|
||||
extern boolean gottoken; ///< Did you get a token? Used for end of act
|
||||
extern INT32 tokenbits; ///< Used for setting token bits
|
||||
extern INT32 sstimer; ///< Time allotted in the special stage
|
||||
extern UINT32 bluescore; ///< Blue Team Scores
|
||||
|
@ -450,19 +454,17 @@ extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
|
|||
|
||||
#if defined (macintosh)
|
||||
#define DEBFILE(msg) I_OutputMsg(msg)
|
||||
extern FILE *debugfile;
|
||||
#else
|
||||
#define DEBUGFILE
|
||||
#ifdef DEBUGFILE
|
||||
#define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } }
|
||||
extern FILE *debugfile;
|
||||
#else
|
||||
#define DEBFILE(msg) {}
|
||||
extern FILE *debugfile;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
extern FILE *debugfile;
|
||||
extern INT32 debugload;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -434,7 +434,6 @@ void F_StartIntro(void)
|
|||
|
||||
G_SetGamestate(GS_INTRO);
|
||||
gameaction = ga_nothing;
|
||||
playerdeadview = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
@ -1125,7 +1124,6 @@ void F_StartCredits(void)
|
|||
}
|
||||
|
||||
gameaction = ga_nothing;
|
||||
playerdeadview = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
@ -1272,7 +1270,6 @@ void F_StartGameEvaluation(void)
|
|||
G_SaveGame((UINT32)cursaveslot);
|
||||
|
||||
gameaction = ga_nothing;
|
||||
playerdeadview = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
@ -1383,7 +1380,6 @@ void F_StartGameEnd(void)
|
|||
G_SetGamestate(GS_GAMEEND);
|
||||
|
||||
gameaction = ga_nothing;
|
||||
playerdeadview = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
@ -1586,7 +1582,6 @@ void F_StartContinue(void)
|
|||
gameaction = ga_nothing;
|
||||
|
||||
keypressed = false;
|
||||
playerdeadview = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
@ -1728,7 +1723,7 @@ static void F_AdvanceToNextScene(void)
|
|||
|
||||
void F_EndCutScene(void)
|
||||
{
|
||||
cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
|
||||
cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later
|
||||
if (runningprecutscene)
|
||||
{
|
||||
if (server)
|
||||
|
@ -1743,7 +1738,7 @@ void F_EndCutScene(void)
|
|||
else if (nextmap < 1100-1)
|
||||
G_NextLevel();
|
||||
else
|
||||
Y_EndGame();
|
||||
G_EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1755,7 +1750,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
G_SetGamestate(GS_CUTSCENE);
|
||||
|
||||
gameaction = ga_nothing;
|
||||
playerdeadview = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ INT32 lastwipetic = 0;
|
|||
static UINT8 *wipe_scr_start; //screen 3
|
||||
static UINT8 *wipe_scr_end; //screen 4
|
||||
static UINT8 *wipe_scr; //screen 0 (main drawing)
|
||||
static fixed_t paldiv;
|
||||
static fixed_t paldiv = 0;
|
||||
|
||||
/** Create fademask_t from lump
|
||||
*
|
||||
|
@ -145,7 +145,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
|||
while (lsize--)
|
||||
{
|
||||
// Determine pixel to use from fademask
|
||||
pcolor = &pLocalPalette[*lump++];
|
||||
pcolor = &pMasterPalette[*lump++];
|
||||
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
UINT8 wipeframe = 0;
|
||||
fademask_t *fmask;
|
||||
|
||||
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
|
||||
if (!paldiv)
|
||||
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
|
||||
|
||||
// Init the wipe
|
||||
WipeInAction = true;
|
||||
|
|
169
src/g_game.c
169
src/g_game.c
|
@ -156,6 +156,7 @@ UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
|
|||
UINT16 emeralds;
|
||||
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
|
||||
INT32 tokenbits; // Used for setting token bits
|
||||
|
||||
// Old Special Stage
|
||||
|
@ -697,8 +698,7 @@ void G_SetNightsRecords(void)
|
|||
free(gpath);
|
||||
|
||||
// If the mare count changed, this will update the score display
|
||||
CV_AddValue(&cv_nextmap, 1);
|
||||
CV_AddValue(&cv_nextmap, -1);
|
||||
Nextmap_OnChange();
|
||||
}
|
||||
|
||||
// for consistency among messages: this modifies the game and removes savemoddata.
|
||||
|
@ -1012,14 +1012,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
if (turnleft)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
|
||||
}
|
||||
if (cv_analog.value || twodlevel
|
||||
if (twodlevel
|
||||
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|
||||
|| (!demoplayback && (player->climbing
|
||||
|| (player->pflags & PF_NIGHTSMODE)
|
||||
|| (player->pflags & PF_SLIDING)
|
||||
|| (player->pflags & PF_FORCESTRAFE)))) // Analog
|
||||
|| (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
|| (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))))) // Analog
|
||||
forcestrafe = true;
|
||||
if (forcestrafe) // Analog
|
||||
if (forcestrafe)
|
||||
{
|
||||
if (turnright)
|
||||
side += sidemove[speed];
|
||||
|
@ -1032,6 +1031,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
side += ((axis * sidemove[1]) >> 10);
|
||||
}
|
||||
}
|
||||
else if (cv_analog.value) // Analog
|
||||
{
|
||||
if (turnright)
|
||||
cmd->buttons |= BT_CAMRIGHT;
|
||||
if (turnleft)
|
||||
cmd->buttons |= BT_CAMLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (turnright)
|
||||
|
@ -1119,15 +1125,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
if (PLAYER1INPUTDOWN(gc_use))
|
||||
cmd->buttons |= BT_USE;
|
||||
|
||||
// Camera Controls
|
||||
if (cv_debug || cv_analog.value || demoplayback || objectplacing || player->pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
if (PLAYER1INPUTDOWN(gc_camleft))
|
||||
cmd->buttons |= BT_CAMLEFT;
|
||||
if (PLAYER1INPUTDOWN(gc_camright))
|
||||
cmd->buttons |= BT_CAMRIGHT;
|
||||
}
|
||||
|
||||
if (PLAYER1INPUTDOWN(gc_camreset))
|
||||
{
|
||||
if (camera.chase && !resetdown)
|
||||
|
@ -1189,10 +1186,19 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
if (!mouseaiming && cv_mousemove.value)
|
||||
forward += mousey;
|
||||
|
||||
if (cv_analog.value ||
|
||||
(!demoplayback && (player->climbing
|
||||
if ((!demoplayback && (player->climbing
|
||||
|| (player->pflags & PF_SLIDING)))) // Analog for mouse
|
||||
side += mousex*2;
|
||||
else if (cv_analog.value)
|
||||
{
|
||||
if (mousex)
|
||||
{
|
||||
if (mousex > 0)
|
||||
cmd->buttons |= BT_CAMRIGHT;
|
||||
else
|
||||
cmd->buttons |= BT_CAMLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - (mousex*8));
|
||||
|
||||
|
@ -1227,9 +1233,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
cmd->sidemove = (SINT8)(cmd->sidemove + side);
|
||||
|
||||
if (cv_analog.value) {
|
||||
cmd->angleturn = (INT16)(thiscam->angle >> 16);
|
||||
if (player->awayviewtics)
|
||||
cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16);
|
||||
else
|
||||
cmd->angleturn = (INT16)(thiscam->angle >> 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1303,12 +1310,11 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
if (turnleft)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
|
||||
}
|
||||
if (cv_analog2.value || twodlevel
|
||||
if (twodlevel
|
||||
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|
||||
|| player->climbing
|
||||
|| (player->pflags & PF_NIGHTSMODE)
|
||||
|| (player->pflags & PF_SLIDING)
|
||||
|| (player->pflags & PF_FORCESTRAFE)) // Analog
|
||||
|| (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
|| (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))) // Analog
|
||||
forcestrafe = true;
|
||||
if (forcestrafe) // Analog
|
||||
{
|
||||
|
@ -1323,6 +1329,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
side += ((axis * sidemove[1]) >> 10);
|
||||
}
|
||||
}
|
||||
else if (cv_analog2.value) // Analog
|
||||
{
|
||||
if (turnright)
|
||||
cmd->buttons |= BT_CAMRIGHT;
|
||||
if (turnleft)
|
||||
cmd->buttons |= BT_CAMLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (turnright)
|
||||
|
@ -1407,15 +1420,6 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
if (PLAYER2INPUTDOWN(gc_use))
|
||||
cmd->buttons |= BT_USE;
|
||||
|
||||
// Camera Controls
|
||||
if (cv_debug || cv_analog2.value || player->pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
if (PLAYER2INPUTDOWN(gc_camleft))
|
||||
cmd->buttons |= BT_CAMLEFT;
|
||||
if (PLAYER2INPUTDOWN(gc_camright))
|
||||
cmd->buttons |= BT_CAMRIGHT;
|
||||
}
|
||||
|
||||
if (PLAYER2INPUTDOWN(gc_camreset))
|
||||
{
|
||||
if (camera2.chase && !resetdown)
|
||||
|
@ -1477,9 +1481,19 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
if (!mouseaiming && cv_mousemove2.value)
|
||||
forward += mouse2y;
|
||||
|
||||
if (cv_analog2.value || player->climbing
|
||||
if (player->climbing
|
||||
|| (player->pflags & PF_SLIDING)) // Analog for mouse
|
||||
side += mouse2x*2;
|
||||
else if (cv_analog2.value)
|
||||
{
|
||||
if (mouse2x)
|
||||
{
|
||||
if (mouse2x > 0)
|
||||
cmd->buttons |= BT_CAMRIGHT;
|
||||
else
|
||||
cmd->buttons |= BT_CAMLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - (mouse2x*8));
|
||||
|
||||
|
@ -1527,9 +1541,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
}
|
||||
|
||||
if (cv_analog2.value) {
|
||||
cmd->angleturn = (INT16)(thiscam->angle >> 16);
|
||||
if (player->awayviewtics)
|
||||
cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16);
|
||||
else
|
||||
cmd->angleturn = (INT16)(thiscam->angle >> 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1566,11 +1581,6 @@ static void Analog_OnChange(void)
|
|||
|
||||
// cameras are not initialized at this point
|
||||
|
||||
if (leveltime > 1)
|
||||
CV_SetValue(&cv_cam_dist, 128);
|
||||
if (cv_analog.value || demoplayback)
|
||||
CV_SetValue(&cv_cam_dist, 192);
|
||||
|
||||
if (!cv_chasecam.value && cv_analog.value) {
|
||||
CV_SetValue(&cv_analog, 0);
|
||||
return;
|
||||
|
@ -1591,11 +1601,6 @@ static void Analog2_OnChange(void)
|
|||
|
||||
// cameras are not initialized at this point
|
||||
|
||||
if (leveltime > 1)
|
||||
CV_SetValue(&cv_cam2_dist, 128);
|
||||
if (cv_analog2.value)
|
||||
CV_SetValue(&cv_cam2_dist, 192);
|
||||
|
||||
if (!cv_chasecam2.value && cv_analog2.value) {
|
||||
CV_SetValue(&cv_analog2, 0);
|
||||
return;
|
||||
|
@ -2082,6 +2087,7 @@ void G_PlayerReborn(INT32 player)
|
|||
UINT8 mare;
|
||||
UINT8 skincolor;
|
||||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
tic_t jointime;
|
||||
boolean spectator;
|
||||
INT16 bot;
|
||||
|
@ -2106,6 +2112,7 @@ void G_PlayerReborn(INT32 player)
|
|||
|
||||
skincolor = players[player].skincolor;
|
||||
skin = players[player].skin;
|
||||
availabilities = players[player].availabilities;
|
||||
camerascale = players[player].camerascale;
|
||||
shieldscale = players[player].shieldscale;
|
||||
charability = players[player].charability;
|
||||
|
@ -2151,6 +2158,7 @@ void G_PlayerReborn(INT32 player)
|
|||
// save player config truth reborn
|
||||
p->skincolor = skincolor;
|
||||
p->skin = skin;
|
||||
p->availabilities = availabilities;
|
||||
p->camerascale = camerascale;
|
||||
p->shieldscale = shieldscale;
|
||||
p->charability = charability;
|
||||
|
@ -2301,6 +2309,9 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
|||
if (starpost) //Don't even bother with looking for a place to spawn.
|
||||
{
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2625,7 +2636,7 @@ void G_ExitLevel(void)
|
|||
CONS_Printf(M_GetText("The round has ended.\n"));
|
||||
|
||||
// Remove CEcho text on round end.
|
||||
HU_DoCEcho("");
|
||||
HU_ClearCEcho();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2773,7 +2784,6 @@ static INT16 RandMap(INT16 tolflags, INT16 pprevmap)
|
|||
static void G_DoCompleted(void)
|
||||
{
|
||||
INT32 i;
|
||||
boolean gottoken = false;
|
||||
|
||||
tokenlist = 0; // Reset the list
|
||||
|
||||
|
@ -2859,10 +2869,9 @@ static void G_DoCompleted(void)
|
|||
if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametype == GT_RACE || gametype == GT_COMPETITION))
|
||||
nextmap = (INT16)(spstage_start-1);
|
||||
|
||||
if (gametype == GT_COOP && token)
|
||||
if ((gottoken = (gametype == GT_COOP && token)))
|
||||
{
|
||||
token--;
|
||||
gottoken = true;
|
||||
|
||||
if (!(emeralds & EMERALD1))
|
||||
nextmap = (INT16)(sstage_start - 1); // Special Stage 1
|
||||
|
@ -2921,7 +2930,7 @@ void G_AfterIntermission(void)
|
|||
if (nextmap < 1100-1)
|
||||
G_NextLevel();
|
||||
else
|
||||
Y_EndGame();
|
||||
G_EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3007,6 +3016,38 @@ static void G_DoContinued(void)
|
|||
gameaction = ga_nothing;
|
||||
}
|
||||
|
||||
//
|
||||
// G_EndGame (formerly Y_EndGame)
|
||||
// Frankly this function fits better in g_game.c than it does in y_inter.c
|
||||
//
|
||||
// ...Gee, (why) end the game?
|
||||
// Because G_AfterIntermission and F_EndCutscene would
|
||||
// both do this exact same thing *in different ways* otherwise,
|
||||
// which made it so that you could only unlock Ultimate mode
|
||||
// if you had a cutscene after the final level and crap like that.
|
||||
// This function simplifies it so only one place has to be updated
|
||||
// when something new is added.
|
||||
void G_EndGame(void)
|
||||
{
|
||||
// Only do evaluation and credits in coop games.
|
||||
if (gametype == GT_COOP)
|
||||
{
|
||||
if (nextmap == 1102-1) // end game with credits
|
||||
{
|
||||
F_StartCredits();
|
||||
return;
|
||||
}
|
||||
if (nextmap == 1101-1) // end game with evaluation
|
||||
{
|
||||
F_StartGameEvaluation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 1100 or competitive multiplayer, so go back to title screen.
|
||||
D_StartTitle();
|
||||
}
|
||||
|
||||
//
|
||||
// G_LoadGameSettings
|
||||
//
|
||||
|
@ -3541,7 +3582,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
|
|||
// This is the map command interpretation something like Command_Map_f
|
||||
//
|
||||
// called at: map cmd execution, doloadgame, doplaydemo
|
||||
void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean skipprecutscene)
|
||||
void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean skipprecutscene, boolean FLS)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
|
@ -3571,7 +3612,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
|||
|
||||
if (netgame || multiplayer)
|
||||
{
|
||||
players[i].lives = cv_startinglives.value;
|
||||
if (!FLS || (players[i].lives < cv_startinglives.value))
|
||||
players[i].lives = cv_startinglives.value;
|
||||
players[i].continues = 0;
|
||||
}
|
||||
else if (pultmode)
|
||||
|
@ -3585,13 +3627,16 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
|||
players[i].continues = 1;
|
||||
}
|
||||
|
||||
if (!((netgame || multiplayer) && (FLS)))
|
||||
players[i].score = 0;
|
||||
|
||||
// The latter two should clear by themselves, but just in case
|
||||
players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS);
|
||||
|
||||
// Clear cheatcodes too, just in case.
|
||||
players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS);
|
||||
|
||||
players[i].score = players[i].xtralife = 0;
|
||||
players[i].xtralife = 0;
|
||||
}
|
||||
|
||||
// Reset unlockable triggers
|
||||
|
@ -3625,7 +3670,6 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
|||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
|
||||
ultimatemode = pultmode;
|
||||
playerdeadview = false;
|
||||
automapactive = false;
|
||||
imcontinuing = false;
|
||||
|
||||
|
@ -3653,6 +3697,9 @@ char *G_BuildMapTitle(INT32 mapnum)
|
|||
{
|
||||
char *title = NULL;
|
||||
|
||||
if (!mapheaderinfo[mapnum-1])
|
||||
P_AllocMapHeader(mapnum-1);
|
||||
|
||||
if (strcmp(mapheaderinfo[mapnum-1]->lvlttl, ""))
|
||||
{
|
||||
size_t len = 1;
|
||||
|
@ -3886,7 +3933,7 @@ void G_GhostAddColor(ghostcolor_t color)
|
|||
ghostext.color = (UINT8)color;
|
||||
}
|
||||
|
||||
void G_GhostAddScale(UINT16 scale)
|
||||
void G_GhostAddScale(fixed_t scale)
|
||||
{
|
||||
if (!demorecording || !(demoflags & DF_GHOST))
|
||||
return;
|
||||
|
@ -3920,12 +3967,8 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
if (!(demoflags & DF_GHOST))
|
||||
return; // No ghost data to write.
|
||||
|
||||
if (ghost->player && ghost->player->pflags & PF_NIGHTSMODE && ghost->tracer)
|
||||
{
|
||||
// We're talking about the NiGHTS thing, not the normal platforming thing!
|
||||
if (ghost->player && ghost->player->powers[pw_carry] == CR_NIGHTSMODE) // We're talking about the NiGHTS thing, not the normal platforming thing!
|
||||
ziptic |= GZT_NIGHTS;
|
||||
ghost = ghost->tracer;
|
||||
}
|
||||
|
||||
ziptic_p = demo_p++; // the ziptic, written at the end of this function
|
||||
|
||||
|
@ -4107,11 +4150,9 @@ void G_ConsGhostTic(void)
|
|||
demo_p++;
|
||||
if (ziptic & GZT_SPR2)
|
||||
demo_p++;
|
||||
if(ziptic & GZT_NIGHTS) {
|
||||
if (!testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer)
|
||||
if (ziptic & GZT_NIGHTS) {
|
||||
if (!testmo->player || !(testmo->player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
nightsfail = true;
|
||||
else
|
||||
testmo = testmo->tracer;
|
||||
}
|
||||
|
||||
if (ziptic & GZT_EXTRA)
|
||||
|
@ -5142,7 +5183,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
memset(playeringame,0,sizeof(playeringame));
|
||||
playeringame[0] = true;
|
||||
P_SetRandSeed(randseed);
|
||||
G_InitNew(false, G_BuildMapName(gamemap), true, true);
|
||||
G_InitNew(false, G_BuildMapName(gamemap), true, true, false);
|
||||
|
||||
// Set skin
|
||||
SetPlayerSkin(0, skin);
|
||||
|
|
|
@ -56,6 +56,9 @@ extern INT16 rw_maximums[NUM_WEAPONS];
|
|||
// used in game menu
|
||||
extern consvar_t cv_crosshair, cv_crosshair2;
|
||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
|
||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
|
||||
extern consvar_t cv_useranalog, cv_useranalog2;
|
||||
extern consvar_t cv_analog, cv_analog2;
|
||||
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis;
|
||||
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2;
|
||||
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
|
||||
|
@ -89,7 +92,7 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo);
|
|||
void G_DoReborn(INT32 playernum);
|
||||
void G_PlayerReborn(INT32 player);
|
||||
void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer,
|
||||
boolean skipprecutscene);
|
||||
boolean skipprecutscene, boolean FLS);
|
||||
char *G_BuildMapTitle(INT32 mapnum);
|
||||
|
||||
// XMOD spawning
|
||||
|
@ -139,7 +142,7 @@ void G_GhostAddSpin(void);
|
|||
void G_GhostAddRev(void);
|
||||
void G_GhostAddColor(ghostcolor_t color);
|
||||
void G_GhostAddFlip(void);
|
||||
void G_GhostAddScale(UINT16 scale);
|
||||
void G_GhostAddScale(fixed_t scale);
|
||||
void G_GhostAddHit(mobj_t *victim);
|
||||
void G_WriteGhostTic(mobj_t *ghost);
|
||||
void G_ConsGhostTic(void);
|
||||
|
@ -171,6 +174,7 @@ void G_NextLevel(void);
|
|||
void G_Continue(void);
|
||||
void G_UseContinue(void);
|
||||
void G_AfterIntermission(void);
|
||||
void G_EndGame(void); // moved from y_inter.c/h and renamed
|
||||
|
||||
void G_Ticker(boolean run);
|
||||
boolean G_Responder(event_t *ev);
|
||||
|
|
|
@ -25,10 +25,10 @@ static CV_PossibleValue_t mousesens_cons_t[] = {{1, "MIN"}, {MAXMOUSESENSITIVITY
|
|||
static CV_PossibleValue_t onecontrolperkey_cons_t[] = {{1, "One"}, {2, "Several"}, {0, NULL}};
|
||||
|
||||
// mouse values are used once
|
||||
consvar_t cv_mousesens = {"mousesens", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousesens2 = {"mousesens2", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens = {"mouseysens", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens2 = {"mouseysens2", "35", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousesens = {"mousesens", "12", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mousesens2 = {"mousesens2", "12", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens = {"mouseysens", "12", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mouseysens2 = {"mouseysens2", "12", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT32 mousex, mousey;
|
||||
|
@ -977,8 +977,6 @@ static const char *gamecontrolname[num_gamecontrols] =
|
|||
"tossflag",
|
||||
"use",
|
||||
"camtoggle",
|
||||
"camleft",
|
||||
"camright",
|
||||
"camreset",
|
||||
"lookup",
|
||||
"lookdown",
|
||||
|
@ -1074,8 +1072,6 @@ void G_Controldefault(void)
|
|||
gamecontrol[gc_use ][0] = KEY_JOY1+1; //B
|
||||
gamecontrol[gc_use ][1] = '.';
|
||||
gamecontrol[gc_camtoggle ][1] = ',';
|
||||
gamecontrol[gc_camleft ][0] = 'o';
|
||||
gamecontrol[gc_camright ][0] = 'p';
|
||||
gamecontrol[gc_camreset ][0] = 'c';
|
||||
gamecontrol[gc_lookup ][0] = KEY_PGUP;
|
||||
gamecontrol[gc_lookdown ][0] = KEY_PGDN;
|
||||
|
@ -1154,10 +1150,8 @@ void G_Controldefault(void)
|
|||
#else
|
||||
void G_Controldefault(void)
|
||||
{
|
||||
gamecontrol[gc_forward ][0] = KEY_UPARROW;
|
||||
gamecontrol[gc_forward ][1] = 'w';
|
||||
gamecontrol[gc_backward ][0] = KEY_DOWNARROW;
|
||||
gamecontrol[gc_backward ][1] = 's';
|
||||
gamecontrol[gc_forward ][0] = 'w';
|
||||
gamecontrol[gc_backward ][0] = 's';
|
||||
gamecontrol[gc_strafeleft ][0] = 'a';
|
||||
gamecontrol[gc_straferight][0] = 'd';
|
||||
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW;
|
||||
|
@ -1178,19 +1172,16 @@ void G_Controldefault(void)
|
|||
gamecontrol[gc_fire ][1] = KEY_MOUSE1+0;
|
||||
gamecontrol[gc_firenormal ][0] = 'c';
|
||||
gamecontrol[gc_tossflag ][0] = '\'';
|
||||
gamecontrol[gc_use ][0] = 'x';
|
||||
gamecontrol[gc_use ][0] = KEY_LSHIFT;
|
||||
gamecontrol[gc_camtoggle ][0] = 'v';
|
||||
gamecontrol[gc_camleft ][0] = '[';
|
||||
gamecontrol[gc_camright ][0] = ']';
|
||||
gamecontrol[gc_camreset ][0] = 'r';
|
||||
gamecontrol[gc_lookup ][0] = KEY_PGUP;
|
||||
gamecontrol[gc_lookdown ][0] = KEY_PGDN;
|
||||
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
|
||||
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;
|
||||
gamecontrol[gc_centerview ][0] = KEY_END;
|
||||
gamecontrol[gc_talkkey ][0] = 't';
|
||||
gamecontrol[gc_teamkey ][0] = 'y';
|
||||
gamecontrol[gc_scores ][0] = KEY_TAB;
|
||||
gamecontrol[gc_jump ][0] = 'z';
|
||||
gamecontrol[gc_jump ][1] = KEY_MOUSE1+1;
|
||||
gamecontrol[gc_jump ][0] = KEY_SPACE;
|
||||
gamecontrol[gc_console ][0] = KEY_CONSOLE;
|
||||
gamecontrol[gc_pause ][0] = KEY_PAUSE;
|
||||
#ifdef WMINPUT
|
||||
|
|
|
@ -105,8 +105,6 @@ typedef enum
|
|||
gc_tossflag,
|
||||
gc_use,
|
||||
gc_camtoggle,
|
||||
gc_camleft,
|
||||
gc_camright,
|
||||
gc_camreset,
|
||||
gc_lookup,
|
||||
gc_lookdown,
|
||||
|
@ -126,6 +124,8 @@ typedef enum
|
|||
|
||||
// mouse values are used once
|
||||
extern consvar_t cv_mousesens, cv_mouseysens;
|
||||
extern consvar_t cv_mousesens2, cv_mouseysens2;
|
||||
extern consvar_t cv_controlperkey;
|
||||
|
||||
extern INT32 mousex, mousey;
|
||||
extern INT32 mlooky; //mousey with mlookSensitivity
|
||||
|
|
|
@ -564,8 +564,6 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
|
|||
subsector_t *sub;
|
||||
seg_t *lseg;
|
||||
|
||||
sscount++;
|
||||
|
||||
sub = &subsectors[num];
|
||||
count = sub->numlines;
|
||||
lseg = &segs[sub->firstline];
|
||||
|
|
|
@ -152,7 +152,9 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
|
||||
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
|
||||
|
||||
if (alphalevel >= 10 && alphalevel < 13)
|
||||
if (alphalevel == 12)
|
||||
alphalevel = 0;
|
||||
else if (alphalevel >= 10 && alphalevel < 13)
|
||||
return;
|
||||
|
||||
// make patch ready in hardware cache
|
||||
|
@ -252,7 +254,9 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
|
||||
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
|
||||
|
||||
if (alphalevel >= 10 && alphalevel < 13)
|
||||
if (alphalevel == 12)
|
||||
alphalevel = 0;
|
||||
else if (alphalevel >= 10 && alphalevel < 13)
|
||||
return;
|
||||
|
||||
// make patch ready in hardware cache
|
||||
|
@ -785,7 +789,7 @@ boolean HWR_Screenshot(const char *lbmname)
|
|||
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
||||
|
||||
#ifdef USE_PNG
|
||||
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL);
|
||||
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, false);
|
||||
#else
|
||||
ret = saveTGA(lbmname, buf, vid.width, vid.height);
|
||||
#endif
|
||||
|
|
|
@ -78,6 +78,7 @@ typedef struct gr_vissprite_s
|
|||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
UINT8 *colormap;
|
||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
float z1, z2;
|
||||
} gr_vissprite_t;
|
||||
|
||||
// --------
|
||||
|
|
|
@ -226,8 +226,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
// Collectible Items
|
||||
&lspr[NOLIGHT], // SPR_RING
|
||||
&lspr[NOLIGHT], // SPR_TRNG
|
||||
&lspr[NOLIGHT], // SPR_EMMY
|
||||
&lspr[BLUEBALL_L], // SPR_TOKE
|
||||
&lspr[NOLIGHT], // SPR_TOKE
|
||||
&lspr[REDBALL_L], // SPR_RFLG
|
||||
&lspr[BLUEBALL_L], // SPR_BFLG
|
||||
&lspr[NOLIGHT], // SPR_NWNG
|
||||
|
@ -243,6 +242,8 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SPIK
|
||||
&lspr[NOLIGHT], // SPR_SFLM
|
||||
&lspr[NOLIGHT], // SPR_USPK
|
||||
&lspr[NOLIGHT], // SPR_WSPK
|
||||
&lspr[NOLIGHT], // SPR_WSPB
|
||||
&lspr[NOLIGHT], // SPR_STPT
|
||||
&lspr[NOLIGHT], // SPR_BMNE
|
||||
|
||||
|
@ -293,6 +294,12 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_FWR4
|
||||
&lspr[NOLIGHT], // SPR_BUS1
|
||||
&lspr[NOLIGHT], // SPR_BUS2
|
||||
// Trees (both GFZ and misc)
|
||||
&lspr[NOLIGHT], // SPR_TRE1
|
||||
&lspr[NOLIGHT], // SPR_TRE2
|
||||
&lspr[NOLIGHT], // SPR_TRE3
|
||||
&lspr[NOLIGHT], // SPR_TRE4
|
||||
&lspr[NOLIGHT], // SPR_TRE5
|
||||
|
||||
// Techno Hill Scenery
|
||||
&lspr[NOLIGHT], // SPR_THZP
|
||||
|
@ -334,6 +341,8 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_XMS1
|
||||
&lspr[NOLIGHT], // SPR_XMS2
|
||||
&lspr[NOLIGHT], // SPR_XMS3
|
||||
&lspr[NOLIGHT], // SPR_XMS4
|
||||
&lspr[NOLIGHT], // SPR_XMS5
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
&lspr[NOLIGHT], // SPR_BSZ1
|
||||
|
@ -345,13 +354,9 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_BSZ7
|
||||
&lspr[NOLIGHT], // SPR_BSZ8
|
||||
|
||||
// Stalagmites
|
||||
// Misc Scenery
|
||||
&lspr[NOLIGHT], // SPR_STLG
|
||||
|
||||
// Disco Ball
|
||||
&lspr[NOLIGHT], // SPR_DBAL
|
||||
|
||||
// ATZ Red Crystal
|
||||
&lspr[NOLIGHT], // SPR_RCRY
|
||||
|
||||
// Powerup Indicators
|
||||
|
@ -396,15 +401,20 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SPRB Graue
|
||||
&lspr[NOLIGHT], // SPR_YSPR
|
||||
&lspr[NOLIGHT], // SPR_RSPR
|
||||
&lspr[NOLIGHT], // SPR_SSWY
|
||||
&lspr[NOLIGHT], // SPR_SSWR
|
||||
&lspr[NOLIGHT], // SPR_SSWB
|
||||
|
||||
// Environmentals Effects
|
||||
// Environmental Effects
|
||||
&lspr[NOLIGHT], // SPR_RAIN
|
||||
&lspr[NOLIGHT], // SPR_SNO1
|
||||
&lspr[NOLIGHT], // SPR_SPLH
|
||||
&lspr[NOLIGHT], // SPR_SPLA
|
||||
&lspr[NOLIGHT], // SPR_SMOK
|
||||
&lspr[NOLIGHT], // SPR_BUBL
|
||||
&lspr[SUPERSPARK_L], // SPR_WZAP
|
||||
&lspr[RINGLIGHT_L], // SPR_WZAP
|
||||
&lspr[NOLIGHT], // SPR_DUST
|
||||
&lspr[NOLIGHT], // SPR_FPRT
|
||||
&lspr[SUPERSPARK_L], // SPR_TFOG
|
||||
&lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed
|
||||
&lspr[NOLIGHT], // SPR_PRTL
|
||||
|
@ -412,9 +422,12 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
// Game Indicators
|
||||
&lspr[NOLIGHT], // SPR_SCOR
|
||||
&lspr[NOLIGHT], // SPR_DRWN
|
||||
&lspr[NOLIGHT], // SPR_LCKN
|
||||
&lspr[NOLIGHT], // SPR_TTAG
|
||||
&lspr[NOLIGHT], // SPR_GFLG
|
||||
|
||||
&lspr[NOLIGHT], // SPR_CORK
|
||||
|
||||
// Ring Weapons
|
||||
&lspr[RINGLIGHT_L], // SPR_RRNG
|
||||
&lspr[RINGLIGHT_L], // SPR_RNGB
|
||||
|
|
|
@ -1084,9 +1084,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
|||
float endheight = 0.0f, endbheight = 0.0f;
|
||||
|
||||
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].y);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
|
||||
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].y);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
|
||||
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
||||
// use this as a temp var to store P_GetZAt's return value each time
|
||||
fixed_t temp;
|
||||
|
@ -3367,7 +3367,6 @@ static void HWR_Subsector(size_t num)
|
|||
|
||||
if (num < numsubsectors)
|
||||
{
|
||||
sscount++;
|
||||
// subsector
|
||||
sub = &subsectors[num];
|
||||
// sector
|
||||
|
@ -3722,6 +3721,9 @@ static void HWR_Subsector(size_t num)
|
|||
|
||||
while (count--)
|
||||
{
|
||||
#ifdef POLYOBJECTS
|
||||
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||
#endif
|
||||
HWR_AddLine(line);
|
||||
line++;
|
||||
}
|
||||
|
@ -4227,6 +4229,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
GLPatch_t *gpatch; // sprite patch converted to hardware
|
||||
FSurfaceInfo Surf;
|
||||
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
||||
//const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE));
|
||||
if (spr->mobj)
|
||||
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
||||
if (hires)
|
||||
|
@ -4270,7 +4273,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
|
||||
// make a wall polygon (with 2 triangles), using the floor/ceiling heights,
|
||||
// and the 2d map coords of start/end vertices
|
||||
wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz;
|
||||
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||
wallVerts[2].z = wallVerts[1].z = spr->z2;
|
||||
|
||||
// transform
|
||||
wv = wallVerts;
|
||||
|
@ -5066,6 +5070,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
angle_t ang;
|
||||
INT32 heightsec, phs;
|
||||
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||
float offset;
|
||||
float ang_scale = 1.0f, ang_scalez = 0.0f;
|
||||
float z1, z2;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
@ -5080,7 +5088,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
||||
// thing is behind view plane?
|
||||
if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
return;
|
||||
|
||||
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
|
||||
|
@ -5118,6 +5126,27 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||
#endif
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
// Use the actual view angle, rather than the angle formed
|
||||
// between the view point and the thing
|
||||
// this makes sure paper sprites always appear at the right angle!
|
||||
// Note: DO NOT do this in software mode version, it actually
|
||||
// makes papersprites look WORSE there (I know, I've tried)
|
||||
// Monster Iestyn - 13/05/17
|
||||
ang = dup_viewangle - thing->angle;
|
||||
ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
if (ang_scale < 0)
|
||||
{
|
||||
ang_scale = -ang_scale;
|
||||
ang_scalez = -ang_scalez;
|
||||
}
|
||||
}
|
||||
else if (sprframe->rotate != SRF_SINGLE)
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
|
||||
if (sprframe->rotate == SRF_SINGLE)
|
||||
{
|
||||
// use single rotation for all views
|
||||
|
@ -5128,8 +5157,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// choose a different rotation based on player view
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
|
@ -5147,9 +5174,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
// calculate edges of the shape
|
||||
if (flip)
|
||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
else
|
||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
||||
|
||||
z1 = tz - (offset * ang_scalez);
|
||||
tx -= offset * ang_scale;
|
||||
|
||||
// project x
|
||||
x1 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||
|
@ -5160,7 +5190,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
x1 = tx;
|
||||
|
||||
tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
||||
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
||||
|
||||
z2 = z1 + (offset * ang_scalez);
|
||||
tx += offset * ang_scale;
|
||||
|
||||
if (papersprite && max(z1, z2) < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
x2 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||
|
||||
if (vflip)
|
||||
|
@ -5209,6 +5246,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
vis->flip = flip;
|
||||
vis->mobj = thing;
|
||||
vis->z1 = z1;
|
||||
vis->z2 = z2;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
|
|
|
@ -244,6 +244,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
|||
#define pglMaterialfv glMaterialfv
|
||||
|
||||
/* Raster functions */
|
||||
#define pglPixelStorei glPixelStorei
|
||||
#define pglReadPixels glReadPixels
|
||||
|
||||
/* Texture mapping */
|
||||
|
@ -262,15 +263,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
|||
/* texture mapping */ //GL_EXT_copy_texture
|
||||
#ifndef KOS_GL_COMPATIBILITY
|
||||
#define pglCopyTexImage2D glCopyTexImage2D
|
||||
#endif
|
||||
|
||||
/* GLU functions */
|
||||
#define pgluBuild2DMipmaps gluBuild2DMipmaps
|
||||
#endif
|
||||
#ifndef MINI_GL_COMPATIBILITY
|
||||
/* 1.3 functions for multitexturing */
|
||||
#define pglActiveTexture glActiveTexture
|
||||
#define pglMultiTexCoord2f glMultiTexCoord2f
|
||||
#endif
|
||||
#else //!STATIC_OPENGL
|
||||
|
||||
/* 1.0 functions */
|
||||
|
@ -365,6 +359,8 @@ typedef void (APIENTRY * PFNglMaterialfv) (GLint face, GLenum pname, GLfloat *pa
|
|||
static PFNglMaterialfv pglMaterialfv;
|
||||
|
||||
/* Raster functions */
|
||||
typedef void (APIENTRY * PFNglPixelStorei) (GLenum pname, GLint param);
|
||||
static PFNglPixelStorei pglPixelStorei;
|
||||
typedef void (APIENTRY * PFNglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||
static PFNglReadPixels pglReadPixels;
|
||||
|
||||
|
@ -391,7 +387,7 @@ static PFNglBindTexture pglBindTexture;
|
|||
/* texture mapping */ //GL_EXT_copy_texture
|
||||
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
static PFNglCopyTexImage2D pglCopyTexImage2D;
|
||||
|
||||
#endif
|
||||
/* GLU functions */
|
||||
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
|
||||
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
|
||||
|
@ -403,7 +399,6 @@ static PFNglActiveTexture pglActiveTexture;
|
|||
typedef void (APIENTRY *PFNglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
|
||||
static PFNglMultiTexCoord2f pglMultiTexCoord2f;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MINI_GL_COMPATIBILITY
|
||||
/* 1.2 Parms */
|
||||
|
@ -494,6 +489,7 @@ boolean SetupGLfunc(void)
|
|||
GETOPENGLFUNC(pglLightModelfv , glLightModelfv)
|
||||
GETOPENGLFUNC(pglMaterialfv , glMaterialfv)
|
||||
|
||||
GETOPENGLFUNC(pglPixelStorei , glPixelStorei)
|
||||
GETOPENGLFUNC(pglReadPixels , glReadPixels)
|
||||
|
||||
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
|
||||
|
@ -519,35 +515,23 @@ boolean SetupGLfunc(void)
|
|||
// This has to be done after the context is created so the version number can be obtained
|
||||
boolean SetupGLFunc13(void)
|
||||
{
|
||||
#ifdef MINI_GL_COMPATIBILITY
|
||||
return false;
|
||||
#else
|
||||
const GLubyte *version = pglGetString(GL_VERSION);
|
||||
int glmajor, glminor;
|
||||
|
||||
gl13 = false;
|
||||
#ifdef MINI_GL_COMPATIBILITY
|
||||
return false;
|
||||
#else
|
||||
#ifdef STATIC_OPENGL
|
||||
gl13 = true;
|
||||
#else
|
||||
|
||||
// Parse the GL version
|
||||
if (version != NULL)
|
||||
{
|
||||
if (sscanf((const char*)version, "%d.%d", &glmajor, &glminor) == 2)
|
||||
{
|
||||
// Look, we gotta prepare for the inevitable arrival of GL 2.0 code...
|
||||
switch (glmajor)
|
||||
{
|
||||
case 1:
|
||||
if (glminor == 3) gl13 = true;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
gl13 = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (glmajor == 1 && glminor >= 3)
|
||||
gl13 = true;
|
||||
else if (glmajor > 1)
|
||||
gl13 = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,9 +552,6 @@ boolean SetupGLFunc13(void)
|
|||
}
|
||||
else
|
||||
DBG_Printf("GL_ARB_multitexture support: disabled\n");
|
||||
#undef GETOPENGLFUNC
|
||||
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -897,7 +878,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
|||
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1);
|
||||
GLubyte *row = malloc(dst_stride);
|
||||
if (!row) return;
|
||||
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
|
||||
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
for(i = 0; i < height/2; i++)
|
||||
{
|
||||
memcpy(row, top, dst_stride);
|
||||
|
@ -913,7 +896,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
|||
INT32 j;
|
||||
GLubyte *image = malloc(width*height*3*sizeof (*image));
|
||||
if (!image) return;
|
||||
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
for (i = height-1; i >= 0; i--)
|
||||
{
|
||||
for (j = 0; j < width; j++)
|
||||
|
@ -1815,13 +1800,11 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
|||
min_filter = GL_NEAREST;
|
||||
#endif
|
||||
}
|
||||
#ifndef STATIC_OPENGL
|
||||
if (!pgluBuild2DMipmaps)
|
||||
{
|
||||
MipMap = GL_FALSE;
|
||||
min_filter = GL_LINEAR;
|
||||
}
|
||||
#endif
|
||||
Flush(); //??? if we want to change filter mode by texture, remove this
|
||||
break;
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ patch_t *tallminus;
|
|||
patch_t *emeraldpics[7];
|
||||
patch_t *tinyemeraldpics[7];
|
||||
static patch_t *emblemicon;
|
||||
static patch_t *tokenicon;
|
||||
patch_t *tokenicon;
|
||||
|
||||
//-------------------------------------------
|
||||
// misc vars
|
||||
|
@ -840,7 +840,7 @@ static void HU_DrawChat(void)
|
|||
else
|
||||
{
|
||||
//charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
}
|
||||
c += charwidth;
|
||||
}
|
||||
|
@ -857,7 +857,7 @@ static void HU_DrawChat(void)
|
|||
else
|
||||
{
|
||||
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true);
|
||||
}
|
||||
|
||||
c += charwidth;
|
||||
|
@ -869,7 +869,7 @@ static void HU_DrawChat(void)
|
|||
}
|
||||
|
||||
if (hu_tick < 4)
|
||||
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value);
|
||||
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1226,9 +1226,9 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
}
|
||||
else
|
||||
{
|
||||
if (players[tab[i].num].powers[pw_super])
|
||||
if (players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS] || players[tab[i].num].mo->state > &states[S_PLAY_SUPER_TRANS9]))
|
||||
{
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
//------------------------------------
|
||||
// heads up font
|
||||
//------------------------------------
|
||||
#define HU_FONTSTART '\x1F' // the first font character
|
||||
#define HU_FONTSTART '\x19' // the first font character
|
||||
#define HU_FONTEND '~'
|
||||
|
||||
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
|
||||
|
@ -71,6 +71,7 @@ extern patch_t *rmatcico;
|
|||
extern patch_t *bmatcico;
|
||||
extern patch_t *tagico;
|
||||
extern patch_t *tallminus;
|
||||
extern patch_t *tokenicon;
|
||||
|
||||
// set true when entering a chat message
|
||||
extern boolean chat_on;
|
||||
|
@ -78,9 +79,6 @@ extern boolean chat_on;
|
|||
// set true whenever the tab rankings are being shown for any reason
|
||||
extern boolean hu_showscores;
|
||||
|
||||
// P_DeathThink sets this true to show scores while dead, in multiplayer
|
||||
extern boolean playerdeadview;
|
||||
|
||||
// init heads up data at game startup.
|
||||
void HU_Init(void);
|
||||
|
||||
|
|
950
src/info.c
950
src/info.c
File diff suppressed because it is too large
Load diff
204
src/info.h
204
src/info.h
|
@ -320,7 +320,6 @@ typedef enum sprite
|
|||
// Collectible Items
|
||||
SPR_RING,
|
||||
SPR_TRNG, // Team Rings
|
||||
SPR_EMMY, // emerald test
|
||||
SPR_TOKE, // Special Stage Token
|
||||
SPR_RFLG, // Red CTF Flag
|
||||
SPR_BFLG, // Blue CTF Flag
|
||||
|
@ -337,6 +336,8 @@ typedef enum sprite
|
|||
SPR_SPIK, // Spike Ball
|
||||
SPR_SFLM, // Spin fire
|
||||
SPR_USPK, // Floor spike
|
||||
SPR_WSPK, // Wall spike
|
||||
SPR_WSPB, // Wall spike base
|
||||
SPR_STPT, // Starpost
|
||||
SPR_BMNE, // Big floating mine
|
||||
|
||||
|
@ -387,6 +388,12 @@ typedef enum sprite
|
|||
SPR_FWR4,
|
||||
SPR_BUS1, // GFZ Bush w/ berries
|
||||
SPR_BUS2, // GFZ Bush w/o berries
|
||||
// Trees (both GFZ and misc)
|
||||
SPR_TRE1, // GFZ
|
||||
SPR_TRE2, // Checker
|
||||
SPR_TRE3, // Frozen Hillside
|
||||
SPR_TRE4, // Polygon
|
||||
SPR_TRE5, // Bush tree
|
||||
|
||||
// Techno Hill Scenery
|
||||
SPR_THZP, // THZ1 Flower
|
||||
|
@ -425,9 +432,11 @@ typedef enum sprite
|
|||
// Egg Rock Scenery
|
||||
|
||||
// Christmas Scenery
|
||||
SPR_XMS1,
|
||||
SPR_XMS2,
|
||||
SPR_XMS3,
|
||||
SPR_XMS1, // Christmas Pole
|
||||
SPR_XMS2, // Candy Cane
|
||||
SPR_XMS3, // Snowman
|
||||
SPR_XMS4, // Lamppost
|
||||
SPR_XMS5, // Hanging Star
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
SPR_BSZ1, // Tall flowers
|
||||
|
@ -450,7 +459,7 @@ typedef enum sprite
|
|||
SPR_ARMB, // Armageddon Shield Ring, Back
|
||||
SPR_WIND, // Whirlwind Shield Orb
|
||||
SPR_MAGN, // Attract Shield Orb
|
||||
SPR_ELEM, // Elemental Shield Orb and Fire
|
||||
SPR_ELEM, // Elemental Shield Orb
|
||||
SPR_FORC, // Force Shield Orb
|
||||
SPR_PITY, // Pity Shield Orb
|
||||
SPR_FIRS, // Flame Shield Orb
|
||||
|
@ -507,9 +516,12 @@ typedef enum sprite
|
|||
// Game Indicators
|
||||
SPR_SCOR, // Score logo
|
||||
SPR_DRWN, // Drowning Timer
|
||||
SPR_LCKN, // Target
|
||||
SPR_TTAG, // Tag Sign
|
||||
SPR_GFLG, // Got Flag sign
|
||||
|
||||
SPR_CORK,
|
||||
|
||||
// Ring Weapons
|
||||
SPR_RRNG, // Red Ring
|
||||
SPR_RNGB, // Bounce Ring
|
||||
|
@ -594,21 +606,21 @@ typedef enum sprite
|
|||
NUMSPRITES
|
||||
} spritenum_t;
|
||||
|
||||
// Make sure to be conscious of FF_FRAMEMASK whenever you change this table.
|
||||
// Currently, FF_FRAMEMASK is 0x1ff, or 511 - and NUMSPRITEFREESLOTS is 256.
|
||||
// Since this is zero-based, there can be at most 256 different SPR2_'s without changing that.
|
||||
// Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table.
|
||||
// Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f.
|
||||
// Since this is zero-based, there can be at most 128 different SPR2_'s without changing that.
|
||||
enum playersprite
|
||||
{
|
||||
SPR2_STND = 0,
|
||||
SPR2_WAIT,
|
||||
SPR2_WALK,
|
||||
SPR2_RUN ,
|
||||
SPR2_PEEL,
|
||||
SPR2_DASH,
|
||||
SPR2_PAIN,
|
||||
SPR2_STUN,
|
||||
SPR2_DEAD,
|
||||
SPR2_DRWN, // drown
|
||||
SPR2_SPIN,
|
||||
SPR2_DASH, // spindash charge
|
||||
SPR2_ROLL,
|
||||
SPR2_GASP,
|
||||
SPR2_JUMP,
|
||||
SPR2_SPNG, // spring
|
||||
|
@ -616,8 +628,7 @@ enum playersprite
|
|||
SPR2_EDGE,
|
||||
SPR2_RIDE,
|
||||
|
||||
SPR2_SIGN, // end sign head
|
||||
SPR2_LIFE, // life monitor icon
|
||||
SPR2_SPIN, // spindash
|
||||
|
||||
SPR2_FLY ,
|
||||
SPR2_SWIM,
|
||||
|
@ -627,36 +638,28 @@ enum playersprite
|
|||
SPR2_CLNG, // cling
|
||||
SPR2_CLMB, // climb
|
||||
|
||||
SPR2_FLT , // float
|
||||
SPR2_FRUN, // float run
|
||||
|
||||
SPR2_BNCE, // bounce
|
||||
SPR2_BLND, // bounce landing
|
||||
|
||||
SPR2_FIRE, // fire
|
||||
|
||||
SPR2_TWIN, // twinspin
|
||||
|
||||
SPR2_MLEE, // melee
|
||||
SPR2_MLEL, // melee land
|
||||
|
||||
SPR2_TRNS, // super transformation
|
||||
SPR2_SSTD, // super stand
|
||||
SPR2_SWLK, // super walk
|
||||
SPR2_SRUN, // super run
|
||||
SPR2_SPEE, // super peelout
|
||||
SPR2_SPAN, // super pain
|
||||
SPR2_SSTN, // super stun
|
||||
SPR2_SDTH, // super death
|
||||
SPR2_SDRN, // super drown
|
||||
SPR2_SSPN, // super spin
|
||||
SPR2_SGSP, // super gasp
|
||||
SPR2_SJMP, // super jump
|
||||
SPR2_SSPG, // super spring
|
||||
SPR2_SFAL, // super fall
|
||||
SPR2_SEDG, // super edge
|
||||
SPR2_SRID, // super ride
|
||||
SPR2_SFLT, // super float
|
||||
SPR2_TRNS, // transformation
|
||||
|
||||
SPR2_NTRN, // NiGHTS transformation
|
||||
SPR2_NSTD, // NiGHTS stand
|
||||
SPR2_NFLT, // NiGHTS float
|
||||
SPR2_NPAN, // NiGHTS pain
|
||||
SPR2_NSTN, // NiGHTS stun
|
||||
SPR2_NPUL, // NiGHTS pull
|
||||
SPR2_NATK, // NiGHTS attack
|
||||
|
||||
// NiGHTS flight.
|
||||
// NiGHTS flight
|
||||
SPR2_NGT0,
|
||||
SPR2_NGT1,
|
||||
SPR2_NGT2,
|
||||
|
@ -671,7 +674,7 @@ enum playersprite
|
|||
SPR2_NGTB,
|
||||
SPR2_NGTC,
|
||||
|
||||
// NiGHTS drill.
|
||||
// NiGHTS drill
|
||||
SPR2_DRL0,
|
||||
SPR2_DRL1,
|
||||
SPR2_DRL2,
|
||||
|
@ -686,8 +689,11 @@ enum playersprite
|
|||
SPR2_DRLB,
|
||||
SPR2_DRLC,
|
||||
|
||||
SPR2_SIGN, // end sign head
|
||||
SPR2_LIFE, // life monitor icon
|
||||
|
||||
SPR2_FIRSTFREESLOT,
|
||||
SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
|
||||
SPR2_LASTFREESLOT = 0x7f,
|
||||
NUMPLAYERSPRITES
|
||||
};
|
||||
|
||||
|
@ -713,19 +719,22 @@ typedef enum state
|
|||
S_PLAY_WAIT,
|
||||
S_PLAY_WALK,
|
||||
S_PLAY_RUN,
|
||||
S_PLAY_PEEL,
|
||||
S_PLAY_DASH,
|
||||
S_PLAY_PAIN,
|
||||
S_PLAY_STUN,
|
||||
S_PLAY_DEAD,
|
||||
S_PLAY_DRWN,
|
||||
S_PLAY_SPIN,
|
||||
S_PLAY_DASH,
|
||||
S_PLAY_ROLL,
|
||||
S_PLAY_GASP,
|
||||
S_PLAY_JUMP, // spin jump
|
||||
S_PLAY_JUMP,
|
||||
S_PLAY_SPRING,
|
||||
S_PLAY_FALL,
|
||||
S_PLAY_EDGE,
|
||||
S_PLAY_RIDE,
|
||||
|
||||
// CA2_SPINDASH
|
||||
S_PLAY_SPINDASH,
|
||||
|
||||
// CA_FLY/SWIM
|
||||
S_PLAY_FLY,
|
||||
S_PLAY_SWIM,
|
||||
|
@ -736,30 +745,25 @@ typedef enum state
|
|||
S_PLAY_CLING,
|
||||
S_PLAY_CLIMB,
|
||||
|
||||
// CA_FLOAT/CA_SLOWFALL
|
||||
S_PLAY_FLOAT,
|
||||
S_PLAY_FLOAT_RUN,
|
||||
|
||||
// CA_BOUNCE
|
||||
S_PLAY_BOUNCE,
|
||||
S_PLAY_BOUNCE_LANDING,
|
||||
|
||||
// CA2_GUNSLINGER
|
||||
S_PLAY_FIRE,
|
||||
S_PLAY_FIRE_FINISH,
|
||||
|
||||
// CA_TWINSPIN
|
||||
S_PLAY_TWINSPIN,
|
||||
|
||||
// CA2_MELEE
|
||||
S_PLAY_MELEE,
|
||||
S_PLAY_MELEE_FINISH,
|
||||
|
||||
// SF_SUPERANIMS
|
||||
S_PLAY_SUPER_STND,
|
||||
S_PLAY_SUPER_WALK,
|
||||
S_PLAY_SUPER_RUN,
|
||||
S_PLAY_SUPER_PEEL,
|
||||
S_PLAY_SUPER_PAIN,
|
||||
S_PLAY_SUPER_STUN,
|
||||
S_PLAY_SUPER_DEAD,
|
||||
S_PLAY_SUPER_DRWN,
|
||||
S_PLAY_SUPER_SPIN,
|
||||
S_PLAY_SUPER_GASP,
|
||||
S_PLAY_SUPER_JUMP, // see note above
|
||||
S_PLAY_SUPER_SPRING,
|
||||
S_PLAY_SUPER_FALL,
|
||||
S_PLAY_SUPER_EDGE,
|
||||
S_PLAY_SUPER_RIDE,
|
||||
S_PLAY_SUPER_FLOAT,
|
||||
S_PLAY_MELEE_LANDING,
|
||||
|
||||
// SF_SUPER
|
||||
S_PLAY_SUPER_TRANS,
|
||||
|
@ -798,7 +802,7 @@ typedef enum state
|
|||
|
||||
S_PLAY_NIGHTS_STAND,
|
||||
S_PLAY_NIGHTS_FLOAT,
|
||||
S_PLAY_NIGHTS_PAIN,
|
||||
S_PLAY_NIGHTS_STUN,
|
||||
S_PLAY_NIGHTS_PULL,
|
||||
S_PLAY_NIGHTS_ATTACK,
|
||||
|
||||
|
@ -1620,12 +1624,8 @@ typedef enum state
|
|||
// Individual Team Rings
|
||||
S_TEAMRING,
|
||||
|
||||
// Special Stage Token
|
||||
S_EMMY,
|
||||
|
||||
// Special Stage Token
|
||||
S_TOKEN,
|
||||
S_MOVINGTOKEN,
|
||||
|
||||
// CTF Flags
|
||||
S_REDFLAG,
|
||||
|
@ -1776,6 +1776,15 @@ typedef enum state
|
|||
S_SPIKED1,
|
||||
S_SPIKED2,
|
||||
|
||||
// Wall spikes
|
||||
S_WALLSPIKE1,
|
||||
S_WALLSPIKE2,
|
||||
S_WALLSPIKE3,
|
||||
S_WALLSPIKE4,
|
||||
S_WALLSPIKE5,
|
||||
S_WALLSPIKE6,
|
||||
S_WALLSPIKEBASE,
|
||||
|
||||
// Starpost
|
||||
S_STARPOST_IDLE,
|
||||
S_STARPOST_FLASH,
|
||||
|
@ -1964,6 +1973,7 @@ typedef enum state
|
|||
S_DEMONFIRE5,
|
||||
S_DEMONFIRE6,
|
||||
|
||||
// GFZ flowers
|
||||
S_GFZFLOWERA,
|
||||
S_GFZFLOWERB,
|
||||
S_GFZFLOWERC,
|
||||
|
@ -1971,6 +1981,18 @@ typedef enum state
|
|||
S_BERRYBUSH,
|
||||
S_BUSH,
|
||||
|
||||
// Trees (both GFZ and misc)
|
||||
S_GFZTREE,
|
||||
S_GFZBERRYTREE,
|
||||
S_GFZCHERRYTREE,
|
||||
S_CHECKERTREE,
|
||||
S_CHECKERSUNSETTREE,
|
||||
S_FHZTREE, // Frozen Hillside
|
||||
S_FHZPINKTREE,
|
||||
S_POLYGONTREE,
|
||||
S_BUSHTREE,
|
||||
S_BUSHREDTREE,
|
||||
|
||||
// THZ Plant
|
||||
S_THZFLOWERA,
|
||||
S_THZFLOWERB,
|
||||
|
@ -1980,6 +2002,7 @@ typedef enum state
|
|||
|
||||
// Deep Sea Gargoyle
|
||||
S_GARGOYLE,
|
||||
S_BIGGARGOYLE,
|
||||
|
||||
// DSZ Seaweed
|
||||
S_SEAWEED1,
|
||||
|
@ -2138,7 +2161,14 @@ typedef enum state
|
|||
// Xmas-specific stuff
|
||||
S_XMASPOLE,
|
||||
S_CANDYCANE,
|
||||
S_SNOWMAN,
|
||||
S_SNOWMAN, // normal
|
||||
S_SNOWMANHAT, // with hat + scarf
|
||||
S_LAMPPOST1, // normal
|
||||
S_LAMPPOST2, // with snow
|
||||
S_HANGSTAR,
|
||||
// Xmas GFZ bushes
|
||||
S_XMASBERRYBUSH,
|
||||
S_XMASBUSH,
|
||||
|
||||
// Botanic Serenity's loads of scenery states
|
||||
S_BSZTALLFLOWER_RED,
|
||||
|
@ -2330,10 +2360,6 @@ typedef enum state
|
|||
S_PITY4,
|
||||
S_PITY5,
|
||||
S_PITY6,
|
||||
S_PITY7,
|
||||
S_PITY8,
|
||||
S_PITY9,
|
||||
S_PITY10,
|
||||
|
||||
S_FIRS1,
|
||||
S_FIRS2,
|
||||
|
@ -2725,14 +2751,18 @@ typedef enum state
|
|||
S_FOUR2,
|
||||
S_FIVE2,
|
||||
|
||||
S_LOCKON1,
|
||||
S_LOCKON2,
|
||||
|
||||
// Tag Sign
|
||||
S_TTAG1,
|
||||
S_TTAG,
|
||||
|
||||
// Got Flag Sign
|
||||
S_GOTFLAG1,
|
||||
S_GOTFLAG2,
|
||||
S_GOTFLAG3,
|
||||
S_GOTFLAG4,
|
||||
S_GOTFLAG,
|
||||
S_GOTREDFLAG,
|
||||
S_GOTBLUEFLAG,
|
||||
|
||||
S_CORK,
|
||||
|
||||
// Red Ring
|
||||
S_RRNG1,
|
||||
|
@ -3234,8 +3264,7 @@ typedef enum mobj_type
|
|||
MT_BLUEBALL, // Blue sphere replacement for special stages
|
||||
MT_REDTEAMRING, //Rings collectable by red team.
|
||||
MT_BLUETEAMRING, //Rings collectable by blue team.
|
||||
MT_EMMY, // emerald token for special stage
|
||||
MT_TOKEN, // Special Stage Token (uncollectible part)
|
||||
MT_TOKEN, // Special Stage token for special stage
|
||||
MT_REDFLAG, // Red CTF Flag
|
||||
MT_BLUEFLAG, // Blue CTF Flag
|
||||
MT_EMBLEM,
|
||||
|
@ -3269,6 +3298,8 @@ typedef enum mobj_type
|
|||
MT_SPECIALSPIKEBALL,
|
||||
MT_SPINFIRE,
|
||||
MT_SPIKE,
|
||||
MT_WALLSPIKE,
|
||||
MT_WALLSPIKEBASE,
|
||||
MT_STARPOST,
|
||||
MT_BIGMINE,
|
||||
MT_BIGAIRMINE,
|
||||
|
@ -3359,6 +3390,17 @@ typedef enum mobj_type
|
|||
MT_GFZFLOWER3,
|
||||
MT_BERRYBUSH,
|
||||
MT_BUSH,
|
||||
// Trees (both GFZ and misc)
|
||||
MT_GFZTREE,
|
||||
MT_GFZBERRYTREE,
|
||||
MT_GFZCHERRYTREE,
|
||||
MT_CHECKERTREE,
|
||||
MT_CHECKERSUNSETTREE,
|
||||
MT_FHZTREE, // Frozen Hillside
|
||||
MT_FHZPINKTREE,
|
||||
MT_POLYGONTREE,
|
||||
MT_BUSHTREE,
|
||||
MT_BUSHREDTREE,
|
||||
|
||||
// Techno Hill Scenery
|
||||
MT_THZFLOWER1,
|
||||
|
@ -3367,6 +3409,7 @@ typedef enum mobj_type
|
|||
|
||||
// Deep Sea Scenery
|
||||
MT_GARGOYLE, // Deep Sea Gargoyle
|
||||
MT_BIGGARGOYLE, // Deep Sea Gargoyle (Big)
|
||||
MT_SEAWEED, // DSZ Seaweed
|
||||
MT_WATERDRIP, // Dripping Water source
|
||||
MT_WATERDROP, // Water drop from dripping water
|
||||
|
@ -3435,7 +3478,14 @@ typedef enum mobj_type
|
|||
// Christmas Scenery
|
||||
MT_XMASPOLE,
|
||||
MT_CANDYCANE,
|
||||
MT_SNOWMAN,
|
||||
MT_SNOWMAN, // normal
|
||||
MT_SNOWMANHAT, // with hat + scarf
|
||||
MT_LAMPPOST1, // normal
|
||||
MT_LAMPPOST2, // with snow
|
||||
MT_HANGSTAR,
|
||||
// Xmas GFZ bushes
|
||||
MT_XMASBERRYBUSH,
|
||||
MT_XMASBUSH,
|
||||
|
||||
// Botanic Serenity scenery
|
||||
MT_BSZTALLFLOWER_RED,
|
||||
|
@ -3542,9 +3592,9 @@ typedef enum mobj_type
|
|||
MT_SCORE, // score logo
|
||||
MT_DROWNNUMBERS, // Drowning Timer
|
||||
MT_GOTEMERALD, // Chaos Emerald (intangible)
|
||||
MT_LOCKON, // Target
|
||||
MT_TAG, // Tag Sign
|
||||
MT_GOTFLAG, // Got Flag sign
|
||||
MT_GOTFLAG2, // Got Flag sign
|
||||
|
||||
// Ambient Sounds
|
||||
MT_AWATERA, // Ambient Water Sound 1
|
||||
|
@ -3558,6 +3608,8 @@ typedef enum mobj_type
|
|||
MT_RANDOMAMBIENT,
|
||||
MT_RANDOMAMBIENT2,
|
||||
|
||||
MT_CORK,
|
||||
|
||||
// Ring Weapons
|
||||
MT_REDRING,
|
||||
MT_BOUNCERING,
|
||||
|
|
|
@ -445,10 +445,32 @@ static int lib_pIsValidSprite2(lua_State *L)
|
|||
INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes > 0)));
|
||||
lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// P_SpawnLockOn doesn't exist either, but we want to expose making a local mobj without encouraging hacks.
|
||||
|
||||
static int lib_pSpawnLockOn(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
mobj_t *lockon = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
statenum_t state = luaL_checkinteger(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!lockon)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (P_IsLocalPlayer(player)) // Only display it on your own view.
|
||||
{
|
||||
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
|
||||
visual->target = lockon;
|
||||
P_SetMobjStateNF(visual, state);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pSpawnMissile(lua_State *L)
|
||||
{
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -793,6 +815,17 @@ static int lib_pStealPlayerScore(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pGetJumpFlags(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
lua_pushinteger(L, P_GetJumpFlags(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pPlayerInPain(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
@ -1055,11 +1088,12 @@ static int lib_pLookForEnemies(lua_State *L)
|
|||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
boolean nonenemies = lua_opttrueboolean(L, 2);
|
||||
boolean bullet = lua_optboolean(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
lua_pushboolean(L, P_LookForEnemies(player, nonenemies));
|
||||
LUA_PushUserdata(L, P_LookForEnemies(player, nonenemies, bullet), META_MOBJ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2147,6 +2181,31 @@ static int lib_sSoundPlaying(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// This doesn't really exist, but we're providing it as a handy netgame-safe wrapper for stuff that should be locally handled.
|
||||
|
||||
static int lib_sStartMusicCaption(lua_State *L)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
const char *caption = luaL_checkstring(L, 1);
|
||||
UINT16 lifespan = (UINT16)luaL_checkinteger(L, 2);
|
||||
//HUDSAFE
|
||||
INLEVEL
|
||||
|
||||
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
|
||||
{
|
||||
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
|
||||
if (lifespan && (!player || P_IsLocalPlayer(player)))
|
||||
{
|
||||
strlcpy(S_sfx[sfx_None].caption, caption, sizeof(S_sfx[sfx_None].caption));
|
||||
S_StartCaption(sfx_None, -1, lifespan);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// G_GAME
|
||||
////////////
|
||||
|
||||
|
@ -2327,6 +2386,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_SpawnMobj",lib_pSpawnMobj},
|
||||
{"P_RemoveMobj",lib_pRemoveMobj},
|
||||
{"P_IsValidSprite2", lib_pIsValidSprite2},
|
||||
{"P_SpawnLockOn", lib_pSpawnLockOn},
|
||||
{"P_SpawnMissile",lib_pSpawnMissile},
|
||||
{"P_SpawnXYZMissile",lib_pSpawnXYZMissile},
|
||||
{"P_SpawnPointMissile",lib_pSpawnPointMissile},
|
||||
|
@ -2354,6 +2414,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection},
|
||||
{"P_AddPlayerScore",lib_pAddPlayerScore},
|
||||
{"P_StealPlayerScore",lib_pStealPlayerScore},
|
||||
{"P_GetJumpFlags",lib_pGetJumpFlags},
|
||||
{"P_PlayerInPain",lib_pPlayerInPain},
|
||||
{"P_DoPlayerPain",lib_pDoPlayerPain},
|
||||
{"P_ResetPlayer",lib_pResetPlayer},
|
||||
|
@ -2457,6 +2518,7 @@ static luaL_Reg lib[] = {
|
|||
{"S_OriginPlaying",lib_sOriginPlaying},
|
||||
{"S_IdPlaying",lib_sIdPlaying},
|
||||
{"S_SoundPlaying",lib_sSoundPlaying},
|
||||
{"S_StartMusicCaption", lib_sStartMusicCaption},
|
||||
|
||||
// g_game
|
||||
{"G_BuildMapName",lib_gBuildMapName},
|
||||
|
|
|
@ -266,4 +266,4 @@ int LUA_BlockmapLib(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,7 @@ enum hook {
|
|||
hook_ShieldSpawn,
|
||||
hook_ShieldSpecial,
|
||||
hook_MobjMoveBlocked,
|
||||
hook_MapThingSpawn,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -83,5 +84,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
|||
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
||||
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
||||
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
||||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"ShieldSpawn",
|
||||
"ShieldSpecial",
|
||||
"MobjMoveBlocked",
|
||||
"MapThingSpawn",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -128,6 +129,7 @@ static int lib_addHook(lua_State *L)
|
|||
case hook_MobjRemoved:
|
||||
case hook_HurtMsg:
|
||||
case hook_MobjMoveBlocked:
|
||||
case hook_MapThingSpawn:
|
||||
hook.s.mt = MT_NULL;
|
||||
if (lua_isnumber(L, 2))
|
||||
hook.s.mt = lua_tonumber(L, 2);
|
||||
|
@ -187,6 +189,7 @@ static int lib_addHook(lua_State *L)
|
|||
case hook_BossDeath:
|
||||
case hook_MobjRemoved:
|
||||
case hook_MobjMoveBlocked:
|
||||
case hook_MapThingSpawn:
|
||||
lastp = &mobjhooks[hook.s.mt];
|
||||
break;
|
||||
case hook_JumpSpecial:
|
||||
|
@ -1073,4 +1076,66 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc)
|
|||
// stack: tables
|
||||
}
|
||||
|
||||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean hooked = false;
|
||||
if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8))))
|
||||
return false;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
|
||||
// Look for all generic mobj map thing spawn hooks
|
||||
for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_MapThingSpawn)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
if (lua_pcall(gL, 2, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (lua_toboolean(gL, -1))
|
||||
hooked = true;
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_MapThingSpawn)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
if (lua_pcall(gL, 2, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (lua_toboolean(gL, -1))
|
||||
hooked = true;
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
return hooked;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,7 @@ enum sfxinfo_read {
|
|||
sfxinfor_singular,
|
||||
sfxinfor_priority,
|
||||
sfxinfor_flags, // "pitch"
|
||||
sfxinfor_caption,
|
||||
sfxinfor_skinsound
|
||||
};
|
||||
const char *const sfxinfo_ropt[] = {
|
||||
|
@ -38,18 +39,21 @@ const char *const sfxinfo_ropt[] = {
|
|||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
"caption",
|
||||
"skinsound",
|
||||
NULL};
|
||||
|
||||
enum sfxinfo_write {
|
||||
sfxinfow_singular = 0,
|
||||
sfxinfow_priority,
|
||||
sfxinfow_flags // "pitch"
|
||||
sfxinfow_flags, // "pitch"
|
||||
sfxinfow_caption
|
||||
};
|
||||
const char *const sfxinfo_wopt[] = {
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
"caption",
|
||||
NULL};
|
||||
|
||||
//
|
||||
|
@ -769,8 +773,8 @@ static int lib_getSfxInfo(lua_State *L)
|
|||
lua_remove(L, 1);
|
||||
|
||||
i = luaL_checkinteger(L, 1);
|
||||
if (i >= NUMSFX)
|
||||
return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1);
|
||||
if (i == 0 || i >= NUMSFX)
|
||||
return luaL_error(L, "sfxinfo[] index %d out of range (1 - %d)", i, NUMSFX-1);
|
||||
LUA_PushUserdata(L, &S_sfx[i], META_SFXINFO);
|
||||
return 1;
|
||||
}
|
||||
|
@ -783,9 +787,9 @@ static int lib_setSfxInfo(lua_State *L)
|
|||
lua_remove(L, 1);
|
||||
{
|
||||
UINT32 i = luaL_checkinteger(L, 1);
|
||||
if (i >= NUMSFX)
|
||||
return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1);
|
||||
info = &S_sfx[i]; // get the mobjinfo to assign to.
|
||||
if (i == 0 || i >= NUMSFX)
|
||||
return luaL_error(L, "sfxinfo[] index %d out of range (1 - %d)", i, NUMSFX-1);
|
||||
info = &S_sfx[i]; // get the sfxinfo to assign to.
|
||||
}
|
||||
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
||||
lua_remove(L, 1); // pop mobjtype num, don't need it any more.
|
||||
|
@ -814,6 +818,9 @@ static int lib_setSfxInfo(lua_State *L)
|
|||
case sfxinfow_flags:
|
||||
info->pitch = (INT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case sfxinfow_caption:
|
||||
strlcpy(info->caption, luaL_checkstring(L, 3), sizeof(info->caption));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -851,11 +858,14 @@ static int sfxinfo_get(lua_State *L)
|
|||
case sfxinfor_flags:
|
||||
lua_pushinteger(L, sfx->pitch);
|
||||
return 1;
|
||||
case sfxinfor_caption:
|
||||
lua_pushstring(L, sfx->caption);
|
||||
return 1;
|
||||
case sfxinfor_skinsound:
|
||||
lua_pushinteger(L, sfx->skinsound);
|
||||
return 1;
|
||||
default:
|
||||
return luaL_error(L, "impossible error");
|
||||
return luaL_error(L, "Field does not exist in sfxinfo_t");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -886,8 +896,11 @@ static int sfxinfo_set(lua_State *L)
|
|||
case sfxinfow_flags:
|
||||
sfx->pitch = luaL_checkinteger(L, 1);
|
||||
break;
|
||||
case sfxinfow_caption:
|
||||
strlcpy(sfx->caption, luaL_checkstring(L, 1), sizeof(sfx->caption));
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, "impossible error");
|
||||
return luaL_error(L, "Field does not exist in sfxinfo_t");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -511,7 +511,8 @@ static int mobj_set(lua_State *L)
|
|||
for (i = 0; i < numskins; i++)
|
||||
if (fastcmp(skins[i].name, skin))
|
||||
{
|
||||
mo->skin = &skins[i];
|
||||
if (!mo->player || R_SkinUsable(mo->player-players, i))
|
||||
mo->skin = &skins[i];
|
||||
return 0;
|
||||
}
|
||||
return luaL_error(L, "mobj.skin '%s' not found!", skin);
|
||||
|
|
|
@ -194,8 +194,6 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->gotcontinue);
|
||||
else if (fastcmp(field,"speed"))
|
||||
lua_pushfixed(L, plr->speed);
|
||||
else if (fastcmp(field,"jumping"))
|
||||
lua_pushboolean(L, plr->jumping);
|
||||
else if (fastcmp(field,"secondjump"))
|
||||
lua_pushinteger(L, plr->secondjump);
|
||||
else if (fastcmp(field,"fly1"))
|
||||
|
@ -459,8 +457,6 @@ static int player_set(lua_State *L)
|
|||
plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"speed"))
|
||||
plr->speed = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"jumping"))
|
||||
plr->jumping = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"secondjump"))
|
||||
plr->secondjump = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"fly1"))
|
||||
|
|
|
@ -596,14 +596,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
||||
WRITEUINT8(save_p, info - mobjinfo);
|
||||
WRITEUINT16(save_p, info - mobjinfo);
|
||||
break;
|
||||
}
|
||||
case ARCH_STATE:
|
||||
{
|
||||
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_STATE);
|
||||
WRITEUINT8(save_p, state - states);
|
||||
WRITEUINT16(save_p, state - states);
|
||||
break;
|
||||
}
|
||||
case ARCH_MOBJ:
|
||||
|
|
|
@ -16,89 +16,127 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
#define META_ITERATIONSTATE "iteration state"
|
||||
|
||||
static const char *const iter_opt[] = {
|
||||
"all",
|
||||
"mobj",
|
||||
NULL};
|
||||
|
||||
static const actionf_p1 iter_funcs[] = {
|
||||
NULL,
|
||||
(actionf_p1)P_MobjThinker
|
||||
};
|
||||
|
||||
struct iterationState {
|
||||
actionf_p1 filter;
|
||||
int next;
|
||||
};
|
||||
|
||||
static int iterationState_gc(lua_State *L)
|
||||
{
|
||||
struct iterationState *it = luaL_checkudata(L, -1, META_ITERATIONSTATE);
|
||||
if (it->next != LUA_REFNIL)
|
||||
{
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
|
||||
it->next = LUA_REFNIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define push_thinker(th) {\
|
||||
if ((th)->function.acp1 == (actionf_p1)P_MobjThinker) \
|
||||
LUA_PushUserdata(L, (th), META_MOBJ); \
|
||||
else \
|
||||
lua_pushlightuserdata(L, (th)); \
|
||||
}
|
||||
|
||||
static int lib_iterateThinkers(lua_State *L)
|
||||
{
|
||||
int state = luaL_checkoption(L, 1, "mobj", iter_opt);
|
||||
|
||||
thinker_t *th = NULL;
|
||||
actionf_p1 searchFunc;
|
||||
const char *searchMeta;
|
||||
thinker_t *th = NULL, *next = NULL;
|
||||
struct iterationState *it;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // remove state now.
|
||||
it = luaL_checkudata(L, 1, META_ITERATIONSTATE);
|
||||
|
||||
switch(state)
|
||||
lua_settop(L, 2);
|
||||
|
||||
if (lua_isnil(L, 2))
|
||||
th = &thinkercap;
|
||||
else if (lua_isuserdata(L, 2))
|
||||
{
|
||||
case 0:
|
||||
searchFunc = NULL;
|
||||
searchMeta = NULL;
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
searchFunc = (actionf_p1)P_MobjThinker;
|
||||
searchMeta = META_MOBJ;
|
||||
break;
|
||||
if (lua_islightuserdata(L, 2))
|
||||
th = lua_touserdata(L, 2);
|
||||
else
|
||||
{
|
||||
th = *(thinker_t **)lua_touserdata(L, -1);
|
||||
if (!th)
|
||||
{
|
||||
if (it->next == LUA_REFNIL)
|
||||
return 0;
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, it->next);
|
||||
if (lua_islightuserdata(L, -1))
|
||||
next = lua_touserdata(L, -1);
|
||||
else
|
||||
next = *(thinker_t **)lua_touserdata(L, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lua_isnil(L, 1)) {
|
||||
if (lua_islightuserdata(L, 1))
|
||||
th = (thinker_t *)lua_touserdata(L, 1);
|
||||
else if (searchMeta)
|
||||
th = *((thinker_t **)luaL_checkudata(L, 1, searchMeta));
|
||||
else
|
||||
th = *((thinker_t **)lua_touserdata(L, 1));
|
||||
} else
|
||||
th = &thinkercap;
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
|
||||
it->next = LUA_REFNIL;
|
||||
|
||||
if (!th) // something got our userdata invalidated!
|
||||
return 0;
|
||||
if (th && !next)
|
||||
next = th->next;
|
||||
if (!next)
|
||||
return luaL_error(L, "next thinker invalidated during iteration");
|
||||
|
||||
if (searchFunc == NULL)
|
||||
{
|
||||
if ((th = th->next) != &thinkercap)
|
||||
for (; next != &thinkercap; next = next->next)
|
||||
if (!it->filter || next->function.acp1 == it->filter)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
LUA_PushUserdata(L, th, META_MOBJ);
|
||||
else
|
||||
lua_pushlightuserdata(L, th);
|
||||
push_thinker(next);
|
||||
if (next->next != &thinkercap)
|
||||
{
|
||||
push_thinker(next->next);
|
||||
it->next = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (th = th->next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != searchFunc)
|
||||
continue;
|
||||
|
||||
LUA_PushUserdata(L, th, searchMeta);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_startIterate(lua_State *L)
|
||||
{
|
||||
struct iterationState *it;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
luaL_checkoption(L, 1, iter_opt[0], iter_opt);
|
||||
lua_pushcfunction(L, lib_iterateThinkers);
|
||||
lua_pushvalue(L, 1);
|
||||
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
it = lua_newuserdata(L, sizeof(struct iterationState));
|
||||
luaL_getmetatable(L, META_ITERATIONSTATE);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
it->filter = iter_funcs[luaL_checkoption(L, 1, "mobj", iter_opt)];
|
||||
it->next = LUA_REFNIL;
|
||||
return 2;
|
||||
}
|
||||
|
||||
#undef push_thinker
|
||||
|
||||
int LUA_ThinkerLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_ITERATIONSTATE);
|
||||
lua_pushcfunction(L, iterationState_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushcfunction(L, lib_startIterate);
|
||||
lua_pushcfunction(L, lib_iterateThinkers);
|
||||
lua_pushcclosure(L, lib_startIterate, 1);
|
||||
lua_setfield(L, -2, "iterate");
|
||||
lua_setglobal(L, "thinkers");
|
||||
return 0;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "v_video.h"
|
||||
#include "i_video.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
// GIFs are always little-endian
|
||||
#include "byteptr.h"
|
||||
|
@ -396,7 +397,6 @@ static void GIF_headwrite(void)
|
|||
{
|
||||
UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL);
|
||||
UINT8 *p = gifhead;
|
||||
RGBA_t *c;
|
||||
INT32 i;
|
||||
UINT16 rwidth, rheight;
|
||||
|
||||
|
@ -427,12 +427,17 @@ static void GIF_headwrite(void)
|
|||
WRITEUINT8(p, 0x00);
|
||||
|
||||
// write color table
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
c = &pLocalPalette[i];
|
||||
WRITEUINT8(p, c->s.red);
|
||||
WRITEUINT8(p, c->s.green);
|
||||
WRITEUINT8(p, c->s.blue);
|
||||
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
|
||||
? pLocalPalette
|
||||
: pMasterPalette);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
WRITEUINT8(p, pal[i].s.red);
|
||||
WRITEUINT8(p, pal[i].s.green);
|
||||
WRITEUINT8(p, pal[i].s.blue);
|
||||
}
|
||||
}
|
||||
|
||||
// write extension block
|
||||
|
|
|
@ -942,7 +942,7 @@ boolean OP_FreezeObjectplace(void)
|
|||
if (!objectplacing)
|
||||
return false;
|
||||
|
||||
if ((maptol & TOL_NIGHTS) && (players[consoleplayer].pflags & PF_NIGHTSMODE))
|
||||
if ((maptol & TOL_NIGHTS) && (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -968,7 +968,7 @@ void OP_NightsObjectplace(player_t *player)
|
|||
if (player->pflags & PF_ATTACKDOWN)
|
||||
{
|
||||
// Are ANY objectplace buttons pressed? If no, remove flag.
|
||||
if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_USE|BT_CAMRIGHT|BT_CAMLEFT)))
|
||||
if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_USE|BT_WEAPONNEXT|BT_WEAPONPREV)))
|
||||
player->pflags &= ~PF_ATTACKDOWN;
|
||||
|
||||
// Do nothing.
|
||||
|
@ -1019,7 +1019,7 @@ void OP_NightsObjectplace(player_t *player)
|
|||
}
|
||||
|
||||
// This places a ring!
|
||||
if (cmd->buttons & BT_CAMRIGHT)
|
||||
if (cmd->buttons & BT_WEAPONNEXT)
|
||||
{
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
if (!OP_HeightOkay(player, false))
|
||||
|
@ -1030,7 +1030,7 @@ void OP_NightsObjectplace(player_t *player)
|
|||
}
|
||||
|
||||
// This places a wing item!
|
||||
if (cmd->buttons & BT_CAMLEFT)
|
||||
if (cmd->buttons & BT_WEAPONPREV)
|
||||
{
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
if (!OP_HeightOkay(player, false))
|
||||
|
@ -1255,7 +1255,7 @@ void Command_ObjectPlace_f(void)
|
|||
{
|
||||
objectplacing = true;
|
||||
|
||||
if ((players[0].pflags & PF_NIGHTSMODE))
|
||||
if ((players[0].powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
|
||||
if (!COM_CheckParm("-silent"))
|
||||
|
@ -1326,7 +1326,7 @@ void Command_ObjectPlace_f(void)
|
|||
|
||||
// Don't touch the NiGHTS Objectplace stuff.
|
||||
// ... or if the mo mysteriously vanished.
|
||||
if (!players[0].mo || (players[0].pflags & PF_NIGHTSMODE))
|
||||
if (!players[0].mo || (players[0].powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
|
||||
// If still in dummy state, get out of it.
|
||||
|
|
34
src/m_cond.c
34
src/m_cond.c
|
@ -573,31 +573,31 @@ extraemblem_t extraemblems[MAXEXTRAEMBLEMS] =
|
|||
unlockable_t unlockables[MAXUNLOCKABLES] =
|
||||
{
|
||||
// Name, Objective, Menu Height, ConditionSet, Unlock Type, Variable, NoCecho, NoChecklist
|
||||
/* 01 */ {"Record Attack", "Complete Greenflower Zone, Act 1", 0, 1, SECRET_RECORDATTACK, 0, true, true, 0},
|
||||
/* 02 */ {"NiGHTS Mode", "Complete Floral Field", 0, 2, SECRET_NIGHTSMODE, 0, true, true, 0},
|
||||
/* 01 */ {"Record Attack", "/", 0, 1, SECRET_RECORDATTACK, 0, true, true, 0},
|
||||
/* 02 */ {"NiGHTS Mode", "/", 0, 2, SECRET_NIGHTSMODE, 0, true, true, 0},
|
||||
|
||||
/* 03 */ {"Play Credits", "Complete 1P Mode", 30, 10, SECRET_CREDITS, 0, true, true, 0},
|
||||
/* 04 */ {"Sound Test", "Complete 1P Mode", 40, 10, SECRET_SOUNDTEST, 0, false, false, 0},
|
||||
/* 03 */ {"Play Credits", "/", 30, 10, SECRET_CREDITS, 0, true, true, 0},
|
||||
/* 04 */ {"Sound Test", "/", 40, 10, SECRET_SOUNDTEST, 0, false, false, 0},
|
||||
|
||||
/* 05 */ {"EXTRA LEVELS", "", 60, 0, SECRET_HEADER, 0, true, true, 0},
|
||||
/* 05 */ {"EXTRA LEVELS", "/", 58, 0, SECRET_HEADER, 0, true, true, 0},
|
||||
|
||||
/* 06 */ {"Aerial Garden Zone", "Complete 1P Mode w/ all emeralds", 70, 11, SECRET_WARP, 40, false, false, 0},
|
||||
/* 07 */ {"Azure Temple Zone", "Complete Aerial Garden Zone", 80, 20, SECRET_WARP, 41, false, false, 0},
|
||||
/* 06 */ {"Aerial Garden Zone", "/", 70, 11, SECRET_WARP, 40, false, false, 0},
|
||||
/* 07 */ {"Azure Temple Zone", "/", 80, 20, SECRET_WARP, 41, false, false, 0},
|
||||
|
||||
/* 08 */ {"BONUS LEVELS", "", 100, 0, SECRET_HEADER, 0, true, true, 0},
|
||||
/* 08 */ {"BONUS LEVELS", "/", 98, 0, SECRET_HEADER, 0, true, true, 0},
|
||||
|
||||
/* 09 */ {"PLACEHOLDER", "PLACEHOLDER", 0, 0, SECRET_NONE, 0, true, true, 0},
|
||||
/* 10 */ {"Mario Koopa Blast", "Collect 60 Emblems", 110, 42, SECRET_WARP, 30, false, false, 0},
|
||||
/* 11 */ {"PLACEHOLDER", "PLACEHOLDER", 0, 0, SECRET_NONE, 0, true, true, 0},
|
||||
/* 09 */ {"PLACEHOLDER", "/", 0, 0, SECRET_NONE, 0, true, true, 0},
|
||||
/* 10 */ {"Mario Koopa Blast", "/", 110, 42, SECRET_WARP, 30, false, false, 0},
|
||||
/* 11 */ {"PLACEHOLDER", "/", 0, 0, SECRET_NONE, 0, true, true, 0},
|
||||
|
||||
/* 12 */ {"Spring Hill Zone", "Collect 100 Emblems", 0, 44, SECRET_NONE, 0, false, false, 0},
|
||||
/* 13 */ {"Black Hole", "A Rank in all Special Stages", 0, 50, SECRET_NONE, 0, false, true, 0},
|
||||
/* 12 */ {"Spring Hill Zone", "/", 0, 44, SECRET_NONE, 0, false, false, 0},
|
||||
/* 13 */ {"Black Hole", "Get grade A in all Special Stages", 0, 50, SECRET_NONE, 0, false, true, 0},
|
||||
|
||||
/* 14 */ {"Emblem Hints", "Collect 40 Emblems", 0, 41, SECRET_EMBLEMHINTS, 0, false, true, 0},
|
||||
/* 15 */ {"Emblem Radar", "Collect 80 Emblems", 0, 43, SECRET_ITEMFINDER, 0, false, true, 0},
|
||||
/* 14 */ {"Emblem Hints", "/", 0, 41, SECRET_EMBLEMHINTS, 0, false, true, 0},
|
||||
/* 15 */ {"Emblem Radar", "/", 0, 43, SECRET_ITEMFINDER, 0, false, true, 0},
|
||||
|
||||
/* 16 */ {"Pandora's Box", "Collect All Emblems", 0, 45, SECRET_PANDORA, 0, false, false, 0},
|
||||
/* 17 */ {"Level Select", "Collect All Emblems", 20, 45, SECRET_LEVELSELECT, 1, false, true, 0},
|
||||
/* 16 */ {"Pandora's Box", "/", 0, 45, SECRET_PANDORA, 0, false, false, 0},
|
||||
/* 17 */ {"Level Select", "/", 20, 45, SECRET_LEVELSELECT, 1, false, true, 0},
|
||||
};
|
||||
|
||||
// Default number of emblems and extra emblems
|
||||
|
|
3545
src/m_menu.c
3545
src/m_menu.c
File diff suppressed because it is too large
Load diff
39
src/m_menu.h
39
src/m_menu.h
|
@ -66,7 +66,7 @@ void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtyp
|
|||
// Called by linux_x/i_video_xshm.c
|
||||
void M_QuitResponse(INT32 ch);
|
||||
|
||||
// Determines whether to show a level in the list
|
||||
// Determines whether to show a level in the list (platter version does not need to be exposed)
|
||||
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||
|
||||
|
||||
|
@ -149,8 +149,6 @@ typedef struct menuitem_s
|
|||
UINT8 alphaKey;
|
||||
} menuitem_t;
|
||||
|
||||
extern menuitem_t PlayerMenu[32];
|
||||
|
||||
typedef struct menu_s
|
||||
{
|
||||
const char *menutitlepic;
|
||||
|
@ -174,14 +172,36 @@ extern menu_t SP_LoadDef;
|
|||
// Stuff for customizing the player select screen
|
||||
typedef struct
|
||||
{
|
||||
boolean used;
|
||||
char notes[441];
|
||||
char picname[8];
|
||||
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
|
||||
UINT16 wadnum; // for duplicate characters
|
||||
UINT8 prev;
|
||||
UINT8 next;
|
||||
} description_t;
|
||||
|
||||
// level select platter
|
||||
typedef struct
|
||||
{
|
||||
char header[22+5]; // mapheader_t lvltttl max length + " ZONE"
|
||||
INT32 maplist[3];
|
||||
char mapnames[3][17+1];
|
||||
boolean mapavailable[4]; // mapavailable[3] == wide or not
|
||||
} levelselectrow_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 numrows;
|
||||
levelselectrow_t *rows;
|
||||
} levelselect_t;
|
||||
// experimental level select end
|
||||
|
||||
// descriptions for gametype select screen
|
||||
typedef struct
|
||||
{
|
||||
char notes[441];
|
||||
} gtdesc_t;
|
||||
|
||||
// mode descriptions for video mode menu
|
||||
typedef struct
|
||||
{
|
||||
|
@ -222,6 +242,9 @@ void M_ForceSaveSlotSelected(INT32 sslot);
|
|||
|
||||
void M_CheatActivationResponder(INT32 ch);
|
||||
|
||||
// Level select updating
|
||||
void Nextmap_OnChange(void);
|
||||
|
||||
// Screenshot menu updating
|
||||
void Moviemode_mode_Onchange(void);
|
||||
void Screenshot_option_Onchange(void);
|
||||
|
@ -263,14 +286,14 @@ void Screenshot_option_Onchange(void);
|
|||
NULL\
|
||||
}
|
||||
|
||||
#define MAPICONMENUSTYLE(header, source, prev)\
|
||||
#define MAPPLATTERMENUSTYLE(header, source)\
|
||||
{\
|
||||
header,\
|
||||
sizeof (source)/sizeof (menuitem_t),\
|
||||
prev,\
|
||||
&MainDef,\
|
||||
source,\
|
||||
M_DrawServerMenu,\
|
||||
27,40,\
|
||||
M_DrawLevelPlatterMenu,\
|
||||
0,0,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
|
56
src/m_misc.c
56
src/m_misc.c
|
@ -100,6 +100,8 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2
|
|||
consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
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};
|
||||
|
||||
|
@ -585,7 +587,7 @@ static const char *Newsnapshotfile(const char *pathname, const char *ext)
|
|||
|
||||
i += add * result;
|
||||
|
||||
if (add < 0 || add > 9999)
|
||||
if (i < 0 || i > 9999)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -610,20 +612,25 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
|
|||
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
|
||||
}
|
||||
|
||||
static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, PNG_CONST png_byte *palette)
|
||||
static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, const boolean palette)
|
||||
{
|
||||
const png_byte png_interlace = PNG_INTERLACE_NONE; //PNG_INTERLACE_ADAM7
|
||||
if (palette)
|
||||
{
|
||||
png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette
|
||||
const png_byte *pal = palette;
|
||||
png_uint_16 i;
|
||||
|
||||
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
|
||||
? pLocalPalette
|
||||
: pMasterPalette);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
png_PLTE[i].red = *pal; pal++;
|
||||
png_PLTE[i].green = *pal; pal++;
|
||||
png_PLTE[i].blue = *pal; pal++;
|
||||
png_PLTE[i].red = pal[i].s.red;
|
||||
png_PLTE[i].green = pal[i].s.green;
|
||||
png_PLTE[i].blue = pal[i].s.blue;
|
||||
}
|
||||
|
||||
png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE,
|
||||
png_interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
png_write_info_before_PLTE(png_ptr, png_info_ptr);
|
||||
|
@ -924,7 +931,7 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr)
|
|||
fseek(apng_FILE, oldpos, SEEK_SET);
|
||||
}
|
||||
|
||||
static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
||||
static boolean M_SetupaPNG(png_const_charp filename, boolean palette)
|
||||
{
|
||||
apng_FILE = fopen(filename,"wb+"); // + mode for reading
|
||||
if (!apng_FILE)
|
||||
|
@ -966,7 +973,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
|||
png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value);
|
||||
png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value);
|
||||
|
||||
M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal);
|
||||
M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, palette);
|
||||
|
||||
M_PNGText(apng_ptr, apng_info_ptr, true);
|
||||
|
||||
|
@ -1007,9 +1014,9 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname)
|
|||
}
|
||||
|
||||
if (rendermode == render_soft)
|
||||
ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE));
|
||||
ret = M_SetupaPNG(va(pandf,pathname,freename), true);
|
||||
else
|
||||
ret = M_SetupaPNG(va(pandf,pathname,freename), NULL);
|
||||
ret = M_SetupaPNG(va(pandf,pathname,freename), false);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
@ -1215,11 +1222,10 @@ void M_StopMovie(void)
|
|||
* \param palette Palette of image data
|
||||
* \note if palette is NULL, BGR888 format
|
||||
*/
|
||||
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette)
|
||||
boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop png_info_ptr;
|
||||
PNG_CONST png_byte *PLTE = (const png_byte *)palette;
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
#ifdef USE_FAR_KEYWORD
|
||||
jmp_buf jmpbuf;
|
||||
|
@ -1282,7 +1288,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
|
|||
png_set_compression_strategy(png_ptr, cv_zlib_strategy.value);
|
||||
png_set_compression_window_bits(png_ptr, cv_zlib_window_bits.value);
|
||||
|
||||
M_PNGhdr(png_ptr, png_info_ptr, width, height, PLTE);
|
||||
M_PNGhdr(png_ptr, png_info_ptr, width, height, palette);
|
||||
|
||||
M_PNGText(png_ptr, png_info_ptr, false);
|
||||
|
||||
|
@ -1329,7 +1335,7 @@ typedef struct
|
|||
* \param palette Palette of image data
|
||||
*/
|
||||
#if NUMSCREENS > 2
|
||||
static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height, const UINT8 *palette)
|
||||
static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height)
|
||||
{
|
||||
int i;
|
||||
size_t length;
|
||||
|
@ -1370,8 +1376,20 @@ static boolean WritePCXfile(const char *filename, const UINT8 *data, int width,
|
|||
|
||||
// write the palette
|
||||
*pack++ = 0x0c; // palette ID byte
|
||||
for (i = 0; i < 768; i++)
|
||||
*pack++ = *palette++;
|
||||
|
||||
// write color table
|
||||
{
|
||||
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
|
||||
? pLocalPalette
|
||||
: pMasterPalette);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
*pack++ = pal[i].s.red;
|
||||
*pack++ = pal[i].s.green;
|
||||
*pack++ = pal[i].s.blue;
|
||||
}
|
||||
}
|
||||
|
||||
// write output file
|
||||
length = pack - (UINT8 *)pcx;
|
||||
|
@ -1445,11 +1463,9 @@ void M_DoScreenShot(void)
|
|||
if (rendermode != render_none)
|
||||
{
|
||||
#ifdef USE_PNG
|
||||
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height,
|
||||
W_CacheLumpName(GetPalette(), PU_CACHE));
|
||||
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, true);
|
||||
#else
|
||||
ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height,
|
||||
W_CacheLumpName(GetPalette(), PU_CACHE));
|
||||
ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "tables.h"
|
||||
|
||||
#include "d_event.h" // Screenshot responder
|
||||
#include "command.h"
|
||||
|
||||
typedef enum {
|
||||
MM_OFF = 0,
|
||||
|
@ -28,6 +29,12 @@ typedef enum {
|
|||
} moviemode_t;
|
||||
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_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;
|
||||
|
||||
void M_StartMovie(void);
|
||||
void M_SaveFrame(void);
|
||||
void M_StopMovie(void);
|
||||
|
@ -57,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension);
|
|||
boolean FIL_CheckExtension(const char *in);
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette);
|
||||
boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette);
|
||||
#endif
|
||||
|
||||
extern boolean takescreenshot;
|
||||
|
|
|
@ -1145,7 +1145,7 @@ void A_JetJawChomp(mobj_t *actor)
|
|||
if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)
|
||||
|| actor->target->health <= 0 || !P_CheckSight(actor, actor->target))
|
||||
{
|
||||
P_SetMobjState(actor, actor->info->spawnstate);
|
||||
P_SetMobjStateNF(actor, actor->info->spawnstate);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3170,6 +3170,8 @@ void A_Invincibility(mobj_t *actor)
|
|||
S_StopMusic();
|
||||
if (mariomode)
|
||||
G_GhostAddColor(GHC_INVINCIBLE);
|
||||
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
|
||||
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
|
||||
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
|
||||
}
|
||||
}
|
||||
|
@ -3208,6 +3210,8 @@ void A_SuperSneakers(mobj_t *actor)
|
|||
S_StopMusic();
|
||||
S_ChangeMusicInternal("_shoes", false);
|
||||
}
|
||||
strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12);
|
||||
S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4182,12 +4186,15 @@ void A_SignPlayer(mobj_t *actor)
|
|||
actor->frame += Color_Opposite[actor->target->player->skincolor*2+1];
|
||||
}
|
||||
|
||||
// spawn an overlay of the player's face.
|
||||
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
|
||||
P_SetTarget(&ov->target, actor);
|
||||
ov->color = actor->target->player->skincolor;
|
||||
ov->skin = skin;
|
||||
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
|
||||
if (skin->sprites[SPR2_SIGN].numframes)
|
||||
{
|
||||
// spawn an overlay of the player's face.
|
||||
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
|
||||
P_SetTarget(&ov->target, actor);
|
||||
ov->color = actor->target->player->skincolor;
|
||||
ov->skin = skin;
|
||||
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_OverlayThink
|
||||
|
@ -4517,7 +4524,7 @@ void A_MinusDigging(mobj_t *actor)
|
|||
|
||||
// If we're close enough to our target, pop out of the ground
|
||||
if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) < actor->radius
|
||||
&& abs(actor->target->z - actor->z) < actor->height)
|
||||
&& abs(actor->target->z - actor->z) < 2*actor->height)
|
||||
P_SetMobjState(actor, actor->info->missilestate);
|
||||
|
||||
// Snap to ground
|
||||
|
@ -5599,7 +5606,10 @@ void A_MixUp(mobj_t *actor)
|
|||
// No mix-up monitors in hide and seek or time only race.
|
||||
// The random factor is okay for other game modes, but in these, it is cripplingly unfair.
|
||||
if (gametype == GT_HIDEANDSEEK || gametype == GT_RACE)
|
||||
{
|
||||
S_StartSound(actor, sfx_lose);
|
||||
return;
|
||||
}
|
||||
|
||||
numplayers = 0;
|
||||
memset(teleported, 0, sizeof (teleported));
|
||||
|
@ -5608,7 +5618,7 @@ void A_MixUp(mobj_t *actor)
|
|||
// and grab their xyz coords
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE
|
||||
&& !players[i].exiting && !players[i].powers[pw_super])
|
||||
&& !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
|
||||
{
|
||||
if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators
|
||||
continue;
|
||||
|
@ -5727,7 +5737,7 @@ void A_MixUp(mobj_t *actor)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && players[i].playerstate == PST_LIVE
|
||||
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super])
|
||||
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
|
||||
{
|
||||
if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators
|
||||
continue;
|
||||
|
@ -5777,7 +5787,7 @@ void A_MixUp(mobj_t *actor)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && players[i].playerstate == PST_LIVE
|
||||
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super])
|
||||
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
|
||||
{
|
||||
if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators
|
||||
continue;
|
||||
|
@ -5807,7 +5817,7 @@ void A_MixUp(mobj_t *actor)
|
|||
if (teleported[i])
|
||||
{
|
||||
if (playeringame[i] && players[i].playerstate == PST_LIVE
|
||||
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super])
|
||||
&& players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE)
|
||||
{
|
||||
if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators
|
||||
continue;
|
||||
|
@ -5949,7 +5959,7 @@ void A_RecyclePowers(mobj_t *actor)
|
|||
|
||||
for (j = 0; j < NUMPOWERS; j++)
|
||||
{
|
||||
if (j == pw_flashing || j == pw_underwater || j == pw_spacetime
|
||||
if (j == pw_flashing || j == pw_underwater || j == pw_spacetime || j == pw_carry
|
||||
|| j == pw_tailsfly || j == pw_extralife || j == pw_nocontrol || j == pw_super)
|
||||
continue;
|
||||
players[recv_pl].powers[j] = powers[send_pl][j];
|
||||
|
@ -8235,7 +8245,7 @@ void A_OrbitNights(mobj_t* actor)
|
|||
#endif
|
||||
|
||||
if (!actor->target || !actor->target->player ||
|
||||
!(actor->target->player->pflags & PF_NIGHTSMODE) || !actor->target->player->nightstime
|
||||
!(actor->target->player->powers[pw_carry] == CR_NIGHTSMODE) || !actor->target->player->nightstime
|
||||
// Also remove this object if they no longer have a NiGHTS helper
|
||||
|| (ishelper && !actor->target->player->powers[pw_nights_helper]))
|
||||
{
|
||||
|
|
|
@ -1776,9 +1776,9 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
|
|||
case MT_SCORE:
|
||||
case MT_DROWNNUMBERS:
|
||||
case MT_GOTEMERALD:
|
||||
case MT_LOCKON:
|
||||
case MT_TAG:
|
||||
case MT_GOTFLAG:
|
||||
case MT_GOTFLAG2:
|
||||
case MT_HOOP:
|
||||
case MT_HOOPCOLLIDE:
|
||||
case MT_NIGHTSCORE:
|
||||
|
@ -2061,6 +2061,33 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
|
|||
P_RemoveThinker(&nobaddies->thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// P_IsObjectOnRealGround
|
||||
//
|
||||
// Helper function for T_EachTimeThinker
|
||||
// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS
|
||||
// I'll consider whether to make this a more globally accessible function or whatever in future
|
||||
// -- Monster Iestyn
|
||||
//
|
||||
static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec)
|
||||
{
|
||||
// Is the object in reverse gravity?
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
// Detect if the player is on the ceiling.
|
||||
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
|
||||
return true;
|
||||
}
|
||||
// Nope!
|
||||
else
|
||||
{
|
||||
// Detect if the player is on the floor.
|
||||
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// P_HavePlayersEnteredArea
|
||||
//
|
||||
|
@ -2113,6 +2140,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
boolean inAndOut = false;
|
||||
boolean floortouch = false;
|
||||
fixed_t bottomheight, topheight;
|
||||
msecnode_t *node;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -2174,7 +2202,23 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
if ((netgame || multiplayer) && players[j].spectator)
|
||||
continue;
|
||||
|
||||
if (players[j].mo->subsector->sector != targetsec)
|
||||
if (players[j].mo->subsector->sector == targetsec)
|
||||
;
|
||||
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
for (node = players[j].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == targetsec)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
|
||||
|
@ -2224,10 +2268,30 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
|||
if ((netgame || multiplayer) && players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (players[i].mo->subsector->sector != sec)
|
||||
if (players[i].mo->subsector->sector == sec)
|
||||
;
|
||||
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == sec)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
if (floortouch == true && P_IsObjectOnGroundIn(players[i].mo, sec))
|
||||
if (!(players[i].mo->subsector->sector == sec
|
||||
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
|
||||
continue;
|
||||
|
||||
if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec))
|
||||
{
|
||||
if (i & 1)
|
||||
eachtime->var2s[i/2] |= 1;
|
||||
|
@ -2557,6 +2621,12 @@ void T_PlaneDisplace(planedisplace_t *pd)
|
|||
direction = (control->floorheight > pd->last_height) ? 1 : -1;
|
||||
diff = FixedMul(control->floorheight-pd->last_height, pd->speed);
|
||||
|
||||
if (pd->reverse) // reverse direction?
|
||||
{
|
||||
direction *= -1;
|
||||
diff *= -1;
|
||||
}
|
||||
|
||||
if (pd->type == pd_floor || pd->type == pd_both)
|
||||
T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor
|
||||
if (pd->type == pd_ceiling || pd->type == pd_both)
|
||||
|
@ -2923,7 +2993,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
|||
fixed_t leftx, rightx;
|
||||
fixed_t topy, bottomy;
|
||||
fixed_t topz, bottomz;
|
||||
fixed_t widthfactor, heightfactor;
|
||||
fixed_t widthfactor = FRACUNIT, heightfactor = FRACUNIT;
|
||||
fixed_t a, b, c;
|
||||
mobjtype_t type = MT_ROCKCRUMBLE1;
|
||||
fixed_t spacing = (32<<FRACBITS);
|
||||
|
@ -3240,14 +3310,6 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL))
|
||||
{
|
||||
mobj_t *tokenobj = P_SpawnMobj(sector->soundorg.x, sector->soundorg.y, topheight, MT_TOKEN);
|
||||
P_SetTarget(&thing->tracer, tokenobj);
|
||||
P_SetTarget(&tokenobj->target, thing);
|
||||
P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate);
|
||||
}
|
||||
|
||||
// "Powerup rise" sound
|
||||
S_StartSound(puncher, sfx_mario9); // Puncher is "close enough"
|
||||
}
|
||||
|
|
133
src/p_inter.c
133
src/p_inter.c
|
@ -257,6 +257,8 @@ void P_DoMatchSuper(player_t *player)
|
|||
S_StopMusic();
|
||||
if (mariomode)
|
||||
G_GhostAddColor(GHC_INVINCIBLE);
|
||||
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
|
||||
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
|
||||
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
|
||||
}
|
||||
|
||||
|
@ -278,6 +280,8 @@ void P_DoMatchSuper(player_t *player)
|
|||
S_StopMusic();
|
||||
if (mariomode)
|
||||
G_GhostAddColor(GHC_INVINCIBLE);
|
||||
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
|
||||
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
|
||||
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
|
||||
}
|
||||
}
|
||||
|
@ -367,11 +371,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
}
|
||||
|
||||
if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|
||||
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|
||||
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|
||||
|| ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|
||||
|| player->powers[pw_invulnerability] || player->powers[pw_super]
|
||||
|| elementalpierce) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
|
@ -379,9 +383,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
{
|
||||
if (elementalpierce == 2)
|
||||
P_DoBubbleBounce(player);
|
||||
else
|
||||
else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
|
||||
toucher->momz = -toucher->momz;
|
||||
}
|
||||
if (player->pflags & PF_BOUNCING)
|
||||
P_DoAbilityBounce(player, false);
|
||||
toucher->momx = -toucher->momx;
|
||||
toucher->momy = -toucher->momy;
|
||||
P_DamageMobj(special, toucher, toucher, 1, 0);
|
||||
|
@ -406,7 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
////////////////////////////////////////////////////////
|
||||
/////ENEMIES!!//////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////
|
||||
if (special->type == MT_GSNAPPER && !(((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
if (special->type == MT_GSNAPPER && !(((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce)
|
||||
&& toucher->z < special->z + special->height && toucher->z + toucher->height > special->z)
|
||||
{
|
||||
|
@ -416,23 +422,30 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
else if (special->type == MT_SHARP
|
||||
&& ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2)))
|
||||
{
|
||||
// Cannot hit sharp from above or when red and angry
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
if (player->pflags & PF_BOUNCING)
|
||||
{
|
||||
toucher->momz = -toucher->momz;
|
||||
P_DoAbilityBounce(player, false);
|
||||
}
|
||||
else // Cannot hit sharp from above or when red and angry
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
}
|
||||
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|
||||
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|
||||
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|
||||
|| ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|
||||
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1))
|
||||
{
|
||||
if (elementalpierce == 2)
|
||||
P_DoBubbleBounce(player);
|
||||
else
|
||||
else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
|
||||
toucher->momz = -toucher->momz;
|
||||
}
|
||||
if (player->pflags & PF_BOUNCING)
|
||||
P_DoAbilityBounce(player, false);
|
||||
|
||||
P_DamageMobj(special, toucher, toucher, 1, 0);
|
||||
}
|
||||
|
@ -557,21 +570,25 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
// Gameplay related collectibles //
|
||||
// ***************************** //
|
||||
// Special Stage Token
|
||||
case MT_EMMY:
|
||||
case MT_TOKEN:
|
||||
if (player->bot)
|
||||
return;
|
||||
tokenlist += special->health;
|
||||
|
||||
P_AddPlayerScore(player, 1000);
|
||||
|
||||
if (ALL7EMERALDS(emeralds)) // Got all 7
|
||||
{
|
||||
P_GivePlayerRings(player, 50);
|
||||
nummaprings += 50; // no cheating towards Perfect!
|
||||
if (!(netgame || multiplayer))
|
||||
{
|
||||
player->continues += 1;
|
||||
players->gotcontinue = true;
|
||||
if (P_IsLocalPlayer(player))
|
||||
S_StartSound(NULL, sfx_s3kac);
|
||||
}
|
||||
}
|
||||
else
|
||||
token++;
|
||||
|
||||
if (special->tracer) // token BG
|
||||
P_RemoveMobj(special->tracer);
|
||||
break;
|
||||
|
||||
// Emerald Hunt
|
||||
|
@ -756,12 +773,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
else //Initial transformation. Don't allow second chances in special stages!
|
||||
{
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
return;
|
||||
|
||||
S_StartSound(toucher, sfx_supert);
|
||||
}
|
||||
if (!(netgame || multiplayer) && !(player->pflags & PF_NIGHTSMODE))
|
||||
if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
P_SetTarget(&special->tracer, toucher);
|
||||
P_NightserizePlayer(player, special->health); // Transform!
|
||||
return;
|
||||
|
@ -885,7 +902,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
// make sure everything is as it should be, THEN take rings from players in special stages
|
||||
if (player->pflags & PF_NIGHTSMODE && !toucher->target)
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target)
|
||||
return;
|
||||
|
||||
if (player->mare != special->threshold) // wrong mare
|
||||
|
@ -923,7 +940,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (player->bumpertime < TICRATE/4)
|
||||
{
|
||||
S_StartSound(toucher, special->info->seesound);
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
player->bumpertime = TICRATE/2;
|
||||
if (special->threshold > 0)
|
||||
|
@ -979,14 +996,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
return;
|
||||
case MT_NIGHTSSUPERLOOP:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
player->powers[pw_nights_superloop] = (UINT16)special->info->speed;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
|
||||
players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed;
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
|
@ -1001,14 +1018,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
break;
|
||||
case MT_NIGHTSDRILLREFILL:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
player->drillmeter = special->info->speed;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
|
||||
players[i].drillmeter = special->info->speed;
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
|
@ -1023,7 +1040,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
break;
|
||||
case MT_NIGHTSHELPER:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
|
@ -1037,7 +1054,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
{
|
||||
mobj_t *flickyobj;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mo && players[i].pflags & PF_NIGHTSMODE) {
|
||||
if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) {
|
||||
players[i].powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, players[i].mo);
|
||||
|
@ -1055,7 +1072,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
break;
|
||||
case MT_NIGHTSEXTRATIME:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
|
@ -1066,7 +1083,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
players[i].nightstime += special->info->speed;
|
||||
players[i].startedtime += special->info->speed;
|
||||
|
@ -1085,7 +1102,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
break;
|
||||
case MT_NIGHTSLINKFREEZE:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
|
@ -1095,7 +1112,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed;
|
||||
players[i].linktimer = 2*TICRATE;
|
||||
|
@ -1153,7 +1170,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (G_IsSpecialStage(gamemap))
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
|
||||
players[i].drillmeter += TICRATE/2;
|
||||
}
|
||||
else if (player->bot)
|
||||
|
@ -1336,9 +1353,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
toucher->momz = -toucher->momz;
|
||||
if (player->pflags & PF_GLIDING)
|
||||
{
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
|
||||
}
|
||||
player->homing = 0;
|
||||
|
||||
// Play a bounce sound?
|
||||
S_StartSound(toucher, special->info->painsound);
|
||||
|
@ -1346,7 +1364,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
case MT_BLACKEGGMAN_GOOPFIRE:
|
||||
if (toucher->state != &states[S_PLAY_PAIN] && !player->powers[pw_flashing])
|
||||
if (!player->powers[pw_flashing])
|
||||
{
|
||||
toucher->momx = 0;
|
||||
toucher->momy = 0;
|
||||
|
@ -1354,13 +1372,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (toucher->momz != 0)
|
||||
special->momz = toucher->momz;
|
||||
|
||||
player->powers[pw_ingoop] = 2;
|
||||
|
||||
if (player->powers[pw_carry] == CR_GENERIC)
|
||||
{
|
||||
P_SetTarget(&toucher->tracer, NULL);
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
}
|
||||
player->powers[pw_carry] = CR_BRAKGOOP;
|
||||
P_SetTarget(&toucher->tracer, special);
|
||||
|
||||
P_ResetPlayer(player);
|
||||
|
||||
|
@ -1372,8 +1385,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_SetMobjState(special->target, special->target->info->raisestate);
|
||||
}
|
||||
}
|
||||
else
|
||||
player->powers[pw_ingoop] = 0;
|
||||
return;
|
||||
case MT_EGGSHIELD:
|
||||
{
|
||||
|
@ -1403,17 +1414,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
toucher->momz = -toucher->momz;
|
||||
if (player->pflags & PF_GLIDING)
|
||||
{
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
|
||||
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
|
||||
}
|
||||
player->homing = 0;
|
||||
|
||||
// Play a bounce sound?
|
||||
S_StartSound(toucher, special->info->painsound);
|
||||
return;
|
||||
}
|
||||
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|
||||
else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
|| ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|
||||
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|
||||
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
|
@ -1463,7 +1475,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
{
|
||||
player->powers[pw_carry] = CR_MACESPIN;
|
||||
S_StartSound(toucher, sfx_spin);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_SPIN);
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_ROLL);
|
||||
}
|
||||
else
|
||||
player->powers[pw_carry] = CR_GENERIC;
|
||||
|
@ -2093,7 +2105,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
{
|
||||
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
|
||||
G_StopMetalRecording();
|
||||
if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
|
||||
if (gametype == GT_MATCH // note, no team match suicide penalty
|
||||
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
|
||||
{ // Suicide penalty
|
||||
if (target->player->score >= 50)
|
||||
|
@ -2597,7 +2609,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
|||
}
|
||||
|
||||
player->powers[pw_flashing] = flashingtics;
|
||||
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_PAIN);
|
||||
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN);
|
||||
S_StartSound(target, sfx_nghurt);
|
||||
|
||||
if (oldnightstime > 10*TICRATE
|
||||
|
@ -2724,7 +2736,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
|
|||
|
||||
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||
{
|
||||
player->pflags &= ~(PF_SLIDING|PF_NIGHTSMODE);
|
||||
player->pflags &= ~PF_SLIDING;
|
||||
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
|
||||
|
@ -2820,10 +2832,7 @@ static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *so
|
|||
|
||||
P_InstaThrust(player->mo, ang, fallbackspeed);
|
||||
|
||||
if (player->charflags & SF_SUPERANIMS)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_STUN);
|
||||
else
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STUN);
|
||||
|
||||
P_ResetPlayer(player);
|
||||
|
||||
|
@ -2886,7 +2895,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, cv_match_scoring.value == 1 ? 25 : 50);
|
||||
P_AddPlayerScore(source->player, 50);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3069,7 +3078,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if (player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
|
||||
if (!(target->player->powers[pw_carry] == CR_NIGHTSMODE || target->player->pflags & PF_NIGHTSFALL) && (maptol & TOL_NIGHTS))
|
||||
return false;
|
||||
|
||||
switch (damagetype)
|
||||
|
@ -3091,7 +3100,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
}
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS damage handling
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
@ -3119,14 +3128,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false; // Don't get hurt by fire generated from friends.
|
||||
}
|
||||
|
||||
// Sudden-Death mode
|
||||
if (source && source->type == MT_PLAYER)
|
||||
{
|
||||
if ((gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) && cv_suddendeath.value
|
||||
&& !player->powers[pw_flashing] && !player->powers[pw_invulnerability])
|
||||
damagetype = DMG_INSTAKILL;
|
||||
}
|
||||
|
||||
// Player hits another player
|
||||
if (!force && source && source->player)
|
||||
{
|
||||
|
|
|
@ -72,7 +72,6 @@
|
|||
|
||||
// both the head and tail of the thinker list
|
||||
extern thinker_t thinkercap;
|
||||
extern INT32 runcount;
|
||||
|
||||
void P_InitThinkers(void);
|
||||
void P_AddThinker(thinker_t *thinker);
|
||||
|
@ -130,6 +129,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam);
|
|||
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
void P_SlideCameraMove(camera_t *thiscam);
|
||||
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
|
||||
pflags_t P_GetJumpFlags(player_t *player);
|
||||
boolean P_PlayerInPain(player_t *player);
|
||||
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
|
||||
void P_ResetPlayer(player_t *player);
|
||||
|
@ -150,11 +150,16 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings);
|
|||
void P_GivePlayerLives(player_t *player, INT32 numlives);
|
||||
UINT8 P_GetNextEmerald(void);
|
||||
void P_GiveEmerald(boolean spawnObj);
|
||||
#if 0
|
||||
void P_ResetScore(player_t *player);
|
||||
#else
|
||||
#define P_ResetScore(player) player->scoreadd = 0
|
||||
#endif
|
||||
boolean P_AutoPause(void);
|
||||
|
||||
void P_DoJumpShield(player_t *player);
|
||||
void P_DoBubbleBounce(player_t *player);
|
||||
void P_DoAbilityBounce(player_t *player, boolean changemomz);
|
||||
void P_BlackOw(player_t *player);
|
||||
void P_ElementalFire(player_t *player, boolean cropcircle);
|
||||
|
||||
|
@ -169,12 +174,16 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move);
|
|||
fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);
|
||||
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
|
||||
|
||||
boolean P_LookForEnemies(player_t *player, boolean nonenemies);
|
||||
mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
|
||||
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
|
||||
void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
|
||||
boolean P_SuperReady(player_t *player);
|
||||
void P_DoJump(player_t *player, boolean soundandstate);
|
||||
#if 0
|
||||
boolean P_AnalogMove(player_t *player);
|
||||
#else
|
||||
#define P_AnalogMove(player) (player->pflags & PF_ANALOGMODE)
|
||||
#endif
|
||||
boolean P_TransferToNextMare(player_t *player);
|
||||
UINT8 P_FindLowestMare(void);
|
||||
void P_FindEmerald(void);
|
||||
|
|
143
src/p_map.c
143
src/p_map.c
|
@ -115,7 +115,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
fixed_t offx, offy;
|
||||
fixed_t vertispeed = spring->info->mass;
|
||||
fixed_t horizspeed = spring->info->damage;
|
||||
UINT8 jumping, secondjump;
|
||||
UINT8 secondjump;
|
||||
|
||||
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
|
||||
return false;
|
||||
|
@ -124,20 +124,25 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
if (object->player && object->player->spectator)
|
||||
return false;
|
||||
|
||||
if (object->player && (object->player->pflags & PF_NIGHTSMODE))
|
||||
if (object->player && (object->player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
{
|
||||
/*Someone want to make these work like bumpers?*/
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you.
|
||||
#endif
|
||||
if (object->player
|
||||
&& ((object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY)
|
||||
|| (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2)))
|
||||
{
|
||||
S_StartSound(object, sfx_s3k8b);
|
||||
horizspeed = FixedMul(horizspeed, (4*FRACUNIT)/3);
|
||||
vertispeed = FixedMul(vertispeed, (6*FRACUNIT)/5); // aprox square root of above
|
||||
}
|
||||
|
||||
object->eflags |= MFE_SPRUNG; // apply this flag asap!
|
||||
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
|
||||
|
||||
if (horizspeed && vertispeed) // Mimic SA
|
||||
if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA
|
||||
{
|
||||
object->momx = object->momy = 0;
|
||||
P_TryMove(object, spring->x, spring->y, true);
|
||||
|
@ -203,32 +208,36 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
}
|
||||
|
||||
pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY); // I still need these.
|
||||
jumping = object->player->jumping;
|
||||
pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY|PF_BOUNCING); // I still need these.
|
||||
secondjump = object->player->secondjump;
|
||||
P_ResetPlayer(object->player);
|
||||
|
||||
if (spring->info->painchance)
|
||||
{
|
||||
object->player->pflags |= PF_JUMPED;
|
||||
object->player->pflags |= P_GetJumpFlags(object->player);
|
||||
P_SetPlayerMobjState(object, S_PLAY_JUMP);
|
||||
}
|
||||
else if (P_MobjFlip(object)*vertispeed > 0)
|
||||
P_SetPlayerMobjState(object, S_PLAY_SPRING);
|
||||
else if (P_MobjFlip(object)*vertispeed < 0)
|
||||
P_SetPlayerMobjState(object, S_PLAY_FALL);
|
||||
else // horizontal spring
|
||||
else if (!vertispeed || (pflags & PF_BOUNCING)) // horizontal spring or bouncing
|
||||
{
|
||||
if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL))
|
||||
if ((pflags & PF_BOUNCING)
|
||||
|| (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL)))
|
||||
{
|
||||
object->player->pflags |= pflags;
|
||||
object->player->jumping = jumping;
|
||||
object->player->secondjump = secondjump;
|
||||
}
|
||||
else
|
||||
P_SetPlayerMobjState(object, S_PLAY_WALK);
|
||||
}
|
||||
else if (P_MobjFlip(object)*vertispeed > 0)
|
||||
P_SetPlayerMobjState(object, S_PLAY_SPRING);
|
||||
else
|
||||
P_SetPlayerMobjState(object, S_PLAY_FALL);
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -324,9 +333,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
|||
if (tails->bot == 1)
|
||||
return;
|
||||
|
||||
if (sonic->pflags & PF_NIGHTSMODE)
|
||||
return;
|
||||
|
||||
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
|
||||
return; // Both should be in same gravity
|
||||
|
||||
|
@ -377,6 +383,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
|||
else {
|
||||
if (sonic-players == consoleplayer && botingame)
|
||||
CV_SetValue(&cv_analog2, true);
|
||||
P_SetTarget(&sonic->mo->tracer, NULL);
|
||||
sonic->powers[pw_carry] = CR_NONE;
|
||||
}
|
||||
}
|
||||
|
@ -460,9 +467,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true;
|
||||
}
|
||||
|
||||
// CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
|
||||
// SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
|
||||
if ((tmthing->player)
|
||||
&& (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
|
||||
&& (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
|
||||
&& (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
|
||||
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|
||||
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
|
||||
|
@ -499,7 +506,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
// Don't collide with your buddies while NiGHTS-flying.
|
||||
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
|
||||
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE)))
|
||||
&& ((tmthing->player->powers[pw_carry] == CR_NIGHTSMODE) || (thing->player->powers[pw_carry] == CR_NIGHTSMODE)))
|
||||
return true;
|
||||
|
||||
blockdist = thing->radius + tmthing->radius;
|
||||
|
@ -785,7 +792,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
{
|
||||
// Hop on the missile for a ride!
|
||||
thing->player->powers[pw_carry] = CR_GENERIC;
|
||||
thing->player->pflags &= ~PF_JUMPED;
|
||||
thing->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
P_SetTarget(&thing->tracer, tmthing);
|
||||
P_SetTarget(&tmthing->target, thing); // Set owner to the player
|
||||
P_SetTarget(&tmthing->tracer, NULL); // Disable homing-ness
|
||||
|
@ -896,7 +903,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
// must be flying in the SAME DIRECTION as the last time you came through.
|
||||
// not (your direction) xor (stored direction)
|
||||
// In other words, you can't u-turn and respawn rings near the drone.
|
||||
if (pl->bonustime && (pl->pflags & PF_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && (
|
||||
if (pl->bonustime && (pl->powers[pw_carry] == CR_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && (
|
||||
!(pl->anotherflyangle >= 90 && pl->anotherflyangle <= 270)
|
||||
^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270)
|
||||
))
|
||||
|
@ -928,11 +935,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (tmthing->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
|
||||
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz)
|
||||
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
||||
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
}
|
||||
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
|
||||
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz)
|
||||
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
||||
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP)))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
}
|
||||
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
|
||||
|
@ -940,14 +949,55 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
|
||||
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale))
|
||||
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
|
||||
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
|
||||
P_DamageMobj(tmthing, thing, thing, 1, 0);
|
||||
}
|
||||
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
||||
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale))
|
||||
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
||||
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
|
||||
P_DamageMobj(tmthing, thing, thing, 1, 0);
|
||||
}
|
||||
|
||||
if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player
|
||||
{
|
||||
fixed_t bottomz, topz;
|
||||
bottomz = tmthing->z;
|
||||
topz = tmthing->z + tmthing->height;
|
||||
if (tmthing->eflags & MFE_VERTICALFLIP)
|
||||
bottomz -= FixedMul(FRACUNIT, tmthing->scale);
|
||||
else
|
||||
topz += FixedMul(FRACUNIT, tmthing->scale);
|
||||
|
||||
if (thing->z + thing->height > bottomz // above bottom
|
||||
&& thing->z < topz) // below top
|
||||
{ // don't check angle, the player was clearly in the way in this case
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||
}
|
||||
}
|
||||
else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player)
|
||||
{
|
||||
fixed_t bottomz, topz;
|
||||
bottomz = thing->z;
|
||||
topz = thing->z + thing->height;
|
||||
if (thing->eflags & MFE_VERTICALFLIP)
|
||||
bottomz -= FixedMul(FRACUNIT, thing->scale);
|
||||
else
|
||||
topz += FixedMul(FRACUNIT, thing->scale);
|
||||
|
||||
if (tmthing->z + tmthing->height > bottomz // above bottom
|
||||
&& tmthing->z < topz // below top
|
||||
&& !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer
|
||||
{ // use base as a reference point to determine what angle you touched the spike at
|
||||
angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y);
|
||||
angle_t diffangle = thing->angle - touchangle;
|
||||
if (diffangle > ANGLE_180)
|
||||
diffangle = InvAngle(diffangle);
|
||||
if (diffangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked!
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->flags & MF_PUSHABLE)
|
||||
{
|
||||
if (tmthing->type == MT_FAN || tmthing->type == MT_STEAM)
|
||||
|
@ -1005,7 +1055,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->player-players == consoleplayer && botingame)
|
||||
CV_SetValue(&cv_analog2, true);
|
||||
if (thing->player->powers[pw_carry] == CR_PLAYER)
|
||||
{
|
||||
P_SetTarget(&thing->tracer, NULL);
|
||||
thing->player->powers[pw_carry] = CR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->player)
|
||||
|
@ -1063,11 +1116,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->flags & MF_MONITOR
|
||||
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|
||||
|| ((tmthing->player->pflags & PF_JUMPED)
|
||||
&& (tmthing->player->pflags & PF_FORCEJUMPDAMAGE
|
||||
|| !(tmthing->player->charflags & SF_NOJUMPSPIN)
|
||||
&& (!(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->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))
|
||||
|| elementalpierce))
|
||||
{
|
||||
|
@ -1084,11 +1136,15 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
{
|
||||
if (elementalpierce == 2)
|
||||
P_DoBubbleBounce(player);
|
||||
else
|
||||
else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
|
||||
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
|
||||
}
|
||||
if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough.
|
||||
{
|
||||
if (player->pflags & PF_BOUNCING)
|
||||
P_DoAbilityBounce(player, false);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
*z -= *momz; // to ensure proper collision.
|
||||
}
|
||||
|
@ -1100,16 +1156,17 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
||||
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
||||
}
|
||||
else if (tmthing->flags & MF_SPRING && (thing->player || thing->flags & MF_PUSHABLE))
|
||||
; // Fix a few nasty spring-jumping bugs that happen sometimes.
|
||||
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
||||
// unless it's a CTF team monitor and you're on the wrong team
|
||||
else if (thing->flags & MF_MONITOR && tmthing->player
|
||||
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|
||||
|| ((tmthing->player->pflags & PF_JUMPED)
|
||||
&& (tmthing->player->pflags & PF_FORCEJUMPDAMAGE
|
||||
|| !(tmthing->player->charflags & SF_NOJUMPSPIN)
|
||||
&& (!(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->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)))
|
||||
&& !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2)))
|
||||
;
|
||||
|
@ -1139,11 +1196,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||
|
||||
if (thing->flags & MF_SPRING)
|
||||
;
|
||||
// block only when jumping not high enough,
|
||||
// (dont climb max. 24units while already in air)
|
||||
// since return false doesn't handle momentum properly,
|
||||
// we lie to P_TryMove() so it's always too high
|
||||
if (tmthing->player && tmthing->z + tmthing->height > topz
|
||||
else if (tmthing->player && tmthing->z + tmthing->height > topz
|
||||
&& tmthing->z + tmthing->height < tmthing->ceilingz)
|
||||
{
|
||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||
|
@ -1155,8 +1214,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
#endif
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
}
|
||||
else if (thing->flags & MF_SPRING)
|
||||
;
|
||||
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
||||
{
|
||||
tmceilingz = topz;
|
||||
|
@ -1185,11 +1242,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||
|
||||
if (thing->flags & MF_SPRING)
|
||||
;
|
||||
// block only when jumping not high enough,
|
||||
// (dont climb max. 24units while already in air)
|
||||
// since return false doesn't handle momentum properly,
|
||||
// we lie to P_TryMove() so it's always too high
|
||||
if (tmthing->player && tmthing->z < topz
|
||||
else if (tmthing->player && tmthing->z < topz
|
||||
&& tmthing->z > tmthing->floorz)
|
||||
{
|
||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||
|
@ -1201,8 +1260,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
#endif
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
}
|
||||
else if (thing->flags & MF_SPRING)
|
||||
;
|
||||
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
||||
{
|
||||
tmfloorz = topz;
|
||||
|
@ -1512,7 +1569,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
|
||||
;
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && thing->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !thing->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !thing->player)
|
||||
|| rover->flags & FF_QUICKSAND))
|
||||
continue;
|
||||
|
||||
|
@ -2890,7 +2947,7 @@ isblocking:
|
|||
slidemo->player->climbing = 5;
|
||||
}
|
||||
|
||||
slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_THOKKED);
|
||||
slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED);
|
||||
slidemo->player->glidetime = 0;
|
||||
slidemo->player->secondjump = 0;
|
||||
|
||||
|
|
523
src/p_mobj.c
523
src/p_mobj.c
|
@ -187,32 +187,41 @@ static void P_CyclePlayerMobjState(mobj_t *mobj)
|
|||
|
||||
//
|
||||
// P_GetMobjSprite2
|
||||
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
|
||||
// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version.
|
||||
//
|
||||
|
||||
UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
|
||||
{
|
||||
player_t *player = mobj->player;
|
||||
skin_t *skin = ((skin_t *)mobj->skin);
|
||||
UINT8 super = (spr2 & FF_SPR2SUPER);
|
||||
|
||||
if (!skin)
|
||||
return 0;
|
||||
|
||||
while ((skin->sprites[spr2].numframes <= 0)
|
||||
while (!(skin->sprites[spr2].numframes)
|
||||
&& spr2 != SPR2_STND)
|
||||
{
|
||||
if (spr2 & FF_SPR2SUPER)
|
||||
{
|
||||
spr2 &= ~FF_SPR2SUPER;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(spr2)
|
||||
{
|
||||
case SPR2_PEEL:
|
||||
spr2 = SPR2_RUN;
|
||||
break;
|
||||
case SPR2_RUN:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_STUN:
|
||||
spr2 = SPR2_PAIN;
|
||||
break;
|
||||
case SPR2_DRWN:
|
||||
spr2 = SPR2_DEAD;
|
||||
break;
|
||||
case SPR2_DASH:
|
||||
spr2 = SPR2_SPIN;
|
||||
case SPR2_SPIN:
|
||||
spr2 = SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_GASP:
|
||||
spr2 = SPR2_SPNG;
|
||||
|
@ -221,7 +230,7 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
|
|||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN;
|
||||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_SPNG: // spring
|
||||
spr2 = SPR2_FALL;
|
||||
|
@ -233,11 +242,11 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
|
|||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
|
||||
case SPR2_FLY:
|
||||
case SPR2_FLY :
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_SWIM:
|
||||
spr2 = SPR2_FLY;
|
||||
spr2 = SPR2_FLY ;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
|
@ -247,91 +256,59 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
|
|||
spr2 = SPR2_FLY;
|
||||
break;
|
||||
case SPR2_CLMB:
|
||||
spr2 = SPR2_SPIN;
|
||||
spr2 = SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_CLNG:
|
||||
spr2 = SPR2_CLMB;
|
||||
break;
|
||||
|
||||
case SPR2_FLT :
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_FRUN:
|
||||
spr2 = SPR2_RUN ;
|
||||
break;
|
||||
|
||||
case SPR2_DASH:
|
||||
spr2 = SPR2_FRUN;
|
||||
break;
|
||||
|
||||
case SPR2_BNCE:
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
case SPR2_BLND:
|
||||
spr2 = SPR2_ROLL;
|
||||
break;
|
||||
|
||||
case SPR2_TWIN:
|
||||
spr2 = SPR2_SPIN;
|
||||
spr2 = SPR2_ROLL;
|
||||
break;
|
||||
|
||||
case SPR2_MLEE:
|
||||
spr2 = SPR2_TWIN;
|
||||
break;
|
||||
|
||||
// Super sprites fallback to regular sprites
|
||||
case SPR2_SWLK:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_SRUN:
|
||||
spr2 = SPR2_RUN;
|
||||
break;
|
||||
case SPR2_SPEE:
|
||||
spr2 = SPR2_PEEL;
|
||||
break;
|
||||
case SPR2_SPAN:
|
||||
spr2 = SPR2_PAIN;
|
||||
break;
|
||||
case SPR2_SSTN:
|
||||
spr2 = SPR2_SPAN;
|
||||
break;
|
||||
case SPR2_SDTH:
|
||||
spr2 = SPR2_DEAD;
|
||||
break;
|
||||
case SPR2_SDRN:
|
||||
spr2 = SPR2_DRWN;
|
||||
break;
|
||||
case SPR2_SSPN:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_SGSP:
|
||||
spr2 = SPR2_GASP;
|
||||
break;
|
||||
case SPR2_SJMP:
|
||||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN;
|
||||
break;
|
||||
case SPR2_SSPG:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_SFAL:
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
case SPR2_SEDG:
|
||||
spr2 = SPR2_EDGE;
|
||||
break;
|
||||
case SPR2_SRID:
|
||||
spr2 = SPR2_RIDE;
|
||||
break;
|
||||
case SPR2_SFLT:
|
||||
spr2 = SPR2_SWLK;
|
||||
break;
|
||||
|
||||
// NiGHTS sprites.
|
||||
case SPR2_NTRN:
|
||||
spr2 = SPR2_TRNS;
|
||||
break;
|
||||
case SPR2_NSTD:
|
||||
spr2 = SPR2_SSTD;
|
||||
spr2 = SPR2_STND;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
case SPR2_NFLT:
|
||||
spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice.
|
||||
spr2 = SPR2_FLT ;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
case SPR2_NSTN:
|
||||
spr2 = SPR2_STUN;
|
||||
break;
|
||||
case SPR2_NPUL:
|
||||
spr2 = SPR2_NFLT;
|
||||
break;
|
||||
case SPR2_NPAN:
|
||||
spr2 = SPR2_NPUL;
|
||||
spr2 = SPR2_NSTN;
|
||||
break;
|
||||
case SPR2_NATK:
|
||||
spr2 = SPR2_SSPN;
|
||||
spr2 = SPR2_ROLL;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
/*case SPR2_NGT0:
|
||||
spr2 = SPR2_STND;
|
||||
spr2 = SPR2_NFLT;
|
||||
break;*/
|
||||
case SPR2_NGT1:
|
||||
case SPR2_NGT7:
|
||||
|
@ -390,7 +367,10 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
|
|||
spr2 = SPR2_STND;
|
||||
break;
|
||||
}
|
||||
|
||||
spr2 |= super;
|
||||
}
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
|
@ -427,45 +407,17 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
|
||||
return P_SetPlayerMobjState(player->mo, S_PLAY_FLY);
|
||||
|
||||
// Catch state changes for Super Sonic
|
||||
if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS))
|
||||
// Catch SF_NOSUPERSPIN jumps for Supers
|
||||
if (player->powers[pw_super] && (player->charflags & SF_NOSUPERSPIN))
|
||||
{
|
||||
switch (state)
|
||||
if (state == S_PLAY_JUMP)
|
||||
{
|
||||
case S_PLAY_STND:
|
||||
case S_PLAY_WAIT:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_STND);
|
||||
case S_PLAY_WALK:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_WALK);
|
||||
case S_PLAY_RUN:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_RUN);
|
||||
case S_PLAY_PEEL:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PEEL);
|
||||
case S_PLAY_PAIN:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PAIN);
|
||||
case S_PLAY_DEAD:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_DEAD);
|
||||
case S_PLAY_DRWN:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_DRWN);
|
||||
case S_PLAY_SPIN:
|
||||
if (!(player->charflags & SF_SUPERSPIN))
|
||||
return true;
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_SPIN);
|
||||
case S_PLAY_GASP:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_GASP);
|
||||
case S_PLAY_JUMP:
|
||||
if (!(player->charflags & SF_SUPERSPIN))
|
||||
return true;
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_JUMP);
|
||||
case S_PLAY_SPRING:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_SPRING);
|
||||
case S_PLAY_FALL:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_FALL);
|
||||
case S_PLAY_EDGE:
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_EDGE);
|
||||
default:
|
||||
break;
|
||||
if (player->mo->state-states == S_PLAY_WALK)
|
||||
return P_SetPlayerMobjState(mobj, S_PLAY_FLOAT);
|
||||
return true;
|
||||
}
|
||||
else if (player->mo->state-states == S_PLAY_FLOAT && state == S_PLAY_STND)
|
||||
return true;
|
||||
}
|
||||
// You were in pain state after taking a hit, and you're moving out of pain state now?
|
||||
else if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == flashingtics && state != mobj->info->painstate)
|
||||
|
@ -481,61 +433,56 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
{
|
||||
case S_PLAY_STND:
|
||||
case S_PLAY_WAIT:
|
||||
case S_PLAY_SUPER_STND:
|
||||
player->panim = PA_IDLE;
|
||||
break;
|
||||
case S_PLAY_EDGE:
|
||||
case S_PLAY_SUPER_EDGE:
|
||||
player->panim = PA_EDGE;
|
||||
break;
|
||||
case S_PLAY_WALK:
|
||||
case S_PLAY_SUPER_WALK:
|
||||
case S_PLAY_SUPER_FLOAT:
|
||||
case S_PLAY_FLOAT:
|
||||
player->panim = PA_WALK;
|
||||
break;
|
||||
case S_PLAY_RUN:
|
||||
case S_PLAY_SUPER_RUN:
|
||||
case S_PLAY_FLOAT_RUN:
|
||||
player->panim = PA_RUN;
|
||||
break;
|
||||
case S_PLAY_PEEL:
|
||||
case S_PLAY_SUPER_PEEL:
|
||||
player->panim = PA_PEEL;
|
||||
case S_PLAY_DASH:
|
||||
player->panim = PA_DASH;
|
||||
break;
|
||||
case S_PLAY_PAIN:
|
||||
case S_PLAY_SUPER_PAIN:
|
||||
case S_PLAY_SUPER_STUN:
|
||||
case S_PLAY_STUN:
|
||||
player->panim = PA_PAIN;
|
||||
break;
|
||||
case S_PLAY_SPIN:
|
||||
//case S_PLAY_DASH: -- everyone can ROLL thanks to zoom tubes...
|
||||
case S_PLAY_SUPER_SPIN:
|
||||
case S_PLAY_ROLL:
|
||||
//case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes...
|
||||
player->panim = PA_ROLL;
|
||||
break;
|
||||
case S_PLAY_JUMP:
|
||||
case S_PLAY_SUPER_JUMP:
|
||||
player->panim = PA_JUMP;
|
||||
break;
|
||||
case S_PLAY_SPRING:
|
||||
case S_PLAY_SUPER_SPRING:
|
||||
player->panim = PA_SPRING;
|
||||
break;
|
||||
case S_PLAY_FALL:
|
||||
case S_PLAY_SUPER_FALL:
|
||||
player->panim = PA_FALL;
|
||||
break;
|
||||
case S_PLAY_FLY:
|
||||
case S_PLAY_SWIM:
|
||||
case S_PLAY_GLIDE:
|
||||
case S_PLAY_BOUNCE:
|
||||
case S_PLAY_BOUNCE_LANDING:
|
||||
case S_PLAY_TWINSPIN:
|
||||
player->panim = PA_ABILITY;
|
||||
break;
|
||||
case S_PLAY_DASH: // ...but the act of SPINDASHING is charability2 specific.
|
||||
case S_PLAY_SPINDASH: // ...but the act of SPINDASHING is charability2 specific.
|
||||
case S_PLAY_FIRE:
|
||||
case S_PLAY_FIRE_FINISH:
|
||||
case S_PLAY_MELEE:
|
||||
case S_PLAY_MELEE_FINISH:
|
||||
case S_PLAY_MELEE_LANDING:
|
||||
player->panim = PA_ABILITY2;
|
||||
break;
|
||||
case S_PLAY_RIDE:
|
||||
case S_PLAY_SUPER_RIDE:
|
||||
player->panim = PA_RIDE;
|
||||
break;
|
||||
default:
|
||||
|
@ -562,7 +509,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
mobj->tics = st->tics;
|
||||
|
||||
// Adjust the player's animation speed to match their velocity.
|
||||
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
|
||||
if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE))
|
||||
mobj->tics = 2;
|
||||
else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
|
||||
{
|
||||
fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
|
||||
if (player->panim == PA_FALL)
|
||||
|
@ -598,7 +547,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
else
|
||||
mobj->tics = 2;
|
||||
}
|
||||
else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying.
|
||||
else if (P_IsObjectOnGround(mobj) || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) // Only if on the ground or superflying.
|
||||
{
|
||||
if (player->panim == PA_WALK)
|
||||
{
|
||||
|
@ -609,7 +558,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
else
|
||||
mobj->tics = 4;
|
||||
}
|
||||
else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL))
|
||||
else if ((player->panim == PA_RUN) || (player->panim == PA_DASH))
|
||||
{
|
||||
if (speed > 52<<FRACBITS)
|
||||
mobj->tics = 1;
|
||||
|
@ -627,7 +576,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
|
||||
UINT8 numframes;
|
||||
|
||||
UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK);
|
||||
UINT8 spr2 = P_GetMobjSprite2(mobj, (((player->powers[pw_super]) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK);
|
||||
|
||||
if (skin)
|
||||
numframes = skin->sprites[spr2].numframes;
|
||||
|
@ -1646,11 +1595,8 @@ static void P_PlayerFlip(mobj_t *mo)
|
|||
G_GhostAddFlip();
|
||||
// Flip aiming to match!
|
||||
|
||||
if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam
|
||||
{
|
||||
if (mo->tracer)
|
||||
mo->tracer->eflags ^= MFE_VERTICALFLIP;
|
||||
}
|
||||
if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS doesn't use flipcam
|
||||
;
|
||||
else if (mo->player->pflags & PF_FLIPCAM)
|
||||
{
|
||||
mo->player->aiming = InvAngle(mo->player->aiming);
|
||||
|
@ -1746,7 +1692,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
|| (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
|
||||
|| mo->state-states == S_PLAY_FLY_TIRED)))
|
||||
gravityadd = gravityadd/3; // less gravity while flying/gliding
|
||||
if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE))
|
||||
if (mo->player->climbing || (mo->player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
gravityadd = 0;
|
||||
|
||||
if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be
|
||||
|
@ -1898,9 +1844,12 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
|||
// spinning friction
|
||||
if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH))
|
||||
{
|
||||
const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT);
|
||||
mo->momx = FixedMul(mo->momx, ns);
|
||||
mo->momy = FixedMul(mo->momy, ns);
|
||||
if (twodlevel || player->mo->flags2 & MF2_TWOD) // Otherwise handled in P_3DMovement
|
||||
{
|
||||
const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT);
|
||||
mo->momx = FixedMul(mo->momx, ns);
|
||||
mo->momy = FixedMul(mo->momy, ns);
|
||||
}
|
||||
}
|
||||
else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale)
|
||||
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
|
||||
|
@ -2326,7 +2275,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
// Check the gravity status.
|
||||
P_CheckGravity(mo, false);
|
||||
|
||||
if (player && !moved && player->pflags & PF_NIGHTSMODE && mo->target)
|
||||
if (player && !moved && player->powers[pw_carry] == CR_NIGHTSMODE && mo->target)
|
||||
{
|
||||
angle_t fa;
|
||||
|
||||
|
@ -2369,7 +2318,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
if (player && player->homing) // no friction for homing
|
||||
return;
|
||||
|
||||
if (player && player->pflags & PF_NIGHTSMODE)
|
||||
if (player && player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
return; // no friction for NiGHTS players
|
||||
|
||||
#ifdef ESLOPE
|
||||
|
@ -2592,6 +2541,9 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
|||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
if (mo->player && mo->player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
if (((mo->z <= mo->subsector->sector->floorheight
|
||||
&& !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
|| (mo->z + mo->height >= mo->subsector->sector->ceilingheight
|
||||
|
@ -2608,10 +2560,18 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover)
|
|||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
||||
&& !(rover->master->flags & ML_BLOCKMONSTERS)
|
||||
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale)))
|
||||
return true;
|
||||
{
|
||||
fixed_t topheight =
|
||||
#ifdef ESLOPE
|
||||
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
|
||||
#endif
|
||||
*rover->topheight;
|
||||
|
||||
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
||||
&& !(rover->master->flags & ML_BLOCKMONSTERS)
|
||||
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > topheight - FixedMul(16*FRACUNIT, mo->scale)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2850,7 +2810,7 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
mo->z = mo->floorz;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (mo->standingslope) // You're still on the ground; why are we here?
|
||||
if (!(mo->flags & MF_MISSILE) && mo->standingslope) // You're still on the ground; why are we here?
|
||||
{
|
||||
mo->momz = 0;
|
||||
return true;
|
||||
|
@ -3151,7 +3111,7 @@ static void P_PlayerZMovement(mobj_t *mo)
|
|||
else
|
||||
mo->z = mo->floorz;
|
||||
|
||||
if (mo->player->pflags & PF_NIGHTSMODE)
|
||||
if (mo->player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
// bounce off floor if you were flying towards it
|
||||
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180)
|
||||
|
@ -3259,60 +3219,69 @@ static void P_PlayerZMovement(mobj_t *mo)
|
|||
// aren't pressing any controls.
|
||||
if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING))
|
||||
{
|
||||
mo->momx = mo->momx/2;
|
||||
mo->momy = mo->momy/2;
|
||||
mo->momx >>= 1;
|
||||
mo->momy >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mo->health)
|
||||
if (mo->health && !P_CheckDeathPitCollide(mo))
|
||||
{
|
||||
if (mo->player->pflags & PF_GLIDING) // ground gliding
|
||||
{
|
||||
mo->player->skidtime = TICRATE;
|
||||
mo->tics = -1;
|
||||
}
|
||||
else if (mo->player->charability2 == CA2_MELEE && mo->player->panim == PA_ABILITY2)
|
||||
else if (mo->player->charability2 == CA2_MELEE && (mo->player->panim == PA_ABILITY2 && mo->state-states != S_PLAY_MELEE_LANDING))
|
||||
{
|
||||
P_InstaThrust(mo, mo->angle, 0);
|
||||
P_SetPlayerMobjState(mo, S_PLAY_STND);
|
||||
P_SetPlayerMobjState(mo, S_PLAY_MELEE_LANDING);
|
||||
mo->tics = (mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(mo->movefactor)))>>FRACBITS;
|
||||
S_StartSound(mo, sfx_s3k8b);
|
||||
mo->player->pflags |= PF_FULLSTASIS;
|
||||
}
|
||||
else if (mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN)
|
||||
|| mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED)
|
||||
{
|
||||
if (mo->player->cmomx || mo->player->cmomy)
|
||||
{
|
||||
if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL)
|
||||
P_SetPlayerMobjState(mo, S_PLAY_PEEL);
|
||||
else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
|
||||
if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(mo, S_PLAY_DASH);
|
||||
else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale)
|
||||
&& (mo->player->panim != PA_RUN || mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(mo, S_PLAY_RUN);
|
||||
else if ((mo->player->rmomx || mo->player->rmomy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
|
||||
else if ((mo->player->rmomx || mo->player->rmomy)
|
||||
&& (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT))
|
||||
P_SetPlayerMobjState(mo, S_PLAY_WALK);
|
||||
else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(mo, S_PLAY_STND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL)
|
||||
P_SetPlayerMobjState(mo, S_PLAY_PEEL);
|
||||
if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
|
||||
if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(mo, S_PLAY_DASH);
|
||||
else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale)
|
||||
&& (mo->player->panim != PA_RUN || mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(mo, S_PLAY_RUN);
|
||||
else if ((mo->momx || mo->momy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
|
||||
else if ((mo->momx || mo->momy)
|
||||
&& (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT))
|
||||
P_SetPlayerMobjState(mo, S_PLAY_WALK);
|
||||
else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(mo, S_PLAY_STND);
|
||||
}
|
||||
}
|
||||
|
||||
if (mo->player->pflags & PF_JUMPED)
|
||||
mo->player->pflags &= ~PF_SPINNING;
|
||||
else if (!(mo->player->pflags & PF_USEDOWN))
|
||||
if ((mo->player->charability2 == CA2_SPINDASH) && !(mo->player->pflags & PF_THOKKED) && (mo->player->cmd.buttons & BT_USE) && (FixedHypot(mo->momx, mo->momy) > (5*mo->scale)))
|
||||
{
|
||||
mo->player->pflags |= PF_SPINNING;
|
||||
P_SetPlayerMobjState(mo, S_PLAY_ROLL);
|
||||
S_StartSound(mo, sfx_spin);
|
||||
}
|
||||
else
|
||||
mo->player->pflags &= ~PF_SPINNING;
|
||||
|
||||
if (!(mo->player->pflags & PF_GLIDING))
|
||||
mo->player->pflags &= ~(PF_JUMPED|PF_FORCEJUMPDAMAGE);
|
||||
mo->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
|
||||
mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
|
||||
mo->player->jumping = 0;
|
||||
mo->player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
|
||||
mo->player->secondjump = 0;
|
||||
mo->player->glidetime = 0;
|
||||
mo->player->climbing = 0;
|
||||
|
@ -3346,6 +3315,16 @@ static void P_PlayerZMovement(mobj_t *mo)
|
|||
clipmomz = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mo->player->pflags & PF_BOUNCING)
|
||||
{
|
||||
P_MobjCheckWater(mo);
|
||||
mo->momz *= -1;
|
||||
P_DoAbilityBounce(mo->player, true);
|
||||
if (mo->player->scoreadd)
|
||||
mo->player->scoreadd--;
|
||||
clipmomz = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(mo->player->pflags & PF_SPINNING))
|
||||
|
@ -3394,7 +3373,7 @@ nightsdone:
|
|||
else
|
||||
mo->z = mo->ceilingz - mo->height;
|
||||
|
||||
if (mo->player->pflags & PF_NIGHTSMODE)
|
||||
if (mo->player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
// bounce off ceiling if you were flying towards it
|
||||
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359)
|
||||
|
@ -3607,11 +3586,17 @@ static boolean P_SceneryZMovement(mobj_t *mo)
|
|||
//
|
||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
||||
{
|
||||
if (!(player->pflags & PF_NIGHTSMODE) && !player->homing
|
||||
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
|
||||
fixed_t topheight =
|
||||
#ifdef ESLOPE
|
||||
*rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
|
||||
#endif
|
||||
*rover->topheight;
|
||||
|
||||
if (!player->powers[pw_carry] && !player->homing
|
||||
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height)
|
||||
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
|
||||
&& !(player->pflags & PF_SLIDING)
|
||||
&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
||||
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -4013,7 +3998,7 @@ void P_DestroyRobots(void)
|
|||
continue; // not a mobj thinker
|
||||
|
||||
mo = (mobj_t *)think;
|
||||
if (mo->health <= 0 || !(mo->flags & MF_ENEMY || mo->flags & MF_BOSS))
|
||||
if (mo->health <= 0 || !(mo->flags & (MF_ENEMY|MF_BOSS)))
|
||||
continue; // not a valid enemy
|
||||
|
||||
if (mo->type == MT_PLAYER) // Don't chase after other players!
|
||||
|
@ -4036,7 +4021,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
|||
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD)))
|
||||
itsatwodlevel = true;
|
||||
|
||||
if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
|
||||
if (player->pflags & PF_FLIPCAM && !(player->powers[pw_carry] == CR_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
|
||||
postimg = postimg_flip;
|
||||
else if (player->awayviewtics)
|
||||
{
|
||||
|
@ -4169,6 +4154,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
// momentum movement
|
||||
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
|
||||
|
||||
if (mobj->state-states == S_PLAY_BOUNCE_LANDING)
|
||||
goto animonly; // no need for checkposition - doesn't move at ALL
|
||||
|
||||
// Zoom tube
|
||||
if (mobj->tracer)
|
||||
{
|
||||
|
@ -4289,9 +4277,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(mobj->player->pflags & PF_NIGHTSMODE)) // "jumping" is used for drilling
|
||||
mobj->player->jumping = 0;
|
||||
mobj->player->pflags &= ~PF_JUMPED;
|
||||
if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // used for drilling
|
||||
mobj->player->pflags &= ~PF_STARTJUMP;
|
||||
mobj->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
|
||||
{
|
||||
mobj->player->secondjump = 0;
|
||||
|
@ -5491,10 +5479,10 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
if (players[i].mo->health <= 0)
|
||||
continue;
|
||||
|
||||
if (players[i].powers[pw_ingoop])
|
||||
if (players[i].powers[pw_carry] == CR_BRAKGOOP)
|
||||
{
|
||||
closestNum = -1;
|
||||
closestdist = 16384*FRACUNIT; // Just in case...
|
||||
closestdist = INT32_MAX; // Just in case...
|
||||
|
||||
// Find waypoint he is closest to
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
|
@ -6903,7 +6891,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
if (/*(mobj->target) -- the following is implicit by P_AddShield
|
||||
&& (mobj->target->player)
|
||||
&& */ (mobj->target->player->homing))
|
||||
&& */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY))
|
||||
{
|
||||
P_SetMobjState(mobj, mobj->info->painstate);
|
||||
mobj->tics++;
|
||||
|
@ -7038,6 +7026,25 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
break;
|
||||
case MT_LOCKON:
|
||||
if (!mobj->target)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
mobj->x = mobj->target->x;
|
||||
mobj->y = mobj->target->y;
|
||||
|
||||
mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
mobj->destscale = mobj->target->destscale;
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
|
||||
if (!(mobj->eflags & MFE_VERTICALFLIP))
|
||||
mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale);
|
||||
else
|
||||
mobj->z = mobj->target->z - FixedMul((16 + abs((leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height;
|
||||
break;
|
||||
case MT_DROWNNUMBERS:
|
||||
if (!mobj->target)
|
||||
{
|
||||
|
@ -7309,7 +7316,6 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
ns = 4 * FRACUNIT;
|
||||
mo2->momx = FixedMul(FINESINE(fa),ns);
|
||||
mo2->momy = FixedMul(FINECOSINE(fa),ns);
|
||||
mo2->angle = fa << ANGLETOFINESHIFT;
|
||||
|
||||
if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack!
|
||||
S_StartSound(mo2, mobj->info->deathsound);
|
||||
|
@ -7321,6 +7327,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetTarget(&flicky->target, mo2);
|
||||
flicky->momx = mo2->momx;
|
||||
flicky->momy = mo2->momy;
|
||||
flicky->angle = fa << ANGLETOFINESHIFT;
|
||||
}
|
||||
|
||||
mobj->fuse--;
|
||||
|
@ -7366,6 +7373,35 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
else switch (mobj->type)
|
||||
{
|
||||
case MT_WALLSPIKEBASE:
|
||||
if (!mobj->target) {
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK);
|
||||
if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle
|
||||
{
|
||||
mobj_t *target = mobj->target; // shortcut
|
||||
const fixed_t baseradius = target->radius/2 - FixedMul(FRACUNIT, target->scale);
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius);
|
||||
mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius);
|
||||
P_SetThingPosition(mobj);
|
||||
mobj->angle = target->angle + ANGLE_90;
|
||||
}
|
||||
break;
|
||||
case MT_FALLINGROCK:
|
||||
// Despawn rocks here in case zmovement code can't do so (blame slopes)
|
||||
if (!mobj->momx && !mobj->momy && !mobj->momz
|
||||
&& ((mobj->eflags & MFE_VERTICALFLIP) ?
|
||||
mobj->z + mobj->height >= mobj->ceilingz
|
||||
: mobj->z <= mobj->floorz))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
P_MobjCheckWater(mobj);
|
||||
break;
|
||||
case MT_EMERALDSPAWN:
|
||||
if (mobj->threshold)
|
||||
{
|
||||
|
@ -7652,7 +7688,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
else if (mobj->tracer && mobj->tracer->player)
|
||||
{
|
||||
if (!(mobj->tracer->player->pflags & PF_NIGHTSMODE))
|
||||
if (!(mobj->tracer->player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
{
|
||||
mobj->flags &= ~MF_NOGRAVITY;
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
|
@ -7704,7 +7740,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetTarget(&mobj->target, NULL);
|
||||
}
|
||||
|
||||
if (mobj->tracer->player->pflags & PF_NIGHTSMODE)
|
||||
if (mobj->tracer->player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
if (mobj->tracer->player->bonustime)
|
||||
{
|
||||
|
@ -8047,6 +8083,10 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|
|||
if (mobj->spawnpoint)
|
||||
mobj->fuse += mobj->spawnpoint->angle;
|
||||
break;
|
||||
case MT_WALLSPIKE:
|
||||
P_SetMobjState(mobj, mobj->state->nextstate);
|
||||
mobj->fuse = mobj->info->speed;
|
||||
break;
|
||||
case MT_NIGHTSCORE:
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
|
@ -8438,9 +8478,17 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
// Collision helper can be stood on but not pushed
|
||||
mobj->flags2 |= MF2_STANDONME;
|
||||
break;
|
||||
case MT_WALLSPIKE:
|
||||
case MT_SPIKE:
|
||||
mobj->flags2 |= MF2_STANDONME;
|
||||
break;
|
||||
case MT_GFZTREE:
|
||||
case MT_GFZBERRYTREE:
|
||||
case MT_GFZCHERRYTREE:
|
||||
case MT_LAMPPOST1:
|
||||
case MT_LAMPPOST2:
|
||||
mobj->flags2 |= MF2_STANDONME;
|
||||
break;
|
||||
case MT_DETON:
|
||||
mobj->movedir = 0;
|
||||
break;
|
||||
|
@ -8506,6 +8554,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
break;
|
||||
case MT_EGGCAPSULE:
|
||||
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
|
||||
break;
|
||||
case MT_REDTEAMRING:
|
||||
mobj->color = skincolor_redteam;
|
||||
break;
|
||||
|
@ -8770,7 +8819,6 @@ consvar_t cv_itemrespawntime = {"respawnitemtime", "30", CV_NETVAR|CV_CHEAT, res
|
|||
consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
void P_SpawnPrecipitation(void)
|
||||
{
|
||||
|
@ -9455,7 +9503,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
}
|
||||
|
||||
if (metalrecording) // Metal Sonic can't use these things.
|
||||
if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_EMMY || i == MT_STARPOST)
|
||||
if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST)
|
||||
return;
|
||||
|
||||
if (i >= MT_EMERALD1 && i <= MT_EMERALD7) // Pickupable Emeralds
|
||||
|
@ -9513,7 +9561,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
// Yeah, this is a dirty hack.
|
||||
if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR)
|
||||
{
|
||||
if (gametype == GT_COMPETITION)
|
||||
if (gametype == GT_COMPETITION || gametype == GT_RACE)
|
||||
{
|
||||
// Set powerup boxes to user settings for competition.
|
||||
if (cv_competitionboxes.value == 1) // Random
|
||||
|
@ -9569,7 +9617,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
return;
|
||||
|
||||
// Emerald Tokens -->> Score Tokens
|
||||
else if (i == MT_EMMY)
|
||||
else if (i == MT_TOKEN)
|
||||
return; /// \todo
|
||||
|
||||
// 1UPs -->> Score TVs
|
||||
|
@ -9586,7 +9634,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
if (ultimatemode)
|
||||
{
|
||||
if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX
|
||||
|| i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX)
|
||||
|| i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX
|
||||
|| i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX)
|
||||
return; // No shields in Ultimate mode
|
||||
|
||||
if (i == MT_RING_BOX && !G_IsSpecialStage(gamemap))
|
||||
|
@ -9596,7 +9645,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
// They're likely facets of the level's design and therefore required to progress.
|
||||
}
|
||||
|
||||
if (i == MT_EMMY && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
|
||||
if (i == MT_TOKEN && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
|
||||
return; // you already got this token, or there are too many, or the gametype's not right
|
||||
|
||||
// Objectplace landing point
|
||||
|
@ -9615,7 +9664,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE)
|
||||
z = ONFLOORZ;
|
||||
else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_EMMY)
|
||||
else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN)
|
||||
{
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
|
@ -9705,14 +9754,23 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
mobj = P_SpawnMobj(x, y, z, i);
|
||||
mobj->spawnpoint = mthing;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MapThingSpawn(mobj, mthing))
|
||||
{
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
}
|
||||
else if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
else
|
||||
#endif
|
||||
switch(mobj->type)
|
||||
{
|
||||
case MT_SKYBOX:
|
||||
mobj->angle = 0;
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
skyboxmo[1] = mobj;
|
||||
skyboxcenterpnts[mthing->extrainfo] = mobj;
|
||||
else
|
||||
skyboxmo[0] = mobj;
|
||||
skyboxviewpnts[mthing->extrainfo] = mobj;
|
||||
break;
|
||||
case MT_FAN:
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
|
@ -9757,20 +9815,16 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
mobjtype_t macetype = MT_SMALLMACE;
|
||||
boolean firsttime;
|
||||
mobj_t *spawnee;
|
||||
size_t line;
|
||||
INT32 line;
|
||||
const size_t mthingi = (size_t)(mthing - mapthings);
|
||||
|
||||
// Why does P_FindSpecialLineFromTag not work here?!?
|
||||
// Monster Iestyn: tag lists haven't been initialised yet for the map, that's why
|
||||
for (line = 0; line < numlines; line++)
|
||||
{
|
||||
if (lines[line].special == 9 && lines[line].tag == mthing->angle)
|
||||
break;
|
||||
}
|
||||
// Find the corresponding linedef special, using angle as tag
|
||||
// P_FindSpecialLineFromTag works here now =D
|
||||
line = P_FindSpecialLineFromTag(9, mthing->angle, -1);
|
||||
|
||||
if (line == numlines)
|
||||
if (line == -1)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
|
@ -9868,18 +9922,15 @@ ML_NOCLIMB : Direction not controllable
|
|||
fixed_t radius, speed, bottomheight, topheight;
|
||||
INT32 type, numdivisions, time, anglespeed;
|
||||
angle_t angledivision;
|
||||
size_t line;
|
||||
INT32 line;
|
||||
const size_t mthingi = (size_t)(mthing - mapthings);
|
||||
|
||||
for (line = 0; line < numlines; line++)
|
||||
{
|
||||
if (lines[line].special == 15 && lines[line].tag == mthing->angle)
|
||||
break;
|
||||
}
|
||||
// Find the corresponding linedef special, using angle as tag
|
||||
line = P_FindSpecialLineFromTag(15, mthing->angle, -1);
|
||||
|
||||
if (line == numlines)
|
||||
if (line == -1)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -10012,28 +10063,10 @@ ML_NOCLIMB : Direction not controllable
|
|||
mobj->radius = (mthing->angle & 16383)*FRACUNIT;
|
||||
}
|
||||
}
|
||||
else if (i == MT_EMMY)
|
||||
else if (i == MT_TOKEN)
|
||||
{
|
||||
if (mthing->options & MTF_OBJECTSPECIAL) // Mario Block version
|
||||
mobj->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
else
|
||||
{
|
||||
fixed_t zheight = mobj->z;
|
||||
mobj_t *tokenobj;
|
||||
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
zheight += mobj->height-FixedMul(mobjinfo[MT_TOKEN].height, mobj->scale); // align with emmy properly!
|
||||
|
||||
tokenobj = P_SpawnMobj(x, y, zheight, MT_TOKEN);
|
||||
P_SetTarget(&mobj->tracer, tokenobj);
|
||||
tokenobj->destscale = mobj->scale;
|
||||
P_SetScale(tokenobj, mobj->scale);
|
||||
if (mthing->options & MTF_OBJECTFLIP) // flip token to match emmy
|
||||
{
|
||||
tokenobj->eflags |= MFE_VERTICALFLIP;
|
||||
tokenobj->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
}
|
||||
|
||||
// We advanced tokenbits earlier due to the return check.
|
||||
// Subtract 1 here for the correct value.
|
||||
|
@ -10093,6 +10126,38 @@ ML_NOCLIMB : Direction not controllable
|
|||
P_SetThingPosition(mobj);
|
||||
}
|
||||
}
|
||||
else if (i == MT_WALLSPIKE)
|
||||
{
|
||||
// Pop up spikes!
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
mobj->flags &= ~MF_SCENERY;
|
||||
mobj->fuse = mobj->info->speed;
|
||||
}
|
||||
// Use per-thing collision for spikes if the deaf flag is checked.
|
||||
if (mthing->options & MTF_AMBUSH && !metalrecording)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOCLIPHEIGHT);
|
||||
mobj->flags |= MF_SOLID;
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
|
||||
// spawn base
|
||||
{
|
||||
const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so...
|
||||
const fixed_t baseradius = mobj->radius/2 - FixedMul(FRACUNIT, mobj->scale);
|
||||
mobj_t *base = P_SpawnMobj(
|
||||
mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius),
|
||||
mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius),
|
||||
mobj->z, MT_WALLSPIKEBASE);
|
||||
base->angle = mobjangle + ANGLE_90;
|
||||
base->destscale = mobj->destscale;
|
||||
P_SetScale(base, mobj->scale);
|
||||
P_SetTarget(&base->target, mobj);
|
||||
P_SetTarget(&mobj->tracer, base);
|
||||
}
|
||||
}
|
||||
|
||||
//count 10 ring boxes into the number of rings equation too.
|
||||
if (i == MT_RING_BOX)
|
||||
|
|
|
@ -35,9 +35,11 @@
|
|||
#pragma interface
|
||||
#endif
|
||||
|
||||
/// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range)
|
||||
#define FF_FRAMEMASK 0x1ff
|
||||
/// \brief Frame flags: only the frame number - 0 to 256 (Frames from 0 to 63, Sprite2 number uses 0 to 127 plus FF_SPR2SUPER)
|
||||
#define FF_FRAMEMASK 0xff
|
||||
|
||||
/// \brief Frame flags - SPR2: Super sprite2
|
||||
#define FF_SPR2SUPER 0x80
|
||||
/// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation
|
||||
#define FF_SPR2ENDSTATE 0x1000
|
||||
/// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation
|
||||
|
|
|
@ -152,7 +152,6 @@ static void P_NetArchivePlayers(void)
|
|||
WRITESINT8(save_p, players[i].xtralife);
|
||||
WRITEUINT8(save_p, players[i].gotcontinue);
|
||||
WRITEFIXED(save_p, players[i].speed);
|
||||
WRITEUINT8(save_p, players[i].jumping);
|
||||
WRITEUINT8(save_p, players[i].secondjump);
|
||||
WRITEUINT8(save_p, players[i].fly1);
|
||||
WRITEUINT8(save_p, players[i].scoreadd);
|
||||
|
@ -332,7 +331,6 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter
|
||||
players[i].gotcontinue = READUINT8(save_p); // got continue from stage
|
||||
players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values)
|
||||
players[i].jumping = READUINT8(save_p); // Jump counter
|
||||
players[i].secondjump = READUINT8(save_p);
|
||||
players[i].fly1 = READUINT8(save_p); // Tails flying
|
||||
players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus
|
||||
|
|
|
@ -199,6 +199,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
const INT16 num = (INT16)(i-1);
|
||||
DEH_WriteUndoline("LEVELNAME", mapheaderinfo[num]->lvlttl, UNDO_NONE);
|
||||
mapheaderinfo[num]->lvlttl[0] = '\0';
|
||||
DEH_WriteUndoline("SELECTHEADING", mapheaderinfo[num]->selectheading, UNDO_NONE);
|
||||
mapheaderinfo[num]->selectheading[0] = '\0';
|
||||
DEH_WriteUndoline("SUBTITLE", mapheaderinfo[num]->subttl, UNDO_NONE);
|
||||
mapheaderinfo[num]->subttl[0] = '\0';
|
||||
DEH_WriteUndoline("ACT", va("%d", mapheaderinfo[num]->actnum), UNDO_NONE);
|
||||
|
@ -2276,6 +2278,17 @@ void P_LoadThingsOnly(void)
|
|||
// Search through all the thinkers.
|
||||
mobj_t *mo;
|
||||
thinker_t *think;
|
||||
INT32 i, viewid = -1, centerid = -1; // for skyboxes
|
||||
|
||||
// check if these are any of the normal viewpoint/centerpoint mobjs in the level or not
|
||||
if (skyboxmo[0] || skyboxmo[1])
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (skyboxmo[0] && skyboxmo[0] == skyboxviewpnts[i])
|
||||
viewid = i; // save id just in case
|
||||
if (skyboxmo[1] && skyboxmo[1] == skyboxcenterpnts[i])
|
||||
centerid = i; // save id just in case
|
||||
}
|
||||
|
||||
for (think = thinkercap.next; think != &thinkercap; think = think->next)
|
||||
{
|
||||
|
@ -2293,6 +2306,10 @@ void P_LoadThingsOnly(void)
|
|||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||
P_LoadThings();
|
||||
|
||||
// restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that
|
||||
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
|
||||
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
|
||||
|
||||
P_SpawnSecretItems(true);
|
||||
}
|
||||
|
||||
|
@ -2574,8 +2591,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
|
||||
postimgtype = postimgtype2 = postimg_none;
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
|
||||
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
|
||||
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0')
|
||||
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
|
||||
|
||||
// chasecam on in chaos, race, coop
|
||||
|
@ -2585,8 +2601,9 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
|
||||
if (!dedicated)
|
||||
{
|
||||
if (!cv_cam_speed.changed)
|
||||
CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);
|
||||
// Salt: CV_ClearChangedFlags() messes with your settings :(
|
||||
/*if (!cv_cam_speed.changed)
|
||||
CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);*/
|
||||
|
||||
if (!cv_chasecam.changed)
|
||||
CV_SetValue(&cv_chasecam, chase);
|
||||
|
@ -2727,15 +2744,25 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
for (i = 0; i < 2; i++)
|
||||
skyboxmo[i] = NULL;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
|
||||
|
||||
P_MapStart();
|
||||
|
||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||
|
||||
// init gravity, tag lists,
|
||||
// anything that P_ResetDynamicSlopes/P_LoadThings needs to know
|
||||
P_InitSpecials();
|
||||
|
||||
#ifdef ESLOPE
|
||||
P_ResetDynamicSlopes();
|
||||
#endif
|
||||
|
||||
P_LoadThings();
|
||||
// skybox mobj defaults
|
||||
skyboxmo[0] = skyboxviewpnts[0];
|
||||
skyboxmo[1] = skyboxcenterpnts[0];
|
||||
|
||||
P_SpawnSecretItems(loademblems);
|
||||
|
||||
|
@ -2749,8 +2776,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame)
|
||||
P_SpawnPrecipitation();
|
||||
|
||||
globalweather = mapheaderinfo[gamemap-1]->weather;
|
||||
|
||||
#ifdef HWRENDER // not win32 only 19990829 by Kin
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
{
|
||||
|
@ -2776,8 +2801,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
players[i].pflags &= ~PF_NIGHTSMODE;
|
||||
|
||||
// Start players with pity shields if possible
|
||||
players[i].pity = -1;
|
||||
|
||||
|
@ -2882,22 +2905,21 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cv_cam_height.changed)
|
||||
|
||||
// Salt: CV_ClearChangedFlags() messes with your settings :(
|
||||
/*if (!cv_cam_height.changed)
|
||||
CV_Set(&cv_cam_height, cv_cam_height.defaultvalue);
|
||||
|
||||
if (!cv_cam_dist.changed)
|
||||
CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue);
|
||||
|
||||
if (!cv_cam_rotate.changed)
|
||||
CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue);
|
||||
|
||||
if (!cv_cam2_height.changed)
|
||||
CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue);
|
||||
|
||||
if (!cv_cam_dist.changed)
|
||||
CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue);
|
||||
if (!cv_cam2_dist.changed)
|
||||
CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);
|
||||
CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);*/
|
||||
|
||||
// Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P
|
||||
if (!cv_cam_rotate.changed)
|
||||
CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue);
|
||||
if (!cv_cam2_rotate.changed)
|
||||
CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue);
|
||||
|
||||
|
|
|
@ -103,12 +103,20 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1)
|
|||
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
|
||||
{
|
||||
size_t i;
|
||||
sector_t *polysec;
|
||||
|
||||
if (!(po->flags & POF_RENDERALL))
|
||||
return true; // the polyobject isn't visible, so we can ignore it
|
||||
|
||||
polysec = po->lines[0]->backsector;
|
||||
|
||||
for (i = 0; i < po->numLines; ++i)
|
||||
{
|
||||
line_t *line = po->lines[i];
|
||||
divline_t divl;
|
||||
const vertex_t *v1,*v2;
|
||||
fixed_t frac;
|
||||
fixed_t topslope, bottomslope;
|
||||
|
||||
// already checked other side?
|
||||
if (line->validcount == validcount)
|
||||
|
@ -140,7 +148,22 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
|
|||
continue;
|
||||
|
||||
// stop because it is not two sided
|
||||
return false;
|
||||
//if (!(po->flags & POF_TESTHEIGHT))
|
||||
//return false;
|
||||
|
||||
frac = P_InterceptVector2(&los->strace, &divl);
|
||||
|
||||
// get slopes of top and bottom of this polyobject line
|
||||
topslope = FixedDiv(polysec->ceilingheight - los->sightzstart , frac);
|
||||
bottomslope = FixedDiv(polysec->floorheight - los->sightzstart , frac);
|
||||
|
||||
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
|
||||
return false; // view completely blocked
|
||||
|
||||
// TODO: figure out if it's worth considering partially blocked cases or not?
|
||||
// maybe to adjust los's top/bottom slopes if needed
|
||||
//if (los->topslope <= los->bottomslope)
|
||||
//return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
376
src/p_spec.c
376
src/p_spec.c
|
@ -46,7 +46,9 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
mobj_t *skyboxmo[2];
|
||||
mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
|
||||
mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
|
@ -111,7 +113,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker
|
|||
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
||||
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee);
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse);
|
||||
|
||||
|
||||
//SoM: 3/7/2000: New sturcture without limits.
|
||||
|
@ -454,7 +456,8 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
|||
|
||||
// Search for existing animdef
|
||||
for (i = 0; i < maxanims; i++)
|
||||
if (stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||
if (animdefs[i].istexture == istexture // Check if it's the same type!
|
||||
&& stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||
{
|
||||
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
||||
|
||||
|
@ -1746,7 +1749,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
case 305: // continuous
|
||||
case 306: // each time
|
||||
case 307: // once
|
||||
if (!(actor && actor->player && actor->player->charability != dist/10))
|
||||
if (!(actor && actor->player && actor->player->charability == dist/10))
|
||||
return false;
|
||||
break;
|
||||
case 309: // continuous
|
||||
|
@ -2442,73 +2445,81 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
|
||||
case 414: // Play SFX
|
||||
{
|
||||
fixed_t sfxnum;
|
||||
INT32 sfxnum;
|
||||
|
||||
sfxnum = sides[line->sidenum[0]].toptexture;
|
||||
|
||||
if (line->tag != 0 && line->flags & ML_EFFECT5)
|
||||
if (sfxnum == sfx_None)
|
||||
return; // Do nothing!
|
||||
if (sfxnum < sfx_None || sfxnum >= NUMSFX)
|
||||
{
|
||||
sector_t *sec;
|
||||
|
||||
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
|
||||
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
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
S_StartSound(&sec->soundorg, sfxnum);
|
||||
// Additionally play the sound from tagged sectors' soundorgs
|
||||
sector_t *sec;
|
||||
|
||||
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
S_StartSound(&sec->soundorg, sfxnum);
|
||||
}
|
||||
}
|
||||
else if (mo) // A mobj must have triggered the executor
|
||||
{
|
||||
// Only trigger if mobj is touching the tag
|
||||
ffloor_t *rover;
|
||||
boolean foundit = false;
|
||||
|
||||
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag != line->tag)
|
||||
continue;
|
||||
|
||||
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||
continue;
|
||||
|
||||
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||
continue;
|
||||
|
||||
foundit = true;
|
||||
}
|
||||
|
||||
if (mo->subsector->sector->tag == line->tag)
|
||||
foundit = true;
|
||||
|
||||
if (!foundit)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (line->tag != 0 && mo)
|
||||
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
// Only trigger if mobj is touching the tag
|
||||
ffloor_t *rover;
|
||||
boolean foundit = false;
|
||||
|
||||
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag != line->tag)
|
||||
continue;
|
||||
|
||||
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||
continue;
|
||||
|
||||
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||
continue;
|
||||
|
||||
foundit = true;
|
||||
}
|
||||
|
||||
if (mo->subsector->sector->tag == line->tag)
|
||||
foundit = true;
|
||||
|
||||
if (!foundit)
|
||||
return;
|
||||
}
|
||||
|
||||
if (sfxnum < NUMSFX && sfxnum > sfx_None)
|
||||
{
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
// play the sound from nowhere, but only if display player triggered it
|
||||
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_EFFECT4)
|
||||
{
|
||||
// play the sound from nowhere
|
||||
// play the sound from nowhere, but only if display player triggered it
|
||||
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_BLOCKMONSTERS)
|
||||
{
|
||||
// play the sound from calling sector's soundorg
|
||||
if (callsec)
|
||||
S_StartSound(&callsec->soundorg, sfxnum);
|
||||
else if (mo)
|
||||
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
|
||||
}
|
||||
}
|
||||
else if (line->flags & ML_EFFECT4)
|
||||
{
|
||||
// play the sound from nowhere
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_BLOCKMONSTERS)
|
||||
{
|
||||
// play the sound from calling sector's soundorg
|
||||
if (callsec)
|
||||
S_StartSound(&callsec->soundorg, sfxnum);
|
||||
else if (mo)
|
||||
{
|
||||
// play the sound from mobj that triggered it
|
||||
S_StartSound(mo, sfxnum);
|
||||
}
|
||||
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
|
||||
}
|
||||
else if (mo)
|
||||
{
|
||||
// play the sound from mobj that triggered it
|
||||
S_StartSound(mo, sfxnum);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3044,7 +3055,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
|
||||
case 443: // Calls a named Lua function
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_LinedefExecute(line, mo, callsec);
|
||||
if (line->text)
|
||||
LUAh_LinedefExecute(line, mo, callsec);
|
||||
else
|
||||
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(line-lines));
|
||||
#else
|
||||
CONS_Alert(CONS_ERROR, "The map is trying to run a Lua script, but this exe was not compiled with Lua support!\n");
|
||||
#endif
|
||||
|
@ -3156,6 +3170,47 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
}
|
||||
break;
|
||||
|
||||
case 448: // Change skybox viewpoint/centerpoint
|
||||
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB))
|
||||
{
|
||||
INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS;
|
||||
INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS;
|
||||
|
||||
if ((line->flags & (ML_EFFECT4|ML_BLOCKMONSTERS)) == ML_EFFECT4) // Solid Midtexture is on but Block Enemies is off?
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,
|
||||
M_GetText("Skybox switch linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"),
|
||||
line->tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set viewpoint mobj
|
||||
if (!(line->flags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting
|
||||
{
|
||||
if (viewid >= 0 && viewid < 16)
|
||||
skyboxmo[0] = skyboxviewpnts[viewid];
|
||||
else
|
||||
skyboxmo[0] = NULL;
|
||||
}
|
||||
|
||||
// set centerpoint mobj
|
||||
if (line->flags & ML_BLOCKMONSTERS) // Block Enemies turns ON centerpoint setting
|
||||
{
|
||||
if (centerid >= 0 && centerid < 16)
|
||||
skyboxmo[1] = skyboxcenterpnts[centerid];
|
||||
else
|
||||
skyboxmo[1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n",
|
||||
viewid,
|
||||
centerid,
|
||||
((line->flags & ML_EFFECT4) ? "no" : "yes"),
|
||||
((line->flags & ML_BLOCKMONSTERS) ? "yes" : "no"));
|
||||
}
|
||||
break;
|
||||
|
||||
case 450: // Execute Linedef Executor - for recursion
|
||||
P_LinedefExecute(line->tag, mo, NULL);
|
||||
break;
|
||||
|
@ -3523,7 +3578,7 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
|||
//
|
||||
// Is player standing on the sector's "ground"?
|
||||
//
|
||||
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
||||
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);
|
||||
|
@ -3575,7 +3630,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
|
||||
break;
|
||||
case 2: // Damage (Water)
|
||||
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE))
|
||||
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER);
|
||||
break;
|
||||
case 3: // Damage (Fire)
|
||||
|
@ -3656,14 +3711,49 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
{
|
||||
if (roversector)
|
||||
{
|
||||
if (players[i].mo->subsector->sector != roversector)
|
||||
if (players[i].mo->subsector->sector == roversector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == roversector)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
goto DoneSection2;
|
||||
|
||||
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].mo->subsector->sector != sector)
|
||||
if (players[i].mo->subsector->sector == sector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == sector)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
goto DoneSection2;
|
||||
|
||||
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
|
||||
|
@ -3792,7 +3882,7 @@ DoneSection2:
|
|||
if (!(player->pflags & PF_SPINNING))
|
||||
player->pflags |= PF_SPINNING;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
}
|
||||
|
||||
player->powers[pw_flashing] = TICRATE/3;
|
||||
|
@ -3953,7 +4043,7 @@ DoneSection2:
|
|||
if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH))
|
||||
{
|
||||
player->pflags |= PF_SPINNING;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
S_StartAttackSound(player->mo, sfx_spin);
|
||||
|
||||
if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
|
||||
|
@ -4030,12 +4120,12 @@ DoneSection2:
|
|||
player->powers[pw_carry] = CR_ZOOMTUBE;
|
||||
player->speed = speed;
|
||||
player->pflags |= PF_SPINNING;
|
||||
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->climbing = 0;
|
||||
|
||||
if (player->mo->state-states != S_PLAY_SPIN)
|
||||
if (player->mo->state-states != S_PLAY_ROLL)
|
||||
{
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
S_StartSound(player->mo, sfx_spin);
|
||||
}
|
||||
}
|
||||
|
@ -4110,12 +4200,12 @@ DoneSection2:
|
|||
player->powers[pw_carry] = CR_ZOOMTUBE;
|
||||
player->speed = speed;
|
||||
player->pflags |= PF_SPINNING;
|
||||
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->climbing = 0;
|
||||
|
||||
if (player->mo->state-states != S_PLAY_SPIN)
|
||||
if (player->mo->state-states != S_PLAY_ROLL)
|
||||
{
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
S_StartSound(player->mo, sfx_spin);
|
||||
}
|
||||
}
|
||||
|
@ -4128,7 +4218,7 @@ DoneSection2:
|
|||
{
|
||||
player->laps++;
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
player->drillmeter += 48*20;
|
||||
|
||||
if (player->laps >= (UINT8)cv_numlaps.value)
|
||||
|
@ -4418,7 +4508,7 @@ DoneSection2:
|
|||
|
||||
S_StartSound(player->mo, sfx_s3k4a);
|
||||
|
||||
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->climbing = 0;
|
||||
P_SetThingPosition(player->mo);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
|
||||
|
@ -4444,6 +4534,7 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
{
|
||||
sector_t *sector;
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
sector = mo->subsector->sector;
|
||||
if (!sector->ffloors)
|
||||
|
@ -4451,8 +4542,6 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!rover->master->frontsector->special)
|
||||
continue;
|
||||
|
||||
|
@ -4500,6 +4589,8 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define TELEPORTED (player->mo->subsector->sector != originalsector)
|
||||
|
||||
/** Checks if a player is standing on or is inside a 3D floor (e.g. water) and
|
||||
* applies any specials.
|
||||
*
|
||||
|
@ -4508,12 +4599,12 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
*/
|
||||
static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
||||
{
|
||||
sector_t *originalsector = player->mo->subsector->sector;
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!rover->master->frontsector->special)
|
||||
continue;
|
||||
|
||||
|
@ -4557,7 +4648,10 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
// This FOF has the special we're looking for, but are we allowed to touch it?
|
||||
if (sector == player->mo->subsector->sector
|
||||
|| (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||
{
|
||||
P_ProcessSpecialSector(player, rover->master->frontsector, sector);
|
||||
if TELEPORTED return;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow sector specials to be applied to polyobjects!
|
||||
|
@ -4568,7 +4662,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
boolean touching = false;
|
||||
boolean inside = false;
|
||||
|
||||
while(po)
|
||||
while (po)
|
||||
{
|
||||
if (po->flags & POF_NOSPECIALS)
|
||||
{
|
||||
|
@ -4644,6 +4738,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
}
|
||||
|
||||
P_ProcessSpecialSector(player, polysec, sector);
|
||||
if TELEPORTED return;
|
||||
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
}
|
||||
|
@ -4748,40 +4843,43 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
|
|||
*/
|
||||
void P_PlayerInSpecialSector(player_t *player)
|
||||
{
|
||||
sector_t *sector;
|
||||
sector_t *originalsector;
|
||||
sector_t *loopsector;
|
||||
msecnode_t *node;
|
||||
|
||||
if (!player->mo)
|
||||
return;
|
||||
|
||||
// Do your ->subsector->sector first
|
||||
sector = player->mo->subsector->sector;
|
||||
P_PlayerOnSpecial3DFloor(player, sector);
|
||||
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
|
||||
// because the player can be teleported in between these times.
|
||||
if (sector == player->mo->subsector->sector)
|
||||
P_RunSpecialSectorCheck(player, sector);
|
||||
originalsector = player->mo->subsector->sector;
|
||||
|
||||
// Iterate through touching_sectorlist
|
||||
P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first.
|
||||
if TELEPORTED return;
|
||||
|
||||
P_RunSpecialSectorCheck(player, originalsector);
|
||||
if TELEPORTED return;
|
||||
|
||||
// Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH
|
||||
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
sector = node->m_sector;
|
||||
loopsector = node->m_sector;
|
||||
|
||||
if (sector == player->mo->subsector->sector) // Don't duplicate
|
||||
if (loopsector == originalsector) // Don't duplicate
|
||||
continue;
|
||||
|
||||
// Check 3D floors...
|
||||
P_PlayerOnSpecial3DFloor(player, sector);
|
||||
P_PlayerOnSpecial3DFloor(player, loopsector);
|
||||
if TELEPORTED return;
|
||||
|
||||
if (!(sector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||
return;
|
||||
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
|
||||
// because the player can be teleported in between these times.
|
||||
if (sector == player->mo->subsector->sector)
|
||||
P_RunSpecialSectorCheck(player, sector);
|
||||
if (!(loopsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||
continue;
|
||||
|
||||
P_RunSpecialSectorCheck(player, loopsector);
|
||||
if TELEPORTED return;
|
||||
}
|
||||
}
|
||||
|
||||
#undef TELEPORTED
|
||||
|
||||
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
|
||||
*
|
||||
* \sa P_CheckTimeLimit, P_CheckPointLimit
|
||||
|
@ -5173,10 +5271,11 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
|
|||
* \param speed Rate of movement relative to control sector
|
||||
* \param control Control sector.
|
||||
* \param affectee Target sector.
|
||||
* \param reverse Reverse direction?
|
||||
* \sa P_SpawnSpecials, T_PlaneDisplace
|
||||
* \author Monster Iestyn
|
||||
*/
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee)
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse)
|
||||
{
|
||||
planedisplace_t *displace;
|
||||
|
||||
|
@ -5190,6 +5289,7 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control,
|
|||
displace->last_height = sectors[control].floorheight;
|
||||
displace->speed = speed;
|
||||
displace->type = type;
|
||||
displace->reverse = reverse;
|
||||
}
|
||||
|
||||
/** Adds a Mario block thinker, which changes the block's texture between blank
|
||||
|
@ -5541,6 +5641,45 @@ static void P_RunLevelLoadExecutors(void)
|
|||
}
|
||||
}
|
||||
|
||||
/** Before things are loaded, initialises certain stuff in case they're needed
|
||||
* by P_ResetDynamicSlopes or P_LoadThings. This was split off from
|
||||
* P_SpawnSpecials, in case you couldn't tell.
|
||||
*
|
||||
* \sa P_SpawnSpecials, P_InitTagLists
|
||||
* \author Monster Iestyn
|
||||
*/
|
||||
void P_InitSpecials(void)
|
||||
{
|
||||
// Set the default gravity. Custom gravity overrides this setting.
|
||||
gravity = FRACUNIT/2;
|
||||
|
||||
// Defaults in case levels don't have them set.
|
||||
sstimer = 90*TICRATE + 6;
|
||||
totalrings = 1;
|
||||
|
||||
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
|
||||
|
||||
// Set curWeather
|
||||
switch (mapheaderinfo[gamemap-1]->weather)
|
||||
{
|
||||
case PRECIP_SNOW: // snow
|
||||
case PRECIP_RAIN: // rain
|
||||
case PRECIP_STORM: // storm
|
||||
case PRECIP_STORM_NORAIN: // storm w/o rain
|
||||
case PRECIP_STORM_NOSTRIKES: // storm w/o lightning
|
||||
curWeather = mapheaderinfo[gamemap-1]->weather;
|
||||
break;
|
||||
default: // blank/none
|
||||
curWeather = PRECIP_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set globalweather
|
||||
globalweather = mapheaderinfo[gamemap-1]->weather;
|
||||
|
||||
P_InitTagLists(); // Create xref tables for tags
|
||||
}
|
||||
|
||||
/** After the map has loaded, scans for specials that spawn 3Dfloors and
|
||||
* thinkers.
|
||||
*
|
||||
|
@ -5562,15 +5701,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// but currently isn't.
|
||||
(void)fromnetsave;
|
||||
|
||||
// Set the default gravity. Custom gravity overrides this setting.
|
||||
gravity = FRACUNIT/2;
|
||||
|
||||
// Defaults in case levels don't have them set.
|
||||
sstimer = 90*TICRATE + 6;
|
||||
totalrings = 1;
|
||||
|
||||
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
|
||||
|
||||
// Init special SECTORs.
|
||||
sector = sectors;
|
||||
for (i = 0; i < numsectors; i++, sector++)
|
||||
|
@ -5619,20 +5749,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
}
|
||||
}
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->weather == 2) // snow
|
||||
curWeather = PRECIP_SNOW;
|
||||
else if (mapheaderinfo[gamemap-1]->weather == 3) // rain
|
||||
curWeather = PRECIP_RAIN;
|
||||
else if (mapheaderinfo[gamemap-1]->weather == 1) // storm
|
||||
curWeather = PRECIP_STORM;
|
||||
else if (mapheaderinfo[gamemap-1]->weather == 5) // storm w/o rain
|
||||
curWeather = PRECIP_STORM_NORAIN;
|
||||
else if (mapheaderinfo[gamemap-1]->weather == 6) // storm w/o lightning
|
||||
curWeather = PRECIP_STORM_NOSTRIKES;
|
||||
else
|
||||
curWeather = PRECIP_NONE;
|
||||
|
||||
P_InitTagLists(); // Create xref tables for tags
|
||||
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
|
||||
|
||||
P_SpawnScrollers(); // Add generalized scrollers
|
||||
|
@ -5909,15 +6025,15 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
|
||||
case 66: // Displace floor by front sector
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB));
|
||||
break;
|
||||
case 67: // Displace ceiling by front sector
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||
P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB));
|
||||
break;
|
||||
case 68: // Displace both floor AND ceiling by front sector
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||
P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB));
|
||||
break;
|
||||
|
||||
case 100: // FOF (solid, opaque, shadows)
|
||||
|
@ -7301,7 +7417,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
|
|||
return false;
|
||||
|
||||
// Allow this to affect pushable objects at some point?
|
||||
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->pflags & PF_NIGHTSMODE))
|
||||
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
{
|
||||
INT32 dist;
|
||||
INT32 speed;
|
||||
|
@ -7332,7 +7448,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
|
|||
// Written with bits and pieces of P_HomingAttack
|
||||
if ((speed > 0) && (P_CheckSight(thing, tmpusher->source)))
|
||||
{
|
||||
if (!(thing->player->pflags & PF_NIGHTSMODE))
|
||||
if (thing->player->powers[pw_carry] != CR_NIGHTSMODE)
|
||||
{
|
||||
// only push wrt Z if health & 1 (mapthing has ambush flag)
|
||||
if (tmpusher->source->health & 1)
|
||||
|
@ -7661,11 +7777,11 @@ void T_Pusher(pusher_t *p)
|
|||
{
|
||||
if (p->slider && thing->player)
|
||||
{
|
||||
boolean jumped = (thing->player->pflags & PF_JUMPED);
|
||||
pflags_t jumped = (thing->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE));
|
||||
P_ResetPlayer (thing->player);
|
||||
|
||||
if (jumped)
|
||||
thing->player->pflags |= PF_JUMPED;
|
||||
thing->player->pflags |= jumped;
|
||||
|
||||
thing->player->pflags |= PF_SLIDING;
|
||||
P_SetPlayerMobjState (thing, thing->info->painstate); // Whee!
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
#ifndef __P_SPEC__
|
||||
#define __P_SPEC__
|
||||
|
||||
extern mobj_t *skyboxmo[2];
|
||||
extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
|
||||
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
// GETSECSPECIAL (specialval, section)
|
||||
//
|
||||
|
@ -32,6 +34,7 @@ void P_InitPicAnims(void);
|
|||
void P_SetupLevelFlatAnims(void);
|
||||
|
||||
// at map load
|
||||
void P_InitSpecials(void);
|
||||
void P_SpawnSpecials(INT32 fromnetsave);
|
||||
|
||||
// every tic
|
||||
|
@ -458,6 +461,7 @@ typedef struct
|
|||
INT32 control; ///< Control sector used to control plane positions.
|
||||
fixed_t last_height; ///< Last known height of control sector.
|
||||
fixed_t speed; ///< Plane movement speed.
|
||||
UINT8 reverse; ///< Move in reverse direction to control sector?
|
||||
/** Types of plane displacement effects.
|
||||
*/
|
||||
enum
|
||||
|
|
|
@ -163,6 +163,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
|
|||
if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing)
|
||||
{
|
||||
players[p].powers[pw_carry] = CR_NONE;
|
||||
P_SetTarget(&players[p].mo->tracer, NULL);
|
||||
break;
|
||||
}
|
||||
thing->player->cmomx = thing->player->cmomy = 0;
|
||||
|
|
1284
src/p_user.c
1284
src/p_user.c
File diff suppressed because it is too large
Load diff
|
@ -210,7 +210,7 @@ void R_PortalClearClipSegs(INT32 start, INT32 end)
|
|||
//
|
||||
// It assumes that Doom has already ruled out a door being closed because
|
||||
// of front-back closure (e.g. front floor is taller than back ceiling).
|
||||
static inline INT32 R_DoorClosed(void)
|
||||
static INT32 R_DoorClosed(void)
|
||||
{
|
||||
return
|
||||
|
||||
|
@ -1222,6 +1222,9 @@ static void R_Subsector(size_t num)
|
|||
while (count--)
|
||||
{
|
||||
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
||||
#ifdef POLYOBJECTS
|
||||
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||
#endif
|
||||
R_AddLine(line);
|
||||
line++;
|
||||
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue