Reimplement squishing damange

This commit is contained in:
NepDisk 2024-07-31 17:05:16 -04:00
parent b37be52225
commit ac72e705a6
14 changed files with 168 additions and 92 deletions

View file

@ -482,7 +482,8 @@ typedef struct player_s
UINT8 boostcharge; // Charge during race start
INT16 growshrinktimer; // > 0 = Big, < 0 = small
INT16 growcancel; // Duration of grow canceling
INT16 growcancel; // Duration of grow canceling
INT16 squishedtimer; // Duration of being squished
UINT16 rocketsneakertimer; // Rocket Sneaker duration timer
UINT16 invincibilitytimer; // Invincibility timer

View file

@ -5506,7 +5506,6 @@ const char *const MOBJFLAG_LIST[] = {
"RUNSPAWNFUNC",
"DONTENCOREMAP",
"PICKUPFROMBELOW",
"NOSQUISH",
NULL
};
@ -6247,6 +6246,7 @@ struct int_const_s const INT_CONST[] = {
// for P_DamageMobj
//// Damage types
{"DMG_NORMAL",DMG_NORMAL},
{"DMG_SQUISH",DMG_SQUISH},
{"DMG_WIPEOUT",DMG_WIPEOUT},
{"DMG_EXPLODE",DMG_EXPLODE},
{"DMG_STING",DMG_STING},

View file

@ -22893,7 +22893,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP|MF_NOSQUISH, // flags
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},

View file

@ -262,7 +262,7 @@ void K_UpdateMatchRaceBots(void)
boolean K_PlayerUsesBotMovement(player_t *player)
{
if (player->exiting)
return true;
return false;
if (player->bot)
return true;
@ -278,11 +278,7 @@ boolean K_PlayerUsesBotMovement(player_t *player)
boolean K_BotCanTakeCut(player_t *player)
{
if (
#if 1
K_TripwirePassConditions(player) != TRIPWIRE_NONE
#else
K_ApplyOffroad(player) == false
#endif
(K_TripwirePassConditions(player) != TRIPWIRE_NONE || K_ApplyOffroad(player) == false)
|| player->itemtype == KITEM_SNEAKER
|| player->itemtype == KITEM_ROCKETSNEAKER
|| player->itemtype == KITEM_INVINCIBILITY

View file

@ -842,8 +842,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
boolean stungT1 = false;
boolean stungT2 = false;
t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)) || (t1->player->invincibilitytimer > 0);
t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)) || (t2->player->invincibilitytimer > 0);
t1Condition = (t1->player->invincibilitytimer > 0);
t2Condition = (t2->player->invincibilitytimer > 0);
if ((t1Condition == true || flameT1 == true) && (t2Condition == true || flameT2 == true))
{
@ -860,6 +860,25 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT);
return true;
}
t1Condition = (t1->scale > t2->scale + (mapobjectscale/8));
t2Condition = (t2->scale > t1->scale + (mapobjectscale/8));
if ((t1Condition == true || flameT1 == true) && (t2Condition == true || flameT2 == true))
{
K_DoPowerClash(t1->player, t2->player);
return false;
}
else if (t1Condition == true && t2Condition == false)
{
P_DamageMobj(t2, t1, t1, 1, DMG_SQUISH);
return true;
}
else if (t1Condition == false && t2Condition == true)
{
P_DamageMobj(t1, t2, t2, 1, DMG_SQUISH);
return true;
}
// Flame Shield dash damage
t1Condition = flameT1;

View file

