diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 9b4da706f..74166b77b 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -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 @@ -219,52 +214,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; } } @@ -519,10 +504,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; @@ -532,25 +518,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 :) @@ -590,35 +580,15 @@ void K_RetireBots(void) if (bot->pflags & PF_NOCONTEST) { - UINT8 skinnum = P_RandomKey(PR_UNDEFINED, 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(PR_RULESCRAMBLE, 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; diff --git a/src/k_grandprix.h b/src/k_grandprix.h index bd20d3894..64085fa00 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -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); /*-------------------------------------------------- diff --git a/src/m_random.h b/src/m_random.h index 6f534b219..c08e32993 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -47,7 +47,7 @@ typedef enum PR_PLAYERSTARTS, // Player starts PR_VOICES, // Player voice sounds - PR_RULESCRAMBLE, // Netgame rule scrambing events + PR_RULESCRAMBLE, // Rule scrambing events PR_ITEM_ROULETTE, // Item results PR_ITEM_RINGS, // Flung ring/bumper/player (on death)