diff --git a/src/d_player.h b/src/d_player.h index d61360ded..10a9cf3a9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -37,6 +37,7 @@ typedef enum { SF_HIRES = 1, // Draw the sprite at different size? SF_MACHINE = 1<<1, // Beep boop. Are you a robot? + SF_IRONMAN = 1<<2, // Pick a new skin during POSITION. I main Random! // free up to and including 1<<31 } skinflags_t; @@ -386,6 +387,9 @@ typedef struct player_s INT32 skin; UINT32 availabilities; + UINT8 fakeskin; // ironman + UINT8 lastfakeskin; + UINT8 kartspeed; // Kart speed stat between 1 and 9 UINT8 kartweight; // Kart weight stat between 1 and 9 diff --git a/src/deh_tables.c b/src/deh_tables.c index 2f68edf2c..6d9c8c7f2 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6318,6 +6318,7 @@ struct int_const_s const INT_CONST[] = { // Character flags (skinflags_t) {"SF_HIRES",SF_HIRES}, {"SF_MACHINE",SF_MACHINE}, + {"SF_IRONMAN",SF_IRONMAN}, // Sound flags {"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE}, diff --git a/src/g_demo.c b/src/g_demo.c index 103a60a41..baad4e3fc 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -274,6 +274,7 @@ void G_ReadDemoExtraData(void) kartspeed = READUINT8(demo_p); kartweight = READUINT8(demo_p); + demo_p++; // lastfakeskin if (stricmp(skins[players[p].skin].name, name) != 0) FindClosestSkinForStats(p, kartspeed, kartweight); @@ -2110,6 +2111,7 @@ void G_BeginRecording(void) // Kart speed and weight WRITEUINT8(demo_p, skins[player->skin].kartspeed); WRITEUINT8(demo_p, skins[player->skin].kartweight); + WRITEUINT8(demo_p, player->lastfakeskin); // And mobjtype_t is best with UINT32 too... WRITEUINT32(demo_p, player->followitem); @@ -2709,7 +2711,7 @@ void G_DoPlayDemo(char *defdemoname) char msg[1024]; boolean spectator; - UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0; + UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], lastfakeskin[MAXPLAYERS], numslots = 0; #if defined(SKIPERRORS) && !defined(DEVELOP) boolean skiperrors = false; @@ -3086,6 +3088,7 @@ void G_DoPlayDemo(char *defdemoname) // Kart stats, temporarily kartspeed[p] = READUINT8(demo_p); kartweight[p] = READUINT8(demo_p); + lastfakeskin[p] = READUINT8(demo_p); if (stricmp(skins[players[p].skin].name, skin) != 0) FindClosestSkinForStats(p, kartspeed[p], kartweight[p]); @@ -3143,6 +3146,7 @@ void G_DoPlayDemo(char *defdemoname) // it would only break the replay if we clipped them. players[i].kartspeed = kartspeed[i]; players[i].kartweight = kartweight[i]; + players[i].fakeskin = lastfakeskin[i]; } demo.deferstart = true; @@ -3334,6 +3338,7 @@ void G_AddGhost(char *defdemoname) kartspeed = READUINT8(p); kartweight = READUINT8(p); + p += 1; // lastfakeskin p += 4; // followitem (maybe change later) diff --git a/src/g_game.c b/src/g_game.c index bf37aadbc..3d06aed1c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2233,6 +2233,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT16 skincolor; INT32 skin; UINT32 availabilities; + UINT8 fakeskin; + UINT8 lastfakeskin; tic_t jointime; @@ -2278,6 +2280,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) skincolor = players[player].skincolor; skin = players[player].skin; + fakeskin = players[player].fakeskin; + lastfakeskin = players[player].lastfakeskin; // SRB2kart kartspeed = players[player].kartspeed; @@ -2431,6 +2435,12 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->botvars.rival = botrival; p->xtralife = xtralife; + if (betweenmaps) + p->fakeskin = MAXSKINS; + else + p->fakeskin = fakeskin; + p->lastfakeskin = lastfakeskin; + // SRB2kart p->itemroulette = itemroulette; p->roulettetype = roulettetype; diff --git a/src/k_hud.c b/src/k_hud.c index d4127e131..a2e2baa1c 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1699,6 +1699,7 @@ static boolean K_drawKartPositionFaces(void) boolean completed[MAXPLAYERS]; INT32 rankplayer[MAXPLAYERS]; INT32 bumperx, emeraldx, numplayersingame = 0; + INT32 xoff, yoff, flipflag = 0; UINT8 *colormap; ranklines = 0; @@ -1784,15 +1785,25 @@ static boolean K_drawKartPositionFaces(void) bumperx = FACE_X+19; emeraldx = FACE_X+16; + if (skins[players[rankplayer[i]].skin].flags & SF_IRONMAN) + { + flipflag = V_FLIP; + xoff = 16; + } else + { + flipflag = 0; + xoff = yoff = 0; + } + if (players[rankplayer[i]].mo->color) { - colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); + colormap = R_GetTranslationColormap(((skin_t*)players[rankplayer[i]].mo->skin) - skins, players[rankplayer[i]].mo->color, GTC_CACHE); if (players[rankplayer[i]].mo->colorized) colormap = R_GetTranslationColormap(TC_RAINBOW, players[rankplayer[i]].mo->color, GTC_CACHE); else - colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); + colormap = R_GetTranslationColormap(((skin_t*)players[rankplayer[i]].mo->skin) - skins, players[rankplayer[i]].mo->color, GTC_CACHE); - V_DrawMappedPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin][FACE_RANK], colormap); + V_DrawMappedPatch(FACE_X + xoff, Y + yoff, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT|flipflag, faceprefix[((skin_t*)players[rankplayer[i]].mo->skin) - skins][FACE_RANK], colormap); if (LUA_HudEnabled(hud_battlebumpers)) { diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c5f5cc4d0..2a3b9e46a 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -410,6 +410,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->skin); else if (fastcmp(field,"availabilities")) lua_pushinteger(L, plr->availabilities); + else if (fastcmp(field,"fakeskin")) + lua_pushinteger(L, plr->fakeskin); + else if (fastcmp(field,"lastfakeskin")) + lua_pushinteger(L, plr->lastfakeskin); else if (fastcmp(field,"score")) lua_pushinteger(L, plr->score); // SRB2kart @@ -575,6 +579,10 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"availabilities")) return NOSET; + else if (fastcmp(field,"fakeskin")) + return NOSET; + else if (fastcmp(field,"lastfakeskin")) + return NOSET; else if (fastcmp(field,"score")) plr->score = luaL_checkinteger(L, 3); // SRB2kart diff --git a/src/m_random.h b/src/m_random.h index c08e32993..dc6f1884b 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -62,6 +62,8 @@ typedef enum PR_MOVINGTARGET, // Randomised moving targets + PR_RANDOMSKIN, // Random skin select from Heavy Magician(?) + PRNUMCLASS } pr_class_t; diff --git a/src/p_saveg.c b/src/p_saveg.c index e35fa823f..b75dfe591 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -151,6 +151,8 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].skincolor); WRITEINT32(save_p, players[i].skin); WRITEUINT32(save_p, players[i].availabilities); + WRITEUINT8(save_p, players[i].fakeskin); + WRITEUINT8(save_p, players[i].lastfakeskin); WRITEUINT32(save_p, players[i].score); WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].xtralife); @@ -470,6 +472,8 @@ static void P_NetUnArchivePlayers(void) players[i].skincolor = READUINT8(save_p); players[i].skin = READINT32(save_p); players[i].availabilities = READUINT32(save_p); + players[i].fakeskin = READUINT8(save_p); + players[i].lastfakeskin = READUINT8(save_p); players[i].score = READUINT32(save_p); players[i].lives = READSINT8(save_p); players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter diff --git a/src/p_user.c b/src/p_user.c index be7beff57..3c64604f4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4167,6 +4167,28 @@ void P_PlayerThink(player_t *player) { player->stairjank--; } + // Random skin / "ironman" + if (((skin_t *)player->mo->skin)->flags & SF_IRONMAN) + { + if (player->mo) { + if (player->fakeskin != MAXSKINS) + { + SetFakePlayerSkin(player, player->fakeskin); + } + else + { + INT32 i; + do { + i = P_RandomKey(PR_RANDOMSKIN, numskins); + } while (skins[i].flags & SF_IRONMAN || i == player->lastfakeskin); + + SetFakePlayerSkin(player, i); + + S_StartSound(NULL, sfx_kc33); + K_SpawnDriftElectricSparks(player, player->skincolor, false); + } + } + } K_KartPlayerThink(player, cmd); // SRB2kart diff --git a/src/r_skins.c b/src/r_skins.c index 0557e9e88..ba081efd6 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -334,6 +334,17 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) SetPlayerSkinByNum(playernum, 0); // not found, put in the default skin } +// Set mo skin but not player_t skin, for ironman +void SetFakePlayerSkin(player_t* player, INT32 skinnum) +{ + player->mo->skin = &skins[skinnum]; + player->fakeskin = skinnum; + player->lastfakeskin = skinnum; + player->kartspeed = skins[skinnum].kartspeed; + player->kartweight = skins[skinnum].kartweight; + player->charflags = skins[skinnum].flags; +} + // // Add skins from a pwad, each skin preceded by 'S_SKIN' marker // @@ -484,6 +495,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) // 1, true, yes are all valid values GETFLAG(HIRES) GETFLAG(MACHINE) + GETFLAG(IRONMAN) #undef GETFLAG else // let's check if it's a sound, otherwise error out diff --git a/src/r_skins.h b/src/r_skins.h index ded45a71f..9e51f025c 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -81,6 +81,7 @@ void R_InitSkins(void); void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 +void SetFakePlayerSkin(player_t* player, INT32 skinnum); boolean R_SkinUsable(INT32 playernum, INT32 skinnum); UINT32 R_GetSkinAvailabilities(void); INT32 R_SkinAvailable(const char *name);