diff --git a/src/lua_baselib.c b/src/lua_baselib.c index fca8050a9..33e54123d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -777,6 +777,16 @@ static int lib_pDoJumpShield(lua_State *L) return 0; } +static int lib_pDoBubbleBounce(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoBubbleBounce(player); + return 0; +} + static int lib_pBlackOw(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2048,6 +2058,7 @@ static luaL_Reg lib[] = { {"P_GivePlayerLives",lib_pGivePlayerLives}, {"P_ResetScore",lib_pResetScore}, {"P_DoJumpShield",lib_pDoJumpShield}, + {"P_DoBubbleBounce",lib_pDoBubbleBounce}, {"P_BlackOw",lib_pBlackOw}, {"P_ElementalFire",lib_pElementalFire}, {"P_DoPlayerExit",lib_pDoPlayerExit}, diff --git a/src/p_inter.c b/src/p_inter.c index 3abb9aaca..56e730017 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -240,7 +240,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player_t *player; INT32 i; - boolean elementalpierce; + UINT8 elementalpierce; if (objectplacing) return; @@ -295,7 +295,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; #endif - elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)); + // 0 = none, 1 = elemental pierce, 2 = bubble bounce + elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY) + ? (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2) + : 0); if (special->flags & MF_BOSS) { @@ -313,8 +316,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce) // Do you possess the ability to subdue the object? { - if ((P_MobjFlip(toucher)*toucher->momz < 0) && !elementalpierce) - toucher->momz = -toucher->momz; + if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) + { + if (elementalpierce == 2) + P_DoBubbleBounce(player); + else + toucher->momz = -toucher->momz; + } toucher->momx = -toucher->momx; toucher->momy = -toucher->momy; P_DamageMobj(special, toucher, toucher, 1, 0); @@ -359,8 +367,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || ((player->charflags & SF_STOMPDAMAGE) && (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) - toucher->momz = -toucher->momz; + if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) + { + if (elementalpierce == 2) + P_DoBubbleBounce(player); + else + toucher->momz = -toucher->momz; + } P_DamageMobj(special, toucher, toucher, 1, 0); } diff --git a/src/p_local.h b/src/p_local.h index ee61d3389..322675f03 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -153,6 +153,7 @@ void P_ResetScore(player_t *player); boolean P_AutoPause(void); void P_DoJumpShield(player_t *player); +void P_DoBubbleBounce(player_t *player); void P_BlackOw(player_t *player); void P_ElementalFire(player_t *player, boolean cropcircle); diff --git a/src/p_map.c b/src/p_map.c index 72668e478..54eecac7a 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1052,9 +1052,10 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) { - boolean elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL - || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) - && (tmthing->player->pflags & PF_SHIELDABILITY)); + // 0 = none, 1 = elemental pierce, 2 = bubble bounce + UINT8 elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY) + ? (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2) + : 0); if (thing->flags & MF_MONITOR && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) || ((tmthing->player->pflags & PF_JUMPED) @@ -1066,6 +1067,7 @@ static boolean PIT_CheckThing(mobj_t *thing) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) || elementalpierce)) { + player_t *player = tmthing->player; SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; fixed_t *z = &tmthing->z; // aau. @@ -1074,9 +1076,14 @@ static boolean PIT_CheckThing(mobj_t *thing) if ((P_MobjWasRemoved(thing) // Monitor was removed || !thing->health) // or otherwise popped && (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up - && !elementalpierce) // you're not piercing through the monitor... - *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. - if (!(elementalpierce && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough. + && (elementalpierce != 1)) // you're not piercing through the monitor... + { + if (elementalpierce == 2) + P_DoBubbleBounce(player); + else + *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. + } + if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough. return false; else *z -= *momz; // to ensure proper collision. diff --git a/src/p_mobj.c b/src/p_mobj.c index c94587ab4..31e0d477c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3236,6 +3236,7 @@ static void P_PlayerZMovement(mobj_t *mo) mo->player->pflags &= ~(PF_JUMPED|PF_FORCEJUMPDAMAGE); mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/); + mo->player->jumping = 0; mo->player->secondjump = 0; mo->player->glidetime = 0; mo->player->climbing = 0; @@ -3265,18 +3266,10 @@ static void P_PlayerZMovement(mobj_t *mo) } else if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack. { - S_StartSound(mo, sfx_s3k44); - P_DoJump(mo->player, false); - if (mo->player->charflags & SF_NOJUMPSPIN) - P_SetPlayerMobjState(mo, S_PLAY_FALL); - mo->player->pflags |= PF_THOKKED; - mo->player->secondjump = UINT8_MAX; - mo->momz = FixedMul(mo->momz, 5*FRACUNIT/4); + P_DoBubbleBounce(mo->player); clipmomz = false; } } - - mo->player->jumping = 0; // done down here because of bubblewrap } } if (!(mo->player->pflags & PF_SPINNING)) diff --git a/src/p_user.c b/src/p_user.c index 3754623de..5aa50458e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3927,6 +3927,24 @@ void P_DoJumpShield(player_t *player) } } +// +// P_DoBubbleBounce +// +// Bubblewrap shield landing handling +// +void P_DoBubbleBounce(player_t *player) +{ + player->pflags &= ~(PF_JUMPED|PF_SHIELDABILITY); + S_StartSound(player->mo, sfx_s3k44); + P_DoJump(player, false); + if (player->charflags & SF_NOJUMPSPIN) + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + player->pflags |= PF_THOKKED; + player->jumping = 0; + player->secondjump = UINT8_MAX; + player->mo->momz = FixedMul(player->mo->momz, 5*FRACUNIT/4); +} + // // P_Telekinesis //