Cherry-pick 4eb69a664

This commit is contained in:
Sally Coolatta 2020-08-23 21:33:47 -04:00
parent 34450fa028
commit 14b379fd27
17 changed files with 267 additions and 191 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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},

View file

@ -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;
}

View file

@ -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

View file

@ -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<<FRACBITS, 5);
}
static void K_HandleTumbleBounce(player_t *player)
{
player->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<<FRACBITS, 5);
K_DropItems(player);
}
// This kind of wipeout happens with no rings -- doesn't remove a bumper, has no invulnerability, and is much shorter.
@ -5649,9 +5665,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->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
{

View file

@ -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);

View file

@ -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},

View file

@ -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"))

View file

@ -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<<FRACBITS, 5);
K_SpinPlayer(player, inflictor, source, KSPIN_WIPEOUT);
K_KartPainEnergyFling(player);
break;

View file

@ -465,7 +465,7 @@ typedef struct BasicFF_s
#define DMG_NORMAL 0x00
#define DMG_WIPEOUT 0x01 // Normal, but with extra flashy effects
#define DMG_EXPLODE 0x02
#define DMG_SQUISH 0x03
#define DMG_TUMBLE 0x03
#define DMG_STING 0x04
//// Death types - cannot be combined with damage types
#define DMG_INSTAKILL 0x80

View file

@ -1209,69 +1209,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
return false;
}
// Damage other players when invincible
if (tmthing->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)

View file

@ -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)) {

View file

@ -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);

View file

@ -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);

View file

@ -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]++;