@ -7,6 +7,7 @@
#include "k_kart.h"
#include "d_player.h"
#include "doomstat.h"
#include "info.h"
#include "k_battle.h"
#include "k_boss.h"
#include "k_pwrlv.h"
@ -1396,6 +1397,11 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2)
return false;
}
}
if ((mobj1->player && mobj1->player->squishedtimer > 0)
|| (mobj2->player && mobj2->player->squishedtimer > 0))
return false;
// Don't bump if you've recently bumped
if (mobj1->player && mobj1->player->justbumped)
@ -3230,6 +3236,76 @@ static void K_RemoveGrowShrink(player_t *player)
P_RestoreMusic(player);
}
INT32 K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, boolean crush)
{
if (crush)
{
if ((player->invincibilitytimer > 0) || (player->growshrinktimer > 0)
|| (player->hyudorotimer > 0) || (player->flashing > 0) || (player->squishedtimer > 0))
{
K_DoInstashield(player);
return 0;
}
player->instashield = 15;
player->squishedtimer = TICRATE;
// Reduce Shrink timer
if (player->growshrinktimer < 0)
{
player->growshrinktimer += TICRATE;
if (player->growshrinktimer >= 0)
K_RemoveGrowShrink(player);
}
player->mo->flags |= MF_NOCLIP;
player->instashield = 15;
player->sneakertimer = 0;
player->driftboost = 0;
player->ringboost = 0;
player->glanceDir = 0;
player->pflags &= ~PF_GAINAX;
K_PlayPainSound(player->mo, NULL);
P_PlayRinglossSound(player->mo);
P_PlayerRingBurst(player, 5);
if (gametyperules & GTR_BUMPERS)
{
if (player->bumpers > 0)
player->bumpers--;
}
return 0;
}
else
{
player->squishedtimer = TICRATE;
// Reduce Shrink timer
if (player->growshrinktimer < 0)
{
player->growshrinktimer += TICRATE;
if (player->growshrinktimer >= 0)
K_RemoveGrowShrink(player);
}
player->mo->flags |= MF_NOCLIP;
player->instashield = 15;
if (cv_kartdebughuddrop.value && !modeattacking)
K_DropItems(player);
else
{
K_DropHnextList(player, false);
}
return 5;
}
}
void K_ApplyTripWire(player_t *player, tripwirestate_t state)
{
if (state == TRIPSTATE_PASSED)
@ -3249,6 +3325,8 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A
K_DirectorFollowAttack(player, inflictor, source);
player->mo->momz = 18*mapobjectscale*P_MobjFlip(player->mo); // please stop forgetting mobjflip checks!!!!
if (player->mo->eflags & MFE_UNDERWATER)
player->mo->momz = (117 * player->mo->momz) / 200;
player->mo->momx = player->mo->momy = 0;
player->spinouttype = KSPIN_EXPLOSION;
@ -3264,9 +3342,6 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A
}
}
if (player->mo->eflags & MFE_UNDERWATER)
player->mo->momz = (117 * player->mo->momz) / 200;
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
if (P_IsDisplayPlayer(player))
@ -4107,50 +4182,6 @@ void K_DriftDustHandling(mobj_t *spawner)
}
}
void K_Squish(mobj_t *mo)
{
const fixed_t maxstretch = 4*FRACUNIT;
const fixed_t factor = 5 * mo->height / 4;
const fixed_t threshold = factor / 6;
fixed_t old3dspeed = abs(mo->lastmomz);
fixed_t new3dspeed = abs(mo->momz);
fixed_t delta = abs(old3dspeed - new3dspeed);
fixed_t grav = mo->height/3;
fixed_t add = abs(grav - new3dspeed);
if (R_ThingIsFloorSprite(mo))
return;
if (delta < 2 * add && new3dspeed > grav)
delta += add;
if (delta > threshold)
{
mo->spritexscale =
FRACUNIT + FixedDiv(delta, factor);
if (mo->spritexscale > maxstretch)
mo->spritexscale = maxstretch;
if (new3dspeed > old3dspeed || new3dspeed > grav)
{
mo->spritexscale =
FixedDiv(FRACUNIT, mo->spritexscale);
}
}
else
{
mo->spritexscale -=
(mo->spritexscale - FRACUNIT)
/ (mo->spritexscale < FRACUNIT ? 8 : 3);
}
mo->spriteyscale =
FixedDiv(FRACUNIT, mo->spritexscale);
}
static mobj_t *K_FindLastTrailMobj(player_t *player)
{
mobj_t *trail;
@ -6563,7 +6594,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->karthud[khud_timeovercam] = 0;
// Make ABSOLUTELY SURE that your flashing tics don't get set WHILE you're still in hit animations.
if (player->spinouttimer != 0 || player->wipeoutslow != 0)
if (player->spinouttimer != 0 || player->wipeoutslow != 0 || player->squishedtimer != 0)
{
if (( player->spinouttype & KSPIN_IFRAMES ) == 0)
player->flashing = 0;
@ -6745,6 +6776,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->stealingtimer--;
else if (player->stealingtimer < 0)
player->stealingtimer++;
if (player->squishedtimer > 0)
player->squishedtimer--;
if (player->justbumped > 0)
player->justbumped--;
@ -6880,6 +6914,19 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
K_HandleDelayedHitByEm(player);
K_RaceStart(player);
// Squishing
// If a Grow player or a sector crushes you, get flattened instead of being killed.
if (player->squishedtimer <= 0)
{
player->mo->flags &= ~MF_NOCLIP;
}
else
{
player->mo->flags |= MF_NOCLIP;
player->mo->momx = 0;
player->mo->momy = 0;
}
}
void K_KartResetPlayerColor(player_t *player)
@ -9013,6 +9060,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_AdjustPlayerFriction(player);
K_KartDrift(player, onground);
// Quick Turning
// You can't turn your kart when you're not moving.
// So now it's time to burn some rubber!
if (player->speed < 2 && leveltime > starttime && player->cmd.buttons & BT_ACCELERATE && player->cmd.buttons & BT_BRAKE && player->cmd.turning != 0)
{
if (leveltime % 8 == 0)
S_StartSound(player->mo, sfx_s224);
}
if (onground == false)
{

View file

@ -74,7 +74,6 @@ void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent);
void K_DriftDustHandling(mobj_t *spawner);
void K_Squish(mobj_t *mo);
mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow);
void K_PuntMine(mobj_t *mine, mobj_t *punter);
void K_DoSneaker(player_t *player, INT32 type);
@ -109,6 +108,7 @@ boolean K_SlopeResistance(player_t *player);
tripwirepass_t K_TripwirePassConditions(player_t *player);
boolean K_TripwirePass(player_t *player);
boolean K_WaterRun(player_t *player);
INT32 K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, boolean crush);
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberbanding);

