diff --git a/src/k_grandprix.c b/src/k_grandprix.c index ddbda5a2e..708390f5a 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -40,7 +40,7 @@ void K_InitGrandPrixBots(void) UINT8 botskinlistpos = 0; UINT8 newplayernum = 0; - UINT8 i; + UINT8 i, j; memset(difficultylevels, MAXBOTDIFFICULTY, sizeof (difficultylevels)); memset(competitors, MAXPLAYERS, sizeof (competitors)); @@ -107,11 +107,25 @@ void K_InitGrandPrixBots(void) wantedbots = playercount - numplayers; // Create rival list + if (numplayers > 0) + { + for (i = 0; i < SKINRIVALS; i++) + { + for (j = 0; j < numplayers; j++) + { + player_t *p = &players[competitors[j]]; + char *rivalname = skins[p->skin].rivals[i]; + SINT8 rivalnum = R_SkinAvailable(rivalname); - // TODO: Use player skin's set rivals - // Starting with P1's rival1, P2's rival1, P3's rival1, P4's rival1, - // then P1's rival2, P2's rival2, etc etc etc etc....... - // then skip over any duplicates. + if (rivalnum != -1 && skinusable[rivalnum]) + { + botskinlist[botskinlistpos] = rivalnum; + skinusable[rivalnum] = false; + botskinlistpos++; + } + } + } + } // Pad the remaining list with random skins if we need to if (botskinlistpos < wantedbots) diff --git a/src/r_things.c b/src/r_things.c index 587be375d..8e92a1c66 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2893,6 +2893,11 @@ static void Sk_SetDefaultValue(skin_t *skin) strncpy(skin->facewant, "PLAYWANT", 9); strncpy(skin->facemmap, "PLAYMMAP", 9); + for (i = 0; i < SKINRIVALS; i++) + { + strcpy(skin->rivals[i], ""); + } + skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; @@ -3163,6 +3168,45 @@ void R_AddSkins(UINT16 wadnum) strupr(value); strncpy(skin->facemmap, value, sizeof skin->facemmap); } + else if (!stricmp(stoken, "rivals")) + { + size_t len = strlen(value); + size_t i; + char rivalname[SKINNAMESIZE] = ""; + UINT8 pos = 0; + UINT8 numrivals = 0; + + // Can't use strtok, because this function's already using it. + // Using it causes it to upset the saved pointer, + // corrupting the reading for the rest of the file. + + // So instead we get to crawl through the value, character by character, + // and write it down as we go, until we hit a comma or the end of the string. + // Yaaay. + + for (i = 0; i <= len; i++) + { + if (numrivals >= SKINRIVALS) + { + break; + } + + if (value[i] == ',' || i == len) + { + STRBUFCPY(skin->rivals[numrivals], rivalname); + strlwr(skin->rivals[numrivals]); + numrivals++; + + memset(rivalname, 0, sizeof (rivalname)); + pos = 0; + + continue; + } + + rivalname[pos] = value[i]; + pos++; + } + } #define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); // character type identification diff --git a/src/r_things.h b/src/r_things.h index 470e32fb2..6d0e86425 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -67,6 +67,7 @@ void R_DrawMasked(void); // SKINS STUFF // ----------- #define SKINNAMESIZE 16 +#define SKINRIVALS 3 // should be all lowercase!! S_SKIN processing does a strlwr #define DEFAULTSKIN "sonic" #define DEFAULTSKIN2 "tails" // secondary player @@ -95,6 +96,8 @@ typedef struct UINT8 prefcolor; fixed_t highresscale; // scale of highres, default is 0.5 + char rivals[SKINRIVALS][SKINNAMESIZE+1]; // Your top 3 rivals for GP mode. Uses names so that you can reference skins that aren't added + // specific sounds per skin sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table } skin_t;