mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'ringbox-rebalance' into 'master'
TA Ring Box rebalance See merge request kart-krew-dev/ring-racers-internal!2405
This commit is contained in:
commit
d608d98756
7 changed files with 87 additions and 30 deletions
|
|
@ -1062,6 +1062,7 @@ struct player_t
|
||||||
|
|
||||||
UINT8 ringboxdelay; // Delay until Ring Box auto-activates
|
UINT8 ringboxdelay; // Delay until Ring Box auto-activates
|
||||||
UINT8 ringboxaward; // Where did we stop?
|
UINT8 ringboxaward; // Where did we stop?
|
||||||
|
UINT32 lastringboost; // What was our accumulated boost when locking the award?
|
||||||
|
|
||||||
UINT8 amps;
|
UINT8 amps;
|
||||||
UINT8 amppickup;
|
UINT8 amppickup;
|
||||||
|
|
|
||||||
|
|
@ -923,13 +923,11 @@ void F_IntroTicker(void)
|
||||||
S_StartSound(NULL, sfx_supflk);
|
S_StartSound(NULL, sfx_supflk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skiptype == 5) // Quick Thunderdome
|
if (skiptype == 5) // Quick Race Menu
|
||||||
{
|
{
|
||||||
ResetSkipSequences();
|
ResetSkipSequences();
|
||||||
CV_StealthSetValue(&cv_kartbot, 13);
|
M_StartControlPanel();
|
||||||
CV_StealthSetValue(&cv_maxplayers, 8);
|
currentMenu = &PLAY_RaceGamemodesDef;
|
||||||
CV_StealthSetValue(&cv_thunderdome, 1);
|
|
||||||
D_MapChange(G_RandMap(TOL_RACE, UINT16_MAX-1, true, false, NULL), GT_RACE, (cv_kartencore.value == 1), true, 0, false, false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1023,19 +1021,19 @@ static void AdvanceSkipSequences(UINT8 input)
|
||||||
UINT8 s2cheat[] = {1, 1, 1};
|
UINT8 s2cheat[] = {1, 1, 1};
|
||||||
UINT8 s3cheat[] = {2, 2, 2};
|
UINT8 s3cheat[] = {2, 2, 2};
|
||||||
UINT8 s3kcheat[] = {3, 3, 3};
|
UINT8 s3kcheat[] = {3, 3, 3};
|
||||||
UINT8 thundercheat[] = {4, 4, 4};
|
UINT8 spincheat[] = {4, 4, 4};
|
||||||
#else
|
#else
|
||||||
UINT8 s2cheat[] = {1, 1, 1, 3, 3, 3, 1};
|
UINT8 s2cheat[] = {1, 1, 1, 3, 3, 3, 1};
|
||||||
UINT8 s3cheat[] = {1, 1, 3, 3, 1, 1, 1, 1};
|
UINT8 s3cheat[] = {1, 1, 3, 3, 1, 1, 1, 1};
|
||||||
UINT8 s3kcheat[] = {4, 4, 4, 2, 2, 2, 1, 1, 1};
|
UINT8 s3kcheat[] = {4, 4, 4, 2, 2, 2, 1, 1, 1};
|
||||||
UINT8 thundercheat[] = {2, 4, 2, 4, 3, 3, 1, 1};
|
UINT8 spincheat[] = {1, 2, 3, 4, 3, 2, 1};
|
||||||
#endif
|
#endif
|
||||||
UINT8 nicetry[] = {1, 1, 3, 3, 4, 2, 4, 2};
|
UINT8 nicetry[] = {1, 1, 3, 3, 4, 2, 4, 2};
|
||||||
|
|
||||||
#define NUMCHEATSPLUSONE 5
|
#define NUMCHEATSPLUSONE 5
|
||||||
|
|
||||||
UINT8 *cheats[NUMCHEATSPLUSONE] = {s2cheat, s3cheat, s3kcheat, nicetry, thundercheat};
|
UINT8 *cheats[NUMCHEATSPLUSONE] = {s2cheat, s3cheat, s3kcheat, nicetry, spincheat};
|
||||||
UINT8 cheatlengths[NUMCHEATSPLUSONE] = {sizeof(s2cheat), sizeof(s3cheat), sizeof(s3kcheat), sizeof(nicetry), sizeof(thundercheat)};
|
UINT8 cheatlengths[NUMCHEATSPLUSONE] = {sizeof(s2cheat), sizeof(s3cheat), sizeof(s3kcheat), sizeof(nicetry), sizeof(spincheat)};
|
||||||
|
|
||||||
for (UINT8 i = 0; i < NUMCHEATSPLUSONE; i++) // for each cheat...
|
for (UINT8 i = 0; i < NUMCHEATSPLUSONE; i++) // for each cheat...
|
||||||
{
|
{
|
||||||
|
|
|
||||||
89
src/k_kart.c
89
src/k_kart.c
|
|
@ -292,7 +292,7 @@ void K_TimerInit(void)
|
||||||
|
|
||||||
if (G_TimeAttackStart())
|
if (G_TimeAttackStart())
|
||||||
{
|
{
|
||||||
starttime = 15*TICRATE; // Longest permitted start. No half-laps in reverse.
|
starttime = 10*TICRATE; // Longest permitted start. No half-laps in reverse.
|
||||||
// (Changed on finish line cross later, don't worry.)
|
// (Changed on finish line cross later, don't worry.)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9399,13 +9399,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
// extreme ringboost duration. Less aggressive for accel types, so they
|
// extreme ringboost duration. Less aggressive for accel types, so they
|
||||||
// retain more speed for small payouts.
|
// retain more speed for small payouts.
|
||||||
|
|
||||||
|
// 2.4: Even if it IS paying out, if the duration gets extreme,
|
||||||
|
// start applying decay anyway!
|
||||||
|
|
||||||
UINT8 roller = TICRATE*2;
|
UINT8 roller = TICRATE*2;
|
||||||
roller += 4*(8-player->kartspeed);
|
roller += 4*(8-player->kartspeed);
|
||||||
|
|
||||||
|
// UINT16 oldringboost = player->ringboost;
|
||||||
|
|
||||||
if (player->superring == 0)
|
if (player->superring == 0)
|
||||||
player->ringboost -= max((player->ringboost / roller), 1);
|
player->ringboost -= max((player->ringboost / roller), 1);
|
||||||
else
|
else
|
||||||
player->ringboost--;
|
player->ringboost -= min(K_GetFullKartRingPower(player, false) - 1, max(player->ringboost / 2 / roller, 1));
|
||||||
|
|
||||||
|
// CONS_Printf("%d - %d\n", player->ringboost, oldringboost - player->ringboost);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->sneakertimer)
|
if (player->sneakertimer)
|
||||||
|
|
@ -9678,7 +9685,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
if (player->superring)
|
if (player->superring)
|
||||||
{
|
{
|
||||||
player->nextringaward++;
|
player->nextringaward++;
|
||||||
UINT8 ringrate = 3 - min(2, player->superring / 20); // Used to consume fat stacks of cash faster.
|
|
||||||
|
UINT8 fastringscaler = (K_GetKartGameSpeedScalar(gamespeed) > FRACUNIT) ? 20 : 20; // If G3 / TA gets out of control, can speed up all ring box payout
|
||||||
|
|
||||||
|
UINT32 existing = (player->lastringboost / K_GetFullKartRingPower(player, true)); // How many rings (effectively) do we have boost credit for right now?
|
||||||
|
|
||||||
|
UINT8 ringrate = 3 - min(2, (player->superring + existing) / fastringscaler); // Used to consume fat stacks of cash faster.
|
||||||
|
|
||||||
if (player->nextringaward >= ringrate)
|
if (player->nextringaward >= ringrate)
|
||||||
{
|
{
|
||||||
if (player->instaWhipCharge)
|
if (player->instaWhipCharge)
|
||||||
|
|
@ -11001,6 +11014,11 @@ INT32 K_GetKartRingPower(const player_t *player, boolean boosted)
|
||||||
return max(ringPower / FRACUNIT, 1);
|
return max(ringPower / FRACUNIT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32 K_GetFullKartRingPower(const player_t *player, boolean boosted)
|
||||||
|
{
|
||||||
|
return 3 + K_GetKartRingPower(player, boosted);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns false if this player being placed here causes them to collide with any other player
|
// Returns false if this player being placed here causes them to collide with any other player
|
||||||
// Used in g_game.c for match etc. respawning
|
// Used in g_game.c for match etc. respawning
|
||||||
// This does not check along the z because the z is not correctly set for the spawnee at this point
|
// This does not check along the z because the z is not correctly set for the spawnee at this point
|
||||||
|
|
@ -11680,6 +11698,12 @@ static void K_KartDrift(player_t *player, boolean onground)
|
||||||
K_SpawnDriftSparks(player);
|
K_SpawnDriftSparks(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Magic numbers ahoy! Meant to allow purple drifts to progress past color transition.
|
||||||
|
if ((player->driftcharge + driftadditive) > (dsthree+(32*3)) && K_TimeAttackRules() && leveltime < starttime)
|
||||||
|
{
|
||||||
|
driftadditive = max(0, (dsthree+(32*3)) - player->driftcharge);
|
||||||
|
}
|
||||||
|
|
||||||
if ((player->driftcharge < dsone && player->driftcharge+driftadditive >= dsone)
|
if ((player->driftcharge < dsone && player->driftcharge+driftadditive >= dsone)
|
||||||
|| (player->driftcharge < dstwo && player->driftcharge+driftadditive >= dstwo)
|
|| (player->driftcharge < dstwo && player->driftcharge+driftadditive >= dstwo)
|
||||||
|| (player->driftcharge < dsthree && player->driftcharge+driftadditive >= dsthree))
|
|| (player->driftcharge < dsthree && player->driftcharge+driftadditive >= dsthree))
|
||||||
|
|
@ -13144,6 +13168,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
player->ringboxdelay--;
|
player->ringboxdelay--;
|
||||||
if (player->ringboxdelay == 0)
|
if (player->ringboxdelay == 0)
|
||||||
{
|
{
|
||||||
|
player->lastringboost = player->ringboost;
|
||||||
UINT32 award = 5*player->ringboxaward + 10;
|
UINT32 award = 5*player->ringboxaward + 10;
|
||||||
if (!K_ThunderDome())
|
if (!K_ThunderDome())
|
||||||
award = 3 * award / 2;
|
award = 3 * award / 2;
|
||||||
|
|
@ -13155,28 +13180,41 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
}
|
}
|
||||||
else if (modeattacking)
|
else if (modeattacking)
|
||||||
{
|
{
|
||||||
// At high distance values, the power of Ring Box is mainly an extra source of speed, to be
|
// TA has:
|
||||||
// stacked with power items (or itself!) during the payout period.
|
// - no one to tether from
|
||||||
// Low-dist Ring Box follows some special rules, to somewhat normalize the reward between stat
|
// - no player damage
|
||||||
// blocks that respond to rings differently; here, variance in payout period counts for a lot!
|
// - no player bumps
|
||||||
|
// ...which nullifies a lot of designed advantages for accel types and high-weight racers.
|
||||||
|
//
|
||||||
|
// In addition, it's at Gear 3 Thunderdome speed, which can make it hard for heavies to
|
||||||
|
// take strong lines without brakedrifting.
|
||||||
|
//
|
||||||
|
// To try and help close this gap, we fudge Ring Box payouts to allow weaker characters
|
||||||
|
// better access to things that make them go fast, without changing core handling.
|
||||||
|
|
||||||
UINT8 accel = 10-player->kartspeed;
|
UINT8 accel = 10-player->kartspeed;
|
||||||
UINT8 weight = player->kartweight;
|
UINT8 weight = player->kartweight;
|
||||||
|
|
||||||
// Fixed point math can suck a dick.
|
// Relative stat power for bonus TA Ring Box awards.
|
||||||
|
// AP 1, WP 2 = weight is worth twice what accel is.
|
||||||
|
// 0 = stat not considered at all!
|
||||||
|
UINT8 accelPower = 0;
|
||||||
|
UINT8 weightPower = 4;
|
||||||
|
|
||||||
if (accel > weight)
|
UINT8 total = accelPower*accel + weightPower*weight;
|
||||||
{
|
UINT8 maxtotal = accelPower*9 + weightPower*9;
|
||||||
accel *= 10;
|
|
||||||
weight *= 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
accel *= 3;
|
|
||||||
weight *= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
award = (110 + accel + weight) * award / 120;
|
// Scale from base payout at 9/1 to max payout at 1/9.
|
||||||
|
award = Easing_InCubic(FRACUNIT*total/maxtotal, 13*award/10, 18*award/10);
|
||||||
|
|
||||||
|
// And, because we don't have to give a damn about sandbagging, up the stakes the longer we progress!
|
||||||
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
|
{
|
||||||
|
UINT8 maxgrade = 10;
|
||||||
|
UINT8 margin = min(player->gradingpointnum, maxgrade);
|
||||||
|
|
||||||
|
award = Easing_Linear(FRACUNIT * margin / maxgrade, award, 2*award);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -13187,6 +13225,19 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
award = award * (behindMulti + 10) / 10;
|
award = award * (behindMulti + 10) / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Felt kinda arbitrary, replaced with G3+ fast payout. Sealed away for later...?
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Stacked Ring Box is good. REALLY good. "Uncapped speed that feeds into itself" good.
|
||||||
|
// Keep highly unusual values under control, using the following core rule:
|
||||||
|
// If we already have more boost than we're about to be awarded, STOP!!!
|
||||||
|
UINT32 existing = (player->ringboost / K_GetFullKartRingPower(player, true)); // How many rings (effectively) do we have boost credit for right now?
|
||||||
|
UINT32 reduction = 8*existing/10; // Take an arbitrary percentage of those rings, and...
|
||||||
|
fixed_t reductionfactor = FixedDiv(FRACUNIT*reduction, FRACUNIT*award); // ...get a ratio to compare our potential award against it. 0 = no existing boost, 1+ = existing boost comparable to our award.
|
||||||
|
reductionfactor = min(reductionfactor, FRACUNIT); // Cap for easing function, and...
|
||||||
|
award = Easing_Linear(reductionfactor, award, award/4); // ...ease between unmodified and minimum award.
|
||||||
|
*/
|
||||||
|
|
||||||
K_AwardPlayerRings(player, award, true);
|
K_AwardPlayerRings(player, award, true);
|
||||||
player->ringboxaward = 0;
|
player->ringboxaward = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ void K_RepairOrbitChain(mobj_t *orbit);
|
||||||
void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
|
void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
|
||||||
mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range);
|
mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range);
|
||||||
INT32 K_GetKartRingPower(const player_t *player, boolean boosted);
|
INT32 K_GetKartRingPower(const player_t *player, boolean boosted);
|
||||||
|
INT32 K_GetFullKartRingPower(const player_t *player, boolean boosted);
|
||||||
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
||||||
INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering);
|
INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering);
|
||||||
INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue);
|
INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue);
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->ringboxdelay);
|
lua_pushinteger(L, plr->ringboxdelay);
|
||||||
else if (fastcmp(field,"ringboxaward"))
|
else if (fastcmp(field,"ringboxaward"))
|
||||||
lua_pushinteger(L, plr->ringboxaward);
|
lua_pushinteger(L, plr->ringboxaward);
|
||||||
|
else if (fastcmp(field,"lastringboost"))
|
||||||
|
lua_pushinteger(L, plr->lastringboost);
|
||||||
else if (fastcmp(field,"amps"))
|
else if (fastcmp(field,"amps"))
|
||||||
lua_pushinteger(L, plr->amps);
|
lua_pushinteger(L, plr->amps);
|
||||||
else if (fastcmp(field,"amppickup"))
|
else if (fastcmp(field,"amppickup"))
|
||||||
|
|
@ -898,6 +900,8 @@ static int player_set(lua_State *L)
|
||||||
plr->ringboxdelay = luaL_checkinteger(L, 3);
|
plr->ringboxdelay = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"ringboxaward"))
|
else if (fastcmp(field,"ringboxaward"))
|
||||||
plr->ringboxaward = luaL_checkinteger(L, 3);
|
plr->ringboxaward = luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"lastringboost"))
|
||||||
|
plr->lastringboost = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"amps"))
|
else if (fastcmp(field,"amps"))
|
||||||
plr->amps = luaL_checkinteger(L, 3);
|
plr->amps = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"amppickup"))
|
else if (fastcmp(field,"amppickup"))
|
||||||
|
|
|
||||||
|
|
@ -3519,7 +3519,7 @@ void A_AttractChase(mobj_t *actor)
|
||||||
angle_t offset = FixedAngle(18<<FRACBITS);
|
angle_t offset = FixedAngle(18<<FRACBITS);
|
||||||
|
|
||||||
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
|
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
|
||||||
actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3;
|
actor->target->player->ringboost += K_GetFullKartRingPower(actor->target->player, true);
|
||||||
|
|
||||||
S_ReducedVFXSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume, NULL);
|
S_ReducedVFXSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume, NULL);
|
||||||
|
|
||||||
|
|
@ -3575,7 +3575,7 @@ void A_AttractChase(mobj_t *actor)
|
||||||
if (actor->extravalue1 >= 16)
|
if (actor->extravalue1 >= 16)
|
||||||
{
|
{
|
||||||
if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed
|
if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed
|
||||||
actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3;
|
actor->target->player->ringboost += K_GetFullKartRingPower(actor->target->player, true);
|
||||||
|
|
||||||
if (actor->cvmem) // caching
|
if (actor->cvmem) // caching
|
||||||
S_StartSound(actor->target, sfx_s1c5);
|
S_StartSound(actor->target, sfx_s1c5);
|
||||||
|
|
|
||||||
|
|
@ -658,6 +658,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
|
|
||||||
WRITEUINT8(save->p, players[i].ringboxdelay);
|
WRITEUINT8(save->p, players[i].ringboxdelay);
|
||||||
WRITEUINT8(save->p, players[i].ringboxaward);
|
WRITEUINT8(save->p, players[i].ringboxaward);
|
||||||
|
WRITEUINT32(save->p, players[i].lastringboost);
|
||||||
|
|
||||||
WRITEUINT8(save->p, players[i].amps);
|
WRITEUINT8(save->p, players[i].amps);
|
||||||
WRITEUINT8(save->p, players[i].amppickup);
|
WRITEUINT8(save->p, players[i].amppickup);
|
||||||
|
|
@ -1294,6 +1295,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
|
|
||||||
players[i].ringboxdelay = READUINT8(save->p);
|
players[i].ringboxdelay = READUINT8(save->p);
|
||||||
players[i].ringboxaward = READUINT8(save->p);
|
players[i].ringboxaward = READUINT8(save->p);
|
||||||
|
players[i].lastringboost = READUINT32(save->p);
|
||||||
|
|
||||||
players[i].amps =READUINT8(save->p);
|
players[i].amps =READUINT8(save->p);
|
||||||
players[i].amppickup =READUINT8(save->p);
|
players[i].amppickup =READUINT8(save->p);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue