diff --git a/src/deh_lua.c b/src/deh_lua.c index 3600c3554..c056db82a 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -11,6 +11,7 @@ /// \brief Lua SOC library #include "deh_lua.h" +#include "g_input.h" // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -596,12 +597,20 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) return luaL_error(L, "translation '%s' could not be found.\n", word); } - // TODO: 2.3: Delete this alias - if (fastcmp(word, "BT_USE")) + // TODO: 2.3: Delete these aliases + else if (fastcmp(word, "BT_USE")) { CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); return 1; - } + } + else if (fastcmp(word, "GC_WEPSLOT8") || fastcmp(word, "GC_WEPSLOT9") || fastcmp(word, "GC_WEPSLOT10")) + { + // Using GC_WEPSLOT7 isn't accurate, but ensures that "if x >= GC_WEPSLOT1 and x <= GC_WEPSLOT10" keeps the intended effect + CacheAndPushConstant(L, word, (lua_Integer)GC_WEPSLOT7); + if (!mathlib) + LUA_Deprecated(L, "GC_WEPSLOT8\"-\"GC_WEPSLOT10", "GC_WEPSLOT1\"-\"GC_WEPSLOT7"); + return 1; + } for (i = 0; INT_CONST[i].n; i++) if (fastcmp(word,INT_CONST[i].n)) { diff --git a/src/deh_tables.c b/src/deh_tables.c index fa86518e2..2ccf80e14 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5315,6 +5315,11 @@ struct int_const_s const INT_CONST[] = { //// Masks {"DMG_CANHURTSELF",DMG_CANHURTSELF}, {"DMG_DEATHMASK",DMG_DEATHMASK}, + // For P_SuperReady + {"SUPERREADY_CLASSIC",SUPERREADY_CLASSIC}, + {"SUPERREADY_TRANSFORM",SUPERREADY_TRANSFORM}, + {"SUPERREADY_DETRANSFORM",SUPERREADY_DETRANSFORM}, + {"NUMSUPERREADY",NUMSUPERREADY}, // Intermission types {"int_none",int_none}, @@ -5737,6 +5742,7 @@ struct int_const_s const INT_CONST[] = { {"JA_DIGITAL",JA_DIGITAL}, {"JA_JUMP",JA_JUMP}, {"JA_SPIN",JA_SPIN}, + {"JA_SHIELD",JA_SHIELD}, {"JA_FIRE",JA_FIRE}, {"JA_FIRENORMAL",JA_FIRENORMAL}, {"JOYAXISRANGE",JOYAXISRANGE}, diff --git a/src/g_demo.c b/src/g_demo.c index f64f34168..7af9c5949 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -98,7 +98,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x0011 +#define DEMOVERSION 0x0012 #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -183,7 +183,11 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) if (ziptic & ZT_ANGLE) oldcmd.angleturn = READINT16(demo_p); if (ziptic & ZT_BUTTONS) + { oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); + if (demoversion < 0x0012 && oldcmd.buttons & BT_SPIN) + oldcmd.buttons |= BT_SHIELD; // Copy BT_SPIN to BT_SHIELD for pre-Shield-button demos + } if (ziptic & ZT_AIMING) oldcmd.aiming = READINT16(demo_p); if (ziptic & ZT_LATENCY) diff --git a/src/g_game.c b/src/g_game.c index 6a99381e7..6fff76ca8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -403,27 +403,29 @@ consvar_t cv_cam_lockonboss[2] = { CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL), }; -consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_shieldaxis = CVAR_INIT ("joyaxis_shield", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_shieldaxis2 = CVAR_INIT ("joyaxis2_shield", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); player_t *seenplayer; // player we're aiming at right now @@ -894,6 +896,9 @@ INT32 JoyAxis(joyaxis_e axissel) case JA_SPIN: axisval = cv_spinaxis.value; break; + case JA_SHIELD: + axisval = cv_shieldaxis.value; + break; case JA_FIRE: axisval = cv_fireaxis.value; break; @@ -967,6 +972,9 @@ INT32 Joy2Axis(joyaxis_e axissel) case JA_SPIN: axisval = cv_spinaxis2.value; break; + case JA_SHIELD: + axisval = cv_shieldaxis2.value; + break; case JA_FIRE: axisval = cv_fireaxis2.value; break; @@ -1334,8 +1342,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV)) cmd->buttons |= BT_WEAPONPREV; // Previous Weapon -#if NUM_WEAPONS > 10 -"Add extra inputs to g_input.h/gamecontrols_e" +#if NUM_WEAPONS > 7 +"Add extra inputs to g_input.h/gamecontrols_e, and fix conflicts in d_ticcmd.h/ticcmd_t/buttons" #endif //use the three avaliable bits to determine the weapon. cmd->buttons &= ~BT_WEAPONMASK; @@ -1361,7 +1369,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->buttons |= BT_TOSSFLAG; // Shield button - if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD)) + axis = PlayerJoyAxis(ssplayer, JA_SHIELD); + if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0)) cmd->buttons |= BT_SHIELD; // Lua scriptable buttons diff --git a/src/g_game.h b/src/g_game.h index 80a815f02..0d5fc7e37 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -71,8 +71,8 @@ typedef enum { #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) extern consvar_t cv_autobrake, cv_autobrake2; -extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; -extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; +extern consvar_t cv_sideaxis, cv_turnaxis, cv_moveaxis, cv_lookaxis, cv_jumpaxis, cv_spinaxis, cv_shieldaxis, cv_fireaxis, cv_firenaxis, cv_deadzone, cv_digitaldeadzone; +extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_shieldaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls @@ -100,6 +100,7 @@ typedef enum JA_JUMP = JA_DIGITAL, JA_SPIN, + JA_SHIELD, JA_FIRE, JA_FIRENORMAL, } joyaxis_e; diff --git a/src/g_input.c b/src/g_input.c index 3f1be37ba..5fa642f1d 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1001,7 +1001,6 @@ static void setcontrol(INT32 (*gc)[2]) // TODO: 2.3: Delete the "use" alias namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; - for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); numctrl++) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 680c6a2c3..a5162837e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1712,12 +1712,14 @@ static int lib_pResetCamera(lua_State *L) static int lib_pSuperReady(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - boolean transform = (boolean)lua_opttrueboolean(L, 2); + superready_t type = luaL_optinteger(L, 2, SUPERREADY_CLASSIC); //HUDSAFE INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushboolean(L, P_SuperReady(player, transform)); + if (type < 0 || type >= NUMSUPERREADY) + return luaL_error(L, "superready type %d out of range (0 - %d)", type, NUMSUPERREADY-1); + lua_pushboolean(L, P_SuperReady(player, type)); return 1; } @@ -2497,6 +2499,17 @@ static int lib_pDoSuperTransformation(lua_State *L) return 0; } +static int lib_pDoSuperDetransformation(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoSuperDetransformation(player); + return 0; +} + static int lib_pExplodeMissile(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -4450,6 +4463,7 @@ static luaL_Reg lib[] = { {"P_VectorInstaThrust",lib_pVectorInstaThrust}, {"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_DoSuperTransformation",lib_pDoSuperTransformation}, + {"P_DoSuperDetransformation",lib_pDoSuperDetransformation}, {"P_ExplodeMissile",lib_pExplodeMissile}, {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor}, diff --git a/src/m_menu.c b/src/m_menu.c index 3c6ef0fe3..cf062c65c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1068,9 +1068,9 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, GC_BACKWARD }, {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, GC_STRAFELEFT }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT }, - {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, - {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, - {IT_CALL | IT_STRING2, NULL, "Shield", M_ChangeControl, GC_SHIELD }, + {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, + {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, + {IT_CALL | IT_STRING2, NULL, "Shield Ability", M_ChangeControl, GC_SHIELD }, {IT_HEADER, NULL, "Camera", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, @@ -1119,13 +1119,15 @@ static menuitem_t OP_ChangeControlsMenu[] = static menuitem_t OP_Joystick1Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 30}, - {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 40}, - {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 50}, - {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 60}, - {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 70}, - {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 80}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 0}, + + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 20}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 30}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 50}, + {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 60}, + {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 70}, + {IT_STRING | IT_CVAR, NULL, "Shield Axis" , &cv_shieldaxis , 80}, {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 90}, {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis ,100}, @@ -1137,13 +1139,15 @@ static menuitem_t OP_Joystick1Menu[] = static menuitem_t OP_Joystick2Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 30}, - {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 40}, - {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 50}, - {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 60}, - {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 70}, - {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 80}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 0}, + + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 20}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 30}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 50}, + {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 60}, + {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 70}, + {IT_STRING | IT_CVAR, NULL, "Shield Axis" , &cv_shieldaxis2 , 80}, {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 90}, {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 ,100}, diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 6bdcaa650..96a6bcea7 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -805,6 +805,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_jumpaxis2); CV_RegisterVar(&cv_spinaxis); CV_RegisterVar(&cv_spinaxis2); + CV_RegisterVar(&cv_shieldaxis); + CV_RegisterVar(&cv_shieldaxis2); CV_RegisterVar(&cv_fireaxis); CV_RegisterVar(&cv_fireaxis2); CV_RegisterVar(&cv_firenaxis); diff --git a/src/p_local.h b/src/p_local.h index 9644e7a24..da8956ae1 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -113,6 +113,14 @@ typedef struct camera_s fixed_t momx, momy, momz; } camera_t; +typedef enum +{ + SUPERREADY_CLASSIC, // Two-button play mode, when Spin and Shield are bound to the same button (pressed on the same tic) + SUPERREADY_TRANSFORM, + SUPERREADY_DETRANSFORM, + NUMSUPERREADY +} superready_t; + extern camera_t camera, camera2; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultiplier, cv_cam_orbit, cv_cam_adjust; @@ -203,7 +211,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user -boolean P_SuperReady(player_t *player, boolean transform); +boolean P_SuperReady(player_t *player, superready_t type); void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip); void P_DoSpinDashDust(player_t *player); #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) @@ -552,6 +560,7 @@ void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc, fixed_t za, fixed_t zb, fixed_t zc, fixed_t momentum, mobj_t *mo); void P_DoSuperTransformation(player_t *player, boolean giverings); +void P_DoSuperDetransformation(player_t *player); void P_ExplodeMissile(mobj_t *mo); void P_CheckGravity(mobj_t *mo, boolean affect); void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); diff --git a/src/p_user.c b/src/p_user.c index 9d0eed288..30650b5bb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1378,7 +1378,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // P_DoSuperDetransformation // // Detransform into regular Sonic! -static void P_DoSuperDetransformation(player_t *player) +void P_DoSuperDetransformation(player_t *player) { player->powers[pw_emeralds] = 0; // lost the power stones P_SpawnGhostMobj(player->mo); @@ -4189,16 +4189,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) I_Assert(player != NULL); I_Assert(!P_MobjWasRemoved(player->mo)); - - // Toss a flag - if (cmd->buttons & BT_TOSSFLAG && G_GametypeHasTeams() - && !(player->powers[pw_super]) && !(player->tossdelay)) - { - if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - P_PlayerEmeraldBurst(player, true); // Toss emeralds - else - P_PlayerFlagBurst(player, true); - } if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL))) { @@ -4208,7 +4198,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) return; } - if (player->pflags & PF_ATTACKDOWN || player->climbing) + if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT))) return; // Fire a fireball if we have the Fire Flower powerup! @@ -4224,7 +4214,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) } // No ringslinging outside of ringslinger! - if (!G_RingSlingerGametype() || player->weapondelay || (G_TagGametype() && !(player->pflags & PF_TAGIT))) + if (!G_RingSlingerGametype() || player->weapondelay) return; player->pflags |= PF_ATTACKDOWN; @@ -4441,25 +4431,54 @@ static void P_DoSuperStuff(player_t *player) // // Returns true if player is ready to transform or detransform // -boolean P_SuperReady(player_t *player, boolean transform) +boolean P_SuperReady(player_t *player, superready_t type) { - if (!transform && - (player->powers[pw_super] < TICRATE*3/2 - || !G_CoopGametype())) // No turning back in competitive! - return false; - else if (transform - && (player->powers[pw_super] - || !ALL7EMERALDS(emeralds) - || !(player->rings >= 50))) - return false; - + switch (type) // Transformation-type-specific checks + { + case SUPERREADY_CLASSIC: + // Pressed Spin and Shield on the same tic? Then you've probably bound them to the same button, + // so let's match the earlier Spin-only button behaviour to still support two-button play + if (!player->powers[pw_super] + && !player->powers[pw_invulnerability] + && !player->powers[pw_tailsfly] + && (player->charflags & SF_SUPER) + && (player->pflags & PF_JUMPED) + && !(player->powers[pw_shield] & SH_NOSTACK) + && !(maptol & TOL_NIGHTS) + && ALL7EMERALDS(emeralds) + && (player->rings >= 50)) + return true; + else + return false; + break; + + case SUPERREADY_TRANSFORM: + // Turning Super by pressing Shield? + if (player->powers[pw_super] + || !ALL7EMERALDS(emeralds) + || !(player->rings >= 50)) + return false; + break; + + case SUPERREADY_DETRANSFORM: + // Reverting from Super by pressing Shield? + if ((player->powers[pw_super] < TICRATE*3/2) // No spamming the transformation sound! + || !G_CoopGametype()) // No turning back in competitive! + return false; + break; + + default: // "type" is an enum, so having a case for every enum value pleases the compiler + break; + } + + // These checks apply to both SUPERREADY_TRANSFORM and SUPERREADY_DETRANSFORM if (player->mo && !player->powers[pw_tailsfly] && !player->powers[pw_carry] && (player->charflags & SF_SUPER) && !P_PlayerInPain(player) && !player->climbing - && !(player->pflags & (PF_FULLSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) + && !(player->pflags & (PF_JUMPSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) && ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE || player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH)))) && !(maptol & TOL_NIGHTS)) @@ -5281,7 +5300,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock // // Handles player jumping // -static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) +static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhack) { mobj_t *lockonthok = NULL, *visual = NULL; @@ -5314,45 +5333,52 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) ; else if (P_PlayerShieldThink(player, cmd, lockonthok, visual)) ; - else if ((cmd->buttons & BT_SPIN) && !LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) + else if (cmd->buttons & BT_SPIN) { - switch (player->charability) + if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, SUPERREADY_CLASSIC)) { - case CA_THOK: - if (player->powers[pw_super]) // Super Sonic float - { - if ((player->speed > 5*player->mo->scale) // FixedMul(5<mo->scale), but scale is FRACUNIT-based - && (P_MobjFlip(player->mo)*player->mo->momz <= 0)) - { - if (player->panim != PA_RUN && player->panim != PA_WALK) - { - if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) - P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); - else - P_SetMobjState(player->mo, S_PLAY_FLOAT); - } - - player->mo->momz = 0; - player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); - player->secondjump = 1; - } - } - break; - case CA_TELEKINESIS: - if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY)) - { - P_Telekinesis(player, - -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) - FixedMul(384*FRACUNIT, player->mo->scale)); - } - break; - case CA_TWINSPIN: - if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY)) - P_DoTwinSpin(player); - break; - default: - break; + // If you're using two-button play, can turn Super and aren't already, + // and you don't have a shield, then turn Super! + P_DoSuperTransformation(player, false); } + else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) + switch (player->charability) + { + case CA_THOK: + if (player->powers[pw_super]) // Super Sonic float + { + if ((player->speed > 5*player->mo->scale) // FixedMul(5<mo->scale), but scale is FRACUNIT-based + && (P_MobjFlip(player->mo)*player->mo->momz <= 0)) + { + if (player->panim != PA_RUN && player->panim != PA_WALK) + { + if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) + P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); + else + P_SetMobjState(player->mo, S_PLAY_FLOAT); + } + + player->mo->momz = 0; + player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); + player->secondjump = 1; + } + } + break; + case CA_TELEKINESIS: + if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY)) + { + P_Telekinesis(player, + -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) + FixedMul(384*FRACUNIT, player->mo->scale)); + } + break; + case CA_TWINSPIN: + if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY)) + P_DoTwinSpin(player); + break; + default: + break; + } } } @@ -8074,6 +8100,7 @@ void P_MovePlayer(player_t *player) { ticcmd_t *cmd; INT32 i; + boolean spinshieldhack = false; // Hack: Is Spin and Shield bound to the same button (pressed on the same tic)? fixed_t runspd; @@ -8696,10 +8723,13 @@ void P_MovePlayer(player_t *player) && !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) P_ElementalFire(player, false); + if ((cmd->buttons & (BT_SPIN|BT_SHIELD)) == (BT_SPIN|BT_SHIELD) && !(player->pflags & (PF_SPINDOWN|PF_SHIELDDOWN))) + spinshieldhack = true; // Spin and Shield is bound to the same button (pressed on the same tic), so enable two-button play (Jump and Spin+Shield) + P_DoSpinAbility(player, cmd); // jumping - P_DoJumpStuff(player, cmd); + P_DoJumpStuff(player, cmd, spinshieldhack); // If you're not spinning, you'd better not be spindashing! if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE) @@ -8777,30 +8807,32 @@ void P_MovePlayer(player_t *player) if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) && player->panim == PA_IDLE && !(player->powers[pw_carry])) P_DoTeeter(player); + + // Toss a flag + if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay)) + { + if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) + P_PlayerEmeraldBurst(player, true); // Toss emeralds + else + P_PlayerFlagBurst(player, true); + } // Check for fire and shield buttons - if (!player->exiting && !(player->pflags & PF_STASIS)) + if (!player->exiting) { - // Check for fire buttons P_DoFiring(player, cmd); - - // Release the shield button - if (!(cmd->buttons & BT_SHIELD)) - player->pflags &= ~PF_SHIELDDOWN; - + // Shield button behavior // Check P_PlayerShieldThink for actual shields! - else if (!(player->pflags & PF_SHIELDDOWN)) + if ((cmd->buttons & BT_SHIELD) && !(player->pflags & PF_SHIELDDOWN) && !spinshieldhack) { // Transform into super if we can! - if (P_SuperReady(player, true)) + if (P_SuperReady(player, SUPERREADY_TRANSFORM)) P_DoSuperTransformation(player, false); - + // Detransform from super if we can! - else if (P_SuperReady(player, false)) + else if (P_SuperReady(player, SUPERREADY_DETRANSFORM)) P_DoSuperDetransformation(player); - - player->pflags |= PF_SHIELDDOWN; } } @@ -12054,7 +12086,7 @@ void P_PlayerThink(player_t *player) ticmiss++; P_DoRopeHang(player); - P_DoJumpStuff(player, &player->cmd); + P_DoJumpStuff(player, &player->cmd, false); // P_DoRopeHang would set PF_SPINDOWN, so no spinshieldhack here } else //if (player->powers[pw_carry] == CR_ZOOMTUBE) { @@ -12324,6 +12356,12 @@ void P_PlayerThink(player_t *player) player->pflags &= ~PF_SPINDOWN; } + // Check for Shield button + if (cmd->buttons & BT_SHIELD) + player->pflags |= PF_SHIELDDOWN; + else + player->pflags &= ~PF_SHIELDDOWN; + // IF PLAYER NOT HERE THEN FLASH END IF if (player->quittime && player->powers[pw_flashing] < flashingtics - 1 && !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag) diff --git a/src/st_stuff.c b/src/st_stuff.c index 67838ddb4..014fbee6e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1170,8 +1170,10 @@ static void ST_drawInput(void) V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_LIVES].f|symb, false) - drawbutt( 4,-3, BT_JUMP, 'J'); - drawbutt(15,-3, BT_SPIN, 'S'); + drawbutt( 4,-3, BT_JUMP, 'J' ); + drawbutt(15,-3, BT_SPIN, 'S' ); + drawbutt(26,-3, BT_SHIELD, '\0'); // Instead of a wide 'J' or 'S', we'll draw a thin "SH" for Shield + V_DrawThinString(x+16+26, y+2+(-3)-offs, hudinfo[HUD_LIVES].f, "SH"); V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_LIVES].f|20); // sundial backing if (stplyr->mo) diff --git a/src/y_inter.c b/src/y_inter.c index bb4fa0690..2add8645b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -579,9 +579,9 @@ void Y_IntermissionDrawer(void) { if (LUA_HudEnabled(hud_intermissiontitletext)) { - const char *ringtext = "\x82" "get 50 rings then"; + const char *ringtext = "\x82" "get 50 rings, then"; const char *tut1text = "\x82" "press " "\x80" "shield"; - const char *tut2text = "\x82" "to " "\x80" "transform"; + const char *tut2text = "\x82" "to transform"; ttheight = 8; V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); ttheight += V_LevelNameHeight(data.spec.passed3) + 2;