View file

@ -127,7 +127,12 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
if (weapon == 2)
{
// Invulnerable
if (player->flashing > 0)
if (player->flashing > 0
|| player->spinouttimer > 0
|| player->squishedtimer > 0
|| player->invincibilitytimer > 0
|| player->growshrinktimer > 0
|| player->hyudorotimer > 0)
return false;
// Already have fake
@ -2051,6 +2056,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
case DMG_KARMA:
ringburst = K_ExplodePlayer(player, inflictor, source);
break;
case DMG_SQUISH:
ringburst = K_SquishPlayer(player, inflictor, source, false);
break;
case DMG_WIPEOUT:
if (P_IsDisplayPlayer(player))
P_StartQuake(32<<FRACBITS, 5);

View file

@ -482,7 +482,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_SQUISH 0x03
#define DMG_STING 0x04
#define DMG_KARMA 0x05 // Karma Bomb explosion -- works like DMG_EXPLODE, but steals half of their bumpers & deletes the rest
//// Death types - cannot be combined with damage types

View file

@ -1229,11 +1229,11 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL);
}
if (K_KartBouncing(tmthing, thing) == true)
{
K_PvPTouchDamage(tmthing, thing);
}
if (K_PvPTouchDamage(tmthing, thing) == true)
K_KartBouncing(tmthing, thing);
else
K_KartBouncing(tmthing, thing);
return BMIT_CONTINUE;
}
else if (thing->type == MT_BLUEROBRA_HEAD || thing->type == MT_BLUEROBRA_JOINT)
@ -1317,7 +1317,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
// collide
if (tmthing->z < thing->z && thing->momz < 0)
;//P_DamageMobj(tmthing, thing, thing, 1, DMG_SQUISH);
P_DamageMobj(tmthing, thing, thing, 1, DMG_SQUISH);
else
{
if ((K_KartSolidBounce(tmthing, thing) == true) && (thing->flags2 & MF2_AMBUSH))
@ -4117,8 +4117,10 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
// Crush the object
if (netgame && thing->player && thing->player->spectator)
P_DamageMobj(thing, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
else if (!thing->player)
P_DamageMobj(thing, killer, killer, 1, DMG_CRUSHED);
else
P_DamageMobj(thing, NULL, NULL, 1, DMG_SQUISH);
return true;
}
}

