Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
117 results
Select Git revision
Show changes
Commits on Source (40)
...@@ -104,6 +104,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ...@@ -104,6 +104,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
lua_hudlib_drawlist.c lua_hudlib_drawlist.c
lua_colorlib.c lua_colorlib.c
lua_inputlib.c lua_inputlib.c
lua_interceptlib.c
) )
# This updates the modification time for comptime.c at the # This updates the modification time for comptime.c at the
......
...@@ -98,3 +98,4 @@ lua_hudlib.c ...@@ -98,3 +98,4 @@ lua_hudlib.c
lua_hudlib_drawlist.c lua_hudlib_drawlist.c
lua_inputlib.c lua_inputlib.c
lua_colorlib.c lua_colorlib.c
lua_interceptlib.c
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "g_game.h" // Joystick axes (for lua) #include "g_game.h" // Joystick axes (for lua)
#include "i_joy.h" #include "i_joy.h"
#include "g_input.h" // Game controls (for lua) #include "g_input.h" // Game controls (for lua)
#include "p_maputl.h" // P_PathTraverse constants (for lua)
#include "deh_tables.h" #include "deh_tables.h"
...@@ -5829,6 +5830,11 @@ struct int_const_s const INT_CONST[] = { ...@@ -5829,6 +5830,11 @@ struct int_const_s const INT_CONST[] = {
{"MB_BUTTON8",MB_BUTTON8}, {"MB_BUTTON8",MB_BUTTON8},
{"MB_SCROLLUP",MB_SCROLLUP}, {"MB_SCROLLUP",MB_SCROLLUP},
{"MB_SCROLLDOWN",MB_SCROLLDOWN}, {"MB_SCROLLDOWN",MB_SCROLLDOWN},
// P_PathTraverse constants
{"PT_ADDLINES",PT_ADDLINES},
{"PT_ADDTHINGS",PT_ADDTHINGS},
{"PT_EARLYOUT",PT_EARLYOUT},
// screen.h constants // screen.h constants
{"BASEVIDWIDTH",BASEVIDWIDTH}, {"BASEVIDWIDTH",BASEVIDWIDTH},
......
...@@ -4589,9 +4589,9 @@ void F_TextPromptDrawer(void) ...@@ -4589,9 +4589,9 @@ void F_TextPromptDrawer(void)
players[j].powers[pw_nocontrol] = 1;\ players[j].powers[pw_nocontrol] = 1;\
if (players[j].mo)\ if (players[j].mo)\
{\ {\
if (players[j].mo->state == states+S_PLAY_STND && players[j].mo->tics != -1)\ if (P_IsPlayerInState(&players[j], S_PLAY_STND) && players[j].mo->tics != -1)\
players[j].mo->tics++;\ players[j].mo->tics++;\
else if (players[j].mo->state == states+S_PLAY_WAIT)\ else if (P_IsPlayerInState(&players[j], S_PLAY_WAIT))\
P_SetMobjState(players[j].mo, S_PLAY_STND);\ P_SetMobjState(players[j].mo, S_PLAY_STND);\
}\ }\
} }
......
...@@ -4518,7 +4518,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = ...@@ -4518,7 +4518,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_pop, // deathsound sfx_pop, // deathsound
0, // speed 0, // speed
12*FRACUNIT, // radius 12*FRACUNIT, // radius
64*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 0, // display offset
100, // mass 100, // mass
0, // damage 0, // damage
......
...@@ -240,6 +240,8 @@ static const struct { ...@@ -240,6 +240,8 @@ static const struct {
{META_KEYEVENT, "keyevent_t"}, {META_KEYEVENT, "keyevent_t"},
{META_TEXTEVENT, "textevent_t"}, {META_TEXTEVENT, "textevent_t"},
{META_MOUSE, "mouse_t"}, {META_MOUSE, "mouse_t"},
{META_INTERCEPT, "intercept_t"},
{NULL, NULL} {NULL, NULL}
}; };
......
...@@ -1158,6 +1158,7 @@ enum mobjinfo_e ...@@ -1158,6 +1158,7 @@ enum mobjinfo_e
mobjinfo_activesound, mobjinfo_activesound,
mobjinfo_flags, mobjinfo_flags,
mobjinfo_raisestate, mobjinfo_raisestate,
mobjinfo_name,
}; };
const char *const mobjinfo_opt[] = { const char *const mobjinfo_opt[] = {
...@@ -1185,6 +1186,7 @@ const char *const mobjinfo_opt[] = { ...@@ -1185,6 +1186,7 @@ const char *const mobjinfo_opt[] = {
"activesound", "activesound",
"flags", "flags",
"raisestate", "raisestate",
"name",
NULL, NULL,
}; };
...@@ -1199,6 +1201,8 @@ static int mobjinfo_get(lua_State *L) ...@@ -1199,6 +1201,8 @@ static int mobjinfo_get(lua_State *L)
I_Assert(info != NULL); I_Assert(info != NULL);
I_Assert(info >= mobjinfo); I_Assert(info >= mobjinfo);
mobjtype_t id = info-mobjinfo;
switch (field) switch (field)
{ {
case mobjinfo_doomednum: case mobjinfo_doomednum:
...@@ -1273,6 +1277,21 @@ static int mobjinfo_get(lua_State *L) ...@@ -1273,6 +1277,21 @@ static int mobjinfo_get(lua_State *L)
case mobjinfo_raisestate: case mobjinfo_raisestate:
lua_pushinteger(L, info->raisestate); lua_pushinteger(L, info->raisestate);
break; break;
case mobjinfo_name:
if (id < MT_FIRSTFREESLOT)
{
lua_pushstring(L, MOBJTYPE_LIST[id]+3);
return 1;
}
id -= MT_FIRSTFREESLOT;
if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id])
{
lua_pushstring(L, FREE_MOBJS[id]);
return 1;
}
return 0;
default: default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2024-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_interceptlib.c
/// \brief intercept library for Lua scripting
#include "doomdef.h"
#include "fastcmp.h"
#include "p_local.h"
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#define NOHUD if (hud_running)\
return luaL_error(L, "HUD rendering code should not call this function!");
enum intercept_e {
intercept_valid = 0,
intercept_frac,
intercept_thing,
intercept_line
};
static const char *const intercept_opt[] = {
"valid",
"frac",
"thing",
"line",
NULL};
static int intercept_fields_ref = LUA_NOREF;
static boolean Lua_PathTraverser(intercept_t *in)
{
boolean traverse = false;
I_Assert(in != NULL);
lua_settop(gL, 6);
lua_pushcfunction(gL, LUA_GetErrorMessage);
I_Assert(lua_isfunction(gL, -2));
lua_pushvalue(gL, -2);
LUA_PushUserdata(gL, in, META_INTERCEPT);
LUA_Call(gL, 1, 1, -3);
traverse = lua_toboolean(gL, -1);
lua_pop(gL, 1);
return !traverse; // Stay consistent with the MobjMoveCollide hook
}
static int intercept_get(lua_State *L)
{
intercept_t *in = *((intercept_t **)luaL_checkudata(L, 1, META_INTERCEPT));
enum intercept_e field = Lua_optoption(L, 2, intercept_valid, intercept_fields_ref);
if (!in)
{
if (field == intercept_valid) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed intercept_t doesn't exist anymore.");
}
switch(field)
{
case intercept_valid: // valid
lua_pushboolean(L, 1);
return 1;
case intercept_frac:
lua_pushfixed(L, in->frac);
return 1;
case intercept_thing:
if (in->isaline)
return 0;
LUA_PushUserdata(L, in->d.thing, META_MOBJ);
return 1;
case intercept_line:
if (!in->isaline)
return 0;
LUA_PushUserdata(L, in->d.line, META_LINE);
return 1;
}
return 0;
}
static int lib_pPathTraverse(lua_State *L)
{
fixed_t px1 = luaL_checkfixed(L, 1);
fixed_t py1 = luaL_checkfixed(L, 2);
fixed_t px2 = luaL_checkfixed(L, 3);
fixed_t py2 = luaL_checkfixed(L, 4);
INT32 flags = (INT32)luaL_checkinteger(L, 5);
luaL_checktype(L, 6, LUA_TFUNCTION);
NOHUD
INLEVEL
lua_pushboolean(L, P_PathTraverse(px1, py1, px2, py2, flags, Lua_PathTraverser));
return 1;
}
int LUA_InterceptLib(lua_State *L)
{
LUA_RegisterUserdataMetatable(L, META_INTERCEPT, intercept_get, NULL, NULL);
intercept_fields_ref = Lua_CreateFieldTable(L, intercept_opt);
lua_register(L, "P_PathTraverse", lib_pPathTraverse);
return 0;
}
...@@ -98,6 +98,8 @@ extern boolean ignoregameinputs; ...@@ -98,6 +98,8 @@ extern boolean ignoregameinputs;
#define META_KEYEVENT "KEYEVENT_T*" #define META_KEYEVENT "KEYEVENT_T*"
#define META_MOUSE "MOUSE_T*" #define META_MOUSE "MOUSE_T*"
#define META_INTERCEPT "INTERCEPT_T*"
boolean luaL_checkboolean(lua_State *L, int narg); boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L); int LUA_EnumLib(lua_State *L);
...@@ -118,3 +120,4 @@ int LUA_BlockmapLib(lua_State *L); ...@@ -118,3 +120,4 @@ int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L); int LUA_HudLib(lua_State *L);
int LUA_ColorLib(lua_State *L); int LUA_ColorLib(lua_State *L);
int LUA_InputLib(lua_State *L); int LUA_InputLib(lua_State *L);
int LUA_InterceptLib(lua_State *L);
...@@ -62,6 +62,7 @@ static lua_CFunction liblist[] = { ...@@ -62,6 +62,7 @@ static lua_CFunction liblist[] = {
LUA_HudLib, // HUD stuff LUA_HudLib, // HUD stuff
LUA_ColorLib, // general color functions LUA_ColorLib, // general color functions
LUA_InputLib, // inputs LUA_InputLib, // inputs
LUA_InterceptLib, // intercept_t
NULL NULL
}; };
......
...@@ -11143,37 +11143,11 @@ static INT32 menuRoomIndex = 0; ...@@ -11143,37 +11143,11 @@ static INT32 menuRoomIndex = 0;
static void M_DrawRoomMenu(void) static void M_DrawRoomMenu(void)
{ {
static fixed_t frame = -(12 << FRACBITS);
int dot_frame;
char text[4];
const char *rmotd; const char *rmotd;
const char *waiting_message; const char *waiting_message;
int dots;
if (m_waiting_mode) if (m_waiting_mode)
{ currentMenu->menuitems[0].text = "...";
dot_frame = (int)(frame >> FRACBITS) / 4;
dots = dot_frame + 3;
strcpy(text, " ");
if (dots > 0)
{
if (dot_frame < 0)
dot_frame = 0;
if (dot_frame != 3)
strncpy(&text[dot_frame], "...", min(dots, 3 - dot_frame));
}
frame += renderdeltatics;
while (frame >= (12 << FRACBITS))
frame -= 12 << FRACBITS;
currentMenu->menuitems[0].text = text;
}
// use generic drawer for cursor, items and title // use generic drawer for cursor, items and title
M_DrawGenericMenu(); M_DrawGenericMenu();
......
...@@ -6109,7 +6109,7 @@ void A_UnidusBall(mobj_t *actor) ...@@ -6109,7 +6109,7 @@ void A_UnidusBall(mobj_t *actor)
else if (locvar1 == 2) else if (locvar1 == 2)
{ {
boolean skull = (actor->target->flags2 & MF2_SKULLFLY) == MF2_SKULLFLY; boolean skull = (actor->target->flags2 & MF2_SKULLFLY) == MF2_SKULLFLY;
if (actor->target->state == &states[actor->target->info->painstate]) if (P_IsMobjInPainState(actor->target))
{ {
P_KillMobj(actor, NULL, NULL, 0); P_KillMobj(actor, NULL, NULL, 0);
return; return;
......
...@@ -412,7 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -412,7 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
if (special->type == MT_STEAM) if (special->type == MT_STEAM)
{ {
if (player && player->mo->state == &states[player->mo->info->painstate]) // can't use gas jets when player is in pain! if (player && P_IsPlayerInState(player, S_PLAY_PAIN)) // can't use gas jets when player is in pain!
return; return;
fixed_t speed = special->info->mass; // gas jets use this for the vertical thrust fixed_t speed = special->info->mass; // gas jets use this for the vertical thrust
...@@ -1820,7 +1820,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -1820,7 +1820,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!player->climbing) if (!player->climbing)
{ {
if (player->bot && player->bot != BOT_MPAI && toucher->state-states != S_PLAY_GASP) if (player->bot && player->bot != BOT_MPAI && !P_IsPlayerInState(player, S_PLAY_GASP))
S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots
P_SetMobjState(toucher, S_PLAY_GASP); P_SetMobjState(toucher, S_PLAY_GASP);
P_ResetPlayer(player); P_ResetPlayer(player);
...@@ -1839,8 +1839,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -1839,8 +1839,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->z = toucher->z+toucher->height-FixedMul(8*FRACUNIT, special->scale); special->z = toucher->z+toucher->height-FixedMul(8*FRACUNIT, special->scale);
special->momz = 0; special->momz = 0;
special->flags |= MF_NOGRAVITY; special->flags |= MF_NOGRAVITY;
P_SetMobjState (special, special->info->deathstate); P_SetMobjState(special, special->info->deathstate);
S_StartSound (special, special->info->deathsound+(P_RandomKey(special->info->mass))); S_StartSound(special, special->info->deathsound+(P_RandomKey(special->info->mass)));
} }
return; return;
......
...@@ -130,6 +130,10 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); ...@@ -130,6 +130,10 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
void P_SlideCameraMove(camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
pflags_t P_GetJumpFlags(player_t *player); pflags_t P_GetJumpFlags(player_t *player);
statenum_t P_GetCanonicalPlayerState(player_t *player, statenum_t state);
boolean P_IsPlayerInState(player_t *player, statenum_t state);
boolean P_IsPlayerInSuperTransformationState(player_t *player);
boolean P_IsPlayerInNightsTransformationState(player_t *player);
boolean P_PlayerInPain(player_t *player); boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player); void P_ResetPlayer(player_t *player);
...@@ -553,5 +557,6 @@ void P_DoSuperDetransformation(player_t *player); ...@@ -553,5 +557,6 @@ void P_DoSuperDetransformation(player_t *player);
void P_ExplodeMissile(mobj_t *mo); void P_ExplodeMissile(mobj_t *mo);
void P_CheckGravity(mobj_t *mo, boolean affect); void P_CheckGravity(mobj_t *mo, boolean affect);
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope);
boolean P_IsMobjInPainState(mobj_t *mobj);
#endif // __P_LOCAL__ #endif // __P_LOCAL__
...@@ -508,7 +508,7 @@ static void P_DoFan(mobj_t *fan, mobj_t *object) ...@@ -508,7 +508,7 @@ static void P_DoFan(mobj_t *fan, mobj_t *object)
fixed_t speed = fan->info->mass; // fans use this for the vertical thrust fixed_t speed = fan->info->mass; // fans use this for the vertical thrust
SINT8 flipval = P_MobjFlip(fan); // virtually everything here centers around the thruster's gravity, not the object's! SINT8 flipval = P_MobjFlip(fan); // virtually everything here centers around the thruster's gravity, not the object's!
if (p && object->state == &states[object->info->painstate]) // can't use fans when player is in pain! if (p && P_IsPlayerInState(p, S_PLAY_PAIN)) // can't use fans when player is in pain!
return; return;
// is object's top below thruster's position? if not, calculate distance between their bottoms // is object's top below thruster's position? if not, calculate distance between their bottoms
...@@ -3033,7 +3033,7 @@ static boolean P_ThingHeightClip(mobj_t *thing) ...@@ -3033,7 +3033,7 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (tmfloorz > oldfloorz+thing->height) if (tmfloorz > oldfloorz+thing->height)
return true; return true;
bouncing = thing->player && thing->state-states == S_PLAY_BOUNCE_LANDING && P_IsObjectOnGround(thing); bouncing = thing->player && P_IsPlayerInState(thing->player, S_PLAY_BOUNCE_LANDING) && P_IsObjectOnGround(thing);
if ((onfloor || bouncing) && !(thing->flags & MF_NOGRAVITY) && floormoved) if ((onfloor || bouncing) && !(thing->flags & MF_NOGRAVITY) && floormoved)
{ {
......
...@@ -1056,7 +1056,7 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *), mobj_ ...@@ -1056,7 +1056,7 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *), mobj_
boolean checkthing = false; boolean checkthing = false;
if (thing) if (thing)
checkthing = true; checkthing = true;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
return true; return true;
...@@ -1434,7 +1434,7 @@ static boolean P_TraverseIntercepts(traverser_t func, fixed_t maxfrac) ...@@ -1434,7 +1434,7 @@ static boolean P_TraverseIntercepts(traverser_t func, fixed_t maxfrac)
if (dist > maxfrac) if (dist > maxfrac)
return true; // Checked everything in range. return true; // Checked everything in range.
if (!func(in)) if (!func(in))
return false; // Don't bother going farther. return false; // Don't bother going farther.
...@@ -1462,7 +1462,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, ...@@ -1462,7 +1462,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
validcount++; validcount++;
intercept_p = intercepts; intercept_p = intercepts;
if (((px1 - bmaporgx) & (MAPBLOCKSIZE-1)) == 0) if (((px1 - bmaporgx) & (MAPBLOCKSIZE-1)) == 0)
px1 += FRACUNIT; // Don't side exactly on a line. px1 += FRACUNIT; // Don't side exactly on a line.
...@@ -1475,7 +1475,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, ...@@ -1475,7 +1475,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
trace.dy = py2 - py1; trace.dy = py2 - py1;
xt1 = px1>>MAPBLOCKSHIFT; xt1 = px1>>MAPBLOCKSHIFT;
yt1 = py2>>MAPBLOCKSHIFT; yt1 = py1>>MAPBLOCKSHIFT;
px1 = (unsigned)(px1 - bmaporgx); px1 = (unsigned)(px1 - bmaporgx);
py1 = (unsigned)(py1 - bmaporgy); py1 = (unsigned)(py1 - bmaporgy);
...@@ -1624,6 +1624,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, ...@@ -1624,6 +1624,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
break; break;
} }
} }
// Go through the sorted list // Go through the sorted list
return P_TraverseIntercepts(trav, FRACUNIT); return P_TraverseIntercepts(trav, FRACUNIT);
} }
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "p_slopes.h" #include "p_slopes.h"
#include "f_finale.h" #include "f_finale.h"
#include "m_cond.h" #include "m_cond.h"
#include "simple_hashmap.h"
#include "netcode/net_command.h" #include "netcode/net_command.h"
static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
...@@ -178,6 +179,61 @@ static void P_CycleMobjState(mobj_t *mobj) ...@@ -178,6 +179,61 @@ static void P_CycleMobjState(mobj_t *mobj)
} }
} }
static panim_t GetPlayerAnimationFromState(player_t *player, statenum_t state)
{
switch(P_GetCanonicalPlayerState(player, state))
{
case S_PLAY_STND:
case S_PLAY_WAIT:
case S_PLAY_NIGHTS_STAND:
return PA_IDLE;
case S_PLAY_EDGE:
return PA_EDGE;
case S_PLAY_WALK:
case S_PLAY_SKID:
case S_PLAY_FLOAT:
return PA_WALK;
case S_PLAY_RUN:
case S_PLAY_FLOAT_RUN:
return PA_RUN;
case S_PLAY_DASH:
return PA_DASH;
case S_PLAY_PAIN:
case S_PLAY_STUN:
return PA_PAIN;
case S_PLAY_ROLL:
//case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes...
case S_PLAY_NIGHTS_ATTACK:
return PA_ROLL;
case S_PLAY_JUMP:
return PA_JUMP;
case S_PLAY_SPRING:
return PA_SPRING;
case S_PLAY_FALL:
case S_PLAY_NIGHTS_FLOAT:
return PA_FALL;
case S_PLAY_FLY:
case S_PLAY_FLY_TIRED:
case S_PLAY_SWIM:
case S_PLAY_GLIDE:
case S_PLAY_BOUNCE:
case S_PLAY_BOUNCE_LANDING:
case S_PLAY_TWINSPIN:
return PA_ABILITY;
case S_PLAY_SPINDASH: // ...but the act of SPINDASHING is charability2 specific.
case S_PLAY_FIRE:
case S_PLAY_FIRE_FINISH:
case S_PLAY_MELEE:
case S_PLAY_MELEE_FINISH:
case S_PLAY_MELEE_LANDING:
return PA_ABILITY2;
case S_PLAY_RIDE:
return PA_RIDE;
default:
return PA_ETC;
}
}
// //
// P_SetPlayerMobjState // P_SetPlayerMobjState
// Returns true if the mobj is still present. // Returns true if the mobj is still present.
...@@ -201,6 +257,12 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) ...@@ -201,6 +257,12 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state); I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state);
#endif #endif
// If the state has been overriden for this skin, use the replacement instead
statenum_t customskinstate;
SIMPLEHASH_FIND_INT(skins[player->skin]->defaulttocustomstate, hashentry_int32_int32_t, state, S_NULL, customskinstate)
if (customskinstate)
state = customskinstate;
// Catch falling for nojumpspin // Catch falling for nojumpspin
if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0)) if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0))
return P_SetPlayerMobjState(mobj, S_PLAY_FALL); return P_SetPlayerMobjState(mobj, S_PLAY_FALL);
...@@ -222,88 +284,24 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) ...@@ -222,88 +284,24 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
{ {
if (state == S_PLAY_JUMP) if (state == S_PLAY_JUMP)
{ {
if (player->mo->state-states == S_PLAY_WALK) if (P_IsPlayerInState(player, S_PLAY_WALK))
return P_SetPlayerMobjState(mobj, S_PLAY_FLOAT); return P_SetPlayerMobjState(mobj, S_PLAY_FLOAT);
return true; return true;
} }
else if (player->mo->state-states == S_PLAY_FLOAT && state == S_PLAY_STND) else if (P_IsPlayerInState(player, S_PLAY_FLOAT) && state == S_PLAY_STND)
return true; return true;
} }
// You were in pain state after taking a hit, and you're moving out of pain state now? // You were in pain state after taking a hit, and you're moving out of pain state now?
else if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == flashingtics && state != mobj->info->painstate) else if (P_IsPlayerInState(player, S_PLAY_PAIN)
&& player->powers[pw_flashing] == flashingtics
&& P_GetCanonicalPlayerState(player, state) != S_PLAY_PAIN)
{ {
// Start flashing, since you've landed. // Start flashing, since you've landed.
player->powers[pw_flashing] = flashingtics-1; player->powers[pw_flashing] = flashingtics-1;
P_DoPityCheck(player); P_DoPityCheck(player);
} }
// Set animation state player->panim = GetPlayerAnimationFromState(player, state);
// The pflags version of this was just as convoluted.
switch(state)
{
case S_PLAY_STND:
case S_PLAY_WAIT:
case S_PLAY_NIGHTS_STAND:
player->panim = PA_IDLE;
break;
case S_PLAY_EDGE:
player->panim = PA_EDGE;
break;
case S_PLAY_WALK:
case S_PLAY_SKID:
case S_PLAY_FLOAT:
player->panim = PA_WALK;
break;
case S_PLAY_RUN:
case S_PLAY_FLOAT_RUN:
player->panim = PA_RUN;
break;
case S_PLAY_DASH:
player->panim = PA_DASH;
break;
case S_PLAY_PAIN:
case S_PLAY_STUN:
player->panim = PA_PAIN;
break;
case S_PLAY_ROLL:
//case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes...
case S_PLAY_NIGHTS_ATTACK:
player->panim = PA_ROLL;
break;
case S_PLAY_JUMP:
player->panim = PA_JUMP;
break;
case S_PLAY_SPRING:
player->panim = PA_SPRING;
break;
case S_PLAY_FALL:
case S_PLAY_NIGHTS_FLOAT:
player->panim = PA_FALL;
break;
case S_PLAY_FLY:
case S_PLAY_FLY_TIRED:
case S_PLAY_SWIM:
case S_PLAY_GLIDE:
case S_PLAY_BOUNCE:
case S_PLAY_BOUNCE_LANDING:
case S_PLAY_TWINSPIN:
player->panim = PA_ABILITY;
break;
case S_PLAY_SPINDASH: // ...but the act of SPINDASHING is charability2 specific.
case S_PLAY_FIRE:
case S_PLAY_FIRE_FINISH:
case S_PLAY_MELEE:
case S_PLAY_MELEE_FINISH:
case S_PLAY_MELEE_LANDING:
player->panim = PA_ABILITY2;
break;
case S_PLAY_RIDE:
player->panim = PA_RIDE;
break;
default:
player->panim = PA_ETC;
break;
}
if (recursion++) // if recursion detected, if (recursion++) // if recursion detected,
memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table
...@@ -3717,7 +3715,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) ...@@ -3717,7 +3715,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
// momentum movement // momentum movement
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
if (mobj->state-states == S_PLAY_BOUNCE_LANDING) if (P_IsPlayerInState(mobj->player, S_PLAY_BOUNCE_LANDING))
goto animonly; // no need for checkposition - doesn't move at ALL goto animonly; // no need for checkposition - doesn't move at ALL
// Zoom tube // Zoom tube
...@@ -14365,3 +14363,11 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo ...@@ -14365,3 +14363,11 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
return newmobj; return newmobj;
} }
boolean P_IsMobjInPainState(mobj_t *mobj)
{
if (mobj->player)
return P_IsPlayerInState(mobj->player, S_PLAY_PAIN);
else
return (mobj->state == &states[mobj->info->painstate]);
}
...@@ -4677,7 +4677,7 @@ static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end) ...@@ -4677,7 +4677,7 @@ static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end)
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
if (player->mo->state-states != S_PLAY_ROLL) if (!P_IsPlayerInState(player, S_PLAY_ROLL))
{ {
P_SetMobjState(player->mo, S_PLAY_ROLL); P_SetMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin); S_StartSound(player->mo, sfx_spin);
...@@ -4758,7 +4758,7 @@ static void P_ProcessRopeHang(player_t *player, mtag_t sectag) ...@@ -4758,7 +4758,7 @@ static void P_ProcessRopeHang(player_t *player, mtag_t sectag)
if (player->cmd.buttons & BT_SPIN) if (player->cmd.buttons & BT_SPIN)
return; return;
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate]) if (!(player->pflags & PF_SLIDING) && P_IsPlayerInState(player, S_PLAY_PAIN))
return; return;
if (player->exiting) if (player->exiting)
...@@ -8805,7 +8805,7 @@ void T_Pusher(pusher_t *p) ...@@ -8805,7 +8805,7 @@ void T_Pusher(pusher_t *p)
if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
continue; continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics)) if (thing->player && P_IsPlayerInState(thing->player, S_PLAY_PAIN) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics))
continue; continue;
inFOF = touching = moved = false; inFOF = touching = moved = false;
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "m_cheat.h" #include "m_cheat.h"
// Thok camera snap (ctrl-f "chalupa") // Thok camera snap (ctrl-f "chalupa")
#include "g_input.h" #include "g_input.h"
#include "simple_hashmap.h"
#ifdef HW3SOUND #ifdef HW3SOUND
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
...@@ -968,6 +969,33 @@ pflags_t P_GetJumpFlags(player_t *player) ...@@ -968,6 +969,33 @@ pflags_t P_GetJumpFlags(player_t *player)
return PF_JUMPED; return PF_JUMPED;
} }
// If the state is a custom state for the player's skin, retrieve its "canonical" state
// e.g. S_SKIN_BIGTHECAT_WALK => S_PLAY_WALK
statenum_t P_GetCanonicalPlayerState(player_t *player, statenum_t state)
{
skin_t *skin = skins[player->skin];
statenum_t mappedstate;
SIMPLEHASH_FIND_INT(skin->customtodefaultstate, hashentry_int32_int32_t, state, state, mappedstate)
return mappedstate;
}
boolean P_IsPlayerInState(player_t *player, statenum_t state)
{
return (P_GetCanonicalPlayerState(player, player->mo->state - states) == state);
}
boolean P_IsPlayerInSuperTransformationState(player_t *player)
{
statenum_t state = player->mo->state - states;
return (state >= S_PLAY_SUPER_TRANS1 && state <= S_PLAY_SUPER_TRANS6);
}
boolean P_IsPlayerInNightsTransformationState(player_t *player)
{
statenum_t state = player->mo->state - states;
return (state >= S_PLAY_NIGHTS_TRANS1 && state <= S_PLAY_NIGHTS_TRANS6);
}
// //
// P_PlayerInPain // P_PlayerInPain
// //
...@@ -983,7 +1011,7 @@ boolean P_PlayerInPain(player_t *player) ...@@ -983,7 +1011,7 @@ boolean P_PlayerInPain(player_t *player)
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing]) if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing])
return true; return true;
if (player->mo->state == &states[S_PLAY_STUN]) if (P_IsPlayerInState(player, S_PLAY_STUN))
return true; return true;
return false; return false;
...@@ -1007,7 +1035,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) ...@@ -1007,7 +1035,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
fixed_t fallbackspeed; fixed_t fallbackspeed;
P_ResetPlayer(player); P_ResetPlayer(player);
P_SetMobjState(player->mo, player->mo->info->painstate); P_SetMobjState(player->mo, S_PLAY_PAIN);
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z--; player->mo->z--;
...@@ -2390,7 +2418,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ...@@ -2390,7 +2418,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (player->pflags & PF_BOUNCING) if (player->pflags & PF_BOUNCING)
{ {
if (dorollstuff && player->mo->state-states != S_PLAY_BOUNCE_LANDING) if (dorollstuff && !P_IsPlayerInState(player, S_PLAY_BOUNCE_LANDING))
{ {
P_MobjCheckWater(player->mo); P_MobjCheckWater(player->mo);
player->mo->momz *= -1; player->mo->momz *= -1;
...@@ -2427,9 +2455,9 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ...@@ -2427,9 +2455,9 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
player->pflags &= ~PF_GLIDING; player->pflags &= ~PF_GLIDING;
} }
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY)) else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY))
&& (player->mo->floorz != player->mo->watertop) && player->mo->state-states == S_PLAY_FALL) && (player->mo->floorz != player->mo->watertop) && P_IsPlayerInState(player, S_PLAY_FALL))
{ {
if (player->mo->state-states != S_PLAY_GLIDE_LANDING) if (!P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
{ {
P_ResetPlayer(player); P_ResetPlayer(player);
P_SetMobjState(player->mo, S_PLAY_GLIDE_LANDING); P_SetMobjState(player->mo, S_PLAY_GLIDE_LANDING);
...@@ -2450,7 +2478,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ...@@ -2450,7 +2478,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
else if (player->charability2 == CA2_MELEE else if (player->charability2 == CA2_MELEE
&& ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY && player->cmd.buttons & (BT_JUMP|BT_SPIN)))) && ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY && player->cmd.buttons & (BT_JUMP|BT_SPIN))))
{ {
if (player->mo->state-states != S_PLAY_MELEE_LANDING) if (!P_IsPlayerInState(player, S_PLAY_MELEE_LANDING))
{ {
mobjtype_t type = player->revitem; mobjtype_t type = player->revitem;
P_SetMobjState(player->mo, S_PLAY_MELEE_LANDING); P_SetMobjState(player->mo, S_PLAY_MELEE_LANDING);
...@@ -2498,7 +2526,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ...@@ -2498,7 +2526,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
} }
} }
} }
else if (player->charability == CA_GLIDEANDCLIMB && (player->mo->state-states == S_PLAY_GLIDE_LANDING)) else if (player->charability == CA_GLIDEANDCLIMB && (P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING)))
; ;
else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
; ;
...@@ -2521,10 +2549,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ...@@ -2521,10 +2549,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH) if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH)
P_SetMobjState(player->mo, S_PLAY_DASH); P_SetMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= runspd else if (player->speed >= runspd
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) && (player->panim != PA_RUN || P_IsPlayerInState(player, S_PLAY_FLOAT_RUN)))
P_SetMobjState(player->mo, S_PLAY_RUN); P_SetMobjState(player->mo, S_PLAY_RUN);
else if ((player->rmomx || player->rmomy) else if ((player->rmomx || player->rmomy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) && (player->panim != PA_WALK || P_IsPlayerInState(player, S_PLAY_FLOAT)))
P_SetMobjState(player->mo, S_PLAY_WALK); P_SetMobjState(player->mo, S_PLAY_WALK);
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE) else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
P_SetMobjState(player->mo, S_PLAY_STND); P_SetMobjState(player->mo, S_PLAY_STND);
...@@ -2534,10 +2562,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ...@@ -2534,10 +2562,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH) if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH)
P_SetMobjState(player->mo, S_PLAY_DASH); P_SetMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= runspd else if (player->speed >= runspd
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) && (player->panim != PA_RUN || P_IsPlayerInState(player, S_PLAY_FLOAT_RUN)))
P_SetMobjState(player->mo, S_PLAY_RUN); P_SetMobjState(player->mo, S_PLAY_RUN);
else if ((player->mo->momx || player->mo->momy) else if ((player->mo->momx || player->mo->momy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) && (player->panim != PA_WALK || P_IsPlayerInState(player, S_PLAY_FLOAT)))
P_SetMobjState(player->mo, S_PLAY_WALK); P_SetMobjState(player->mo, S_PLAY_WALK);
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE) else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
P_SetMobjState(player->mo, S_PLAY_STND); P_SetMobjState(player->mo, S_PLAY_STND);
...@@ -3711,9 +3739,9 @@ static void P_DoClimbing(player_t *player) ...@@ -3711,9 +3739,9 @@ static void P_DoClimbing(player_t *player)
climb = false; climb = false;
if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz) if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz)
&& player->mo->state-states != S_PLAY_CLIMB) && !P_IsPlayerInState(player, S_PLAY_CLIMB))
P_SetMobjState(player->mo, S_PLAY_CLIMB); P_SetMobjState(player->mo, S_PLAY_CLIMB);
else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING) else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && !P_IsPlayerInState(player, S_PLAY_CLING))
P_SetMobjState(player->mo, S_PLAY_CLING); P_SetMobjState(player->mo, S_PLAY_CLING);
if (!floorclimb) if (!floorclimb)
...@@ -3746,9 +3774,9 @@ static void P_DoClimbing(player_t *player) ...@@ -3746,9 +3774,9 @@ static void P_DoClimbing(player_t *player)
climb = false; climb = false;
if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz) if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz)
&& player->mo->state-states != S_PLAY_CLIMB) && !P_IsPlayerInState(player, S_PLAY_CLIMB))
P_SetMobjState(player->mo, S_PLAY_CLIMB); P_SetMobjState(player->mo, S_PLAY_CLIMB);
else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING) else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && !P_IsPlayerInState(player, S_PLAY_CLING))
P_SetMobjState(player->mo, S_PLAY_CLING); P_SetMobjState(player->mo, S_PLAY_CLING);
if (cmd->buttons & BT_SPIN && !(player->pflags & PF_JUMPSTASIS)) if (cmd->buttons & BT_SPIN && !(player->pflags & PF_JUMPSTASIS))
...@@ -4436,7 +4464,7 @@ static void P_DoSuperStuff(player_t *player) ...@@ -4436,7 +4464,7 @@ static void P_DoSuperStuff(player_t *player)
G_GhostAddColor(GHC_SUPER); G_GhostAddColor(GHC_SUPER);
if (player->mo->state == &states[S_PLAY_SUPER_TRANS6]) // stop here for now if (P_IsPlayerInState(player, S_PLAY_SUPER_TRANS6)) // stop here for now
return; return;
// Deplete one ring every second while super // Deplete one ring every second while super
...@@ -4719,7 +4747,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) ...@@ -4719,7 +4747,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{ {
boolean canstand = true; // can we stand on the ground? (mostly relevant for slopes) boolean canstand = true; // can we stand on the ground? (mostly relevant for slopes)
if (player->pflags & PF_STASIS if (player->pflags & PF_STASIS
&& (player->pflags & PF_JUMPSTASIS || player->mo->state-states != S_PLAY_GLIDE_LANDING)) && (player->pflags & PF_JUMPSTASIS || !P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING)))
return; return;
if (cmd->buttons & BT_SPIN) if (cmd->buttons & BT_SPIN)
...@@ -4739,7 +4767,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) ...@@ -4739,7 +4767,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{ {
case CA2_SPINDASH: // Spinning and Spindashing case CA2_SPINDASH: // Spinning and Spindashing
// Start revving // Start revving
if ((cmd->buttons & BT_SPIN) && (player->speed < FixedMul(5<<FRACBITS, player->mo->scale) || player->mo->state - states == S_PLAY_GLIDE_LANDING) if ((cmd->buttons & BT_SPIN) && (player->speed < FixedMul(5<<FRACBITS, player->mo->scale) || P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
&& !player->mo->momz && onground && !(player->pflags & (PF_SPINDOWN|PF_SPINNING)) && !player->mo->momz && onground && !(player->pflags & (PF_SPINDOWN|PF_SPINNING))
&& canstand) && canstand)
{ {
...@@ -5028,7 +5056,7 @@ void P_DoBubbleBounce(player_t *player) ...@@ -5028,7 +5056,7 @@ void P_DoBubbleBounce(player_t *player)
// //
void P_DoAbilityBounce(player_t *player, boolean changemomz) void P_DoAbilityBounce(player_t *player, boolean changemomz)
{ {
if (player->mo->state-states == S_PLAY_BOUNCE_LANDING) if (P_IsPlayerInState(player, S_PLAY_BOUNCE_LANDING))
return; return;
if (changemomz) if (changemomz)
...@@ -5202,7 +5230,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock ...@@ -5202,7 +5230,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
if (!P_MobjWasRemoved(visual)) if (!P_MobjWasRemoved(visual))
{ {
P_SetTarget(&visual->target, lockonshield); P_SetTarget(&visual->target, lockonshield);
visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
P_SetMobjStateNF(visual, visual->info->spawnstate+1); P_SetMobjStateNF(visual, visual->info->spawnstate+1);
} }
} }
...@@ -6109,7 +6137,7 @@ static void P_3dMovement(player_t *player) ...@@ -6109,7 +6137,7 @@ static void P_3dMovement(player_t *player)
// When sliding, don't allow forward/back // When sliding, don't allow forward/back
if (player->pflags & PF_SLIDING) if (player->pflags & PF_SLIDING)
cmd->forwardmove = 0; cmd->forwardmove = 0;
else if (onground && player->mo->state == states+S_PLAY_PAIN) else if (onground && P_IsPlayerInState(player, S_PLAY_PAIN))
P_SetMobjState(player->mo, S_PLAY_WALK); P_SetMobjState(player->mo, S_PLAY_WALK);
player->aiming = cmd->aiming<<FRACBITS; player->aiming = cmd->aiming<<FRACBITS;
...@@ -6162,7 +6190,7 @@ static void P_3dMovement(player_t *player) ...@@ -6162,7 +6190,7 @@ static void P_3dMovement(player_t *player)
{ {
if (player->pflags & PF_BOUNCING) if (player->pflags & PF_BOUNCING)
{ {
if (player->mo->state-states == S_PLAY_BOUNCE_LANDING) if (P_IsPlayerInState(player, S_PLAY_BOUNCE_LANDING))
{ {
thrustfactor = player->thrustfactor*8; thrustfactor = player->thrustfactor*8;
acceleration = player->accelstart/8 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/8; acceleration = player->accelstart/8 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/8;
...@@ -6915,10 +6943,10 @@ static void P_DoNiGHTSCapsule(player_t *player) ...@@ -6915,10 +6943,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
{ {
if (player->mo->momx || player->mo->momy || player->mo->momz) if (player->mo->momx || player->mo->momy || player->mo->momz)
{ {
if (player->mo->state != &states[S_PLAY_NIGHTS_PULL]) if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_PULL))
P_SetMobjState(player->mo, S_PLAY_NIGHTS_PULL); P_SetMobjState(player->mo, S_PLAY_NIGHTS_PULL);
} }
else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK]) else if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_ATTACK))
{ {
S_StartSound(player->mo, sfx_spin); S_StartSound(player->mo, sfx_spin);
P_SetMobjState(player->mo, S_PLAY_NIGHTS_ATTACK); P_SetMobjState(player->mo, S_PLAY_NIGHTS_ATTACK);
...@@ -6934,7 +6962,7 @@ static void P_DoNiGHTSCapsule(player_t *player) ...@@ -6934,7 +6962,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (!(player->charflags & SF_NONIGHTSROTATION)) if (!(player->charflags & SF_NONIGHTSROTATION))
{ {
if ((player->mo->state == &states[S_PLAY_NIGHTS_PULL]) if ((P_IsPlayerInState(player, S_PLAY_NIGHTS_PULL))
&& (player->mo->sprite2 == SPR2_NPUL)) && (player->mo->sprite2 == SPR2_NPUL))
player->mo->spriteroll -= ANG30; player->mo->spriteroll -= ANG30;
else else
...@@ -7249,15 +7277,11 @@ static void P_NiGHTSMovement(player_t *player) ...@@ -7249,15 +7277,11 @@ static void P_NiGHTSMovement(player_t *player)
if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/
&& (players[i].capsule && players[i].capsule->reactiontime)) && (players[i].capsule && players[i].capsule->reactiontime))
capsule = true; capsule = true;
if (!capsule if (!capsule && !P_IsPlayerInNightsTransformationState(player) && !player->exiting)
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
&& !player->exiting)
player->nightstime--; player->nightstime--;
} }
else if (!(gametyperules & GTR_RACE) else if (!(gametyperules & GTR_RACE)
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] && !P_IsPlayerInNightsTransformationState(player)
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
&& !(player->capsule && player->capsule->reactiontime) && !(player->capsule && player->capsule->reactiontime)
&& !player->exiting) && !player->exiting)
player->nightstime--; player->nightstime--;
...@@ -7397,8 +7421,7 @@ static void P_NiGHTSMovement(player_t *player) ...@@ -7397,8 +7421,7 @@ static void P_NiGHTSMovement(player_t *player)
return; return;
} }
if (player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] if (P_IsPlayerInNightsTransformationState(player))
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
{ {
player->mo->momx = player->mo->momy = player->mo->momz = 0; player->mo->momx = player->mo->momy = player->mo->momz = 0;
player->mo->spriteroll = 0; player->mo->spriteroll = 0;
...@@ -7417,14 +7440,14 @@ static void P_NiGHTSMovement(player_t *player) ...@@ -7417,14 +7440,14 @@ static void P_NiGHTSMovement(player_t *player)
#if 0//def ROTSPRITE #if 0//def ROTSPRITE
if (!(player->charflags & SF_NONIGHTSROTATION) && player->mo->momz) if (!(player->charflags & SF_NONIGHTSROTATION) && player->mo->momz)
{ {
if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL]) if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_DRILL))
P_SetMobjState(player->mo, S_PLAY_NIGHTS_DRILL); P_SetMobjState(player->mo, S_PLAY_NIGHTS_DRILL);
player->mo->spriteroll = ANGLE_90; player->mo->spriteroll = ANGLE_90;
} }
else else
#endif #endif
{ {
if (player->mo->state != &states[S_PLAY_NIGHTS_FLOAT]) if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_FLOAT))
P_SetMobjState(player->mo, S_PLAY_NIGHTS_FLOAT); P_SetMobjState(player->mo, S_PLAY_NIGHTS_FLOAT);
player->drawangle += ANGLE_22h; player->drawangle += ANGLE_22h;
} }
...@@ -8056,7 +8079,7 @@ static void P_SkidStuff(player_t *player) ...@@ -8056,7 +8079,7 @@ static void P_SkidStuff(player_t *player)
// Spawn a particle every 3 tics. // Spawn a particle every 3 tics.
if (!(player->skidtime % 3)) if (!(player->skidtime % 3))
{ {
if (player->mo->state-states == S_PLAY_GLIDE_LANDING) if (P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
P_SpawnSkidDust(player, player->mo->radius, true); P_SpawnSkidDust(player, player->mo->radius, true);
else else
P_SpawnSkidDust(player, 0, false); P_SpawnSkidDust(player, 0, false);
...@@ -8076,7 +8099,7 @@ static void P_SkidStuff(player_t *player) ...@@ -8076,7 +8099,7 @@ static void P_SkidStuff(player_t *player)
// If your push angle is more than this close to a full 180 degrees, trigger a skid. // If your push angle is more than this close to a full 180 degrees, trigger a skid.
if (dang > ANGLE_157h) if (dang > ANGLE_157h)
{ {
if (player->mo->state-states != S_PLAY_SKID) if (!P_IsPlayerInState(player, S_PLAY_SKID))
P_SetMobjState(player->mo, S_PLAY_SKID); P_SetMobjState(player->mo, S_PLAY_SKID);
player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
S_StartSound(player->mo, sfx_skid); S_StartSound(player->mo, sfx_skid);
...@@ -8100,7 +8123,7 @@ void P_MovePlayer(player_t *player) ...@@ -8100,7 +8123,7 @@ void P_MovePlayer(player_t *player)
fixed_t runspd; fixed_t runspd;
if (player->mo->state >= &states[S_PLAY_SUPER_TRANS1] && player->mo->state <= &states[S_PLAY_SUPER_TRANS6]) if (P_IsPlayerInSuperTransformationState(player))
{ {
player->mo->momx = player->mo->momy = player->mo->momz = 0; player->mo->momx = player->mo->momy = player->mo->momz = 0;
return; return;
...@@ -8121,7 +8144,7 @@ void P_MovePlayer(player_t *player) ...@@ -8121,7 +8144,7 @@ void P_MovePlayer(player_t *player)
if ((player->powers[pw_carry] == CR_BRAKGOOP) if ((player->powers[pw_carry] == CR_BRAKGOOP)
|| (player->pflags & PF_GLIDING && player->skidtime) || (player->pflags & PF_GLIDING && player->skidtime)
|| (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) || (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
|| (player->charability2 == CA2_MELEE && player->mo->state-states == S_PLAY_MELEE_LANDING)) || (player->charability2 == CA2_MELEE && P_IsPlayerInState(player, S_PLAY_MELEE_LANDING)))
player->pflags |= PF_FULLSTASIS; player->pflags |= PF_FULLSTASIS;
else if (player->powers[pw_nocontrol]) else if (player->powers[pw_nocontrol])
{ {
...@@ -8130,7 +8153,7 @@ void P_MovePlayer(player_t *player) ...@@ -8130,7 +8153,7 @@ void P_MovePlayer(player_t *player)
player->pflags |= PF_JUMPSTASIS; player->pflags |= PF_JUMPSTASIS;
} }
if (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) if (player->charability == CA_GLIDEANDCLIMB && P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
{ {
player->pflags |= PF_STASIS; player->pflags |= PF_STASIS;
} }
...@@ -8309,7 +8332,7 @@ void P_MovePlayer(player_t *player) ...@@ -8309,7 +8332,7 @@ void P_MovePlayer(player_t *player)
{ {
// If the player is in dashmode, here's their peelout. // If the player is in dashmode, here's their peelout.
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim == PA_RUN && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim == PA_RUN && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]))
P_SetMobjState (player->mo, S_PLAY_DASH); P_SetMobjState(player->mo, S_PLAY_DASH);
// If the player is moving fast enough, // If the player is moving fast enough,
// break into a run! // break into a run!
else if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime else if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime
...@@ -8323,11 +8346,11 @@ void P_MovePlayer(player_t *player) ...@@ -8323,11 +8346,11 @@ void P_MovePlayer(player_t *player)
// Floating at slow speeds has its own special animation. // Floating at slow speeds has its own special animation.
else if ((((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) && player->panim == PA_IDLE && !onground) else if ((((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) && player->panim == PA_IDLE && !onground)
P_SetMobjState (player->mo, S_PLAY_FLOAT); P_SetMobjState(player->mo, S_PLAY_FLOAT);
// Otherwise, just walk. // Otherwise, just walk.
else if ((player->rmomx || player->rmomy) && player->panim == PA_IDLE) else if ((player->rmomx || player->rmomy) && player->panim == PA_IDLE)
P_SetMobjState (player->mo, S_PLAY_WALK); P_SetMobjState(player->mo, S_PLAY_WALK);
} }
// If your peelout animation is playing, and you're // If your peelout animation is playing, and you're
...@@ -8348,9 +8371,9 @@ void P_MovePlayer(player_t *player) ...@@ -8348,9 +8371,9 @@ void P_MovePlayer(player_t *player)
// Correct floating when ending up on the ground. // Correct floating when ending up on the ground.
if (onground) if (onground)
{ {
if (player->mo->state-states == S_PLAY_FLOAT) if (P_IsPlayerInState(player, S_PLAY_FLOAT))
P_SetMobjState(player->mo, S_PLAY_WALK); P_SetMobjState(player->mo, S_PLAY_WALK);
else if (player->mo->state-states == S_PLAY_FLOAT_RUN) else if (P_IsPlayerInState(player, S_PLAY_FLOAT_RUN))
P_SetMobjState(player->mo, S_PLAY_RUN); P_SetMobjState(player->mo, S_PLAY_RUN);
} }
...@@ -8416,7 +8439,7 @@ void P_MovePlayer(player_t *player) ...@@ -8416,7 +8439,7 @@ void P_MovePlayer(player_t *player)
fixed_t glidespeed = player->actionspd; fixed_t glidespeed = player->actionspd;
fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy; fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy;
angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy); angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy);
boolean swimming = mo->state - states == S_PLAY_SWIM; boolean swimming = P_IsPlayerInState(player, S_PLAY_SWIM);
boolean in2d = mo->flags2 & MF2_TWOD || twodlevel; boolean in2d = mo->flags2 & MF2_TWOD || twodlevel;
if (player->powers[pw_super] || player->powers[pw_sneakers]) if (player->powers[pw_super] || player->powers[pw_sneakers])
...@@ -8563,7 +8586,7 @@ void P_MovePlayer(player_t *player) ...@@ -8563,7 +8586,7 @@ void P_MovePlayer(player_t *player)
} }
} }
} }
else if (player->mo->state-states == S_PLAY_BOUNCE) else if (P_IsPlayerInState(player, S_PLAY_BOUNCE))
P_SetMobjState(player->mo, S_PLAY_FALL); P_SetMobjState(player->mo, S_PLAY_FALL);
// If you're running fast enough, you can create splashes as you run in shallow water. // If you're running fast enough, you can create splashes as you run in shallow water.
...@@ -8607,7 +8630,7 @@ void P_MovePlayer(player_t *player) ...@@ -8607,7 +8630,7 @@ 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->charability == CA_FLY || player->charability == CA_SWIM)) // why are you flying when you cannot fly?!
{ {
if (player->powers[pw_tailsfly] if (player->powers[pw_tailsfly]
|| player->mo->state-states == S_PLAY_FLY_TIRED) || P_IsPlayerInState(player, S_PLAY_FLY_TIRED))
{ {
if (onground) if (onground)
P_SetMobjState(player->mo, S_PLAY_WALK); P_SetMobjState(player->mo, S_PLAY_WALK);
...@@ -8675,11 +8698,11 @@ void P_MovePlayer(player_t *player) ...@@ -8675,11 +8698,11 @@ void P_MovePlayer(player_t *player)
else else
{ {
// Tails-gets-tired Stuff // Tails-gets-tired Stuff
if (player->panim == PA_ABILITY && player->mo->state-states != S_PLAY_FLY_TIRED) if (player->panim == PA_ABILITY && !P_IsPlayerInState(player, S_PLAY_FLY_TIRED))
P_SetMobjState(player->mo, S_PLAY_FLY_TIRED); P_SetMobjState(player->mo, S_PLAY_FLY_TIRED);
if (player->charability == CA_FLY && (leveltime % 10 == 0) if (player->charability == CA_FLY && (leveltime % 10 == 0)
&& player->mo->state-states == S_PLAY_FLY_TIRED && P_IsPlayerInState(player, S_PLAY_FLY_TIRED)
&& !(player->mo->eflags & MFE_UNDERWATER) && !(player->mo->eflags & MFE_UNDERWATER)
&& !player->spectator) && !player->spectator)
S_StartSound(player->mo, sfx_pudpud); S_StartSound(player->mo, sfx_pudpud);
...@@ -8774,7 +8797,7 @@ void P_MovePlayer(player_t *player) ...@@ -8774,7 +8797,7 @@ void P_MovePlayer(player_t *player)
} }
// Otherwise, face the direction you're travelling. // Otherwise, face the direction you're travelling.
else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_DASH || player->panim == PA_ROLL || player->panim == PA_JUMP else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_DASH || player->panim == PA_ROLL || player->panim == PA_JUMP
|| (player->panim == PA_ABILITY && player->mo->state-states == S_PLAY_GLIDE)) || (player->panim == PA_ABILITY && P_IsPlayerInState(player, S_PLAY_GLIDE)))
player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
// Update the local angle control. // Update the local angle control.
...@@ -9035,7 +9058,7 @@ static void P_DoRopeHang(player_t *player) ...@@ -9035,7 +9058,7 @@ static void P_DoRopeHang(player_t *player)
return; return;
} }
if (player->mo->state-states != S_PLAY_RIDE) if (!P_IsPlayerInState(player, S_PLAY_RIDE))
P_SetMobjState(player->mo, S_PLAY_RIDE); P_SetMobjState(player->mo, S_PLAY_RIDE);
// If not allowed to move, we're done here. // If not allowed to move, we're done here.
...@@ -9972,9 +9995,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall ...@@ -9972,9 +9995,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
&& !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value) && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)
&& !(twodlevel || (mo->flags2 & MF2_TWOD))) && !(twodlevel || (mo->flags2 & MF2_TWOD)))
sign = mo->target; sign = mo->target;
else if ((player->powers[pw_carry] == CR_NIGHTSMODE) else if (player->powers[pw_carry] == CR_NIGHTSMODE && !P_IsPlayerInNightsTransformationState(player))
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]))
{ {
P_CalcChasePostImg(player, thiscam); P_CalcChasePostImg(player, thiscam);
return true; return true;
...@@ -11291,7 +11312,7 @@ static void P_MinecartThink(player_t *player) ...@@ -11291,7 +11312,7 @@ static void P_MinecartThink(player_t *player)
} }
} }
if (player->mo->state-states != S_PLAY_STND) if (!P_IsPlayerInState(player, S_PLAY_STND))
{ {
P_SetMobjState(player->mo, S_PLAY_STND); P_SetMobjState(player->mo, S_PLAY_STND);
player->mo->tics = -1; player->mo->tics = -1;
...@@ -11369,12 +11390,12 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) ...@@ -11369,12 +11390,12 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
} }
else if (player->panim == PA_PAIN) else if (player->panim == PA_PAIN)
backwards /= 16; backwards /= 16;
else if (player->mo->state-states == S_PLAY_GASP) else if (P_IsPlayerInState(player, S_PLAY_GASP))
{ {
backwards /= 16; backwards /= 16;
zoffs += 12*FRACUNIT; zoffs += 12*FRACUNIT;
} }
else if (player->mo->state-states == S_PLAY_EDGE) else if (P_IsPlayerInState(player, S_PLAY_EDGE))
{ {
backwards /= 16; backwards /= 16;
zoffs = 3*FRACUNIT; zoffs = 3*FRACUNIT;
...@@ -11403,13 +11424,13 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) ...@@ -11403,13 +11424,13 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
} }
else if (player->panim == PA_SPRING || player->panim == PA_JUMP) else if (player->panim == PA_SPRING || player->panim == PA_JUMP)
chosenstate = S_TAILSOVERLAY_MINUS60DEGREES; chosenstate = S_TAILSOVERLAY_MINUS60DEGREES;
else if (player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE) else if (player->panim == PA_FALL || P_IsPlayerInState(player, S_PLAY_RIDE))
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES; chosenstate = S_TAILSOVERLAY_PLUS60DEGREES;
else if (player->panim == PA_PAIN) else if (player->panim == PA_PAIN)
chosenstate = S_TAILSOVERLAY_PAIN; chosenstate = S_TAILSOVERLAY_PAIN;
else if (player->mo->state-states == S_PLAY_GASP) else if (P_IsPlayerInState(player, S_PLAY_GASP))
chosenstate = S_TAILSOVERLAY_GASP; chosenstate = S_TAILSOVERLAY_GASP;
else if (player->mo->state-states == S_PLAY_EDGE) else if (P_IsPlayerInState(player, S_PLAY_EDGE))
chosenstate = S_TAILSOVERLAY_EDGE; chosenstate = S_TAILSOVERLAY_EDGE;
else if (player->panim == PA_DASH) else if (player->panim == PA_DASH)
chosenstate = S_TAILSOVERLAY_DASH; chosenstate = S_TAILSOVERLAY_DASH;
...@@ -11417,7 +11438,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) ...@@ -11417,7 +11438,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
chosenstate = S_TAILSOVERLAY_RUN; chosenstate = S_TAILSOVERLAY_RUN;
else if (player->panim == PA_WALK) else if (player->panim == PA_WALK)
{ {
if (!smilesonground || player->mo->state-states == S_PLAY_SKID) if (!smilesonground || P_IsPlayerInState(player, S_PLAY_SKID))
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES; chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale)) else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale))
chosenstate = S_TAILSOVERLAY_0DEGREES; chosenstate = S_TAILSOVERLAY_0DEGREES;
...@@ -11459,7 +11480,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) ...@@ -11459,7 +11480,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
#endif #endif
// animation... // animation...
if (player->panim == PA_SPRING || player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE) if (player->panim == PA_SPRING || player->panim == PA_FALL || P_IsPlayerInState(player, S_PLAY_RIDE))
{ {
if (FixedDiv(abs(player->mo->momz), player->mo->scale) < 20<<FRACBITS) if (FixedDiv(abs(player->mo->momz), player->mo->scale) < 20<<FRACBITS)
ticnum = 2; ticnum = 2;
...@@ -11468,7 +11489,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) ...@@ -11468,7 +11489,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
} }
else if (player->panim == PA_PAIN) else if (player->panim == PA_PAIN)
ticnum = 2; ticnum = 2;
else if (player->mo->state-states == S_PLAY_GASP) else if (P_IsPlayerInState(player, S_PLAY_GASP))
tails->tics = -1; tails->tics = -1;
else if (player->mo->sprite2 == SPR2_TIRE) else if (player->mo->sprite2 == SPR2_TIRE)
ticnum = (doswim ? 2 : 4); ticnum = (doswim ? 2 : 4);
...@@ -12291,10 +12312,9 @@ void P_PlayerThink(player_t *player) ...@@ -12291,10 +12312,9 @@ void P_PlayerThink(player_t *player)
diff = InvAngle(diff); diff = InvAngle(diff);
if (diff > ANG10/2) if (diff > ANG10/2)
{ {
statenum_t stat = player->mo->state-states; if (P_IsPlayerInState(player, S_PLAY_WAIT))
if (stat == S_PLAY_WAIT)
P_SetMobjState(player->mo, S_PLAY_STND); P_SetMobjState(player->mo, S_PLAY_STND);
else if (stat == S_PLAY_STND && player->mo->tics != -1) else if (P_IsPlayerInState(player, S_PLAY_STND) && player->mo->tics != -1)
player->mo->tics++; player->mo->tics++;
} }
} }
...@@ -12319,7 +12339,7 @@ void P_PlayerThink(player_t *player) ...@@ -12319,7 +12339,7 @@ void P_PlayerThink(player_t *player)
// fake skidding! see P_SkidStuff for reference on conditionals // fake skidding! see P_SkidStuff for reference on conditionals
else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl
{ {
if (player->mo->state-states != S_PLAY_SKID) if (!P_IsPlayerInState(player, S_PLAY_SKID))
P_SetMobjState(player->mo, S_PLAY_SKID); P_SetMobjState(player->mo, S_PLAY_SKID);
player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
...@@ -12490,16 +12510,14 @@ void P_PlayerThink(player_t *player) ...@@ -12490,16 +12510,14 @@ void P_PlayerThink(player_t *player)
player->stronganim = 0; player->stronganim = 0;
//pw_super acts as a timer now //pw_super acts as a timer now
if (player->powers[pw_super] if (player->powers[pw_super] && !P_IsPlayerInSuperTransformationState(player))
&& (player->mo->state < &states[S_PLAY_SUPER_TRANS1]
|| player->mo->state > &states[S_PLAY_SUPER_TRANS6]))
player->powers[pw_super]++; player->powers[pw_super]++;
if (player->powers[pw_carry] == CR_BRAKGOOP) if (player->powers[pw_carry] == CR_BRAKGOOP)
{ {
if (!player->powers[pw_flashing]) if (!player->powers[pw_flashing])
{ {
if (player->mo->state != &states[S_PLAY_STND]) if (!P_IsPlayerInState(player, S_PLAY_STND))
P_SetMobjState(player->mo, S_PLAY_STND); P_SetMobjState(player->mo, S_PLAY_STND);
else else
player->mo->tics = 2; player->mo->tics = 2;
...@@ -12864,7 +12882,7 @@ void P_PlayerAfterThink(player_t *player) ...@@ -12864,7 +12882,7 @@ void P_PlayerAfterThink(player_t *player)
S_StartSound(NULL, sfx_wepchg); S_StartSound(NULL, sfx_wepchg);
if ((player->pflags & PF_SLIDING) && ((player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) != PF_JUMPED)) if ((player->pflags & PF_SLIDING) && ((player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) != PF_JUMPED))
P_SetMobjState(player->mo, player->mo->info->painstate); P_SetMobjState(player->mo, S_PLAY_PAIN);
/* if (player->powers[pw_carry] == CR_NONE && player->mo->tracer && !player->homing) /* if (player->powers[pw_carry] == CR_NONE && player->mo->tracer && !player->homing)
P_SetTarget(&player->mo->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL);
...@@ -12924,7 +12942,7 @@ void P_PlayerAfterThink(player_t *player) ...@@ -12924,7 +12942,7 @@ void P_PlayerAfterThink(player_t *player)
if (player->powers[pw_carry] == CR_PLAYER) if (player->powers[pw_carry] == CR_PLAYER)
{ {
if (player->mo->state-states != S_PLAY_RIDE) if (!P_IsPlayerInState(player, S_PLAY_RIDE))
P_SetMobjState(player->mo, S_PLAY_RIDE); P_SetMobjState(player->mo, S_PLAY_RIDE);
if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER))
tails->player->powers[pw_tailsfly] = 0; tails->player->powers[pw_tailsfly] = 0;
...@@ -12949,7 +12967,7 @@ void P_PlayerAfterThink(player_t *player) ...@@ -12949,7 +12967,7 @@ void P_PlayerAfterThink(player_t *player)
player->mo->z = item->z - FixedDiv(player->mo->height, 3*FRACUNIT/2); player->mo->z = item->z - FixedDiv(player->mo->height, 3*FRACUNIT/2);
player->mo->momx = player->mo->momy = player->mo->momz = 0; player->mo->momx = player->mo->momy = player->mo->momz = 0;
P_SetThingPosition(player->mo); P_SetThingPosition(player->mo);
if (player->mo->state-states != S_PLAY_RIDE) if (!P_IsPlayerInState(player, S_PLAY_RIDE))
P_SetMobjState(player->mo, S_PLAY_RIDE); P_SetMobjState(player->mo, S_PLAY_RIDE);
// Controllable missile // Controllable missile
...@@ -13147,7 +13165,7 @@ void P_PlayerAfterThink(player_t *player) ...@@ -13147,7 +13165,7 @@ void P_PlayerAfterThink(player_t *player)
ptera->waterbottom >>= 1; ptera->waterbottom >>= 1;
ptera->cvmem >>= 1; ptera->cvmem >>= 1;
if (player->mo->state-states != S_PLAY_FALL) if (!P_IsPlayerInState(player, S_PLAY_FALL))
P_SetMobjState(player->mo, S_PLAY_FALL); P_SetMobjState(player->mo, S_PLAY_FALL);
break; break;
...@@ -13294,9 +13312,9 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) ...@@ -13294,9 +13312,9 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player)
return false; return false;
return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING)) // players who are spinning, sliding, or gliding return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING)) // players who are spinning, sliding, or gliding
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide || (player->charability == CA_GLIDEANDCLIMB && P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING)) // players who are landing from a glide
|| ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) || ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
&& player->dashmode >= DASHMODE_THRESHOLD && player->mo->state-states == S_PLAY_DASH) // machine players in dashmode && player->dashmode >= DASHMODE_THRESHOLD && P_IsPlayerInState(player, S_PLAY_DASH)) // machine players in dashmode
|| JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way
} }
...@@ -13304,13 +13322,13 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) ...@@ -13304,13 +13322,13 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player)
boolean P_PlayerShouldUseSpinHeight(player_t *player) boolean P_PlayerShouldUseSpinHeight(player_t *player)
{ {
return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING)) return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING))
|| (player->mo->state == &states[player->mo->info->painstate]) || P_IsPlayerInState(player, S_PLAY_PAIN)
|| (player->panim == PA_ROLL) || (player->panim == PA_ROLL)
|| ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && P_IsPlayerInState(player, S_PLAY_FLY_TIRED)))
&& !(player->charflags & SF_NOJUMPSPIN)) && !(player->charflags & SF_NOJUMPSPIN))
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_GLIDEANDCLIMB && P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
|| ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) || ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
&& player->dashmode >= DASHMODE_THRESHOLD && player->mo->state-states == S_PLAY_DASH) && player->dashmode >= DASHMODE_THRESHOLD && P_IsPlayerInState(player, S_PLAY_DASH))
|| JUMPCURLED(player)); || JUMPCURLED(player));
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "p_local.h" #include "p_local.h"
#include "dehacked.h" // get_number (for thok) #include "dehacked.h" // get_number (for thok)
#include "m_cond.h" #include "m_cond.h"
#include "deh_tables.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_md2.h" #include "hardware/hw_md2.h"
#endif #endif
...@@ -791,6 +792,88 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) ...@@ -791,6 +792,88 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
return true; return true;
} }
// e.g. "RUN" => S_PLAY_RUN, "RUN1" => S_PLAY_RUN, "RUN8" => S_PLAY_RUN
static statenum_t GetCanonicalPlayerStateNumByName(const char *name)
{
if (startswith(name, "STAND")) return S_PLAY_STND;
else if (startswith(name, "STND")) return S_PLAY_STND;
else if (startswith(name, "WAIT")) return S_PLAY_WAIT;
else if (startswith(name, "WALK")) return S_PLAY_WALK;
else if (startswith(name, "SKID")) return S_PLAY_SKID;
else if (startswith(name, "RUN")) return S_PLAY_RUN;
else if (startswith(name, "DASH")) return S_PLAY_DASH;
else if (startswith(name, "PAIN")) return S_PLAY_PAIN;
else if (startswith(name, "STUN")) return S_PLAY_STUN;
else if (startswith(name, "DEAD")) return S_PLAY_DEAD;
else if (startswith(name, "DRWN")) return S_PLAY_DRWN;
else if (startswith(name, "ROLL")) return S_PLAY_ROLL;
else if (startswith(name, "GASP")) return S_PLAY_GASP;
else if (startswith(name, "JUMP")) return S_PLAY_JUMP;
else if (startswith(name, "SPRING")) return S_PLAY_SPRING;
else if (startswith(name, "FALL")) return S_PLAY_FALL;
else if (startswith(name, "EDGE")) return S_PLAY_EDGE;
else if (startswith(name, "RIDE")) return S_PLAY_RIDE;
else if (startswith(name, "SPINDASH")) return S_PLAY_SPINDASH;
else if (startswith(name, "FLY")) return S_PLAY_FLY;
else if (startswith(name, "SWIM")) return S_PLAY_SWIM;
else if (startswith(name, "FLY_TIRED")) return S_PLAY_FLY_TIRED;
else if (startswith(name, "GLIDE")) return S_PLAY_GLIDE;
else if (startswith(name, "GLIDE_LANDING")) return S_PLAY_GLIDE_LANDING;
else if (startswith(name, "CLING")) return S_PLAY_CLING;
else if (startswith(name, "CLIMB")) return S_PLAY_CLIMB;
else if (startswith(name, "FLOAT")) return S_PLAY_FLOAT;
else if (startswith(name, "FLOAT_RUN")) return S_PLAY_FLOAT_RUN;
else if (startswith(name, "BOUNCE")) return S_PLAY_BOUNCE;
else if (startswith(name, "BOUNCE_LANDING")) return S_PLAY_BOUNCE_LANDING;
else if (startswith(name, "FIRE")) return S_PLAY_FIRE;
else if (startswith(name, "FIRE_FINISH")) return S_PLAY_FIRE_FINISH;
else if (startswith(name, "TWINSPIN")) return S_PLAY_TWINSPIN;
else if (startswith(name, "MELEE")) return S_PLAY_MELEE;
else if (startswith(name, "MELEE_FINISH")) return S_PLAY_MELEE_FINISH;
else if (startswith(name, "MELEE_LANDING")) return S_PLAY_MELEE_LANDING;
else if (startswith(name, "NIGHTS_STAND")) return S_PLAY_NIGHTS_STAND;
else if (startswith(name, "NIGHTS_FLOAT")) return S_PLAY_NIGHTS_FLOAT;
else if (startswith(name, "NIGHTS_FLY")) return S_PLAY_NIGHTS_FLY;
else if (startswith(name, "NIGHTS_DRILL")) return S_PLAY_NIGHTS_DRILL;
else if (startswith(name, "NIGHTS_STUN")) return S_PLAY_NIGHTS_STUN;
else if (startswith(name, "NIGHTS_PULL")) return S_PLAY_NIGHTS_PULL;
else if (startswith(name, "NIGHTS_ATTACK")) return S_PLAY_NIGHTS_ATTACK;
else return S_NULL;
}
static void CacheCustomSkinStates(skin_t *skin)
{
SIMPLEHASH_CLEAR(skin->defaulttocustomstate, hashentry_int32_int32_t)
SIMPLEHASH_CLEAR(skin->customtodefaultstate, hashentry_int32_int32_t)
char *skinstateprefix = va("SKIN_%s_", skin->name);
strupr(skinstateprefix);
size_t skinstateprefixlen = strlen(skinstateprefix);
for (INT32 state = S_FIRSTFREESLOT; state <= S_LASTFREESLOT; state++)
{
const char *statename = FREE_STATES[state - S_FIRSTFREESLOT];
if (!statename)
continue;
if (strncmp(statename, skinstateprefix, skinstateprefixlen))
continue;
statenum_t defaultstate = GetCanonicalPlayerStateNumByName(&statename[skinstateprefixlen]);
if (defaultstate)
{
// If a default state is overriden by multiple custom states, use the first one as reference
// e.g. WALK+WALK2+WALK3+WALK4 instead of just WALK
statenum_t alreadyoverriden;
SIMPLEHASH_FIND_INT(skin->defaulttocustomstate, hashentry_int32_int32_t, defaultstate, S_NULL, alreadyoverriden)
if (!alreadyoverriden)
SIMPLEHASH_REPLACE_INT(skin->defaulttocustomstate, hashentry_int32_int32_t, defaultstate, state)
SIMPLEHASH_REPLACE_INT(skin->customtodefaultstate, hashentry_int32_int32_t, state, defaultstate)
}
}
}
// //
// Find skin sprites, sounds & optional status bar face, & add them // Find skin sprites, sounds & optional status bar face, & add them
// //
...@@ -945,6 +1028,8 @@ next_token: ...@@ -945,6 +1028,8 @@ next_token:
R_FlushTranslationColormapCache(); R_FlushTranslationColormapCache();
CacheCustomSkinStates(skin);
if (mainfile == false) if (mainfile == false)
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
...@@ -1082,6 +1167,8 @@ next_token: ...@@ -1082,6 +1167,8 @@ next_token:
R_FlushTranslationColormapCache(); R_FlushTranslationColormapCache();
CacheCustomSkinStates(skin);
if (mainfile == false) if (mainfile == false)
CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name); CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name);
} }
......