Merge public master

This commit is contained in:
Eidolon 2025-08-12 16:17:14 -05:00
commit 892a6b8620
49 changed files with 244 additions and 255 deletions

View file

@ -1646,7 +1646,7 @@ bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
&& (info->mo->player != NULL)) && (info->mo->player != NULL))
{ {
UINT8 skin = info->mo->player->skin; UINT8 skin = info->mo->player->skin;
thread->dataStk.push(~env->getString( skins[skin].name )->idx); thread->dataStk.push(~env->getString( skins[skin]->name )->idx);
return false; return false;
} }
@ -3701,11 +3701,11 @@ bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
#define PROP_SKIN(x, y) \ #define PROP_SKIN(x, y) \
case x: \ case x: \
{ \ { \
INT32 newSkin = (mobj->skin != NULL) ? (static_cast<skin_t *>(mobj->skin)) - skins : -1; \ INT32 newSkin = (mobj->skin != NULL) ? (static_cast<skin_t *>(mobj->skin)->skinnum) : -1; \
bool success = ACS_GetSkinFromString(thread->scopeMap->getString( value )->str, &newSkin); \ bool success = ACS_GetSkinFromString(thread->scopeMap->getString( value )->str, &newSkin); \
if (success == true) \ if (success == true) \
{ \ { \
mobj->y = (newSkin >= 0 && newSkin < numskins) ? &skins[ newSkin ] : NULL; \ mobj->y = (newSkin >= 0 && newSkin < numskins) ? skins[ newSkin ] : NULL; \
} \ } \
break; \ break; \
} }

View file

@ -2138,7 +2138,7 @@ static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth
if ((value < 0) || (value >= numskins)) if ((value < 0) || (value >= numskins))
tmpskin = "None"; tmpskin = "None";
else else
tmpskin = skins[value].name; tmpskin = skins[value]->name;
strlcpy(val, tmpskin, SKINNAMESIZE+1); strlcpy(val, tmpskin, SKINNAMESIZE+1);
} }
else else

View file

@ -2069,7 +2069,7 @@ void D_SRB2Main(void)
INT32 importskin = R_SkinAvailableEx(pr->skinname, false); INT32 importskin = R_SkinAvailableEx(pr->skinname, false);
if (importskin != -1) if (importskin != -1)
{ {
skins[importskin].records.wins = pr->wins; skins[importskin]->records.wins = pr->wins;
cupheader_t *cup; cupheader_t *cup;
for (cup = kartcupheaders; cup; cup = cup->next) for (cup = kartcupheaders; cup; cup = cup->next)
@ -2095,7 +2095,7 @@ void D_SRB2Main(void)
} }
} }
CONS_Printf(" Wins for profile \"%s\" imported onto character \"%s\"\n", pr->profilename, skins[importskin].name); CONS_Printf(" Wins for profile \"%s\" imported onto character \"%s\"\n", pr->profilename, skins[importskin]->name);
} }
} }

View file

@ -888,7 +888,7 @@ static void ForceAllSkins(INT32 forcedskin)
if (!playeringame[g_localplayers[i]]) if (!playeringame[g_localplayers[i]])
continue; continue;
CV_StealthSet(&cv_skin[i], skins[forcedskin].name); CV_StealthSet(&cv_skin[i], skins[forcedskin]->name);
} }
} }
@ -982,7 +982,7 @@ static void SendNameAndColor(const UINT8 n)
// Don't change skin if the server doesn't want you to. // Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(playernum)) if (!CanChangeSkin(playernum))
{ {
CV_StealthSet(&cv_skin[n], skins[player->skin].name); CV_StealthSet(&cv_skin[n], skins[player->skin]->name);
} }
// check if player has the skin loaded (cv_skin may have // check if player has the skin loaded (cv_skin may have
@ -1016,7 +1016,7 @@ static void SendNameAndColor(const UINT8 n)
// Don't send if everything was identical. // Don't send if everything was identical.
if (!strcmp(cv_playername[n].string, player_names[playernum]) if (!strcmp(cv_playername[n].string, player_names[playernum])
&& sendColor == player->prefcolor && sendColor == player->prefcolor
&& !stricmp(cv_skin[n].string, skins[player->prefskin].name) && !stricmp(cv_skin[n].string, skins[player->prefskin]->name)
&& !stricmp(cv_follower[n].string, && !stricmp(cv_follower[n].string,
(player->preffollower < 0 ? "None" : followers[player->preffollower].name)) (player->preffollower < 0 ? "None" : followers[player->preffollower].name))
&& sendFollowerColor == player->preffollowercolor) && sendFollowerColor == player->preffollowercolor)
@ -6973,7 +6973,7 @@ static void Skin_OnChange(const UINT8 p)
if (!CV_CheatsEnabled() && !(netgame || K_CanChangeRules(false)) if (!CV_CheatsEnabled() && !(netgame || K_CanChangeRules(false))
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y && (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
{ {
CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name); CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin]->name);
return; return;
} }
@ -6984,7 +6984,7 @@ static void Skin_OnChange(const UINT8 p)
else else
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name); CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin]->name);
} }
} }

View file

@ -956,7 +956,7 @@ void DRPC_UpdatePresence(void)
// Character image // Character image
if ((unsigned)players[consoleplayer].skin < g_discord_skins) // Supported skins if ((unsigned)players[consoleplayer].skin < g_discord_skins) // Supported skins
{ {
snprintf(charimg, 128, "%schar_%s%s", IMAGE_REPO, skins[ players[consoleplayer].skin ].name, IMAGE_EXT); snprintf(charimg, 128, "%schar_%s%s", IMAGE_REPO, skins[ players[consoleplayer].skin ]->name, IMAGE_EXT);
discordPresence.smallImageKey = charimg; discordPresence.smallImageKey = charimg;
} }
else else
@ -965,7 +965,7 @@ void DRPC_UpdatePresence(void)
discordPresence.smallImageKey = IMAGE_REPO "custom_char" IMAGE_EXT; discordPresence.smallImageKey = IMAGE_REPO "custom_char" IMAGE_EXT;
} }
snprintf(charname, 128, "Character: %s", skins[players[consoleplayer].skin].realname); snprintf(charname, 128, "Character: %s", skins[players[consoleplayer].skin]->realname);
discordPresence.smallImageText = charname; // Character name discordPresence.smallImageText = charname; // Character name
} }
} }

View file

