diff --git a/src/cvars.cpp b/src/cvars.cpp index 633250a73..ebf279432 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -686,6 +686,7 @@ consvar_t cv_items[] = { UnsavedNetVar("droptarget", "On").on_off(), UnsavedNetVar("gardentop", "On").on_off(), UnsavedNetVar("gachabom", "On").on_off(), + UnsavedNetVar("stoneshoe", "On").on_off(), UnsavedNetVar("dualsneaker", "On").on_off(), UnsavedNetVar("triplesneaker", "On").on_off(), UnsavedNetVar("triplebanana", "On").on_off(), diff --git a/src/d_player.h b/src/d_player.h index 96af19f80..1e7d1f8b5 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -193,7 +193,8 @@ Run this macro, then #undef FOREACH afterward FOREACH (KITCHENSINK, 20),\ FOREACH (DROPTARGET, 21),\ FOREACH (GARDENTOP, 22),\ - FOREACH (GACHABOM, 23) + FOREACH (GACHABOM, 23),\ + FOREACH (STONESHOE, 24) typedef enum { @@ -214,6 +215,8 @@ typedef enum NUMKARTRESULTS, + KDROP_STONESHOETRAP, + // Power-ups exist in the same enum as items so it's easy // for paper items to be reused for them. FIRSTPOWERUP, @@ -771,6 +774,7 @@ struct player_t fixed_t accelboost; // Boost value smoothing for acceleration fixed_t handleboost; // Boost value smoothing for handling angle_t boostangle; // angle set when not spun out OR boosted to determine what direction you should keep going at if you're spun out and boosted. + fixed_t stonedrag; fixed_t draftpower; // (0 to FRACUNIT) - Drafting power, doubles your top speed & acceleration at max UINT16 draftleeway; // Leniency timer before removing draft power @@ -1047,6 +1051,7 @@ struct player_t mobj_t *whip; mobj_t *hand; mobj_t *flickyAttacker; + mobj_t *stoneShoe; SINT8 pitblame; // Index of last player that hit you, resets after being in control for a bit. If you deathpit, credit the old attacker! diff --git a/src/deh_tables.c b/src/deh_tables.c index 63a8929ff..b8ba3ebea 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3109,6 +3109,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi // Flybot767 (stun) "S_FLYBOT767", + + "S_STON", }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -4009,6 +4011,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_AMPS", "MT_FLYBOT767", + + "MT_STONESHOE", + "MT_STONESHOE_CHAIN", }; const char *const MOBJFLAG_LIST[] = { @@ -5194,6 +5199,7 @@ struct int_const_s const INT_CONST[] = { {"KRITEM_DUALJAWZ",KRITEM_DUALJAWZ}, {"KRITEM_TRIPLEGACHABOM",KRITEM_TRIPLEGACHABOM}, {"NUMKARTRESULTS",NUMKARTRESULTS}, + {"KDROP_STONESHOETRAP",KDROP_STONESHOETRAP}, {"FIRSTPOWERUP",FIRSTPOWERUP}, {"POWERUP_SMONITOR",POWERUP_SMONITOR}, {"POWERUP_BARRIER",POWERUP_BARRIER}, diff --git a/src/info.c b/src/info.c index f15ec9b9f..0cde7d230 100644 --- a/src/info.c +++ b/src/info.c @@ -792,6 +792,8 @@ char sprnames[NUMSPRITES + 1][5] = // Flybot767 (stun) "STUN", + "STON", + // Pulley "HCCH", "HCHK", @@ -3680,6 +3682,8 @@ state_t states[NUMSTATES] = // Flybot767 (stun) {SPR_STUN, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 4, 4, S_NULL}, // S_FLYBOT767 + + {SPR_STON, 0, -1, {NULL}, 0, 0, S_STON}, // S_STON }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -22529,6 +22533,58 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_NOCLIPTHING, // flags S_NULL // raisestate }, + { // MT_STONESHOE + -1, // doomednum + S_STON, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 4*FRACUNIT, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // dispoffset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_NOSQUISH|MF_NOHITLAGFORME|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_STONESHOE_CHAIN + -1, // doomednum + S_SHRINK_CHAIN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SCENERY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, }; diff --git a/src/info.h b/src/info.h index 6a6b1f60f..737daf64b 100644 --- a/src/info.h +++ b/src/info.h @@ -1329,6 +1329,8 @@ typedef enum sprite // Flybot767 (stun) SPR_STUN, + SPR_STON, + // Pulley SPR_HCCH, SPR_HCHK, @@ -4167,6 +4169,8 @@ typedef enum state // Flybot767 (stun) S_FLYBOT767, + S_STON, + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES @@ -5090,6 +5094,9 @@ typedef enum mobj_type MT_FLYBOT767, + MT_STONESHOE, + MT_STONESHOE_CHAIN, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/k_hud.cpp b/src/k_hud.cpp index d36d74169..f37af401b 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -171,6 +171,7 @@ static patch_t *kp_kitchensink[3]; static patch_t *kp_droptarget[3]; static patch_t *kp_gardentop[3]; static patch_t *kp_gachabom[3]; +static patch_t *kp_stoneshoe[3]; static patch_t *kp_bar[2]; static patch_t *kp_doublebar[2]; static patch_t *kp_triplebar[2]; @@ -639,6 +640,7 @@ void K_LoadKartHUDGraphics(void) HU_UpdatePatch(&kp_droptarget[0], "K_ITDTRG"); HU_UpdatePatch(&kp_gardentop[0], "K_ITGTOP"); HU_UpdatePatch(&kp_gachabom[0], "K_ITGBOM"); + HU_UpdatePatch(&kp_stoneshoe[0], "K_ITSTON"); HU_UpdatePatch(&kp_bar[0], "K_RBBAR"); HU_UpdatePatch(&kp_doublebar[0], "K_RBBAR2"); HU_UpdatePatch(&kp_triplebar[0], "K_RBBAR3"); @@ -699,6 +701,7 @@ void K_LoadKartHUDGraphics(void) HU_UpdatePatch(&kp_droptarget[1], "K_ISDTRG"); HU_UpdatePatch(&kp_gardentop[1], "K_ISGTOP"); HU_UpdatePatch(&kp_gachabom[1], "K_ISGBOM"); + HU_UpdatePatch(&kp_stoneshoe[1], "K_ISSTON"); HU_UpdatePatch(&kp_bar[1], "K_SBBAR"); HU_UpdatePatch(&kp_doublebar[1], "K_SBBAR2"); HU_UpdatePatch(&kp_triplebar[1], "K_SBBAR3"); @@ -757,6 +760,7 @@ void K_LoadKartHUDGraphics(void) HU_UpdatePatch(&kp_droptarget[2], "ISPYDTRG"); HU_UpdatePatch(&kp_gardentop[2], "ISPYGTOP"); HU_UpdatePatch(&kp_gachabom[2], "ISPYGBOM"); + HU_UpdatePatch(&kp_stoneshoe[2], "ISPYSTON"); // CHECK indicators sprintf(buffer, "K_CHECKx"); @@ -1177,6 +1181,7 @@ static patch_t *K_GetCachedItemPatch(INT32 item, UINT8 offset) kp_droptarget, kp_gardentop, kp_gachabom, + kp_stoneshoe, }; if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS)) diff --git a/src/k_kart.c b/src/k_kart.c index 8a1a6869a..9b99f04b2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -15446,6 +15446,10 @@ void K_UpdateMobjItemOverlay(mobj_t *part, SINT8 itemType, UINT8 itemCount) part->sprite = SPR_ITEM; part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE; break; + case KDROP_STONESHOETRAP: + part->sprite = SPR_STON; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|4; + break; default: if (itemType >= FIRSTPOWERUP) { diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 0c08a1044..00c0c5864 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -92,6 +92,7 @@ typedef enum TRICKINDICATOR = 0x2000, BARRIER = 0x4000, BALLHOGRETICULE = 0x8000, + STONESHOE = 0x10000, } player_saveflags; static inline void P_ArchivePlayer(savebuffer_t *save) @@ -364,6 +365,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (players[i].powerup.barrier) flags |= BARRIER; + if (players[i].stoneShoe) + flags |= STONESHOE; + WRITEUINT32(save->p, flags); if (flags & SKYBOXVIEW) @@ -411,6 +415,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (flags & BARRIER) WRITEUINT32(save->p, players[i].powerup.barrier->mobjnum); + if (flags & STONESHOE) + WRITEUINT32(save->p, players[i].stoneShoe->mobjnum); + WRITEUINT32(save->p, (UINT32)players[i].followitem); WRITEUINT32(save->p, players[i].charflags); @@ -499,6 +506,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEFIXED(save->p, players[i].accelboost); WRITEFIXED(save->p, players[i].handleboost); WRITEANGLE(save->p, players[i].boostangle); + WRITEFIXED(save->p, players[i].stonedrag); WRITEFIXED(save->p, players[i].draftpower); WRITEUINT16(save->p, players[i].draftleeway); @@ -1058,6 +1066,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) if (flags & BARRIER) players[i].powerup.barrier = (mobj_t *)(size_t)READUINT32(save->p); + if (flags & STONESHOE) + players[i].stoneShoe = (mobj_t *)(size_t)READUINT32(save->p); + players[i].followitem = (mobjtype_t)READUINT32(save->p); //SetPlayerSkinByNum(i, players[i].skin); @@ -1147,6 +1158,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].accelboost = READFIXED(save->p); players[i].handleboost = READFIXED(save->p); players[i].boostangle = READANGLE(save->p); + players[i].stonedrag = READFIXED(save->p); players[i].draftpower = READFIXED(save->p); players[i].draftleeway = READUINT16(save->p); @@ -6218,6 +6230,11 @@ static void P_RelinkPointers(void) if (!RelinkMobj(&players[i].powerup.barrier)) CONS_Debug(DBG_GAMELOGIC, "powerup.barrier not found on player %d\n", i); } + if (players[i].stoneShoe) + { + if (!RelinkMobj(&players[i].stoneShoe)) + CONS_Debug(DBG_GAMELOGIC, "stoneShoe not found on player %d\n", i); + } } } diff --git a/src/p_user.c b/src/p_user.c index 5859aa916..604cc506b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4241,6 +4241,7 @@ void P_PlayerThink(player_t *player) PlayerPointerErase(player->hoverhyudoro); PlayerPointerErase(player->ballhogreticule); PlayerPointerErase(player->flickyAttacker); + PlayerPointerErase(player->stoneShoe); PlayerPointerErase(player->powerup.flickyController); PlayerPointerErase(player->powerup.barrier);