Trick panels

This commit is contained in:
Sally Coolatta 2020-05-31 21:23:22 -04:00
parent a21b235034
commit ede66a6632
13 changed files with 164 additions and 105 deletions

View file

@ -575,6 +575,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart
rsp->frameangle = (angle_t)LONG(players[i].frameangle); // SRB2kart
rsp->trickpanel = (UINT8)players[i].trickpanel;
rsp->trickdelay = (tic_t)LONG(players[i].trickdelay);
// Score is resynched in the rspfirm resync packet
rsp->health = 0; // resynched with mo health
@ -705,6 +707,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart
players[i].frameangle = (angle_t)LONG(rsp->frameangle); // SRB2kart
players[i].trickpanel = (UINT8)rsp->trickpanel;
players[i].trickdelay = (tic_t)LONG(rsp->trickdelay);
// Score is resynched in the rspfirm resync packet
players[i].health = rsp->health;

View file

@ -215,6 +215,8 @@ typedef struct
INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart
angle_t frameangle; // SRB2kart
UINT8 trickpanel;
tic_t trickdelay;
// Score is resynched in the confirm resync packet
INT32 health;

View file

@ -289,7 +289,6 @@ typedef enum
k_sparkleanim, // Angle offset for ring sparkle animation
k_jmp, // In Mario Kart, letting go of the jump button stops the drift
k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
k_pogospring, // Pogo spring bounce effect
k_brakestop, // Wait until you've made a complete stop for a few tics before letting brake go in reverse.
k_waterskip, // Water skipping counter
k_dashpadcooldown, // Separate the vanilla SA-style dash pads from using pw_flashing
@ -477,6 +476,8 @@ typedef struct player_s
INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right
UINT32 distancetofinish;
waypoint_t *nextwaypoint;
UINT8 trickpanel; // Trick panel state
tic_t trickdelay;
// Bit flags.
// See pflags_t, above.

View file

@ -8341,7 +8341,6 @@ static const char *const KARTSTUFF_LIST[] = {
"SPARKLEANIM",
"JMP",
"OFFROAD",
"POGOSPRING",
"BRAKESTOP",
"WATERSKIP",
"DASHPADCOOLDOWN",

View file

@ -978,7 +978,7 @@ static void K_DebtStingPlayer(player_t *player, INT32 length)
player->kartstuff[k_driftboost] = 0;
player->kartstuff[k_drift] = 0;
player->kartstuff[k_driftcharge] = 0;
player->kartstuff[k_pogospring] = 0;
player->trickpanel = 0;
player->kartstuff[k_spinouttype] = 2;
player->kartstuff[k_spinouttimer] = length;
@ -2416,18 +2416,6 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove
oldspeed = p_speed;
newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION);
if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust
{
const fixed_t hscale = mapobjectscale /*+ (mapobjectscale - player->mo->scale)*/;
const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale;
if (newspeed > maxspeed && player->kartstuff[k_pogospring] == 2)
newspeed = maxspeed;
if (newspeed < minspeed)
newspeed = minspeed;
}
finalspeed = newspeed - oldspeed;
// forwardmove is:
@ -2526,7 +2514,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
player->kartstuff[k_drift] = 0;
player->kartstuff[k_driftcharge] = 0;
player->kartstuff[k_pogospring] = 0;
player->trickpanel = 0;
if (G_BattleGametype())
{
@ -2673,7 +2661,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor)
player->kartstuff[k_drift] = 0;
player->kartstuff[k_driftcharge] = 0;
player->kartstuff[k_pogospring] = 0;
player->trickpanel = 0;
if (G_BattleGametype())
{
@ -2800,7 +2788,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
player->kartstuff[k_drift] = 0;
player->kartstuff[k_driftcharge] = 0;
player->kartstuff[k_pogospring] = 0;
player->trickpanel = 0;
// This is the only part that SHOULDN'T combo :VVVVV
if (G_BattleGametype() && !(player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinouttype] != 2)))
@ -4335,10 +4323,10 @@ static void K_DoShrink(player_t *user)
}
}
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
{
const fixed_t vscale = mapobjectscale + (mo->scale - mapobjectscale);
fixed_t thrust = 0;
if (mo->player && mo->player->spectator)
return;
@ -4352,47 +4340,39 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
mo->eflags |= MFE_SPRUNG;
if (mo->eflags & MFE_VERTICALFLIP)
vertispeed *= -1;
if (vertispeed == 0)
{
fixed_t thrust;
if (mo->player)
{
thrust = 3*mo->player->speed/2;
if (thrust < 48<<FRACBITS)
thrust = 48<<FRACBITS;
if (thrust > 72<<FRACBITS)
thrust = 72<<FRACBITS;
if (mo->player->kartstuff[k_pogospring] != 2)
{
if (EITHERSNEAKER(mo->player))
thrust = FixedMul(thrust, (5*FRACUNIT)/4);
else if (mo->player->kartstuff[k_invincibilitytimer])
thrust = FixedMul(thrust, (9*FRACUNIT)/8);
}
}
else
{
thrust = FixedDiv(3*P_AproxDistance(mo->momx, mo->momy)/2, 5*FRACUNIT/2);
if (thrust < 16<<FRACBITS)
thrust = 16<<FRACBITS;
if (thrust > 32<<FRACBITS)
thrust = 32<<FRACBITS;
}
mo->momz = P_MobjFlip(mo)*FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, vscale));
thrust = P_AproxDistance(mo->momx, mo->momy) * P_MobjFlip(mo);
thrust = FixedMul(thrust, FINESINE(ANGLE_22h >> ANGLETOFINESHIFT));
}
else
mo->momz = FixedMul(vertispeed, vscale);
{
thrust = vertispeed * P_MobjFlip(mo);
}
if (mo->player)
{
if (EITHERSNEAKER(mo->player))
{
thrust = FixedMul(thrust, 5*FRACUNIT/4);
}
else if (mo->player->kartstuff[k_invincibilitytimer])
{
thrust = FixedMul(thrust, 9*FRACUNIT/8);
}
}
mo->momz = FixedMul(thrust, vscale);
if (mo->eflags & MFE_UNDERWATER)
mo->momz = (117 * mo->momz) / 200;
{
mo->momz = FixedDiv(mo->momz, FixedSqrt(3*FRACUNIT));
}
if (sound)
{
S_StartSound(mo, (sound == 1 ? sfx_kc2f : sfx_kpogos));
}
}
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
@ -5994,10 +5974,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_comebacktimer])
player->kartstuff[k_comebackmode] = 0;
if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_pogospring])
if (P_IsObjectOnGround(player->mo) && player->trickpanel != 0)
{
if (P_MobjFlip(player->mo)*player->mo->momz <= 0)
player->kartstuff[k_pogospring] = 0;
if (P_MobjFlip(player->mo) * player->mo->momz <= 0)
{
player->trickpanel = 0;
}
}
if (cmd->buttons & BT_DRIFT)
@ -6519,6 +6501,11 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
return turnvalue;
}
if (player->trickpanel != 0)
{
return 0;
}
if (K_PlayerUsesBotMovement(player))
{
turnvalue = 5*turnvalue/4; // Base increase to turning
@ -7512,12 +7499,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
break;
case KITEM_POGOSPRING:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
&& !player->kartstuff[k_pogospring])
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->trickpanel == 0)
{
K_PlayBoostTaunt(player->mo);
K_DoPogoSpring(player->mo, 32<<FRACBITS, 2);
player->kartstuff[k_pogospring] = 1;
player->trickpanel = 1;
player->trickdelay = TICRATE/2;
player->kartstuff[k_itemamount]--;
}
break;
@ -7656,6 +7643,54 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{
player->mo->flags2 &= ~MF2_SHADOW;
}
if (player->trickpanel == 1 && player->trickdelay <= 0)
{
const angle_t lr = ANGLE_45;
fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy);
if (cmd->driftturn > 0)
{
P_InstaThrust(player->mo, player->mo->angle + lr, speed*2);
player->trickpanel = 2;
}
else if (cmd->driftturn < 0)
{
P_InstaThrust(player->mo, player->mo->angle - lr, speed*2);
player->trickpanel = 3;
}
else if (player->kartstuff[k_throwdir] == 1)
{
if (player->mo->momz * P_MobjFlip(player->mo) > 0)
{
player->mo->momz = 0;
}
P_InstaThrust(player->mo, player->mo->angle, speed*3);
player->trickpanel = 2;
}
else if (player->kartstuff[k_throwdir] == -1)
{
boolean relative = true;
player->mo->momx /= 3;
player->mo->momy /= 3;
if (player->mo->momz * P_MobjFlip(player->mo) <= 0)
{
relative = false;
}
P_SetObjectMomZ(player->mo, 24*FRACUNIT, relative);
player->trickpanel = 3;
}
}
if (player->trickdelay > 0)
{
player->trickdelay--;
}
}
if (onground)

View file

@ -216,6 +216,10 @@ static int player_get(lua_State *L)
LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF);
else if (fastcmp(field,"frameangle"))
lua_pushangle(L, plr->frameangle);
else if (fastcmp(field,"trickpanel"))
lua_pushinteger(L, plr->trickpanel);
else if (fastcmp(field,"trickdelay"))
lua_pushinteger(L, plr->trickdelay);
else if (fastcmp(field,"pflags"))
lua_pushinteger(L, plr->pflags);
else if (fastcmp(field,"panim"))
@ -483,6 +487,10 @@ static int player_set(lua_State *L)
return NOSET;
else if (fastcmp(field,"frameangle"))
plr->frameangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"trickpanel"))
plr->trickpanel = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickdelay"))
plr->trickdelay = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"kartspeed"))
plr->kartspeed = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"kartweight"))

View file

@ -8650,7 +8650,7 @@ void A_SPBChase(mobj_t *actor)
actor->lastlook = actor->tracer->player-players; // Save the player num for death scumming...
actor->tracer->player->kartstuff[k_ringlock] = 1; // set ring lock
if (!P_IsObjectOnGround(actor->tracer) /*&& !actor->tracer->player->kartstuff[k_pogospring]*/)
if (!P_IsObjectOnGround(actor->tracer))
{
// In the air you have no control; basically don't hit unless you make a near complete stop
defspeed = (7 * actor->tracer->player->speed) / 8;

View file

@ -2324,7 +2324,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
else*/ if (G_BattleGametype())
K_CheckBumpers();
target->player->kartstuff[k_pogospring] = 0;
target->player->trickpanel = 0;
}
if (source && target && target->player && source->player)

View file

@ -469,9 +469,14 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
{
if (object->eflags & MFE_SPRUNG)
break;
if (object->player)
object->player->kartstuff[k_pogospring] = 1;
K_DoPogoSpring(object, 0, 0);
{
object->player->trickpanel = 1;
object->player->trickdelay = TICRATE/2;
}
K_DoPogoSpring(object, 32<<FRACBITS, 0);
return;
}
else
@ -1462,7 +1467,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
mo1 = thing;
mo2 = tmthing;
if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring])
if (G_BattleGametype() && tmthing->player->trickpanel)
{
K_StealBumper(tmthing->player, thing->player, false);
K_SpinPlayer(thing->player, tmthing, 0, tmthing, false);
@ -1472,7 +1477,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
zbounce = true;
if (G_BattleGametype() && thing->player->kartstuff[k_pogospring])
if (G_BattleGametype() && thing->player->trickpanel)
{
K_StealBumper(thing->player, tmthing->player, false);
K_SpinPlayer(tmthing->player, thing, 0, thing, false);
@ -3558,7 +3563,7 @@ void P_BouncePlayerMove(mobj_t *mo)
mmomx = mo->player->rmomx;
mmomy = mo->player->rmomy;
mo->player->kartstuff[k_pogospring] = 0;
mo->player->trickpanel = 0;
// trace along the three leading corners
if (mo->momx > 0)

View file

@ -1279,15 +1279,15 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
P_PlayerFlip(mo);
}
if (mo->player->kartstuff[k_pogospring])
{
gravityadd = (5*gravityadd)/2;
}
if (mo->player->kartstuff[k_waterskip])
{
gravityadd = (4*gravityadd)/3;
}
if (mo->player->trickpanel == 2 || mo->player->trickpanel == 3)
{
gravityadd = (5*gravityadd)/2;
}
}
else
{
@ -8054,7 +8054,7 @@ void P_MobjThinker(mobj_t *mobj)
P_Thrust(mobj, mobj->angle, thrustamount);
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
K_DoPogoSpring(mobj, 0, 1);
K_DoPogoSpring(mobj, 32<<FRACBITS, 1);
if (mobj->threshold > 0)
mobj->threshold--;
@ -8084,7 +8084,7 @@ void P_MobjThinker(mobj_t *mobj)
K_DriftDustHandling(mobj);
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
K_DoPogoSpring(mobj, 0, 1);
K_DoPogoSpring(mobj, 32<<FRACBITS, 1);
break;
}
@ -8137,7 +8137,7 @@ void P_MobjThinker(mobj_t *mobj)
P_Thrust(mobj, mobj->angle, thrustamount);
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
K_DoPogoSpring(mobj, 0, 1);
K_DoPogoSpring(mobj, 32<<FRACBITS, 1);
if (mobj->threshold > 0)
mobj->threshold--;

View file

@ -269,6 +269,9 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].distancetofinish);
WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
WRITEUINT8(save_p, players[i].trickpanel);
WRITEUINT32(save_p, players[i].trickdelay);
WRITEUINT8(save_p, players[i].botvars.difficulty);
WRITEUINT32(save_p, players[i].botvars.itemdelay);
WRITEUINT32(save_p, players[i].botvars.itemconfirm);
@ -445,6 +448,9 @@ static void P_NetUnArchivePlayers(void)
players[i].distancetofinish = READUINT32(save_p);
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p);
players[i].trickpanel = READUINT8(save_p);
players[i].trickdelay = READUINT32(save_p);
players[i].botvars.difficulty = READUINT8(save_p);
players[i].botvars.itemdelay = READUINT32(save_p);
players[i].botvars.itemconfirm = READUINT32(save_p);

View file

@ -4004,49 +4004,46 @@ DoneSection2:
switch (special)
{
case 1: // SRB2kart: Spring Panel
case 3:
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
fixed_t speed = FixedHypot(player->mo->momx, player->mo->momy);
fixed_t upwards = 32*FRACUNIT;
angle_t pushangle = (speed ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle);
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
if (player->mo->eflags & MFE_SPRUNG)
{
break;
}
if (player->speed < minspeed) // Push forward to prevent getting stuck
P_InstaThrust(player->mo, pushangle, minspeed);
if (special == 3)
{
upwards /= 2;
}
player->kartstuff[k_pogospring] = 1;
K_DoPogoSpring(player->mo, 0, 1);
player->trickpanel = 1;
player->trickdelay = TICRATE/2;
K_DoPogoSpring(player->mo, upwards, 1);
// Reduce speed
speed /= 2;
if (speed < minspeed)
{
speed = minspeed;
}
player->mo->angle = pushangle;
P_InstaThrust(player->mo, pushangle, speed);
}
break;
case 2: // Wind/Current
break;
case 3: // SRB2kart: Spring Panel (capped speed)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
if (player->mo->eflags & MFE_SPRUNG)
break;
if (player->speed > maxspeed) // Prevent overshooting jumps
P_InstaThrust(player->mo, pushangle, maxspeed);
else if (player->speed < minspeed) // Push forward to prevent getting stuck
P_InstaThrust(player->mo, pushangle, minspeed);
player->kartstuff[k_pogospring] = 2;
K_DoPogoSpring(player->mo, 0, 1);
}
break;
case 4: // Conveyor Belt
break;
@ -4089,7 +4086,7 @@ DoneSection2:
P_InstaThrust(player->mo, lineangle, linespeed);
player->kartstuff[k_dashpadcooldown] = TICRATE/3;
player->kartstuff[k_pogospring] = 0;
player->trickpanel = 0;
S_StartSound(player->mo, sfx_spdpad);
{

View file

@ -4019,8 +4019,7 @@ static void P_3dMovement(player_t *player)
cmd->forwardmove = cmd->sidemove = 0;
}
if (!(player->pflags & PF_FORCESTRAFE) && !player->kartstuff[k_pogospring])
cmd->sidemove = 0;
cmd->sidemove = 0; // TODO: Remove sidemove entirely
if (player->kartstuff[k_drift] != 0)
movepushangle = player->mo->angle-(ANGLE_45/5)*player->kartstuff[k_drift];
@ -4088,8 +4087,7 @@ static void P_3dMovement(player_t *player)
cmd->forwardmove = 0;
// Do not let the player control movement if not onground.
// SRB2Kart: pogo spring and speed bumps are supposed to control like you're on the ground
onground = (P_IsObjectOnGround(player->mo) || (player->kartstuff[k_pogospring]));
onground = P_IsObjectOnGround(player->mo);
player->aiming = cmd->aiming<<FRACBITS;
@ -5896,10 +5894,14 @@ static void P_MovePlayer(player_t *player)
{
K_KartMoveAnimation(player);
if (player->kartstuff[k_pogospring])
if (player->trickpanel == 2)
{
player->frameangle += ANGLE_22h;
}
else if (player->trickpanel == 3)
{
player->frameangle -= ANGLE_22h;
}
else
{
player->frameangle = player->mo->angle;