From 4de68f7fe2e10346c3fe9a43bf00ce2606bbb545 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 6 Sep 2018 22:17:29 +0100 Subject: [PATCH] Dropping items! * Shield Drop... * Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.) * Pops your Thunder Shield. * Happens upon ANY hit, except for deathpits. * HUD Drop... * Also does the above, except for the Thunder Shield thing. * If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item! * You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type. * Happens upon Size Down and battle elimination. * Can also be forced on with `cv_kartdebughuddrop on`! * Some other random stuff. * Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity. * Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter). * Allow shrunken players to pick up item boxes again. * Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.) * Break NiGHTS a little through my machinations. --- src/d_netcmd.c | 1 + src/d_netcmd.h | 2 +- src/dehacked.c | 3 + src/info.c | 29 ++++++ src/info.h | 3 + src/k_kart.c | 268 ++++++++++++++++++++++++++++++++++++++++--------- src/k_kart.h | 6 +- src/p_inter.c | 38 +++++-- src/p_map.c | 2 +- src/p_mobj.c | 202 +++++++++++++++++++++++++++---------- src/sounds.c | 1 + src/sounds.h | 1 + 12 files changed, 446 insertions(+), 110 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8e046d92..c9343b07 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -370,6 +370,7 @@ static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 3f118944..97dac8a9 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -133,7 +133,7 @@ extern consvar_t cv_karteliminatelast; extern consvar_t cv_votetime; -extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution; +extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugcheckpoint; extern consvar_t cv_itemfinder; diff --git a/src/dehacked.c b/src/dehacked.c index 3473eb87..78d6c4df 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6233,6 +6233,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RANDOMITEMPOP4", //} + "S_ITEMICON", + // Drift Sparks "S_DRIFTSPARK1", "S_DRIFTSPARK2", @@ -7208,6 +7210,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BLUEDIAG", "MT_RANDOMITEM", "MT_RANDOMITEMPOP", + "MT_FLOATINGITEM", "MT_SNEAKERTRAIL", "MT_SPARKLETRAIL", diff --git a/src/info.c b/src/info.c index 60cac109..75a7655f 100644 --- a/src/info.c +++ b/src/info.c @@ -2566,6 +2566,8 @@ state_t states[NUMSTATES] = {SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3 {SPR_RPOP, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL}, // S_RANDOMITEMPOP4 + {SPR_NULL, 0|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON + {SPR_DRIF, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK2}, // S_DRIFTSPARK1 {SPR_DRIF, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK3}, // S_DRIFTSPARK2 {SPR_DRIF, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK1}, // S_DRIFTSPARK3 @@ -14390,6 +14392,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FLOATINGITEM + -1, // doomednum + S_ITEMICON, // spawnstate + 1, // 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_mcitm1, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_NULL // raisestate + }, + { // MT_SNEAKERTRAIL -1, // doomednum S_KARTFIRE1, // spawnstate diff --git a/src/info.h b/src/info.h index 736fdfde..ad876dc7 100644 --- a/src/info.h +++ b/src/info.h @@ -3078,6 +3078,8 @@ typedef enum state S_RANDOMITEMPOP4, //} + S_ITEMICON, + // Drift Sparks S_DRIFTSPARK1, S_DRIFTSPARK2, @@ -4070,6 +4072,7 @@ typedef enum mobj_type MT_BLUEDIAG, MT_RANDOMITEM, MT_RANDOMITEMPOP, + MT_FLOATINGITEM, MT_SNEAKERTRAIL, MT_SPARKLETRAIL, diff --git a/src/k_kart.c b/src/k_kart.c index 40956016..0c75635b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -414,6 +414,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebugamount); CV_RegisterVar(&cv_kartdebugshrink); CV_RegisterVar(&cv_kartdebugdistribution); + CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebugcheckpoint); } @@ -1101,7 +1102,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) fx->eflags |= MFE_VERTICALFLIP; else fx->eflags &= ~MFE_VERTICALFLIP; - fx->scale = mobj1->scale; + P_SetScale(fx, mobj1->scale); // Because this is done during collision now, rmomx and rmomy need to be recalculated // so that friction doesn't immediately decide to stop the player if they're at a standstill @@ -1715,6 +1716,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem P_SetPlayerMobjState(player->mo, S_KART_SPIN); player->kartstuff[k_instashield] = 15; + if (cv_kartdebughuddrop.value) + K_DropItems(player); + else + K_DropHnextList(player); return; } @@ -1784,6 +1789,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source) P_PlayRinglossSound(player->mo); player->kartstuff[k_instashield] = 15; + if (cv_kartdebughuddrop.value) + K_DropItems(player); + else + K_DropHnextList(player); return; } @@ -1861,6 +1870,10 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju } player->kartstuff[k_instashield] = 15; + if (cv_kartdebughuddrop.value) + K_DropItems(player); + else + K_DropHnextList(player); return; } @@ -1936,6 +1949,10 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force) victim->kartstuff[k_comebacktimer] = comebacktime;*/ victim->kartstuff[k_instashield] = 15; + if (cv_kartdebughuddrop.value) + K_DropItems(victim); + else + K_DropHnextList(victim); return; } @@ -2043,14 +2060,14 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) { dust = P_SpawnMobj(source->x, source->y, source->z, MT_SMOKE); dust->angle = (ANGLE_180/16) * i; - dust->scale = source->scale; + P_SetScale(dust, source->scale); dust->destscale = source->scale*10; P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, source->scale)); truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, source->y + P_RandomRange(-radius, radius)*FRACUNIT, source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMEXPLODE); - truc->scale = source->scale*2; + P_SetScale(truc, source->scale); truc->destscale = source->scale*6; speed = FixedMul(10*FRACUNIT, source->scale)>>FRACBITS; truc->momx = P_RandomRange(-speed, speed)*FRACUNIT; @@ -2065,7 +2082,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) dust = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, source->y + P_RandomRange(-radius, radius)*FRACUNIT, source->z + P_RandomRange(0, height)*FRACUNIT, MT_SMOKE); - dust->scale = source->scale; + P_SetScale(dust, source->scale); dust->destscale = source->scale*10; dust->tics = 30; dust->momz = P_RandomRange(FixedMul(3*FRACUNIT, source->scale)>>FRACBITS, FixedMul(7*FRACUNIT, source->scale)>>FRACBITS)*FRACUNIT; @@ -2073,7 +2090,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT, source->y + P_RandomRange(-radius, radius)*FRACUNIT, source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMPARTICLE); - truc->scale = source->scale; + P_SetScale(truc, source->scale); truc->destscale = source->scale*5; speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS; truc->momx = P_RandomRange(-speed, speed)*FRACUNIT; @@ -2350,7 +2367,7 @@ void K_DriftDustHandling(mobj_t *spawner) dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<momz = P_MobjFlip(spawner) * P_RandomRange(1, 4)<scale = spawner->scale/2; + P_SetScale(dust, spawner->scale/2); dust->destscale = spawner->scale * 3; if (leveltime % 6 == 0) @@ -2808,46 +2825,190 @@ killnext: } // Just for firing/dropping items. -void K_CleanHnextList(mobj_t *work) -{ - mobj_t *nextwork; - - if (!work) - return; - - work = work->hnext; - - while (work && !P_MobjWasRemoved(work)) - { - nextwork = work->hnext; - - P_RemoveMobj(work); - - work = nextwork; - } -} - -// Ditto. -void K_UpdateHnextList(player_t *player) +void K_UpdateHnextList(player_t *player, boolean clean) { mobj_t *work = player->mo, *nextwork; if (!work) return; - work = work->hnext; + nextwork = work->hnext; - while (work && !P_MobjWasRemoved(work)) + while ((work = nextwork) && !P_MobjWasRemoved(work)) { nextwork = work->hnext; - if (work->movedir > 0 && work->movedir > (UINT16)player->kartstuff[k_itemamount]) - P_RemoveMobj(work); + if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount])) + continue; - work = nextwork; + P_RemoveMobj(work); } } +// For getting hit! +void K_DropHnextList(player_t *player) +{ + mobj_t *work = player->mo, *nextwork, *dropwork; + INT32 flip; + mobjtype_t type; + boolean orbit, ponground; + + if (!work) + return; + + flip = P_MobjFlip(player->mo); + ponground = P_IsObjectOnGround(player->mo); + + if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD && player->kartstuff[k_itemamount]) + { + K_DoThunderShield(player); + player->kartstuff[k_itemamount] = 0; + player->kartstuff[k_itemtype] = KITEM_NONE; + } + + nextwork = work->hnext; + + while ((work = nextwork) && !P_MobjWasRemoved(work)) + { + nextwork = work->hnext; + + switch (work->type) + { + // Kart orbit items + case MT_ORBINAUT_SHIELD: + orbit = true; + type = MT_ORBINAUT; + break; + case MT_JAWZ_SHIELD: + orbit = true; + type = MT_JAWZ_DUD; + break; + // Kart trailing items + case MT_BANANA_SHIELD: + orbit = false; + type = MT_BANANA; + break; + case MT_SSMINE_SHIELD: + orbit = false; + type = MT_SSMINE; + break; + case MT_FAKESHIELD: + orbit = false; + type = MT_FAKEITEM; + break; + // intentionally do nothing + case MT_SINK_SHIELD: + return; + default: + continue; + } + + dropwork = P_SpawnMobj(work->x, work->y, work->z, type); + P_SetTarget(&dropwork->target, player->mo); + dropwork->angle = work->angle; + dropwork->flags2 = work->flags2; + dropwork->flags |= MF_NOCLIPTHING; + dropwork->floorz = work->floorz; + dropwork->ceilingz = work->ceilingz; + + if (ponground) + { + // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn + // This should set it for FOFs + //P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing + + if (flip == 1) + { + if (dropwork->floorz > dropwork->target->z - dropwork->height) + { + dropwork->z = dropwork->floorz; + } + } + else + { + if (dropwork->ceilingz < dropwork->target->z + dropwork->target->height + dropwork->height) + { + dropwork->z = dropwork->ceilingz - dropwork->height; + } + } + } + + if (orbit) // splay out + { + dropwork->flags2 |= MF2_AMBUSH; + dropwork->z += flip; + dropwork->momx = player->mo->momx>>1; + dropwork->momy = player->mo->momy>>1; + dropwork->momz = 3*flip*mapheaderinfo[gamemap-1]->mobj_scale; + P_Thrust(dropwork, work->angle - ANGLE_90, 6*(mapheaderinfo[gamemap-1]->mobj_scale)); + dropwork->movecount = 2; + dropwork->movedir = work->angle - ANGLE_90; + P_SetMobjState(dropwork, dropwork->info->deathstate); + dropwork->tics = -1; + if (type == MT_JAWZ_DUD) + dropwork->z += 20*flip*dropwork->scale; + else + { + dropwork->color = work->color; + dropwork->angle -= ANGLE_90; + } + } + else // plop on the ground + { + dropwork->flags &= ~MF_NOCLIPTHING; + dropwork->threshold = 10; + } + + P_RemoveMobj(work); + } + + { + // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... + P_SetTarget(&player->mo->hnext, NULL); + player->kartstuff[k_bananadrag] = 0; + if (player->kartstuff[k_eggmanheld]) + player->kartstuff[k_eggmanheld] = 0; + else if (player->kartstuff[k_itemheld]) + { + player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; + player->kartstuff[k_itemtype] = KITEM_NONE; + } + } +} + +// For getting EXTRA hit! +void K_DropItems(player_t *player) +{ + boolean thunderhack = (player->kartstuff[k_curshield] && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD); + + if (thunderhack) + player->kartstuff[k_itemtype] = KITEM_NONE; + + K_DropHnextList(player); + + if (player->mo && player->kartstuff[k_itemamount]) + { + mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM); + P_SetScale(drop, drop->scale>>5); + drop->destscale = (3*drop->destscale)/2;; + + drop->angle = player->mo->angle + ANGLE_90; + drop->momx = player->mo->momx>>1; + drop->momy = player->mo->momy>>1; + P_Thrust(drop, + FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90, + 8*(mapheaderinfo[gamemap-1]->mobj_scale)); + drop->momz = P_MobjFlip(player->mo)*3*(mapheaderinfo[gamemap-1]->mobj_scale); + + drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]); + drop->movecount = player->kartstuff[k_itemamount]; + + drop->flags |= MF_NOCLIPTHING; + } + + K_StripItems(player); +} + // When an item in the hnext chain dies. void K_RepairOrbitChain(mobj_t *orbit) { @@ -3859,20 +4020,18 @@ static void K_KartUpdatePosition(player_t *player) // void K_StripItems(player_t *player) { - player->kartstuff[k_itemtype] = 0; + player->kartstuff[k_itemtype] = KITEM_NONE; player->kartstuff[k_itemamount] = 0; player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_roulettetype] = 0; - player->kartstuff[k_rocketsneakertimer] = 0; - player->kartstuff[k_invincibilitytimer] = 0; - player->kartstuff[k_growshrinktimer] = 0; + if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2) + { + player->kartstuff[k_itemroulette] = 0; + player->kartstuff[k_roulettetype] = 0; + } player->kartstuff[k_eggmanheld] = 0; - player->kartstuff[k_eggmanexplode] = 0; - player->kartstuff[k_eggmanblame] = 0; player->kartstuff[k_hyudorotimer] = 0; player->kartstuff[k_stealingtimer] = 0; @@ -3884,7 +4043,19 @@ void K_StripItems(player_t *player) player->kartstuff[k_sadtimer] = 0; - K_CleanHnextList(player->mo); + K_UpdateHnextList(player, true); +} + +void K_StripOther(player_t *player) +{ + player->kartstuff[k_itemroulette] = 0; + player->kartstuff[k_roulettetype] = 0; + + player->kartstuff[k_invincibilitytimer] = 0; + player->kartstuff[k_growshrinktimer] = 0; + + player->kartstuff[k_eggmanexplode] = 0; + player->kartstuff[k_eggmanblame] = 0; } // @@ -3950,7 +4121,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_ThrowKartItem(player, false, MT_FAKEITEM, -1, 0); K_PlayTauntSound(player->mo); player->kartstuff[k_eggmanheld] = 0; - K_CleanHnextList(player->mo); + K_UpdateHnextList(player, true); } // Rocket Sneaker else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO @@ -4037,7 +4208,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_ThrowKartItem(player, false, MT_BANANA, -1, 0); K_PlayTauntSound(player->mo); player->kartstuff[k_itemamount]--; - K_UpdateHnextList(player); + K_UpdateHnextList(player, false); } break; case KITEM_EGGMAN: @@ -4097,7 +4268,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0); K_PlayTauntSound(player->mo); player->kartstuff[k_itemamount]--; - K_UpdateHnextList(player); + K_UpdateHnextList(player, false); } break; case KITEM_JAWZ: @@ -4140,7 +4311,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, 0); K_PlayTauntSound(player->mo); player->kartstuff[k_itemamount]--; - K_UpdateHnextList(player); + K_UpdateHnextList(player, false); } break; case KITEM_MINE: @@ -4166,7 +4337,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayTauntSound(player->mo); player->kartstuff[k_itemamount]--; player->kartstuff[k_itemheld] = 0; - K_CleanHnextList(player->mo); + K_UpdateHnextList(player, true); } break; case KITEM_BALLHOG: @@ -4293,7 +4464,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayTauntSound(player->mo); player->kartstuff[k_itemamount]--; player->kartstuff[k_itemheld] = 0; - K_CleanHnextList(player->mo); + K_UpdateHnextList(player, true); } break; case KITEM_SAD: @@ -4372,7 +4543,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb { - K_StripItems(player); + K_DropItems(player); //K_StripItems(player); + K_StripOther(player); player->mo->flags2 |= MF2_SHADOW; player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; } diff --git a/src/k_kart.h b/src/k_kart.h index 9865d373..bbef6c00 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -39,14 +39,16 @@ void K_DriftDustHandling(mobj_t *spawner); void K_DoSneaker(player_t *player, boolean doPFlag); void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute); void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source); -void K_CleanHnextList(mobj_t *work); -void K_UpdateHnextList(player_t *player); +void K_UpdateHnextList(player_t *player, boolean clean); +void K_DropHnextList(player_t *player); void K_RepairOrbitChain(mobj_t *orbit); player_t *K_FindJawzTarget(mobj_t *actor, player_t *source); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); fixed_t K_GetKartDriftSparkValue(player_t *player); +void K_DropItems(player_t *player); void K_StripItems(player_t *player); +void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); fixed_t K_GetKartAccel(player_t *player); diff --git a/src/p_inter.c b/src/p_inter.c index 7e35731a..c8d42b23 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -181,13 +181,13 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) { // Item-specific timer going off if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] - || player->kartstuff[k_growshrinktimer] != 0 || player->kartstuff[k_rocketsneakertimer] + || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_rocketsneakertimer] || player->kartstuff[k_eggmanexplode]) return false; // Item slot already taken up if (player->kartstuff[k_itemroulette] - || player->kartstuff[k_itemamount] + || (weapon != 3 && player->kartstuff[k_itemamount]) || player->kartstuff[k_itemheld]) return false; } @@ -429,6 +429,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // We now identify by object type, not sprite! Tails 04-11-2001 switch (special->type) { + case MT_FLOATINGITEM: // SRB2kart + if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) + return; + + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) + return; + + player->kartstuff[k_itemtype] = special->threshold; + player->kartstuff[k_itemamount] += special->movecount; + if (player->kartstuff[k_itemamount] > 255) + player->kartstuff[k_itemamount] = 255; + + S_StartSound(special, special->info->deathsound); + + P_SetTarget(&special->tracer, toucher); + special->flags2 |= MF2_NIGHTSPULL; + special->destscale = mapheaderinfo[gamemap-1]->mobj_scale>>5; + special->scalespeed <<= 1; + + special->flags &= ~MF_SPECIAL; + return; case MT_RANDOMITEM: // SRB2kart if (!P_CanPickupItem(player, 1)) return; @@ -469,9 +490,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE); S_StartSound(poof, special->info->deathsound); - K_StripItems(player); - if (player->kartstuff[k_itemroulette] <= 0) - player->kartstuff[k_itemroulette] = 1; + K_DropItems(player); //K_StripItems(player); + K_StripOther(player); + player->kartstuff[k_itemroulette] = 1; player->kartstuff[k_roulettetype] = 2; if (special->target && special->target->player && (G_RaceGametype() || special->target->player->kartstuff[k_bumper] > 0)) @@ -2626,6 +2647,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) } } + if ((target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD) && !(target->flags2 & MF2_AMBUSH)) + { + target->z += P_MobjFlip(target)*20*target->scale; + } + if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL) { const fixed_t x=target->x,y=target->y,z=target->z; @@ -3335,6 +3361,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->mo->destscale = 6*player->mo->destscale/8; // Wipeout + K_DropItems(player); K_SpinPlayer(player, source, 1, false); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); @@ -3346,7 +3373,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da quake.time = 5; } - K_StripItems(player); player->kartstuff[k_growshrinktimer] -= (200+(40*(16-player->kartstuff[k_position]))); } // Grow? Let's take that away. diff --git a/src/p_map.c b/src/p_map.c index 88045a3e..c97ee909 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -497,7 +497,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE))) + if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)) || (thing->flags & MF_NOCLIPTHING)) return true; // Don't collide with your buddies while NiGHTS-flying. diff --git a/src/p_mobj.c b/src/p_mobj.c index fb6eed54..dc4ac036 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6006,7 +6006,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y return; // change angle - source->angle = R_PointToAngle2(source->x, source->y, tx, ty); + //source->angle = R_PointToAngle2(source->x, source->y, tx, ty); // change slope dist = P_AproxDistance(P_AproxDistance(tx - source->x, ty - source->y), tz - source->z); @@ -6015,7 +6015,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y dist = 1; if (nightsgrab) - speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); + speedmul = P_AproxDistance(dest->momx, dest->momy) + source->scale; else speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); @@ -6348,6 +6348,9 @@ void P_RunShadows(void) break; } } + + if (mobj->target->type == MT_FLOATINGITEM) + P_SetScale(mobj, mobj->scale/2); } P_SetTarget(&shadowcap, NULL); } @@ -6727,7 +6730,7 @@ void P_MobjThinker(mobj_t *mobj) /*if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->health > 0 && !mobj->target->player->spectator) { - // Was this so hard? -- Handled this with K_UpdateHnextList and K_ClearHnextList instead of thinking it away... + // Was this so hard? -- Handled this with K_UpdateHnextList instead of thinking it away... if ((mobj->type == MT_ORBINAUT_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT) || (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ) || (mobj->movedir > 0 && ((UINT16)mobj->target->player->kartstuff[k_itemamount] < mobj->movedir)) @@ -6911,14 +6914,16 @@ void P_MobjThinker(mobj_t *mobj) mobj->x = mobj->target->x; mobj->y = mobj->target->y; + mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's + if (!(mobj->target->eflags & MFE_VERTICALFLIP)) { - mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT; + mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+(16+11)*mapheaderinfo[gamemap-1]->mobj_scale; mobj->eflags &= ~MFE_VERTICALFLIP; } else { - mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT; + mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+(16+11)*mapheaderinfo[gamemap-1]->mobj_scale; mobj->eflags |= MFE_VERTICALFLIP; } P_SetThingPosition(mobj); @@ -6934,7 +6939,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->tracer = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); P_SetTarget(&mobj->tracer->target, mobj); P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); - P_SetScale(mobj->tracer, mobj->scale); + P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later + P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale)); } if (!(mobj->flags2 & MF2_DONTDRAW)) @@ -7027,7 +7033,7 @@ void P_MobjThinker(mobj_t *mobj) else { P_SetMobjState(mobj, S_PLAYERARROW); - P_SetMobjState(mobj->tracer, S_INVISIBLE); + P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later } mobj->tracer->destscale = scale; @@ -7097,12 +7103,12 @@ void P_MobjThinker(mobj_t *mobj) if (!(mobj->target->eflags & MFE_VERTICALFLIP)) { - mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale)); + mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*mapheaderinfo[gamemap-1]->mobj_scale+(64*mobj->scale)); mobj->eflags &= ~MFE_VERTICALFLIP; } else { - mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale)); + mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*mapheaderinfo[gamemap-1]->mobj_scale+(64*mobj->scale)); mobj->eflags |= MFE_VERTICALFLIP; } P_SetThingPosition(mobj); @@ -8007,46 +8013,120 @@ void P_MobjThinker(mobj_t *mobj) mobj->threshold = 0; } break; - case MT_ORBINAUT: + case MT_FLOATINGITEM: { - sector_t *sec2; - fixed_t finalspeed = mobj->info->speed; - - P_SpawnGhostMobj(mobj); - - if (gamespeed == 0) - finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); - else if (gamespeed == 2) - finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4); - - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - if (mobj->health <= 5) + if (mobj->flags & MF_NOCLIPTHING) { - INT32 i; - for (i = 5; i >= mobj->health; i--) + if (P_IsObjectOnGround(mobj)) { - finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); + mobj->momx = 1; + mobj->momy = 0; + mobj->flags &= ~MF_NOCLIPTHING; + mobj->flags |= MF_NOGRAVITY; } - finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale); - P_InstaThrust(mobj, mobj->angle, finalspeed); } else { - finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale); - P_InstaThrust(mobj, mobj->angle, finalspeed); + mobj->angle += 2*ANG2; + if (mobj->flags2 & MF2_NIGHTSPULL) + { + if (!mobj->tracer || !mobj->tracer->health + || mobj->scale <= mapheaderinfo[gamemap-1]->mobj_scale>>5) + { + P_RemoveMobj(mobj); + return; + } + P_Attract(mobj, mobj->tracer, true); + } + else + { + fixed_t adj = FixedMul(FRACUNIT - FINECOSINE((mobj->movedir>>ANGLETOFINESHIFT) & FINEMASK), (mapheaderinfo[gamemap-1]->mobj_scale<<3)); + mobj->movedir += 2*ANG2; + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->ceilingz - mobj->height - adj; + else + mobj->z = mobj->floorz + adj; + } } - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, false); + switch (mobj->threshold) + { + case KITEM_ORBINAUT: + mobj->sprite = SPR_ITMO; + mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(min(mobj->movecount-1, 3)); + break; + case KITEM_INVINCIBILITY: + mobj->sprite = SPR_ITMI; + mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|((leveltime % (7*3)) / 3); + break; + case KITEM_SAD: + mobj->sprite = SPR_ITEM; + mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE; + break; + default: + mobj->sprite = SPR_ITEM; + mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(mobj->threshold); + break; + } + break; + } + case MT_ORBINAUT: + { + boolean grounded = P_IsObjectOnGround(mobj); + if (mobj->flags2 & MF2_AMBUSH) + { + if (grounded && (mobj->flags & MF_NOCLIPTHING)) + { + mobj->momx = 1; + mobj->momy = 0; + mobj->frame = 3; + S_StartSound(mobj, mobj->info->activesound); + mobj->flags &= ~MF_NOCLIPTHING; + } + else if (mobj->movecount) + mobj->movecount--; + else if (mobj->frame < 3) + { + mobj->movecount = 2; + mobj->frame++; + } + } + else + { + fixed_t finalspeed = mobj->info->speed; - if (mobj->threshold > 0) - mobj->threshold--; + P_SpawnGhostMobj(mobj); - if (leveltime % 6 == 0) - S_StartSound(mobj, mobj->info->activesound); + if (gamespeed == 0) + finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); + else if (gamespeed == 2) + finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4); + + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + if (mobj->health <= 5) + { + INT32 i; + for (i = 5; i >= mobj->health; i--) + finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); + } + finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale); + P_InstaThrust(mobj, mobj->angle, finalspeed); + + if (grounded) + { + sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); + if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) + || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) + && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + K_DoPogoSpring(mobj, 0, false); + } + + if (mobj->threshold > 0) + mobj->threshold--; + + if (leveltime % 6 == 0) + S_StartSound(mobj, mobj->info->activesound); + } break; } case MT_JAWZ: @@ -8119,23 +8199,38 @@ void P_MobjThinker(mobj_t *mobj) } case MT_JAWZ_DUD: { - sector_t *sec2; + boolean grounded = P_IsObjectOnGround(mobj); + if (mobj->flags2 & MF2_AMBUSH) + { + if (grounded && (mobj->flags & MF_NOCLIPTHING)) + { + mobj->momx = 1; + mobj->momy = 0; + S_StartSound(mobj, mobj->info->deathsound); + mobj->flags &= ~MF_NOCLIPTHING; + } + } + else + { + P_SpawnGhostMobj(mobj); + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + P_InstaThrust(mobj, mobj->angle, mobj->info->speed); - P_SpawnGhostMobj(mobj); - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_InstaThrust(mobj, mobj->angle, mobj->info->speed); + if (grounded) + { + sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); + if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) + || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) + && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + K_DoPogoSpring(mobj, 0, false); + } - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, false); + if (mobj->threshold > 0) + mobj->threshold--; - if (mobj->threshold > 0) - mobj->threshold--; - - if (leveltime % TICRATE == 0) - S_StartSound(mobj, mobj->info->activesound); + if (leveltime % TICRATE == 0) + S_StartSound(mobj, mobj->info->activesound); + } break; } @@ -9155,6 +9250,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BIGMACE: case MT_SMALLMACE: case MT_FALLINGROCK: //case MT_RANDOMITEM: + case MT_FLOATINGITEM: case MT_BATTLEBUMPER: case MT_BANANA: case MT_BANANA_SHIELD: //case MT_FAKEITEM: case MT_FAKESHIELD: @@ -9254,6 +9350,8 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster) if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN) mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale; + P_SetScale(mobj, mobj->destscale); + // set subsector and/or block links P_SetThingPosition(mobj); I_Assert(mobj->subsector != NULL); diff --git a/src/sounds.c b/src/sounds.c index 6e956260..b68c8afa 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -811,6 +811,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"noooo1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"noooo2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"hogbom", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, + {"mcitm1", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"dbgsal", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // SRB2kart - Skin sounds diff --git a/src/sounds.h b/src/sounds.h index 2f073273..86319c33 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -883,6 +883,7 @@ typedef enum sfx_noooo1, sfx_noooo2, sfx_hogbom, + sfx_mcitm1, sfx_dbgsal, sfx_kwin,