From c2a07b486b89a03ef626b20b235d23c0db905a36 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 11 May 2019 15:20:06 -0400 Subject: [PATCH] Add Flame Shield --- src/d_player.h | 16 +++ src/dehacked.c | 36 ++++++- src/info.c | 101 ++++++++++++++++--- src/info.h | 27 ++++- src/k_kart.c | 262 ++++++++++++++++++++++++++++++++++++++++--------- src/k_kart.h | 1 + src/p_enemy.c | 2 +- src/p_inter.c | 14 +-- src/p_map.c | 4 + src/p_mobj.c | 71 +++++++++++++- src/p_user.c | 2 +- 11 files changed, 464 insertions(+), 72 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 48faca92c..024c2e04f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -214,6 +214,8 @@ typedef enum KITEM_GROW, KITEM_SHRINK, KITEM_THUNDERSHIELD, + KITEM_BUBBLESHIELD, + KITEM_FLAMESHIELD, KITEM_HYUDORO, KITEM_POGOSPRING, KITEM_SUPERRING, @@ -232,6 +234,15 @@ typedef enum NUMKARTRESULTS } kartitems_t; +typedef enum +{ + KSHIELD_NONE = 0, + KSHIELD_THUNDER = 1, + KSHIELD_BUBBLE = 2, + KSHIELD_FLAME = 3, + NUMKARTSHIELDS +} kartshields_t; + //{ SRB2kart - kartstuff typedef enum { @@ -311,6 +322,8 @@ typedef enum k_squishedtimer, // Squished frame timer k_rocketsneakertimer, // Rocket Sneaker duration timer k_invincibilitytimer, // Invincibility timer + k_flameready, // Flame Shield dash ready to activate + k_flamedash, // Flame Shield dash power k_eggmanheld, // Eggman monitor held, separate from k_itemheld so it doesn't stop you from getting items k_eggmanexplode, // Fake item recieved, explode in a few seconds k_eggmanblame, // Fake item recieved, who set this fake @@ -342,6 +355,9 @@ typedef enum // QUICKLY GET EITHER SNEAKER OR LEVEL BOOSTER SINCE THEY ARE FUNCTIONALLY IDENTICAL #define EITHERSNEAKER(p) (p->kartstuff[k_sneakertimer] || p->kartstuff[k_levelbooster]) +// QUICKLY GET RING TOTAL, INCLUDING RINGS CURRENTLY IN THE PICKUP ANIMATION +#define RINGTOTAL(p) (p->kartstuff[k_rings] + p->kartstuff[k_pickuprings]) + //} #define WEP_AUTO 1 diff --git a/src/dehacked.c b/src/dehacked.c index 7e4b94117..7ae32e384 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6623,6 +6623,27 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_THUNDERSHIELD23", "S_THUNDERSHIELD24", + // Flame Shield + "S_FLAMESHIELD1", + "S_FLAMESHIELD2", + "S_FLAMESHIELD3", + "S_FLAMESHIELD4", + "S_FLAMESHIELD5", + "S_FLAMESHIELD6", + "S_FLAMESHIELD7", + "S_FLAMESHIELD8", + "S_FLAMESHIELD9", + "S_FLAMESHIELD10", + "S_FLAMESHIELD11", + "S_FLAMESHIELD12", + "S_FLAMESHIELD13", + "S_FLAMESHIELD14", + "S_FLAMESHIELD15", + "S_FLAMESHIELD16", + "S_FLAMESHIELD17", + "S_FLAMESHIELD18", + "S_FLAMESHIELDDASH", + // The legend "S_SINK", "S_SINK_SHIELD", @@ -7757,7 +7778,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SPB", // Self-Propelled Bomb "MT_SPBEXPLOSION", - "MT_THUNDERSHIELD", // Thunder Shield stuff + "MT_THUNDERSHIELD", // Shields + "MT_BUBBLESHIELD", + "MT_FLAMESHIELD", "MT_SINK", // Kitchen Sink Stuff "MT_SINK_SHIELD", @@ -8450,6 +8473,8 @@ static const char *const KARTSTUFF_LIST[] = { "SQUISHEDTIMER", "ROCKETSNEAKERTIMER", "INVINCIBILITYTIMER", + "FLAMEREADY", + "FLAMEDASH", "EGGMANHELD", "EGGMANEXPLODE", "EGGMANBLAME", @@ -8993,6 +9018,8 @@ struct { {"KITEM_GROW",KITEM_GROW}, {"KITEM_SHRINK",KITEM_SHRINK}, {"KITEM_THUNDERSHIELD",KITEM_THUNDERSHIELD}, + {"KITEM_BUBBLESHIELD",KITEM_BUBBLESHIELD}, + {"KITEM_FLAMESHIELD",KITEM_FLAMESHIELD}, {"KITEM_HYUDORO",KITEM_HYUDORO}, {"KITEM_POGOSPRING",KITEM_POGOSPRING}, {"KITEM_SUPERRING",KITEM_SUPERRING}, @@ -9006,6 +9033,13 @@ struct { {"KRITEM_DUALJAWZ",KRITEM_DUALJAWZ}, {"NUMKARTRESULTS",NUMKARTRESULTS}, + // kartshields_t + {"KSHIELD_NONE",KSHIELD_NONE}, + {"KSHIELD_THUNDER",KSHIELD_THUNDER}, + {"KSHIELD_BUBBLE",KSHIELD_BUBBLE}, + {"KSHIELD_FLAME",KSHIELD_FLAME}, + {"NUMKARTSHIELDS",NUMKARTSHIELDS}, + // translation colormaps {"TC_DEFAULT",TC_DEFAULT}, {"TC_BOSS",TC_BOSS}, diff --git a/src/info.c b/src/info.c index 31f2f8348..c87ac4866 100644 --- a/src/info.c +++ b/src/info.c @@ -57,19 +57,19 @@ char sprnames[NUMSPRITES + 1][5] = //SRB2kart Sprites "SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE", "KINV","KINF","WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN", - "JAWZ","SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN", - "DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM", - "SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB", - "ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3", - "RETI","AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS", - "MARB","FUFO","RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC", - "PGTR","PGF1","PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR", - "REAP","JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST", - "FROG","CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB", - "CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS","ZTCH", - "MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH","BFRT", - "OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN","FWRK", - "MXCL","RGSP","DRAF","XMS4","XMS5","VIEW" + "JAWZ","SSMN","KRBM","BHOG","BHBM","SPBM","THNS","BUBS","FLMS","SINK", + "SITR","KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS", + "BUZB","CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW", + "ISTA","ISTB","ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1", + "HIT2","HIT3","RETI","AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM", + "FPRT","SBUS","MARB","FUFO","RUST","BLON","VAPE","HTZA","HTZB","SGVA", + "SGVB","SGVC","PGTR","PGF1","PGF2","PGF3","PGBH","DPLR","SPTL","ENM1", + "GARU","MARR","REAP","JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR", + "COCO","BDST","FROG","CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP", + "SNOB","ICEB","CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN", + "PGSS","ZTCH","MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE", + "TOAH","BFRT","OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ", + "WBLN","FWRK","MXCL","RGSP","DRAF","XMS4","XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2850,6 +2850,26 @@ state_t states[NUMSTATES] = {SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD24}, // S_THUNDERSHIELD23 {SPR_THNS, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_THUNDERSHIELD1}, // S_THUNDERSHIELD24 + {SPR_FLMS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_FLAMESHIELD2}, // S_FLAMESHIELD1 + {SPR_FLMS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_FLAMESHIELD3}, // S_FLAMESHIELD2 + {SPR_FLMS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_FLAMESHIELD4}, // S_FLAMESHIELD3 + {SPR_FLMS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_FLAMESHIELD5}, // S_FLAMESHIELD4 + {SPR_FLMS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_FLAMESHIELD6}, // S_FLAMESHIELD5 + {SPR_FLMS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_FLAMESHIELD7}, // S_FLAMESHIELD6 + {SPR_FLMS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_FLAMESHIELD8}, // S_FLAMESHIELD7 + {SPR_FLMS, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_FLAMESHIELD9}, // S_FLAMESHIELD8 + {SPR_FLMS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_FLAMESHIELD10}, // S_FLAMESHIELD9 + {SPR_FLMS, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_FLAMESHIELD11}, // S_FLAMESHIELD10 + {SPR_FLMS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_FLAMESHIELD12}, // S_FLAMESHIELD11 + {SPR_FLMS, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_FLAMESHIELD13}, // S_FLAMESHIELD12 + {SPR_FLMS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_FLAMESHIELD14}, // S_FLAMESHIELD13 + {SPR_FLMS, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_FLAMESHIELD15}, // S_FLAMESHIELD14 + {SPR_FLMS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_FLAMESHIELD16}, // S_FLAMESHIELD15 + {SPR_FLMS, FF_FULLBRIGHT|16, 2, {NULL}, 0, 0, S_FLAMESHIELD17}, // S_FLAMESHIELD16 + {SPR_FLMS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_FLAMESHIELD18}, // S_FLAMESHIELD17 + {SPR_FLMS, FF_FULLBRIGHT|17, 2, {NULL}, 0, 0, S_FLAMESHIELD1}, // S_FLAMESHIELD18 + {SPR_FLMS, FF_FULLBRIGHT|18, -1, {NULL}, 0, 0, S_FLAMESHIELDDASH}, // S_FLAMESHIELDDASH + {SPR_SINK, 0, 1, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK {SPR_SINK, 0|FF_TRANS80|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_SINK_SHIELD}, // S_SINK_SHIELD {SPR_SITR, 0, 1, {NULL}, 0, 0, S_SINKTRAIL2}, // S_SINKTRAIL1 @@ -15935,6 +15955,61 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BUBBLESHIELD + -1, // doomednum + S_THUNDERSHIELD1, // 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 + 8, // speed + 20*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_FLAMESHIELD + -1, // doomednum + S_FLAMESHIELD1, // 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 + 8, // speed + 20*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_SINK -1, // doomednum S_SINK, // spawnstate diff --git a/src/info.h b/src/info.h index e2a60e131..a302aa679 100644 --- a/src/info.h +++ b/src/info.h @@ -617,6 +617,8 @@ typedef enum sprite SPR_BHBM, // Ballhog BOOM SPR_SPBM, // Self-Propelled Bomb SPR_THNS, // Thunder Shield + SPR_BUBS, // Bubble Shield (not Bubs) + SPR_FLMS, // Flame Shield SPR_SINK, // Kitchen Sink SPR_SITR, // Kitchen Sink Trail SPR_KBLN, // Battle Mode Bumper @@ -3516,6 +3518,27 @@ typedef enum state S_THUNDERSHIELD23, S_THUNDERSHIELD24, + // Flame Shield + S_FLAMESHIELD1, + S_FLAMESHIELD2, + S_FLAMESHIELD3, + S_FLAMESHIELD4, + S_FLAMESHIELD5, + S_FLAMESHIELD6, + S_FLAMESHIELD7, + S_FLAMESHIELD8, + S_FLAMESHIELD9, + S_FLAMESHIELD10, + S_FLAMESHIELD11, + S_FLAMESHIELD12, + S_FLAMESHIELD13, + S_FLAMESHIELD14, + S_FLAMESHIELD15, + S_FLAMESHIELD16, + S_FLAMESHIELD17, + S_FLAMESHIELD18, + S_FLAMESHIELDDASH, + // The legend S_SINK, S_SINK_SHIELD, @@ -4682,7 +4705,9 @@ typedef enum mobj_type MT_SPB, // SPB stuff MT_SPBEXPLOSION, - MT_THUNDERSHIELD, // Thunder Shield stuff + MT_THUNDERSHIELD, // Shields + MT_BUBBLESHIELD, + MT_FLAMESHIELD, MT_SINK, // Kitchen Sink Stuff MT_SINK_SHIELD, diff --git a/src/k_kart.c b/src/k_kart.c index adce3c111..d0f777daf 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -652,24 +652,26 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value) static INT32 K_KartItemOddsRace[NUMKARTRESULTS][8] = { //P-Odds 0 1 2 3 4 5 6 7 - /*Sneaker*/ { 0, 0, 4, 6, 7, 0, 0, 0 }, // Sneaker - /*Rocket Sneaker*/ { 0, 0, 0, 0, 1, 4, 5, 3 }, // Rocket Sneaker - /*Invincibility*/ { 0, 0, 0, 0, 1, 4, 6,10 }, // Invincibility - /*Banana*/ { 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana + /*Sneaker*/ { 0, 0, 3, 5, 6, 0, 0, 0 }, // Sneaker + /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 2, 4, 6 }, // Rocket Sneaker + /*Invincibility*/ { 0, 0, 0, 0, 1, 4, 8,12 }, // Invincibility + /*Banana*/ { 7, 4, 2, 1, 0, 0, 0, 0 }, // Banana /*Eggman Monitor*/ { 3, 2, 1, 0, 0, 0, 0, 0 }, // Eggman Monitor - /*Orbinaut*/ { 7, 6, 4, 2, 0, 0, 0, 0 }, // Orbinaut + /*Orbinaut*/ { 7, 5, 4, 2, 0, 0, 0, 0 }, // Orbinaut /*Jawz*/ { 0, 3, 2, 1, 1, 0, 0, 0 }, // Jawz /*Mine*/ { 0, 2, 2, 1, 0, 0, 0, 0 }, // Mine /*Ballhog*/ { 0, 0, 2, 1, 0, 0, 0, 0 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 1, 2, 3, 4, 2, 2, 0 }, // Self-Propelled Bomb - /*Grow*/ { 0, 0, 0, 0, 0, 2, 5, 7 }, // Grow + /*Grow*/ { 0, 0, 0, 1, 1, 2, 0, 0 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink /*Thunder Shield*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield + /*Bubble Shield*/ { 0, 0, 0, 0, 0, 0, 0, 0 }, // Bubble Shield + /*Flame Shield*/ { 0, 0, 0, 0, 0, 0, 1, 2 }, // Flame Shield /*Hyudoro*/ { 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring /*Super Ring*/ { 2, 1, 1, 0, 0, 0, 0, 0 }, // Super Ring /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink - /*Sneaker x3*/ { 0, 0, 0, 3, 7, 9, 2, 0 }, // Sneaker x3 + /*Sneaker x3*/ { 0, 0, 0, 2, 6,10, 5, 0 }, // Sneaker x3 /*Banana x3*/ { 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 /*Banana x10*/ { 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10 /*Orbinaut x3*/ { 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3 @@ -693,6 +695,8 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = /*Grow*/ { 0, 0, 1, 2, 4, 2 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0 }, // Shrink /*Thunder Shield*/ { 0, 0, 0, 0, 0, 0 }, // Thunder Shield + /*Bubble Shield*/ { 0, 0, 0, 0, 0, 0 }, // Bubble Shield + /*Flame Shield*/ { 0, 0, 0, 0, 0, 0 }, // Flame Shield /*Hyudoro*/ { 1, 1, 0, 0, 0, 0 }, // Hyudoro /*Pogo Spring*/ { 1, 1, 0, 0, 0, 0 }, // Pogo Spring /*Super Ring*/ { 0, 0, 0, 0, 0, 0 }, // Super Ring @@ -707,6 +711,17 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = #define DISTVAR (64*14) +INT32 K_GetShieldFromItem(INT32 item) +{ + switch (item) + { + case KITEM_THUNDERSHIELD: return KSHIELD_THUNDER; + case KITEM_BUBBLESHIELD: return KSHIELD_BUBBLE; + case KITEM_FLAMESHIELD: return KSHIELD_FLAME; + default: return KSHIELD_NONE; + } +} + /** \brief Item Roulette for Kart \param player player @@ -774,9 +789,10 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp INT32 newodds; INT32 i; UINT8 pingame = 0, pexiting = 0; - boolean thunderisout = false; + boolean shieldout[NUMKARTSHIELDS-1]; SINT8 first = -1, second = -1; INT32 secondist = 0; + INT32 shieldtype = KSHIELD_NONE; boolean itemenabled[NUMKARTRESULTS-1] = { cv_sneaker.value, cv_rocketsneaker.value, @@ -816,6 +832,8 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp // Base multiplication to ALL item odds to simulate fractional precision newodds *= 4; + memset(shieldout, false, sizeof(shieldout)); + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -827,18 +845,16 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp if (players[i].exiting) pexiting++; - if (players[i].mo) - { - if (players[i].kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) - thunderisout = true; + shieldtype = K_GetShieldFromItem(players[i].kartstuff[k_itemtype]); + if (shieldtype != KSHIELD_NONE) + shieldout[shieldtype-1] = true; - if (!G_BattleGametype()) - { - if (players[i].kartstuff[k_position] == 1 && first == -1) - first = i; - if (players[i].kartstuff[k_position] == 2 && second == -1) - second = i; - } + if (players[i].mo && G_RaceGametype()) + { + if (players[i].kartstuff[k_position] == 1 && first == -1) + first = i; + if (players[i].kartstuff[k_position] == 2 && second == -1) + second = i; } } @@ -852,6 +868,11 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp secondist = ((28 + (8-pingame)) * secondist) / 28; } + // Don't allow more than one of each shield type at a time + shieldtype = K_GetShieldFromItem(item); + if (shieldout[shieldtype-1]) + return 0; + // POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items. // First, it multiplies it by 2 if franticitems is true; easy-peasy. // Next, it multiplies it again if it's in SPB mode and 2nd needs to apply pressure to 1st. @@ -889,6 +910,8 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp case KITEM_INVINCIBILITY: case KITEM_MINE: case KITEM_GROW: + case KITEM_BUBBLESHIELD: + case KITEM_FLAMESHIELD: if (COOLDOWNONSTART) newodds = 0; else @@ -907,10 +930,11 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp POWERITEMODDS(newodds); break; case KITEM_THUNDERSHIELD: - if (thunderisout || spbplace != -1) + if (spbplace != -1 || COOLDOWNONSTART) newodds = 0; else POWERITEMODDS(newodds); + break; case KITEM_HYUDORO: if ((hyubgone > 0) || COOLDOWNONSTART) newodds = 0; @@ -1600,11 +1624,16 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur SKINCOLOR_CHERRY }; fixed_t minimumdist = FixedMul(RING_DIST>>1, player->mo->scale); - UINT8 c = FixedMul(CHAOTIXBANDCOLORS<> FRACBITS; UINT8 n = CHAOTIXBANDLEN; UINT8 offset = ((leveltime / 3) % 3); fixed_t stepx, stepy, stepz; fixed_t curx, cury, curz; + UINT8 c; + + if (maxdist == 0) + c = 0; + else + c = FixedMul(CHAOTIXBANDCOLORS<> FRACBITS; stepx = (victim->mo->x - player->mo->x) / CHAOTIXBANDLEN; stepy = (victim->mo->y - player->mo->y) / CHAOTIXBANDLEN; @@ -1656,13 +1685,21 @@ static void K_UpdateDraft(player_t *player) UINT8 leniency; UINT8 i; - // Distance you have to be to draft. If you're still accelerating, then this distance is lessened. - // This distance biases toward low weight! (min weight gets 4096 units, max weight gets 3072 units) - // This distance is also scaled based on game speed. - draftdistance = (3072 + (128 * (9 - player->kartweight))) * player->mo->scale; - if (player->speed < topspd) - draftdistance = FixedMul(draftdistance, FixedDiv(player->speed, topspd)); - draftdistance = FixedMul(draftdistance, K_GetKartGameSpeedScalar(gamespeed)); + if (player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + { + // Flame Shield gets infinite draft distance as its passive effect. + draftdistance = 0; + } + else + { + // Distance you have to be to draft. If you're still accelerating, then this distance is lessened. + // This distance biases toward low weight! (min weight gets 4096 units, max weight gets 3072 units) + // This distance is also scaled based on game speed. + draftdistance = (3072 + (128 * (9 - player->kartweight))) * player->mo->scale; + if (player->speed < topspd) + draftdistance = FixedMul(draftdistance, FixedDiv(player->speed, topspd)); + draftdistance = FixedMul(draftdistance, K_GetKartGameSpeedScalar(gamespeed)); + } // On the contrary, the leniency period biases toward high weight. // (See also: the leniency variable in K_SpawnDraftDust) @@ -1722,7 +1759,7 @@ static void K_UpdateDraft(player_t *player) continue; // Not close enough to draft. - if (dist > draftdistance) + if (dist > draftdistance && draftdistance > 0) continue; #endif @@ -2220,6 +2257,12 @@ static void K_GetKartBoostPower(player_t *player) if (player->kartstuff[k_invincibilitytimer]) // Invincibility ADDBOOST((3*FRACUNIT)/8, 3*FRACUNIT); // + 37.5% top speed, + 300% acceleration + if (player->kartstuff[k_flamedash]) // Flame Shield dash + { + fixed_t dashval = ((player->kartstuff[k_flamedash]<kartstuff[k_startboost]) // Startup Boost ADDBOOST(FRACUNIT/4, 6*FRACUNIT); // + 25% top speed, + 600% acceleration @@ -3842,6 +3885,29 @@ static void K_DoThunderShield(player_t *player) #undef THUNDERRADIUS +static void K_FlameShieldPop(mobj_t *src) +{ + mobj_t *smoke; + UINT8 i; + + //S_StartSound(src, sfx_zio3); + + // spawn vertical bolt + for (i = 0; i < 8; i++) + { + smoke = P_SpawnMobj(src->x, src->y, src->z, MT_SMOKE); + P_SetMobjState(smoke, S_OPAQUESMOKE1); + P_SetScale(smoke, 2*smoke->scale); + smoke->destscale = 8*smoke->scale; + smoke->angle = FixedAngle((i*45)<fuse = P_RandomRange(20, 50); + smoke->momx = src->momx; + smoke->momy = src->momy; + smoke->momz = src->momz + (P_RandomRange(1,4) * smoke->scale); + P_Thrust(smoke, smoke->angle, (P_RandomRange(1,2) * smoke->scale)); + } +} + static void K_DoHyudoroSteal(player_t *player) { INT32 i, numplayers = 0; @@ -3849,6 +3915,10 @@ static void K_DoHyudoroSteal(player_t *player) INT32 stealplayer = -1; // The player that's getting stolen from INT32 prandom = 0; boolean sink = P_RandomChance(FRACUNIT/64); + INT32 hyu = hyudorotime; + + if (G_RaceGametype()) + hyu = (hyu<<1); // double in race for (i = 0; i < MAXPLAYERS; i++) { @@ -4132,11 +4202,18 @@ void K_DropHnextList(player_t *player) flip = P_MobjFlip(player->mo); ponground = P_IsObjectOnGround(player->mo); - if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD && player->kartstuff[k_itemamount]) + if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) { K_DoThunderShield(player); - player->kartstuff[k_itemamount] = 0; player->kartstuff[k_itemtype] = KITEM_NONE; + player->kartstuff[k_itemamount] = 0; + player->kartstuff[k_curshield] = 0; + } + else if (player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + { + //K_PopFlameShield(player); + player->kartstuff[k_itemtype] = KITEM_NONE; + player->kartstuff[k_itemamount] = 0; player->kartstuff[k_curshield] = 0; } @@ -4258,9 +4335,12 @@ void K_DropHnextList(player_t *player) // For getting EXTRA hit! void K_DropItems(player_t *player) { - boolean thunderhack = (player->kartstuff[k_curshield] && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD); + INT32 shieldhack = 0; - if (thunderhack) + if (player->kartstuff[k_curshield]) + shieldhack = K_GetShieldFromItem(player->kartstuff[k_itemtype]); + + if (shieldhack) player->kartstuff[k_itemtype] = KITEM_NONE; K_DropHnextList(player); @@ -4279,7 +4359,13 @@ void K_DropItems(player_t *player) if (drop->eflags & MFE_UNDERWATER) drop->momz = (117 * drop->momz) / 200; - drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]); + switch (shieldhack) + { + case KSHIELD_THUNDER: drop->threshold = KITEM_THUNDERSHIELD; break; + case KSHIELD_BUBBLE: drop->threshold = KITEM_BUBBLESHIELD; break; + case KSHIELD_FLAME: drop->threshold = KITEM_FLAMESHIELD; break; + default: drop->threshold = player->kartstuff[k_itemtype]; break; + } drop->movecount = player->kartstuff[k_itemamount]; drop->flags |= MF_NOCLIPTHING; @@ -5384,6 +5470,14 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) if (player->spectator) return turnvalue; + if (player->kartstuff[k_flamedash]) // Reduce turning + { + fixed_t dashval = ((player->kartstuff[k_flamedash]< FRACUNIT) + return 0; // NO MORE TURNING! + turnvalue = FixedMul(turnvalue, FRACUNIT-dashval); + } + if (player->kartstuff[k_drift] != 0 && P_IsObjectOnGround(player->mo)) { // If we're drifting we have a completely different turning value @@ -5402,7 +5496,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) turnvalue = FixedMul(turnvalue, adjustangle); // Weight has a small effect on turning if (EITHERSNEAKER(player) || player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_growshrinktimer] > 0) - turnvalue = FixedMul(turnvalue, FixedDiv(5*FRACUNIT, 4*FRACUNIT)); + turnvalue = FixedMul(turnvalue, (5*FRACUNIT)/4); return turnvalue; } @@ -6223,14 +6317,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } break; case KITEM_THUNDERSHIELD: - if (player->kartstuff[k_curshield] != 1) + if (player->kartstuff[k_curshield] != KSHIELD_THUNDER) { mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetTarget(&shield->target, player->mo); - S_StartSound(shield, sfx_s3k41); - player->kartstuff[k_curshield] = 1; + S_StartSound(player->mo, sfx_s3k41); + player->kartstuff[k_curshield] = KSHIELD_THUNDER; } + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { K_DoThunderShield(player); @@ -6238,6 +6333,53 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayAttackTaunt(player->mo); } break; + case KITEM_BUBBLESHIELD: + if (player->kartstuff[k_curshield] != KSHIELD_BUBBLE) + { + //mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BUBBLESHIELD); + //P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); + //P_SetTarget(&shield->target, player->mo); + S_StartSound(player->mo, sfx_s3k3f); + player->kartstuff[k_curshield] = KSHIELD_BUBBLE; + } + case KITEM_FLAMESHIELD: + if (player->kartstuff[k_curshield] != KSHIELD_FLAME) + { + mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FLAMESHIELD); + P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); + P_SetTarget(&shield->target, player->mo); + S_StartSound(player->mo, sfx_s3k3e); + player->kartstuff[k_curshield] = KSHIELD_FLAME; + } + + if (!HOLDING_ITEM && NO_HYUDORO) + { + if (cmd->buttons & BT_ATTACK) + { + if (player->kartstuff[k_flameready]) + { + if (player->kartstuff[k_flamedash] == 0) + K_PlayBoostTaunt(player->mo); + player->kartstuff[k_flamedash]++; + } + } + else + { + if (player->kartstuff[k_flamedash] > TICRATE) + { + K_FlameShieldPop(player->mo); + player->kartstuff[k_flamedash] = 0; + player->kartstuff[k_flameready] = 0; + player->kartstuff[k_itemamount]--; + } + else + { + player->kartstuff[k_flamedash] = 0; + player->kartstuff[k_flameready] = 1; + } + } + } + break; case KITEM_HYUDORO: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { @@ -6315,11 +6457,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) { - if ((player->kartstuff[k_rings]+player->kartstuff[k_pickuprings]) < 20 && !player->kartstuff[k_ringlock]) + if (RINGTOTAL(player) < 20 && !player->kartstuff[k_ringlock]) K_LookForRings(player->mo); } - else - player->kartstuff[k_curshield] = 0; + + if (player->kartstuff[k_itemtype] != KITEM_FLAMESHIELD + || player->exiting || player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer]) + { + if (player->kartstuff[k_flamedash]) + K_FlameShieldPop(player->mo); + player->kartstuff[k_flamedash] = 0; + player->kartstuff[k_flameready] = 0; + } + + if (K_GetShieldFromItem(player->kartstuff[k_itemtype]) == KSHIELD_NONE) + player->kartstuff[k_curshield] = KSHIELD_NONE; // RESET shield type if (player->kartstuff[k_itemtype] == KITEM_SPB || player->kartstuff[k_itemtype] == KITEM_SHRINK @@ -6335,7 +6487,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else player->mo->flags2 &= ~MF2_DONTDRAW; - if (player->kartstuff[k_hyudorotimer] >= (1*TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyudorotime-(1*TICRATE/2)) + if (player->kartstuff[k_hyudorotimer] >= (TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyudorotime-(TICRATE/2)) { if (player == &players[displayplayers[1]]) player->mo->eflags |= MFE_DRAWONLYFORP2; @@ -6354,7 +6506,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else { if (P_IsDisplayPlayer(player) - || (!P_IsDisplayPlayer(player) && (player->kartstuff[k_hyudorotimer] < (1*TICRATE/2) || player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)))) + || (!P_IsDisplayPlayer(player) && (player->kartstuff[k_hyudorotimer] < (TICRATE/2) || player->kartstuff[k_hyudorotimer] > hyudorotime-(TICRATE/2)))) { if (leveltime & 1) player->mo->flags2 |= MF2_DONTDRAW; @@ -6877,6 +7029,8 @@ static patch_t *kp_selfpropelledbomb[2]; static patch_t *kp_grow[2]; static patch_t *kp_shrink[2]; static patch_t *kp_thundershield[2]; +static patch_t *kp_bubbleshield[2]; +static patch_t *kp_flameshield[2]; static patch_t *kp_hyudoro[2]; static patch_t *kp_pogospring[2]; static patch_t *kp_kitchensink[2]; @@ -7063,6 +7217,8 @@ void K_LoadKartHUDGraphics(void) kp_grow[0] = W_CachePatchName("K_ITGROW", PU_HUDGFX); kp_shrink[0] = W_CachePatchName("K_ITSHRK", PU_HUDGFX); kp_thundershield[0] = W_CachePatchName("K_ITTHNS", PU_HUDGFX); + kp_bubbleshield[0] = W_CachePatchName("K_ITBUBS", PU_HUDGFX); + kp_flameshield[0] = W_CachePatchName("K_ITFLMS", PU_HUDGFX); kp_hyudoro[0] = W_CachePatchName("K_ITHYUD", PU_HUDGFX); kp_pogospring[0] = W_CachePatchName("K_ITPOGO", PU_HUDGFX); kp_kitchensink[0] = W_CachePatchName("K_ITSINK", PU_HUDGFX); @@ -7093,6 +7249,8 @@ void K_LoadKartHUDGraphics(void) kp_grow[1] = W_CachePatchName("K_ISGROW", PU_HUDGFX); kp_shrink[1] = W_CachePatchName("K_ISSHRK", PU_HUDGFX); kp_thundershield[1] = W_CachePatchName("K_ISTHNS", PU_HUDGFX); + kp_bubbleshield[1] = W_CachePatchName("K_ISBUBS", PU_HUDGFX); + kp_flameshield[1] = W_CachePatchName("K_ISFLMS", PU_HUDGFX); kp_hyudoro[1] = W_CachePatchName("K_ISHYUD", PU_HUDGFX); kp_pogospring[1] = W_CachePatchName("K_ISPOGO", PU_HUDGFX); kp_kitchensink[1] = W_CachePatchName("K_ISSINK", PU_HUDGFX); @@ -7215,6 +7373,10 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny) return (tiny ? "K_ISSHRK" : "K_ITSHRK"); case KITEM_THUNDERSHIELD: return (tiny ? "K_ISTHNS" : "K_ITTHNS"); + case KITEM_BUBBLESHIELD: + return (tiny ? "K_ISBUBS" : "K_ITBUBS"); + case KITEM_FLAMESHIELD: + return (tiny ? "K_ISFLMS" : "K_ITFLMS"); case KITEM_HYUDORO: return (tiny ? "K_ISHYUD" : "K_ITHYUD"); case KITEM_POGOSPRING: @@ -7602,6 +7764,14 @@ static void K_drawKartItem(void) localpatch = kp_thundershield[offset]; localbg = kp_itembg[offset+1]; break; + case KITEM_BUBBLESHIELD: + localpatch = kp_bubbleshield[offset]; + localbg = kp_itembg[offset+1]; + break; + case KITEM_FLAMESHIELD: + localpatch = kp_flameshield[offset]; + localbg = kp_itembg[offset+1]; + break; case KITEM_HYUDORO: localpatch = kp_hyudoro[offset]; break; @@ -8885,8 +9055,8 @@ static void K_drawKartMinimap(void) if (players[i].kartstuff[k_hyudorotimer] > 0) { - if (!((players[i].kartstuff[k_hyudorotimer] < 1*TICRATE/2 - || players[i].kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)) + if (!((players[i].kartstuff[k_hyudorotimer] < TICRATE/2 + || players[i].kartstuff[k_hyudorotimer] > hyudorotime-(TICRATE/2)) && !(leveltime & 1))) continue; } @@ -9439,6 +9609,8 @@ static void K_drawDistributionDebugger(void) kp_grow[1], kp_shrink[1], kp_thundershield[1], + kp_bubbleshield[1], + kp_flameshield[1], kp_hyudoro[1], kp_pogospring[1], kp_superring[1], diff --git a/src/k_kart.h b/src/k_kart.h index b91e8c8a1..ccbb7b55a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -23,6 +23,7 @@ void K_RegisterKartStuff(void); boolean K_IsPlayerLosing(player_t *player); boolean K_IsPlayerWanted(player_t *player); fixed_t K_GetKartGameSpeedScalar(SINT8 value); +INT32 K_GetShieldFromItem(INT32 item); void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); void K_KartPainEnergyFling(player_t *player); void K_FlipFromObject(mobj_t *mo, mobj_t *master); diff --git a/src/p_enemy.c b/src/p_enemy.c index 91268b504..4ee97a59f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3676,7 +3676,7 @@ void A_AttractChase(mobj_t *actor) if (actor->tracer && actor->tracer->player && actor->tracer->health //&& P_CheckSight(actor, actor->tracer) && actor->tracer->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD - && (actor->tracer->player->kartstuff[k_rings]+actor->tracer->player->kartstuff[k_pickuprings]) < 20 + && RINGTOTAL(actor->tracer->player) < 20 && !actor->tracer->player->kartstuff[k_ringlock]) { fixed_t dist; diff --git a/src/p_inter.c b/src/p_inter.c index 8d898f83d..e51fbb39f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -142,8 +142,8 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) || player->kartstuff[k_itemheld]) return false; - if (weapon == 3 && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) - return false; // No stacking thunder shields! + if (weapon == 3 && K_GetShieldFromItem(player->kartstuff[k_itemtype]) != KSHIELD_NONE) + return false; // No stacking shields! } } @@ -629,7 +629,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // kill - if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0) + if (player->kartstuff[k_invincibilitytimer] > 0 + || player->kartstuff[k_growshrinktimer] > 0 + || player->kartstuff[k_flamedash] > 0) { P_KillMobj(special, toucher, toucher); return; @@ -704,7 +706,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // Reached the cap, don't waste 'em! - if ((player->kartstuff[k_rings] + player->kartstuff[k_pickuprings]) >= 20) + if (RINGTOTAL(player) >= 20) return; special->momx = special->momy = special->momz = 0; @@ -3297,8 +3299,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) if (!player) return; - // Has a shield? Don't lose your rings! - if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) + // Have a shield? You get hit, but don't lose your rings! + if (K_GetShieldFromItem(player->kartstuff[k_itemtype]) != KSHIELD_NONE) return; // 20 is the ring cap in kart diff --git a/src/p_map.c b/src/p_map.c index 3dd026ee4..025d84b02 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1452,6 +1452,10 @@ static boolean PIT_CheckThing(mobj_t *thing) P_DamageMobj(thing, tmthing, tmthing, 1); else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) P_DamageMobj(tmthing, thing, thing, 1); + else if (tmthing->player->kartstuff[k_flamedash] && !thing->player->kartstuff[k_flamedash]) // SRB2kart - Then flame shield! + P_DamageMobj(thing, tmthing, tmthing, 1); + else if (thing->player->kartstuff[k_flamedash] && !tmthing->player->kartstuff[k_flamedash]) + P_DamageMobj(tmthing, thing, thing, 1); /*if (G_BattleGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) { diff --git a/src/p_mobj.c b/src/p_mobj.c index be4bf0c1a..96c442d64 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6232,7 +6232,9 @@ void P_RunShadows(void) dest = mobj->target; - if (dest->type == MT_THUNDERSHIELD) + if (dest->type == MT_THUNDERSHIELD + || dest->type == MT_BUBBLESHIELD + || dest->type == MT_FLAMESHIELD) dest = dest->target; P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z); @@ -8362,7 +8364,8 @@ void P_MobjThinker(mobj_t *mobj) case MT_THUNDERSHIELD: { fixed_t destx, desty; - if (!mobj->target || !mobj->target->health || (mobj->target->player && mobj->target->player->kartstuff[k_curshield] != 1)) + if (!mobj->target || !mobj->target->health || !mobj->target->player + || mobj->target->player->kartstuff[k_curshield] != KSHIELD_THUNDER) { P_RemoveMobj(mobj); return; @@ -8381,8 +8384,9 @@ void P_MobjThinker(mobj_t *mobj) else viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, camera[0].x, camera[0].y); - if (curstate > S_THUNDERSHIELD15) + if (curstate > S_THUNDERSHIELD15 && curstate <= S_THUNDERSHIELD24) viewingangle += ANGLE_180; + destx = mobj->target->x + P_ReturnThrustX(mobj->target, viewingangle, mobj->scale>>4); desty = mobj->target->y + P_ReturnThrustY(mobj->target, viewingangle, mobj->scale>>4); } @@ -8395,6 +8399,64 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(mobj, destx, desty, mobj->target->z); break; } + case MT_FLAMESHIELD: + { + fixed_t destx, desty; + statenum_t curstate; + + if (!mobj->target || !mobj->target->health || !mobj->target->player + || mobj->target->player->kartstuff[k_curshield] != KSHIELD_FLAME) + { + P_RemoveMobj(mobj); + return; + } + P_SetScale(mobj, (mobj->destscale = (5*mobj->target->destscale)>>2)); + + curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states))); + + if (mobj->target->player->kartstuff[k_flamedash]) + { + if (curstate != S_FLAMESHIELDDASH) + P_SetMobjState(mobj, S_FLAMESHIELDDASH); + mobj->flags2 ^= MF2_DONTDRAW; + } + else + { + if (curstate == S_FLAMESHIELDDASH) + P_SetMobjState(mobj, S_FLAMESHIELD1); + mobj->flags2 &= ~MF2_DONTDRAW; + } + + if (!splitscreen /*&& rendermode != render_soft*/) + { + angle_t viewingangle; + + if (players[displayplayers[0]].awayviewtics) + viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayers[0]].awayviewmobj->x, players[displayplayers[0]].awayviewmobj->y); + else if (!camera[0].chase && players[displayplayers[0]].mo) + viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y); + else + viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, camera[0].x, camera[0].y); + + if (curstate >= S_FLAMESHIELD1 && curstate < S_FLAMESHIELDDASH && ((curstate-S_FLAMESHIELD1) & 1)) + viewingangle += ANGLE_180; + + destx = mobj->target->x + P_ReturnThrustX(mobj->target, viewingangle, mobj->scale>>4); + desty = mobj->target->y + P_ReturnThrustY(mobj->target, viewingangle, mobj->scale>>4); + } + else + { + destx = mobj->target->x; + desty = mobj->target->y; + } + + P_TeleportMove(mobj, destx, desty, mobj->target->z); + if (mobj->target->momx || mobj->target->momy) + mobj->angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); + else + mobj->angle = mobj->target->angle; + break; + } case MT_ROCKETSNEAKER: if (!mobj->target || !mobj->target->health) { @@ -10116,7 +10178,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: case MT_SSMINE: case MT_SSMINE_SHIELD: case MT_BALLHOG: case MT_SINK: - case MT_THUNDERSHIELD: case MT_ROCKETSNEAKER: + case MT_THUNDERSHIELD: case MT_BUBBLESHIELD: case MT_FLAMESHIELD: + case MT_ROCKETSNEAKER: case MT_SPB: P_SpawnShadowMobj(mobj); default: diff --git a/src/p_user.c b/src/p_user.c index bd2e8ee28..7e2b13023 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1083,7 +1083,7 @@ void P_PlayLivesJingle(player_t *player) void P_PlayRinglossSound(mobj_t *source) { - if (source->player && source->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) + if (source->player && K_GetShieldFromItem(source->player->kartstuff[k_itemtype]) != KSHIELD_NONE) S_StartSound(source, sfx_s1a3); // Shield hit (no ring loss) else if (source->player && source->player->kartstuff[k_rings] <= 0) S_StartSound(source, sfx_s1a6); // Ring debt (lessened ring loss)