@ -1519,7 +1519,7 @@ void F_GameEvaluationDrawer(void)
const char *rtatext, *cuttext; const char *rtatext, *cuttext;
rtatext = (marathonmode & MA_INGAME) ? "In-game timer" : "RTA timer"; rtatext = (marathonmode & MA_INGAME) ? "In-game timer" : "RTA timer";
cuttext = (marathonmode & MA_NOCUTSCENES) ? "" : " w/ cutscenes"; cuttext = (marathonmode & MA_NOCUTSCENES) ? "" : " w/ cutscenes";
endingtext = va("%s, %s%s", skins[players[consoleplayer].skin].realname, rtatext, cuttext); endingtext = va("%s, %s%s", skins[players[consoleplayer].skin]->realname, rtatext, cuttext);
V_DrawCenteredString(BASEVIDWIDTH/2, 182, V_SNAPTOBOTTOM|(ultimatemode ? V_REDMAP : V_YELLOWMAP), endingtext); V_DrawCenteredString(BASEVIDWIDTH/2, 182, V_SNAPTOBOTTOM|(ultimatemode ? V_REDMAP : V_YELLOWMAP), endingtext);
} }
@ -2034,13 +2034,13 @@ void F_TitleScreenDrawer(void)
if (eggSkin != -1) if (eggSkin != -1)
{ {
eggColor = skins[eggSkin].prefcolor; eggColor = skins[eggSkin]->prefcolor;
} }
eggColormap = R_GetTranslationColormap(TC_DEFAULT, eggColor, GTC_MENUCACHE); eggColormap = R_GetTranslationColormap(TC_DEFAULT, eggColor, GTC_MENUCACHE);
if (tailsSkin != -1) if (tailsSkin != -1)
{ {
tailsColor = skins[tailsSkin].prefcolor; tailsColor = skins[tailsSkin]->prefcolor;
} }
tailsColormap = R_GetTranslationColormap(TC_DEFAULT, tailsColor, GTC_MENUCACHE); tailsColormap = R_GetTranslationColormap(TC_DEFAULT, tailsColor, GTC_MENUCACHE);
@ -2391,9 +2391,9 @@ void F_StartWaitingPlayers(void)
if (waitcolormap) if (waitcolormap)
Z_Free(waitcolormap); Z_Free(waitcolormap);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0); waitcolormap = R_GetTranslationColormap(randskin, skins[randskin]->prefcolor, 0);
sprdef = &skins[randskin].sprites[P_GetSkinSprite2(&skins[randskin], SPR2_FSTN, NULL)]; sprdef = &skins[randskin]->sprites[P_GetSkinSprite2(skins[randskin], SPR2_FSTN, NULL)];
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {

View file

@ -899,14 +899,14 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
} }
if (ghost->player && ( if (ghost->player && (
ghostext[playernum].skinid != (UINT8)(((skin_t *)ghost->skin)-skins) || ghostext[playernum].skinid != (UINT8)(((skin_t *)ghost->skin)->skinnum) ||
ghostext[playernum].kartspeed != ghost->player->kartspeed || ghostext[playernum].kartspeed != ghost->player->kartspeed ||
ghostext[playernum].kartweight != ghost->player->kartweight || ghostext[playernum].kartweight != ghost->player->kartweight ||
ghostext[playernum].charflags != ghost->player->charflags ghostext[playernum].charflags != ghost->player->charflags
)) ))
{ {
ghostext[playernum].flags |= EZT_STATDATA; ghostext[playernum].flags |= EZT_STATDATA;
ghostext[playernum].skinid = (UINT8)(((skin_t *)ghost->skin)-skins); ghostext[playernum].skinid = (UINT8)(((skin_t *)ghost->skin)->skinnum);
ghostext[playernum].kartspeed = ghost->player->kartspeed; ghostext[playernum].kartspeed = ghost->player->kartspeed;
ghostext[playernum].kartweight = ghost->player->kartweight; ghostext[playernum].kartweight = ghost->player->kartweight;
ghostext[playernum].charflags = ghost->player->charflags; ghostext[playernum].charflags = ghost->player->charflags;
@ -990,7 +990,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
if (ghost->player->followmobj->colorized) if (ghost->player->followmobj->colorized)
followtic |= FZT_COLORIZED; followtic |= FZT_COLORIZED;
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
WRITEUINT8(demobuf.p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))-skins)); WRITEUINT8(demobuf.p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))->skinnum));
oldghost[playernum].flags2 |= MF2_AMBUSH; oldghost[playernum].flags2 |= MF2_AMBUSH;
} }
@ -1214,13 +1214,13 @@ void G_ConsGhostTic(INT32 playernum)
if (players[playernum].kartspeed != ghostext[playernum].kartspeed if (players[playernum].kartspeed != ghostext[playernum].kartspeed
|| players[playernum].kartweight != ghostext[playernum].kartweight || players[playernum].kartweight != ghostext[playernum].kartweight
|| players[playernum].charflags != ghostext[playernum].charflags || || players[playernum].charflags != ghostext[playernum].charflags ||
demo.skinlist[ghostext[playernum].skinid].mapping != (UINT8)(((skin_t *)testmo->skin)-skins)) demo.skinlist[ghostext[playernum].skinid].mapping != (UINT8)(((skin_t *)testmo->skin)->skinnum))
{ {
if (demosynced) if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (Character/stats)!\n")); CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (Character/stats)!\n"));
demosynced = false; demosynced = false;
testmo->skin = &skins[demo.skinlist[ghostext[playernum].skinid].mapping]; testmo->skin = skins[demo.skinlist[ghostext[playernum].skinid].mapping];
players[playernum].kartspeed = ghostext[playernum].kartspeed; players[playernum].kartspeed = ghostext[playernum].kartspeed;
players[playernum].kartweight = ghostext[playernum].kartweight; players[playernum].kartweight = ghostext[playernum].kartweight;
players[playernum].charflags = ghostext[playernum].charflags; players[playernum].charflags = ghostext[playernum].charflags;
@ -1477,7 +1477,7 @@ fadeghost:
UINT8 skinid = READUINT8(g->p); UINT8 skinid = READUINT8(g->p);
if (skinid >= g->numskins) if (skinid >= g->numskins)
skinid = 0; skinid = 0;
g->mo->skin = &skins[g->skinlist[skinid].mapping]; g->mo->skin = skins[g->skinlist[skinid].mapping];
g->p += 6; // kartspeed, kartweight, charflags g->p += 6; // kartspeed, kartweight, charflags
} }
} }
@ -1512,7 +1512,7 @@ fadeghost:
follow->colorized = true; follow->colorized = true;
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
follow->skin = &skins[READUINT8(g->p)]; follow->skin = skins[READUINT8(g->p)];
} }
if (follow) if (follow)
{ {
@ -1841,12 +1841,12 @@ static void G_SaveDemoSkins(UINT8 **pp, const DemoBufferSizes &psizes)
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
{ {
// Skinname, for first attempt at identification. // Skinname, for first attempt at identification.
(*pp) += copy_fixed_buf((*pp), skins[i].name, psizes.skin_name); (*pp) += copy_fixed_buf((*pp), skins[i]->name, psizes.skin_name);
// Backup information for second pass. // Backup information for second pass.
WRITEUINT8((*pp), skins[i].kartspeed); WRITEUINT8((*pp), skins[i]->kartspeed);
WRITEUINT8((*pp), skins[i].kartweight); WRITEUINT8((*pp), skins[i]->kartweight);
WRITEUINT32((*pp), skins[i].flags); WRITEUINT32((*pp), skins[i]->flags);
} }
for (i = 0; i < MAXAVAILABILITY; i++) for (i = 0; i < MAXAVAILABILITY; i++)
@ -2244,14 +2244,14 @@ void G_SetDemoCheckpointTiming(player_t *player, tic_t time, UINT8 checkpoint)
demoghost *g; demoghost *g;
tic_t lowest = INT32_MAX; tic_t lowest = INT32_MAX;
UINT32 lowestskin = ((skin_t*)player->mo->skin) - skins; UINT32 lowestskin = ((skin_t*)player->mo->skin)->skinnum;
UINT32 lowestcolor = player->skincolor; UINT32 lowestcolor = player->skincolor;
for (g = ghosts; g; g = g->next) for (g = ghosts; g; g = g->next)
{ {
if (lowest > g->splits[checkpoint]) if (lowest > g->splits[checkpoint])
{ {
lowest = g->splits[checkpoint]; lowest = g->splits[checkpoint];
lowestskin = ((skin_t*)g->mo->skin)-skins; lowestskin = ((skin_t*)g->mo->skin)->skinnum;
lowestcolor = g->mo->color; lowestcolor = g->mo->color;
} }
@ -3389,7 +3389,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
UINT8 *p; UINT8 *p;
mapthing_t *mthing; mapthing_t *mthing;
UINT16 count, ghostversion; UINT16 count, ghostversion;
skin_t *ghskin = &skins[0]; skin_t *ghskin = skins[0];
UINT8 worknumskins; UINT8 worknumskins;
UINT32 num_classes; UINT32 num_classes;
democharlist_t *skinlist = NULL; democharlist_t *skinlist = NULL;
@ -3538,7 +3538,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
// Skin // Skin
i = READUINT8(p); i = READUINT8(p);
if (i < worknumskins) if (i < worknumskins)
ghskin = &skins[skinlist[i].mapping]; ghskin = skins[skinlist[i].mapping];
p++; // lastfakeskin p++; // lastfakeskin
p++; // team p++; // team

View file

@ -1821,7 +1821,7 @@ void G_UpdatePlayerPreferences(player_t *const player)
UINT16 new_color = player->prefcolor; UINT16 new_color = player->prefcolor;
if (new_color == SKINCOLOR_NONE) if (new_color == SKINCOLOR_NONE)
{ {
new_color = skins[player->skin].prefcolor; new_color = skins[player->skin]->prefcolor;
} }
if (G_GametypeHasTeams() == true && player->team != TEAM_UNASSIGNED) if (G_GametypeHasTeams() == true && player->team != TEAM_UNASSIGNED)
@ -2343,9 +2343,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
if (betweenmaps) if (betweenmaps)
{ {
fakeskin = MAXSKINS; fakeskin = MAXSKINS;
kartspeed = skins[players[player].skin].kartspeed; kartspeed = skins[players[player].skin]->kartspeed;
kartweight = skins[players[player].skin].kartweight; kartweight = skins[players[player].skin]->kartweight;
charflags = skins[players[player].skin].flags; charflags = skins[players[player].skin]->flags;
for (i = 0; i < LAP__MAX; i++) for (i = 0; i < LAP__MAX; i++)
{ {
@ -2356,7 +2356,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[player]].flags ? demo.skinlist[demo.currentskinid[player]].flags
: skins[players[player].skin].flags; : skins[players[player].skin]->flags;
fakeskin = players[player].fakeskin; fakeskin = players[player].fakeskin;
kartspeed = players[player].kartspeed; kartspeed = players[player].kartspeed;
@ -5401,7 +5401,7 @@ void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ss
} }
SetPlayerSkinByNum(consoleplayer, pickedchar); SetPlayerSkinByNum(consoleplayer, pickedchar);
CV_StealthSet(&cv_skin[0], skins[pickedchar].name); CV_StealthSet(&cv_skin[0], skins[pickedchar]->name);
if (color != SKINCOLOR_NONE) if (color != SKINCOLOR_NONE)
{ {

View file

@ -137,7 +137,7 @@ void srb2::save_ng_gamedata()
for (int i = 0; i < numskins; i++) for (int i = 0; i < numskins; i++)
{ {
skin_t& memskin = skins[i]; skin_t& memskin = *skins[i];
auto skin = skintojson(&memskin.records); auto skin = skintojson(&memskin.records);
srb2::String name { memskin.name }; srb2::String name { memskin.name };
@ -218,7 +218,7 @@ void srb2::save_ng_gamedata()
} }
else if (skinref.id < numskins) else if (skinref.id < numskins)
{ {
newrecords.bestskin = String(skins[skinref.id].name); newrecords.bestskin = String(skins[skinref.id]->name);
} }
newrecords.gotemerald = windata[i].got_emerald; newrecords.gotemerald = windata[i].got_emerald;
@ -554,7 +554,7 @@ void srb2::load_ng_gamedata()
if (skin != -1) if (skin != -1)
{ {
skins[skin].records = dummyrecord; skins[skin]->records = dummyrecord;
} }
else if (dummyrecord.wins) else if (dummyrecord.wins)
{ {

View file

@ -4512,7 +4512,7 @@ static void HWR_DrawSprites(void)
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{ {
if (!cv_glmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) if (!cv_glmodels.value || md2_playermodels[((skin_t*)(spr->mobj->skin))->skinnum].notfound || md2_playermodels[((skin_t*)(spr->mobj->skin))->skinnum].scale < 0.0f)
HWR_DrawSprite(spr); HWR_DrawSprite(spr);
else else
{ {
@ -4725,7 +4725,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (cv_glmodels.value) //Yellow: Only MD2's dont disappear if (cv_glmodels.value) //Yellow: Only MD2's dont disappear
{ {
if (thing->skin && thing->sprite == SPR_PLAY) if (thing->skin && thing->sprite == SPR_PLAY)
md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )]; md2 = &md2_playermodels[((skin_t *)thing->skin)->skinnum];
else else
md2 = &md2_models[thing->sprite]; md2 = &md2_models[thing->sprite];
@ -5077,7 +5077,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
{ {
skinnum = (skin_t*)vis->mobj->skin-skins; skinnum = ((skin_t*)vis->mobj->skin)->skinnum;
} }
// Hide not-yet-unlocked characters in replays from other people // Hide not-yet-unlocked characters in replays from other people

View file

@ -632,7 +632,7 @@ void HWR_AddPlayerModel(INT32 skin) // For skins that were added after startup
if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen)) if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen))
skinname += prefixlen; skinname += prefixlen;
if (stricmp(skinname, skins[skin].name) == 0) if (stricmp(skinname, skins[skin]->name) == 0)
{ {
md2_playermodels[skin].skin = skin; md2_playermodels[skin].skin = skin;
md2_playermodels[skin].scale = scale; md2_playermodels[skin].scale = scale;
@ -1447,10 +1447,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
// 1. load model+texture if not already loaded // 1. load model+texture if not already loaded
// 2. draw model with correct position, rotation,... // 2. draw model with correct position, rotation,...
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && !md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound) // Use the player MD2 list if the mobj has a skin and is using the player sprites if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && !md2_playermodels[((skin_t*)spr->mobj->skin)->skinnum].notfound) // Use the player MD2 list if the mobj has a skin and is using the player sprites
{ {
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2 = &md2_playermodels[((skin_t*)spr->mobj->skin)->skinnum];
md2->skin = (skin_t*)spr->mobj->skin-skins; md2->skin = ((skin_t*)spr->mobj->skin)->skinnum;
} }
else else
{ {
@ -1524,7 +1524,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // This thing is a player! if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // This thing is a player!
{ {
skinnum = (skin_t*)spr->mobj->skin-skins; skinnum = ((skin_t*)spr->mobj->skin)->skinnum;
} }
// Hide not-yet-unlocked characters in replays from other people // Hide not-yet-unlocked characters in replays from other people

View file

@ -133,8 +133,8 @@ void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e st
// For each subsequent round of GP, K_UpdateGrandPrixBots will handle this. // For each subsequent round of GP, K_UpdateGrandPrixBots will handle this.
players[newplayernum].spectator = grandprixinfo.gp && grandprixinfo.initalize && K_BotDefaultSpectator(); players[newplayernum].spectator = grandprixinfo.gp && grandprixinfo.initalize && K_BotDefaultSpectator();
skincolornum_t color = static_cast<skincolornum_t>(skins[skinnum].prefcolor); skincolornum_t color = static_cast<skincolornum_t>(skins[skinnum]->prefcolor);
const char *realname = skins[skinnum].realname; const char *realname = skins[skinnum]->realname;
if (tutorialchallenge == TUTORIALSKIP_INPROGRESS) if (tutorialchallenge == TUTORIALSKIP_INPROGRESS)
{ {
// The ROYGBIV Rangers // The ROYGBIV Rangers

View file

@ -147,7 +147,7 @@ void K_HitlagColormap(UINT8 *dest_colormap)
v = K_HitlagColorValue(color); v = K_HitlagColorValue(color);
// Convert raw brightness value to an offset from the greyscale palette line // Convert raw brightness value to an offset from the greyscale palette line
offset = (255 - v) / 8; offset = (255 - v) / 8;
dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves. dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves.
} }
@ -163,7 +163,7 @@ static void K_IntermissionColormap(UINT8 *dest_colormap)
RGBA_t color; RGBA_t color;
INT32 i; INT32 i;
// for every colour in the palette, check its // for every colour in the palette, check its
for (i = 0; i < NUM_PALETTE_ENTRIES; i++) for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{ {
color = V_GetColor(i); color = V_GetColor(i);
@ -264,7 +264,7 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, skincolornum_t
return; return;
} }
starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum]->starttranscolor : DEFAULT_STARTTRANSCOLOR;
// Fill in the entries of the palette that are fixed // Fill in the entries of the palette that are fixed
for (i = 0; i < starttranscolor; i++) for (i = 0; i < starttranscolor; i++)

View file

@ -188,7 +188,7 @@ void Dialogue::SetSpeaker(srb2::String skinName, int portraitID)
if (skinID >= 0 && skinID < numskins) if (skinID >= 0 && skinID < numskins)
{ {
const skin_t *skin = &skins[skinID]; const skin_t *skin = skins[skinID];
const spritedef_t *sprdef = &skin->sprites[SPR2_TALK]; const spritedef_t *sprdef = &skin->sprites[SPR2_TALK];
if (sprdef->numframes > 0) if (sprdef->numframes > 0)

View file

@ -273,7 +273,7 @@ UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, U
if (playerskin == NULL) if (playerskin == NULL)
{ {
// Nothing from this line down is valid if playerskin is invalid, just guess Eggman? // Nothing from this line down is valid if playerskin is invalid, just guess Eggman?
playerskin = &skins[0]; playerskin = skins[0];
} }
playercolor = playerskin->prefcolor; playercolor = playerskin->prefcolor;
@ -424,7 +424,7 @@ void K_HandleFollower(player_t *player)
if (player->followerskin < 0) // using a fallback follower if (player->followerskin < 0) // using a fallback follower
color = fl->defaultcolor; color = fl->defaultcolor;
else else
color = K_GetEffectiveFollowerColor(player->followercolor, fl, player->skincolor, &skins[player->skin]); color = K_GetEffectiveFollowerColor(player->followercolor, fl, player->skincolor, skins[player->skin]);
if (player->follower == NULL || P_MobjWasRemoved(player->follower)) // follower doesn't exist / isn't valid if (player->follower == NULL || P_MobjWasRemoved(player->follower)) // follower doesn't exist / isn't valid
{ {

View file

@ -307,7 +307,7 @@ void K_InitGrandPrixBots(void)
for (j = 0; j < numplayers; j++) for (j = 0; j < numplayers; j++)
{ {
player_t *p = &players[competitors[j]]; player_t *p = &players[competitors[j]];
const char *rivalname = skins[p->skin].rivals[i]; const char *rivalname = skins[p->skin]->rivals[i];
INT32 rivalnum = R_SkinAvailable(rivalname); INT32 rivalnum = R_SkinAvailable(rivalname);
// Intentionally referenced before (currently dummied out) unlock check. Such a tease! // Intentionally referenced before (currently dummied out) unlock check. Such a tease!
@ -1020,10 +1020,10 @@ void K_RetireBots(void)
bot->botvars.difficulty = newDifficulty; bot->botvars.difficulty = newDifficulty;
bot->botvars.diffincrease = 0; bot->botvars.diffincrease = 0;
K_SetNameForBot(bot - players, skins[skinnum].realname); K_SetNameForBot(bot - players, skins[skinnum]->realname);
bot->prefskin = skinnum; bot->prefskin = skinnum;
bot->prefcolor = skins[skinnum].prefcolor; bot->prefcolor = skins[skinnum]->prefcolor;
bot->preffollower = -1; bot->preffollower = -1;
bot->preffollowercolor = SKINCOLOR_NONE; bot->preffollowercolor = SKINCOLOR_NONE;
G_UpdatePlayerPreferences(bot); G_UpdatePlayerPreferences(bot);

View file

@ -2864,7 +2864,7 @@ void PositionFacesInfo::draw_1p()
skinflags = (demo.playback) skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[rankplayer[i]]].flags ? demo.skinlist[demo.currentskinid[rankplayer[i]]].flags
: skins[players[rankplayer[i]].skin].flags; : skins[players[rankplayer[i]].skin]->flags;
// Flip SF_IRONMAN portraits, but only if they're transformed // Flip SF_IRONMAN portraits, but only if they're transformed
if (skinflags & SF_IRONMAN if (skinflags & SF_IRONMAN
@ -2881,7 +2881,7 @@ void PositionFacesInfo::draw_1p()
if (players[rankplayer[i]].mo->color) if (players[rankplayer[i]].mo->color)
{ {
if ((skin_t*)players[rankplayer[i]].mo->skin) if ((skin_t*)players[rankplayer[i]].mo->skin)
workingskin = (skin_t*)players[rankplayer[i]].mo->skin - skins; workingskin = ((skin_t*)players[rankplayer[i]].mo->skin)->skinnum;
else else
workingskin = players[rankplayer[i]].skin; workingskin = players[rankplayer[i]].skin;
@ -3535,7 +3535,7 @@ static void K_drawKartDuelScores(void)
skinflags = (demo.playback) skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[drawme]].flags ? demo.skinlist[demo.currentskinid[drawme]].flags
: skins[players[drawme].skin].flags; : skins[players[drawme].skin]->flags;
// Flip SF_IRONMAN portraits, but only if they're transformed // Flip SF_IRONMAN portraits, but only if they're transformed
if (skinflags & SF_IRONMAN if (skinflags & SF_IRONMAN
@ -3550,7 +3550,7 @@ static void K_drawKartDuelScores(void)
} }
if ((skin_t*)players[drawme].mo->skin) if ((skin_t*)players[drawme].mo->skin)
workingskin = (skin_t*)players[drawme].mo->skin - skins; workingskin = ((skin_t*)players[drawme].mo->skin)->skinnum;
else else
workingskin = players[drawme].skin; workingskin = players[drawme].skin;
@ -5438,7 +5438,7 @@ playertagtype_t K_WhichPlayerTag(player_t *p)
{ {
if (gametype == GT_TUTORIAL) if (gametype == GT_TUTORIAL)
{ {
return (skins[p->skin].flags & SF_MACHINE) return (skins[p->skin]->flags & SF_MACHINE)
? PLAYERTAG_CPU ? PLAYERTAG_CPU
: PLAYERTAG_TUTORIALFAKELOCAL; : PLAYERTAG_TUTORIALFAKELOCAL;
} }
@ -6061,7 +6061,7 @@ static void K_drawKartMinimap(void)
{ {
if (g->mo && !P_MobjWasRemoved(g->mo) && g->mo->skin) if (g->mo && !P_MobjWasRemoved(g->mo) && g->mo->skin)
{ {
skin = ((skin_t*)g->mo->skin)-skins; skin = ((skin_t*)g->mo->skin)->skinnum;
workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap;
@ -6138,7 +6138,7 @@ static void K_drawKartMinimap(void)
} }
else else
{ {
skin = ((skin_t*)mobj->skin)-skins; skin = ((skin_t*)mobj->skin)->skinnum;
workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap;
@ -6338,7 +6338,7 @@ static void K_drawKartMinimap(void)
} }
else else
{ {
skin = ((skin_t*)mobj->skin)-skins; skin = ((skin_t*)mobj->skin)->skinnum;
workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap;
@ -6374,7 +6374,7 @@ static void K_drawKartMinimap(void)
ang = ANGLE_180 - ang; ang = ANGLE_180 - ang;
if (skin && mobj->color && !mobj->colorized // relevant to redo if (skin && mobj->color && !mobj->colorized // relevant to redo
&& skins[skin].starttranscolor != skins[0].starttranscolor) // redoing would have an affect && skins[skin]->starttranscolor != skins[0]->starttranscolor) // redoing would have an affect
{ {
colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(mobj->color), GTC_CACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
} }

View file

@ -2871,7 +2871,7 @@ static UINT8 K_ObjectToSkinIDForSounds(mobj_t *source)
if (!source->skin) if (!source->skin)
return MAXSKINS; return MAXSKINS;
return ((skin_t *)source->skin)-skins; return ((skin_t *)source->skin)->skinnum;
} }
static void K_PlayGenericTastefulTaunt(mobj_t *source, sfxenum_t sfx_id) static void K_PlayGenericTastefulTaunt(mobj_t *source, sfxenum_t sfx_id)
@ -2958,7 +2958,7 @@ static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sf
{ {
S_StartSound( S_StartSound(
alwaysHear ? NULL : source, alwaysHear ? NULL : source,
skins[skinid].soundsid[S_sfx[sfx_id].skinsound] skins[skinid]->soundsid[S_sfx[sfx_id].skinsound]
); );
} }
@ -4610,7 +4610,7 @@ void K_CheckpointCrossAward(player_t *player)
// Doing this here because duel exit is a weird path, and we don't want to transform for endcam. // Doing this here because duel exit is a weird path, and we don't want to transform for endcam.
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags ? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin].flags; : skins[player->skin]->flags;
if (skinflags & SF_IRONMAN) if (skinflags & SF_IRONMAN)
{ {
SetRandomFakePlayerSkin(player, true, false); SetRandomFakePlayerSkin(player, true, false);
@ -9285,7 +9285,7 @@ void K_KartPlayerHUDUpdate(player_t *player)
if (player->skin >= 0 && player->skin < numskins) if (player->skin >= 0 && player->skin < numskins)
{ {
skin_t *playerskin; skin_t *playerskin;
playerskin = &skins[player->skin]; playerskin = skins[player->skin];
playerskin->records.tumbletime++; playerskin->records.tumbletime++;
} }
} }
@ -9387,7 +9387,7 @@ boolean K_LegacyRingboost(player_t *player)
return false; return false;
if (!modeattacking) if (!modeattacking)
return false; return false;
if (!(skins[player->skin].flags & SF_HIVOLT)) if (!(skins[player->skin]->flags & SF_HIVOLT))
return false; return false;
return true; return true;
} }

View file

@ -359,7 +359,7 @@ UINT16 M_GetCvPlayerColor(UINT8 pnum)
if (skin == -1) if (skin == -1)
return SKINCOLOR_NONE; return SKINCOLOR_NONE;
return skins[skin].prefcolor; return skins[skin]->prefcolor;
} }
static void M_DrawMenuParty(void) static void M_DrawMenuParty(void)
@ -392,7 +392,7 @@ static void M_DrawMenuParty(void)
if (skin == -1) \ if (skin == -1) \
skin = 0; \ skin = 0; \
if (color == SKINCOLOR_NONE) \ if (color == SKINCOLOR_NONE) \
color = skins[skin].prefcolor; \ color = skins[skin]->prefcolor; \
colormap = R_GetTranslationColormap(skin, color, GTC_MENUCACHE); \ colormap = R_GetTranslationColormap(skin, color, GTC_MENUCACHE); \
} }
@ -1611,7 +1611,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
skin = setup_chargrid[p->gridx][p->gridy].skinlist[n]; skin = setup_chargrid[p->gridx][p->gridy].skinlist[n];
patch = faceprefix[skin][FACE_RANK]; patch = faceprefix[skin][FACE_RANK];
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
radius = 24<<FRACBITS; radius = 24<<FRACBITS;
cx -= (SHORT(patch->width) << FRACBITS) >> 1; cx -= (SHORT(patch->width) << FRACBITS) >> 1;
@ -1636,7 +1636,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
n = r = M_GetColorAfter(&p->colors, r, 1); n = r = M_GetColorAfter(&p->colors, r, 1);
} }
colormap = R_GetTranslationColormap(TC_DEFAULT, (n == SKINCOLOR_NONE) ? skins[p->skin].prefcolor : n, GTC_MENUCACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, (n == SKINCOLOR_NONE) ? skins[p->skin]->prefcolor : n, GTC_MENUCACHE);
diff = (numoptions - i) / 2; // only 0 when i == numoptions-1 diff = (numoptions - i) / 2; // only 0 when i == numoptions-1
@ -1735,7 +1735,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
patch = W_CachePatchName(fl->icon, PU_CACHE); patch = W_CachePatchName(fl->icon, PU_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, colormap = R_GetTranslationColormap(TC_DEFAULT,
K_GetEffectiveFollowerColor(fl->defaultcolor, fl, p->color, &skins[p->skin]), K_GetEffectiveFollowerColor(fl->defaultcolor, fl, p->color, skins[p->skin]),
GTC_MENUCACHE GTC_MENUCACHE
); );
} }
@ -1765,7 +1765,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
n = r = M_GetColorAfter(&p->colors, r, 1); n = r = M_GetColorAfter(&p->colors, r, 1);
} }
col = K_GetEffectiveFollowerColor(n, &followers[p->followern], p->color, &skins[p->skin]); col = K_GetEffectiveFollowerColor(n, &followers[p->followern], p->color, skins[p->skin]);
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
@ -1819,8 +1819,8 @@ boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, UINT8 spr2, UINT8 ro
spriteframe_t *sprframe; spriteframe_t *sprframe;
patch_t *sprpatch; patch_t *sprpatch;
spr = P_GetSkinSprite2(&skins[skin], spr2, NULL); spr = P_GetSkinSprite2(skins[skin], spr2, NULL);
sprdef = &skins[skin].sprites[spr]; sprdef = &skins[skin]->sprites[spr];
if (!sprdef->numframes) // No frames ?? if (!sprdef->numframes) // No frames ??
return false; // Can't render! return false; // Can't render!
@ -1835,11 +1835,11 @@ boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, UINT8 spr2, UINT8 ro
addflags ^= V_FLIP; // This sprite is left/right flipped! addflags ^= V_FLIP; // This sprite is left/right flipped!
} }
if (skins[skin].highresscale != FRACUNIT) if (skins[skin]->highresscale != FRACUNIT)
{ {
V_DrawFixedPatch(x<<FRACBITS, V_DrawFixedPatch(x<<FRACBITS,
y<<FRACBITS, y<<FRACBITS,
skins[skin].highresscale, skins[skin]->highresscale,
addflags, sprpatch, colormap); addflags, sprpatch, colormap);
} }
else else
@ -1907,7 +1907,7 @@ static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, boolean charfli
(p->mdepth < CSSTEP_FOLLOWERCOLORS && p->mdepth != CSSTEP_ASKCHANGES) ? fl->defaultcolor : p->followercolor, (p->mdepth < CSSTEP_FOLLOWERCOLORS && p->mdepth != CSSTEP_ASKCHANGES) ? fl->defaultcolor : p->followercolor,
fl, fl,
p->color, p->color,
&skins[p->skin] skins[p->skin]
); );
sine = FixedMul(fl->bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, fl->bobspeed) * p->follower_timer)>>ANGLETOFINESHIFT) & FINEMASK)); sine = FixedMul(fl->bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, fl->bobspeed) * p->follower_timer)>>ANGLETOFINESHIFT) & FINEMASK));
colormap = R_GetTranslationColormap(TC_DEFAULT, color, GTC_MENUCACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, color, GTC_MENUCACHE);
@ -1931,7 +1931,7 @@ static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y, boolean charflip
if (p->mdepth < CSSTEP_COLORS && p->mdepth != CSSTEP_ASKCHANGES) if (p->mdepth < CSSTEP_COLORS && p->mdepth != CSSTEP_ASKCHANGES)
{ {
color = skins[p->skin].prefcolor; color = skins[p->skin]->prefcolor;
} }
else else
{ {
@ -1940,7 +1940,7 @@ static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y, boolean charflip
if (color == SKINCOLOR_NONE) if (color == SKINCOLOR_NONE)
{ {
color = skins[p->skin].prefcolor; color = skins[p->skin]->prefcolor;
} }
colormap = R_GetTranslationColormap(p->skin, color, GTC_MENUCACHE); colormap = R_GetTranslationColormap(p->skin, color, GTC_MENUCACHE);
@ -2124,9 +2124,9 @@ static void M_DrawCharSelectPreview(UINT8 num)
&& setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum] < numskins) && setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum] < numskins)
{ {
V_DrawThinString(x-3, y+12, 0, V_DrawThinString(x-3, y+12, 0,
skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]].name); skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]]->name);
randomskin = (skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]].flags & SF_IRONMAN); randomskin = (skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]]->flags & SF_IRONMAN);
doping = (skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]].flags & SF_HIVOLT); doping = (skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]]->flags & SF_HIVOLT);
} }
else else
{ {
@ -2279,7 +2279,7 @@ static void M_DrawCharSelectCursor(UINT8 num)
{ {
if (p->skin >= 0) if (p->skin >= 0)
{ {
color = skins[p->skin].prefcolor; color = skins[p->skin]->prefcolor;
} }
else else
{ {
@ -2343,7 +2343,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
{ {
if (skinnum >= 0) if (skinnum >= 0)
{ {
truecol = skins[skinnum].prefcolor; truecol = skins[skinnum]->prefcolor;
} }
else else
{ {
@ -2384,7 +2384,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
{ {
if (M_DrawFollowerSprite(x-22 - 16, y+119, 0, false, 0, 0, sp)) if (M_DrawFollowerSprite(x-22 - 16, y+119, 0, false, 0, 0, sp))
{ {
UINT16 col = K_GetEffectiveFollowerColor(sp->followercolor, &followers[sp->followern], sp->color, &skins[sp->skin]); UINT16 col = K_GetEffectiveFollowerColor(sp->followercolor, &followers[sp->followern], sp->color, skins[sp->skin]);
patch_t *ico = W_CachePatchName(followers[sp->followern].icon, PU_CACHE); patch_t *ico = W_CachePatchName(followers[sp->followern].icon, PU_CACHE);
UINT8 *fcolormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); UINT8 *fcolormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
V_DrawMappedPatch(x+14+18, y+66, 0, ico, fcolormap); V_DrawMappedPatch(x+14+18, y+66, 0, ico, fcolormap);
@ -2412,7 +2412,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
p->followercolor, p->followercolor,
&followers[fln], &followers[fln],
p->color, p->color,
&skins[skinnum] skins[skinnum]
); );
UINT8 *fcolormap = R_GetTranslationColormap( UINT8 *fcolormap = R_GetTranslationColormap(
(K_FollowerUsable(fln) ? TC_DEFAULT : TC_BLINK), (K_FollowerUsable(fln) ? TC_DEFAULT : TC_BLINK),
@ -2503,14 +2503,14 @@ void M_DrawCharacterSelect(void)
// Draw the icons now // Draw the icons now
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
{ {
if ((forceskin == true) && (i != skins[cv_forceskin.value].kartspeed-1)) if ((forceskin == true) && (i != skins[cv_forceskin.value]->kartspeed-1))
continue; continue;
for (j = 0; j < 9; j++) for (j = 0; j < 9; j++)
{ {
if (forceskin == true) if (forceskin == true)
{ {
if (j != skins[cv_forceskin.value].kartweight-1) if (j != skins[cv_forceskin.value]->kartweight-1)
continue; continue;
skin = cv_forceskin.value; skin = cv_forceskin.value;
} }
@ -2538,7 +2538,7 @@ void M_DrawCharacterSelect(void)
if (k == setup_numplayers) if (k == setup_numplayers)
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE); colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
else else
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
V_DrawMappedPatch(basex + 82 + (i*16) + quadx, 22 + (j*16) + quady, 0, faceprefix[skin][FACE_RANK], colormap); V_DrawMappedPatch(basex + 82 + (i*16) + quadx, 22 + (j*16) + quady, 0, faceprefix[skin][FACE_RANK], colormap);
@ -3056,7 +3056,7 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi
{ {
UINT8 skin = windata->best_skin.id; UINT8 skin = windata->best_skin.id;
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
charPat = faceprefix[skin][FACE_MINIMAP]; charPat = faceprefix[skin][FACE_MINIMAP];
} }
@ -6901,7 +6901,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
INT32 skin = M_UnlockableSkinNum(ref); INT32 skin = M_UnlockableSkinNum(ref);
if (skin != -1) if (skin != -1)
{ {
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
pat = faceprefix[skin][(ref->majorunlock) ? FACE_WANTED : FACE_RANK]; pat = faceprefix[skin][(ref->majorunlock) ? FACE_WANTED : FACE_RANK];
} }
break; break;
@ -6912,7 +6912,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
if (skin != -1) if (skin != -1)
{ {
INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false); INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false);
UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? &skins[psk] : &skins[0]); UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? skins[psk] : skins[0]);
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
pat = W_CachePatchName(followers[skin].icon, PU_CACHE); pat = W_CachePatchName(followers[skin].icon, PU_CACHE);
} }
@ -7099,7 +7099,7 @@ void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap,
INT32 s, w; INT32 s, w;
if (skins[baseskin].flags & SF_IRONMAN) if (skins[baseskin]->flags & SF_IRONMAN)
{ {
// this is the last thing i will do for rr pre-launhc ~toast 150424 // this is the last thing i will do for rr pre-launhc ~toast 150424
// quoth tyron: "stat block rave holy shit" // quoth tyron: "stat block rave holy shit"
@ -7128,7 +7128,7 @@ void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap,
} }
} }
else if (skins[baseskin].flags & SF_HIVOLT) else if (skins[baseskin]->flags & SF_HIVOLT)
{ {
UINT32 fucktimer = (gamedata->totalmenutime/2)%8; UINT32 fucktimer = (gamedata->totalmenutime/2)%8;
UINT8 sq[] = {0, 1, 2, 2, 2, 1, 0, 0}; UINT8 sq[] = {0, 1, 2, 2, 2, 1, 0, 0};
@ -7140,8 +7140,8 @@ void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap,
{ {
// The following is a partial duplication of R_GetEngineClass // The following is a partial duplication of R_GetEngineClass
s = (skins[skin].kartspeed - 1)/3; s = (skins[skin]->kartspeed - 1)/3;
w = (skins[skin].kartweight - 1)/3; w = (skins[skin]->kartweight - 1)/3;
#define LOCKSTAT(stat) \ #define LOCKSTAT(stat) \
if (stat < 0) { stat = 0; } \ if (stat < 0) { stat = 0; } \
@ -7204,19 +7204,19 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
// Draw our character! // Draw our character!
if (skin != -1) if (skin != -1)
{ {
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
M_DrawCharacterSprite(x, y, skin, SPR2_STIN, 7, 0, 0, colormap); M_DrawCharacterSprite(x, y, skin, SPR2_STIN, 7, 0, 0, colormap);
for (i = 0; i < skin; i++) for (i = 0; i < skin; i++)
{ {
if (!R_SkinUsable(-1, i, false)) if (!R_SkinUsable(-1, i, false))
continue; continue;
if (skins[i].kartspeed != skins[skin].kartspeed) if (skins[i]->kartspeed != skins[skin]->kartspeed)
continue; continue;
if (skins[i].kartweight != skins[skin].kartweight) if (skins[i]->kartweight != skins[skin]->kartweight)
continue; continue;
colormap = R_GetTranslationColormap(i, skins[i].prefcolor, GTC_MENUCACHE); colormap = R_GetTranslationColormap(i, skins[i]->prefcolor, GTC_MENUCACHE);
break; break;
} }
@ -7238,7 +7238,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
// Draw follower next to them // Draw follower next to them
if (fskin != -1) if (fskin != -1)
{ {
UINT16 col = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, &skins[skin]); UINT16 col = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, skins[skin]);
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
M_DrawFollowerSprite(x - 16, y, fskin, false, 0, colormap, NULL); M_DrawFollowerSprite(x - 16, y, fskin, false, 0, colormap, NULL);
@ -8663,14 +8663,14 @@ static void M_DrawStatsChars(void)
} }
{ {
UINT8 *colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); UINT8 *colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
M_DrawCharacterIconAndEngine(24, y, skin, colormap, skin); M_DrawCharacterIconAndEngine(24, y, skin, colormap, skin);
} }
V_DrawThinString(24+32+2, y+3, 0, skins[skin].realname); V_DrawThinString(24+32+2, y+3, 0, skins[skin]->realname);
V_DrawRightAlignedThinString(BASEVIDWIDTH/2 + 30, y+3, 0, va("%d/%d", skins[skin].records.wins, skins[skin].records.rounds)); V_DrawRightAlignedThinString(BASEVIDWIDTH/2 + 30, y+3, 0, va("%d/%d", skins[skin]->records.wins, skins[skin]->records.rounds));
y += STATSSTEP; y += STATSSTEP;
@ -9025,7 +9025,7 @@ static void M_DrawWrongPlayer(UINT8 i)
if (wrongpl.skin >= numskins) if (wrongpl.skin >= numskins)
return; return;
UINT8 *colormap = R_GetTranslationColormap(wrongpl.skin, skins[wrongpl.skin].prefcolor, GTC_MENUCACHE); UINT8 *colormap = R_GetTranslationColormap(wrongpl.skin, skins[wrongpl.skin]->prefcolor, GTC_MENUCACHE);
M_DrawCharacterSprite( M_DrawCharacterSprite(
wrongpl.across, wrongpl.across,

View file

@ -294,11 +294,11 @@ void podiumData_s::Init(void)
// but not this close to release // but not this close to release
if (rank.position > RANK_NEUTRAL_POSITION || grade < GRADE_C) if (rank.position > RANK_NEUTRAL_POSITION || grade < GRADE_C)
{ {
gradeVoice = skins[rank.skin].soundsid[S_sfx[sfx_klose].skinsound]; gradeVoice = skins[rank.skin]->soundsid[S_sfx[sfx_klose].skinsound];
} }
else else
{ {
gradeVoice = skins[rank.skin].soundsid[S_sfx[sfx_kwin].skinsound]; gradeVoice = skins[rank.skin]->soundsid[S_sfx[sfx_kwin].skinsound];
} }
} }

View file

@ -429,7 +429,7 @@ void level_tally_t::Init(player_t *player)
{ {
snprintf( snprintf(
header, sizeof header, header, sizeof header,
"%s", R_CanShowSkinInDemo(player->skin) ? skins[player->skin].realname : "???" "%s", R_CanShowSkinInDemo(player->skin) ? skins[player->skin]->realname : "???"
); );
} }
@ -527,11 +527,11 @@ void level_tally_t::Init(player_t *player)
; ;
else if (rank < GRADE_C) else if (rank < GRADE_C)
{ {
gradeVoice = skins[skinid].soundsid[S_sfx[sfx_klose].skinsound]; gradeVoice = skins[skinid]->soundsid[S_sfx[sfx_klose].skinsound];
} }
else else
{ {
gradeVoice = skins[skinid].soundsid[S_sfx[sfx_kwin].skinsound]; gradeVoice = skins[skinid]->soundsid[S_sfx[sfx_kwin].skinsound];
} }
} }

View file

@ -431,9 +431,9 @@ static int libd_getSprite2Patch(lua_State *L)
if (super) if (super)
j |= FF_SPR2SUPER; j |= FF_SPR2SUPER;
j = P_GetSkinSprite2(&skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary j = P_GetSkinSprite2(skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary
sprdef = &skins[i].sprites[j]; sprdef = &skins[i]->sprites[j];
// set frame number // set frame number
frame = luaL_optinteger(L, 2, 0); frame = luaL_optinteger(L, 2, 0);
@ -461,7 +461,7 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle); INT32 rot = R_GetRollAngle(rollangle);
if (rot) { if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), true, &skins[i].sprinfo[j], rot); patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), true, &skins[i]->sprinfo[j], rot);
LUA_PushUserdata(L, rotsprite, META_PATCH); LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false); lua_pushboolean(L, false);
lua_pushboolean(L, true); lua_pushboolean(L, true);
@ -604,7 +604,7 @@ static int libd_drawOnMinimap(lua_State *L)
if (!lua_isnoneornil(L, 5)) if (!lua_isnoneornil(L, 5))
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP)); colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
centered = lua_optboolean(L, 6); centered = lua_optboolean(L, 6);
// Draw the HUD only when playing in a level. // Draw the HUD only when playing in a level.
// hu_stuff needs this, unlike st_stuff. // hu_stuff needs this, unlike st_stuff.
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
@ -612,17 +612,17 @@ static int libd_drawOnMinimap(lua_State *L)
if (R_GetViewNumber() != 0) if (R_GetViewNumber() != 0)
return 0; return 0;
AutomapPic = minimapinfo.minimap_pic; AutomapPic = minimapinfo.minimap_pic;
if (!AutomapPic) if (!AutomapPic)
{ {
return 0; // no pic, just get outta here return 0; // no pic, just get outta here
} }
// Handle offsets and stuff. // Handle offsets and stuff.
mm_x = MINI_X; mm_x = MINI_X;
mm_y = MINI_Y - SHORT(AutomapPic->topoffset); mm_y = MINI_Y - SHORT(AutomapPic->topoffset);
if (encoremode) if (encoremode)
{ {
mm_x += SHORT(AutomapPic->leftoffset); mm_x += SHORT(AutomapPic->leftoffset);

View file

@ -725,7 +725,7 @@ static int mobj_set(lua_State *L)
{ {
if (demo.playback) if (demo.playback)
skin = demo.skinlist[skin].mapping; skin = demo.skinlist[skin].mapping;
mo->skin = &skins[skin]; mo->skin = skins[skin];
} }
return 0; return 0;

View file

@ -93,7 +93,7 @@ static int skin_get(lua_State *L)
case skin_kartweight: case skin_kartweight:
lua_pushinteger(L, skin->kartweight); lua_pushinteger(L, skin->kartweight);
break; break;
// //
case skin_followitem: case skin_followitem:
lua_pushinteger(L, skin->followitem); lua_pushinteger(L, skin->followitem);
break; break;
@ -137,7 +137,7 @@ static int skin_num(lua_State *L)
// skins are always valid, only added, never removed // skins are always valid, only added, never removed
I_Assert(skin != NULL); I_Assert(skin != NULL);
lua_pushinteger(L, skin-skins); lua_pushinteger(L, skin->skinnum);
return 1; return 1;
} }
@ -156,14 +156,14 @@ static int lib_iterateSkins(lua_State *L)
lua_remove(L, 1); // state is unused. lua_remove(L, 1); // state is unused.
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
i = (INT32)(*((skin_t **)luaL_checkudata(L, 1, META_SKIN)) - skins) + 1; i = (INT32)((*((skin_t **)luaL_checkudata(L, 1, META_SKIN)))->skinnum) + 1;
else else
i = 0; i = 0;
// skins are always valid, only added, never removed // skins are always valid, only added, never removed
if (i < numskins) if (i < numskins)
{ {
LUA_PushUserdata(L, &skins[i], META_SKIN); LUA_PushUserdata(L, skins[i], META_SKIN);
return 1; return 1;
} }
@ -183,7 +183,7 @@ static int lib_getSkin(lua_State *L)
return luaL_error(L, "skins[] index %d out of range (0 - %d)", i, MAXSKINS-1); return luaL_error(L, "skins[] index %d out of range (0 - %d)", i, MAXSKINS-1);
if (i >= numskins) if (i >= numskins)
return 0; return 0;
LUA_PushUserdata(L, &skins[i], META_SKIN); LUA_PushUserdata(L, skins[i], META_SKIN);
return 1; return 1;
} }
@ -200,7 +200,7 @@ static int lib_getSkin(lua_State *L)
i = R_SkinAvailableEx(field, false); i = R_SkinAvailableEx(field, false);
if (i != -1) if (i != -1)
{ {
LUA_PushUserdata(L, &skins[i], META_SKIN); LUA_PushUserdata(L, skins[i], META_SKIN);
return 1; return 1;
} }

View file

@ -670,7 +670,7 @@ void M_ClearStats(void)
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
{ {
memset(&skins[i].records, 0, sizeof(skins[i].records)); memset(&skins[i]->records, 0, sizeof(skins[i]->records));
} }
unloaded_skin_t *unloadedskin, *nextunloadedskin = NULL; unloaded_skin_t *unloadedskin, *nextunloadedskin = NULL;
@ -1596,7 +1596,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
if (cn->requirement < 0) if (cn->requirement < 0)
return false; return false;
return (skins[cn->requirement].records.wins >= (UINT32)cn->extrainfo1); return (skins[cn->requirement]->records.wins >= (UINT32)cn->extrainfo1);
case UC_ALLCUPRECORDS: case UC_ALLCUPRECORDS:
{ {
@ -1810,9 +1810,9 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
return (player->roundconditions.switched_skin == false return (player->roundconditions.switched_skin == false
&& player->skin < numskins && player->skin < numskins
&& R_GetEngineClass( && R_GetEngineClass(
skins[player->skin].kartspeed, skins[player->skin]->kartspeed,
skins[player->skin].kartweight, skins[player->skin]->kartweight,
skins[player->skin].flags skins[player->skin]->flags
) == (unsigned)cn->requirement); ) == (unsigned)cn->requirement);
case UCRP_HASFOLLOWER: case UCRP_HASFOLLOWER:
return (cn->requirement != -1 && player->followerskin == cn->requirement); return (cn->requirement != -1 && player->followerskin == cn->requirement);
@ -2234,7 +2234,7 @@ static const char *M_GetConditionCharacter(INT32 skin, boolean directlyrequires)
for (j = 0; j < SKINRIVALS; j++) for (j = 0; j < SKINRIVALS; j++)
{ {
const char *rivalname = skins[i].rivals[j]; const char *rivalname = skins[i]->rivals[j];
INT32 rivalnum = R_SkinAvailableEx(rivalname, false); INT32 rivalnum = R_SkinAvailableEx(rivalname, false);
if (rivalnum != skin) if (rivalnum != skin)
@ -2257,7 +2257,7 @@ static const char *M_GetConditionCharacter(INT32 skin, boolean directlyrequires)
} }
return (permitname) return (permitname)
? skins[skin].realname ? skins[skin]->realname
: "???"; : "???";
} }
@ -2396,7 +2396,7 @@ static const char *M_GetConditionString(condition_t *cn)
case UC_CHARACTERWINS: case UC_CHARACTERWINS:
{ {
if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) if (cn->requirement < 0 || !skins[cn->requirement]->realname[0])
return va("INVALID CHAR CONDITION \"%d:%d:%d\"", cn->type, cn->requirement, cn->extrainfo1); return va("INVALID CHAR CONDITION \"%d:%d:%d\"", cn->type, cn->requirement, cn->extrainfo1);
work = M_GetConditionCharacter(cn->requirement, true); work = M_GetConditionCharacter(cn->requirement, true);
return va("win %d Round%s as %s", return va("win %d Round%s as %s",
@ -2721,7 +2721,7 @@ static const char *M_GetConditionString(condition_t *cn)
Z_Free(title); Z_Free(title);
return work; return work;
case UCRP_ISCHARACTER: case UCRP_ISCHARACTER:
if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) if (cn->requirement < 0 || !skins[cn->requirement]->realname[0])
return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement); return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement);
work = M_GetConditionCharacter(cn->requirement, true); work = M_GetConditionCharacter(cn->requirement, true);
return va("as %s", work); return va("as %s", work);
@ -2854,7 +2854,7 @@ static const char *M_GetConditionString(condition_t *cn)
case UCRP_MAKERETIRE: case UCRP_MAKERETIRE:
{ {
if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) if (cn->requirement < 0 || !skins[cn->requirement]->realname[0])
return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement); return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement);
work = M_GetConditionCharacter(cn->requirement, false); work = M_GetConditionCharacter(cn->requirement, false);

View file

@ -752,7 +752,7 @@ void M_ChallengesTick(void)
INT32 skin = M_UnlockableSkinNum(ref); INT32 skin = M_UnlockableSkinNum(ref);
if (skin != -1) if (skin != -1)
{ {
bombcolor = skins[skin].prefcolor; bombcolor = skins[skin]->prefcolor;
} }
break; break;
} }
@ -764,7 +764,7 @@ void M_ChallengesTick(void)
INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false); INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false);
if (psk == -1) if (psk == -1)
psk = 0; psk = 0;
bombcolor = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, &skins[psk]); bombcolor = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, skins[psk]);
} }
break; break;
} }

