mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-04 04:36:21 +00:00
Implement the Special Stage item table
This commit is contained in:
parent
8ca3d41696
commit
b55d299fdb
5 changed files with 149 additions and 83 deletions
20
src/k_hud.c
20
src/k_hud.c
|
|
@ -4570,25 +4570,7 @@ static void K_drawDistributionDebugger(void)
|
|||
bestbumper = players[i].bumpers;
|
||||
}
|
||||
|
||||
// lovely double loop......
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator
|
||||
&& players[i].position == 1)
|
||||
{
|
||||
// This player is first! Yay!
|
||||
pdis = stplyr->distancetofinish - players[i].distancetofinish;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pdis = K_ScaleItemDistance(pdis, pingame);
|
||||
|
||||
if (stplyr->bot && stplyr->botvars.rival)
|
||||
{
|
||||
// Rival has better odds :)
|
||||
pdis = (15 * pdis) / 14;
|
||||
}
|
||||
pdis = K_GetItemRouletteDistance(stplyr, pingame);
|
||||
|
||||
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper);
|
||||
|
||||
|
|
|
|||
196
src/k_kart.c
196
src/k_kart.c
|
|
@ -485,8 +485,6 @@ static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
|
|||
{ 5, 1 } // Jawz x2
|
||||
};
|
||||
|
||||
// TODO: add back when this gets used
|
||||
#if 0
|
||||
static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] =
|
||||
{
|
||||
//M N O P
|
||||
|
|
@ -519,7 +517,6 @@ static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] =
|
|||
{ 0, 0, 1, 1 }, // Orbinaut x4
|
||||
{ 0, 0, 1, 1 } // Jawz x2
|
||||
};
|
||||
#endif
|
||||
|
||||
#define DISTVAR (2048) // Magic number distance for use with item roulette tiers
|
||||
#define SPBSTARTDIST (6*DISTVAR) // Distance when SPB can start appearing
|
||||
|
|
@ -797,6 +794,11 @@ INT32 K_KartGetItemOdds(
|
|||
I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table
|
||||
newodds = K_KartItemOddsBattle[item-1][pos];
|
||||
}
|
||||
else if (specialStage.active == true)
|
||||
{
|
||||
I_Assert(pos < 4); // Ditto
|
||||
newodds = K_KartItemOddsSpecial[item-1][pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Assert(pos < 8); // Ditto
|
||||
|
|
@ -902,29 +904,32 @@ INT32 K_KartGetItemOdds(
|
|||
cooldownOnStart = true;
|
||||
notNearEnd = true;
|
||||
|
||||
if (firstDist < ENDDIST*2 // No SPB when 1st is almost done
|
||||
|| isFirst == true) // No SPB for 1st ever
|
||||
if (specialStage.active == false)
|
||||
{
|
||||
newodds = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST);
|
||||
const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST;
|
||||
const UINT8 maxOdds = 20;
|
||||
fixed_t multiplier = (dist * FRACUNIT) / distRange;
|
||||
|
||||
if (multiplier < 0)
|
||||
if (firstDist < ENDDIST*2 // No SPB when 1st is almost done
|
||||
|| isFirst == true) // No SPB for 1st ever
|
||||
{
|
||||
multiplier = 0;
|
||||
newodds = 0;
|
||||
}
|
||||
|
||||
if (multiplier > FRACUNIT)
|
||||
else
|
||||
{
|
||||
multiplier = FRACUNIT;
|
||||
}
|
||||
const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST);
|
||||
const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST;
|
||||
const UINT8 maxOdds = 20;
|
||||
fixed_t multiplier = (dist * FRACUNIT) / distRange;
|
||||
|
||||
newodds = FixedMul(maxOdds * 4, multiplier);
|
||||
if (multiplier < 0)
|
||||
{
|
||||
multiplier = 0;
|
||||
}
|
||||
|
||||
if (multiplier > FRACUNIT)
|
||||
{
|
||||
multiplier = FRACUNIT;
|
||||
}
|
||||
|
||||
newodds = FixedMul(maxOdds * 4, multiplier);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1005,6 +1010,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
UINT8 useodds = 0;
|
||||
UINT8 disttable[14];
|
||||
UINT8 distlen = 0;
|
||||
UINT8 totalsize = 0;
|
||||
boolean oddsvalid[8];
|
||||
|
||||
// Unused now, oops :V
|
||||
|
|
@ -1015,10 +1021,15 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
UINT8 j;
|
||||
boolean available = false;
|
||||
|
||||
if (gametype == GT_BATTLE && i > 1)
|
||||
if (specialStage.active == true && i > 3)
|
||||
{
|
||||
oddsvalid[i] = false;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
else if (gametype == GT_BATTLE && i > 1)
|
||||
{
|
||||
oddsvalid[i] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 1; j < NUMKARTRESULTS; j++)
|
||||
|
|
@ -1039,6 +1050,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
}
|
||||
|
||||
#define SETUPDISTTABLE(odds, num) \
|
||||
totalsize++;\
|
||||
if (oddsvalid[odds]) \
|
||||
for (i = num; i; --i) \
|
||||
disttable[distlen++] = odds;
|
||||
|
|
@ -1063,26 +1075,44 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
}
|
||||
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);
|
||||
UINT32 itotaldis = 0;
|
||||
|
||||
if (specialStage.active == true) // Special Stages
|
||||
{
|
||||
SETUPDISTTABLE(0,1);
|
||||
SETUPDISTTABLE(1,2);
|
||||
SETUPDISTTABLE(2,3);
|
||||
SETUPDISTTABLE(3,1);
|
||||
}
|
||||
else // Race
|
||||
{
|
||||
SETUPDISTTABLE(0,1);
|
||||
SETUPDISTTABLE(1,1);
|
||||
SETUPDISTTABLE(2,1);
|
||||
SETUPDISTTABLE(3,2);
|
||||
SETUPDISTTABLE(4,2);
|
||||
SETUPDISTTABLE(5,3);
|
||||
SETUPDISTTABLE(6,3);
|
||||
SETUPDISTTABLE(7,1);
|
||||
}
|
||||
|
||||
itotaldis = DISTVAR * (((totalsize - 2) * distlen) / totalsize);
|
||||
|
||||
if (pdis == 0)
|
||||
{
|
||||
useodds = disttable[0];
|
||||
else if (pdis > DISTVAR * ((12 * distlen) / 14))
|
||||
}
|
||||
else if (pdis > itotaldis)
|
||||
{
|
||||
useodds = disttable[distlen-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < 13; i++)
|
||||
for (i = 1; i < totalsize-1; i++)
|
||||
{
|
||||
if (pdis <= DISTVAR * ((i * distlen) / 14))
|
||||
if (pdis <= DISTVAR * ((i * distlen) / totalsize))
|
||||
{
|
||||
useodds = disttable[((i * distlen) / 14)];
|
||||
useodds = disttable[((i * distlen) / totalsize)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1118,6 +1148,11 @@ INT32 K_GetRollingRouletteItem(player_t *player)
|
|||
odds_row = K_KartItemOddsBattle[0];
|
||||
odds_row_size = sizeof K_KartItemOddsBattle[0];
|
||||
}
|
||||
else if (specialStage.active == true)
|
||||
{
|
||||
odds_row = K_KartItemOddsSpecial[0];
|
||||
odds_row_size = sizeof K_KartItemOddsSpecial[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
odds_row = K_KartItemOddsRace[0];
|
||||
|
|
@ -1160,6 +1195,11 @@ boolean K_ForcedSPB(player_t *player)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (specialStage.active == true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->position <= 1)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -1216,6 +1256,61 @@ boolean K_ForcedSPB(player_t *player)
|
|||
return (secondToFirst >= SPBFORCEDIST);
|
||||
}
|
||||
|
||||
UINT32 K_GetItemRouletteDistance(player_t *player, UINT8 pingame)
|
||||
{
|
||||
UINT32 pdis = 0;
|
||||
|
||||
if (specialStage.active == true)
|
||||
{
|
||||
UINT32 ufoDis = K_GetSpecialUFODistance();
|
||||
|
||||
if (player->distancetofinish <= ufoDis)
|
||||
{
|
||||
// You're ahead of the UFO.
|
||||
pdis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subtract the UFO's distance from your distance!
|
||||
pdis = player->distancetofinish - ufoDis;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator
|
||||
&& players[i].position == 1)
|
||||
{
|
||||
// This player is first! Yay!
|
||||
|
||||
if (player->distancetofinish <= players[i].distancetofinish)
|
||||
{
|
||||
// Guess you're in first / tied for first?
|
||||
pdis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subtract 1st's distance from your distance, to get your distance from 1st!
|
||||
pdis = player->distancetofinish - players[i].distancetofinish;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pdis = K_ScaleItemDistance(pdis, pingame);
|
||||
|
||||
if (player->bot && player->botvars.rival)
|
||||
{
|
||||
// Rival has better odds :)
|
||||
pdis = (15 * pdis) / 14;
|
||||
}
|
||||
|
||||
return pdis;
|
||||
}
|
||||
|
||||
static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -1271,34 +1366,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
else if (!(player->itemroulette >= (TICRATE*3)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator
|
||||
&& players[i].position == 1)
|
||||
{
|
||||
// This player is first! Yay!
|
||||
|
||||
if (player->distancetofinish <= players[i].distancetofinish)
|
||||
{
|
||||
// Guess you're in first / tied for first?
|
||||
pdis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subtract 1st's distance from your distance, to get your distance from 1st!
|
||||
pdis = player->distancetofinish - players[i].distancetofinish;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pdis = K_ScaleItemDistance(pdis, pingame);
|
||||
|
||||
if (player->bot && player->botvars.rival)
|
||||
{
|
||||
// Rival has better odds :)
|
||||
pdis = (15 * pdis) / 14;
|
||||
}
|
||||
pdis = K_GetItemRouletteDistance(player, pingame);
|
||||
|
||||
// SPECIAL CASE No. 1:
|
||||
// Fake Eggman items
|
||||
|
|
@ -1331,7 +1399,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
// SPECIAL CASE No. 3:
|
||||
// Record Attack / alone mashing behavior
|
||||
if (modeattacking || pingame == 1)
|
||||
if ((modeattacking || pingame == 1) && (specialStage.active == false))
|
||||
{
|
||||
if (gametype == GT_RACE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers);
|
|||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean bot, boolean rival);
|
||||
INT32 K_GetRollingRouletteItem(player_t *player);
|
||||
boolean K_ForcedSPB(player_t *player);
|
||||
UINT32 K_GetItemRouletteDistance(player_t *player, UINT8 pingame);
|
||||
INT32 K_GetShieldFromItem(INT32 item);
|
||||
SINT8 K_ItemResultToType(SINT8 getitem);
|
||||
UINT8 K_ItemResultToAmount(SINT8 getitem);
|
||||
|
|
|
|||
|
|
@ -57,5 +57,6 @@ void Obj_DuelBombInit(mobj_t *bomb);
|
|||
/* Special Stage UFO */
|
||||
void Obj_SpecialUFOThinker(mobj_t *bomb);
|
||||
mobj_t *Obj_CreateSpecialUFO(void);
|
||||
UINT32 K_GetSpecialUFODistance(void);
|
||||
|
||||
#endif/*k_objects_H*/
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_specialstage.h"
|
||||
|
||||
#define UFO_BASE_SPEED (12 * FRACUNIT) // UFO's slowest speed.
|
||||
#define UFO_SPEEDUP (FRACUNIT)
|
||||
|
|
@ -373,3 +374,16 @@ mobj_t *Obj_CreateSpecialUFO(void)
|
|||
|
||||
return InitSpecialUFO(startWaypoint);
|
||||
}
|
||||
|
||||
UINT32 K_GetSpecialUFODistance(void)
|
||||
{
|
||||
if (specialStage.active == true)
|
||||
{
|
||||
if (specialStage.ufo != NULL && P_MobjWasRemoved(specialStage.ufo) == false)
|
||||
{
|
||||
return (UINT32)ufo_distancetofinish(specialStage.ufo);
|
||||
}
|
||||
}
|
||||
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue