diff --git a/src/d_player.h b/src/d_player.h index 1c57e6167..229ab6570 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -66,6 +66,7 @@ typedef enum CA_AIRDRILL, CA_JUMPTHOK, CA_DASHMODE, + CA_BOUNCE, CA_TWINSPIN } charability_t; @@ -158,9 +159,12 @@ typedef enum PF_SHIELDABILITY = 1<<28, // Force jump damage? - PF_FORCEJUMPDAMAGE = 1<<29 + PF_FORCEJUMPDAMAGE = 1<<29, - // free up to and including 1<<31 + // Bouncing + PF_BOUNCING = 1<<30 + + // 1<<31 is free } pflags_t; typedef enum diff --git a/src/dehacked.c b/src/dehacked.c index f45b05b04..6427d0602 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3816,6 +3816,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAY_CLING", "S_PLAY_CLIMB", + // CA_BOUNCE + "S_PLAY_BOUNCE", + "S_PLAY_BOUNCE_LANDING", + // CA_TWINSPIN "S_PLAY_TWINSPIN", @@ -6790,6 +6794,7 @@ static const char *const PLAYERFLAG_LIST[] = { "CANCARRY", // Can carry? "SHIELDABILITY", // Thokked with shield ability "FORCEJUMPDAMAGE", // Force jump damage + "BOUNCING", NULL // stop loop here. }; @@ -7207,6 +7212,7 @@ struct { {"CA_AIRDRILL",CA_AIRDRILL}, {"CA_JUMPTHOK",CA_JUMPTHOK}, {"CA_DASHMODE",CA_DASHMODE}, + {"CA_BOUNCE",CA_BOUNCE}, {"CA_TWINSPIN",CA_TWINSPIN}, // Secondary {"CA2_NONE",CA2_NONE}, // now slot 0! diff --git a/src/info.c b/src/info.c index ad4aec136..4edaa5737 100644 --- a/src/info.c +++ b/src/info.c @@ -402,6 +402,9 @@ char spr2names[NUMPLAYERSPRITES][5] = "CLNG", "CLMB", + "BNCE", + "BLND", + "TWIN", "MLEE", @@ -514,6 +517,10 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB + // CA_BOUNCE + {SPR_PLAY, SPR2_BNCE|FF_ANIMATE, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_BOUNCE + {SPR_PLAY, SPR2_BLND|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_BOUNCE, 4, S_PLAY_BOUNCE_LANDING}, // S_PLAY_BOUNCE_LANDING + // CA_TWINSPIN {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN diff --git a/src/info.h b/src/info.h index 932180ebf..0202a71c4 100644 --- a/src/info.h +++ b/src/info.h @@ -604,6 +604,9 @@ enum playersprite SPR2_CLNG, // cling SPR2_CLMB, // climb + SPR2_BNCE, // bounce + SPR2_BLND, // bounce landing + SPR2_TWIN, // twinspin SPR2_MLEE, // melee @@ -713,6 +716,10 @@ typedef enum state S_PLAY_CLING, S_PLAY_CLIMB, + // CA_BOUNCE + S_PLAY_BOUNCE, + S_PLAY_BOUNCE_LANDING, + // CA_TWINSPIN S_PLAY_TWINSPIN, diff --git a/src/p_inter.c b/src/p_inter.c index 974ae1b8f..16f128da9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -371,7 +371,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || (player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) - || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) + || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce) // Do you possess the ability to subdue the object? { @@ -423,7 +423,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || (player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) - || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) + || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) @@ -1395,7 +1395,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || ((player->pflags & PF_JUMPED) && (player->pflags & PF_FORCEJUMPDAMAGE || !(player->charflags & SF_NOJUMPSPIN) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) - || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) + || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || (player->pflags & (PF_SPINNING|PF_GLIDING)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { diff --git a/src/p_map.c b/src/p_map.c index 7afd266fd..d31f46ba0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1063,7 +1063,7 @@ static boolean PIT_CheckThing(mobj_t *thing) || !(tmthing->player->charflags & SF_NOJUMPSPIN) || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) + || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) || elementalpierce)) { @@ -1105,7 +1105,7 @@ static boolean PIT_CheckThing(mobj_t *thing) || !(tmthing->player->charflags & SF_NOJUMPSPIN) || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) + || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) && !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2))) ; diff --git a/src/p_mobj.c b/src/p_mobj.c index 97147d642..8d4ef4202 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -253,6 +253,13 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) spr2 = SPR2_CLMB; break; + case SPR2_BNCE: + spr2 = SPR2_FALL; + break; + case SPR2_BLND: + spr2 = SPR2_SPIN; + break; + case SPR2_TWIN: spr2 = SPR2_SPIN; break; @@ -526,6 +533,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case S_PLAY_FLY: case S_PLAY_SWIM: case S_PLAY_GLIDE: + case S_PLAY_BOUNCE: + case S_PLAY_BOUNCE_LANDING: case S_PLAY_TWINSPIN: player->panim = PA_ABILITY; break; @@ -3306,6 +3315,22 @@ static void P_PlayerZMovement(mobj_t *mo) clipmomz = false; } } + + if (mo->player->pflags & PF_BOUNCING) + { + fixed_t prevmomz = P_MobjFlip(mo)*abs(mo->momz); + if (mo->eflags & MFE_UNDERWATER) + { + prevmomz /= 2; + } + S_StartSound(mo, sfx_boingf); + P_DoJump(mo->player, false); + P_SetPlayerMobjState(mo, S_PLAY_BOUNCE_LANDING); + mo->player->pflags |= PF_BOUNCING; + mo->player->jumping = 0; + mo->momz = (FixedMul(mo->momz, 3*FRACUNIT/2) + prevmomz)/2; + clipmomz = false; + } } } if (!(mo->player->pflags & PF_SPINNING)) @@ -4127,6 +4152,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // momentum movement mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; + if (mobj->state-states == S_PLAY_BOUNCE_LANDING) + goto animonly; + // Zoom tube if (mobj->tracer) { diff --git a/src/p_user.c b/src/p_user.c index df9fbb2c1..d1ba7d5e9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -870,7 +870,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Useful when you want to kill everything the player is doing. void P_ResetPlayer(player_t *player) { - player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_FORCEJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY); + player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_FORCEJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING); player->powers[pw_carry] = CR_NONE; player->jumping = 0; player->secondjump = 0; @@ -3934,7 +3934,7 @@ void P_DoJumpShield(player_t *player) player->jumping = 0; player->secondjump = 0; player->pflags |= PF_THOKKED|PF_SHIELDABILITY; - player->pflags &= ~PF_SPINNING; + player->pflags &= ~(PF_SPINNING|PF_BOUNCING); if (electric) { mobj_t *spark; @@ -4278,6 +4278,16 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_spndsh); } break; + case CA_BOUNCE: + if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) + { + P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE); + player->pflags &= ~PF_JUMPED; + player->pflags |= PF_BOUNCING; + player->mo->momx >>= 1; + player->mo->momy >>= 1; + } + break; case CA_TWINSPIN: if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) { @@ -4785,11 +4795,16 @@ static void P_3dMovement(player_t *player) } // Better maneuverability while flying - if(player->powers[pw_tailsfly]) + if (player->powers[pw_tailsfly]) { thrustfactor = player->thrustfactor*2; acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; } + else if (player->pflags & PF_BOUNCING) + { + thrustfactor = player->thrustfactor/2; + acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; + } // Forward movement if (player->climbing) @@ -6703,9 +6718,44 @@ static void P_MovePlayer(player_t *player) player->climbing = 0; } + if ((!(player->charability == CA_BOUNCE) || player->gotflag) // If you can't bounce, then why the heck would you be bouncing? + && (player->pflags & PF_BOUNCING)) + { + if (onground) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else + { + player->pflags |= PF_JUMPED; + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + } + player->pflags &= ~PF_BOUNCING; + } + + // Bouncing... + if (player->pflags & PF_BOUNCING) + { + if (!(player->pflags & PF_JUMPDOWN)) // If not holding the jump button + { + P_ResetPlayer(player); // down, stop bouncing. + if (onground) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (player->charability2 == CA2_MULTIABILITY) + { + player->pflags |= PF_JUMPED; + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + } + else + { + player->pflags |= PF_THOKKED; + player->mo->momx >>= 1; + player->mo->momy >>= 1; + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + } + } + } // Glide MOMZ // AKA my own gravity. =) - if (player->pflags & PF_GLIDING) + else if (player->pflags & PF_GLIDING) { fixed_t leeway; fixed_t glidespeed = player->actionspd; @@ -6749,8 +6799,7 @@ static void P_MovePlayer(player_t *player) P_ResetPlayer(player); // down, stop gliding. if (onground) P_SetPlayerMobjState(player->mo, S_PLAY_WALK); - else if (player->charability2 == CA2_MULTIABILITY - && player->charability == CA_GLIDEANDCLIMB) + else if (player->charability2 == CA2_MULTIABILITY) { player->pflags |= PF_JUMPED; P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); @@ -9330,7 +9379,7 @@ void P_PlayerThink(player_t *player) player->pflags &= ~PF_SLIDING; #define dashmode player->dashmode - // Dash mode ability for Metal Sonic + // Dash mode ability if ((player->charability == CA_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. { if (player->speed >= FixedMul(player->runspeed, player->mo->scale) || (player->pflags & PF_STARTDASH))