diff --git a/SRB2.cbp b/SRB2.cbp
index 4834563ec..5a03955b8 100644
--- a/SRB2.cbp
+++ b/SRB2.cbp
@@ -154,8 +154,8 @@ HW3SOUND for 3D hardware sound support
-
-
+
+
@@ -200,8 +200,8 @@ HW3SOUND for 3D hardware sound support
-
-
+
+
@@ -4141,283 +4141,170 @@ HW3SOUND for 3D hardware sound support
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4590,13 +4477,13 @@ HW3SOUND for 3D hardware sound support
-
+
+
-
-
-
+
+
diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake
index faa556a88..9e789e19c 100644
--- a/cmake/Modules/FindSDL2.cmake
+++ b/cmake/Modules/FindSDL2.cmake
@@ -27,7 +27,6 @@ find_library(SDL2_LIBRARY
"/usr/local/lib"
)
-
# set include dir variables
set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR)
set(SDL2_PROCESS_LIBS SDL2_LIBRARY)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6859e27c3..bb4f9a4a6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -150,6 +150,7 @@ set(SRB2_CORE_GAME_SOURCES
p_saveg.c
p_setup.c
p_sight.c
+ p_slopes.c
p_spec.c
p_telept.c
p_tick.c
@@ -162,6 +163,7 @@ set(SRB2_CORE_GAME_SOURCES
p_pspr.h
p_saveg.h
p_setup.h
+ p_slopes.h
p_spec.h
p_tick.h
)
diff --git a/src/Makefile b/src/Makefile
index d4cc64a4b..bee608047 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -454,6 +454,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/p_telept.o \
$(OBJDIR)/p_tick.o \
$(OBJDIR)/p_user.o \
+ $(OBJDIR)/p_slopes.o \
$(OBJDIR)/tables.o \
$(OBJDIR)/r_bsp.o \
$(OBJDIR)/r_data.o \
diff --git a/src/b_bot.c b/src/b_bot.c
index 5e62e58e6..0636d9366 100644
--- a/src/b_bot.c
+++ b/src/b_bot.c
@@ -273,11 +273,11 @@ void B_RespawnBot(INT32 playernum)
P_TeleportMove(tails, x, y, z);
if (player->charability == CA_FLY)
{
- P_SetPlayerMobjState(tails, S_PLAY_ABL1);
+ P_SetPlayerMobjState(tails, S_PLAY_FLY);
tails->player->powers[pw_tailsfly] = (UINT16)-1;
}
else
- P_SetPlayerMobjState(tails, S_PLAY_FALL1);
+ P_SetPlayerMobjState(tails, S_PLAY_FALL);
P_SetScale(tails, sonic->scale);
tails->destscale = sonic->destscale;
}
diff --git a/src/blua/luaconf.h b/src/blua/luaconf.h
index 4fb940799..9e2948f41 100644
--- a/src/blua/luaconf.h
+++ b/src/blua/luaconf.h
@@ -11,6 +11,13 @@
#include
#include
+#ifdef _MSC_VER
+#define INT32 __int32
+#else
+#include
+#define INT32 int32_t
+#endif
+
/*
** ==================================================================
@@ -140,7 +147,7 @@
** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
** machines, ptrdiff_t gives a good choice between int or long.)
*/
-#define LUA_INTEGER ptrdiff_t
+#define LUA_INTEGER INT32
/*
@@ -502,13 +509,13 @@
*/
//#define LUA_NUMBER_DOUBLE
-#define LUA_NUMBER ptrdiff_t
+#define LUA_NUMBER INT32
/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number.
*/
-#define LUAI_UACNUMBER ptrdiff_t
+#define LUAI_UACNUMBER INT32
/*
@@ -519,14 +526,14 @@
@@ lua_str2number converts a string to a number.
*/
#ifdef LUA_WIN
- #define LUA_NUMBER_SCAN "%Ii"
- #define LUA_NUMBER_FMT "%Ii"
+ #define LUA_NUMBER_SCAN "%d"
+ #define LUA_NUMBER_FMT "%d"
#else
- #define LUA_NUMBER_SCAN "%ti"
- #define LUA_NUMBER_FMT "%ti"
+ #define LUA_NUMBER_SCAN "%d"
+ #define LUA_NUMBER_FMT "%d"
#endif
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+#define LUAI_MAXNUMBER2STR 12 /* 10 digits, sign, and \0 */
#define lua_str2number(s,p) strtol((s), (p), 10)
diff --git a/src/d_main.c b/src/d_main.c
index 709cbea7b..c5f0d0b39 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -96,6 +96,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hardware/hw3sound.h"
#endif
+#ifdef HAVE_BLUA
+#include "lua_script.h"
+#endif
+
// platform independant focus loss
UINT8 window_notinfocus = false;
@@ -634,6 +638,10 @@ void D_SRB2Loop(void)
#ifdef HW3SOUND
HW3S_EndFrameUpdate();
#endif
+
+#ifdef HAVE_BLUA
+ LUA_Step();
+#endif
}
}
@@ -943,9 +951,9 @@ void D_SRB2Main(void)
#endif
#if defined (_WIN32_WCE) //|| defined (_DEBUG) || defined (GP2X)
- devparm = !M_CheckParm("-nodebug");
+ devparm = M_CheckParm("-nodebug") == 0;
#else
- devparm = M_CheckParm("-debug");
+ devparm = M_CheckParm("-debug") != 0;
#endif
// for dedicated server
@@ -1118,7 +1126,7 @@ void D_SRB2Main(void)
#endif
D_CleanFile();
-#if 1 // md5s last updated 12/14/14
+#ifndef DEVELOP // md5s last updated 12/14/14
// Check MD5s of autoloaded files
//W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 266161c7c..557715064 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -1911,7 +1911,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
}
if (players[suicideplayer].mo)
- P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 10000);
+ P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 1, DMG_INSTAKILL);
}
/** Deals with an ::XD_RANDOMSEED message in a netgame.
@@ -2442,7 +2442,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (players[playernum].mo)
{
if (!players[playernum].spectator)
- P_DamageMobj(players[playernum].mo, NULL, NULL, 10000);
+ P_DamageMobj(players[playernum].mo, NULL, NULL, 1, DMG_INSTAKILL);
else
{
P_RemoveMobj(players[playernum].mo);
@@ -3193,7 +3193,27 @@ static void Command_ModDetails_f(void)
//
static void Command_ShowGametype_f(void)
{
- CONS_Printf(M_GetText("Current gametype is %d\n"), gametype);
+ INT32 j;
+ const char *gametypestr = NULL;
+
+ if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op"
+ {
+ CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player"));
+ return;
+ }
+ // find name string for current gametype
+ for (j = 0; gametype_cons_t[j].strvalue; j++)
+ {
+ if (gametype_cons_t[j].value == gametype)
+ {
+ gametypestr = gametype_cons_t[j].strvalue;
+ break;
+ }
+ }
+ if (gametypestr)
+ CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr);
+ else // string for current gametype was not found above (should never happen)
+ CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype);
}
/** Plays the intro.
diff --git a/src/d_player.h b/src/d_player.h
index b9fcdef75..e2a1081b0 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -161,11 +161,15 @@ typedef enum
// Are animation frames playing?
PA_ETC=0,
PA_IDLE,
+ PA_EDGE,
PA_WALK,
PA_RUN,
+ PA_PAIN,
PA_ROLL,
+ PA_JUMP,
PA_FALL,
- PA_ABILITY
+ PA_ABILITY,
+ PA_RIDE
} panim_t;
typedef enum
diff --git a/src/dehacked.c b/src/dehacked.c
index b22f7b867..6905d8379 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -473,6 +473,7 @@ static void readPlayer(MYFILE *f, INT32 num)
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done;
+ PlayerMenu[num].status = IT_CALL;
for (i = 0; i < MAXLINELEN-3; i++)
{
@@ -545,6 +546,7 @@ static void readPlayer(MYFILE *f, INT32 num)
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done;
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
+ PlayerMenu[num].status = IT_CALL;
strncpy(description[num].picname, word2, 8);
}
else if (fastcmp(word, "STATUS"))
@@ -576,6 +578,8 @@ static void readPlayer(MYFILE *f, INT32 num)
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done;
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
+ PlayerMenu[num].status = IT_CALL;
+
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
strlwr(description[num].skinname);
}
@@ -994,7 +998,7 @@ static const struct {
static void readlevelheader(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
- char *word = s;
+ char *word;
char *word2;
//char *word3; // Non-uppercase version of word2
char *tmp;
@@ -1023,6 +1027,9 @@ static void readlevelheader(MYFILE *f, INT32 num)
if (s == tmp)
continue; // Skip comment lines, but don't break.
+ // Set / reset word, because some things (Lua.) move it
+ word = s;
+
// Get the part before the " = "
tmp = strchr(s, '=');
*(tmp-1) = '\0';
@@ -3736,52 +3743,48 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Thok
"S_THOK",
+ // Player
"S_PLAY_STND",
- "S_PLAY_TAP1",
- "S_PLAY_TAP2",
- "S_PLAY_RUN1",
- "S_PLAY_RUN2",
- "S_PLAY_RUN3",
- "S_PLAY_RUN4",
- "S_PLAY_RUN5",
- "S_PLAY_RUN6",
- "S_PLAY_RUN7",
- "S_PLAY_RUN8",
- "S_PLAY_SPD1",
- "S_PLAY_SPD2",
- "S_PLAY_SPD3",
- "S_PLAY_SPD4",
- "S_PLAY_ATK1",
- "S_PLAY_ATK2",
- "S_PLAY_ATK3",
- "S_PLAY_ATK4",
- "S_PLAY_SPRING",
- "S_PLAY_FALL1",
- "S_PLAY_FALL2",
- "S_PLAY_ABL1",
- "S_PLAY_ABL2",
- "S_PLAY_SPC1",
- "S_PLAY_SPC2",
- "S_PLAY_SPC3",
- "S_PLAY_SPC4",
- "S_PLAY_CLIMB1",
- "S_PLAY_CLIMB2",
- "S_PLAY_CLIMB3",
- "S_PLAY_CLIMB4",
- "S_PLAY_CLIMB5",
- "S_PLAY_GASP",
+ "S_PLAY_WAIT",
+ "S_PLAY_WALK",
+ "S_PLAY_RUN",
"S_PLAY_PAIN",
- "S_PLAY_DIE",
- "S_PLAY_TEETER1",
- "S_PLAY_TEETER2",
- "S_PLAY_CARRY",
- "S_PLAY_SUPERSTAND",
- "S_PLAY_SUPERWALK1",
- "S_PLAY_SUPERWALK2",
- "S_PLAY_SUPERFLY1",
- "S_PLAY_SUPERFLY2",
- "S_PLAY_SUPERTEETER",
- "S_PLAY_SUPERHIT",
+ "S_PLAY_DEAD",
+ "S_PLAY_DRWN",
+ "S_PLAY_SPIN",
+ "S_PLAY_DASH",
+ "S_PLAY_GASP",
+ "S_PLAY_JUMP",
+ "S_PLAY_FALL",
+ "S_PLAY_EDGE",
+ "S_PLAY_RIDE",
+
+ // CA_FLY
+ "S_PLAY_FLY",
+ "S_PLAY_FLY_TIRED",
+
+ // CA_GLIDEANDCLIMB
+ "S_PLAY_GLIDE",
+ "S_PLAY_CLING",
+ "S_PLAY_CLIMB",
+
+ // SF_SUPERANIMS
+ "S_PLAY_SUPER_STND",
+ "S_PLAY_SUPER_WALK",
+ "S_PLAY_SUPER_RUN",
+ "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_FALL",
+ "S_PLAY_SUPER_EDGE",
+ "S_PLAY_SUPER_RIDE",
+ "S_PLAY_SUPER_FLOAT",
+
+ // SF_SUPER
"S_PLAY_SUPERTRANS1",
"S_PLAY_SUPERTRANS2",
"S_PLAY_SUPERTRANS3",
@@ -3807,7 +3810,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Blue Crawla
"S_POSS_STND",
- "S_POSS_STND2",
"S_POSS_RUN1",
"S_POSS_RUN2",
"S_POSS_RUN3",
@@ -3817,7 +3819,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Red Crawla
"S_SPOS_STND",
- "S_SPOS_STND2",
"S_SPOS_RUN1",
"S_SPOS_RUN2",
"S_SPOS_RUN3",
@@ -4534,7 +4535,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// S_PLAY_TAP1
"S_METALSONIC_WAIT1",
"S_METALSONIC_WAIT2",
- // S_PLAY_RUN1
+ // S_PLAY_WALK
"S_METALSONIC_WALK1",
"S_METALSONIC_WALK2",
"S_METALSONIC_WALK3",
@@ -7172,7 +7173,6 @@ static const char *const MOBJFLAG2_LIST[] = {
"EXPLOSION", // Thrown ring has explosive properties
"SCATTER", // Thrown ring has scatter properties
"BEYONDTHEGRAVE",// Source of this missile has died and has since respawned.
- "PUSHED", // Mobj was already pushed this tic
"SLIDEPUSH", // MF_PUSHABLE that pushes continuously.
"CLASSICPUSH", // Drops straight down when object has negative Z.
"STANDONME", // While not pushable, stand on me anyway.
@@ -7201,6 +7201,9 @@ static const char *const MOBJEFLAG_LIST[] = {
"JUSTSTEPPEDDOWN", // used for ramp sectors
"VERTICALFLIP", // Vertically flip sprite/allow upside-down physics
"GOOWATER", // Goo water
+ "PUSHED", // Mobj was already pushed this tic
+ "SPRUNG", // Mobj was already sprung this tic
+ "APPLYPMOMZ", // Platform movement
NULL
};
@@ -7303,6 +7306,7 @@ static const char *const ML_LIST[16] = {
};
// This DOES differ from r_draw's Color_Names, unfortunately.
+// Also includes Super colors
static const char *COLOR_ENUMS[] = {
"NONE", // SKINCOLOR_NONE
"WHITE", // SKINCOLOR_WHITE
@@ -7334,6 +7338,24 @@ static const char *COLOR_ENUMS[] = {
"MAGENTA", // SKINCOLOR_MAGENTA
"PINK", // SKINCOLOR_PINK
"ROSY" // SKINCOLOR_ROSY
+ // Super special awesome Super flashing colors!
+ "SUPER1", // SKINCOLOR_SUPER1
+ "SUPER2", // SKINCOLOR_SUPER2,
+ "SUPER3", // SKINCOLOR_SUPER3,
+ "SUPER4", // SKINCOLOR_SUPER4,
+ "SUPER5", // SKINCOLOR_SUPER5,
+ // Super Tails
+ "TSUPER1", // SKINCOLOR_TSUPER1,
+ "TSUPER2", // SKINCOLOR_TSUPER2,
+ "TSUPER3", // SKINCOLOR_TSUPER3,
+ "TSUPER4", // SKINCOLOR_TSUPER4,
+ "TSUPER5", // SKINCOLOR_TSUPER5,
+ // Super Knuckles
+ "KSUPER1", // SKINCOLOR_KSUPER1,
+ "KSUPER2", // SKINCOLOR_KSUPER2,
+ "KSUPER3", // SKINCOLOR_KSUPER3,
+ "KSUPER4", // SKINCOLOR_KSUPER4,
+ "KSUPER5" // SKINCOLOR_KSUPER5,
};
static const char *const POWERS_LIST[] = {
@@ -7540,8 +7562,9 @@ struct {
{"EMERALD6",EMERALD6},
{"EMERALD7",EMERALD7},
- // SKINCOLOR_ doesn't include this..!
+ // SKINCOLOR_ doesn't include these..!
{"MAXSKINCOLORS",MAXSKINCOLORS},
+ {"MAXTRANSLATIONS",MAXTRANSLATIONS},
// Precipitation
{"PRECIP_NONE",PRECIP_NONE},
@@ -7651,11 +7674,15 @@ struct {
// Player animation (panim_t)
{"PA_ETC",PA_ETC},
{"PA_IDLE",PA_IDLE},
+ {"PA_EDGE",PA_EDGE},
{"PA_WALK",PA_WALK},
{"PA_RUN",PA_RUN},
+ {"PA_PAIN",PA_PAIN},
{"PA_ROLL",PA_ROLL},
+ {"PA_JUMP",PA_JUMP},
{"PA_FALL",PA_FALL},
{"PA_ABILITY",PA_ABILITY},
+ {"PA_RIDE",PA_RIDE},
// Current weapon
{"WEP_AUTO",WEP_AUTO},
@@ -7734,36 +7761,36 @@ struct {
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
// Angles
- {"ANG1",ANG1},
- {"ANG2",ANG2},
- {"ANG10",ANG10},
- {"ANG15",ANG15},
- {"ANG20",ANG20},
- {"ANG30",ANG30},
- {"ANG60",ANG60},
- {"ANG64h",ANG64h},
- {"ANG105",ANG105},
- {"ANG210",ANG210},
- {"ANG255",ANG255},
- {"ANG340",ANG340},
- {"ANG350",ANG350},
- {"ANGLE_11hh",ANGLE_11hh},
- {"ANGLE_22h",ANGLE_22h},
- {"ANGLE_45",ANGLE_45},
- {"ANGLE_67h",ANGLE_67h},
- {"ANGLE_90",ANGLE_90},
- {"ANGLE_112h",ANGLE_112h},
- {"ANGLE_135",ANGLE_135},
- {"ANGLE_157h",ANGLE_157h},
- {"ANGLE_180",ANGLE_180},
- {"ANGLE_202h",ANGLE_202h},
- {"ANGLE_225",ANGLE_225},
- {"ANGLE_247h",ANGLE_247h},
- {"ANGLE_270",ANGLE_270},
- {"ANGLE_292h",ANGLE_292h},
- {"ANGLE_315",ANGLE_315},
- {"ANGLE_337h",ANGLE_337h},
- {"ANGLE_MAX",ANGLE_MAX},
+ {"ANG1",ANG1>>16},
+ {"ANG2",ANG2>>16},
+ {"ANG10",ANG10>>16},
+ {"ANG15",ANG15>>16},
+ {"ANG20",ANG20>>16},
+ {"ANG30",ANG30>>16},
+ {"ANG60",ANG60>>16},
+ {"ANG64h",ANG64h>>16},
+ {"ANG105",ANG105>>16},
+ {"ANG210",ANG210>>16},
+ {"ANG255",ANG255>>16},
+ {"ANG340",ANG340>>16},
+ {"ANG350",ANG350>>16},
+ {"ANGLE_11hh",ANGLE_11hh>>16},
+ {"ANGLE_22h",ANGLE_22h>>16},
+ {"ANGLE_45",ANGLE_45>>16},
+ {"ANGLE_67h",ANGLE_67h>>16},
+ {"ANGLE_90",ANGLE_90>>16},
+ {"ANGLE_112h",ANGLE_112h>>16},
+ {"ANGLE_135",ANGLE_135>>16},
+ {"ANGLE_157h",ANGLE_157h>>16},
+ {"ANGLE_180",ANGLE_180>>16},
+ {"ANGLE_202h",ANGLE_202h>>16},
+ {"ANGLE_225",ANGLE_225>>16},
+ {"ANGLE_247h",ANGLE_247h>>16},
+ {"ANGLE_270",ANGLE_270>>16},
+ {"ANGLE_292h",ANGLE_292h>>16},
+ {"ANGLE_315",ANGLE_315>>16},
+ {"ANGLE_337h",ANGLE_337h>>16},
+ {"ANGLE_MAX",ANGLE_MAX>>16},
// P_Chase directions (dirtype_t)
{"DI_NODIR",DI_NODIR},
@@ -8162,7 +8189,7 @@ static fixed_t find_const(const char **rword)
}
else if (fastncmp("SKINCOLOR_",word,10)) {
char *p = word+10;
- for (i = 0; i < MAXSKINCOLORS; i++)
+ for (i = 0; i < MAXTRANSLATIONS; i++)
if (fastcmp(p, COLOR_ENUMS[i])) {
free(word);
return i;
@@ -8221,8 +8248,8 @@ void DEH_Check(void)
if (dehpowers != NUMPOWERS)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers));
- if (dehcolors != MAXSKINCOLORS)
- I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXSKINCOLORS, sizeu1(dehcolors));
+ if (dehcolors != MAXTRANSLATIONS)
+ I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors));
#endif
}
@@ -8491,6 +8518,27 @@ static inline int lib_getenum(lua_State *L)
if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word);
return 0;
}
+ else if (fastncmp("SPR2_",word,4)) {
+ p = word+5;
+ for (i = 0; i < NUMPLAYERSPRITES; i++)
+ if (!spr2names[i][4])
+ {
+ // special 3-char cases, e.g. SPR2_RUN
+ // the spr2names entry will have "_" on the end, as in "RUN_"
+ if (spr2names[i][3] == '_' && !p[3]) {
+ if (fastncmp(p,spr2names[i],3)) {
+ lua_pushinteger(L, i);
+ return 1;
+ }
+ }
+ else if (fastncmp(p,spr2names[i],4)) {
+ lua_pushinteger(L, i);
+ return 1;
+ }
+ }
+ if (mathlib) return luaL_error(L, "player sprite '%s' could not be found.\n", word);
+ return 0;
+ }
else if (!mathlib && fastncmp("sfx_",word,4)) {
p = word+4;
for (i = 0; i < NUMSFX; i++)
@@ -8576,7 +8624,7 @@ static inline int lib_getenum(lua_State *L)
}
else if (fastncmp("SKINCOLOR_",word,10)) {
p = word+10;
- for (i = 0; i < MAXSKINCOLORS; i++)
+ for (i = 0; i < MAXTRANSLATIONS; i++)
if (fastcmp(p, COLOR_ENUMS[i])) {
lua_pushinteger(L, i);
return 1;
@@ -8701,7 +8749,7 @@ static inline int lib_getenum(lua_State *L)
lua_pushinteger(L, mapmusic);
return 1;
} else if (fastcmp(word,"server")) {
- if (!playeringame[serverplayer])
+ if ((!multiplayer || !netgame) && !playeringame[serverplayer])
return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1;
diff --git a/src/doomdef.h b/src/doomdef.h
index 88fc206a2..46dcd0808 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -138,15 +138,17 @@
extern FILE *logstream;
#endif
-#if 0
+#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
+#ifdef DEVELOP
#define VERSION 0 // Game version
#define SUBVERSION 0 // more precise version number
#define VERSIONSTRING "Trunk"
+#define VERSIONSTRINGW L"Trunk"
#else
-#define VERSION 201 // Game version
-#define SUBVERSION 14 // more precise version number
-#define VERSIONSTRING "v2.1.14"
-#define VERSIONSTRINGW L"v2.1.14"
+#define VERSION 202 // Game version
+#define SUBVERSION 0 // more precise version number
+#define VERSIONSTRING "v2.2"
+#define VERSIONSTRINGW L"v2.2"
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
@@ -193,7 +195,7 @@ extern FILE *logstream;
// and should not be changed unless you have merged changes between versions of SRB2
// (such as 2.0.4 to 2.0.5, etc) into your working copy.
// Will always resemble the versionstring, 205 = 2.0.5, 210 = 2.1, etc.
-#define CODEBASE 210
+#define CODEBASE 220
// The Modification ID; must be obtained from Inuyasha ( http://mb.srb2.org/private.php?do=newpm&u=2604 ).
// DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server.
@@ -204,7 +206,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 19
+#define MODVERSION 20
@@ -441,6 +443,9 @@ extern const char *compdate, *comptime, *comprevision;
/// Fun experimental slope stuff!
//#define SLOPENESS
+/// Kalaron/Eternity Engine slope code (SRB2CB ported)
+#define ESLOPE
+
/// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE
diff --git a/src/f_finale.c b/src/f_finale.c
index f541995d4..a85fd11cb 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -982,6 +982,7 @@ static const char *credits[] = {
"",
"\1Programming",
"\1Assistance",
+ "\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
"Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick",
"Julio \"Chaos Zero 64\" Guir",
diff --git a/src/g_game.c b/src/g_game.c
index 17734da64..0f29d6a41 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2180,8 +2180,7 @@ void G_PlayerReborn(INT32 player)
p->health = 1; // 0 rings
p->panim = PA_IDLE; // standing animation
- if ((netgame || multiplayer) && !p->spectator
- && gametype != GT_RACE)
+ if ((netgame || multiplayer) && !p->spectator)
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
if (p-players == consoleplayer)
@@ -3687,6 +3686,7 @@ static ticcmd_t oldcmd;
#define GZT_SPRITE 0x10 // Animation frame
#define GZT_EXTRA 0x20
#define GZT_NIGHTS 0x40 // NiGHTS Mode stuff!
+#define GZT_SPR2 0x80 // Player animations
// GZT_EXTRA flags
#define EZT_THOK 0x01 // Spawned a thok object
@@ -3890,8 +3890,6 @@ void G_WriteGhostTic(mobj_t *ghost)
char ziptic = 0;
UINT8 *ziptic_p;
UINT32 i;
- UINT8 sprite;
- UINT8 frame;
if (!demo_p)
return;
@@ -3966,19 +3964,25 @@ void G_WriteGhostTic(mobj_t *ghost)
}
// Store the sprite frame.
- frame = ghost->frame & 0xFF;
- if (frame != oldghost.frame)
+ if ((ghost->frame & 0xFF) != oldghost.frame)
{
- oldghost.frame = frame;
+ oldghost.frame = (ghost->frame & 0xFF);
ziptic |= GZT_SPRITE;
WRITEUINT8(demo_p,oldghost.frame);
}
- // Check for sprite set changes
- sprite = ghost->sprite;
- if (sprite != oldghost.sprite)
+ if (ghost->sprite == SPR_PLAY
+ && ghost->sprite2 != oldghost.sprite2)
{
- oldghost.sprite = sprite;
+ oldghost.sprite2 = ghost->sprite2;
+ ziptic |= GZT_SPR2;
+ WRITEUINT8(demo_p,oldghost.sprite2);
+ }
+
+ // Check for sprite set changes
+ if (ghost->sprite != oldghost.sprite)
+ {
+ oldghost.sprite = ghost->sprite;
ghostext.flags |= EZT_SPRITE;
}
@@ -4021,7 +4025,7 @@ void G_WriteGhostTic(mobj_t *ghost)
ghostext.hitlist = NULL;
}
if (ghostext.flags & EZT_SPRITE)
- WRITEUINT8(demo_p,sprite);
+ WRITEUINT8(demo_p,oldghost.sprite);
ghostext.flags = 0;
}
@@ -4077,6 +4081,8 @@ void G_ConsGhostTic(void)
demo_p++;
if (ziptic & GZT_SPRITE)
demo_p++;
+ if (ziptic & GZT_SPR2)
+ demo_p++;
if(ziptic & GZT_NIGHTS) {
if (!testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer)
nightsfail = true;
@@ -4128,7 +4134,7 @@ void G_ConsGhostTic(void)
if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
- P_DamageMobj(mobj, players[0].mo, players[0].mo, 1);
+ P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, 0);
}
}
}
@@ -4208,6 +4214,8 @@ void G_GhostTicker(void)
g->oldmo.angle = READUINT8(g->p)<<24;
if (ziptic & GZT_SPRITE)
g->oldmo.frame = READUINT8(g->p);
+ if (ziptic & GZT_SPR2)
+ g->oldmo.sprite2 = READUINT8(g->p);
// Update ghost
P_UnsetThingPosition(g->mo);
@@ -4217,6 +4225,7 @@ void G_GhostTicker(void)
P_SetThingPosition(g->mo);
g->mo->angle = g->oldmo.angle;
g->mo->frame = g->oldmo.frame | tr_trans30<mo->sprite2 = g->oldmo.sprite2;
if (ziptic & GZT_EXTRA)
{ // But wait, there's more!
@@ -4330,20 +4339,10 @@ void G_GhostTicker(void)
switch(g->color)
{
case GHC_SUPER: // Super Sonic (P_DoSuperStuff)
- // Yousa yellow now!
- g->mo->color = SKINCOLOR_SUPER1 + (leveltime/2) % 5;
- if (g->mo->skin)
- switch (((skin_t*)g->mo->skin)-skins)
- {
- case 1: // Golden orange supertails.
- g->mo->color = SKINCOLOR_TSUPER1 + (leveltime/2) % 5;
- break;
- case 2: // Pink superknux.
- g->mo->color = SKINCOLOR_KSUPER1 + (leveltime/2) % 5;
- break;
- default:
- break;
- }
+ if (leveltime % 9 < 5)
+ g->mo->color = SKINCOLOR_SUPER1 + leveltime % 9;
+ else
+ g->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS);
@@ -4401,6 +4400,8 @@ void G_ReadMetalTic(mobj_t *metal)
oldmetal.angle = READUINT8(metal_p)<<24;
if (ziptic & GZT_SPRITE)
metal_p++; // Currently unused. (Metal Sonic figures out what he's doing his own damn self.)
+ if (ziptic & GZT_SPR2)
+ metal_p++;
// Set movement, position, and angle
// oldmetal contains where you're supposed to be.
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index db812c0df..820eb25fc 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3527,6 +3527,184 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
return false;
}
+static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale)
+{
+ UINT8 i;
+ float tr_x, tr_y;
+ FOutVector *wv;
+ FOutVector swallVerts[4];
+ FSurfaceInfo sSurf;
+ fixed_t floorheight, mobjfloor;
+
+ mobjfloor = HWR_OpaqueFloorAtPos(
+ spr->mobj->x, spr->mobj->y,
+ spr->mobj->z, spr->mobj->height);
+ if (cv_shadowoffs.value)
+ {
+ angle_t shadowdir;
+
+ // Set direction
+ if (splitscreen && stplyr != &players[displayplayer])
+ shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
+ else
+ shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
+
+ // Find floorheight
+ floorheight = HWR_OpaqueFloorAtPos(
+ spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
+ spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
+ spr->mobj->z, spr->mobj->height);
+
+ // The shadow is falling ABOVE it's mobj?
+ // Don't draw it, then!
+ if (spr->mobj->z < floorheight)
+ return;
+ else
+ {
+ fixed_t floorz;
+ floorz = HWR_OpaqueFloorAtPos(
+ spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
+ spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
+ spr->mobj->z, spr->mobj->height);
+ // The shadow would be falling on a wall? Don't draw it, then.
+ // Would draw midair otherwise.
+ if (floorz < floorheight)
+ return;
+ }
+
+ floorheight = FixedInt(spr->mobj->z - floorheight);
+ }
+ else
+ floorheight = FixedInt(spr->mobj->z - mobjfloor);
+
+ // create the sprite billboard
+ //
+ // 3--2
+ // | /|
+ // |/ |
+ // 0--1
+
+ // x1/x2 were already scaled in HWR_ProjectSprite
+ swallVerts[0].x = swallVerts[3].x = spr->x1;
+ swallVerts[2].x = swallVerts[1].x = spr->x2;
+
+ if (spr->mobj && this_scale != 1.0f)
+ {
+ // Always a pixel above the floor, perfectly flat.
+ swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3);
+
+ swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale;
+ swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale;
+ }
+ else
+ {
+ // Always a pixel above the floor, perfectly flat.
+ swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3);
+
+ // Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.)
+ swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset);
+ swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset;
+ }
+
+ // transform
+ wv = swallVerts;
+
+ for (i = 0; i < 4; i++,wv++)
+ {
+ // Offset away from the camera based on height from floor.
+ if (cv_shadowoffs.value)
+ wv->z += floorheight;
+ wv->z += 3;
+
+ //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ tr_x = wv->z;
+ tr_y = wv->y;
+ wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin);
+ wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos);
+ // ---------------------- mega lame test ----------------------------------
+
+ //scale y before frustum so that frustum can be scaled to screen height
+ wv->y *= ORIGINAL_ASPECT * gr_fovlud;
+ wv->x *= gr_fovlud;
+ }
+
+ if (spr->flip)
+ {
+ swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s;
+ swallVerts[2].sow = swallVerts[1].sow = 0;
+ }
+ else
+ {
+ swallVerts[0].sow = swallVerts[3].sow = 0;
+ swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s;
+ }
+
+ // flip the texture coords (look familiar?)
+ if (spr->vflip)
+ {
+ swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t;
+ swallVerts[0].tow = swallVerts[1].tow = 0;
+ }
+ else
+ {
+ swallVerts[3].tow = swallVerts[2].tow = 0;
+ swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t;
+ }
+
+ sSurf.FlatColor.s.red = 0x00;
+ sSurf.FlatColor.s.blue = 0x00;
+ sSurf.FlatColor.s.green = 0x00;
+
+ /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
+ {
+ sector_t *sector = spr->mobj->subsector->sector;
+ UINT8 lightlevel = 255;
+ extracolormap_t *colormap = sector->extra_colormap;
+
+ if (sector->numlights)
+ {
+ INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false);
+
+ if (!(spr->mobj->frame & FF_FULLBRIGHT))
+ lightlevel = *sector->lightlist[light].lightlevel;
+
+ if (sector->lightlist[light].extra_colormap)
+ colormap = sector->lightlist[light].extra_colormap;
+ }
+ else
+ {
+ lightlevel = sector->lightlevel;
+
+ if (sector->extra_colormap)
+ colormap = sector->extra_colormap;
+ }
+
+ if (colormap)
+ sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
+ else
+ sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
+ }*/
+
+ // shadow is always half as translucent as the sprite itself
+ if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency)
+ sSurf.FlatColor.s.alpha = 0x80; // default
+ else if (spr->mobj->flags2 & MF2_SHADOW)
+ sSurf.FlatColor.s.alpha = 0x20;
+ else if (spr->mobj->frame & FF_TRANSMASK)
+ {
+ HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
+ sSurf.FlatColor.s.alpha /= 2; //cut alpha in half!
+ }
+ else
+ sSurf.FlatColor.s.alpha = 0x80; // default
+
+ if (sSurf.FlatColor.s.alpha > floorheight/4)
+ {
+ sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4);
+ HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
+ }
+}
+
// -----------------+
// HWR_DrawSprite : Draw flat sprites
// : (monsters, bonuses, weapons, lights, ...)
@@ -3629,7 +3807,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
// Draw shadow BEFORE sprite
if (cv_shadow.value // Shadows enabled
- && !(spr->mobj->flags & MF_SCENERY && spr->mobj->flags & MF_SPAWNCEILING && spr->mobj->flags & MF_NOGRAVITY) // Ceiling scenery have no shadow.
+ && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
#ifdef ALAM_LIGHTING
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
@@ -3640,187 +3818,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
////////////////////
// SHADOW SPRITE! //
////////////////////
- FOutVector swallVerts[4];
- FSurfaceInfo sSurf;
- fixed_t floorheight, mobjfloor;
-
- mobjfloor = HWR_OpaqueFloorAtPos(
- spr->mobj->x, spr->mobj->y,
- spr->mobj->z, spr->mobj->height);
- if (cv_shadowoffs.value)
- {
- angle_t shadowdir;
-
- // Set direction
- if (splitscreen && stplyr != &players[displayplayer])
- shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
- else
- shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
-
- // Find floorheight
- floorheight = HWR_OpaqueFloorAtPos(
- spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
- spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
- spr->mobj->z, spr->mobj->height);
-
- // The shadow is falling ABOVE it's mobj?
- // Don't draw it, then!
- if (spr->mobj->z < floorheight)
- goto noshadow;
- else
- {
- fixed_t floorz;
- floorz = HWR_OpaqueFloorAtPos(
- spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
- spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
- spr->mobj->z, spr->mobj->height);
- // The shadow would be falling on a wall? Don't draw it, then.
- // Would draw midair otherwise.
- if (floorz < floorheight)
- goto noshadow;
- }
-
- floorheight = FixedInt(spr->mobj->z - floorheight);
- }
- else
- floorheight = FixedInt(spr->mobj->z - mobjfloor);
-
- // create the sprite billboard
- //
- // 3--2
- // | /|
- // |/ |
- // 0--1
-
- // x1/x2 were already scaled in HWR_ProjectSprite
- swallVerts[0].x = swallVerts[3].x = spr->x1;
- swallVerts[2].x = swallVerts[1].x = spr->x2;
-
- if (spr->mobj && this_scale != 1.0f)
- {
- // Always a pixel above the floor, perfectly flat.
- swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3);
-
- swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale;
- swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale;
- }
- else
- {
- // Always a pixel above the floor, perfectly flat.
- swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3);
-
- // Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.)
- swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset);
- swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset;
- }
-
- // transform
- wv = swallVerts;
-
- for (i = 0; i < 4; i++,wv++)
- {
- // Offset away from the camera based on height from floor.
- if (cv_shadowoffs.value)
- wv->z += floorheight;
- wv->z += 3;
-
- //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- tr_x = wv->z;
- tr_y = wv->y;
- wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin);
- wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos);
- // ---------------------- mega lame test ----------------------------------
-
- //scale y before frustum so that frustum can be scaled to screen height
- wv->y *= ORIGINAL_ASPECT * gr_fovlud;
- wv->x *= gr_fovlud;
- }
-
- if (spr->flip)
- {
- swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s;
- swallVerts[2].sow = swallVerts[1].sow = 0;
- }
- else
- {
- swallVerts[0].sow = swallVerts[3].sow = 0;
- swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s;
- }
-
- // flip the texture coords (look familiar?)
- if (spr->vflip)
- {
- swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t;
- swallVerts[0].tow = swallVerts[1].tow = 0;
- }
- else
- {
- swallVerts[3].tow = swallVerts[2].tow = 0;
- swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t;
- }
-
- sSurf.FlatColor.s.red = 0x00;
- sSurf.FlatColor.s.blue = 0x00;
- sSurf.FlatColor.s.green = 0x00;
-
- /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
- {
- sector_t *sector = spr->mobj->subsector->sector;
- UINT8 lightlevel = sector->lightlevel;
- extracolormap_t *colormap = sector->extra_colormap;
-
- if (sector->numlights)
- {
- INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false);
-
- if (!(spr->mobj->frame & FF_FULLBRIGHT))
- lightlevel = *sector->lightlist[light].lightlevel;
- else
- lightlevel = 255;
-
- if (sector->lightlist[light].extra_colormap)
- colormap = sector->lightlist[light].extra_colormap;
- }
- else
- {
- lightlevel = sector->lightlevel;
-
- if (sector->extra_colormap)
- colormap = sector->extra_colormap;
- }
-
- if (colormap)
- sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
- else
- sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
- }*/
-
- // shadow is always half as translucent as the sprite itself
- if (!cv_translucency.value)
- ; // translucency disabled
- else if (spr->mobj->flags2 & MF2_SHADOW)
- sSurf.FlatColor.s.alpha = 0x20;
- else if (spr->mobj->frame & FF_TRANSMASK)
- {
- HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
- sSurf.FlatColor.s.alpha /= 2; //cut alpha in half!
- }
- else
- sSurf.FlatColor.s.alpha = 0x80; // default
-
- /// \todo do the test earlier
- if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f) || (md2_models[spr->mobj->sprite].notfound = true) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound = true))
- {
- if (sSurf.FlatColor.s.alpha > floorheight/4)
- {
- sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4);
- HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
- }
- }
+ HWR_DrawSpriteShadow(spr, gpatch, this_scale);
}
-noshadow:
-
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
// sprite lighting by modulating the RGB components
/// \todo coloured
@@ -3828,7 +3828,7 @@ noshadow:
// colormap test
{
sector_t *sector = spr->mobj->subsector->sector;
- UINT8 lightlevel = sector->lightlevel;
+ UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights)
@@ -3839,8 +3839,6 @@ noshadow:
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
- else
- lightlevel = 255;
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
@@ -3849,27 +3847,25 @@ noshadow:
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
- else
- lightlevel = 255;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
}
- if (spr->mobj->frame & FF_FULLBRIGHT)
- lightlevel = 255;
-
if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
}
- /// \todo do the test earlier
- if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f))
{
FBITFIELD blend = 0;
- if (spr->mobj->flags2 & MF2_SHADOW)
+ if (!cv_translucency.value) // translucency disabled
+ {
+ Surf.FlatColor.s.alpha = 0xFF;
+ blend = PF_Translucent|PF_Occlude;
+ }
+ else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.FlatColor.s.alpha = 0x40;
blend = PF_Translucent;
@@ -4390,10 +4386,10 @@ static void HWR_DrawSprites(void)
#endif
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{
- if (!cv_grmd2.value || (cv_grmd2.value && md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == true))
+ if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
HWR_DrawSprite(spr);
}
- else if (!cv_grmd2.value || (cv_grmd2.value && md2_models[spr->mobj->sprite].notfound == true))
+ else if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
HWR_DrawSprite(spr);
}
}
@@ -4419,7 +4415,7 @@ static void HWR_DrawMD2S(void)
#endif
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{
- if ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false) && (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f))
+ if (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false && md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f)
HWR_DrawMD2(spr);
}
else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f)
@@ -4461,23 +4457,12 @@ static void HWR_AddSprites(sector_t *sec)
// If a limit exists, handle things a tiny bit different.
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS))
{
- if (!players[displayplayer].mo)
- return; // Draw nothing if no player.
- // todo: is this really the best option for this situation?
-
for (thing = sec->thinglist; thing; thing = thing->snext)
{
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
continue;
- approx_dist = P_AproxDistance(
- players[displayplayer].mo->x - thing->x,
- players[displayplayer].mo->y - thing->y);
-
- if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo)
- approx_dist = P_AproxDistance(
- players[secondarydisplayplayer].mo->x - thing->x,
- players[secondarydisplayplayer].mo->y - thing->y);
+ approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
if (approx_dist <= limit_dist)
HWR_ProjectSprite(thing);
@@ -4495,23 +4480,12 @@ static void HWR_AddSprites(sector_t *sec)
// Someone seriously wants infinite draw distance for precipitation?
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS))
{
- if (!players[displayplayer].mo)
- return; // Draw nothing if no player.
- // todo: is this really the best option for this situation?
-
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
{
- if (precipthing->invisible)
+ if (precipthing->precipflags & PCF_INVISIBLE)
continue;
- approx_dist = P_AproxDistance(
- players[displayplayer].mo->x - precipthing->x,
- players[displayplayer].mo->y - precipthing->y);
-
- if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo)
- approx_dist = P_AproxDistance(
- players[secondarydisplayplayer].mo->x - precipthing->x,
- players[secondarydisplayplayer].mo->y - precipthing->y);
+ approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
if (approx_dist <= limit_dist)
HWR_ProjectPrecipitationSprite(precipthing);
@@ -4521,7 +4495,7 @@ static void HWR_AddSprites(sector_t *sec)
{
// Draw everything in sector, no checks
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
- if (!precipthing->invisible)
+ if (!(precipthing->precipflags & PCF_INVISIBLE))
HWR_ProjectPrecipitationSprite(precipthing);
}
#endif
@@ -4576,16 +4550,17 @@ static void HWR_ProjectSprite(mobj_t *thing)
//Fab : 02-08-98: 'skin' override spritedef currently used for skin
if (thing->skin && thing->sprite == SPR_PLAY)
- sprdef = &((skin_t *)thing->skin)->spritedef;
+ sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
else
sprdef = &sprites[thing->sprite];
if (rot >= sprdef->numframes)
{
- CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
+ CONS_Alert(CONS_ERROR, M_GetText("HWR_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame;
+ sprdef = &sprites[thing->sprite];
rot = thing->frame&FF_FRAMEMASK;
thing->state->sprite = thing->sprite;
thing->state->frame = thing->frame;
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index 02f505351..8d578a1ec 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -921,24 +921,25 @@ void HWR_InitMD2(void)
}
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
+ if (stricmp(name, "PLAY") == 0)
+ {
+ CONS_Printf("MD2 for sprite PLAY detected in md2.dat, use a player skin instead!\n");
+ continue;
+ }
+
for (i = 0; i < NUMSPRITES; i++)
{
if (stricmp(name, sprnames[i]) == 0)
{
- if (stricmp(name, "PLAY") == 0)
- continue;
+ //if (stricmp(name, "PLAY") == 0)
+ //continue;
//CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset);
md2_models[i].scale = scale;
md2_models[i].offset = offset;
md2_models[i].notfound = false;
strcpy(md2_models[i].filename, filename);
- break;
- }
- if (i == NUMSPRITES)
- {
- CONS_Printf("MD2 for sprite %s not found\n", name);
- md2_models[i].notfound = true;
+ goto md2found;
}
}
@@ -952,15 +953,14 @@ void HWR_InitMD2(void)
md2_playermodels[s].offset = offset;
md2_playermodels[s].notfound = false;
strcpy(md2_playermodels[s].filename, filename);
- break;
- }
- if (s == MAXSKINS-1)
- {
- CONS_Printf("MD2 for player skin %s not found\n", name);
- md2_playermodels[s].notfound = true;
+ goto md2found;
}
}
-
+ // no sprite/player skin name found?!?
+ CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name);
+md2found:
+ // move on to next line...
+ continue;
}
fclose(f);
}
@@ -996,17 +996,14 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
md2_playermodels[skin].offset = offset;
md2_playermodels[skin].notfound = false;
strcpy(md2_playermodels[skin].filename, filename);
- break;
- }
- if (skin == MAXSKINS-1)
- {
- CONS_Printf("MD2 for player skin %s not found\n", name);
- md2_playermodels[skin].notfound = true;
+ goto playermd2found;
}
}
+ //CONS_Printf("MD2 for player skin %s not found\n", skins[skin].name);
+ md2_playermodels[skin].notfound = true;
+playermd2found:
fclose(f);
-
}
@@ -1021,6 +1018,9 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
if (nomd2s)
return;
+ if (spritenum == SPR_PLAY) // Handled already NEWMD2: Per sprite, per-skin check
+ return;
+
// Read the md2.dat file
f = fopen("md2.dat", "rt");
@@ -1034,27 +1034,19 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
// Check for any MD2s that match the names of player skins!
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
+ if (stricmp(name, sprnames[spritenum]) == 0)
{
- if (stricmp(name, sprnames[spritenum]) == 0)
- {
- if (stricmp(name, "PLAY") == 0) // Handled already NEWMD2: Per sprite, per-skin check
- continue;
-
- md2_models[spritenum].scale = scale;
- md2_models[spritenum].offset = offset;
- md2_models[spritenum].notfound = false;
- strcpy(md2_models[spritenum].filename, filename);
- break;
- }
-
- if (spritenum == NUMSPRITES-1)
- {
- CONS_Printf("MD2 for sprite %s not found\n", name);
- md2_models[spritenum].notfound = true;
- }
+ md2_models[spritenum].scale = scale;
+ md2_models[spritenum].offset = offset;
+ md2_models[spritenum].notfound = false;
+ strcpy(md2_models[spritenum].filename, filename);
+ goto spritemd2found;
}
}
+ //CONS_Printf("MD2 for sprite %s not found\n", sprnames[spritenum]);
+ md2_models[spritenum].notfound = true;
+spritemd2found:
fclose(f);
}
@@ -1090,11 +1082,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
md2_t *md2;
UINT8 color[4];
+ if (!cv_grmd2.value)
+ return;
+
+ if (!spr->precip)
+ return;
+
// MD2 colormap fix
// colormap test
{
sector_t *sector = spr->mobj->subsector->sector;
- UINT8 lightlevel = sector->lightlevel;
+ UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights)
@@ -1105,8 +1103,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
- else
- lightlevel = 255;
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
@@ -1115,24 +1111,18 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
- else
- lightlevel = 255;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
}
- if (spr->mobj->frame & FF_FULLBRIGHT)
- lightlevel = 255;
-
if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
}
- // Look at HWR_ProjetctSprite for more
- if (cv_grmd2.value && ((md2_models[spr->mobj->sprite].scale > 0.0f) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f)) && !spr->precip)
+ // Look at HWR_ProjectSprite for more
{
GLPatch_t *gpatch;
INT32 *buff;
@@ -1149,15 +1139,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
//durs = tics;
if (spr->mobj->flags2 & MF2_SHADOW)
- {
Surf.FlatColor.s.alpha = 0x40;
- }
else if (spr->mobj->frame & FF_TRANSMASK)
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else
- {
Surf.FlatColor.s.alpha = 0xFF;
- }
// dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted
@@ -1215,7 +1201,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1
&& spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
- && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND]))
+ && !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND]))
{
const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
@@ -1231,7 +1217,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.z = FIXED_TO_FLOAT(spr->mobj->z);
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
- sprdef = &((skin_t *)spr->mobj->skin)->spritedef;
+ sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2];
else
sprdef = &sprites[spr->mobj->sprite];
@@ -1263,8 +1249,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.flip = false;
HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color);
-
-
}
}
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 76543e259..d14324c30 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -1910,6 +1910,13 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
+ // Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?!
+ if (color[3] < 255)
+ {
+ pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
+ pglDepthMask(GL_FALSE);
+ }
+
val = *gl_cmd_buffer++;
while (val != 0)
diff --git a/src/info.c b/src/info.c
index fb30258c3..8d7c249ad 100644
--- a/src/info.c
+++ b/src/info.c
@@ -56,6 +56,50 @@ char sprnames[NUMSPRITES + 1][5] =
"SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO",
};
+char spr2names[NUMPLAYERSPRITES][5] =
+{
+ "STND",
+ "WAIT",
+ "WALK",
+ "RUN_",
+ "PAIN",
+ "DEAD",
+ "DRWN",
+ "SPIN",
+ "DASH",
+ "GASP",
+ "JUMP",
+ "FALL",
+ "EDGE",
+ "RIDE",
+
+ "SIGN",
+ "LIFE",
+
+ "FLY_",
+ "TIRE",
+
+ "GLID",
+ "CLNG",
+ "CLMB",
+
+ "TRNS",
+ "SSTD",
+ "SWLK",
+ "SRUN",
+ "SPAN",
+ "SMSL",
+ "SDTH",
+ "SDRN",
+ "SSPN",
+ "SGSP",
+ "SJMP",
+ "SFAL",
+ "SEDG",
+ "SRID",
+ "SFLT"
+};
+
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
state_t states[NUMSTATES] =
{
@@ -81,77 +125,71 @@ state_t states[NUMSTATES] =
{SPR_THOK, FF_TRANS50, 8, {NULL}, 0, 0, S_NULL}, // S_THOK
// Player
- {SPR_PLAY, 0, 105, {NULL}, 0, 0, S_PLAY_TAP1}, // S_PLAY_STND
- {SPR_PLAY, 1, 16, {NULL}, 0, 0, S_PLAY_TAP2}, // S_PLAY_TAP1
- {SPR_PLAY, 2, 16, {NULL}, 0, 0, S_PLAY_TAP1}, // S_PLAY_TAP2
- {SPR_PLAY, 3, 4, {NULL}, 0, 0, S_PLAY_RUN2}, // S_PLAY_RUN1
- {SPR_PLAY, 4, 4, {NULL}, 0, 0, S_PLAY_RUN3}, // S_PLAY_RUN2
- {SPR_PLAY, 5, 4, {NULL}, 0, 0, S_PLAY_RUN4}, // S_PLAY_RUN3
- {SPR_PLAY, 6, 4, {NULL}, 0, 0, S_PLAY_RUN5}, // S_PLAY_RUN4
- {SPR_PLAY, 7, 4, {NULL}, 0, 0, S_PLAY_RUN6}, // S_PLAY_RUN5
- {SPR_PLAY, 8, 4, {NULL}, 0, 0, S_PLAY_RUN7}, // S_PLAY_RUN6
- {SPR_PLAY, 9, 4, {NULL}, 0, 0, S_PLAY_RUN8}, // S_PLAY_RUN7
- {SPR_PLAY, 10, 4, {NULL}, 0, 0, S_PLAY_RUN1}, // S_PLAY_RUN8
- {SPR_PLAY, 16, 2, {NULL}, 0, 0, S_PLAY_SPD2}, // S_PLAY_SPD1
- {SPR_PLAY, 17, 2, {NULL}, 0, 0, S_PLAY_SPD3}, // S_PLAY_SPD2
- {SPR_PLAY, 18, 2, {NULL}, 0, 0, S_PLAY_SPD4}, // S_PLAY_SPD3
- {SPR_PLAY, 19, 2, {NULL}, 0, 0, S_PLAY_SPD1}, // S_PLAY_SPD4
- {SPR_PLAY, 11, 1, {NULL}, 0, 0, S_PLAY_ATK2}, // S_PLAY_ATK1
- {SPR_PLAY, 12, 1, {NULL}, 0, 0, S_PLAY_ATK3}, // S_PLAY_ATK2
- {SPR_PLAY, 13, 1, {NULL}, 0, 0, S_PLAY_ATK4}, // S_PLAY_ATK3
- {SPR_PLAY, 14, 1, {NULL}, 0, 0, S_PLAY_ATK1}, // S_PLAY_ATK4
- {SPR_PLAY, 15, -1, {NULL}, 0, 0, S_PLAY_FALL1}, // S_PLAY_SPRING
- {SPR_PLAY, 31, 2, {NULL}, 0, 0, S_PLAY_FALL2}, // S_PLAY_FALL1
- {SPR_PLAY, 32, 2, {NULL}, 0, 0, S_PLAY_FALL1}, // S_PLAY_FALL2
- {SPR_PLAY, 20, 2, {NULL}, 0, 0, S_PLAY_ABL2}, // S_PLAY_ABL1
- {SPR_PLAY, 21, 2, {NULL}, 0, 0, S_PLAY_ABL1}, // S_PLAY_ABL2
- {SPR_PLAY, 22, 6, {NULL}, 0, 0, S_PLAY_SPC2}, // S_PLAY_SPC1
- {SPR_PLAY, 23, 6, {NULL}, 0, 0, S_PLAY_SPC3}, // S_PLAY_SPC2
- {SPR_PLAY, 24, 6, {NULL}, 0, 0, S_PLAY_SPC4}, // S_PLAY_SPC3
- {SPR_PLAY, 25, 6, {NULL}, 0, 0, S_PLAY_SPC1}, // S_PLAY_SPC4
- {SPR_PLAY, 22, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_CLIMB1
- {SPR_PLAY, 23, 5, {NULL}, 0, 0, S_PLAY_CLIMB3}, // S_PLAY_CLIMB2
- {SPR_PLAY, 24, 5, {NULL}, 0, 0, S_PLAY_CLIMB4}, // S_PLAY_CLIMB3
- {SPR_PLAY, 25, 5, {NULL}, 0, 0, S_PLAY_CLIMB5}, // S_PLAY_CLIMB4
- {SPR_PLAY, 24, 5, {NULL}, 0, 0, S_PLAY_CLIMB2}, // S_PLAY_CLIMB5
- {SPR_PLAY, 26, 14, {NULL}, 0, 0, S_PLAY_RUN1}, // S_PLAY_GASP
- {SPR_PLAY, 27, 350, {NULL}, 0, 0, S_PLAY_FALL1}, // S_PLAY_PAIN
- {SPR_PLAY, 28, -1, {A_Fall}, 0, 0, S_NULL}, // S_PLAY_DIE
- {SPR_PLAY, 29, 12, {NULL}, 0, 0, S_PLAY_TEETER2}, // S_PLAY_TEETER1
- {SPR_PLAY, 30, 12, {NULL}, 0, 0, S_PLAY_TEETER1}, // S_PLAY_TEETER2
- {SPR_PLAY, 33, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_CARRY
- {SPR_PLAY, 20, -1, {NULL}, 0, 0, S_PLAY_SUPERSTAND}, // S_PLAY_SUPERSTAND
- {SPR_PLAY, 20, 7, {NULL}, 0, 0, S_PLAY_SUPERWALK2}, // S_PLAY_SUPERWALK1
- {SPR_PLAY, 21, 7, {NULL}, 0, 0, S_PLAY_SUPERWALK1}, // S_PLAY_SUPERWALK2
- {SPR_PLAY, 22, 7, {NULL}, 0, 0, S_PLAY_SUPERFLY2}, // S_PLAY_SUPERFLY1
- {SPR_PLAY, 23, 7, {NULL}, 0, 0, S_PLAY_SUPERFLY1}, // S_PLAY_SUPERFLY2
- {SPR_PLAY, 24, 12, {NULL}, 0, 0, S_PLAY_SUPERTEETER}, // S_PLAY_SUPERTEETER
- {SPR_PLAY, 25, -1, {NULL}, 0, 0, S_PLAY_SUPERSTAND}, // S_PLAY_SUPERHIT
- {SPR_PLAY, 36, 4, {NULL}, 0, 0, S_PLAY_SUPERTRANS2}, // S_PLAY_SUPERTRANS1
- {SPR_PLAY, 37, 4, {NULL}, 0, 0, S_PLAY_SUPERTRANS3}, // S_PLAY_SUPERTRANS2
- {SPR_PLAY, 32806, 4, {NULL}, 0, 0, S_PLAY_SUPERTRANS4}, // S_PLAY_SUPERTRANS3
- {SPR_PLAY, 39, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS5}, // S_PLAY_SUPERTRANS4
- {SPR_PLAY, 40, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS6}, // S_PLAY_SUPERTRANS5
- {SPR_PLAY, 41, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS7}, // S_PLAY_SUPERTRANS6
- {SPR_PLAY, 42, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS8}, // S_PLAY_SUPERTRANS7
- {SPR_PLAY, 43, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS9}, // S_PLAY_SUPERTRANS8
- {SPR_PLAY, 44, 16, {NULL}, 0, 0, S_PLAY_RUN1}, // S_PLAY_SUPERTRANS9
+ {SPR_PLAY, SPR2_STND, 105, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_STND
+ {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT
+ {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
+ {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
+ {SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN
+ {SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD
+ {SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN
+ {SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN
+ {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH
+ {SPR_PLAY, SPR2_GASP, 14, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_GASP
+ {SPR_PLAY, SPR2_JUMP, 2, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP
+ {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL
+ {SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE
+ {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE
+
+ // Tails abilities
+ {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
+ {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED
+
+ // Knuckles abilities
+ {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
+ {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING
+ {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
+
+ // Super Sonic
+ {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND
+ {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
+ {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN
+ {SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN
+ {SPR_PLAY, SPR2_SMSL, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN
+ {SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD
+ {SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN
+ {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
+ {SPR_PLAY, SPR2_SGSP, 14, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP
+ {SPR_PLAY, SPR2_SJMP, 2, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP
+ {SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL
+ {SPR_PLAY, SPR2_SEDG, 12, {NULL}, 0, 0, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE
+ {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE
+ {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT
+
+ // Transforming into Super
+ {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
+ {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
+ {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
+ {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
+ {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
+ {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
+ {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
+ {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
+ {SPR_PLAY, SPR2_TRNS, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
// 1-Up Box Sprites (uses player sprite)
- {SPR_PLAY, 35, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1
- {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2
- {SPR_PLAY, 35, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1
- {SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2
- {SPR_PLAY, 35, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
+ {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1
+ {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2
+ {SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1
+ {SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2
+ {SPR_PLAY, SPR2_LIFE, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
// Level end sign (uses player sprite)
- {SPR_PLAY, 34, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
+ {SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
// Blue Crawla
- {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND2}, // S_POSS_STND
- {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND2
+ {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND
{SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1
{SPR_POSS, 1, 3, {A_Chase}, 0, 0, S_POSS_RUN3}, // S_POSS_RUN2
{SPR_POSS, 2, 3, {A_Chase}, 0, 0, S_POSS_RUN4}, // S_POSS_RUN3
@@ -160,8 +198,7 @@ state_t states[NUMSTATES] =
{SPR_POSS, 5, 3, {A_Chase}, 0, 0, S_POSS_RUN1}, // S_POSS_RUN6
// Red Crawla
- {SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND2}, // S_SPOS_STND
- {SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND}, // S_SPOS_STND2
+ {SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND}, // S_SPOS_STND
{SPR_SPOS, 0, 1, {A_Chase}, 0, 0, S_SPOS_RUN2}, // S_SPOS_RUN1
{SPR_SPOS, 1, 1, {A_Chase}, 0, 0, S_SPOS_RUN3}, // S_SPOS_RUN2
{SPR_SPOS, 2, 1, {A_Chase}, 0, 0, S_SPOS_RUN4}, // S_SPOS_RUN3
@@ -3110,7 +3147,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
-1, // doomednum
S_PLAY_STND, // spawnstate
1, // spawnhealth
- S_PLAY_RUN1, // seestate
+ S_PLAY_WALK, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_thok, // attacksound
@@ -3118,9 +3155,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MT_THOK, // painchance
sfx_None, // painsound
S_NULL, // meleestate
- S_PLAY_ATK1, // missilestate
- S_PLAY_DIE, // deathstate
- S_NULL, // xdeathstate
+ S_PLAY_SPIN, // missilestate
+ S_PLAY_DEAD, // deathstate
+ S_PLAY_DRWN, // xdeathstate
sfx_None, // deathsound
1, // speed
16*FRACUNIT, // radius
diff --git a/src/info.h b/src/info.h
index 0c73281df..e313526b9 100644
--- a/src/info.h
+++ b/src/info.h
@@ -575,6 +575,52 @@ typedef enum sprite
NUMSPRITES
} spritenum_t;
+enum playersprite
+{
+ SPR2_STND = 0,
+ SPR2_WAIT,
+ SPR2_WALK,
+ SPR2_RUN ,
+ SPR2_PAIN,
+ SPR2_DEAD,
+ SPR2_DRWN,
+ SPR2_SPIN,
+ SPR2_DASH,
+ SPR2_GASP,
+ SPR2_JUMP,
+ SPR2_FALL,
+ SPR2_EDGE,
+ SPR2_RIDE,
+
+ SPR2_SIGN,
+ SPR2_LIFE,
+
+ SPR2_FLY ,
+ SPR2_TIRE,
+
+ SPR2_GLID,
+ SPR2_CLNG,
+ SPR2_CLMB,
+
+ SPR2_TRNS,
+ SPR2_SSTD,
+ SPR2_SWLK,
+ SPR2_SRUN,
+ SPR2_SPAN,
+ SPR2_SMSL,
+ SPR2_SDTH,
+ SPR2_SDRN,
+ SPR2_SSPN,
+ SPR2_SGSP,
+ SPR2_SJMP,
+ SPR2_SFAL,
+ SPR2_SEDG,
+ SPR2_SRID,
+ SPR2_SFLT,
+
+ NUMPLAYERSPRITES
+};
+
typedef enum state
{
S_NULL,
@@ -592,61 +638,57 @@ typedef enum state
// Thok
S_THOK,
+ // Player
S_PLAY_STND,
- S_PLAY_TAP1,
- S_PLAY_TAP2,
- S_PLAY_RUN1,
- S_PLAY_RUN2,
- S_PLAY_RUN3,
- S_PLAY_RUN4,
- S_PLAY_RUN5,
- S_PLAY_RUN6,
- S_PLAY_RUN7,
- S_PLAY_RUN8,
- S_PLAY_SPD1,
- S_PLAY_SPD2,
- S_PLAY_SPD3,
- S_PLAY_SPD4,
- S_PLAY_ATK1,
- S_PLAY_ATK2,
- S_PLAY_ATK3,
- S_PLAY_ATK4,
- S_PLAY_SPRING,
- S_PLAY_FALL1,
- S_PLAY_FALL2,
- S_PLAY_ABL1,
- S_PLAY_ABL2,
- S_PLAY_SPC1,
- S_PLAY_SPC2,
- S_PLAY_SPC3,
- S_PLAY_SPC4,
- S_PLAY_CLIMB1,
- S_PLAY_CLIMB2,
- S_PLAY_CLIMB3,
- S_PLAY_CLIMB4,
- S_PLAY_CLIMB5,
- S_PLAY_GASP,
+ S_PLAY_WAIT,
+ S_PLAY_WALK,
+ S_PLAY_RUN,
S_PLAY_PAIN,
- S_PLAY_DIE,
- S_PLAY_TEETER1,
- S_PLAY_TEETER2,
- S_PLAY_CARRY,
- S_PLAY_SUPERSTAND,
- S_PLAY_SUPERWALK1,
- S_PLAY_SUPERWALK2,
- S_PLAY_SUPERFLY1,
- S_PLAY_SUPERFLY2,
- S_PLAY_SUPERTEETER,
- S_PLAY_SUPERHIT,
- S_PLAY_SUPERTRANS1,
- S_PLAY_SUPERTRANS2,
- S_PLAY_SUPERTRANS3,
- S_PLAY_SUPERTRANS4,
- S_PLAY_SUPERTRANS5,
- S_PLAY_SUPERTRANS6,
- S_PLAY_SUPERTRANS7,
- S_PLAY_SUPERTRANS8,
- S_PLAY_SUPERTRANS9, // This has special significance in the code. If you add more frames, search for it and make the appropriate changes.
+ S_PLAY_DEAD,
+ S_PLAY_DRWN,
+ S_PLAY_SPIN,
+ S_PLAY_DASH,
+ S_PLAY_GASP,
+ S_PLAY_JUMP,
+ S_PLAY_FALL,
+ S_PLAY_EDGE,
+ S_PLAY_RIDE,
+
+ // CA_FLY
+ S_PLAY_FLY,
+ S_PLAY_FLY_TIRED,
+
+ // CA_GLIDEANDCLIMB
+ S_PLAY_GLIDE,
+ S_PLAY_CLING,
+ S_PLAY_CLIMB,
+
+ // SF_SUPERANIMS
+ S_PLAY_SUPER_STND,
+ S_PLAY_SUPER_WALK,
+ S_PLAY_SUPER_RUN,
+ 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_FALL,
+ S_PLAY_SUPER_EDGE,
+ S_PLAY_SUPER_RIDE,
+ S_PLAY_SUPER_FLOAT,
+
+ // SF_SUPER
+ S_PLAY_SUPER_TRANS,
+ S_PLAY_SUPER_TRANS2,
+ S_PLAY_SUPER_TRANS3,
+ S_PLAY_SUPER_TRANS4,
+ S_PLAY_SUPER_TRANS5,
+ S_PLAY_SUPER_TRANS6,
+ S_PLAY_SUPER_TRANS7,
+ S_PLAY_SUPER_TRANS8,
+ S_PLAY_SUPER_TRANS9,
// technically the player goes here but it's an infinite tic state
S_OBJPLACE_DUMMY,
@@ -663,7 +705,6 @@ typedef enum state
// Blue Crawla
S_POSS_STND,
- S_POSS_STND2,
S_POSS_RUN1,
S_POSS_RUN2,
S_POSS_RUN3,
@@ -673,7 +714,6 @@ typedef enum state
// Red Crawla
S_SPOS_STND,
- S_SPOS_STND2,
S_SPOS_RUN1,
S_SPOS_RUN2,
S_SPOS_RUN3,
@@ -1390,7 +1430,7 @@ typedef enum state
// S_PLAY_TAP1
S_METALSONIC_WAIT1,
S_METALSONIC_WAIT2,
- // S_PLAY_RUN1
+ // S_PLAY_WALK
S_METALSONIC_WALK1,
S_METALSONIC_WALK2,
S_METALSONIC_WALK3,
@@ -3488,6 +3528,7 @@ typedef struct
extern state_t states[NUMSTATES];
extern char sprnames[NUMSPRITES + 1][5];
+char spr2names[NUMPLAYERSPRITES][5];
extern state_t *astate;
typedef enum mobj_type
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index ad5d740f8..4be103106 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -85,13 +85,6 @@ static int lib_print(lua_State *L)
return 0;
}
-static int lib_evalMath(lua_State *L)
-{
- const char *word = luaL_checkstring(L, 1);
- lua_pushinteger(L, LUA_EvalMath(word));
- return 1;
-}
-
// M_RANDOM
//////////////
@@ -138,25 +131,25 @@ static int lib_pRandomRange(lua_State *L)
static int lib_pAproxDistance(lua_State *L)
{
- fixed_t dx = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t dy = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t dx = luaL_checkfixed(L, 1);
+ fixed_t dy = luaL_checkfixed(L, 2);
//HUDSAFE
- lua_pushinteger(L, P_AproxDistance(dx, dy));
+ lua_pushfixed(L, P_AproxDistance(dx, dy));
return 1;
}
static int lib_pClosestPointOnLine(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE));
vertex_t result;
//HUDSAFE
if (!line)
return LUA_ErrInvalid(L, "line_t");
P_ClosestPointOnLine(x, y, line, &result);
- lua_pushinteger(L, result.x);
- lua_pushinteger(L, result.y);
+ lua_pushfixed(L, result.x);
+ lua_pushfixed(L, result.y);
return 2;
}
@@ -241,9 +234,9 @@ static int lib_pLookForPlayers(lua_State *L)
static int lib_pSpawnMobj(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
+ fixed_t z = luaL_checkfixed(L, 3);
mobjtype_t type = luaL_checkinteger(L, 4);
NOHUD
if (type > MT_LASTFREESLOT)
@@ -283,9 +276,9 @@ static int lib_pSpawnXYZMissile(lua_State *L)
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *dest = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
mobjtype_t type = luaL_checkinteger(L, 3);
- fixed_t x = (fixed_t)luaL_checkinteger(L, 4);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 5);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 6);
+ fixed_t x = luaL_checkfixed(L, 4);
+ fixed_t y = luaL_checkfixed(L, 5);
+ fixed_t z = luaL_checkfixed(L, 6);
NOHUD
if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t");
@@ -298,13 +291,13 @@ static int lib_pSpawnXYZMissile(lua_State *L)
static int lib_pSpawnPointMissile(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t xa = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t ya = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t za = (fixed_t)luaL_checkinteger(L, 4);
+ fixed_t xa = luaL_checkfixed(L, 2);
+ fixed_t ya = luaL_checkfixed(L, 3);
+ fixed_t za = luaL_checkfixed(L, 4);
mobjtype_t type = luaL_checkinteger(L, 5);
- fixed_t x = (fixed_t)luaL_checkinteger(L, 6);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 7);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 8);
+ fixed_t x = luaL_checkfixed(L, 6);
+ fixed_t y = luaL_checkfixed(L, 7);
+ fixed_t z = luaL_checkfixed(L, 8);
NOHUD
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
@@ -318,9 +311,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobjtype_t type = luaL_checkinteger(L, 2);
- fixed_t x = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 4);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 5);
+ fixed_t x = luaL_checkfixed(L, 3);
+ fixed_t y = luaL_checkfixed(L, 4);
+ fixed_t z = luaL_checkfixed(L, 5);
INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5);
NOHUD
if (!source)
@@ -348,7 +341,7 @@ static int lib_pSPMAngle(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobjtype_t type = luaL_checkinteger(L, 2);
- angle_t angle = (angle_t)luaL_checkinteger(L, 3);
+ angle_t angle = luaL_checkangle(L, 3);
UINT8 allowaim = (UINT8)luaL_optinteger(L, 4, 0);
UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0);
NOHUD
@@ -418,13 +411,13 @@ static int lib_pGetClosestAxis(lua_State *L)
static int lib_pSpawnParaloop(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t radius = (fixed_t)luaL_checkinteger(L, 4);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
+ fixed_t z = luaL_checkfixed(L, 3);
+ fixed_t radius = luaL_checkfixed(L, 4);
INT32 number = (INT32)luaL_checkinteger(L, 5);
mobjtype_t type = luaL_checkinteger(L, 6);
- angle_t rotangle = (angle_t)luaL_checkinteger(L, 7);
+ angle_t rotangle = luaL_checkangle(L, 7);
statenum_t nstate = luaL_optinteger(L, 8, S_NULL);
boolean spawncenter = lua_optboolean(L, 9);
NOHUD
@@ -458,7 +451,7 @@ static int lib_pSupermanLook4Players(lua_State *L)
static int lib_pSetScale(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t newscale = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t newscale = luaL_checkfixed(L, 2);
NOHUD
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
@@ -526,7 +519,7 @@ static int lib_pGetPlayerHeight(lua_State *L)
//HUDSAFE
if (!player)
return LUA_ErrInvalid(L, "player_t");
- lua_pushinteger(L, P_GetPlayerHeight(player));
+ lua_pushfixed(L, P_GetPlayerHeight(player));
return 1;
}
@@ -536,7 +529,7 @@ static int lib_pGetPlayerSpinHeight(lua_State *L)
//HUDSAFE
if (!player)
return LUA_ErrInvalid(L, "player_t");
- lua_pushinteger(L, P_GetPlayerSpinHeight(player));
+ lua_pushfixed(L, P_GetPlayerSpinHeight(player));
return 1;
}
@@ -639,7 +632,7 @@ static int lib_pInQuicksand(lua_State *L)
static int lib_pSetObjectMomZ(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t value = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t value = luaL_checkfixed(L, 2);
boolean relative = lua_optboolean(L, 3);
NOHUD
if (!mo)
@@ -753,8 +746,8 @@ static int lib_pDoPlayerExit(lua_State *L)
static int lib_pInstaThrust(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- angle_t angle = (angle_t)luaL_checkinteger(L, 2);
- fixed_t move = (fixed_t)luaL_checkinteger(L, 3);
+ angle_t angle = luaL_checkangle(L, 2);
+ fixed_t move = luaL_checkfixed(L, 3);
NOHUD
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
@@ -768,10 +761,10 @@ static int lib_pReturnThrustX(lua_State *L)
fixed_t move;
if (lua_isnil(L, 1) || lua_isuserdata(L, 1))
lua_remove(L, 1); // ignore mobj as arg1
- angle = (angle_t)luaL_checkinteger(L, 1);
- move = (fixed_t)luaL_checkinteger(L, 2);
+ angle = luaL_checkangle(L, 1);
+ move = luaL_checkfixed(L, 2);
//HUDSAFE
- lua_pushinteger(L, P_ReturnThrustX(NULL, angle, move));
+ lua_pushfixed(L, P_ReturnThrustX(NULL, angle, move));
return 1;
}
@@ -781,10 +774,10 @@ static int lib_pReturnThrustY(lua_State *L)
fixed_t move;
if (lua_isnil(L, 1) || lua_isuserdata(L, 1))
lua_remove(L, 1); // ignore mobj as arg1
- angle = (angle_t)luaL_checkinteger(L, 1);
- move = (fixed_t)luaL_checkinteger(L, 2);
+ angle = luaL_checkangle(L, 1);
+ move = luaL_checkfixed(L, 2);
//HUDSAFE
- lua_pushinteger(L, P_ReturnThrustY(NULL, angle, move));
+ lua_pushfixed(L, P_ReturnThrustY(NULL, angle, move));
return 1;
}
@@ -802,7 +795,7 @@ static int lib_pNukeEnemies(lua_State *L)
{
mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
- fixed_t radius = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t radius = luaL_checkfixed(L, 3);
NOHUD
if (!inflictor || !source)
return LUA_ErrInvalid(L, "mobj_t");
@@ -868,8 +861,8 @@ static int lib_pSpawnSpinMobj(lua_State *L)
static int lib_pTelekinesis(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
- fixed_t thrust = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t range = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t thrust = luaL_checkfixed(L, 2);
+ fixed_t range = luaL_checkfixed(L, 3);
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
@@ -884,8 +877,8 @@ static int lib_pCheckPosition(lua_State *L)
{
mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t x = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t x = luaL_checkfixed(L, 2);
+ fixed_t y = luaL_checkfixed(L, 3);
NOHUD
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
@@ -899,8 +892,8 @@ static int lib_pTryMove(lua_State *L)
{
mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t x = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t x = luaL_checkfixed(L, 2);
+ fixed_t y = luaL_checkfixed(L, 3);
boolean allowdropoff = lua_optboolean(L, 4);
NOHUD
if (!thing)
@@ -915,7 +908,7 @@ static int lib_pMove(lua_State *L)
{
mobj_t *ptmthing = tmthing;
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t speed = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t speed = luaL_checkfixed(L, 2);
NOHUD
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
@@ -929,9 +922,9 @@ static int lib_pTeleportMove(lua_State *L)
{
mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t x = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 4);
+ fixed_t x = luaL_checkfixed(L, 2);
+ fixed_t y = luaL_checkfixed(L, 3);
+ fixed_t z = luaL_checkfixed(L, 4);
NOHUD
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
@@ -975,10 +968,10 @@ static int lib_pCheckSight(lua_State *L)
static int lib_pCheckHoopPosition(lua_State *L)
{
mobj_t *hoopthing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- fixed_t x = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 4);
- fixed_t radius = (fixed_t)luaL_checkinteger(L, 5);
+ fixed_t x = luaL_checkfixed(L, 2);
+ fixed_t y = luaL_checkfixed(L, 3);
+ fixed_t z = luaL_checkfixed(L, 4);
+ fixed_t radius = luaL_checkfixed(L, 5);
NOHUD
if (!hoopthing)
return LUA_ErrInvalid(L, "mobj_t");
@@ -990,7 +983,7 @@ static int lib_pRadiusAttack(lua_State *L)
{
mobj_t *spot = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
- fixed_t damagedist = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t damagedist = luaL_checkfixed(L, 3);
NOHUD
if (!spot || !source)
return LUA_ErrInvalid(L, "mobj_t");
@@ -1000,12 +993,12 @@ static int lib_pRadiusAttack(lua_State *L)
static int lib_pFloorzAtPos(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t z = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t height = (fixed_t)luaL_checkinteger(L, 4);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
+ fixed_t z = luaL_checkfixed(L, 3);
+ fixed_t height = luaL_checkfixed(L, 4);
//HUDSAFE
- lua_pushinteger(L, P_FloorzAtPos(x, y, z, height));
+ lua_pushfixed(L, P_FloorzAtPos(x, y, z, height));
return 1;
}
@@ -1016,8 +1009,8 @@ static int lib_pDoSpring(lua_State *L)
NOHUD
if (!spring || !object)
return LUA_ErrInvalid(L, "mobj_t");
- P_DoSpring(spring, object);
- return 0;
+ lua_pushboolean(L, P_DoSpring(spring, object));
+ return 1;
}
// P_INTER
@@ -1037,6 +1030,7 @@ static int lib_pDamageMobj(lua_State *L)
{
mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL;
INT32 damage;
+ UINT8 damagetype;
NOHUD
if (!target)
return LUA_ErrInvalid(L, "mobj_t");
@@ -1045,13 +1039,15 @@ static int lib_pDamageMobj(lua_State *L)
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
damage = (INT32)luaL_optinteger(L, 4, 1);
- lua_pushboolean(L, P_DamageMobj(target, inflictor, source, damage));
+ damagetype = (UINT8)luaL_optinteger(L, 5, 0);
+ lua_pushboolean(L, P_DamageMobj(target, inflictor, source, damage, damagetype));
return 1;
}
static int lib_pKillMobj(lua_State *L)
{
mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL;
+ UINT8 damagetype;
NOHUD
if (!target)
return LUA_ErrInvalid(L, "mobj_t");
@@ -1059,7 +1055,8 @@ static int lib_pKillMobj(lua_State *L)
inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
- P_KillMobj(target, inflictor, source);
+ damagetype = (UINT8)luaL_optinteger(L, 4, 0);
+ P_KillMobj(target, inflictor, source, damagetype);
return 0;
}
@@ -1209,8 +1206,8 @@ static int lib_pDoNightsScore(lua_State *L)
static int lib_pThrust(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
- angle_t angle = (angle_t)luaL_checkinteger(L, 2);
- fixed_t move = (fixed_t)luaL_checkinteger(L, 3);
+ angle_t angle = luaL_checkangle(L, 2);
+ fixed_t move = luaL_checkfixed(L, 3);
NOHUD
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
@@ -1485,48 +1482,48 @@ static int lib_evCrumbleChain(lua_State *L)
static int lib_rPointToAngle(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
//HUDSAFE
- lua_pushinteger(L, R_PointToAngle(x, y));
+ lua_pushangle(L, R_PointToAngle(x, y));
return 1;
}
static int lib_rPointToAngle2(lua_State *L)
{
- fixed_t px2 = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t py2 = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t px1 = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t py1 = (fixed_t)luaL_checkinteger(L, 4);
+ fixed_t px2 = luaL_checkfixed(L, 1);
+ fixed_t py2 = luaL_checkfixed(L, 2);
+ fixed_t px1 = luaL_checkfixed(L, 3);
+ fixed_t py1 = luaL_checkfixed(L, 4);
//HUDSAFE
- lua_pushinteger(L, R_PointToAngle2(px2, py2, px1, py1));
+ lua_pushangle(L, R_PointToAngle2(px2, py2, px1, py1));
return 1;
}
static int lib_rPointToDist(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
//HUDSAFE
- lua_pushinteger(L, R_PointToDist(x, y));
+ lua_pushfixed(L, R_PointToDist(x, y));
return 1;
}
static int lib_rPointToDist2(lua_State *L)
{
- fixed_t px2 = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t py2 = (fixed_t)luaL_checkinteger(L, 2);
- fixed_t px1 = (fixed_t)luaL_checkinteger(L, 3);
- fixed_t py1 = (fixed_t)luaL_checkinteger(L, 4);
+ fixed_t px2 = luaL_checkfixed(L, 1);
+ fixed_t py2 = luaL_checkfixed(L, 2);
+ fixed_t px1 = luaL_checkfixed(L, 3);
+ fixed_t py1 = luaL_checkfixed(L, 4);
//HUDSAFE
- lua_pushinteger(L, R_PointToDist2(px2, py2, px1, py1));
+ lua_pushfixed(L, R_PointToDist2(px2, py2, px1, py1));
return 1;
}
static int lib_rPointInSubsector(lua_State *L)
{
- fixed_t x = (fixed_t)luaL_checkinteger(L, 1);
- fixed_t y = (fixed_t)luaL_checkinteger(L, 2);
+ fixed_t x = luaL_checkfixed(L, 1);
+ fixed_t y = luaL_checkfixed(L, 2);
//HUDSAFE
LUA_PushUserdata(L, R_PointInSubsector(x, y), META_SUBSECTOR);
return 1;
@@ -1660,7 +1657,7 @@ static int lib_sChangeMusic(lua_State *L)
static int lib_sSpeedMusic(lua_State *L)
{
- fixed_t fixedspeed = (fixed_t)luaL_checkinteger(L, 1);
+ fixed_t fixedspeed = luaL_checkfixed(L, 1);
float speed = FIXED_TO_FLOAT(fixedspeed);
player_t *player = NULL;
NOHUD
@@ -1861,7 +1858,6 @@ static int lib_gTicsToMilliseconds(lua_State *L)
static luaL_Reg lib[] = {
{"print", lib_print},
- {"EvalMath", lib_evalMath},
// m_random
{"P_Random",lib_pRandom},
diff --git a/src/lua_hook.h b/src/lua_hook.h
index fae3bb7e6..da2dcdc38 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -41,7 +41,7 @@ enum hook {
hook_BotAI,
hook_LinedefExecute,
hook_PlayerMsg,
- hook_DeathMsg,
+ hook_HurtMsg,
hook_MAX // last hook
};
@@ -54,8 +54,9 @@ void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers)
boolean LUAh_MobjHook(mobj_t *mo, enum hook which);
boolean LUAh_PlayerHook(player_t *plr, enum hook which);
#define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type
-UINT8 LUAh_MobjCollide(mobj_t *thing1, mobj_t *thing2); // Hook for PIT_CheckThing by (thing) mobj type
-UINT8 LUAh_MobjMoveCollide(mobj_t *thing1, mobj_t *thing2); // Hook for PIT_CheckThing by (tmthing) mobj type
+UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which);
+#define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type
+#define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type
boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type
#define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type
#define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type
@@ -73,6 +74,6 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
-boolean LUAh_DeathMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
+boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
#endif
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index 532726ac2..0415d23e6 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -56,23 +56,40 @@ const char *const hookNames[hook_MAX+1] = {
NULL
};
+// Hook metadata
+struct hook_s
+{
+ struct hook_s *next;
+ enum hook type;
+ UINT16 id;
+ union {
+ mobjtype_t mt;
+ char *skinname;
+ char *funcname;
+ } s;
+ boolean error;
+};
+typedef struct hook_s* hook_p;
+
+#define FMT_HOOKID "hook_%d"
+
+hook_p roothook;
+
// Takes hook, function, and additional arguments (mobj type to act on, etc.)
static int lib_addHook(lua_State *L)
{
- UINT16 hook;
- boolean notable = false;
- boolean subtable = false;
- UINT32 subindex = 0;
- char *subfield = NULL;
- const char *lsubfield = NULL;
+ static struct hook_s hook = {NULL, 0, 0, {0}, false};
+ hook_p hookp, *lastp;
- hook = (UINT16)luaL_checkoption(L, 1, NULL, hookNames);
- luaL_checktype(L, 2, LUA_TFUNCTION);
+ hook.type = luaL_checkoption(L, 1, NULL, hookNames);
+ lua_remove(L, 1);
+
+ luaL_checktype(L, 1, LUA_TFUNCTION);
if (hud_running)
return luaL_error(L, "HUD rendering code should not call this function!");
- switch(hook)
+ switch(hook.type)
{
// Take a mobjtype enum which this hook is specifically for.
case hook_MobjSpawn:
@@ -87,918 +104,668 @@ static int lib_addHook(lua_State *L)
case hook_MobjDeath:
case hook_BossDeath:
case hook_MobjRemoved:
- subtable = true;
- if (lua_isnumber(L, 3))
- subindex = (UINT32)luaL_checkinteger(L, 3);
- else
- lsubfield = "a";
- lua_settop(L, 2);
+ case hook_HurtMsg:
+ hook.s.mt = MT_NULL;
+ if (lua_isnumber(L, 2))
+ hook.s.mt = lua_tonumber(L, 2);
break;
- case hook_BotAI: // Only one AI function per skin, please!
- notable = true;
- subtable = true;
- subfield = ZZ_Alloc(strlen(luaL_checkstring(L, 3))+1);
+ case hook_BotAI:
+ hook.s.skinname = NULL;
+ if (lua_isstring(L, 2))
{ // lowercase copy
- char *p = subfield;
- const char *s = luaL_checkstring(L, 3);
+ const char *s = lua_tostring(L, 2);
+ char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1);
do {
*p = tolower(*s);
++p;
} while(*(++s));
*p = 0;
}
- lua_settop(L, 3);
break;
- case hook_LinedefExecute: // Get one linedef executor function by name
- notable = true;
- subtable = true;
- subfield = ZZ_Alloc(strlen(luaL_checkstring(L, 3))+1);
+ case hook_LinedefExecute: // Linedef executor functions
{ // uppercase copy
- char *p = subfield;
- const char *s = luaL_checkstring(L, 3);
+ const char *s = luaL_checkstring(L, 2);
+ char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1);
do {
*p = toupper(*s);
++p;
} while(*(++s));
*p = 0;
}
- lua_settop(L, 3);
break;
default:
- lua_settop(L, 2);
break;
}
+ lua_settop(L, 1); // lua stack contains only the function now.
- lua_getfield(L, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(L, -1));
+ hooksAvailable[hook.type/8] |= 1<<(hook.type%8);
- // This hook type only allows one entry, not an array of hooks.
- // New hooks will overwrite the previous ones, and the stack is one table shorter.
- if (notable)
+ // iterate the hook metadata structs
+ // set hook.id to the highest id + 1
+ // set lastp to the last hook struct's "next" pointer.
+ lastp = &roothook;
+ hook.id = 0;
+ for (hookp = roothook; hookp; hookp = hookp->next)
{
- if (subtable)
- {
- lua_rawgeti(L, -1, hook);
- lua_remove(L, -2); // pop "hook"
- I_Assert(lua_istable(L, -1));
- lua_pushvalue(L, 2);
- if (subfield)
- lua_setfield(L, -2, subfield);
- else if (lsubfield)
- lua_setfield(L, -2, lsubfield);
- else
- lua_rawseti(L, -2, subindex);
- } else {
- lua_pushvalue(L, 2);
- lua_rawseti(L, -2, hook);
- }
- hooksAvailable[hook/8] |= 1<<(hook%8);
- return 0;
+ if (hookp->id >= hook.id)
+ hook.id = hookp->id+1;
+ lastp = &hookp->next;
}
- // Fetch the hook's table from the registry.
- // It should always exist, since LUA_HookLib creates a table for every hook.
- lua_rawgeti(L, -1, hook);
- lua_remove(L, -2); // pop "hook"
- I_Assert(lua_istable(L, -1));
- if (subtable)
- {
- // Fetch a subtable based on index
- if (subfield)
- lua_getfield(L, -1, subfield);
- else if (lsubfield)
- lua_getfield(L, -1, lsubfield);
- else
- lua_rawgeti(L, -1, subindex);
+ // allocate a permanent memory struct to stuff hook.
+ hookp = ZZ_Alloc(sizeof(struct hook_s));
+ memcpy(hookp, &hook, sizeof(struct hook_s));
+ // tack it onto the end of the linked list.
+ *lastp = hookp;
- // Subtable doesn't exist, make one now.
- if (lua_isnil(L, -1))
- {
- lua_pop(L, 1);
- lua_newtable(L);
-
- // Store a link to the subtable for later.
- lua_pushvalue(L, -1);
- if (subfield)
- lua_setfield(L, -3, subfield);
- else if (lsubfield)
- lua_setfield(L, -3, lsubfield);
- else
- lua_rawseti(L, -3, subindex);
- } }
-
- // Add function to the table.
- lua_pushvalue(L, 2);
- lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1));
-
- if (subfield)
- Z_Free(subfield);
-
- hooksAvailable[hook/8] |= 1<<(hook%8);
+ // set the hook function in the registry.
+ lua_pushfstring(L, FMT_HOOKID, hook.id);
+ lua_pushvalue(L, 1);
+ lua_settable(L, LUA_REGISTRYINDEX);
return 0;
}
int LUA_HookLib(lua_State *L)
{
- // Create all registry tables
- enum hook i;
memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1]));
-
- lua_newtable(L);
- for (i = 0; i < hook_MAX; i++)
- {
- lua_newtable(L);
- switch(i)
- {
- default:
- break;
- case hook_MobjSpawn:
- case hook_MobjCollide:
- case hook_MobjMoveCollide:
- case hook_TouchSpecial:
- case hook_MobjFuse:
- case hook_MobjThinker:
- case hook_BossThinker:
- case hook_ShouldDamage:
- case hook_MobjDamage:
- case hook_MobjDeath:
- case hook_BossDeath:
- case hook_MobjRemoved:
- lua_pushstring(L, "a");
- lua_newtable(L);
- lua_rawset(L, -3);
- break;
- }
- lua_rawseti(L, -2, i);
- }
- lua_setfield(L, LUA_REGISTRYINDEX, "hook");
+ roothook = NULL;
lua_register(L, "addHook", lib_addHook);
return 0;
}
boolean LUAh_MobjHook(mobj_t *mo, enum hook which)
{
+ hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
return false;
- // clear the stack (just in case)
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, which);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // generic subtable
- lua_pushstring(gL, "a");
- lua_rawget(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- LUA_PushUserdata(gL, mo, META_MOBJ);
- lua_pushnil(gL);
- while (lua_next(gL, -3)) {
- CONS_Debug(DBG_LUA, "MobjHook: Calling hook_%s for generic mobj types\n", hookNames[which]);
- lua_pushvalue(gL, -3); // mo
- // stack is: hook_Mobj table, subtable "a", mobj, i, function, mobj
- if (lua_pcall(gL, 1, 1, 0)) {
- // A run-time error occurred.
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
- lua_pop(gL, 1);
- // Remove this function from the hook table to prevent further errors.
- lua_pushvalue(gL, -1); // key
- lua_pushnil(gL); // value
- lua_rawset(gL, -5); // table
- CONS_Printf("Hook removed.\n");
- }
- else
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == which
+ && (hookp->s.mt == MT_NULL || hookp->s.mt == mo->type))
{
+ if (lua_gettop(gL) == 0)
+ LUA_PushUserdata(gL, mo, META_MOBJ);
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -2);
+ if (lua_pcall(gL, 1, 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);
}
- }
- // stack is: hook_Mobj table, subtable "a", mobj
- lua_remove(gL, -2); // pop subtable, leave mobj
- // mobjtype subtable
- // stack is: hook_Mobj table, mobj
- lua_rawgeti(gL, -2, mo->type);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 3); // pop hook_Mobj table, mobj, and nil
- // the stack should now be empty.
- return false;
- }
- lua_remove(gL, -3); // remove hook table
- // stack is: mobj, mobjtype subtable
- lua_insert(gL, lua_gettop(gL)-1); // swap subtable with mobj
- // stack is: mobjtype subtable, mobj
-
- lua_pushnil(gL);
- while (lua_next(gL, -3)) {
- CONS_Debug(DBG_LUA, "MobjHook: Calling hook_%s for mobj type %d\n", hookNames[which], mo->type);
- lua_pushvalue(gL, -3); // mo
- // stack is: mobjtype subtable, mobj, i, function, mobj
- if (lua_pcall(gL, 1, 1, 0)) {
- // A run-time error occurred.
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
- lua_pop(gL, 1);
- // Remove this function from the hook table to prevent further errors.
- lua_pushvalue(gL, -1); // key
- lua_pushnil(gL); // value
- lua_rawset(gL, -5); // table
- CONS_Printf("Hook removed.\n");
- }
- else
- {
- if (lua_toboolean(gL, -1))
- hooked = true;
- lua_pop(gL, 1);
- }
- }
-
- lua_pop(gL, 2); // pop mobj and subtable
- // the stack should now be empty.
-
- lua_gc(gL, LUA_GCSTEP, 3);
+ lua_settop(gL, 0);
return hooked;
}
boolean LUAh_PlayerHook(player_t *plr, enum hook which)
{
+ hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
return false;
- // clear the stack (just in case)
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, which);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- LUA_PushUserdata(gL, plr, META_PLAYER);
-
- lua_pushnil(gL);
- while (lua_next(gL, -3) != 0) {
- lua_pushvalue(gL, -3); // player
- if (lua_pcall(gL, 1, 1, 0)) { // pops hook function, player, pushes 1 return result
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == which)
+ {
+ if (lua_gettop(gL) == 0)
+ LUA_PushUserdata(gL, plr, META_PLAYER);
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -2);
+ if (lua_pcall(gL, 1, 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);
- continue;
}
- if (lua_toboolean(gL, -1)) // if return true,
- hooked = true; // override vanilla behavior
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCSTEP, 1);
+ lua_settop(gL, 0);
return hooked;
}
// Hook for map change (before load)
void LUAh_MapChange(void)
{
+ hook_p hookp;
if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8))))
return;
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_MapChange);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
+ lua_settop(gL, 0);
lua_pushinteger(gL, gamemap);
- lua_pushnil(gL);
- while (lua_next(gL, -3) != 0) {
- lua_pushvalue(gL, -3); // gamemap
- LUA_Call(gL, 1);
- }
- lua_pop(gL, 1);
- lua_gc(gL, LUA_GCSTEP, 1);
+
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_MapChange)
+ {
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -2);
+ LUA_Call(gL, 1);
+ }
+
+ lua_settop(gL, 0);
}
// Hook for map load
void LUAh_MapLoad(void)
{
+ hook_p hookp;
if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8))))
return;
- lua_pop(gL, -1);
-
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_MapLoad);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
+ lua_settop(gL, 0);
lua_pushinteger(gL, gamemap);
- lua_pushnil(gL);
- while (lua_next(gL, -3) != 0) {
- lua_pushvalue(gL, -3); // gamemap
- LUA_Call(gL, 1);
- }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCCOLLECT, 0);
+
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_MapLoad)
+ {
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -2);
+ LUA_Call(gL, 1);
+ }
+
+ lua_settop(gL, 0);
}
// Hook for Got_AddPlayer
void LUAh_PlayerJoin(int playernum)
{
+ hook_p hookp;
if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8))))
return;
- lua_pop(gL, -1);
-
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_PlayerJoin);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
+ lua_settop(gL, 0);
lua_pushinteger(gL, playernum);
- lua_pushnil(gL);
- while (lua_next(gL, -3) != 0) {
- lua_pushvalue(gL, -3); // playernum
- LUA_Call(gL, 1);
- }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCCOLLECT, 0);
+
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_PlayerJoin)
+ {
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -2);
+ LUA_Call(gL, 1);
+ }
+
+ lua_settop(gL, 0);
}
// Hook for frame (after mobj and player thinkers)
void LUAh_ThinkFrame(void)
{
+ hook_p hookp;
if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8))))
return;
- lua_pop(gL, -1);
-
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_ThinkFrame);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- lua_pushnil(gL);
- while (lua_next(gL, -2) != 0)
- {
- //LUA_Call(gL, 0);
- if (lua_pcall(gL, 0, 0, 0))
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_ThinkFrame)
{
- // A run-time error occurred.
- CONS_Alert(CONS_WARNING,"%s\n", lua_tostring(gL, -1));
- lua_pop(gL, 1);
- // Remove this function from the hook table to prevent further errors.
- lua_pushvalue(gL, -1); // key
- lua_pushnil(gL); // value
- lua_rawset(gL, -4); // table
- CONS_Printf("Hook removed.\n");
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ if (lua_pcall(gL, 0, 0, 0)) {
+ if (!hookp->error || cv_debug & DBG_LUA)
+ CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+ lua_pop(gL, 1);
+ hookp->error = true;
+ }
}
- }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCCOLLECT, 0);
}
-// Hook for PIT_CheckThing by (thing) mobj type (thing1 = thing, thing2 = tmthing)
-UINT8 LUAh_MobjCollide(mobj_t *thing1, mobj_t *thing2)
+// Hook for mobj collisions
+UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which)
{
+ hook_p hookp;
UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no.
- if (!gL || !(hooksAvailable[hook_MobjCollide/8] & (1<<(hook_MobjCollide%8))))
+ if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
return 0;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_MobjCollide);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // mobjtype subtable
- lua_rawgeti(gL, -1, thing1->type);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return 0;
- }
- lua_remove(gL, -2); // remove hook table
-
- LUA_PushUserdata(gL, thing1, META_MOBJ);
- LUA_PushUserdata(gL, thing2, META_MOBJ);
- lua_pushnil(gL);
- while (lua_next(gL, -4)) {
- lua_pushvalue(gL, -4); // thing1
- lua_pushvalue(gL, -4); // thing2
- if (lua_pcall(gL, 2, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == which
+ && (hookp->s.mt == MT_NULL || hookp->s.mt == thing1->type))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, thing1, META_MOBJ);
+ LUA_PushUserdata(gL, thing2, META_MOBJ);
+ }
+ 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_isnil(gL, -1))
+ { // if nil, leave shouldCollide = 0.
+ if (lua_toboolean(gL, -1))
+ shouldCollide = 1; // Force yes
+ else
+ shouldCollide = 2; // Force no
+ }
lua_pop(gL, 1);
- continue;
}
- if (!lua_isnil(gL, -1))
- { // if nil, leave shouldCollide = 0.
- if (lua_toboolean(gL, -1))
- shouldCollide = 1; // Force yes
- else
- shouldCollide = 2; // Force no
- }
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 3); // pop arguments and mobjtype table
- lua_gc(gL, LUA_GCSTEP, 1);
- return shouldCollide;
-}
-
-// Hook for PIT_CheckThing by (tmthing) mobj type (thing1 = tmthing, thing2 = thing)
-UINT8 LUAh_MobjMoveCollide(mobj_t *thing1, mobj_t *thing2)
-{
- UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no.
- if (!gL || !(hooksAvailable[hook_MobjMoveCollide/8] & (1<<(hook_MobjMoveCollide%8))))
- return 0;
-
- // clear the stack
- lua_pop(gL, -1);
-
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_MobjMoveCollide);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // mobjtype subtable
- lua_rawgeti(gL, -1, thing1->type);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return 0;
- }
- lua_remove(gL, -2); // remove hook table
-
- LUA_PushUserdata(gL, thing1, META_MOBJ);
- LUA_PushUserdata(gL, thing2, META_MOBJ);
- lua_pushnil(gL);
- while (lua_next(gL, -4)) {
- lua_pushvalue(gL, -4); // thing1
- lua_pushvalue(gL, -4); // thing2
- if (lua_pcall(gL, 2, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
- lua_pop(gL, 1);
- continue;
- }
- if (!lua_isnil(gL, -1))
- { // if nil, leave shouldCollide = 0.
- if (lua_toboolean(gL, -1))
- shouldCollide = 1; // Force yes
- else
- shouldCollide = 2; // Force no
- }
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 3); // pop arguments and mobjtype table
-
- lua_gc(gL, LUA_GCSTEP, 1);
+ lua_settop(gL, 0);
return shouldCollide;
}
// Hook for P_TouchSpecialThing by mobj type
boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher)
{
+ hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8))))
- return false;
+ return 0;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // get hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_TouchSpecial);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // get mobjtype subtable
- lua_pushinteger(gL, special->type);
- lua_rawget(gL, 1);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return false;
- }
- lua_remove(gL, 1); // pop hook table off the stack
-
- LUA_PushUserdata(gL, special, META_MOBJ);
- LUA_PushUserdata(gL, toucher, META_MOBJ);
-
- lua_pushnil(gL);
- while (lua_next(gL, 1) != 0) {
- lua_pushvalue(gL, 2); // special
- lua_pushvalue(gL, 3); // toucher
- if (lua_pcall(gL, 2, 1, 0)) { // pops hook function, special, toucher, pushes 1 return result
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_TouchSpecial
+ && (hookp->s.mt == MT_NULL || hookp->s.mt == special->type))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, special, META_MOBJ);
+ LUA_PushUserdata(gL, toucher, META_MOBJ);
+ }
+ 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);
- continue;
}
- if (lua_toboolean(gL, -1)) // if return true,
- hooked = true; // override vanilla behavior
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCSTEP, 1);
+ lua_settop(gL, 0);
return hooked;
}
// Hook for P_DamageMobj by mobj type (Should mobj take damage?)
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
+ hook_p hookp;
UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8))))
return 0;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_ShouldDamage);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // mobjtype subtable
- lua_rawgeti(gL, -1, target->type);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return 0;
- }
- lua_remove(gL, -2); // remove hook table
-
- LUA_PushUserdata(gL, target, META_MOBJ);
- LUA_PushUserdata(gL, inflictor, META_MOBJ);
- LUA_PushUserdata(gL, source, META_MOBJ);
- lua_pushinteger(gL, damage);
- lua_pushnil(gL);
- while (lua_next(gL, -6)) {
- lua_pushvalue(gL, -6); // target
- lua_pushvalue(gL, -6); // inflictor
- lua_pushvalue(gL, -6); // source
- lua_pushvalue(gL, -6); // damage
- if (lua_pcall(gL, 4, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_ShouldDamage
+ && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, target, META_MOBJ);
+ LUA_PushUserdata(gL, inflictor, META_MOBJ);
+ LUA_PushUserdata(gL, source, META_MOBJ);
+ lua_pushinteger(gL, damage);
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ if (lua_pcall(gL, 4, 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_isnil(gL, -1))
+ {
+ if (lua_toboolean(gL, -1))
+ shouldDamage = 1; // Force yes
+ else
+ shouldDamage = 2; // Force no
+ }
lua_pop(gL, 1);
- continue;
}
- if (!lua_isnil(gL, -1))
- { // if nil, leave shouldDamage = 0.
- if (lua_toboolean(gL, -1))
- shouldDamage = 1; // Force yes
- else
- shouldDamage = 2; // Force no
- }
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 5); // pop arguments and mobjtype table
- lua_gc(gL, LUA_GCSTEP, 1);
+ lua_settop(gL, 0);
return shouldDamage;
}
// Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
- boolean handled = false;
+ hook_p hookp;
+ boolean hooked = false;
if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8))))
- return false;
+ return 0;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_MobjDamage);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // mobjtype subtable
- lua_rawgeti(gL, -1, target->type);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return false;
- }
- lua_remove(gL, -2); // remove hook table
-
- LUA_PushUserdata(gL, target, META_MOBJ);
- LUA_PushUserdata(gL, inflictor, META_MOBJ);
- LUA_PushUserdata(gL, source, META_MOBJ);
- lua_pushinteger(gL, damage);
- lua_pushnil(gL);
- while (lua_next(gL, -6)) {
- lua_pushvalue(gL, -6); // target
- lua_pushvalue(gL, -6); // inflictor
- lua_pushvalue(gL, -6); // source
- lua_pushvalue(gL, -6); // damage
- if (lua_pcall(gL, 4, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_MobjDamage
+ && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, target, META_MOBJ);
+ LUA_PushUserdata(gL, inflictor, META_MOBJ);
+ LUA_PushUserdata(gL, source, META_MOBJ);
+ lua_pushinteger(gL, damage);
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ if (lua_pcall(gL, 4, 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);
- continue;
}
- if (lua_toboolean(gL, -1))
- handled = true;
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 5); // pop arguments and mobjtype table
- lua_gc(gL, LUA_GCSTEP, 1);
- return handled;
+ lua_settop(gL, 0);
+ return hooked;
}
// Hook for P_KillMobj by mobj type
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
- boolean handled = false;
+ hook_p hookp;
+ boolean hooked = false;
if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8))))
- return false;
+ return 0;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_MobjDeath);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // mobjtype subtable
- lua_rawgeti(gL, -1, target->type);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return false;
- }
- lua_remove(gL, -2); // remove hook table
-
- LUA_PushUserdata(gL, target, META_MOBJ);
- LUA_PushUserdata(gL, inflictor, META_MOBJ);
- LUA_PushUserdata(gL, source, META_MOBJ);
- lua_pushnil(gL);
- while (lua_next(gL, -5)) {
- lua_pushvalue(gL, -5); // target
- lua_pushvalue(gL, -5); // inflictor
- lua_pushvalue(gL, -5); // source
- if (lua_pcall(gL, 3, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_MobjDeath
+ && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, target, META_MOBJ);
+ LUA_PushUserdata(gL, inflictor, META_MOBJ);
+ LUA_PushUserdata(gL, source, META_MOBJ);
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -4);
+ lua_pushvalue(gL, -4);
+ lua_pushvalue(gL, -4);
+ if (lua_pcall(gL, 3, 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);
- continue;
}
- if (lua_toboolean(gL, -1))
- handled = true;
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 4); // pop arguments and mobjtype table
- lua_gc(gL, LUA_GCSTEP, 1);
- return handled;
+ lua_settop(gL, 0);
+ return hooked;
}
// Hook for B_BuildTiccmd
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd)
{
+ hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8))))
return false;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_BotTiccmd);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- LUA_PushUserdata(gL, bot, META_PLAYER);
- LUA_PushUserdata(gL, cmd, META_TICCMD);
-
- lua_pushnil(gL);
- while (lua_next(gL, 1)) {
- lua_pushvalue(gL, 2); // bot
- lua_pushvalue(gL, 3); // cmd
- if (lua_pcall(gL, 2, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_BotTiccmd)
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, bot, META_PLAYER);
+ LUA_PushUserdata(gL, cmd, META_TICCMD);
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -3);
+ lua_pushvalue(gL, -3);
+ if (lua_pcall(gL, 2, 1, 0)) {
+ if (!hookp->error || cv_debug & DBG_LUA)
+ CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+ lua_pop(gL, 1);
+ hookp->error = true;
+ continue;
+ }
+ if (lua_toboolean(gL, -1))
+ hooked = true;
lua_pop(gL, 1);
- continue;
}
- if (lua_toboolean(gL, -1))
- hooked = true;
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCSTEP, 1);
+ lua_settop(gL, 0);
return hooked;
}
// Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
{
- if (!gL || !tails->skin || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8))))
+ hook_p hookp;
+ boolean hooked = false;
+ if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8))))
return false;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_BotAI);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
-
- // bot skin ai function
- lua_getfield(gL, 1, ((skin_t *)tails->skin)->name);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return false;
- }
- lua_remove(gL, 1); // pop the hook table
-
- // Takes sonic, tails
- // Returns forward, backward, left, right, jump, spin
- LUA_PushUserdata(gL, sonic, META_MOBJ);
- LUA_PushUserdata(gL, tails, META_MOBJ);
- if (lua_pcall(gL, 2, 8, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
- lua_pop(gL,-1);
- return false;
- }
-
- // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails.
- if (lua_istable(gL, 1)) {
- boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false;
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_BotAI
+ && (hookp->s.skinname == NULL || !strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name)))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, sonic, META_MOBJ);
+ LUA_PushUserdata(gL, tails, META_MOBJ);
+ }
+ 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, 8, 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;
+ }
+ // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails.
+ if (lua_istable(gL, 2+1)) {
+ boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false;
#define CHECKFIELD(field) \
- lua_getfield(gL, 1, #field);\
- if (lua_toboolean(gL, -1))\
- field = true;\
- lua_pop(gL, 1);
-
- CHECKFIELD(forward)
- CHECKFIELD(backward)
- CHECKFIELD(left)
- CHECKFIELD(right)
- CHECKFIELD(strafeleft)
- CHECKFIELD(straferight)
- CHECKFIELD(jump)
- CHECKFIELD(spin)
+ lua_getfield(gL, 2+1, #field);\
+ if (lua_toboolean(gL, -1))\
+ field = true;\
+ lua_pop(gL, 1);
+ CHECKFIELD(forward)
+ CHECKFIELD(backward)
+ CHECKFIELD(left)
+ CHECKFIELD(right)
+ CHECKFIELD(strafeleft)
+ CHECKFIELD(straferight)
+ CHECKFIELD(jump)
+ CHECKFIELD(spin)
#undef CHECKFIELD
+ B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin);
+ } else
+ B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8));
- B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin);
- } else
- B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 1), lua_toboolean(gL, 2), lua_toboolean(gL, 3), lua_toboolean(gL, 4), lua_toboolean(gL, 5), lua_toboolean(gL, 6), lua_toboolean(gL, 7), lua_toboolean(gL, 8));
+ lua_pop(gL, 8);
+ hooked = true;
+ }
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCSTEP, 1);
- return true;
+ lua_settop(gL, 0);
+ return hooked;
}
// Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
+ hook_p hookp;
+ boolean hooked = false;
if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8))))
- return false;
+ return 0;
- // clear the stack
- lua_pop(gL, -1);
+ lua_settop(gL, 0);
- // get hook table
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_LinedefExecute);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_LinedefExecute
+ && !strcmp(hookp->s.funcname, line->text))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, line, META_LINE);
+ LUA_PushUserdata(gL, mo, META_MOBJ);
+ LUA_PushUserdata(gL, sector, META_SECTOR);
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -4);
+ lua_pushvalue(gL, -4);
+ lua_pushvalue(gL, -4);
+ LUA_Call(gL, 3);
+ hooked = true;
+ }
- // get function by line text
- lua_getfield(gL, 1, line->text);
- if (lua_isnil(gL, -1)) {
- lua_pop(gL, 2);
- return false;
- }
- lua_remove(gL, 1); // pop hook table off the stack
-
- LUA_PushUserdata(gL, line, META_LINE);
- LUA_PushUserdata(gL, mo, META_MOBJ);
- LUA_PushUserdata(gL, sector, META_SECTOR);
- LUA_Call(gL, 3); // pops hook function, line, mo, sector
-
- lua_pop(gL, -1);
- lua_gc(gL, LUA_GCSTEP, 1);
- return true;
+ lua_settop(gL, 0);
+ return hooked;
}
-// Hook for PlayerMsg -Red
+// Hook for player chat
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
{
- boolean handled = false;
-
+ hook_p hookp;
+ boolean hooked = false;
if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8))))
return false;
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_PlayerMsg);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
+ lua_settop(gL, 0);
- LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player
-
- if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c
- lua_pushinteger(gL, 3); // type
- lua_pushnil(gL); // target
- } else if (target == -1) { // sayteam
- lua_pushinteger(gL, 1); // type
- lua_pushnil(gL); // target
- } else if (target == 0) { // say
- lua_pushinteger(gL, 0); // type
- lua_pushnil(gL); // target
- } else { // sayto
- lua_pushinteger(gL, 2); // type
- LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target
- }
-
- lua_pushstring(gL, msg); // msg
-
- lua_pushnil(gL);
-
- while (lua_next(gL, -6)) {
- lua_pushvalue(gL, -6); // source
- lua_pushvalue(gL, -6); // type
- lua_pushvalue(gL, -6); // target
- lua_pushvalue(gL, -6); // msg
- if (lua_pcall(gL, 4, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_PlayerMsg)
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player
+ if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c
+ lua_pushinteger(gL, 3); // type
+ lua_pushnil(gL); // target
+ } else if (target == -1) { // sayteam
+ lua_pushinteger(gL, 1); // type
+ lua_pushnil(gL); // target
+ } else if (target == 0) { // say
+ lua_pushinteger(gL, 0); // type
+ lua_pushnil(gL); // target
+ } else { // sayto
+ lua_pushinteger(gL, 2); // type
+ LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target
+ }
+ lua_pushstring(gL, msg); // msg
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ lua_pushvalue(gL, -5);
+ if (lua_pcall(gL, 4, 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);
- continue;
}
- if (lua_toboolean(gL, -1))
- handled = true;
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 4); // pop arguments and mobjtype table
- lua_gc(gL, LUA_GCSTEP, 1);
- return handled;
+ lua_settop(gL, 0);
+ return hooked;
}
-// Hook for hurt messages -Red
-// The internal name is DeathMsg, but the API name is "HurtMsg". Keep that in mind. (Should this be fixed at some point?)
-// @TODO This hook should be fixed to take mobj type at the addHook parameter to compare to inflictor. (I couldn't get this to work without crashing)
-boolean LUAh_DeathMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
+// Hook for hurt messages
+boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
{
- boolean handled = false;
-
- if (!gL || !(hooksAvailable[hook_DeathMsg/8] & (1<<(hook_DeathMsg%8))))
+ hook_p hookp;
+ boolean hooked = false;
+ if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8))))
return false;
- lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
- I_Assert(lua_istable(gL, -1));
- lua_rawgeti(gL, -1, hook_DeathMsg);
- lua_remove(gL, -2);
- I_Assert(lua_istable(gL, -1));
+ lua_settop(gL, 0);
- LUA_PushUserdata(gL, player, META_PLAYER); // Player
- LUA_PushUserdata(gL, inflictor, META_MOBJ); // Inflictor
- LUA_PushUserdata(gL, source, META_MOBJ); // Source
-
- lua_pushnil(gL);
-
- while (lua_next(gL, -5)) {
- lua_pushvalue(gL, -5); // player
- lua_pushvalue(gL, -5); // inflictor
- lua_pushvalue(gL, -5); // source
- if (lua_pcall(gL, 3, 1, 0)) {
- CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
+ for (hookp = roothook; hookp; hookp = hookp->next)
+ if (hookp->type == hook_HurtMsg
+ && (hookp->s.mt == MT_NULL || (inflictor && hookp->s.mt == inflictor->type)))
+ {
+ if (lua_gettop(gL) == 0)
+ {
+ LUA_PushUserdata(gL, player, META_PLAYER);
+ LUA_PushUserdata(gL, inflictor, META_MOBJ);
+ LUA_PushUserdata(gL, source, META_MOBJ);
+ }
+ lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+ lua_gettable(gL, LUA_REGISTRYINDEX);
+ lua_pushvalue(gL, -4);
+ lua_pushvalue(gL, -4);
+ lua_pushvalue(gL, -4);
+ if (lua_pcall(gL, 3, 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);
- continue;
}
- if (lua_toboolean(gL, -1))
- handled = true;
- lua_pop(gL, 1); // pop return value
- }
- lua_pop(gL, 3); // pop arguments and mobjtype table
- lua_gc(gL, LUA_GCSTEP, 1);
- return handled;
+ lua_settop(gL, 0);
+ return hooked;
}
#endif
diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c
index 19390d50d..5a83d95b5 100644
--- a/src/lua_hudlib.c
+++ b/src/lua_hudlib.c
@@ -126,8 +126,6 @@ static const char *const widtht_opt[] = {
enum cameraf {
camera_chase = 0,
camera_aiming,
- camera_viewheight,
- camera_startangle,
camera_x,
camera_y,
camera_z,
@@ -137,7 +135,6 @@ enum cameraf {
camera_ceilingz,
camera_radius,
camera_height,
- camera_relativex,
camera_momx,
camera_momy,
camera_momz
@@ -147,8 +144,6 @@ enum cameraf {
static const char *const camera_opt[] = {
"chase",
"aiming",
- "viewheight",
- "startangle",
"x",
"y",
"z",
@@ -158,7 +153,6 @@ static const char *const camera_opt[] = {
"ceilingz",
"radius",
"height",
- "relativex",
"momx",
"momy",
"momz",
@@ -279,12 +273,6 @@ static int camera_get(lua_State *L)
case camera_aiming:
lua_pushinteger(L, cam->aiming);
break;
- case camera_viewheight:
- lua_pushinteger(L, cam->viewheight);
- break;
- case camera_startangle:
- lua_pushinteger(L, cam->startangle);
- break;
case camera_x:
lua_pushinteger(L, cam->x);
break;
@@ -312,9 +300,6 @@ static int camera_get(lua_State *L)
case camera_height:
lua_pushinteger(L, cam->height);
break;
- case camera_relativex:
- lua_pushinteger(L, cam->relativex);
- break;
case camera_momx:
lua_pushinteger(L, cam->momx);
break;
@@ -689,8 +674,6 @@ void LUAh_GameHUD(player_t *stplayr)
LUA_Call(gL, 3);
}
lua_pop(gL, -1);
- lua_gc(gL, LUA_GCCOLLECT, 0);
-
hud_running = false;
}
@@ -716,8 +699,6 @@ void LUAh_ScoresHUD(void)
LUA_Call(gL, 1);
}
lua_pop(gL, -1);
- lua_gc(gL, LUA_GCCOLLECT, 0);
-
hud_running = false;
}
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index 2c968218c..a983bb002 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -91,6 +91,44 @@ static int lib_sprnamelen(lua_State *L)
return 1;
}
+//
+// Player Sprite Names
+//
+
+// push sprite name
+static int lib_getSpr2name(lua_State *L)
+{
+ UINT32 i;
+
+ lua_remove(L, 1); // don't care about spr2names[] dummy userdata.
+
+ if (lua_isnumber(L, 1))
+ {
+ i = lua_tonumber(L, 1);
+ if (i > NUMPLAYERSPRITES)
+ return 0;
+ lua_pushlstring(L, spr2names[i], 4);
+ return 1;
+ }
+ else if (lua_isstring(L, 1))
+ {
+ const char *name = lua_tostring(L, 1);
+ for (i = 0; i < NUMPLAYERSPRITES; i++)
+ if (fastcmp(name, spr2names[i]))
+ {
+ lua_pushinteger(L, i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int lib_spr2namelen(lua_State *L)
+{
+ lua_pushinteger(L, NUMPLAYERSPRITES);
+ return 1;
+}
+
////////////////
// STATE INFO //
////////////////
@@ -137,8 +175,6 @@ static void A_Lua(mobj_t *actor)
--superstack;
superactions[superstack] = NULL;
}
-
- lua_gc(gL, LUA_GCSTEP, 1);
}
// Arbitrary states[] table index -> state_t *
@@ -510,11 +546,11 @@ static int lib_setMobjInfo(lua_State *L)
else if (i == 15 || (str && fastcmp(str,"deathsound")))
info->deathsound = luaL_checkinteger(L, 3);
else if (i == 16 || (str && fastcmp(str,"speed")))
- info->speed = (fixed_t)luaL_checkinteger(L, 3);
+ info->speed = luaL_checkfixed(L, 3);
else if (i == 17 || (str && fastcmp(str,"radius")))
- info->radius = (fixed_t)luaL_checkinteger(L, 3);
+ info->radius = luaL_checkfixed(L, 3);
else if (i == 18 || (str && fastcmp(str,"height")))
- info->height = (fixed_t)luaL_checkinteger(L, 3);
+ info->height = luaL_checkfixed(L, 3);
else if (i == 19 || (str && fastcmp(str,"dispoffset")))
info->dispoffset = (INT32)luaL_checkinteger(L, 3);
else if (i == 20 || (str && fastcmp(str,"mass")))
@@ -580,11 +616,11 @@ static int mobjinfo_get(lua_State *L)
else if (fastcmp(field,"deathsound"))
lua_pushinteger(L, info->deathsound);
else if (fastcmp(field,"speed"))
- lua_pushinteger(L, info->speed);
+ lua_pushinteger(L, info->speed); // sometimes it's fixed_t, sometimes it's not...
else if (fastcmp(field,"radius"))
- lua_pushinteger(L, info->radius);
+ lua_pushfixed(L, info->radius);
else if (fastcmp(field,"height"))
- lua_pushinteger(L, info->height);
+ lua_pushfixed(L, info->height);
else if (fastcmp(field,"dispoffset"))
lua_pushinteger(L, info->dispoffset);
else if (fastcmp(field,"mass"))
@@ -656,11 +692,11 @@ static int mobjinfo_set(lua_State *L)
else if (fastcmp(field,"deathsound"))
info->deathsound = luaL_checkinteger(L, 3);
else if (fastcmp(field,"speed"))
- info->speed = (fixed_t)luaL_checkinteger(L, 3);
+ info->speed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"radius"))
- info->radius = (fixed_t)luaL_checkinteger(L, 3);
+ info->radius = luaL_checkfixed(L, 3);
else if (fastcmp(field,"height"))
- info->height = (fixed_t)luaL_checkinteger(L, 3);
+ info->height = luaL_checkfixed(L, 3);
else if (fastcmp(field,"dispoffset"))
info->dispoffset = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"mass"))
@@ -904,6 +940,16 @@ int LUA_InfoLib(lua_State *L)
lua_setmetatable(L, -2);
lua_setglobal(L, "sprnames");
+ lua_newuserdata(L, 0);
+ lua_createtable(L, 0, 2);
+ lua_pushcfunction(L, lib_getSpr2name);
+ lua_setfield(L, -2, "__index");
+
+ lua_pushcfunction(L, lib_spr2namelen);
+ lua_setfield(L, -2, "__len");
+ lua_setmetatable(L, -2);
+ lua_setglobal(L, "spr2names");
+
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getState);
diff --git a/src/lua_maplib.c b/src/lua_maplib.c
index 80f66ed60..0a12478ca 100644
--- a/src/lua_maplib.c
+++ b/src/lua_maplib.c
@@ -60,7 +60,6 @@ enum subsector_e {
subsector_sector,
subsector_numlines,
subsector_firstline,
- subsector_validcount
};
static const char *const subsector_opt[] = {
@@ -68,7 +67,6 @@ static const char *const subsector_opt[] = {
"sector",
"numlines",
"firstline",
- "validcount",
NULL};
enum line_e {
@@ -86,7 +84,6 @@ enum line_e {
line_slopetype,
line_frontsector,
line_backsector,
- line_validcount,
line_firsttag,
line_nexttag,
line_text,
@@ -108,7 +105,6 @@ static const char *const line_opt[] = {
"slopetype",
"frontsector",
"backsector",
- "validcount",
"firsttag",
"nexttag",
"text",
@@ -284,10 +280,10 @@ static int sector_get(lua_State *L)
lua_pushboolean(L, 1);
return 1;
case sector_floorheight:
- lua_pushinteger(L, sector->floorheight);
+ lua_pushfixed(L, sector->floorheight);
return 1;
case sector_ceilingheight:
- lua_pushinteger(L, sector->ceilingheight);
+ lua_pushfixed(L, sector->ceilingheight);
return 1;
case sector_floorpic: { // floorpic
levelflat_t *levelflat;
@@ -400,26 +396,30 @@ static int sector_set(lua_State *L)
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
case sector_floorheight: { // floorheight
boolean flag;
+ mobj_t *ptmthing = tmthing;
fixed_t lastpos = sector->floorheight;
- sector->floorheight = (fixed_t)luaL_checkinteger(L, 3);
+ sector->floorheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
if (flag && sector->numattached)
{
sector->floorheight = lastpos;
P_CheckSector(sector, true);
}
+ P_SetTarget(&tmthing, ptmthing);
break;
}
case sector_ceilingheight: { // ceilingheight
boolean flag;
+ mobj_t *ptmthing = tmthing;
fixed_t lastpos = sector->ceilingheight;
- sector->ceilingheight = (fixed_t)luaL_checkinteger(L, 3);
+ sector->ceilingheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
if (flag && sector->numattached)
{
sector->ceilingheight = lastpos;
P_CheckSector(sector, true);
}
+ P_SetTarget(&tmthing, ptmthing);
break;
}
case sector_floorpic:
@@ -476,9 +476,6 @@ static int subsector_get(lua_State *L)
case subsector_firstline:
lua_pushinteger(L, subsector->firstline);
return 1;
- case subsector_validcount:
- lua_pushinteger(L, subsector->validcount);
- return 1;
}
return 0;
}
@@ -516,10 +513,10 @@ static int line_get(lua_State *L)
LUA_PushUserdata(L, line->v2, META_VERTEX);
return 1;
case line_dx:
- lua_pushinteger(L, line->dx);
+ lua_pushfixed(L, line->dx);
return 1;
case line_dy:
- lua_pushinteger(L, line->dy);
+ lua_pushfixed(L, line->dy);
return 1;
case line_flags:
lua_pushinteger(L, line->flags);
@@ -564,9 +561,6 @@ static int line_get(lua_State *L)
case line_backsector:
LUA_PushUserdata(L, line->backsector, META_SECTOR);
return 1;
- case line_validcount:
- lua_pushinteger(L, line->validcount);
- return 1;
case line_firsttag:
lua_pushinteger(L, line->firsttag);
return 1;
@@ -638,10 +632,10 @@ static int side_get(lua_State *L)
lua_pushboolean(L, 1);
return 1;
case side_textureoffset:
- lua_pushinteger(L, side->textureoffset);
+ lua_pushfixed(L, side->textureoffset);
return 1;
case side_rowoffset:
- lua_pushinteger(L, side->rowoffset);
+ lua_pushfixed(L, side->rowoffset);
return 1;
case side_toptexture:
lua_pushinteger(L, side->toptexture);
@@ -668,6 +662,50 @@ static int side_get(lua_State *L)
return 0;
}
+static int side_set(lua_State *L)
+{
+ side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
+ enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt);
+
+ if (!side)
+ {
+ if (field == side_valid) {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+ return luaL_error(L, "accessed side_t doesn't exist anymore.");
+ }
+
+ switch(field)
+ {
+ case side_valid: // valid
+ case side_sector:
+ case side_special:
+ case side_text:
+ default:
+ return luaL_error(L, "side_t field " LUA_QS " cannot be set.", side_opt[field]);
+ case side_textureoffset:
+ side->textureoffset = luaL_checkfixed(L, 3);
+ break;
+ case side_rowoffset:
+ side->rowoffset = luaL_checkfixed(L, 3);
+ break;
+ case side_toptexture:
+ side->toptexture = luaL_checkinteger(L, 3);
+ break;
+ case side_bottomtexture:
+ side->bottomtexture = luaL_checkinteger(L, 3);
+ break;
+ case side_midtexture:
+ side->midtexture = luaL_checkinteger(L, 3);
+ break;
+ case side_repeatcnt:
+ side->repeatcnt = luaL_checkinteger(L, 3);
+ break;
+ }
+ return 0;
+}
+
static int side_num(lua_State *L)
{
side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
@@ -695,13 +733,13 @@ static int vertex_get(lua_State *L)
lua_pushboolean(L, 1);
return 1;
case vertex_x:
- lua_pushinteger(L, vertex->x);
+ lua_pushfixed(L, vertex->x);
return 1;
case vertex_y:
- lua_pushinteger(L, vertex->y);
+ lua_pushfixed(L, vertex->y);
return 1;
case vertex_z:
- lua_pushinteger(L, vertex->z);
+ lua_pushfixed(L, vertex->z);
return 1;
}
return 0;
@@ -964,7 +1002,7 @@ static int ffloor_get(lua_State *L)
lua_pushboolean(L, 1);
return 1;
case ffloor_topheight:
- lua_pushinteger(L, *ffloor->topheight);
+ lua_pushfixed(L, *ffloor->topheight);
return 1;
case ffloor_toppic: { // toppic
levelflat_t *levelflat;
@@ -978,7 +1016,7 @@ static int ffloor_get(lua_State *L)
lua_pushinteger(L, *ffloor->toplightlevel);
return 1;
case ffloor_bottomheight:
- lua_pushinteger(L, *ffloor->bottomheight);
+ lua_pushfixed(L, *ffloor->bottomheight);
return 1;
case ffloor_bottompic: { // bottompic
levelflat_t *levelflat;
@@ -1037,14 +1075,16 @@ static int ffloor_set(lua_State *L)
case ffloor_topheight: { // topheight
boolean flag;
fixed_t lastpos = *ffloor->topheight;
+ mobj_t *ptmthing = tmthing;
sector_t *sector = §ors[ffloor->secnum];
- sector->ceilingheight = (fixed_t)luaL_checkinteger(L, 3);
+ sector->ceilingheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
if (flag && sector->numattached)
{
*ffloor->topheight = lastpos;
P_CheckSector(sector, true);
}
+ P_SetTarget(&tmthing, ptmthing);
break;
}
case ffloor_toppic:
@@ -1056,14 +1096,16 @@ static int ffloor_set(lua_State *L)
case ffloor_bottomheight: { // bottomheight
boolean flag;
fixed_t lastpos = *ffloor->bottomheight;
+ mobj_t *ptmthing = tmthing;
sector_t *sector = §ors[ffloor->secnum];
- sector->floorheight = (fixed_t)luaL_checkinteger(L, 3);
+ sector->floorheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
if (flag && sector->numattached)
{
*ffloor->bottomheight = lastpos;
P_CheckSector(sector, true);
}
+ P_SetTarget(&tmthing, ptmthing);
break;
}
case ffloor_bottompic:
@@ -1224,6 +1266,9 @@ int LUA_MapLib(lua_State *L)
lua_pushcfunction(L, side_get);
lua_setfield(L, -2, "__index");
+ lua_pushcfunction(L, side_set);
+ lua_setfield(L, -2, "__newindex");
+
lua_pushcfunction(L, side_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c
index f8b33ffd2..8ca2e17af 100644
--- a/src/lua_mathlib.c
+++ b/src/lua_mathlib.c
@@ -47,37 +47,37 @@ static int lib_max(lua_State *L)
static int lib_fixedangle(lua_State *L)
{
- lua_pushinteger(L, FixedAngle((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushangle(L, FixedAngle(luaL_checkfixed(L, 1)));
return 1;
}
static int lib_anglefixed(lua_State *L)
{
- lua_pushinteger(L, AngleFixed((angle_t)luaL_checkinteger(L, 1)));
+ lua_pushfixed(L, AngleFixed(luaL_checkangle(L, 1)));
return 1;
}
static int lib_invangle(lua_State *L)
{
- lua_pushinteger(L, InvAngle((angle_t)luaL_checkinteger(L, 1)));
+ lua_pushangle(L, InvAngle(luaL_checkangle(L, 1)));
return 1;
}
static int lib_finesine(lua_State *L)
{
- lua_pushinteger(L, FINESINE((luaL_checkinteger(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
+ lua_pushfixed(L, FINESINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
return 1;
}
static int lib_finecosine(lua_State *L)
{
- lua_pushinteger(L, FINECOSINE((luaL_checkinteger(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
+ lua_pushfixed(L, FINECOSINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
return 1;
}
static int lib_finetangent(lua_State *L)
{
- lua_pushinteger(L, FINETANGENT((luaL_checkinteger(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
+ lua_pushfixed(L, FINETANGENT((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
return 1;
}
@@ -86,61 +86,61 @@ static int lib_finetangent(lua_State *L)
static int lib_fixedmul(lua_State *L)
{
- lua_pushinteger(L, FixedMul((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2)));
+ lua_pushfixed(L, FixedMul(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
return 1;
}
static int lib_fixedint(lua_State *L)
{
- lua_pushinteger(L, FixedInt((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushinteger(L, FixedInt(luaL_checkfixed(L, 1)));
return 1;
}
static int lib_fixeddiv(lua_State *L)
{
- lua_pushinteger(L, FixedDiv((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2)));
+ lua_pushfixed(L, FixedDiv(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
return 1;
}
static int lib_fixedrem(lua_State *L)
{
- lua_pushinteger(L, FixedRem((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2)));
+ lua_pushfixed(L, FixedRem(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
return 1;
}
static int lib_fixedsqrt(lua_State *L)
{
- lua_pushinteger(L, FixedSqrt((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushfixed(L, FixedSqrt(luaL_checkfixed(L, 1)));
return 1;
}
static int lib_fixedhypot(lua_State *L)
{
- lua_pushinteger(L, FixedHypot((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2)));
+ lua_pushfixed(L, FixedHypot(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
return 1;
}
static int lib_fixedfloor(lua_State *L)
{
- lua_pushinteger(L, FixedFloor((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushfixed(L, FixedFloor(luaL_checkfixed(L, 1)));
return 1;
}
static int lib_fixedtrunc(lua_State *L)
{
- lua_pushinteger(L, FixedTrunc((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushfixed(L, FixedTrunc(luaL_checkfixed(L, 1)));
return 1;
}
static int lib_fixedceil(lua_State *L)
{
- lua_pushinteger(L, FixedCeil((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushfixed(L, FixedCeil(luaL_checkfixed(L, 1)));
return 1;
}
static int lib_fixedround(lua_State *L)
{
- lua_pushinteger(L, FixedRound((fixed_t)luaL_checkinteger(L, 1)));
+ lua_pushfixed(L, FixedRound(luaL_checkfixed(L, 1)));
return 1;
}
@@ -156,7 +156,7 @@ static int lib_getsecspecial(lua_State *L)
static int lib_all7emeralds(lua_State *L)
{
- lua_pushinteger(L, ALL7EMERALDS(luaL_checkinteger(L, 1)));
+ lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1)));
return 1;
}
diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c
index f455edf1f..83e7039e4 100644
--- a/src/lua_mobjlib.c
+++ b/src/lua_mobjlib.c
@@ -162,13 +162,13 @@ static int mobj_get(lua_State *L)
lua_pushboolean(L, 1);
break;
case mobj_x:
- lua_pushinteger(L, mo->x);
+ lua_pushfixed(L, mo->x);
break;
case mobj_y:
- lua_pushinteger(L, mo->y);
+ lua_pushfixed(L, mo->y);
break;
case mobj_z:
- lua_pushinteger(L, mo->z);
+ lua_pushfixed(L, mo->z);
break;
case mobj_snext:
LUA_PushUserdata(L, mo->snext, META_MOBJ);
@@ -179,7 +179,7 @@ static int mobj_get(lua_State *L)
// i.e. it will always ultimately point to THIS mobj -- so that's actually not useful to Lua and won't be included.
return UNIMPLEMENTED;
case mobj_angle:
- lua_pushinteger(L, mo->angle);
+ lua_pushangle(L, mo->angle);
break;
case mobj_sprite:
lua_pushinteger(L, mo->sprite);
@@ -193,28 +193,28 @@ static int mobj_get(lua_State *L)
LUA_PushUserdata(L, mo->subsector, META_SUBSECTOR);
break;
case mobj_floorz:
- lua_pushinteger(L, mo->floorz);
+ lua_pushfixed(L, mo->floorz);
break;
case mobj_ceilingz:
- lua_pushinteger(L, mo->ceilingz);
+ lua_pushfixed(L, mo->ceilingz);
break;
case mobj_radius:
- lua_pushinteger(L, mo->radius);
+ lua_pushfixed(L, mo->radius);
break;
case mobj_height:
- lua_pushinteger(L, mo->height);
+ lua_pushfixed(L, mo->height);
break;
case mobj_momx:
- lua_pushinteger(L, mo->momx);
+ lua_pushfixed(L, mo->momx);
break;
case mobj_momy:
- lua_pushinteger(L, mo->momy);
+ lua_pushfixed(L, mo->momy);
break;
case mobj_momz:
- lua_pushinteger(L, mo->momz);
+ lua_pushfixed(L, mo->momz);
break;
case mobj_pmomz:
- lua_pushinteger(L, mo->pmomz);
+ lua_pushfixed(L, mo->pmomz);
break;
case mobj_tics:
lua_pushinteger(L, mo->tics);
@@ -299,32 +299,32 @@ static int mobj_get(lua_State *L)
LUA_PushUserdata(L, mo->tracer, META_MOBJ);
break;
case mobj_friction:
- lua_pushinteger(L, mo->friction);
+ lua_pushfixed(L, mo->friction);
break;
case mobj_movefactor:
- lua_pushinteger(L, mo->movefactor);
+ lua_pushfixed(L, mo->movefactor);
break;
case mobj_fuse:
lua_pushinteger(L, mo->fuse);
break;
case mobj_watertop:
- lua_pushinteger(L, mo->watertop);
+ lua_pushfixed(L, mo->watertop);
break;
case mobj_waterbottom:
- lua_pushinteger(L, mo->waterbottom);
+ lua_pushfixed(L, mo->waterbottom);
break;
case mobj_mobjnum:
// mobjnum is a networking thing generated for $$$.sav
// and therefore shouldn't be used by Lua.
return UNIMPLEMENTED;
case mobj_scale:
- lua_pushinteger(L, mo->scale);
+ lua_pushfixed(L, mo->scale);
break;
case mobj_destscale:
- lua_pushinteger(L, mo->destscale);
+ lua_pushfixed(L, mo->destscale);
break;
case mobj_scalespeed:
- lua_pushinteger(L, mo->scalespeed);
+ lua_pushfixed(L, mo->scalespeed);
break;
case mobj_extravalue1:
lua_pushinteger(L, mo->extravalue1);
@@ -382,7 +382,7 @@ static int mobj_set(lua_State *L)
{
// z doesn't cross sector bounds so it's okay.
mobj_t *ptmthing = tmthing;
- mo->z = (fixed_t)luaL_checkinteger(L, 3);
+ mo->z = luaL_checkfixed(L, 3);
P_CheckPosition(mo, mo->x, mo->y);
mo->floorz = tmfloorz;
mo->ceilingz = tmceilingz;
@@ -394,7 +394,7 @@ static int mobj_set(lua_State *L)
case mobj_sprev:
return UNIMPLEMENTED;
case mobj_angle:
- mo->angle = (angle_t)luaL_checkinteger(L, 3);
+ mo->angle = luaL_checkangle(L, 3);
if (mo->player == &players[consoleplayer])
localangle = mo->angle;
else if (mo->player == &players[secondarydisplayplayer])
@@ -417,7 +417,7 @@ static int mobj_set(lua_State *L)
case mobj_radius:
{
mobj_t *ptmthing = tmthing;
- mo->radius = (fixed_t)luaL_checkinteger(L, 3);
+ mo->radius = luaL_checkfixed(L, 3);
if (mo->radius < 0)
mo->radius = 0;
P_CheckPosition(mo, mo->x, mo->y);
@@ -429,7 +429,7 @@ static int mobj_set(lua_State *L)
case mobj_height:
{
mobj_t *ptmthing = tmthing;
- mo->height = (fixed_t)luaL_checkinteger(L, 3);
+ mo->height = luaL_checkfixed(L, 3);
if (mo->height < 0)
mo->height = 0;
P_CheckPosition(mo, mo->x, mo->y);
@@ -439,16 +439,17 @@ static int mobj_set(lua_State *L)
break;
}
case mobj_momx:
- mo->momx = (fixed_t)luaL_checkinteger(L, 3);
+ mo->momx = luaL_checkfixed(L, 3);
break;
case mobj_momy:
- mo->momy = (fixed_t)luaL_checkinteger(L, 3);
+ mo->momy = luaL_checkfixed(L, 3);
break;
case mobj_momz:
- mo->momz = (fixed_t)luaL_checkinteger(L, 3);
+ mo->momz = luaL_checkfixed(L, 3);
break;
case mobj_pmomz:
- mo->pmomz = (fixed_t)luaL_checkinteger(L, 3);
+ mo->pmomz = luaL_checkfixed(L, 3);
+ mo->eflags |= MFE_APPLYPMOMZ;
break;
case mobj_tics:
mo->tics = luaL_checkinteger(L, 3);
@@ -500,7 +501,7 @@ static int mobj_set(lua_State *L)
return luaL_error(L, "mobj.skin '%s' not found!", skin);
}
case mobj_color:
- mo->color = ((UINT8)luaL_checkinteger(L, 3)) % MAXSKINCOLORS;
+ mo->color = ((UINT8)luaL_checkinteger(L, 3)) % MAXTRANSLATIONS;
break;
case mobj_bnext:
return NOSETPOS;
@@ -572,25 +573,25 @@ static int mobj_set(lua_State *L)
}
break;
case mobj_friction:
- mo->friction = (fixed_t)luaL_checkinteger(L, 3);
+ mo->friction = luaL_checkfixed(L, 3);
break;
case mobj_movefactor:
- mo->movefactor = (fixed_t)luaL_checkinteger(L, 3);
+ mo->movefactor = luaL_checkfixed(L, 3);
break;
case mobj_fuse:
mo->fuse = luaL_checkinteger(L, 3);
break;
case mobj_watertop:
- mo->watertop = (fixed_t)luaL_checkinteger(L, 3);
+ mo->watertop = luaL_checkfixed(L, 3);
break;
case mobj_waterbottom:
- mo->waterbottom = (fixed_t)luaL_checkinteger(L, 3);
+ mo->waterbottom = luaL_checkfixed(L, 3);
break;
case mobj_mobjnum:
return UNIMPLEMENTED;
case mobj_scale:
{
- fixed_t scale = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t scale = luaL_checkfixed(L, 3);
if (scale < FRACUNIT/100)
scale = FRACUNIT/100;
mo->destscale = scale;
@@ -599,14 +600,14 @@ static int mobj_set(lua_State *L)
}
case mobj_destscale:
{
- fixed_t scale = (fixed_t)luaL_checkinteger(L, 3);
+ fixed_t scale = luaL_checkfixed(L, 3);
if (scale < FRACUNIT/100)
scale = FRACUNIT/100;
mo->destscale = scale;
break;
}
case mobj_scalespeed:
- mo->scalespeed = (fixed_t)luaL_checkinteger(L, 3);
+ mo->scalespeed = luaL_checkfixed(L, 3);
break;
case mobj_extravalue1:
mo->extravalue1 = luaL_checkinteger(L, 3);
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 7f64fff62..64513ab97 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -109,15 +109,15 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"playerstate"))
lua_pushinteger(L, plr->playerstate);
else if (fastcmp(field,"viewz"))
- lua_pushinteger(L, plr->viewz);
+ lua_pushfixed(L, plr->viewz);
else if (fastcmp(field,"viewheight"))
- lua_pushinteger(L, plr->viewheight);
+ lua_pushfixed(L, plr->viewheight);
else if (fastcmp(field,"deltaviewheight"))
- lua_pushinteger(L, plr->deltaviewheight);
+ lua_pushfixed(L, plr->deltaviewheight);
else if (fastcmp(field,"bob"))
- lua_pushinteger(L, plr->bob);
+ lua_pushfixed(L, plr->bob);
else if (fastcmp(field,"aiming"))
- lua_pushinteger(L, plr->aiming);
+ lua_pushangle(L, plr->aiming);
else if (fastcmp(field,"health"))
lua_pushinteger(L, plr->health);
else if (fastcmp(field,"pity"))
@@ -141,13 +141,13 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"score"))
lua_pushinteger(L, plr->score);
else if (fastcmp(field,"dashspeed"))
- lua_pushinteger(L, plr->dashspeed);
+ lua_pushfixed(L, plr->dashspeed);
else if (fastcmp(field,"dashtime"))
lua_pushinteger(L, plr->dashtime);
else if (fastcmp(field,"normalspeed"))
- lua_pushinteger(L, plr->normalspeed);
+ lua_pushfixed(L, plr->normalspeed);
else if (fastcmp(field,"runspeed"))
- lua_pushinteger(L, plr->runspeed);
+ lua_pushfixed(L, plr->runspeed);
else if (fastcmp(field,"thrustfactor"))
lua_pushinteger(L, plr->thrustfactor);
else if (fastcmp(field,"accelstart"))
@@ -167,13 +167,13 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"revitem"))
lua_pushinteger(L, plr->revitem);
else if (fastcmp(field,"actionspd"))
- lua_pushinteger(L, plr->actionspd);
+ lua_pushfixed(L, plr->actionspd);
else if (fastcmp(field,"mindash"))
- lua_pushinteger(L, plr->mindash);
+ lua_pushfixed(L, plr->mindash);
else if (fastcmp(field,"maxdash"))
- lua_pushinteger(L, plr->maxdash);
+ lua_pushfixed(L, plr->maxdash);
else if (fastcmp(field,"jumpfactor"))
- lua_pushinteger(L, plr->jumpfactor);
+ lua_pushfixed(L, plr->jumpfactor);
else if (fastcmp(field,"lives"))
lua_pushinteger(L, plr->lives);
else if (fastcmp(field,"continues"))
@@ -183,7 +183,7 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"gotcontinue"))
lua_pushinteger(L, plr->gotcontinue);
else if (fastcmp(field,"speed"))
- lua_pushinteger(L, plr->speed);
+ lua_pushfixed(L, plr->speed);
else if (fastcmp(field,"jumping"))
lua_pushboolean(L, plr->jumping);
else if (fastcmp(field,"secondjump"))
@@ -205,13 +205,13 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"skidtime"))
lua_pushinteger(L, plr->skidtime);
else if (fastcmp(field,"cmomx"))
- lua_pushinteger(L, plr->cmomx);
+ lua_pushfixed(L, plr->cmomx);
else if (fastcmp(field,"cmomy"))
- lua_pushinteger(L, plr->cmomy);
+ lua_pushfixed(L, plr->cmomy);
else if (fastcmp(field,"rmomx"))
- lua_pushinteger(L, plr->rmomx);
+ lua_pushfixed(L, plr->rmomx);
else if (fastcmp(field,"rmomy"))
- lua_pushinteger(L, plr->rmomy);
+ lua_pushfixed(L, plr->rmomy);
else if (fastcmp(field,"numboxes"))
lua_pushinteger(L, plr->numboxes);
else if (fastcmp(field,"totalring"))
@@ -239,11 +239,11 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"starposttime"))
lua_pushinteger(L, plr->starposttime);
else if (fastcmp(field,"starpostangle"))
- lua_pushinteger(L, plr->starpostangle);
+ lua_pushangle(L, plr->starpostangle);
else if (fastcmp(field,"angle_pos"))
- lua_pushinteger(L, plr->angle_pos);
+ lua_pushangle(L, plr->angle_pos);
else if (fastcmp(field,"old_angle_pos"))
- lua_pushinteger(L, plr->old_angle_pos);
+ lua_pushangle(L, plr->old_angle_pos);
else if (fastcmp(field,"axis1"))
LUA_PushUserdata(L, plr->axis1, META_MOBJ);
else if (fastcmp(field,"axis2"))
@@ -305,16 +305,16 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"awayviewtics"))
lua_pushinteger(L, plr->awayviewtics);
else if (fastcmp(field,"awayviewaiming"))
- lua_pushinteger(L, plr->awayviewaiming);
+ lua_pushangle(L, plr->awayviewaiming);
else if (fastcmp(field,"spectator"))
- lua_pushinteger(L, plr->spectator);
+ lua_pushboolean(L, plr->spectator);
else if (fastcmp(field,"bot"))
lua_pushinteger(L, plr->bot);
else if (fastcmp(field,"jointime"))
lua_pushinteger(L, plr->jointime);
#ifdef HWRENDER
else if (fastcmp(field,"fovadd"))
- lua_pushinteger(L, plr->fovadd);
+ lua_pushfixed(L, plr->fovadd);
#endif
else {
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
@@ -354,15 +354,15 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"playerstate"))
plr->playerstate = luaL_checkinteger(L, 3);
else if (fastcmp(field,"viewz"))
- plr->viewz = (fixed_t)luaL_checkinteger(L, 3);
+ plr->viewz = luaL_checkfixed(L, 3);
else if (fastcmp(field,"viewheight"))
- plr->viewheight = (fixed_t)luaL_checkinteger(L, 3);
+ plr->viewheight = luaL_checkfixed(L, 3);
else if (fastcmp(field,"deltaviewheight"))
- plr->deltaviewheight = (fixed_t)luaL_checkinteger(L, 3);
+ plr->deltaviewheight = luaL_checkfixed(L, 3);
else if (fastcmp(field,"bob"))
- plr->bob = (fixed_t)luaL_checkinteger(L, 3);
+ plr->bob = luaL_checkfixed(L, 3);
else if (fastcmp(field,"aiming")) {
- plr->aiming = (angle_t)luaL_checkinteger(L, 3);
+ plr->aiming = luaL_checkangle(L, 3);
if (plr == &players[consoleplayer])
localaiming = plr->aiming;
else if (plr == &players[secondarydisplayplayer])
@@ -391,13 +391,13 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"score"))
plr->score = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"dashspeed"))
- plr->dashspeed = (fixed_t)luaL_checkinteger(L, 3);
+ plr->dashspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"dashtime"))
plr->dashtime = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"normalspeed"))
- plr->normalspeed = (fixed_t)luaL_checkinteger(L, 3);
+ plr->normalspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"runspeed"))
- plr->runspeed = (fixed_t)luaL_checkinteger(L, 3);
+ plr->runspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"thrustfactor"))
plr->thrustfactor = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"accelstart"))
@@ -433,7 +433,7 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"gotcontinue"))
plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"speed"))
- plr->speed = (fixed_t)luaL_checkinteger(L, 3);
+ plr->speed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"jumping"))
plr->jumping = luaL_checkboolean(L, 3);
else if (fastcmp(field,"secondjump"))
@@ -455,13 +455,13 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"skidtime"))
plr->skidtime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"cmomx"))
- plr->cmomx = (fixed_t)luaL_checkinteger(L, 3);
+ plr->cmomx = luaL_checkfixed(L, 3);
else if (fastcmp(field,"cmomy"))
- plr->cmomy = (fixed_t)luaL_checkinteger(L, 3);
+ plr->cmomy = luaL_checkfixed(L, 3);
else if (fastcmp(field,"rmomx"))
- plr->rmomx = (fixed_t)luaL_checkinteger(L, 3);
+ plr->rmomx = luaL_checkfixed(L, 3);
else if (fastcmp(field,"rmomy"))
- plr->rmomy = (fixed_t)luaL_checkinteger(L, 3);
+ plr->rmomy = luaL_checkfixed(L, 3);
else if (fastcmp(field,"numboxes"))
plr->numboxes = (INT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"totalring"))
@@ -489,11 +489,11 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"starposttime"))
plr->starposttime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostangle"))
- plr->starpostangle = (angle_t)luaL_checkinteger(L, 3);
+ plr->starpostangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"angle_pos"))
- plr->angle_pos = (angle_t)luaL_checkinteger(L, 3);
+ plr->angle_pos = luaL_checkangle(L, 3);
else if (fastcmp(field,"old_angle_pos"))
- plr->old_angle_pos = (angle_t)luaL_checkinteger(L, 3);
+ plr->old_angle_pos = luaL_checkangle(L, 3);
else if (fastcmp(field,"axis1"))
P_SetTarget(&plr->axis1, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)));
else if (fastcmp(field,"axis2"))
@@ -569,7 +569,7 @@ static int player_set(lua_State *L)
P_SetTarget(&plr->awayviewmobj, plr->mo); // but since the script might set awayviewmobj immediately AFTER setting awayviewtics, use player mobj as filler for now.
}
else if (fastcmp(field,"awayviewaiming"))
- plr->awayviewaiming = (angle_t)luaL_checkinteger(L, 3);
+ plr->awayviewaiming = luaL_checkangle(L, 3);
else if (fastcmp(field,"spectator"))
plr->spectator = lua_toboolean(L, 3);
else if (fastcmp(field,"bot"))
@@ -578,7 +578,7 @@ static int player_set(lua_State *L)
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
#ifdef HWRENDER
else if (fastcmp(field,"fovadd"))
- plr->fovadd = (fixed_t)luaL_checkinteger(L, 3);
+ plr->fovadd = luaL_checkfixed(L, 3);
#endif
else {
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
diff --git a/src/lua_script.c b/src/lua_script.c
index 8b40d9f00..a7315ad62 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -442,7 +442,6 @@ enum
ARCH_NULL=0,
ARCH_BOOLEAN,
ARCH_SIGNED,
- ARCH_UNSIGNED,
ARCH_STRING,
ARCH_TABLE,
@@ -522,13 +521,8 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
case LUA_TNUMBER:
{
lua_Integer number = lua_tointeger(gL, myindex);
- if (number < 0) {
- WRITEUINT8(save_p, ARCH_SIGNED);
- WRITEFIXED(save_p, number);
- } else {
- WRITEUINT8(save_p, ARCH_UNSIGNED);
- WRITEANGLE(save_p, number);
- }
+ WRITEUINT8(save_p, ARCH_SIGNED);
+ WRITEFIXED(save_p, number);
break;
}
case LUA_TSTRING:
@@ -743,7 +737,7 @@ static int NetArchive(lua_State *L)
{
int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L);
- for (i = 0; i < n; i++)
+ for (i = 1; i <= n; i++)
ArchiveValue(TABLESINDEX, i);
return n;
}
@@ -797,9 +791,6 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_SIGNED:
lua_pushinteger(gL, READFIXED(save_p));
break;
- case ARCH_UNSIGNED:
- lua_pushinteger(gL, READANGLE(save_p));
- break;
case ARCH_STRING:
{
char value[1024];
@@ -893,7 +884,7 @@ static int NetUnArchive(lua_State *L)
{
int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L);
- for (i = 0; i < n; i++)
+ for (i = 1; i <= n; i++)
UnArchiveValue(TABLESINDEX);
return n;
}
@@ -948,6 +939,14 @@ static void NetArchiveHook(lua_CFunction archFunc)
lua_pop(gL, 2);
}
+void LUA_Step(void)
+{
+ if (!gL)
+ return;
+ lua_settop(gL, 0);
+ lua_gc(gL, LUA_GCSTEP, 1);
+}
+
void LUA_Archive(void)
{
INT32 i;
diff --git a/src/lua_script.h b/src/lua_script.h
index eaef13d1e..292160a0b 100644
--- a/src/lua_script.h
+++ b/src/lua_script.h
@@ -19,9 +19,21 @@
#include "blua/lua.h"
#include "blua/lualib.h"
#include "blua/lauxlib.h"
+
#define lua_optboolean(L, i) (!lua_isnoneornil(L, i) && lua_toboolean(L, i))
#define lua_opttrueboolean(L, i) (lua_isnoneornil(L, i) || lua_toboolean(L, i))
+// fixed_t casting
+// TODO add some distinction between fixed numbers and integer numbers
+// for at least the purpose of printing and maybe math.
+#define luaL_checkfixed(L, i) luaL_checkinteger(L, i)
+#define lua_pushfixed(L, f) lua_pushinteger(L, f)
+
+// angle_t casting
+// we reduce the angle to a fixed point between 0.0 and 1.0
+#define luaL_checkangle(L, i) (((angle_t)(luaL_checkfixed(L, i)&0xFFFF))<<16)
+#define lua_pushangle(L, a) lua_pushfixed(L, a>>16)
+
#ifdef _DEBUG
void LUA_ClearExtVars(void);
#endif
@@ -36,6 +48,7 @@ void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);
void LUA_InvalidateMapthings(void);
void LUA_InvalidatePlayer(player_t *player);
+void LUA_Step(void);
void LUA_Archive(void);
void LUA_UnArchive(void);
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c
index f797f30d6..f07b4564c 100644
--- a/src/lua_skinlib.c
+++ b/src/lua_skinlib.c
@@ -147,19 +147,19 @@ static int skin_get(lua_State *L)
lua_pushinteger(L, skin->revitem);
break;
case skin_actionspd:
- lua_pushinteger(L, skin->actionspd);
+ lua_pushfixed(L, skin->actionspd);
break;
case skin_mindash:
- lua_pushinteger(L, skin->mindash);
+ lua_pushfixed(L, skin->mindash);
break;
case skin_maxdash:
- lua_pushinteger(L, skin->maxdash);
+ lua_pushfixed(L, skin->maxdash);
break;
case skin_normalspeed:
- lua_pushinteger(L, skin->normalspeed);
+ lua_pushfixed(L, skin->normalspeed);
break;
case skin_runspeed:
- lua_pushinteger(L, skin->runspeed);
+ lua_pushfixed(L, skin->runspeed);
break;
case skin_thrustfactor:
lua_pushinteger(L, skin->thrustfactor);
@@ -171,7 +171,7 @@ static int skin_get(lua_State *L)
lua_pushinteger(L, skin->acceleration);
break;
case skin_jumpfactor:
- lua_pushinteger(L, skin->jumpfactor);
+ lua_pushfixed(L, skin->jumpfactor);
break;
case skin_starttranscolor:
lua_pushinteger(L, skin->starttranscolor);
diff --git a/src/m_cheat.c b/src/m_cheat.c
index 8cea4c6ae..4da9b3ba7 100644
--- a/src/m_cheat.c
+++ b/src/m_cheat.c
@@ -91,6 +91,33 @@ static UINT8 cheatf_warp(void)
return 1;
}
+#ifdef DEVELOP
+static UINT8 cheatf_devmode(void)
+{
+ UINT8 i;
+
+ if (modifiedgame)
+ return 0;
+
+ if (menuactive && currentMenu != &MainDef)
+ return 0; // Only on the main menu!
+
+ S_StartSound(0, sfx_itemup);
+
+ // Just unlock all the things and turn on -debug and console devmode.
+ G_SetGameModified(false);
+ for (i = 0; i < MAXUNLOCKABLES; i++)
+ unlockables[i].unlocked = true;
+ devparm = TRUE;
+ cv_debug |= 0x8000;
+
+ // Refresh secrets menu existing.
+ M_ClearMenus(true);
+ M_StartControlPanel();
+ return 1;
+}
+#endif
+
static cheatseq_t cheat_ultimate = {
0, cheatf_ultimate,
{ SCRAMBLE('u'), SCRAMBLE('l'), SCRAMBLE('t'), SCRAMBLE('i'), SCRAMBLE('m'), SCRAMBLE('a'), SCRAMBLE('t'), SCRAMBLE('e'), 0xff }
@@ -115,6 +142,14 @@ static cheatseq_t cheat_warp_joy = {
SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW),
SCRAMBLE(KEY_ENTER), 0xff }
};
+
+#ifdef DEVELOP
+static cheatseq_t cheat_devmode = {
+ 0, cheatf_devmode,
+ { SCRAMBLE('d'), SCRAMBLE('e'), SCRAMBLE('v'), SCRAMBLE('m'), SCRAMBLE('o'), SCRAMBLE('d'), SCRAMBLE('e'), 0xff }
+};
+#endif
+
// ==========================================================================
// CHEAT SEQUENCE PACKAGE
// ==========================================================================
@@ -221,6 +256,9 @@ boolean cht_Responder(event_t *ev)
ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch);
ret += cht_CheckCheat(&cheat_warp, (char)ch);
ret += cht_CheckCheat(&cheat_warp_joy, (char)ch);
+#ifdef DEVELOP
+ ret += cht_CheckCheat(&cheat_devmode, (char)ch);
+#endif
return (ret != 0);
}
@@ -334,7 +372,7 @@ void Command_Hurtme_f(void)
return;
}
- P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)));
+ P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)), 0);
}
// Moves the NiGHTS player to another axis within the current mare
diff --git a/src/m_fixed.c b/src/m_fixed.c
index 25a25a966..53974936e 100644
--- a/src/m_fixed.c
+++ b/src/m_fixed.c
@@ -119,8 +119,6 @@ fixed_t FixedHypot(fixed_t x, fixed_t y)
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
}
-#ifdef NEED_FIXED_VECTOR
-
vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y)
{
vec->x = x;
@@ -863,8 +861,6 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z)
#undef M
}
-#endif
-
#ifdef M_TESTCASE
//#define MULDIV_TEST
#define SQRT_TEST
diff --git a/src/m_fixed.h b/src/m_fixed.h
index e68de0308..cd22d483f 100644
--- a/src/m_fixed.h
+++ b/src/m_fixed.h
@@ -357,8 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x)
return INT32_MAX;
}
-#ifdef NEED_FIXED_VECTOR
-
typedef struct
{
fixed_t x;
@@ -437,6 +435,4 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme);
void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
-#endif // defined NEED_FIXED_VECTOR
-
#endif //m_fixed.h
diff --git a/src/m_menu.c b/src/m_menu.c
index f115e9d44..13465b266 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -110,10 +110,10 @@ const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003
description_t description[32] =
{
- {"\x82Sonic\x80 is the fastest of the three, but also the hardest to control. Beginners beware, but experts will find Sonic very powerful.\n\n\x82""Ability:\x80 Speed Thok\nDouble jump to zoom forward with a huge burst of speed.\n\n\x82Tip:\x80 Simply letting go of forward does not slow down in SRB2. To slow down, hold the opposite direction.", "", "sonic"},
- {"\x82Tails\x80 is the most mobile of the three, but has the slowest speed. Because of his mobility, he's well-\nsuited to beginners.\n\n\x82""Ability:\x80 Fly\nDouble jump to start flying for a limited time. Repetitively hit the jump button to ascend.\n\n\x82Tip:\x80 To quickly descend while flying, hit the spin button.", "", "tails"},
- {"\x82Knuckles\x80 is well-\nrounded and can destroy breakable walls simply by touching them, but he can't jump as high as the other two.\n\n\x82""Ability:\x80 Glide & Climb\nDouble jump to glide in the air as long as jump is held. Glide into a wall to climb it.\n\n\x82Tip:\x80 Press spin while climbing to jump off the wall; press jump instead to jump off\nand face away from\nthe wall.", "", "knuckles"},
- {"\x82Sonic & Tails\x80 team up to take on Dr. Eggman!\nControl Sonic while Tails desperately struggles to keep up.\n\nPlayer 2 can control Tails directly by setting the controls in the options menu.\nTails's directional controls are relative to Player 1's camera.\n\nTails can pick up Sonic while flying and carry him around.", "CHRS&T", "sonic&tails"},
+ {"???", "", ""},
+ {"???", "", ""},
+ {"???", "", ""},
+ {"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
@@ -827,10 +827,10 @@ static menuitem_t SP_LevelStatsMenu[] =
// And I'm too lazy to go through and rename it everywhere. ARRGH!
menuitem_t PlayerMenu[32] =
{
- {IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
- {IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
- {IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
- {IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
+ {IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
+ {IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
+ {IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
+ {IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
@@ -2203,6 +2203,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking)
return true;
M_StartControlPanel();
+ M_Options(0);
currentMenu = &OP_SoundOptionsDef;
itemOn = 0;
return true;
@@ -2212,6 +2213,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking)
return true;
M_StartControlPanel();
+ M_Options(0);
M_VideoModeMenu(0);
return true;
#endif
@@ -2223,6 +2225,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking)
return true;
M_StartControlPanel();
+ M_Options(0);
M_SetupNextMenu(&OP_MainDef);
return true;
@@ -6331,8 +6334,8 @@ static void M_HandleConnectIP(INT32 choice)
#define PLBOXW 8
#define PLBOXH 9
-static INT32 multi_tics;
-static state_t *multi_state;
+static UINT8 multi_tics;
+static UINT8 multi_frame;
// this is set before entering the MultiPlayer setup menu,
// for either player 1 or 2
@@ -6346,11 +6349,10 @@ static INT32 setupm_fakecolor;
static void M_DrawSetupMultiPlayerMenu(void)
{
- INT32 mx, my, st, flags = 0;
+ INT32 mx, my, flags = 0;
spritedef_t *sprdef;
spriteframe_t *sprframe;
patch_t *patch;
- UINT8 frame;
mx = MP_PlayerSetupDef.x;
my = MP_PlayerSetupDef.y;
@@ -6378,28 +6380,23 @@ static void M_DrawSetupMultiPlayerMenu(void)
// anim the player in the box
if (--multi_tics <= 0)
{
- st = multi_state->nextstate;
- if (st != S_NULL)
- multi_state = &states[st];
- multi_tics = multi_state->tics;
- if (multi_tics == -1)
- multi_tics = 15;
+ multi_frame++;
+ multi_tics = 4;
}
// skin 0 is default player sprite
if (R_SkinAvailable(skins[setupm_fakeskin].name) != -1)
- sprdef = &skins[R_SkinAvailable(skins[setupm_fakeskin].name)].spritedef;
+ sprdef = &skins[R_SkinAvailable(skins[setupm_fakeskin].name)].sprites[SPR2_WALK];
else
- sprdef = &skins[0].spritedef;
+ sprdef = &skins[0].sprites[SPR2_WALK];
if (!sprdef->numframes) // No frames ??
return; // Can't render!
- frame = multi_state->frame & FF_FRAMEMASK;
- if (frame >= sprdef->numframes) // Walking animation missing
- frame = 0; // Try to use standing frame
+ if (multi_frame >= sprdef->numframes)
+ multi_frame = 0;
- sprframe = &sprdef->spriteframes[frame];
+ sprframe = &sprdef->spriteframes[multi_frame];
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
if (sprframe->flip & 1) // Only for first sprite
flags |= V_FLIP; // This sprite is left/right flipped!
@@ -6533,8 +6530,8 @@ static void M_SetupMultiPlayer(INT32 choice)
{
(void)choice;
- multi_state = &states[mobjinfo[MT_PLAYER].seestate];
- multi_tics = multi_state->tics;
+ multi_frame = 0;
+ multi_tics = 4;
strcpy(setupm_name, cv_playername.string);
// set for player 1
@@ -6564,8 +6561,8 @@ static void M_SetupMultiPlayer2(INT32 choice)
{
(void)choice;
- multi_state = &states[mobjinfo[MT_PLAYER].seestate];
- multi_tics = multi_state->tics;
+ multi_frame = 0;
+ multi_tics = 4;
strcpy (setupm_name, cv_playername2.string);
// set for splitscreen secondary player
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 18a4ec5ff..d5da92e38 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -363,12 +363,12 @@ boolean P_CheckMissileRange(mobj_t *actor)
if (!actor->target)
return false;
- if (!P_CheckSight(actor, actor->target))
- return false;
-
if (actor->reactiontime)
return false; // do not attack yet
+ if (!P_CheckSight(actor, actor->target))
+ return false;
+
// OPTIMIZE: get this from a global checksight
dist = P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) - FixedMul(64*FRACUNIT, actor->scale);
@@ -652,6 +652,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
player = &players[actor->lastlook];
+ if ((netgame || multiplayer) && player->spectator)
+ continue;
+
if (player->health <= 0)
continue; // dead
@@ -661,12 +664,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
if (!player->mo || P_MobjWasRemoved(player->mo))
continue;
- if (!P_CheckSight(actor, player->mo))
- continue; // out of sight
-
- if ((netgame || multiplayer) && player->spectator)
- continue;
-
if (dist > 0
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
continue; // Too far away
@@ -683,6 +680,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
}
}
+ if (!P_CheckSight(actor, player->mo))
+ continue; // out of sight
+
if (tracer)
P_SetTarget(&actor->tracer, player->mo);
else
@@ -2513,7 +2513,7 @@ void A_1upThinker(mobj_t *actor)
}
}
- if (closestplayer == -1 || skins[players[closestplayer].skin].spritedef.numframes <= states[S_PLAY_BOX1].frame)
+ if (closestplayer == -1 || skins[players[closestplayer].skin].sprites[SPR2_LIFE].numframes == 0)
{ // Closest player not found (no players in game?? may be empty dedicated server!), or does not have correct sprite.
actor->frame = 0;
if (actor->tracer) {
@@ -2658,7 +2658,7 @@ for (i = cvar.value; i; --i) spawnchance[numchoices++] = type
if (actor->tracer) // Remove the old lives icon.
P_RemoveMobj(actor->tracer);
- if (!newmobj->target->skin || ((skin_t *)newmobj->target->skin)->spritedef.numframes <= states[S_PLAY_BOX1].frame)
+ if (!newmobj->target->skin || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0)
newmobj->frame -= 2; // No lives icon for this player, use the default.
else
{ // Spawn the lives icon.
@@ -4813,7 +4813,7 @@ void A_UnidusBall(mobj_t *actor)
boolean skull = (actor->target->flags2 & MF2_SKULLFLY) == MF2_SKULLFLY;
if (actor->target->state == &states[actor->target->info->painstate])
{
- P_KillMobj(actor, NULL, NULL);
+ P_KillMobj(actor, NULL, NULL, 0);
return;
}
switch(actor->extravalue2)
@@ -5024,7 +5024,7 @@ void A_MaceRotate(mobj_t *actor)
actor->movecount += actor->target->lastlook;
actor->movecount &= FINEMASK;
- actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook);
+ actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS);
v[0] = FRACUNIT;
v[1] = 0;
@@ -5032,7 +5032,7 @@ void A_MaceRotate(mobj_t *actor)
v[3] = FRACUNIT;
// Calculate the angle matrixes for the link.
- res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold << FRACBITS)));
+ res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold)));
M_Memcpy(&v, res, sizeof(v));
res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT));
M_Memcpy(&v, res, sizeof(v));
@@ -5278,7 +5278,7 @@ void A_RingExplode(mobj_t *actor)
if (mo2->flags & MF_SHOOTABLE)
{
actor->flags2 |= MF2_DEBRIS;
- P_DamageMobj(mo2, actor, actor->target, 1);
+ P_DamageMobj(mo2, actor, actor->target, 1, 0);
continue;
}
}
@@ -5606,8 +5606,13 @@ void A_MixUp(mobj_t *actor)
P_SetThingPosition(players[i].mo);
+#ifdef ESLOPE
+ players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
+ players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
+#else
players[i].mo->floorz = players[i].mo->subsector->sector->floorheight;
players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight;
+#endif
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y);
}
@@ -5660,6 +5665,11 @@ void A_RecyclePowers(mobj_t *actor)
if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE
&& !players[i].exiting && !((netgame || multiplayer) && players[i].spectator))
{
+#ifndef WEIGHTEDRECYCLER
+ if (players[i].powers[pw_super])
+ continue; // Ignore super players
+#endif
+
numplayers++;
postscramble[j] = playerslist[j] = (UINT8)i;
@@ -6378,7 +6388,7 @@ void A_EggmanBox(mobj_t *actor)
return;
}
- P_DamageMobj(actor->target, actor, actor, 1); // Ow!
+ P_DamageMobj(actor->target, actor, actor, 1, 0); // Ow!
}
// Function: A_TurretFire
@@ -7645,26 +7655,33 @@ void A_SetObjectFlags(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
+ boolean unlinkthings = false;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_SetObjectFlags", actor))
return;
#endif
- P_UnsetThingPosition(actor);
- if (sector_list)
- {
- P_DelSeclist(sector_list);
- sector_list = NULL;
+ if (locvar2 == 2)
+ locvar1 = actor->flags | locvar1;
+ else if (locvar2 == 1)
+ locvar1 = actor->flags & ~locvar1;
+
+ if ((locvar1 & (MF_NOBLOCKMAP|MF_NOSECTOR)) != (actor->flags & (MF_NOBLOCKMAP|MF_NOSECTOR))) // Blockmap/sector status has changed, so reset the links
+ unlinkthings = true;
+
+ if (unlinkthings) {
+ P_UnsetThingPosition(actor);
+ if (sector_list)
+ {
+ P_DelSeclist(sector_list);
+ sector_list = NULL;
+ }
}
- if (locvar2 == 2)
- actor->flags |= locvar1;
- else if (locvar2 == 1)
- actor->flags &= ~locvar1;
- else
- actor->flags = locvar1;
+ actor->flags = locvar1;
- P_SetThingPosition(actor);
+ if (unlinkthings)
+ P_SetThingPosition(actor);
}
// Function: A_SetObjectFlags2
@@ -9363,9 +9380,9 @@ void A_RemoteDamage(mobj_t *actor)
if (locvar2 == 1) // Kill mobj!
{
if (target->player) // players die using P_DamageMobj instead for some reason
- P_DamageMobj(target, source, source, 10000);
+ P_DamageMobj(target, source, source, 1, DMG_INSTAKILL);
else
- P_KillMobj(target, source, source);
+ P_KillMobj(target, source, source, 0);
}
else if (locvar2 == 2) // Remove mobj!
{
@@ -9375,7 +9392,7 @@ void A_RemoteDamage(mobj_t *actor)
P_RemoveMobj(target);
}
else // default: Damage mobj!
- P_DamageMobj(target, source, source, 1);
+ P_DamageMobj(target, source, source, 1, 0);
}
// Function: A_HomingChase
@@ -9610,7 +9627,7 @@ void A_VileAttack(mobj_t *actor)
return;
S_StartSound(actor, soundtoplay);
- P_DamageMobj(actor->target, actor, actor, 1);
+ P_DamageMobj(actor->target, actor, actor, 1, 0);
//actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; // How id did it
actor->target->momz += FixedMul(10*FRACUNIT, actor->scale)*P_MobjFlip(actor->target); // How we're doing it
if (explosionType != MT_NULL)
@@ -9651,7 +9668,7 @@ void A_VileAttack(mobj_t *actor)
continue;
S_StartSound(actor, soundtoplay);
- P_DamageMobj(players[i].mo, actor, actor, 1);
+ P_DamageMobj(players[i].mo, actor, actor, 1, 0);
//actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; // How id did it
players[i].mo->momz += FixedMul(10*FRACUNIT, actor->scale)*P_MobjFlip(players[i].mo); // How we're doing it
if (explosionType != MT_NULL)
diff --git a/src/p_floor.c b/src/p_floor.c
index f798174ad..ec52abeb9 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -1174,12 +1174,15 @@ void T_SpikeSector(levelspecthink_t *spikes)
if (affectsec == spikes->sector) // Applied to an actual sector
{
+ fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec);
+ fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec);
+
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue;
- if (thing->z == affectsec->floorheight)
+ if (thing->z == affectfloor)
dothepain = true;
}
@@ -1188,18 +1191,20 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue;
- if (thing->z + thing->height == affectsec->ceilingheight)
+ if (thing->z + thing->height == affectceil)
dothepain = true;
}
}
else
{
+ fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector);
+ fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector);
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue;
- if (thing->z == affectsec->ceilingheight)
+ if (thing->z == affectceil)
dothepain = true;
}
@@ -1208,16 +1213,14 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue;
- if (thing->z + thing->height == affectsec->floorheight)
+ if (thing->z + thing->height == affectfloor)
dothepain = true;
}
}
if (dothepain)
{
- mobj_t *killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL);
- killer->threshold = 43; // Special flag that it was spikes which hurt you.
- P_DamageMobj(thing, killer, killer, 1);
+ P_DamageMobj(thing, NULL, NULL, 1, DMG_SPIKE);
break;
}
}
@@ -1968,51 +1971,71 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
{
size_t i;
fixed_t upperbound, lowerbound;
- INT32 s;
- sector_t *checksector;
+ sector_t *sec = NULL;
+ sector_t *targetsec = NULL;
+ INT32 secnum = -1;
msecnode_t *node;
mobj_t *thing;
- boolean exists = false;
+ boolean FOFsector = false;
- for (i = 0; i < nobaddies->sector->linecount; i++)
+ while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0)
{
- if (nobaddies->sector->lines[i]->special == 223)
+ sec = §ors[secnum];
+
+ FOFsector = false;
+
+ // Check the lines of this sector, to see if it is a FOF control sector.
+ for (i = 0; i < sec->linecount; i++)
{
+ INT32 targetsecnum = -1;
- upperbound = nobaddies->sector->ceilingheight;
- lowerbound = nobaddies->sector->floorheight;
+ if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
+ continue;
- for (s = -1; (s = P_FindSectorFromLineTag(nobaddies->sector->lines[i], s)) >= 0 ;)
+ FOFsector = true;
+
+ while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0)
{
- checksector = §ors[s];
+ targetsec = §ors[targetsecnum];
- node = checksector->touching_thinglist; // things touching this sector
+ upperbound = targetsec->ceilingheight;
+ lowerbound = targetsec->floorheight;
+ node = targetsec->touching_thinglist; // things touching this sector
while (node)
{
thing = node->m_thing;
if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0
- && thing->z < upperbound && thing->z+thing->height > lowerbound)
- {
- exists = true;
- goto foundenemy;
- }
+ && thing->z < upperbound && thing->z+thing->height > lowerbound)
+ return;
node = node->m_snext;
}
}
}
+
+ if (!FOFsector)
+ {
+ upperbound = sec->ceilingheight;
+ lowerbound = sec->floorheight;
+ node = sec->touching_thinglist; // things touching this sector
+ while (node)
+ {
+ thing = node->m_thing;
+
+ if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0
+ && thing->z < upperbound && thing->z+thing->height > lowerbound)
+ return;
+
+ node = node->m_snext;
+ }
+ }
}
-foundenemy:
- if (exists)
- return;
- s = P_AproxDistance(nobaddies->sourceline->dx, nobaddies->sourceline->dy)>>FRACBITS;
+ CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", nobaddies->sourceline->tag);
- CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", s);
-
- // Otherwise, run the linedef exec and terminate this thinker
- P_LinedefExecute((INT16)s, NULL, NULL);
+ // No enemies found, run the linedef exec and terminate this thinker
+ P_RunTriggerLinedef(nobaddies->sourceline, NULL, NULL);
P_RemoveThinker(&nobaddies->thinker);
}
@@ -2067,6 +2090,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
boolean FOFsector = false;
boolean inAndOut = false;
boolean floortouch = false;
+ fixed_t bottomheight, topheight;
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -2131,10 +2155,13 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
if (players[j].mo->subsector->sector != targetsec)
continue;
- if (players[j].mo->z > sec->ceilingheight)
+ topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
+ bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec);
+
+ if (players[j].mo->z > topheight)
continue;
- if (players[j].mo->z + players[j].mo->height < sec->floorheight)
+ if (players[j].mo->z + players[j].mo->height < bottomheight)
continue;
if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec))
@@ -2217,7 +2244,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
oldPlayersArea = oldPlayersInArea;
}
- if ((affectPlayer = P_HavePlayersEnteredArea(playersArea, oldPlayersArea, inAndOut)) != -1)
+ while ((affectPlayer = P_HavePlayersEnteredArea(playersArea, oldPlayersArea, inAndOut)) != -1)
{
if (GETSECSPECIAL(sec->special, 2) == 2 || GETSECSPECIAL(sec->special, 2) == 3)
{
@@ -2250,6 +2277,8 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
if (!eachtime->sourceline->special) // this happens only for "Trigger on X calls" linedefs
P_RemoveThinker(&eachtime->thinker);
+
+ oldPlayersArea[affectPlayer]=playersArea[affectPlayer];
}
}
@@ -2292,7 +2321,7 @@ void T_RaiseSector(levelspecthink_t *raise)
if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH))
continue;
- if (!(thing->z == raise->sector->ceilingheight))
+ if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector)))
continue;
playeronme = true;
@@ -3105,7 +3134,7 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
P_SetThingPosition(thing);
if (thing->flags & MF_SHOOTABLE)
- P_DamageMobj(thing, puncher, puncher, 1);
+ P_DamageMobj(thing, puncher, puncher, 1, 0);
else if (thing->type == MT_RING || thing->type == MT_COIN)
{
thing->momz = FixedMul(3*FRACUNIT, thing->scale);
diff --git a/src/p_inter.c b/src/p_inter.c
index 8eaa4765a..f9dc3c342 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -291,7 +291,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
if (special->type == MT_BLACKEGGMAN)
{
- P_DamageMobj(toucher, special, special, 1); // ouch
+ P_DamageMobj(toucher, special, special, 1, 0); // ouch
return;
}
@@ -303,20 +303,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->momz = -toucher->momz;
toucher->momx = -toucher->momx;
toucher->momy = -toucher->momy;
- P_DamageMobj(special, toucher, toucher, 1);
+ P_DamageMobj(special, toucher, toucher, 1, 0);
}
else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP))
|| (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP)))
&& player->charability == CA_FLY
&& (player->powers[pw_tailsfly]
- || (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller.
+ || toucher->state-states == S_PLAY_FLY_TIRED)) // Tails can shred stuff with his propeller.
{
toucher->momz = -toucher->momz/2;
- P_DamageMobj(special, toucher, toucher, 1);
+ P_DamageMobj(special, toucher, toucher, 1, 0);
}
else
- P_DamageMobj(toucher, special, special, 1);
+ P_DamageMobj(toucher, special, special, 1, 0);
return;
}
@@ -330,13 +330,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
&& toucher->z < special->z + special->height && toucher->z + toucher->height > special->z)
{
// Can only hit snapper from above
- P_DamageMobj(toucher, special, special, 1);
+ P_DamageMobj(toucher, special, special, 1, 0);
}
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);
+ P_DamageMobj(toucher, special, special, 1, 0);
}
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
@@ -345,27 +345,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (P_MobjFlip(toucher)*toucher->momz < 0)
toucher->momz = -toucher->momz;
- P_DamageMobj(special, toucher, toucher, 1);
+ P_DamageMobj(special, toucher, toucher, 1, 0);
}
else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP))
|| (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) // Flame is bad at logic - JTE
&& player->charability == CA_FLY
&& (player->powers[pw_tailsfly]
- || (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller.
+ || toucher->state-states == S_PLAY_FLY_TIRED)) // Tails can shred stuff with his propeller.
{
if (P_MobjFlip(toucher)*toucher->momz < 0)
toucher->momz = -toucher->momz/2;
- P_DamageMobj(special, toucher, toucher, 1);
+ P_DamageMobj(special, toucher, toucher, 1, 0);
}
else
- P_DamageMobj(toucher, special, special, 1);
+ P_DamageMobj(toucher, special, special, 1, 0);
return;
}
else if (special->flags & MF_FIRE)
{
- P_DamageMobj(toucher, special, special, 1);
+ P_DamageMobj(toucher, special, special, 1, DMG_FIRE);
return;
}
else
@@ -743,7 +743,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (mo2->flags & MF_SHOOTABLE)
{
- P_DamageMobj(mo2, toucher, toucher, 1);
+ P_DamageMobj(mo2, toucher, toucher, 1, 0);
continue;
}
@@ -875,7 +875,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_ResetPlayer(player);
- P_SetPlayerMobjState(toucher, S_PLAY_FALL1);
+ P_SetPlayerMobjState(toucher, S_PLAY_FALL);
}
}
return;
@@ -1212,7 +1212,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->pflags & PF_GLIDING)
{
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
- P_SetPlayerMobjState(toucher, S_PLAY_FALL1);
+ P_SetPlayerMobjState(toucher, S_PLAY_FALL);
}
// Play a bounce sound?
@@ -1279,7 +1279,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->pflags & PF_GLIDING)
{
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
- P_SetPlayerMobjState(toucher, S_PLAY_FALL1);
+ P_SetPlayerMobjState(toucher, S_PLAY_FALL);
}
// Play a bounce sound?
@@ -1335,7 +1335,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
player->pflags |= PF_MACESPIN;
S_StartSound(toucher, sfx_spin);
- P_SetPlayerMobjState(toucher, S_PLAY_ATK1);
+ P_SetPlayerMobjState(toucher, S_PLAY_SPIN);
}
else
player->pflags |= PF_ITEMHANG;
@@ -1351,7 +1351,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_SPECIALSPIKEBALL:
if (!(!useNightsSS && G_IsSpecialStage(gamemap))) // Only for old special stages
{
- P_DamageMobj(toucher, special, special, 1);
+ P_DamageMobj(toucher, special, special, 1, 0);
return;
}
@@ -1382,7 +1382,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// Goomba Stomp'd!
if (special->target->momz < 0)
{
- P_DamageMobj(toucher, special, special->target, 1);
+ P_DamageMobj(toucher, special, special->target, 1, 0);
//special->target->momz = -special->target->momz;
special->target->momx = special->target->momy = 0;
special->target->momz = 0;
@@ -1446,7 +1446,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings
- P_KillMobj(special, NULL, toucher);
+ P_KillMobj(special, NULL, toucher, 0);
}
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
@@ -1457,8 +1457,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
* \param player Affected player.
* \param inflictor The attack weapon used, can be NULL.
* \param source The attacker, can be NULL.
+ * \param damagetype The type of damage dealt to the player. If bit 7 (0x80) is set, this was an instant-kill.
*/
-static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source)
+static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
{
const char *str = NULL;
boolean deathonly = false;
@@ -1478,7 +1479,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
return; // Presumably it's obvious what's happening in splitscreen.
#ifdef HAVE_BLUA
- if (LUAh_DeathMsg(player, inflictor, source))
+ if (LUAh_HurtMsg(player, inflictor, source))
return;
#endif
@@ -1567,22 +1568,6 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
}
else switch (source->type)
{
- case MT_NULL:
- switch(source->threshold)
- {
- case 42:
- deathonly = true;
- str = M_GetText("%s drowned.\n");
- break;
- case 43:
- str = M_GetText("%s was %s by spikes.\n");
- break;
- case 44:
- deathonly = true;
- str = M_GetText("%s was crushed.\n");
- break;
- }
- break;
case MT_EGGMANICO:
case MT_EGGMANBOX:
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
@@ -1598,30 +1583,52 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
else
{
// null source, environment kills
- // TERRIBLE HACK for hit damage because P_DoPlayerPain moves the player...
- // I'll put it back, I promise!
- player->mo->z -= player->mo->momz+1;
- if (P_PlayerTouchingSectorSpecial(player, 1, 2))
- str = M_GetText("%s was %s by chemical water.\n");
- else if (P_PlayerTouchingSectorSpecial(player, 1, 3))
- str = M_GetText("%s was %s by molten lava.\n");
- else if (P_PlayerTouchingSectorSpecial(player, 1, 4))
- str = M_GetText("%s was %s by electricity.\n");
- else if (deadtarget)
+ switch (damagetype)
{
- deathonly = true;
- if (P_PlayerTouchingSectorSpecial(player, 1, 6)
- || P_PlayerTouchingSectorSpecial(player, 1, 7))
- str = M_GetText("%s fell into a bottomless pit.\n");
- else if (P_PlayerTouchingSectorSpecial(player, 1, 12))
- str = M_GetText("%s asphyxiated in space.\n");
- else
- str = M_GetText("%s died.\n");
+ case DMG_WATER:
+ str = M_GetText("%s was %s by chemical water.\n");
+ break;
+ case DMG_FIRE:
+ str = M_GetText("%s was %s by molten lava.\n");
+ break;
+ case DMG_ELECTRIC:
+ str = M_GetText("%s was %s by electricity.\n");
+ break;
+ case DMG_SPIKE:
+ str = M_GetText("%s was %s by spikes.\n");
+ break;
+ case DMG_DROWNED:
+ deathonly = true;
+ str = M_GetText("%s drowned.\n");
+ break;
+ case DMG_CRUSHED:
+ deathonly = true;
+ str = M_GetText("%s was crushed.\n");
+ break;
+ case DMG_DEATHPIT:
+ if (deadtarget)
+ {
+ deathonly = true;
+ str = M_GetText("%s fell into a bottomless pit.\n");
+ }
+ break;
+ case DMG_SPACEDROWN:
+ if (deadtarget)
+ {
+ deathonly = true;
+ str = M_GetText("%s asphyxiated in space.\n");
+ }
+ break;
+ default:
+ if (deadtarget)
+ {
+ deathonly = true;
+ str = M_GetText("%s died.\n");
+ }
+ break;
}
if (!str)
str = M_GetText("%s was %s by an environmental hazard.\n");
-
- player->mo->z += player->mo->momz+1;
}
if (!str) // Should not happen! Unless we missed catching something above.
@@ -1799,10 +1806,11 @@ boolean P_CheckRacers(void)
* \param target The victim.
* \param inflictor The attack weapon. May be NULL (environmental damage).
* \param source The attacker. May be NULL.
+ * \param damagetype The type of damage dealt that killed the target. If bit 7 (0x80) was set, this was an instant-death.
* \todo Cleanup, refactor, split up.
* \sa P_DamageMobj
*/
-void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
+void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
{
mobjtype_t item;
mobj_t *mo;
@@ -1945,7 +1953,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
target->flags &= ~(MF_SOLID|MF_SHOOTABLE); // does not block
P_UnsetThingPosition(target);
- target->flags |= MF_NOBLOCKMAP;
+ target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
P_SetThingPosition(target);
if (!target->player->bot && !G_IsSpecialStage(gamemap)
@@ -1988,7 +1996,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
// allow them to try again, rather than sitting the whole thing out.
if (leveltime >= hidetime * TICRATE)
{
- if (gametype == GT_HIDEANDSEEK)//suiciding in survivor makes you IT.
+ if (gametype == GT_TAG)//suiciding in survivor makes you IT.
{
target->player->pflags |= PF_TAGIT;
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it!
@@ -2126,15 +2134,19 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
case MT_PLAYER:
target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
target->momx = target->momy = target->momz = 0;
- if (!(source && source->type == MT_NULL && source->threshold == 42)) // Don't jump up when drowning
- P_SetObjectMomZ(target, 14*FRACUNIT, false);
-
- if (source && source->type == MT_NULL && source->threshold == 42) // drowned
+ if (damagetype == DMG_DROWNED) // drowned
+ {
S_StartSound(target, sfx_drown);
- else if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // Spikes
- S_StartSound(target, sfx_spkdth);
+ // Don't jump up when drowning
+ }
else
- P_PlayDeathSound(target);
+ {
+ P_SetObjectMomZ(target, 14*FRACUNIT, false);
+ if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes
+ S_StartSound(target, sfx_spkdth);
+ else
+ P_PlayDeathSound(target);
+ }
break;
default:
break;
@@ -2277,7 +2289,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
}
}
else if (target->player)
- P_SetPlayerMobjState(target, target->info->deathstate);
+ {
+ if (damagetype == DMG_DROWNED || damagetype == DMG_SPACEDROWN)
+ P_SetPlayerMobjState(target, target->info->xdeathstate);
+ else
+ P_SetPlayerMobjState(target, target->info->deathstate);
+ }
else
#ifdef DEBUG_NULL_DEATHSTATE
P_SetMobjState(target, S_NULL);
@@ -2384,7 +2401,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
{
P_AddPlayerScore(source->player, 100); //award points to tagger.
- P_HitDeathMessages(player, inflictor, source);
+ P_HitDeathMessages(player, inflictor, source, 0);
if (gametype == GT_TAG) //survivor
{
@@ -2570,7 +2587,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_SUPERHIT);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_STUN);
else
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
@@ -2640,7 +2657,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
}
}
-static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
+static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
{
@@ -2648,7 +2665,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
- if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes
+ if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
S_StartSound(player->mo, sfx_spkdth);
}
@@ -2677,21 +2694,21 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
/** Damages an object, which may or may not be a player.
* For melee attacks, source and inflictor are the same.
*
- * \param target The object being damaged.
- * \param inflictor The thing that caused the damage: creature, missile,
- * gargoyle, and so forth. Can be NULL in the case of
- * environmental damage, such as slime or crushing.
- * \param source The creature or person responsible. For example, if a
- * player is hit by a ring, the player who shot it. In some
- * cases, the target will go after this object after
- * receiving damage. This can be NULL.
- * \param damage Amount of damage to be dealt. 10000 is instant death.
+ * \param target The object being damaged.
+ * \param inflictor The thing that caused the damage: creature, missile,
+ * gargoyle, and so forth. Can be NULL in the case of
+ * environmental damage, such as slime or crushing.
+ * \param source The creature or person responsible. For example, if a
+ * player is hit by a ring, the player who shot it. In some
+ * cases, the target will go after this object after
+ * receiving damage. This can be NULL.
+ * \param damage Amount of damage to be dealt.
+ * \param damagetype Type of damage to be dealt. If bit 7 (0x80) is set, this is an instant-kill.
* \return True if the target sustained damage, otherwise false.
* \todo Clean up this mess, split into multiple functions.
- * \todo Get rid of the magic number 10000.
* \sa P_KillMobj
*/
-boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
+boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
player_t *player;
#ifdef HAVE_BLUA
@@ -2709,9 +2726,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Spectator handling
if (netgame)
{
- if (damage == 42000 && target->player && target->player->spectator)
- damage = 10000;
- else if (target->player && target->player->spectator)
+ if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
return false;
if (source && source->player && source->player->spectator)
@@ -2819,6 +2834,21 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
return false;
+
+ switch (damagetype)
+ {
+ case DMG_WATER:
+ case DMG_FIRE:
+ if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
+ return false; // Invincible to water/fire damage
+ break;
+ case DMG_ELECTRIC:
+ if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
+ return false; // Invincible to electric damage
+ break;
+ default:
+ break;
+ }
}
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling
@@ -2840,12 +2870,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
- if (!force && inflictor && (inflictor->flags & MF_FIRE))
+ if (!force && inflictor && inflictor->flags & MF_FIRE)
{
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
return false; // Invincible to fire objects
- if (G_PlatformGametype() && source && source->player)
+ if (G_PlatformGametype() && inflictor && source && source->player)
return false; // Don't get hurt by fire generated from friends.
}
@@ -2854,7 +2884,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{
if ((gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) && cv_suddendeath.value
&& !player->powers[pw_flashing] && !player->powers[pw_invulnerability])
- damage = 10000;
+ damagetype = DMG_INSTAKILL;
}
// Player hits another player
@@ -2868,7 +2898,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// Instant-Death
- if (damage == 10000)
+ if (damagetype & DMG_DEATHMASK)
P_KillPlayer(player, source, damage);
else if (metalrecording)
{
@@ -2876,7 +2906,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
inflictor = source;
if (inflictor && inflictor->flags & MF_ENEMY)
{ // Metal Sonic destroy enemy !!
- P_KillMobj(inflictor, NULL, target);
+ P_KillMobj(inflictor, NULL, target, damagetype);
return false;
}
else if (inflictor && inflictor->flags & MF_MISSILE)
@@ -2915,7 +2945,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else if (player->mo->health > 1) // No shield but have rings.
{
damage = player->mo->health - 1;
- P_RingDamage(player, inflictor, source, damage);
+ P_RingDamage(player, inflictor, source, damage, damagetype);
}
else // No shield, no rings, no invincibility.
{
@@ -2952,21 +2982,20 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
P_PlayerFlagBurst(player, false);
}
+ else if (damagetype & DMG_DEATHMASK)
+ player->health = 0;
else
{
player->health -= damage; // mirror mobj health here
- if (damage < 10000)
- {
- target->player->powers[pw_flashing] = flashingtics;
- if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
- P_PlayerRingBurst(player, damage);
- }
+ target->player->powers[pw_flashing] = flashingtics;
+ if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
+ P_PlayerRingBurst(player, damage);
}
if (player->health < 0)
player->health = 0;
- P_HitDeathMessages(player, inflictor, source);
+ P_HitDeathMessages(player, inflictor, source, damagetype);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
}
@@ -2974,7 +3003,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Killing dead. Just for kicks.
// Require source and inflictor be player. Don't hurt for firing rings.
if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_Random() < 80)
- P_DamageMobj(source, target, target, 1);
+ P_DamageMobj(source, target, target, 1, 0);
// do the damage
if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player))
@@ -2983,6 +3012,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health < 2)
target->health = 2;
}
+ else if (damagetype & DMG_DEATHMASK)
+ target->health = 0;
else
target->health -= damage;
@@ -2991,7 +3022,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health <= 0)
{
- P_KillMobj(target, inflictor, source);
+ P_KillMobj(target, inflictor, source, damagetype);
return true;
}
diff --git a/src/p_local.h b/src/p_local.h
index 0b27c40f3..498bf0828 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -38,6 +38,9 @@
#define MAPBMASK (MAPBLOCKSIZE-1)
#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
+// Convenience macro to fix issue with collision along bottom/left edges of blockmap -Red
+#define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;}
+
// player radius used only in am_map.c
#define PLAYERRADIUS (16*FRACUNIT)
@@ -214,6 +217,23 @@ boolean P_RailThinker(mobj_t *mobj);
void P_PushableThinker(mobj_t *mobj);
void P_SceneryThinker(mobj_t *mobj);
+
+fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
+fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
+#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
+#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false)
+#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
+#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
+#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true)
+#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true)
+
+fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
+fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
+#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false)
+#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false)
+#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
+#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
+
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
boolean P_CheckDeathPitCollide(mobj_t *mo);
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
@@ -273,9 +293,13 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
extern boolean floatok;
extern fixed_t tmfloorz;
extern fixed_t tmceilingz;
-extern boolean tmsprung;
-extern mobj_t *tmfloorthing, *tmthing;
+extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
extern camera_t *mapcampointer;
+extern fixed_t tmx;
+extern fixed_t tmy;
+#ifdef ESLOPE
+extern pslope_t *tmfloorslope, *tmceilingslope;
+#endif
/* cphipps 2004/08/30 */
extern void P_MapStart(void);
@@ -314,7 +338,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist);
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
boolean PIT_PushableMoved(mobj_t *thing);
-void P_DoSpring(mobj_t *spring, mobj_t *object);
+boolean P_DoSpring(mobj_t *spring, mobj_t *object);
//
// P_SETUP
@@ -343,12 +367,29 @@ typedef struct BasicFF_s
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
} BasicFF_t;
+/* Damage/death types, for P_DamageMobj and related */
+//// Damage types
+//#define DMG_NORMAL 0 (unneeded?)
+#define DMG_WATER 1
+#define DMG_FIRE 2
+#define DMG_ELECTRIC 3
+#define DMG_SPIKE 4
+//#define DMG_SPECIALSTAGE 5
+//// Death types - cannot be combined with damage types
+#define DMG_INSTAKILL 0x80
+#define DMG_DROWNED 0x80+1
+#define DMG_SPACEDROWN 0x80+2
+#define DMG_DEATHPIT 0x80+3
+#define DMG_CRUSHED 0x80+4
+#define DMG_SPECTATOR 0x80+5
+#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
+
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
void P_ForceConstant(const BasicFF_t *FFInfo);
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End);
void P_RemoveShield(player_t *player);
-boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage);
-void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source);
+boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
+void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c
void P_PlayerWeaponPanelBurst(player_t *player);
void P_PlayerWeaponAmmoBurst(player_t *player);
diff --git a/src/p_map.c b/src/p_map.c
index 62cbf7b77..214048fb3 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -27,6 +27,10 @@
#include "r_splats.h"
+#ifdef ESLOPE
+#include "p_slopes.h"
+#endif
+
#include "z_zone.h"
#include "lua_hook.h"
@@ -34,8 +38,8 @@
fixed_t tmbbox[4];
mobj_t *tmthing;
static INT32 tmflags;
-static fixed_t tmx;
-static fixed_t tmy;
+fixed_t tmx;
+fixed_t tmy;
static precipmobj_t *tmprecipthing;
static fixed_t preciptmbbox[4];
@@ -47,10 +51,10 @@ boolean floatok;
fixed_t tmfloorz, tmceilingz;
static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
-static mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
-
-// turned on or off in PIT_CheckThing
-boolean tmsprung;
+mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
+#ifdef ESLOPE
+pslope_t *tmfloorslope, *tmceilingslope;
+#endif
// keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls
@@ -105,24 +109,27 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
// MOVEMENT ITERATOR FUNCTIONS
// =========================================================================
-void P_DoSpring(mobj_t *spring, mobj_t *object)
+boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{
INT32 pflags;
fixed_t offx, offy;
fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage;
- fixed_t origvertispeed = vertispeed; // for vertical flipping
+
+ if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
+ return false;
// Spectators don't trigger springs.
if (object->player && object->player->spectator)
- return;
+ return false;
if (object->player && (object->player->pflags & PF_NIGHTSMODE))
{
/*Someone want to make these work like bumpers?*/
- return;
+ return false;
}
+ object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
if (horizspeed && vertispeed) // Mimic SA
@@ -191,24 +198,25 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED); // I still need these.
P_ResetPlayer(object->player);
- if (origvertispeed > 0)
- P_SetPlayerMobjState(object, S_PLAY_SPRING);
- else if (origvertispeed < 0)
- P_SetPlayerMobjState(object, S_PLAY_FALL1);
+ if (P_MobjFlip(object)*vertispeed > 0)
+ P_SetPlayerMobjState(object, S_PLAY_JUMP);
+ else if (P_MobjFlip(object)*vertispeed < 0)
+ P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring
{
if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL)
object->player->pflags = pflags;
else
- P_SetPlayerMobjState(object, S_PLAY_RUN1);
+ P_SetPlayerMobjState(object, S_PLAY_WALK);
}
if (spring->info->painchance)
{
object->player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(object, S_PLAY_ATK1);
+ P_SetPlayerMobjState(object, S_PLAY_SPIN);
}
}
+ return true;
}
static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
@@ -255,7 +263,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
{
P_ResetPlayer(p);
if (p->panim != PA_FALL)
- P_SetPlayerMobjState(object, S_PLAY_FALL1);
+ P_SetPlayerMobjState(object, S_PLAY_FALL);
}
break;
case MT_STEAM: // Steam
@@ -270,7 +278,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
{
P_ResetPlayer(p);
if (p->panim != PA_FALL)
- P_SetPlayerMobjState(object, S_PLAY_FALL1);
+ P_SetPlayerMobjState(object, S_PLAY_FALL);
}
break;
default:
@@ -288,7 +296,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo)
return;
- if (!tails->powers[pw_tailsfly] && !(tails->charability == CA_FLY && (tails->mo->state >= &states[S_PLAY_SPC1] && tails->mo->state <= &states[S_PLAY_SPC4])))
+ if (!tails->powers[pw_tailsfly] && !(tails->charability == CA_FLY && tails->mo->state-states == S_PLAY_FLY_TIRED))
return;
if (tails->bot == 1)
@@ -365,12 +373,14 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
static boolean PIT_CheckThing(mobj_t *thing)
{
fixed_t blockdist;
+ boolean iwassprung = false;
// don't clip against self
- tmsprung = false;
+ if (thing == tmthing)
+ return true;
// Ignore... things.
- if (!tmthing || !thing)
+ if (!tmthing || !thing || P_MobjWasRemoved(thing))
return true;
I_Assert(!P_MobjWasRemoved(tmthing));
@@ -425,12 +435,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
S_StartSound(tmthing, thing->info->deathsound);
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
- P_KillMobj(thing, tmthing, tmthing);
+ P_KillMobj(thing, tmthing, tmthing, 0);
}
else
{
thing->health = 0;
- P_KillMobj(thing, tmthing, tmthing);
+ P_KillMobj(thing, tmthing, tmthing, 0);
}
return true;
}
@@ -438,9 +448,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
return true;
- if (!tmthing || !thing || thing == tmthing || P_MobjWasRemoved(thing))
- return true;
-
// 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)))
@@ -485,7 +492,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
else
thing->z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale);
if (thing->flags & MF_SHOOTABLE)
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ P_DamageMobj(thing, tmthing, tmthing, 1, 0);
return true;
}
@@ -497,7 +504,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z + thing->height < tmthing->z)
return true; // underneath
if (tmthing->player && tmthing->flags & MF_SHOOTABLE)
- P_DamageMobj(tmthing, thing, thing, 1);
+ {
+ UINT8 damagetype = 0;
+ if (thing->flags & MF_FIRE) // BURN!
+ damagetype = DMG_FIRE;
+ P_DamageMobj(tmthing, thing, thing, 1, damagetype);
+ }
return true;
}
else if (tmthing->flags & MF_PAIN)
@@ -508,7 +520,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (thing->player && thing->flags & MF_SHOOTABLE)
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ {
+ UINT8 damagetype = 0;
+ if (tmthing->flags & MF_FIRE) // BURN!
+ damagetype = DMG_FIRE;
+ P_DamageMobj(thing, tmthing, tmthing, 1, damagetype);
+ }
return true;
}
@@ -549,7 +566,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
if ((tmznext <= thzh && tmz > thzh) || (tmznext > thzh - sprarea && tmznext < thzh))
{
P_DoSpring(thing, tmthing);
- tmsprung = true;
return true;
}
else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down
@@ -630,7 +646,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return false;
else // hit shield from behind, shield is destroyed!
{
- P_KillMobj(thing, tmthing, tmthing);
+ P_KillMobj(thing, tmthing, tmthing, 0);
return false;
}
}
@@ -639,7 +655,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
// damage / explode
if (tmthing->flags & MF_ENEMY) // An actual ENEMY! (Like the deton, for example)
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ P_DamageMobj(thing, tmthing, tmthing, 1, 0);
else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player
&& (thing->player->pflags & PF_JUMPED)
&& !thing->player->powers[pw_flashing]
@@ -675,7 +691,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
P_SetThingPosition(tmthing);
}
else
- P_DamageMobj(thing, tmthing, tmthing->target, 1);
+ P_DamageMobj(thing, tmthing, tmthing->target, 1, 0);
// don't traverse any more
@@ -789,11 +805,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
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)
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ 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)
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ P_DamageMobj(thing, tmthing, tmthing, 1, 0);
}
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
{
@@ -801,11 +817,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale))
- P_DamageMobj(tmthing, thing, thing, 1);
+ 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))
- P_DamageMobj(tmthing, thing, thing, 1);
+ P_DamageMobj(tmthing, thing, thing, 1, 0);
}
if (thing->flags & MF_PUSHABLE)
@@ -818,15 +834,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing);
-
- if ((!(thing->eflags & MFE_VERTICALFLIP) && (tmthing->z <= (thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)) && (tmthing->z + tmthing->height) >= thing->z))
- || ((thing->eflags & MFE_VERTICALFLIP) && (tmthing->z + tmthing->height >= (thing->z - FixedMul(FRACUNIT, thing->scale)) && tmthing->z <= (thing->z + thing->height))))
+ else if (thing->flags & MF_SPRING)
{
- if (thing->flags & MF_SPRING)
- {
- P_DoSpring(thing, tmthing);
- tmsprung = true;
- }
+ if ( thing->z <= tmthing->z + tmthing->height
+ && tmthing->z <= thing->z + thing->height)
+ iwassprung = P_DoSpring(thing, tmthing);
}
}
@@ -839,10 +851,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super])
&& !thing->player->powers[pw_super])
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ P_DamageMobj(thing, tmthing, tmthing, 1, 0);
else if ((thing->player->powers[pw_invulnerability] || thing->player->powers[pw_super])
&& !tmthing->player->powers[pw_super])
- P_DamageMobj(tmthing, thing, thing, 1);
+ P_DamageMobj(tmthing, thing, thing, 1, 0);
}
// If players are using touch tag, seekers damage hiders.
@@ -850,9 +862,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
((thing->player->pflags & PF_TAGIT) != (tmthing->player->pflags & PF_TAGIT)))
{
if ((tmthing->player->pflags & PF_TAGIT) && !(thing->player->pflags & PF_TAGIT))
- P_DamageMobj(thing, tmthing, tmthing, 1);
+ P_DamageMobj(thing, tmthing, tmthing, 1, 0);
else if ((thing->player->pflags & PF_TAGIT) && !(tmthing->player->pflags & PF_TAGIT))
- P_DamageMobj(tmthing, thing, tmthing, 1);
+ P_DamageMobj(tmthing, thing, tmthing, 1, 0);
}
}
@@ -875,7 +887,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
// Doesn't matter what gravity player's following! Just do your stuff in YOUR direction only
if (tmthing->eflags & MFE_VERTICALFLIP
- && (tmthing->z + tmthing->height + tmthing->momz > thing->z
+ && (tmthing->z + tmthing->height + tmthing->momz < thing->z
|| tmthing->z + tmthing->height + tmthing->momz >= thing->z + thing->height))
;
else if (!(tmthing->eflags & MFE_VERTICALFLIP)
@@ -890,7 +902,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
// Objects kill you if it falls from above.
if (thing != tmthing->target)
- P_DamageMobj(thing, tmthing, tmthing->target, 10000);
+ P_DamageMobj(thing, tmthing, tmthing->target, 1, DMG_INSTAKILL);
tmthing->momz = -tmthing->momz/2; // Bounce, just for fun!
// The tmthing->target allows the pusher of the object
@@ -909,22 +921,22 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing);
-
+ else if (thing->flags & MF_SPRING)
+ {
+ if ( thing->z <= tmthing->z + tmthing->height
+ && tmthing->z <= thing->z + thing->height)
+ iwassprung = P_DoSpring(thing, tmthing);
+ }
// Are you touching the side of the object you're interacting with?
- if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
+ else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{
- if (thing->flags & MF_SPRING)
- {
- P_DoSpring(thing, tmthing);
- tmsprung = true;
- }
- else if (thing->flags & MF_MONITOR
+ if (thing->flags & MF_MONITOR
&& tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
{
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
- P_DamageMobj(thing, tmthing, tmthing, 1); // break the monitor
+ P_DamageMobj(thing, tmthing, tmthing, 1, 0); // break the monitor
// Going down? Then bounce back up.
if ((P_MobjWasRemoved(thing) // Monitor was removed
|| !thing->health) // or otherwise popped
@@ -932,17 +944,17 @@ static boolean PIT_CheckThing(mobj_t *thing)
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
return false;
}
-/*
- else if ((thing->flags & (MF_SOLID|MF_NOCLIP|MF_PUSHABLE)) == MF_SOLID)
- return false; // this fixes both monitors and non-pushable solids being walked through on bobbing FOFs... for now!
-*/
}
}
-
+ if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE))
+ {
+ 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
+ }
// 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
- if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)
+ else if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)
&& !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
;
// z checking at last
@@ -962,6 +974,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z + thing->height > tmfloorz)
{
tmfloorz = thing->z + thing->height;
+#ifdef ESLOPE
+ tmfloorslope = NULL;
+#endif
}
return true;
}
@@ -980,6 +995,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
{
tmceilingz = topz;
+#ifdef ESLOPE
+ tmceilingslope = NULL;
+#endif
tmfloorthing = thing; // thing we may stand on
}
}
@@ -993,6 +1011,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z < tmceilingz)
{
tmceilingz = thing->z;
+#ifdef ESLOPE
+ tmceilingslope = NULL;
+#endif
}
return true;
}
@@ -1010,6 +1031,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz > tmfloorz && tmthing->z >= thing->z)
{
tmfloorz = topz;
+#ifdef ESLOPE
+ tmfloorslope = NULL;
+#endif
tmfloorthing = thing; // thing we may stand on
}
}
@@ -1132,11 +1156,13 @@ static boolean PIT_CheckLine(line_t *ld)
{
tmceilingz = opentop;
ceilingline = ld;
+ tmceilingslope = opentopslope;
}
if (openbottom > tmfloorz)
{
tmfloorz = openbottom;
+ tmfloorslope = openbottomslope;
}
if (highceiling > tmdrpoffceilz)
@@ -1213,8 +1239,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
// that contains the point.
// Any contacted lines the step closer together
// will adjust them.
- tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
- tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
+ tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight;
+ tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
+#ifdef ESLOPE
+ tmfloorslope = newsubsec->sector->f_slope;
+ tmceilingslope = newsubsec->sector->c_slope;
+#endif
// Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors)
@@ -1225,35 +1255,48 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
+
if (!(rover->flags & FF_EXISTS))
continue;
+ topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
+ bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
+
if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
{
// If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
- fixed_t minspeed = FixedMul(thing->info->height/12, thing->scale);
- if (thing->z < *rover->topheight && *rover->bottomheight < thingtop
+ fixed_t minspeed = FixedMul(thing->info->height/9, thing->scale);
+ if (thing->z < topheight && bottomheight < thingtop
&& abs(thing->momz) < minspeed)
{
// Oh no! The object is stick in between the surface of the goo and sinklevel! help them out!
- if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel
+ if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel
&& thing->momz >= 0 && thing->momz < (minspeed>>2))
thing->momz += minspeed>>2;
- else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel
+ else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel
&& thing->momz <= 0 && thing->momz > -(minspeed>>2))
thing->momz -= minspeed>>2;
// Land on the top or the bottom, depending on gravity flip.
- if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0)
+ if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0)
{
- if (tmfloorz < *rover->topheight - sinklevel)
- tmfloorz = *rover->topheight - sinklevel;
+ if (tmfloorz < topheight - sinklevel) {
+ tmfloorz = topheight - sinklevel;
+#ifdef ESLOPE
+ tmfloorslope = *rover->t_slope;
+#endif
+ }
}
- else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0)
+ else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
{
- if (tmceilingz > *rover->bottomheight + sinklevel)
- tmceilingz = *rover->bottomheight + sinklevel;
+ if (tmceilingz > bottomheight + sinklevel) {
+ tmceilingz = bottomheight + sinklevel;
+#ifdef ESLOPE
+ tmceilingslope = *rover->b_slope;
+#endif
+ }
}
}
continue;
@@ -1270,30 +1313,40 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (rover->flags & FF_QUICKSAND)
{
- if (thing->z < *rover->topheight && *rover->bottomheight < thingtop)
+ if (thing->z < topheight && bottomheight < thingtop)
{
- if (tmfloorz < thing->z)
+ if (tmfloorz < thing->z) {
tmfloorz = thing->z;
+#ifdef ESLOPE
+ tmfloorslope = NULL;
+#endif
+ }
}
// Quicksand blocks never change heights otherwise.
continue;
}
- delta1 = thing->z - (*rover->bottomheight
- + ((*rover->topheight - *rover->bottomheight)/2));
- delta2 = thingtop - (*rover->bottomheight
- + ((*rover->topheight - *rover->bottomheight)/2));
+ delta1 = thing->z - (bottomheight
+ + ((topheight - bottomheight)/2));
+ delta2 = thingtop - (bottomheight
+ + ((topheight - bottomheight)/2));
- if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)
+ if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
{
- tmfloorz = tmdropoffz = *rover->topheight;
+ tmfloorz = tmdropoffz = topheight;
+#ifdef ESLOPE
+ tmfloorslope = *rover->t_slope;
+#endif
}
- if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
+ if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
{
- tmceilingz = tmdrpoffceilz = *rover->bottomheight;
+ tmceilingz = tmdrpoffceilz = bottomheight;
+#ifdef ESLOPE
+ tmceilingslope = *rover->b_slope;
+#endif
}
}
}
@@ -1308,6 +1361,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{
@@ -1364,11 +1419,19 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
- if (polytop > tmfloorz && abs(delta1) < abs(delta2))
+ if (polytop > tmfloorz && abs(delta1) < abs(delta2)) {
tmfloorz = tmdropoffz = polytop;
+#ifdef ESLOPE
+ tmfloorslope = NULL;
+#endif
+ }
- if (polybottom < tmceilingz && abs(delta1) >= abs(delta2))
+ if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
tmceilingz = tmdrpoffceilz = polybottom;
+#ifdef ESLOPE
+ tmceilingslope = NULL;
+#endif
+ }
}
plink = (polymaplink_t *)(plink->link.next);
}
@@ -1470,8 +1533,9 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// that contains the point.
// Any contacted lines the step closer together
// will adjust them.
- tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
- tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
+ tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL);
+
+ tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL);
// Cameras use the heightsec's heights rather then the actual sector heights.
// If you can see through it, why not move the camera through it too?
@@ -1497,20 +1561,24 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
- delta1 = thiscam->z - (*rover->bottomheight
- + ((*rover->topheight - *rover->bottomheight)/2));
- delta2 = thingtop - (*rover->bottomheight
- + ((*rover->topheight - *rover->bottomheight)/2));
- if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2))
+ topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL);
+ bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL);
+
+ delta1 = thiscam->z - (bottomheight
+ + ((topheight - bottomheight)/2));
+ delta2 = thingtop - (bottomheight
+ + ((topheight - bottomheight)/2));
+ if (topheight > tmfloorz && abs(delta1) < abs(delta2))
{
- tmfloorz = tmdropoffz = *rover->topheight;
+ tmfloorz = tmdropoffz = topheight;
}
- if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
+ if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
{
- tmceilingz = tmdrpoffceilz = *rover->bottomheight;
+ tmceilingz = tmdrpoffceilz = bottomheight;
}
}
}
@@ -1525,6 +1593,8 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{
@@ -1703,8 +1773,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
}
else
{
- tmfloorz = thiscam->subsector->sector->floorheight;
- tmceilingz = thiscam->subsector->sector->ceilingheight;
+ tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL);
+ tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL);
}
// the move is ok,
@@ -1766,11 +1836,14 @@ boolean PIT_PushableMoved(mobj_t *thing)
boolean oldfltok = floatok;
fixed_t oldflrz = tmfloorz;
fixed_t oldceilz = tmceilingz;
- boolean oldsprung = tmsprung;
mobj_t *oldflrthing = tmfloorthing;
mobj_t *oldthing = tmthing;
line_t *oldceilline = ceilingline;
line_t *oldblockline = blockingline;
+#ifdef ESLOPE
+ pslope_t *oldfslope = tmfloorslope;
+ pslope_t *oldcslope = tmceilingslope;
+#endif
// Move the player
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
@@ -1779,11 +1852,14 @@ boolean PIT_PushableMoved(mobj_t *thing)
floatok = oldfltok;
tmfloorz = oldflrz;
tmceilingz = oldceilz;
- tmsprung = oldsprung;
tmfloorthing = oldflrthing;
P_SetTarget(&tmthing, oldthing);
ceilingline = oldceilline;
blockingline = oldblockline;
+#ifdef ESLOPE
+ tmfloorslope = oldfslope;
+ tmceilingslope = oldcslope;
+#endif
thing->momz = stand->momz;
}
else
@@ -1805,6 +1881,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t tryy = thing->y;
fixed_t radius = thing->radius;
fixed_t thingtop = thing->z + thing->height;
+#ifdef ESLOPE
+ fixed_t startingonground = P_IsObjectOnGround(thing);
+#endif
floatok = false;
if (radius < MAXRADIUS/2)
@@ -1850,7 +1929,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
// Don't 'step up' while springing,
// Only step up "if needed".
- if (thing->state == &states[S_PLAY_SPRING]
+ if (thing->player->panim == PA_JUMP
&& P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale))
maxstep = 0;
}
@@ -1893,13 +1972,23 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
{
- thing->z = tmceilingz - thing->height;
+ thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
+ thing->eflags |= MFE_JUSTSTEPPEDDOWN;
+ }
+ else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
+ {
+ thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{
- thing->z = tmfloorz;
+ thing->z = thing->floorz = tmfloorz;
+ thing->eflags |= MFE_JUSTSTEPPEDDOWN;
+ }
+ else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
+ {
+ thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
@@ -1954,6 +2043,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
xh = (unsigned)(thing->x + MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT;
xl = (unsigned)(thing->x - MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
stand = thing;
standx = x;
standy = y;
@@ -1968,6 +2059,25 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->floorz = tmfloorz;
thing->ceilingz = tmceilingz;
+
+#ifdef ESLOPE
+ // Assign thing's standingslope if needed
+ if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
+ if (!startingonground && tmfloorslope)
+ P_HandleSlopeLanding(thing, tmfloorslope);
+
+ if (thing->momz <= 0)
+ thing->standingslope = tmfloorslope;
+ }
+ else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
+ if (!startingonground && tmceilingslope)
+ P_HandleSlopeLanding(thing, tmceilingslope);
+
+ if (thing->momz >= 0)
+ thing->standingslope = tmceilingslope;
+ }
+#endif
+
thing->x = x;
thing->y = y;
@@ -1983,6 +2093,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
{
fixed_t tryx, tryy;
+
tryx = thing->x;
tryy = thing->y;
do {
@@ -2047,6 +2158,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
//
static boolean P_ThingHeightClip(mobj_t *thing)
{
+ boolean floormoved;
fixed_t oldfloorz = thing->floorz;
boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz);
@@ -2058,6 +2170,9 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (P_MobjWasRemoved(thing))
return true;
+ floormoved = (thing->eflags & MFE_VERTICALFLIP && tmceilingz != thing->ceilingz)
+ || (!(thing->eflags & MFE_VERTICALFLIP) && tmfloorz != thing->floorz);
+
thing->floorz = tmfloorz;
thing->ceilingz = tmceilingz;
@@ -2066,20 +2181,13 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (tmfloorz > oldfloorz+thing->height)
return true;
- if (/*!tmfloorthing && */onfloor && !(thing->flags & MF_NOGRAVITY))
+ if (onfloor && !(thing->flags & MF_NOGRAVITY) && floormoved)
{
if (thing->eflags & MFE_VERTICALFLIP)
thing->pmomz = thing->ceilingz - (thing->z + thing->height);
else
thing->pmomz = thing->floorz - thing->z;
-
- if (thing->player)
- {
- if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer])
- camera2.z += thing->pmomz;
- else if (camera.chase && thing->player == &players[displayplayer])
- camera.z += thing->pmomz;
- }
+ thing->eflags |= MFE_APPLYPMOMZ;
if (thing->eflags & MFE_VERTICALFLIP)
thing->z = thing->ceilingz - thing->height;
@@ -2308,15 +2416,25 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{
fixed_t platx, platy;
subsector_t *glidesector;
+ fixed_t floorz, ceilingz;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
+#ifdef ESLOPE
+ floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight;
+ ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight;
+#else
+ floorz = glidesector->sector->floorheight;
+ ceilingz = glidesector->sector->ceilingheight;
+#endif
+
if (glidesector->sector != player->mo->subsector->sector)
{
boolean floorclimb = false;
+ fixed_t topheight, bottomheight;
if (glidesector->sector->ffloors)
{
@@ -2326,34 +2444,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
continue;
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
+#endif
+
floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
- if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight))
+ if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
{
floorclimb = true;
}
- if (*rover->topheight < player->mo->z) // Waaaay below the ledge.
+ if (topheight < player->mo->z) // Waaaay below the ledge.
{
floorclimb = false;
}
- if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
+ if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
else
{
- if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight))
+ if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
{
floorclimb = true;
}
- if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
+ if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
{
floorclimb = false;
}
- if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
+ if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
@@ -2366,30 +2494,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
- if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height)
- && ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight))
+ if ((floorz <= player->mo->z + player->mo->height)
+ && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
floorclimb = true;
- if ((glidesector->sector->floorheight > player->mo->z)
+ if ((floorz > player->mo->z)
&& glidesector->sector->floorpic == skyflatnum)
return false;
- if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight)
- || (player->mo->z + player->mo->height <= glidesector->sector->floorheight))
+ if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
+ || (player->mo->z + player->mo->height <= floorz))
floorclimb = true;
}
else
{
- if ((glidesector->sector->ceilingheight >= player->mo->z)
- && ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight))
+ if ((ceilingz >= player->mo->z)
+ && ((player->mo->z - player->mo->momz) >= ceilingz))
floorclimb = true;
- if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height)
+ if ((ceilingz < player->mo->z+player->mo->height)
&& glidesector->sector->ceilingpic == skyflatnum)
return false;
- if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight)
- || (player->mo->z >= glidesector->sector->ceilingheight))
+ if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
+ || (player->mo->z >= ceilingz))
floorclimb = true;
}
@@ -2461,6 +2589,7 @@ isblocking:
line_t *checkline = li;
sector_t *checksector;
ffloor_t *rover;
+ fixed_t topheight, bottomheight;
boolean fofline = false;
INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li);
@@ -2476,13 +2605,23 @@ isblocking:
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
- if (*rover->topheight < slidemo->z)
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
+#endif
+
+ if (topheight < slidemo->z)
continue;
- if (*rover->bottomheight > slidemo->z + slidemo->height)
+ if (bottomheight > slidemo->z + slidemo->height)
continue;
- // Got this far, so I guess it's climbable.
+ // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this?
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = li-checksector->lines[0];
@@ -3018,7 +3157,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
if (P_CheckSight(thing, bombspot))
{ // must be in direct path
- P_DamageMobj(thing, bombspot, bombsource, 1); // Tails 01-11-2001
+ P_DamageMobj(thing, bombspot, bombsource, 1, 0); // Tails 01-11-2001
}
return true;
@@ -3040,6 +3179,8 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist)
xh = (unsigned)(spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT;
xl = (unsigned)(spot->x - dist - bmaporgx)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
bombspot = spot;
bombsource = source;
bombdamage = FixedMul(damagedist, spot->scale);
@@ -3100,6 +3241,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE))
{
ffloor_t *rover;
+ fixed_t topheight, bottomheight;
fixed_t delta1, delta2;
INT32 thingtop = thing->z + thing->height;
@@ -3109,9 +3251,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|| ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS))
continue;
- delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2;
- delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2;
- if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+/*#ifdef ESLOPE
+ if (rover->t_slope)
+ topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
+ if (rover->b_slope)
+ bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);
+#endif*/
+
+ delta1 = thing->z - (bottomheight + topheight)/2;
+ delta2 = thingtop - (bottomheight + topheight)/2;
+ if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
{
if (thing->flags & MF_PUSHABLE)
{
@@ -3151,22 +3303,15 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
{
// Crush the object
if (netgame && thing->player && thing->player->spectator)
- P_DamageMobj(thing, NULL, NULL, 42000); // Respawn crushed spectators
+ P_DamageMobj(thing, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
- {
- if (!killer)
- {
- //Nobody is responsible for crushing the object, so give a generic crush message
- killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL);
- killer->threshold = 44; // Special flag for crushing
- }
- P_DamageMobj(thing, killer, killer, 10000);
- }
+ P_DamageMobj(thing, killer, killer, 1, DMG_CRUSHED);
+ return true;
}
}
if (realcrush && crushchange)
- P_DamageMobj(thing, NULL, NULL, 1);
+ P_DamageMobj(thing, NULL, NULL, 1, 0);
// keep checking (crush other things)
return true;
@@ -3661,6 +3806,8 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockLinesIterator(bx, by, PIT_GetSectors);
@@ -3738,6 +3885,8 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
yl = (unsigned)(preciptmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(preciptmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockLinesIterator(bx, by, PIT_GetPrecipSectors);
@@ -3785,7 +3934,7 @@ void P_MapEnd(void)
}
// P_FloorzAtPos
-// Returns the floorz of the XYZ position
+// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too
// Tails 05-26-2003
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{
@@ -3800,15 +3949,26 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
for (rover = sec->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, x, y);
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, x, y);
+#endif
+
if (rover->flags & FF_QUICKSAND)
{
- if (z < *rover->topheight && *rover->bottomheight < thingtop)
+ if (z < topheight && bottomheight < thingtop)
{
if (floorz < z)
floorz = z;
@@ -3816,10 +3976,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
continue;
}
- delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
- delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
- if (*rover->topheight > floorz && abs(delta1) < abs(delta2))
- floorz = *rover->topheight;
+ delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
+ delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
+ if (topheight > floorz && abs(delta1) < abs(delta2))
+ floorz = topheight;
}
}
diff --git a/src/p_maputl.c b/src/p_maputl.c
index 48dd54e8d..8f349a2a9 100644
--- a/src/p_maputl.c
+++ b/src/p_maputl.c
@@ -17,8 +17,10 @@
#include "p_local.h"
#include "r_main.h"
+#include "r_data.h"
#include "p_maputl.h"
#include "p_polyobj.h"
+#include "p_slopes.h"
#include "z_zone.h"
//
@@ -321,6 +323,9 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
// OPTIMIZE: keep this precalculated
//
fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
+#ifdef ESLOPE
+pslope_t *opentopslope, *openbottomslope;
+#endif
// P_CameraLineOpening
// P_LineOpening, but for camera
@@ -347,31 +352,56 @@ void P_CameraLineOpening(line_t *linedef)
{
frontfloor = sectors[front->camsec].floorheight;
frontceiling = sectors[front->camsec].ceilingheight;
+#ifdef ESLOPE
+ if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
+ frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y);
+ if (sectors[front->camsec].c_slope)
+ frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y);
+#endif
+
}
else if (front->heightsec >= 0)
{
frontfloor = sectors[front->heightsec].floorheight;
frontceiling = sectors[front->heightsec].ceilingheight;
+#ifdef ESLOPE
+ if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
+ frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y);
+ if (sectors[front->heightsec].c_slope)
+ frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y);
+#endif
}
else
{
- frontfloor = front->floorheight;
- frontceiling = front->ceilingheight;
+ frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef);
+ frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
}
if (back->camsec >= 0)
{
backfloor = sectors[back->camsec].floorheight;
backceiling = sectors[back->camsec].ceilingheight;
+#ifdef ESLOPE
+ if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
+ frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y);
+ if (sectors[back->camsec].c_slope)
+ frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y);
+#endif
}
else if (back->heightsec >= 0)
{
backfloor = sectors[back->heightsec].floorheight;
backceiling = sectors[back->heightsec].ceilingheight;
+#ifdef ESLOPE
+ if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
+ frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y);
+ if (sectors[back->heightsec].c_slope)
+ frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y);
+#endif
}
else
{
- backfloor = back->floorheight;
- backceiling = back->ceilingheight;
+ backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef);
+ backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef);
}
{
@@ -413,40 +443,48 @@ void P_CameraLineOpening(line_t *linedef)
if (front->ffloors)
for (rover = front->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
- delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
- delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
- if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
- lowestceiling = *rover->bottomheight;
- else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
- highestceiling = *rover->bottomheight;
+ topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
+ bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
- if (*rover->topheight > highestfloor && delta1 < delta2)
- highestfloor = *rover->topheight;
- else if (*rover->topheight > lowestfloor && delta1 < delta2)
- lowestfloor = *rover->topheight;
+ delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
+ delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
+ if (bottomheight < lowestceiling && delta1 >= delta2)
+ lowestceiling = bottomheight;
+ else if (bottomheight < highestceiling && delta1 >= delta2)
+ highestceiling = bottomheight;
+
+ if (topheight > highestfloor && delta1 < delta2)
+ highestfloor = topheight;
+ else if (topheight > lowestfloor && delta1 < delta2)
+ lowestfloor = topheight;
}
// Check for backsectors fake floors
if (back->ffloors)
for (rover = back->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
- delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
- delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
- if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
- lowestceiling = *rover->bottomheight;
- else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
- highestceiling = *rover->bottomheight;
+ topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
+ bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
- if (*rover->topheight > highestfloor && delta1 < delta2)
- highestfloor = *rover->topheight;
- else if (*rover->topheight > lowestfloor && delta1 < delta2)
- lowestfloor = *rover->topheight;
+ delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
+ delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
+ if (bottomheight < lowestceiling && delta1 >= delta2)
+ lowestceiling = bottomheight;
+ else if (bottomheight < highestceiling && delta1 >= delta2)
+ highestceiling = bottomheight;
+
+ if (topheight > highestfloor && delta1 < delta2)
+ highestfloor = topheight;
+ else if (topheight > lowestfloor && delta1 < delta2)
+ lowestfloor = topheight;
}
if (highestceiling < highceiling)
@@ -494,32 +532,91 @@ void P_LineOpening(line_t *linedef)
I_Assert(front != NULL);
I_Assert(back != NULL);
- if (front->ceilingheight < back->ceilingheight)
- {
- opentop = front->ceilingheight;
- highceiling = back->ceilingheight;
- }
- else
- {
- opentop = back->ceilingheight;
- highceiling = front->ceilingheight;
- }
+ { // Set open and high/low values here
+ fixed_t frontheight, backheight;
- if (front->floorheight > back->floorheight)
- {
- openbottom = front->floorheight;
- lowfloor = back->floorheight;
- }
- else
- {
- openbottom = back->floorheight;
- lowfloor = front->floorheight;
+ frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef);
+ backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef);
+
+ if (frontheight < backheight)
+ {
+ opentop = frontheight;
+ highceiling = backheight;
+ opentopslope = front->c_slope;
+ }
+ else
+ {
+ opentop = backheight;
+ highceiling = frontheight;
+ opentopslope = back->c_slope;
+ }
+
+ frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef);
+ backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef);
+
+ if (frontheight > backheight)
+ {
+ openbottom = frontheight;
+ lowfloor = backheight;
+ openbottomslope = front->f_slope;
+ }
+ else
+ {
+ openbottom = backheight;
+ lowfloor = frontheight;
+ openbottomslope = back->f_slope;
+ }
}
if (tmthing)
{
fixed_t thingtop = tmthing->z + tmthing->height;
+ // Check for collision with front side's midtexture if Effect 4 is set
+ if (linedef->flags & ML_EFFECT4) {
+ side_t *side = &sides[linedef->sidenum[0]];
+ fixed_t textop, texbottom, texheight;
+ fixed_t texmid, delta1, delta2;
+
+ // Get the midtexture's height
+ texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS;
+
+ // Set texbottom and textop to the Z coordinates of the texture's boundaries
+#ifdef POLYOBJECTS
+ if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
+ if (linedef->flags & ML_DONTPEGBOTTOM) {
+ texbottom = back->floorheight + side->rowoffset;
+ textop = texbottom + texheight*(side->repeatcnt+1);
+ } else {
+ textop = back->ceilingheight - side->rowoffset;
+ texbottom = textop - texheight*(side->repeatcnt+1);
+ }
+ } else
+#endif
+ {
+ if (linedef->flags & ML_DONTPEGBOTTOM) {
+ texbottom = openbottom + side->rowoffset;
+ textop = texbottom + texheight*(side->repeatcnt+1);
+ } else {
+ textop = opentop - side->rowoffset;
+ texbottom = textop - texheight*(side->repeatcnt+1);
+ }
+ }
+
+ texmid = texbottom+(textop-texbottom)/2;
+
+ delta1 = abs(tmthing->z - texmid);
+ delta2 = abs(thingtop - texmid);
+
+ if (delta1 > delta2) { // Below
+ if (opentop > texbottom)
+ opentop = texbottom;
+ } else { // Above
+ if (openbottom < textop)
+ openbottom = textop;
+ }
+ }
+
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors
#ifdef POLYOBJECTS
@@ -534,10 +631,15 @@ void P_LineOpening(line_t *linedef)
fixed_t highestfloor = openbottom;
fixed_t lowestfloor = lowfloor;
fixed_t delta1, delta2;
+#ifdef ESLOPE
+ pslope_t *ceilingslope = opentopslope;
+ pslope_t *floorslope = openbottomslope;
+#endif
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -547,29 +649,41 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue;
- delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
- delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
+ topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef);
+ bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef);
+
+ delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
+ delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
- if (*rover->bottomheight < lowestceiling)
- lowestceiling = *rover->bottomheight;
- else if (*rover->bottomheight < highestceiling)
- highestceiling = *rover->bottomheight;
+ if (bottomheight < lowestceiling) {
+ lowestceiling = bottomheight;
+#ifdef ESLOPE
+ ceilingslope = *rover->b_slope;
+#endif
+ }
+ else if (bottomheight < highestceiling)
+ highestceiling = bottomheight;
}
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{
- if (*rover->topheight > highestfloor)
- highestfloor = *rover->topheight;
- else if (*rover->topheight > lowestfloor)
- lowestfloor = *rover->topheight;
+ if (topheight > highestfloor) {
+ highestfloor = topheight;
+#ifdef ESLOPE
+ floorslope = *rover->t_slope;
+#endif
+ }
+ else if (topheight > lowestfloor)
+ lowestfloor = topheight;
}
}
// Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -579,23 +693,34 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue;
- delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
- delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
+ topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef);
+ bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef);
+
+ delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
+ delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
- if (*rover->bottomheight < lowestceiling)
- lowestceiling = *rover->bottomheight;
- else if (*rover->bottomheight < highestceiling)
- highestceiling = *rover->bottomheight;
+ if (bottomheight < lowestceiling) {
+ lowestceiling = bottomheight;
+#ifdef ESLOPE
+ ceilingslope = *rover->b_slope;
+#endif
+ }
+ else if (bottomheight < highestceiling)
+ highestceiling = bottomheight;
}
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{
- if (*rover->topheight > highestfloor)
- highestfloor = *rover->topheight;
- else if (*rover->topheight > lowestfloor)
- lowestfloor = *rover->topheight;
+ if (topheight > highestfloor) {
+ highestfloor = topheight;
+#ifdef ESLOPE
+ floorslope = *rover->t_slope;
+#endif
+ }
+ else if (topheight > lowestfloor)
+ lowestfloor = topheight;
}
}
@@ -607,13 +732,21 @@ void P_LineOpening(line_t *linedef)
delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
- if (polysec->floorheight < lowestceiling && delta1 >= delta2)
+ if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
lowestceiling = polysec->floorheight;
+#ifdef ESLOPE
+ ceilingslope = NULL;
+#endif
+ }
else if (polysec->floorheight < highestceiling && delta1 >= delta2)
highestceiling = polysec->floorheight;
- if (polysec->ceilingheight > highestfloor && delta1 < delta2)
+ if (polysec->ceilingheight > highestfloor && delta1 < delta2) {
highestfloor = polysec->ceilingheight;
+#ifdef ESLOPE
+ floorslope = NULL;
+#endif
+ }
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
lowestfloor = polysec->ceilingheight;
}
@@ -621,11 +754,19 @@ void P_LineOpening(line_t *linedef)
if (highestceiling < highceiling)
highceiling = highestceiling;
- if (highestfloor > openbottom)
+ if (highestfloor > openbottom) {
openbottom = highestfloor;
+#ifdef ESLOPE
+ openbottomslope = floorslope;
+#endif
+ }
- if (lowestceiling < opentop)
+ if (lowestceiling < opentop) {
opentop = lowestceiling;
+#ifdef ESLOPE
+ opentopslope = ceilingslope;
+#endif
+ }
if (lowestfloor > lowfloor)
lowfloor = lowestfloor;
@@ -723,6 +864,7 @@ void P_SetThingPosition(mobj_t *thing)
{ // link into subsector
subsector_t *ss;
sector_t *oldsec = NULL;
+ fixed_t tfloorz, tceilz;
I_Assert(thing != NULL);
I_Assert(!P_MobjWasRemoved(thing));
@@ -792,12 +934,15 @@ void P_SetThingPosition(mobj_t *thing)
// sector's floor is the same height.
if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector)
{
+ tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL);
+ tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL);
+
if (thing->eflags & MFE_VERTICALFLIP)
{
- if (thing->z + thing->height >= thing->subsector->sector->ceilingheight)
+ if (thing->z + thing->height >= tceilz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
- else if (thing->z <= thing->subsector->sector->floorheight)
+ else if (thing->z <= tfloorz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
diff --git a/src/p_maputl.h b/src/p_maputl.h
index 66f7db2db..7471899cc 100644
--- a/src/p_maputl.h
+++ b/src/p_maputl.h
@@ -55,6 +55,9 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y);
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
+#ifdef ESLOPE
+extern pslope_t *opentopslope, *openbottomslope;
+#endif
void P_LineOpening(line_t *plinedef);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index cac4bc24b..915c742e8 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -31,6 +31,9 @@
#include "i_video.h"
#include "lua_hook.h"
#include "b_bot.h"
+#ifdef ESLOPE
+#include "p_slopes.h"
+#endif
// protos.
static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}};
@@ -141,45 +144,30 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
switch (state)
{
case S_PLAY_STND:
- case S_PLAY_TAP1:
- case S_PLAY_TAP2:
- case S_PLAY_GASP:
- P_SetPlayerMobjState(mobj, S_PLAY_SUPERSTAND);
- return true;
- case S_PLAY_FALL1:
- case S_PLAY_SPRING:
- case S_PLAY_RUN1:
- case S_PLAY_RUN2:
- case S_PLAY_RUN3:
- case S_PLAY_RUN4:
- P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK1);
- return true;
- case S_PLAY_FALL2:
- case S_PLAY_RUN5:
- case S_PLAY_RUN6:
- case S_PLAY_RUN7:
- case S_PLAY_RUN8:
- P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK2);
- return true;
- case S_PLAY_SPD1:
- case S_PLAY_SPD2:
- P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY1);
- return true;
- case S_PLAY_SPD3:
- case S_PLAY_SPD4:
- P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY2);
- return true;
- case S_PLAY_TEETER1:
- case S_PLAY_TEETER2:
- P_SetPlayerMobjState(mobj, S_PLAY_SUPERTEETER);
- return true;
- case S_PLAY_ATK1:
- case S_PLAY_ATK2:
- case S_PLAY_ATK3:
- case S_PLAY_ATK4:
+ 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_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;
- break;
+ return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_SPIN);
+ case S_PLAY_GASP:
+ return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_GASP);
+ case S_PLAY_JUMP:
+ return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_JUMP);
+ 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;
}
@@ -194,23 +182,56 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
// Set animation state
// The pflags version of this was just as convoluted.
- if ((state >= S_PLAY_STND && state <= S_PLAY_TAP2) || (state >= S_PLAY_TEETER1 && state <= S_PLAY_TEETER2) || state == S_PLAY_CARRY
- || state == S_PLAY_SUPERSTAND || state == S_PLAY_SUPERTEETER)
+ switch(state)
+ {
+ case S_PLAY_STND:
+ case S_PLAY_WAIT:
+ case S_PLAY_SUPER_STND:
player->panim = PA_IDLE;
- else if ((state >= S_PLAY_RUN1 && state <= S_PLAY_RUN8)
- || (state >= S_PLAY_SUPERWALK1 && state <= S_PLAY_SUPERWALK2))
+ 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:
player->panim = PA_WALK;
- else if ((state >= S_PLAY_SPD1 && state <= S_PLAY_SPD4)
- || (state >= S_PLAY_SUPERFLY1 && state <= S_PLAY_SUPERFLY2))
+ break;
+ case S_PLAY_RUN:
+ case S_PLAY_SUPER_RUN:
player->panim = PA_RUN;
- else if (state >= S_PLAY_ATK1 && state <= S_PLAY_ATK4)
+ break;
+ case S_PLAY_PAIN:
+ case S_PLAY_SUPER_PAIN:
+ case S_PLAY_SUPER_STUN:
+ player->panim = PA_PAIN;
+ break;
+ case S_PLAY_SPIN:
+ case S_PLAY_DASH:
+ case S_PLAY_SUPER_SPIN:
player->panim = PA_ROLL;
- else if (state >= S_PLAY_FALL1 && state <= S_PLAY_FALL2)
+ break;
+ case S_PLAY_JUMP:
+ case S_PLAY_SUPER_JUMP:
+ player->panim = PA_JUMP;
+ break;
+ case S_PLAY_FALL:
+ case S_PLAY_SUPER_FALL:
player->panim = PA_FALL;
- else if (state >= S_PLAY_ABL1 && state <= S_PLAY_ABL2)
+ break;
+ case S_PLAY_FLY:
+ case S_PLAY_GLIDE:
player->panim = PA_ABILITY;
- else
+ break;
+ case S_PLAY_RIDE:
+ case S_PLAY_SUPER_RIDE:
+ player->panim = PA_RIDE;
+ break;
+ default:
player->panim = PA_ETC;
+ break;
+ }
if (recursion++) // if recursion detected,
memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table
@@ -274,8 +295,131 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
}
}
- mobj->sprite = st->sprite;
- mobj->frame = st->frame;
+ // Player animations
+ if (st->sprite == SPR_PLAY)
+ {
+ boolean noalt = false;
+ UINT8 spr2 = st->frame & FF_FRAMEMASK;
+ UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
+
+ while (((skin_t *)mobj->skin)->sprites[spr2].numframes <= 0
+ && spr2 != SPR2_STND)
+ {
+ switch(spr2)
+ {
+ case SPR2_RUN:
+ spr2 = SPR2_WALK;
+ break;
+ case SPR2_DRWN:
+ spr2 = SPR2_DEAD;
+ break;
+ case SPR2_DASH:
+ spr2 = SPR2_SPIN;
+ break;
+ case SPR2_GASP:
+ spr2 = SPR2_JUMP;
+ break;
+ case SPR2_JUMP:
+ spr2 = SPR2_FALL;
+ break;
+ case SPR2_FALL:
+ spr2 = SPR2_WALK;
+ break;
+ case SPR2_RIDE:
+ spr2 = SPR2_FALL;
+ break;
+
+ case SPR2_FLY:
+ spr2 = SPR2_JUMP;
+ break;
+ case SPR2_TIRE:
+ spr2 = SPR2_FLY;
+ break;
+
+ case SPR2_GLID:
+ spr2 = SPR2_FLY;
+ break;
+ case SPR2_CLMB:
+ spr2 = SPR2_WALK;
+ break;
+ case SPR2_CLNG:
+ spr2 = SPR2_CLMB;
+ break;
+
+ case SPR2_SIGN:
+ case SPR2_LIFE:
+ noalt = true;
+ break;
+
+ // Super sprites fallback to regular sprites
+ case SPR2_SWLK:
+ spr2 = SPR2_WALK;
+ break;
+ case SPR2_SRUN:
+ spr2 = SPR2_RUN;
+ break;
+ case SPR2_SPAN:
+ spr2 = SPR2_PAIN;
+ break;
+ case SPR2_SMSL:
+ 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 = SPR2_JUMP;
+ 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;
+
+ // Dunno? Just go to standing then.
+ default:
+ spr2 = SPR2_STND;
+ break;
+ }
+ if (noalt)
+ break;
+ }
+
+ if (mobj->sprite != SPR_PLAY)
+ {
+ mobj->sprite = SPR_PLAY;
+ frame = 0;
+ }
+ else if (mobj->sprite2 != spr2)
+ frame = 0;
+
+ mobj->sprite2 = spr2;
+ if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes)
+ frame = 0;
+ mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
+ }
+ // Regular sprites
+ else
+ {
+ mobj->sprite = st->sprite;
+ mobj->frame = st->frame;
+ }
// Modified handling.
// Call action functions when the state is set
@@ -341,8 +485,30 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
st = &states[state];
mobj->state = st;
mobj->tics = st->tics;
- mobj->sprite = st->sprite;
- mobj->frame = st->frame;
+
+ // Player animations
+ if (st->sprite == SPR_PLAY)
+ {
+ UINT8 spr2 = st->frame & FF_FRAMEMASK;
+ UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
+ if (mobj->sprite != SPR_PLAY)
+ {
+ mobj->sprite = SPR_PLAY;
+ frame = 0;
+ }
+ else if (mobj->sprite2 != spr2)
+ frame = 0;
+ mobj->sprite2 = spr2;
+ if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes)
+ frame = 0;
+ mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
+ }
+ // Regular sprites
+ else
+ {
+ mobj->sprite = st->sprite;
+ mobj->frame = st->frame;
+ }
// Modified handling.
// Call action functions when the state is set
@@ -674,7 +840,7 @@ void P_ExplodeMissile(mobj_t *mo)
S_StartSound(explodemo, sfx_cybdth);
// Hack: Release an animal.
- P_DamageMobj(mo, NULL, NULL, 10000);
+ P_DamageMobj(mo, NULL, NULL, 1, DMG_INSTAKILL);
}
mo->flags &= ~MF_MISSILE;
@@ -693,6 +859,7 @@ void P_ExplodeMissile(mobj_t *mo)
// Returns TRUE if mobj is inside a non-solid 3d floor.
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
return false;
@@ -700,15 +867,441 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
|| ((rover->flags & FF_BLOCKOTHERS) && !mobj->player)))
return false;
- if (mobj->z > *rover->topheight)
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y);
+#endif
+
+ if (mobj->z > topheight)
return false;
- if (mobj->z + mobj->height < *rover->bottomheight)
+ if (mobj->z + mobj->height < bottomheight)
return false;
return true;
}
+// P_GetFloorZ (and its ceiling counterpart)
+// Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y]
+// If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line
+// Supply boundsec ONLY when checking for specials! It should be the "in-level" sector, and sector the control sector (if separate).
+// If set, then this function will iterate through boundsec's linedefs to find the highest contact point on the slope. Non-special-checking
+// usage will handle that later.
+static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest)
+{
+ // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
+ // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
+ // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two.
+ vertex_t v1, v2;
+ v1.x = line->v1->x;
+ v1.y = line->v1->y;
+ v2.x = line->v2->x;
+ v2.y = line->v2->y;
+
+ /*CONS_Printf("BEFORE: v1 = %f %f %f\n",
+ FIXED_TO_FLOAT(v1.x),
+ FIXED_TO_FLOAT(v1.y),
+ FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
+ );
+ CONS_Printf(" v2 = %f %f %f\n",
+ FIXED_TO_FLOAT(v2.x),
+ FIXED_TO_FLOAT(v2.y),
+ FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
+ );*/
+
+ if (abs(v1.x-x) > radius) {
+ // v1's x is out of range, so rein it in
+ fixed_t diff = abs(v1.x-x) - radius;
+
+ if (v1.x < x) { // Moving right
+ v1.x += diff;
+ v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
+ } else { // Moving left
+ v1.x -= diff;
+ v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
+ }
+ }
+
+ if (abs(v1.y-y) > radius) {
+ // v1's y is out of range, so rein it in
+ fixed_t diff = abs(v1.y-y) - radius;
+
+ if (v1.y < y) { // Moving up
+ v1.y += diff;
+ v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
+ } else { // Moving down
+ v1.y -= diff;
+ v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
+ }
+ }
+
+ if (abs(v2.x-x) > radius) {
+ // v1's x is out of range, so rein it in
+ fixed_t diff = abs(v2.x-x) - radius;
+
+ if (v2.x < x) { // Moving right
+ v2.x += diff;
+ v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
+ } else { // Moving left
+ v2.x -= diff;
+ v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
+ }
+ }
+
+ if (abs(v2.y-y) > radius) {
+ // v2's y is out of range, so rein it in
+ fixed_t diff = abs(v2.y-y) - radius;
+
+ if (v2.y < y) { // Moving up
+ v2.y += diff;
+ v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
+ } else { // Moving down
+ v2.y -= diff;
+ v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
+ }
+ }
+
+ /*CONS_Printf("AFTER: v1 = %f %f %f\n",
+ FIXED_TO_FLOAT(v1.x),
+ FIXED_TO_FLOAT(v1.y),
+ FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
+ );
+ CONS_Printf(" v2 = %f %f %f\n",
+ FIXED_TO_FLOAT(v2.x),
+ FIXED_TO_FLOAT(v2.y),
+ FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
+ );*/
+
+ // Return the higher of the two points
+ if (actuallylowest)
+ return min(
+ P_GetZAt(slope, v1.x, v1.y),
+ P_GetZAt(slope, v2.x, v2.y)
+ );
+ else
+ return max(
+ P_GetZAt(slope, v1.x, v1.y),
+ P_GetZAt(slope, v2.x, v2.y)
+ );
+}
+
+fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
+{
+ I_Assert(mobj != NULL);
+ I_Assert(sector != NULL);
+#ifdef ESLOPE
+ if (sector->f_slope) {
+ fixed_t testx, testy;
+ pslope_t *slope = sector->f_slope;
+
+ // Get the corner of the object that should be the highest on the slope
+ if (slope->d.x < 0)
+ testx = mobj->radius;
+ else
+ testx = -mobj->radius;
+
+ if (slope->d.y < 0)
+ testy = mobj->radius;
+ else
+ testy = -mobj->radius;
+
+ if ((slope->zdelta > 0) ^ !!(lowest)) {
+ testx = -testx;
+ testy = -testy;
+ }
+
+ testx += x;
+ testy += y;
+
+ // If the highest point is in the sector, then we have it easy! Just get the Z at that point
+ if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector))
+ return P_GetZAt(slope, testx, testy);
+
+ // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
+ if (perfect) {
+ size_t i;
+ line_t *ld;
+ fixed_t bbox[4];
+ fixed_t finalheight;
+
+ if (lowest)
+ finalheight = INT32_MAX;
+ else
+ finalheight = INT32_MIN;
+
+ bbox[BOXLEFT] = x-mobj->radius;
+ bbox[BOXRIGHT] = x+mobj->radius;
+ bbox[BOXTOP] = y+mobj->radius;
+ bbox[BOXBOTTOM] = y-mobj->radius;
+ for (i = 0; i < boundsec->linecount; i++) {
+ ld = boundsec->lines[i];
+
+ if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
+ || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
+ continue;
+
+ if (P_BoxOnLineSide(bbox, ld) != -1)
+ continue;
+
+ if (lowest)
+ finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
+ else
+ finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
+ }
+
+ return finalheight;
+ }
+
+ // If we're just testing for base sector location (no collision line), just go for the center's spot...
+ // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
+ if (line == NULL)
+ return P_GetZAt(slope, x, y);
+
+ return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
+ } else // Well, that makes it easy. Just get the floor height
+#endif
+ return sector->floorheight;
+}
+
+fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
+{
+ I_Assert(mobj != NULL);
+ I_Assert(sector != NULL);
+#ifdef ESLOPE
+ if (sector->c_slope) {
+ fixed_t testx, testy;
+ pslope_t *slope = sector->c_slope;
+
+ // Get the corner of the object that should be the highest on the slope
+ if (slope->d.x < 0)
+ testx = mobj->radius;
+ else
+ testx = -mobj->radius;
+
+ if (slope->d.y < 0)
+ testy = mobj->radius;
+ else
+ testy = -mobj->radius;
+
+ if ((slope->zdelta > 0) ^ !!(lowest)) {
+ testx = -testx;
+ testy = -testy;
+ }
+
+ testx += x;
+ testy += y;
+
+ // If the highest point is in the sector, then we have it easy! Just get the Z at that point
+ if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector))
+ return P_GetZAt(slope, testx, testy);
+
+ // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
+ if (perfect) {
+ size_t i;
+ line_t *ld;
+ fixed_t bbox[4];
+ fixed_t finalheight;
+
+ if (lowest)
+ finalheight = INT32_MAX;
+ else
+ finalheight = INT32_MIN;
+
+ bbox[BOXLEFT] = x-mobj->radius;
+ bbox[BOXRIGHT] = x+mobj->radius;
+ bbox[BOXTOP] = y+mobj->radius;
+ bbox[BOXBOTTOM] = y-mobj->radius;
+ for (i = 0; i < boundsec->linecount; i++) {
+ ld = boundsec->lines[i];
+
+ if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
+ || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
+ continue;
+
+ if (P_BoxOnLineSide(bbox, ld) != -1)
+ continue;
+
+ if (lowest)
+ finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
+ else
+ finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
+ }
+
+ return finalheight;
+ }
+
+ // If we're just testing for base sector location (no collision line), just go for the center's spot...
+ // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
+ if (line == NULL)
+ return P_GetZAt(slope, x, y);
+
+ return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
+ } else // Well, that makes it easy. Just get the ceiling height
+#endif
+ return sector->ceilingheight;
+}
+
+// Now do the same as all above, but for cameras because apparently cameras are special?
+fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
+{
+ I_Assert(mobj != NULL);
+ I_Assert(sector != NULL);
+#ifdef ESLOPE
+ if (sector->f_slope) {
+ fixed_t testx, testy;
+ pslope_t *slope = sector->f_slope;
+
+ // Get the corner of the object that should be the highest on the slope
+ if (slope->d.x < 0)
+ testx = mobj->radius;
+ else
+ testx = -mobj->radius;
+
+ if (slope->d.y < 0)
+ testy = mobj->radius;
+ else
+ testy = -mobj->radius;
+
+ if ((slope->zdelta > 0) ^ !!(lowest)) {
+ testx = -testx;
+ testy = -testy;
+ }
+
+ testx += x;
+ testy += y;
+
+ // If the highest point is in the sector, then we have it easy! Just get the Z at that point
+ if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector))
+ return P_GetZAt(slope, testx, testy);
+
+ // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
+ if (perfect) {
+ size_t i;
+ line_t *ld;
+ fixed_t bbox[4];
+ fixed_t finalheight;
+
+ if (lowest)
+ finalheight = INT32_MAX;
+ else
+ finalheight = INT32_MIN;
+
+ bbox[BOXLEFT] = x-mobj->radius;
+ bbox[BOXRIGHT] = x+mobj->radius;
+ bbox[BOXTOP] = y+mobj->radius;
+ bbox[BOXBOTTOM] = y-mobj->radius;
+ for (i = 0; i < boundsec->linecount; i++) {
+ ld = boundsec->lines[i];
+
+ if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
+ || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
+ continue;
+
+ if (P_BoxOnLineSide(bbox, ld) != -1)
+ continue;
+
+ if (lowest)
+ finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
+ else
+ finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
+ }
+
+ return finalheight;
+ }
+
+ // If we're just testing for base sector location (no collision line), just go for the center's spot...
+ // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
+ if (line == NULL)
+ return P_GetZAt(slope, x, y);
+
+ return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
+ } else // Well, that makes it easy. Just get the floor height
+#endif
+ return sector->floorheight;
+}
+
+fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
+{
+ I_Assert(mobj != NULL);
+ I_Assert(sector != NULL);
+#ifdef ESLOPE
+ if (sector->c_slope) {
+ fixed_t testx, testy;
+ pslope_t *slope = sector->c_slope;
+
+ // Get the corner of the object that should be the highest on the slope
+ if (slope->d.x < 0)
+ testx = mobj->radius;
+ else
+ testx = -mobj->radius;
+
+ if (slope->d.y < 0)
+ testy = mobj->radius;
+ else
+ testy = -mobj->radius;
+
+ if ((slope->zdelta > 0) ^ !!(lowest)) {
+ testx = -testx;
+ testy = -testy;
+ }
+
+ testx += x;
+ testy += y;
+
+ // If the highest point is in the sector, then we have it easy! Just get the Z at that point
+ if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector))
+ return P_GetZAt(slope, testx, testy);
+
+ // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
+ if (perfect) {
+ size_t i;
+ line_t *ld;
+ fixed_t bbox[4];
+ fixed_t finalheight;
+
+ if (lowest)
+ finalheight = INT32_MAX;
+ else
+ finalheight = INT32_MIN;
+
+ bbox[BOXLEFT] = x-mobj->radius;
+ bbox[BOXRIGHT] = x+mobj->radius;
+ bbox[BOXTOP] = y+mobj->radius;
+ bbox[BOXBOTTOM] = y-mobj->radius;
+ for (i = 0; i < boundsec->linecount; i++) {
+ ld = boundsec->lines[i];
+
+ if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
+ || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
+ continue;
+
+ if (P_BoxOnLineSide(bbox, ld) != -1)
+ continue;
+
+ if (lowest)
+ finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
+ else
+ finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
+ }
+
+ return finalheight;
+ }
+
+ // If we're just testing for base sector location (no collision line), just go for the center's spot...
+ // It'll get fixed when we test for collision anyway, and the final result can't be lower than this
+ if (line == NULL)
+ return P_GetZAt(slope, x, y);
+
+ return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
+ } else // Well, that makes it easy. Just get the ceiling height
+#endif
+ return sector->ceilingheight;
+}
static void P_PlayerFlip(mobj_t *mo)
{
if (!mo->player)
@@ -820,7 +1413,7 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (mo->player)
{
if (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
- || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4])))
+ || mo->state-states == S_PLAY_FLY_TIRED))
gravityadd = gravityadd/3; // less gravity while flying
if (mo->player->pflags & PF_GLIDING)
gravityadd = gravityadd/3; // less gravity while gliding
@@ -975,7 +1568,11 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
}
else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale)
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
- && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)))
+ && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))
+#ifdef ESLOPE
+ && !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
+#endif
+ )
{
// if in a walking frame, stop moving
if (player->panim == PA_WALK)
@@ -1119,6 +1716,11 @@ void P_XYMovement(mobj_t *mo)
fixed_t xmove, ymove;
fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls
boolean moved;
+#ifdef ESLOPE
+ pslope_t *oldslope = NULL;
+ vector3_t slopemom;
+ fixed_t predictedz = 0;
+#endif
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
@@ -1150,11 +1752,35 @@ void P_XYMovement(mobj_t *mo)
oldx = mo->x;
oldy = mo->y;
+#ifdef ESLOPE
+ // adjust various things based on slope
+ if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) {
+ if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing!
+ P_SlopeLaunch(mo);
+ xmove = mo->momx;
+ ymove = mo->momy;
+ } else { // Still on the ground.
+ slopemom.x = xmove;
+ slopemom.y = ymove;
+ slopemom.z = 0;
+ P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
+
+ xmove = slopemom.x;
+ ymove = slopemom.y;
+
+ predictedz = mo->z + slopemom.z; // We'll use this later...
+
+ oldslope = mo->standingslope;
+ }
+ } else if (P_IsObjectOnGround(mo) && !mo->momz)
+ predictedz = mo->z;
+#endif
+
// Pushables can break some blocks
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
P_PushableCheckBustables(mo);
- if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !tmsprung)
+ if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
{
// blocked move
@@ -1270,6 +1896,54 @@ void P_XYMovement(mobj_t *mo)
if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;;
return;
+#ifdef ESLOPE
+ if (moved && oldslope) { // Check to see if we ran off
+
+ if (oldslope != mo->standingslope) { // First, compare different slopes
+ angle_t oldangle, newangle;
+ angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
+
+ oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT));
+
+ if (mo->standingslope)
+ newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
+ else
+ newangle = 0;
+
+ // Now compare the Zs of the different quantizations
+ if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
+ mo->standingslope = oldslope;
+ P_SlopeLaunch(mo);
+
+ //CONS_Printf("launched off of slope - ");
+ }
+
+ /*CONS_Printf("old angle %f - new angle %f = %f\n",
+ FIXED_TO_FLOAT(AngleFixed(oldangle)),
+ FIXED_TO_FLOAT(AngleFixed(newangle)),
+ FIXED_TO_FLOAT(AngleFixed(oldangle-newangle))
+ );*/
+ } else if (predictedz-mo->z > abs(slopemom.z/2)) { // Now check if we were supposed to stick to this slope
+ //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2));
+ P_SlopeLaunch(mo);
+ }
+ } else if (moved && mo->standingslope && predictedz) {
+ angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
+ angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
+
+ /*CONS_Printf("flat to angle %f - predicted z of %f\n",
+ FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)),
+ FIXED_TO_FLOAT(predictedz)
+ );*/
+ if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) {
+ mo->momz = P_MobjFlip(mo)*FRACUNIT/2;
+ mo->z = predictedz + P_MobjFlip(mo);
+ mo->standingslope = NULL;
+ //CONS_Printf("Launched off of flat surface running into downward slope\n");
+ }
+ }
+#endif
+
// Check the gravity status.
P_CheckGravity(mo, false);
@@ -1316,6 +1990,12 @@ void P_XYMovement(mobj_t *mo)
if (player && player->homing) // no friction for homing
return;
+#ifdef ESLOPE
+ if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED)
+ && (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)) // Special exception for tumbleweeds on slopes
+ return;
+#endif
+
if (((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
&& !(player && player->pflags & PF_SLIDING))
return; // no friction when airborne
@@ -1372,6 +2052,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
{
ffloor_t *rover;
fixed_t delta1, delta2, thingtop;
+ fixed_t topheight, bottomheight;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
@@ -1383,6 +2064,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
if (!(rover->flags & FF_EXISTS))
continue;
+ topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
+ bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
+
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected
;
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
@@ -1397,14 +2081,14 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
switch (motype)
{
case 2: // scenery does things differently for some reason
- if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
+ if (mo->z < topheight && bottomheight < thingtop)
{
mo->floorz = mo->z;
continue;
}
break;
default:
- if (mo->z < *rover->topheight && *rover->bottomheight < thingtop)
+ if (mo->z < topheight && bottomheight < thingtop)
{
if (mo->floorz < mo->z)
mo->floorz = mo->z;
@@ -1413,17 +2097,17 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
}
}
- delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
- delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
- if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2)
+ delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
+ delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
+ if (topheight > mo->floorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
{
- mo->floorz = *rover->topheight;
+ mo->floorz = topheight;
}
- if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
+ if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM))
{
- mo->ceilingz = *rover->bottomheight;
+ mo->ceilingz = bottomheight;
}
}
}
@@ -1493,10 +2177,10 @@ static void P_RingZMovement(mobj_t *mo)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
- if (mo->pmomz && mo->z != mo->floorz)
+ if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
- mo->pmomz = 0;
+ mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@@ -1555,6 +2239,11 @@ static boolean P_ZMovement(mobj_t *mo)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
+#ifdef ESLOPE
+ if (mo->standingslope && !P_IsObjectOnGround(mo))
+ P_SlopeLaunch(mo);
+#endif
+
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
@@ -1562,10 +2251,10 @@ static boolean P_ZMovement(mobj_t *mo)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
- if (mo->pmomz && mo->z != mo->floorz)
+ if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
- mo->pmomz = 0;
+ mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@@ -1706,7 +2395,7 @@ static boolean P_ZMovement(mobj_t *mo)
// Kill enemies and bosses that fall into death pits.
if (mo->health)
{
- P_KillMobj(mo, NULL, NULL);
+ P_KillMobj(mo, NULL, NULL, 0);
return false;
}
}
@@ -1742,14 +2431,31 @@ static boolean P_ZMovement(mobj_t *mo)
|| (mo->z + mo->height >= mo->ceilingz && mo->eflags & MFE_VERTICALFLIP))
&& !(mo->flags & MF_NOCLIPHEIGHT))
{
+ vector3_t mom;
+ mom.x = mo->momx;
+ mom.y = mo->momy;
+ mom.z = mo->momz;
+
if (mo->eflags & MFE_VERTICALFLIP)
mo->z = mo->ceilingz - mo->height;
else
mo->z = mo->floorz;
+#ifdef ESLOPE
+ P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
+ if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) {
+ mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
+
+ // Reverse quantizing might could use its own function later
+ mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle;
+ P_QuantizeMomentumToSlope(&mom, mo->standingslope);
+ mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle;
+ }
+#endif
+
// hit the floor
if (mo->type == MT_FIREBALL) // special case for the fireball
- mo->momz = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale);
+ mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale);
else if (mo->type == MT_SPINFIRE) // elemental shield fire is another exception here
;
else if (mo->flags & MF_MISSILE)
@@ -1764,12 +2470,12 @@ static boolean P_ZMovement(mobj_t *mo)
if (mo->flags & MF_GRENADEBOUNCE)
{
// Going down? (Or up in reverse gravity?)
- if (P_MobjFlip(mo)*mo->momz < 0)
+ if (P_MobjFlip(mo)*mom.z < 0)
{
// If going slower than a fracunit, just stop.
- if (abs(mo->momz) < FixedMul(FRACUNIT, mo->scale))
+ if (abs(mom.z) < FixedMul(FRACUNIT, mo->scale))
{
- mo->momx = mo->momy = mo->momz = 0;
+ mom.x = mom.y = mom.z = 0;
// Napalm hack
if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE && mo->fuse)
@@ -1777,7 +2483,7 @@ static boolean P_ZMovement(mobj_t *mo)
}
// Otherwise bounce up at half speed.
else
- mo->momz = -mo->momz/2;
+ mom.z = -mom.z/2;
S_StartSound(mo, mo->info->activesound);
}
}
@@ -1800,14 +2506,14 @@ static boolean P_ZMovement(mobj_t *mo)
}
}
- if (P_MobjFlip(mo)*mo->momz < 0) // falling
+ if (P_MobjFlip(mo)*mom.z < 0) // falling
{
if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
|| tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)
mo->eflags |= MFE_JUSTHITFLOOR;
if (mo->flags2 & MF2_SKULLFLY) // the skull slammed into something
- mo->momz = -mo->momz;
+ mom.z = -mom.z;
else
// Flingrings bounce
if (mo->type == MT_FLINGRING
@@ -1820,35 +2526,42 @@ static boolean P_ZMovement(mobj_t *mo)
|| mo->type == MT_FALLINGROCK)
{
if (maptol & TOL_NIGHTS)
- mo->momz = -FixedDiv(mo->momz, 10*FRACUNIT);
+ mom.z = -FixedDiv(mom.z, 10*FRACUNIT);
else
- mo->momz = -FixedMul(mo->momz, FixedDiv(17*FRACUNIT,20*FRACUNIT));
+ mom.z = -FixedMul(mom.z, FixedDiv(17*FRACUNIT,20*FRACUNIT));
if (mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED)
{
- if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale)
- && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale)
- && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale))
+ if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale)
+ && abs(mom.y) < FixedMul(STOPSPEED, mo->scale)
+ && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale))
{
- if (!(mo->flags & MF_AMBUSH))
- {
- mo->momx = mo->momy = mo->momz = 0;
- P_SetMobjState(mo, mo->info->spawnstate);
- }
- else
+ if (mo->flags & MF_AMBUSH)
{
// If deafed, give the tumbleweed another random kick if it runs out of steam.
- mo->momz += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale);
+ mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale);
if (P_Random() & 1)
- mo->momx += FixedMul(6*FRACUNIT, mo->scale);
+ mom.x += FixedMul(6*FRACUNIT, mo->scale);
else
- mo->momx -= FixedMul(6*FRACUNIT, mo->scale);
+ mom.x -= FixedMul(6*FRACUNIT, mo->scale);
if (P_Random() & 1)
- mo->momy += FixedMul(6*FRACUNIT, mo->scale);
+ mom.y += FixedMul(6*FRACUNIT, mo->scale);
else
- mo->momy -= FixedMul(6*FRACUNIT, mo->scale);
+ mom.y -= FixedMul(6*FRACUNIT, mo->scale);
+ }
+#ifdef ESLOPE
+ else if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)
+ {
+ // Pop the object up a bit to encourage bounciness
+ //mom.z = P_MobjFlip(mo)*mo->scale;
+ }
+#endif
+ else
+ {
+ mom.x = mom.y = mom.z = 0;
+ P_SetMobjState(mo, mo->info->spawnstate);
}
}
@@ -1858,14 +2571,14 @@ static boolean P_ZMovement(mobj_t *mo)
}
else if (mo->type == MT_FALLINGROCK)
{
- if (P_MobjFlip(mo)*mo->momz > FixedMul(2*FRACUNIT, mo->scale))
+ if (P_MobjFlip(mo)*mom.z > FixedMul(2*FRACUNIT, mo->scale))
S_StartSound(mo, mo->info->activesound + P_RandomKey(mo->info->mass));
- mo->momz /= 2; // Rocks not so bouncy
+ mom.z /= 2; // Rocks not so bouncy
- if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale)
- && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale)
- && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale))
+ if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale)
+ && abs(mom.y) < FixedMul(STOPSPEED, mo->scale)
+ && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale))
{
P_RemoveMobj(mo);
return false;
@@ -1873,20 +2586,30 @@ static boolean P_ZMovement(mobj_t *mo)
}
else if (mo->type == MT_CANNONBALLDECOR)
{
- mo->momz /= 2;
- if (abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale))
- mo->momz = 0;
+ mom.z /= 2;
+ if (abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale))
+ mom.z = 0;
}
}
else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
|| tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER))
- mo->momz = tmfloorthing->momz;
+ mom.z = tmfloorthing->momz;
else if (!tmfloorthing)
- mo->momz = 0;
+ mom.z = 0;
}
else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
|| tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER))
- mo->momz = tmfloorthing->momz;
+ mom.z = tmfloorthing->momz;
+
+#ifdef ESLOPE
+ if (mo->standingslope) {
+ P_QuantizeMomentumToSlope(&mom, mo->standingslope);
+ }
+#endif
+
+ mo->momx = mom.x;
+ mo->momy = mom.y;
+ mo->momz = mom.z;
if (mo->type == MT_STEAM)
return true;
@@ -1987,11 +2710,11 @@ static void P_PlayerZMovement(mobj_t *mo)
}
// adjust height
-/* if (mo->pmomz && mo->z > mo->floorz && !(mo->player->pflags & PF_JUMPED))
+ if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
- mo->pmomz = 0;
- }*/
+ mo->eflags &= ~MFE_APPLYPMOMZ;
+ }
mo->z += mo->momz;
@@ -2000,6 +2723,11 @@ static void P_PlayerZMovement(mobj_t *mo)
|| mo->player->playerstate == PST_REBORN)
return;
+#ifdef ESLOPE
+ if (mo->standingslope && !P_IsObjectOnGround(mo))
+ P_SlopeLaunch(mo);
+#endif
+
// clip movement
if (P_IsObjectOnGround(mo) && !(mo->flags & MF_NOCLIPHEIGHT))
{
@@ -2008,7 +2736,7 @@ static void P_PlayerZMovement(mobj_t *mo)
else
mo->z = mo->floorz;
- if (mo->player && (mo->player->pflags & PF_NIGHTSMODE))
+ if (mo->player->pflags & PF_NIGHTSMODE)
{
if (mo->player->flyangle < 90 || mo->player->flyangle >= 270)
mo->player->flyangle += P_MobjFlip(mo)*90;
@@ -2018,17 +2746,23 @@ static void P_PlayerZMovement(mobj_t *mo)
goto nightsdone;
}
// Get up if you fell.
- if (mo->state == &states[mo->info->painstate] || mo->state == &states[S_PLAY_SUPERHIT])
+ if (mo->player->panim == PA_PAIN)
P_SetPlayerMobjState(mo, S_PLAY_STND);
+#ifdef ESLOPE
+ if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) {
+ // Handle landing on slope during Z movement
+ P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope));
+ }
+#endif
+
if (P_MobjFlip(mo)*mo->momz < 0) // falling
{
+ mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement.
+
// Squat down. Decrease viewheight for a moment after hitting the ground (hard),
- if (mo->player)
- {
- if (P_MobjFlip(mo)*mo->momz < -FixedMul(8*FRACUNIT, mo->scale))
- mo->player->deltaviewheight = (P_MobjFlip(mo)*mo->momz)>>3; // make sure momz is negative
- }
+ if (P_MobjFlip(mo)*mo->momz < -FixedMul(8*FRACUNIT, mo->scale))
+ mo->player->deltaviewheight = (P_MobjFlip(mo)*mo->momz)>>3; // make sure momz is negative
if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
|| tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) // Spin Attack
@@ -2101,14 +2835,14 @@ static void P_PlayerZMovement(mobj_t *mo)
// Cut momentum in half when you hit the ground and
// aren't pressing any controls.
- if (!mo->player || (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)))
+ 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;
}
}
- if (mo->health && mo->player)
+ if (mo->health)
{
if (mo->player->pflags & PF_GLIDING) // ground gliding
{
@@ -2116,23 +2850,23 @@ static void P_PlayerZMovement(mobj_t *mo)
mo->tics = -1;
}
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_SPC1] && mo->state <= &states[S_PLAY_SPC4]))
+ || mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED)
{
if (mo->player->cmomx || mo->player->cmomy)
{
if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
- P_SetPlayerMobjState(mo, S_PLAY_SPD1);
- else if ((mo->player->rmomx || mo->player->rmomy) && mo->player->panim != PA_WALK)
- P_SetPlayerMobjState(mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(mo, S_PLAY_RUN);
+ else if ((mo->player->rmomx || mo->player->rmomy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
+ P_SetPlayerMobjState(mo, S_PLAY_WALK);
else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE)
P_SetPlayerMobjState(mo, S_PLAY_STND);
}
else
{
if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
- P_SetPlayerMobjState(mo, S_PLAY_SPD1);
- else if ((mo->momx || mo->momy) && mo->player->panim != PA_WALK)
- P_SetPlayerMobjState(mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(mo, S_PLAY_RUN);
+ else if ((mo->momx || mo->momy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
+ P_SetPlayerMobjState(mo, S_PLAY_WALK);
else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE)
P_SetPlayerMobjState(mo, S_PLAY_STND);
}
@@ -2154,7 +2888,7 @@ static void P_PlayerZMovement(mobj_t *mo)
mo->player->powers[pw_tailsfly] = 0;
}
}
- if (mo->player && !(mo->player->pflags & PF_SPINNING))
+ if (!(mo->player->pflags & PF_SPINNING))
mo->player->pflags &= ~PF_STARTDASH;
if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
@@ -2197,7 +2931,7 @@ nightsdone:
else
mo->z = mo->ceilingz - mo->height;
- if (mo->player && (mo->player->pflags & PF_NIGHTSMODE))
+ if (mo->player->pflags & PF_NIGHTSMODE)
{
if (mo->player->flyangle < 90 || mo->player->flyangle >= 270)
mo->player->flyangle -= P_MobjFlip(mo)*90;
@@ -2212,7 +2946,7 @@ nightsdone:
{
msecnode_t *node;
- if (CheckForMarioBlocks && mo->player && !(netgame && mo->player->spectator)) // Only let the player punch
+ if (CheckForMarioBlocks && !(netgame && mo->player->spectator)) // Only let the player punch
{
// Search the touching sectors, from side-to-side...
for (node = mo->touching_sectorlist; node; node = node->m_snext)
@@ -2240,7 +2974,7 @@ nightsdone:
if (mariomode)
S_StartSound(mo, sfx_mario1);
- if (!(mo->player && mo->player->climbing))
+ if (!mo->player->climbing)
mo->momz = 0;
}
}
@@ -2255,10 +2989,10 @@ static boolean P_SceneryZMovement(mobj_t *mo)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
- if (mo->pmomz && mo->z != mo->floorz)
+ if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
- mo->pmomz = 0;
+ mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@@ -2429,46 +3163,58 @@ void P_MobjCheckWater(mobj_t *mobj)
player_t *p = mobj->player; // Will just be null if not a player.
// Default if no water exists.
- mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT;
+ mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
// Reset water state.
mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER|MFE_GOOWATER);
for (rover = sector->ffloors; rover; rover = rover->next)
{
+ fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE)
|| (((rover->flags & FF_BLOCKPLAYER) && mobj->player)
|| ((rover->flags & FF_BLOCKOTHERS) && !mobj->player)))
continue;
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
+
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y);
+#endif
+
if (mobj->eflags & MFE_VERTICALFLIP)
{
- if (*rover->topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale))
- || *rover->bottomheight > thingtop)
+ if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale))
+ || bottomheight > thingtop)
continue;
}
else
{
- if (*rover->topheight < mobj->z
- || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale)))
+ if (topheight < mobj->z
+ || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale)))
continue;
}
// Set the watertop and waterbottom
- mobj->watertop = *rover->topheight;
- mobj->waterbottom = *rover->bottomheight;
+ mobj->watertop = topheight;
+ mobj->waterbottom = bottomheight;
// Just touching the water?
- if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < *rover->bottomheight)
- || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight))
+ if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight)
+ || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight))
{
mobj->eflags |= MFE_TOUCHWATER;
if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY))
mobj->eflags |= MFE_GOOWATER;
}
// Actually in the water?
- if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > *rover->bottomheight)
- || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < *rover->topheight))
+ if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight)
+ || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight))
{
mobj->eflags |= MFE_UNDERWATER;
if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY))
@@ -2526,10 +3272,8 @@ void P_MobjCheckWater(mobj_t *mobj)
return;
if ((mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water.
- if (wasinwater && P_MobjFlip(mobj)*mobj->momz > 0)
- mobj->momz = FixedMul(mobj->momz, FixedDiv(9*FRACUNIT, 8*FRACUNIT)); // Give the mobj a little out-of-goo boost.
- else if (P_MobjFlip(mobj)*mobj->momz < 0)
- mobj->momz = FixedMul(mobj->momz, FixedDiv(2*FRACUNIT, 5*FRACUNIT)); // KILL its momentum.
+ if (P_MobjFlip(mobj)*mobj->momz < 0) // You are entering the goo?
+ mobj->momz = FixedMul(mobj->momz, FixedDiv(2*FRACUNIT, 5*FRACUNIT)); // kill momentum significantly, to make the goo feel thick.
}
else if (wasinwater && P_MobjFlip(mobj)*mobj->momz > 0)
mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT)); // Give the mobj a little out-of-water boost.
@@ -2647,7 +3391,7 @@ static void P_SceneryCheckWater(mobj_t *mobj)
sector_t *sector;
// Default if no water exists.
- mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT;
+ mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
// see if we are in water, and set some flags for later
sector = mobj->subsector->sector;
@@ -2655,6 +3399,7 @@ static void P_SceneryCheckWater(mobj_t *mobj)
if (sector->ffloors)
{
ffloor_t *rover;
+ fixed_t topheight, bottomheight;
mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER);
@@ -2662,20 +3407,32 @@ static void P_SceneryCheckWater(mobj_t *mobj)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
continue;
- if (*rover->topheight <= mobj->z
- || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale)))
+
+ topheight = *rover->topheight;
+ bottomheight = *rover->bottomheight;
+
+#ifdef ESLOPE
+ if (*rover->t_slope)
+ topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
+
+ if (*rover->b_slope)
+ bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y);
+#endif
+
+ if (topheight <= mobj->z
+ || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale)))
continue;
- if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight)
+ if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)
mobj->eflags |= MFE_TOUCHWATER;
else
mobj->eflags &= ~MFE_TOUCHWATER;
// Set the watertop and waterbottom
- mobj->watertop = *rover->topheight;
- mobj->waterbottom = *rover->bottomheight;
+ mobj->watertop = topheight;
+ mobj->waterbottom = bottomheight;
- if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < *rover->topheight)
+ if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight)
mobj->eflags |= MFE_UNDERWATER;
else
mobj->eflags &= ~MFE_UNDERWATER;
@@ -2705,7 +3462,15 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
if (!(rover->flags & FF_EXISTS))
continue;
- if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight)
+ if (halfheight >= (
+#ifdef ESLOPE
+ *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) :
+#endif
+ *rover->topheight) || halfheight <= (
+#ifdef ESLOPE
+ *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) :
+#endif
+ *rover->bottomheight))
continue;
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
@@ -2733,7 +3498,15 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
continue;
- if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight)
+ if (halfheight >= (
+#ifdef ESLOPE
+ *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) :
+#endif
+ *rover->topheight) || halfheight <= (
+#ifdef ESLOPE
+ *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) :
+#endif
+ *rover->bottomheight))
continue;
return true;
@@ -2762,7 +3535,7 @@ void P_DestroyRobots(void)
continue;
// Found a target enemy
- P_KillMobj(mo, players[consoleplayer].mo, players[consoleplayer].mo);
+ P_KillMobj(mo, players[consoleplayer].mo, players[consoleplayer].mo, 0);
}
}
@@ -2838,10 +3611,10 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
thiscam->floorz = tmfloorz;
thiscam->ceilingz = tmceilingz;
- if (thiscam->momz)
+ if (thiscam->momz || player->mo->pmomz)
{
// adjust height
- thiscam->z += thiscam->momz;
+ thiscam->z += thiscam->momz + player->mo->pmomz;
if (!itsatwodlevel && !(player->pflags & PF_NOCLIP))
{
@@ -2899,10 +3672,15 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
msecnode_t *node;
I_Assert(mobj != NULL);
+ I_Assert(mobj->player != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
P_MobjCheckWater(mobj);
+#ifdef ESLOPE
+ P_ButteredSlope(mobj);
+#endif
+
// momentum movement
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
@@ -2917,7 +3695,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
}
- else if (mobj->player && (mobj->player->pflags & PF_MACESPIN) && mobj->tracer)
+ else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer)
{
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
@@ -2936,11 +3714,12 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
else
P_TryMove(mobj, mobj->x, mobj->y, true);
- if (!(netgame && mobj->player && mobj->player->spectator))
+ if (!(netgame && mobj->player->spectator))
{
// Crumbling platforms
for (node = mobj->touching_sectorlist; node; node = node->m_snext)
{
+ fixed_t topheight, bottomheight;
ffloor_t *rover;
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
@@ -2948,8 +3727,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE))
continue;
- if ((*rover->topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP))
- || (*rover->bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut.
+ topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector);
+ bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector);
+
+ if ((topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP))
+ || (bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut.
EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN));
}
}
@@ -3019,18 +3801,14 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
}
else
{
- if (mobj->player)
+ mobj->player->jumping = 0;
+ mobj->player->pflags &= ~PF_JUMPED;
+ if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
{
- mobj->player->jumping = 0;
- mobj->player->pflags &= ~PF_JUMPED;
- if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
- {
- mobj->player->secondjump = 0;
- mobj->player->powers[pw_tailsfly] = 0;
- P_SetPlayerMobjState(mobj, S_PLAY_RUN1);
- }
+ mobj->player->secondjump = 0;
+ mobj->player->powers[pw_tailsfly] = 0;
+ P_SetPlayerMobjState(mobj, S_PLAY_WALK);
}
- mobj->pmomz = 0;
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
@@ -3443,7 +4221,7 @@ static void P_Boss3Thinker(mobj_t *mobj)
continue;
if (players[i].mo->eflags & MFE_UNDERWATER)
- P_DamageMobj(players[i].mo, mobj, mobj, 1);
+ P_DamageMobj(players[i].mo, mobj, mobj, 1, 0);
}
// Make the water flash
@@ -3784,7 +4562,7 @@ static void P_Boss4PopSpikeballs(mobj_t *mobj)
P_SetTarget(&base->tracer, NULL);
for (seg = base; seg; seg = seg->hnext)
if (seg->health)
- P_KillMobj(seg, NULL, NULL);
+ P_KillMobj(seg, NULL, NULL, 0);
base = next;
}
}
@@ -4084,7 +4862,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
{
INT32 i;
- P_KillMobj(mobj, NULL, NULL);
+ P_KillMobj(mobj, NULL, NULL, 0);
// It was a team effort
for (i = 0; i < MAXPLAYERS; i++)
@@ -4135,7 +4913,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
&& players[i].mo->z < mobj->z + mobj->height + 128*FRACUNIT) // You can't be in the vicinity, either...
{
// Punch him!
- P_DamageMobj(players[i].mo, mobj, mobj, 1);
+ P_DamageMobj(players[i].mo, mobj, mobj, 1, 0);
mobj->state->nextstate = mobj->info->spawnstate;
// Laugh
@@ -4358,7 +5136,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
if (players[i].mo->z < mobj->z - 64*FRACUNIT)
continue;
- P_DamageMobj(players[i].mo, mobj, mobj, 1);
+ P_DamageMobj(players[i].mo, mobj, mobj, 1, 0);
// Laugh
S_StartSound(0, sfx_bewar1 + P_RandomKey(4));
@@ -5448,7 +6226,9 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
P_SetTarget(&mobj->tracer, NULL);
- mobj->flags2 &= ~MF2_PUSHED;
+ mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
+
+ tmfloorthing = tmhitthing = NULL;
// 970 allows ANY mobj to trigger a linedef exec
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)
@@ -5780,7 +6560,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL
&& (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
{
- P_KillMobj(mobj, NULL, NULL);
+ P_KillMobj(mobj, NULL, NULL, 0);
return;
}
}
@@ -6412,7 +7192,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL
&& (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
{
- P_KillMobj(mobj, NULL, NULL);
+ P_KillMobj(mobj, NULL, NULL, 0);
return;
}
break;
@@ -6497,19 +7277,22 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->spawnpoint->options & MTF_OBJECTFLIP)
{
z = ss->sector->ceilingheight - mobjinfo[mobj->type].height;
- if (mobj->spawnpoint->z)
- z -= mobj->spawnpoint->z << FRACBITS;
+ if (mobj->spawnpoint->options >> ZSHIFT)
+ z -= (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS;
}
else
{
z = ss->sector->floorheight;
- if (mobj->spawnpoint->z)
- z += mobj->spawnpoint->z << FRACBITS;
+ if (mobj->spawnpoint->options >> ZSHIFT)
+ z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS;
}
flagmo = P_SpawnMobj(x, y, z, mobj->type);
flagmo->spawnpoint = mobj->spawnpoint;
if (mobj->spawnpoint->options & MTF_OBJECTFLIP)
- flagmo->spawnpoint->options |= MTF_OBJECTFLIP;
+ {
+ flagmo->eflags |= MFE_VERTICALFLIP;
+ flagmo->flags2 |= MF2_OBJECTFLIP;
+ }
if (mobj->type == MT_REDFLAG)
{
@@ -6643,25 +7426,29 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
}
else
{
- if (mobj->player)
- {
- mobj->player->jumping = 0;
- mobj->player->pflags &= ~PF_JUMPED;
- if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
- {
- mobj->player->secondjump = 0;
- mobj->player->powers[pw_tailsfly] = 0;
- P_SetPlayerMobjState(mobj, S_PLAY_RUN1);
- }
- }
mobj->pmomz = 0; // to prevent that weird rocketing gargoyle bug
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
+#ifdef ESLOPE // Sliding physics for slidey mobjs!
+ if (mobj->type == MT_FLINGRING
+ || mobj->type == MT_FLINGCOIN
+ || P_WeaponOrPanel(mobj->type)
+ || mobj->type == MT_FLINGEMERALD
+ || mobj->type == MT_BIGTUMBLEWEED
+ || mobj->type == MT_LITTLETUMBLEWEED
+ || mobj->type == MT_CANNONBALLDECOR
+ || mobj->type == MT_FALLINGROCK) {
+ P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
+ //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n");
+ P_ButteredSlope(mobj);
+ }
+#endif
+
if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health
&& P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz
{
- P_KillMobj(mobj, NULL, NULL);
+ P_KillMobj(mobj, NULL, NULL, DMG_DEATHPIT);
return;
}
@@ -6675,7 +7462,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
&& !(mobj->flags & MF_NOCLIPHEIGHT)
&& mobj->health > 0)
{
- P_KillMobj(mobj, NULL, NULL);
+ P_KillMobj(mobj, NULL, NULL, DMG_CRUSHED);
return;
}
}
@@ -6854,17 +7641,6 @@ void P_SceneryThinker(mobj_t *mobj)
}
else
{
- if (mobj->player)
- {
- mobj->player->jumping = 0;
- mobj->player->pflags &= ~PF_JUMPED;
- if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
- {
- mobj->player->secondjump = 0;
- mobj->player->powers[pw_tailsfly] = 0;
- P_SetPlayerMobjState(mobj, S_PLAY_RUN1);
- }
- }
mobj->pmomz = 0; // to prevent that weird rocketing gargoyle bug
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
@@ -6931,8 +7707,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// Make sure scale matches destscale immediately when spawned
P_SetScale(mobj, mobj->destscale);
- mobj->floorz = mobj->subsector->sector->floorheight;
- mobj->ceilingz = mobj->subsector->sector->ceilingheight;
+ mobj->floorz =
+#ifdef ESLOPE
+ mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) :
+#endif
+ mobj->subsector->sector->floorheight;
+ mobj->ceilingz =
+#ifdef ESLOPE
+ mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) :
+#endif
+ mobj->subsector->sector->ceilingheight;
// Tells MobjCheckWater that the water height was not set.
mobj->watertop = INT32_MAX;
@@ -7989,7 +8773,11 @@ void P_SpawnMapThing(mapthing_t *mthing)
return;
ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS);
- mthing->z = (INT16)((ss->sector->floorheight>>FRACBITS) + (mthing->options >> ZSHIFT));
+ mthing->z = (INT16)(((
+#ifdef ESLOPE
+ ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) :
+#endif
+ ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT));
if (numhuntemeralds < MAXHUNTEMERALDS)
huntemeralds[numhuntemeralds++] = mthing;
@@ -8107,14 +8895,22 @@ void P_SpawnMapThing(mapthing_t *mthing)
ss = R_PointInSubsector(x, y);
if (i == MT_NIGHTSBUMPER)
- z = ss->sector->floorheight + ((mthing->options >> ZSHIFT) << FRACBITS);
+ z = (
+#ifdef ESLOPE
+ ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
+#endif
+ 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)
{
if (mthing->options & MTF_OBJECTFLIP)
{
- z = ss->sector->ceilingheight;
+ z = (
+#ifdef ESLOPE
+ ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
+#endif
+ ss->sector->ceilingheight);
if (mthing->options & MTF_AMBUSH) // Special flag for rings
z -= 24*FRACUNIT;
@@ -8125,7 +8921,11 @@ void P_SpawnMapThing(mapthing_t *mthing)
}
else
{
- z = ss->sector->floorheight;
+ z = (
+#ifdef ESLOPE
+ ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
+#endif
+ ss->sector->floorheight);
if (mthing->options & MTF_AMBUSH) // Special flag for rings
z += 24*FRACUNIT;
@@ -8145,9 +8945,17 @@ void P_SpawnMapThing(mapthing_t *mthing)
// base positions
if (flip)
- z = ss->sector->ceilingheight - mobjinfo[i].height;
+ z = (
+#ifdef ESLOPE
+ ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
+#endif
+ ss->sector->ceilingheight) - mobjinfo[i].height;
else
- z = ss->sector->floorheight;
+ z = (
+#ifdef ESLOPE
+ ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
+#endif
+ ss->sector->floorheight);
// offsetting
if (mthing->options >> ZSHIFT)
@@ -8661,7 +9469,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Screw these damn hoops, I need this thinker.
//hoopcenter->flags |= MF_NOTHINK;
- z += sec->floorheight;
+ z +=
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight;
hoopcenter->z = z - hoopcenter->height/2;
@@ -8794,7 +9606,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
hoopcenter->spawnpoint = mthing;
- z += sec->floorheight;
+ z +=
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight;
hoopcenter->z = z - hoopcenter->height/2;
P_UnsetThingPosition(hoopcenter);
@@ -8906,7 +9722,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Wing logo item.
else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum)
{
- z = sec->floorheight;
+ z =
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
@@ -8958,13 +9778,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Set proper height
if (mthing->options & MTF_OBJECTFLIP)
{
- z = sec->ceilingheight - mobjinfo[ringthing].height;
+ z = (
+#ifdef ESLOPE
+ sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
+#endif
+ sec->ceilingheight) - mobjinfo[ringthing].height;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
- z = sec->floorheight;
+ z =
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
@@ -9018,13 +9846,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
{
if (mthing->options & MTF_OBJECTFLIP)
{
- z = sec->ceilingheight - mobjinfo[ringthing].height - dist*r;
+ z = (
+#ifdef ESLOPE
+ sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
+#endif
+ sec->ceilingheight) - mobjinfo[ringthing].height - dist*r;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
- z = sec->floorheight + dist*r;
+ z = (
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight) + dist*r;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
@@ -9070,13 +9906,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (mthing->options & MTF_OBJECTFLIP)
{
- z = sec->ceilingheight - mobjinfo[ringthing].height - 64*FRACUNIT*r;
+ z = (
+#ifdef ESLOPE
+ sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
+#endif
+ sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
- z = sec->floorheight + 64*FRACUNIT*r;
+ z = (
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight) + 64*FRACUNIT*r;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
@@ -9107,7 +9951,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
size = 192*FRACUNIT;
}
- z = sec->floorheight;
+ z =
+#ifdef ESLOPE
+ sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
+#endif
+ sec->floorheight;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 6d120c473..76a87096c 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -175,24 +175,23 @@ typedef enum
MF2_EXPLOSION = 1<<7, // Thrown ring has explosive properties
MF2_SCATTER = 1<<8, // Thrown ring has scatter properties
MF2_BEYONDTHEGRAVE = 1<<9, // Source of this missile has died and has since respawned.
- MF2_PUSHED = 1<<10, // Mobj was already pushed this tic
- MF2_SLIDEPUSH = 1<<11, // MF_PUSHABLE that pushes continuously.
- MF2_CLASSICPUSH = 1<<12, // Drops straight down when object has negative Z.
- MF2_STANDONME = 1<<13, // While not pushable, stand on me anyway.
- MF2_INFLOAT = 1<<14, // Floating to a height for a move, don't auto float to target's height.
- MF2_DEBRIS = 1<<15, // Splash ring from explosion ring
- MF2_NIGHTSPULL = 1<<16, // Attracted from a paraloop
- MF2_JUSTATTACKED = 1<<17, // can be pushed by other moving mobjs
- MF2_FIRING = 1<<18, // turret fire
- MF2_SUPERFIRE = 1<<19, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
- MF2_SHADOW = 1<<20, // Fuzzy draw, makes targeting harder.
- MF2_STRONGBOX = 1<<21, // Flag used for "strong" random monitors.
- MF2_OBJECTFLIP = 1<<22, // Flag for objects that always have flipped gravity.
- MF2_SKULLFLY = 1<<23, // Special handling: skull in flight.
- MF2_FRET = 1<<24, // Flashing from a previous hit
- MF2_BOSSNOTRAP = 1<<25, // No Egg Trap after boss
- MF2_BOSSFLEE = 1<<26, // Boss is fleeing!
- MF2_BOSSDEAD = 1<<27, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
+ MF2_SLIDEPUSH = 1<<10, // MF_PUSHABLE that pushes continuously.
+ MF2_CLASSICPUSH = 1<<11, // Drops straight down when object has negative Z.
+ MF2_STANDONME = 1<<12, // While not pushable, stand on me anyway.
+ MF2_INFLOAT = 1<<13, // Floating to a height for a move, don't auto float to target's height.
+ MF2_DEBRIS = 1<<14, // Splash ring from explosion ring
+ MF2_NIGHTSPULL = 1<<15, // Attracted from a paraloop
+ MF2_JUSTATTACKED = 1<<16, // can be pushed by other moving mobjs
+ MF2_FIRING = 1<<17, // turret fire
+ MF2_SUPERFIRE = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
+ MF2_SHADOW = 1<<19, // Fuzzy draw, makes targeting harder.
+ MF2_STRONGBOX = 1<<20, // Flag used for "strong" random monitors.
+ MF2_OBJECTFLIP = 1<<21, // Flag for objects that always have flipped gravity.
+ MF2_SKULLFLY = 1<<22, // Special handling: skull in flight.
+ MF2_FRET = 1<<23, // Flashing from a previous hit
+ MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss
+ MF2_BOSSFLEE = 1<<25, // Boss is fleeing!
+ MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
// free: to and including 1<<31
} mobjflag2_t;
@@ -232,7 +231,13 @@ typedef enum
MFE_VERTICALFLIP = 1<<5,
// Goo water
MFE_GOOWATER = 1<<6,
- // free: to and including 1<<7
+ // Mobj was already pushed this tic
+ MFE_PUSHED = 1<<7,
+ // Mobj was already sprung this tic
+ MFE_SPRUNG = 1<<8,
+ // Platform movement
+ MFE_APPLYPMOMZ = 1<<9,
+ // free: to and including 1<<15
} mobjeflag_t;
//
@@ -265,6 +270,7 @@ typedef struct mobj_s
angle_t angle; // orientation
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
+ UINT8 sprite2; // player sprites
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@@ -286,7 +292,7 @@ typedef struct mobj_s
state_t *state;
UINT32 flags; // flags from mobjinfo tables
UINT32 flags2; // MF2_ flags
- UINT8 eflags; // extra flags
+ UINT16 eflags; // extra flags
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
// Player and mobj sprites in multiplayer modes are modified
@@ -349,6 +355,10 @@ typedef struct mobj_s
INT32 cusval;
INT32 cvmem;
+#ifdef ESLOPE
+ struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
+#endif
+
// WARNING: New fields must be added separately to savegame and Lua.
} mobj_t;
diff --git a/src/p_polyobj.c b/src/p_polyobj.c
index 9c955c97b..faa3242d4 100644
--- a/src/p_polyobj.c
+++ b/src/p_polyobj.c
@@ -239,24 +239,39 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox)
//
// Polyobj_GetInfo
//
-// Finds the 'polyobject settings' linedef that shares the same tag
-// as the polyobj linedef to get the settings for it.
+// Finds the 'polyobject settings' linedef for a polyobject
+// the polyobject's id should be set as its tag
//
-void Polyobj_GetInfo(INT16 tag, INT32 *polyID, INT32 *mirrorID, UINT16 *exparg)
+void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans)
{
- INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, tag, -1);
+ INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, poid, -1);
if (i == -1)
- I_Error("Polyobject (tag: %d) needs line %d for information.\n", tag, POLYINFO_SPECIALNUM);
+ return; // no extra settings to apply, let's leave it
- if (polyID)
- *polyID = lines[i].frontsector->floorheight>>FRACBITS;
+ if (parentID)
+ *parentID = lines[i].frontsector->special;
- if (mirrorID)
- *mirrorID = lines[i].frontsector->special;
+ if (potrans)
+ *potrans = (lines[i].frontsector->floorheight>>FRACBITS) / 100;
- if (exparg)
- *exparg = (UINT16)lines[i].frontsector->lightlevel;
+ if (lines[i].flags & ML_EFFECT1)
+ *poflags |= POF_ONESIDE;
+
+ if (lines[i].flags & ML_EFFECT2)
+ *poflags &= ~POF_SOLID;
+
+ if (lines[i].flags & ML_EFFECT3)
+ *poflags |= POF_PUSHABLESTOP;
+
+ if (lines[i].flags & ML_EFFECT4)
+ *poflags |= POF_RENDERPLANES;
+
+ /*if (lines[i].flags & ML_EFFECT5)
+ *poflags &= ~POF_CLIPPLANES;*/
+
+ if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor
+ *poflags |= POF_LDEXEC;
}
// Reallocating array maintenance
@@ -478,6 +493,7 @@ newseg:
CONS_Debug(DBG_POLYOBJ, "Polyobject %d is not closed\n", po->id);
}
+/*
// structure used to store segs during explicit search process
typedef struct segitem_s
{
@@ -553,7 +569,7 @@ static void Polyobj_findExplicit(polyobj_t *po)
// free the temporary array
Z_Free(segitems);
-}
+}*/
// Setup functions
@@ -591,47 +607,27 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
for (i = 0; i < numsegs; ++i)
{
seg_t *seg = &segs[i];
- INT32 polyID, parentID;
+ INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES;
+ INT32 parentID = 0, potrans = 0;
if (seg->linedef->special != POLYOBJ_START_LINE)
continue;
- Polyobj_GetInfo(seg->linedef->tag, &polyID, &parentID, NULL);
+ if (seg->linedef->tag != po->id)
+ continue;
- // is it a START line with this polyobject's id?
- if (polyID == po->id)
- {
- po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES;
+ Polyobj_GetInfo(po->id, &poflags, &parentID, &potrans); // apply extra settings if they exist!
- if (seg->linedef->flags & ML_EFFECT1)
- po->flags |= POF_ONESIDE;
+ // save original flags and translucency to reference later for netgames!
+ po->spawnflags = po->flags = poflags;
+ po->spawntrans = po->translucency = potrans;
- if (seg->linedef->flags & ML_EFFECT2)
- po->flags &= ~POF_SOLID;
-
- if (seg->linedef->flags & ML_EFFECT3)
- po->flags |= POF_PUSHABLESTOP;
-
- if (seg->linedef->flags & ML_EFFECT4)
- po->flags |= POF_RENDERPLANES;
-
- // TODO: Use a different linedef flag for this if we really need it!!
- // This clashes with texture tiling, also done by Effect 5 flag
- /*if (seg->linedef->flags & ML_EFFECT5)
- po->flags &= ~POF_CLIPPLANES;*/
-
- if (seg->linedef->flags & ML_NOCLIMB) // Has a linedef executor
- po->flags |= POF_LDEXEC;
-
- po->spawnflags = po->flags; // save original flags to reference later for netgames!
-
- Polyobj_findSegs(po, seg);
- po->parent = parentID;
- if (po->parent == po->id) // do not allow a self-reference
- po->parent = -1;
- // TODO: sound sequence is in args[2]
- break;
- }
+ Polyobj_findSegs(po, seg);
+ po->parent = parentID;
+ if (po->parent == po->id) // do not allow a self-reference
+ po->parent = -1;
+ // TODO: sound sequence is in args[2]
+ break;
}
CONS_Debug(DBG_POLYOBJ, "PO ID: %d; Num verts: %s\n", po->id, sizeu1(po->numVertices));
@@ -640,6 +636,7 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
if (po->isBad)
return;
+ /*
// 2. If no such line existed in the first step, look for a seg with the
// "explicit" special with tag matching this polyobject's id number. If
// found, continue to search for all such lines, storing them in a
@@ -658,8 +655,16 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
if (po->parent == po->id) // do not allow a self-reference
po->parent = -1;
// TODO: sound sequence is in args[3]
- }
+ }*/
+ // make sure array isn't empty
+ // since Polyobj_findExplicit is disabled currently, we have to do things here instead now!
+ if (po->segCount == 0)
+ {
+ po->isBad = true;
+ CONS_Debug(DBG_POLYOBJ, "Polyobject %d is empty\n", po->id);
+ return;
+ }
// set the polyobject's spawn spot
po->spawnSpot.x = spawnSpot->x;
@@ -1043,9 +1048,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy)
mo->lastlook = pomovecount;
- // always push players even if not solid
- if (!((mo->flags & MF_SOLID) || mo->player))
+ // Don't scroll objects that aren't affected by gravity
+ if (mo->flags & MF_NOGRAVITY)
continue;
+ // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red)
if (mo->flags & MF_NOCLIP)
continue;
@@ -1097,9 +1103,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line)
for (; mo; mo = mo->bnext)
{
- // always push players even if not solid
- if (!((mo->flags & MF_SOLID) || mo->player))
+
+ // Don't scroll objects that aren't affected by gravity
+ if (mo->flags & MF_NOGRAVITY)
continue;
+ // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red)
if (mo->flags & MF_NOCLIP)
continue;
@@ -1259,6 +1267,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
{
static INT32 pomovecount = 10000;
INT32 x, y;
+ angle_t deltafine = delta >> ANGLETOFINESHIFT;
pomovecount++;
@@ -1283,9 +1292,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
mo->lastlook = pomovecount;
- // always push players even if not solid
- if (!((mo->flags & MF_SOLID) || mo->player))
+ // Don't scroll objects that aren't affected by gravity
+ if (mo->flags & MF_NOGRAVITY)
continue;
+ // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red)
if (mo->flags & MF_NOCLIP)
continue;
@@ -1300,21 +1310,28 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
continue;
{
- fixed_t newxoff, newyoff;
- angle_t angletoobj = R_PointToAngle2(origin.x, origin.y, mo->x, mo->y);
- fixed_t disttoobj = R_PointToDist2(origin.x, origin.y, mo->x, mo->y);
+ fixed_t oldxoff, oldyoff, newxoff, newyoff;
+ fixed_t c, s;
+
+ c = FINECOSINE(deltafine);
+ s = FINESINE(deltafine);
+
+ oldxoff = mo->x-origin.x;
+ oldyoff = mo->y-origin.y;
if (mo->player) // Hack to fix players sliding off of spinning polys -Red
{
- disttoobj = FixedMul(disttoobj, 0xfe40);
+ fixed_t temp;
+
+ temp = FixedMul(oldxoff, c)-FixedMul(oldyoff, s);
+ oldyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s);
+ oldxoff = temp;
}
- angletoobj += delta;
- angletoobj >>= ANGLETOFINESHIFT;
- newxoff = FixedMul(FINECOSINE(angletoobj), disttoobj);
- newyoff = FixedMul(FINESINE(angletoobj), disttoobj);
+ newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s);
+ newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s);
- Polyobj_slideThing(mo, origin.x+newxoff-mo->x, origin.y+newyoff-mo->y);
+ Polyobj_slideThing(mo, newxoff-oldxoff, newyoff-oldyoff);
if (turnthings == 2 || (turnthings == 1 && !mo->player)) {
mo->angle += delta;
@@ -2491,6 +2508,10 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
return 0;
}
+ // Hotfix to not crash on single-waypoint sequences -Red
+ if (!last)
+ last = first;
+
// Set diffx, diffy, diffz
// Put these at 0 for now...might not be needed after all.
th->diffx = 0;//first->x - po->centerPt.x;
diff --git a/src/p_polyobj.h b/src/p_polyobj.h
index 71cf965e3..cfcb3b99c 100644
--- a/src/p_polyobj.h
+++ b/src/p_polyobj.h
@@ -28,7 +28,7 @@
#define POLYOBJ_ANCHOR_DOOMEDNUM 760
#define POLYOBJ_SPAWN_DOOMEDNUM 761
-#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762
+#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE
#define POLYOBJ_START_LINE 20
#define POLYOBJ_EXPLICIT_LINE 21
@@ -100,8 +100,11 @@ typedef struct polyobj_s
UINT8 isBad; // a bad polyobject: should not be rendered/manipulated
INT32 translucency; // index to translucency tables
+ struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later
+
// these are saved for netgames, so do not let Lua touch these!
INT32 spawnflags; // Flags the polyobject originally spawned with
+ INT32 spawntrans; // Translucency the polyobject originally spawned with
} polyobj_t;
//
@@ -274,7 +277,7 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y);
boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo);
boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo);
boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox);
-void Polyobj_GetInfo(INT16 tag, INT32 *polyID, INT32 *parentID, UINT16 *exparg);
+void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans);
// thinkers (needed in p_saveg.c)
void T_PolyObjRotate(polyrotate_t *);
diff --git a/src/p_saveg.c b/src/p_saveg.c
index 851d653fa..07e7b3564 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -30,6 +30,9 @@
#include "r_sky.h"
#include "p_polyobj.h"
#include "lua_script.h"
+#ifdef ESLOPE
+#include "p_slopes.h"
+#endif
savedata_t savedata;
UINT8 *save_p;
@@ -921,7 +924,8 @@ typedef enum
MD2_EXTVAL1 = 1<<5,
MD2_EXTVAL2 = 1<<6,
MD2_HNEXT = 1<<7,
- MD2_HPREV = 1<<8
+ MD2_HPREV = 1<<8,
+ MD2_SLOPE = 1<<9
} mobj_diff2_t;
typedef enum
@@ -1052,6 +1056,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff |= MD_TICS;
if (mobj->sprite != mobj->state->sprite)
diff |= MD_SPRITE;
+ if (mobj->sprite == SPR_PLAY && mobj->sprite2 != 0)
+ diff |= MD_SPRITE;
if (mobj->frame != mobj->state->frame)
diff |= MD_FRAME;
if (mobj->eflags)
@@ -1109,6 +1115,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_HNEXT;
if (mobj->hprev)
diff2 |= MD2_HPREV;
+ if (mobj->standingslope)
+ diff2 |= MD2_SLOPE;
if (diff2 != 0)
diff |= MD_MORE;
@@ -1169,12 +1177,15 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT16(save_p, mobj->state-states);
if (diff & MD_TICS)
WRITEINT32(save_p, mobj->tics);
- if (diff & MD_SPRITE)
+ if (diff & MD_SPRITE) {
WRITEUINT16(save_p, mobj->sprite);
+ if (mobj->sprite == SPR_PLAY)
+ WRITEUINT8(save_p, mobj->sprite2);
+ }
if (diff & MD_FRAME)
WRITEUINT32(save_p, mobj->frame);
if (diff & MD_EFLAGS)
- WRITEUINT8(save_p, mobj->eflags);
+ WRITEUINT16(save_p, mobj->eflags);
if (diff & MD_PLAYER)
WRITEUINT8(save_p, mobj->player-players);
if (diff & MD_MOVEDIR)
@@ -1221,6 +1232,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum);
+ if (diff2 & MD2_SLOPE)
+ WRITEUINT16(save_p, mobj->standingslope->id);
WRITEUINT32(save_p, mobj->mobjnum);
}
@@ -1991,16 +2004,22 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->tics = READINT32(save_p);
else
mobj->tics = mobj->state->tics;
- if (diff & MD_SPRITE)
+ if (diff & MD_SPRITE) {
mobj->sprite = READUINT16(save_p);
- else
+ if (mobj->sprite == SPR_PLAY)
+ mobj->sprite2 = READUINT8(save_p);
+ }
+ else {
mobj->sprite = mobj->state->sprite;
+ if (mobj->sprite == SPR_PLAY)
+ mobj->sprite2 = mobj->state->frame&FF_FRAMEMASK;
+ }
if (diff & MD_FRAME)
mobj->frame = READUINT32(save_p);
else
mobj->frame = mobj->state->frame;
if (diff & MD_EFLAGS)
- mobj->eflags = READUINT8(save_p);
+ mobj->eflags = READUINT16(save_p);
if (diff & MD_PLAYER)
{
i = READUINT8(save_p);
@@ -2068,6 +2087,9 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
+ if (diff2 & MD2_SLOPE)
+ mobj->standingslope = P_SlopeById(READUINT16(save_p));
+
if (diff & MD_REDFLAG)
{
@@ -2789,7 +2811,7 @@ static inline void P_ArchivePolyObj(polyobj_t *po)
if (po->flags != po->spawnflags)
diff |= PD_FLAGS;
- if (po->translucency != 0)
+ if (po->translucency != po->spawntrans)
diff |= PD_TRANS;
WRITEUINT8(save_p, diff);
diff --git a/src/p_setup.c b/src/p_setup.c
index f2b0c49d8..3491669c7 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -72,6 +72,10 @@
#include "hardware/hw_light.h"
#endif
+#ifdef ESLOPE
+#include "p_slopes.h"
+#endif
+
//
// Map MD5, calculated on level load.
// Sent to clients in PT_SERVERINFO.
@@ -846,7 +850,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
//
// P_LoadThings
//
-static void P_LoadThings(lumpnum_t lumpnum)
+static void P_PrepareThings(lumpnum_t lumpnum)
{
size_t i;
mapthing_t *mt;
@@ -884,13 +888,27 @@ static void P_LoadThings(lumpnum_t lumpnum)
}
Z_Free(datastart);
+}
+
+static void P_LoadThings(void)
+{
+ size_t i;
+ mapthing_t *mt;
+
+ // Loading the things lump itself into memory is now handled in P_PrepareThings, above
+
mt = mapthings;
numhuntemeralds = 0;
for (i = 0; i < nummapthings; i++, mt++)
{
+ sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector;
+
// Z for objects
- mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
- ->sector->floorheight>>FRACBITS);
+ mt->z = (INT16)(
+#ifdef ESLOPE
+ mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) :
+#endif
+ mtsector->floorheight)>>FRACBITS;
if (mt->type == 1700 // MT_AXIS
|| mt->type == 1701 // MT_AXISTRANSFER
@@ -2114,7 +2132,8 @@ void P_LoadThingsOnly(void)
P_LevelInitStuff();
- P_LoadThings(lastloadedmaplumpnum + ML_THINGS);
+ P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
+ P_LoadThings();
P_SpawnSecretItems(true);
}
@@ -2531,7 +2550,13 @@ boolean P_SetupLevel(boolean skipprecip)
P_MapStart();
- P_LoadThings(lastloadedmaplumpnum + ML_THINGS);
+ P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
+
+#ifdef ESLOPE
+ P_ResetDynamicSlopes();
+#endif
+
+ P_LoadThings();
P_SpawnSecretItems(loademblems);
diff --git a/src/p_slopes.c b/src/p_slopes.c
new file mode 100644
index 000000000..755939039
--- /dev/null
+++ b/src/p_slopes.c
@@ -0,0 +1,1139 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2004 Stephen McGranahan
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+//--------------------------------------------------------------------------
+//
+// DESCRIPTION:
+// Slopes
+// SoM created 05/10/09
+// ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron
+//
+//-----------------------------------------------------------------------------
+
+
+#include "doomdef.h"
+#include "r_defs.h"
+#include "r_state.h"
+#include "m_bbox.h"
+#include "z_zone.h"
+#include "p_local.h"
+#include "p_spec.h"
+#include "p_slopes.h"
+#include "p_setup.h"
+#include "r_main.h"
+#include "p_maputl.h"
+#include "w_wad.h"
+
+#ifdef ESLOPE
+
+static pslope_t *slopelist = NULL;
+static UINT16 slopecount = 0;
+
+// Calculate line normal
+void P_CalculateSlopeNormal(pslope_t *slope) {
+ slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
+ slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
+ slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
+}
+
+// With a vertex slope that has its vertices set, configure relevant slope info
+void P_ReconfigureVertexSlope(pslope_t *slope)
+{
+ vector3_t vec1, vec2;
+
+ // Set slope normal
+ vec1.x = (slope->vertices[1]->x - slope->vertices[0]->x) << FRACBITS;
+ vec1.y = (slope->vertices[1]->y - slope->vertices[0]->y) << FRACBITS;
+ vec1.z = (slope->vertices[1]->z - slope->vertices[0]->z) << FRACBITS;
+
+ vec2.x = (slope->vertices[2]->x - slope->vertices[0]->x) << FRACBITS;
+ vec2.y = (slope->vertices[2]->y - slope->vertices[0]->y) << FRACBITS;
+ vec2.z = (slope->vertices[2]->z - slope->vertices[0]->z) << FRACBITS;
+
+ // ugggggggh fixed-point maaaaaaath
+ slope->extent = max(
+ max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)),
+ max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z))
+ ) >> (FRACBITS+5);
+ vec1.x /= slope->extent;
+ vec1.y /= slope->extent;
+ vec1.z /= slope->extent;
+ vec2.x /= slope->extent;
+ vec2.y /= slope->extent;
+ vec2.z /= slope->extent;
+
+ FV3_Cross(&vec1, &vec2, &slope->normal);
+
+ slope->extent = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z);
+ if (slope->normal.z < 0)
+ slope->extent = -slope->extent;
+
+ slope->normal.x = FixedDiv(slope->normal.x, slope->extent);
+ slope->normal.y = FixedDiv(slope->normal.y, slope->extent);
+ slope->normal.z = FixedDiv(slope->normal.z, slope->extent);
+
+ // Set origin
+ slope->o.x = slope->vertices[0]->x << FRACBITS;
+ slope->o.y = slope->vertices[0]->y << FRACBITS;
+ slope->o.z = slope->vertices[0]->z << FRACBITS;
+
+ if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope"
+ slope->zangle = slope->xydirection = 0;
+ slope->zdelta = slope->d.x = slope->d.y = 0;
+ } else {
+ // Get direction vector
+ slope->extent = R_PointToDist2(0, 0, slope->normal.x, slope->normal.y);
+ slope->d.x = -FixedDiv(slope->normal.x, slope->extent);
+ slope->d.y = -FixedDiv(slope->normal.y, slope->extent);
+
+ // Z delta
+ slope->zdelta = FixedDiv(slope->extent, slope->normal.z);
+
+ // Get angles
+ slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180;
+ slope->zangle = -R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta);
+ }
+}
+
+// Recalculate dynamic slopes
+void P_RunDynamicSlopes(void) {
+ pslope_t *slope;
+
+ for (slope = slopelist; slope; slope = slope->next) {
+ fixed_t zdelta;
+
+ if (slope->flags & SL_NODYNAMIC)
+ continue;
+
+ switch(slope->refpos) {
+ case 1: // front floor
+ zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight;
+ slope->o.z = slope->sourceline->frontsector->floorheight;
+ break;
+ case 2: // front ceiling
+ zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight;
+ slope->o.z = slope->sourceline->frontsector->ceilingheight;
+ break;
+ case 3: // back floor
+ zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight;
+ slope->o.z = slope->sourceline->backsector->floorheight;
+ break;
+ case 4: // back ceiling
+ zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight;
+ slope->o.z = slope->sourceline->backsector->ceilingheight;
+ break;
+ case 5: // vertices
+ {
+ mapthing_t *mt;
+ size_t i;
+ INT32 l;
+ line_t *line;
+
+ for (i = 0; i < 3; i++) {
+ mt = slope->vertices[i];
+ l = P_FindSpecialLineFromTag(799, mt->angle, -1);
+ if (l != -1) {
+ line = &lines[l];
+ mt->z = line->frontsector->floorheight >> FRACBITS;
+ }
+ }
+
+ P_ReconfigureVertexSlope(slope);
+ }
+ continue; // TODO
+
+ default:
+ I_Error("P_RunDynamicSlopes: slope has invalid type!");
+ }
+
+ if (slope->zdelta != FixedDiv(zdelta, slope->extent)) {
+ slope->zdelta = FixedDiv(zdelta, slope->extent);
+ slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta);
+ P_CalculateSlopeNormal(slope);
+ }
+ }
+}
+
+//
+// P_MakeSlope
+//
+// Alocates and fill the contents of a slope structure.
+//
+static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d,
+ const fixed_t zdelta, UINT8 flags)
+{
+ pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
+ memset(ret, 0, sizeof(*ret));
+
+ ret->o.x = o->x;
+ ret->o.y = o->y;
+ ret->o.z = o->z;
+
+ ret->d.x = d->x;
+ ret->d.y = d->y;
+
+ ret->zdelta = zdelta;
+
+ ret->flags = flags;
+
+ // Add to the slope list
+ ret->next = slopelist;
+ slopelist = ret;
+
+ slopecount++;
+ ret->id = slopecount;
+
+ return ret;
+}
+
+//
+// P_GetExtent
+//
+// Returns the distance to the first line within the sector that
+// is intersected by a line parallel to the plane normal with the point (ox, oy)
+//
+static fixed_t P_GetExtent(sector_t *sector, line_t *line)
+{
+ // ZDoom code reference: v3float_t = vertex_t
+ fixed_t fardist = -FRACUNIT;
+ size_t i;
+
+ // Find furthest vertex from the reference line. It, along with the two ends
+ // of the line, will define the plane.
+ // SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep
+ for(i = 0; i < sector->linecount; i++)
+ {
+ line_t *li = sector->lines[i];
+ vertex_t tempv;
+ fixed_t dist;
+
+ // Don't compare to the slope line.
+ if(li == line)
+ continue;
+
+ P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv);
+ dist = R_PointToDist2(tempv.x, tempv.y, li->v1->x, li->v1->y);
+ if(dist > fardist)
+ fardist = dist;
+
+ // Okay, maybe do it for v2 as well?
+ P_ClosestPointOnLine(li->v2->x, li->v2->y, line, &tempv);
+ dist = R_PointToDist2(tempv.x, tempv.y, li->v2->x, li->v2->y);
+ if(dist > fardist)
+ fardist = dist;
+ }
+
+ return fardist;
+}
+
+
+//
+// P_SpawnSlope_Line
+//
+// Creates one or more slopes based on the given line type and front/back
+// sectors.
+// Kalaron: Check if dynamic slopes need recalculation
+//
+void P_SpawnSlope_Line(int linenum)
+{
+ // With dynamic slopes, it's fine to just leave this function as normal,
+ // because checking to see if a slope had changed will waste more memory than
+ // if the slope was just updated when called
+ line_t *line = lines + linenum;
+ INT16 special = line->special;
+ pslope_t *fslope = NULL, *cslope = NULL;
+ vector3_t origin, point;
+ vector2_t direction;
+ fixed_t nx, ny, dz, extent;
+
+ boolean frontfloor = (special == 700 || special == 702 || special == 703);
+ boolean backfloor = (special == 710 || special == 712 || special == 713);
+ boolean frontceil = (special == 701 || special == 702 || special == 713);
+ boolean backceil = (special == 711 || special == 712 || special == 703);
+
+ UINT8 flags = 0; // Slope flags
+ if (line->flags & ML_NOSONIC)
+ flags |= SL_NOPHYSICS;
+ if (line->flags & ML_NOTAILS)
+ flags |= SL_NODYNAMIC;
+ if (line->flags & ML_NOKNUX)
+ flags |= SL_ANCHORVERTEX;
+
+ if(!frontfloor && !backfloor && !frontceil && !backceil)
+ {
+ CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n");
+ return;
+ }
+
+ if(!line->frontsector || !line->backsector)
+ {
+ CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n");
+ return;
+ }
+
+ {
+ fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy);
+ nx = FixedDiv(line->dy, len);
+ ny = -FixedDiv(line->dx, len);
+ }
+
+ // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF
+ origin.x = line->v1->x + (line->v2->x - line->v1->x)/2;
+ origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
+
+ // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map!
+ if(frontfloor || frontceil)
+ {
+ line->frontsector->hasslope = true; // Tell the software renderer that we're sloped
+
+ origin.z = line->backsector->floorheight;
+ direction.x = nx;
+ direction.y = ny;
+
+ extent = P_GetExtent(line->frontsector, line);
+
+ if(extent < 0)
+ {
+ CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum);
+ return;
+ }
+
+ // reposition the origin according to the extent
+ point.x = origin.x + FixedMul(direction.x, extent);
+ point.y = origin.y + FixedMul(direction.y, extent);
+ direction.x = -direction.x;
+ direction.y = -direction.y;
+
+ // TODO: We take origin and point 's xy values and translate them to the center of an FOF!
+
+ if(frontfloor)
+ {
+ fixed_t highest, lowest;
+ size_t l;
+ point.z = line->frontsector->floorheight; // Startz
+ dz = FixedDiv(origin.z - point.z, extent); // Destinationz
+
+ // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef
+
+ fslope = line->frontsector->f_slope =
+ P_MakeSlope(&point, &direction, dz, flags);
+
+ // Set up some shit
+ fslope->extent = extent;
+ fslope->refpos = 1;
+
+ // Now remember that f_slope IS a vector
+ // fslope->o = origin 3D point 1 of the vector
+ // fslope->d = destination 3D point 2 of the vector
+ // fslope->normal is a 3D line perpendicular to the 3D vector
+
+ // Sync the linedata of the line that started this slope
+ // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ fslope->sourceline = line;
+
+ // To find the real highz/lowz of a slope, you need to check all the vertexes
+ // in the slope's sector with P_GetZAt to get the REAL lowz & highz
+ // Although these slopes are set by floorheights the ANGLE is what a slope is,
+ // so technically any slope can extend on forever (they are just bound by sectors)
+ // *You can use sourceline as a reference to see if two slopes really are the same
+
+ // Default points for high and low
+ highest = point.z > origin.z ? point.z : origin.z;
+ lowest = point.z < origin.z ? point.z : origin.z;
+
+ // Now check to see what the REAL high and low points of the slope inside the sector
+ // TODO: Is this really needed outside of FOFs? -Red
+
+ for (l = 0; l < line->frontsector->linecount; l++)
+ {
+ fixed_t height = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y);
+
+ if (height > highest)
+ highest = height;
+
+ if (height < lowest)
+ lowest = height;
+ }
+
+ // Sets extra clipping data for the frontsector's slope
+ fslope->highz = highest;
+ fslope->lowz = lowest;
+
+ fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
+ fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
+
+ P_CalculateSlopeNormal(fslope);
+ }
+ if(frontceil)
+ {
+ fixed_t highest, lowest;
+ size_t l;
+ origin.z = line->backsector->ceilingheight;
+ point.z = line->frontsector->ceilingheight;
+ dz = FixedDiv(origin.z - point.z, extent);
+
+ cslope = line->frontsector->c_slope =
+ P_MakeSlope(&point, &direction, dz, flags);
+
+ // Set up some shit
+ cslope->extent = extent;
+ cslope->refpos = 2;
+
+ // Sync the linedata of the line that started this slope
+ // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ cslope->sourceline = line;
+
+ // Remember the way the slope is formed
+ highest = point.z > origin.z ? point.z : origin.z;
+ lowest = point.z < origin.z ? point.z : origin.z;
+
+ for (l = 0; l < line->frontsector->linecount; l++)
+ {
+ fixed_t height = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y);
+
+ if (height > highest)
+ highest = height;
+
+ if (height < lowest)
+ lowest = height;
+ }
+
+ // This line special sets extra clipping data for the frontsector's slope
+ cslope->highz = highest;
+ cslope->lowz = lowest;
+
+ cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
+ cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
+
+ P_CalculateSlopeNormal(cslope);
+ }
+ }
+ if(backfloor || backceil)
+ {
+ line->backsector->hasslope = true; // Tell the software renderer that we're sloped
+
+ origin.z = line->frontsector->floorheight;
+ // Backsector
+ direction.x = -nx;
+ direction.y = -ny;
+
+ extent = P_GetExtent(line->backsector, line);
+
+ if(extent < 0)
+ {
+ CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum);
+ return;
+ }
+
+ // reposition the origin according to the extent
+ point.x = origin.x + FixedMul(direction.x, extent);
+ point.y = origin.y + FixedMul(direction.y, extent);
+ direction.x = -direction.x;
+ direction.y = -direction.y;
+
+ if(backfloor)
+ {
+ fixed_t highest, lowest;
+ size_t l;
+ point.z = line->backsector->floorheight;
+ dz = FixedDiv(origin.z - point.z, extent);
+
+ fslope = line->backsector->f_slope =
+ P_MakeSlope(&point, &direction, dz, flags);
+
+ // Set up some shit
+ fslope->extent = extent;
+ fslope->refpos = 3;
+
+ // Sync the linedata of the line that started this slope
+ // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ fslope->sourceline = line;
+
+ // Remember the way the slope is formed
+ highest = point.z > origin.z ? point.z : origin.z;
+ lowest = point.z < origin.z ? point.z : origin.z;
+
+ for (l = 0; l < line->backsector->linecount; l++)
+ {
+ fixed_t height = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y);
+
+ if (height > highest)
+ highest = height;
+
+ if (height < lowest)
+ lowest = height;
+ }
+
+ // This line special sets extra clipping data for the frontsector's slope
+ fslope->highz = highest;
+ fslope->lowz = lowest;
+
+ fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
+ fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
+
+ P_CalculateSlopeNormal(fslope);
+ }
+ if(backceil)
+ {
+ fixed_t highest, lowest;
+ size_t l;
+ origin.z = line->frontsector->ceilingheight;
+ point.z = line->backsector->ceilingheight;
+ dz = FixedDiv(origin.z - point.z, extent);
+
+ cslope = line->backsector->c_slope =
+ P_MakeSlope(&point, &direction, dz, flags);
+
+ // Set up some shit
+ cslope->extent = extent;
+ cslope->refpos = 4;
+
+ // Sync the linedata of the line that started this slope
+ // SRB2CBTODO: Anything special for remote(control sector)-based slopes later?
+ cslope->sourceline = line;
+
+ // Remember the way the slope is formed
+ highest = point.z > origin.z ? point.z : origin.z;
+ lowest = point.z < origin.z ? point.z : origin.z;
+
+ for (l = 0; l < line->backsector->linecount; l++)
+ {
+ fixed_t height = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y);
+
+ if (height > highest)
+ highest = height;
+
+ if (height < lowest)
+ lowest = height;
+ }
+
+ // This line special sets extra clipping data for the backsector's slope
+ cslope->highz = highest;
+ cslope->lowz = lowest;
+
+ cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
+ cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
+
+ P_CalculateSlopeNormal(cslope);
+ }
+ }
+
+ if(!line->tag)
+ return;
+}
+
+//
+// P_NewVertexSlope
+//
+// Creates a new slope from three vertices with the specified IDs
+//
+pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags)
+{
+ size_t i;
+ mapthing_t *mt = mapthings;
+
+ pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
+ memset(ret, 0, sizeof(*ret));
+
+ // Start by setting flags
+ ret->flags = flags;
+
+ // Now set up the vertex list
+ ret->vertices = Z_Malloc(3*sizeof(mapthing_t), PU_LEVEL, NULL);
+ memset(ret->vertices, 0, 3*sizeof(mapthing_t));
+
+ // And... look for the vertices in question.
+ for (i = 0; i < nummapthings; i++, mt++) {
+ if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something!
+ continue;
+
+ if (!ret->vertices[0] && mt->angle == tag1)
+ ret->vertices[0] = mt;
+ else if (!ret->vertices[1] && mt->angle == tag2)
+ ret->vertices[1] = mt;
+ else if (!ret->vertices[2] && mt->angle == tag3)
+ ret->vertices[2] = mt;
+ }
+
+ if (!ret->vertices[0])
+ CONS_Printf("PANIC 0\n");
+ if (!ret->vertices[1])
+ CONS_Printf("PANIC 1\n");
+ if (!ret->vertices[2])
+ CONS_Printf("PANIC 2\n");
+
+ // Now set heights for each vertex, because they haven't been set yet
+ for (i = 0; i < 3; i++) {
+ mt = ret->vertices[i];
+ if (mt->extrainfo)
+ mt->z = mt->options;
+ else
+ mt->z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight >> FRACBITS) + (mt->options >> ZSHIFT);
+ }
+
+ P_ReconfigureVertexSlope(ret);
+ ret->refpos = 5;
+
+ // Add to the slope list
+ ret->next = slopelist;
+ slopelist = ret;
+
+ slopecount++;
+ ret->id = slopecount;
+
+ return ret;
+}
+
+
+
+//
+// P_CopySectorSlope
+//
+// Searches through tagged sectors and copies
+//
+void P_CopySectorSlope(line_t *line)
+{
+ sector_t *fsec = line->frontsector;
+ int i, special = line->special;
+
+ // Check for copy linedefs
+ for(i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;)
+ {
+ sector_t *srcsec = sectors + i;
+
+ if((special - 719) & 1 && !fsec->f_slope && srcsec->f_slope)
+ fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope);
+ if((special - 719) & 2 && !fsec->c_slope && srcsec->c_slope)
+ fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope);
+ }
+
+ fsec->hasslope = true;
+
+ line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef
+}
+
+//
+// P_SlopeById
+//
+// Looks in the slope list for a slope with a specified ID. Mostly useful for netgame sync
+//
+pslope_t *P_SlopeById(UINT16 id)
+{
+ pslope_t *ret;
+ for (ret = slopelist; ret && ret->id != id; ret = ret->next);
+ return ret;
+}
+
+#ifdef SPRINGCLEAN
+#include "byteptr.h"
+
+#include "p_setup.h"
+#include "p_local.h"
+
+//==========================================================================
+//
+// P_SetSlopesFromVertexHeights
+//
+//==========================================================================
+void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum)
+{
+ mapthing_t *mt;
+ boolean vt_found = false;
+ size_t i, j, k, l, q;
+
+ //size_t i;
+ //mapthing_t *mt;
+ char *data;
+ char *datastart;
+
+ // SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10
+ // anything else seems to make a map not load properly,
+ // but this hard-coded value MUST have some reason for being what it is
+ size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short));
+ mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL);
+ fixed_t x, y;
+ sector_t *sector;
+ // Spawn axis points first so they are
+ // at the front of the list for fast searching.
+ data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
+ mt = smapthings;
+ for (i = 0; i < snummapthings; i++, mt++)
+ {
+ mt->x = READINT16(data);
+ mt->y = READINT16(data);
+ mt->angle = READINT16(data);
+ mt->type = READINT16(data);
+ mt->options = READINT16(data);
+ // mt->z hasn't been set yet!
+ //mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types
+
+ //mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!!
+ x = mt->x*FRACUNIT;
+ y = mt->y*FRACUNIT;
+ sector = R_PointInSubsector(x, y)->sector;
+ // Z for objects
+#ifdef ESLOPE
+ if (sector->f_slope)
+ mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS);
+ else
+#endif
+ mt->z = (short)(sector->floorheight>>FRACBITS);
+
+ mt->z = mt->z + (mt->options >> ZSHIFT);
+
+ if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ
+ {
+ for(l = 0; l < numvertexes; l++)
+ {
+ if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT)
+ {
+ if (mt->type == THING_VertexFloorZ)
+ {
+ vertexes[l].z = mt->z*FRACUNIT;
+ //I_Error("Z value: %i", vertexes[l].z/FRACUNIT);
+
+ }
+ else
+ {
+ vertexes[l].z = mt->z*FRACUNIT; // celing floor
+ }
+ vt_found = true;
+ }
+ }
+ //mt->type = 0; // VPHYSICS: Dynamic slopes
+
+
+
+
+
+
+ if (vt_found)
+ {
+ for (k = 0; k < numsectors; k++)
+ {
+ sector_t *sec = §ors[k];
+ if (sec->linecount != 3) continue; // only works with triangular sectors
+
+ v3float_t vt1, vt2, vt3; // cross = ret->normalf
+ v3float_t vec1, vec2;
+
+ int vi1, vi2, vi3;
+
+ vi1 = (int)(sec->lines[0]->v1 - vertexes);
+ vi2 = (int)(sec->lines[0]->v2 - vertexes);
+ vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)?
+ (int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes);
+
+ //if (vertexes[vi1].z)
+ // I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT);
+ //if (vertexes[vi2].z)
+ // I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT);
+ //if (vertexes[vi3].z)
+ // I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT);
+
+ //I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z);
+
+ //I_Error("%i, %i, %i", mt->x, mt->y, mt->z);
+ //P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING);
+
+ // TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the
+ // triangle sector to setup the real vertex slopes
+ // Check for the vertexes of all sectors
+ for(q = 0; q < numvertexes; q++)
+ {
+ if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT)
+ {
+ //I_Error("yeah %i", vertexes[q].z);
+ P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING);
+#if 0
+ if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
+ && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
+ && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
+ P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING);
+ else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
+ && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
+ && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
+ P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV);
+ else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)
+ && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
+ && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z))
+ P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1);
+ else
+#endif
+ continue;
+ }
+ }
+
+ vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x);
+ vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y);
+ vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x);
+ vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y);
+ vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x);
+ vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y);
+
+ for(j = 0; j < 2; j++)
+ {
+
+ fixed_t z3;
+ //I_Error("Lo hicimos");
+
+ vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight);
+ vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight);
+ z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height
+ vt3.z = FIXED_TO_FLOAT(z3);
+
+ if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0)
+ {
+ vec1.x = vt2.x - vt3.x;
+ vec1.y = vt2.y - vt3.y;
+ vec1.z = vt2.z - vt3.z;
+
+ vec2.x = vt1.x - vt3.x;
+ vec2.y = vt1.y - vt3.y;
+ vec2.z = vt1.z - vt3.z;
+ }
+ else
+ {
+ vec1.x = vt1.x - vt3.x;
+ vec1.y = vt1.y - vt3.y;
+ vec1.z = vt1.z - vt3.z;
+
+ vec2.x = vt2.x - vt3.x;
+ vec2.y = vt2.y - vt3.y;
+ vec2.z = vt2.z - vt3.z;
+ }
+
+
+ pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
+ memset(ret, 0, sizeof(*ret));
+
+ {
+ M_CrossProduct3f(&ret->normalf, &vec1, &vec2);
+
+ // Cross product length
+ float len = (float)sqrt(ret->normalf.x * ret->normalf.x +
+ ret->normalf.y * ret->normalf.y +
+ ret->normalf.z * ret->normalf.z);
+
+ if (len == 0)
+ {
+ // Only happens when all vertices in this sector are on the same line.
+ // Let's just ignore this case.
+ //CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16));
+ return;
+ }
+ // cross/len
+ ret->normalf.x /= len;
+ ret->normalf.y /= len;
+ ret->normalf.z /= len;
+
+ // ZDoom cross = ret->normalf
+ // Fix backward normals
+ if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1))
+ {
+ // cross = -cross
+ ret->normalf.x = -ret->normalf.x;
+ ret->normalf.y = -ret->normalf.x;
+ ret->normalf.z = -ret->normalf.x;
+ }
+ }
+
+ secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL);
+
+ srcplane->a = FLOAT_TO_FIXED (ret->normalf.x);
+ srcplane->b = FLOAT_TO_FIXED (ret->normalf.y);
+ srcplane->c = FLOAT_TO_FIXED (ret->normalf.z);
+ //srcplane->ic = FixedDiv(FRACUNIT, srcplane->c);
+ srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x,
+ srcplane->b, vertexes[vi3].y,
+ srcplane->c, z3);
+
+ if (j == 0)
+ {
+ sec->f_slope = ret;
+ sec->f_slope->secplane = *srcplane;
+ }
+ else if (j == 1)
+ {
+ sec->c_slope = ret;
+ sec->c_slope->secplane = *srcplane;
+ }
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+ }
+ }
+ Z_Free(datastart);
+
+
+
+
+}
+#endif
+
+// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
+void P_ResetDynamicSlopes(void) {
+ size_t i;
+#if 1 // Rewrite old specials to new ones, and give a console warning
+ boolean warned = false;
+#endif
+
+ slopelist = NULL;
+ slopecount = 0;
+
+ // We'll handle copy slopes later, after all the tag lists have been made.
+ // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you.
+ for (i = 0; i < numlines; i++)
+ {
+ switch (lines[i].special)
+ {
+#if 1 // Rewrite old specials to new ones, and give a console warning
+#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
+ case 386:
+ case 387:
+ case 388:
+ lines[i].special += 700-386;
+ WARNME
+ P_SpawnSlope_Line(i);
+ break;
+
+ case 389:
+ case 390:
+ case 391:
+ case 392:
+ lines[i].special += 710-389;
+ WARNME
+ P_SpawnSlope_Line(i);
+ break;
+
+ case 393:
+ lines[i].special = 703;
+ WARNME
+ P_SpawnSlope_Line(i);
+ break;
+
+ case 394:
+ case 395:
+ case 396:
+ lines[i].special += 720-394;
+ WARNME
+ break;
+
+#endif
+
+ case 700:
+ case 701:
+ case 702:
+ case 703:
+ case 710:
+ case 711:
+ case 712:
+ case 713:
+ P_SpawnSlope_Line(i);
+ break;
+
+ case 704:
+ case 705:
+ case 714:
+ case 715:
+ {
+ pslope_t **slopetoset;
+ size_t which = lines[i].special;
+
+ UINT8 flags = SL_VERTEXSLOPE;
+ if (lines[i].flags & ML_NOSONIC)
+ flags |= SL_NOPHYSICS;
+ if (!(lines[i].flags & ML_NOTAILS))
+ flags |= SL_NODYNAMIC;
+
+ if (which == 704)
+ {
+ slopetoset = &lines[i].frontsector->f_slope;
+ which = 0;
+ }
+ else if (which == 705)
+ {
+ slopetoset = &lines[i].frontsector->c_slope;
+ which = 0;
+ }
+ else if (which == 714)
+ {
+ slopetoset = &lines[i].backsector->f_slope;
+ which = 1;
+ }
+ else // 715
+ {
+ slopetoset = &lines[i].backsector->c_slope;
+ which = 1;
+ }
+
+ if (lines[i].flags & ML_NOKNUX)
+ *slopetoset = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[which]].textureoffset >> FRACBITS,
+ sides[lines[i].sidenum[which]].rowoffset >> FRACBITS, flags);
+ else
+ *slopetoset = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags);
+
+ sides[lines[i].sidenum[which]].sector->hasslope = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+
+
+// ============================================================================
+//
+// Various utilities related to slopes
+//
+
+//
+// P_GetZAt
+//
+// Returns the height of the sloped plane at (x, y) as a fixed_t
+//
+fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
+{
+ fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) +
+ FixedMul(y - slope->o.y, slope->d.y);
+
+ return slope->o.z + FixedMul(dist, slope->zdelta);
+}
+
+
+//
+// P_QuantizeMomentumToSlope
+//
+// When given a vector, rotates it and aligns it to a slope
+void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
+{
+ vector3_t axis;
+ axis.x = -slope->d.y;
+ axis.y = slope->d.x;
+ axis.z = 0;
+
+ FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT);
+}
+
+//
+// P_SlopeLaunch
+//
+// Handles slope ejection for objects
+void P_SlopeLaunch(mobj_t *mo)
+{
+ // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
+ // vertical launch given from slopes while increasing the horizontal launch
+ // given. Good for SRB2's gravity and horizontal speeds.
+ vector3_t slopemom;
+ slopemom.x = mo->momx;
+ slopemom.y = mo->momy;
+ slopemom.z = mo->momz*2;
+ P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
+
+ mo->momx = slopemom.x;
+ mo->momy = slopemom.y;
+ mo->momz = slopemom.z/2;
+
+ //CONS_Printf("Launched off of slope.\n");
+ mo->standingslope = NULL;
+}
+
+// Function to help handle landing on slopes
+void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
+{
+ vector3_t mom;
+ mom.x = thing->momx;
+ mom.y = thing->momy;
+ mom.z = thing->momz*2;
+
+ //CONS_Printf("langing on slope\n");
+
+ // Reverse quantizing might could use its own function later
+ slope->zangle = ANGLE_MAX-slope->zangle;
+ P_QuantizeMomentumToSlope(&mom, slope);
+ slope->zangle = ANGLE_MAX-slope->zangle;
+
+ if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
+ thing->momx = mom.x;
+ thing->momy = mom.y;
+ thing->momz = -P_MobjFlip(thing);
+
+ thing->standingslope = slope;
+ }
+}
+
+// https://yourlogicalfallacyis.com/slippery-slope
+// Handles sliding down slopes, like if they were made of butter :)
+void P_ButteredSlope(mobj_t *mo)
+{
+ fixed_t thrust;
+
+ if (!mo->standingslope)
+ return;
+
+ if (mo->player) {
+ if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING))
+ return; // Don't slide on non-steep slopes unless spinning
+
+ if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy))
+ return; // Allow the player to stand still on slopes below a certain steepness
+ }
+
+ thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
+
+ if (mo->player && (mo->player->pflags & PF_SPINNING)) {
+ fixed_t mult = 0;
+ if (mo->momx || mo->momy) {
+ angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection;
+
+ if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0)
+ angle ^= ANGLE_180;
+
+ mult = FINECOSINE(angle >> ANGLETOFINESHIFT);
+ }
+
+ //CONS_Printf("%d\n", mult);
+
+ thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8);
+ }
+
+ if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed
+ thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16);
+ // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
+
+ // Multiply by gravity
+ thrust = FixedMul(thrust, FRACUNIT/2); // TODO actually get this
+
+ P_Thrust(mo, mo->standingslope->xydirection, thrust);
+}
+
+// EOF
+#endif // #ifdef ESLOPE
diff --git a/src/p_slopes.h b/src/p_slopes.h
new file mode 100644
index 000000000..f2d1cd81e
--- /dev/null
+++ b/src/p_slopes.h
@@ -0,0 +1,85 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2004 Stephen McGranahan
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+//--------------------------------------------------------------------------
+//
+// DESCRIPTION:
+// Slopes
+// SoM created 05/10/09
+//
+//-----------------------------------------------------------------------------
+
+#ifndef P_SLOPES_H__
+#define P_SLOPES_H__
+
+#ifdef ESLOPE
+void P_CalculateSlopeNormal(pslope_t *slope);
+void P_ReconfigureVertexSlope(pslope_t *slope);
+
+void P_ResetDynamicSlopes(void);
+void P_RunDynamicSlopes(void);
+// P_SpawnSlope_Line
+// Creates one or more slopes based on the given line type and front/back
+// sectors.
+void P_SpawnSlope_Line(int linenum);
+
+pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags);
+
+#ifdef SPRINGCLEAN
+// Loads just map objects that make slopes,
+// terrain affecting objects have to be spawned first
+void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum);
+
+typedef enum
+{
+ THING_SlopeFloorPointLine = 9500,
+ THING_SlopeCeilingPointLine = 9501,
+ THING_SetFloorSlope = 9502,
+ THING_SetCeilingSlope = 9503,
+ THING_CopyFloorPlane = 9510,
+ THING_CopyCeilingPlane = 9511,
+ THING_VavoomFloor=1500,
+ THING_VavoomCeiling=1501,
+ THING_VertexFloorZ=1504,
+ THING_VertexCeilingZ=1505,
+} slopething_e;
+#endif
+
+//
+// P_CopySectorSlope
+//
+// Searches through tagged sectors and copies
+//
+void P_CopySectorSlope(line_t *line);
+
+pslope_t *P_SlopeById(UINT16 id);
+
+// Returns the height of the sloped plane at (x, y) as a fixed_t
+fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
+
+// Lots of physics-based bullshit
+void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
+void P_SlopeLaunch(mobj_t *mo);
+void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
+void P_ButteredSlope(mobj_t *mo);
+
+#endif
+
+// EOF
+#endif // #ifdef ESLOPE
diff --git a/src/p_spec.c b/src/p_spec.c
index 8228c60b3..0d786c695 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -29,6 +29,7 @@
#include "r_main.h" //Two extra includes.
#include "r_sky.h"
#include "p_polyobj.h"
+#include "p_slopes.h"
#include "hu_stuff.h"
#include "m_misc.h"
#include "m_cond.h" //unlock triggers
@@ -1890,6 +1891,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|| specialtype == 304 // Ring count - Once
|| specialtype == 307 // Character ability - Once
|| specialtype == 308 // Race only - Once
+ || specialtype == 313 // No More Enemies - Once
|| specialtype == 315 // No of pushables - Once
|| specialtype == 318 // Unlockable trigger - Once
|| specialtype == 320 // Unlockable - Once
@@ -3364,6 +3366,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec)
{
ffloor_t *rover;
+ fixed_t top, bottom;
if (!mo->player) // should NEVER happen
return false;
@@ -3380,6 +3383,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
//if (!(rover->flags & FF_EXISTS))
// return false;
+ top = P_GetSpecialTopZ(mo, sector, targetsec);
+ bottom = P_GetSpecialBottomZ(mo, sector, targetsec);
+
// Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER)
{
@@ -3387,27 +3393,27 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
- if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight)
+ if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top)
return false;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(mo->eflags & MFE_VERTICALFLIP)
- || mo->z + mo->height != *rover->bottomheight)
+ || mo->z + mo->height != bottom)
return false;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
- if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight)
- || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight)))
+ if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom)
+ || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top)))
return false;
}
}
else
{
// Water and intangible FOFs
- if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight)
+ if (mo->z > top || (mo->z + mo->height) < bottom)
return false;
}
@@ -3425,9 +3431,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
{
if (mo->eflags & MFE_VERTICALFLIP)
- return (mo->z+mo->height == sec->ceilingheight && sec->flags & SF_FLIPSPECIAL_CEILING);
+ return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
else
- return (mo->z == sec->floorheight && sec->flags & SF_FLIPSPECIAL_FLOOR);
+ return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR);
}
/** Applies a sector special to a player.
@@ -3471,19 +3477,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
{
case 1: // Damage (Generic)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
- P_DamageMobj(player->mo, NULL, NULL, 1);
+ 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) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
- P_DamageMobj(player->mo, NULL, NULL, 1);
+ if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE))
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER);
break;
case 3: // Damage (Fire)
- if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
- P_DamageMobj(player->mo, NULL, NULL, 1);
+ if (roversector || P_MobjReadyToTrigger(player->mo, sector))
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_FIRE);
break;
case 4: // Damage (Electrical)
- if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT)
- P_DamageMobj(player->mo, NULL, NULL, 1);
+ if (roversector || P_MobjReadyToTrigger(player->mo, sector))
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC);
break;
case 5: // Spikes
// Don't do anything. In Soviet Russia, spikes find you.
@@ -3491,10 +3497,10 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
case 6: // Death Pit (Camera Mod)
case 7: // Death Pit (No Camera Mod)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
- P_DamageMobj(player->mo, NULL, NULL, 10000);
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT);
break;
case 8: // Instant Kill
- P_DamageMobj(player->mo, NULL, NULL, 10000);
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
break;
case 9: // Ring Drainer (Floor Touch)
case 10: // Ring Drainer (No Floor Touch)
@@ -3598,7 +3604,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
mo2 = (mobj_t *)th;
if (mo2->type == MT_EGGTRAP)
- P_KillMobj(mo2, NULL, player->mo);
+ P_KillMobj(mo2, NULL, player->mo, 0);
}
// clear the special so you can't push the button twice.
@@ -3684,7 +3690,7 @@ DoneSection2:
if (!(player->pflags & PF_SPINNING))
player->pflags |= PF_SPINNING;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
player->powers[pw_flashing] = TICRATE/3;
@@ -3826,7 +3832,7 @@ DoneSection2:
P_ResetPlayer(player);
if (player->panim != PA_FALL)
- P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
break;
case 6: // Super Sonic transformer
@@ -3838,7 +3844,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_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
S_StartAttackSound(player->mo, sfx_spin);
if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
@@ -3912,9 +3918,9 @@ DoneSection2:
player->pflags &= ~PF_GLIDING;
player->climbing = 0;
- if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4]))
+ if (player->mo->state-states != S_PLAY_SPIN)
{
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
S_StartSound(player->mo, sfx_spin);
}
}
@@ -3984,9 +3990,9 @@ DoneSection2:
player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED;
- if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4]))
+ if (player->mo->state-states != S_PLAY_SPIN)
{
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
S_StartSound(player->mo, sfx_spin);
}
}
@@ -4289,7 +4295,7 @@ DoneSection2:
player->pflags &= ~PF_SLIDING;
player->climbing = 0;
P_SetThingPosition(player->mo);
- P_SetPlayerMobjState(player->mo, S_PLAY_CARRY);
+ P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
}
break;
case 12: // Camera noclip
@@ -4388,27 +4394,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
- if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight)
+ if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))
continue;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(player->mo->eflags & MFE_VERTICALFLIP)
- || player->mo->z + player->mo->height != *rover->bottomheight)
+ || player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
continue;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
- if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight)
- || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight)))
+ if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
+ || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))))
continue;
}
}
else
{
// Water and DEATH FOG!!! heh
- if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight)
+ if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
continue;
}
@@ -4518,6 +4524,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
{
boolean nofloorneeded = false;
+ fixed_t f_affectpoint, c_affectpoint;
if (!sector->special) // nothing special, exit
return;
@@ -4580,16 +4587,19 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
return;
}
+ f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector);
+ c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector);
+
// Only go further if on the ground
- if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight)
+ if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint)
return;
- if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight)
+ if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint)
return;
if ((sector->flags & SF_FLIPSPECIAL_BOTH)
- && player->mo->z != sector->floorheight
- && player->mo->z + player->mo->height != sector->ceilingheight)
+ && player->mo->z != f_affectpoint
+ && player->mo->z + player->mo->height != c_affectpoint)
return;
P_ProcessSpecialSector(player, sector, NULL);
@@ -4750,6 +4760,9 @@ void P_UpdateSpecials(void)
// POINT LIMIT
P_CheckPointLimit();
+ // Dynamic slopeness
+ P_RunDynamicSlopes();
+
// ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++)
{
@@ -4893,6 +4906,12 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
ffloor->topyoffs = &sec2->ceiling_yoffs;
ffloor->topangle = &sec2->ceilingpic_angle;
+#ifdef ESLOPE
+ // Add slopes
+ ffloor->t_slope = &sec2->c_slope;
+ ffloor->b_slope = &sec2->f_slope;
+#endif
+
if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only
flags &= ~FF_BLOCKOTHERS;
@@ -5326,6 +5345,7 @@ void T_LaserFlash(laserthink_t *flash)
sector_t *sourcesec;
ffloor_t *ffloor = flash->ffloor;
sector_t *sector = flash->sector;
+ fixed_t top, bottom;
if (!ffloor || !(ffloor->flags & FF_EXISTS))
return;
@@ -5349,14 +5369,17 @@ void T_LaserFlash(laserthink_t *flash)
&& thing->flags & MF_BOSS)
continue; // Don't hurt bosses
- if (thing->z >= sourcesec->ceilingheight
- || thing->z + thing->height <= sourcesec->floorheight)
+ top = P_GetSpecialTopZ(thing, sourcesec, sector);
+ bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);
+
+ if (thing->z >= top
+ || thing->z + thing->height <= bottom)
continue;
if (thing->flags & MF_SHOOTABLE)
- P_DamageMobj(thing, NULL, NULL, 1);
+ P_DamageMobj(thing, NULL, NULL, 1, 0);
else if (thing->type == MT_EGGSHIELD)
- P_KillMobj(thing, NULL, NULL);
+ P_KillMobj(thing, NULL, NULL, 0);
}
}
@@ -6429,6 +6452,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
sectors[s].midmap = lines[i].frontsector->midmap;
break;
+#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
+ case 720:
+ case 721:
+ case 722:
+ P_CopySectorSlope(&lines[i]);
+ break;
+#endif
+
default:
break;
}
@@ -6526,7 +6557,7 @@ static void P_DoScrollMove(mobj_t *thing, fixed_t dx, fixed_t dy, INT32 exclusiv
thing->momy += dy;
if (exclusive)
- thing->flags2 |= MF2_PUSHED;
+ thing->eflags |= MFE_PUSHED;
}
/** Processes an active scroller.
@@ -6630,9 +6661,11 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
- if (thing->flags2 & MF2_PUSHED) // Already pushed this tic by an exclusive pusher.
+ if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher.
continue;
+ height = P_GetSpecialBottomZ(thing, sec, psec);
+
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height
{
@@ -6650,9 +6683,11 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
- if (thing->flags2 & MF2_PUSHED)
+ if (thing->eflags & MFE_PUSHED)
continue;
+ height = P_GetSpecialBottomZ(thing, sec, sec);
+
if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z > height)))
{
@@ -6689,9 +6724,11 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
- if (thing->flags2 & MF2_PUSHED)
+ if (thing->eflags & MFE_PUSHED)
continue;
+ height = P_GetSpecialTopZ(thing, sec, psec);
+
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height
{
@@ -6709,9 +6746,11 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
- if (thing->flags2 & MF2_PUSHED)
+ if (thing->eflags & MFE_PUSHED)
continue;
+ height = P_GetSpecialTopZ(thing, sec, sec);
+
if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height)))
{
@@ -7005,7 +7044,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32
*/
void T_Friction(friction_t *f)
{
- sector_t *sec;
+ sector_t *sec, *referrer = NULL;
mobj_t *thing;
msecnode_t *node;
@@ -7014,7 +7053,7 @@ void T_Friction(friction_t *f)
// Make sure the sector type hasn't changed
if (f->roverfriction)
{
- sector_t *referrer = sectors + f->referrer;
+ referrer = sectors + f->referrer;
if (!(GETSECSPECIAL(referrer->special, 3) == 1
|| GETSECSPECIAL(referrer->special, 3) == 3))
@@ -7046,9 +7085,7 @@ void T_Friction(friction_t *f)
{
if (f->roverfriction)
{
- sector_t *referrer = §ors[f->referrer];
-
- if (thing->floorz != referrer->ceilingheight)
+ if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec))
{
node = node->m_snext;
continue;
@@ -7061,7 +7098,7 @@ void T_Friction(friction_t *f)
thing->movefactor = f->movefactor;
}
}
- else if (sec->floorheight == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
+ else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
|| f->friction < thing->friction))
{
thing->friction = f->friction;
@@ -7192,7 +7229,7 @@ static pusher_t *tmpusher; // pusher structure for blockmap searches
*/
static inline boolean PIT_PushThing(mobj_t *thing)
{
- if (thing->flags2 & MF2_PUSHED)
+ if (thing->eflags & MFE_PUSHED)
return false;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
@@ -7322,7 +7359,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
}
if (tmpusher->exclusive)
- thing->flags2 |= MF2_PUSHED;
+ thing->eflags |= MFE_PUSHED;
return true;
}
@@ -7335,7 +7372,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
*/
void T_Pusher(pusher_t *p)
{
- sector_t *sec;
+ sector_t *sec, *referrer = NULL;
mobj_t *thing;
msecnode_t *node;
INT32 xspeed = 0,yspeed = 0;
@@ -7344,7 +7381,6 @@ void T_Pusher(pusher_t *p)
//INT32 ht = 0;
boolean inFOF;
boolean touching;
- boolean foundfloor = false;
boolean moved;
xspeed = yspeed = 0;
@@ -7356,19 +7392,16 @@ void T_Pusher(pusher_t *p)
if (p->roverpusher)
{
- sector_t *referrer = §ors[p->referrer];
+ referrer = §ors[p->referrer];
- if (GETSECSPECIAL(referrer->special, 3) == 2
- || GETSECSPECIAL(referrer->special, 3) == 3)
- foundfloor = true;
+ if (!(GETSECSPECIAL(referrer->special, 3) == 2
+ || GETSECSPECIAL(referrer->special, 3) == 3))
+ return;
}
else if (!(GETSECSPECIAL(sec->special, 3) == 2
|| GETSECSPECIAL(sec->special, 3) == 3))
return;
- if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK.
- return;
-
// For constant pushers (wind/current) there are 3 situations:
//
// 1) Affected Thing is above the floor.
@@ -7429,7 +7462,7 @@ void T_Pusher(pusher_t *p)
|| thing->type == MT_BIGTUMBLEWEED))
continue;
- if (thing->flags2 & MF2_PUSHED)
+ if (thing->eflags & MFE_PUSHED)
continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
@@ -7443,41 +7476,38 @@ void T_Pusher(pusher_t *p)
// Find the area that the 'thing' is in
if (p->roverpusher)
{
- sector_t *referrer = §ors[p->referrer];
- INT32 special;
+ fixed_t top, bottom;
- special = GETSECSPECIAL(referrer->special, 3);
-
- if (!(special == 2 || special == 3))
- return;
+ top = P_GetSpecialTopZ(thing, referrer, sec);
+ bottom = P_GetSpecialBottomZ(thing, referrer, sec);
if (thing->eflags & MFE_VERTICALFLIP)
{
- if (referrer->floorheight > thing->z + thing->height
- || referrer->ceilingheight < (thing->z + (thing->height >> 1)))
+ if (bottom > thing->z + thing->height
+ || top < (thing->z + (thing->height >> 1)))
continue;
- if (thing->z < referrer->floorheight)
+ if (thing->z < bottom)
touching = true;
- if (thing->z + (thing->height >> 1) > referrer->floorheight)
+ if (thing->z + (thing->height >> 1) > bottom)
inFOF = true;
}
else
{
- if (referrer->ceilingheight < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1)))
+ if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1)))
continue;
- if (thing->z + thing->height > referrer->ceilingheight)
+ if (thing->z + thing->height > top)
touching = true;
- if (thing->z + (thing->height >> 1) < referrer->ceilingheight)
+ if (thing->z + (thing->height >> 1) < top)
inFOF = true;
}
}
else // Treat the entire sector as one big FOF
{
- if (thing->z == thing->subsector->sector->floorheight)
+ if (thing->z == P_GetSpecialBottomZ(thing, sec, sec))
touching = true;
else if (p->type != p_current)
inFOF = true;
@@ -7599,7 +7629,7 @@ void T_Pusher(pusher_t *p)
}
if (p->exclusive)
- thing->flags2 |= MF2_PUSHED;
+ thing->eflags |= MFE_PUSHED;
}
}
}
diff --git a/src/p_tick.c b/src/p_tick.c
index 2973505f3..15d3abc80 100644
--- a/src/p_tick.c
+++ b/src/p_tick.c
@@ -662,7 +662,7 @@ void P_Ticker(boolean run)
if (!players[i].mo)
continue;
- P_DamageMobj(players[i].mo, NULL, NULL, 10000);
+ P_DamageMobj(players[i].mo, NULL, NULL, 1, DMG_INSTAKILL);
}
}
diff --git a/src/p_user.c b/src/p_user.c
index 6844d2cba..8854d8d64 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -29,6 +29,7 @@
#include "m_random.h"
#include "m_misc.h"
#include "i_video.h"
+#include "p_slopes.h"
#include "p_spec.h"
#include "r_splats.h"
#include "z_zone.h"
@@ -607,7 +608,7 @@ static void P_DeNightserizePlayer(player_t *player)
if (player->mo->tracer)
P_RemoveMobj(player->mo->tracer);
- P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
player->pflags |= PF_NIGHTSFALL;
// If in a special stage, add some preliminary exit time.
@@ -632,7 +633,7 @@ static void P_DeNightserizePlayer(player_t *player)
continue;
if (mo2->flags & MF_AMBUSH)
- P_DamageMobj(player->mo, NULL, NULL, 10000);
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
break;
}
@@ -970,7 +971,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
// Transformation animation
- P_SetPlayerMobjState(player->mo, S_PLAY_SUPERTRANS1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS);
player->mo->momx = player->mo->momy = player->mo->momz = 0;
@@ -1212,7 +1213,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
if (mo->eflags & MFE_VERTICALFLIP)
{
// Detect if the player is on the ceiling.
- if (mo->z+mo->height >= sec->ceilingheight)
+ if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true;
// Otherwise, detect if the player is on the bottom of a FOF.
else
@@ -1236,7 +1237,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue;
// Actually check if the player is on the suitable FOF.
- if (mo->z+mo->height == *rover->bottomheight)
+ if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec))
return true;
}
}
@@ -1245,7 +1246,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
else
{
// Detect if the player is on the floor.
- if (mo->z <= sec->floorheight)
+ if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true;
// Otherwise, detect if the player is on the top of a FOF.
else
@@ -1269,7 +1270,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue;
// Actually check if the player is on the suitable FOF.
- if (mo->z == *rover->topheight)
+ if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec))
return true;
}
}
@@ -1444,6 +1445,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->angle = mobj->angle;
ghost->sprite = mobj->sprite;
+ ghost->sprite2 = mobj->sprite2;
ghost->frame = mobj->frame;
ghost->tics = -1;
ghost->frame &= ~FF_TRANSMASK;
@@ -1596,7 +1598,7 @@ void P_DoPlayerExit(player_t *player)
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
player->powers[pw_underwater] = 0;
player->powers[pw_spacetime] = 0;
@@ -1789,6 +1791,9 @@ static void P_CheckBouncySectors(player_t *player)
fixed_t oldx;
fixed_t oldy;
fixed_t oldz;
+#ifdef ESLOPE
+ vector3_t momentum;
+#endif
oldx = player->mo->x;
oldy = player->mo->y;
@@ -1809,16 +1814,21 @@ static void P_CheckBouncySectors(player_t *player)
{
ffloor_t *rover;
boolean top = true;
+ fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
- if (player->mo->z > *rover->topheight)
+ topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+ bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+
+ if (player->mo->z > topheight)
continue;
- if (player->mo->z + player->mo->height < *rover->bottomheight)
+ if (player->mo->z + player->mo->height < bottomheight)
continue;
- if (oldz < *rover->topheight && oldz > *rover->bottomheight)
+ if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)
+ && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
top = false;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
@@ -1833,7 +1843,29 @@ static void P_CheckBouncySectors(player_t *player)
{
fixed_t newmom;
+#ifdef ESLOPE
+ pslope_t *slope;
+ if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top
+ slope = *rover->t_slope;
+ } else { // Hit bottom
+ slope = *rover->b_slope;
+ }
+
+ momentum.x = player->mo->momx;
+ momentum.y = player->mo->momy;
+ momentum.z = player->mo->momz*2;
+
+ if (slope) {
+ // Reverse quantizing might could use its own function later
+ slope->zangle = ANGLE_MAX-slope->zangle;
+ P_QuantizeMomentumToSlope(&momentum, slope);
+ slope->zangle = ANGLE_MAX-slope->zangle;
+ }
+
+ newmom = momentum.z = -FixedMul(momentum.z,linedist)/2;
+#else
newmom = -FixedMul(player->mo->momz,linedist);
+#endif
if (abs(newmom) < (linedist*2))
{
@@ -1856,7 +1888,18 @@ static void P_CheckBouncySectors(player_t *player)
else if (newmom < -P_GetPlayerHeight(player)/2)
newmom = -P_GetPlayerHeight(player)/2;
+#ifdef ESLOPE
+ momentum.z = newmom*2;
+
+ if (slope)
+ P_QuantizeMomentumToSlope(&momentum, slope);
+
+ player->mo->momx = momentum.x;
+ player->mo->momy = momentum.y;
+ player->mo->momz = momentum.z/2;
+#else
player->mo->momz = newmom;
+#endif
if (player->pflags & PF_SPINNING)
{
@@ -1997,21 +2040,15 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
// Underwater timer runs out
else if (player->powers[pw_underwater] == 1)
{
- mobj_t *killer;
-
if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
-
- killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL);
- killer->threshold = 42; // Special flag that it was drowning which killed you.
- P_DamageMobj(player->mo, killer, killer, 10000);
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED);
}
else if (player->powers[pw_spacetime] == 1)
{
if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
-
- P_DamageMobj(player->mo, NULL, NULL, 10000);
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN);
}
if (numbermobj)
@@ -2276,14 +2313,27 @@ static void P_DoClimbing(player_t *player)
boolean thrust;
boolean boostup;
boolean skyclimber;
+ fixed_t floorheight, ceilingheight; // ESLOPE
thrust = false;
floorclimb = false;
boostup = false;
skyclimber = false;
+#ifdef ESLOPE
+ floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y)
+ : glidesector->sector->floorheight;
+ ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y)
+ : glidesector->sector->ceilingheight;
+#else
+ floorheight = glidesector->sector->floorheight;
+ ceilingheight = glidesector->sector->ceilingheight;
+#endif
+
if (glidesector->sector->ffloors)
{
ffloor_t *rover;
+ fixed_t topheight, bottomheight; // ESLOPE
+
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
@@ -2291,13 +2341,21 @@ static void P_DoClimbing(player_t *player)
floorclimb = true;
+#ifdef ESLOPE
+ bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
+ topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
+#else
+ bottomheight = *rover->bottomheight;
+ topheight = *rover->topheight;
+#endif
+
// Only supports rovers that are moving like an 'elevator', not just the top or bottom.
if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
{
- if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height)
- && (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
- || ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z)
- && (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
+ if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
+ && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
+ || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
+ && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{
if (cmd->forwardmove != 0)
player->mo->momz += rover->master->frontsector->floorspeed;
@@ -2313,8 +2371,9 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
// Trying to climb down past the bottom of the FOF
- if ((*rover->topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= *rover->topheight))
+ if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
{
+ fixed_t bottomheight2;
ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
@@ -2329,7 +2388,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover)
continue;
- if (*roverbelow->bottomheight < *rover->topheight + FixedMul(16*FRACUNIT, player->mo->scale))
+#ifdef ESLOPE
+ bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight;
+#else
+ bottomheight2 = *roverbelow->bottomheight;
+#endif
+
+ if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true;
}
@@ -2338,7 +2403,7 @@ static void P_DoClimbing(player_t *player)
}
// Below the FOF
- if (*rover->topheight <= player->mo->z)
+ if (topheight <= player->mo->z)
{
floorclimb = false;
boostup = false;
@@ -2346,7 +2411,7 @@ static void P_DoClimbing(player_t *player)
}
// Above the FOF
- if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
+ if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
@@ -2356,8 +2421,9 @@ static void P_DoClimbing(player_t *player)
else
{
// Trying to climb down past the bottom of a FOF
- if ((*rover->bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= *rover->bottomheight))
+ if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
{
+ fixed_t topheight2;
ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
@@ -2372,7 +2438,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover)
continue;
- if (*roverbelow->topheight > *rover->bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
+#ifdef ESLOPE
+ topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight;
+#else
+ topheight2 = *roverbelow->topheight;
+#endif
+
+ if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true;
}
@@ -2381,7 +2453,7 @@ static void P_DoClimbing(player_t *player)
}
// Below the FOF
- if (*rover->bottomheight >= player->mo->z + player->mo->height)
+ if (bottomheight >= player->mo->z + player->mo->height)
{
floorclimb = false;
boostup = false;
@@ -2389,7 +2461,7 @@ static void P_DoClimbing(player_t *player)
}
// Above the FOF
- if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
+ if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
@@ -2410,7 +2482,7 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
// Trying to climb down past the upper texture area
- if ((glidesector->sector->floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= glidesector->sector->floorheight))
+ if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
{
boolean foundfof = false;
floorclimb = true;
@@ -2418,13 +2490,20 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{
+ fixed_t bottomheight;
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
- if (*rover->bottomheight < glidesector->sector->floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
+#ifdef ESLOPE
+ bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
+#else
+ bottomheight = *rover->bottomheight;
+#endif
+
+ if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
@@ -2437,8 +2516,8 @@ static void P_DoClimbing(player_t *player)
}
// Reached the top of the lower texture area
- if (!floorclimb && glidesector->sector->ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
- && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
+ if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
+ && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
@@ -2448,7 +2527,7 @@ static void P_DoClimbing(player_t *player)
else
{
// Trying to climb down past the upper texture area
- if ((glidesector->sector->ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= glidesector->sector->ceilingheight))
+ if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
{
boolean foundfof = false;
floorclimb = true;
@@ -2462,7 +2541,7 @@ static void P_DoClimbing(player_t *player)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
- if (*rover->topheight > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
@@ -2475,7 +2554,7 @@ static void P_DoClimbing(player_t *player)
}
// Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
- if (player->mo->z > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
+ if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = true;
thrust = false;
@@ -2483,8 +2562,8 @@ static void P_DoClimbing(player_t *player)
}
// Reached the top of the lower texture area
- if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
- && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
+ if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
+ && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
@@ -2493,14 +2572,14 @@ static void P_DoClimbing(player_t *player)
}
// Trying to climb on the sky
- if ((glidesector->sector->ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
+ if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
{
skyclimber = true;
}
// Climbing on the lower texture area?
- if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < glidesector->sector->floorheight)
- || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= glidesector->sector->floorheight))
+ if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight)
+ || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight))
{
floorclimb = true;
@@ -2516,8 +2595,8 @@ static void P_DoClimbing(player_t *player)
}
}
// Climbing on the upper texture area?
- else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= glidesector->sector->ceilingheight)
- || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > glidesector->sector->ceilingheight))
+ else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight)
+ || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight))
{
floorclimb = true;
@@ -2596,10 +2675,10 @@ static void P_DoClimbing(player_t *player)
climb = false;
if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz)
- && !(player->mo->state >= &states[S_PLAY_CLIMB2] && player->mo->state <= &states[S_PLAY_CLIMB5]))
- P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB2);
- else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state != &states[S_PLAY_CLIMB1])
- P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB1);
+ && player->mo->state-states != S_PLAY_CLIMB)
+ P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB);
+ else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING)
+ P_SetPlayerMobjState(player->mo, S_PLAY_CLING);
if (!floorclimb)
{
@@ -2610,21 +2689,21 @@ static void P_DoClimbing(player_t *player)
player->climbing = 0;
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
if (skyclimber)
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
}
else
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
if (cmd->sidemove != 0 || cmd->forwardmove != 0)
@@ -2633,16 +2712,16 @@ static void P_DoClimbing(player_t *player)
climb = false;
if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz)
- && !(player->mo->state >= &states[S_PLAY_CLIMB2] && player->mo->state <= &states[S_PLAY_CLIMB5]))
- P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB2);
- else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state != &states[S_PLAY_CLIMB1])
- P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB1);
+ && player->mo->state-states != S_PLAY_CLIMB)
+ P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB);
+ else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING)
+ P_SetPlayerMobjState(player->mo, S_PLAY_CLING);
if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPSTASIS))
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetObjectMomZ(player->mo, 4*FRACUNIT, false);
P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale));
}
@@ -2653,7 +2732,7 @@ static void P_DoClimbing(player_t *player)
localangle2 = player->mo->angle;
if (player->climbing == 0)
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
if (player->climbing && P_IsObjectOnGround(player->mo))
{
@@ -2963,6 +3042,8 @@ static void P_DoTeeter(player_t *player)
xh = (unsigned)(player->mo->x + player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT;
xl = (unsigned)(player->mo->x - player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
// Polyobjects
#ifdef POLYOBJECTS
validcount++;
@@ -3081,10 +3162,10 @@ teeterdone:
}
if (teeter)
{
- if ((player->mo->state == &states[S_PLAY_STND] || player->mo->state == &states[S_PLAY_TAP1] || player->mo->state == &states[S_PLAY_TAP2] || player->mo->state == &states[S_PLAY_SUPERSTAND]))
- P_SetPlayerMobjState(player->mo, S_PLAY_TEETER1);
+ if (player->panim == PA_IDLE)
+ P_SetPlayerMobjState(player->mo, S_PLAY_EDGE);
}
- else if (checkedforteeter && (player->mo->state == &states[S_PLAY_TEETER1] || player->mo->state == &states[S_PLAY_TEETER2] || player->mo->state == &states[S_PLAY_SUPERTEETER]))
+ else if (checkedforteeter && player->panim == PA_EDGE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
@@ -3330,8 +3411,9 @@ firenormal:
//
static void P_DoSuperStuff(player_t *player)
{
+ mobj_t *spark;
ticcmd_t *cmd = &player->cmd;
- if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9])
+ if (player->mo->state >= &states[S_PLAY_SUPER_TRANS] && player->mo->state <= &states[S_PLAY_SUPER_TRANS9])
return; // don't do anything right now, we're in the middle of transforming!
if (player->pflags & PF_NIGHTSMODE)
@@ -3384,19 +3466,32 @@ static void P_DoSuperStuff(player_t *player)
switch (player->skin)
{
case 1: // Golden orange supertails.
- player->mo->color = SKINCOLOR_TSUPER1 + (leveltime/2) % 5;
+ if (leveltime % 9 < 5)
+ player->mo->color = SKINCOLOR_TSUPER1 + leveltime % 9;
+ else
+ player->mo->color = SKINCOLOR_TSUPER1 + 9 - leveltime % 9;
break;
case 2: // Pink superknux.
- player->mo->color = SKINCOLOR_KSUPER1 + (leveltime/2) % 5;
+ if (leveltime % 9 < 5)
+ player->mo->color = SKINCOLOR_KSUPER1 + leveltime % 9;
+ else
+ player->mo->color = SKINCOLOR_KSUPER1 + 9 - leveltime % 9;
break;
default: // Yousa yellow now!
- player->mo->color = SKINCOLOR_SUPER1 + (leveltime/2) % 5;
+ if (leveltime % 9 < 5)
+ player->mo->color = SKINCOLOR_SUPER1 + leveltime % 9;
+ else
+ player->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
break;
}
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
- P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
+ {
+ spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
+ spark->destscale = player->mo->scale;
+ P_SetScale(spark, player->mo->scale);
+ }
G_GhostAddColor(GHC_SUPER);
@@ -3425,14 +3520,35 @@ static void P_DoSuperStuff(player_t *player)
if (player->mo->health > 0)
{
- if ((player->pflags & PF_JUMPED) || (player->pflags & PF_SPINNING))
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
- else if (player->panim == PA_RUN)
- P_SetPlayerMobjState(player->mo, S_PLAY_SPD1);
- else if (player->panim == PA_WALK)
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
- else
+ if ((player->pflags & PF_JUMPED || player->pflags & PF_SPINNING)
+ && player->mo->state-states != S_PLAY_DASH)
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
+ else switch (player->mo->state-states)
+ {
+ default:
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
+ break;
+ case S_PLAY_DASH:
+ break;
+ case S_PLAY_SUPER_WALK:
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
+ break;
+ case S_PLAY_SUPER_RUN:
+ P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
+ break;
+ case S_PLAY_SUPER_PAIN:
+ P_SetPlayerMobjState(player->mo, S_PLAY_PAIN);
+ break;
+ case S_PLAY_SUPER_JUMP:
+ P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
+ break;
+ case S_PLAY_SUPER_FALL:
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
+ break;
+ case S_PLAY_SUPER_RIDE:
+ P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
+ break;
+ }
if (!player->exiting)
{
@@ -3619,11 +3735,22 @@ void P_DoJump(player_t *player, boolean soundandstate)
// set just an eensy above the ground
if (player->mo->eflags & MFE_VERTICALFLIP)
+ {
player->mo->z--;
+ if (player->mo->pmomz < 0)
+ player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
+ else
+ player->mo->pmomz = 0;
+ }
else
+ {
player->mo->z++;
-
- player->mo->z += player->mo->pmomz; // Solves problem of 'hitting around again after jumping on a moving platform'.
+ if (player->mo->pmomz > 0)
+ player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
+ else
+ player->mo->pmomz = 0;
+ }
+ player->mo->eflags &= ~MFE_APPLYPMOMZ;
player->pflags |= PF_JUMPED;
@@ -3633,9 +3760,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
S_StartSound(player->mo, sfx_jump); // Play jump sound!
if (!(player->charability2 == CA2_SPINDASH))
- P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
+ P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
else
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
}
@@ -3661,14 +3788,18 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting
&& !P_PlayerInPain(player)) // subsequent revs
{
- if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
+ if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)
+#ifdef ESLOPE
+ && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+#endif
+ )
{
player->mo->momx = player->cmomx;
player->mo->momy = player->cmomy;
player->pflags |= PF_STARTDASH|PF_SPINNING;
player->dashspeed = FixedMul(FRACUNIT, player->mo->scale);
player->dashtime = 0;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
player->pflags |= PF_USEDOWN;
}
else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH))
@@ -3681,19 +3812,26 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
S_StartSound(player->mo, sfx_spndsh); // Make the rev sound!
// Now spawn the color thok circle.
- P_SpawnSpinMobj(player, player->revitem);
- if (demorecording)
- G_GhostAddRev();
+ if (player->mo->sprite2 != SPR2_DASH)
+ {
+ P_SpawnSpinMobj(player, player->revitem);
+ if (demorecording)
+ G_GhostAddRev();
+ }
}
}
// If not moving up or down, and travelling faster than a speed of four while not holding
// down the spin button and not spinning.
// AKA Just go into a spin on the ground, you idiot. ;)
else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20))
- && !player->climbing && !player->mo->momz && onground && player->speed > FixedMul(5<mo->scale) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
+ && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<mo->scale)
+#ifdef ESLOPE
+ || (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
+#endif
+ ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
{
player->pflags |= PF_SPINNING;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
if (!player->spectator)
S_StartSound(player->mo, sfx_spin);
player->pflags |= PF_USEDOWN;
@@ -3702,7 +3840,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
// Rolling normally
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
- && player->speed < FixedMul(5*FRACUNIT,player->mo->scale))
+ && player->speed < FixedMul(5*FRACUNIT,player->mo->scale)
+#ifdef ESLOPE
+ && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+#endif
+ )
{
if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
@@ -3725,6 +3867,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
player->pflags &= ~PF_STARTDASH;
if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE))
{
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!!
if (!player->spectator)
S_StartSound(player->mo, sfx_zoom);
@@ -3732,8 +3875,10 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
player->dashspeed = 0;
}
- if (onground && (player->pflags & PF_SPINNING) && !(player->panim == PA_ROLL))
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ if (onground && player->pflags & PF_STARTDASH && player->mo->state-states != S_PLAY_DASH)
+ P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
+ else if (onground && player->pflags & PF_SPINNING && !(player->panim == PA_ROLL))
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
//
@@ -3753,7 +3898,7 @@ void P_DoJumpShield(player_t *player)
player->jumping = 0;
player->pflags |= PF_THOKKED;
player->pflags &= ~PF_SPINNING;
- P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
S_StartSound(player->mo, sfx_wdjump);
}
@@ -3980,7 +4125,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
; // Can't do anything if you're a fish out of water!
else if (!(player->pflags & PF_THOKKED) && !(player->powers[pw_tailsfly]))
{
- P_SetPlayerMobjState(player->mo, S_PLAY_ABL1); // Change to the flying animation
+ P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation
player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer
@@ -4006,7 +4151,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->pflags &= ~PF_THOKKED;
}
- P_SetPlayerMobjState(player->mo, S_PLAY_ABL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
P_InstaThrust(player->mo, player->mo->angle, FixedMul(glidespeed, player->mo->scale));
player->pflags &= ~(PF_SPINNING|PF_STARTDASH);
}
@@ -4240,7 +4385,7 @@ static void P_2dMovement(player_t *player)
else if (player->exiting)
{
player->pflags &= ~PF_GLIDING;
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
player->skidtime = 0;
}
}
@@ -4406,12 +4551,16 @@ static void P_3dMovement(player_t *player)
angle_t dangle; // replaces old quadrants bits
fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
boolean analogmove = false;
-#ifndef OLD_MOVEMENT_CODE
fixed_t oldMagnitude, newMagnitude;
+#ifdef ESLOPE
+ vector3_t totalthrust;
+
+ totalthrust.x = totalthrust.y = 0; // I forget if this is needed
+ totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes
+#endif // ESLOPE
// Get the old momentum; this will be needed at the end of the function! -SH
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
-#endif
analogmove = P_AnalogMove(player);
@@ -4427,7 +4576,7 @@ static void P_3dMovement(player_t *player)
else if (player->exiting)
{
player->pflags &= ~PF_GLIDING;
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
player->skidtime = 0;
}
}
@@ -4588,17 +4737,10 @@ static void P_3dMovement(player_t *player)
}
movepushforward = FixedMul(movepushforward, player->mo->scale);
-#ifdef OLD_MOVEMENT_CODE
- if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed
- P_Thrust(player->mo, movepushangle, movepushforward);
- else if (mforward && cmd->forwardmove < 0)
- P_Thrust(player->mo, movepushangle, movepushforward);
- else if (player->speed < topspeed && mbackward && cmd->forwardmove < 0)
- P_Thrust(player->mo, movepushangle, movepushforward);
- else if (mbackward && cmd->forwardmove > 0)
- P_Thrust(player->mo, movepushangle, movepushforward);
- else if (!mforward && !mbackward)
- P_Thrust(player->mo, movepushangle, movepushforward);
+
+#ifdef ESLOPE
+ totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward);
+ totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward);
#else
P_Thrust(player->mo, movepushangle, movepushforward);
#endif
@@ -4617,33 +4759,12 @@ static void P_3dMovement(player_t *player)
if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player)))
{
angle_t controldirection;
-#ifdef OLD_MOVEMENT_CODE
- angle_t controlplayerdirection;
- boolean cforward; // controls pointing forward from the player
- boolean cbackward; // controls pointing backward from the player
- angle_t dangle;
- cforward = cbackward = false;
-#endif
// Calculate the angle at which the controls are pointing
// to figure out the proper mforward and mbackward.
// (Why was it so complicated before? ~Red)
controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle;
-#ifdef OLD_MOVEMENT_CODE
- controlplayerdirection = player->mo->angle;
-
- dangle = controldirection - controlplayerdirection;
-
- if (dangle > ANGLE_180) //flip to keep to one side
- dangle = InvAngle(dangle);
-
- if (dangle > ANGLE_90)
- cbackward = true; // Controls pointing backwards from player
- else
- cforward = true; // Controls pointing in player's general direction
-#endif
-
movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
// allow very small movement while in air for gameplay
@@ -4666,13 +4787,10 @@ static void P_3dMovement(player_t *player)
movepushsideangle = controldirection;
movepushforward = FixedMul(movepushforward, player->mo->scale);
-#ifdef OLD_MOVEMENT_CODE
- if (player->speed < topspeed)
- P_Thrust(player->mo, controldirection, movepushforward);
- else if ((mforward) && (cbackward))
- P_Thrust(player->mo, controldirection, movepushforward);
- else if ((mbackward) && (cforward))
- P_Thrust(player->mo, controldirection, movepushforward);
+
+#ifdef ESLOPE
+ totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward);
+ totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward);
#else
P_Thrust(player->mo, controldirection, movepushforward);
#endif
@@ -4680,29 +4798,6 @@ static void P_3dMovement(player_t *player)
}
else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player))
{
-#ifdef OLD_MOVEMENT_CODE
- boolean mright = 0;
- boolean mleft = 0;
- angle_t sideangle;
-
- sideangle = player->mo->angle - ANGLE_90;
-
- // Monster Iestyn - 04-11-13
- // Quadrants are stupid, excessive and broken, let's do this a much simpler way!
- // Get delta angle from rmom angle and player angle first
- dangle = R_PointToAngle2(0,0, player->rmomx, player->rmomy) - sideangle;
- if (dangle > ANGLE_180)
- dangle = InvAngle(dangle);
-
- // now use it to determine direction!
- if (dangle <= ANGLE_45) // angles 0-45 or 315-360
- mright = 1; // going right
- else if (dangle >= ANGLE_135) // angles 135-225
- mleft = 1; // going left
-
- // anything else will leave both at 0, so no need to do anything else
-#endif
-
movepushside = cmd->sidemove * (thrustfactor * acceleration);
if (!onground)
@@ -4725,19 +4820,37 @@ static void P_3dMovement(player_t *player)
// Finally move the player now that his speed/direction has been decided.
movepushside = FixedMul(movepushside, player->mo->scale);
-#ifdef OLD_MOVEMENT_CODE
- if (player->speed < topspeed)
- P_Thrust(player->mo, movepushsideangle, movepushside);
- else if (mright && cmd->sidemove < 0)
- P_Thrust(player->mo, movepushsideangle, movepushside);
- else if (mleft && cmd->sidemove > 0)
- P_Thrust(player->mo, movepushsideangle, movepushside);
+
+#ifdef ESLOPE
+ totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside);
+ totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside);
#else
P_Thrust(player->mo, movepushsideangle, movepushside);
#endif
}
-#ifndef OLD_MOVEMENT_CODE
+#ifdef ESLOPE
+ if ((totalthrust.x || totalthrust.y)
+ && player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
+ // Factor thrust to slope, but only for the part pushing up it!
+ // The rest is unaffected.
+ angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
+
+ if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward
+ if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) {
+ P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
+ }
+ } else { // Direction goes up, so thrustangle needs to face away
+ if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) {
+ P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
+ }
+ }
+ }
+
+ player->mo->momx += totalthrust.x;
+ player->mo->momy += totalthrust.y;
+#endif
+
// Time to ask three questions:
// 1) Are we over topspeed?
// 2) If "yes" to 1, were we moving over topspeed to begin with?
@@ -4771,7 +4884,6 @@ static void P_3dMovement(player_t *player)
player->mo->momy = tempmomy + player->cmomy;
}
}
-#endif
}
//
@@ -6006,7 +6118,7 @@ static void P_NiGHTSMovement(player_t *player)
if (player->powers[pw_flashing] == 1)
player->powers[pw_flashing] = 3;
else
- P_DamageMobj(player->mo, NULL, NULL, 1);
+ P_DamageMobj(player->mo, NULL, NULL, 1, 0);
}
if (movingangle >= ANGLE_90 && movingangle <= ANGLE_180)
@@ -6165,7 +6277,7 @@ static void P_SkidStuff(player_t *player)
{
player->skidtime = 0;
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
- P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
}
// Get up and brush yourself off, idiot.
else if (player->glidetime > 15)
@@ -6231,7 +6343,7 @@ static void P_SkidStuff(player_t *player)
player->skidtime = TICRATE/2;
S_StartSound(player->mo, sfx_skid);
if (player->panim != PA_WALK)
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN4); // this switches to S_PLAY_SUPERWALK1 for superanims
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
player->mo->tics = player->skidtime;
}
}
@@ -6256,7 +6368,7 @@ static void P_MovePlayer(player_t *player)
if (countdowntimeup)
return;
- if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9])
+ if (player->mo->state >= &states[S_PLAY_SUPER_TRANS] && player->mo->state <= &states[S_PLAY_SUPER_TRANS9])
{
player->mo->momx = player->mo->momy = player->mo->momz = 0;
return;
@@ -6368,7 +6480,7 @@ static void P_MovePlayer(player_t *player)
players[i].exiting = (14*TICRATE)/5 + 1;
}
else if (player->health > 1)
- P_DamageMobj(player->mo, NULL, NULL, 1);
+ P_DamageMobj(player->mo, NULL, NULL, 1, 0);
player->pflags &= ~PF_NIGHTSFALL;
}
}
@@ -6400,28 +6512,37 @@ static void P_MovePlayer(player_t *player)
// MOVEMENT ANIMATIONS //
/////////////////////////
- if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && player->mo->z > player->mo->floorz))
+ if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && !onground))
{
// If the player is moving fast enough,
// break into a run!
if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || player->powers[pw_super]))
- P_SetPlayerMobjState (player->mo, S_PLAY_SPD1);
+ P_SetPlayerMobjState (player->mo, S_PLAY_RUN);
+
+ // Super floating at slow speeds has its own special animation.
+ else if (player->powers[pw_super] && player->panim == PA_IDLE && !onground)
+ P_SetPlayerMobjState (player->mo, S_PLAY_SUPER_FLOAT);
// Otherwise, just walk.
else if ((player->rmomx || player->rmomy) && player->panim == PA_IDLE)
- P_SetPlayerMobjState (player->mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState (player->mo, S_PLAY_WALK);
}
// If your running animation is playing, and you're
// going too slow, switch back to the walking frames.
if (player->panim == PA_RUN && player->speed < runspd)
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
+ {
+ if (!onground && player->powers[pw_super])
+ P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_FLOAT);
+ else
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
+ }
// If Springing, but travelling DOWNWARD, change back!
- if (player->mo->state == &states[S_PLAY_SPRING] && P_MobjFlip(player->mo)*player->mo->momz < 0)
- P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
+ if (player->panim == PA_JUMP && P_MobjFlip(player->mo)*player->mo->momz < 0)
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
// If Springing but on the ground, change back!
- else if (onground && (player->mo->state == &states[S_PLAY_SPRING] || player->panim == PA_FALL || player->mo->state == &states[S_PLAY_CARRY]) && !player->mo->momz)
+ else if (onground && (player->panim == PA_JUMP || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
// If you are stopped and are still walking, stand still!
@@ -6456,11 +6577,11 @@ static void P_MovePlayer(player_t *player)
if (player->pflags & PF_GLIDING || player->climbing)
{
if (onground)
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else
{
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
}
player->pflags &= ~PF_GLIDING;
@@ -6513,19 +6634,19 @@ static void P_MovePlayer(player_t *player)
{
P_ResetPlayer(player); // down, stop gliding.
if (onground)
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if ((player->charability2 == CA2_MULTIABILITY)
|| (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_GLIDEANDCLIMB))
{
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
else
{
player->pflags |= PF_THOKKED;
player->mo->momx >>= 1;
player->mo->momy >>= 1;
- P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
}
}
}
@@ -6581,14 +6702,14 @@ static void P_MovePlayer(player_t *player)
if (!(player->charability == CA_FLY || player->charability == CA_SWIM)) // why are you flying when you cannot fly?!
{
if (player->powers[pw_tailsfly]
- || (player->mo->state >= &states[S_PLAY_SPC1] && player->mo->state <= &states[S_PLAY_SPC4]))
+ || player->mo->state-states == S_PLAY_FLY_TIRED)
{
if (onground)
- P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else
{
player->pflags |= PF_JUMPED;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
}
player->powers[pw_tailsfly] = 0;
@@ -6640,11 +6761,10 @@ static void P_MovePlayer(player_t *player)
{
// Tails-gets-tired Stuff
if (player->panim == PA_ABILITY)
- P_SetPlayerMobjState(player->mo, S_PLAY_SPC4);
+ P_SetPlayerMobjState(player->mo, S_PLAY_FLY_TIRED);
if (player->charability == CA_FLY && (leveltime % 10 == 0)
- && player->mo->state >= &states[S_PLAY_SPC1]
- && player->mo->state <= &states[S_PLAY_SPC4]
+ && player->mo->state-states == S_PLAY_FLY_TIRED
&& !player->spectator)
S_StartSound(player->mo, sfx_pudpud);
}
@@ -6739,7 +6859,7 @@ static void P_MovePlayer(player_t *player)
}
// Otherwise, face the direction you're travelling.
else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL
- || ((player->mo->state >= &states[S_PLAY_ABL1] && player->mo->state <= &states[S_PLAY_SPC4]) && player->charability == CA_FLY))
+ || (player->mo->state-states == S_PLAY_FLY || player->mo->state-states == S_PLAY_FLY_TIRED))
player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
// Update the local angle control.
@@ -6787,8 +6907,8 @@ static void P_MovePlayer(player_t *player)
if (player->charflags & SF_SUPER && player->powers[pw_super] && player->speed > FixedMul(5<mo->scale)
&& P_MobjFlip(player->mo)*player->mo->momz <= 0)
{
- if (player->panim == PA_ROLL || player->mo->state == &states[S_PLAY_PAIN])
- P_SetPlayerMobjState(player->mo, S_PLAY_SUPERWALK1);
+ if (player->panim == PA_ROLL || player->mo->state-states == S_PLAY_PAIN || player->panim == PA_WALK)
+ P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_FLOAT);
player->mo->momz = 0;
player->pflags &= ~PF_SPINNING;
@@ -6847,7 +6967,7 @@ static void P_MovePlayer(player_t *player)
}
// Make sure you're not teetering when you shouldn't be.
- if ((player->mo->state == &states[S_PLAY_TEETER1] || player->mo->state == &states[S_PLAY_TEETER2] || player->mo->state == &states[S_PLAY_SUPERTEETER])
+ if (player->panim == PA_EDGE
&& (player->mo->momx || player->mo->momy || player->mo->momz))
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
@@ -6873,10 +6993,10 @@ static void P_MovePlayer(player_t *player)
fixed_t oldheight = player->mo->height;
// Less height while spinning. Good for spinning under things...?
- if ((player->mo->state == &states[player->mo->info->painstate] || player->mo->state == &states[S_PLAY_SUPERHIT])
+ if ((player->mo->state == &states[player->mo->info->painstate] || player->mo->state == &states[S_PLAY_SUPER_PAIN])
|| (player->charability2 == CA2_SPINDASH && (player->pflags & (PF_SPINNING|PF_JUMPED)))
|| player->powers[pw_tailsfly] || player->pflags & PF_GLIDING
- || (player->charability == CA_FLY && (player->mo->state >= &states[S_PLAY_SPC1] && player->mo->state <= &states[S_PLAY_SPC4])))
+ || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
player->mo->height = P_GetPlayerSpinHeight(player);
else
player->mo->height = P_GetPlayerHeight(player);
@@ -6892,18 +7012,14 @@ static void P_MovePlayer(player_t *player)
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING))
{
player->pflags |= PF_SPINNING;
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
else if (player->mo->ceilingz - player->mo->floorz < player->mo->height)
{
if ((netgame || multiplayer) && player->spectator)
- P_DamageMobj(player->mo, NULL, NULL, 42000); // Respawn crushed spectators
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
- {
- mobj_t *killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL);
- killer->threshold = 44; // Special flag that it was crushing which killed you.
- P_DamageMobj(player->mo, killer, killer, 10000);
- }
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED);
if (player->playerstate == PST_DEAD)
return;
@@ -7173,7 +7289,7 @@ static void P_DoRopeHang(player_t *player)
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
return;
}
@@ -7290,7 +7406,7 @@ static void P_DoRopeHang(player_t *player)
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
P_SetTarget(&player->mo->tracer, NULL);
@@ -7334,7 +7450,7 @@ static void P_NukeAllPlayers(player_t *player)
if (mo == player->mo)
continue;
- P_DamageMobj(mo, player->mo, player->mo, 1);
+ P_DamageMobj(mo, player->mo, player->mo, 1, 0);
}
CONS_Printf(M_GetText("%s caused a world of pain.\n"), player_names[player-players]);
@@ -7392,12 +7508,12 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
mo->flags |= MF_SPECIAL|MF_SHOOTABLE;
if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield!
- P_KillMobj(mo->tracer, inflictor, source);
+ P_KillMobj(mo->tracer, inflictor, source, 0);
if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players!
- P_DamageMobj(mo, inflictor, source, 1);
+ P_DamageMobj(mo, inflictor, source, 1, 0);
else
- P_DamageMobj(mo, inflictor, source, 1000);
+ P_DamageMobj(mo, inflictor, source, 1000, 0);
}
}
@@ -7769,24 +7885,24 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
angle_t angle = 0, focusangle = 0, focusaiming = 0;
fixed_t x, y, z, dist, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
INT32 camrotate;
- boolean camstill, forceon = false, cameranoclip;
+ boolean camstill, cameranoclip;
mobj_t *mo;
subsector_t *newsubsec;
fixed_t f1, f2;
cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
- if (player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD)
- forceon = true;
+ if (!(player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD))
+ {
+ if (player->spectator) // force cam off for spectators
+ return true;
- if (!forceon && player->spectator) // force cam off for spectators
- return true;
+ if (!cv_chasecam.value && thiscam == &camera)
+ return true;
- if (!forceon && !cv_chasecam.value && thiscam == &camera)
- return true;
-
- if (!forceon && !cv_chasecam2.value && thiscam == &camera2)
- return true;
+ if (!cv_chasecam2.value && thiscam == &camera2)
+ return true;
+ }
if (!thiscam->chase && !resetcalled)
{
@@ -8085,6 +8201,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
+ BMBOUNDFIX(xl, xh, yl, yh);
+
for (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++)
{
@@ -8601,10 +8719,10 @@ void P_PlayerThink(player_t *player)
if (player->pflags & PF_GLIDING)
{
if (player->panim != PA_ABILITY)
- P_SetPlayerMobjState(player->mo, S_PLAY_ABL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
}
else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
if (player->flashcount)
player->flashcount--;
@@ -8670,7 +8788,7 @@ void P_PlayerThink(player_t *player)
}
player->lives = 2; // Don't start the game over music!
- P_DamageMobj(player->mo, NULL, NULL, 10000);
+ P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
player->lives = 0;
if (player->playerstate == PST_DEAD)
@@ -8844,14 +8962,14 @@ void P_PlayerThink(player_t *player)
ticmiss++;
P_DoRopeHang(player);
- P_SetPlayerMobjState(player->mo, S_PLAY_CARRY);
+ P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
P_DoJumpStuff(player, &player->cmd);
}
else
{
P_DoZoomTube(player);
if (!(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
}
player->rmomx = player->rmomy = 0; // no actual momentum from your controls
P_ResetScore(player);
@@ -9028,7 +9146,6 @@ void P_PlayerThink(player_t *player)
player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
}
- player->mo->pmomz = 0;
player->pflags &= ~PF_SLIDING;
/*
@@ -9077,7 +9194,7 @@ void P_PlayerAfterThink(player_t *player)
{
ticcmd_t *cmd;
INT32 oldweapon = player->currentweapon;
- camera_t *thiscam;
+ camera_t *thiscam = NULL; // if not one of the displayed players, just don't bother
#ifdef PARANOIA
if (!player->mo)
@@ -9091,7 +9208,7 @@ void P_PlayerAfterThink(player_t *player)
if (splitscreen && player == &players[secondarydisplayplayer])
thiscam = &camera2;
- else
+ else if (player == &players[displayplayer])
thiscam = &camera;
if (player->playerstate == PST_DEAD)
@@ -9099,7 +9216,7 @@ void P_PlayerAfterThink(player_t *player)
// camera may still move when guy is dead
//if (!netgame)
{
- if (((splitscreen && player == &players[secondarydisplayplayer]) || player == &players[displayplayer]) && thiscam->chase)
+ if (thiscam && thiscam->chase)
P_MoveChaseCamera(player, thiscam, false);
}
return;
@@ -9225,7 +9342,7 @@ void P_PlayerAfterThink(player_t *player)
if (player->pflags & PF_GLIDING)
{
if (player->panim != PA_ABILITY)
- P_SetPlayerMobjState(player->mo, S_PLAY_ABL1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
}
else if (player->pflags & PF_SLIDING)
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
@@ -9233,17 +9350,15 @@ void P_PlayerAfterThink(player_t *player)
&& ((!player->powers[pw_super] && player->panim != PA_ROLL)
|| player->mo->state == &states[player->mo->info->painstate])
&& player->charability2 == CA2_SPINDASH)
- P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
+ P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
if (player->pflags & PF_CARRIED && player->mo->tracer)
{
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
- // State check for the carrier - Flame
- // You are an IDIOT, those aren't even the right frames! >_> - JTE
if (player->mo->tracer->player
- && !(player->mo->tracer->state >= &states[S_PLAY_ABL1]
- && player->mo->tracer->state <= &states[S_PLAY_SPC4]))
+ && player->mo->tracer->state-states != S_PLAY_FLY
+ && player->mo->tracer->state-states != S_PLAY_FLY_TIRED)
player->pflags &= ~PF_CARRIED;
if (player->mo->eflags & MFE_VERTICALFLIP)
@@ -9286,7 +9401,7 @@ void P_PlayerAfterThink(player_t *player)
if (P_AproxDistance(player->mo->x - player->mo->tracer->x, player->mo->y - player->mo->tracer->y) > player->mo->radius)
player->pflags &= ~PF_CARRIED;
- P_SetPlayerMobjState(player->mo, S_PLAY_CARRY);
+ P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, !(player->pflags & PF_CARRIED));
@@ -9303,7 +9418,7 @@ void P_PlayerAfterThink(player_t *player)
player->mo->z = player->mo->tracer->z - FixedDiv(player->mo->height, 3*FRACUNIT/2);
player->mo->momx = player->mo->momy = player->mo->momz = 0;
P_SetThingPosition(player->mo);
- P_SetPlayerMobjState(player->mo, S_PLAY_CARRY);
+ P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
// Controllable missile
if (player->mo->tracer->type == MT_BLACKEGGMAN_MISSILE)
@@ -9354,7 +9469,7 @@ void P_PlayerAfterThink(player_t *player)
}
}
- if ((splitscreen && player == &players[secondarydisplayplayer]) || player == &players[displayplayer])
+ if (thiscam)
{
if (!thiscam->chase) // bob view only if looking through the player's eyes
{
@@ -9381,4 +9496,7 @@ void P_PlayerAfterThink(player_t *player)
player->mo->flags2 |= MF2_DONTDRAW;
player->mo->flags |= MF_NOGRAVITY;
}
+
+ if (P_IsObjectOnGround(player->mo))
+ player->mo->pmomz = 0;
}
diff --git a/src/r_bsp.c b/src/r_bsp.c
index e967e28ce..badf8bdac 100644
--- a/src/r_bsp.c
+++ b/src/r_bsp.c
@@ -18,6 +18,7 @@
#include "r_splats.h"
#include "p_local.h" // camera
+#include "p_slopes.h"
#include "z_zone.h" // Check R_Prep3DFloors
seg_t *curline;
@@ -459,6 +460,11 @@ static void R_AddLine(seg_t *line)
doorclosed = 0;
// Closed door.
+#ifdef ESLOPE
+ // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than
+ // random renderer stopping around slopes...
+ if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
+#endif
if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight)
{
@@ -487,6 +493,10 @@ static void R_AddLine(seg_t *line)
#endif
backsector->ceilingpic == frontsector->ceilingpic
&& backsector->floorpic == frontsector->floorpic
+#ifdef ESLOPE
+ && backsector->f_slope == frontsector->f_slope
+ && backsector->c_slope == frontsector->c_slope
+#endif
&& backsector->lightlevel == frontsector->lightlevel
&& !curline->sidedef->midtexture
// Check offsets too!
@@ -842,11 +852,19 @@ static void R_Subsector(size_t num)
sub->sector->moved = frontsector->moved = false;
}
- light = R_GetPlaneLight(frontsector, frontsector->floorheight, false);
+ light = R_GetPlaneLight(frontsector,
+#ifdef ESLOPE
+ frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
+#endif
+ frontsector->floorheight, false);
if (frontsector->floorlightsec == -1)
floorlightlevel = *frontsector->lightlist[light].lightlevel;
floorcolormap = frontsector->lightlist[light].extra_colormap;
- light = R_GetPlaneLight(frontsector, frontsector->ceilingheight, false);
+ light = R_GetPlaneLight(frontsector,
+#ifdef ESLOPE
+ frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
+#endif
+ frontsector->ceilingheight, false);
if (frontsector->ceilinglightsec == -1)
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
ceilingcolormap = frontsector->lightlist[light].extra_colormap;
@@ -854,32 +872,52 @@ static void R_Subsector(size_t num)
sub->sector->extra_colormap = frontsector->extra_colormap;
- if ((frontsector->floorheight < viewz || (frontsector->heightsec != -1
+ if (((
+#ifdef ESLOPE
+ frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
+#endif
+ frontsector->floorheight) < viewz || (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].ceilingpic == skyflatnum)))
{
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
- frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL);
+ frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
+#ifdef ESLOPE
+ , frontsector->f_slope
+#endif
+ );
}
else
floorplane = NULL;
- if ((frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum
+ if (((
+#ifdef ESLOPE
+ frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) :
+#endif
+ frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum
|| (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].floorpic == skyflatnum)))
{
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
- ceilingcolormap, NULL);
+ ceilingcolormap, NULL
+#ifdef ESLOPE
+ , frontsector->c_slope
+#endif
+ );
}
else
ceilingplane = NULL;
numffloors = 0;
+#ifdef ESLOPE
+ ffloor[numffloors].slope = NULL;
+#endif
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (frontsector->ffloors)
{
ffloor_t *rover;
+ fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz;
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
{
@@ -897,18 +935,60 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
- if (*rover->bottomheight <= frontsector->ceilingheight
- && *rover->bottomheight >= frontsector->floorheight
- && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES))
- || (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES))))
+
+ floorcenterz =
+#ifdef ESLOPE
+ frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
+#endif
+ frontsector->floorheight;
+
+ ceilingcenterz =
+#ifdef ESLOPE
+ frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
+#endif
+ frontsector->ceilingheight;
+
+ heightcheck =
+#ifdef ESLOPE
+ *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
+#endif
+ *rover->bottomheight;
+
+ planecenterz =
+#ifdef ESLOPE
+ *rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
+#endif
+ *rover->bottomheight;
+ if (planecenterz <= ceilingcenterz
+ && planecenterz >= floorcenterz
+ && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES))
+ || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
{
- light = R_GetPlaneLight(frontsector, *rover->bottomheight,
+ light = R_GetPlaneLight(frontsector, planecenterz,
viewz < *rover->bottomheight);
+
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
- *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover);
+ *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
+#ifdef ESLOPE
+ , *rover->b_slope
+#endif
+ );
+
+#ifdef ESLOPE
+ ffloor[numffloors].slope = *rover->b_slope;
+
+ // Tell the renderer this sector has slopes in it.
+ if (ffloor[numffloors].slope)
+ frontsector->hasslope = true;
+#endif
+
+ ffloor[numffloors].height =
+#ifdef ESLOPE
+ *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
+#endif
+ *rover->bottomheight;
- ffloor[numffloors].height = *rover->bottomheight;
ffloor[numffloors].ffloor = rover;
numffloors++;
}
@@ -916,16 +996,47 @@ static void R_Subsector(size_t num)
break;
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
- if (*rover->topheight >= frontsector->floorheight
- && *rover->topheight <= frontsector->ceilingheight
- && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES))
- || (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES))))
+
+ heightcheck =
+#ifdef ESLOPE
+ *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
+#endif
+ *rover->topheight;
+
+ planecenterz =
+#ifdef ESLOPE
+ *rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
+#endif
+ *rover->topheight;
+ if (planecenterz >= floorcenterz
+ && planecenterz <= ceilingcenterz
+ && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
+ || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
{
- light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight);
+ light = R_GetPlaneLight(frontsector, planecenterz, viewz < *rover->topheight);
+
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
- frontsector->lightlist[light].extra_colormap, rover);
- ffloor[numffloors].height = *rover->topheight;
+ frontsector->lightlist[light].extra_colormap, rover
+#ifdef ESLOPE
+ , *rover->t_slope
+#endif
+ );
+
+#ifdef ESLOPE
+ ffloor[numffloors].slope = *rover->t_slope;
+
+ // Tell the renderer this sector has slopes in it.
+ if (ffloor[numffloors].slope)
+ frontsector->hasslope = true;
+#endif
+
+ ffloor[numffloors].height =
+#ifdef ESLOPE
+ *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
+#endif
+ *rover->topheight;
+
ffloor[numffloors].ffloor = rover;
numffloors++;
}
@@ -977,12 +1088,20 @@ static void R_Subsector(size_t num)
polysec->lightlevel, xoff, yoff,
polysec->floorpic_angle-po->angle,
NULL,
- NULL);
- ffloor[numffloors].plane->polyobj = po;
+ NULL
+#ifdef ESLOPE
+ , NULL // will ffloors be slopable eventually?
+#endif
+ );
+ //ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po;
+#ifdef ESLOPE
+ ffloor[numffloors].slope = NULL;
+#endif
// ffloor[numffloors].ffloor = rover;
+ po->visplane = ffloor[numffloors].plane;
numffloors++;
}
@@ -1013,12 +1132,20 @@ static void R_Subsector(size_t num)
light = 0;
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle,
- NULL, NULL);
- ffloor[numffloors].plane->polyobj = po;
+ NULL, NULL
+#ifdef ESLOPE
+ , NULL // will ffloors be slopable eventually?
+#endif
+ );
+ //ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight;
+#ifdef ESLOPE
+ ffloor[numffloors].slope = NULL;
+#endif
// ffloor[numffloors].ffloor = rover;
+ po->visplane = ffloor[numffloors].plane;
numffloors++;
}
@@ -1075,6 +1202,11 @@ void R_Prep3DFloors(sector_t *sector)
fixed_t bestheight, maxheight;
INT32 count, i, mapnum;
sector_t *sec;
+#ifdef ESLOPE
+ pslope_t *bestslope;
+ fixed_t heighttest; // I think it's better to check the Z height at the sector's center
+ // than assume unsloped heights are accurate indicators of order in sloped sectors. -Red
+#endif
count = 1;
for (rover = sector->ffloors; rover; rover = rover->next)
@@ -1097,7 +1229,14 @@ void R_Prep3DFloors(sector_t *sector)
else
memset(sector->lightlist, 0, sizeof (lightlist_t) * count);
+#ifdef ESLOPE
+ heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight;
+
+ sector->lightlist[0].height = heighttest + 1;
+ sector->lightlist[0].slope = sector->c_slope;
+#else
sector->lightlist[0].height = sector->ceilingheight + 1;
+#endif
sector->lightlist[0].lightlevel = §or->lightlevel;
sector->lightlist[0].caster = NULL;
sector->lightlist[0].extra_colormap = sector->extra_colormap;
@@ -1115,6 +1254,29 @@ void R_Prep3DFloors(sector_t *sector)
&& !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
continue;
+#ifdef ESLOPE
+ heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight;
+
+ if (heighttest > bestheight && heighttest < maxheight)
+ {
+ best = rover;
+ bestheight = heighttest;
+ bestslope = *rover->t_slope;
+ continue;
+ }
+ if (rover->flags & FF_DOUBLESHADOW) {
+ heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight;
+
+ if (heighttest > bestheight
+ && heighttest < maxheight)
+ {
+ best = rover;
+ bestheight = heighttest;
+ bestslope = *rover->b_slope;
+ continue;
+ }
+ }
+#else
if (*rover->topheight > bestheight && *rover->topheight < maxheight)
{
best = rover;
@@ -1128,6 +1290,7 @@ void R_Prep3DFloors(sector_t *sector)
bestheight = *rover->bottomheight;
continue;
}
+#endif
}
if (!best)
{
@@ -1138,6 +1301,9 @@ void R_Prep3DFloors(sector_t *sector)
sector->lightlist[i].height = maxheight = bestheight;
sector->lightlist[i].caster = best;
sector->lightlist[i].flags = best->flags;
+#ifdef ESLOPE
+ sector->lightlist[i].slope = bestslope;
+#endif
sec = §ors[best->secnum];
mapnum = sec->midmap;
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
@@ -1163,7 +1329,12 @@ void R_Prep3DFloors(sector_t *sector)
if (best->flags & FF_DOUBLESHADOW)
{
+#ifdef ESLOPE
+ heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight;
+ if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red
+#else
if (bestheight == *best->bottomheight)
+#endif
{
sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel;
sector->lightlist[i].extra_colormap =
diff --git a/src/r_defs.h b/src/r_defs.h
index 7f8bd7e1d..f18410fe8 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -155,6 +155,12 @@ typedef struct ffloor_s
fixed_t *bottomyoffs;
angle_t *bottomangle;
+#ifdef ESLOPE
+ // Pointers to pointers. Yup.
+ struct pslope_s **t_slope;
+ struct pslope_s **b_slope;
+#endif
+
size_t secnum;
ffloortype_e flags;
struct line_s *master;
@@ -184,6 +190,9 @@ typedef struct lightlist_s
extracolormap_t *extra_colormap;
INT32 flags;
ffloor_t *caster;
+#ifdef ESLOPE
+ struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
+#endif
} lightlist_t;
@@ -224,6 +233,52 @@ typedef struct secplane_t
fixed_t a, b, c, d, ic;
} secplane_t;
+// Slopes
+#ifdef ESLOPE
+typedef enum {
+ SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope
+ SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it
+ SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position
+ SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things
+} slopeflags_t;
+
+typedef struct pslope_s
+{
+ UINT16 id; // The number of the slope, mostly used for netgame syncing purposes
+
+ // --- Information used in clipping/projection ---
+ // Origin vector for the plane
+ vector3_t o;
+
+ // 2-Dimentional vector (x, y) normalized. Used to determine distance from
+ // the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle)
+ vector2_t d;
+
+ // The rate at which z changes based on distance from the origin plane.
+ fixed_t zdelta;
+
+ // The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red
+ vector3_t normal;
+
+ // For comparing when a slope should be rendered
+ fixed_t lowz;
+ fixed_t highz;
+
+ // This values only check and must be updated if the slope itself is modified
+ angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees)
+ angle_t xydirection; // The direction the slope is facing (north, west, south, etc.)
+
+ struct line_s *sourceline; // The line that generated the slope
+ fixed_t extent; // Distance value used for recalculating zdelta
+ UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping)
+
+ UINT8 flags; // Slope options
+ mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor
+
+ struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later
+} pslope_t;
+#endif
+
typedef enum
{
SF_FLIPSPECIAL_FLOOR = 1,
@@ -337,6 +392,13 @@ typedef struct sector_s
precipmobj_t *preciplist;
struct mprecipsecnode_s *touching_preciplist;
+#ifdef ESLOPE
+ // Eternity engine slope
+ pslope_t *f_slope; // floor slope
+ pslope_t *c_slope; // ceiling slope
+ boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
+#endif
+
// these are saved for netgames, so do not let Lua touch these!
// offsets sector spawned with (via linedef type 7)
@@ -612,6 +674,12 @@ typedef struct drawseg_s
INT16 *thicksidecol;
INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH];
+
+#ifdef ESLOPE
+ fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
+
+ vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
+#endif
} drawseg_t;
typedef enum
diff --git a/src/r_draw.c b/src/r_draw.c
index 420b96c1d..4cc70b795 100644
--- a/src/r_draw.c
+++ b/src/r_draw.c
@@ -103,6 +103,12 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
UINT8 *ds_source; // start of a 64*64 tile image
UINT8 *ds_transmap; // one of the translucency tables
+#ifdef ESLOPE
+pslope_t *ds_slope; // Current slope being used
+floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
+float focallengthf, zeroheight;
+#endif
+
/** \brief Variable flat sizes
*/
diff --git a/src/r_draw.h b/src/r_draw.h
index 061a271b1..0ece26487 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -60,6 +60,16 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern UINT8 *ds_source; // start of a 64*64 tile image
extern UINT8 *ds_transmap;
+#ifdef ESLOPE
+typedef struct {
+ float x, y, z;
+} floatv3_t;
+
+extern pslope_t *ds_slope; // Current slope being used
+extern floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
+extern float focallengthf, zeroheight;
+#endif
+
// Variable flat sizes
extern UINT32 nflatxshift;
extern UINT32 nflatyshift;
@@ -141,6 +151,12 @@ void ASMCALL R_DrawSpan_8_MMX(void);
void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void);
void R_DrawSpan_8(void);
+#ifdef ESLOPE
+void R_CalcTiltedLighting(fixed_t start, fixed_t end);
+void R_DrawTiltedSpan_8(void);
+void R_DrawTiltedTranslucentSpan_8(void);
+void R_DrawTiltedSplat_8(void);
+#endif
void R_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void);
void R_DrawTranslucentSpan_8(void);
diff --git a/src/r_draw8.c b/src/r_draw8.c
index d6c109574..d3f6e18d6 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -526,6 +526,447 @@ void R_DrawSpan_8 (void)
}
}
+#ifdef ESLOPE
+// R_CalcTiltedLighting
+// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
+static INT32 tiltlighting[MAXVIDWIDTH];
+void R_CalcTiltedLighting(fixed_t start, fixed_t end)
+{
+ // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
+ // of this function. Here's my own.
+ INT32 left = ds_x1, right = ds_x2;
+ fixed_t step = (end-start)/(ds_x2-ds_x1+1);
+ INT32 i;
+
+ // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
+ // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
+
+ for (i = left; i <= right; i++) {
+ tiltlighting[i] = (start += step) >> FRACBITS;
+ if (tiltlighting[i] < 0)
+ tiltlighting[i] = 0;
+ else if (tiltlighting[i] >= MAXLIGHTSCALE)
+ tiltlighting[i] = MAXLIGHTSCALE-1;
+ }
+}
+
+
+/** \brief The R_DrawTiltedSpan_8 function
+ Draw slopes! Holy sheit!
+*/
+void R_DrawTiltedSpan_8(void)
+{
+ // x1, x2 = ds_x1, ds_x2
+ int width = ds_x2 - ds_x1;
+ double iz, uz, vz;
+ UINT32 u, v;
+ int i;
+
+ UINT8 *source;
+ UINT8 *colormap;
+ UINT8 *dest;
+
+ double startz, startu, startv;
+ double izstep, uzstep, vzstep;
+ double endz, endu, endv;
+ UINT32 stepu, stepv;
+
+ iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
+
+ // Lighting is simple. It's just linear interpolation from start to end
+ {
+ float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
+ float lightstart, lightend;
+
+ lightend = (iz + ds_sz.x*width) * planelightfloat;
+ lightstart = iz * planelightfloat;
+
+ R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
+ //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
+ }
+
+ uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
+ vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
+
+ dest = ylookup[ds_y] + columnofs[ds_x1];
+ source = ds_source;
+ //colormap = ds_colormap;
+
+#if 0 // The "perfect" reference version of this routine. Pretty slow.
+ // Use it only to see how things are supposed to look.
+ i = 0;
+ do
+ {
+ double z = 1.f/iz;
+ u = (INT64)(uz*z) + viewx;
+ v = (INT64)(vz*z) + viewy;
+
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+
+ *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ dest++;
+ iz += ds_sz.x;
+ uz += ds_su.x;
+ vz += ds_sv.x;
+ } while (--width >= 0);
+#else
+#define SPANSIZE 16
+#define INVSPAN 0.0625f
+
+ startz = 1.f/iz;
+ startu = uz*startz;
+ startv = vz*startz;
+
+ izstep = ds_sz.x * SPANSIZE;
+ uzstep = ds_su.x * SPANSIZE;
+ vzstep = ds_sv.x * SPANSIZE;
+ //x1 = 0;
+ width++;
+
+ while (width >= SPANSIZE)
+ {
+ iz += izstep;
+ uz += uzstep;
+ vz += vzstep;
+
+ endz = 1.f/iz;
+ endu = uz*endz;
+ endv = vz*endz;
+ stepu = (INT64)((endu - startu) * INVSPAN);
+ stepv = (INT64)((endv - startv) * INVSPAN);
+ u = (INT64)(startu) + viewx;
+ v = (INT64)(startv) + viewy;
+
+ for (i = SPANSIZE-1; i >= 0; i--)
+ {
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ dest++;
+ u += stepu;
+ v += stepv;
+ }
+ startu = endu;
+ startv = endv;
+ width -= SPANSIZE;
+ }
+ if (width > 0)
+ {
+ if (width == 1)
+ {
+ u = (INT64)(startu);
+ v = (INT64)(startv);
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ }
+ else
+ {
+ double left = width;
+ iz += ds_sz.x * left;
+ uz += ds_su.x * left;
+ vz += ds_sv.x * left;
+
+ endz = 1.f/iz;
+ endu = uz*endz;
+ endv = vz*endz;
+ left = 1.f/left;
+ stepu = (INT64)((endu - startu) * left);
+ stepv = (INT64)((endv - startv) * left);
+ u = (INT64)(startu) + viewx;
+ v = (INT64)(startv) + viewy;
+
+ for (; width != 0; width--)
+ {
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ dest++;
+ u += stepu;
+ v += stepv;
+ }
+ }
+ }
+#endif
+}
+
+/** \brief The R_DrawTiltedTranslucentSpan_8 function
+ Like DrawTiltedSpan, but translucent
+*/
+void R_DrawTiltedTranslucentSpan_8(void)
+{
+ // x1, x2 = ds_x1, ds_x2
+ int width = ds_x2 - ds_x1;
+ double iz, uz, vz;
+ UINT32 u, v;
+ int i;
+
+ UINT8 *source;
+ UINT8 *colormap;
+ UINT8 *dest;
+
+ double startz, startu, startv;
+ double izstep, uzstep, vzstep;
+ double endz, endu, endv;
+ UINT32 stepu, stepv;
+
+ iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
+
+ // Lighting is simple. It's just linear interpolation from start to end
+ {
+ float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
+ float lightstart, lightend;
+
+ lightend = (iz + ds_sz.x*width) * planelightfloat;
+ lightstart = iz * planelightfloat;
+
+ R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
+ //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
+ }
+
+ uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
+ vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
+
+ dest = ylookup[ds_y] + columnofs[ds_x1];
+ source = ds_source;
+ //colormap = ds_colormap;
+
+#if 0 // The "perfect" reference version of this routine. Pretty slow.
+ // Use it only to see how things are supposed to look.
+ i = 0;
+ do
+ {
+ double z = 1.f/iz;
+ u = (INT64)(uz*z) + viewx;
+ v = (INT64)(vz*z) + viewy;
+
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+
+ *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+ dest++;
+ iz += ds_sz.x;
+ uz += ds_su.x;
+ vz += ds_sv.x;
+ } while (--width >= 0);
+#else
+#define SPANSIZE 16
+#define INVSPAN 0.0625f
+
+ startz = 1.f/iz;
+ startu = uz*startz;
+ startv = vz*startz;
+
+ izstep = ds_sz.x * SPANSIZE;
+ uzstep = ds_su.x * SPANSIZE;
+ vzstep = ds_sv.x * SPANSIZE;
+ //x1 = 0;
+ width++;
+
+ while (width >= SPANSIZE)
+ {
+ iz += izstep;
+ uz += uzstep;
+ vz += vzstep;
+
+ endz = 1.f/iz;
+ endu = uz*endz;
+ endv = vz*endz;
+ stepu = (INT64)((endu - startu) * INVSPAN);
+ stepv = (INT64)((endv - startv) * INVSPAN);
+ u = (INT64)(startu) + viewx;
+ v = (INT64)(startv) + viewy;
+
+ for (i = SPANSIZE-1; i >= 0; i--)
+ {
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+ dest++;
+ u += stepu;
+ v += stepv;
+ }
+ startu = endu;
+ startv = endv;
+ width -= SPANSIZE;
+ }
+ if (width > 0)
+ {
+ if (width == 1)
+ {
+ u = (INT64)(startu);
+ v = (INT64)(startv);
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+ }
+ else
+ {
+ double left = width;
+ iz += ds_sz.x * left;
+ uz += ds_su.x * left;
+ vz += ds_sv.x * left;
+
+ endz = 1.f/iz;
+ endu = uz*endz;
+ endv = vz*endz;
+ left = 1.f/left;
+ stepu = (INT64)((endu - startu) * left);
+ stepv = (INT64)((endv - startv) * left);
+ u = (INT64)(startu) + viewx;
+ v = (INT64)(startv) + viewy;
+
+ for (; width != 0; width--)
+ {
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+ dest++;
+ u += stepu;
+ v += stepv;
+ }
+ }
+ }
+#endif
+}
+
+void R_DrawTiltedSplat_8(void)
+{
+ // x1, x2 = ds_x1, ds_x2
+ int width = ds_x2 - ds_x1;
+ double iz, uz, vz;
+ UINT32 u, v;
+ int i;
+
+ UINT8 *source;
+ UINT8 *colormap;
+ UINT8 *dest;
+
+ UINT8 val;
+
+ double startz, startu, startv;
+ double izstep, uzstep, vzstep;
+ double endz, endu, endv;
+ UINT32 stepu, stepv;
+
+ iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
+
+ // Lighting is simple. It's just linear interpolation from start to end
+ {
+ float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
+ float lightstart, lightend;
+
+ lightend = (iz + ds_sz.x*width) * planelightfloat;
+ lightstart = iz * planelightfloat;
+
+ R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
+ //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
+ }
+
+ uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
+ vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
+
+ dest = ylookup[ds_y] + columnofs[ds_x1];
+ source = ds_source;
+ //colormap = ds_colormap;
+
+#if 0 // The "perfect" reference version of this routine. Pretty slow.
+ // Use it only to see how things are supposed to look.
+ i = 0;
+ do
+ {
+ double z = 1.f/iz;
+ u = (INT64)(uz*z) + viewx;
+ v = (INT64)(vz*z) + viewy;
+
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+
+ val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ if (val != TRANSPARENTPIXEL)
+ *dest = val;
+ dest++;
+ iz += ds_sz.x;
+ uz += ds_su.x;
+ vz += ds_sv.x;
+ } while (--width >= 0);
+#else
+#define SPANSIZE 16
+#define INVSPAN 0.0625f
+
+ startz = 1.f/iz;
+ startu = uz*startz;
+ startv = vz*startz;
+
+ izstep = ds_sz.x * SPANSIZE;
+ uzstep = ds_su.x * SPANSIZE;
+ vzstep = ds_sv.x * SPANSIZE;
+ //x1 = 0;
+ width++;
+
+ while (width >= SPANSIZE)
+ {
+ iz += izstep;
+ uz += uzstep;
+ vz += vzstep;
+
+ endz = 1.f/iz;
+ endu = uz*endz;
+ endv = vz*endz;
+ stepu = (INT64)((endu - startu) * INVSPAN);
+ stepv = (INT64)((endv - startv) * INVSPAN);
+ u = (INT64)(startu) + viewx;
+ v = (INT64)(startv) + viewy;
+
+ for (i = SPANSIZE-1; i >= 0; i--)
+ {
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ if (val != TRANSPARENTPIXEL)
+ *dest = val;
+ dest++;
+ u += stepu;
+ v += stepv;
+ }
+ startu = endu;
+ startv = endv;
+ width -= SPANSIZE;
+ }
+ if (width > 0)
+ {
+ if (width == 1)
+ {
+ u = (INT64)(startu);
+ v = (INT64)(startv);
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ if (val != TRANSPARENTPIXEL)
+ *dest = val;
+ }
+ else
+ {
+ double left = width;
+ iz += ds_sz.x * left;
+ uz += ds_su.x * left;
+ vz += ds_sv.x * left;
+
+ endz = 1.f/iz;
+ endu = uz*endz;
+ endv = vz*endz;
+ left = 1.f/left;
+ stepu = (INT64)((endu - startu) * left);
+ stepv = (INT64)((endv - startv) * left);
+ u = (INT64)(startu) + viewx;
+ v = (INT64)(startv) + viewy;
+
+ for (; width != 0; width--)
+ {
+ colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+ val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+ if (val != TRANSPARENTPIXEL)
+ *dest = val;
+ dest++;
+ u += stepu;
+ v += stepv;
+ }
+ }
+ }
+#endif
+}
+#endif // ESLOPE
+
/** \brief The R_DrawSplat_8 function
Just like R_DrawSpan_8, but skips transparent pixels.
*/
diff --git a/src/r_main.c b/src/r_main.c
index 77d6a456c..734e18d80 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -316,13 +316,13 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y)
x >= 0 ?
y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
- ANGLE_90-1-tantoangle[SlopeDiv(x,y)] : // octant 1
+ ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1
x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7
- y >= 0 ? (x = -x) > y ? ANGLE_180-1-tantoangle[SlopeDiv(y,x)] :// octant 3
+ y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3
ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
- (x = -x) > (y = -y) ? ANGLE_180+tantoangle[ SlopeDiv(y,x)] : // octant 4
- ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
+ (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
+ ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0;
}
@@ -332,13 +332,13 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y)
x >= 0 ?
y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
- ANGLE_90-1-tantoangle[SlopeDiv(x,y)] : // octant 1
+ ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1
x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7
- y >= 0 ? (x = -x) > y ? ANGLE_180-1-tantoangle[SlopeDiv(y,x)] :// octant 3
+ y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3
ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
- (x = -x) > (y = -y) ? ANGLE_180+tantoangle[ SlopeDiv(y,x)] : // octant 4
- ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
+ (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
+ ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0;
}
@@ -527,6 +527,8 @@ static void R_InitTextureMapping(void)
focallength = FixedDiv(centerxfrac,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
+ focallengthf = FIXED_TO_FLOAT(focallength);
+
for (i = 0; i < FINEANGLES/2; i++)
{
if (FINETANGENT(i) > FRACUNIT*2)
@@ -1026,34 +1028,31 @@ void R_SetupFrame(player_t *player, boolean skybox)
{
INT32 dy = 0;
camera_t *thiscam;
- boolean forcechase = false;
+ boolean chasecam = false;
if (splitscreen && player == &players[secondarydisplayplayer]
&& player != &players[consoleplayer])
{
thiscam = &camera2;
+ chasecam = (cv_chasecam2.value != 0);
}
else
+ {
thiscam = &camera;
+ chasecam = (cv_chasecam.value != 0);
+ }
if (player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD)
- forcechase = true;
+ chasecam = true; // force chasecam on
+ else if (player->spectator) // no spectator chasecam
+ chasecam = false; // force chasecam off
- if (!forcechase && player->spectator) // no spectator chasecam
- thiscam->chase = false;
- else if ((cv_chasecam.value || forcechase) && !player->spectator && thiscam == &camera && !thiscam->chase)
+ if (chasecam && !thiscam->chase)
{
- P_ResetCamera(player, &camera);
+ P_ResetCamera(player, thiscam);
thiscam->chase = true;
}
- else if ((cv_chasecam2.value || forcechase) && !player->spectator && thiscam == &camera2 && !thiscam->chase)
- {
- P_ResetCamera(player, &camera2);
- thiscam->chase = true;
- }
- else if (!(cv_chasecam.value || forcechase) && thiscam == &camera)
- thiscam->chase = false;
- else if (!(cv_chasecam2.value || forcechase) && thiscam == &camera2)
+ else if (!chasecam)
thiscam->chase = false;
viewsky = !skybox;
@@ -1066,9 +1065,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
aimingangle = player->awayviewaiming;
viewangle = viewmobj->angle;
}
- else if (!player->spectator && (forcechase
- || (cv_chasecam.value && thiscam == &camera)
- || (cv_chasecam2.value && thiscam == &camera2)))
+ else if (!player->spectator && chasecam)
// use outside cam view
{
viewmobj = NULL;
@@ -1105,8 +1102,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
viewplayer = player;
- if ((forcechase || (cv_chasecam.value && thiscam == &camera) || (cv_chasecam2.value && thiscam == &camera2))
- && !player->awayviewtics && !player->spectator)
+ if (chasecam && !player->awayviewtics && !player->spectator)
{
viewx = thiscam->x;
viewy = thiscam->y;
diff --git a/src/r_plane.c b/src/r_plane.c
index dcff25c13..fa0e0eac3 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -28,6 +28,8 @@
#include "p_setup.h" // levelflats
+#include "p_slopes.h"
+
//
// opening
//
@@ -74,7 +76,7 @@ static INT32 spanstart[MAXVIDHEIGHT];
//
// texture mapping
//
-static lighttable_t **planezlight;
+lighttable_t **planezlight;
static fixed_t planeheight;
//added : 10-02-98: yslopetab is what yslope used to be,
@@ -327,6 +329,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
+#ifdef ESLOPE
+ if (currentplane->slope)
+ ds_colormap = colormaps;
+ else
+#endif
ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap)
@@ -423,11 +430,18 @@ static visplane_t *new_visplane(unsigned hash)
//
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
- ffloor_t *pfloor)
+ ffloor_t *pfloor
+#ifdef ESLOPE
+ , pslope_t *slope
+#endif
+ )
{
visplane_t *check;
unsigned hash;
+#ifdef ESLOPE
+ if (slope); else // Don't mess with this right now if a slope is involved
+#endif
if (plangle != 0)
{
// Add the view offset, rotated by the plane angle.
@@ -462,7 +476,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
&& xoff == check->xoffs && yoff == check->yoffs
&& planecolormap == check->extra_colormap
&& !pfloor && !check->ffloor && check->viewz == viewz
- && check->viewangle == viewangle)
+ && check->viewangle == viewangle
+#ifdef ESLOPE
+ && check->slope == slope
+#endif
+ )
{
return check;
}
@@ -485,6 +503,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
#ifdef POLYOBJECTS_PLANES
check->polyobj = NULL;
#endif
+#ifdef ESLOPE
+ check->slope = slope;
+#endif
memset(check->top, 0xff, sizeof (check->top));
memset(check->bottom, 0x00, sizeof (check->bottom));
@@ -551,6 +572,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->plangle = pl->plangle;
#ifdef POLYOBJECTS_PLANES
new_pl->polyobj = pl->polyobj;
+#endif
+#ifdef ESLOPE
+ new_pl->slope = pl->slope;
#endif
pl = new_pl;
pl->minx = start;
@@ -814,7 +838,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
- if (pl->ffloor->flags & FF_RIPPLE)
+ if (pl->ffloor->flags & FF_RIPPLE
+#ifdef ESLOPE
+ && !pl->slope
+#endif
+ )
{
INT32 top, bottom;
@@ -842,6 +870,9 @@ void R_DrawSinglePlane(visplane_t *pl)
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
+#ifdef ESLOPE
+ if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later
+#endif
if (viewangle != pl->viewangle)
{
memset(cachedheight, 0, sizeof (cachedheight));
@@ -915,6 +946,106 @@ void R_DrawSinglePlane(visplane_t *pl)
if (light < 0)
light = 0;
+#ifdef ESLOPE
+ if (pl->slope) {
+ // Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
+ // I copied ZDoom's code and adapted it to SRB2... -Red
+ floatv3_t p, m, n;
+ float ang;
+ float vx, vy, vz;
+ float fudge;
+ // 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;
+
+ xoffs &= ((1 << (32-nflatshiftup))-1);
+ yoffs &= ((1 << (32-nflatshiftup))-1);
+
+ xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
+ yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
+
+ // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
+ fudge = ((1<slope, viewx, viewy);
+ zeroheight = FIXED_TO_FLOAT(temp);
+
+#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
+
+ // p is the texture origin in view space
+ // Don't add in the offsets at this stage, because doing so can result in
+ // errors if the flat is rotated.
+ ang = ANG2RAD(ANGLE_270 - viewangle);
+ p.x = vx * cos(ang) - vy * sin(ang);
+ p.z = vx * sin(ang) + vy * cos(ang);
+ temp = P_GetZAt(pl->slope, -xoffs, yoffs);
+ p.y = FIXED_TO_FLOAT(temp) - vz;
+
+ // m is the v direction vector in view space
+ ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle);
+ m.x = cos(ang);
+ m.z = sin(ang);
+
+ // n is the u direction vector in view space
+ n.x = sin(ang);
+ n.z = -cos(ang);
+
+ ang = ANG2RAD(pl->plangle);
+ temp = P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang)));
+ m.y = FIXED_TO_FLOAT(temp) - zeroheight;
+ temp = P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang)));
+ n.y = FIXED_TO_FLOAT(temp) - zeroheight;
+
+ m.x /= fudge;
+ m.y /= fudge;
+ m.z /= fudge;
+
+ n.x *= fudge;
+ n.y *= fudge;
+ n.z *= fudge;
+
+ // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
+#define CROSS(d, v1, v2) \
+ d.x = (v1.y * v2.z) - (v1.z * v2.y);\
+ d.y = (v1.z * v2.x) - (v1.x * v2.z);\
+ d.z = (v1.x * v2.y) - (v1.y * v2.x)
+ CROSS(ds_su, p, m);
+ CROSS(ds_sv, p, n);
+ CROSS(ds_sz, m, n);
+#undef CROSS
+
+ ds_su.z *= focallengthf;
+ ds_sv.z *= focallengthf;
+ ds_sz.z *= focallengthf;
+
+ // Premultiply the texture vectors with the scale factors
+#define SFMULT 65536.f*(1<scale1 + (x1 - ds->x1)*rw_scalestep;
}
+
+#ifndef ESLOPE
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
dc_texturemid = front->floorheight > back->floorheight
@@ -492,12 +503,21 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_texturemid += (textureheight[texnum])*times;
else
dc_texturemid -= (textureheight[texnum])*times;
+#endif
dc_texheight = textureheight[texnum]>>FRACBITS;
// draw the columns
for (dc_x = x1; dc_x <= x2; dc_x++)
{
+#ifdef ESLOPE
+ dc_texturemid = ds->maskedtextureheight[dc_x];
+
+ if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3))
+ dc_texturemid += (textureheight[texnum])*times + textureheight[texnum];
+ else
+ dc_texturemid -= (textureheight[texnum])*times;
+#endif
// calculate lighting
if (maskedtexturecol[dc_x] != INT16_MAX)
{
@@ -679,6 +699,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
r_lightlist_t *rlight;
fixed_t lheight;
line_t *newline = NULL;
+#ifdef ESLOPE
+ // Render FOF sides kinda like normal sides, with the frac and step and everything
+ fixed_t top_frac, top_step, bottom_frac, bottom_step;
+#endif
void (*colfunc_2s) (column_t *);
@@ -853,6 +877,34 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
column2s_length = textures[texnum]->height;
}
+#ifdef ESLOPE
+ // Set heights according to plane, or slope, whichever
+ {
+ fixed_t left_top, right_top, left_bottom, right_bottom;
+
+ left_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->topheight;
+ right_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->topheight;
+ left_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->bottomheight;
+ right_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->bottomheight;
+
+ left_top -= viewz;
+ right_top -= viewz;
+ left_bottom -= viewz;
+ right_bottom -= viewz;
+
+ top_frac = centeryfrac - FixedMul(left_top, ds->scale1);
+ bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1);
+ top_step = centeryfrac - FixedMul(right_top, ds->scale2);
+ bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2);
+
+ top_step = (top_step-top_frac)/(ds->x2-ds->x1+1);
+ bottom_step = (bottom_step-bottom_frac)/(ds->x2-ds->x1+1);
+
+ top_frac += top_step * (x1 - ds->x1);
+ bottom_frac += bottom_step * (x1 - ds->x1);
+ }
+#endif
+
// draw the columns
for (dc_x = x1; dc_x <= x2; dc_x++)
{
@@ -868,8 +920,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
INT32 solid = 0;
INT32 lighteffect = 0;
+#ifdef ESLOPE
+ sprtopscreen = windowtop = top_frac;
+ sprbotscreen = windowbottom = bottom_frac;
+
+ top_frac += top_step;
+ bottom_frac += bottom_step;
+#else
sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
+#endif
// SoM: If column is out of range, why bother with it??
if (windowbottom < topbounds || windowtop > bottombounds)
@@ -1011,11 +1071,24 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|| ((signed)dc_texturemid < 0 && (spryscale) && (signed)(dc_texturemid)>>FRACBITS < (INT32_MIN / spryscale)))
{
spryscale += rw_scalestep;
+#ifdef ESLOPE
+ top_frac += top_step;
+ bottom_frac += bottom_step;
+#endif
continue;
}
+#ifdef ESLOPE
+ sprtopscreen = windowtop = top_frac;
+ sprbotscreen = windowbottom = bottom_frac;
+
+ top_frac += top_step;
+ bottom_frac += bottom_step;
+#else
sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
+#endif
+
dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
@@ -1061,6 +1134,7 @@ static void R_RenderSegLoop (void)
INT32 mid;
fixed_t texturecolumn = 0;
+ fixed_t oldtexturecolumn = -1;
INT32 top;
INT32 bottom;
INT32 i;
@@ -1197,6 +1271,17 @@ static void R_RenderSegLoop (void)
// calculate texture offset
angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance);
+
+#ifdef ESLOPE
+ if (oldtexturecolumn != -1) {
+ rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn);
+ rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn);
+ rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn);
+ rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn);
+ }
+ oldtexturecolumn = texturecolumn;
+#endif
+
texturecolumn >>= FRACBITS;
// texturecolumn and lighting are independent of wall tiers
@@ -1345,6 +1430,14 @@ static void R_RenderSegLoop (void)
// save texturecol
// for backdrawing of masked mid texture
maskedtexturecol[rw_x] = (INT16)texturecolumn;
+
+#ifdef ESLOPE
+ if (maskedtextureheight != NULL) {
+ maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ?
+ max(rw_midtexturemid, rw_midtextureback) :
+ min(rw_midtexturemid, rw_midtextureback));
+ }
+#endif
}
if (dc_numlights)
@@ -1397,13 +1490,23 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t hyp;
fixed_t sineval;
angle_t distangle, offsetangle;
- fixed_t vtop;
+ //fixed_t vtop;
INT32 lightnum;
INT32 i, p;
lightlist_t *light;
r_lightlist_t *rlight;
+#ifdef ESLOPE
+ vertex_t segleft, segright;
+ fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
+#endif
static size_t maxdrawsegs = 0;
+ maskedtextureheight = NULL;
+
+ //initialize segleft and segright
+ memset(&segleft, 0x00, sizeof(segleft));
+ memset(&segright, 0x00, sizeof(segright));
+
if (ds_p == drawsegs+maxdrawsegs)
{
size_t pos = ds_p - drawsegs;
@@ -1502,8 +1605,80 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// calculate texture boundaries
// and decide if floor / ceiling marks are needed
- worldtop = frontsector->ceilingheight - viewz;
- worldbottom = frontsector->floorheight - viewz;
+#ifdef ESLOPE
+ // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit
+ if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red
+ {
+ angle_t temp;
+
+ // left
+ temp = xtoviewangle[start]+viewangle;
+
+ {
+ // Both lines can be written in slope-intercept form, so figure out line intersection
+ float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector...
+ ///TODO: convert to FPU
+
+ a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y);
+ b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x);
+ c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y);
+
+ a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT));
+ b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT));
+ c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy);
+
+ det = a1*b2 - a2*b1;
+
+ ds_p->leftpos.x = segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det);
+ ds_p->leftpos.y = segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det);
+ }
+
+ // right
+ temp = xtoviewangle[stop]+viewangle;
+
+ {
+ // Both lines can be written in slope-intercept form, so figure out line intersection
+ float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector...
+ ///TODO: convert to FPU
+
+ a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y);
+ b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x);
+ c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y);
+
+ a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT));
+ b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT));
+ c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy);
+
+ det = a1*b2 - a2*b1;
+
+ ds_p->rightpos.x = segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det);
+ ds_p->rightpos.y = segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det);
+ }
+ }
+
+ if (frontsector->c_slope) {
+ worldtop = P_GetZAt(frontsector->c_slope, segleft.x, segleft.y) - viewz;
+ worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz;
+ } else {
+ worldtopslope =
+#else
+ {
+#endif
+ worldtop = frontsector->ceilingheight - viewz;
+ }
+
+
+#ifdef ESLOPE
+ if (frontsector->f_slope) {
+ worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz;
+ worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz;
+ } else {
+ worldbottomslope =
+#else
+ {
+#endif
+ worldbottom = frontsector->floorheight - viewz;
+ }
midtexture = toptexture = bottomtexture = maskedtexture = 0;
ds_p->maskedtexturecol = NULL;
@@ -1524,27 +1699,72 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg))
continue;
#endif
+
+#ifdef ESLOPE
+ if (ffloor[i].slope) {
+ ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz;
+ ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz;
+ } else
+ ffloor[i].f_pos_slope =
+#endif
ffloor[i].f_pos = ffloor[i].height - viewz;
}
}
+#ifdef ESLOPE
+ // Set up texture Y offset slides for sloped walls
+ rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0;
+ ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0;
+
+ {
+ angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
+
+ if (frontsector->f_slope)
+ floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT));
+
+ if (frontsector->c_slope)
+ ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT));
+
+ if (backsector && backsector->f_slope)
+ floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT));
+
+ if (backsector && backsector->c_slope)
+ ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT));
+ }
+#endif
+
if (!backsector)
{
// single sided line
midtexture = texturetranslation[sidedef->midtexture];
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true;
-
+#ifdef ESLOPE
+ if (!(linedef->flags & ML_EFFECT1)) {
+ if (linedef->flags & ML_DONTPEGBOTTOM)
+ rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz;
+ else
+ rw_midtexturemid = frontsector->ceilingheight;
+ }
+#endif
if (linedef->flags & ML_DONTPEGBOTTOM)
{
+#ifdef ESLOPE
+ rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture];
+ rw_midtextureslide = floorfrontslide;
+#else
vtop = frontsector->floorheight + textureheight[sidedef->midtexture];
// bottom of texture at bottom
rw_midtexturemid = vtop - viewz;
+#endif
}
else
{
// top of texture at top
rw_midtexturemid = worldtop;
+#ifdef ESLOPE
+ rw_midtextureslide = ceilingfrontslide;
+#endif
}
rw_midtexturemid += sidedef->rowoffset;
@@ -1557,47 +1777,120 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else
{
// two sided line
+
+#ifdef ESLOPE
+ if (backsector->c_slope) {
+ worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz;
+ worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz;
+ } else {
+ worldhighslope =
+#else
+ {
+#endif
+ worldhigh = backsector->ceilingheight - viewz;
+ }
+
+
+#ifdef ESLOPE
+ if (backsector->f_slope) {
+ worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz;
+ worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz;
+ } else {
+ worldlowslope =
+#else
+ {
+#endif
+ worldlow = backsector->floorheight - viewz;
+ }
+
+
+ // hack to allow height changes in outdoor areas
+ if (frontsector->ceilingpic == skyflatnum
+ && backsector->ceilingpic == skyflatnum)
+ {
+#ifdef ESLOPE
+ worldtopslope = worldhighslope =
+#endif
+ worldtop = worldhigh;
+ }
+
ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
ds_p->silhouette = 0;
- if (frontsector->floorheight > backsector->floorheight)
+ if (
+#ifdef ESLOPE
+ worldbottomslope > worldlowslope ||
+#endif
+ worldbottom > worldlow)
{
ds_p->silhouette = SIL_BOTTOM;
+#ifdef ESLOPE
+ ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight);
+#else
ds_p->bsilheight = frontsector->floorheight;
+#endif
}
+#ifdef ESLOPE
+ else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz)
+#else
else if (backsector->floorheight > viewz)
+#endif
{
ds_p->silhouette = SIL_BOTTOM;
ds_p->bsilheight = INT32_MAX;
// ds_p->sprbottomclip = negonearray;
}
- if (frontsector->ceilingheight < backsector->ceilingheight)
+ if (
+#ifdef ESLOPE
+ worldtopslope < worldhighslope ||
+#endif
+ worldtop < worldhigh)
{
ds_p->silhouette |= SIL_TOP;
+#ifdef ESLOPE
+ ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight);
+#else
ds_p->tsilheight = frontsector->ceilingheight;
+#endif
}
+#ifdef ESLOPE
+ else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz)
+#else
else if (backsector->ceilingheight < viewz)
+#endif
{
ds_p->silhouette |= SIL_TOP;
ds_p->tsilheight = INT32_MIN;
// ds_p->sprtopclip = screenheightarray;
}
- if (backsector->ceilingheight <= frontsector->floorheight)
+#ifdef ESLOPE
+ if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)
+#else
+ if (worldhigh <= worldbottom)
+#endif
{
ds_p->sprbottomclip = negonearray;
ds_p->bsilheight = INT32_MAX;
ds_p->silhouette |= SIL_BOTTOM;
}
- if (backsector->floorheight >= frontsector->ceilingheight)
+#ifdef ESLOPE
+ if (worldlow >= worldtop && worldlowslope >= worldtopslope)
+#else
+ if (worldlow >= worldtop)
+#endif
{
ds_p->sprtopclip = screenheightarray;
ds_p->tsilheight = INT32_MIN;
ds_p->silhouette |= SIL_TOP;
}
+#ifdef ESLOPE
+ // This causes issues with slopes.
+ if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
+#endif
//SoM: 3/25/2000: This code fixes an automap bug that didn't check
// frontsector->ceiling and backsector->floor to see if a door was closed.
// Without the following code, sprites get displayed behind closed doors.
@@ -1616,17 +1909,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
}
- worldhigh = backsector->ceilingheight - viewz;
- worldlow = backsector->floorheight - viewz;
-
- // hack to allow height changes in outdoor areas
- if (frontsector->ceilingpic == skyflatnum
- && backsector->ceilingpic == skyflatnum)
- {
- worldtop = worldhigh;
- }
-
if (worldlow != worldbottom
+#ifdef ESLOPE
+ || worldlowslope != worldbottomslope
+ || backsector->f_slope != frontsector->f_slope
+#endif
|| backsector->floorpic != frontsector->floorpic
|| backsector->lightlevel != frontsector->lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
@@ -1649,6 +1936,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
if (worldhigh != worldtop
+#ifdef ESLOPE
+ || worldhighslope != worldtopslope
+ || backsector->c_slope != frontsector->c_slope
+#endif
|| backsector->ceilingpic != frontsector->ceilingpic
|| backsector->lightlevel != frontsector->lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
@@ -1678,7 +1969,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
// check TOP TEXTURE
- if (worldhigh < worldtop)
+ if (worldhigh < worldtop
+#ifdef ESLOPE
+ || worldhighslope < worldtopslope
+#endif
+ )
{
// top texture
if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM))
@@ -1691,49 +1986,100 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (!toptexture) //Second side has no texture, use the first side's instead.
toptexture = texturetranslation[sidedef->toptexture];
+#ifdef ESLOPE
+ if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
+ if (linedef->flags & ML_DONTPEGTOP)
+ rw_toptexturemid = frontsector->ceilingheight - viewz;
+ else
+ rw_toptexturemid = backsector->ceilingheight - viewz;
+ } else
+#endif
if (linedef->flags & ML_DONTPEGTOP)
{
// top of texture at top
rw_toptexturemid = worldtop;
+#ifdef ESLOPE
+ rw_toptextureslide = ceilingfrontslide;
+#endif
}
else
{
+#ifdef ESLOPE
+ rw_toptexturemid = worldhigh + textureheight[def->toptexture];
+ rw_toptextureslide = ceilingbackslide;
+#else
vtop = backsector->ceilingheight + textureheight[def->toptexture];
// bottom of texture
rw_toptexturemid = vtop - viewz;
+#endif
}
}
else
{
toptexture = texturetranslation[sidedef->toptexture];
+#ifdef ESLOPE
+ if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
+ if (linedef->flags & ML_DONTPEGTOP)
+ rw_toptexturemid = frontsector->ceilingheight - viewz;
+ else
+ rw_toptexturemid = backsector->ceilingheight - viewz;
+ } else
+#endif
if (linedef->flags & ML_DONTPEGTOP)
{
// top of texture at top
rw_toptexturemid = worldtop;
+#ifdef ESLOPE
+ rw_toptextureslide = ceilingfrontslide;
+#endif
}
else
{
+#ifdef ESLOPE
+ rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture];
+ rw_toptextureslide = ceilingbackslide;
+#else
vtop = backsector->ceilingheight + textureheight[sidedef->toptexture];
// bottom of texture
rw_toptexturemid = vtop - viewz;
+#endif
}
}
}
// check BOTTOM TEXTURE
- if (worldlow > worldbottom) //seulement si VISIBLE!!!
+ if (worldlow > worldbottom
+#ifdef ESLOPE
+ || worldlowslope > worldbottomslope
+#endif
+ ) //seulement si VISIBLE!!!
{
// bottom texture
bottomtexture = texturetranslation[sidedef->bottomtexture];
+#ifdef ESLOPE
+ if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
+ if (linedef->flags & ML_DONTPEGBOTTOM)
+ rw_bottomtexturemid = frontsector->floorheight - viewz;
+ else
+ rw_bottomtexturemid = backsector->floorheight - viewz;
+ } else
+#endif
if (linedef->flags & ML_DONTPEGBOTTOM)
{
// bottom of texture at bottom
// top of texture at top
- rw_bottomtexturemid = worldtop;
+ rw_bottomtexturemid = worldbottom;
+#ifdef ESLOPE
+ rw_bottomtextureslide = floorfrontslide;
+#endif
}
- else // top of texture at top
+ else { // top of texture at top
rw_bottomtexturemid = worldlow;
+#ifdef ESLOPE
+ rw_bottomtextureslide = floorbackslide;
+#endif
+ }
}
rw_toptexturemid += sidedef->rowoffset;
@@ -1745,6 +2091,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor_t *rover;
ffloor_t *r2;
fixed_t lowcut, highcut;
+#ifdef ESLOPE
+ fixed_t lowcutslope, highcutslope;
+
+ // Used for height comparisons and etc across FOFs and slopes
+ fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2;
+#endif
//markceiling = markfloor = true;
maskedtexture = true;
@@ -1752,8 +2104,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x;
lastopening += rw_stopx - rw_x;
- lowcut = frontsector->floorheight > backsector->floorheight ? frontsector->floorheight : backsector->floorheight;
- highcut = frontsector->ceilingheight < backsector->ceilingheight ? frontsector->ceilingheight : backsector->ceilingheight;
+ lowcut = max(worldbottom, worldlow) + viewz;
+ highcut = min(worldtop, worldhigh) + viewz;
+#ifdef ESLOPE
+ lowcutslope = max(worldbottomslope, worldlowslope) + viewz;
+ highcutslope = min(worldtopslope, worldhighslope) + viewz;
+#endif
if (frontsector->ffloors && backsector->ffloors)
{
@@ -1764,16 +2120,33 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue;
if (rover->flags & FF_INVERTSIDES)
continue;
- if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
- continue;
if (rover->norender == leveltime)
continue;
+#ifdef ESLOPE
+ if (*rover->t_slope) {
+ high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y);
+ highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y);
+ } else
+ high1 = highslope1 = *rover->topheight;
+ if (*rover->b_slope) {
+ low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y);
+ lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y);
+ } else
+ low1 = lowslope1 = *rover->bottomheight;
+
+ if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
+ continue;
+#else
+ if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
+ continue;
+#endif
+
for (r2 = frontsector->ffloors; r2; r2 = r2->next)
{
if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)
- || *r2->topheight < lowcut || *r2->bottomheight > highcut)
+ || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red
continue;
if (r2->norender == leveltime)
@@ -1793,8 +2166,24 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue;
}
+#ifdef ESLOPE
+ if (*r2->t_slope) {
+ high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y);
+ highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y);
+ } else
+ high2 = highslope2 = *r2->topheight;
+ if (*r2->b_slope) {
+ low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y);
+ lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y);
+ } else
+ low2 = lowslope2 = *r2->bottomheight;
+
+ if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2))
+ continue;
+#else
if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
continue;
+#endif
break;
}
@@ -1811,16 +2200,33 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue;
if (!(rover->flags & FF_ALLSIDES))
continue;
- if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
- continue;
if (rover->norender == leveltime)
continue;
+#ifdef ESLOPE
+ if (*rover->t_slope) {
+ high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y);
+ highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y);
+ } else
+ high1 = highslope1 = *rover->topheight;
+ if (*rover->b_slope) {
+ low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y);
+ lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y);
+ } else
+ low1 = lowslope1 = *rover->bottomheight;
+
+ if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
+ continue;
+#else
+ if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
+ continue;
+#endif
+
for (r2 = backsector->ffloors; r2; r2 = r2->next)
{
if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)
- || *r2->topheight < lowcut || *r2->bottomheight > highcut)
+ || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red
continue;
if (r2->norender == leveltime)
@@ -1840,8 +2246,24 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue;
}
+#ifdef ESLOPE
+ if (*r2->t_slope) {
+ high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y);
+ highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y);
+ } else
+ high2 = highslope2 = *r2->topheight;
+ if (*r2->b_slope) {
+ low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y);
+ lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y);
+ } else
+ low2 = lowslope2 = *r2->bottomheight;
+
+ if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2))
+ continue;
+#else
if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
continue;
+#endif
break;
}
@@ -1858,11 +2280,21 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES)
continue;
- if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
- continue;
if (rover->norender == leveltime)
continue;
+#ifdef ESLOPE
+ // Oy vey.
+ if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz
+ && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz)
+ ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz
+ && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz))
+ continue;
+#else
+ if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
+ continue;
+#endif
+
ds_p->thicksides[i] = rover;
i++;
}
@@ -1873,12 +2305,27 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES))
continue;
+ if (rover->norender == leveltime)
+ continue;
+#ifdef ESLOPE
+ // Oy vey.
+ if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz
+ && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz)
+ ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz
+ && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz))
+ continue;
+
+ if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz
+ && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz)
+ ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz
+ && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz))
+ continue;
+#else
if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
continue;
if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight)
continue;
- if (rover->norender == leveltime)
- continue;
+#endif
ds_p->thicksides[i] = rover;
i++;
@@ -1898,6 +2345,32 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else
ds_p->maskedtexturecol = ds_p->thicksidecol;
+#ifdef ESLOPE
+ maskedtextureheight = &(ds_p->maskedtextureheight[0]); // ????
+
+ // Set midtexture starting height
+ if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing
+ rw_midtextureslide = rw_midtexturebackslide = 0;
+ if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
+ rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
+ else
+ rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz;
+
+ } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
+ rw_midtexturemid = worldbottom;
+ rw_midtextureslide = floorfrontslide;
+ rw_midtextureback = worldlow;
+ rw_midtexturebackslide = floorbackslide;
+ } else {
+ rw_midtexturemid = worldtop;
+ rw_midtextureslide = ceilingfrontslide;
+ rw_midtextureback = worldhigh;
+ rw_midtexturebackslide = ceilingbackslide;
+ }
+ rw_midtexturemid += sidedef->rowoffset;
+ rw_midtextureback += sidedef->rowoffset;
+#endif
+
maskedtexture = true;
}
}
@@ -1950,13 +2423,21 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// and doesn't need to be marked.
if (frontsector->heightsec == -1)
{
- if (frontsector->floorheight >= viewz)
+ if ((
+#ifdef ESLOPE
+ frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
+#endif
+ frontsector->floorheight) >= viewz)
{
// above view plane
markfloor = false;
}
- if (frontsector->ceilingheight <= viewz &&
+ if ((
+#ifdef ESLOPE
+ frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) :
+#endif
+ frontsector->ceilingheight) <= viewz &&
frontsector->ceilingpic != skyflatnum)
{
// below view plane
@@ -1967,6 +2448,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// calculate incremental stepping values for texture edges
worldtop >>= 4;
worldbottom >>= 4;
+#ifdef ESLOPE
+ worldtopslope >>= 4;
+ worldbottomslope >>= 4;
+#endif
topstep = -FixedMul (rw_scalestep, worldtop);
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
@@ -1974,6 +2459,17 @@ void R_StoreWallRange(INT32 start, INT32 stop)
bottomstep = -FixedMul (rw_scalestep,worldbottom);
bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
+#ifdef ESLOPE
+ if (frontsector->c_slope) {
+ fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2);
+ topstep = (topfracend-topfrac)/(stop-start+1);
+ }
+ if (frontsector->f_slope) {
+ fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2);
+ bottomstep = (bottomfracend-bottomfrac)/(stop-start+1);
+ }
+#endif
+
dc_numlights = 0;
if (frontsector->numlights)
@@ -1987,26 +2483,83 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (i = p = 0; i < dc_numlights; i++)
{
+#ifdef ESLOPE
+ fixed_t leftheight, rightheight;
+#endif
+
light = &frontsector->lightlist[i];
rlight = &dc_lightlist[p];
+#ifdef ESLOPE
+ if (light->slope) {
+ leftheight = P_GetZAt(light->slope, segleft.x, segleft.y);
+ rightheight = P_GetZAt(light->slope, segright.x, segright.y);
+
+ // Flag sector as having slopes
+ frontsector->hasslope = true;
+ } else
+ leftheight = rightheight = light->height;
+
+ leftheight -= viewz;
+ rightheight -= viewz;
+
+ leftheight >>= 4;
+ rightheight >>= 4;
+#endif
+
if (i != 0)
{
+#ifdef ESLOPE
+ if (leftheight < worldbottom && rightheight < worldbottomslope)
+ continue;
+
+ if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight)
+ continue;
+#else
if (light->height < frontsector->floorheight)
continue;
if (light->height > frontsector->ceilingheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight)
continue;
+#endif
}
+#ifdef ESLOPE
+ rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale);
+ rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2);
+ rlight->heightstep = (rlight->heightstep-rlight->height)/(stop-start+1);
+#else
rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale);
rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4);
+#endif
rlight->flags = light->flags;
if (light->caster && light->caster->flags & FF_SOLID)
{
+#ifdef ESLOPE
+ if (*light->caster->b_slope) {
+ leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y);
+ rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y);
+
+ // Flag sector as having slopes
+ frontsector->hasslope = true;
+ } else
+ leftheight = rightheight = *light->caster->bottomheight;
+
+ leftheight -= viewz;
+ rightheight -= viewz;
+
+ leftheight >>= 4;
+ rightheight >>= 4;
+
+ rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale);
+ rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2);
+ rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(stop-start+1);
+
+#else
rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale);
rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4);
+#endif
}
rlight->lightlevel = *light->lightlevel;
@@ -2027,8 +2580,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#endif
ffloor[i].f_pos >>= 4;
+#ifdef ESLOPE
+ ffloor[i].f_pos_slope >>= 4;
+ ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
+ ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(stop-start+1);
+#else
ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos);
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
+#endif
}
}
@@ -2036,21 +2595,50 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
worldhigh >>= 4;
worldlow >>= 4;
+#ifdef ESLOPE
+ worldhighslope >>= 4;
+ worldlowslope >>= 4;
+#endif
- if (worldhigh < worldtop)
+ if (worldhigh < worldtop
+#ifdef ESLOPE
+ || worldhighslope <= worldtopslope
+#endif
+ )
{
pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
pixhighstep = -FixedMul (rw_scalestep,worldhigh);
+
+#ifdef ESLOPE
+ if (backsector->c_slope) {
+ fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2);
+ pixhighstep = (topfracend-pixhigh)/(stop-start+1);
+ }
+#endif
}
- if (worldlow > worldbottom)
+ if (worldlow > worldbottom
+#ifdef ESLOPE
+ || worldlowslope >= worldbottomslope
+#endif
+ )
{
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
pixlowstep = -FixedMul (rw_scalestep,worldlow);
+#ifdef ESLOPE
+ if (backsector->f_slope) {
+ fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2);
+ pixlowstep = (bottomfracend-pixlow)/(stop-start+1);
+ }
+#endif
}
{
ffloor_t * rover;
+#ifdef ESLOPE
+ fixed_t rovertest;
+ fixed_t planevistest;
+#endif
i = 0;
if (backsector->ffloors)
@@ -2062,6 +2650,52 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (rover->norender == leveltime)
continue;
+#ifdef ESLOPE
+ // Let the renderer know this sector is sloped.
+ if (*rover->b_slope || *rover->t_slope)
+ backsector->hasslope = true;
+
+ rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->bottomheight) - viewz;
+ planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight);
+
+ if (rovertest>>4 <= worldhigh &&
+ rovertest>>4 >= worldlow &&
+ ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
+ (viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
+ {
+ //ffloor[i].slope = *rover->b_slope;
+ ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz;
+ ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz;
+ ffloor[i].b_pos >>= 4;
+ ffloor[i].b_pos_slope >>= 4;
+ ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
+ ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
+ ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1);
+ i++;
+ }
+
+ if (i >= MAXFFLOORS)
+ break;
+
+ rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->topheight) - viewz;
+ planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight);
+
+ if (rovertest>>4 <= worldhigh &&
+ rovertest>>4 >= worldlow &&
+ ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
+ (viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
+ {
+ //ffloor[i].slope = *rover->t_slope;
+ ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz;
+ ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz;
+ ffloor[i].b_pos >>= 4;
+ ffloor[i].b_pos_slope >>= 4;
+ ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
+ ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
+ ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1);
+ i++;
+ }
+#else
if (*rover->bottomheight <= backsector->ceilingheight &&
*rover->bottomheight >= backsector->floorheight &&
((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) ||
@@ -2073,8 +2707,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
}
+
if (i >= MAXFFLOORS)
break;
+
if (*rover->topheight >= backsector->floorheight &&
*rover->topheight <= backsector->ceilingheight &&
((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) ||
@@ -2086,6 +2722,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
}
+#endif
}
}
else if (frontsector && frontsector->ffloors)
@@ -2097,6 +2734,53 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (rover->norender == leveltime)
continue;
+
+#ifdef ESLOPE
+ // Let the renderer know this sector is sloped.
+ if (*rover->b_slope || *rover->t_slope)
+ frontsector->hasslope = true;
+
+ rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight) - viewz;
+ planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight);
+
+ if (rovertest>>4 <= worldtop &&
+ rovertest>>4 >= worldbottom &&
+ ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
+ (viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
+ {
+ //ffloor[i].slope = *rover->b_slope;
+ ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz;
+ ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz;
+ ffloor[i].b_pos >>= 4;
+ ffloor[i].b_pos_slope >>= 4;
+ ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
+ ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
+ ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1);
+ i++;
+ }
+
+ if (i >= MAXFFLOORS)
+ break;
+
+ rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight) - viewz;
+ planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight);
+
+ if (rovertest>>4 <= worldtop &&
+ rovertest>>4 >= worldbottom &&
+ ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
+ (viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
+ {
+ //ffloor[i].slope = *rover->t_slope;
+ ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz;
+ ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz;
+ ffloor[i].b_pos >>= 4;
+ ffloor[i].b_pos_slope >>= 4;
+ ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
+ ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
+ ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1);
+ i++;
+ }
+#else
if (*rover->bottomheight <= frontsector->ceilingheight &&
*rover->bottomheight >= frontsector->floorheight &&
((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) ||
@@ -2121,6 +2805,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
}
+#endif
}
}
#ifdef POLYOBJECTS_PLANES
@@ -2137,6 +2822,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (ffloor[i].plane->maxx < ds_p->x2)
ffloor[i].plane->maxx = ds_p->x2;
+#ifdef ESLOPE
+ ffloor[i].slope = NULL;
+#endif
ffloor[i].b_pos = backsector->floorheight;
ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
@@ -2153,6 +2841,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (ffloor[i].plane->maxx < ds_p->x2)
ffloor[i].plane->maxx = ds_p->x2;
+#ifdef ESLOPE
+ ffloor[i].slope = NULL;
+#endif
ffloor[i].b_pos = backsector->ceilingheight;
ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
diff --git a/src/r_things.c b/src/r_things.c
index 3b46d4d3d..72b89a0aa 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -24,6 +24,7 @@
#include "r_plane.h"
#include "p_tick.h"
#include "p_local.h"
+#include "p_slopes.h"
#include "dehacked.h" // get_number (for thok)
#include "d_netfil.h" // blargh. for nameonly().
#include "m_cheat.h" // objectplace
@@ -338,6 +339,10 @@ void R_AddSpriteDefs(UINT16 wadnum)
else
start++; // just after S_START
+ // ignore skin wads (we don't want skin sprites interfering with vanilla sprites)
+ if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != INT16_MAX)
+ return;
+
end = W_CheckNumForNamePwad("S_END",wadnum,start);
if (end == INT16_MAX)
end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib.
@@ -950,12 +955,22 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
for (i = 1; i < sector->numlights; i++)
{
- if (sector->lightlist[i].height >= sprite->gzt || !(sector->lightlist[i].caster->flags & FF_CUTSPRITES))
+ fixed_t testheight = sector->lightlist[i].height;
+
+ if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES))
continue;
- if (sector->lightlist[i].height <= sprite->gz)
+
+#ifdef ESLOPE
+ if (sector->lightlist[i].slope)
+ testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy);
+#endif
+
+ if (testheight >= sprite->gzt)
+ continue;
+ if (testheight <= sprite->gz)
return;
- cutfrac = (INT16)((centeryfrac - FixedMul(sector->lightlist[i].height - viewz, sprite->scale))>>FRACBITS);
+ cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS);
if (cutfrac < 0)
continue;
if (cutfrac > vid.height)
@@ -966,15 +981,15 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
sprite->cut |= SC_BOTTOM;
- sprite->gz = sector->lightlist[i].height;
+ sprite->gz = testheight;
newsprite->gzt = sprite->gz;
sprite->sz = cutfrac;
newsprite->szt = (INT16)(sprite->sz - 1);
- if (sector->lightlist[i].height < sprite->pzt && sector->lightlist[i].height > sprite->pz)
- sprite->pz = newsprite->pzt = sector->lightlist[i].height;
+ if (testheight < sprite->pzt && testheight > sprite->pz)
+ sprite->pz = newsprite->pzt = testheight;
else
{
newsprite->pz = newsprite->gz;
@@ -1088,9 +1103,14 @@ static void R_ProjectSprite(mobj_t *thing)
//Fab : 02-08-98: 'skin' override spritedef currently used for skin
if (thing->skin && thing->sprite == SPR_PLAY)
{
- sprdef = &((skin_t *)thing->skin)->spritedef;
- if (rot >= sprdef->numframes)
+ sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
+ if (rot >= sprdef->numframes) {
+ CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[SPR2_%s] frame %d\n"), ((skin_t *)thing->skin)->name, spr2names[thing->sprite2], rot);
+ thing->sprite = states[S_UNKNOWN].sprite;
+ thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite];
+ rot = thing->frame&FF_FRAMEMASK;
+ }
}
else
sprdef = &sprites[thing->sprite];
@@ -1191,7 +1211,20 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->subsector->sector->numlights)
{
INT32 lightnum;
+#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights!
+ light = thing->subsector->sector->numlights - 1;
+
+ for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
+ fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y)
+ : thing->subsector->sector->lightlist[lightnum].height;
+ if (h <= gzt) {
+ light = lightnum - 1;
+ break;
+ }
+ }
+#else
light = R_GetPlaneLight(thing->subsector->sector, gzt, false);
+#endif
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
if (lightnum < 0)
@@ -1546,23 +1579,12 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
// If a limit exists, handle things a tiny bit different.
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS))
{
- if (!players[displayplayer].mo)
- return; // Draw nothing if no player.
- // todo: is this really the best option for this situation?
-
for (thing = sec->thinglist; thing; thing = thing->snext)
{
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
continue;
- approx_dist = P_AproxDistance(
- players[displayplayer].mo->x - thing->x,
- players[displayplayer].mo->y - thing->y);
-
- if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo)
- approx_dist = P_AproxDistance(
- players[secondarydisplayplayer].mo->x - thing->x,
- players[secondarydisplayplayer].mo->y - thing->y);
+ approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
if (approx_dist <= limit_dist)
R_ProjectSprite(thing);
@@ -1579,23 +1601,12 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
// Someone seriously wants infinite draw distance for precipitation?
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS))
{
- if (!players[displayplayer].mo)
- return; // Draw nothing if no player.
- // todo: is this really the best option for this situation?
-
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
{
if (precipthing->precipflags & PCF_INVISIBLE)
continue;
- approx_dist = P_AproxDistance(
- players[displayplayer].mo->x - precipthing->x,
- players[displayplayer].mo->y - precipthing->y);
-
- if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo)
- approx_dist = P_AproxDistance(
- players[secondarydisplayplayer].mo->x - precipthing->x,
- players[secondarydisplayplayer].mo->y - precipthing->y);
+ approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
if (approx_dist <= limit_dist)
R_ProjectPrecipitationSprite(precipthing);
@@ -1704,6 +1715,19 @@ static void R_CreateDrawNodes(void)
}
if (ds->maskedtexturecol)
{
+#ifdef POLYOBJECTS_PLANES
+ // Check for a polyobject plane, but only if this is a front line
+ if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) {
+ // Put it in!
+
+ entry = R_CreateDrawNode(&nodehead);
+ entry->plane = ds->curline->polyseg->visplane;
+ entry->seg = ds;
+ ds->curline->polyseg->visplane->polyobj = ds->curline->polyseg;
+ ds->curline->polyseg->visplane = NULL;
+ }
+#endif
+
entry = R_CreateDrawNode(&nodehead);
entry->seg = ds;
}
@@ -1720,7 +1744,7 @@ static void R_CreateDrawNodes(void)
plane = ds->ffloorplanes[p];
R_PlaneBounds(plane);
- if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low)
+ if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low || plane->polyobj)
{
ds->ffloorplanes[p] = NULL;
continue;
@@ -1761,24 +1785,34 @@ static void R_CreateDrawNodes(void)
{
if (r2->plane)
{
+ fixed_t planeobjectz, planecameraz;
if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1)
continue;
if (rover->szt > r2->plane->low || rover->sz < r2->plane->high)
continue;
+#ifdef ESLOPE
+ // Effective height may be different for each comparison in the case of slopes
+ if (r2->plane->slope) {
+ planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy);
+ planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy);
+ } else
+#endif
+ planeobjectz = planecameraz = r2->plane->height;
+
if (rover->mobjflags & MF_NOCLIPHEIGHT)
{
//Objects with NOCLIPHEIGHT can appear halfway in.
- if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= r2->plane->height)
+ if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz)
continue;
- if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= r2->plane->height)
+ if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz)
continue;
}
else
{
- if (r2->plane->height < viewz && rover->pz >= r2->plane->height)
+ if (planecameraz < viewz && rover->pz >= planeobjectz)
continue;
- if (r2->plane->height > viewz && rover->pzt <= r2->plane->height)
+ if (planecameraz > viewz && rover->pzt <= planeobjectz)
continue;
}
@@ -1808,6 +1842,7 @@ static void R_CreateDrawNodes(void)
}
else if (r2->thickseg)
{
+ fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1)
continue;
@@ -1818,9 +1853,25 @@ static void R_CreateDrawNodes(void)
if (scale <= rover->scale)
continue;
- if ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) ||
- (*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) ||
- (*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight))
+#ifdef ESLOPE
+ if (*r2->ffloor->t_slope) {
+ topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy);
+ topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy);
+ } else
+#endif
+ topplaneobjectz = topplanecameraz = *r2->ffloor->topheight;
+
+#ifdef ESLOPE
+ if (*r2->ffloor->b_slope) {
+ botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy);
+ botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy);
+ } else
+#endif
+ botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight;
+
+ if ((topplanecameraz > viewz && botplanecameraz < viewz) ||
+ (topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||
+ (botplanecameraz > viewz && rover->gz > botplaneobjectz))
{
entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry;
@@ -1831,7 +1882,7 @@ static void R_CreateDrawNodes(void)
}
else if (r2->seg)
{
-#ifdef POLYOBJECTS_PLANES
+#if 0 //#ifdef POLYOBJECTS_PLANES
if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) {
// Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where
// polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red
@@ -2039,21 +2090,21 @@ void R_ClipSprites(void)
if (spr->gzt <= ds->tsilheight)
silhouette &= ~SIL_TOP;
- if (silhouette == 1)
+ if (silhouette == SIL_BOTTOM)
{
// bottom sil
for (x = r1; x <= r2; x++)
if (spr->clipbot[x] == -2)
spr->clipbot[x] = ds->sprbottomclip[x];
}
- else if (silhouette == 2)
+ else if (silhouette == SIL_TOP)
{
// top sil
for (x = r1; x <= r2; x++)
if (spr->cliptop[x] == -2)
spr->cliptop[x] = ds->sprtopclip[x];
}
- else if (silhouette == 3)
+ else if (silhouette == (SIL_TOP|SIL_BOTTOM))
{
// both
for (x = r1; x <= r2; x++)
@@ -2225,7 +2276,6 @@ static void Sk_SetDefaultValue(skin_t *skin)
sizeof skin->name, "skin %u", (UINT32)(skin-skins));
skin->name[sizeof skin->name - 1] = '\0';
skin->wadnum = INT16_MAX;
- strcpy(skin->sprite, "");
skin->flags = 0;
@@ -2267,7 +2317,6 @@ static void Sk_SetDefaultValue(skin_t *skin)
//
void R_InitSkins(void)
{
- skin_t *skin;
#ifdef SKINVALUES
INT32 i;
@@ -2278,43 +2327,8 @@ void R_InitSkins(void)
}
#endif
- // skin[0] = Sonic skin
- skin = &skins[0];
- numskins = 1;
- Sk_SetDefaultValue(skin);
-
- // Hardcoded S_SKIN customizations for Sonic.
- strcpy(skin->name, DEFAULTSKIN);
-#ifdef SKINVALUES
- skin_cons_t[0].strvalue = skins[0].name;
-#endif
- skin->flags = SF_SUPER|SF_SUPERANIMS|SF_SUPERSPIN;
- strcpy(skin->realname, "Sonic");
- strcpy(skin->hudname, "SONIC");
-
- strncpy(skin->charsel, "CHRSONIC", 8);
- strncpy(skin->face, "LIVSONIC", 8);
- strncpy(skin->superface, "LIVSUPER", 8);
- skin->prefcolor = SKINCOLOR_BLUE;
-
- skin->ability = CA_THOK;
- skin->actionspd = 60<normalspeed = 36<runspeed = 28<thrustfactor = 5;
- skin->accelstart = 96;
- skin->acceleration = 40;
-
- skin->spritedef.numframes = sprites[SPR_PLAY].numframes;
- skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes;
- ST_LoadFaceGraphics(skin->face, skin->superface, 0);
-
- //MD2 for sonic doesn't want to load in Linux.
-#ifdef HWRENDER
- if (rendermode == render_opengl)
- HWR_AddPlayerMD2(0);
-#endif
+ // no default skin!
+ numskins = 0;
}
// returns true if the skin name is found (loaded from pwad)
@@ -2559,11 +2573,6 @@ void R_AddSkins(UINT16 wadnum)
STRBUFCPY(skin->realname, skin->hudname);
}
- else if (!stricmp(stoken, "sprite"))
- {
- strupr(value);
- strncpy(skin->sprite, value, sizeof skin->sprite);
- }
else if (!stricmp(stoken, "charsel"))
{
strupr(value);
@@ -2645,71 +2654,25 @@ next_token:
}
free(buf2);
- // Not in vanilla, you don't.
- skin->flags &= ~SF_SUPER;
+ if (skin != &skins[0])
+ skin->flags &= ~SF_SUPER;
- lump++; // if no sprite defined use spirte just after this one
- if (skin->sprite[0] == '\0')
+ // Add sprites
{
- const char *csprname = W_CheckNameForNumPwad(wadnum, lump);
+ UINT16 z;
+ UINT8 sprite2;
- // skip to end of this skin's frames
- lastlump = lump;
- while (W_CheckNameForNumPwad(wadnum,lastlump) && memcmp(W_CheckNameForNumPwad(wadnum, lastlump),csprname,4)==0)
- lastlump++;
- // allocate (or replace) sprite frames, and set spritedef
- R_AddSingleSpriteDef(csprname, &skin->spritedef, wadnum, lump, lastlump);
- }
- else
- {
- // search in the normal sprite tables
- size_t name;
- boolean found = false;
- const char *sprname = skin->sprite;
- for (name = 0;sprnames[name][0] != '\0';name++)
- if (strncmp(sprnames[name], sprname, 4) == 0)
- {
- found = true;
- skin->spritedef = sprites[name];
- }
+ lump++; // start after S_SKIN
+ lastlump = W_CheckNumForNamePwad("S_END",wadnum,lump); // stop at S_END
+ // old wadding practices die hard -- stop at S_SKIN or S_START if they come before S_END.
+ z = W_CheckNumForNamePwad("S_SKIN",wadnum,lump);
+ if (z < lastlump) lastlump = z;
+ z = W_CheckNumForNamePwad("S_START",wadnum,lump);
+ if (z < lastlump) lastlump = z;
- // not found so make a new one
- // go through the entire current wad looking for our sprite
- // don't just mass add anything beginning with our four letters.
- // "HOODFACE" is not a sprite name.
- if (!found)
- {
- UINT16 localllump = 0, lstart = UINT16_MAX, lend = UINT16_MAX;
- const char *lname;
-
- while ((lname = W_CheckNameForNumPwad(wadnum,localllump)))
- {
- // If this is a valid sprite...
- if (!memcmp(lname,sprname,4) && lname[4] && lname[5] && lname[5] >= '0' && lname[5] <= '8')
- {
- if (lstart == UINT16_MAX)
- lstart = localllump;
- // If already set do nothing
- }
- else
- {
- if (lstart != UINT16_MAX)
- {
- lend = localllump;
- break;
- }
- // If not already set do nothing
- }
- ++localllump;
- }
-
- R_AddSingleSpriteDef(sprname, &skin->spritedef, wadnum, lstart, lend);
- }
-
- // I don't particularly care about skipping to the end of the used frames.
- // We could be using frames from ANYWHERE in the current WAD file, including
- // right before us, which is a terrible idea.
- // So just let the function in the while loop take care of it for us.
+ // load all sprite sets we are aware of.
+ for (sprite2 = 0; sprite2 < NUMPLAYERSPRITES; sprite2++)
+ R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
}
R_FlushTranslationColormapCache();
diff --git a/src/r_things.h b/src/r_things.h
index 5a7036c6a..054a6497d 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -68,9 +68,7 @@ void R_DrawMasked(void);
typedef struct
{
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin
- spritedef_t spritedef;
UINT16 wadnum;
- char sprite[4]; // Sprite name, if seperated from S_SKIN.
skinflags_t flags;
char realname[SKINNAMESIZE+1]; // Display name for level completion.
@@ -102,6 +100,8 @@ typedef struct
// specific sounds per skin
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
+
+ spritedef_t sprites[NUMPLAYERSPRITES];
} skin_t;
// -----------
diff --git a/src/sdl/SDL_icon.xpm b/src/sdl/SDL_icon.xpm
index 70bb02d3c..cf72960df 100644
--- a/src/sdl/SDL_icon.xpm
+++ b/src/sdl/SDL_icon.xpm
@@ -1,80 +1,425 @@
/* XPM */
-static const char * SDL_icon_xpm[] = {
-"32 32 45 1",
-" c None",
-". c #6B6BFF",
-"+ c #3D00B9",
-"@ c #4848FF",
-"# c #2525FF",
-"$ c #310096",
-"% c #003196",
-"& c #003DB9",
-"* c #620096",
-"= c #6E6E6E",
-"- c #966200",
-"; c #250073",
-"> c #626262",
-", c #FF8F6B",
-"' c #FFC66B",
-") c #FFAB8E",
-"! c #000080",
-"~ c #B6B6B6",
-"{ c #929292",
-"] c #FFD48E",
-"^ c #0000B9",
-"/ c #565656",
-"( c #868686",
-"_ c #808080",
-": c #C0C0C0",
-"< c #DADADA",
-"[ c #F2F2F2",
-"} c #FFFFFF",
-"| c #CECECE",
-"1 c #AAAAAA",
-"2 c #E6E6E6",
-"3 c #000096",
-"4 c #AB8EFF",
-"5 c #190050",
-"6 c #000000",
-"7 c #8E8EFF",
-"8 c #3E3E3E",
-"9 c #7A7A7A",
-"0 c #0E0E0E",
-"a c #9E9E9E",
-"b c #001950",
-"c c #C2C2C2",
-"d c #323232",
-"e c #002573",
-"f c #A0A0A4",
-" ",
-" ",
-" ",
-" .+@##@. ",
-" @@.@#######@ ",
-" @@....######### ",
-" .. .@.....@+##$%%%&&% ",
-" ..@# @@....@+#*=-;%%%%% ",
-" ..@#@......@>,')!%%%$ ",
-" ~..$#.........{])^#+%/ ",
-" +##@.........()^@@@@@_ ",
-" $####@........#=#######+ ",
-" +######....@@##^#########_ ",
-" +#####=:<<:+##############/ ",
-"[<=####{<}}}}|###############= ",
-" }1###=2}}}}}}.############### ",
-" }<3#3~}}}}}}}4################ ",
-" }<5#6:}}}}}}}7################/",
-" }:6861}}}}}}}.########$$ 9 .@$",
-" }:0a6~}}}}}}}@######5b ",
-"22cd262}}}}}}2######5b$ ",
-" 2>1a}}}}}}}{(*###%be## ",
-" 860)1<[22c1)]]+##be### ",
-" ~)]]]))))]]]]]=#bb#### ",
-" )]]]]]]]]](]]=eb$#### ",
-" :]]]]]]]]]'9bbb$##### ",
-" ),'''''( >db+### ",
-" =##f ",
-" { ",
-" ",
-" ",
-" "};
+static char * C:\Repo\srb2\src\sdl\SDL_icon_xpm[] = {
+"32 32 390 2",
+" c None",
+". c #4F4F70",
+"+ c #4D4D87",
+"@ c #4D4D84",
+"# c #4E4E6C",
+"$ c #6C6C95",
+"% c #5E5EB2",
+"& c #6B6BE7",
+"* c #7373F9",
+"= c #7C7CFF",
+"- c #6F70E7",
+"; c #494BB2",
+"> c #4F4FA3",
+", c #6464D4",
+"' c #7979F5",
+") c #5F5FCA",
+"! c #5D5D93",
+"~ c #3A3A9F",
+"{ c #6060AC",
+"] c #777793",
+"^ c #5C5CB3",
+"/ c #7373EA",
+"( c #7A7AFF",
+"_ c #7575FF",
+": c #7979FF",
+"< c #6264DD",
+"[ c #47478C",
+"} c #564567",
+"| c #4647D0",
+"1 c #5C5CAE",
+"2 c #5E5EFF",
+"3 c #2929FF",
+"4 c #1D1DFF",
+"5 c #1919D1",
+"6 c #4F4F90",
+"7 c #1E1ECE",
+"8 c #5858FF",
+"9 c #6767A8",
+"0 c #4949A0",
+"a c #7070FB",
+"b c #7D7DFF",
+"c c #7777FF",
+"d c #7373FF",
+"e c #7272FF",
+"f c #7878FF",
+"g c #6465D8",
+"h c #363886",
+"i c #9F7655",
+"j c #C89B5C",
+"k c #1D1CB7",
+"l c #3031B1",
+"m c #1919F4",
+"n c #1111FF",
+"o c #1818FF",
+"p c #1B1BFF",
+"q c #1C1CFF",
+"r c #2626B3",
+"s c #1E1EC8",
+"t c #1A1AE8",
+"u c #24249F",
+"v c #2F2FD2",
+"w c #7676FF",
+"x c #6869E2",
+"y c #414290",
+"z c #8C6751",
+"A c #FCBA68",
+"B c #E9BD7D",
+"C c #201EB8",
+"D c #090AB8",
+"E c #1616EB",
+"F c #1818FD",
+"G c #1414EE",
+"H c #1010E1",
+"I c #0E0EE2",
+"J c #0E0EF4",
+"K c #0606B2",
+"L c #7A7A89",
+"M c #0C0C9A",
+"N c #0A0AA7",
+"O c #2424E4",
+"P c #6669E6",
+"Q c #4F4A8F",
+"R c #BF853B",
+"S c #FFD98D",
+"T c #CDAB76",
+"U c #1717C4",
+"V c #0F10BA",
+"W c #0909B6",
+"X c #0505C3",
+"Y c #0000B6",
+"Z c #0000BE",
+"` c #0000AD",
+" . c #1D1D83",
+".. c #63638E",
+"+. c #090975",
+"@. c #1414F3",
+"#. c #5B5BFF",
+"$. c #7B7BFF",
+"%. c #7070FF",
+"&. c #6E6EFF",
+"*. c #7172F6",
+"=. c #625DAF",
+"-. c #BA9E6C",
+";. c #887167",
+">. c #090DF2",
+",. c #1313BE",
+"'. c #000085",
+"). c #0000AC",
+"!. c #0202AA",
+"~. c #242488",
+"{. c #1414C7",
+"]. c #1717FF",
+"^. c #5959FF",
+"/. c #7F7FFF",
+"(. c #7474FF",
+"_. c #7171FF",
+":. c #8686FF",
+"<. c #7574FF",
+"[. c #797CFF",
+"}. c #5756B8",
+"|. c #1C19A4",
+"1. c #1617FF",
+"2. c #1212BD",
+"3. c #040485",
+"4. c #0707A4",
+"5. c #1B1B71",
+"6. c #373797",
+"7. c #1616FF",
+"8. c #5050FF",
+"9. c #8080FF",
+"0. c #AAAAFF",
+"a. c #AEAEF6",
+"b. c #8A8AEF",
+"c. c #6969FB",
+"d. c #2728FF",
+"e. c #1314FF",
+"f. c #1919FF",
+"g. c #1313E8",
+"h. c #1F1FF4",
+"i. c #5454FF",
+"j. c #6D6DF0",
+"k. c #6868B5",
+"l. c #0B0BB8",
+"m. c #1212C5",
+"n. c #1616FC",
+"o. c #1515FF",
+"p. c #1212FF",
+"q. c #2323FF",
+"r. c #3636FF",
+"s. c #4040FF",
+"t. c #4343F9",
+"u. c #5D5DB8",
+"v. c #7F7F92",
+"w. c #878793",
+"x. c #4B4B94",
+"y. c #0B0CE2",
+"z. c #1313FF",
+"A. c #4C4CFF",
+"B. c #8282FF",
+"C. c #7171ED",
+"D. c #636394",
+"E. c #575785",
+"F. c #A9A99C",
+"G. c #1414BC",
+"H. c #1414FF",
+"I. c #0707FD",
+"J. c #2525AA",
+"K. c #A8A8A4",
+"L. c #EBEBE2",
+"M. c #F9F9F2",
+"N. c #E1E1CC",
+"O. c #4D4D9F",
+"P. c #0B0BF7",
+"Q. c #2121FF",
+"R. c #3232FF",
+"S. c #5555FF",
+"T. c #6161B4",
+"U. c #B5B5B2",
+"V. c #FFFFF8",
+"W. c #4F4F9A",
+"X. c #0B0BF5",
+"Y. c #1616C5",
+"Z. c #A8A8A1",
+"`. c #FFFFFC",
+" + c #FFFFFF",
+".+ c #C0C0C4",
+"++ c #1212D4",
+"@+ c #4444FF",
+"#+ c #6464FF",
+"$+ c #8383FF",
+"%+ c #6767C3",
+"&+ c #E4E4E4",
+"*+ c #9494AE",
+"=+ c #0808DF",
+"-+ c #0D0DF2",
+";+ c #61619A",
+">+ c #F1F1E0",
+",+ c #E8E8DD",
+"'+ c #2424BB",
+")+ c #1010FF",
+"!+ c #3434FF",
+"~+ c #6161FF",
+"{+ c #6969D2",
+"]+ c #EFEFF0",
+"^+ c #C2C2BA",
+"/+ c #1010B6",
+"(+ c #0909AC",
+"_+ c #A4A49A",
+":+ c #EAEADE",
+"<+ c #2525B8",
+"[+ c #2F2FFF",
+"}+ c #3C3CB5",
+"|+ c #EEEEEE",
+"1+ c #BBBBAD",
+"2+ c #0B0B56",
+"3+ c #0B0BFC",
+"4+ c #1212EF",
+"5+ c #0C0C3E",
+"6+ c #919187",
+"7+ c #DEDED6",
+"8+ c #1F1FC0",
+"9+ c #1A1AFF",
+"0+ c #1717FA",
+"a+ c #1515F8",
+"b+ c #1111FC",
+"c+ c #494992",
+"d+ c #999998",
+"e+ c #3E3E3B",
+"f+ c #3C3C99",
+"g+ c #535397",
+"h+ c #5A5A4D",
+"i+ c #6F6F70",
+"j+ c #BFBFC9",
+"k+ c #1111D6",
+"l+ c #1515F1",
+"m+ c #0F0FE2",
+"n+ c #0D0DD9",
+"o+ c #0909CD",
+"p+ c #0808C7",
+"q+ c #0505C7",
+"r+ c #0303CB",
+"s+ c #0101C0",
+"t+ c #0202AF",
+"u+ c #0606AC",
+"v+ c #121283",
+"w+ c #BBBBBB",
+"x+ c #BEBEBE",
+"y+ c #2F2F2E",
+"z+ c #C7C8BB",
+"A+ c #D8DAD1",
+"B+ c #272828",
+"C+ c #929292",
+"D+ c #8688C7",
+"E+ c #0506F6",
+"F+ c #1616F5",
+"G+ c #0B0BD3",
+"H+ c #0202B6",
+"I+ c #0000AF",
+"J+ c #0000B4",
+"K+ c #0000BD",
+"L+ c #0000BB",
+"M+ c #00009E",
+"N+ c #2C2C7E",
+"O+ c #6A6A8B",
+"P+ c #959595",
+"Q+ c #F0F0F1",
+"R+ c #E1E1E1",
+"S+ c #8C8E90",
+"T+ c #BEBEBF",
+"U+ c #C9C7C5",
+"V+ c #939699",
+"W+ c #E7EAED",
+"X+ c #CBCBC7",
+"Y+ c #413B9B",
+"Z+ c #0607DD",
+"`+ c #0C0CE2",
+" @ c #0303B9",
+".@ c #0000A8",
+"+@ c #181888",
+"@@ c #6A6A6A",
+"#@ c #626263",
+"$@ c #4B4B4C",
+"%@ c #3E3B36",
+"&@ c #9B805C",
+"*@ c #D9B07D",
+"=@ c #C9AE89",
+"-@ c #B9AF9E",
+";@ c #C7C5C4",
+">@ c #CBCCCF",
+",@ c #C7C6C6",
+"'@ c #AEA59A",
+")@ c #B69974",
+"!@ c #D8B87F",
+"~@ c #9B8272",
+"{@ c #0E0B9B",
+"]@ c #0000B7",
+"^@ c #0000B8",
+"/@ c #000082",
+"(@ c #00007A",
+"_@ c #636379",
+":@ c #62533E",
+"<@ c #B59B6C",
+"[@ c #DEB07B",
+"}@ c #FECC90",
+"|@ c #FFCE92",
+"1@ c #FEC98C",
+"2@ c #F1BD82",
+"3@ c #D1A979",
+"4@ c #BC9E73",
+"5@ c #CCA777",
+"6@ c #EAB980",
+"7@ c #FFCD90",
+"8@ c #FFD595",
+"9@ c #FDD782",
+"0@ c #413678",
+"a@ c #0000AE",
+"b@ c #000077",
+"c@ c #010193",
+"d@ c #0C0CE4",
+"e@ c #38389E",
+"f@ c #EEC585",
+"g@ c #FFDA9D",
+"h@ c #FFC992",
+"i@ c #FFC88F",
+"j@ c #FFC990",
+"k@ c #FFCE93",
+"l@ c #FFD094",
+"m@ c #FFCC92",
+"n@ c #C9A174",
+"o@ c #EDBD88",
+"p@ c #FAD287",
+"q@ c #3A2F7F",
+"r@ c #0000BA",
+"s@ c #0000B0",
+"t@ c #0101B2",
+"u@ c #1111ED",
+"v@ c #1919C1",
+"w@ c #95887C",
+"x@ c #DCAC6E",
+"y@ c #FFD393",
+"z@ c #FFCD94",
+"A@ c #FFCA93",
+"B@ c #FFC991",
+"C@ c #FFC78E",
+"D@ c #FFCB91",
+"E@ c #E0B581",
+"F@ c #BB9A6F",
+"G@ c #FFDC97",
+"H@ c #C1A173",
+"I@ c #0E0B9A",
+"J@ c #0000B5",
+"K@ c #0101B6",
+"L@ c #1010E0",
+"M@ c #1616EC",
+"N@ c #A68156",
+"O@ c #E7AC6B",
+"P@ c #FFC582",
+"Q@ c #FFCF8F",
+"R@ c #FFD195",
+"S@ c #FFD296",
+"T@ c #FFD396",
+"U@ c #FFD193",
+"V@ c #FFD28F",
+"W@ c #D2A96B",
+"X@ c #2F2482",
+"Y@ c #0000C1",
+"Z@ c #0000C0",
+"`@ c #0000BF",
+" # c #0101BF",
+".# c #1212F0",
+"+# c #767698",
+"@# c #9C866E",
+"## c #A9865D",
+"$# c #C0915D",
+"%# c #C89760",
+" c #C29360",
+"*# c #AD8A61",
+"=# c #9D8971",
+"-# c #7F7A7A",
+";# c #70708F",
+"># c #6F6F91",
+",# c #575788",
+"'# c #464687",
+")# c #2F2F87",
+"!# c #15158F",
+"~# c #0101A8",
+"{# c #1313FB",
+"]# c #57579F",
+"^# c #343487",
+"/# c #434388",
+" ",
+" ",
+" ",
+" . + @ # ",
+" $ % & * = - ; > , ' ) ! ",
+" ~ { ] ^ / = ( _ : < [ } | 1 2 3 4 5 6 ",
+" 7 8 9 0 a b c d e f g h i j k l m n o p q r ",
+" s t u v _ f d d d w x y z A B C D E F G H I J K L ",
+" M N O _ c e d d d _ P Q R S T U V W X Y Z ` ... ",
+" +.@.#.$.d d d d %.&._ *.=.-.;.>.,.'.).!.~. ",
+" {.].^./.(.d d _.$.:._ <.[.}.|.1.2.3.4.5. ",
+" 6.7.7.4 8.e : w 9.0.a.b.c.2 d.e.f.g.h.i.j.k. ",
+" l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.o o z.A.B./.b C.D. ",
+" E.F.G.].o H.z.I.J.K.L.M.N.O.P.o o o Q.R.S._.b B.T. ",
+" U.V.W.X.f.f.7.Y.Z.`. + + +.+++].o o o.n z.q.@+#+$+%+ ",
+" &+ +*+=+].o -+;+>+ + + + +,+'+H.o o o o o H.)+o !+~+{+ ",
+" ]+ +^+/+H.o.(+_+ + + + + +:+<+z.o o o o o o o 7.n H.[+}+ ",
+" |+ +1+2+3+4+5+6+ + + + + +7+8+H.o o f.9+f.9+f.F 0+a+b+o.c+ ",
+" &+ +d+e+f+g+h+i+ + + + + +j+k+].f.9+l+m+n+o+p+q+r+s+t+u+v+ ",
+" w+ +x+y+z+A+B+C+ + + + + +D+E+9+F+G+H+I+J+K+L+M+N+O+ ",
+" P+Q+R+S+T+U+V+W+ + + + +X+Y+Z+`+ @I+J+Z .@+@E. ",
+" @@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@I+/@(@_@ ",
+" :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@L+a@b@c@d@e@ ",
+" f@g@h@i@i@j@k@l@|@m@n@o@p@q@r@s@t@u@p v@ ",
+" w@x@y@z@A@B@i@C@D@E@F@G@H@I@L+J@K@L@p M@ ",
+" N@O@P@Q@R@S@T@U@V@W@X@Y@Z@Y@`@ #.#p +# ",
+" @###$#%#*#=#-#;#>#,#'#)#!#~#{#]# ",
+" ^#/# ",
+" ",
+" ",
+" ",
+" "};
diff --git a/src/sdl/Srb2SDL.ico b/src/sdl/Srb2SDL.ico
index 5ab791af3..700276fd4 100644
Binary files a/src/sdl/Srb2SDL.ico and b/src/sdl/Srb2SDL.ico differ
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index fa09dc343..66e1ece18 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -2759,8 +2759,8 @@ static const char *locateWad(void)
if (isWadPathOk(returnWadPath))
return NULL;
#endif
-
-
+
+
#ifdef CMAKECONFIG
#ifndef NDEBUG
I_OutputMsg(","CMAKE_ASSETS_DIR);
@@ -2771,7 +2771,7 @@ static const char *locateWad(void)
}
#endif
#endif
-
+
#ifdef __APPLE__
OSX_GetResourcesPath(returnWadPath);
I_OutputMsg(",%s", returnWadPath);
@@ -2779,7 +2779,7 @@ static const char *locateWad(void)
{
return returnWadPath;
}
-
+
#endif
// examine default dirs
diff --git a/src/sdl12/SDL_icon.xpm b/src/sdl12/SDL_icon.xpm
index 70bb02d3c..cf72960df 100644
--- a/src/sdl12/SDL_icon.xpm
+++ b/src/sdl12/SDL_icon.xpm
@@ -1,80 +1,425 @@
/* XPM */
-static const char * SDL_icon_xpm[] = {
-"32 32 45 1",
-" c None",
-". c #6B6BFF",
-"+ c #3D00B9",
-"@ c #4848FF",
-"# c #2525FF",
-"$ c #310096",
-"% c #003196",
-"& c #003DB9",
-"* c #620096",
-"= c #6E6E6E",
-"- c #966200",
-"; c #250073",
-"> c #626262",
-", c #FF8F6B",
-"' c #FFC66B",
-") c #FFAB8E",
-"! c #000080",
-"~ c #B6B6B6",
-"{ c #929292",
-"] c #FFD48E",
-"^ c #0000B9",
-"/ c #565656",
-"( c #868686",
-"_ c #808080",
-": c #C0C0C0",
-"< c #DADADA",
-"[ c #F2F2F2",
-"} c #FFFFFF",
-"| c #CECECE",
-"1 c #AAAAAA",
-"2 c #E6E6E6",
-"3 c #000096",
-"4 c #AB8EFF",
-"5 c #190050",
-"6 c #000000",
-"7 c #8E8EFF",
-"8 c #3E3E3E",
-"9 c #7A7A7A",
-"0 c #0E0E0E",
-"a c #9E9E9E",
-"b c #001950",
-"c c #C2C2C2",
-"d c #323232",
-"e c #002573",
-"f c #A0A0A4",
-" ",
-" ",
-" ",
-" .+@##@. ",
-" @@.@#######@ ",
-" @@....######### ",
-" .. .@.....@+##$%%%&&% ",
-" ..@# @@....@+#*=-;%%%%% ",
-" ..@#@......@>,')!%%%$ ",
-" ~..$#.........{])^#+%/ ",
-" +##@.........()^@@@@@_ ",
-" $####@........#=#######+ ",
-" +######....@@##^#########_ ",
-" +#####=:<<:+##############/ ",
-"[<=####{<}}}}|###############= ",
-" }1###=2}}}}}}.############### ",
-" }<3#3~}}}}}}}4################ ",
-" }<5#6:}}}}}}}7################/",
-" }:6861}}}}}}}.########$$ 9 .@$",
-" }:0a6~}}}}}}}@######5b ",
-"22cd262}}}}}}2######5b$ ",
-" 2>1a}}}}}}}{(*###%be## ",
-" 860)1<[22c1)]]+##be### ",
-" ~)]]]))))]]]]]=#bb#### ",
-" )]]]]]]]]](]]=eb$#### ",
-" :]]]]]]]]]'9bbb$##### ",
-" ),'''''( >db+### ",
-" =##f ",
-" { ",
-" ",
-" ",
-" "};
+static char * C:\Repo\srb2\src\sdl\SDL_icon_xpm[] = {
+"32 32 390 2",
+" c None",
+". c #4F4F70",
+"+ c #4D4D87",
+"@ c #4D4D84",
+"# c #4E4E6C",
+"$ c #6C6C95",
+"% c #5E5EB2",
+"& c #6B6BE7",
+"* c #7373F9",
+"= c #7C7CFF",
+"- c #6F70E7",
+"; c #494BB2",
+"> c #4F4FA3",
+", c #6464D4",
+"' c #7979F5",
+") c #5F5FCA",
+"! c #5D5D93",
+"~ c #3A3A9F",
+"{ c #6060AC",
+"] c #777793",
+"^ c #5C5CB3",
+"/ c #7373EA",
+"( c #7A7AFF",
+"_ c #7575FF",
+": c #7979FF",
+"< c #6264DD",
+"[ c #47478C",
+"} c #564567",
+"| c #4647D0",
+"1 c #5C5CAE",
+"2 c #5E5EFF",
+"3 c #2929FF",
+"4 c #1D1DFF",
+"5 c #1919D1",
+"6 c #4F4F90",
+"7 c #1E1ECE",
+"8 c #5858FF",
+"9 c #6767A8",
+"0 c #4949A0",
+"a c #7070FB",
+"b c #7D7DFF",
+"c c #7777FF",
+"d c #7373FF",
+"e c #7272FF",
+"f c #7878FF",
+"g c #6465D8",
+"h c #363886",
+"i c #9F7655",
+"j c #C89B5C",
+"k c #1D1CB7",
+"l c #3031B1",
+"m c #1919F4",
+"n c #1111FF",
+"o c #1818FF",
+"p c #1B1BFF",
+"q c #1C1CFF",
+"r c #2626B3",
+"s c #1E1EC8",
+"t c #1A1AE8",
+"u c #24249F",
+"v c #2F2FD2",
+"w c #7676FF",
+"x c #6869E2",
+"y c #414290",
+"z c #8C6751",
+"A c #FCBA68",
+"B c #E9BD7D",
+"C c #201EB8",
+"D c #090AB8",
+"E c #1616EB",
+"F c #1818FD",
+"G c #1414EE",
+"H c #1010E1",
+"I c #0E0EE2",
+"J c #0E0EF4",
+"K c #0606B2",
+"L c #7A7A89",
+"M c #0C0C9A",
+"N c #0A0AA7",
+"O c #2424E4",
+"P c #6669E6",
+"Q c #4F4A8F",
+"R c #BF853B",
+"S c #FFD98D",
+"T c #CDAB76",
+"U c #1717C4",
+"V c #0F10BA",
+"W c #0909B6",
+"X c #0505C3",
+"Y c #0000B6",
+"Z c #0000BE",
+"` c #0000AD",
+" . c #1D1D83",
+".. c #63638E",
+"+. c #090975",
+"@. c #1414F3",
+"#. c #5B5BFF",
+"$. c #7B7BFF",
+"%. c #7070FF",
+"&. c #6E6EFF",
+"*. c #7172F6",
+"=. c #625DAF",
+"-. c #BA9E6C",
+";. c #887167",
+">. c #090DF2",
+",. c #1313BE",
+"'. c #000085",
+"). c #0000AC",
+"!. c #0202AA",
+"~. c #242488",
+"{. c #1414C7",
+"]. c #1717FF",
+"^. c #5959FF",
+"/. c #7F7FFF",
+"(. c #7474FF",
+"_. c #7171FF",
+":. c #8686FF",
+"<. c #7574FF",
+"[. c #797CFF",
+"}. c #5756B8",
+"|. c #1C19A4",
+"1. c #1617FF",
+"2. c #1212BD",
+"3. c #040485",
+"4. c #0707A4",
+"5. c #1B1B71",
+"6. c #373797",
+"7. c #1616FF",
+"8. c #5050FF",
+"9. c #8080FF",
+"0. c #AAAAFF",
+"a. c #AEAEF6",
+"b. c #8A8AEF",
+"c. c #6969FB",
+"d. c #2728FF",
+"e. c #1314FF",
+"f. c #1919FF",
+"g. c #1313E8",
+"h. c #1F1FF4",
+"i. c #5454FF",
+"j. c #6D6DF0",
+"k. c #6868B5",
+"l. c #0B0BB8",
+"m. c #1212C5",
+"n. c #1616FC",
+"o. c #1515FF",
+"p. c #1212FF",
+"q. c #2323FF",
+"r. c #3636FF",
+"s. c #4040FF",
+"t. c #4343F9",
+"u. c #5D5DB8",
+"v. c #7F7F92",
+"w. c #878793",
+"x. c #4B4B94",
+"y. c #0B0CE2",
+"z. c #1313FF",
+"A. c #4C4CFF",
+"B. c #8282FF",
+"C. c #7171ED",
+"D. c #636394",
+"E. c #575785",
+"F. c #A9A99C",
+"G. c #1414BC",
+"H. c #1414FF",
+"I. c #0707FD",
+"J. c #2525AA",
+"K. c #A8A8A4",
+"L. c #EBEBE2",
+"M. c #F9F9F2",
+"N. c #E1E1CC",
+"O. c #4D4D9F",
+"P. c #0B0BF7",
+"Q. c #2121FF",
+"R. c #3232FF",
+"S. c #5555FF",
+"T. c #6161B4",
+"U. c #B5B5B2",
+"V. c #FFFFF8",
+"W. c #4F4F9A",
+"X. c #0B0BF5",
+"Y. c #1616C5",
+"Z. c #A8A8A1",
+"`. c #FFFFFC",
+" + c #FFFFFF",
+".+ c #C0C0C4",
+"++ c #1212D4",
+"@+ c #4444FF",
+"#+ c #6464FF",
+"$+ c #8383FF",
+"%+ c #6767C3",
+"&+ c #E4E4E4",
+"*+ c #9494AE",
+"=+ c #0808DF",
+"-+ c #0D0DF2",
+";+ c #61619A",
+">+ c #F1F1E0",
+",+ c #E8E8DD",
+"'+ c #2424BB",
+")+ c #1010FF",
+"!+ c #3434FF",
+"~+ c #6161FF",
+"{+ c #6969D2",
+"]+ c #EFEFF0",
+"^+ c #C2C2BA",
+"/+ c #1010B6",
+"(+ c #0909AC",
+"_+ c #A4A49A",
+":+ c #EAEADE",
+"<+ c #2525B8",
+"[+ c #2F2FFF",
+"}+ c #3C3CB5",
+"|+ c #EEEEEE",
+"1+ c #BBBBAD",
+"2+ c #0B0B56",
+"3+ c #0B0BFC",
+"4+ c #1212EF",
+"5+ c #0C0C3E",
+"6+ c #919187",
+"7+ c #DEDED6",
+"8+ c #1F1FC0",
+"9+ c #1A1AFF",
+"0+ c #1717FA",
+"a+ c #1515F8",
+"b+ c #1111FC",
+"c+ c #494992",
+"d+ c #999998",
+"e+ c #3E3E3B",
+"f+ c #3C3C99",
+"g+ c #535397",
+"h+ c #5A5A4D",
+"i+ c #6F6F70",
+"j+ c #BFBFC9",
+"k+ c #1111D6",
+"l+ c #1515F1",
+"m+ c #0F0FE2",
+"n+ c #0D0DD9",
+"o+ c #0909CD",
+"p+ c #0808C7",
+"q+ c #0505C7",
+"r+ c #0303CB",
+"s+ c #0101C0",
+"t+ c #0202AF",
+"u+ c #0606AC",
+"v+ c #121283",
+"w+ c #BBBBBB",
+"x+ c #BEBEBE",
+"y+ c #2F2F2E",
+"z+ c #C7C8BB",
+"A+ c #D8DAD1",
+"B+ c #272828",
+"C+ c #929292",
+"D+ c #8688C7",
+"E+ c #0506F6",
+"F+ c #1616F5",
+"G+ c #0B0BD3",
+"H+ c #0202B6",
+"I+ c #0000AF",
+"J+ c #0000B4",
+"K+ c #0000BD",
+"L+ c #0000BB",
+"M+ c #00009E",
+"N+ c #2C2C7E",
+"O+ c #6A6A8B",
+"P+ c #959595",
+"Q+ c #F0F0F1",
+"R+ c #E1E1E1",
+"S+ c #8C8E90",
+"T+ c #BEBEBF",
+"U+ c #C9C7C5",
+"V+ c #939699",
+"W+ c #E7EAED",
+"X+ c #CBCBC7",
+"Y+ c #413B9B",
+"Z+ c #0607DD",
+"`+ c #0C0CE2",
+" @ c #0303B9",
+".@ c #0000A8",
+"+@ c #181888",
+"@@ c #6A6A6A",
+"#@ c #626263",
+"$@ c #4B4B4C",
+"%@ c #3E3B36",
+"&@ c #9B805C",
+"*@ c #D9B07D",
+"=@ c #C9AE89",
+"-@ c #B9AF9E",
+";@ c #C7C5C4",
+">@ c #CBCCCF",
+",@ c #C7C6C6",
+"'@ c #AEA59A",
+")@ c #B69974",
+"!@ c #D8B87F",
+"~@ c #9B8272",
+"{@ c #0E0B9B",
+"]@ c #0000B7",
+"^@ c #0000B8",
+"/@ c #000082",
+"(@ c #00007A",
+"_@ c #636379",
+":@ c #62533E",
+"<@ c #B59B6C",
+"[@ c #DEB07B",
+"}@ c #FECC90",
+"|@ c #FFCE92",
+"1@ c #FEC98C",
+"2@ c #F1BD82",
+"3@ c #D1A979",
+"4@ c #BC9E73",
+"5@ c #CCA777",
+"6@ c #EAB980",
+"7@ c #FFCD90",
+"8@ c #FFD595",
+"9@ c #FDD782",
+"0@ c #413678",
+"a@ c #0000AE",
+"b@ c #000077",
+"c@ c #010193",
+"d@ c #0C0CE4",
+"e@ c #38389E",
+"f@ c #EEC585",
+"g@ c #FFDA9D",
+"h@ c #FFC992",
+"i@ c #FFC88F",
+"j@ c #FFC990",
+"k@ c #FFCE93",
+"l@ c #FFD094",
+"m@ c #FFCC92",
+"n@ c #C9A174",
+"o@ c #EDBD88",
+"p@ c #FAD287",
+"q@ c #3A2F7F",
+"r@ c #0000BA",
+"s@ c #0000B0",
+"t@ c #0101B2",
+"u@ c #1111ED",
+"v@ c #1919C1",
+"w@ c #95887C",
+"x@ c #DCAC6E",
+"y@ c #FFD393",
+"z@ c #FFCD94",
+"A@ c #FFCA93",
+"B@ c #FFC991",
+"C@ c #FFC78E",
+"D@ c #FFCB91",
+"E@ c #E0B581",
+"F@ c #BB9A6F",
+"G@ c #FFDC97",
+"H@ c #C1A173",
+"I@ c #0E0B9A",
+"J@ c #0000B5",
+"K@ c #0101B6",
+"L@ c #1010E0",
+"M@ c #1616EC",
+"N@ c #A68156",
+"O@ c #E7AC6B",
+"P@ c #FFC582",
+"Q@ c #FFCF8F",
+"R@ c #FFD195",
+"S@ c #FFD296",
+"T@ c #FFD396",
+"U@ c #FFD193",
+"V@ c #FFD28F",
+"W@ c #D2A96B",
+"X@ c #2F2482",
+"Y@ c #0000C1",
+"Z@ c #0000C0",
+"`@ c #0000BF",
+" # c #0101BF",
+".# c #1212F0",
+"+# c #767698",
+"@# c #9C866E",
+"## c #A9865D",
+"$# c #C0915D",
+"%# c #C89760",
+" c #C29360",
+"*# c #AD8A61",
+"=# c #9D8971",
+"-# c #7F7A7A",
+";# c #70708F",
+"># c #6F6F91",
+",# c #575788",
+"'# c #464687",
+")# c #2F2F87",
+"!# c #15158F",
+"~# c #0101A8",
+"{# c #1313FB",
+"]# c #57579F",
+"^# c #343487",
+"/# c #434388",
+" ",
+" ",
+" ",
+" . + @ # ",
+" $ % & * = - ; > , ' ) ! ",
+" ~ { ] ^ / = ( _ : < [ } | 1 2 3 4 5 6 ",
+" 7 8 9 0 a b c d e f g h i j k l m n o p q r ",
+" s t u v _ f d d d w x y z A B C D E F G H I J K L ",
+" M N O _ c e d d d _ P Q R S T U V W X Y Z ` ... ",
+" +.@.#.$.d d d d %.&._ *.=.-.;.>.,.'.).!.~. ",
+" {.].^./.(.d d _.$.:._ <.[.}.|.1.2.3.4.5. ",
+" 6.7.7.4 8.e : w 9.0.a.b.c.2 d.e.f.g.h.i.j.k. ",
+" l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.o o z.A.B./.b C.D. ",
+" E.F.G.].o H.z.I.J.K.L.M.N.O.P.o o o Q.R.S._.b B.T. ",
+" U.V.W.X.f.f.7.Y.Z.`. + + +.+++].o o o.n z.q.@+#+$+%+ ",
+" &+ +*+=+].o -+;+>+ + + + +,+'+H.o o o o o H.)+o !+~+{+ ",
+" ]+ +^+/+H.o.(+_+ + + + + +:+<+z.o o o o o o o 7.n H.[+}+ ",
+" |+ +1+2+3+4+5+6+ + + + + +7+8+H.o o f.9+f.9+f.F 0+a+b+o.c+ ",
+" &+ +d+e+f+g+h+i+ + + + + +j+k+].f.9+l+m+n+o+p+q+r+s+t+u+v+ ",
+" w+ +x+y+z+A+B+C+ + + + + +D+E+9+F+G+H+I+J+K+L+M+N+O+ ",
+" P+Q+R+S+T+U+V+W+ + + + +X+Y+Z+`+ @I+J+Z .@+@E. ",
+" @@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@I+/@(@_@ ",
+" :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@L+a@b@c@d@e@ ",
+" f@g@h@i@i@j@k@l@|@m@n@o@p@q@r@s@t@u@p v@ ",
+" w@x@y@z@A@B@i@C@D@E@F@G@H@I@L+J@K@L@p M@ ",
+" N@O@P@Q@R@S@T@U@V@W@X@Y@Z@Y@`@ #.#p +# ",
+" @###$#%#*#=#-#;#>#,#'#)#!#~#{#]# ",
+" ^#/# ",
+" ",
+" ",
+" ",
+" "};
diff --git a/src/sdl12/Srb2SDL.ico b/src/sdl12/Srb2SDL.ico
index 5ab791af3..700276fd4 100644
Binary files a/src/sdl12/Srb2SDL.ico and b/src/sdl12/Srb2SDL.ico differ
diff --git a/src/st_stuff.c b/src/st_stuff.c
index 13cc36fe1..5ed9fbe48 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -1590,7 +1590,7 @@ static void ST_drawSpecialStageHUD(void)
if (sstimer)
{
V_DrawString(hudinfo[HUD_TIMELEFT].x, STRINGY(hudinfo[HUD_TIMELEFT].y), V_HUDTRANS, M_GetText("TIME LEFT"));
- ST_DrawNightsOverlayNum(SCX(hudinfo[HUD_TIMELEFTNUM].x), SCY(hudinfo[HUD_TIMELEFTNUM].y), V_HUDTRANS, sstimer/TICRATE, tallnum, SKINCOLOR_WHITE);
+ ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE);
}
else
ST_DrawPatchFromHud(HUD_TIMEUP, timeup);
diff --git a/src/tables.c b/src/tables.c
index fa71effef..6f0446e01 100644
--- a/src/tables.c
+++ b/src/tables.c
@@ -679,1284 +679,1284 @@ fixed_t finetangent[4096] =
fixed_t finesine[10240] =
{
- 25, 75, 125, 175, 226, 276, 326, 376,
- 427, 477, 527, 578, 628, 678, 728, 779,
- 829, 879, 929, 980, 1030, 1080, 1130, 1181,
- 1231, 1281, 1331, 1382, 1432, 1482, 1532, 1583,
- 1633, 1683, 1733, 1784, 1834, 1884, 1934, 1985,
- 2035, 2085, 2135, 2186, 2236, 2286, 2336, 2387,
- 2437, 2487, 2537, 2587, 2638, 2688, 2738, 2788,
- 2839, 2889, 2939, 2989, 3039, 3090, 3140, 3190,
- 3240, 3291, 3341, 3391, 3441, 3491, 3541, 3592,
- 3642, 3692, 3742, 3792, 3843, 3893, 3943, 3993,
- 4043, 4093, 4144, 4194, 4244, 4294, 4344, 4394,
- 4445, 4495, 4545, 4595, 4645, 4695, 4745, 4796,
- 4846, 4896, 4946, 4996, 5046, 5096, 5146, 5197,
- 5247, 5297, 5347, 5397, 5447, 5497, 5547, 5597,
- 5647, 5697, 5748, 5798, 5848, 5898, 5948, 5998,
- 6048, 6098, 6148, 6198, 6248, 6298, 6348, 6398,
- 6448, 6498, 6548, 6598, 6648, 6698, 6748, 6798,
- 6848, 6898, 6948, 6998, 7048, 7098, 7148, 7198,
- 7248, 7298, 7348, 7398, 7448, 7498, 7548, 7598,
- 7648, 7697, 7747, 7797, 7847, 7897, 7947, 7997,
- 8047, 8097, 8147, 8196, 8246, 8296, 8346, 8396,
- 8446, 8496, 8545, 8595, 8645, 8695, 8745, 8794,
- 8844, 8894, 8944, 8994, 9043, 9093, 9143, 9193,
- 9243, 9292, 9342, 9392, 9442, 9491, 9541, 9591,
- 9640, 9690, 9740, 9790, 9839, 9889, 9939, 9988,
- 10038, 10088, 10137, 10187, 10237, 10286, 10336, 10386,
- 10435, 10485, 10534, 10584, 10634, 10683, 10733, 10782,
- 10832, 10882, 10931, 10981, 11030, 11080, 11129, 11179,
- 11228, 11278, 11327, 11377, 11426, 11476, 11525, 11575,
- 11624, 11674, 11723, 11773, 11822, 11872, 11921, 11970,
- 12020, 12069, 12119, 12168, 12218, 12267, 12316, 12366,
- 12415, 12464, 12514, 12563, 12612, 12662, 12711, 12760,
- 12810, 12859, 12908, 12957, 13007, 13056, 13105, 13154,
- 13204, 13253, 13302, 13351, 13401, 13450, 13499, 13548,
- 13597, 13647, 13696, 13745, 13794, 13843, 13892, 13941,
- 13990, 14040, 14089, 14138, 14187, 14236, 14285, 14334,
- 14383, 14432, 14481, 14530, 14579, 14628, 14677, 14726,
- 14775, 14824, 14873, 14922, 14971, 15020, 15069, 15118,
- 15167, 15215, 15264, 15313, 15362, 15411, 15460, 15509,
- 15557, 15606, 15655, 15704, 15753, 15802, 15850, 15899,
- 15948, 15997, 16045, 16094, 16143, 16191, 16240, 16289,
- 16338, 16386, 16435, 16484, 16532, 16581, 16629, 16678,
- 16727, 16775, 16824, 16872, 16921, 16970, 17018, 17067,
- 17115, 17164, 17212, 17261, 17309, 17358, 17406, 17455,
- 17503, 17551, 17600, 17648, 17697, 17745, 17793, 17842,
- 17890, 17939, 17987, 18035, 18084, 18132, 18180, 18228,
- 18277, 18325, 18373, 18421, 18470, 18518, 18566, 18614,
- 18663, 18711, 18759, 18807, 18855, 18903, 18951, 19000,
- 19048, 19096, 19144, 19192, 19240, 19288, 19336, 19384,
- 19432, 19480, 19528, 19576, 19624, 19672, 19720, 19768,
- 19816, 19864, 19912, 19959, 20007, 20055, 20103, 20151,
- 20199, 20246, 20294, 20342, 20390, 20438, 20485, 20533,
- 20581, 20629, 20676, 20724, 20772, 20819, 20867, 20915,
- 20962, 21010, 21057, 21105, 21153, 21200, 21248, 21295,
- 21343, 21390, 21438, 21485, 21533, 21580, 21628, 21675,
- 21723, 21770, 21817, 21865, 21912, 21960, 22007, 22054,
- 22102, 22149, 22196, 22243, 22291, 22338, 22385, 22433,
- 22480, 22527, 22574, 22621, 22668, 22716, 22763, 22810,
- 22857, 22904, 22951, 22998, 23045, 23092, 23139, 23186,
- 23233, 23280, 23327, 23374, 23421, 23468, 23515, 23562,
- 23609, 23656, 23703, 23750, 23796, 23843, 23890, 23937,
- 23984, 24030, 24077, 24124, 24171, 24217, 24264, 24311,
- 24357, 24404, 24451, 24497, 24544, 24591, 24637, 24684,
- 24730, 24777, 24823, 24870, 24916, 24963, 25009, 25056,
- 25102, 25149, 25195, 25241, 25288, 25334, 25381, 25427,
- 25473, 25520, 25566, 25612, 25658, 25705, 25751, 25797,
- 25843, 25889, 25936, 25982, 26028, 26074, 26120, 26166,
- 26212, 26258, 26304, 26350, 26396, 26442, 26488, 26534,
- 26580, 26626, 26672, 26718, 26764, 26810, 26856, 26902,
- 26947, 26993, 27039, 27085, 27131, 27176, 27222, 27268,
- 27313, 27359, 27405, 27450, 27496, 27542, 27587, 27633,
- 27678, 27724, 27770, 27815, 27861, 27906, 27952, 27997,
- 28042, 28088, 28133, 28179, 28224, 28269, 28315, 28360,
- 28405, 28451, 28496, 28541, 28586, 28632, 28677, 28722,
- 28767, 28812, 28858, 28903, 28948, 28993, 29038, 29083,
- 29128, 29173, 29218, 29263, 29308, 29353, 29398, 29443,
- 29488, 29533, 29577, 29622, 29667, 29712, 29757, 29801,
- 29846, 29891, 29936, 29980, 30025, 30070, 30114, 30159,
- 30204, 30248, 30293, 30337, 30382, 30426, 30471, 30515,
- 30560, 30604, 30649, 30693, 30738, 30782, 30826, 30871,
- 30915, 30959, 31004, 31048, 31092, 31136, 31181, 31225,
- 31269, 31313, 31357, 31402, 31446, 31490, 31534, 31578,
- 31622, 31666, 31710, 31754, 31798, 31842, 31886, 31930,
- 31974, 32017, 32061, 32105, 32149, 32193, 32236, 32280,
- 32324, 32368, 32411, 32455, 32499, 32542, 32586, 32630,
- 32673, 32717, 32760, 32804, 32847, 32891, 32934, 32978,
- 33021, 33065, 33108, 33151, 33195, 33238, 33281, 33325,
- 33368, 33411, 33454, 33498, 33541, 33584, 33627, 33670,
- 33713, 33756, 33799, 33843, 33886, 33929, 33972, 34015,
- 34057, 34100, 34143, 34186, 34229, 34272, 34315, 34358,
- 34400, 34443, 34486, 34529, 34571, 34614, 34657, 34699,
- 34742, 34785, 34827, 34870, 34912, 34955, 34997, 35040,
- 35082, 35125, 35167, 35210, 35252, 35294, 35337, 35379,
- 35421, 35464, 35506, 35548, 35590, 35633, 35675, 35717,
- 35759, 35801, 35843, 35885, 35927, 35969, 36011, 36053,
- 36095, 36137, 36179, 36221, 36263, 36305, 36347, 36388,
- 36430, 36472, 36514, 36555, 36597, 36639, 36681, 36722,
- 36764, 36805, 36847, 36889, 36930, 36972, 37013, 37055,
- 37096, 37137, 37179, 37220, 37262, 37303, 37344, 37386,
- 37427, 37468, 37509, 37551, 37592, 37633, 37674, 37715,
- 37756, 37797, 37838, 37879, 37920, 37961, 38002, 38043,
- 38084, 38125, 38166, 38207, 38248, 38288, 38329, 38370,
- 38411, 38451, 38492, 38533, 38573, 38614, 38655, 38695,
- 38736, 38776, 38817, 38857, 38898, 38938, 38979, 39019,
- 39059, 39100, 39140, 39180, 39221, 39261, 39301, 39341,
- 39382, 39422, 39462, 39502, 39542, 39582, 39622, 39662,
- 39702, 39742, 39782, 39822, 39862, 39902, 39942, 39982,
- 40021, 40061, 40101, 40141, 40180, 40220, 40260, 40300,
- 40339, 40379, 40418, 40458, 40497, 40537, 40576, 40616,
- 40655, 40695, 40734, 40773, 40813, 40852, 40891, 40931,
- 40970, 41009, 41048, 41087, 41127, 41166, 41205, 41244,
- 41283, 41322, 41361, 41400, 41439, 41478, 41517, 41556,
- 41595, 41633, 41672, 41711, 41750, 41788, 41827, 41866,
- 41904, 41943, 41982, 42020, 42059, 42097, 42136, 42174,
- 42213, 42251, 42290, 42328, 42366, 42405, 42443, 42481,
- 42520, 42558, 42596, 42634, 42672, 42711, 42749, 42787,
- 42825, 42863, 42901, 42939, 42977, 43015, 43053, 43091,
- 43128, 43166, 43204, 43242, 43280, 43317, 43355, 43393,
- 43430, 43468, 43506, 43543, 43581, 43618, 43656, 43693,
- 43731, 43768, 43806, 43843, 43880, 43918, 43955, 43992,
- 44029, 44067, 44104, 44141, 44178, 44215, 44252, 44289,
- 44326, 44363, 44400, 44437, 44474, 44511, 44548, 44585,
- 44622, 44659, 44695, 44732, 44769, 44806, 44842, 44879,
- 44915, 44952, 44989, 45025, 45062, 45098, 45135, 45171,
- 45207, 45244, 45280, 45316, 45353, 45389, 45425, 45462,
- 45498, 45534, 45570, 45606, 45642, 45678, 45714, 45750,
- 45786, 45822, 45858, 45894, 45930, 45966, 46002, 46037,
- 46073, 46109, 46145, 46180, 46216, 46252, 46287, 46323,
- 46358, 46394, 46429, 46465, 46500, 46536, 46571, 46606,
- 46642, 46677, 46712, 46747, 46783, 46818, 46853, 46888,
- 46923, 46958, 46993, 47028, 47063, 47098, 47133, 47168,
- 47203, 47238, 47273, 47308, 47342, 47377, 47412, 47446,
- 47481, 47516, 47550, 47585, 47619, 47654, 47688, 47723,
- 47757, 47792, 47826, 47860, 47895, 47929, 47963, 47998,
- 48032, 48066, 48100, 48134, 48168, 48202, 48237, 48271,
- 48305, 48338, 48372, 48406, 48440, 48474, 48508, 48542,
- 48575, 48609, 48643, 48676, 48710, 48744, 48777, 48811,
- 48844, 48878, 48911, 48945, 48978, 49012, 49045, 49078,
- 49112, 49145, 49178, 49211, 49244, 49278, 49311, 49344,
- 49377, 49410, 49443, 49476, 49509, 49542, 49575, 49608,
- 49640, 49673, 49706, 49739, 49771, 49804, 49837, 49869,
- 49902, 49935, 49967, 50000, 50032, 50065, 50097, 50129,
- 50162, 50194, 50226, 50259, 50291, 50323, 50355, 50387,
- 50420, 50452, 50484, 50516, 50548, 50580, 50612, 50644,
- 50675, 50707, 50739, 50771, 50803, 50834, 50866, 50898,
- 50929, 50961, 50993, 51024, 51056, 51087, 51119, 51150,
- 51182, 51213, 51244, 51276, 51307, 51338, 51369, 51401,
- 51432, 51463, 51494, 51525, 51556, 51587, 51618, 51649,
- 51680, 51711, 51742, 51773, 51803, 51834, 51865, 51896,
- 51926, 51957, 51988, 52018, 52049, 52079, 52110, 52140,
- 52171, 52201, 52231, 52262, 52292, 52322, 52353, 52383,
- 52413, 52443, 52473, 52503, 52534, 52564, 52594, 52624,
- 52653, 52683, 52713, 52743, 52773, 52803, 52832, 52862,
- 52892, 52922, 52951, 52981, 53010, 53040, 53069, 53099,
- 53128, 53158, 53187, 53216, 53246, 53275, 53304, 53334,
- 53363, 53392, 53421, 53450, 53479, 53508, 53537, 53566,
- 53595, 53624, 53653, 53682, 53711, 53739, 53768, 53797,
- 53826, 53854, 53883, 53911, 53940, 53969, 53997, 54026,
- 54054, 54082, 54111, 54139, 54167, 54196, 54224, 54252,
- 54280, 54308, 54337, 54365, 54393, 54421, 54449, 54477,
- 54505, 54533, 54560, 54588, 54616, 54644, 54672, 54699,
- 54727, 54755, 54782, 54810, 54837, 54865, 54892, 54920,
- 54947, 54974, 55002, 55029, 55056, 55084, 55111, 55138,
- 55165, 55192, 55219, 55246, 55274, 55300, 55327, 55354,
- 55381, 55408, 55435, 55462, 55489, 55515, 55542, 55569,
- 55595, 55622, 55648, 55675, 55701, 55728, 55754, 55781,
- 55807, 55833, 55860, 55886, 55912, 55938, 55965, 55991,
- 56017, 56043, 56069, 56095, 56121, 56147, 56173, 56199,
- 56225, 56250, 56276, 56302, 56328, 56353, 56379, 56404,
- 56430, 56456, 56481, 56507, 56532, 56557, 56583, 56608,
- 56633, 56659, 56684, 56709, 56734, 56760, 56785, 56810,
- 56835, 56860, 56885, 56910, 56935, 56959, 56984, 57009,
- 57034, 57059, 57083, 57108, 57133, 57157, 57182, 57206,
- 57231, 57255, 57280, 57304, 57329, 57353, 57377, 57402,
- 57426, 57450, 57474, 57498, 57522, 57546, 57570, 57594,
- 57618, 57642, 57666, 57690, 57714, 57738, 57762, 57785,
- 57809, 57833, 57856, 57880, 57903, 57927, 57950, 57974,
- 57997, 58021, 58044, 58067, 58091, 58114, 58137, 58160,
- 58183, 58207, 58230, 58253, 58276, 58299, 58322, 58345,
- 58367, 58390, 58413, 58436, 58459, 58481, 58504, 58527,
- 58549, 58572, 58594, 58617, 58639, 58662, 58684, 58706,
- 58729, 58751, 58773, 58795, 58818, 58840, 58862, 58884,
- 58906, 58928, 58950, 58972, 58994, 59016, 59038, 59059,
- 59081, 59103, 59125, 59146, 59168, 59190, 59211, 59233,
- 59254, 59276, 59297, 59318, 59340, 59361, 59382, 59404,
- 59425, 59446, 59467, 59488, 59509, 59530, 59551, 59572,
- 59593, 59614, 59635, 59656, 59677, 59697, 59718, 59739,
- 59759, 59780, 59801, 59821, 59842, 59862, 59883, 59903,
- 59923, 59944, 59964, 59984, 60004, 60025, 60045, 60065,
- 60085, 60105, 60125, 60145, 60165, 60185, 60205, 60225,
- 60244, 60264, 60284, 60304, 60323, 60343, 60363, 60382,
- 60402, 60421, 60441, 60460, 60479, 60499, 60518, 60537,
- 60556, 60576, 60595, 60614, 60633, 60652, 60671, 60690,
- 60709, 60728, 60747, 60766, 60785, 60803, 60822, 60841,
- 60859, 60878, 60897, 60915, 60934, 60952, 60971, 60989,
- 61007, 61026, 61044, 61062, 61081, 61099, 61117, 61135,
- 61153, 61171, 61189, 61207, 61225, 61243, 61261, 61279,
- 61297, 61314, 61332, 61350, 61367, 61385, 61403, 61420,
- 61438, 61455, 61473, 61490, 61507, 61525, 61542, 61559,
- 61577, 61594, 61611, 61628, 61645, 61662, 61679, 61696,
- 61713, 61730, 61747, 61764, 61780, 61797, 61814, 61831,
- 61847, 61864, 61880, 61897, 61913, 61930, 61946, 61963,
- 61979, 61995, 62012, 62028, 62044, 62060, 62076, 62092,
- 62108, 62125, 62141, 62156, 62172, 62188, 62204, 62220,
- 62236, 62251, 62267, 62283, 62298, 62314, 62329, 62345,
- 62360, 62376, 62391, 62407, 62422, 62437, 62453, 62468,
- 62483, 62498, 62513, 62528, 62543, 62558, 62573, 62588,
- 62603, 62618, 62633, 62648, 62662, 62677, 62692, 62706,
- 62721, 62735, 62750, 62764, 62779, 62793, 62808, 62822,
- 62836, 62850, 62865, 62879, 62893, 62907, 62921, 62935,
- 62949, 62963, 62977, 62991, 63005, 63019, 63032, 63046,
- 63060, 63074, 63087, 63101, 63114, 63128, 63141, 63155,
- 63168, 63182, 63195, 63208, 63221, 63235, 63248, 63261,
- 63274, 63287, 63300, 63313, 63326, 63339, 63352, 63365,
- 63378, 63390, 63403, 63416, 63429, 63441, 63454, 63466,
- 63479, 63491, 63504, 63516, 63528, 63541, 63553, 63565,
- 63578, 63590, 63602, 63614, 63626, 63638, 63650, 63662,
- 63674, 63686, 63698, 63709, 63721, 63733, 63745, 63756,
- 63768, 63779, 63791, 63803, 63814, 63825, 63837, 63848,
- 63859, 63871, 63882, 63893, 63904, 63915, 63927, 63938,
- 63949, 63960, 63971, 63981, 63992, 64003, 64014, 64025,
- 64035, 64046, 64057, 64067, 64078, 64088, 64099, 64109,
- 64120, 64130, 64140, 64151, 64161, 64171, 64181, 64192,
- 64202, 64212, 64222, 64232, 64242, 64252, 64261, 64271,
- 64281, 64291, 64301, 64310, 64320, 64330, 64339, 64349,
- 64358, 64368, 64377, 64387, 64396, 64405, 64414, 64424,
- 64433, 64442, 64451, 64460, 64469, 64478, 64487, 64496,
- 64505, 64514, 64523, 64532, 64540, 64549, 64558, 64566,
- 64575, 64584, 64592, 64601, 64609, 64617, 64626, 64634,
- 64642, 64651, 64659, 64667, 64675, 64683, 64691, 64699,
- 64707, 64715, 64723, 64731, 64739, 64747, 64754, 64762,
- 64770, 64777, 64785, 64793, 64800, 64808, 64815, 64822,
- 64830, 64837, 64844, 64852, 64859, 64866, 64873, 64880,
- 64887, 64895, 64902, 64908, 64915, 64922, 64929, 64936,
- 64943, 64949, 64956, 64963, 64969, 64976, 64982, 64989,
- 64995, 65002, 65008, 65015, 65021, 65027, 65033, 65040,
- 65046, 65052, 65058, 65064, 65070, 65076, 65082, 65088,
- 65094, 65099, 65105, 65111, 65117, 65122, 65128, 65133,
- 65139, 65144, 65150, 65155, 65161, 65166, 65171, 65177,
- 65182, 65187, 65192, 65197, 65202, 65207, 65212, 65217,
- 65222, 65227, 65232, 65237, 65242, 65246, 65251, 65256,
- 65260, 65265, 65270, 65274, 65279, 65283, 65287, 65292,
- 65296, 65300, 65305, 65309, 65313, 65317, 65321, 65325,
- 65329, 65333, 65337, 65341, 65345, 65349, 65352, 65356,
- 65360, 65363, 65367, 65371, 65374, 65378, 65381, 65385,
- 65388, 65391, 65395, 65398, 65401, 65404, 65408, 65411,
- 65414, 65417, 65420, 65423, 65426, 65429, 65431, 65434,
- 65437, 65440, 65442, 65445, 65448, 65450, 65453, 65455,
- 65458, 65460, 65463, 65465, 65467, 65470, 65472, 65474,
- 65476, 65478, 65480, 65482, 65484, 65486, 65488, 65490,
- 65492, 65494, 65496, 65497, 65499, 65501, 65502, 65504,
- 65505, 65507, 65508, 65510, 65511, 65513, 65514, 65515,
- 65516, 65518, 65519, 65520, 65521, 65522, 65523, 65524,
- 65525, 65526, 65527, 65527, 65528, 65529, 65530, 65530,
+ 0, 50, 100, 150, 201, 251, 301, 351,
+ 402, 452, 502, 552, 603, 653, 703, 753,
+ 804, 854, 904, 955, 1005, 1055, 1105, 1156,
+ 1206, 1256, 1306, 1357, 1407, 1457, 1507, 1558,
+ 1608, 1658, 1708, 1759, 1809, 1859, 1909, 1960,
+ 2010, 2060, 2110, 2161, 2211, 2261, 2311, 2361,
+ 2412, 2462, 2512, 2562, 2613, 2663, 2713, 2763,
+ 2814, 2864, 2914, 2964, 3014, 3065, 3115, 3165,
+ 3215, 3265, 3316, 3366, 3416, 3466, 3516, 3567,
+ 3617, 3667, 3717, 3767, 3818, 3868, 3918, 3968,
+ 4018, 4068, 4119, 4169, 4219, 4269, 4319, 4369,
+ 4420, 4470, 4520, 4570, 4620, 4670, 4720, 4770,
+ 4821, 4871, 4921, 4971, 5021, 5071, 5121, 5171,
+ 5222, 5272, 5322, 5372, 5422, 5472, 5522, 5572,
+ 5622, 5672, 5722, 5773, 5823, 5873, 5923, 5973,
+ 6023, 6073, 6123, 6173, 6223, 6273, 6323, 6373,
+ 6423, 6473, 6523, 6573, 6623, 6673, 6723, 6773,
+ 6823, 6873, 6923, 6973, 7023, 7073, 7123, 7173,
+ 7223, 7273, 7323, 7373, 7423, 7473, 7523, 7573,
+ 7623, 7672, 7722, 7772, 7822, 7872, 7922, 7972,
+ 8022, 8072, 8122, 8171, 8221, 8271, 8321, 8371,
+ 8421, 8471, 8520, 8570, 8620, 8670, 8720, 8770,
+ 8819, 8869, 8919, 8969, 9019, 9068, 9118, 9168,
+ 9218, 9267, 9317, 9367, 9417, 9466, 9516, 9566,
+ 9616, 9665, 9715, 9765, 9814, 9864, 9914, 9964,
+ 10013, 10063, 10113, 10162, 10212, 10262, 10311, 10361,
+ 10410, 10460, 10510, 10559, 10609, 10658, 10708, 10758,
+ 10807, 10857, 10906, 10956, 11006, 11055, 11105, 11154,
+ 11204, 11253, 11303, 11352, 11402, 11451, 11501, 11550,
+ 11600, 11649, 11699, 11748, 11797, 11847, 11896, 11946,
+ 11995, 12045, 12094, 12143, 12193, 12242, 12292, 12341,
+ 12390, 12440, 12489, 12538, 12588, 12637, 12686, 12736,
+ 12785, 12834, 12884, 12933, 12982, 13031, 13081, 13130,
+ 13179, 13228, 13278, 13327, 13376, 13425, 13474, 13524,
+ 13573, 13622, 13671, 13720, 13769, 13819, 13868, 13917,
+ 13966, 14015, 14064, 14113, 14162, 14211, 14260, 14309,
+ 14359, 14408, 14457, 14506, 14555, 14604, 14653, 14702,
+ 14751, 14800, 14849, 14897, 14946, 14995, 15044, 15093,
+ 15142, 15191, 15240, 15289, 15338, 15387, 15435, 15484,
+ 15533, 15582, 15631, 15680, 15728, 15777, 15826, 15875,
+ 15923, 15972, 16021, 16070, 16118, 16167, 16216, 16265,
+ 16313, 16362, 16411, 16459, 16508, 16557, 16605, 16654,
+ 16702, 16751, 16800, 16848, 16897, 16945, 16994, 17042,
+ 17091, 17139, 17188, 17236, 17285, 17333, 17382, 17430,
+ 17479, 17527, 17576, 17624, 17672, 17721, 17769, 17818,
+ 17866, 17914, 17963, 18011, 18059, 18108, 18156, 18204,
+ 18253, 18301, 18349, 18397, 18446, 18494, 18542, 18590,
+ 18638, 18687, 18735, 18783, 18831, 18879, 18927, 18975,
+ 19024, 19072, 19120, 19168, 19216, 19264, 19312, 19360,
+ 19408, 19456, 19504, 19552, 19600, 19648, 19696, 19744,
+ 19792, 19840, 19888, 19935, 19983, 20031, 20079, 20127,
+ 20175, 20223, 20270, 20318, 20366, 20414, 20461, 20509,
+ 20557, 20605, 20652, 20700, 20748, 20795, 20843, 20891,
+ 20938, 20986, 21034, 21081, 21129, 21176, 21224, 21271,
+ 21319, 21367, 21414, 21462, 21509, 21557, 21604, 21651,
+ 21699, 21746, 21794, 21841, 21889, 21936, 21983, 22031,
+ 22078, 22125, 22173, 22220, 22267, 22314, 22362, 22409,
+ 22456, 22503, 22551, 22598, 22645, 22692, 22739, 22786,
+ 22833, 22881, 22928, 22975, 23022, 23069, 23116, 23163,
+ 23210, 23257, 23304, 23351, 23398, 23445, 23492, 23539,
+ 23586, 23632, 23679, 23726, 23773, 23820, 23867, 23914,
+ 23960, 24007, 24054, 24101, 24147, 24194, 24241, 24287,
+ 24334, 24381, 24427, 24474, 24521, 24567, 24614, 24660,
+ 24707, 24754, 24800, 24847, 24893, 24940, 24986, 25033,
+ 25079, 25125, 25172, 25218, 25265, 25311, 25357, 25404,
+ 25450, 25496, 25543, 25589, 25635, 25681, 25728, 25774,
+ 25820, 25866, 25913, 25959, 26005, 26051, 26097, 26143,
+ 26189, 26235, 26281, 26327, 26373, 26419, 26465, 26511,
+ 26557, 26603, 26649, 26695, 26741, 26787, 26833, 26879,
+ 26925, 26970, 27016, 27062, 27108, 27153, 27199, 27245,
+ 27291, 27336, 27382, 27428, 27473, 27519, 27565, 27610,
+ 27656, 27701, 27747, 27792, 27838, 27883, 27929, 27974,
+ 28020, 28065, 28111, 28156, 28201, 28247, 28292, 28337,
+ 28383, 28428, 28473, 28519, 28564, 28609, 28654, 28699,
+ 28745, 28790, 28835, 28880, 28925, 28970, 29015, 29060,
+ 29105, 29151, 29196, 29241, 29285, 29330, 29375, 29420,
+ 29465, 29510, 29555, 29600, 29645, 29690, 29734, 29779,
+ 29824, 29869, 29913, 29958, 30003, 30047, 30092, 30137,
+ 30181, 30226, 30271, 30315, 30360, 30404, 30449, 30493,
+ 30538, 30582, 30627, 30671, 30715, 30760, 30804, 30849,
+ 30893, 30937, 30982, 31026, 31070, 31114, 31159, 31203,
+ 31247, 31291, 31335, 31379, 31424, 31468, 31512, 31556,
+ 31600, 31644, 31688, 31732, 31776, 31820, 31864, 31908,
+ 31952, 31995, 32039, 32083, 32127, 32171, 32215, 32258,
+ 32302, 32346, 32390, 32433, 32477, 32521, 32564, 32608,
+ 32651, 32695, 32738, 32782, 32826, 32869, 32912, 32956,
+ 32999, 33043, 33086, 33130, 33173, 33216, 33260, 33303,
+ 33346, 33389, 33433, 33476, 33519, 33562, 33605, 33649,
+ 33692, 33735, 33778, 33821, 33864, 33907, 33950, 33993,
+ 34036, 34079, 34122, 34165, 34208, 34251, 34293, 34336,
+ 34379, 34422, 34465, 34507, 34550, 34593, 34635, 34678,
+ 34721, 34763, 34806, 34849, 34891, 34934, 34976, 35019,
+ 35061, 35104, 35146, 35188, 35231, 35273, 35316, 35358,
+ 35400, 35442, 35485, 35527, 35569, 35611, 35654, 35696,
+ 35738, 35780, 35822, 35864, 35906, 35948, 35990, 36032,
+ 36074, 36116, 36158, 36200, 36242, 36284, 36326, 36368,
+ 36409, 36451, 36493, 36535, 36576, 36618, 36660, 36701,
+ 36743, 36785, 36826, 36868, 36909, 36951, 36992, 37034,
+ 37075, 37117, 37158, 37200, 37241, 37282, 37324, 37365,
+ 37406, 37447, 37489, 37530, 37571, 37612, 37653, 37695,
+ 37736, 37777, 37818, 37859, 37900, 37941, 37982, 38023,
+ 38064, 38105, 38146, 38186, 38227, 38268, 38309, 38350,
+ 38390, 38431, 38472, 38512, 38553, 38594, 38634, 38675,
+ 38716, 38756, 38797, 38837, 38878, 38918, 38958, 38999,
+ 39039, 39080, 39120, 39160, 39201, 39241, 39281, 39321,
+ 39362, 39402, 39442, 39482, 39522, 39562, 39602, 39642,
+ 39682, 39722, 39762, 39802, 39842, 39882, 39922, 39962,
+ 40002, 40041, 40081, 40121, 40161, 40200, 40240, 40280,
+ 40319, 40359, 40399, 40438, 40478, 40517, 40557, 40596,
+ 40636, 40675, 40714, 40754, 40793, 40832, 40872, 40911,
+ 40950, 40990, 41029, 41068, 41107, 41146, 41185, 41224,
+ 41263, 41303, 41342, 41381, 41419, 41458, 41497, 41536,
+ 41575, 41614, 41653, 41692, 41730, 41769, 41808, 41846,
+ 41885, 41924, 41962, 42001, 42040, 42078, 42117, 42155,
+ 42194, 42232, 42271, 42309, 42347, 42386, 42424, 42462,
+ 42501, 42539, 42577, 42615, 42653, 42692, 42730, 42768,
+ 42806, 42844, 42882, 42920, 42958, 42996, 43034, 43072,
+ 43110, 43147, 43185, 43223, 43261, 43298, 43336, 43374,
+ 43412, 43449, 43487, 43524, 43562, 43600, 43637, 43675,
+ 43712, 43749, 43787, 43824, 43862, 43899, 43936, 43974,
+ 44011, 44048, 44085, 44122, 44160, 44197, 44234, 44271,
+ 44308, 44345, 44382, 44419, 44456, 44493, 44530, 44567,
+ 44603, 44640, 44677, 44714, 44750, 44787, 44824, 44861,
+ 44897, 44934, 44970, 45007, 45043, 45080, 45116, 45153,
+ 45189, 45226, 45262, 45298, 45335, 45371, 45407, 45443,
+ 45480, 45516, 45552, 45588, 45624, 45660, 45696, 45732,
+ 45768, 45804, 45840, 45876, 45912, 45948, 45984, 46019,
+ 46055, 46091, 46127, 46162, 46198, 46234, 46269, 46305,
+ 46340, 46376, 46411, 46447, 46482, 46518, 46553, 46589,
+ 46624, 46659, 46695, 46730, 46765, 46800, 46835, 46871,
+ 46906, 46941, 46976, 47011, 47046, 47081, 47116, 47151,
+ 47186, 47220, 47255, 47290, 47325, 47360, 47394, 47429,
+ 47464, 47498, 47533, 47568, 47602, 47637, 47671, 47706,
+ 47740, 47775, 47809, 47843, 47878, 47912, 47946, 47981,
+ 48015, 48049, 48083, 48117, 48151, 48185, 48219, 48254,
+ 48288, 48321, 48355, 48389, 48423, 48457, 48491, 48525,
+ 48558, 48592, 48626, 48660, 48693, 48727, 48760, 48794,
+ 48828, 48861, 48895, 48928, 48961, 48995, 49028, 49062,
+ 49095, 49128, 49161, 49195, 49228, 49261, 49294, 49327,
+ 49360, 49393, 49426, 49459, 49492, 49525, 49558, 49591,
+ 49624, 49657, 49690, 49722, 49755, 49788, 49820, 49853,
+ 49886, 49918, 49951, 49983, 50016, 50048, 50081, 50113,
+ 50146, 50178, 50210, 50242, 50275, 50307, 50339, 50371,
+ 50403, 50436, 50468, 50500, 50532, 50564, 50596, 50628,
+ 50660, 50691, 50723, 50755, 50787, 50819, 50850, 50882,
+ 50914, 50945, 50977, 51008, 51040, 51072, 51103, 51134,
+ 51166, 51197, 51229, 51260, 51291, 51323, 51354, 51385,
+ 51416, 51447, 51478, 51510, 51541, 51572, 51603, 51634,
+ 51665, 51695, 51726, 51757, 51788, 51819, 51850, 51880,
+ 51911, 51942, 51972, 52003, 52033, 52064, 52095, 52125,
+ 52155, 52186, 52216, 52247, 52277, 52307, 52338, 52368,
+ 52398, 52428, 52458, 52488, 52518, 52549, 52579, 52609,
+ 52639, 52668, 52698, 52728, 52758, 52788, 52818, 52847,
+ 52877, 52907, 52936, 52966, 52996, 53025, 53055, 53084,
+ 53114, 53143, 53172, 53202, 53231, 53260, 53290, 53319,
+ 53348, 53377, 53407, 53436, 53465, 53494, 53523, 53552,
+ 53581, 53610, 53639, 53667, 53696, 53725, 53754, 53783,
+ 53811, 53840, 53869, 53897, 53926, 53954, 53983, 54011,
+ 54040, 54068, 54097, 54125, 54153, 54182, 54210, 54238,
+ 54266, 54294, 54323, 54351, 54379, 54407, 54435, 54463,
+ 54491, 54519, 54546, 54574, 54602, 54630, 54658, 54685,
+ 54713, 54741, 54768, 54796, 54823, 54851, 54879, 54906,
+ 54933, 54961, 54988, 55015, 55043, 55070, 55097, 55124,
+ 55152, 55179, 55206, 55233, 55260, 55287, 55314, 55341,
+ 55368, 55395, 55422, 55448, 55475, 55502, 55529, 55555,
+ 55582, 55609, 55635, 55662, 55688, 55715, 55741, 55768,
+ 55794, 55820, 55847, 55873, 55899, 55925, 55952, 55978,
+ 56004, 56030, 56056, 56082, 56108, 56134, 56160, 56186,
+ 56212, 56237, 56263, 56289, 56315, 56340, 56366, 56392,
+ 56417, 56443, 56468, 56494, 56519, 56545, 56570, 56595,
+ 56621, 56646, 56671, 56697, 56722, 56747, 56772, 56797,
+ 56822, 56847, 56872, 56897, 56922, 56947, 56972, 56997,
+ 57022, 57046, 57071, 57096, 57120, 57145, 57170, 57194,
+ 57219, 57243, 57268, 57292, 57316, 57341, 57365, 57389,
+ 57414, 57438, 57462, 57486, 57510, 57534, 57558, 57582,
+ 57606, 57630, 57654, 57678, 57702, 57726, 57750, 57773,
+ 57797, 57821, 57844, 57868, 57892, 57915, 57939, 57962,
+ 57986, 58009, 58032, 58056, 58079, 58102, 58125, 58149,
+ 58172, 58195, 58218, 58241, 58264, 58287, 58310, 58333,
+ 58356, 58379, 58402, 58424, 58447, 58470, 58493, 58515,
+ 58538, 58560, 58583, 58605, 58628, 58650, 58673, 58695,
+ 58718, 58740, 58762, 58784, 58807, 58829, 58851, 58873,
+ 58895, 58917, 58939, 58961, 58983, 59005, 59027, 59049,
+ 59070, 59092, 59114, 59135, 59157, 59179, 59200, 59222,
+ 59243, 59265, 59286, 59308, 59329, 59350, 59372, 59393,
+ 59414, 59435, 59457, 59478, 59499, 59520, 59541, 59562,
+ 59583, 59604, 59625, 59645, 59666, 59687, 59708, 59728,
+ 59749, 59770, 59790, 59811, 59831, 59852, 59872, 59893,
+ 59913, 59934, 59954, 59974, 59994, 60015, 60035, 60055,
+ 60075, 60095, 60115, 60135, 60155, 60175, 60195, 60215,
+ 60235, 60254, 60274, 60294, 60313, 60333, 60353, 60372,
+ 60392, 60411, 60431, 60450, 60470, 60489, 60508, 60528,
+ 60547, 60566, 60585, 60604, 60624, 60643, 60662, 60681,
+ 60700, 60719, 60737, 60756, 60775, 60794, 60813, 60831,
+ 60850, 60869, 60887, 60906, 60924, 60943, 60961, 60980,
+ 60998, 61017, 61035, 61053, 61071, 61090, 61108, 61126,
+ 61144, 61162, 61180, 61198, 61216, 61234, 61252, 61270,
+ 61288, 61305, 61323, 61341, 61359, 61376, 61394, 61411,
+ 61429, 61446, 61464, 61481, 61499, 61516, 61533, 61551,
+ 61568, 61585, 61602, 61619, 61637, 61654, 61671, 61688,
+ 61705, 61721, 61738, 61755, 61772, 61789, 61805, 61822,
+ 61839, 61855, 61872, 61889, 61905, 61922, 61938, 61954,
+ 61971, 61987, 62003, 62020, 62036, 62052, 62068, 62084,
+ 62100, 62117, 62133, 62148, 62164, 62180, 62196, 62212,
+ 62228, 62244, 62259, 62275, 62291, 62306, 62322, 62337,
+ 62353, 62368, 62384, 62399, 62414, 62430, 62445, 62460,
+ 62475, 62491, 62506, 62521, 62536, 62551, 62566, 62581,
+ 62596, 62610, 62625, 62640, 62655, 62670, 62684, 62699,
+ 62714, 62728, 62743, 62757, 62772, 62786, 62800, 62815,
+ 62829, 62843, 62858, 62872, 62886, 62900, 62914, 62928,
+ 62942, 62956, 62970, 62984, 62998, 63012, 63026, 63039,
+ 63053, 63067, 63080, 63094, 63108, 63121, 63135, 63148,
+ 63162, 63175, 63188, 63202, 63215, 63228, 63241, 63254,
+ 63268, 63281, 63294, 63307, 63320, 63333, 63346, 63358,
+ 63371, 63384, 63397, 63410, 63422, 63435, 63447, 63460,
+ 63473, 63485, 63498, 63510, 63522, 63535, 63547, 63559,
+ 63571, 63584, 63596, 63608, 63620, 63632, 63644, 63656,
+ 63668, 63680, 63692, 63704, 63715, 63727, 63739, 63750,
+ 63762, 63774, 63785, 63797, 63808, 63820, 63831, 63842,
+ 63854, 63865, 63876, 63888, 63899, 63910, 63921, 63932,
+ 63943, 63954, 63965, 63976, 63987, 63998, 64009, 64019,
+ 64030, 64041, 64051, 64062, 64073, 64083, 64094, 64104,
+ 64115, 64125, 64135, 64146, 64156, 64166, 64176, 64186,
+ 64197, 64207, 64217, 64227, 64237, 64247, 64257, 64266,
+ 64276, 64286, 64296, 64305, 64315, 64325, 64334, 64344,
+ 64353, 64363, 64372, 64382, 64391, 64401, 64410, 64419,
+ 64428, 64437, 64447, 64456, 64465, 64474, 64483, 64492,
+ 64501, 64510, 64518, 64527, 64536, 64545, 64553, 64562,
+ 64571, 64579, 64588, 64596, 64605, 64613, 64622, 64630,
+ 64638, 64646, 64655, 64663, 64671, 64679, 64687, 64695,
+ 64703, 64711, 64719, 64727, 64735, 64743, 64751, 64758,
+ 64766, 64774, 64781, 64789, 64796, 64804, 64811, 64819,
+ 64826, 64834, 64841, 64848, 64855, 64863, 64870, 64877,
+ 64884, 64891, 64898, 64905, 64912, 64919, 64926, 64933,
+ 64939, 64946, 64953, 64959, 64966, 64973, 64979, 64986,
+ 64992, 64999, 65005, 65011, 65018, 65024, 65030, 65036,
+ 65043, 65049, 65055, 65061, 65067, 65073, 65079, 65085,
+ 65091, 65096, 65102, 65108, 65114, 65119, 65125, 65131,
+ 65136, 65142, 65147, 65153, 65158, 65163, 65169, 65174,
+ 65179, 65184, 65190, 65195, 65200, 65205, 65210, 65215,
+ 65220, 65225, 65230, 65235, 65239, 65244, 65249, 65253,
+ 65258, 65263, 65267, 65272, 65276, 65281, 65285, 65290,
+ 65294, 65298, 65302, 65307, 65311, 65315, 65319, 65323,
+ 65327, 65331, 65335, 65339, 65343, 65347, 65350, 65354,
+ 65358, 65362, 65365, 65369, 65372, 65376, 65379, 65383,
+ 65386, 65390, 65393, 65396, 65400, 65403, 65406, 65409,
+ 65412, 65415, 65418, 65421, 65424, 65427, 65430, 65433,
+ 65436, 65438, 65441, 65444, 65446, 65449, 65452, 65454,
+ 65457, 65459, 65461, 65464, 65466, 65468, 65471, 65473,
+ 65475, 65477, 65479, 65481, 65483, 65485, 65487, 65489,
+ 65491, 65493, 65495, 65496, 65498, 65500, 65501, 65503,
+ 65505, 65506, 65508, 65509, 65511, 65512, 65513, 65515,
+ 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523,
+ 65524, 65525, 65526, 65527, 65528, 65529, 65529, 65530,
65531, 65531, 65532, 65532, 65533, 65533, 65534, 65534,
65534, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
- 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65534,
- 65534, 65534, 65533, 65533, 65532, 65532, 65531, 65531,
- 65530, 65530, 65529, 65528, 65527, 65527, 65526, 65525,
- 65524, 65523, 65522, 65521, 65520, 65519, 65518, 65516,
- 65515, 65514, 65513, 65511, 65510, 65508, 65507, 65505,
- 65504, 65502, 65501, 65499, 65497, 65496, 65494, 65492,
- 65490, 65488, 65486, 65484, 65482, 65480, 65478, 65476,
- 65474, 65472, 65470, 65467, 65465, 65463, 65460, 65458,
- 65455, 65453, 65450, 65448, 65445, 65442, 65440, 65437,
- 65434, 65431, 65429, 65426, 65423, 65420, 65417, 65414,
- 65411, 65408, 65404, 65401, 65398, 65395, 65391, 65388,
- 65385, 65381, 65378, 65374, 65371, 65367, 65363, 65360,
- 65356, 65352, 65349, 65345, 65341, 65337, 65333, 65329,
- 65325, 65321, 65317, 65313, 65309, 65305, 65300, 65296,
- 65292, 65287, 65283, 65279, 65274, 65270, 65265, 65260,
- 65256, 65251, 65246, 65242, 65237, 65232, 65227, 65222,
- 65217, 65212, 65207, 65202, 65197, 65192, 65187, 65182,
- 65177, 65171, 65166, 65161, 65155, 65150, 65144, 65139,
- 65133, 65128, 65122, 65117, 65111, 65105, 65099, 65094,
- 65088, 65082, 65076, 65070, 65064, 65058, 65052, 65046,
- 65040, 65033, 65027, 65021, 65015, 65008, 65002, 64995,
- 64989, 64982, 64976, 64969, 64963, 64956, 64949, 64943,
- 64936, 64929, 64922, 64915, 64908, 64902, 64895, 64887,
- 64880, 64873, 64866, 64859, 64852, 64844, 64837, 64830,
- 64822, 64815, 64808, 64800, 64793, 64785, 64777, 64770,
- 64762, 64754, 64747, 64739, 64731, 64723, 64715, 64707,
- 64699, 64691, 64683, 64675, 64667, 64659, 64651, 64642,
- 64634, 64626, 64617, 64609, 64600, 64592, 64584, 64575,
- 64566, 64558, 64549, 64540, 64532, 64523, 64514, 64505,
- 64496, 64487, 64478, 64469, 64460, 64451, 64442, 64433,
- 64424, 64414, 64405, 64396, 64387, 64377, 64368, 64358,
- 64349, 64339, 64330, 64320, 64310, 64301, 64291, 64281,
- 64271, 64261, 64252, 64242, 64232, 64222, 64212, 64202,
- 64192, 64181, 64171, 64161, 64151, 64140, 64130, 64120,
- 64109, 64099, 64088, 64078, 64067, 64057, 64046, 64035,
- 64025, 64014, 64003, 63992, 63981, 63971, 63960, 63949,
- 63938, 63927, 63915, 63904, 63893, 63882, 63871, 63859,
- 63848, 63837, 63825, 63814, 63803, 63791, 63779, 63768,
- 63756, 63745, 63733, 63721, 63709, 63698, 63686, 63674,
- 63662, 63650, 63638, 63626, 63614, 63602, 63590, 63578,
- 63565, 63553, 63541, 63528, 63516, 63504, 63491, 63479,
- 63466, 63454, 63441, 63429, 63416, 63403, 63390, 63378,
- 63365, 63352, 63339, 63326, 63313, 63300, 63287, 63274,
- 63261, 63248, 63235, 63221, 63208, 63195, 63182, 63168,
- 63155, 63141, 63128, 63114, 63101, 63087, 63074, 63060,
- 63046, 63032, 63019, 63005, 62991, 62977, 62963, 62949,
- 62935, 62921, 62907, 62893, 62879, 62865, 62850, 62836,
- 62822, 62808, 62793, 62779, 62764, 62750, 62735, 62721,
- 62706, 62692, 62677, 62662, 62648, 62633, 62618, 62603,
- 62588, 62573, 62558, 62543, 62528, 62513, 62498, 62483,
- 62468, 62453, 62437, 62422, 62407, 62391, 62376, 62360,
- 62345, 62329, 62314, 62298, 62283, 62267, 62251, 62236,
- 62220, 62204, 62188, 62172, 62156, 62141, 62125, 62108,
- 62092, 62076, 62060, 62044, 62028, 62012, 61995, 61979,
- 61963, 61946, 61930, 61913, 61897, 61880, 61864, 61847,
- 61831, 61814, 61797, 61780, 61764, 61747, 61730, 61713,
- 61696, 61679, 61662, 61645, 61628, 61611, 61594, 61577,
- 61559, 61542, 61525, 61507, 61490, 61473, 61455, 61438,
- 61420, 61403, 61385, 61367, 61350, 61332, 61314, 61297,
- 61279, 61261, 61243, 61225, 61207, 61189, 61171, 61153,
- 61135, 61117, 61099, 61081, 61062, 61044, 61026, 61007,
- 60989, 60971, 60952, 60934, 60915, 60897, 60878, 60859,
- 60841, 60822, 60803, 60785, 60766, 60747, 60728, 60709,
- 60690, 60671, 60652, 60633, 60614, 60595, 60576, 60556,
- 60537, 60518, 60499, 60479, 60460, 60441, 60421, 60402,
- 60382, 60363, 60343, 60323, 60304, 60284, 60264, 60244,
- 60225, 60205, 60185, 60165, 60145, 60125, 60105, 60085,
- 60065, 60045, 60025, 60004, 59984, 59964, 59944, 59923,
- 59903, 59883, 59862, 59842, 59821, 59801, 59780, 59759,
- 59739, 59718, 59697, 59677, 59656, 59635, 59614, 59593,
- 59572, 59551, 59530, 59509, 59488, 59467, 59446, 59425,
- 59404, 59382, 59361, 59340, 59318, 59297, 59276, 59254,
- 59233, 59211, 59190, 59168, 59146, 59125, 59103, 59081,
- 59059, 59038, 59016, 58994, 58972, 58950, 58928, 58906,
- 58884, 58862, 58840, 58818, 58795, 58773, 58751, 58729,
- 58706, 58684, 58662, 58639, 58617, 58594, 58572, 58549,
- 58527, 58504, 58481, 58459, 58436, 58413, 58390, 58367,
- 58345, 58322, 58299, 58276, 58253, 58230, 58207, 58183,
- 58160, 58137, 58114, 58091, 58067, 58044, 58021, 57997,
- 57974, 57950, 57927, 57903, 57880, 57856, 57833, 57809,
- 57785, 57762, 57738, 57714, 57690, 57666, 57642, 57618,
- 57594, 57570, 57546, 57522, 57498, 57474, 57450, 57426,
- 57402, 57377, 57353, 57329, 57304, 57280, 57255, 57231,
- 57206, 57182, 57157, 57133, 57108, 57083, 57059, 57034,
- 57009, 56984, 56959, 56935, 56910, 56885, 56860, 56835,
- 56810, 56785, 56760, 56734, 56709, 56684, 56659, 56633,
- 56608, 56583, 56557, 56532, 56507, 56481, 56456, 56430,
- 56404, 56379, 56353, 56328, 56302, 56276, 56250, 56225,
- 56199, 56173, 56147, 56121, 56095, 56069, 56043, 56017,
- 55991, 55965, 55938, 55912, 55886, 55860, 55833, 55807,
- 55781, 55754, 55728, 55701, 55675, 55648, 55622, 55595,
- 55569, 55542, 55515, 55489, 55462, 55435, 55408, 55381,
- 55354, 55327, 55300, 55274, 55246, 55219, 55192, 55165,
- 55138, 55111, 55084, 55056, 55029, 55002, 54974, 54947,
- 54920, 54892, 54865, 54837, 54810, 54782, 54755, 54727,
- 54699, 54672, 54644, 54616, 54588, 54560, 54533, 54505,
- 54477, 54449, 54421, 54393, 54365, 54337, 54308, 54280,
- 54252, 54224, 54196, 54167, 54139, 54111, 54082, 54054,
- 54026, 53997, 53969, 53940, 53911, 53883, 53854, 53826,
- 53797, 53768, 53739, 53711, 53682, 53653, 53624, 53595,
- 53566, 53537, 53508, 53479, 53450, 53421, 53392, 53363,
- 53334, 53304, 53275, 53246, 53216, 53187, 53158, 53128,
- 53099, 53069, 53040, 53010, 52981, 52951, 52922, 52892,
- 52862, 52832, 52803, 52773, 52743, 52713, 52683, 52653,
- 52624, 52594, 52564, 52534, 52503, 52473, 52443, 52413,
- 52383, 52353, 52322, 52292, 52262, 52231, 52201, 52171,
- 52140, 52110, 52079, 52049, 52018, 51988, 51957, 51926,
- 51896, 51865, 51834, 51803, 51773, 51742, 51711, 51680,
- 51649, 51618, 51587, 51556, 51525, 51494, 51463, 51432,
- 51401, 51369, 51338, 51307, 51276, 51244, 51213, 51182,
- 51150, 51119, 51087, 51056, 51024, 50993, 50961, 50929,
- 50898, 50866, 50834, 50803, 50771, 50739, 50707, 50675,
- 50644, 50612, 50580, 50548, 50516, 50484, 50452, 50420,
- 50387, 50355, 50323, 50291, 50259, 50226, 50194, 50162,
- 50129, 50097, 50065, 50032, 50000, 49967, 49935, 49902,
- 49869, 49837, 49804, 49771, 49739, 49706, 49673, 49640,
- 49608, 49575, 49542, 49509, 49476, 49443, 49410, 49377,
- 49344, 49311, 49278, 49244, 49211, 49178, 49145, 49112,
- 49078, 49045, 49012, 48978, 48945, 48911, 48878, 48844,
- 48811, 48777, 48744, 48710, 48676, 48643, 48609, 48575,
- 48542, 48508, 48474, 48440, 48406, 48372, 48338, 48304,
- 48271, 48237, 48202, 48168, 48134, 48100, 48066, 48032,
- 47998, 47963, 47929, 47895, 47860, 47826, 47792, 47757,
- 47723, 47688, 47654, 47619, 47585, 47550, 47516, 47481,
- 47446, 47412, 47377, 47342, 47308, 47273, 47238, 47203,
- 47168, 47133, 47098, 47063, 47028, 46993, 46958, 46923,
- 46888, 46853, 46818, 46783, 46747, 46712, 46677, 46642,
- 46606, 46571, 46536, 46500, 46465, 46429, 46394, 46358,
- 46323, 46287, 46252, 46216, 46180, 46145, 46109, 46073,
- 46037, 46002, 45966, 45930, 45894, 45858, 45822, 45786,
- 45750, 45714, 45678, 45642, 45606, 45570, 45534, 45498,
- 45462, 45425, 45389, 45353, 45316, 45280, 45244, 45207,
- 45171, 45135, 45098, 45062, 45025, 44989, 44952, 44915,
- 44879, 44842, 44806, 44769, 44732, 44695, 44659, 44622,
- 44585, 44548, 44511, 44474, 44437, 44400, 44363, 44326,
- 44289, 44252, 44215, 44178, 44141, 44104, 44067, 44029,
- 43992, 43955, 43918, 43880, 43843, 43806, 43768, 43731,
- 43693, 43656, 43618, 43581, 43543, 43506, 43468, 43430,
- 43393, 43355, 43317, 43280, 43242, 43204, 43166, 43128,
- 43091, 43053, 43015, 42977, 42939, 42901, 42863, 42825,
- 42787, 42749, 42711, 42672, 42634, 42596, 42558, 42520,
- 42481, 42443, 42405, 42366, 42328, 42290, 42251, 42213,
- 42174, 42136, 42097, 42059, 42020, 41982, 41943, 41904,
- 41866, 41827, 41788, 41750, 41711, 41672, 41633, 41595,
- 41556, 41517, 41478, 41439, 41400, 41361, 41322, 41283,
- 41244, 41205, 41166, 41127, 41088, 41048, 41009, 40970,
- 40931, 40891, 40852, 40813, 40773, 40734, 40695, 40655,
- 40616, 40576, 40537, 40497, 40458, 40418, 40379, 40339,
- 40300, 40260, 40220, 40180, 40141, 40101, 40061, 40021,
- 39982, 39942, 39902, 39862, 39822, 39782, 39742, 39702,
- 39662, 39622, 39582, 39542, 39502, 39462, 39422, 39382,
- 39341, 39301, 39261, 39221, 39180, 39140, 39100, 39059,
- 39019, 38979, 38938, 38898, 38857, 38817, 38776, 38736,
- 38695, 38655, 38614, 38573, 38533, 38492, 38451, 38411,
- 38370, 38329, 38288, 38248, 38207, 38166, 38125, 38084,
- 38043, 38002, 37961, 37920, 37879, 37838, 37797, 37756,
- 37715, 37674, 37633, 37592, 37551, 37509, 37468, 37427,
- 37386, 37344, 37303, 37262, 37220, 37179, 37137, 37096,
- 37055, 37013, 36972, 36930, 36889, 36847, 36805, 36764,
- 36722, 36681, 36639, 36597, 36556, 36514, 36472, 36430,
- 36388, 36347, 36305, 36263, 36221, 36179, 36137, 36095,
- 36053, 36011, 35969, 35927, 35885, 35843, 35801, 35759,
- 35717, 35675, 35633, 35590, 35548, 35506, 35464, 35421,
- 35379, 35337, 35294, 35252, 35210, 35167, 35125, 35082,
- 35040, 34997, 34955, 34912, 34870, 34827, 34785, 34742,
- 34699, 34657, 34614, 34571, 34529, 34486, 34443, 34400,
- 34358, 34315, 34272, 34229, 34186, 34143, 34100, 34057,
- 34015, 33972, 33929, 33886, 33843, 33799, 33756, 33713,
- 33670, 33627, 33584, 33541, 33498, 33454, 33411, 33368,
- 33325, 33281, 33238, 33195, 33151, 33108, 33065, 33021,
- 32978, 32934, 32891, 32847, 32804, 32760, 32717, 32673,
- 32630, 32586, 32542, 32499, 32455, 32411, 32368, 32324,
- 32280, 32236, 32193, 32149, 32105, 32061, 32017, 31974,
- 31930, 31886, 31842, 31798, 31754, 31710, 31666, 31622,
- 31578, 31534, 31490, 31446, 31402, 31357, 31313, 31269,
- 31225, 31181, 31136, 31092, 31048, 31004, 30959, 30915,
- 30871, 30826, 30782, 30738, 30693, 30649, 30604, 30560,
- 30515, 30471, 30426, 30382, 30337, 30293, 30248, 30204,
- 30159, 30114, 30070, 30025, 29980, 29936, 29891, 29846,
- 29801, 29757, 29712, 29667, 29622, 29577, 29533, 29488,
- 29443, 29398, 29353, 29308, 29263, 29218, 29173, 29128,
- 29083, 29038, 28993, 28948, 28903, 28858, 28812, 28767,
- 28722, 28677, 28632, 28586, 28541, 28496, 28451, 28405,
- 28360, 28315, 28269, 28224, 28179, 28133, 28088, 28042,
- 27997, 27952, 27906, 27861, 27815, 27770, 27724, 27678,
- 27633, 27587, 27542, 27496, 27450, 27405, 27359, 27313,
- 27268, 27222, 27176, 27131, 27085, 27039, 26993, 26947,
- 26902, 26856, 26810, 26764, 26718, 26672, 26626, 26580,
- 26534, 26488, 26442, 26396, 26350, 26304, 26258, 26212,
- 26166, 26120, 26074, 26028, 25982, 25936, 25889, 25843,
- 25797, 25751, 25705, 25658, 25612, 25566, 25520, 25473,
- 25427, 25381, 25334, 25288, 25241, 25195, 25149, 25102,
- 25056, 25009, 24963, 24916, 24870, 24823, 24777, 24730,
- 24684, 24637, 24591, 24544, 24497, 24451, 24404, 24357,
- 24311, 24264, 24217, 24171, 24124, 24077, 24030, 23984,
- 23937, 23890, 23843, 23796, 23750, 23703, 23656, 23609,
- 23562, 23515, 23468, 23421, 23374, 23327, 23280, 23233,
- 23186, 23139, 23092, 23045, 22998, 22951, 22904, 22857,
- 22810, 22763, 22716, 22668, 22621, 22574, 22527, 22480,
- 22433, 22385, 22338, 22291, 22243, 22196, 22149, 22102,
- 22054, 22007, 21960, 21912, 21865, 21817, 21770, 21723,
- 21675, 21628, 21580, 21533, 21485, 21438, 21390, 21343,
- 21295, 21248, 21200, 21153, 21105, 21057, 21010, 20962,
- 20915, 20867, 20819, 20772, 20724, 20676, 20629, 20581,
- 20533, 20485, 20438, 20390, 20342, 20294, 20246, 20199,
- 20151, 20103, 20055, 20007, 19959, 19912, 19864, 19816,
- 19768, 19720, 19672, 19624, 19576, 19528, 19480, 19432,
- 19384, 19336, 19288, 19240, 19192, 19144, 19096, 19048,
- 19000, 18951, 18903, 18855, 18807, 18759, 18711, 18663,
- 18614, 18566, 18518, 18470, 18421, 18373, 18325, 18277,
- 18228, 18180, 18132, 18084, 18035, 17987, 17939, 17890,
- 17842, 17793, 17745, 17697, 17648, 17600, 17551, 17503,
- 17455, 17406, 17358, 17309, 17261, 17212, 17164, 17115,
- 17067, 17018, 16970, 16921, 16872, 16824, 16775, 16727,
- 16678, 16629, 16581, 16532, 16484, 16435, 16386, 16338,
- 16289, 16240, 16191, 16143, 16094, 16045, 15997, 15948,
- 15899, 15850, 15802, 15753, 15704, 15655, 15606, 15557,
- 15509, 15460, 15411, 15362, 15313, 15264, 15215, 15167,
- 15118, 15069, 15020, 14971, 14922, 14873, 14824, 14775,
- 14726, 14677, 14628, 14579, 14530, 14481, 14432, 14383,
- 14334, 14285, 14236, 14187, 14138, 14089, 14040, 13990,
- 13941, 13892, 13843, 13794, 13745, 13696, 13646, 13597,
- 13548, 13499, 13450, 13401, 13351, 13302, 13253, 13204,
- 13154, 13105, 13056, 13007, 12957, 12908, 12859, 12810,
- 12760, 12711, 12662, 12612, 12563, 12514, 12464, 12415,
- 12366, 12316, 12267, 12218, 12168, 12119, 12069, 12020,
- 11970, 11921, 11872, 11822, 11773, 11723, 11674, 11624,
- 11575, 11525, 11476, 11426, 11377, 11327, 11278, 11228,
- 11179, 11129, 11080, 11030, 10981, 10931, 10882, 10832,
- 10782, 10733, 10683, 10634, 10584, 10534, 10485, 10435,
- 10386, 10336, 10286, 10237, 10187, 10137, 10088, 10038,
- 9988, 9939, 9889, 9839, 9790, 9740, 9690, 9640,
- 9591, 9541, 9491, 9442, 9392, 9342, 9292, 9243,
- 9193, 9143, 9093, 9043, 8994, 8944, 8894, 8844,
- 8794, 8745, 8695, 8645, 8595, 8545, 8496, 8446,
- 8396, 8346, 8296, 8246, 8196, 8147, 8097, 8047,
- 7997, 7947, 7897, 7847, 7797, 7747, 7697, 7648,
- 7598, 7548, 7498, 7448, 7398, 7348, 7298, 7248,
- 7198, 7148, 7098, 7048, 6998, 6948, 6898, 6848,
- 6798, 6748, 6698, 6648, 6598, 6548, 6498, 6448,
- 6398, 6348, 6298, 6248, 6198, 6148, 6098, 6048,
- 5998, 5948, 5898, 5848, 5798, 5748, 5697, 5647,
- 5597, 5547, 5497, 5447, 5397, 5347, 5297, 5247,
- 5197, 5146, 5096, 5046, 4996, 4946, 4896, 4846,
- 4796, 4745, 4695, 4645, 4595, 4545, 4495, 4445,
- 4394, 4344, 4294, 4244, 4194, 4144, 4093, 4043,
- 3993, 3943, 3893, 3843, 3792, 3742, 3692, 3642,
- 3592, 3541, 3491, 3441, 3391, 3341, 3291, 3240,
- 3190, 3140, 3090, 3039, 2989, 2939, 2889, 2839,
- 2788, 2738, 2688, 2638, 2587, 2537, 2487, 2437,
- 2387, 2336, 2286, 2236, 2186, 2135, 2085, 2035,
- 1985, 1934, 1884, 1834, 1784, 1733, 1683, 1633,
- 1583, 1532, 1482, 1432, 1382, 1331, 1281, 1231,
- 1181, 1130, 1080, 1030, 980, 929, 879, 829,
- 779, 728, 678, 628, 578, 527, 477, 427,
- 376, 326, 276, 226, 175, 125, 75, 25,
- -25, -75, -125, -175, -226, -276, -326, -376,
- -427, -477, -527, -578, -628, -678, -728, -779,
- -829, -879, -929, -980, -1030, -1080, -1130, -1181,
- -1231, -1281, -1331, -1382, -1432, -1482, -1532, -1583,
- -1633, -1683, -1733, -1784, -1834, -1884, -1934, -1985,
- -2035, -2085, -2135, -2186, -2236, -2286, -2336, -2387,
- -2437, -2487, -2537, -2588, -2638, -2688, -2738, -2788,
- -2839, -2889, -2939, -2989, -3039, -3090, -3140, -3190,
- -3240, -3291, -3341, -3391, -3441, -3491, -3541, -3592,
- -3642, -3692, -3742, -3792, -3843, -3893, -3943, -3993,
- -4043, -4093, -4144, -4194, -4244, -4294, -4344, -4394,
- -4445, -4495, -4545, -4595, -4645, -4695, -4745, -4796,
- -4846, -4896, -4946, -4996, -5046, -5096, -5146, -5197,
- -5247, -5297, -5347, -5397, -5447, -5497, -5547, -5597,
- -5647, -5697, -5748, -5798, -5848, -5898, -5948, -5998,
- -6048, -6098, -6148, -6198, -6248, -6298, -6348, -6398,
- -6448, -6498, -6548, -6598, -6648, -6698, -6748, -6798,
- -6848, -6898, -6948, -6998, -7048, -7098, -7148, -7198,
- -7248, -7298, -7348, -7398, -7448, -7498, -7548, -7598,
- -7648, -7697, -7747, -7797, -7847, -7897, -7947, -7997,
- -8047, -8097, -8147, -8196, -8246, -8296, -8346, -8396,
- -8446, -8496, -8545, -8595, -8645, -8695, -8745, -8794,
- -8844, -8894, -8944, -8994, -9043, -9093, -9143, -9193,
- -9243, -9292, -9342, -9392, -9442, -9491, -9541, -9591,
- -9640, -9690, -9740, -9790, -9839, -9889, -9939, -9988,
- -10038, -10088, -10137, -10187, -10237, -10286, -10336, -10386,
- -10435, -10485, -10534, -10584, -10634, -10683, -10733, -10782,
- -10832, -10882, -10931, -10981, -11030, -11080, -11129, -11179,
- -11228, -11278, -11327, -11377, -11426, -11476, -11525, -11575,
- -11624, -11674, -11723, -11773, -11822, -11872, -11921, -11970,
- -12020, -12069, -12119, -12168, -12218, -12267, -12316, -12366,
- -12415, -12464, -12514, -12563, -12612, -12662, -12711, -12760,
- -12810, -12859, -12908, -12957, -13007, -13056, -13105, -13154,
- -13204, -13253, -13302, -13351, -13401, -13450, -13499, -13548,
- -13597, -13647, -13696, -13745, -13794, -13843, -13892, -13941,
- -13990, -14040, -14089, -14138, -14187, -14236, -14285, -14334,
- -14383, -14432, -14481, -14530, -14579, -14628, -14677, -14726,
- -14775, -14824, -14873, -14922, -14971, -15020, -15069, -15118,
- -15167, -15215, -15264, -15313, -15362, -15411, -15460, -15509,
- -15557, -15606, -15655, -15704, -15753, -15802, -15850, -15899,
- -15948, -15997, -16045, -16094, -16143, -16191, -16240, -16289,
- -16338, -16386, -16435, -16484, -16532, -16581, -16629, -16678,
- -16727, -16775, -16824, -16872, -16921, -16970, -17018, -17067,
- -17115, -17164, -17212, -17261, -17309, -17358, -17406, -17455,
- -17503, -17551, -17600, -17648, -17697, -17745, -17793, -17842,
- -17890, -17939, -17987, -18035, -18084, -18132, -18180, -18228,
- -18277, -18325, -18373, -18421, -18470, -18518, -18566, -18614,
- -18663, -18711, -18759, -18807, -18855, -18903, -18951, -19000,
- -19048, -19096, -19144, -19192, -19240, -19288, -19336, -19384,
- -19432, -19480, -19528, -19576, -19624, -19672, -19720, -19768,
- -19816, -19864, -19912, -19959, -20007, -20055, -20103, -20151,
- -20199, -20246, -20294, -20342, -20390, -20438, -20485, -20533,
- -20581, -20629, -20676, -20724, -20772, -20819, -20867, -20915,
- -20962, -21010, -21057, -21105, -21153, -21200, -21248, -21295,
- -21343, -21390, -21438, -21485, -21533, -21580, -21628, -21675,
- -21723, -21770, -21817, -21865, -21912, -21960, -22007, -22054,
- -22102, -22149, -22196, -22243, -22291, -22338, -22385, -22433,
- -22480, -22527, -22574, -22621, -22668, -22716, -22763, -22810,
- -22857, -22904, -22951, -22998, -23045, -23092, -23139, -23186,
- -23233, -23280, -23327, -23374, -23421, -23468, -23515, -23562,
- -23609, -23656, -23703, -23750, -23796, -23843, -23890, -23937,
- -23984, -24030, -24077, -24124, -24171, -24217, -24264, -24311,
- -24357, -24404, -24451, -24497, -24544, -24591, -24637, -24684,
- -24730, -24777, -24823, -24870, -24916, -24963, -25009, -25056,
- -25102, -25149, -25195, -25241, -25288, -25334, -25381, -25427,
- -25473, -25520, -25566, -25612, -25658, -25705, -25751, -25797,
- -25843, -25889, -25936, -25982, -26028, -26074, -26120, -26166,
- -26212, -26258, -26304, -26350, -26396, -26442, -26488, -26534,
- -26580, -26626, -26672, -26718, -26764, -26810, -26856, -26902,
- -26947, -26993, -27039, -27085, -27131, -27176, -27222, -27268,
- -27313, -27359, -27405, -27450, -27496, -27542, -27587, -27633,
- -27678, -27724, -27770, -27815, -27861, -27906, -27952, -27997,
- -28042, -28088, -28133, -28179, -28224, -28269, -28315, -28360,
- -28405, -28451, -28496, -28541, -28586, -28632, -28677, -28722,
- -28767, -28812, -28858, -28903, -28948, -28993, -29038, -29083,
- -29128, -29173, -29218, -29263, -29308, -29353, -29398, -29443,
- -29488, -29533, -29577, -29622, -29667, -29712, -29757, -29801,
- -29846, -29891, -29936, -29980, -30025, -30070, -30114, -30159,
- -30204, -30248, -30293, -30337, -30382, -30426, -30471, -30515,
- -30560, -30604, -30649, -30693, -30738, -30782, -30826, -30871,
- -30915, -30959, -31004, -31048, -31092, -31136, -31181, -31225,
- -31269, -31313, -31357, -31402, -31446, -31490, -31534, -31578,
- -31622, -31666, -31710, -31754, -31798, -31842, -31886, -31930,
- -31974, -32017, -32061, -32105, -32149, -32193, -32236, -32280,
- -32324, -32368, -32411, -32455, -32499, -32542, -32586, -32630,
- -32673, -32717, -32760, -32804, -32847, -32891, -32934, -32978,
- -33021, -33065, -33108, -33151, -33195, -33238, -33281, -33325,
- -33368, -33411, -33454, -33498, -33541, -33584, -33627, -33670,
- -33713, -33756, -33799, -33843, -33886, -33929, -33972, -34015,
- -34057, -34100, -34143, -34186, -34229, -34272, -34315, -34358,
- -34400, -34443, -34486, -34529, -34571, -34614, -34657, -34699,
- -34742, -34785, -34827, -34870, -34912, -34955, -34997, -35040,
- -35082, -35125, -35167, -35210, -35252, -35294, -35337, -35379,
- -35421, -35464, -35506, -35548, -35590, -35633, -35675, -35717,
- -35759, -35801, -35843, -35885, -35927, -35969, -36011, -36053,
- -36095, -36137, -36179, -36221, -36263, -36305, -36347, -36388,
- -36430, -36472, -36514, -36555, -36597, -36639, -36681, -36722,
- -36764, -36805, -36847, -36889, -36930, -36972, -37013, -37055,
- -37096, -37137, -37179, -37220, -37262, -37303, -37344, -37386,
- -37427, -37468, -37509, -37551, -37592, -37633, -37674, -37715,
- -37756, -37797, -37838, -37879, -37920, -37961, -38002, -38043,
- -38084, -38125, -38166, -38207, -38248, -38288, -38329, -38370,
- -38411, -38451, -38492, -38533, -38573, -38614, -38655, -38695,
- -38736, -38776, -38817, -38857, -38898, -38938, -38979, -39019,
- -39059, -39100, -39140, -39180, -39221, -39261, -39301, -39341,
- -39382, -39422, -39462, -39502, -39542, -39582, -39622, -39662,
- -39702, -39742, -39782, -39822, -39862, -39902, -39942, -39982,
- -40021, -40061, -40101, -40141, -40180, -40220, -40260, -40299,
- -40339, -40379, -40418, -40458, -40497, -40537, -40576, -40616,
- -40655, -40695, -40734, -40773, -40813, -40852, -40891, -40931,
- -40970, -41009, -41048, -41087, -41127, -41166, -41205, -41244,
- -41283, -41322, -41361, -41400, -41439, -41478, -41517, -41556,
- -41595, -41633, -41672, -41711, -41750, -41788, -41827, -41866,
- -41904, -41943, -41982, -42020, -42059, -42097, -42136, -42174,
- -42213, -42251, -42290, -42328, -42366, -42405, -42443, -42481,
- -42520, -42558, -42596, -42634, -42672, -42711, -42749, -42787,
- -42825, -42863, -42901, -42939, -42977, -43015, -43053, -43091,
- -43128, -43166, -43204, -43242, -43280, -43317, -43355, -43393,
- -43430, -43468, -43506, -43543, -43581, -43618, -43656, -43693,
- -43731, -43768, -43806, -43843, -43880, -43918, -43955, -43992,
- -44029, -44067, -44104, -44141, -44178, -44215, -44252, -44289,
- -44326, -44363, -44400, -44437, -44474, -44511, -44548, -44585,
- -44622, -44659, -44695, -44732, -44769, -44806, -44842, -44879,
- -44915, -44952, -44989, -45025, -45062, -45098, -45135, -45171,
- -45207, -45244, -45280, -45316, -45353, -45389, -45425, -45462,
- -45498, -45534, -45570, -45606, -45642, -45678, -45714, -45750,
- -45786, -45822, -45858, -45894, -45930, -45966, -46002, -46037,
- -46073, -46109, -46145, -46180, -46216, -46252, -46287, -46323,
- -46358, -46394, -46429, -46465, -46500, -46536, -46571, -46606,
- -46642, -46677, -46712, -46747, -46783, -46818, -46853, -46888,
- -46923, -46958, -46993, -47028, -47063, -47098, -47133, -47168,
- -47203, -47238, -47273, -47308, -47342, -47377, -47412, -47446,
- -47481, -47516, -47550, -47585, -47619, -47654, -47688, -47723,
- -47757, -47792, -47826, -47860, -47895, -47929, -47963, -47998,
- -48032, -48066, -48100, -48134, -48168, -48202, -48236, -48271,
- -48304, -48338, -48372, -48406, -48440, -48474, -48508, -48542,
- -48575, -48609, -48643, -48676, -48710, -48744, -48777, -48811,
- -48844, -48878, -48911, -48945, -48978, -49012, -49045, -49078,
- -49112, -49145, -49178, -49211, -49244, -49278, -49311, -49344,
- -49377, -49410, -49443, -49476, -49509, -49542, -49575, -49608,
- -49640, -49673, -49706, -49739, -49771, -49804, -49837, -49869,
- -49902, -49935, -49967, -50000, -50032, -50065, -50097, -50129,
- -50162, -50194, -50226, -50259, -50291, -50323, -50355, -50387,
- -50420, -50452, -50484, -50516, -50548, -50580, -50612, -50644,
- -50675, -50707, -50739, -50771, -50803, -50834, -50866, -50898,
- -50929, -50961, -50993, -51024, -51056, -51087, -51119, -51150,
- -51182, -51213, -51244, -51276, -51307, -51338, -51369, -51401,
- -51432, -51463, -51494, -51525, -51556, -51587, -51618, -51649,
- -51680, -51711, -51742, -51773, -51803, -51834, -51865, -51896,
- -51926, -51957, -51988, -52018, -52049, -52079, -52110, -52140,
- -52171, -52201, -52231, -52262, -52292, -52322, -52353, -52383,
- -52413, -52443, -52473, -52503, -52534, -52564, -52594, -52624,
- -52653, -52683, -52713, -52743, -52773, -52803, -52832, -52862,
- -52892, -52922, -52951, -52981, -53010, -53040, -53069, -53099,
- -53128, -53158, -53187, -53216, -53246, -53275, -53304, -53334,
- -53363, -53392, -53421, -53450, -53479, -53508, -53537, -53566,
- -53595, -53624, -53653, -53682, -53711, -53739, -53768, -53797,
- -53826, -53854, -53883, -53911, -53940, -53969, -53997, -54026,
- -54054, -54082, -54111, -54139, -54167, -54196, -54224, -54252,
- -54280, -54308, -54337, -54365, -54393, -54421, -54449, -54477,
- -54505, -54533, -54560, -54588, -54616, -54644, -54672, -54699,
- -54727, -54755, -54782, -54810, -54837, -54865, -54892, -54920,
- -54947, -54974, -55002, -55029, -55056, -55084, -55111, -55138,
- -55165, -55192, -55219, -55246, -55274, -55300, -55327, -55354,
- -55381, -55408, -55435, -55462, -55489, -55515, -55542, -55569,
- -55595, -55622, -55648, -55675, -55701, -55728, -55754, -55781,
- -55807, -55833, -55860, -55886, -55912, -55938, -55965, -55991,
- -56017, -56043, -56069, -56095, -56121, -56147, -56173, -56199,
- -56225, -56250, -56276, -56302, -56328, -56353, -56379, -56404,
- -56430, -56456, -56481, -56507, -56532, -56557, -56583, -56608,
- -56633, -56659, -56684, -56709, -56734, -56760, -56785, -56810,
- -56835, -56860, -56885, -56910, -56935, -56959, -56984, -57009,
- -57034, -57059, -57083, -57108, -57133, -57157, -57182, -57206,
- -57231, -57255, -57280, -57304, -57329, -57353, -57377, -57402,
- -57426, -57450, -57474, -57498, -57522, -57546, -57570, -57594,
- -57618, -57642, -57666, -57690, -57714, -57738, -57762, -57785,
- -57809, -57833, -57856, -57880, -57903, -57927, -57950, -57974,
- -57997, -58021, -58044, -58067, -58091, -58114, -58137, -58160,
- -58183, -58207, -58230, -58253, -58276, -58299, -58322, -58345,
- -58367, -58390, -58413, -58436, -58459, -58481, -58504, -58527,
- -58549, -58572, -58594, -58617, -58639, -58662, -58684, -58706,
- -58729, -58751, -58773, -58795, -58818, -58840, -58862, -58884,
- -58906, -58928, -58950, -58972, -58994, -59016, -59038, -59059,
- -59081, -59103, -59125, -59146, -59168, -59190, -59211, -59233,
- -59254, -59276, -59297, -59318, -59340, -59361, -59382, -59404,
- -59425, -59446, -59467, -59488, -59509, -59530, -59551, -59572,
- -59593, -59614, -59635, -59656, -59677, -59697, -59718, -59739,
- -59759, -59780, -59801, -59821, -59842, -59862, -59883, -59903,
- -59923, -59944, -59964, -59984, -60004, -60025, -60045, -60065,
- -60085, -60105, -60125, -60145, -60165, -60185, -60205, -60225,
- -60244, -60264, -60284, -60304, -60323, -60343, -60363, -60382,
- -60402, -60421, -60441, -60460, -60479, -60499, -60518, -60537,
- -60556, -60576, -60595, -60614, -60633, -60652, -60671, -60690,
- -60709, -60728, -60747, -60766, -60785, -60803, -60822, -60841,
- -60859, -60878, -60897, -60915, -60934, -60952, -60971, -60989,
- -61007, -61026, -61044, -61062, -61081, -61099, -61117, -61135,
- -61153, -61171, -61189, -61207, -61225, -61243, -61261, -61279,
- -61297, -61314, -61332, -61350, -61367, -61385, -61403, -61420,
- -61438, -61455, -61473, -61490, -61507, -61525, -61542, -61559,
- -61577, -61594, -61611, -61628, -61645, -61662, -61679, -61696,
- -61713, -61730, -61747, -61764, -61780, -61797, -61814, -61831,
- -61847, -61864, -61880, -61897, -61913, -61930, -61946, -61963,
- -61979, -61995, -62012, -62028, -62044, -62060, -62076, -62092,
- -62108, -62125, -62141, -62156, -62172, -62188, -62204, -62220,
- -62236, -62251, -62267, -62283, -62298, -62314, -62329, -62345,
- -62360, -62376, -62391, -62407, -62422, -62437, -62453, -62468,
- -62483, -62498, -62513, -62528, -62543, -62558, -62573, -62588,
- -62603, -62618, -62633, -62648, -62662, -62677, -62692, -62706,
- -62721, -62735, -62750, -62764, -62779, -62793, -62808, -62822,
- -62836, -62850, -62865, -62879, -62893, -62907, -62921, -62935,
- -62949, -62963, -62977, -62991, -63005, -63019, -63032, -63046,
- -63060, -63074, -63087, -63101, -63114, -63128, -63141, -63155,
- -63168, -63182, -63195, -63208, -63221, -63235, -63248, -63261,
- -63274, -63287, -63300, -63313, -63326, -63339, -63352, -63365,
- -63378, -63390, -63403, -63416, -63429, -63441, -63454, -63466,
- -63479, -63491, -63504, -63516, -63528, -63541, -63553, -63565,
- -63578, -63590, -63602, -63614, -63626, -63638, -63650, -63662,
- -63674, -63686, -63698, -63709, -63721, -63733, -63745, -63756,
- -63768, -63779, -63791, -63803, -63814, -63825, -63837, -63848,
- -63859, -63871, -63882, -63893, -63904, -63915, -63927, -63938,
- -63949, -63960, -63971, -63981, -63992, -64003, -64014, -64025,
- -64035, -64046, -64057, -64067, -64078, -64088, -64099, -64109,
- -64120, -64130, -64140, -64151, -64161, -64171, -64181, -64192,
- -64202, -64212, -64222, -64232, -64242, -64252, -64261, -64271,
- -64281, -64291, -64301, -64310, -64320, -64330, -64339, -64349,
- -64358, -64368, -64377, -64387, -64396, -64405, -64414, -64424,
- -64433, -64442, -64451, -64460, -64469, -64478, -64487, -64496,
- -64505, -64514, -64523, -64532, -64540, -64549, -64558, -64566,
- -64575, -64584, -64592, -64601, -64609, -64617, -64626, -64634,
- -64642, -64651, -64659, -64667, -64675, -64683, -64691, -64699,
- -64707, -64715, -64723, -64731, -64739, -64747, -64754, -64762,
- -64770, -64777, -64785, -64793, -64800, -64808, -64815, -64822,
- -64830, -64837, -64844, -64852, -64859, -64866, -64873, -64880,
- -64887, -64895, -64902, -64908, -64915, -64922, -64929, -64936,
- -64943, -64949, -64956, -64963, -64969, -64976, -64982, -64989,
- -64995, -65002, -65008, -65015, -65021, -65027, -65033, -65040,
- -65046, -65052, -65058, -65064, -65070, -65076, -65082, -65088,
- -65094, -65099, -65105, -65111, -65117, -65122, -65128, -65133,
- -65139, -65144, -65150, -65155, -65161, -65166, -65171, -65177,
- -65182, -65187, -65192, -65197, -65202, -65207, -65212, -65217,
- -65222, -65227, -65232, -65237, -65242, -65246, -65251, -65256,
- -65260, -65265, -65270, -65274, -65279, -65283, -65287, -65292,
- -65296, -65300, -65305, -65309, -65313, -65317, -65321, -65325,
- -65329, -65333, -65337, -65341, -65345, -65349, -65352, -65356,
- -65360, -65363, -65367, -65371, -65374, -65378, -65381, -65385,
- -65388, -65391, -65395, -65398, -65401, -65404, -65408, -65411,
- -65414, -65417, -65420, -65423, -65426, -65429, -65431, -65434,
- -65437, -65440, -65442, -65445, -65448, -65450, -65453, -65455,
- -65458, -65460, -65463, -65465, -65467, -65470, -65472, -65474,
- -65476, -65478, -65480, -65482, -65484, -65486, -65488, -65490,
- -65492, -65494, -65496, -65497, -65499, -65501, -65502, -65504,
- -65505, -65507, -65508, -65510, -65511, -65513, -65514, -65515,
- -65516, -65518, -65519, -65520, -65521, -65522, -65523, -65524,
- -65525, -65526, -65527, -65527, -65528, -65529, -65530, -65530,
+ 65536, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
+ 65534, 65534, 65534, 65533, 65533, 65532, 65532, 65531,
+ 65531, 65530, 65529, 65529, 65528, 65527, 65526, 65525,
+ 65524, 65523, 65522, 65521, 65520, 65519, 65518, 65517,
+ 65516, 65515, 65513, 65512, 65511, 65509, 65508, 65506,
+ 65505, 65503, 65501, 65500, 65498, 65496, 65495, 65493,
+ 65491, 65489, 65487, 65485, 65483, 65481, 65479, 65477,
+ 65475, 65473, 65471, 65468, 65466, 65464, 65461, 65459,
+ 65457, 65454, 65452, 65449, 65446, 65444, 65441, 65438,
+ 65436, 65433, 65430, 65427, 65424, 65421, 65418, 65415,
+ 65412, 65409, 65406, 65403, 65400, 65396, 65393, 65390,
+ 65386, 65383, 65379, 65376, 65372, 65369, 65365, 65362,
+ 65358, 65354, 65350, 65347, 65343, 65339, 65335, 65331,
+ 65327, 65323, 65319, 65315, 65311, 65307, 65302, 65298,
+ 65294, 65290, 65285, 65281, 65276, 65272, 65267, 65263,
+ 65258, 65253, 65249, 65244, 65239, 65235, 65230, 65225,
+ 65220, 65215, 65210, 65205, 65200, 65195, 65190, 65184,
+ 65179, 65174, 65169, 65163, 65158, 65153, 65147, 65142,
+ 65136, 65131, 65125, 65119, 65114, 65108, 65102, 65096,
+ 65091, 65085, 65079, 65073, 65067, 65061, 65055, 65049,
+ 65043, 65036, 65030, 65024, 65018, 65011, 65005, 64999,
+ 64992, 64986, 64979, 64973, 64966, 64959, 64953, 64946,
+ 64939, 64933, 64926, 64919, 64912, 64905, 64898, 64891,
+ 64884, 64877, 64870, 64863, 64855, 64848, 64841, 64834,
+ 64826, 64819, 64811, 64804, 64796, 64789, 64781, 64774,
+ 64766, 64758, 64751, 64743, 64735, 64727, 64719, 64711,
+ 64703, 64695, 64687, 64679, 64671, 64663, 64655, 64646,
+ 64638, 64630, 64622, 64613, 64605, 64596, 64588, 64579,
+ 64571, 64562, 64553, 64545, 64536, 64527, 64518, 64510,
+ 64501, 64492, 64483, 64474, 64465, 64456, 64447, 64437,
+ 64428, 64419, 64410, 64401, 64391, 64382, 64372, 64363,
+ 64353, 64344, 64334, 64325, 64315, 64305, 64296, 64286,
+ 64276, 64266, 64257, 64247, 64237, 64227, 64217, 64207,
+ 64197, 64186, 64176, 64166, 64156, 64146, 64135, 64125,
+ 64115, 64104, 64094, 64083, 64073, 64062, 64051, 64041,
+ 64030, 64019, 64009, 63998, 63987, 63976, 63965, 63954,
+ 63943, 63932, 63921, 63910, 63899, 63888, 63876, 63865,
+ 63854, 63842, 63831, 63820, 63808, 63797, 63785, 63774,
+ 63762, 63750, 63739, 63727, 63715, 63704, 63692, 63680,
+ 63668, 63656, 63644, 63632, 63620, 63608, 63596, 63584,
+ 63571, 63559, 63547, 63535, 63522, 63510, 63498, 63485,
+ 63473, 63460, 63447, 63435, 63422, 63410, 63397, 63384,
+ 63371, 63358, 63346, 63333, 63320, 63307, 63294, 63281,
+ 63268, 63254, 63241, 63228, 63215, 63202, 63188, 63175,
+ 63162, 63148, 63135, 63121, 63108, 63094, 63080, 63067,
+ 63053, 63039, 63026, 63012, 62998, 62984, 62970, 62956,
+ 62942, 62928, 62914, 62900, 62886, 62872, 62858, 62843,
+ 62829, 62815, 62800, 62786, 62772, 62757, 62743, 62728,
+ 62714, 62699, 62684, 62670, 62655, 62640, 62625, 62610,
+ 62596, 62581, 62566, 62551, 62536, 62521, 62506, 62491,
+ 62475, 62460, 62445, 62430, 62414, 62399, 62384, 62368,
+ 62353, 62337, 62322, 62306, 62291, 62275, 62259, 62244,
+ 62228, 62212, 62196, 62180, 62164, 62148, 62133, 62117,
+ 62100, 62084, 62068, 62052, 62036, 62020, 62003, 61987,
+ 61971, 61954, 61938, 61922, 61905, 61889, 61872, 61855,
+ 61839, 61822, 61805, 61789, 61772, 61755, 61738, 61721,
+ 61705, 61688, 61671, 61654, 61637, 61619, 61602, 61585,
+ 61568, 61551, 61533, 61516, 61499, 61481, 61464, 61446,
+ 61429, 61411, 61394, 61376, 61359, 61341, 61323, 61305,
+ 61288, 61270, 61252, 61234, 61216, 61198, 61180, 61162,
+ 61144, 61126, 61108, 61090, 61071, 61053, 61035, 61017,
+ 60998, 60980, 60961, 60943, 60924, 60906, 60887, 60869,
+ 60850, 60831, 60813, 60794, 60775, 60756, 60737, 60719,
+ 60700, 60681, 60662, 60643, 60624, 60604, 60585, 60566,
+ 60547, 60528, 60508, 60489, 60470, 60450, 60431, 60411,
+ 60392, 60372, 60353, 60333, 60313, 60294, 60274, 60254,
+ 60235, 60215, 60195, 60175, 60155, 60135, 60115, 60095,
+ 60075, 60055, 60035, 60015, 59994, 59974, 59954, 59934,
+ 59913, 59893, 59872, 59852, 59831, 59811, 59790, 59770,
+ 59749, 59728, 59708, 59687, 59666, 59645, 59625, 59604,
+ 59583, 59562, 59541, 59520, 59499, 59478, 59457, 59435,
+ 59414, 59393, 59372, 59350, 59329, 59308, 59286, 59265,
+ 59243, 59222, 59200, 59179, 59157, 59135, 59114, 59092,
+ 59070, 59049, 59027, 59005, 58983, 58961, 58939, 58917,
+ 58895, 58873, 58851, 58829, 58807, 58784, 58762, 58740,
+ 58718, 58695, 58673, 58650, 58628, 58605, 58583, 58560,
+ 58538, 58515, 58493, 58470, 58447, 58424, 58402, 58379,
+ 58356, 58333, 58310, 58287, 58264, 58241, 58218, 58195,
+ 58172, 58149, 58125, 58102, 58079, 58056, 58032, 58009,
+ 57986, 57962, 57939, 57915, 57892, 57868, 57844, 57821,
+ 57797, 57773, 57750, 57726, 57702, 57678, 57654, 57630,
+ 57606, 57582, 57558, 57534, 57510, 57486, 57462, 57438,
+ 57414, 57389, 57365, 57341, 57316, 57292, 57268, 57243,
+ 57219, 57194, 57170, 57145, 57120, 57096, 57071, 57046,
+ 57022, 56997, 56972, 56947, 56922, 56897, 56872, 56847,
+ 56822, 56797, 56772, 56747, 56722, 56697, 56671, 56646,
+ 56621, 56595, 56570, 56545, 56519, 56494, 56468, 56443,
+ 56417, 56392, 56366, 56340, 56315, 56289, 56263, 56237,
+ 56212, 56186, 56160, 56134, 56108, 56082, 56056, 56030,
+ 56004, 55978, 55952, 55925, 55899, 55873, 55847, 55820,
+ 55794, 55768, 55741, 55715, 55688, 55662, 55635, 55609,
+ 55582, 55555, 55529, 55502, 55475, 55448, 55422, 55395,
+ 55368, 55341, 55314, 55287, 55260, 55233, 55206, 55179,
+ 55152, 55124, 55097, 55070, 55043, 55015, 54988, 54961,
+ 54933, 54906, 54879, 54851, 54823, 54796, 54768, 54741,
+ 54713, 54685, 54658, 54630, 54602, 54574, 54546, 54519,
+ 54491, 54463, 54435, 54407, 54379, 54351, 54323, 54294,
+ 54266, 54238, 54210, 54182, 54153, 54125, 54097, 54068,
+ 54040, 54011, 53983, 53954, 53926, 53897, 53869, 53840,
+ 53811, 53783, 53754, 53725, 53696, 53667, 53639, 53610,
+ 53581, 53552, 53523, 53494, 53465, 53436, 53407, 53377,
+ 53348, 53319, 53290, 53260, 53231, 53202, 53172, 53143,
+ 53114, 53084, 53055, 53025, 52996, 52966, 52936, 52907,
+ 52877, 52847, 52818, 52788, 52758, 52728, 52698, 52668,
+ 52639, 52609, 52579, 52549, 52518, 52488, 52458, 52428,
+ 52398, 52368, 52338, 52307, 52277, 52247, 52216, 52186,
+ 52155, 52125, 52095, 52064, 52033, 52003, 51972, 51942,
+ 51911, 51880, 51850, 51819, 51788, 51757, 51726, 51695,
+ 51665, 51634, 51603, 51572, 51541, 51510, 51478, 51447,
+ 51416, 51385, 51354, 51323, 51291, 51260, 51229, 51197,
+ 51166, 51134, 51103, 51072, 51040, 51008, 50977, 50945,
+ 50914, 50882, 50850, 50819, 50787, 50755, 50723, 50691,
+ 50660, 50628, 50596, 50564, 50532, 50500, 50468, 50436,
+ 50403, 50371, 50339, 50307, 50275, 50242, 50210, 50178,
+ 50146, 50113, 50081, 50048, 50016, 49983, 49951, 49918,
+ 49886, 49853, 49820, 49788, 49755, 49722, 49690, 49657,
+ 49624, 49591, 49558, 49525, 49492, 49459, 49426, 49393,
+ 49360, 49327, 49294, 49261, 49228, 49195, 49161, 49128,
+ 49095, 49062, 49028, 48995, 48961, 48928, 48895, 48861,
+ 48828, 48794, 48760, 48727, 48693, 48660, 48626, 48592,
+ 48558, 48525, 48491, 48457, 48423, 48389, 48355, 48321,
+ 48288, 48254, 48219, 48185, 48151, 48117, 48083, 48049,
+ 48015, 47981, 47946, 47912, 47878, 47843, 47809, 47775,
+ 47740, 47706, 47671, 47637, 47602, 47568, 47533, 47498,
+ 47464, 47429, 47394, 47360, 47325, 47290, 47255, 47220,
+ 47186, 47151, 47116, 47081, 47046, 47011, 46976, 46941,
+ 46906, 46871, 46835, 46800, 46765, 46730, 46695, 46659,
+ 46624, 46589, 46553, 46518, 46482, 46447, 46411, 46376,
+ 46340, 46305, 46269, 46234, 46198, 46162, 46127, 46091,
+ 46055, 46019, 45984, 45948, 45912, 45876, 45840, 45804,
+ 45768, 45732, 45696, 45660, 45624, 45588, 45552, 45516,
+ 45480, 45443, 45407, 45371, 45335, 45298, 45262, 45226,
+ 45189, 45153, 45116, 45080, 45043, 45007, 44970, 44934,
+ 44897, 44861, 44824, 44787, 44750, 44714, 44677, 44640,
+ 44603, 44567, 44530, 44493, 44456, 44419, 44382, 44345,
+ 44308, 44271, 44234, 44197, 44160, 44122, 44085, 44048,
+ 44011, 43974, 43936, 43899, 43862, 43824, 43787, 43749,
+ 43712, 43675, 43637, 43600, 43562, 43524, 43487, 43449,
+ 43412, 43374, 43336, 43298, 43261, 43223, 43185, 43147,
+ 43110, 43072, 43034, 42996, 42958, 42920, 42882, 42844,
+ 42806, 42768, 42730, 42692, 42653, 42615, 42577, 42539,
+ 42501, 42462, 42424, 42386, 42347, 42309, 42271, 42232,
+ 42194, 42155, 42117, 42078, 42040, 42001, 41962, 41924,
+ 41885, 41846, 41808, 41769, 41730, 41692, 41653, 41614,
+ 41575, 41536, 41497, 41458, 41419, 41381, 41342, 41303,
+ 41263, 41224, 41185, 41146, 41107, 41068, 41029, 40990,
+ 40950, 40911, 40872, 40832, 40793, 40754, 40714, 40675,
+ 40636, 40596, 40557, 40517, 40478, 40438, 40399, 40359,
+ 40319, 40280, 40240, 40200, 40161, 40121, 40081, 40041,
+ 40002, 39962, 39922, 39882, 39842, 39802, 39762, 39722,
+ 39682, 39642, 39602, 39562, 39522, 39482, 39442, 39402,
+ 39362, 39321, 39281, 39241, 39201, 39160, 39120, 39080,
+ 39039, 38999, 38958, 38918, 38878, 38837, 38797, 38756,
+ 38716, 38675, 38634, 38594, 38553, 38512, 38472, 38431,
+ 38390, 38350, 38309, 38268, 38227, 38186, 38146, 38105,
+ 38064, 38023, 37982, 37941, 37900, 37859, 37818, 37777,
+ 37736, 37695, 37653, 37612, 37571, 37530, 37489, 37447,
+ 37406, 37365, 37324, 37282, 37241, 37200, 37158, 37117,
+ 37075, 37034, 36992, 36951, 36909, 36868, 36826, 36785,
+ 36743, 36701, 36660, 36618, 36576, 36535, 36493, 36451,
+ 36409, 36368, 36326, 36284, 36242, 36200, 36158, 36116,
+ 36074, 36032, 35990, 35948, 35906, 35864, 35822, 35780,
+ 35738, 35696, 35654, 35611, 35569, 35527, 35485, 35442,
+ 35400, 35358, 35316, 35273, 35231, 35188, 35146, 35104,
+ 35061, 35019, 34976, 34934, 34891, 34849, 34806, 34763,
+ 34721, 34678, 34635, 34593, 34550, 34507, 34465, 34422,
+ 34379, 34336, 34293, 34251, 34208, 34165, 34122, 34079,
+ 34036, 33993, 33950, 33907, 33864, 33821, 33778, 33735,
+ 33692, 33649, 33605, 33562, 33519, 33476, 33433, 33389,
+ 33346, 33303, 33260, 33216, 33173, 33130, 33086, 33043,
+ 32999, 32956, 32912, 32869, 32826, 32782, 32738, 32695,
+ 32651, 32608, 32564, 32521, 32477, 32433, 32390, 32346,
+ 32302, 32258, 32215, 32171, 32127, 32083, 32039, 31995,
+ 31952, 31908, 31864, 31820, 31776, 31732, 31688, 31644,
+ 31600, 31556, 31512, 31468, 31424, 31379, 31335, 31291,
+ 31247, 31203, 31159, 31114, 31070, 31026, 30982, 30937,
+ 30893, 30849, 30804, 30760, 30715, 30671, 30627, 30582,
+ 30538, 30493, 30449, 30404, 30360, 30315, 30271, 30226,
+ 30181, 30137, 30092, 30047, 30003, 29958, 29913, 29869,
+ 29824, 29779, 29734, 29690, 29645, 29600, 29555, 29510,
+ 29465, 29420, 29375, 29330, 29285, 29241, 29196, 29151,
+ 29105, 29060, 29015, 28970, 28925, 28880, 28835, 28790,
+ 28745, 28699, 28654, 28609, 28564, 28519, 28473, 28428,
+ 28383, 28337, 28292, 28247, 28201, 28156, 28111, 28065,
+ 28020, 27974, 27929, 27883, 27838, 27792, 27747, 27701,
+ 27656, 27610, 27565, 27519, 27473, 27428, 27382, 27336,
+ 27291, 27245, 27199, 27153, 27108, 27062, 27016, 26970,
+ 26925, 26879, 26833, 26787, 26741, 26695, 26649, 26603,
+ 26557, 26511, 26465, 26419, 26373, 26327, 26281, 26235,
+ 26189, 26143, 26097, 26051, 26005, 25959, 25913, 25866,
+ 25820, 25774, 25728, 25681, 25635, 25589, 25543, 25496,
+ 25450, 25404, 25357, 25311, 25265, 25218, 25172, 25125,
+ 25079, 25033, 24986, 24940, 24893, 24847, 24800, 24754,
+ 24707, 24660, 24614, 24567, 24521, 24474, 24427, 24381,
+ 24334, 24287, 24241, 24194, 24147, 24101, 24054, 24007,
+ 23960, 23914, 23867, 23820, 23773, 23726, 23679, 23632,
+ 23586, 23539, 23492, 23445, 23398, 23351, 23304, 23257,
+ 23210, 23163, 23116, 23069, 23022, 22975, 22928, 22881,
+ 22833, 22786, 22739, 22692, 22645, 22598, 22551, 22503,
+ 22456, 22409, 22362, 22314, 22267, 22220, 22173, 22125,
+ 22078, 22031, 21983, 21936, 21889, 21841, 21794, 21746,
+ 21699, 21651, 21604, 21557, 21509, 21462, 21414, 21367,
+ 21319, 21271, 21224, 21176, 21129, 21081, 21034, 20986,
+ 20938, 20891, 20843, 20795, 20748, 20700, 20652, 20605,
+ 20557, 20509, 20461, 20414, 20366, 20318, 20270, 20223,
+ 20175, 20127, 20079, 20031, 19983, 19935, 19888, 19840,
+ 19792, 19744, 19696, 19648, 19600, 19552, 19504, 19456,
+ 19408, 19360, 19312, 19264, 19216, 19168, 19120, 19072,
+ 19024, 18975, 18927, 18879, 18831, 18783, 18735, 18687,
+ 18638, 18590, 18542, 18494, 18446, 18397, 18349, 18301,
+ 18253, 18204, 18156, 18108, 18059, 18011, 17963, 17914,
+ 17866, 17818, 17769, 17721, 17672, 17624, 17576, 17527,
+ 17479, 17430, 17382, 17333, 17285, 17236, 17188, 17139,
+ 17091, 17042, 16994, 16945, 16897, 16848, 16800, 16751,
+ 16702, 16654, 16605, 16557, 16508, 16459, 16411, 16362,
+ 16313, 16265, 16216, 16167, 16118, 16070, 16021, 15972,
+ 15923, 15875, 15826, 15777, 15728, 15680, 15631, 15582,
+ 15533, 15484, 15435, 15387, 15338, 15289, 15240, 15191,
+ 15142, 15093, 15044, 14995, 14946, 14897, 14849, 14800,
+ 14751, 14702, 14653, 14604, 14555, 14506, 14457, 14408,
+ 14359, 14309, 14260, 14211, 14162, 14113, 14064, 14015,
+ 13966, 13917, 13868, 13819, 13769, 13720, 13671, 13622,
+ 13573, 13524, 13474, 13425, 13376, 13327, 13278, 13228,
+ 13179, 13130, 13081, 13031, 12982, 12933, 12884, 12834,
+ 12785, 12736, 12686, 12637, 12588, 12538, 12489, 12440,
+ 12390, 12341, 12292, 12242, 12193, 12143, 12094, 12045,
+ 11995, 11946, 11896, 11847, 11797, 11748, 11699, 11649,
+ 11600, 11550, 11501, 11451, 11402, 11352, 11303, 11253,
+ 11204, 11154, 11105, 11055, 11006, 10956, 10906, 10857,
+ 10807, 10758, 10708, 10658, 10609, 10559, 10510, 10460,
+ 10410, 10361, 10311, 10262, 10212, 10162, 10113, 10063,
+ 10013, 9964, 9914, 9864, 9814, 9765, 9715, 9665,
+ 9616, 9566, 9516, 9466, 9417, 9367, 9317, 9267,
+ 9218, 9168, 9118, 9068, 9019, 8969, 8919, 8869,
+ 8819, 8770, 8720, 8670, 8620, 8570, 8520, 8471,
+ 8421, 8371, 8321, 8271, 8221, 8171, 8122, 8072,
+ 8022, 7972, 7922, 7872, 7822, 7772, 7722, 7672,
+ 7623, 7573, 7523, 7473, 7423, 7373, 7323, 7273,
+ 7223, 7173, 7123, 7073, 7023, 6973, 6923, 6873,
+ 6823, 6773, 6723, 6673, 6623, 6573, 6523, 6473,
+ 6423, 6373, 6323, 6273, 6223, 6173, 6123, 6073,
+ 6023, 5973, 5923, 5873, 5823, 5773, 5722, 5672,
+ 5622, 5572, 5522, 5472, 5422, 5372, 5322, 5272,
+ 5222, 5171, 5121, 5071, 5021, 4971, 4921, 4871,
+ 4821, 4770, 4720, 4670, 4620, 4570, 4520, 4470,
+ 4420, 4369, 4319, 4269, 4219, 4169, 4119, 4068,
+ 4018, 3968, 3918, 3868, 3818, 3767, 3717, 3667,
+ 3617, 3567, 3516, 3466, 3416, 3366, 3316, 3265,
+ 3215, 3165, 3115, 3065, 3014, 2964, 2914, 2864,
+ 2814, 2763, 2713, 2663, 2613, 2562, 2512, 2462,
+ 2412, 2361, 2311, 2261, 2211, 2161, 2110, 2060,
+ 2010, 1960, 1909, 1859, 1809, 1759, 1708, 1658,
+ 1608, 1558, 1507, 1457, 1407, 1357, 1306, 1256,
+ 1206, 1156, 1105, 1055, 1005, 955, 904, 854,
+ 804, 753, 703, 653, 603, 552, 502, 452,
+ 402, 351, 301, 251, 201, 150, 100, 50,
+ 0, -50, -100, -150, -201, -251, -301, -351,
+ -402, -452, -502, -552, -603, -653, -703, -753,
+ -804, -854, -904, -955, -1005, -1055, -1105, -1156,
+ -1206, -1256, -1306, -1357, -1407, -1457, -1507, -1558,
+ -1608, -1658, -1708, -1759, -1809, -1859, -1909, -1960,
+ -2010, -2060, -2110, -2161, -2211, -2261, -2311, -2361,
+ -2412, -2462, -2512, -2562, -2613, -2663, -2713, -2763,
+ -2814, -2864, -2914, -2964, -3014, -3065, -3115, -3165,
+ -3215, -3265, -3316, -3366, -3416, -3466, -3516, -3567,
+ -3617, -3667, -3717, -3767, -3818, -3868, -3918, -3968,
+ -4018, -4068, -4119, -4169, -4219, -4269, -4319, -4369,
+ -4420, -4470, -4520, -4570, -4620, -4670, -4720, -4770,
+ -4821, -4871, -4921, -4971, -5021, -5071, -5121, -5171,
+ -5222, -5272, -5322, -5372, -5422, -5472, -5522, -5572,
+ -5622, -5672, -5722, -5773, -5823, -5873, -5923, -5973,
+ -6023, -6073, -6123, -6173, -6223, -6273, -6323, -6373,
+ -6423, -6473, -6523, -6573, -6623, -6673, -6723, -6773,
+ -6823, -6873, -6923, -6973, -7023, -7073, -7123, -7173,
+ -7223, -7273, -7323, -7373, -7423, -7473, -7523, -7573,
+ -7623, -7672, -7722, -7772, -7822, -7872, -7922, -7972,
+ -8022, -8072, -8122, -8171, -8221, -8271, -8321, -8371,
+ -8421, -8471, -8520, -8570, -8620, -8670, -8720, -8770,
+ -8819, -8869, -8919, -8969, -9019, -9068, -9118, -9168,
+ -9218, -9267, -9317, -9367, -9417, -9466, -9516, -9566,
+ -9616, -9665, -9715, -9765, -9814, -9864, -9914, -9964,
+ -10013, -10063, -10113, -10162, -10212, -10262, -10311, -10361,
+ -10410, -10460, -10510, -10559, -10609, -10658, -10708, -10758,
+ -10807, -10857, -10906, -10956, -11006, -11055, -11105, -11154,
+ -11204, -11253, -11303, -11352, -11402, -11451, -11501, -11550,
+ -11600, -11649, -11699, -11748, -11797, -11847, -11896, -11946,
+ -11995, -12045, -12094, -12143, -12193, -12242, -12292, -12341,
+ -12390, -12440, -12489, -12538, -12588, -12637, -12686, -12736,
+ -12785, -12834, -12884, -12933, -12982, -13031, -13081, -13130,
+ -13179, -13228, -13278, -13327, -13376, -13425, -13474, -13524,
+ -13573, -13622, -13671, -13720, -13769, -13819, -13868, -13917,
+ -13966, -14015, -14064, -14113, -14162, -14211, -14260, -14309,
+ -14359, -14408, -14457, -14506, -14555, -14604, -14653, -14702,
+ -14751, -14800, -14849, -14897, -14946, -14995, -15044, -15093,
+ -15142, -15191, -15240, -15289, -15338, -15387, -15435, -15484,
+ -15533, -15582, -15631, -15680, -15728, -15777, -15826, -15875,
+ -15923, -15972, -16021, -16070, -16118, -16167, -16216, -16265,
+ -16313, -16362, -16411, -16459, -16508, -16557, -16605, -16654,
+ -16702, -16751, -16800, -16848, -16897, -16945, -16994, -17042,
+ -17091, -17139, -17188, -17236, -17285, -17333, -17382, -17430,
+ -17479, -17527, -17576, -17624, -17672, -17721, -17769, -17818,
+ -17866, -17914, -17963, -18011, -18059, -18108, -18156, -18204,
+ -18253, -18301, -18349, -18397, -18446, -18494, -18542, -18590,
+ -18638, -18687, -18735, -18783, -18831, -18879, -18927, -18975,
+ -19024, -19072, -19120, -19168, -19216, -19264, -19312, -19360,
+ -19408, -19456, -19504, -19552, -19600, -19648, -19696, -19744,
+ -19792, -19840, -19888, -19935, -19983, -20031, -20079, -20127,
+ -20175, -20223, -20270, -20318, -20366, -20414, -20461, -20509,
+ -20557, -20605, -20652, -20700, -20748, -20795, -20843, -20891,
+ -20938, -20986, -21034, -21081, -21129, -21176, -21224, -21271,
+ -21319, -21367, -21414, -21462, -21509, -21557, -21604, -21651,
+ -21699, -21746, -21794, -21841, -21889, -21936, -21983, -22031,
+ -22078, -22125, -22173, -22220, -22267, -22314, -22362, -22409,
+ -22456, -22503, -22551, -22598, -22645, -22692, -22739, -22786,
+ -22833, -22881, -22928, -22975, -23022, -23069, -23116, -23163,
+ -23210, -23257, -23304, -23351, -23398, -23445, -23492, -23539,
+ -23586, -23632, -23679, -23726, -23773, -23820, -23867, -23914,
+ -23960, -24007, -24054, -24101, -24147, -24194, -24241, -24287,
+ -24334, -24381, -24427, -24474, -24521, -24567, -24614, -24660,
+ -24707, -24754, -24800, -24847, -24893, -24940, -24986, -25033,
+ -25079, -25125, -25172, -25218, -25265, -25311, -25357, -25404,
+ -25450, -25496, -25543, -25589, -25635, -25681, -25728, -25774,
+ -25820, -25866, -25913, -25959, -26005, -26051, -26097, -26143,
+ -26189, -26235, -26281, -26327, -26373, -26419, -26465, -26511,
+ -26557, -26603, -26649, -26695, -26741, -26787, -26833, -26879,
+ -26925, -26970, -27016, -27062, -27108, -27153, -27199, -27245,
+ -27291, -27336, -27382, -27428, -27473, -27519, -27565, -27610,
+ -27656, -27701, -27747, -27792, -27838, -27883, -27929, -27974,
+ -28020, -28065, -28111, -28156, -28201, -28247, -28292, -28337,
+ -28383, -28428, -28473, -28519, -28564, -28609, -28654, -28699,
+ -28745, -28790, -28835, -28880, -28925, -28970, -29015, -29060,
+ -29105, -29151, -29196, -29241, -29285, -29330, -29375, -29420,
+ -29465, -29510, -29555, -29600, -29645, -29690, -29734, -29779,
+ -29824, -29869, -29913, -29958, -30003, -30047, -30092, -30137,
+ -30181, -30226, -30271, -30315, -30360, -30404, -30449, -30493,
+ -30538, -30582, -30627, -30671, -30715, -30760, -30804, -30849,
+ -30893, -30937, -30982, -31026, -31070, -31114, -31159, -31203,
+ -31247, -31291, -31335, -31379, -31424, -31468, -31512, -31556,
+ -31600, -31644, -31688, -31732, -31776, -31820, -31864, -31908,
+ -31952, -31995, -32039, -32083, -32127, -32171, -32215, -32258,
+ -32302, -32346, -32390, -32433, -32477, -32521, -32564, -32608,
+ -32651, -32695, -32738, -32782, -32826, -32869, -32912, -32956,
+ -32999, -33043, -33086, -33130, -33173, -33216, -33260, -33303,
+ -33346, -33389, -33433, -33476, -33519, -33562, -33605, -33649,
+ -33692, -33735, -33778, -33821, -33864, -33907, -33950, -33993,
+ -34036, -34079, -34122, -34165, -34208, -34251, -34293, -34336,
+ -34379, -34422, -34465, -34507, -34550, -34593, -34635, -34678,
+ -34721, -34763, -34806, -34849, -34891, -34934, -34976, -35019,
+ -35061, -35104, -35146, -35188, -35231, -35273, -35316, -35358,
+ -35400, -35442, -35485, -35527, -35569, -35611, -35654, -35696,
+ -35738, -35780, -35822, -35864, -35906, -35948, -35990, -36032,
+ -36074, -36116, -36158, -36200, -36242, -36284, -36326, -36368,
+ -36409, -36451, -36493, -36535, -36576, -36618, -36660, -36701,
+ -36743, -36785, -36826, -36868, -36909, -36951, -36992, -37034,
+ -37075, -37117, -37158, -37200, -37241, -37282, -37324, -37365,
+ -37406, -37447, -37489, -37530, -37571, -37612, -37653, -37695,
+ -37736, -37777, -37818, -37859, -37900, -37941, -37982, -38023,
+ -38064, -38105, -38146, -38186, -38227, -38268, -38309, -38350,
+ -38390, -38431, -38472, -38512, -38553, -38594, -38634, -38675,
+ -38716, -38756, -38797, -38837, -38878, -38918, -38958, -38999,
+ -39039, -39080, -39120, -39160, -39201, -39241, -39281, -39321,
+ -39362, -39402, -39442, -39482, -39522, -39562, -39602, -39642,
+ -39682, -39722, -39762, -39802, -39842, -39882, -39922, -39962,
+ -40002, -40041, -40081, -40121, -40161, -40200, -40240, -40280,
+ -40319, -40359, -40399, -40438, -40478, -40517, -40557, -40596,
+ -40636, -40675, -40714, -40754, -40793, -40832, -40872, -40911,
+ -40950, -40990, -41029, -41068, -41107, -41146, -41185, -41224,
+ -41263, -41303, -41342, -41381, -41419, -41458, -41497, -41536,
+ -41575, -41614, -41653, -41692, -41730, -41769, -41808, -41846,
+ -41885, -41924, -41962, -42001, -42040, -42078, -42117, -42155,
+ -42194, -42232, -42271, -42309, -42347, -42386, -42424, -42462,
+ -42501, -42539, -42577, -42615, -42653, -42692, -42730, -42768,
+ -42806, -42844, -42882, -42920, -42958, -42996, -43034, -43072,
+ -43110, -43147, -43185, -43223, -43261, -43298, -43336, -43374,
+ -43412, -43449, -43487, -43524, -43562, -43600, -43637, -43675,
+ -43712, -43749, -43787, -43824, -43862, -43899, -43936, -43974,
+ -44011, -44048, -44085, -44122, -44160, -44197, -44234, -44271,
+ -44308, -44345, -44382, -44419, -44456, -44493, -44530, -44567,
+ -44603, -44640, -44677, -44714, -44750, -44787, -44824, -44861,
+ -44897, -44934, -44970, -45007, -45043, -45080, -45116, -45153,
+ -45189, -45226, -45262, -45298, -45335, -45371, -45407, -45443,
+ -45480, -45516, -45552, -45588, -45624, -45660, -45696, -45732,
+ -45768, -45804, -45840, -45876, -45912, -45948, -45984, -46019,
+ -46055, -46091, -46127, -46162, -46198, -46234, -46269, -46305,
+ -46340, -46376, -46411, -46447, -46482, -46518, -46553, -46589,
+ -46624, -46659, -46695, -46730, -46765, -46800, -46835, -46871,
+ -46906, -46941, -46976, -47011, -47046, -47081, -47116, -47151,
+ -47186, -47220, -47255, -47290, -47325, -47360, -47394, -47429,
+ -47464, -47498, -47533, -47568, -47602, -47637, -47671, -47706,
+ -47740, -47775, -47809, -47843, -47878, -47912, -47946, -47981,
+ -48015, -48049, -48083, -48117, -48151, -48185, -48219, -48254,
+ -48288, -48321, -48355, -48389, -48423, -48457, -48491, -48525,
+ -48558, -48592, -48626, -48660, -48693, -48727, -48760, -48794,
+ -48828, -48861, -48895, -48928, -48961, -48995, -49028, -49062,
+ -49095, -49128, -49161, -49195, -49228, -49261, -49294, -49327,
+ -49360, -49393, -49426, -49459, -49492, -49525, -49558, -49591,
+ -49624, -49657, -49690, -49722, -49755, -49788, -49820, -49853,
+ -49886, -49918, -49951, -49983, -50016, -50048, -50081, -50113,
+ -50146, -50178, -50210, -50242, -50275, -50307, -50339, -50371,
+ -50403, -50436, -50468, -50500, -50532, -50564, -50596, -50628,
+ -50660, -50691, -50723, -50755, -50787, -50819, -50850, -50882,
+ -50914, -50945, -50977, -51008, -51040, -51072, -51103, -51134,
+ -51166, -51197, -51229, -51260, -51291, -51323, -51354, -51385,
+ -51416, -51447, -51478, -51510, -51541, -51572, -51603, -51634,
+ -51665, -51695, -51726, -51757, -51788, -51819, -51850, -51880,
+ -51911, -51942, -51972, -52003, -52033, -52064, -52095, -52125,
+ -52155, -52186, -52216, -52247, -52277, -52307, -52338, -52368,
+ -52398, -52428, -52458, -52488, -52518, -52549, -52579, -52609,
+ -52639, -52668, -52698, -52728, -52758, -52788, -52818, -52847,
+ -52877, -52907, -52936, -52966, -52996, -53025, -53055, -53084,
+ -53114, -53143, -53172, -53202, -53231, -53260, -53290, -53319,
+ -53348, -53377, -53407, -53436, -53465, -53494, -53523, -53552,
+ -53581, -53610, -53639, -53667, -53696, -53725, -53754, -53783,
+ -53811, -53840, -53869, -53897, -53926, -53954, -53983, -54011,
+ -54040, -54068, -54097, -54125, -54153, -54182, -54210, -54238,
+ -54266, -54294, -54323, -54351, -54379, -54407, -54435, -54463,
+ -54491, -54519, -54546, -54574, -54602, -54630, -54658, -54685,
+ -54713, -54741, -54768, -54796, -54823, -54851, -54879, -54906,
+ -54933, -54961, -54988, -55015, -55043, -55070, -55097, -55124,
+ -55152, -55179, -55206, -55233, -55260, -55287, -55314, -55341,
+ -55368, -55395, -55422, -55448, -55475, -55502, -55529, -55555,
+ -55582, -55609, -55635, -55662, -55688, -55715, -55741, -55768,
+ -55794, -55820, -55847, -55873, -55899, -55925, -55952, -55978,
+ -56004, -56030, -56056, -56082, -56108, -56134, -56160, -56186,
+ -56212, -56237, -56263, -56289, -56315, -56340, -56366, -56392,
+ -56417, -56443, -56468, -56494, -56519, -56545, -56570, -56595,
+ -56621, -56646, -56671, -56697, -56722, -56747, -56772, -56797,
+ -56822, -56847, -56872, -56897, -56922, -56947, -56972, -56997,
+ -57022, -57046, -57071, -57096, -57120, -57145, -57170, -57194,
+ -57219, -57243, -57268, -57292, -57316, -57341, -57365, -57389,
+ -57414, -57438, -57462, -57486, -57510, -57534, -57558, -57582,
+ -57606, -57630, -57654, -57678, -57702, -57726, -57750, -57773,
+ -57797, -57821, -57844, -57868, -57892, -57915, -57939, -57962,
+ -57986, -58009, -58032, -58056, -58079, -58102, -58125, -58149,
+ -58172, -58195, -58218, -58241, -58264, -58287, -58310, -58333,
+ -58356, -58379, -58402, -58424, -58447, -58470, -58493, -58515,
+ -58538, -58560, -58583, -58605, -58628, -58650, -58673, -58695,
+ -58718, -58740, -58762, -58784, -58807, -58829, -58851, -58873,
+ -58895, -58917, -58939, -58961, -58983, -59005, -59027, -59049,
+ -59070, -59092, -59114, -59135, -59157, -59179, -59200, -59222,
+ -59243, -59265, -59286, -59308, -59329, -59350, -59372, -59393,
+ -59414, -59435, -59457, -59478, -59499, -59520, -59541, -59562,
+ -59583, -59604, -59625, -59645, -59666, -59687, -59708, -59728,
+ -59749, -59770, -59790, -59811, -59831, -59852, -59872, -59893,
+ -59913, -59934, -59954, -59974, -59994, -60015, -60035, -60055,
+ -60075, -60095, -60115, -60135, -60155, -60175, -60195, -60215,
+ -60235, -60254, -60274, -60294, -60313, -60333, -60353, -60372,
+ -60392, -60411, -60431, -60450, -60470, -60489, -60508, -60528,
+ -60547, -60566, -60585, -60604, -60624, -60643, -60662, -60681,
+ -60700, -60719, -60737, -60756, -60775, -60794, -60813, -60831,
+ -60850, -60869, -60887, -60906, -60924, -60943, -60961, -60980,
+ -60998, -61017, -61035, -61053, -61071, -61090, -61108, -61126,
+ -61144, -61162, -61180, -61198, -61216, -61234, -61252, -61270,
+ -61288, -61305, -61323, -61341, -61359, -61376, -61394, -61411,
+ -61429, -61446, -61464, -61481, -61499, -61516, -61533, -61551,
+ -61568, -61585, -61602, -61619, -61637, -61654, -61671, -61688,
+ -61705, -61721, -61738, -61755, -61772, -61789, -61805, -61822,
+ -61839, -61855, -61872, -61889, -61905, -61922, -61938, -61954,
+ -61971, -61987, -62003, -62020, -62036, -62052, -62068, -62084,
+ -62100, -62117, -62133, -62148, -62164, -62180, -62196, -62212,
+ -62228, -62244, -62259, -62275, -62291, -62306, -62322, -62337,
+ -62353, -62368, -62384, -62399, -62414, -62430, -62445, -62460,
+ -62475, -62491, -62506, -62521, -62536, -62551, -62566, -62581,
+ -62596, -62610, -62625, -62640, -62655, -62670, -62684, -62699,
+ -62714, -62728, -62743, -62757, -62772, -62786, -62800, -62815,
+ -62829, -62843, -62858, -62872, -62886, -62900, -62914, -62928,
+ -62942, -62956, -62970, -62984, -62998, -63012, -63026, -63039,
+ -63053, -63067, -63080, -63094, -63108, -63121, -63135, -63148,
+ -63162, -63175, -63188, -63202, -63215, -63228, -63241, -63254,
+ -63268, -63281, -63294, -63307, -63320, -63333, -63346, -63358,
+ -63371, -63384, -63397, -63410, -63422, -63435, -63447, -63460,
+ -63473, -63485, -63498, -63510, -63522, -63535, -63547, -63559,
+ -63571, -63584, -63596, -63608, -63620, -63632, -63644, -63656,
+ -63668, -63680, -63692, -63704, -63715, -63727, -63739, -63750,
+ -63762, -63774, -63785, -63797, -63808, -63820, -63831, -63842,
+ -63854, -63865, -63876, -63888, -63899, -63910, -63921, -63932,
+ -63943, -63954, -63965, -63976, -63987, -63998, -64009, -64019,
+ -64030, -64041, -64051, -64062, -64073, -64083, -64094, -64104,
+ -64115, -64125, -64135, -64146, -64156, -64166, -64176, -64186,
+ -64197, -64207, -64217, -64227, -64237, -64247, -64257, -64266,
+ -64276, -64286, -64296, -64305, -64315, -64325, -64334, -64344,
+ -64353, -64363, -64372, -64382, -64391, -64401, -64410, -64419,
+ -64428, -64437, -64447, -64456, -64465, -64474, -64483, -64492,
+ -64501, -64510, -64518, -64527, -64536, -64545, -64553, -64562,
+ -64571, -64579, -64588, -64596, -64605, -64613, -64622, -64630,
+ -64638, -64646, -64655, -64663, -64671, -64679, -64687, -64695,
+ -64703, -64711, -64719, -64727, -64735, -64743, -64751, -64758,
+ -64766, -64774, -64781, -64789, -64796, -64804, -64811, -64819,
+ -64826, -64834, -64841, -64848, -64855, -64863, -64870, -64877,
+ -64884, -64891, -64898, -64905, -64912, -64919, -64926, -64933,
+ -64939, -64946, -64953, -64959, -64966, -64973, -64979, -64986,
+ -64992, -64999, -65005, -65011, -65018, -65024, -65030, -65036,
+ -65043, -65049, -65055, -65061, -65067, -65073, -65079, -65085,
+ -65091, -65096, -65102, -65108, -65114, -65119, -65125, -65131,
+ -65136, -65142, -65147, -65153, -65158, -65163, -65169, -65174,
+ -65179, -65184, -65190, -65195, -65200, -65205, -65210, -65215,
+ -65220, -65225, -65230, -65235, -65239, -65244, -65249, -65253,
+ -65258, -65263, -65267, -65272, -65276, -65281, -65285, -65290,
+ -65294, -65298, -65302, -65307, -65311, -65315, -65319, -65323,
+ -65327, -65331, -65335, -65339, -65343, -65347, -65350, -65354,
+ -65358, -65362, -65365, -65369, -65372, -65376, -65379, -65383,
+ -65386, -65390, -65393, -65396, -65400, -65403, -65406, -65409,
+ -65412, -65415, -65418, -65421, -65424, -65427, -65430, -65433,
+ -65436, -65438, -65441, -65444, -65446, -65449, -65452, -65454,
+ -65457, -65459, -65461, -65464, -65466, -65468, -65471, -65473,
+ -65475, -65477, -65479, -65481, -65483, -65485, -65487, -65489,
+ -65491, -65493, -65495, -65496, -65498, -65500, -65501, -65503,
+ -65505, -65506, -65508, -65509, -65511, -65512, -65513, -65515,
+ -65516, -65517, -65518, -65519, -65520, -65521, -65522, -65523,
+ -65524, -65525, -65526, -65527, -65528, -65529, -65529, -65530,
-65531, -65531, -65532, -65532, -65533, -65533, -65534, -65534,
-65534, -65535, -65535, -65535, -65535, -65535, -65535, -65535,
- -65535, -65535, -65535, -65535, -65535, -65535, -65535, -65534,
- -65534, -65534, -65533, -65533, -65532, -65532, -65531, -65531,
- -65530, -65530, -65529, -65528, -65527, -65527, -65526, -65525,
- -65524, -65523, -65522, -65521, -65520, -65519, -65518, -65516,
- -65515, -65514, -65513, -65511, -65510, -65508, -65507, -65505,
- -65504, -65502, -65501, -65499, -65497, -65496, -65494, -65492,
- -65490, -65488, -65486, -65484, -65482, -65480, -65478, -65476,
- -65474, -65472, -65470, -65467, -65465, -65463, -65460, -65458,
- -65455, -65453, -65450, -65448, -65445, -65442, -65440, -65437,
- -65434, -65431, -65429, -65426, -65423, -65420, -65417, -65414,
- -65411, -65408, -65404, -65401, -65398, -65395, -65391, -65388,
- -65385, -65381, -65378, -65374, -65371, -65367, -65363, -65360,
- -65356, -65352, -65349, -65345, -65341, -65337, -65333, -65329,
- -65325, -65321, -65317, -65313, -65309, -65305, -65300, -65296,
- -65292, -65287, -65283, -65279, -65274, -65270, -65265, -65260,
- -65256, -65251, -65246, -65242, -65237, -65232, -65227, -65222,
- -65217, -65212, -65207, -65202, -65197, -65192, -65187, -65182,
- -65177, -65171, -65166, -65161, -65155, -65150, -65144, -65139,
- -65133, -65128, -65122, -65117, -65111, -65105, -65099, -65094,
- -65088, -65082, -65076, -65070, -65064, -65058, -65052, -65046,
- -65040, -65033, -65027, -65021, -65015, -65008, -65002, -64995,
- -64989, -64982, -64976, -64969, -64963, -64956, -64949, -64943,
- -64936, -64929, -64922, -64915, -64908, -64902, -64895, -64887,
- -64880, -64873, -64866, -64859, -64852, -64844, -64837, -64830,
- -64822, -64815, -64808, -64800, -64793, -64785, -64777, -64770,
- -64762, -64754, -64747, -64739, -64731, -64723, -64715, -64707,
- -64699, -64691, -64683, -64675, -64667, -64659, -64651, -64642,
- -64634, -64626, -64617, -64609, -64601, -64592, -64584, -64575,
- -64566, -64558, -64549, -64540, -64532, -64523, -64514, -64505,
- -64496, -64487, -64478, -64469, -64460, -64451, -64442, -64433,
- -64424, -64414, -64405, -64396, -64387, -64377, -64368, -64358,
- -64349, -64339, -64330, -64320, -64310, -64301, -64291, -64281,
- -64271, -64261, -64252, -64242, -64232, -64222, -64212, -64202,
- -64192, -64181, -64171, -64161, -64151, -64140, -64130, -64120,
- -64109, -64099, -64088, -64078, -64067, -64057, -64046, -64035,
- -64025, -64014, -64003, -63992, -63981, -63971, -63960, -63949,
- -63938, -63927, -63915, -63904, -63893, -63882, -63871, -63859,
- -63848, -63837, -63825, -63814, -63803, -63791, -63779, -63768,
- -63756, -63745, -63733, -63721, -63709, -63698, -63686, -63674,
- -63662, -63650, -63638, -63626, -63614, -63602, -63590, -63578,
- -63565, -63553, -63541, -63528, -63516, -63504, -63491, -63479,
- -63466, -63454, -63441, -63429, -63416, -63403, -63390, -63378,
- -63365, -63352, -63339, -63326, -63313, -63300, -63287, -63274,
- -63261, -63248, -63235, -63221, -63208, -63195, -63182, -63168,
- -63155, -63141, -63128, -63114, -63101, -63087, -63074, -63060,
- -63046, -63032, -63019, -63005, -62991, -62977, -62963, -62949,
- -62935, -62921, -62907, -62893, -62879, -62865, -62850, -62836,
- -62822, -62808, -62793, -62779, -62764, -62750, -62735, -62721,
- -62706, -62692, -62677, -62662, -62648, -62633, -62618, -62603,
- -62588, -62573, -62558, -62543, -62528, -62513, -62498, -62483,
- -62468, -62453, -62437, -62422, -62407, -62391, -62376, -62360,
- -62345, -62329, -62314, -62298, -62283, -62267, -62251, -62236,
- -62220, -62204, -62188, -62172, -62156, -62141, -62125, -62108,
- -62092, -62076, -62060, -62044, -62028, -62012, -61995, -61979,
- -61963, -61946, -61930, -61913, -61897, -61880, -61864, -61847,
- -61831, -61814, -61797, -61780, -61764, -61747, -61730, -61713,
- -61696, -61679, -61662, -61645, -61628, -61611, -61594, -61577,
- -61559, -61542, -61525, -61507, -61490, -61473, -61455, -61438,
- -61420, -61403, -61385, -61367, -61350, -61332, -61314, -61297,
- -61279, -61261, -61243, -61225, -61207, -61189, -61171, -61153,
- -61135, -61117, -61099, -61081, -61062, -61044, -61026, -61007,
- -60989, -60971, -60952, -60934, -60915, -60897, -60878, -60859,
- -60841, -60822, -60803, -60785, -60766, -60747, -60728, -60709,
- -60690, -60671, -60652, -60633, -60614, -60595, -60576, -60556,
- -60537, -60518, -60499, -60479, -60460, -60441, -60421, -60402,
- -60382, -60363, -60343, -60323, -60304, -60284, -60264, -60244,
- -60225, -60205, -60185, -60165, -60145, -60125, -60105, -60085,
- -60065, -60045, -60025, -60004, -59984, -59964, -59944, -59923,
- -59903, -59883, -59862, -59842, -59821, -59801, -59780, -59759,
- -59739, -59718, -59697, -59677, -59656, -59635, -59614, -59593,
- -59572, -59551, -59530, -59509, -59488, -59467, -59446, -59425,
- -59404, -59382, -59361, -59340, -59318, -59297, -59276, -59254,
- -59233, -59211, -59189, -59168, -59146, -59125, -59103, -59081,
- -59059, -59038, -59016, -58994, -58972, -58950, -58928, -58906,
- -58884, -58862, -58840, -58818, -58795, -58773, -58751, -58729,
- -58706, -58684, -58662, -58639, -58617, -58594, -58572, -58549,
- -58527, -58504, -58481, -58459, -58436, -58413, -58390, -58367,
- -58345, -58322, -58299, -58276, -58253, -58230, -58207, -58183,
- -58160, -58137, -58114, -58091, -58067, -58044, -58021, -57997,
- -57974, -57950, -57927, -57903, -57880, -57856, -57833, -57809,
- -57785, -57762, -57738, -57714, -57690, -57666, -57642, -57618,
- -57594, -57570, -57546, -57522, -57498, -57474, -57450, -57426,
- -57402, -57377, -57353, -57329, -57304, -57280, -57255, -57231,
- -57206, -57182, -57157, -57133, -57108, -57083, -57059, -57034,
- -57009, -56984, -56959, -56935, -56910, -56885, -56860, -56835,
- -56810, -56785, -56760, -56734, -56709, -56684, -56659, -56633,
- -56608, -56583, -56557, -56532, -56507, -56481, -56456, -56430,
- -56404, -56379, -56353, -56328, -56302, -56276, -56250, -56225,
- -56199, -56173, -56147, -56121, -56095, -56069, -56043, -56017,
- -55991, -55965, -55938, -55912, -55886, -55860, -55833, -55807,
- -55781, -55754, -55728, -55701, -55675, -55648, -55622, -55595,
- -55569, -55542, -55515, -55489, -55462, -55435, -55408, -55381,
- -55354, -55327, -55300, -55274, -55246, -55219, -55192, -55165,
- -55138, -55111, -55084, -55056, -55029, -55002, -54974, -54947,
- -54920, -54892, -54865, -54837, -54810, -54782, -54755, -54727,
- -54699, -54672, -54644, -54616, -54588, -54560, -54533, -54505,
- -54477, -54449, -54421, -54393, -54365, -54337, -54308, -54280,
- -54252, -54224, -54196, -54167, -54139, -54111, -54082, -54054,
- -54026, -53997, -53969, -53940, -53911, -53883, -53854, -53826,
- -53797, -53768, -53739, -53711, -53682, -53653, -53624, -53595,
- -53566, -53537, -53508, -53479, -53450, -53421, -53392, -53363,
- -53334, -53304, -53275, -53246, -53216, -53187, -53158, -53128,
- -53099, -53069, -53040, -53010, -52981, -52951, -52922, -52892,
- -52862, -52832, -52803, -52773, -52743, -52713, -52683, -52653,
- -52624, -52594, -52564, -52534, -52503, -52473, -52443, -52413,
- -52383, -52353, -52322, -52292, -52262, -52231, -52201, -52171,
- -52140, -52110, -52079, -52049, -52018, -51988, -51957, -51926,
- -51896, -51865, -51834, -51803, -51773, -51742, -51711, -51680,
- -51649, -51618, -51587, -51556, -51525, -51494, -51463, -51432,
- -51401, -51369, -51338, -51307, -51276, -51244, -51213, -51182,
- -51150, -51119, -51087, -51056, -51024, -50993, -50961, -50929,
- -50898, -50866, -50834, -50803, -50771, -50739, -50707, -50675,
- -50644, -50612, -50580, -50548, -50516, -50484, -50452, -50420,
- -50387, -50355, -50323, -50291, -50259, -50226, -50194, -50162,
- -50129, -50097, -50065, -50032, -50000, -49967, -49935, -49902,
- -49869, -49837, -49804, -49771, -49739, -49706, -49673, -49640,
- -49608, -49575, -49542, -49509, -49476, -49443, -49410, -49377,
- -49344, -49311, -49278, -49244, -49211, -49178, -49145, -49112,
- -49078, -49045, -49012, -48978, -48945, -48911, -48878, -48844,
- -48811, -48777, -48744, -48710, -48676, -48643, -48609, -48575,
- -48542, -48508, -48474, -48440, -48406, -48372, -48338, -48305,
- -48271, -48237, -48202, -48168, -48134, -48100, -48066, -48032,
- -47998, -47963, -47929, -47895, -47860, -47826, -47792, -47757,
- -47723, -47688, -47654, -47619, -47585, -47550, -47516, -47481,
- -47446, -47412, -47377, -47342, -47307, -47273, -47238, -47203,
- -47168, -47133, -47098, -47063, -47028, -46993, -46958, -46923,
- -46888, -46853, -46818, -46783, -46747, -46712, -46677, -46642,
- -46606, -46571, -46536, -46500, -46465, -46429, -46394, -46358,
- -46323, -46287, -46251, -46216, -46180, -46145, -46109, -46073,
- -46037, -46002, -45966, -45930, -45894, -45858, -45822, -45786,
- -45750, -45714, -45678, -45642, -45606, -45570, -45534, -45498,
- -45462, -45425, -45389, -45353, -45316, -45280, -45244, -45207,
- -45171, -45135, -45098, -45062, -45025, -44989, -44952, -44915,
- -44879, -44842, -44806, -44769, -44732, -44695, -44659, -44622,
- -44585, -44548, -44511, -44474, -44437, -44400, -44363, -44326,
- -44289, -44252, -44215, -44178, -44141, -44104, -44067, -44029,
- -43992, -43955, -43918, -43880, -43843, -43806, -43768, -43731,
- -43693, -43656, -43618, -43581, -43543, -43506, -43468, -43430,
- -43393, -43355, -43317, -43280, -43242, -43204, -43166, -43128,
- -43091, -43053, -43015, -42977, -42939, -42901, -42863, -42825,
- -42787, -42749, -42711, -42672, -42634, -42596, -42558, -42520,
- -42481, -42443, -42405, -42366, -42328, -42290, -42251, -42213,
- -42174, -42136, -42097, -42059, -42020, -41982, -41943, -41904,
- -41866, -41827, -41788, -41750, -41711, -41672, -41633, -41595,
- -41556, -41517, -41478, -41439, -41400, -41361, -41322, -41283,
- -41244, -41205, -41166, -41127, -41087, -41048, -41009, -40970,
- -40931, -40891, -40852, -40813, -40773, -40734, -40695, -40655,
- -40616, -40576, -40537, -40497, -40458, -40418, -40379, -40339,
- -40299, -40260, -40220, -40180, -40141, -40101, -40061, -40021,
- -39982, -39942, -39902, -39862, -39822, -39782, -39742, -39702,
- -39662, -39622, -39582, -39542, -39502, -39462, -39422, -39382,
- -39341, -39301, -39261, -39221, -39180, -39140, -39100, -39059,
- -39019, -38979, -38938, -38898, -38857, -38817, -38776, -38736,
- -38695, -38655, -38614, -38573, -38533, -38492, -38451, -38411,
- -38370, -38329, -38288, -38248, -38207, -38166, -38125, -38084,
- -38043, -38002, -37961, -37920, -37879, -37838, -37797, -37756,
- -37715, -37674, -37633, -37592, -37550, -37509, -37468, -37427,
- -37386, -37344, -37303, -37262, -37220, -37179, -37137, -37096,
- -37055, -37013, -36972, -36930, -36889, -36847, -36805, -36764,
- -36722, -36681, -36639, -36597, -36556, -36514, -36472, -36430,
- -36388, -36347, -36305, -36263, -36221, -36179, -36137, -36095,
- -36053, -36011, -35969, -35927, -35885, -35843, -35801, -35759,
- -35717, -35675, -35633, -35590, -35548, -35506, -35464, -35421,
- -35379, -35337, -35294, -35252, -35210, -35167, -35125, -35082,
- -35040, -34997, -34955, -34912, -34870, -34827, -34785, -34742,
- -34699, -34657, -34614, -34571, -34529, -34486, -34443, -34400,
- -34358, -34315, -34272, -34229, -34186, -34143, -34100, -34057,
- -34015, -33972, -33929, -33886, -33843, -33799, -33756, -33713,
- -33670, -33627, -33584, -33541, -33498, -33454, -33411, -33368,
- -33325, -33281, -33238, -33195, -33151, -33108, -33065, -33021,
- -32978, -32934, -32891, -32847, -32804, -32760, -32717, -32673,
- -32630, -32586, -32542, -32499, -32455, -32411, -32368, -32324,
- -32280, -32236, -32193, -32149, -32105, -32061, -32017, -31974,
- -31930, -31886, -31842, -31798, -31754, -31710, -31666, -31622,
- -31578, -31534, -31490, -31446, -31402, -31357, -31313, -31269,
- -31225, -31181, -31136, -31092, -31048, -31004, -30959, -30915,
- -30871, -30826, -30782, -30738, -30693, -30649, -30604, -30560,
- -30515, -30471, -30426, -30382, -30337, -30293, -30248, -30204,
- -30159, -30114, -30070, -30025, -29980, -29936, -29891, -29846,
- -29801, -29757, -29712, -29667, -29622, -29577, -29533, -29488,
- -29443, -29398, -29353, -29308, -29263, -29218, -29173, -29128,
- -29083, -29038, -28993, -28948, -28903, -28858, -28812, -28767,
- -28722, -28677, -28632, -28586, -28541, -28496, -28451, -28405,
- -28360, -28315, -28269, -28224, -28179, -28133, -28088, -28042,
- -27997, -27952, -27906, -27861, -27815, -27770, -27724, -27678,
- -27633, -27587, -27542, -27496, -27450, -27405, -27359, -27313,
- -27268, -27222, -27176, -27131, -27085, -27039, -26993, -26947,
- -26902, -26856, -26810, -26764, -26718, -26672, -26626, -26580,
- -26534, -26488, -26442, -26396, -26350, -26304, -26258, -26212,
- -26166, -26120, -26074, -26028, -25982, -25936, -25889, -25843,
- -25797, -25751, -25705, -25658, -25612, -25566, -25520, -25473,
- -25427, -25381, -25334, -25288, -25241, -25195, -25149, -25102,
- -25056, -25009, -24963, -24916, -24870, -24823, -24777, -24730,
- -24684, -24637, -24591, -24544, -24497, -24451, -24404, -24357,
- -24311, -24264, -24217, -24171, -24124, -24077, -24030, -23984,
- -23937, -23890, -23843, -23796, -23750, -23703, -23656, -23609,
- -23562, -23515, -23468, -23421, -23374, -23327, -23280, -23233,
- -23186, -23139, -23092, -23045, -22998, -22951, -22904, -22857,
- -22810, -22763, -22716, -22668, -22621, -22574, -22527, -22480,
- -22432, -22385, -22338, -22291, -22243, -22196, -22149, -22102,
- -22054, -22007, -21960, -21912, -21865, -21817, -21770, -21723,
- -21675, -21628, -21580, -21533, -21485, -21438, -21390, -21343,
- -21295, -21248, -21200, -21153, -21105, -21057, -21010, -20962,
- -20915, -20867, -20819, -20772, -20724, -20676, -20629, -20581,
- -20533, -20485, -20438, -20390, -20342, -20294, -20246, -20199,
- -20151, -20103, -20055, -20007, -19959, -19912, -19864, -19816,
- -19768, -19720, -19672, -19624, -19576, -19528, -19480, -19432,
- -19384, -19336, -19288, -19240, -19192, -19144, -19096, -19048,
- -19000, -18951, -18903, -18855, -18807, -18759, -18711, -18663,
- -18614, -18566, -18518, -18470, -18421, -18373, -18325, -18277,
- -18228, -18180, -18132, -18084, -18035, -17987, -17939, -17890,
- -17842, -17793, -17745, -17697, -17648, -17600, -17551, -17503,
- -17455, -17406, -17358, -17309, -17261, -17212, -17164, -17115,
- -17067, -17018, -16970, -16921, -16872, -16824, -16775, -16727,
- -16678, -16629, -16581, -16532, -16484, -16435, -16386, -16338,
- -16289, -16240, -16191, -16143, -16094, -16045, -15997, -15948,
- -15899, -15850, -15802, -15753, -15704, -15655, -15606, -15557,
- -15509, -15460, -15411, -15362, -15313, -15264, -15215, -15167,
- -15118, -15069, -15020, -14971, -14922, -14873, -14824, -14775,
- -14726, -14677, -14628, -14579, -14530, -14481, -14432, -14383,
- -14334, -14285, -14236, -14187, -14138, -14089, -14040, -13990,
- -13941, -13892, -13843, -13794, -13745, -13696, -13647, -13597,
- -13548, -13499, -13450, -13401, -13351, -13302, -13253, -13204,
- -13154, -13105, -13056, -13007, -12957, -12908, -12859, -12810,
- -12760, -12711, -12662, -12612, -12563, -12514, -12464, -12415,
- -12366, -12316, -12267, -12217, -12168, -12119, -12069, -12020,
- -11970, -11921, -11872, -11822, -11773, -11723, -11674, -11624,
- -11575, -11525, -11476, -11426, -11377, -11327, -11278, -11228,
- -11179, -11129, -11080, -11030, -10981, -10931, -10882, -10832,
- -10782, -10733, -10683, -10634, -10584, -10534, -10485, -10435,
- -10386, -10336, -10286, -10237, -10187, -10137, -10088, -10038,
- -9988, -9939, -9889, -9839, -9790, -9740, -9690, -9640,
- -9591, -9541, -9491, -9442, -9392, -9342, -9292, -9243,
- -9193, -9143, -9093, -9043, -8994, -8944, -8894, -8844,
- -8794, -8745, -8695, -8645, -8595, -8545, -8496, -8446,
- -8396, -8346, -8296, -8246, -8196, -8147, -8097, -8047,
- -7997, -7947, -7897, -7847, -7797, -7747, -7697, -7648,
- -7598, -7548, -7498, -7448, -7398, -7348, -7298, -7248,
- -7198, -7148, -7098, -7048, -6998, -6948, -6898, -6848,
- -6798, -6748, -6698, -6648, -6598, -6548, -6498, -6448,
- -6398, -6348, -6298, -6248, -6198, -6148, -6098, -6048,
- -5998, -5948, -5898, -5848, -5798, -5747, -5697, -5647,
- -5597, -5547, -5497, -5447, -5397, -5347, -5297, -5247,
- -5197, -5146, -5096, -5046, -4996, -4946, -4896, -4846,
- -4796, -4745, -4695, -4645, -4595, -4545, -4495, -4445,
- -4394, -4344, -4294, -4244, -4194, -4144, -4093, -4043,
- -3993, -3943, -3893, -3843, -3792, -3742, -3692, -3642,
- -3592, -3541, -3491, -3441, -3391, -3341, -3291, -3240,
- -3190, -3140, -3090, -3039, -2989, -2939, -2889, -2839,
- -2788, -2738, -2688, -2638, -2588, -2537, -2487, -2437,
- -2387, -2336, -2286, -2236, -2186, -2135, -2085, -2035,
- -1985, -1934, -1884, -1834, -1784, -1733, -1683, -1633,
- -1583, -1532, -1482, -1432, -1382, -1331, -1281, -1231,
- -1181, -1130, -1080, -1030, -980, -929, -879, -829,
- -779, -728, -678, -628, -578, -527, -477, -427,
- -376, -326, -276, -226, -175, -125, -75, -25,
- 25, 75, 125, 175, 226, 276, 326, 376,
- 427, 477, 527, 578, 628, 678, 728, 779,
- 829, 879, 929, 980, 1030, 1080, 1130, 1181,
- 1231, 1281, 1331, 1382, 1432, 1482, 1532, 1583,
- 1633, 1683, 1733, 1784, 1834, 1884, 1934, 1985,
- 2035, 2085, 2135, 2186, 2236, 2286, 2336, 2387,
- 2437, 2487, 2537, 2587, 2638, 2688, 2738, 2788,
- 2839, 2889, 2939, 2989, 3039, 3090, 3140, 3190,
- 3240, 3291, 3341, 3391, 3441, 3491, 3542, 3592,
- 3642, 3692, 3742, 3792, 3843, 3893, 3943, 3993,
- 4043, 4093, 4144, 4194, 4244, 4294, 4344, 4394,
- 4445, 4495, 4545, 4595, 4645, 4695, 4745, 4796,
- 4846, 4896, 4946, 4996, 5046, 5096, 5146, 5197,
- 5247, 5297, 5347, 5397, 5447, 5497, 5547, 5597,
- 5647, 5697, 5747, 5798, 5848, 5898, 5948, 5998,
- 6048, 6098, 6148, 6198, 6248, 6298, 6348, 6398,
- 6448, 6498, 6548, 6598, 6648, 6698, 6748, 6798,
- 6848, 6898, 6948, 6998, 7048, 7098, 7148, 7198,
- 7248, 7298, 7348, 7398, 7448, 7498, 7548, 7598,
- 7648, 7697, 7747, 7797, 7847, 7897, 7947, 7997,
- 8047, 8097, 8147, 8196, 8246, 8296, 8346, 8396,
- 8446, 8496, 8545, 8595, 8645, 8695, 8745, 8794,
- 8844, 8894, 8944, 8994, 9043, 9093, 9143, 9193,
- 9243, 9292, 9342, 9392, 9442, 9491, 9541, 9591,
- 9640, 9690, 9740, 9790, 9839, 9889, 9939, 9988,
- 10038, 10088, 10137, 10187, 10237, 10286, 10336, 10386,
- 10435, 10485, 10534, 10584, 10634, 10683, 10733, 10782,
- 10832, 10882, 10931, 10981, 11030, 11080, 11129, 11179,
- 11228, 11278, 11327, 11377, 11426, 11476, 11525, 11575,
- 11624, 11674, 11723, 11773, 11822, 11872, 11921, 11970,
- 12020, 12069, 12119, 12168, 12218, 12267, 12316, 12366,
- 12415, 12464, 12514, 12563, 12612, 12662, 12711, 12760,
- 12810, 12859, 12908, 12957, 13007, 13056, 13105, 13154,
- 13204, 13253, 13302, 13351, 13401, 13450, 13499, 13548,
- 13597, 13647, 13696, 13745, 13794, 13843, 13892, 13941,
- 13990, 14040, 14089, 14138, 14187, 14236, 14285, 14334,
- 14383, 14432, 14481, 14530, 14579, 14628, 14677, 14726,
- 14775, 14824, 14873, 14922, 14971, 15020, 15069, 15118,
- 15167, 15215, 15264, 15313, 15362, 15411, 15460, 15509,
- 15557, 15606, 15655, 15704, 15753, 15802, 15850, 15899,
- 15948, 15997, 16045, 16094, 16143, 16191, 16240, 16289,
- 16338, 16386, 16435, 16484, 16532, 16581, 16629, 16678,
- 16727, 16775, 16824, 16872, 16921, 16970, 17018, 17067,
- 17115, 17164, 17212, 17261, 17309, 17358, 17406, 17455,
- 17503, 17551, 17600, 17648, 17697, 17745, 17793, 17842,
- 17890, 17939, 17987, 18035, 18084, 18132, 18180, 18228,
- 18277, 18325, 18373, 18421, 18470, 18518, 18566, 18614,
- 18663, 18711, 18759, 18807, 18855, 18903, 18951, 19000,
- 19048, 19096, 19144, 19192, 19240, 19288, 19336, 19384,
- 19432, 19480, 19528, 19576, 19624, 19672, 19720, 19768,
- 19816, 19864, 19912, 19959, 20007, 20055, 20103, 20151,
- 20199, 20246, 20294, 20342, 20390, 20438, 20485, 20533,
- 20581, 20629, 20676, 20724, 20772, 20819, 20867, 20915,
- 20962, 21010, 21057, 21105, 21153, 21200, 21248, 21295,
- 21343, 21390, 21438, 21485, 21533, 21580, 21628, 21675,
- 21723, 21770, 21817, 21865, 21912, 21960, 22007, 22054,
- 22102, 22149, 22196, 22243, 22291, 22338, 22385, 22432,
- 22480, 22527, 22574, 22621, 22668, 22716, 22763, 22810,
- 22857, 22904, 22951, 22998, 23045, 23092, 23139, 23186,
- 23233, 23280, 23327, 23374, 23421, 23468, 23515, 23562,
- 23609, 23656, 23703, 23750, 23796, 23843, 23890, 23937,
- 23984, 24030, 24077, 24124, 24171, 24217, 24264, 24311,
- 24357, 24404, 24451, 24497, 24544, 24591, 24637, 24684,
- 24730, 24777, 24823, 24870, 24916, 24963, 25009, 25056,
- 25102, 25149, 25195, 25241, 25288, 25334, 25381, 25427,
- 25473, 25520, 25566, 25612, 25658, 25705, 25751, 25797,
- 25843, 25889, 25936, 25982, 26028, 26074, 26120, 26166,
- 26212, 26258, 26304, 26350, 26396, 26442, 26488, 26534,
- 26580, 26626, 26672, 26718, 26764, 26810, 26856, 26902,
- 26947, 26993, 27039, 27085, 27131, 27176, 27222, 27268,
- 27313, 27359, 27405, 27450, 27496, 27542, 27587, 27633,
- 27678, 27724, 27770, 27815, 27861, 27906, 27952, 27997,
- 28042, 28088, 28133, 28179, 28224, 28269, 28315, 28360,
- 28405, 28451, 28496, 28541, 28586, 28632, 28677, 28722,
- 28767, 28812, 28858, 28903, 28948, 28993, 29038, 29083,
- 29128, 29173, 29218, 29263, 29308, 29353, 29398, 29443,
- 29488, 29533, 29577, 29622, 29667, 29712, 29757, 29801,
- 29846, 29891, 29936, 29980, 30025, 30070, 30114, 30159,
- 30204, 30248, 30293, 30337, 30382, 30427, 30471, 30516,
- 30560, 30604, 30649, 30693, 30738, 30782, 30826, 30871,
- 30915, 30959, 31004, 31048, 31092, 31136, 31181, 31225,
- 31269, 31313, 31357, 31402, 31446, 31490, 31534, 31578,
- 31622, 31666, 31710, 31754, 31798, 31842, 31886, 31930,
- 31974, 32017, 32061, 32105, 32149, 32193, 32236, 32280,
- 32324, 32368, 32411, 32455, 32499, 32542, 32586, 32630,
- 32673, 32717, 32760, 32804, 32847, 32891, 32934, 32978,
- 33021, 33065, 33108, 33151, 33195, 33238, 33281, 33325,
- 33368, 33411, 33454, 33498, 33541, 33584, 33627, 33670,
- 33713, 33756, 33799, 33843, 33886, 33929, 33972, 34015,
- 34057, 34100, 34143, 34186, 34229, 34272, 34315, 34358,
- 34400, 34443, 34486, 34529, 34571, 34614, 34657, 34699,
- 34742, 34785, 34827, 34870, 34912, 34955, 34997, 35040,
- 35082, 35125, 35167, 35210, 35252, 35294, 35337, 35379,
- 35421, 35464, 35506, 35548, 35590, 35633, 35675, 35717,
- 35759, 35801, 35843, 35885, 35927, 35969, 36011, 36053,
- 36095, 36137, 36179, 36221, 36263, 36305, 36347, 36388,
- 36430, 36472, 36514, 36556, 36597, 36639, 36681, 36722,
- 36764, 36805, 36847, 36889, 36930, 36972, 37013, 37055,
- 37096, 37137, 37179, 37220, 37262, 37303, 37344, 37386,
- 37427, 37468, 37509, 37551, 37592, 37633, 37674, 37715,
- 37756, 37797, 37838, 37879, 37920, 37961, 38002, 38043,
- 38084, 38125, 38166, 38207, 38248, 38288, 38329, 38370,
- 38411, 38451, 38492, 38533, 38573, 38614, 38655, 38695,
- 38736, 38776, 38817, 38857, 38898, 38938, 38979, 39019,
- 39059, 39100, 39140, 39180, 39221, 39261, 39301, 39341,
- 39382, 39422, 39462, 39502, 39542, 39582, 39622, 39662,
- 39702, 39742, 39782, 39822, 39862, 39902, 39942, 39982,
- 40021, 40061, 40101, 40141, 40180, 40220, 40260, 40299,
- 40339, 40379, 40418, 40458, 40497, 40537, 40576, 40616,
- 40655, 40695, 40734, 40773, 40813, 40852, 40891, 40931,
- 40970, 41009, 41048, 41087, 41127, 41166, 41205, 41244,
- 41283, 41322, 41361, 41400, 41439, 41478, 41517, 41556,
- 41595, 41633, 41672, 41711, 41750, 41788, 41827, 41866,
- 41904, 41943, 41982, 42020, 42059, 42097, 42136, 42174,
- 42213, 42251, 42290, 42328, 42366, 42405, 42443, 42481,
- 42520, 42558, 42596, 42634, 42672, 42711, 42749, 42787,
- 42825, 42863, 42901, 42939, 42977, 43015, 43053, 43091,
- 43128, 43166, 43204, 43242, 43280, 43317, 43355, 43393,
- 43430, 43468, 43506, 43543, 43581, 43618, 43656, 43693,
- 43731, 43768, 43806, 43843, 43880, 43918, 43955, 43992,
- 44029, 44067, 44104, 44141, 44178, 44215, 44252, 44289,
- 44326, 44363, 44400, 44437, 44474, 44511, 44548, 44585,
- 44622, 44659, 44695, 44732, 44769, 44806, 44842, 44879,
- 44915, 44952, 44989, 45025, 45062, 45098, 45135, 45171,
- 45207, 45244, 45280, 45316, 45353, 45389, 45425, 45462,
- 45498, 45534, 45570, 45606, 45642, 45678, 45714, 45750,
- 45786, 45822, 45858, 45894, 45930, 45966, 46002, 46037,
- 46073, 46109, 46145, 46180, 46216, 46252, 46287, 46323,
- 46358, 46394, 46429, 46465, 46500, 46536, 46571, 46606,
- 46642, 46677, 46712, 46747, 46783, 46818, 46853, 46888,
- 46923, 46958, 46993, 47028, 47063, 47098, 47133, 47168,
- 47203, 47238, 47273, 47308, 47342, 47377, 47412, 47446,
- 47481, 47516, 47550, 47585, 47619, 47654, 47688, 47723,
- 47757, 47792, 47826, 47861, 47895, 47929, 47963, 47998,
- 48032, 48066, 48100, 48134, 48168, 48202, 48237, 48271,
- 48305, 48338, 48372, 48406, 48440, 48474, 48508, 48542,
- 48575, 48609, 48643, 48676, 48710, 48744, 48777, 48811,
- 48844, 48878, 48911, 48945, 48978, 49012, 49045, 49078,
- 49112, 49145, 49178, 49211, 49244, 49278, 49311, 49344,
- 49377, 49410, 49443, 49476, 49509, 49542, 49575, 49608,
- 49640, 49673, 49706, 49739, 49771, 49804, 49837, 49869,
- 49902, 49935, 49967, 50000, 50032, 50064, 50097, 50129,
- 50162, 50194, 50226, 50259, 50291, 50323, 50355, 50387,
- 50420, 50452, 50484, 50516, 50548, 50580, 50612, 50644,
- 50675, 50707, 50739, 50771, 50803, 50834, 50866, 50898,
- 50929, 50961, 50993, 51024, 51056, 51087, 51119, 51150,
- 51182, 51213, 51244, 51276, 51307, 51338, 51369, 51401,
- 51432, 51463, 51494, 51525, 51556, 51587, 51618, 51649,
- 51680, 51711, 51742, 51773, 51803, 51834, 51865, 51896,
- 51926, 51957, 51988, 52018, 52049, 52079, 52110, 52140,
- 52171, 52201, 52231, 52262, 52292, 52322, 52353, 52383,
- 52413, 52443, 52473, 52503, 52534, 52564, 52594, 52624,
- 52653, 52683, 52713, 52743, 52773, 52803, 52832, 52862,
- 52892, 52922, 52951, 52981, 53010, 53040, 53069, 53099,
- 53128, 53158, 53187, 53216, 53246, 53275, 53304, 53334,
- 53363, 53392, 53421, 53450, 53479, 53508, 53537, 53566,
- 53595, 53624, 53653, 53682, 53711, 53739, 53768, 53797,
- 53826, 53854, 53883, 53912, 53940, 53969, 53997, 54026,
- 54054, 54082, 54111, 54139, 54167, 54196, 54224, 54252,
- 54280, 54309, 54337, 54365, 54393, 54421, 54449, 54477,
- 54505, 54533, 54560, 54588, 54616, 54644, 54672, 54699,
- 54727, 54755, 54782, 54810, 54837, 54865, 54892, 54920,
- 54947, 54974, 55002, 55029, 55056, 55084, 55111, 55138,
- 55165, 55192, 55219, 55246, 55274, 55300, 55327, 55354,
- 55381, 55408, 55435, 55462, 55489, 55515, 55542, 55569,
- 55595, 55622, 55648, 55675, 55701, 55728, 55754, 55781,
- 55807, 55833, 55860, 55886, 55912, 55938, 55965, 55991,
- 56017, 56043, 56069, 56095, 56121, 56147, 56173, 56199,
- 56225, 56250, 56276, 56302, 56328, 56353, 56379, 56404,
- 56430, 56456, 56481, 56507, 56532, 56557, 56583, 56608,
- 56633, 56659, 56684, 56709, 56734, 56760, 56785, 56810,
- 56835, 56860, 56885, 56910, 56935, 56959, 56984, 57009,
- 57034, 57059, 57083, 57108, 57133, 57157, 57182, 57206,
- 57231, 57255, 57280, 57304, 57329, 57353, 57377, 57402,
- 57426, 57450, 57474, 57498, 57522, 57546, 57570, 57594,
- 57618, 57642, 57666, 57690, 57714, 57738, 57762, 57785,
- 57809, 57833, 57856, 57880, 57903, 57927, 57950, 57974,
- 57997, 58021, 58044, 58067, 58091, 58114, 58137, 58160,
- 58183, 58207, 58230, 58253, 58276, 58299, 58322, 58345,
- 58367, 58390, 58413, 58436, 58459, 58481, 58504, 58527,
- 58549, 58572, 58594, 58617, 58639, 58662, 58684, 58706,
- 58729, 58751, 58773, 58795, 58818, 58840, 58862, 58884,
- 58906, 58928, 58950, 58972, 58994, 59016, 59038, 59059,
- 59081, 59103, 59125, 59146, 59168, 59190, 59211, 59233,
- 59254, 59276, 59297, 59318, 59340, 59361, 59382, 59404,
- 59425, 59446, 59467, 59488, 59509, 59530, 59551, 59572,
- 59593, 59614, 59635, 59656, 59677, 59697, 59718, 59739,
- 59759, 59780, 59801, 59821, 59842, 59862, 59883, 59903,
- 59923, 59944, 59964, 59984, 60004, 60025, 60045, 60065,
- 60085, 60105, 60125, 60145, 60165, 60185, 60205, 60225,
- 60244, 60264, 60284, 60304, 60323, 60343, 60363, 60382,
- 60402, 60421, 60441, 60460, 60479, 60499, 60518, 60537,
- 60556, 60576, 60595, 60614, 60633, 60652, 60671, 60690,
- 60709, 60728, 60747, 60766, 60785, 60803, 60822, 60841,
- 60859, 60878, 60897, 60915, 60934, 60952, 60971, 60989,
- 61007, 61026, 61044, 61062, 61081, 61099, 61117, 61135,
- 61153, 61171, 61189, 61207, 61225, 61243, 61261, 61279,
- 61297, 61314, 61332, 61350, 61367, 61385, 61403, 61420,
- 61438, 61455, 61473, 61490, 61507, 61525, 61542, 61559,
- 61577, 61594, 61611, 61628, 61645, 61662, 61679, 61696,
- 61713, 61730, 61747, 61764, 61780, 61797, 61814, 61831,
- 61847, 61864, 61880, 61897, 61913, 61930, 61946, 61963,
- 61979, 61995, 62012, 62028, 62044, 62060, 62076, 62092,
- 62108, 62125, 62141, 62156, 62172, 62188, 62204, 62220,
- 62236, 62251, 62267, 62283, 62298, 62314, 62329, 62345,
- 62360, 62376, 62391, 62407, 62422, 62437, 62453, 62468,
- 62483, 62498, 62513, 62528, 62543, 62558, 62573, 62588,
- 62603, 62618, 62633, 62648, 62662, 62677, 62692, 62706,
- 62721, 62735, 62750, 62764, 62779, 62793, 62808, 62822,
- 62836, 62850, 62865, 62879, 62893, 62907, 62921, 62935,
- 62949, 62963, 62977, 62991, 63005, 63019, 63032, 63046,
- 63060, 63074, 63087, 63101, 63114, 63128, 63141, 63155,
- 63168, 63182, 63195, 63208, 63221, 63235, 63248, 63261,
- 63274, 63287, 63300, 63313, 63326, 63339, 63352, 63365,
- 63378, 63390, 63403, 63416, 63429, 63441, 63454, 63466,
- 63479, 63491, 63504, 63516, 63528, 63541, 63553, 63565,
- 63578, 63590, 63602, 63614, 63626, 63638, 63650, 63662,
- 63674, 63686, 63698, 63709, 63721, 63733, 63745, 63756,
- 63768, 63779, 63791, 63803, 63814, 63825, 63837, 63848,
- 63859, 63871, 63882, 63893, 63904, 63915, 63927, 63938,
- 63949, 63960, 63971, 63981, 63992, 64003, 64014, 64025,
- 64035, 64046, 64057, 64067, 64078, 64088, 64099, 64109,
- 64120, 64130, 64140, 64151, 64161, 64171, 64181, 64192,
- 64202, 64212, 64222, 64232, 64242, 64252, 64261, 64271,
- 64281, 64291, 64301, 64310, 64320, 64330, 64339, 64349,
- 64358, 64368, 64377, 64387, 64396, 64405, 64414, 64424,
- 64433, 64442, 64451, 64460, 64469, 64478, 64487, 64496,
- 64505, 64514, 64523, 64532, 64540, 64549, 64558, 64566,
- 64575, 64584, 64592, 64600, 64609, 64617, 64626, 64634,
- 64642, 64651, 64659, 64667, 64675, 64683, 64691, 64699,
- 64707, 64715, 64723, 64731, 64739, 64747, 64754, 64762,
- 64770, 64777, 64785, 64793, 64800, 64808, 64815, 64822,
- 64830, 64837, 64844, 64852, 64859, 64866, 64873, 64880,
- 64887, 64895, 64902, 64908, 64915, 64922, 64929, 64936,
- 64943, 64949, 64956, 64963, 64969, 64976, 64982, 64989,
- 64995, 65002, 65008, 65015, 65021, 65027, 65033, 65040,
- 65046, 65052, 65058, 65064, 65070, 65076, 65082, 65088,
- 65094, 65099, 65105, 65111, 65117, 65122, 65128, 65133,
- 65139, 65144, 65150, 65155, 65161, 65166, 65171, 65177,
- 65182, 65187, 65192, 65197, 65202, 65207, 65212, 65217,
- 65222, 65227, 65232, 65237, 65242, 65246, 65251, 65256,
- 65260, 65265, 65270, 65274, 65279, 65283, 65287, 65292,
- 65296, 65300, 65305, 65309, 65313, 65317, 65321, 65325,
- 65329, 65333, 65337, 65341, 65345, 65349, 65352, 65356,
- 65360, 65363, 65367, 65371, 65374, 65378, 65381, 65385,
- 65388, 65391, 65395, 65398, 65401, 65404, 65408, 65411,
- 65414, 65417, 65420, 65423, 65426, 65429, 65431, 65434,
- 65437, 65440, 65442, 65445, 65448, 65450, 65453, 65455,
- 65458, 65460, 65463, 65465, 65467, 65470, 65472, 65474,
- 65476, 65478, 65480, 65482, 65484, 65486, 65488, 65490,
- 65492, 65494, 65496, 65497, 65499, 65501, 65502, 65504,
- 65505, 65507, 65508, 65510, 65511, 65513, 65514, 65515,
- 65516, 65518, 65519, 65520, 65521, 65522, 65523, 65524,
- 65525, 65526, 65527, 65527, 65528, 65529, 65530, 65530,
+ -65536, -65535, -65535, -65535, -65535, -65535, -65535, -65535,
+ -65534, -65534, -65534, -65533, -65533, -65532, -65532, -65531,
+ -65531, -65530, -65529, -65529, -65528, -65527, -65526, -65525,
+ -65524, -65523, -65522, -65521, -65520, -65519, -65518, -65517,
+ -65516, -65515, -65513, -65512, -65511, -65509, -65508, -65506,
+ -65505, -65503, -65501, -65500, -65498, -65496, -65495, -65493,
+ -65491, -65489, -65487, -65485, -65483, -65481, -65479, -65477,
+ -65475, -65473, -65471, -65468, -65466, -65464, -65461, -65459,
+ -65457, -65454, -65452, -65449, -65446, -65444, -65441, -65438,
+ -65436, -65433, -65430, -65427, -65424, -65421, -65418, -65415,
+ -65412, -65409, -65406, -65403, -65400, -65396, -65393, -65390,
+ -65386, -65383, -65379, -65376, -65372, -65369, -65365, -65362,
+ -65358, -65354, -65350, -65347, -65343, -65339, -65335, -65331,
+ -65327, -65323, -65319, -65315, -65311, -65307, -65302, -65298,
+ -65294, -65290, -65285, -65281, -65276, -65272, -65267, -65263,
+ -65258, -65253, -65249, -65244, -65239, -65235, -65230, -65225,
+ -65220, -65215, -65210, -65205, -65200, -65195, -65190, -65184,
+ -65179, -65174, -65169, -65163, -65158, -65153, -65147, -65142,
+ -65136, -65131, -65125, -65119, -65114, -65108, -65102, -65096,
+ -65091, -65085, -65079, -65073, -65067, -65061, -65055, -65049,
+ -65043, -65036, -65030, -65024, -65018, -65011, -65005, -64999,
+ -64992, -64986, -64979, -64973, -64966, -64959, -64953, -64946,
+ -64939, -64933, -64926, -64919, -64912, -64905, -64898, -64891,
+ -64884, -64877, -64870, -64863, -64855, -64848, -64841, -64834,
+ -64826, -64819, -64811, -64804, -64796, -64789, -64781, -64774,
+ -64766, -64758, -64751, -64743, -64735, -64727, -64719, -64711,
+ -64703, -64695, -64687, -64679, -64671, -64663, -64655, -64646,
+ -64638, -64630, -64622, -64613, -64605, -64596, -64588, -64579,
+ -64571, -64562, -64553, -64545, -64536, -64527, -64518, -64510,
+ -64501, -64492, -64483, -64474, -64465, -64456, -64447, -64437,
+ -64428, -64419, -64410, -64401, -64391, -64382, -64372, -64363,
+ -64353, -64344, -64334, -64325, -64315, -64305, -64296, -64286,
+ -64276, -64266, -64257, -64247, -64237, -64227, -64217, -64207,
+ -64197, -64186, -64176, -64166, -64156, -64146, -64135, -64125,
+ -64115, -64104, -64094, -64083, -64073, -64062, -64051, -64041,
+ -64030, -64019, -64009, -63998, -63987, -63976, -63965, -63954,
+ -63943, -63932, -63921, -63910, -63899, -63888, -63876, -63865,
+ -63854, -63842, -63831, -63820, -63808, -63797, -63785, -63774,
+ -63762, -63750, -63739, -63727, -63715, -63704, -63692, -63680,
+ -63668, -63656, -63644, -63632, -63620, -63608, -63596, -63584,
+ -63571, -63559, -63547, -63535, -63522, -63510, -63498, -63485,
+ -63473, -63460, -63447, -63435, -63422, -63410, -63397, -63384,
+ -63371, -63358, -63346, -63333, -63320, -63307, -63294, -63281,
+ -63268, -63254, -63241, -63228, -63215, -63202, -63188, -63175,
+ -63162, -63148, -63135, -63121, -63108, -63094, -63080, -63067,
+ -63053, -63039, -63026, -63012, -62998, -62984, -62970, -62956,
+ -62942, -62928, -62914, -62900, -62886, -62872, -62858, -62843,
+ -62829, -62815, -62800, -62786, -62772, -62757, -62743, -62728,
+ -62714, -62699, -62684, -62670, -62655, -62640, -62625, -62610,
+ -62596, -62581, -62566, -62551, -62536, -62521, -62506, -62491,
+ -62475, -62460, -62445, -62430, -62414, -62399, -62384, -62368,
+ -62353, -62337, -62322, -62306, -62291, -62275, -62259, -62244,
+ -62228, -62212, -62196, -62180, -62164, -62148, -62133, -62117,
+ -62100, -62084, -62068, -62052, -62036, -62020, -62003, -61987,
+ -61971, -61954, -61938, -61922, -61905, -61889, -61872, -61855,
+ -61839, -61822, -61805, -61789, -61772, -61755, -61738, -61721,
+ -61705, -61688, -61671, -61654, -61637, -61619, -61602, -61585,
+ -61568, -61551, -61533, -61516, -61499, -61481, -61464, -61446,
+ -61429, -61411, -61394, -61376, -61359, -61341, -61323, -61305,
+ -61288, -61270, -61252, -61234, -61216, -61198, -61180, -61162,
+ -61144, -61126, -61108, -61090, -61071, -61053, -61035, -61017,
+ -60998, -60980, -60961, -60943, -60924, -60906, -60887, -60869,
+ -60850, -60831, -60813, -60794, -60775, -60756, -60737, -60719,
+ -60700, -60681, -60662, -60643, -60624, -60604, -60585, -60566,
+ -60547, -60528, -60508, -60489, -60470, -60450, -60431, -60411,
+ -60392, -60372, -60353, -60333, -60313, -60294, -60274, -60254,
+ -60235, -60215, -60195, -60175, -60155, -60135, -60115, -60095,
+ -60075, -60055, -60035, -60015, -59994, -59974, -59954, -59934,
+ -59913, -59893, -59872, -59852, -59831, -59811, -59790, -59770,
+ -59749, -59728, -59708, -59687, -59666, -59645, -59625, -59604,
+ -59583, -59562, -59541, -59520, -59499, -59478, -59457, -59435,
+ -59414, -59393, -59372, -59350, -59329, -59308, -59286, -59265,
+ -59243, -59222, -59200, -59179, -59157, -59135, -59114, -59092,
+ -59070, -59049, -59027, -59005, -58983, -58961, -58939, -58917,
+ -58895, -58873, -58851, -58829, -58807, -58784, -58762, -58740,
+ -58718, -58695, -58673, -58650, -58628, -58605, -58583, -58560,
+ -58538, -58515, -58493, -58470, -58447, -58424, -58402, -58379,
+ -58356, -58333, -58310, -58287, -58264, -58241, -58218, -58195,
+ -58172, -58149, -58125, -58102, -58079, -58056, -58032, -58009,
+ -57986, -57962, -57939, -57915, -57892, -57868, -57844, -57821,
+ -57797, -57773, -57750, -57726, -57702, -57678, -57654, -57630,
+ -57606, -57582, -57558, -57534, -57510, -57486, -57462, -57438,
+ -57414, -57389, -57365, -57341, -57316, -57292, -57268, -57243,
+ -57219, -57194, -57170, -57145, -57120, -57096, -57071, -57046,
+ -57022, -56997, -56972, -56947, -56922, -56897, -56872, -56847,
+ -56822, -56797, -56772, -56747, -56722, -56697, -56671, -56646,
+ -56621, -56595, -56570, -56545, -56519, -56494, -56468, -56443,
+ -56417, -56392, -56366, -56340, -56315, -56289, -56263, -56237,
+ -56212, -56186, -56160, -56134, -56108, -56082, -56056, -56030,
+ -56004, -55978, -55952, -55925, -55899, -55873, -55847, -55820,
+ -55794, -55768, -55741, -55715, -55688, -55662, -55635, -55609,
+ -55582, -55555, -55529, -55502, -55475, -55448, -55422, -55395,
+ -55368, -55341, -55314, -55287, -55260, -55233, -55206, -55179,
+ -55152, -55124, -55097, -55070, -55043, -55015, -54988, -54961,
+ -54933, -54906, -54879, -54851, -54823, -54796, -54768, -54741,
+ -54713, -54685, -54658, -54630, -54602, -54574, -54546, -54519,
+ -54491, -54463, -54435, -54407, -54379, -54351, -54323, -54294,
+ -54266, -54238, -54210, -54182, -54153, -54125, -54097, -54068,
+ -54040, -54011, -53983, -53954, -53926, -53897, -53869, -53840,
+ -53811, -53783, -53754, -53725, -53696, -53667, -53639, -53610,
+ -53581, -53552, -53523, -53494, -53465, -53436, -53407, -53377,
+ -53348, -53319, -53290, -53260, -53231, -53202, -53172, -53143,
+ -53114, -53084, -53055, -53025, -52996, -52966, -52936, -52907,
+ -52877, -52847, -52818, -52788, -52758, -52728, -52698, -52668,
+ -52639, -52609, -52579, -52549, -52518, -52488, -52458, -52428,
+ -52398, -52368, -52338, -52307, -52277, -52247, -52216, -52186,
+ -52155, -52125, -52095, -52064, -52033, -52003, -51972, -51942,
+ -51911, -51880, -51850, -51819, -51788, -51757, -51726, -51695,
+ -51665, -51634, -51603, -51572, -51541, -51510, -51478, -51447,
+ -51416, -51385, -51354, -51323, -51291, -51260, -51229, -51197,
+ -51166, -51134, -51103, -51072, -51040, -51008, -50977, -50945,
+ -50914, -50882, -50850, -50819, -50787, -50755, -50723, -50691,
+ -50660, -50628, -50596, -50564, -50532, -50500, -50468, -50436,
+ -50403, -50371, -50339, -50307, -50275, -50242, -50210, -50178,
+ -50146, -50113, -50081, -50048, -50016, -49983, -49951, -49918,
+ -49886, -49853, -49820, -49788, -49755, -49722, -49690, -49657,
+ -49624, -49591, -49558, -49525, -49492, -49459, -49426, -49393,
+ -49360, -49327, -49294, -49261, -49228, -49195, -49161, -49128,
+ -49095, -49062, -49028, -48995, -48961, -48928, -48895, -48861,
+ -48828, -48794, -48760, -48727, -48693, -48660, -48626, -48592,
+ -48558, -48525, -48491, -48457, -48423, -48389, -48355, -48321,
+ -48288, -48254, -48219, -48185, -48151, -48117, -48083, -48049,
+ -48015, -47981, -47946, -47912, -47878, -47843, -47809, -47775,
+ -47740, -47706, -47671, -47637, -47602, -47568, -47533, -47498,
+ -47464, -47429, -47394, -47360, -47325, -47290, -47255, -47220,
+ -47186, -47151, -47116, -47081, -47046, -47011, -46976, -46941,
+ -46906, -46871, -46835, -46800, -46765, -46730, -46695, -46659,
+ -46624, -46589, -46553, -46518, -46482, -46447, -46411, -46376,
+ -46340, -46305, -46269, -46234, -46198, -46162, -46127, -46091,
+ -46055, -46019, -45984, -45948, -45912, -45876, -45840, -45804,
+ -45768, -45732, -45696, -45660, -45624, -45588, -45552, -45516,
+ -45480, -45443, -45407, -45371, -45335, -45298, -45262, -45226,
+ -45189, -45153, -45116, -45080, -45043, -45007, -44970, -44934,
+ -44897, -44861, -44824, -44787, -44750, -44714, -44677, -44640,
+ -44603, -44567, -44530, -44493, -44456, -44419, -44382, -44345,
+ -44308, -44271, -44234, -44197, -44160, -44122, -44085, -44048,
+ -44011, -43974, -43936, -43899, -43862, -43824, -43787, -43749,
+ -43712, -43675, -43637, -43600, -43562, -43524, -43487, -43449,
+ -43412, -43374, -43336, -43298, -43261, -43223, -43185, -43147,
+ -43110, -43072, -43034, -42996, -42958, -42920, -42882, -42844,
+ -42806, -42768, -42730, -42692, -42653, -42615, -42577, -42539,
+ -42501, -42462, -42424, -42386, -42347, -42309, -42271, -42232,
+ -42194, -42155, -42117, -42078, -42040, -42001, -41962, -41924,
+ -41885, -41846, -41808, -41769, -41730, -41692, -41653, -41614,
+ -41575, -41536, -41497, -41458, -41419, -41381, -41342, -41303,
+ -41263, -41224, -41185, -41146, -41107, -41068, -41029, -40990,
+ -40950, -40911, -40872, -40832, -40793, -40754, -40714, -40675,
+ -40636, -40596, -40557, -40517, -40478, -40438, -40399, -40359,
+ -40319, -40280, -40240, -40200, -40161, -40121, -40081, -40041,
+ -40002, -39962, -39922, -39882, -39842, -39802, -39762, -39722,
+ -39682, -39642, -39602, -39562, -39522, -39482, -39442, -39402,
+ -39362, -39321, -39281, -39241, -39201, -39160, -39120, -39080,
+ -39039, -38999, -38958, -38918, -38878, -38837, -38797, -38756,
+ -38716, -38675, -38634, -38594, -38553, -38512, -38472, -38431,
+ -38390, -38350, -38309, -38268, -38227, -38186, -38146, -38105,
+ -38064, -38023, -37982, -37941, -37900, -37859, -37818, -37777,
+ -37736, -37695, -37653, -37612, -37571, -37530, -37489, -37447,
+ -37406, -37365, -37324, -37282, -37241, -37200, -37158, -37117,
+ -37075, -37034, -36992, -36951, -36909, -36868, -36826, -36785,
+ -36743, -36701, -36660, -36618, -36576, -36535, -36493, -36451,
+ -36409, -36368, -36326, -36284, -36242, -36200, -36158, -36116,
+ -36074, -36032, -35990, -35948, -35906, -35864, -35822, -35780,
+ -35738, -35696, -35654, -35611, -35569, -35527, -35485, -35442,
+ -35400, -35358, -35316, -35273, -35231, -35188, -35146, -35104,
+ -35061, -35019, -34976, -34934, -34891, -34849, -34806, -34763,
+ -34721, -34678, -34635, -34593, -34550, -34507, -34465, -34422,
+ -34379, -34336, -34293, -34251, -34208, -34165, -34122, -34079,
+ -34036, -33993, -33950, -33907, -33864, -33821, -33778, -33735,
+ -33692, -33649, -33605, -33562, -33519, -33476, -33433, -33389,
+ -33346, -33303, -33260, -33216, -33173, -33130, -33086, -33043,
+ -32999, -32956, -32912, -32869, -32826, -32782, -32738, -32695,
+ -32651, -32608, -32564, -32521, -32477, -32433, -32390, -32346,
+ -32302, -32258, -32215, -32171, -32127, -32083, -32039, -31995,
+ -31952, -31908, -31864, -31820, -31776, -31732, -31688, -31644,
+ -31600, -31556, -31512, -31468, -31424, -31379, -31335, -31291,
+ -31247, -31203, -31159, -31114, -31070, -31026, -30982, -30937,
+ -30893, -30849, -30804, -30760, -30715, -30671, -30627, -30582,
+ -30538, -30493, -30449, -30404, -30360, -30315, -30271, -30226,
+ -30181, -30137, -30092, -30047, -30003, -29958, -29913, -29869,
+ -29824, -29779, -29734, -29690, -29645, -29600, -29555, -29510,
+ -29465, -29420, -29375, -29330, -29285, -29241, -29196, -29151,
+ -29105, -29060, -29015, -28970, -28925, -28880, -28835, -28790,
+ -28745, -28699, -28654, -28609, -28564, -28519, -28473, -28428,
+ -28383, -28337, -28292, -28247, -28201, -28156, -28111, -28065,
+ -28020, -27974, -27929, -27883, -27838, -27792, -27747, -27701,
+ -27656, -27610, -27565, -27519, -27473, -27428, -27382, -27336,
+ -27291, -27245, -27199, -27153, -27108, -27062, -27016, -26970,
+ -26925, -26879, -26833, -26787, -26741, -26695, -26649, -26603,
+ -26557, -26511, -26465, -26419, -26373, -26327, -26281, -26235,
+ -26189, -26143, -26097, -26051, -26005, -25959, -25913, -25866,
+ -25820, -25774, -25728, -25681, -25635, -25589, -25543, -25496,
+ -25450, -25404, -25357, -25311, -25265, -25218, -25172, -25125,
+ -25079, -25033, -24986, -24940, -24893, -24847, -24800, -24754,
+ -24707, -24660, -24614, -24567, -24521, -24474, -24427, -24381,
+ -24334, -24287, -24241, -24194, -24147, -24101, -24054, -24007,
+ -23960, -23914, -23867, -23820, -23773, -23726, -23679, -23632,
+ -23586, -23539, -23492, -23445, -23398, -23351, -23304, -23257,
+ -23210, -23163, -23116, -23069, -23022, -22975, -22928, -22881,
+ -22833, -22786, -22739, -22692, -22645, -22598, -22551, -22503,
+ -22456, -22409, -22362, -22314, -22267, -22220, -22173, -22125,
+ -22078, -22031, -21983, -21936, -21889, -21841, -21794, -21746,
+ -21699, -21651, -21604, -21557, -21509, -21462, -21414, -21367,
+ -21319, -21271, -21224, -21176, -21129, -21081, -21034, -20986,
+ -20938, -20891, -20843, -20795, -20748, -20700, -20652, -20605,
+ -20557, -20509, -20461, -20414, -20366, -20318, -20270, -20223,
+ -20175, -20127, -20079, -20031, -19983, -19935, -19888, -19840,
+ -19792, -19744, -19696, -19648, -19600, -19552, -19504, -19456,
+ -19408, -19360, -19312, -19264, -19216, -19168, -19120, -19072,
+ -19024, -18975, -18927, -18879, -18831, -18783, -18735, -18687,
+ -18638, -18590, -18542, -18494, -18446, -18397, -18349, -18301,
+ -18253, -18204, -18156, -18108, -18059, -18011, -17963, -17914,
+ -17866, -17818, -17769, -17721, -17672, -17624, -17576, -17527,
+ -17479, -17430, -17382, -17333, -17285, -17236, -17188, -17139,
+ -17091, -17042, -16994, -16945, -16897, -16848, -16800, -16751,
+ -16702, -16654, -16605, -16557, -16508, -16459, -16411, -16362,
+ -16313, -16265, -16216, -16167, -16118, -16070, -16021, -15972,
+ -15923, -15875, -15826, -15777, -15728, -15680, -15631, -15582,
+ -15533, -15484, -15435, -15387, -15338, -15289, -15240, -15191,
+ -15142, -15093, -15044, -14995, -14946, -14897, -14849, -14800,
+ -14751, -14702, -14653, -14604, -14555, -14506, -14457, -14408,
+ -14359, -14309, -14260, -14211, -14162, -14113, -14064, -14015,
+ -13966, -13917, -13868, -13819, -13769, -13720, -13671, -13622,
+ -13573, -13524, -13474, -13425, -13376, -13327, -13278, -13228,
+ -13179, -13130, -13081, -13031, -12982, -12933, -12884, -12834,
+ -12785, -12736, -12686, -12637, -12588, -12538, -12489, -12440,
+ -12390, -12341, -12292, -12242, -12193, -12143, -12094, -12045,
+ -11995, -11946, -11896, -11847, -11797, -11748, -11699, -11649,
+ -11600, -11550, -11501, -11451, -11402, -11352, -11303, -11253,
+ -11204, -11154, -11105, -11055, -11006, -10956, -10906, -10857,
+ -10807, -10758, -10708, -10658, -10609, -10559, -10510, -10460,
+ -10410, -10361, -10311, -10262, -10212, -10162, -10113, -10063,
+ -10013, -9964, -9914, -9864, -9814, -9765, -9715, -9665,
+ -9616, -9566, -9516, -9466, -9417, -9367, -9317, -9267,
+ -9218, -9168, -9118, -9068, -9019, -8969, -8919, -8869,
+ -8819, -8770, -8720, -8670, -8620, -8570, -8520, -8471,
+ -8421, -8371, -8321, -8271, -8221, -8171, -8122, -8072,
+ -8022, -7972, -7922, -7872, -7822, -7772, -7722, -7672,
+ -7623, -7573, -7523, -7473, -7423, -7373, -7323, -7273,
+ -7223, -7173, -7123, -7073, -7023, -6973, -6923, -6873,
+ -6823, -6773, -6723, -6673, -6623, -6573, -6523, -6473,
+ -6423, -6373, -6323, -6273, -6223, -6173, -6123, -6073,
+ -6023, -5973, -5923, -5873, -5823, -5773, -5722, -5672,
+ -5622, -5572, -5522, -5472, -5422, -5372, -5322, -5272,
+ -5222, -5171, -5121, -5071, -5021, -4971, -4921, -4871,
+ -4821, -4770, -4720, -4670, -4620, -4570, -4520, -4470,
+ -4420, -4369, -4319, -4269, -4219, -4169, -4119, -4068,
+ -4018, -3968, -3918, -3868, -3818, -3767, -3717, -3667,
+ -3617, -3567, -3516, -3466, -3416, -3366, -3316, -3265,
+ -3215, -3165, -3115, -3065, -3014, -2964, -2914, -2864,
+ -2814, -2763, -2713, -2663, -2613, -2562, -2512, -2462,
+ -2412, -2361, -2311, -2261, -2211, -2161, -2110, -2060,
+ -2010, -1960, -1909, -1859, -1809, -1759, -1708, -1658,
+ -1608, -1558, -1507, -1457, -1407, -1357, -1306, -1256,
+ -1206, -1156, -1105, -1055, -1005, -955, -904, -854,
+ -804, -753, -703, -653, -603, -552, -502, -452,
+ -402, -351, -301, -251, -201, -150, -100, -50,
+ 0, 50, 100, 150, 201, 251, 301, 351,
+ 402, 452, 502, 552, 603, 653, 703, 753,
+ 804, 854, 904, 955, 1005, 1055, 1105, 1156,
+ 1206, 1256, 1306, 1357, 1407, 1457, 1507, 1558,
+ 1608, 1658, 1708, 1759, 1809, 1859, 1909, 1960,
+ 2010, 2060, 2110, 2161, 2211, 2261, 2311, 2361,
+ 2412, 2462, 2512, 2562, 2613, 2663, 2713, 2763,
+ 2814, 2864, 2914, 2964, 3014, 3065, 3115, 3165,
+ 3215, 3265, 3316, 3366, 3416, 3466, 3516, 3567,
+ 3617, 3667, 3717, 3767, 3818, 3868, 3918, 3968,
+ 4018, 4068, 4119, 4169, 4219, 4269, 4319, 4369,
+ 4420, 4470, 4520, 4570, 4620, 4670, 4720, 4770,
+ 4821, 4871, 4921, 4971, 5021, 5071, 5121, 5171,
+ 5222, 5272, 5322, 5372, 5422, 5472, 5522, 5572,
+ 5622, 5672, 5722, 5773, 5823, 5873, 5923, 5973,
+ 6023, 6073, 6123, 6173, 6223, 6273, 6323, 6373,
+ 6423, 6473, 6523, 6573, 6623, 6673, 6723, 6773,
+ 6823, 6873, 6923, 6973, 7023, 7073, 7123, 7173,
+ 7223, 7273, 7323, 7373, 7423, 7473, 7523, 7573,
+ 7623, 7672, 7722, 7772, 7822, 7872, 7922, 7972,
+ 8022, 8072, 8122, 8171, 8221, 8271, 8321, 8371,
+ 8421, 8471, 8520, 8570, 8620, 8670, 8720, 8770,
+ 8819, 8869, 8919, 8969, 9019, 9068, 9118, 9168,
+ 9218, 9267, 9317, 9367, 9417, 9466, 9516, 9566,
+ 9616, 9665, 9715, 9765, 9814, 9864, 9914, 9964,
+ 10013, 10063, 10113, 10162, 10212, 10262, 10311, 10361,
+ 10410, 10460, 10510, 10559, 10609, 10658, 10708, 10758,
+ 10807, 10857, 10906, 10956, 11006, 11055, 11105, 11154,
+ 11204, 11253, 11303, 11352, 11402, 11451, 11501, 11550,
+ 11600, 11649, 11699, 11748, 11797, 11847, 11896, 11946,
+ 11995, 12045, 12094, 12143, 12193, 12242, 12292, 12341,
+ 12390, 12440, 12489, 12538, 12588, 12637, 12686, 12736,
+ 12785, 12834, 12884, 12933, 12982, 13031, 13081, 13130,
+ 13179, 13228, 13278, 13327, 13376, 13425, 13474, 13524,
+ 13573, 13622, 13671, 13720, 13769, 13819, 13868, 13917,
+ 13966, 14015, 14064, 14113, 14162, 14211, 14260, 14309,
+ 14359, 14408, 14457, 14506, 14555, 14604, 14653, 14702,
+ 14751, 14800, 14849, 14897, 14946, 14995, 15044, 15093,
+ 15142, 15191, 15240, 15289, 15338, 15387, 15435, 15484,
+ 15533, 15582, 15631, 15680, 15728, 15777, 15826, 15875,
+ 15923, 15972, 16021, 16070, 16118, 16167, 16216, 16265,
+ 16313, 16362, 16411, 16459, 16508, 16557, 16605, 16654,
+ 16702, 16751, 16800, 16848, 16897, 16945, 16994, 17042,
+ 17091, 17139, 17188, 17236, 17285, 17333, 17382, 17430,
+ 17479, 17527, 17576, 17624, 17672, 17721, 17769, 17818,
+ 17866, 17914, 17963, 18011, 18059, 18108, 18156, 18204,
+ 18253, 18301, 18349, 18397, 18446, 18494, 18542, 18590,
+ 18638, 18687, 18735, 18783, 18831, 18879, 18927, 18975,
+ 19024, 19072, 19120, 19168, 19216, 19264, 19312, 19360,
+ 19408, 19456, 19504, 19552, 19600, 19648, 19696, 19744,
+ 19792, 19840, 19888, 19935, 19983, 20031, 20079, 20127,
+ 20175, 20223, 20270, 20318, 20366, 20414, 20461, 20509,
+ 20557, 20605, 20652, 20700, 20748, 20795, 20843, 20891,
+ 20938, 20986, 21034, 21081, 21129, 21176, 21224, 21271,
+ 21319, 21367, 21414, 21462, 21509, 21557, 21604, 21651,
+ 21699, 21746, 21794, 21841, 21889, 21936, 21983, 22031,
+ 22078, 22125, 22173, 22220, 22267, 22314, 22362, 22409,
+ 22456, 22503, 22551, 22598, 22645, 22692, 22739, 22786,
+ 22833, 22881, 22928, 22975, 23022, 23069, 23116, 23163,
+ 23210, 23257, 23304, 23351, 23398, 23445, 23492, 23539,
+ 23586, 23632, 23679, 23726, 23773, 23820, 23867, 23914,
+ 23960, 24007, 24054, 24101, 24147, 24194, 24241, 24287,
+ 24334, 24381, 24427, 24474, 24521, 24567, 24614, 24660,
+ 24707, 24754, 24800, 24847, 24893, 24940, 24986, 25033,
+ 25079, 25125, 25172, 25218, 25265, 25311, 25357, 25404,
+ 25450, 25496, 25543, 25589, 25635, 25681, 25728, 25774,
+ 25820, 25866, 25913, 25959, 26005, 26051, 26097, 26143,
+ 26189, 26235, 26281, 26327, 26373, 26419, 26465, 26511,
+ 26557, 26603, 26649, 26695, 26741, 26787, 26833, 26879,
+ 26925, 26970, 27016, 27062, 27108, 27153, 27199, 27245,
+ 27291, 27336, 27382, 27428, 27473, 27519, 27565, 27610,
+ 27656, 27701, 27747, 27792, 27838, 27883, 27929, 27974,
+ 28020, 28065, 28111, 28156, 28201, 28247, 28292, 28337,
+ 28383, 28428, 28473, 28519, 28564, 28609, 28654, 28699,
+ 28745, 28790, 28835, 28880, 28925, 28970, 29015, 29060,
+ 29105, 29151, 29196, 29241, 29285, 29330, 29375, 29420,
+ 29465, 29510, 29555, 29600, 29645, 29690, 29734, 29779,
+ 29824, 29869, 29913, 29958, 30003, 30047, 30092, 30137,
+ 30181, 30226, 30271, 30315, 30360, 30404, 30449, 30493,
+ 30538, 30582, 30627, 30671, 30715, 30760, 30804, 30849,
+ 30893, 30937, 30982, 31026, 31070, 31114, 31159, 31203,
+ 31247, 31291, 31335, 31379, 31424, 31468, 31512, 31556,
+ 31600, 31644, 31688, 31732, 31776, 31820, 31864, 31908,
+ 31952, 31995, 32039, 32083, 32127, 32171, 32215, 32258,
+ 32302, 32346, 32390, 32433, 32477, 32521, 32564, 32608,
+ 32651, 32695, 32738, 32782, 32826, 32869, 32912, 32956,
+ 32999, 33043, 33086, 33130, 33173, 33216, 33260, 33303,
+ 33346, 33389, 33433, 33476, 33519, 33562, 33605, 33649,
+ 33692, 33735, 33778, 33821, 33864, 33907, 33950, 33993,
+ 34036, 34079, 34122, 34165, 34208, 34251, 34293, 34336,
+ 34379, 34422, 34465, 34507, 34550, 34593, 34635, 34678,
+ 34721, 34763, 34806, 34849, 34891, 34934, 34976, 35019,
+ 35061, 35104, 35146, 35188, 35231, 35273, 35316, 35358,
+ 35400, 35442, 35485, 35527, 35569, 35611, 35654, 35696,
+ 35738, 35780, 35822, 35864, 35906, 35948, 35990, 36032,
+ 36074, 36116, 36158, 36200, 36242, 36284, 36326, 36368,
+ 36409, 36451, 36493, 36535, 36576, 36618, 36660, 36701,
+ 36743, 36785, 36826, 36868, 36909, 36951, 36992, 37034,
+ 37075, 37117, 37158, 37200, 37241, 37282, 37324, 37365,
+ 37406, 37447, 37489, 37530, 37571, 37612, 37653, 37695,
+ 37736, 37777, 37818, 37859, 37900, 37941, 37982, 38023,
+ 38064, 38105, 38146, 38186, 38227, 38268, 38309, 38350,
+ 38390, 38431, 38472, 38512, 38553, 38594, 38634, 38675,
+ 38716, 38756, 38797, 38837, 38878, 38918, 38958, 38999,
+ 39039, 39080, 39120, 39160, 39201, 39241, 39281, 39321,
+ 39362, 39402, 39442, 39482, 39522, 39562, 39602, 39642,
+ 39682, 39722, 39762, 39802, 39842, 39882, 39922, 39962,
+ 40002, 40041, 40081, 40121, 40161, 40200, 40240, 40280,
+ 40319, 40359, 40399, 40438, 40478, 40517, 40557, 40596,
+ 40636, 40675, 40714, 40754, 40793, 40832, 40872, 40911,
+ 40950, 40990, 41029, 41068, 41107, 41146, 41185, 41224,
+ 41263, 41303, 41342, 41381, 41419, 41458, 41497, 41536,
+ 41575, 41614, 41653, 41692, 41730, 41769, 41808, 41846,
+ 41885, 41924, 41962, 42001, 42040, 42078, 42117, 42155,
+ 42194, 42232, 42271, 42309, 42347, 42386, 42424, 42462,
+ 42501, 42539, 42577, 42615, 42653, 42692, 42730, 42768,
+ 42806, 42844, 42882, 42920, 42958, 42996, 43034, 43072,
+ 43110, 43147, 43185, 43223, 43261, 43298, 43336, 43374,
+ 43412, 43449, 43487, 43524, 43562, 43600, 43637, 43675,
+ 43712, 43749, 43787, 43824, 43862, 43899, 43936, 43974,
+ 44011, 44048, 44085, 44122, 44160, 44197, 44234, 44271,
+ 44308, 44345, 44382, 44419, 44456, 44493, 44530, 44567,
+ 44603, 44640, 44677, 44714, 44750, 44787, 44824, 44861,
+ 44897, 44934, 44970, 45007, 45043, 45080, 45116, 45153,
+ 45189, 45226, 45262, 45298, 45335, 45371, 45407, 45443,
+ 45480, 45516, 45552, 45588, 45624, 45660, 45696, 45732,
+ 45768, 45804, 45840, 45876, 45912, 45948, 45984, 46019,
+ 46055, 46091, 46127, 46162, 46198, 46234, 46269, 46305,
+ 46340, 46376, 46411, 46447, 46482, 46518, 46553, 46589,
+ 46624, 46659, 46695, 46730, 46765, 46800, 46835, 46871,
+ 46906, 46941, 46976, 47011, 47046, 47081, 47116, 47151,
+ 47186, 47220, 47255, 47290, 47325, 47360, 47394, 47429,
+ 47464, 47498, 47533, 47568, 47602, 47637, 47671, 47706,
+ 47740, 47775, 47809, 47843, 47878, 47912, 47946, 47981,
+ 48015, 48049, 48083, 48117, 48151, 48185, 48219, 48254,
+ 48288, 48321, 48355, 48389, 48423, 48457, 48491, 48525,
+ 48558, 48592, 48626, 48660, 48693, 48727, 48760, 48794,
+ 48828, 48861, 48895, 48928, 48961, 48995, 49028, 49062,
+ 49095, 49128, 49161, 49195, 49228, 49261, 49294, 49327,
+ 49360, 49393, 49426, 49459, 49492, 49525, 49558, 49591,
+ 49624, 49657, 49690, 49722, 49755, 49788, 49820, 49853,
+ 49886, 49918, 49951, 49983, 50016, 50048, 50081, 50113,
+ 50146, 50178, 50210, 50242, 50275, 50307, 50339, 50371,
+ 50403, 50436, 50468, 50500, 50532, 50564, 50596, 50628,
+ 50660, 50691, 50723, 50755, 50787, 50819, 50850, 50882,
+ 50914, 50945, 50977, 51008, 51040, 51072, 51103, 51134,
+ 51166, 51197, 51229, 51260, 51291, 51323, 51354, 51385,
+ 51416, 51447, 51478, 51510, 51541, 51572, 51603, 51634,
+ 51665, 51695, 51726, 51757, 51788, 51819, 51850, 51880,
+ 51911, 51942, 51972, 52003, 52033, 52064, 52095, 52125,
+ 52155, 52186, 52216, 52247, 52277, 52307, 52338, 52368,
+ 52398, 52428, 52458, 52488, 52518, 52549, 52579, 52609,
+ 52639, 52668, 52698, 52728, 52758, 52788, 52818, 52847,
+ 52877, 52907, 52936, 52966, 52996, 53025, 53055, 53084,
+ 53114, 53143, 53172, 53202, 53231, 53260, 53290, 53319,
+ 53348, 53377, 53407, 53436, 53465, 53494, 53523, 53552,
+ 53581, 53610, 53639, 53667, 53696, 53725, 53754, 53783,
+ 53811, 53840, 53869, 53897, 53926, 53954, 53983, 54011,
+ 54040, 54068, 54097, 54125, 54153, 54182, 54210, 54238,
+ 54266, 54294, 54323, 54351, 54379, 54407, 54435, 54463,
+ 54491, 54519, 54546, 54574, 54602, 54630, 54658, 54685,
+ 54713, 54741, 54768, 54796, 54823, 54851, 54879, 54906,
+ 54933, 54961, 54988, 55015, 55043, 55070, 55097, 55124,
+ 55152, 55179, 55206, 55233, 55260, 55287, 55314, 55341,
+ 55368, 55395, 55422, 55448, 55475, 55502, 55529, 55555,
+ 55582, 55609, 55635, 55662, 55688, 55715, 55741, 55768,
+ 55794, 55820, 55847, 55873, 55899, 55925, 55952, 55978,
+ 56004, 56030, 56056, 56082, 56108, 56134, 56160, 56186,
+ 56212, 56237, 56263, 56289, 56315, 56340, 56366, 56392,
+ 56417, 56443, 56468, 56494, 56519, 56545, 56570, 56595,
+ 56621, 56646, 56671, 56697, 56722, 56747, 56772, 56797,
+ 56822, 56847, 56872, 56897, 56922, 56947, 56972, 56997,
+ 57022, 57046, 57071, 57096, 57120, 57145, 57170, 57194,
+ 57219, 57243, 57268, 57292, 57316, 57341, 57365, 57389,
+ 57414, 57438, 57462, 57486, 57510, 57534, 57558, 57582,
+ 57606, 57630, 57654, 57678, 57702, 57726, 57750, 57773,
+ 57797, 57821, 57844, 57868, 57892, 57915, 57939, 57962,
+ 57986, 58009, 58032, 58056, 58079, 58102, 58125, 58149,
+ 58172, 58195, 58218, 58241, 58264, 58287, 58310, 58333,
+ 58356, 58379, 58402, 58424, 58447, 58470, 58493, 58515,
+ 58538, 58560, 58583, 58605, 58628, 58650, 58673, 58695,
+ 58718, 58740, 58762, 58784, 58807, 58829, 58851, 58873,
+ 58895, 58917, 58939, 58961, 58983, 59005, 59027, 59049,
+ 59070, 59092, 59114, 59135, 59157, 59179, 59200, 59222,
+ 59243, 59265, 59286, 59308, 59329, 59350, 59372, 59393,
+ 59414, 59435, 59457, 59478, 59499, 59520, 59541, 59562,
+ 59583, 59604, 59625, 59645, 59666, 59687, 59708, 59728,
+ 59749, 59770, 59790, 59811, 59831, 59852, 59872, 59893,
+ 59913, 59934, 59954, 59974, 59994, 60015, 60035, 60055,
+ 60075, 60095, 60115, 60135, 60155, 60175, 60195, 60215,
+ 60235, 60254, 60274, 60294, 60313, 60333, 60353, 60372,
+ 60392, 60411, 60431, 60450, 60470, 60489, 60508, 60528,
+ 60547, 60566, 60585, 60604, 60624, 60643, 60662, 60681,
+ 60700, 60719, 60737, 60756, 60775, 60794, 60813, 60831,
+ 60850, 60869, 60887, 60906, 60924, 60943, 60961, 60980,
+ 60998, 61017, 61035, 61053, 61071, 61090, 61108, 61126,
+ 61144, 61162, 61180, 61198, 61216, 61234, 61252, 61270,
+ 61288, 61305, 61323, 61341, 61359, 61376, 61394, 61411,
+ 61429, 61446, 61464, 61481, 61499, 61516, 61533, 61551,
+ 61568, 61585, 61602, 61619, 61637, 61654, 61671, 61688,
+ 61705, 61721, 61738, 61755, 61772, 61789, 61805, 61822,
+ 61839, 61855, 61872, 61889, 61905, 61922, 61938, 61954,
+ 61971, 61987, 62003, 62020, 62036, 62052, 62068, 62084,
+ 62100, 62117, 62133, 62148, 62164, 62180, 62196, 62212,
+ 62228, 62244, 62259, 62275, 62291, 62306, 62322, 62337,
+ 62353, 62368, 62384, 62399, 62414, 62430, 62445, 62460,
+ 62475, 62491, 62506, 62521, 62536, 62551, 62566, 62581,
+ 62596, 62610, 62625, 62640, 62655, 62670, 62684, 62699,
+ 62714, 62728, 62743, 62757, 62772, 62786, 62800, 62815,
+ 62829, 62843, 62858, 62872, 62886, 62900, 62914, 62928,
+ 62942, 62956, 62970, 62984, 62998, 63012, 63026, 63039,
+ 63053, 63067, 63080, 63094, 63108, 63121, 63135, 63148,
+ 63162, 63175, 63188, 63202, 63215, 63228, 63241, 63254,
+ 63268, 63281, 63294, 63307, 63320, 63333, 63346, 63358,
+ 63371, 63384, 63397, 63410, 63422, 63435, 63447, 63460,
+ 63473, 63485, 63498, 63510, 63522, 63535, 63547, 63559,
+ 63571, 63584, 63596, 63608, 63620, 63632, 63644, 63656,
+ 63668, 63680, 63692, 63704, 63715, 63727, 63739, 63750,
+ 63762, 63774, 63785, 63797, 63808, 63820, 63831, 63842,
+ 63854, 63865, 63876, 63888, 63899, 63910, 63921, 63932,
+ 63943, 63954, 63965, 63976, 63987, 63998, 64009, 64019,
+ 64030, 64041, 64051, 64062, 64073, 64083, 64094, 64104,
+ 64115, 64125, 64135, 64146, 64156, 64166, 64176, 64186,
+ 64197, 64207, 64217, 64227, 64237, 64247, 64257, 64266,
+ 64276, 64286, 64296, 64305, 64315, 64325, 64334, 64344,
+ 64353, 64363, 64372, 64382, 64391, 64401, 64410, 64419,
+ 64428, 64437, 64447, 64456, 64465, 64474, 64483, 64492,
+ 64501, 64510, 64518, 64527, 64536, 64545, 64553, 64562,
+ 64571, 64579, 64588, 64596, 64605, 64613, 64622, 64630,
+ 64638, 64646, 64655, 64663, 64671, 64679, 64687, 64695,
+ 64703, 64711, 64719, 64727, 64735, 64743, 64751, 64758,
+ 64766, 64774, 64781, 64789, 64796, 64804, 64811, 64819,
+ 64826, 64834, 64841, 64848, 64855, 64863, 64870, 64877,
+ 64884, 64891, 64898, 64905, 64912, 64919, 64926, 64933,
+ 64939, 64946, 64953, 64959, 64966, 64973, 64979, 64986,
+ 64992, 64999, 65005, 65011, 65018, 65024, 65030, 65036,
+ 65043, 65049, 65055, 65061, 65067, 65073, 65079, 65085,
+ 65091, 65096, 65102, 65108, 65114, 65119, 65125, 65131,
+ 65136, 65142, 65147, 65153, 65158, 65163, 65169, 65174,
+ 65179, 65184, 65190, 65195, 65200, 65205, 65210, 65215,
+ 65220, 65225, 65230, 65235, 65239, 65244, 65249, 65253,
+ 65258, 65263, 65267, 65272, 65276, 65281, 65285, 65290,
+ 65294, 65298, 65302, 65307, 65311, 65315, 65319, 65323,
+ 65327, 65331, 65335, 65339, 65343, 65347, 65350, 65354,
+ 65358, 65362, 65365, 65369, 65372, 65376, 65379, 65383,
+ 65386, 65390, 65393, 65396, 65400, 65403, 65406, 65409,
+ 65412, 65415, 65418, 65421, 65424, 65427, 65430, 65433,
+ 65436, 65438, 65441, 65444, 65446, 65449, 65452, 65454,
+ 65457, 65459, 65461, 65464, 65466, 65468, 65471, 65473,
+ 65475, 65477, 65479, 65481, 65483, 65485, 65487, 65489,
+ 65491, 65493, 65495, 65496, 65498, 65500, 65501, 65503,
+ 65505, 65506, 65508, 65509, 65511, 65512, 65513, 65515,
+ 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523,
+ 65524, 65525, 65526, 65527, 65528, 65529, 65529, 65530,
65531, 65531, 65532, 65532, 65533, 65533, 65534, 65534,
65534, 65535, 65535, 65535, 65535, 65535, 65535, 65535
};
@@ -2225,9 +2225,6 @@ angle_t tantoangle[2049] =
536870912
};
-
-#ifdef NEED_FIXED_VECTOR
-
static angle_t fineacon[65536*2] = {
ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208,
2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825,
@@ -10706,5 +10703,3 @@ void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z)
M(3, 3) = FRACUNIT;
#undef M
}
-
-#endif
diff --git a/src/tables.h b/src/tables.h
index 219d668b9..d7ec589da 100644
--- a/src/tables.h
+++ b/src/tables.h
@@ -96,9 +96,6 @@ FUNCMATH angle_t FixedAngle(fixed_t fa);
// and with a factor, with +factor for (fa/factor) and -factor for (fa*factor)
FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor);
-
-#ifdef NEED_FIXED_VECTOR
-
/// The FixedAcos function
FUNCMATH angle_t FixedAcos(fixed_t x);
@@ -112,8 +109,6 @@ void FV3_Rotate(vector3_t *rotVec, const vector3_t *axisVec, const angle_t angle
/// Fixed Point Matrix functions
void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z);
-#endif // defined NEED_FIXED_VECTOR
-
// The table values in tables.c are calculated with this many fractional bits.
#define FINE_FRACBITS 16
diff --git a/src/v_video.c b/src/v_video.c
index 64bf825bd..524c15cc7 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -635,7 +635,7 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
else
{
- spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK];
+ spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
diff --git a/src/w_wad.c b/src/w_wad.c
index 79ed1f478..9d6a11fb5 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -413,6 +413,7 @@ UINT16 W_LoadWadFile(const char *filename)
lump_p->disksize -= 4;
}
else lump_p->compressed = 0;
+ memset(lump_p->name, 0x00, 9);
strncpy(lump_p->name, fileinfo->name, 8);
}
free(fileinfov);
diff --git a/src/win32/Srb2win.ico b/src/win32/Srb2win.ico
index e369735ef..700276fd4 100644
Binary files a/src/win32/Srb2win.ico and b/src/win32/Srb2win.ico differ
diff --git a/src/win32ce/Srb2win.ico b/src/win32ce/Srb2win.ico
index 0036a827a..700276fd4 100644
Binary files a/src/win32ce/Srb2win.ico and b/src/win32ce/Srb2win.ico differ
diff --git a/tools/anglechk.c b/tools/anglechk.c
index bb9c4d9ea..4a67069bf 100644
--- a/tools/anglechk.c
+++ b/tools/anglechk.c
@@ -351,6 +351,13 @@ int main(int argc, char** argv)
return 0;
}
+static void *cpu_cpy(void *dest, const void *src, size_t n)
+{
+ return memcpy(dest, src, n);
+}
+
+void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy;
+
void I_Error(const char *error, ...)
{
(void)error;