View file

@ -133,16 +133,16 @@ static void M_StatisticsChars(void)
statisticsmenu.maplist[statisticsmenu.nummaps++] = i; statisticsmenu.maplist[statisticsmenu.nummaps++] = i;
if (skins[i].records.wins == 0) if (skins[i]->records.wins == 0)
continue; continue;
// The following is a partial duplication of R_GetEngineClass // The following is a partial duplication of R_GetEngineClass
{ {
if (skins[i].flags & SF_IRONMAN) if (skins[i]->flags & SF_IRONMAN)
continue; // does not add to any engine class continue; // does not add to any engine class
INT32 s = (skins[i].kartspeed - 1); INT32 s = (skins[i]->kartspeed - 1);
INT32 w = (skins[i].kartweight - 1); INT32 w = (skins[i]->kartweight - 1);
#define LOCKSTAT(stat) \ #define LOCKSTAT(stat) \
if (stat < 0) { continue; } \ if (stat < 0) { continue; } \
@ -152,12 +152,12 @@ static void M_StatisticsChars(void)
#undef LOCKSTAT #undef LOCKSTAT
if ( if (
statisticsmenu.statgridplayed[s][w] > skins[i].records.wins statisticsmenu.statgridplayed[s][w] > skins[i]->records.wins
&& (UINT32_MAX - statisticsmenu.statgridplayed[s][w]) < skins[i].records.wins && (UINT32_MAX - statisticsmenu.statgridplayed[s][w]) < skins[i]->records.wins
) )
continue; // overflow protection continue; // overflow protection
statisticsmenu.statgridplayed[s][w] += skins[i].records.wins; statisticsmenu.statgridplayed[s][w] += skins[i]->records.wins;
if (beststat >= statisticsmenu.statgridplayed[s][w]) if (beststat >= statisticsmenu.statgridplayed[s][w])
continue; continue;
@ -172,9 +172,9 @@ static void M_StatisticsChars(void)
statisticsmenu.maplist, statisticsmenu.maplist,
statisticsmenu.maplist + statisticsmenu.nummaps, statisticsmenu.maplist + statisticsmenu.nummaps,
[](UINT16 a, UINT16 b) { [](UINT16 a, UINT16 b) {
if (skins[a].records.rounds > skins[b].records.rounds) if (skins[a]->records.rounds > skins[b]->records.rounds)
return true; return true;
if (skins[a].records.rounds != skins[b].records.rounds) if (skins[a]->records.rounds != skins[b]->records.rounds)
return false; return false;
// Stable for skin ID // Stable for skin ID
return (a < b); return (a < b);

View file

@ -255,7 +255,7 @@ public:
return sfx_ktalk; return sfx_ktalk;
return skins[ skinID ] return skins[ skinID ]
.soundsid[ S_sfx[sfx_ktalk].skinsound ]; ->soundsid[ S_sfx[sfx_ktalk].skinsound ];
}; };
int GetSkinID(void) int GetSkinID(void)
@ -1319,7 +1319,7 @@ static void M_GonerDrawer(void)
{ {
line = line line = line
.xy(-16, -2) .xy(-16, -2)
.colormap(skinID, static_cast<skincolornum_t>(skins[skinID].prefcolor)); .colormap(skinID, static_cast<skincolornum_t>(skins[skinID]->prefcolor));
if (gamedata->gonerlevel > GDGONER_VIDEO) if (gamedata->gonerlevel > GDGONER_VIDEO)
line.patch(faceprefix[skinID][FACE_MINIMAP]); line.patch(faceprefix[skinID][FACE_MINIMAP]);
else else

View file

@ -235,12 +235,12 @@ static void M_SetupProfileGridPos(setup_player_t *p)
if (!R_SkinUsable(g_localplayers[0], i, false)) if (!R_SkinUsable(g_localplayers[0], i, false))
{ {
i = GetSkinNumClosestToStats(skins[i].kartspeed, skins[i].kartweight, skins[i].flags, false); i = GetSkinNumClosestToStats(skins[i]->kartspeed, skins[i]->kartweight, skins[i]->flags, false);
} }
// Now position the grid for skin // Now position the grid for skin
p->gridx = skins[i].kartspeed-1; p->gridx = skins[i]->kartspeed-1;
p->gridy = skins[i].kartweight-1; p->gridy = skins[i]->kartweight-1;
// Now this put our cursor on the good alt // Now this put our cursor on the good alt
while (alt < setup_chargrid[p->gridx][p->gridy].numskins && setup_chargrid[p->gridx][p->gridy].skinlist[alt] != i) while (alt < setup_chargrid[p->gridx][p->gridy].numskins && setup_chargrid[p->gridx][p->gridy].skinlist[alt] != i)
@ -253,7 +253,7 @@ static void M_SetupProfileGridPos(setup_player_t *p)
{ {
p->color = SKINCOLOR_NONE; p->color = SKINCOLOR_NONE;
} }
} }
static void M_SetupMidGameGridPos(setup_player_t *p, UINT8 num) static void M_SetupMidGameGridPos(setup_player_t *p, UINT8 num)
@ -273,8 +273,8 @@ static void M_SetupMidGameGridPos(setup_player_t *p, UINT8 num)
p->followern = -1; p->followern = -1;
// Now position the grid for skin // Now position the grid for skin
p->gridx = skins[i].kartspeed-1; p->gridx = skins[i]->kartspeed-1;
p->gridy = skins[i].kartweight-1; p->gridy = skins[i]->kartweight-1;
// Now this put our cursor on the good alt // Now this put our cursor on the good alt
while (alt < setup_chargrid[p->gridx][p->gridy].numskins && setup_chargrid[p->gridx][p->gridy].skinlist[alt] != i) while (alt < setup_chargrid[p->gridx][p->gridy].numskins && setup_chargrid[p->gridx][p->gridy].skinlist[alt] != i)
@ -347,8 +347,8 @@ void M_CharacterSelectInit(void)
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
{ {
UINT8 x = skins[i].kartspeed-1; UINT8 x = skins[i]->kartspeed-1;
UINT8 y = skins[i].kartweight-1; UINT8 y = skins[i]->kartweight-1;
if (!R_SkinUsable(g_localplayers[0], i, false)) if (!R_SkinUsable(g_localplayers[0], i, false))
continue; continue;
@ -792,7 +792,7 @@ static void M_HandleBeginningFollowers(setup_player_t *p)
static void M_HandleBeginningColorsOrFollowers(setup_player_t *p) static void M_HandleBeginningColorsOrFollowers(setup_player_t *p)
{ {
if (p->skin != -1) if (p->skin != -1)
S_StartSound(NULL, skins[p->skin].soundsid[S_sfx[sfx_kattk1].skinsound]); S_StartSound(NULL, skins[p->skin]->soundsid[S_sfx[sfx_kattk1].skinsound]);
if (M_HandleBeginningColors(p)) if (M_HandleBeginningColors(p))
S_StartSound(NULL, sfx_s3k63); S_StartSound(NULL, sfx_s3k63);
else else
@ -865,8 +865,8 @@ static boolean M_HandleCharacterGrid(setup_player_t *p, UINT8 num)
{ {
if (forceskin) if (forceskin)
{ {
if ((p->gridx != skins[cv_forceskin.value].kartspeed-1) if ((p->gridx != skins[cv_forceskin.value]->kartspeed-1)
|| (p->gridy != skins[cv_forceskin.value].kartweight-1)) || (p->gridy != skins[cv_forceskin.value]->kartweight-1))
{ {
S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2 S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2
} }
@ -1346,8 +1346,8 @@ boolean M_CharacterSelectHandler(INT32 choice)
// Just makes it easier to access later // Just makes it easier to access later
if (forceskin) if (forceskin)
{ {
if (p->gridx != skins[cv_forceskin.value].kartspeed-1 if (p->gridx != skins[cv_forceskin.value]->kartspeed-1
|| p->gridy != skins[cv_forceskin.value].kartweight-1) || p->gridy != skins[cv_forceskin.value]->kartweight-1)
p->skin = -1; p->skin = -1;
else else
p->skin = cv_forceskin.value; p->skin = cv_forceskin.value;
@ -1400,7 +1400,7 @@ static void M_MPConfirmCharacterSelection(void)
// finally, call the skin[x] console command. // finally, call the skin[x] console command.
// This will call SendNameAndColor which will synch everything we sent here and apply the changes! // This will call SendNameAndColor which will synch everything we sent here and apply the changes!
CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name); CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin]->name);
// ...actually, let's do this last - Skin_OnChange has some return-early occasions // ...actually, let's do this last - Skin_OnChange has some return-early occasions
// follower color // follower color
@ -1454,7 +1454,7 @@ void M_CharacterSelectTick(void)
if (optionsmenu.profile) if (optionsmenu.profile)
{ {
// save player // save player
strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin].name); strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin]->name);
optionsmenu.profile->color = setup_player[0].color; optionsmenu.profile->color = setup_player[0].color;
// save follower // save follower
@ -1472,7 +1472,7 @@ void M_CharacterSelectTick(void)
{ {
for (i = 0; i < setup_numplayers; i++) for (i = 0; i < setup_numplayers; i++)
{ {
CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name); CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin]->name);
CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color); CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color);
if (setup_player[i].followern < 0) if (setup_player[i].followern < 0)

View file

@ -100,7 +100,7 @@ static void M_StartCup(UINT8 entry)
// finally, call the skin[x] console command. // finally, call the skin[x] console command.
// This will call SendNameAndColor which will synch everything we sent here and apply the changes! // This will call SendNameAndColor which will synch everything we sent here and apply the changes!
CV_StealthSet(&cv_skin[0], skins[savedata.skin].name); CV_StealthSet(&cv_skin[0], skins[savedata.skin]->name);
// ...actually, let's do this last - Skin_OnChange has some return-early occasions // ...actually, let's do this last - Skin_OnChange has some return-early occasions
// follower color // follower color

View file

@ -688,7 +688,7 @@ void M_LevelSelectInit(INT32 choice)
if (levellist.levelsearch.timeattack && gt == GT_RACE) if (levellist.levelsearch.timeattack && gt == GT_RACE)
{ {
const INT32 skinid = R_SkinAvailableEx(cv_skin[0].string, false); const INT32 skinid = R_SkinAvailableEx(cv_skin[0].string, false);
if (skinid >= 0 && (skins[skinid].flags & SF_HIVOLT)) if (skinid >= 0 && (skins[skinid]->flags & SF_HIVOLT))
{ {
M_StartMessage("A long-forgotten power...", "You are using a \x82prototype engine\x80.\nRecords will not be saved.", NULL, MM_NOTHING, NULL, NULL); M_StartMessage("A long-forgotten power...", "You are using a \x82prototype engine\x80.\nRecords will not be saved.", NULL, MM_NOTHING, NULL, NULL);
S_StartSound(NULL, sfx_s3k81); S_StartSound(NULL, sfx_s3k81);

View file

@ -317,11 +317,11 @@ struct Kart : Mobj
Mobj* p = player(); Mobj* p = player();
bool pValid = Mobj::valid(p) && p->player; bool pValid = Mobj::valid(p) && p->player;
bool hasCustomHusk = pValid && skins[p->player->skin].sprites[SPR2_DKRT].numframes; bool hasCustomHusk = pValid && skins[p->player->skin]->sprites[SPR2_DKRT].numframes;
if(hasCustomHusk) if(hasCustomHusk)
{ {
skin = (void*)(&skins[p->player->skin]); skin = (void*)(skins[p->player->skin]);
frame = 0; frame = 0;
} }
@ -347,7 +347,7 @@ struct Kart : Mobj
if(pValid) if(pValid)
{ {
if((skins[p->player->skin].flags & SF_BADNIK)) if((skins[p->player->skin]->flags & SF_BADNIK))
{ {
P_SpawnBadnikExplosion(p); P_SpawnBadnikExplosion(p);
p->spritescale({2*FRACUNIT, 2*FRACUNIT}); p->spritescale({2*FRACUNIT, 2*FRACUNIT});

View file

@ -234,7 +234,7 @@ static void RingShooterCountdown(mobj_t *mo)
if (playeringame[rs_base_playerface(mo)] == true) if (playeringame[rs_base_playerface(mo)] == true)
{ {
player_t *player = &players[ rs_base_playerid(mo) ]; player_t *player = &players[ rs_base_playerid(mo) ];
part->skin = &skins[player->skin]; part->skin = skins[player->skin];
} }
} }
@ -780,9 +780,9 @@ void Obj_UpdateRingShooterFace(mobj_t *part)
// it's a good idea to set the actor's skin *before* it uses this action, // it's a good idea to set the actor's skin *before* it uses this action,
// but just in case, if it doesn't have the player's skin, set its skin then call the state again to get the correct sprite // but just in case, if it doesn't have the player's skin, set its skin then call the state again to get the correct sprite
if (part->skin != &skins[player->skin]) if (part->skin != skins[player->skin])
{ {
part->skin = &skins[player->skin]; part->skin = skins[player->skin];
P_SetMobjState(part, (statenum_t)(part->state - states)); P_SetMobjState(part, (statenum_t)(part->state - states));
return; return;
} }

View file

@ -968,7 +968,7 @@ boolean Obj_SpecialUFODamage(mobj_t *ufo, mobj_t *inflictor, mobj_t *source, UIN
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(source->player-players)]].flags ? demo.skinlist[demo.currentskinid[(source->player-players)]].flags
: skins[source->player->skin].flags; : skins[source->player->skin]->flags;
if (skinflags & SF_IRONMAN) if (skinflags & SF_IRONMAN)
SetRandomFakePlayerSkin(source->player, true, false); SetRandomFakePlayerSkin(source->player, true, false);
} }

View file

@ -702,7 +702,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->flags |= MF_NOGRAVITY; toucher->flags |= MF_NOGRAVITY;
toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher); toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher);
toucher->player->carry = CR_TRAPBUBBLE; toucher->player->carry = CR_TRAPBUBBLE;
P_SetTarget(&toucher->tracer, special); //use tracer to acces the object P_SetTarget(&toucher->tracer, special); //use tracer to acces the object
// Snap to the unfortunate player and quit moving laterally, or we can end up quite far away // Snap to the unfortunate player and quit moving laterally, or we can end up quite far away
special->momx = 0; special->momx = 0;
@ -2675,6 +2675,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
{ {
if (gametyperules & (GTR_BUMPERS|GTR_CHECKPOINTS)) if (gametyperules & (GTR_BUMPERS|GTR_CHECKPOINTS))
player->mo->health--; player->mo->health--;
} }
if (modeattacking & ATTACKING_SPB) if (modeattacking & ATTACKING_SPB)
@ -2708,11 +2709,11 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags ? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin].flags; : skins[player->skin]->flags;
if (skinflags & SF_IRONMAN) if (skinflags & SF_IRONMAN)
{ {
player->mo->skin = &skins[player->skin]; player->mo->skin = skins[player->skin];
player->charflags = skinflags; player->charflags = skinflags;
K_SpawnMagicianParticles(player->mo, 5); K_SpawnMagicianParticles(player->mo, 5);
S_StartSound(player->mo, sfx_slip); S_StartSound(player->mo, sfx_slip);
@ -3106,7 +3107,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
sfx = sfx_s3k3a; sfx = sfx_s3k3a;
clash = true; clash = true;
} }
else if (player->overshield && else if (player->overshield &&
(type != DMG_EXPLODE || inflictor->type != MT_SPBEXPLOSION || !inflictor->movefactor)) (type != DMG_EXPLODE || inflictor->type != MT_SPBEXPLOSION || !inflictor->movefactor))
{ {
clash = true; clash = true;
@ -3386,7 +3387,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
UINT32 hurtskinflags = (demo.playback) UINT32 hurtskinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags ? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin].flags; : skins[player->skin]->flags;
if (hurtskinflags & SF_IRONMAN) if (hurtskinflags & SF_IRONMAN)
{ {
if (gametyperules & GTR_BUMPERS) if (gametyperules & GTR_BUMPERS)
@ -3401,11 +3402,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags ? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin].flags; : skins[player->skin]->flags;
if (skinflags & SF_IRONMAN) if (skinflags & SF_IRONMAN)
{ {
player->mo->skin = &skins[player->skin]; player->mo->skin = skins[player->skin];
player->charflags = skinflags; player->charflags = skinflags;
K_SpawnMagicianParticles(player->mo, 5); K_SpawnMagicianParticles(player->mo, 5);
} }

View file

@ -7990,7 +7990,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_MoveOrigin(mobj, P_MoveOrigin(mobj,
target->x - FixedMul(xofs, sin) + FixedMul(frontoffset, cos), target->x - FixedMul(xofs, sin) + FixedMul(frontoffset, cos),
target->y + FixedMul(xofs, cos) + FixedMul(frontoffset, sin), target->y + FixedMul(xofs, cos) + FixedMul(frontoffset, sin),
target->z + zofs + (target->height / 2)); target->z + zofs + (target->height / 2));
mobj->angle = facing + ANGLE_90 + (mobj->extravalue1 ? ANGLE_45 : -1*ANGLE_45); mobj->angle = facing + ANGLE_90 + (mobj->extravalue1 ? ANGLE_45 : -1*ANGLE_45);
K_MatchGenericExtraFlags(mobj, target); K_MatchGenericExtraFlags(mobj, target);
@ -8028,7 +8028,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (!mobj->target || !mobj->target->health if (!mobj->target || !mobj->target->health
|| !mobj->target->player || !mobj->target->player->tripwireLeniency) || !mobj->target->player || !mobj->target->player->tripwireLeniency)
{ {
if (mobj->target && mobj->target->player if (mobj->target && mobj->target->player
&& P_IsDisplayPlayer(mobj->target->player) && P_IsDisplayPlayer(mobj->target->player)
&& !(mobj->target->player->curshield == KSHIELD_TOP)) && !(mobj->target->player->curshield == KSHIELD_TOP))
{ {
@ -8332,7 +8332,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (vfx) if (vfx)
{ {
if (P_IsObjectOnGround(mobj->target) || mobj->target->player->fastfall if (P_IsObjectOnGround(mobj->target) || mobj->target->player->fastfall
|| !K_CanSuperTransfer(mobj->target->player)) || !K_CanSuperTransfer(mobj->target->player))
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
@ -8790,6 +8790,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_InstaScale(mobj, mobj->target->scale); P_InstaScale(mobj, mobj->target->scale);
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2);
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
break; break;
} }
case MT_BUBBLESHIELD: case MT_BUBBLESHIELD:
@ -9368,7 +9369,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
UINT8 pnum = (newplayer-players); UINT8 pnum = (newplayer-players);
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[pnum]].flags ? demo.skinlist[demo.currentskinid[pnum]].flags
: skins[newplayer->skin].flags; : skins[newplayer->skin]->flags;
if (skinflags & SF_IRONMAN) if (skinflags & SF_IRONMAN)
{ {
@ -9419,7 +9420,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (newplayer != NULL) if (newplayer != NULL)
{ {
cur->skin = &skins[newplayer->skin]; cur->skin = skins[newplayer->skin];
cur->color = newplayer->skincolor; cur->color = newplayer->skincolor;
// Even if we didn't have the Perfect Sign to consider, // Even if we didn't have the Perfect Sign to consider,
@ -9427,7 +9428,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_SetMobjState(cur, (newperfect == true) ? S_KART_SIGL : S_KART_SIGN); P_SetMobjState(cur, (newperfect == true) ? S_KART_SIGL : S_KART_SIGN);
if (cv_shittysigns.value && cur->state != &states[S_KART_SIGL]) if (cv_shittysigns.value && cur->state != &states[S_KART_SIGL])
cur->sprite2 = P_GetSkinSprite2(&skins[newplayer->skin], SPR2_SSIG, NULL);; cur->sprite2 = P_GetSkinSprite2(skins[newplayer->skin], SPR2_SSIG, NULL);;
} }
} }
else if (cur->state == &states[S_SIGN_ERROR]) else if (cur->state == &states[S_SIGN_ERROR])
@ -9838,7 +9839,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
// Mash speed limit // Mash speed limit
UINT8 MASHPWR = TICRATE/2; // Amount to deduct from timer when mashing UINT8 MASHPWR = TICRATE/2; // Amount to deduct from timer when mashing
UINT8 MAXMASHFREQUENCY = 6; // Nerf fast mashing: allow optimal decay with X inputs per second UINT8 MAXMASHFREQUENCY = 6; // Nerf fast mashing: allow optimal decay with X inputs per second
UINT8 ticsbetweenmashing = TICRATE/MAXMASHFREQUENCY; UINT8 ticsbetweenmashing = TICRATE/MAXMASHFREQUENCY;
UINT8 decaypertic = MASHPWR / ticsbetweenmashing; UINT8 decaypertic = MASHPWR / ticsbetweenmashing;
if (mobj->cusval) if (mobj->cusval)
@ -10385,7 +10386,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
{ {
return false; return false;
} }
break; break;
} }
@ -12641,7 +12642,7 @@ void P_SpawnPlayer(INT32 playernum)
// set 'spritedef' override in mobj for player skins.. (see ProjectSprite) // set 'spritedef' override in mobj for player skins.. (see ProjectSprite)
// (usefulness: when body mobj is detached from player (who respawns), // (usefulness: when body mobj is detached from player (who respawns),
// the dead body mobj retains the skin through the 'spritedef' override). // the dead body mobj retains the skin through the 'spritedef' override).
mobj->skin = &skins[p->skin]; mobj->skin = skins[p->skin];
P_SetupStateAnimation(mobj, mobj->state); P_SetupStateAnimation(mobj, mobj->state);
mobj->health = 1; mobj->health = 1;
@ -12652,7 +12653,7 @@ void P_SpawnPlayer(INT32 playernum)
p->realtime = leveltime; p->realtime = leveltime;
} }
p->followitem = skins[p->skin].followitem; p->followitem = skins[p->skin]->followitem;
if (p->jointime <= 1 || leveltime <= 1) if (p->jointime <= 1 || leveltime <= 1)
{ {
@ -14276,7 +14277,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
if (!playeringame[i] || players[i].spectator == true) if (!playeringame[i] || players[i].spectator == true)
continue; continue;
if (strcmp(skins[players[i].skin].name, "sakura") == 0) if (strcmp(skins[players[i].skin]->name, "sakura") == 0)
{ {
state = mobj->info->spawnstate; state = mobj->info->spawnstate;
break; break;

View file

@ -109,7 +109,7 @@ static inline void P_ArchivePlayer(savebuffer_t *save)
if (skin > numskins) if (skin > numskins)
skin = 0; skin = 0;
WRITESTRINGN(save->p, skins[skin].name, SKINNAMESIZE); WRITESTRINGN(save->p, skins[skin]->name, SKINNAMESIZE);
if (player->followerskin < 0 || player->followerskin >= numfollowers) if (player->followerskin < 0 || player->followerskin >= numfollowers)
WRITESTRINGN(save->p, "None", SKINNAMESIZE); WRITESTRINGN(save->p, "None", SKINNAMESIZE);
@ -134,7 +134,7 @@ static inline void P_ArchivePlayer(savebuffer_t *save)
if (skin > numskins) if (skin > numskins)
skin = 0; skin = 0;
WRITESTRINGN(save->p, skins[skin].name, SKINNAMESIZE); WRITESTRINGN(save->p, skins[skin]->name, SKINNAMESIZE);
WRITEUINT8(save->p, players[i].botvars.difficulty); WRITEUINT8(save->p, players[i].botvars.difficulty);
WRITEUINT8(save->p, (UINT8)players[i].botvars.rival); WRITEUINT8(save->p, (UINT8)players[i].botvars.rival);
@ -188,7 +188,7 @@ static boolean P_UnArchivePlayer(savebuffer_t *save)
{ {
// It is not worth destroying an otherwise good savedata over extra added skins. // It is not worth destroying an otherwise good savedata over extra added skins.
// Let's just say they didn't show up to the rematch, so some Eggrobos subbed in. // Let's just say they didn't show up to the rematch, so some Eggrobos subbed in.
CONS_Alert(CONS_WARNING, "P_UnArchivePlayer: Bot's character \"%s\" was not loaded, replacing with default \"%s\".\n", skinname, skins[defaultbotskin].name); CONS_Alert(CONS_WARNING, "P_UnArchivePlayer: Bot's character \"%s\" was not loaded, replacing with default \"%s\".\n", skinname, skins[defaultbotskin]->name);
skin = defaultbotskin; skin = defaultbotskin;
} }
@ -3535,7 +3535,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (diff2 & MD2_CVMEM) if (diff2 & MD2_CVMEM)
WRITEINT32(save->p, mobj->cvmem); WRITEINT32(save->p, mobj->cvmem);
if (diff2 & MD2_SKIN) if (diff2 & MD2_SKIN)
WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin - skins)); WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin)->skinnum);
if (diff2 & MD2_COLOR) if (diff2 & MD2_COLOR)
WRITEUINT16(save->p, mobj->color); WRITEUINT16(save->p, mobj->color);
if (diff2 & MD2_EXTVAL1) if (diff2 & MD2_EXTVAL1)

View file

@ -7886,7 +7886,7 @@ static void P_LoadRecordGhosts(void)
if (allGhosts) if (allGhosts)
{ {
for (i = 0; i < numskins; ++i) for (i = 0; i < numskins; ++i)
add_ghosts(fmt::format("{}-{}{}", gpath, skins[i].name, modeprefix), allGhosts); add_ghosts(fmt::format("{}-{}{}", gpath, skins[i]->name, modeprefix), allGhosts);
} }
if (sameGhosts) if (sameGhosts)
@ -7894,7 +7894,7 @@ static void P_LoadRecordGhosts(void)
INT32 skin = R_SkinAvailableEx(cv_skin[0].string, false); INT32 skin = R_SkinAvailableEx(cv_skin[0].string, false);
if (skin < 0 || !R_SkinUsable(-1, skin, false)) if (skin < 0 || !R_SkinUsable(-1, skin, false))
skin = 0; // use default skin skin = 0; // use default skin
add_ghosts(fmt::format("{}-{}{}", gpath, skins[skin].name, modeprefix), sameGhosts); add_ghosts(fmt::format("{}-{}{}", gpath, skins[skin]->name, modeprefix), sameGhosts);
} }
// Guest ghost // Guest ghost
@ -8074,7 +8074,7 @@ static void P_InitPlayers(void)
if (!R_SkinUsable(g_localplayers[0], skin, false)) if (!R_SkinUsable(g_localplayers[0], skin, false))
{ {
skin = GetSkinNumClosestToStats(skins[skin].kartspeed, skins[skin].kartweight, skins[skin].flags, false); skin = GetSkinNumClosestToStats(skins[skin]->kartspeed, skins[skin]->kartweight, skins[skin]->flags, false);
} }
if (K_ColorUsable(static_cast<skincolornum_t>(p->color), false, true) == true) if (K_ColorUsable(static_cast<skincolornum_t>(p->color), false, true) == true)
@ -8123,7 +8123,7 @@ static void P_InitPlayers(void)
if (skin != -1) if (skin != -1)
{ {
SetPlayerSkinByNum(i, skin); SetPlayerSkinByNum(i, skin);
players[i].skincolor = (col != SKINCOLOR_NONE) ? col : skins[skin].prefcolor; players[i].skincolor = (col != SKINCOLOR_NONE) ? col : skins[skin]->prefcolor;
players[i].followerskin = follower; players[i].followerskin = follower;
if (follower != -1) if (follower != -1)

View file

@ -1592,7 +1592,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
return false; return false;
if (!triggerline->stringargs[0]) if (!triggerline->stringargs[0])
return false; return false;
if (!(stricmp(triggerline->stringargs[0], skins[actor->player->skin].name) == 0) ^ !!(triggerline->args[1])) if (!(stricmp(triggerline->stringargs[0], skins[actor->player->skin]->name) == 0) ^ !!(triggerline->args[1]))
return false; return false;
break; break;
case 334: // object dye case 334: // object dye
@ -2021,7 +2021,7 @@ static void K_HandleLapIncrement(player_t *player)
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags ? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin].flags; : skins[player->skin]->flags;
if (skinflags & SF_IRONMAN) if (skinflags & SF_IRONMAN)
{ {
if ((player->laps == 1 && lapisfresh) || !K_InRaceDuel()) // We'll do this in K_CheckpointCrossAward if necessary. if ((player->laps == 1 && lapisfresh) || !K_InRaceDuel()) // We'll do this in K_CheckpointCrossAward if necessary.

View file

@ -841,7 +841,7 @@ void P_Ticker(boolean run)
continue; continue;
} }
playerskin = &skins[players[i].skin]; playerskin = skins[players[i].skin];
playerskin->records.timeplayed++; playerskin->records.timeplayed++;
} }
@ -901,7 +901,7 @@ void P_Ticker(boolean run)
continue; continue;
} }
playerskin = &skins[players[i].skin]; playerskin = skins[players[i].skin];
playerskin->records.modetimeplayed[mode]++; playerskin->records.modetimeplayed[mode]++;
} }
} }

View file

@ -1368,7 +1368,7 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
// Skin records (saved to gamedata) // Skin records (saved to gamedata)
if (player->skin < numskins) if (player->skin < numskins)
{ {
skin_t *playerskin = &skins[player->skin]; skin_t *playerskin = skins[player->skin];
if (!losing) if (!losing)
{ {
playerskin->records.wins++; playerskin->records.wins++;
@ -4640,7 +4640,7 @@ void P_PlayerThink(player_t *player)
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[playeri]].flags ? demo.skinlist[demo.currentskinid[playeri]].flags
: skins[player->skin].flags; : skins[player->skin]->flags;
if (skinflags & SF_IRONMAN) // we are Heavy Magician if (skinflags & SF_IRONMAN) // we are Heavy Magician
{ {

View file

@ -1448,7 +1448,7 @@ static void R_ParseSpriteInfoSkin(struct ParseSpriteInfoState *parser)
static void copy_to_skin (struct ParseSpriteInfoState *parser, INT32 skinnum) static void copy_to_skin (struct ParseSpriteInfoState *parser, INT32 skinnum)
{ {
skin_t *skin = &skins[skinnum]; skin_t *skin = skins[skinnum];
spriteinfo_t *sprinfo = skin->sprinfo; spriteinfo_t *sprinfo = skin->sprinfo;
if (parser->any) if (parser->any)

View file

@ -42,7 +42,7 @@
#endif #endif
INT32 numskins = 0; INT32 numskins = 0;
skin_t skins[MAXSKINS]; skin_t **skins;
unloaded_skin_t *unloadedskins = NULL; unloaded_skin_t *unloadedskins = NULL;
@ -111,7 +111,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
// //
memset(skin, 0, sizeof (skin_t)); memset(skin, 0, sizeof (skin_t));
snprintf(skin->name, snprintf(skin->name,
sizeof skin->name, "skin %u", (UINT32)(skin-skins)); sizeof skin->name, "skin %u", skin->skinnum);
skin->name[sizeof skin->name - 1] = '\0'; skin->name[sizeof skin->name - 1] = '\0';
skin->wadnum = INT16_MAX; skin->wadnum = INT16_MAX;
@ -168,16 +168,6 @@ void R_InitSkins(void)
{ {
size_t i; size_t i;
// it can be is do before loading config for skin cvar possible value
// (... what the fuck did you just say to me? "it can be is do"?)
#ifdef SKINVALUES
for (i = 0; i <= MAXSKINS; i++)
{
skin_cons_t[i].value = 0;
skin_cons_t[i].strvalue = NULL;
}
#endif
// no default skin! // no default skin!
numskins = 0; numskins = 0;
@ -334,7 +324,7 @@ UINT32 R_GetLocalRandomSkin(void)
return grabskins[M_RandomKey(usableskins)]; return grabskins[M_RandomKey(usableskins)];
} }
// returns true if the skin name is found (loaded from pwad) // returns the skin number if the skin name is found (loaded from pwad)
// warning return -1 if not found // warning return -1 if not found
INT32 R_SkinAvailable(const char *name) INT32 R_SkinAvailable(const char *name)
{ {
@ -362,10 +352,10 @@ INT32 R_SkinAvailableEx(const char *name, boolean demoskins)
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
{ {
if (skins[i].namehash != hash) if (skins[i]->namehash != hash)
continue; continue;
if (stricmp(skins[i].name,name)!=0) if (stricmp(skins[i]->name,name)!=0)
continue; continue;
return i; return i;
@ -401,7 +391,7 @@ static void SetSkin(player_t *player, INT32 skinnum)
if (demo.playback) if (demo.playback)
skinnum = demo.skinlist[skinnum].mapping; skinnum = demo.skinlist[skinnum].mapping;
skin_t *skin = &skins[skinnum]; skin_t *skin = skins[skinnum];
player->skin = skinnum; player->skin = skinnum;
@ -510,9 +500,9 @@ void SetFakePlayerSkin(player_t* player, INT32 skinid)
} }
else else
{ {
player->kartspeed = skins[skinid].kartspeed; player->kartspeed = skins[skinid]->kartspeed;
player->kartweight = skins[skinid].kartweight; player->kartweight = skins[skinid]->kartweight;
player->charflags = skins[skinid].flags; player->charflags = skins[skinid]->flags;
} }
player->mo->skin = &skins[skinid]; player->mo->skin = &skins[skinid];
@ -536,7 +526,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast, boolean instant)
if (demo.skinlist[i].flags & SF_IRONMAN) if (demo.skinlist[i].flags & SF_IRONMAN)
continue; continue;
} }
else if (skins[i].flags & SF_IRONMAN) else if (skins[i]->flags & SF_IRONMAN)
continue; continue;
if (!R_SkinUsable(player-players, i, true)) if (!R_SkinUsable(player-players, i, true))
continue; continue;
@ -615,7 +605,7 @@ void ClearFakePlayerSkin(player_t* player)
else else
{ {
skinid = player->skin; skinid = player->skin;
flags = skins[player->skin].flags; flags = skins[player->skin]->flags;
} }
if ((flags & SF_IRONMAN) && !P_MobjWasRemoved(player->mo)) if ((flags & SF_IRONMAN) && !P_MobjWasRemoved(player->mo))
@ -648,8 +638,8 @@ flaglessretry:
{ {
continue; continue;
} }
stat_diff = abs(skins[i].kartspeed - kartspeed) + abs(skins[i].kartweight - kartweight); stat_diff = abs(skins[i]->kartspeed - kartspeed) + abs(skins[i]->kartweight - kartweight);
if (doflagcheck && (skins[i].flags & flagcheck) != flagcheck) if (doflagcheck && (skins[i]->flags & flagcheck) != flagcheck)
{ {
continue; continue;
} }
@ -957,8 +947,10 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
buf2[size] = '\0'; buf2[size] = '\0';
// set defaults // set defaults
skin = &skins[numskins]; skins = Z_Realloc(skins, sizeof(skin_t*) * (numskins + 1), PU_STATIC, NULL);
skin = skins[numskins] = Z_Calloc(sizeof(skin_t), PU_STATIC, NULL);
Sk_SetDefaultValue(skin); Sk_SetDefaultValue(skin);
skin->skinnum = numskins;
skin->wadnum = wadnum; skin->wadnum = wadnum;
realname = false; realname = false;
// parse // parse
@ -1033,14 +1025,9 @@ next_token:
if (mainfile == false) if (mainfile == false)
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
#ifdef SKINVALUES
skin_cons_t[numskins].value = numskins;
skin_cons_t[numskins].strvalue = skin->name;
#endif
// Update the forceskin possiblevalues // Update the forceskin possiblevalues
Forceskin_cons_t[numskins+1].value = numskins; Forceskin_cons_t[numskins+1].value = numskins;
Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name; Forceskin_cons_t[numskins+1].strvalue = skins[numskins]->name;
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
@ -1178,7 +1165,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile)
strlwr(value); strlwr(value);
skinnum = R_SkinAvailableEx(value, false); skinnum = R_SkinAvailableEx(value, false);
if (skinnum != -1) if (skinnum != -1)
skin = &skins[skinnum]; skin = skins[skinnum];
else else
{ {
CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);

View file

@ -38,7 +38,8 @@ extern "C" {
/// The skin_t struct /// The skin_t struct
struct skin_t struct skin_t
{ {
char name[SKINNAMESIZE+1]; // descriptive name of the skin char name[SKINNAMESIZE+1]; // name of skin
UINT8 skinnum;
UINT32 namehash; // quickncasehash(->name, SKINNAMESIZE) UINT32 namehash; // quickncasehash(->name, SKINNAMESIZE)
UINT16 wadnum; UINT16 wadnum;
skinflags_t flags; skinflags_t flags;
@ -92,16 +93,15 @@ typedef enum {
ENGINECLASS_H, ENGINECLASS_H,
ENGINECLASS_I, ENGINECLASS_I,
ENGINECLASS_J, ENGINECLASS_J,
ENGINECLASS_R = 17, ENGINECLASS_R = 17,
} engineclass_t; } engineclass_t;
engineclass_t R_GetEngineClass(SINT8 speed, SINT8 weight, skinflags_t flags); engineclass_t R_GetEngineClass(SINT8 speed, SINT8 weight, skinflags_t flags);
/// Externs /// Externs
extern INT32 numskins; extern INT32 numskins;
extern skin_t skins[MAXSKINS]; extern skin_t **skins;
extern CV_PossibleValue_t Forceskin_cons_t[]; extern CV_PossibleValue_t Forceskin_cons_t[];

View file

@ -45,7 +45,7 @@ INT32 R_ThingLightLevel(mobj_t* thing)
lightlevel -= 255; lightlevel -= 255;
} }
if (!R_CanShowSkinInDemo((skin_t*)thing->skin-skins) if (!R_CanShowSkinInDemo(((skin_t*)thing->skin)->skinnum)
&& !thing->colorized && !thing->colorized
&& !thing->hitlag) && !thing->hitlag)
{ {

View file

@ -848,7 +848,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
{ {
skinnum = (skin_t*)vis->mobj->skin-skins; skinnum = ((skin_t*)vis->mobj->skin)->skinnum;
// Hide not-yet-unlocked characters in replays from other people // Hide not-yet-unlocked characters in replays from other people
if (!R_CanShowSkinInDemo(skinnum)) if (!R_CanShowSkinInDemo(skinnum))

View file

@ -519,8 +519,8 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (sfx->skinsound != -1 && origin && (origin->player || origin->skin)) if (sfx->skinsound != -1 && origin && (origin->player || origin->skin))
{ {
// redirect player sound to the sound in the skin table // redirect player sound to the sound in the skin table
skin_t *skin = (origin->player ? &skins[origin->player->skin] : ((skin_t *)origin->skin)); skin_t *skin = (origin->player ? skins[origin->player->skin] : ((skin_t *)origin->skin));
if (R_CanShowSkinInDemo(skin-skins) == false) if (R_CanShowSkinInDemo(skin->skinnum) == false)
return; return;
sfx_id = skin->soundsid[sfx->skinsound]; sfx_id = skin->soundsid[sfx->skinsound];
sfx = &S_sfx[sfx_id]; sfx = &S_sfx[sfx_id];

View file

@ -179,7 +179,7 @@ void ST_LoadGraphics(void)
void ST_LoadFaceGraphics(INT32 skinnum) void ST_LoadFaceGraphics(INT32 skinnum)
{ {
#define FACE_MAX (FACE_MINIMAP+1) #define FACE_MAX (FACE_MINIMAP+1)
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; spritedef_t *sprdef = &skins[skinnum]->sprites[SPR2_XTRA];
spriteframe_t *sprframe; spriteframe_t *sprframe;
UINT8 i = 0, maxer = min(sprdef->numframes, FACE_MAX); UINT8 i = 0, maxer = min(sprdef->numframes, FACE_MAX);
while (i < maxer) while (i < maxer)

View file

@ -490,7 +490,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
snprintf(data.headerstring, snprintf(data.headerstring,
sizeof data.headerstring, sizeof data.headerstring,
"%s", "%s",
R_CanShowSkinInDemo(players[i].skin) ? skins[players[i].skin].realname : "???"); R_CanShowSkinInDemo(players[i].skin) ? skins[players[i].skin]->realname : "???");
} }
data.showroundnum = true; data.showroundnum = true;