Merge branch 'bumper-boats' into 'master'

Improved combo escape mechanics in Battle

See merge request KartKrew/Kart!1914
This commit is contained in:
Oni 2024-02-12 18:50:20 +00:00
commit 796e2b9517
9 changed files with 106 additions and 1 deletions

View file

@ -980,9 +980,11 @@ struct player_t
angle_t besthanddirection;
INT16 incontrol; // -1 to -175 when spinning out or tumbling, 1 to 175 when not. Use to check for combo hits or emergency inputs.
UINT16 progressivethrust; // When getting beat up in GTR_BUMPERS, speed up the longer you've been out of control.
boolean markedfordeath;
boolean dotrickfx;
UINT8 bumperinflate;
UINT8 ringboxdelay; // Delay until Ring Box auto-activates
UINT8 ringboxaward; // Where did we stop?

View file

@ -4562,6 +4562,22 @@ static boolean K_LastTumbleBounceCondition(player_t *player)
return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60);
}
// Bumpers give you bonus launch height and speed, strengthening your DI to help evade combos.
// bumperinflate visuals are handled by MT_BATTLEBUMPER, but the effects are in K_KartPlayerThink.
void K_BumperInflate(player_t *player)
{
if (!player || P_MobjWasRemoved(player->mo))
return;
if (!(gametyperules & GTR_BUMPERS))
return;
player->bumperinflate = 3;
if (player->mo->health > 1)
S_StartSound(player->mo, sfx_cdpcm9);
}
static void K_HandleTumbleBounce(player_t *player)
{
player->tumbleBounces++;
@ -4609,6 +4625,8 @@ static void K_HandleTumbleBounce(player_t *player)
}
}
K_BumperInflate(player);
// A bit of damage hitlag.
// This gives a window for DI!!
K_AddHitLag(player->mo, 3, true);
@ -8794,6 +8812,33 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->hyudorotimer)
player->hyudorotimer--;
if (player->bumperinflate && player->mo->hitlag == 0)
{
fixed_t thrustdelta = MAXCOMBOTHRUST - MINCOMBOTHRUST;
fixed_t floatdelta = MAXCOMBOFLOAT - MINCOMBOFLOAT;
fixed_t thrustpertic = thrustdelta / MAXCOMBOTIME;
fixed_t floatpertic = floatdelta / MAXCOMBOTIME;
fixed_t totalthrust = thrustpertic * player->progressivethrust + MINCOMBOTHRUST;
fixed_t totalfloat = floatpertic * player->progressivethrust + MINCOMBOFLOAT;
if (player->speed > K_GetKartSpeed(player, false, false))
totalthrust = 0;
if (player->tumbleBounces && player->tumbleBounces <= TUMBLEBOUNCES)
{
player->mo->momz += totalfloat;
P_Thrust(player->mo, K_MomentumAngle(player->mo), totalthrust/2);
}
else
{
P_Thrust(player->mo, K_MomentumAngle(player->mo), totalthrust);
}
player->bumperinflate--;
}
if (player->ringvolume < MINRINGVOLUME)
player->ringvolume = MINRINGVOLUME;
else if (MAXRINGVOLUME - player->ringvolume < RINGVOLUMEREGEN)
@ -8900,12 +8945,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->spinouttimer || player->tumbleBounces)
{
if (player->progressivethrust < MAXCOMBOTIME)
player->progressivethrust++;
if (player->incontrol > 0)
player->incontrol = 0;
player->incontrol--;
}
else
{
if (player->progressivethrust)
player->progressivethrust--;
if (player->incontrol < 0)
player->incontrol = 0;
player->incontrol++;

View file

@ -37,6 +37,12 @@ Make sure this matches the actual number of states
#define INSTAWHIP_TETHERBLOCK (TICRATE*4)
#define PUNISHWINDOW (7*TICRATE/10)
#define MAXCOMBOTHRUST (mapobjectscale*20)
#define MAXCOMBOFLOAT (mapobjectscale*10)
#define MINCOMBOTHRUST (mapobjectscale*2)
#define MINCOMBOFLOAT (mapobjectscale*1)
#define MAXCOMBOTIME (TICRATE*4)
#define FLAMESHIELD_MAX (120)
#define RR_PROJECTILE_FUSE (8*TICRATE)
@ -257,6 +263,8 @@ boolean K_IsPlayingDisplayPlayer(player_t *player);
boolean K_PlayerCanPunt(player_t *player);
void K_MakeObjectReappear(mobj_t *mo);
void K_BumperInflate(player_t *player);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -257,8 +257,14 @@ static int player_get(lua_State *L)
lua_pushboolean(L, plr->flipDI);
else if (fastcmp(field,"markedfordeath"))
lua_pushboolean(L, plr->markedfordeath);
else if (fastcmp(field,"incontrol"))
lua_pushboolean(L, plr->incontrol);
else if (fastcmp(field,"progressivethrust"))
lua_pushboolean(L, plr->progressivethrust);
else if (fastcmp(field,"dotrickfx"))
lua_pushboolean(L, plr->dotrickfx);
else if (fastcmp(field,"bumperinflate"))
lua_pushboolean(L, plr->bumperinflate);
else if (fastcmp(field,"ringboxdelay"))
lua_pushinteger(L, plr->ringboxdelay);
else if (fastcmp(field,"ringboxaward"))
@ -783,10 +789,16 @@ static int player_set(lua_State *L)
plr->justDI = luaL_checkinteger(L, 3);
else if (fastcmp(field,"flipDI"))
plr->flipDI = luaL_checkboolean(L, 3);
else if (fastcmp(field,"incontrol"))
plr->incontrol = luaL_checkinteger(L, 3);
else if (fastcmp(field,"progressivethrust"))
plr->progressivethrust = luaL_checkboolean(L, 3);
else if (fastcmp(field,"markedfordeath"))
plr->markedfordeath = luaL_checkboolean(L, 3);
else if (fastcmp(field,"dotrickfx"))
plr->dotrickfx = luaL_checkboolean(L, 3);
else if (fastcmp(field,"bumperinflate"))
plr->bumperinflate = luaL_checkboolean(L, 3);
else if (fastcmp(field,"ringboxdelay"))
plr->ringboxdelay = luaL_checkinteger(L, 3);
else if (fastcmp(field,"ringboxaward"))

View file

@ -3161,6 +3161,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
player->preventfailsafe = TICRATE*3;
player->pflags &= ~PF_GAINAX;
Obj_EndBungee(player);
K_BumperInflate(target->player);
if (player->spectator == false && !(player->charflags & SF_IRONMAN))
{
@ -3185,6 +3186,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
//P_KillPlayer(player, inflictor, source, damagetype);
}
// Death save! On your last hit, no matter what, demote to weakest damage type for one last escape chance.
if (player->mo->health == 2 && damage && gametyperules & GTR_BUMPERS)
{
S_StartSound(target, sfx_gshc7);
player->flashing = TICRATE;
type = DMG_STUMBLE;
}
switch (type)
{
case DMG_STING:

View file

@ -4064,6 +4064,15 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
P_PlayerHitBounceLine(bestslideline, &result->normal);
mo->eflags |= MFE_JUSTBOUNCEDWALL;
// Combo avoidance!
if (mo->player && P_PlayerInPain(mo->player) && gametyperules & GTR_BUMPERS && mo->health == 1)
{
K_StumblePlayer(mo->player);
K_BumperInflate(mo->player);
mo->player->tumbleBounces = TUMBLEBOUNCES;
mo->hitlag = max(mo->hitlag, 6);
}
mo->momx = tmxmove;
mo->momy = tmymove;
mo->player->cmomx = tmxmove;

View file

@ -6235,6 +6235,18 @@ static void P_MobjSceneryThink(mobj_t *mobj)
// Shrink your items if the player shrunk too.
P_SetScale(mobj, mobj->target->scale);
if (mobj->target->player->bumperinflate && bumpers > mobj->threshold)
{
mobj->frame |= FF_INVERT;
// This line sucks. Scale to player, plus up to 1.5x their size based on how long the combo you're in is.
P_SetScale(mobj, mobj->target->scale + (mobj->target->player->progressivethrust * 3 * mobj->target->scale / 2 / MAXCOMBOTIME));
}
else
{
mobj->frame &= ~FF_INVERT;
}
P_UnsetThingPosition(mobj);
{
const angle_t fa = ang >> ANGLETOFINESHIFT;

View file

@ -592,9 +592,11 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEANGLE(save->p, players[i].besthanddirection);
WRITEINT16(save->p, players[i].incontrol);
WRITEUINT16(save->p, players[i].progressivethrust);
WRITEUINT8(save->p, players[i].markedfordeath);
WRITEUINT8(save->p, players[i].dotrickfx);
WRITEUINT8(save->p, players[i].bumperinflate);
WRITEUINT8(save->p, players[i].ringboxdelay);
WRITEUINT8(save->p, players[i].ringboxaward);
@ -1169,9 +1171,11 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].besthanddirection = READANGLE(save->p);
players[i].incontrol = READINT16(save->p);
players[i].progressivethrust = READUINT16(save->p);
players[i].markedfordeath = READUINT8(save->p);
players[i].dotrickfx = READUINT8(save->p);
players[i].bumperinflate = READUINT8(save->p);
players[i].ringboxdelay = READUINT8(save->p);
players[i].ringboxaward = READUINT8(save->p);

View file

@ -1448,7 +1448,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"gshc4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gshc5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gshc6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gshc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gshc7", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, //x8away
{"gshc8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gshc9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gshca", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},