From e6db4e4d9b590f78fba9d6cd68cb0c05dc3cdfb9 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Fri, 23 Aug 2024 21:02:43 -0700 Subject: [PATCH] Backshots resurrection --- src/k_collide.cpp | 6 +++--- src/k_kart.c | 44 ++++++++++++++++++++++++++++++++++++++++++ src/k_kart.h | 1 + src/objects/hyudoro.c | 2 +- src/objects/orbinaut.c | 3 ++- src/p_inter.c | 7 ++++++- 6 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/k_collide.cpp b/src/k_collide.cpp index be57d0542..c5cef9e7f 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -695,9 +695,9 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) S_StartSound(t2, sfx_kdtrg1); } - if (t1->tracer && t1->tracer->player) + if (t1->tracer && t1->tracer->player && t1->player && t1->player != t1->tracer->player) { - K_SpawnAmps(t1->tracer->player, 20, t1); + K_SpawnAmps(t1->tracer->player, K_PvPAmpReward(20, t1->tracer->player, t1->player), t1); } if (draggeddroptarget && !P_MobjWasRemoved(draggeddroptarget) && draggeddroptarget->player) @@ -1194,7 +1194,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) auto doStumble = [](mobj_t *t1, mobj_t *t2) { K_StumblePlayer(t2->player); - K_SpawnAmps(t1->player, 20, t2); + K_SpawnAmps(t1->player, K_PvPAmpReward(20, t1->player, t2->player), t2); }; if (forEither(shouldStumble, doStumble)) diff --git a/src/k_kart.c b/src/k_kart.c index 0f5ca15b6..5b81d705b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -967,6 +967,12 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2) || (mobj2->player && mobj2->player->respawn.state != RESPAWNST_NONE)) return false; + if ((P_IsKartItem(mobj1->type) && mobj1->cvmem) + || (P_IsKartItem(mobj2->type) && mobj2->cvmem)) // Dropped orbital or backward shot, will be stumble + { + return false; + } + if (mobj1->type != MT_DROPTARGET && mobj1->type != MT_DROPTARGET_SHIELD) { // Don't bump if you're flashing INT32 flash; @@ -4002,6 +4008,33 @@ angle_t K_MomentumAngleReal(const mobj_t *mo) } } +// Scale amp rewards for crab bucketing. Play ambitiously! +boolean K_PvPAmpReward(UINT32 award, player_t *attacker, player_t *defender) +{ + UINT32 epsilon = FixedMul(2048/4, mapobjectscale); // How close is close enough that full reward seems fair, even if you're technically ahead? + UINT32 range = FixedMul(2048, mapobjectscale); + UINT32 atkdist = attacker->distancetofinish + epsilon; + UINT32 defdist = defender->distancetofinish; + + if (!attacker->bot) + CONS_Printf("%d - %d - ", atkdist, defdist); + + if (atkdist > defdist) + { + // Full reward for an active, even fight. + } + else + { + // Reduce the award for an attacker that's significantly ahead. + UINT32 delta = min(range, defdist - atkdist); + award -= (delta * award / range / 2); + } + + if (!attacker->bot) + CONS_Printf("%d\n", award); + return award; +} + void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact) { if (gametyperules & GTR_SPHERES) @@ -4009,8 +4042,10 @@ void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact) UINT16 scaledamps = min(amps, amps * (10 + (9-player->kartspeed) - (9-player->kartweight)) / 10); + /* if (player->position <= 1) scaledamps /= 2; + */ for (int i = 0; i < (scaledamps/2); i++) { @@ -6666,6 +6701,12 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, } } + // Missiles set as traps inflict a nocollide stumble + if (dir < 0 && (mapthing == MT_ORBINAUT || mapthing == MT_ORBINAUT_SHIELD || mapthing == MT_JAWZ || mapthing == MT_JAWZ_SHIELD || mapthing == MT_BALLHOG || mapthing == MT_GACHABOM)) + { + mo->cvmem = 1; + } + return mo; } @@ -7399,6 +7440,9 @@ void K_DropHnextList(player_t *player) } } + if (P_IsKartItem(dropwork->type)) + dropwork->cvmem = 1; + P_RemoveMobj(work); } diff --git a/src/k_kart.h b/src/k_kart.h index 0f6c14c5f..9036081bd 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -134,6 +134,7 @@ void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngleEx(const mobj_t *mo, const fixed_t threshold); angle_t K_MomentumAngleReal(const mobj_t *mo); #define K_MomentumAngle(mo) K_MomentumAngleEx(mo, 6 * mo->scale) +boolean K_PvPAmpReward(UINT32 award, player_t *attacker, player_t *defender); void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact); void K_AwardPlayerAmps(player_t *player, UINT8 amps); void K_AwardPlayerRings(player_t *player, UINT16 rings, boolean overload); diff --git a/src/objects/hyudoro.c b/src/objects/hyudoro.c index b8926ab43..588ab5e04 100644 --- a/src/objects/hyudoro.c +++ b/src/objects/hyudoro.c @@ -599,7 +599,7 @@ hyudoro_patrol_hit_player P_SetTarget(&hyudoro_target(hyu), master); - K_SpawnAmps(master->player, 20, toucher); + K_SpawnAmps(master->player, K_PvPAmpReward(20, master->player, player), toucher); if (center) P_RemoveMobj(center); diff --git a/src/objects/orbinaut.c b/src/objects/orbinaut.c index 5da81f252..90c028325 100644 --- a/src/objects/orbinaut.c +++ b/src/objects/orbinaut.c @@ -226,8 +226,9 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) { P_DamageMobj(t2, t1, t1->target, 1, DMG_WOMBO | (tumbleitem ? DMG_TUMBLE : DMG_WIPEOUT)); + K_KartBouncing(t2, t1); } - K_KartBouncing(t2, t1); + S_StartSound(t2, sfx_s3k7b); } diff --git a/src/p_inter.c b/src/p_inter.c index 52a0da4f5..1b6d52a99 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3181,7 +3181,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source != player->mo && source->player) { - K_SpawnAmps(source->player, 20, target); + K_SpawnAmps(source->player, K_PvPAmpReward(20, source->player, player), target); // Extend the invincibility if the hit was a direct hit. if (inflictor == source && source->player->invincibilitytimer && @@ -3300,6 +3300,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da type = DMG_STUMBLE; } + if (inflictor && !P_MobjWasRemoved(inflictor) && P_IsKartItem(inflictor->type) && inflictor->cvmem) + { + type = DMG_STUMBLE; + } + switch (type) { case DMG_STING: