Implement distance based itemodds when legacy waypoints are in play
This commit is contained in:
parent
1dc91b43ec
commit
92d86be813
10 changed files with 537 additions and 43 deletions
|
|
@ -715,6 +715,7 @@ extern boolean comeback;
|
|||
extern SINT8 battlewanted[4];
|
||||
extern tic_t wantedcalcdelay;
|
||||
extern tic_t indirectitemcooldown;
|
||||
extern tic_t hyubgone;
|
||||
extern tic_t mapreset;
|
||||
extern boolean thwompsactive;
|
||||
extern UINT8 lastLowestLap;
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ SINT8 pickedvote; // What vote the host rolls
|
|||
SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points
|
||||
tic_t wantedcalcdelay; // Time before it recalculates WANTED
|
||||
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
|
||||
tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled
|
||||
tic_t mapreset; // Map reset delay when enough players have joined an empty game
|
||||
boolean thwompsactive; // Thwomps activate on lap 2
|
||||
UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors
|
||||
|
|
|
|||
111
src/k_hud.c
111
src/k_hud.c
|
|
@ -4407,57 +4407,86 @@ static void K_drawDistributionDebugger(void)
|
|||
pdis = (15 * pdis) / 14;
|
||||
}
|
||||
|
||||
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush);
|
||||
if (numbosswaypoints > 0)
|
||||
useodds = K_FindLegacyUseodds(stplyr, 0, pdis, bestbumper, spbrush);
|
||||
else
|
||||
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush);
|
||||
|
||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||
if (pingame == 1)
|
||||
{
|
||||
if (stplyr->itemroulette && (stplyr->cmd.buttons & BT_ATTACK) && (cv_superring.value && !ringsdisabled))
|
||||
V_DrawScaledPatch(x, y, V_HUDTRANS|V_SNAPTOTOP, kp_superring[1]);
|
||||
else
|
||||
V_DrawScaledPatch(x, y, V_HUDTRANS|V_SNAPTOTOP, items[1]);
|
||||
V_DrawThinString(x+11, y+31, V_HUDTRANS|V_SNAPTOTOP, va("%d", 200));
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 itemodds = K_KartGetItemOdds(
|
||||
useodds, i,
|
||||
stplyr->distancetofinish,
|
||||
0,
|
||||
spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival)
|
||||
);
|
||||
|
||||
if (itemodds <= 0)
|
||||
continue;
|
||||
|
||||
V_DrawScaledPatch(x, y, V_HUDTRANS|V_SNAPTOTOP, items[i]);
|
||||
V_DrawThinString(x+11, y+31, V_HUDTRANS|V_SNAPTOTOP, va("%d", itemodds));
|
||||
|
||||
// Display amount for multi-items
|
||||
if (i >= NUMKARTITEMS)
|
||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
INT32 amount;
|
||||
switch (i)
|
||||
INT32 itemodds;
|
||||
|
||||
|
||||
|
||||
if (numbosswaypoints > 0)
|
||||
itemodds = K_KartGetLegacyItemOdds(useodds, i, 0, spbrush);
|
||||
else
|
||||
itemodds = K_KartGetItemOdds(
|
||||
useodds, i,
|
||||
stplyr->distancetofinish,
|
||||
0,
|
||||
spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival)
|
||||
);
|
||||
|
||||
if (itemodds <= 0)
|
||||
continue;
|
||||
|
||||
V_DrawScaledPatch(x, y, V_HUDTRANS|V_SNAPTOTOP, items[i]);
|
||||
V_DrawThinString(x+11, y+31, V_HUDTRANS|V_SNAPTOTOP, va("%d", itemodds));
|
||||
|
||||
// Display amount for multi-items
|
||||
if (i >= NUMKARTITEMS)
|
||||
{
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
amount = 10;
|
||||
break;
|
||||
case KRITEM_QUADORBINAUT:
|
||||
amount = 4;
|
||||
break;
|
||||
case KRITEM_DUALJAWZ:
|
||||
amount = 2;
|
||||
break;
|
||||
case KRITEM_DUALSNEAKER:
|
||||
amount = 2;
|
||||
break;
|
||||
default:
|
||||
amount = 3;
|
||||
break;
|
||||
INT32 amount;
|
||||
switch (i)
|
||||
{
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
amount = 10;
|
||||
break;
|
||||
case KRITEM_QUADORBINAUT:
|
||||
amount = 4;
|
||||
break;
|
||||
case KRITEM_DUALJAWZ:
|
||||
amount = 2;
|
||||
break;
|
||||
case KRITEM_DUALSNEAKER:
|
||||
amount = 2;
|
||||
break;
|
||||
default:
|
||||
amount = 3;
|
||||
break;
|
||||
}
|
||||
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOTOP, va("x%d", amount));
|
||||
}
|
||||
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOTOP, va("x%d", amount));
|
||||
}
|
||||
|
||||
x += 32;
|
||||
if (x >= 297)
|
||||
{
|
||||
x = -9;
|
||||
y += 32;
|
||||
x += 32;
|
||||
if (x >= 297)
|
||||
{
|
||||
x = -9;
|
||||
y += 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
V_DrawString(0, 0, V_HUDTRANS|V_SNAPTOTOP, va("USEODDS %d", useodds));
|
||||
if (pingame == 1)
|
||||
V_DrawString(0, 0, V_HUDTRANS|V_SNAPTOTOP, "TA MODE");
|
||||
else
|
||||
V_DrawString(0, 0, V_HUDTRANS|V_SNAPTOTOP, va("USEODDS %d", useodds));
|
||||
|
||||
if (numbosswaypoints > 0)
|
||||
V_DrawSmallString(70, 0, V_HUDTRANS|V_SNAPTOTOP, "Legacy Distance Mode");
|
||||
|
||||
}
|
||||
|
||||
static void K_drawCheckpointDebugger(void)
|
||||
|
|
|
|||
417
src/k_kart.c
417
src/k_kart.c
|
|
@ -425,6 +425,9 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem)
|
|||
if (getitem == KITEM_SPB || getitem == KITEM_SHRINK) // Indirect items
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
|
||||
if (getitem == KITEM_HYUDORO) // Hyudoro cooldown
|
||||
hyubgone = 20*TICRATE;
|
||||
|
||||
player->botvars.itemdelay = TICRATE;
|
||||
player->botvars.itemconfirm = 0;
|
||||
|
||||
|
|
@ -654,7 +657,6 @@ INT32 K_KartGetItemOdds(
|
|||
case KITEM_LANDMINE:
|
||||
case KITEM_DROPTARGET:
|
||||
case KITEM_BALLHOG:
|
||||
case KITEM_HYUDORO:
|
||||
case KRITEM_TRIPLESNEAKER:
|
||||
case KRITEM_TRIPLEORBINAUT:
|
||||
case KRITEM_QUADORBINAUT:
|
||||
|
|
@ -715,6 +717,12 @@ INT32 K_KartGetItemOdds(
|
|||
if (spbplace != -1)
|
||||
newodds = 0;
|
||||
break;
|
||||
case KITEM_HYUDORO:
|
||||
cooldownOnStart = true;
|
||||
|
||||
if (hyubgone > 0)
|
||||
newodds = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -771,6 +779,181 @@ INT32 K_KartGetItemOdds(
|
|||
return newodds;
|
||||
}
|
||||
|
||||
INT32 K_KartGetLegacyItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush)
|
||||
{
|
||||
INT32 newodds;
|
||||
INT32 i;
|
||||
UINT8 pingame = 0, pexiting = 0;
|
||||
SINT8 first = -1, second = -1;
|
||||
UINT32 secondToFirst = 0;
|
||||
INT32 shieldtype = KSHIELD_NONE;
|
||||
|
||||
boolean powerItem = false;
|
||||
boolean cooldownOnStart = false;
|
||||
boolean indirectItem = false;
|
||||
|
||||
I_Assert(item > KITEM_NONE); // too many off by one scenarioes.
|
||||
|
||||
if (!KartItemCVars[item-1]->value && !modeattacking)
|
||||
return 0;
|
||||
|
||||
if (gametype == GT_BATTLE)
|
||||
newodds = K_KartItemOddsBattle[item-1][pos];
|
||||
else
|
||||
newodds = K_KartItemOddsRace[item-1][pos];
|
||||
|
||||
// Base multiplication to ALL item odds to simulate fractional precision
|
||||
newodds *= 4;
|
||||
|
||||
shieldtype = K_GetShieldFromItem(item);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (!(gametyperules & GTR_BUMPERS) || players[i].bumper)
|
||||
pingame++;
|
||||
|
||||
if (players[i].exiting)
|
||||
pexiting++;
|
||||
|
||||
if (shieldtype != KSHIELD_NONE && shieldtype == K_GetShieldFromItem(players[i].itemtype))
|
||||
{
|
||||
// Don't allow more than one of each shield type at a time
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (players[i].mo && gametype == GT_RACE)
|
||||
{
|
||||
if (players[i].position == 1 && first == -1)
|
||||
first = i;
|
||||
if (players[i].position == 2 && second == -1)
|
||||
second = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB
|
||||
{
|
||||
secondToFirst = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x,
|
||||
players[first].mo->y - players[second].mo->y),
|
||||
players[first].mo->z - players[second].mo->z) / FRACUNIT;
|
||||
secondToFirst = K_ScaleItemDistance(secondToFirst, pingame, spbrush);
|
||||
}
|
||||
|
||||
switch (item)
|
||||
{
|
||||
case KITEM_ROCKETSNEAKER:
|
||||
case KITEM_JAWZ:
|
||||
case KITEM_BALLHOG:
|
||||
case KITEM_LANDMINE:
|
||||
case KITEM_DROPTARGET:
|
||||
case KRITEM_TRIPLESNEAKER:
|
||||
case KRITEM_TRIPLEBANANA:
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
case KRITEM_TRIPLEORBINAUT:
|
||||
case KRITEM_QUADORBINAUT:
|
||||
case KRITEM_DUALJAWZ:
|
||||
powerItem = true;
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
case KITEM_MINE:
|
||||
case KITEM_GROW:
|
||||
case KITEM_BUBBLESHIELD:
|
||||
case KITEM_FLAMESHIELD:
|
||||
cooldownOnStart = true;
|
||||
powerItem = true;
|
||||
break;
|
||||
case KITEM_SPB:
|
||||
cooldownOnStart = true;
|
||||
indirectItem = true;
|
||||
//powerItem = true;
|
||||
|
||||
if (pexiting > 0)
|
||||
{
|
||||
newodds = 0;
|
||||
}
|
||||
else if (pos != 9) // Force SPB
|
||||
{
|
||||
const INT32 distFromStart = max(0, (INT32)secondToFirst - SPBSTARTDIST);
|
||||
const INT32 distRange = SPBFORCEDIST - SPBSTARTDIST;
|
||||
const fixed_t mulMax = 3*FRACUNIT;
|
||||
|
||||
fixed_t multiplier = (distFromStart * mulMax) / distRange;
|
||||
|
||||
if (multiplier < 0)
|
||||
multiplier = 0;
|
||||
|
||||
if (multiplier > mulMax)
|
||||
multiplier = mulMax;
|
||||
|
||||
newodds = FixedMul(newodds * FRACUNIT, multiplier) / FRACUNIT;
|
||||
}
|
||||
break;
|
||||
case KITEM_SHRINK:
|
||||
cooldownOnStart = true;
|
||||
powerItem = true;
|
||||
indirectItem = true;
|
||||
|
||||
if (pingame-1 <= pexiting)
|
||||
newodds = 0;
|
||||
break;
|
||||
case KITEM_THUNDERSHIELD:
|
||||
cooldownOnStart = true;
|
||||
powerItem = true;
|
||||
break;
|
||||
case KITEM_HYUDORO:
|
||||
cooldownOnStart = true;
|
||||
|
||||
if (hyubgone > 0)
|
||||
newodds = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (newodds == 0)
|
||||
{
|
||||
// Nothing else we want to do with odds matters at this point :p
|
||||
return newodds;
|
||||
}
|
||||
|
||||
if ((indirectItem == true) && (indirectitemcooldown > 0))
|
||||
{
|
||||
// Too many items that act indirectly in a match can feel kind of bad.
|
||||
newodds = 0;
|
||||
}
|
||||
else if ((cooldownOnStart == true) && (leveltime < (30*TICRATE)+starttime))
|
||||
{
|
||||
// This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items)
|
||||
newodds = 0;
|
||||
}
|
||||
else if (powerItem == true)
|
||||
{
|
||||
// This item is a "power item". This activates "frantic item" toggle related functionality.
|
||||
fixed_t fracOdds = newodds * FRACUNIT;
|
||||
|
||||
if (franticitems == true)
|
||||
{
|
||||
// First, power items multiply their odds by 2 if frantic items are on; easy-peasy.
|
||||
fracOdds *= 2;
|
||||
}
|
||||
|
||||
fracOdds = FixedMul(fracOdds, FRACUNIT + K_ItemOddsScale(pingame, spbrush));
|
||||
|
||||
if (mashed > 0)
|
||||
{
|
||||
// Lastly, it *divides* it based on your mashed value, so that power items are less likely when you mash.
|
||||
fracOdds = FixedDiv(fracOdds, FRACUNIT + mashed);
|
||||
}
|
||||
|
||||
newodds = fracOdds / FRACUNIT;
|
||||
}
|
||||
|
||||
return newodds;
|
||||
}
|
||||
|
||||
|
||||
//{ SRB2kart Roulette Code - Distance Based, yes waypoints
|
||||
|
||||
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush)
|
||||
|
|
@ -868,6 +1051,232 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
return useodds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INT32 K_FindLegacyUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush)
|
||||
{
|
||||
SINT8 sortedPlayers[MAXPLAYERS];
|
||||
UINT8 sortLength = 0;
|
||||
|
||||
UINT32 pdis = 0;
|
||||
|
||||
UINT8 disttable[14];
|
||||
UINT8 distlen = 0;
|
||||
|
||||
boolean oddsvalid[8];
|
||||
INT32 useodds = 0;
|
||||
|
||||
INT32 i;
|
||||
|
||||
// Unused now, oops :V
|
||||
(void)bestbumper;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
INT32 j;
|
||||
boolean available = false;
|
||||
|
||||
if (gametype == GT_BATTLE && i > 1)
|
||||
{
|
||||
oddsvalid[i] = false;
|
||||
break;
|
||||
}
|
||||
|
||||
for (j = 1; j < NUMKARTRESULTS; j++)
|
||||
{
|
||||
|
||||
if (K_KartGetLegacyItemOdds(i, j, mashed, spbrush) > 0)
|
||||
{
|
||||
available = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
oddsvalid[i] = available;
|
||||
}
|
||||
|
||||
memset(sortedPlayers, -1, sizeof(sortedPlayers));
|
||||
|
||||
if (player->mo != NULL && P_MobjWasRemoved(player->mo) == false)
|
||||
{
|
||||
// Sort all of the players ahead of you.
|
||||
// Then tally up their distances in a conga line.
|
||||
|
||||
// This will create a much more consistent item
|
||||
// distance algorithm than the "spider web" thing
|
||||
// that it was doing before.
|
||||
|
||||
// Add yourself to the list.
|
||||
// You'll always be the end of the list,
|
||||
// so we can also calculate the length here.
|
||||
sortedPlayers[ player->position - 1 ] = player - players;
|
||||
sortLength = player->position;
|
||||
|
||||
// Will only need to do this if there's goint to be
|
||||
// more than yourself in the list.
|
||||
if (sortLength > 1)
|
||||
{
|
||||
SINT8 firstIndex = -1;
|
||||
SINT8 secondIndex = -1;
|
||||
INT32 startFrom = INT32_MAX;
|
||||
|
||||
// Add all of the other players.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
INT32 pos = INT32_MAX;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (players[i].mo == NULL || P_MobjWasRemoved(players[i].mo) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pos = players[i].position;
|
||||
|
||||
if (pos <= 0 || pos > MAXPLAYERS)
|
||||
{
|
||||
// Invalid position.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pos >= player->position)
|
||||
{
|
||||
// Tied / behind us.
|
||||
// Also handles ourselves, obviously.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ties are done with port priority, if there are any.
|
||||
if (sortedPlayers[ pos - 1 ] == -1)
|
||||
{
|
||||
sortedPlayers[ pos - 1 ] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// The chance of this list having gaps is improbable,
|
||||
// but not impossible. So we need to spend some extra time
|
||||
// to prevent the gaps from mattering.
|
||||
for (i = 0; i < sortLength-1; i++)
|
||||
{
|
||||
if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS)
|
||||
{
|
||||
// First valid index in the list found.
|
||||
firstIndex = sortedPlayers[i];
|
||||
|
||||
// Start the next loop after this player.
|
||||
startFrom = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstIndex >= 0 && firstIndex < MAXPLAYERS
|
||||
&& startFrom < sortLength)
|
||||
{
|
||||
// First index is valid, so we can
|
||||
// start comparing the players.
|
||||
|
||||
player_t *firstPlayer = NULL;
|
||||
player_t *secondPlayer = NULL;
|
||||
|
||||
for (i = startFrom; i < sortLength; i++)
|
||||
{
|
||||
if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS)
|
||||
{
|
||||
secondIndex = sortedPlayers[i];
|
||||
|
||||
firstPlayer = &players[firstIndex];
|
||||
secondPlayer = &players[secondIndex];
|
||||
|
||||
// Add the distance to the player behind you.
|
||||
pdis += P_AproxDistance(P_AproxDistance(
|
||||
firstPlayer->mo->x - secondPlayer->mo->x,
|
||||
firstPlayer->mo->y - secondPlayer->mo->y),
|
||||
firstPlayer->mo->z - secondPlayer->mo->z) / FRACUNIT;
|
||||
|
||||
// Advance to next index.
|
||||
firstIndex = secondIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SETUPDISTTABLE(odds, num) \
|
||||
if (oddsvalid[odds]) \
|
||||
for (i = num; i; --i) \
|
||||
disttable[distlen++] = odds;
|
||||
|
||||
if (gametype == GT_BATTLE) // Battle Mode
|
||||
{
|
||||
if (player->roulettetype == 1 && oddsvalid[1] == true)
|
||||
{
|
||||
// 1 is the extreme odds of player-controlled "Karma" items
|
||||
useodds = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
useodds = 0;
|
||||
|
||||
if (oddsvalid[0] == false && oddsvalid[1] == true)
|
||||
{
|
||||
// try to use karma odds as a fallback
|
||||
useodds = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SETUPDISTTABLE(0,1);
|
||||
SETUPDISTTABLE(1,1);
|
||||
SETUPDISTTABLE(2,1);
|
||||
SETUPDISTTABLE(3,2);
|
||||
SETUPDISTTABLE(4,2);
|
||||
SETUPDISTTABLE(5,3);
|
||||
SETUPDISTTABLE(6,3);
|
||||
SETUPDISTTABLE(7,1);
|
||||
|
||||
pdis = K_ScaleItemDistance(pdis, pingame, spbrush);
|
||||
|
||||
if (pingame == 1 && oddsvalid[0])
|
||||
{
|
||||
// Record Attack / FREE PLAY
|
||||
useodds = 0;
|
||||
}
|
||||
else if (pdis <= 0)
|
||||
{
|
||||
// 1st place
|
||||
useodds = disttable[0];
|
||||
}
|
||||
else if (pdis > DISTVAR * ((12 * distlen) / 14))
|
||||
{
|
||||
// Back of the pack
|
||||
useodds = disttable[distlen-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < 13; i++)
|
||||
{
|
||||
if (pdis <= (unsigned)(DISTVAR * ((i * distlen) / 14)))
|
||||
{
|
||||
useodds = disttable[((i * distlen) / 14)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef SETUPDISTTABLE
|
||||
|
||||
//CONS_Printf("Got useodds %d. (position: %d, distance: %d)\n", useodds, player->position, pdis);
|
||||
|
||||
return useodds;
|
||||
}
|
||||
|
||||
static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -1111,7 +1520,11 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
spawnchance[i] = 0;
|
||||
|
||||
// Split into another function for a debug function below
|
||||
useodds = K_FindUseodds(player, mashed, pdis, bestbumper, spbrush);
|
||||
// Use a legacy version for maps not using waypoints.
|
||||
if (numbosswaypoints > 0)
|
||||
useodds = K_FindLegacyUseodds(player, mashed, pdis, bestbumper, spbrush);
|
||||
else
|
||||
useodds = K_FindUseodds(player, mashed, pdis, bestbumper, spbrush);
|
||||
|
||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,9 +38,11 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value);
|
|||
extern consvar_t *KartItemCVars[NUMKARTRESULTS-1];
|
||||
|
||||
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush);
|
||||
INT32 K_FindLegacyUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush);
|
||||
fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush);
|
||||
UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush);
|
||||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean spbrush, boolean bot, boolean rival);
|
||||
INT32 K_KartGetLegacyItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush);
|
||||
INT32 K_GetShieldFromItem(INT32 item);
|
||||
fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against);
|
||||
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2);
|
||||
|
|
|
|||
|
|
@ -3903,6 +3903,41 @@ static int lib_kDeclareWeakspot(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// sets the remaining time before players blow up
|
||||
static int lib_kSetRaceCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
racecountdown = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// sets the remaining time before the race ends after everyone finishes
|
||||
static int lib_kSetExitCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
exitcountdown = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sets the item cooldown before another shrink / SPB can be rolled
|
||||
static int lib_kSetIndirectItemCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
indirectitemcooldown = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sets the item cooldown before another shrink / SPB can be rolled
|
||||
static int lib_kSetHyuCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
hyubgone = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_getTimeMicros(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
|
||||
|
|
@ -4195,6 +4230,10 @@ static luaL_Reg lib[] = {
|
|||
{"K_GetKartAccel",lib_kGetKartAccel},
|
||||
{"K_GetKartFlashing",lib_kGetKartFlashing},
|
||||
{"K_GetItemPatch",lib_kGetItemPatch},
|
||||
{"K_SetRaceCountdown",lib_kSetRaceCountdown},
|
||||
{"K_SetExitCountdown",lib_kSetExitCountdown},
|
||||
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
|
||||
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
|
||||
|
||||
{"K_GetCollideAngle",lib_kGetCollideAngle},
|
||||
|
||||
|
|
|
|||
|
|
@ -363,6 +363,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word,"gamespeed")) {
|
||||
lua_pushinteger(L, gamespeed);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"hyubgone")) {
|
||||
lua_pushinteger(L, hyubgone);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"encoremode")) {
|
||||
lua_pushboolean(L, encoremode);
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -5009,6 +5009,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
|
||||
WRITEUINT32(save->p, wantedcalcdelay);
|
||||
WRITEUINT32(save->p, indirectitemcooldown);
|
||||
WRITEUINT32(save->p, hyubgone);
|
||||
WRITEUINT32(save->p, mapreset);
|
||||
|
||||
WRITEUINT8(save->p, spectateGriefed);
|
||||
|
|
@ -5174,6 +5175,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
|
|||
battlewanted[i] = READSINT8(save->p);
|
||||
|
||||
wantedcalcdelay = READUINT32(save->p);
|
||||
hyubgone = READUINT32(save->p);
|
||||
indirectitemcooldown = READUINT32(save->p);
|
||||
mapreset = READUINT32(save->p);
|
||||
|
||||
|
|
|
|||
|
|
@ -8036,6 +8036,7 @@ static void P_InitGametype(void)
|
|||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
hyubgone = 0;
|
||||
mapreset = 0;
|
||||
|
||||
thwompsactive = false;
|
||||
|
|
|
|||
|
|
@ -848,6 +848,9 @@ void P_Ticker(boolean run)
|
|||
if (indirectitemcooldown > 0)
|
||||
indirectitemcooldown--;
|
||||
|
||||
if (hyubgone > 0)
|
||||
hyubgone--;
|
||||
|
||||
K_BossInfoTicker();
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS))
|
||||
|
|
|
|||
Loading…
Reference in a new issue