Rework bot skin randomisation
- Instead of picking over numskins and adjust the number if it picks an already used skin, build and shuffle a list of allowed skins and pick over that instead. - Fixes some issues with increased weighting towards the skins immediately after your rivals' skins. - Use PR_RULESCRAMBLE instead of PR_UNDEFINED. - Why am I doing it in this branch? I'm getting re-acquainted with how bots are handled between matches in advance of disabling them for bonus events without losing or corrupting data.
This commit is contained in:
parent
21dc144d55
commit
887345e663
3 changed files with 60 additions and 91 deletions
|
|
@ -96,14 +96,14 @@ INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
SINT8 K_BotDefaultSkin(void)
|
||||
UINT8 K_BotDefaultSkin(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
SINT8 K_BotDefaultSkin(void)
|
||||
UINT8 K_BotDefaultSkin(void)
|
||||
{
|
||||
const char *defaultbotskinname = "eggrobo";
|
||||
SINT8 defaultbotskin = R_SkinAvailable(defaultbotskinname);
|
||||
INT32 defaultbotskin = R_SkinAvailable(defaultbotskinname);
|
||||
|
||||
if (defaultbotskin == -1)
|
||||
{
|
||||
|
|
@ -111,7 +111,7 @@ SINT8 K_BotDefaultSkin(void)
|
|||
defaultbotskin = 0;
|
||||
}
|
||||
|
||||
return defaultbotskin;
|
||||
return (UINT8)defaultbotskin;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -121,7 +121,7 @@ SINT8 K_BotDefaultSkin(void)
|
|||
--------------------------------------------------*/
|
||||
void K_InitGrandPrixBots(void)
|
||||
{
|
||||
const SINT8 defaultbotskin = K_BotDefaultSkin();
|
||||
const UINT8 defaultbotskin = K_BotDefaultSkin();
|
||||
|
||||
const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed);
|
||||
UINT8 difficultylevels[MAXPLAYERS];
|
||||
|
|
@ -132,7 +132,9 @@ void K_InitGrandPrixBots(void)
|
|||
UINT8 numplayers = 0;
|
||||
UINT8 competitors[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
boolean skinusable[MAXSKINS];
|
||||
UINT8 usableskins;
|
||||
UINT8 grabskins[MAXSKINS];
|
||||
|
||||
UINT8 botskinlist[MAXPLAYERS];
|
||||
UINT8 botskinlistpos = 0;
|
||||
|
||||
|
|
@ -142,17 +144,10 @@ void K_InitGrandPrixBots(void)
|
|||
memset(competitors, MAXPLAYERS, sizeof (competitors));
|
||||
memset(botskinlist, defaultbotskin, sizeof (botskinlist));
|
||||
|
||||
// init usable bot skins list
|
||||
for (i = 0; i < MAXSKINS; i++)
|
||||
// Init usable bot skins list
|
||||
for (usableskins = 0; usableskins < numskins; usableskins++)
|
||||
{
|
||||
if (i < numskins)
|
||||
{
|
||||
skinusable[i] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
skinusable[i] = false;
|
||||
}
|
||||
grabskins[usableskins] = usableskins;
|
||||
}
|
||||
|
||||
#if MAXPLAYERS != 16
|
||||
|
|
@ -192,7 +187,7 @@ void K_InitGrandPrixBots(void)
|
|||
if (numplayers < MAXSPLITSCREENPLAYERS && !players[i].spectator)
|
||||
{
|
||||
competitors[numplayers] = i;
|
||||
skinusable[players[i].skin] = false;
|
||||
grabskins[players[i].skin] = MAXSKINS;
|
||||
numplayers++;
|
||||
}
|
||||
else
|
||||
|
|
@ -228,52 +223,42 @@ void K_InitGrandPrixBots(void)
|
|||
{
|
||||
player_t *p = &players[competitors[j]];
|
||||
char *rivalname = skins[p->skin].rivals[i];
|
||||
SINT8 rivalnum = R_SkinAvailable(rivalname);
|
||||
INT32 rivalnum = R_SkinAvailable(rivalname);
|
||||
|
||||
if (rivalnum != -1 && skinusable[rivalnum])
|
||||
// Intentionally referenced before (currently dummied out) unlock check. Such a tease!
|
||||
if (rivalnum != -1 && grabskins[(UINT8)rivalnum] != MAXSKINS)
|
||||
{
|
||||
botskinlist[botskinlistpos] = rivalnum;
|
||||
skinusable[rivalnum] = false;
|
||||
botskinlist[botskinlistpos++] = (UINT8)rivalnum;
|
||||
grabskins[(UINT8)rivalnum] = MAXSKINS;
|
||||
botskinlistpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rearrange usable bot skins list to prevent gaps for randomised selection
|
||||
for (i = 0; i < usableskins; i++)
|
||||
{
|
||||
if (grabskins[i] != MAXSKINS /*&& !K_SkinLocked(usableskins)*/)
|
||||
continue;
|
||||
grabskins[i] = grabskins[--usableskins];
|
||||
}
|
||||
|
||||
// Pad the remaining list with random skins if we need to
|
||||
if (botskinlistpos < wantedbots)
|
||||
{
|
||||
for (i = botskinlistpos; i < wantedbots; i++)
|
||||
while (botskinlistpos < wantedbots)
|
||||
{
|
||||
UINT8 val = M_RandomKey(numskins);
|
||||
UINT8 loops = 0;
|
||||
UINT8 skinnum = defaultbotskin;
|
||||
|
||||
while (!skinusable[val])
|
||||
if (usableskins > 0)
|
||||
{
|
||||
if (loops >= numskins)
|
||||
{
|
||||
// no more skins
|
||||
break;
|
||||
}
|
||||
|
||||
val++;
|
||||
|
||||
if (val >= numskins)
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
|
||||
loops++;
|
||||
UINT8 index = M_RandomKey(usableskins);
|
||||
skinnum = grabskins[index];
|
||||
grabskins[index] = grabskins[--usableskins];
|
||||
}
|
||||
|
||||
if (loops >= numskins)
|
||||
{
|
||||
// leave the rest of the table as the default skin
|
||||
break;
|
||||
}
|
||||
|
||||
botskinlist[i] = val;
|
||||
skinusable[val] = false;
|
||||
botskinlist[botskinlistpos++] = skinnum;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -528,10 +513,11 @@ void K_IncreaseBotDifficulty(player_t *bot)
|
|||
--------------------------------------------------*/
|
||||
void K_RetireBots(void)
|
||||
{
|
||||
const SINT8 defaultbotskin = K_BotDefaultSkin();
|
||||
const UINT8 defaultbotskin = K_BotDefaultSkin();
|
||||
SINT8 newDifficulty;
|
||||
|
||||
boolean skinusable[MAXSKINS];
|
||||
UINT8 usableskins;
|
||||
UINT8 grabskins[MAXSKINS];
|
||||
|
||||
UINT8 i;
|
||||
|
||||
|
|
@ -541,25 +527,29 @@ void K_RetireBots(void)
|
|||
return;
|
||||
}
|
||||
|
||||
// init usable bot skins list
|
||||
for (i = 0; i < MAXSKINS; i++)
|
||||
// Init usable bot skins list
|
||||
for (usableskins = 0; usableskins < numskins; usableskins++)
|
||||
{
|
||||
if (i < numskins)
|
||||
{
|
||||
skinusable[i] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
skinusable[i] = false;
|
||||
}
|
||||
grabskins[usableskins] = usableskins;
|
||||
}
|
||||
|
||||
// Exclude player skins
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
{
|
||||
skinusable[players[i].skin] = false;
|
||||
}
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (players[i].spectator)
|
||||
continue;
|
||||
|
||||
grabskins[players[i].skin] = MAXSKINS;
|
||||
}
|
||||
|
||||
// Rearrange usable bot skins list to prevent gaps for randomised selection
|
||||
for (i = 0; i < usableskins; i++)
|
||||
{
|
||||
if (grabskins[i] != MAXSKINS /*&& !K_SkinLocked(usableskins)*/)
|
||||
continue;
|
||||
grabskins[i] = grabskins[--usableskins];
|
||||
}
|
||||
|
||||
if (!grandprixinfo.gp) // Sure, let's let this happen all the time :)
|
||||
|
|
@ -599,35 +589,15 @@ void K_RetireBots(void)
|
|||
|
||||
if (bot->pflags & PF_NOCONTEST)
|
||||
{
|
||||
UINT8 skinnum = P_RandomKey(numskins);
|
||||
UINT8 loops = 0;
|
||||
UINT8 skinnum = defaultbotskin;
|
||||
|
||||
while (!skinusable[skinnum])
|
||||
if (usableskins > 0)
|
||||
{
|
||||
if (loops >= numskins)
|
||||
{
|
||||
// no more skins
|
||||
break;
|
||||
}
|
||||
|
||||
skinnum++;
|
||||
|
||||
if (skinnum >= numskins)
|
||||
{
|
||||
skinnum = 0;
|
||||
}
|
||||
|
||||
loops++;
|
||||
UINT8 index = P_RandomKey(usableskins);
|
||||
skinnum = grabskins[index];
|
||||
grabskins[index] = grabskins[--usableskins];
|
||||
}
|
||||
|
||||
if (loops >= numskins)
|
||||
{
|
||||
// Use default skin
|
||||
skinnum = defaultbotskin;
|
||||
}
|
||||
|
||||
skinusable[skinnum] = false;
|
||||
|
||||
bot->botvars.difficulty = newDifficulty;
|
||||
bot->botvars.diffincrease = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,13 +63,13 @@ INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers);
|
|||
|
||||
|
||||
/*--------------------------------------------------
|
||||
SINT8 K_BotDefaultSkin(void);
|
||||
UINT8 K_BotDefaultSkin(void);
|
||||
|
||||
Returns the skin number of the skin the game
|
||||
uses as a fallback option.
|
||||
--------------------------------------------------*/
|
||||
|
||||
SINT8 K_BotDefaultSkin(void);
|
||||
UINT8 K_BotDefaultSkin(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
//#define DEBUGRANDOM
|
||||
|
||||
|
||||
// M_Random functions pull random numbers of various types that aren't network synced.
|
||||
// P_Random functions pulls random bytes from a PRNG that is network synced.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue