diff --git a/src/d_player.h b/src/d_player.h index 371b315f..0b392a06 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -319,6 +319,7 @@ typedef enum k_invincibilitytimer, // Invincibility timer k_deathsentence, // 30 seconds to live... (SPB murder timer (not actually 30 sec, I just couldn't help the FF reference :p)) 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_bananadrag, // After a second of holding a banana behind you, you start to slow down k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam") k_wipeoutslow, // Timer before you slowdown when getting wiped out diff --git a/src/dehacked.c b/src/dehacked.c index f73f1385..62f878f3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7679,12 +7679,10 @@ static const char *const KARTSTUFF_LIST[] = { "ITEMROULETTE", "ROULETTETYPE", - // Item held stuff "ITEMTYPE", "ITEMAMOUNT", "ITEMHELD", - // Some items use timers for their duration or effects //"THUNDERANIM", "CURSHIELD", "HYUDOROTIMER", @@ -7697,6 +7695,7 @@ static const char *const KARTSTUFF_LIST[] = { "INVINCIBILITYTIMER", "DEATHSENTENCE", "EGGMANHELD", + "EGGMANEXPLODE", "BANANADRAG", "SPINOUTTIMER", "WIPEOUTSLOW", @@ -7704,7 +7703,6 @@ static const char *const KARTSTUFF_LIST[] = { "COMEBACKTIMER", "SADTIMER", - // Battle Mode vars "BUMPER", "COMEBACKPOINTS", "COMEBACKMODE", diff --git a/src/k_kart.c b/src/k_kart.c index cc51c7b5..fcb0b4ca 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -784,11 +784,24 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_ATTACK) player->pflags |= PF_ATTACKDOWN; + if (player->kartstuff[k_roulettetype] == 2) // Fake items + { + player->kartstuff[k_eggmanexplode] = 4*TICRATE; + player->kartstuff[k_itemroulette] = 0; + player->kartstuff[k_roulettetype] = 0; + if (P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_mkitmF); + return; + } + if (cv_kartdebugitem.value != 0) { K_KartGetItemResult(player, cv_kartdebugitem.value); player->kartstuff[k_itemamount] = cv_kartdebugamount.value; player->kartstuff[k_itemroulette] = 0; + player->kartstuff[k_roulettetype] = 0; + if (P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_mkitmF); return; } @@ -3162,6 +3175,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_instashield]) player->kartstuff[k_instashield]--; + if (player->kartstuff[k_eggmanexplode]) + { + player->kartstuff[k_eggmanexplode]--; + if (player->kartstuff[k_eggmanexplode] <= 0) + { + /*mobj_t *eggsexplode; + eggsexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); + P_SetTarget(&eggsexplode->target, player->mo);*/ + P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); + } + } + // ??? /* if (player->kartstuff[k_jmp] > 1 && onground) @@ -3638,6 +3663,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) newitem->fuse = 15*TICRATE; // selected randomly. newitem->threshold = 69; // selected "randomly". } + // Eggman Monitor exploding + else if (player->kartstuff[k_eggmanexplode]) + { + if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanexplode] <= 3*TICRATE && player->kartstuff[k_eggmanexplode] > 1) + player->kartstuff[k_eggmanexplode] = 1; + } // Eggman Monitor throwing else if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanheld]) { @@ -4893,6 +4924,13 @@ static void K_drawKartItem(void) { localpatch = kp_hyudoro[offset]; } + else if (stplyr->kartstuff[k_eggmanexplode] > 1) + { + if (leveltime & 1) + localpatch = kp_eggman[offset]; + else if (!(leveltime & 1)) + localpatch = kp_nodraw; + } else if (stplyr->kartstuff[k_rocketsneakertimer] > 1) { if (leveltime & 1) @@ -4963,6 +5001,15 @@ static void K_drawKartItem(void) } else V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); + + // Quick hack + if (stplyr->kartstuff[k_eggmanexplode] > 1) + { + if (splitscreen > 1) + V_DrawString(ITEM_X+12, ITEM_Y+12, V_HUDTRANS|splitflags, va("%d", G_TicsToSeconds(stplyr->kartstuff[k_eggmanexplode]))); + else + V_DrawKartString(ITEM_X+18, ITEM_Y+18, V_HUDTRANS|splitflags, va("%d", G_TicsToSeconds(stplyr->kartstuff[k_eggmanexplode]))); + } } static void K_drawKartTimestamp(void) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d74b16e3..7c44c796 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1315,7 +1315,7 @@ static int lib_pPlayLivesJingle(lua_State *L) static int lib_pCanPickupItem(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - boolean weapon = lua_optboolean(L, 2); + UINT8 weapon = (UINT8)luaL_optinteger(L, 2, 0); //HUDSAFE if (!player) return LUA_ErrInvalid(L, "player_t"); diff --git a/src/p_inter.c b/src/p_inter.c index 6e7e1bf4..f6417303 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -150,7 +150,7 @@ void P_ResetStarposts(void) // // Returns true if the player is in a state where they can pick up items. // -boolean P_CanPickupItem(player_t *player, boolean weapon) +boolean P_CanPickupItem(player_t *player, UINT8 weapon) { if (player->exiting || mapreset) return false; @@ -161,10 +161,11 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) if (weapon) { if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] - || player->kartstuff[k_growshrinktimer] != 0 || player->kartstuff[k_rocketsneakertimer]) // Item-specific timer going off + || player->kartstuff[k_growshrinktimer] != 0 || player->kartstuff[k_rocketsneakertimer] + || player->kartstuff[k_eggmanexplode]) // Item-specific timer going off return false; - if (player->kartstuff[k_itemroulette] + if ((player->kartstuff[k_itemroulette] && weapon != 2) || player->kartstuff[k_itemamount] || player->kartstuff[k_itemheld]) // Item slot already taken up return false; @@ -407,7 +408,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) switch (special->type) { case MT_RANDOMITEM: // SRB2kart - if (!P_CanPickupItem(player, true)) + if (!P_CanPickupItem(player, 1)) return; if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) @@ -465,7 +466,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) K_ExplodePlayer(player, special->target); } } - else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, true)) + else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1)) { mobj_t *poof = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_EXPLODE); S_StartSound(poof, special->info->seesound); @@ -496,7 +497,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) /* FALLTHRU */ case MT_RING: case MT_FLINGRING: - if (!(P_CanPickupItem(player, false))) + if (!(P_CanPickupItem(player, 0))) return; special->momx = special->momy = special->momz = 0; @@ -508,7 +509,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_COIN: case MT_FLINGCOIN: - if (!(P_CanPickupItem(player, false))) + if (!(P_CanPickupItem(player, 0))) return; special->momx = special->momy = 0; @@ -518,7 +519,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DoNightsScore(player); break; case MT_BLUEBALL: - if (!(P_CanPickupItem(player, false))) + if (!(P_CanPickupItem(player, 0))) return; P_GivePlayerRings(player, 1); @@ -539,7 +540,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_GRENADEPICKUP: case MT_EXPLODEPICKUP: case MT_RAILPICKUP: - if (!(P_CanPickupItem(player, true))) + if (!(P_CanPickupItem(player, 1))) return; // Give the power and ringweapon @@ -563,7 +564,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_GRENADERING: case MT_EXPLOSIONRING: case MT_RAILRING: - if (!(P_CanPickupItem(player, true))) + if (!(P_CanPickupItem(player, 1))) return; if (special->info->mass >= pw_infinityring && special->info->mass <= pw_railring) @@ -651,7 +652,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Power stones / Match emeralds case MT_FLINGEMERALD: - if (!(P_CanPickupItem(player, true)) || player->tossdelay) + if (!(P_CanPickupItem(player, 1)) || player->tossdelay) return; player->powers[pw_emeralds] |= special->threshold; @@ -3326,16 +3327,13 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (inflictor && (inflictor->type == MT_ORBINAUT || inflictor->type == MT_ORBINAUT_SHIELD || inflictor->type == MT_JAWZ || inflictor->type == MT_JAWZ_SHIELD || inflictor->type == MT_JAWZ_DUD - || inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD || inflictor->player)) { player->kartstuff[k_sneakertimer] = 0; - K_SpinPlayer(player, source, 1, (inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD)); + K_SpinPlayer(player, source, 1, false); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); - if (inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD) - player->mo->momx = player->mo->momy = 0; if (P_IsLocalPlayer(player)) { quake.intensity = 32*FRACUNIT; diff --git a/src/p_local.h b/src/p_local.h index 3bf98bee..7d7342bc 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -409,7 +409,7 @@ boolean P_CheckRacers(void); void P_ClearStarPost(INT32 postnum); void P_ResetStarposts(void); -boolean P_CanPickupItem(player_t *player, boolean weapon); +boolean P_CanPickupItem(player_t *player, UINT8 weapon); void P_DoNightsScore(player_t *player); // diff --git a/src/p_map.c b/src/p_map.c index 52ab6154..2bf39940 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1036,7 +1036,17 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->type == MT_PLAYER) { // Player Damage - P_DamageMobj(thing, tmthing, tmthing->target, 1); + { + mobj_t *poof = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_EXPLODE); + S_StartSound(poof, sfx_kc2e); + } + + if (P_CanPickupItem(thing->player, 2)) + { + if (thing->player->kartstuff[k_itemroulette] <= 0) + thing->player->kartstuff[k_itemroulette] = 1; + thing->player->kartstuff[k_roulettetype] = 2; + } // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -1045,10 +1055,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmthing->z += tmthing->height; S_StartSound(tmthing, tmthing->info->deathsound); - P_KillMobj(tmthing, thing, thing); - - P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); - P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + P_RemoveMobj(tmthing); } return true; @@ -1111,12 +1118,12 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // underneath if (tmthing->player && tmthing->player->powers[pw_flashing] - && !(thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)) + && !(thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + || thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM)) return true; if (thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD - || thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD - || thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM) + || thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD) { if ((thing->target == tmthing) && (thing->threshold > 0)) return true; @@ -1126,9 +1133,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // Player Damage P_DamageMobj(tmthing, thing, thing->target, 1); - - if (thing->type != MT_FAKESHIELD && thing->type != MT_FAKEITEM) - K_KartBouncing(tmthing, thing, false, false); + K_KartBouncing(tmthing, thing, false, false); if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD) S_StartSound(tmthing, sfx_shelit); @@ -1145,6 +1150,36 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(thing, 8*FRACUNIT, false); P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); } + else if (thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM) + { + if ((thing->target == tmthing) && (thing->threshold > 0)) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + // Player Damage + { + mobj_t *poof = P_SpawnMobj(thing->x, thing->y, thing->z, MT_EXPLODE); + S_StartSound(poof, sfx_kc2e); + } + + if (P_CanPickupItem(tmthing->player, 2)) + { + if (tmthing->player->kartstuff[k_itemroulette] <= 0) + tmthing->player->kartstuff[k_itemroulette] = 1; + tmthing->player->kartstuff[k_roulettetype] = 2; + } + + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_RemoveMobj(thing); + } else if (thing->type == MT_BANANA_SHIELD || thing->type == MT_BANANA || thing->type == MT_BALLHOG) {