diff --git a/src/d_player.h b/src/d_player.h index ca700d4e1..1409e28b3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -158,6 +158,10 @@ typedef enum PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs PF_CANCARRY = 1<<29, // Can carry another player? PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting + + // True if shield button down last tic + // This may be the final flag, but 2.3 could free up the others + PF_SHIELDDOWN = 1<<31, // up to 1<<31 is free } pflags_t; diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 2481ed738..43eb0f00b 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -26,20 +26,23 @@ // Button/action code definitions. typedef enum { - // First 4 bits are weapon change info, DO NOT USE! - BT_WEAPONMASK = 0x0F, //our first four bits. + // First 3 bits are weapon change info, DO NOT USE! + BT_WEAPONMASK = 0x07, //our first three bits. + + BT_SHIELD = 1<<3, // shield or super action - BT_WEAPONNEXT = 1<<4, - BT_WEAPONPREV = 1<<5, - - BT_ATTACK = 1<<6, // shoot rings - BT_SPIN = 1<<7, - BT_CAMLEFT = 1<<8, // turn camera left - BT_CAMRIGHT = 1<<9, // turn camera right - BT_TOSSFLAG = 1<<10, - BT_JUMP = 1<<11, - BT_FIRENORMAL = 1<<12, // Fire a normal ring no matter what + BT_WEAPONNEXT = 1<<4, // select next weapon + BT_WEAPONPREV = 1<<5, // select previous weapon + BT_ATTACK = 1<<6, // shoot rings + BT_SPIN = 1<<7, // spin action + BT_CAMLEFT = 1<<8, // turn camera left + BT_CAMRIGHT = 1<<9, // turn camera right + BT_TOSSFLAG = 1<<10, // toss flag or emeralds + BT_JUMP = 1<<11, // jump action + BT_FIRENORMAL = 1<<12, // fire a normal ring no matter what + + // custom lua buttons BT_CUSTOM1 = 1<<13, BT_CUSTOM2 = 1<<14, BT_CUSTOM3 = 1<<15, diff --git a/src/deh_lua.c b/src/deh_lua.c index e596e166f..b8daa0430 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -589,7 +589,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) { CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); 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 bf148d82b..b53cd00c8 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5576,7 +5576,8 @@ struct int_const_s const INT_CONST[] = { {"ROTAXIS_Z",ROTAXIS_Z}, // Buttons (ticcmd_t) - {"BT_WEAPONMASK",BT_WEAPONMASK}, //our first four bits. + {"BT_WEAPONMASK",BT_WEAPONMASK}, //our first three bits. + {"BT_SHIELD",BT_SHIELD}, {"BT_WEAPONNEXT",BT_WEAPONNEXT}, {"BT_WEAPONPREV",BT_WEAPONPREV}, {"BT_ATTACK",BT_ATTACK}, // shoot rings @@ -5756,9 +5757,7 @@ struct int_const_s const INT_CONST[] = { {"GC_WEPSLOT5",GC_WEPSLOT5}, {"GC_WEPSLOT6",GC_WEPSLOT6}, {"GC_WEPSLOT7",GC_WEPSLOT7}, - {"GC_WEPSLOT8",GC_WEPSLOT8}, - {"GC_WEPSLOT9",GC_WEPSLOT9}, - {"GC_WEPSLOT10",GC_WEPSLOT10}, + {"GC_SHIELD",GC_SHIELD}, {"GC_FIRE",GC_FIRE}, {"GC_FIRENORMAL",GC_FIRENORMAL}, {"GC_TOSSFLAG",GC_TOSSFLAG}, diff --git a/src/g_game.c b/src/g_game.c index 438428b90..1388148e7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1335,7 +1335,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) #if NUM_WEAPONS > 10 "Add extra inputs to g_input.h/gamecontrols_e" #endif - //use the four avaliable bits to determine the weapon. + //use the three avaliable bits to determine the weapon. cmd->buttons &= ~BT_WEAPONMASK; for (i = 0; i < NUM_WEAPONS; ++i) if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i)) @@ -1353,9 +1353,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; - + + // Toss flag button if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) cmd->buttons |= BT_TOSSFLAG; + + // Shield button + if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD)) + cmd->buttons |= BT_SHIELD; // Lua scriptable buttons if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1)) @@ -2748,6 +2753,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->pflags |= PF_SPINDOWN; p->pflags |= PF_ATTACKDOWN; p->pflags |= PF_JUMPDOWN; + p->pflags |= PF_SHIELDDOWN; p->playerstate = PST_LIVE; p->panim = PA_IDLE; // standing animation diff --git a/src/g_input.c b/src/g_input.c index 8b5056331..3f1be37ba 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -576,9 +576,7 @@ static const char *gamecontrolname[NUM_GAMECONTROLS] = "weapon5", "weapon6", "weapon7", - "weapon8", - "weapon9", - "weapon10", + "shield", "fire", "firenormal", "tossflag", @@ -693,6 +691,7 @@ void G_DefineDefaultControls(void) gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL; gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT; + gamecontroldefault[gcs_fps][GC_SHIELD ][0] = KEY_LALT; gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL; gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT; @@ -713,6 +712,7 @@ void G_DefineDefaultControls(void) gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END; gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT; + gamecontroldefault[gcs_platform][GC_SHIELD ][0] = KEY_LALT; gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's'; gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w'; @@ -728,9 +728,6 @@ void G_DefineDefaultControls(void) gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5'; gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6'; gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7'; - gamecontroldefault[i][GC_WEPSLOT8 ][0] = '8'; - gamecontroldefault[i][GC_WEPSLOT9 ][0] = '9'; - gamecontroldefault[i][GC_WEPSLOT10 ][0] = '0'; gamecontroldefault[i][GC_TOSSFLAG ][0] = '\''; gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v'; gamecontroldefault[i][GC_CAMRESET ][0] = 'r'; @@ -749,15 +746,15 @@ void G_DefineDefaultControls(void) gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick - gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+4; // LB + gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+4; // LB gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB - gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_JOY1+6; // Back + gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up - gamecontroldefault[i][GC_SCORES ][1] = KEY_HAT1+1; // D-Pad Down + gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+1; // D-Pad Down // Second player controls only have joypad defaults gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A @@ -765,15 +762,15 @@ void G_DefineDefaultControls(void) gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick - gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+4; // LB + gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+4; // LB gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB - gamecontrolbisdefault[i][GC_SCREENSHOT ][1] = KEY_2JOY1+6; // Back + //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up - //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2HAT1+1; // D-Pad Down + gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2HAT1+1; // D-Pad Down } } @@ -1004,6 +1001,7 @@ 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/g_input.h b/src/g_input.h index e9c909e6e..48c103076 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -74,9 +74,7 @@ typedef enum GC_WEPSLOT5, GC_WEPSLOT6, GC_WEPSLOT7, - GC_WEPSLOT8, - GC_WEPSLOT9, - GC_WEPSLOT10, + GC_SHIELD, GC_FIRE, GC_FIRENORMAL, GC_TOSSFLAG, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 16f238abe..bdc5c4501 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1686,11 +1686,12 @@ static int lib_pHomingAttack(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); //HUDSAFE INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushboolean(L, P_SuperReady(player)); + lua_pushboolean(L, P_SuperReady(player, transform)); return 1; } diff --git a/src/m_menu.c b/src/m_menu.c index 629f53d24..45e74c0fc 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1068,6 +1068,7 @@ static menuitem_t OP_ChangeControlsMenu[] = {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_HEADER, NULL, "Camera", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, @@ -13167,23 +13168,23 @@ static void M_Setup1PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Unhide the nine non-P2 controls and their headers - //OP_ChangeControlsMenu[18+0].status = IT_HEADER; - //OP_ChangeControlsMenu[18+1].status = IT_SPACE; + //OP_ChangeControlsMenu[19+0].status = IT_HEADER; + //OP_ChangeControlsMenu[19+1].status = IT_SPACE; // ... - OP_ChangeControlsMenu[18+2].status = IT_CALL|IT_STRING2; - OP_ChangeControlsMenu[18+3].status = IT_CALL|IT_STRING2; - OP_ChangeControlsMenu[18+4].status = IT_CALL|IT_STRING2; - OP_ChangeControlsMenu[18+5].status = IT_CALL|IT_STRING2; - OP_ChangeControlsMenu[18+6].status = IT_CALL|IT_STRING2; - //OP_ChangeControlsMenu[18+7].status = IT_CALL|IT_STRING2; - //OP_ChangeControlsMenu[18+8].status = IT_CALL|IT_STRING2; - OP_ChangeControlsMenu[18+9].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[19+2].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[19+3].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[19+4].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[19+5].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[19+6].status = IT_CALL|IT_STRING2; + //OP_ChangeControlsMenu[19+7].status = IT_CALL|IT_STRING2; + //OP_ChangeControlsMenu[19+8].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[19+9].status = IT_CALL|IT_STRING2; // ... - OP_ChangeControlsMenu[28+0].status = IT_HEADER; - OP_ChangeControlsMenu[28+1].status = IT_SPACE; + OP_ChangeControlsMenu[29+0].status = IT_HEADER; + OP_ChangeControlsMenu[29+1].status = IT_SPACE; // ... - OP_ChangeControlsMenu[28+2].status = IT_CALL|IT_STRING2; - OP_ChangeControlsMenu[28+3].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[29+2].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[29+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level @@ -13199,23 +13200,23 @@ static void M_Setup2PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Hide the nine non-P2 controls and their headers - //OP_ChangeControlsMenu[18+0].status = IT_GRAYEDOUT2; - //OP_ChangeControlsMenu[18+1].status = IT_GRAYEDOUT2; + //OP_ChangeControlsMenu[19+0].status = IT_GRAYEDOUT2; + //OP_ChangeControlsMenu[19+1].status = IT_GRAYEDOUT2; // ... - OP_ChangeControlsMenu[18+2].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[18+3].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[18+4].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[18+5].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[18+6].status = IT_GRAYEDOUT2; - //OP_ChangeControlsMenu[18+7].status = IT_GRAYEDOUT2; - //OP_ChangeControlsMenu[18+8].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[18+9].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[19+2].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[19+3].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[19+4].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[19+5].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[19+6].status = IT_GRAYEDOUT2; + //OP_ChangeControlsMenu[19+7].status = IT_GRAYEDOUT2; + //OP_ChangeControlsMenu[19+8].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[19+9].status = IT_GRAYEDOUT2; // ... - OP_ChangeControlsMenu[28+0].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[28+1].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[29+0].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[29+1].status = IT_GRAYEDOUT2; // ... - OP_ChangeControlsMenu[28+2].status = IT_GRAYEDOUT2; - OP_ChangeControlsMenu[28+3].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[29+2].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[29+3].status = IT_GRAYEDOUT2; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level diff --git a/src/p_local.h b/src/p_local.h index c26c09860..1f1548b86 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -202,7 +202,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 P_SuperReady(player_t *player, boolean transform); void P_DoJump(player_t *player, boolean soundandstate); void P_DoSpinDashDust(player_t *player); #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) diff --git a/src/p_user.c b/src/p_user.c index c0e87bf73..a856d2592 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -666,7 +666,7 @@ static void P_DeNightserizePlayer(player_t *player) player->powers[pw_carry] = CR_NIGHTSFALL; player->powers[pw_underwater] = 0; - player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); + player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); player->secondjump = 0; player->homing = 0; player->climbing = 0; @@ -794,7 +794,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) } } - player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); + player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); player->homing = 0; player->mo->fuse = 0; player->speed = 0; @@ -1342,8 +1342,6 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) P_PlayJingle(player, JT_SUPER); - S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi - player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0; // Transformation animation @@ -1360,8 +1358,11 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) player->powers[pw_sneakers] = 0; } - if (!G_CoopGametype()) + if (G_CoopGametype()) + S_StartSound(player->mo, sfx_supert); //only hear it near yourself in co-op + else { + S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players])); @@ -1370,6 +1371,56 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_PlayerFlagBurst(player, false); } +// +// P_DoSuperDetransformation +// +// Detransform into regular Sonic! +static void P_DoSuperDetransformation(player_t *player) +{ + player->powers[pw_emeralds] = 0; // lost the power stones + P_SpawnGhostMobj(player->mo); + + player->powers[pw_super] = 0; + + // Restore color + if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) + { + player->mo->color = SKINCOLOR_WHITE; + G_GhostAddColor(GHC_FIREFLOWER); + } + else + { + player->mo->color = P_GetPlayerColor(player); + G_GhostAddColor(GHC_NORMAL); + } + + if (!G_CoopGametype()) + player->powers[pw_flashing] = flashingtics-1; + + if (player->mo->sprite2 & FF_SPR2SUPER) + P_SetPlayerMobjState(player->mo, player->mo->state-states); + + // Inform the netgame that the champion has fallen in the heat of battle. + if (!G_CoopGametype()) + { + S_StartSound(NULL, sfx_s3k66); //let all players hear it. + HU_SetCEchoFlags(0); + HU_SetCEchoDuration(5); + HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players])); + } + + // Resume normal music if you're the console player + if (P_IsLocalPlayer(player)) + { + music_stack_noposition = true; // HACK: Do not reposition next music + music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music + } + P_RestoreMusic(player); + + // If you had a shield, restore its visual significance. + P_SpawnShieldOrb(player); +} + // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { @@ -4086,6 +4137,16 @@ 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))) { @@ -4095,9 +4156,10 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) return; } - if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT))) + if (player->pflags & PF_ATTACKDOWN || player->climbing) return; + // Fire a fireball if we have the Fire Flower powerup! if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay)) { player->pflags |= PF_ATTACKDOWN; @@ -4109,7 +4171,8 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) return; } - if (!G_RingSlingerGametype() || player->weapondelay) + // No ringslinging outside of ringslinger! + if (!G_RingSlingerGametype() || player->weapondelay || (G_TagGametype() && !(player->pflags & PF_TAGIT))) return; player->pflags |= PF_ATTACKDOWN; @@ -4287,34 +4350,7 @@ static void P_DoSuperStuff(player_t *player) // If you're super and not Sonic, de-superize! if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER)) { - player->powers[pw_super] = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_STND); - if (P_IsLocalPlayer(player)) - { - music_stack_noposition = true; // HACK: Do not reposition next music - music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music - } - P_RestoreMusic(player); - P_SpawnShieldOrb(player); - - // Restore color - if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) - { - player->mo->color = SKINCOLOR_WHITE; - G_GhostAddColor(GHC_FIREFLOWER); - } - else - { - player->mo->color = P_GetPlayerColor(player); - G_GhostAddColor(GHC_NORMAL); - } - - if (!G_CoopGametype()) - { - HU_SetCEchoFlags(0); - HU_SetCEchoDuration(5); - HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players])); - } + P_DoSuperDetransformation(player); return; } @@ -4341,69 +4377,37 @@ static void P_DoSuperStuff(player_t *player) // Ran out of rings while super! if (player->rings <= 0 || player->exiting) - { - player->powers[pw_emeralds] = 0; // lost the power stones - P_SpawnGhostMobj(player->mo); - - player->powers[pw_super] = 0; - - // Restore color - if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) - { - player->mo->color = SKINCOLOR_WHITE; - G_GhostAddColor(GHC_FIREFLOWER); - } - else - { - player->mo->color = P_GetPlayerColor(player); - G_GhostAddColor(GHC_NORMAL); - } - - if (!G_CoopGametype()) - player->powers[pw_flashing] = flashingtics-1; - - if (player->mo->sprite2 & FF_SPR2SUPER) - P_SetPlayerMobjState(player->mo, player->mo->state-states); - - // Inform the netgame that the champion has fallen in the heat of battle. - if (!G_CoopGametype()) - { - S_StartSound(NULL, sfx_s3k66); //let all players hear it. - HU_SetCEchoFlags(0); - HU_SetCEchoDuration(5); - HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players])); - } - - // Resume normal music if you're the console player - if (P_IsLocalPlayer(player)) - { - music_stack_noposition = true; // HACK: Do not reposition next music - music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music - } - P_RestoreMusic(player); - - // If you had a shield, restore its visual significance. - P_SpawnShieldOrb(player); - } + P_DoSuperDetransformation(player); } } // // P_SuperReady // -// Returns true if player is ready to turn super, duh +// Returns true if player is ready to transform or detransform // -boolean P_SuperReady(player_t *player) +boolean P_SuperReady(player_t *player, boolean transform) { - if (!player->powers[pw_super] - && !player->powers[pw_invulnerability] + 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; + + if (player->mo && !player->powers[pw_tailsfly] + && !player->powers[pw_carry] && (player->charflags & SF_SUPER) - && (player->pflags & PF_JUMPED) - && !(player->powers[pw_shield] & SH_NOSTACK) - && !(maptol & TOL_NIGHTS) - && ALL7EMERALDS(emeralds) - && (player->rings >= 50)) + && !P_PlayerInPain(player) + && !player->climbing + && !(player->pflags & (PF_FULLSTASIS|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)) return true; return false; @@ -5094,7 +5098,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock { mobj_t *lockonshield = NULL; - if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) + if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SHIELDDOWN) && ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted { if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY)) @@ -5121,7 +5125,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Spin button effects + if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SHIELD && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Shield button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5242,52 +5246,45 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) ; else if (P_PlayerShieldThink(player, cmd, lockonthok, visual)) ; - else if ((cmd->buttons & BT_SPIN)) + else if ((cmd->buttons & BT_SPIN) && !LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) { - if (!(player->pflags & PF_SPINDOWN) && P_SuperReady(player)) + switch (player->charability) { - // If you can turn super and aren't already, - // and you don't have a shield, do it! - 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 + 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->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->panim != PA_RUN && player->panim != PA_WALK) - { - if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); - else - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); - } - - player->mo->momz = 0; - player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); - player->secondjump = 1; + if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + else + P_SetPlayerMobjState(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; - } + } + 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; + } } } @@ -5350,12 +5347,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY) ; - /*else if (P_SuperReady(player)) - { - // If you can turn super and aren't already, - // and you don't have a shield, do it! - P_DoSuperTransformation(player, false); - }*/ else if (player->pflags & PF_JUMPED) { if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) @@ -8686,18 +8677,31 @@ void P_MovePlayer(player_t *player) && 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)) + // Check for fire and shield buttons + if (!player->exiting && !(player->pflags & PF_STASIS)) { - if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - P_PlayerEmeraldBurst(player, true); // Toss emeralds - else - P_PlayerFlagBurst(player, true); - } - - // check for fire - 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)) + { + // Transform into super if we can! + if (P_SuperReady(player, true)) + P_DoSuperTransformation(player, false); + + // Detransform from super if we can! + else if (P_SuperReady(player, false)) + P_DoSuperDetransformation(player); + + player->pflags |= PF_SHIELDDOWN; + } + } { boolean atspinheight = false; diff --git a/src/y_inter.c b/src/y_inter.c index 369ec3904..cbe057582 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" "50 rings, no shield"; - const char *tut1text = "\x82" "press " "\x80" "spin"; - const char *tut2text = "\x82" "mid-" "\x80" "jump"; + const char *ringtext = "\x82" "get 50 rings then"; + const char *tut1text = "\x82" "press " "\x80" "shield"; + const char *tut2text = "\x82" "to " "\x80" "transform"; ttheight = 8; V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); ttheight += V_LevelNameHeight(data.spec.passed3) + 2;