View file

@ -2733,7 +2733,7 @@ void P_PlayerZMovement(mobj_t *mo)
K_UpdateMobjTerrain(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingpic : tmfloorpic));
// Get up if you fell.
if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0)
if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0 && mo->player->squishedtimer == 0)
{
P_SetPlayerMobjState(mo, S_KART_STILL);
}
@ -3663,17 +3663,6 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj)
}
}
static void P_SquishThink(mobj_t *mobj)
{
if (!(mobj->flags & MF_NOSQUISH) &&
!(mobj->eflags & MFE_SLOPELAUNCHED))
{
K_Squish(mobj);
}
mobj->lastmomz = mobj->momz;
}
static void P_PlayerMobjThinker(mobj_t *mobj)
{
I_Assert(mobj != NULL);
@ -3739,7 +3728,6 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
P_SquishThink(mobj);
K_UpdateTerrainOverlay(mobj);
animonly:
@ -9269,7 +9257,6 @@ void P_MobjThinker(mobj_t *mobj)
P_ButteredSlope(mobj);
}
P_SquishThink(mobj);
K_UpdateTerrainOverlay(mobj);
if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health

View file

@ -159,10 +159,8 @@ typedef enum
MF_DONTENCOREMAP = 1<<28,
// Hitbox extends just as far below as above.
MF_PICKUPFROMBELOW = 1<<29,
// Disable momentum-based squash and stretch.
MF_NOSQUISH = 1<<30,
// Free
// = (INT32)(1U<<31),
//free = 1<<30,
//free = (INT32)(1U<<31),
// no more free slots, next up I suppose we can get rid of shit like MF_BOXICON?
} mobjflag_t;

View file

@ -257,6 +257,7 @@ static void P_NetArchivePlayers(void)
WRITEUINT16(save_p, players[i].flashing);
WRITEUINT16(save_p, players[i].spinouttimer);
WRITEUINT8(save_p, players[i].spinouttype);
WRITEINT16(save_p, players[i].squishedtimer);
WRITEUINT8(save_p, players[i].instashield);
WRITEUINT8(save_p, players[i].wipeoutslow);
WRITEUINT8(save_p, players[i].justbumped);
@ -541,6 +542,7 @@ static void P_NetUnArchivePlayers(void)
players[i].flashing = READUINT16(save_p);
players[i].spinouttimer = READUINT16(save_p);
players[i].spinouttype = READUINT8(save_p);
players[i].squishedtimer = READINT16(save_p);
players[i].instashield = READUINT8(save_p);
players[i].wipeoutslow = READUINT8(save_p);
players[i].justbumped = READUINT8(save_p);

View file

@ -20,6 +20,7 @@
#include "d_event.h"
#include "d_net.h"
#include "g_game.h"
#include "info.h"
#include "p_local.h"
#include "r_fps.h"
#include "r_main.h"
@ -454,7 +455,7 @@ UINT8 P_FindHighestLap(void)
//
boolean P_PlayerInPain(player_t *player)
{
if (player->spinouttimer)
if (player->spinouttimer || player->squishedtimer)
return true;
return false;
@ -2144,7 +2145,14 @@ void P_MovePlayer(player_t *player)
player->justDI = 0;
}
if (player->carry == CR_SLIDING)
if (player->squishedtimer > 0)
{
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
player->mo->spriteyscale = (FRACUNIT / 4);
if (player->squishedtimer == 1)
player->mo->spriteyscale = FRACUNIT;
}
else if (player->carry == CR_SLIDING)
{
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
player->drawangle -= ANGLE_22h;
@ -2171,8 +2179,7 @@ void P_MovePlayer(player_t *player)
}
else if (player->nocontrol && player->pflags & PF_SKIDDOWN)
{
if (player->mo->state != &states[S_KART_SPINOUT])
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
if (((player->nocontrol + 5) % 20) < 10)
player->drawangle += ANGLE_11hh;
@ -2345,7 +2352,7 @@ void P_MovePlayer(player_t *player)
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);
K_SquishPlayer(player, NULL, NULL, true); // SRB2kart - we don't kill when squished, we squish when squished.
if (player->playerstate == PST_DEAD)
return;