diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a87d04cb5..46a033bb3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -351,6 +351,7 @@ consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR|CV_C consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7e36b6585..bd435c49e 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -66,7 +66,7 @@ extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_ingamecap, cv_res // SRB2kart items extern consvar_t cv_superring, cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana; -extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine; +extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine, cv_landmine; extern consvar_t cv_ballhog, cv_selfpropelledbomb, cv_grow, cv_shrink; extern consvar_t cv_thundershield, cv_bubbleshield, cv_flameshield; extern consvar_t cv_hyudoro, cv_pogospring, cv_kitchensink; diff --git a/src/d_player.h b/src/d_player.h index 1d71668f4..db1777b0f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -245,17 +245,18 @@ Run this macro, then #undef FOREACH afterward FOREACH (ORBINAUT, 6),\ FOREACH (JAWZ, 7),\ FOREACH (MINE, 8),\ - FOREACH (BALLHOG, 9),\ - FOREACH (SPB, 10),\ - FOREACH (GROW, 11),\ - FOREACH (SHRINK, 12),\ - FOREACH (THUNDERSHIELD, 13),\ - FOREACH (BUBBLESHIELD, 14),\ - FOREACH (FLAMESHIELD, 15),\ - FOREACH (HYUDORO, 16),\ - FOREACH (POGOSPRING, 17),\ - FOREACH (SUPERRING, 18),\ - FOREACH (KITCHENSINK, 19) + FOREACH (LANDMINE, 9),\ + FOREACH (BALLHOG, 10),\ + FOREACH (SPB, 11),\ + FOREACH (GROW, 12),\ + FOREACH (SHRINK, 13),\ + FOREACH (THUNDERSHIELD, 14),\ + FOREACH (BUBBLESHIELD, 15),\ + FOREACH (FLAMESHIELD, 16),\ + FOREACH (HYUDORO, 17),\ + FOREACH (POGOSPRING, 18),\ + FOREACH (SUPERRING, 19),\ + FOREACH (KITCHENSINK, 20) typedef enum { diff --git a/src/dehacked.c b/src/dehacked.c index 471499c5c..bb34ebd13 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8520,6 +8520,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SLOWBOOM9", "S_SLOWBOOM10", + // Land Mine + "S_LANDMINE", + "S_LANDMINE_EXPLODE", + // Ballhog "S_BALLHOG1", "S_BALLHOG2", @@ -10154,6 +10158,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BOOMEXPLODE", "MT_BOOMPARTICLE", + "MT_LANDMINE", // Land Mine + "MT_BALLHOG", // Ballhog "MT_BALLHOGBOOM", diff --git a/src/info.c b/src/info.c index c797c9283..9fda6292a 100644 --- a/src/info.c +++ b/src/info.c @@ -543,6 +543,7 @@ char sprnames[NUMSPRITES + 1][5] = "JAWZ", // Jawz "SSMN", // SS Mine "KRBM", // SS Mine BOOM + "LNDM", // Land Mine "BHOG", // Ballhog "BHBM", // Ballhog BOOM "SPBM", // Self-Propelled Bomb @@ -4209,6 +4210,9 @@ state_t states[NUMSTATES] = {SPR_KRBM, FF_FULLBRIGHT|8, 5, {NULL}, 0, 0, S_SLOWBOOM10}, // S_SLOWBOOM9 {SPR_KRBM, FF_FULLBRIGHT|9, 5, {NULL}, 0, 0, S_NULL}, // S_SLOWBOOM10 + {SPR_LNDM, 0, -1, {NULL}, 0, 0, S_LANDMINE}, // S_LANDMINE + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_LANDMINE_EXPLODE + {SPR_BHOG, 0, 3, {A_PlaySound}, sfx_s1bd, 1, S_BALLHOG2}, // S_BALLHOG1 {SPR_BHOG, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOG3}, // S_BALLHOG2 {SPR_BHOG, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_BALLHOG4}, // S_BALLHOG3 @@ -23842,6 +23846,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_LANDMINE + -1, // doomednum + S_LANDMINE, // spawnstate + 2, // spawnhealth + S_NULL, // seestate + sfx_tossed, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_LANDMINE_EXPLODE, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_s3k5c, // activesound + MF_SHOOTABLE|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_BALLHOG -1, // doomednum S_BALLHOG1, // spawnstate diff --git a/src/info.h b/src/info.h index 8e8a05ca3..af2778b62 100644 --- a/src/info.h +++ b/src/info.h @@ -814,6 +814,7 @@ typedef enum sprite SPR_JAWZ, // Jawz SPR_SSMN, // SS Mine SPR_KRBM, // SS Mine BOOM + SPR_LNDM, // Land Mine SPR_BHOG, // Ballhog SPR_BHBM, // Ballhog BOOM SPR_SPBM, // Self-Propelled Bomb @@ -4363,6 +4364,10 @@ typedef enum state S_SLOWBOOM9, S_SLOWBOOM10, + // Land mine + S_LANDMINE, + S_LANDMINE_EXPLODE, + // Ballhog S_BALLHOG1, S_BALLHOG2, @@ -6037,6 +6042,8 @@ typedef enum mobj_type MT_BOOMEXPLODE, MT_BOOMPARTICLE, + MT_LANDMINE, // Land Mine + MT_BALLHOG, // Ballhog MT_BALLHOGBOOM, diff --git a/src/k_botitem.c b/src/k_botitem.c index ce56b9b6e..a871c2305 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -1036,6 +1036,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) K_BotItemSneaker(player, cmd); break; case KITEM_BANANA: + case KITEM_LANDMINE: if (!player->kartstuff[k_itemheld]) { K_BotItemGenericTrapShield(player, cmd, turnamt, false); diff --git a/src/k_botsearch.c b/src/k_botsearch.c index d5a08d2ad..5d6425127 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -589,6 +589,7 @@ static boolean K_BotSteerObjects(mobj_t *thing) case MT_JAWZ_SHIELD: case MT_SSMINE: case MT_SSMINE_SHIELD: + case MT_LANDMINE: case MT_BALLHOG: case MT_SPB: case MT_BUBBLESHIELDTRAP: diff --git a/src/k_collide.c b/src/k_collide.c index 0f2361062..1adb1a694 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -68,7 +68,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) damageitem = true; } - else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE) + else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE) { damageitem = true; // Bomb death @@ -158,6 +158,12 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) damageitem = true; } + else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE) + { + damageitem = true; + // Bomb death + P_KillMobj(t2, t1, t1, DMG_NORMAL); + } else if (t2->flags & MF_SHOOTABLE) { // Shootable damage @@ -325,6 +331,73 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) return true; } +boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) +{ + if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0))) + return true; + + if (t1->health <= 0 || t2->health <= 0) + return true; + + if (t2->player) + { + if (t2->player->powers[pw_flashing]) + return true; + + // Banana snipe! + if (t1->health > 1) + S_StartSound(t2, sfx_bsnipe); + + if (t2->player->kartstuff[k_flamedash] && t2->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) + { + // Melt item + S_StartSound(t2, sfx_s3k43); + } + else + { + // Player Damage + P_DamageMobj(t2, t1, t1->target, 1, DMG_TUMBLE); + } + + P_KillMobj(t1, t2, t2, DMG_NORMAL); + } + else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD + || t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD + || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_JAWZ_SHIELD + || t2->type == MT_BALLHOG) + { + // Other Item Damage + if (t2->eflags & MFE_VERTICALFLIP) + t2->z -= t2->height; + else + t2->z += t2->height; + + S_StartSound(t2, t2->info->deathsound); + P_KillMobj(t2, t1, t1, DMG_NORMAL); + + P_SetObjectMomZ(t2, 8*FRACUNIT, false); + P_InstaThrust(t2, R_PointToAngle2(t1->x, t1->y, t2->x, t2->y)+ANGLE_90, 16*FRACUNIT); + + P_SpawnMobj(t2->x/2 + t1->x/2, t2->y/2 + t1->y/2, t2->z/2 + t1->z/2, MT_ITEMCLASH); + + P_KillMobj(t1, t2, t2, DMG_NORMAL); + } + else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE) + { + P_KillMobj(t1, t2, t2, DMG_NORMAL); + // Bomb death + P_KillMobj(t2, t1, t1, DMG_NORMAL); + } + else if (t2->flags & MF_SHOOTABLE) + { + // Shootable damage + P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); + P_KillMobj(t1, t2, t2, DMG_NORMAL); + } + + return true; +} + boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) { if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0))) diff --git a/src/k_collide.h b/src/k_collide.h index 75a9404f8..e005bc497 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -9,6 +9,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2); boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2); boolean K_MineCollide(mobj_t *t1, mobj_t *t2); boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); +boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); diff --git a/src/k_hud.c b/src/k_hud.c index 42c7fd7c2..63ecce767 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -111,6 +111,7 @@ static patch_t *kp_eggman[2]; static patch_t *kp_orbinaut[5]; static patch_t *kp_jawz[2]; static patch_t *kp_mine[2]; +static patch_t *kp_landmine[2]; static patch_t *kp_ballhog[2]; static patch_t *kp_selfpropelledbomb[2]; static patch_t *kp_grow[2]; @@ -386,6 +387,7 @@ void K_LoadKartHUDGraphics(void) } kp_jawz[0] = W_CachePatchName("K_ITJAWZ", PU_HUDGFX); kp_mine[0] = W_CachePatchName("K_ITMINE", PU_HUDGFX); + kp_landmine[0] = W_CachePatchName("K_ITLNDM", PU_HUDGFX); kp_ballhog[0] = W_CachePatchName("K_ITBHOG", PU_HUDGFX); kp_selfpropelledbomb[0] = W_CachePatchName("K_ITSPB", PU_HUDGFX); kp_grow[0] = W_CachePatchName("K_ITGROW", PU_HUDGFX); @@ -435,6 +437,7 @@ void K_LoadKartHUDGraphics(void) kp_orbinaut[4] = W_CachePatchName("K_ISORBN", PU_HUDGFX); kp_jawz[1] = W_CachePatchName("K_ISJAWZ", PU_HUDGFX); kp_mine[1] = W_CachePatchName("K_ISMINE", PU_HUDGFX); + kp_landmine[1] = W_CachePatchName("K_ISLNDM", PU_HUDGFX); kp_ballhog[1] = W_CachePatchName("K_ISBHOG", PU_HUDGFX); kp_selfpropelledbomb[1] = W_CachePatchName("K_ISSPB", PU_HUDGFX); kp_grow[1] = W_CachePatchName("K_ISGROW", PU_HUDGFX); @@ -611,6 +614,8 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny) return (tiny ? "K_ISJAWZ" : "K_ITJAWZ"); case KITEM_MINE: return (tiny ? "K_ISMINE" : "K_ITMINE"); + case KITEM_LANDMINE: + return (tiny ? "K_ISLNDM" : "K_ITLNDM"); case KITEM_BALLHOG: return (tiny ? "K_ISBHOG" : "K_ITBHOG"); case KITEM_SPB: @@ -961,6 +966,10 @@ static void K_drawKartItem(void) localpatch = kp_superring[offset]; //localcolor = SKINCOLOR_GOLD; break; + case 15: // Land Mine + localpatch = kp_landmine[offset]; + //localcolor = SKINCOLOR_JET; + break; /*case 15: // Pogo Spring localpatch = kp_pogospring[offset]; localcolor = SKINCOLOR_TANGERINE; @@ -1046,6 +1055,9 @@ static void K_drawKartItem(void) case KITEM_MINE: localpatch = kp_mine[offset]; break; + case KITEM_LANDMINE: + localpatch = kp_landmine[offset]; + break; case KITEM_BALLHOG: localpatch = kp_ballhog[offset]; break; @@ -3722,6 +3734,7 @@ static void K_drawDistributionDebugger(void) kp_orbinaut[4], kp_jawz[1], kp_mine[1], + kp_landmine[1], kp_ballhog[1], kp_selfpropelledbomb[1], kp_grow[1], diff --git a/src/k_kart.c b/src/k_kart.c index 26a878679..6cc0e2c93 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -151,6 +151,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_orbinaut); CV_RegisterVar(&cv_jawz); CV_RegisterVar(&cv_mine); + CV_RegisterVar(&cv_landmine); CV_RegisterVar(&cv_ballhog); CV_RegisterVar(&cv_selfpropelledbomb); CV_RegisterVar(&cv_grow); @@ -252,6 +253,7 @@ consvar_t *KartItemCVars[NUMKARTRESULTS-1] = &cv_orbinaut, &cv_jawz, &cv_mine, + &cv_landmine, &cv_ballhog, &cv_selfpropelledbomb, &cv_grow, @@ -281,11 +283,12 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = /*Sneaker*/ { 0, 0, 2, 4, 6, 0, 0, 0 }, // Sneaker /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 2, 4, 6 }, // Rocket Sneaker /*Invincibility*/ { 0, 0, 0, 0, 2, 4, 6, 9 }, // Invincibility - /*Banana*/ { 7, 3, 1, 0, 0, 0, 0, 0 }, // Banana - /*Eggman Monitor*/ { 3, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor + /*Banana*/ { 6, 3, 1, 0, 0, 0, 0, 0 }, // Banana + /*Eggman Monitor*/ { 2, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor /*Orbinaut*/ { 7, 4, 2, 2, 0, 0, 0, 0 }, // Orbinaut /*Jawz*/ { 0, 3, 2, 1, 1, 0, 0, 0 }, // Jawz /*Mine*/ { 0, 2, 3, 1, 0, 0, 0, 0 }, // Mine + /*Land Mine*/ { 2, 0, 0, 0, 0, 0, 0, 0 }, // Land 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, 1, 2, 3, 0, 0 }, // Grow @@ -317,6 +320,7 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = /*Orbinaut*/ { 8, 0 }, // Orbinaut /*Jawz*/ { 8, 1 }, // Jawz /*Mine*/ { 4, 1 }, // Mine + /*Land Mine*/ { 0, 0 }, // Land Mine /*Ballhog*/ { 2, 1 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb /*Grow*/ { 2, 1 }, // Grow @@ -525,6 +529,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, case KITEM_ORBINAUT: case KITEM_JAWZ: case KITEM_MINE: + case KITEM_LANDMINE: case KITEM_BALLHOG: case KITEM_SPB: case KITEM_GROW: @@ -553,6 +558,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, { case KITEM_ROCKETSNEAKER: case KITEM_JAWZ: + case KITEM_LANDMINE: case KITEM_BALLHOG: case KRITEM_TRIPLESNEAKER: case KRITEM_TRIPLEBANANA: @@ -4201,6 +4207,40 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) S_StartSound(mo, (sound == 1 ? sfx_kc2f : sfx_kpogos)); } +static void K_ThrowLandMine(player_t *player) +{ + mobj_t *landMine; + mobj_t *throwmo; + + landMine = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_LANDMINE); + K_FlipFromObject(landMine, player->mo); + landMine->threshold = 10; + + if (landMine->info->seesound) + S_StartSound(player->mo, landMine->info->seesound); + + P_SetTarget(&landMine->target, player->mo); + + P_SetScale(landMine, player->mo->scale); + landMine->destscale = player->mo->destscale; + + landMine->angle = player->mo->angle; + + landMine->momz = (30 * mapobjectscale * P_MobjFlip(player->mo)) + player->mo->momz; + landMine->color = player->skincolor; + + throwmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FIREDITEM); + P_SetTarget(&throwmo->target, player->mo); + // Ditto: + if (player->mo->eflags & MFE_VERTICALFLIP) + { + throwmo->z -= player->mo->height; + throwmo->eflags |= MFE_VERTICALFLIP; + } + + throwmo->movecount = 0; // above player +} + void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source) { mobj_t *cachenext; @@ -7469,6 +7509,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_UpdateHnextList(player, true); } break; + case KITEM_LANDMINE: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + player->kartstuff[k_itemamount]--; + K_ThrowLandMine(player); + K_PlayAttackTaunt(player->mo); + } + break; case KITEM_BALLHOG: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { diff --git a/src/p_inter.c b/src/p_inter.c index 7d47599ae..1a5064f76 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1821,7 +1821,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player) // Player is the target { const UINT8 type = (damagetype & DMG_TYPEMASK); - const boolean combo = (type == DMG_EXPLODE); // This damage type can be comboed from other damage + const boolean combo = (type == DMG_EXPLODE || type == DMG_TUMBLE); // This damage type can be comboed from other damage INT16 ringburst = 5; if (player->pflags & PF_GODMODE) @@ -1943,7 +1943,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_PlayerRingBurst(player, ringburst); K_PlayPainSound(player->mo); - if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking)) + if ((combo == true) || (cv_kartdebughuddrop.value && !modeattacking)) { K_DropItems(player); } diff --git a/src/p_map.c b/src/p_map.c index a8b0ae784..07995e9bf 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -725,7 +725,7 @@ static boolean PIT_CheckThing(mobj_t *thing) || (thing->player && thing->player->kartstuff[k_bubbleblowup])) && (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD || tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG - || tmthing->type == MT_SSMINE || tmthing->type == MT_SINK + || tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK || (tmthing->type == MT_PLAYER && thing->target != tmthing))) { // see if it went over / under @@ -783,7 +783,7 @@ static boolean PIT_CheckThing(mobj_t *thing) || (tmthing->player && tmthing->player->kartstuff[k_bubbleblowup])) && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD || thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG - || thing->type == MT_SSMINE || thing->type == MT_SINK + || thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK || (thing->type == MT_PLAYER && tmthing->target != thing))) { // see if it went over / under @@ -928,6 +928,27 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_MineExplosionCollide(thing, tmthing); } + if (tmthing->type == MT_LANDMINE) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + return K_LandMineCollide(tmthing, thing); + } + else if (thing->type == MT_LANDMINE) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + return K_LandMineCollide(thing, tmthing); + } + if (tmthing->type == MT_SINK) { // see if it went over / under diff --git a/src/p_mobj.c b/src/p_mobj.c index 4d443cea2..403bd82d6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1168,6 +1168,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_BANANA: case MT_EGGMANITEM: case MT_SSMINE: + case MT_LANDMINE: case MT_SINK: if (mo->extravalue2 > 0) gravityadd *= mo->extravalue2; @@ -2092,6 +2093,7 @@ boolean P_ZMovement(mobj_t *mo) case MT_JAWZ_DUD: case MT_BALLHOG: case MT_SSMINE: + case MT_LANDMINE: case MT_BUBBLESHIELDTRAP: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) @@ -4478,7 +4480,8 @@ boolean P_IsKartItem(INT32 type) type == MT_JAWZ || type == MT_JAWZ_DUD || type == MT_JAWZ_SHIELD || type == MT_SSMINE || type == MT_SSMINE_SHIELD || type == MT_SINK || type == MT_SINK_SHIELD || - type == MT_SPB || type == MT_BALLHOG || type == MT_BUBBLESHIELDTRAP) + type == MT_SPB || type == MT_BALLHOG || type == MT_BUBBLESHIELDTRAP || + type == MT_LANDMINE) return true; else return false; @@ -5759,6 +5762,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) case MT_ORBINAUT: case MT_BANANA: case MT_EGGMANITEM: + case MT_LANDMINE: case MT_SPB: if (P_IsObjectOnGround(mobj)) { @@ -6369,6 +6373,25 @@ static boolean P_MobjRegularThink(mobj_t *mobj) || (mobj->state >= &states[S_SSMINE_DEPLOY8] && mobj->state <= &states[S_SSMINE_DEPLOY13])) A_GrenadeRing(mobj); + if (mobj->threshold > 0) + mobj->threshold--; + break; + case MT_LANDMINE: + mobj->friction = ORIG_FRICTION/4; + + if (mobj->momx || mobj->momy || mobj->momz) + { + mobj_t *ghost = P_SpawnGhostMobj(mobj); + ghost->colorized = true; // already has color! + } + + if (P_IsObjectOnGround(mobj) && mobj->health > 1) + { + S_StartSound(mobj, mobj->info->activesound); + mobj->momx = mobj->momy = 0; + mobj->health = 1; + } + if (mobj->threshold > 0) mobj->threshold--; break; @@ -8508,7 +8531,8 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->type == MT_BANANA || mobj->type == MT_EGGMANITEM || mobj->type == MT_ORBINAUT || mobj->type == MT_BALLHOG || mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD - || mobj->type == MT_SSMINE || mobj->type == MT_BUBBLESHIELDTRAP) + || mobj->type == MT_SSMINE || mobj->type == MT_BUBBLESHIELDTRAP + || mobj->type == MT_LANDMINE) { if (mobj->health > 0 && P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) { @@ -8889,6 +8913,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_JAWZ_SHIELD: case MT_SSMINE: case MT_SSMINE_SHIELD: + case MT_LANDMINE: case MT_BALLHOG: case MT_SINK: case MT_ROCKETSNEAKER: diff --git a/src/p_user.c b/src/p_user.c index c294d3f64..61c7c5e8a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2169,6 +2169,9 @@ void P_MovePlayer(player_t *player) UINT8 rollSpeed = max(1, min(8, player->tumbleHeight / 10)); + if (player->tumbleLastBounce == true) + spinSpeed = 2; + P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); player->drawangle -= (ANGLE_11hh * spinSpeed); @@ -2176,6 +2179,9 @@ void P_MovePlayer(player_t *player) if (player->tumbleLastBounce == true) { + if (abs((signed)(player->mo->angle - player->drawangle)) < ANGLE_22h) + player->drawangle = player->mo->angle; + if (abs((signed)player->mo->rollangle) < ANGLE_22h) player->mo->rollangle = 0; }