mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-18 05:52:48 +00:00
Merge branch 'close-to-leader-items' into 'master'
Fewer speed items when crowding 1st See merge request kart-krew-dev/ring-racers-internal!2888
This commit is contained in:
commit
7109cd8c13
4 changed files with 48 additions and 20 deletions
|
|
@ -755,7 +755,7 @@ extern int
|
||||||
|
|
||||||
// Exp
|
// Exp
|
||||||
#define EXP_STABLERATE 3*FRACUNIT/10 // how low is your placement before losing XP? 4*FRACUNIT/10 = top 40% of race will gain
|
#define EXP_STABLERATE 3*FRACUNIT/10 // how low is your placement before losing XP? 4*FRACUNIT/10 = top 40% of race will gain
|
||||||
#define EXP_POWER 2*FRACUNIT/100 // adjust to change overall xp volatility
|
#define EXP_POWER 3*FRACUNIT/100 // adjust to change overall xp volatility
|
||||||
#define EXP_MIN 25 // The min value target
|
#define EXP_MIN 25 // The min value target
|
||||||
#define EXP_TARGET 120 // Used for grading ...
|
#define EXP_TARGET 120 // Used for grading ...
|
||||||
#define EXP_MAX 120 // The max value displayed by the hud and in the tally screen and GP results screen
|
#define EXP_MAX 120 // The max value displayed by the hud and in the tally screen and GP results screen
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,8 @@ fixed_t K_EffectiveGradingFactor(const player_t *player)
|
||||||
if (gf > GRADINGFACTORSOFTCAP && !K_PlayerUsesBotMovement(player))
|
if (gf > GRADINGFACTORSOFTCAP && !K_PlayerUsesBotMovement(player))
|
||||||
gf = GRADINGFACTORSOFTCAP + FixedDiv(gf - GRADINGFACTORSOFTCAP, GRADINGFACTORCAPSTRENGTH);
|
gf = GRADINGFACTORSOFTCAP + FixedDiv(gf - GRADINGFACTORSOFTCAP, GRADINGFACTORCAPSTRENGTH);
|
||||||
|
|
||||||
|
gf = (gf + FRACUNIT)/2;
|
||||||
|
|
||||||
return max(min, gf);
|
return max(min, gf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -15508,7 +15510,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
}
|
}
|
||||||
|
|
||||||
player->growshrinktimer = max(0, player->growshrinktimer);
|
player->growshrinktimer = max(0, player->growshrinktimer);
|
||||||
player->growshrinktimer += ((gametyperules & GTR_CLOSERPLAYERS) ? 8 : 12) * TICRATE;
|
player->growshrinktimer = max(player->growshrinktimer + 5*TICRATE, ((gametyperules & GTR_CLOSERPLAYERS) ? 8 : 12) * TICRATE);
|
||||||
|
|
||||||
S_StartSound(player->mo, sfx_kc5a);
|
S_StartSound(player->mo, sfx_kc5a);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ player_t *K_DuelOpponent(player_t *player);
|
||||||
fixed_t K_EffectiveGradingFactor(const player_t *player);
|
fixed_t K_EffectiveGradingFactor(const player_t *player);
|
||||||
#define MINGRADINGFACTOR (FRACUNIT/2)
|
#define MINGRADINGFACTOR (FRACUNIT/2)
|
||||||
#define MINFRANTICFACTOR (8*FRACUNIT/10)
|
#define MINFRANTICFACTOR (8*FRACUNIT/10)
|
||||||
#define GRADINGFACTORSOFTCAP (FRACUNIT)
|
#define GRADINGFACTORSOFTCAP (2*FRACUNIT)
|
||||||
#define GRADINGFACTORCAPSTRENGTH (3*FRACUNIT)
|
#define GRADINGFACTORCAPSTRENGTH (3*FRACUNIT)
|
||||||
|
|
||||||
void K_TimerReset(void);
|
void K_TimerReset(void);
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
static UINT32 K_DynamicItemOddsRace[NUMKARTRESULTS-1][2] =
|
static UINT32 K_DynamicItemOddsRace[NUMKARTRESULTS-1][2] =
|
||||||
{
|
{
|
||||||
// distance, duplication tolerance
|
// distance, duplication tolerance
|
||||||
{20, 10}, // sneaker
|
{25, 10}, // sneaker
|
||||||
{63, 12}, // rocketsneaker
|
{63, 12}, // rocketsneaker
|
||||||
{60, 19}, // invincibility
|
{60, 19}, // invincibility
|
||||||
{8, 4}, // banana
|
{8, 4}, // banana
|
||||||
|
|
@ -491,12 +491,7 @@ UINT32 K_ScaleItemDistance(INT32 distance, UINT8 numPlayers)
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
static UINT32 K_GetUnscaledFirstDistance(const player_t *player)
|
||||||
static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers)
|
|
||||||
|
|
||||||
See header file for description.
|
|
||||||
--------------------------------------------------*/
|
|
||||||
UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers)
|
|
||||||
{
|
{
|
||||||
UINT32 pdis = 0;
|
UINT32 pdis = 0;
|
||||||
|
|
||||||
|
|
@ -546,6 +541,19 @@ UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers)
|
||||||
}
|
}
|
||||||
|
|
||||||
pdis = K_UndoMapScaling(pdis);
|
pdis = K_UndoMapScaling(pdis);
|
||||||
|
|
||||||
|
return pdis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers)
|
||||||
|
{
|
||||||
|
UINT32 pdis = K_GetUnscaledFirstDistance(player);
|
||||||
pdis = K_ScaleItemDistance(pdis, numPlayers);
|
pdis = K_ScaleItemDistance(pdis, numPlayers);
|
||||||
|
|
||||||
if (player->bot && (player->botvars.rival || cv_levelskull.value))
|
if (player->bot && (player->botvars.rival || cv_levelskull.value))
|
||||||
|
|
@ -1047,7 +1055,7 @@ ATTRUNUSED static boolean K_IsItemUselessAlone(kartitems_t item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTRUNUSED static boolean K_IsItemSpeed(kartitems_t item)
|
static boolean K_IsItemSpeed(kartitems_t item)
|
||||||
{
|
{
|
||||||
switch (item)
|
switch (item)
|
||||||
{
|
{
|
||||||
|
|
@ -1422,12 +1430,6 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
// 5: Skim any items that are much weaker than the reel's average out of the roulette
|
// 5: Skim any items that are much weaker than the reel's average out of the roulette
|
||||||
// 6: Cram it all in
|
// 6: Cram it all in
|
||||||
|
|
||||||
fixed_t largegamescaler = roulette->playing * 14 + 100; // Spread out item odds in large games for a less insane experience.
|
|
||||||
if (franticitems)
|
|
||||||
largegamescaler = 100; // Except in Frantic, where you know what you're getting
|
|
||||||
|
|
||||||
UINT32 targetpower = 100 * roulette->dist / largegamescaler; // fill roulette with items around this value!
|
|
||||||
|
|
||||||
UINT32 powers[NUMKARTRESULTS]; // how strong is each item? think of this as a "target distance" for this item to spawn at
|
UINT32 powers[NUMKARTRESULTS]; // how strong is each item? think of this as a "target distance" for this item to spawn at
|
||||||
UINT32 deltas[NUMKARTRESULTS]; // how different is that strength from target?
|
UINT32 deltas[NUMKARTRESULTS]; // how different is that strength from target?
|
||||||
UINT32 candidates[NUMKARTRESULTS]; // how many of this item should we try to insert?
|
UINT32 candidates[NUMKARTRESULTS]; // how many of this item should we try to insert?
|
||||||
|
|
@ -1435,7 +1437,12 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
boolean permit[NUMKARTRESULTS]; // is this item allowed?
|
boolean permit[NUMKARTRESULTS]; // is this item allowed?
|
||||||
|
|
||||||
UINT32 lonelinessSuppressor = DISTVAR; // This close to 1st? Dampen loneliness (you have a target!)
|
UINT32 lonelinessSuppressor = DISTVAR; // This close to 1st? Dampen loneliness (you have a target!)
|
||||||
UINT32 maxEXPDistanceCut = 3*DISTVAR/2; // The maximum amount you can be displaced by EXP
|
UINT32 maxEXPDistanceCut = 3*DISTVAR; // The maximum amount you can be displaced by EXP
|
||||||
|
|
||||||
|
// If we're too close to 1st in absolute units, crush our top-end item odds down.
|
||||||
|
fixed_t crowdingFirst = 0;
|
||||||
|
if (player->position != 1)
|
||||||
|
crowdingFirst = FixedRescale(K_GetUnscaledFirstDistance(player), 0, 4*DISTVAR, Easing_InCubic, FRACUNIT, 0);
|
||||||
|
|
||||||
if ((gametyperules & GTR_CIRCUIT) && !K_Cooperative())
|
if ((gametyperules & GTR_CIRCUIT) && !K_Cooperative())
|
||||||
{
|
{
|
||||||
|
|
@ -1450,6 +1457,14 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fixed_t largegamescaler = roulette->playing * 5 + 100; // Spread out item odds in large games for a less insane experience.
|
||||||
|
if (franticitems)
|
||||||
|
largegamescaler = 100; // Except in Frantic, where you know what you're getting
|
||||||
|
|
||||||
|
UINT32 targetpower = 100 * roulette->dist / largegamescaler; // fill roulette with items around this value!
|
||||||
|
if (!(specialstageinfo.valid))
|
||||||
|
targetpower = Easing_Linear(crowdingFirst, targetpower, targetpower/2);
|
||||||
|
|
||||||
boolean rival = (player->bot && (player->botvars.rival || cv_levelskull.value));
|
boolean rival = (player->bot && (player->botvars.rival || cv_levelskull.value));
|
||||||
boolean filterweakitems = true; // strip unusually weak items from reel?
|
boolean filterweakitems = true; // strip unusually weak items from reel?
|
||||||
UINT8 reelsize = 15; // How many items to attempt to add in prepass?
|
UINT8 reelsize = 15; // How many items to attempt to add in prepass?
|
||||||
|
|
@ -1503,6 +1518,10 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
{
|
{
|
||||||
powers[i] = humanscaler * K_DynamicItemOddsRace[i-1][0];
|
powers[i] = humanscaler * K_DynamicItemOddsRace[i-1][0];
|
||||||
dupetolerance[i] = K_DynamicItemOddsRace[i-1][1];
|
dupetolerance[i] = K_DynamicItemOddsRace[i-1][1];
|
||||||
|
|
||||||
|
// Bias towards attack items when close to the leader, gotta work for the slingshot pass!
|
||||||
|
if (K_IsItemSpeed(i) && i != KITEM_SUPERRING)
|
||||||
|
powers[i] = Easing_Linear(crowdingFirst, powers[i], 2*powers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxpower = max(maxpower, powers[i]);
|
maxpower = max(maxpower, powers[i]);
|
||||||
|
|
@ -1642,6 +1661,13 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
UINT8 added = 0; // How many items added so far?
|
UINT8 added = 0; // How many items added so far?
|
||||||
UINT32 totalreelpower = 0; // How much total item power in the reel? Used for an average later.
|
UINT32 totalreelpower = 0; // How much total item power in the reel? Used for an average later.
|
||||||
|
|
||||||
|
UINT32 basepenalty = 4*DISTVAR; // How much to penalize repicked items, to ensure item variety.
|
||||||
|
// BUT, keep the item distribution tighter if we're close to the frontrunner...
|
||||||
|
UINT32 penalty = Easing_Linear(crowdingFirst, basepenalty, basepenalty/2);
|
||||||
|
if (player->position == 1) // ...unless we ARE the frontrunner.
|
||||||
|
penalty = basepenalty;
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < reelsize; i++)
|
for (i = 0; i < reelsize; i++)
|
||||||
{
|
{
|
||||||
UINT32 lowestdelta = INT32_MAX;
|
UINT32 lowestdelta = INT32_MAX;
|
||||||
|
|
@ -1668,7 +1694,7 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
// Impose a penalty to this item's delta, to bias against selecting it again.
|
// Impose a penalty to this item's delta, to bias against selecting it again.
|
||||||
// This is naively slashed by an item's "duplicate tolerance":
|
// This is naively slashed by an item's "duplicate tolerance":
|
||||||
// lower tolerance means that an item is less likely to be reselected (it's "rarer").
|
// lower tolerance means that an item is less likely to be reselected (it's "rarer").
|
||||||
UINT32 deltapenalty = 4*DISTVAR*(1+candidates[bestitem])/dupetolerance[bestitem];
|
UINT32 deltapenalty = penalty*(1+candidates[bestitem])/dupetolerance[bestitem];
|
||||||
|
|
||||||
// Power items get better odds in frantic, or if you're the rival.
|
// Power items get better odds in frantic, or if you're the rival.
|
||||||
// (For the rival, this is way more likely to matter at lower skills, where they're
|
// (For the rival, this is way more likely to matter at lower skills, where they're
|
||||||
|
|
@ -1754,7 +1780,7 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
INT32 FLAGS = V_SNAPTOTOP|V_SNAPTORIGHT;
|
INT32 FLAGS = V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||||
V_DrawRightAlignedThinString(BASE_X - 12, 5, FLAGS, va("TP %d", targetpower/humanscaler));
|
V_DrawRightAlignedThinString(BASE_X - 12, 5, FLAGS, va("TP %d", targetpower/humanscaler));
|
||||||
V_DrawRightAlignedThinString(BASE_X - 12, 5+12, FLAGS, va("FB %d / %d", toFront, toBack));
|
V_DrawRightAlignedThinString(BASE_X - 12, 5+12, FLAGS, va("FB %d / %d", toFront, toBack));
|
||||||
V_DrawRightAlignedThinString(BASE_X - 12, 5+24, FLAGS, va("L %d", loneliness));
|
V_DrawRightAlignedThinString(BASE_X - 12, 5+24, FLAGS, va("L %d / CF %d", loneliness, crowdingFirst));
|
||||||
V_DrawRightAlignedThinString(BASE_X - 12, 5+36, FLAGS, va("D %d / %d", roulette->preexpdist, roulette->dist));
|
V_DrawRightAlignedThinString(BASE_X - 12, 5+36, FLAGS, va("D %d / %d", roulette->preexpdist, roulette->dist));
|
||||||
for(UINT8 k = 0; k < candidates[i]; k++)
|
for(UINT8 k = 0; k < candidates[i]; k++)
|
||||||
V_DrawFixedPatch((BASE_X + 3*k)*FRACUNIT, (BASE_Y-7)*FRACUNIT, (FRACUNIT >> 1), FLAGS, K_GetSmallStaticCachedItemPatch(i), NULL);
|
V_DrawFixedPatch((BASE_X + 3*k)*FRACUNIT, (BASE_Y-7)*FRACUNIT, (FRACUNIT >> 1), FLAGS, K_GetSmallStaticCachedItemPatch(i), NULL);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue