diff --git a/src/k_battle.c b/src/k_battle.c index d77ab0432..42343002e 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,18 +277,45 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +void K_CheckEmeralds(player_t *player) +{ + UINT8 i; + + if (!ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + { + return; + } + + player->marescore++; // lol + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (&players[i] == player) + { + continue; + } + + players[i].bumpers = 0; + } + + K_CheckBumpers(); +} + mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) { boolean validEmerald = true; mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); - emerald->angle = angle; - P_Thrust(emerald, FixedAngle(P_RandomFixed() * 180) + angle, - 16*mapobjectscale); + 32 * mapobjectscale); - emerald->momz = flip * 3 * mapobjectscale; + emerald->momz = flip * 24 * mapobjectscale; if (emerald->eflags & MFE_UNDERWATER) emerald->momz = (117 * emerald->momz) / 200; @@ -331,6 +358,25 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em return emerald; } +void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) +{ + UINT8 i; + SINT8 flip = P_MobjFlip(player->mo); + + for (i = 0; i < 14; i++) + { + UINT32 emeraldFlag = (1 << i); + + if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) + { + mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle, flip, emeraldFlag); + P_SetTarget(&emerald->target, player->mo); + + player->powers[pw_emeralds] &= ~emeraldFlag; + } + } +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); diff --git a/src/k_battle.h b/src/k_battle.h index 346e57c48..c83cd7e04 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,7 +20,9 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +void K_CheckEmeralds(player_t *player); mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); +void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); diff --git a/src/p_inter.c b/src/p_inter.c index 2b91278df..e8157543f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -421,26 +421,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->powers[pw_emeralds] |= special->extravalue1; - - if (ALLCHAOSEMERALDS(player->powers[pw_emeralds])) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (&players[i] == player) - { - continue; - } - - players[i].bumpers = 0; - } - - K_CheckBumpers(); - } + K_CheckEmeralds(player); break; /* case MT_EERIEFOG: @@ -1680,6 +1661,8 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } + K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1909,9 +1892,23 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { K_PlayHitEmSound(source); K_StealBumper(source->player, player, bumpadd); + + if (damagetype & DMG_STEAL) + { + // Give them ALL of your emeralds :) + source->player->powers[pw_emeralds] |= player->powers[pw_emeralds]; + player->powers[pw_emeralds] = 0; + K_CheckEmeralds(source->player); + } } K_RemoveBumper(player, inflictor, source, bumpadd, false); + + if (!(damagetype & DMG_STEAL)) + { + // Drop all of your emeralds + K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + } } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; diff --git a/src/p_mobj.c b/src/p_mobj.c index cc3bc3a9b..dd8aef239 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1163,6 +1163,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_EGGMANITEM: case MT_SSMINE: case MT_SINK: + case MT_EMERALD: if (mo->extravalue2 > 0) gravityadd *= mo->extravalue2; gravityadd = (5*gravityadd)/2; @@ -2081,7 +2082,6 @@ boolean P_ZMovement(mobj_t *mo) case MT_BALLHOG: case MT_SSMINE: case MT_BUBBLESHIELDTRAP: - case MT_EMERALD: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -2089,6 +2089,7 @@ boolean P_ZMovement(mobj_t *mo) return false; } break; + case MT_REDFLAG: case MT_BLUEFLAG: // Remove from death pits. DON'T FUCKING DESPAWN IT DAMMIT @@ -2099,6 +2100,20 @@ boolean P_ZMovement(mobj_t *mo) } break; + case MT_EMERALD: + if (P_CheckDeathPitCollide(mo)) + { + P_RemoveMobj(mo); + return false; + } + + if (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) + { + // Stop when hitting the floor + mo->momx = mo->momy = 0; + } + break; + case MT_RING: // Ignore still rings case MT_BLUESPHERE: case MT_FLINGRING: @@ -8877,7 +8892,6 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: - case MT_EMERALD: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: @@ -8904,6 +8918,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_RING: case MT_FLOATINGITEM: case MT_BLUESPHERE: + case MT_EMERALD: thing->shadowscale = FRACUNIT/2; break; case MT_DRIFTCLIP: