mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 20:41:46 +00:00
Merge branch 'speed-assist' into 'master'
Speed Assist See merge request kart-krew-dev/ring-racers-internal!2753
This commit is contained in:
commit
4734249c2e
7 changed files with 206 additions and 29 deletions
|
|
@ -874,6 +874,8 @@ struct player_t
|
||||||
UINT16 invincibilitytimer; // Invincibility timer
|
UINT16 invincibilitytimer; // Invincibility timer
|
||||||
UINT16 invincibilityextensions; // Used to control invinc time gains when it's already been extended.
|
UINT16 invincibilityextensions; // Used to control invinc time gains when it's already been extended.
|
||||||
|
|
||||||
|
fixed_t loneliness; // How long has a player been too far to interact? Do they need speed assist?
|
||||||
|
|
||||||
UINT8 eggmanexplode; // Fake item recieved, explode in a few seconds
|
UINT8 eggmanexplode; // Fake item recieved, explode in a few seconds
|
||||||
SINT8 eggmanblame; // (-1 to 15) - Fake item recieved, who set this fake
|
SINT8 eggmanblame; // (-1 to 15) - Fake item recieved, who set this fake
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4730,6 +4730,11 @@ static void K_drawKartSpeedometer(boolean gametypeinfoshown)
|
||||||
V_DrawScaledPatch(LAPS_X+19, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[2]]);
|
V_DrawScaledPatch(LAPS_X+19, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[2]]);
|
||||||
V_DrawScaledPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]);
|
V_DrawScaledPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// debug for Speed Assist
|
||||||
|
V_DrawThinString(LAPS_X+7, fy-10, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d\%", stplyr->loneliness*100/FRACUNIT));
|
||||||
|
*/
|
||||||
|
|
||||||
K_drawKartAccessibilityIcons(gametypeinfoshown, 56);
|
K_drawKartAccessibilityIcons(gametypeinfoshown, 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
147
src/k_kart.c
147
src/k_kart.c
|
|
@ -3950,6 +3950,29 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
|
||||||
return finalspeed;
|
return finalspeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Speed Assist pt.2: If we need assistance, how much?
|
||||||
|
static fixed_t K_GetKartSpeedAssist(const player_t *player)
|
||||||
|
{
|
||||||
|
if (!M_NotFreePlay())
|
||||||
|
return 0;
|
||||||
|
if (modeattacking)
|
||||||
|
return 0;
|
||||||
|
if (gametyperules & GTR_BUMPERS)
|
||||||
|
return 0;
|
||||||
|
if (gametype == GT_TUTORIAL)
|
||||||
|
return 0;
|
||||||
|
if (specialstageinfo.valid)
|
||||||
|
return 0;
|
||||||
|
if (K_PlayerUsesBotMovement(player))
|
||||||
|
return 0;
|
||||||
|
if (player->loneliness < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fixed_t MAX_SPEED_ASSIST = FRACUNIT/4;
|
||||||
|
|
||||||
|
return FixedMul(player->loneliness, MAX_SPEED_ASSIST);
|
||||||
|
}
|
||||||
|
|
||||||
fixed_t K_GetKartSpeed(const player_t *player, boolean doboostpower, boolean dorubberband)
|
fixed_t K_GetKartSpeed(const player_t *player, boolean doboostpower, boolean dorubberband)
|
||||||
{
|
{
|
||||||
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
|
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
|
||||||
|
|
@ -4016,6 +4039,40 @@ fixed_t K_GetKartSpeed(const player_t *player, boolean doboostpower, boolean dor
|
||||||
finalspeed += FixedMul(player->outrun, physicsScale);
|
finalspeed += FixedMul(player->outrun, physicsScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Speed Assist pt.3: How much of our potential assist do we apply?
|
||||||
|
if (doboostpower && K_GetKartSpeedAssist(player))
|
||||||
|
{
|
||||||
|
fixed_t assist = K_GetKartSpeedAssist(player);
|
||||||
|
|
||||||
|
// Don't use all of our speed assist if we're already under boost effect.
|
||||||
|
fixed_t START_ASSIST_ROLLOFF = 3*FRACUNIT/2; // Don't roll off at below this speed
|
||||||
|
fixed_t END_ASSIST_ROLLOFF = 5*FRACUNIT/2; // Use minimum assist power at above this speed
|
||||||
|
fixed_t MIN_ASSIST_POWER = 0; // % assist to apply while going fast (FRACUNIT=full, 0=none)
|
||||||
|
|
||||||
|
fixed_t speedgap = END_ASSIST_ROLLOFF - START_ASSIST_ROLLOFF;
|
||||||
|
|
||||||
|
fixed_t bonusspeed = FixedDiv(player->speed, K_GetKartSpeed(player, false, false));
|
||||||
|
|
||||||
|
if (doboostpower)
|
||||||
|
{
|
||||||
|
if (bonusspeed < START_ASSIST_ROLLOFF)
|
||||||
|
{
|
||||||
|
// :)
|
||||||
|
}
|
||||||
|
else if (bonusspeed > END_ASSIST_ROLLOFF)
|
||||||
|
{
|
||||||
|
assist = FixedMul(assist, MIN_ASSIST_POWER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t normalizer = FixedDiv((bonusspeed - START_ASSIST_ROLLOFF), speedgap);
|
||||||
|
assist = Easing_Linear(normalizer, assist, FixedMul(assist, MIN_ASSIST_POWER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finalspeed = FixedMul(finalspeed, FRACUNIT + assist);
|
||||||
|
}
|
||||||
|
|
||||||
return finalspeed;
|
return finalspeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9963,6 +10020,96 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Speed Assist pt.1
|
||||||
|
if (!K_PlayerUsesBotMovement(player))
|
||||||
|
{
|
||||||
|
UINT32 toDefender = 0;
|
||||||
|
UINT32 toFirst = 0;
|
||||||
|
|
||||||
|
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i] == false || players[i].spectator == true || players[i].exiting)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].position == player->position - 1)
|
||||||
|
toDefender = K_UndoMapScaling(player->distancetofinish - players[i].distancetofinish);
|
||||||
|
|
||||||
|
if (players[i].position == 1)
|
||||||
|
toFirst = K_UndoMapScaling(player->distancetofinish - players[i].distancetofinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 average = 0;
|
||||||
|
UINT8 counted = 0;
|
||||||
|
UINT32 firstRaw = 0;
|
||||||
|
|
||||||
|
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i] == false || players[i].spectator == true || players[i].exiting)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].position != 1 && players[i].position >= ((D_NumPlayersInRace()*3)/4) - 1) // Not in 1st, but also back quarter of the average (-1 guy, for leeway)
|
||||||
|
{
|
||||||
|
counted++;
|
||||||
|
average += K_UndoMapScaling(players[i].distancetofinish);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
firstRaw = K_UndoMapScaling(players[i].distancetofinish);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
average /= max(counted, 1);
|
||||||
|
|
||||||
|
if (D_NumPlayersInRace() == 2)
|
||||||
|
{
|
||||||
|
average = firstRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 REALLY_FAR = average + 10000; // This far back, get max gain
|
||||||
|
UINT32 TOO_CLOSE = average + 7000; // Start gaining here, lose if closer
|
||||||
|
UINT32 WAY_TOO_CLOSE = average + 6000; // Lose at max rate here
|
||||||
|
|
||||||
|
fixed_t MAX_GAIN_PER_SEC = FRACUNIT/20; // % assist to gain per sec when REALLY_FAR
|
||||||
|
fixed_t MAX_LOSS_PER_SEC = FRACUNIT/5; // % assist to lose per sec when WAY_TOO_CLOSE
|
||||||
|
|
||||||
|
UINT32 gaingap = REALLY_FAR - TOO_CLOSE;
|
||||||
|
UINT32 lossgap = TOO_CLOSE - WAY_TOO_CLOSE;
|
||||||
|
|
||||||
|
UINT32 mydist = K_UndoMapScaling(player->distancetofinish);
|
||||||
|
|
||||||
|
if (mydist >= TOO_CLOSE)
|
||||||
|
{
|
||||||
|
fixed_t gain = MAX_GAIN_PER_SEC / TICRATE;
|
||||||
|
fixed_t gainrate = FRACUNIT * (mydist - TOO_CLOSE) / gaingap;
|
||||||
|
gainrate = clamp(gainrate, 0, FRACUNIT);
|
||||||
|
gainrate = Easing_InCubic(gainrate, 0, FRACUNIT);
|
||||||
|
|
||||||
|
gain = FixedMul(gain, gainrate);
|
||||||
|
|
||||||
|
player->loneliness += gain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t loss = MAX_LOSS_PER_SEC / TICRATE;
|
||||||
|
if (mydist < WAY_TOO_CLOSE)
|
||||||
|
mydist = WAY_TOO_CLOSE;
|
||||||
|
fixed_t lossrate = FRACUNIT * (mydist - WAY_TOO_CLOSE) / lossgap;
|
||||||
|
lossrate = FRACUNIT - clamp(lossrate, 0, FRACUNIT);
|
||||||
|
lossrate = Easing_InCubic(lossrate, 0, FRACUNIT);
|
||||||
|
|
||||||
|
loss = FixedMul(loss, lossrate);
|
||||||
|
|
||||||
|
player->loneliness -= loss;
|
||||||
|
}
|
||||||
|
|
||||||
|
player->loneliness = clamp(player->loneliness, 0, FRACUNIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->loneliness = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (player->spheres > 40)
|
if (player->spheres > 40)
|
||||||
player->spheres = 40;
|
player->spheres = 40;
|
||||||
// where's the < 0 check? see below the following block!
|
// where's the < 0 check? see below the following block!
|
||||||
|
|
|
||||||
|
|
@ -436,7 +436,7 @@ fixed_t K_ItemOddsScale(UINT8 playerCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
static UINT32 K_UndoMapScaling(UINT32 distance)
|
UINT32 K_UndoMapScaling(UINT32 distance)
|
||||||
|
|
||||||
Takes a raw map distance and adjusts it to
|
Takes a raw map distance and adjusts it to
|
||||||
be in x1 scale.
|
be in x1 scale.
|
||||||
|
|
@ -447,7 +447,7 @@ fixed_t K_ItemOddsScale(UINT8 playerCount)
|
||||||
Return:-
|
Return:-
|
||||||
Distance unscaled by mapobjectscale.
|
Distance unscaled by mapobjectscale.
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static UINT32 K_UndoMapScaling(UINT32 distance)
|
UINT32 K_UndoMapScaling(UINT32 distance)
|
||||||
{
|
{
|
||||||
if (mapobjectscale != FRACUNIT)
|
if (mapobjectscale != FRACUNIT)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,21 @@ fixed_t K_ItemOddsScale(UINT8 playerCount);
|
||||||
|
|
||||||
UINT32 K_ScaleItemDistance(INT32 distance, UINT8 numPlayers);
|
UINT32 K_ScaleItemDistance(INT32 distance, UINT8 numPlayers);
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
UINT32 K_UndoMapScaling(UINT32 distance)
|
||||||
|
|
||||||
|
Takes a raw map distance and adjusts it to
|
||||||
|
be in x1 scale.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
distance - Original distance.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
Distance unscaled by mapobjectscale.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
UINT32 K_UndoMapScaling(UINT32 distance);
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item)
|
void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->invincibilitytimer);
|
lua_pushinteger(L, plr->invincibilitytimer);
|
||||||
else if (fastcmp(field,"invincibilityextensions"))
|
else if (fastcmp(field,"invincibilityextensions"))
|
||||||
lua_pushinteger(L, plr->invincibilityextensions);
|
lua_pushinteger(L, plr->invincibilityextensions);
|
||||||
|
else if (fastcmp(field,"loneliness"))
|
||||||
|
lua_pushinteger(L, plr->loneliness);
|
||||||
else if (fastcmp(field,"eggmanexplode"))
|
else if (fastcmp(field,"eggmanexplode"))
|
||||||
lua_pushinteger(L, plr->eggmanexplode);
|
lua_pushinteger(L, plr->eggmanexplode);
|
||||||
else if (fastcmp(field,"eggmanblame"))
|
else if (fastcmp(field,"eggmanblame"))
|
||||||
|
|
@ -1178,6 +1180,8 @@ static int player_set(lua_State *L)
|
||||||
plr->invincibilitytimer = luaL_checkinteger(L, 3);
|
plr->invincibilitytimer = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"invincibilityextensions"))
|
else if (fastcmp(field,"invincibilityextensions"))
|
||||||
plr->invincibilityextensions = luaL_checkinteger(L, 3);
|
plr->invincibilityextensions = luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"loneliness"))
|
||||||
|
plr->loneliness = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"eggmanexplode"))
|
else if (fastcmp(field,"eggmanexplode"))
|
||||||
plr->eggmanexplode = luaL_checkinteger(L, 3);
|
plr->eggmanexplode = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"eggmanblame"))
|
else if (fastcmp(field,"eggmanblame"))
|
||||||
|
|
|
||||||
|
|
@ -585,6 +585,8 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
WRITEUINT16(save->p, players[i].invincibilitytimer);
|
WRITEUINT16(save->p, players[i].invincibilitytimer);
|
||||||
WRITEUINT16(save->p, players[i].invincibilityextensions);
|
WRITEUINT16(save->p, players[i].invincibilityextensions);
|
||||||
|
|
||||||
|
WRITEFIXED(save->p, players[i].loneliness);
|
||||||
|
|
||||||
WRITEUINT8(save->p, players[i].eggmanexplode);
|
WRITEUINT8(save->p, players[i].eggmanexplode);
|
||||||
WRITESINT8(save->p, players[i].eggmanblame);
|
WRITESINT8(save->p, players[i].eggmanblame);
|
||||||
|
|
||||||
|
|
@ -1256,6 +1258,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
players[i].invincibilitytimer = READUINT16(save->p);
|
players[i].invincibilitytimer = READUINT16(save->p);
|
||||||
players[i].invincibilityextensions = READUINT16(save->p);
|
players[i].invincibilityextensions = READUINT16(save->p);
|
||||||
|
|
||||||
|
players[i].loneliness = READFIXED(save->p);
|
||||||
|
|
||||||
players[i].eggmanexplode = READUINT8(save->p);
|
players[i].eggmanexplode = READUINT8(save->p);
|
||||||
players[i].eggmanblame = READSINT8(save->p);
|
players[i].eggmanblame = READSINT8(save->p);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue