From ede66a663280150637c2adbbcdb29b9879ee2adb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 31 May 2020 21:23:22 -0400 Subject: [PATCH] Trick panels --- src/d_clisrv.c | 4 ++ src/d_clisrv.h | 2 + src/d_player.h | 3 +- src/dehacked.c | 1 - src/k_kart.c | 145 +++++++++++++++++++++++++++----------------- src/lua_playerlib.c | 8 +++ src/p_enemy.c | 2 +- src/p_inter.c | 2 +- src/p_map.c | 15 +++-- src/p_mobj.c | 16 ++--- src/p_saveg.c | 6 ++ src/p_spec.c | 53 ++++++++-------- src/p_user.c | 12 ++-- 13 files changed, 164 insertions(+), 105 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 37e39aadf..e2e44039e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 1ef85b4f9..ae2c59fbf 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -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; diff --git a/src/d_player.h b/src/d_player.h index 6ed9fd719..1eea9b6f1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -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. diff --git a/src/dehacked.c b/src/dehacked.c index ac7c213f7..260cb6f10 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8341,7 +8341,6 @@ static const char *const KARTSTUFF_LIST[] = { "SPARKLEANIM", "JMP", "OFFROAD", - "POGOSPRING", "BRAKESTOP", "WATERSKIP", "DASHPADCOOLDOWN", diff --git a/src/k_kart.c b/src/k_kart.c index e00013128..6a499e1dd 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -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< 72<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< 32<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<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) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 433803648..b81ee3941 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -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")) diff --git a/src/p_enemy.c b/src/p_enemy.c index b05d0bc68..70708c9bf 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -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; diff --git a/src/p_inter.c b/src/p_inter.c index 959e0453a..26ec310ad 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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) diff --git a/src/p_map.c b/src/p_map.c index d635c4a6d..b866aee01 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -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<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) diff --git a/src/p_mobj.c b/src/p_mobj.c index 221b38f8d..13be9759b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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<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<angle, thrustamount); if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); + K_DoPogoSpring(mobj, 32<threshold > 0) mobj->threshold--; diff --git a/src/p_saveg.c b/src/p_saveg.c index 5aa988075..f92ce0c71 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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); diff --git a/src/p_spec.c b/src/p_spec.c index 8678f31cc..114a82a00 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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); { diff --git a/src/p_user.c b/src/p_user.c index 28273ca82..47c12fa27 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -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<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;