From 14b379fd2741e658672adddb0a9039f21d81148a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 23 Aug 2020 21:33:47 -0400 Subject: [PATCH] Cherry-pick 4eb69a664 --- src/d_clisrv.c | 8 +++ src/d_clisrv.h | 4 ++ src/d_player.h | 4 ++ src/dehacked.c | 2 +- src/k_collide.c | 106 +++++++++++++++++++++++++++++++- src/k_collide.h | 1 + src/k_kart.c | 144 ++++++++++++++++++++++---------------------- src/k_kart.h | 2 +- src/lua_baselib.c | 6 +- src/lua_playerlib.c | 12 ++++ src/p_inter.c | 9 +-- src/p_local.h | 2 +- src/p_map.c | 92 ++-------------------------- src/p_mobj.c | 7 ++- src/p_saveg.c | 8 +++ src/p_spec.c | 3 - src/p_user.c | 48 ++++++++++----- 17 files changed, 267 insertions(+), 191 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e4e19d259..036170c29 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -616,6 +616,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); + rsp->tumbleBounces = players[i].tumbleBounces; + rsp->tumbleHeight = SHORT(players[i].tumbleHeight); + rsp->tumbleLastBounce = players[i].tumbleLastBounce; + // respawnvars_t rsp->respawn_state = players[i].respawn.state; rsp->respawn_pointx = (fixed_t)LONG(players[i].respawn.pointx); @@ -759,6 +763,10 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); + players[i].tumbleBounces = rsp->tumbleBounces; + players[i].tumbleHeight = SHORT(rsp->tumbleHeight); + players[i].tumbleLastBounce = (boolean)rsp->tumbleLastBounce; + // respawnvars_t players[i].respawn.state = rsp->respawn_state; players[i].respawn.pointx = (fixed_t)LONG(rsp->respawn_pointx); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 013990325..05d12250b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,6 +281,10 @@ typedef struct INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; + UINT8 tumbleBounces; + UINT16 tumbleHeight; + boolean tumbleLastBounce; + // respawnvars_t UINT8 respawn_state; fixed_t respawn_pointx; diff --git a/src/d_player.h b/src/d_player.h index f4683a62b..1d71668f4 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -553,6 +553,10 @@ typedef struct player_s UINT16 followercolor; // Kart: Used to store the follower colour the player wishes to use mobj_t *follower; // Kart: This is the follower object we have. (If any) + UINT8 tumbleBounces; + UINT16 tumbleHeight; + boolean tumbleLastBounce; + // UINT32 charflags; // Extra abilities/settings for skins (combinable stuff) diff --git a/src/dehacked.c b/src/dehacked.c index 7f6be7e6d..471499c5c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -11273,7 +11273,7 @@ struct { {"DMG_NORMAL",DMG_NORMAL}, {"DMG_WIPEOUT",DMG_WIPEOUT}, {"DMG_EXPLODE",DMG_EXPLODE}, - {"DMG_SQUISH",DMG_SQUISH}, + {"DMG_TUMBLE",DMG_TUMBLE}, {"DMG_STING",DMG_STING}, //// Death types {"DMG_INSTAKILL",DMG_INSTAKILL}, diff --git a/src/k_collide.c b/src/k_collide.c index 7fbe17603..0f2361062 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -380,10 +380,112 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) if (t1->health) P_KillMobj(t1, t2, t2, DMG_NORMAL); - /*if (t2->player && (t2->player->kartstuff[k_invincibilitytimer] > 0 + /* + if (t2->player && (t2->player->kartstuff[k_invincibilitytimer] > 0 || t2->player->kartstuff[k_growshrinktimer] > 0)) - return true;*/ + return true; + */ K_KartBouncing(t2, t1, false, true); return false; } + +boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) +{ + boolean t1Condition = false; + boolean t2Condition = false; + boolean stung = false; + + // Grow damage + t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)); + t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)); + + if (t1Condition == true && t2Condition == false) + { + P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE); + return true; + } + else if (t1Condition == false && t2Condition == true) + { + P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); + return true; + } + + // Invincibility damage + t1Condition = (t1->player->kartstuff[k_invincibilitytimer] > 0); + t2Condition = (t2->player->kartstuff[k_invincibilitytimer] > 0); + + if (t1Condition == true && t2Condition == false) + { + P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE); + return true; + } + else if (t1Condition == false && t2Condition == true) + { + P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); + return true; + } + + // Flame Shield dash damage + t1Condition = (t1->player->kartstuff[k_flamedash] > 0 && t1->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD); + t2Condition = (t2->player->kartstuff[k_flamedash] > 0 && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD); + + if (t1Condition == true && t2Condition == false) + { + P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT); + return true; + } + else if (t1Condition == false && t2Condition == true) + { + P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT); + return true; + } + + // Battle Mode Sneaker damage + // (Pogo Spring damage is handled in head-stomping code) + if (gametyperules & GTR_BUMPERS) + { + t1Condition = (t1->player->kartstuff[k_sneakertimer] > 0 && t1->player->powers[pw_flashing] != 0); + t2Condition = (t2->player->kartstuff[k_sneakertimer] > 0 && t2->player->powers[pw_flashing] != 0); + + if (t1Condition == true && t2Condition == false) + { + P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_STEAL); + return true; + } + else if (t1Condition == false && t2Condition == true) + { + P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_STEAL); + return true; + } + } + + // Ring sting, this is a bit more unique + t1Condition = (K_GetShieldFromItem(t2->player->kartstuff[k_itemtype]) == KSHIELD_NONE); + t2Condition = (K_GetShieldFromItem(t1->player->kartstuff[k_itemtype]) == KSHIELD_NONE); + + if (t1Condition == true) + { + if (t2->player->rings <= 0) + { + P_DamageMobj(t2, t1, t1, 1, DMG_STING); + stung = true; + } + + P_PlayerRingBurst(t2->player, 1); + stung = true; + } + + if (t2Condition == true) + { + if (t1->player->rings <= 0) + { + P_DamageMobj(t1, t2, t2, 1, DMG_STING); + stung = true; + } + + P_PlayerRingBurst(t2->player, 1); + } + + return stung; +} diff --git a/src/k_collide.h b/src/k_collide.h index 86f643b3f..75a9404f8 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -12,5 +12,6 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); +boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/k_kart.c b/src/k_kart.c index e35b9ff56..26a878679 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -976,7 +976,7 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) return weight; if (against && !P_MobjWasRemoved(against) && against->player - && ((!against->player->kartstuff[k_spinouttimer] && mobj->player->kartstuff[k_spinouttimer]) // You're in spinout + && ((!P_PlayerInPain(against->player) && P_PlayerInPain(mobj->player)) // You're hurt || (against->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD && mobj->player->kartstuff[k_itemtype] != KITEM_BUBBLESHIELD))) // They have a Bubble Shield { weight = 0; // This player does not cause any bump action @@ -1056,24 +1056,21 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) || (mobj2->player && mobj2->player->respawn.state != RESPAWNST_NONE)) return; - { // Don't bump if you're flashing - INT32 flash; + // Don't bump if you're flashing + if (mobj1->player && mobj1->player->powers[pw_flashing] > 0 && !P_PlayerInPain(mobj1->player)) + { + INT32 flash = K_GetKartFlashing(mobj1->player); + if (mobj1->player->powers[pw_flashing] < flash) + mobj1->player->powers[pw_flashing]++; + return; + } - flash = K_GetKartFlashing(mobj1->player); - if (mobj1->player && mobj1->player->powers[pw_flashing] > 0 && mobj1->player->powers[pw_flashing] < flash) - { - if (mobj1->player->powers[pw_flashing] < flash-1) - mobj1->player->powers[pw_flashing]++; - return; - } - - flash = K_GetKartFlashing(mobj2->player); - if (mobj2->player && mobj2->player->powers[pw_flashing] > 0 && mobj2->player->powers[pw_flashing] < flash) - { - if (mobj2->player->powers[pw_flashing] < flash-1) - mobj2->player->powers[pw_flashing]++; - return; - } + if (mobj2->player && mobj2->player->powers[pw_flashing] > 0 && !P_PlayerInPain(mobj2->player)) + { + INT32 flash = K_GetKartFlashing(mobj2->player); + if (mobj2->player->powers[pw_flashing] < flash) + mobj2->player->powers[pw_flashing]++; + return; } // Don't bump if you've recently bumped @@ -1199,15 +1196,6 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) mobj1->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj1->player->kartstuff[k_spinouttimer]); //mobj1->player->kartstuff[k_spinouttype] = KSPIN_WIPEOUT; // Enforce type } - else if (mobj2->player // Player VS player bumping only - && (K_GetShieldFromItem(mobj1->player->kartstuff[k_itemtype]) == KSHIELD_NONE)) // Ignore for shields - { - if (mobj1->player->rings <= 0) - { - P_DamageMobj(mobj1, mobj2, mobj2, 1, DMG_STING); - } - P_PlayerRingBurst(mobj1->player, 1); - } } if (mobj2->player) @@ -1223,15 +1211,6 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) mobj2->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj2->player->kartstuff[k_spinouttimer]); //mobj2->player->kartstuff[k_spinouttype] = KSPIN_WIPEOUT; // Enforce type } - else if (mobj1->player // Player VS player bumping only - && (K_GetShieldFromItem(mobj2->player->kartstuff[k_itemtype]) == KSHIELD_NONE)) // Ignore for shields - { - if (mobj2->player->rings <= 0) - { - P_DamageMobj(mobj2, mobj1, mobj1, 1, DMG_STING); - } - P_PlayerRingBurst(mobj2->player, 1); - } } } @@ -2583,25 +2562,64 @@ static void K_RemoveGrowShrink(player_t *player) P_RestoreMusic(player); } -void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source) +void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) { - (void)inflictor; (void)source; - player->kartstuff[k_squishedtimer] = TICRATE; + player->tumbleBounces = 1; - // Reduce Shrink timer - if (player->kartstuff[k_growshrinktimer] < 0) + player->mo->momx = 2 * player->mo->momx / 3; + player->mo->momy = 2 * player->mo->momy / 3; + + player->tumbleHeight = 30; + + if (inflictor && !P_MobjWasRemoved(inflictor)) { - player->kartstuff[k_growshrinktimer] += TICRATE; - if (player->kartstuff[k_growshrinktimer] >= 0) - K_RemoveGrowShrink(player); + const fixed_t infSpeed = P_AproxDistance(inflictor->momx, inflictor->momy) / 2; + player->tumbleHeight += (infSpeed / player->mo->scale); } - player->mo->flags |= MF_NOCLIP; + player->mo->momz = player->tumbleHeight * player->mo->scale * P_MobjFlip(player->mo); - if (player->mo->state != &states[S_KART_SQUISH]) // Squash - P_SetPlayerMobjState(player->mo, S_KART_SQUISH); + P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); + + if (P_IsDisplayPlayer(player)) + P_StartQuake(64<tumbleBounces++; + player->tumbleHeight = (player->tumbleHeight * 4) / 5; + + if (player->tumbleHeight < 10) + { + // 10 minimum bounce height + player->tumbleHeight = 10; + } + + if (player->tumbleBounces > 4 && player->tumbleHeight < 30) + { + // Leave tumble state when below 30 height, and have bounced off the ground enough + + if (player->tumbleLastBounce == true) + { + // End tumble state + player->tumbleBounces = 0; + return; + } + else + { + // One last bounce at the minimum height, to reset the animation + player->tumbleHeight = 10; + player->tumbleLastBounce = true; + } + } + + player->mo->momx = player->mo->momx / 2; + player->mo->momy = player->mo->momy / 2; + + player->mo->momz = player->tumbleHeight * player->mo->scale * P_MobjFlip(player->mo); } void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer @@ -2630,8 +2648,6 @@ void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A b if (P_IsDisplayPlayer(player)) P_StartQuake(64<powers[pw_flashing] = 0; } // Make ABSOLUTELY SURE that your flashing tics don't get set WHILE you're still in hit animations. - else if (player->kartstuff[k_spinouttimer] != 0 - || player->kartstuff[k_wipeoutslow] != 0 - || player->kartstuff[k_squishedtimer] != 0) + else if (player->kartstuff[k_spinouttimer] != 0 || player->kartstuff[k_wipeoutslow] != 0) { player->powers[pw_flashing] = K_GetKartFlashing(player); } @@ -5776,22 +5790,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_stolentimer]) player->kartstuff[k_stolentimer]--; - if (player->kartstuff[k_squishedtimer]) - { - player->kartstuff[k_squishedtimer]--; - - if ((player->kartstuff[k_squishedtimer] == 0) && !(player->pflags & PF_NOCLIP)) - { - player->mo->flags &= ~MF_NOCLIP; - } - } - if (player->kartstuff[k_justbumped] > 0) player->kartstuff[k_justbumped]--; if (player->kartstuff[k_tiregrease]) player->kartstuff[k_tiregrease]--; + if (player->tumbleBounces > 0) + { + if (P_IsObjectOnGround(player->mo) && player->mo->momz * P_MobjFlip(player->mo) <= 0) + K_HandleTumbleBounce(player); + } + // This doesn't go in HUD update because it has potential gameplay ramifications if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0) { @@ -7774,16 +7784,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_KartDrift(player, P_IsObjectOnGround(player->mo)); // Not using onground, since we don't want this affected by spring pads K_KartSpindash(player); - // Squishing - // If a Grow player or a sector crushes you, get flattened instead of being killed. - - if (player->kartstuff[k_squishedtimer] > 0) - { - //player->mo->flags |= MF_NOCLIP; - player->mo->momx = 0; - player->mo->momy = 0; - } - // Play the starting countdown sounds if (player == &players[g_localplayers[0]]) // Don't play louder in splitscreen { diff --git a/src/k_kart.h b/src/k_kart.h index 408ed3303..e26e3de86 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -45,7 +45,7 @@ void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); -void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); +void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_StealBumper(player_t *player, player_t *victim); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 42e433254..81978546d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3400,7 +3400,7 @@ static int lib_kSpinPlayer(lua_State *L) return 0; } -static int lib_kSquishPlayer(lua_State *L) +static int lib_kTumblePlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *inflictor = NULL; @@ -3412,7 +3412,7 @@ static int lib_kSquishPlayer(lua_State *L) inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - K_SquishPlayer(player, inflictor, source); + K_TumblePlayer(player, inflictor, source); return 0; } @@ -3916,7 +3916,7 @@ static luaL_Reg lib[] = { {"K_DoInstashield",lib_kDoInstashield}, {"K_SpawnBattlePoints",lib_kSpawnBattlePoints}, {"K_SpinPlayer",lib_kSpinPlayer}, - {"K_SquishPlayer",lib_kSquishPlayer}, + {"K_TumblePlayer",lib_kTumblePlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, {"K_StealBumper",lib_kStealBumper}, {"K_SpawnKartExplosion",lib_kSpawnKartExplosion}, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 8a0113f08..812135f17 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -212,6 +212,12 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); else if (fastcmp(field,"airtime")) lua_pushinteger(L, plr->airtime); + else if (fastcmp(field,"tumbleBounces")) + lua_pushinteger(L, plr->tumbleBounces); + else if (fastcmp(field,"tumbleHeight")) + lua_pushinteger(L, plr->tumbleHeight); + else if (fastcmp(field,"tumbleLastBounce")) + lua_pushboolean(L, plr->tumbleLastBounce); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) @@ -499,6 +505,12 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"airtime")) plr->airtime = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"tumbleBounces")) + plr->tumbleBounces = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"tumbleHeight")) + plr->tumbleHeight = (UINT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"tumbleLastBounce")) + plr->tumbleLastBounce = luaL_checkboolean(L, 3); else if (fastcmp(field,"kartspeed")) plr->kartspeed = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartweight")) diff --git a/src/p_inter.c b/src/p_inter.c index efa3d3eaa..7d47599ae 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -282,7 +282,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!special->target->player->kartstuff[k_comebackmode]) { - if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_squishedtimer] + if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_hyudorotimer] || P_PlayerInPain(player) || player->kartstuff[k_invincibilitytimer] || player->powers[pw_flashing]) return; @@ -465,8 +465,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } // no interaction - if (player->powers[pw_flashing] > 0 || player->kartstuff[k_hyudorotimer] > 0 - || player->kartstuff[k_squishedtimer] > 0 || P_PlayerInPain(player)) + if (player->powers[pw_flashing] > 0 || player->kartstuff[k_hyudorotimer] > 0 || P_PlayerInPain(player)) return; // attach to player! @@ -1918,13 +1917,15 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_KartPainEnergyFling(player); ringburst = 0; break; + case DMG_TUMBLE: + K_TumblePlayer(player, inflictor, source); + break; case DMG_EXPLODE: K_ExplodePlayer(player, inflictor, source); break; case DMG_WIPEOUT: if (P_IsDisplayPlayer(player)) P_StartQuake(32<player && thing->player - // Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person. - && !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height)) - { - if (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam) - { - if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first! - { - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SQUISH); - } - else if (thing->scale > tmthing->scale + (mapobjectscale/8)) - { - P_DamageMobj(tmthing, thing, thing, 1, DMG_SQUISH); - } - else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility! - { - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT); - } - else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) - { - P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT); - } - else if ((tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) - && !(thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield! - { - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT); - } - else if ((thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) - && !(tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) - { - P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT); - } - } - } - if (thing->player) { - // Doesn't matter what gravity player's following! Just do your stuff in YOUR direction only - if (tmthing->eflags & MFE_VERTICALFLIP - && (tmthing->z + tmthing->height + tmthing->momz < thing->z - || tmthing->z + tmthing->height + tmthing->momz >= thing->z + thing->height)) - ; - else if (!(tmthing->eflags & MFE_VERTICALFLIP) - && (tmthing->z + tmthing->momz > thing->z + thing->height - || tmthing->z + tmthing->momz <= thing->z)) - ; - else if (P_IsObjectOnGround(thing) - && !P_IsObjectOnGround(tmthing) // Don't crush if the monitor is on the ground... - && (tmthing->flags & MF_SOLID)) - { - if (tmthing->flags & (MF_MONITOR|MF_PUSHABLE)) - { - // Objects kill you if it falls from above. - if (thing != tmthing->target) - P_DamageMobj(thing, tmthing, tmthing->target, 1, DMG_CRUSHED); - - tmthing->momz = -tmthing->momz/2; // Bounce, just for fun! - // The tmthing->target allows the pusher of the object - // to get the point if he topples it on an opponent. - } - } - if (tmthing->type == MT_FAN || tmthing->type == MT_STEAM) P_DoFanAndGasJet(tmthing, thing); } @@ -1299,10 +1238,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->player->kartstuff[k_squishedtimer] || thing->player->kartstuff[k_hyudorotimer] - || thing->player->kartstuff[k_justbumped] || thing->scale > tmthing->scale + (mapobjectscale/8) - || tmthing->player->kartstuff[k_squishedtimer] || tmthing->player->kartstuff[k_hyudorotimer] - || tmthing->player->kartstuff[k_justbumped] || tmthing->scale > thing->scale + (mapobjectscale/8)) + if (thing->player->kartstuff[k_hyudorotimer] || tmthing->player->kartstuff[k_hyudorotimer]) { return true; } @@ -1337,19 +1273,8 @@ static boolean PIT_CheckThing(mobj_t *thing) P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); } - if ((gametyperules & GTR_BUMPERS)) - { - if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible - { - P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); - } - else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing])) - { - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); - } - } - K_KartBouncing(mo1, mo2, zbounce, false); + K_PvPTouchDamage(mo1, mo2); } return true; @@ -1429,22 +1354,13 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - // continue to squish - if (tmthing->player->kartstuff[k_squishedtimer]) - { - tmthing->player->kartstuff[k_squishedtimer] = 2*TICRATE; - tmthing->player->powers[pw_flashing] = K_GetKartFlashing(tmthing->player); - return true; - } - // no interaction - if (tmthing->player->powers[pw_flashing] > 0 || tmthing->player->kartstuff[k_hyudorotimer] > 0 - || tmthing->player->kartstuff[k_spinouttimer] > 0) //|| tmthing->player->kartstuff[k_squishedtimer] > 0 + if (tmthing->player->powers[pw_flashing] > 0 || tmthing->player->kartstuff[k_hyudorotimer] > 0 || tmthing->player->kartstuff[k_spinouttimer] > 0) return true; // collide if (tmthing->z < thing->z && thing->momz < 0) - K_SquishPlayer(tmthing->player, thing, thing); + P_DamageMobj(tmthing, thing, thing, 1, DMG_TUMBLE); else { if (thing->flags2 & MF2_AMBUSH) diff --git a/src/p_mobj.c b/src/p_mobj.c index 42e61a918..4d443cea2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1105,6 +1105,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo) { gravityadd = (4*gravityadd)/3; } + + if (mo->player->tumbleBounces > 0) + { + gravityadd = (5*gravityadd)/2; + } } else { @@ -2605,7 +2610,7 @@ void P_PlayerZMovement(mobj_t *mo) mo->z = mo->floorz; // Get up if you fell. - if (mo->player->panim == PA_PAIN && mo->player->kartstuff[k_spinouttimer] == 0 && mo->player->kartstuff[k_squishedtimer] == 0) + if (mo->player->panim == PA_PAIN && mo->player->kartstuff[k_spinouttimer] == 0 && mo->player->tumbleBounces == 0) P_SetPlayerMobjState(mo, S_KART_STILL); if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { diff --git a/src/p_saveg.c b/src/p_saveg.c index e8309f8d5..7c9a3a96f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -256,6 +256,10 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); + WRITEUINT8(save_p, players[i].tumbleBounces); + WRITEUINT16(save_p, players[i].tumbleHeight); + WRITEUINT8(save_p, players[i].tumbleLastBounce); + // respawnvars_t WRITEUINT8(save_p, players[i].respawn.state); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -441,6 +445,10 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); + players[i].tumbleBounces = READUINT8(save_p); + players[i].tumbleHeight = READUINT16(save_p); + players[i].tumbleLastBounce = (boolean)READUINT8(save_p); + // respawnvars_t players[i].respawn.state = READUINT8(save_p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index 3d0eddd2e..c0ed5b63b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4832,9 +4832,6 @@ DoneSection2: if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; - if (player->powers[pw_ignorelatch] & (1<<15)) - break; - // Find line #3 tagged to this sector lineindex = P_FindSpecialLineFromTag(3, sector->tag, -1); diff --git a/src/p_user.c b/src/p_user.c index 6c6c0578a..c294d3f64 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -461,7 +461,10 @@ UINT8 P_FindHighestLap(void) // boolean P_PlayerInPain(player_t *player) { - if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer] || player->respawn.state != RESPAWNST_NONE) + if (player->respawn.state != RESPAWNST_NONE) + return true; + + if (player->kartstuff[k_spinouttimer] || player->tumbleBounces > 0) return true; if (gametyperules & GTR_KARMA) @@ -2157,18 +2160,35 @@ void P_MovePlayer(player_t *player) P_3dMovement(player); // Kart frames - if (player->kartstuff[k_squishedtimer] > 0) + if (player->tumbleBounces > 0) { - P_SetPlayerMobjState(player->mo, S_KART_SQUISH); + fixed_t playerSpeed = P_AproxDistance(player->mo->momx, player->mo->momy); // maybe momz too? + + const UINT8 minSpinSpeed = 4; + UINT8 spinSpeed = max(minSpinSpeed, min(8 + minSpinSpeed, (playerSpeed / player->mo->scale) * 2)); + + UINT8 rollSpeed = max(1, min(8, player->tumbleHeight / 10)); + + P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); + player->drawangle -= (ANGLE_11hh * spinSpeed); + + player->mo->rollangle -= (ANGLE_11hh * rollSpeed); + + if (player->tumbleLastBounce == true) + { + if (abs((signed)player->mo->rollangle) < ANGLE_22h) + player->mo->rollangle = 0; + } } else if (player->pflags & PF_SLIDING) { P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); player->drawangle -= ANGLE_22h; + player->mo->rollangle = 0; } else if (player->kartstuff[k_spinouttimer] > 0) { - INT32 speed = max(1, min(8, player->kartstuff[k_spinouttimer]/8)); + UINT8 speed = max(1, min(8, player->kartstuff[k_spinouttimer]/8)); P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); @@ -2176,6 +2196,8 @@ void P_MovePlayer(player_t *player) player->drawangle = player->mo->angle; // Face forward at the end of the animation else player->drawangle -= (ANGLE_11hh * speed); + + player->mo->rollangle = 0; } else if (player->pflags & PF_FAULT) { @@ -2185,6 +2207,8 @@ void P_MovePlayer(player_t *player) player->drawangle += ANGLE_11hh; else player->drawangle -= ANGLE_11hh; + + player->mo->rollangle = 0; } else { @@ -2204,6 +2228,8 @@ void P_MovePlayer(player_t *player) player->drawangle += a; } } + + player->mo->rollangle = 0; } player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. @@ -2358,7 +2384,7 @@ void P_MovePlayer(player_t *player) // Crush test... if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) && !(player->mo->flags & MF_NOCLIP)) { - if ((netgame || multiplayer) && player->spectator) + if (player->spectator) P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators else P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); @@ -4240,7 +4266,8 @@ void P_PlayerThink(player_t *player) // Track airtime if (P_IsObjectOnGround(player->mo)) { - player->airtime = 0; + if (!P_PlayerInPain(player)) + player->airtime = 0; } else { @@ -4502,10 +4529,6 @@ void P_PlayerThink(player_t *player) else player->pflags &= ~PF_SPINDOWN; - // IF PLAYER NOT HERE THEN FLASH END IF - if (player->quittime && player->powers[pw_flashing] < K_GetKartFlashing(player) && !player->gotflag) - player->powers[pw_flashing] = K_GetKartFlashing(player); - // Counters, time dependent power ups. // Time Bonus & Ring Bonus count settings @@ -4524,11 +4547,6 @@ void P_PlayerThink(player_t *player) else player->powers[pw_nocontrol] = 0; - if (player->powers[pw_ignorelatch] & ((1<<15)-1) && player->powers[pw_ignorelatch] < UINT16_MAX) - player->powers[pw_ignorelatch]--; - else - player->powers[pw_ignorelatch] = 0; - //pw_super acts as a timer now if (player->powers[pw_super]) player->powers[pw_super]++;