From 0de25ce771a7870b5298a23b7cf2407b44736cec Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 9 Aug 2020 15:15:52 -0400 Subject: [PATCH] Merge p_inter.c --- src/p_inter.c | 3349 ++----------------------------------------------- 1 file changed, 109 insertions(+), 3240 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index d0b6c4a98..bc4092373 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -27,18 +27,13 @@ #include "m_cheat.h" // objectplace #include "m_misc.h" #include "v_video.h" // video flags for CEchos -<<<<<<< HEAD -#include "k_kart.h" // SRB2kart +#include "f_finale.h" + +// SRB2kart +#include "k_kart.h" #include "k_battle.h" #include "k_pwrlv.h" -// CTF player names -#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" -#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : "" -======= -#include "f_finale.h" ->>>>>>> srb2/next - // CTF player names #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" #define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : "" @@ -103,40 +98,6 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End) // GET STUFF // -<<<<<<< HEAD -======= -/** Makes sure all previous starposts are cleared. - * For instance, hitting starpost 5 will clear starposts 1 through 4, even if - * you didn't touch them. This is how the classic games work, although it can - * lead to bizarre situations on levels that allow you to make a circuit. - * - * \param postnum The number of the starpost just touched. - */ -void P_ClearStarPost(INT32 postnum) -{ - thinker_t *th; - mobj_t *mo2; - - // scan the thinkers - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_STARPOST) - continue; - - if (mo2->health > postnum) - continue; - - P_SetMobjState(mo2, mo2->info->seestate); - } - return; -} - ->>>>>>> srb2/next // // P_CanPickupItem // @@ -147,15 +108,8 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (player->exiting || mapreset) return false; -<<<<<<< HEAD /*if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // No bumpers in Match return false;*/ -======= - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; ->>>>>>> srb2/next if (weapon) { @@ -166,7 +120,6 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (player->powers[pw_flashing] > 0) return false; -<<<<<<< HEAD // Already have fake if (player->kartstuff[k_roulettetype] == 2 || player->kartstuff[k_eggmanexplode]) @@ -190,172 +143,10 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) return false; // No stacking shields! } } -======= - if (post->type != MT_STARPOST) - continue; - - P_SetMobjState(post, post->info->spawnstate); - } -} - -// -// P_CanPickupItem -// -// Returns true if the player is in a state where they can pick up items. -// -boolean P_CanPickupItem(player_t *player, boolean weapon) -{ - if (!player->mo || player->mo->health <= 0) - return false; - - if (player->bot) - { - if (weapon) - return false; - return P_CanPickupItem(&players[consoleplayer], true); // weapon is true to prevent infinite recursion if p1 is bot - doesn't occur in vanilla, but may be relevant for mods - } - - if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] < UINT16_MAX) - return false; ->>>>>>> srb2/next return true; } -// -// P_DoNightsScore -// -// When you pick up some items in nights, it displays -// a score sign, and awards you some drill time. -// -void P_DoNightsScore(player_t *player) -{ - mobj_t *dummymo; - - if (player->exiting) - return; // Don't do any fancy shit for failures. - - dummymo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z+player->mo->height/2, MT_NIGHTSCORE); - - if (G_IsSpecialStage(gamemap)) // Global link count? Maybe not a good idea... - { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - { - if (++players[i].linkcount > players[i].maxlink) - players[i].maxlink = players[i].linkcount; - players[i].linktimer = nightslinktics; - } - } - else // Individual link counts - { - if (++player->linkcount > player->maxlink) - player->maxlink = player->linkcount; - player->linktimer = nightslinktics; - } - - if (player->linkcount < 10) - { - if (player->bonustime) - { - P_AddPlayerScore(player, player->linkcount*20); - P_SetMobjState(dummymo, dummymo->info->xdeathstate+player->linkcount-1); - } - else - { - P_AddPlayerScore(player, player->linkcount*10); - P_SetMobjState(dummymo, dummymo->info->spawnstate+player->linkcount-1); - } - } - else - { - if (player->bonustime) - { - P_AddPlayerScore(player, 200); - P_SetMobjState(dummymo, dummymo->info->xdeathstate+9); - } - else - { - P_AddPlayerScore(player, 100); - P_SetMobjState(dummymo, dummymo->info->spawnstate+9); - } - } - - // Hoops are the only things that should add to your drill meter - //player->drillmeter += TICRATE; - dummymo->momz = FRACUNIT; - dummymo->fuse = 3*TICRATE; - - // What?! NO, don't use the camera! Scale up instead! - //P_InstaThrust(dummymo, R_PointToAngle2(dummymo->x, dummymo->y, camera[0].x, camera[0].y), 3*FRACUNIT); - dummymo->scalespeed = FRACUNIT/25; - dummymo->destscale = 2*FRACUNIT; -} - -// -// P_DoMatchSuper -// -// Checks if you have all 7 pw_emeralds, then turns you "super". =P -// -void P_DoMatchSuper(player_t *player) -{ - UINT16 match_emeralds = player->powers[pw_emeralds]; - boolean doteams = false; - int i; - - // If this gametype has teams, check every player on your team for emeralds. - if (G_GametypeHasTeams()) - { - doteams = true; - for (i = 0; i < MAXPLAYERS; i++) - if (players[i].ctfteam == player->ctfteam) - match_emeralds |= players[i].powers[pw_emeralds]; - } - - if (!ALL7EMERALDS(match_emeralds)) - return; - - // Got 'em all? Turn "super"! - emeraldspawndelay = invulntics + 1; - player->powers[pw_emeralds] = 0; - player->powers[pw_invulnerability] = emeraldspawndelay; - player->powers[pw_sneakers] = emeraldspawndelay; - if (P_IsLocalPlayer(player) && !player->powers[pw_super]) - { - S_StopMusic(); - if (mariomode) - G_GhostAddColor(GHC_INVINCIBLE); - strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); - S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); - S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); - } - - // Also steal 50 points from every enemy, sealing your victory. - P_StealPlayerScore(player, 50); - - // In a team game? - // Check everyone else on your team for emeralds, and turn those helpful assisting players invincible too. - if (doteams) - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].ctfteam == player->ctfteam - && players[i].powers[pw_emeralds] != 0) - { - players[i].powers[pw_emeralds] = 0; - player->powers[pw_invulnerability] = invulntics + 1; - player->powers[pw_sneakers] = player->powers[pw_invulnerability]; - if (P_IsLocalPlayer(player) && !player->powers[pw_super]) - { - S_StopMusic(); - if (mariomode) - G_GhostAddColor(GHC_INVINCIBLE); - strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); - S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); - S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); - } - } -} - /** Takes action based on a ::MF_SPECIAL thing touched by a player. * Actually, this just checks a few things (heights, toucher->player, no * objectplace, no dead or disappearing things) @@ -372,7 +163,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player_t *player; INT32 i; - UINT8 elementalpierce; if (objectplacing) return; @@ -389,26 +179,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (heightcheck) { - /*if (special->type == MT_FLINGEMERALD) // little hack here... - { // flingemerald sprites are low to the ground, so extend collision radius down some. - if (toucher->z > (special->z + special->height)) + if (toucher->momz < 0) { + if (toucher->z + toucher->momz > special->z + special->height) return; - if (special->z - special->height > (toucher->z + toucher->height)) + } else if (toucher->z > special->z + special->height) + return; + if (toucher->momz > 0) { + if (toucher->z + toucher->height + toucher->momz < special->z) return; - } - else*/ - { - if (toucher->momz < 0) { - if (toucher->z + toucher->momz > special->z + special->height) - return; - } else if (toucher->z > special->z + special->height) - return; - if (toucher->momz > 0) { - if (toucher->z + toucher->height + toucher->momz < special->z) - return; - } else if (toucher->z + toucher->height < special->z) - return; - } + } else if (toucher->z + toucher->height < special->z) + return; } player = toucher->player; @@ -423,53 +203,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (LUAh_TouchSpecial(special, toucher) || P_MobjWasRemoved(special)) return; -<<<<<<< HEAD -#endif - - if (special->flags & MF_BOSS) - { - /*if (special->type == MT_BLACKEGGMAN) - { - P_DamageMobj(toucher, special, special, 1); // ouch - return; - } - - if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? - { - if (P_MobjFlip(toucher)*toucher->momz < 0) - toucher->momz = -toucher->momz; - toucher->momx = -toucher->momx; - toucher->momy = -toucher->momy; - P_DamageMobj(special, toucher, toucher, 1); - } - else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP)) - || (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) - && player->charability == CA_FLY - && (player->powers[pw_tailsfly] - || (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller. - { - toucher->momz = -toucher->momz/2; - - P_DamageMobj(special, toucher, toucher, 1); - } - // SRB2kart - Removed: No more fly states - else*/ - P_DamageMobj(toucher, special, special, 1); - - return; - } - else if ((special->flags & MF_ENEMY) && !(special->flags & MF_MISSILE) - && (special->type != MT_SPRINGSHELL)) // Kart: prevent random hits from these things - { - P_DamageMobj(toucher, special, special, 1); -======= - - // 0 = none, 1 = elemental pierce, 2 = bubble bounce - elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY) - ? (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2) - : 0); if ((special->flags & (MF_ENEMY|MF_BOSS)) && !(special->flags & MF_MISSILE)) { @@ -484,7 +217,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DamageMobj(toucher, special, special, 1, 0); // ouch return; } - case MT_BIGMINE: + + case MT_BIGMINE: { special->momx = toucher->momx/3; special->momy = toucher->momy/3; @@ -499,9 +233,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->homing = 0; return; } + case MT_GSNAPPER: - if (!elementalpierce - && toucher->z < special->z + special->height + if (toucher->z < special->z + special->height && toucher->z + toucher->height > special->z && P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) return; // Can only hit snapper from above @@ -510,20 +244,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_SPINCUSHION: if (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) { - if (player->pflags & PF_BOUNCING) - { - toucher->momz = -toucher->momz; - P_DoAbilityBounce(player, false); - return; - } - else if (P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) + if (P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) return; // Cannot hit sharp from above } break; + case MT_FANG: - if (!player->powers[pw_flashing] - && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) - && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + if (!player->powers[pw_flashing]) { if ((special->state == &states[S_FANG_BOUNCE3] || special->state == &states[S_FANG_BOUNCE4] @@ -551,58 +278,19 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } } break; + case MT_PYREFLY: if (special->extravalue2 == 2 && P_DamageMobj(player->mo, special, special, 1, DMG_FIRE)) return; + default: break; } - if (P_PlayerCanDamage(player, special)) // Do you possess the ability to subdue the object? - { - if (special->type == MT_PTERABYTE && special->target == player->mo && special->extravalue1 == 1) - return; // Can't hurt a Pterabyte if it's trying to pick you up + if (special->type == MT_PTERABYTE && special->target == player->mo) + return; // Don't hurt the player you're trying to grab - if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) - { - if (elementalpierce == 2) - P_DoBubbleBounce(player); - else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) - toucher->momz = -toucher->momz; - } - if (player->pflags & PF_BOUNCING) - P_DoAbilityBounce(player, false); - if (special->info->spawnhealth > 1) // Multi-hit? Bounce back! - { - toucher->momx = -toucher->momx; - toucher->momy = -toucher->momy; - if (player->charability == CA_FLY && player->panim == PA_ABILITY) - toucher->momz = -toucher->momz/2; - else if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) - { - player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); - toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); - toucher->momx = 7*toucher->momx>>3; - toucher->momy = 7*toucher->momy>>3; - } - else if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) - && player->panim == PA_DASH) - P_DoPlayerPain(player, special, special); - } - P_DamageMobj(special, toucher, toucher, 1, 0); - if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) - P_TwinSpinRejuvenate(player, player->thokitem); - } - else - { - if (special->type == MT_PTERABYTE && special->target == player->mo) - return; // Don't hurt the player you're trying to grab - - P_DamageMobj(toucher, special, special, 1, 0); - } - ->>>>>>> srb2/next + P_DamageMobj(toucher, special, special, 1, 0); return; } else if (special->flags & MF_FIRE) @@ -893,9 +581,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) //P_SetTarget(&special->target, toucher); special->fuse = 2*TICRATE; break; + case MT_BALLOON: // SRB2kart P_SetObjectMomZ(toucher, 20<target == toucher || special->target == toucher->target) && (special->threshold > 0)) return; @@ -916,20 +606,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(toucher, sfx_s1b2); return; -// ***************************************** // -// Rings, coins, spheres, weapon panels, etc // -// ***************************************** // - case MT_REDTEAMRING: - if (player->ctfteam != 1) - return; - /* FALLTHRU */ - case MT_BLUETEAMRING: // Yes, I'm lazy. Oh well, deal with it. - if (special->type == MT_BLUETEAMRING && player->ctfteam != 2) - return; - /* FALLTHRU */ case MT_RING: case MT_FLINGRING: -<<<<<<< HEAD if (special->extravalue1) return; @@ -948,17 +626,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Reached the cap, don't waste 'em! if (RINGTOTAL(player) >= 20) -======= - case MT_COIN: - case MT_FLINGCOIN: - case MT_NIGHTSSTAR: - if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) ->>>>>>> srb2/next return; special->momx = special->momy = special->momz = 0; -<<<<<<< HEAD special->extravalue1 = 1; // Ring collect animation timer special->angle = R_PointToAngle2(toucher->x, toucher->y, special->x, special->y); // animation angle P_SetTarget(&special->target, toucher); // toucher for thinker @@ -966,199 +637,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; - case MT_COIN: - case MT_FLINGCOIN: - if (!(P_CanPickupItem(player, 0))) -======= - if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING && special->type != MT_FLINGCOIN) - P_DoNightsScore(player); - break; - case MT_BLUESPHERE: - case MT_FLINGBLUESPHERE: - case MT_NIGHTSCHIP: - case MT_FLINGNIGHTSCHIP: - if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) ->>>>>>> srb2/next - return; - - special->momx = special->momy = special->momz = 0; - P_GivePlayerSpheres(player, 1); - - if (special->type == MT_BLUESPHERE) - { - special->destscale = ((player->powers[pw_carry] == CR_NIGHTSMODE) ? 4 : 2)*special->scale; - if (states[special->info->deathstate].tics > 0) - special->scalespeed = FixedDiv(FixedDiv(special->destscale, special->scale), states[special->info->deathstate].tics<scalespeed = 4*FRACUNIT/5; - } - - if (maptol & TOL_NIGHTS) - P_DoNightsScore(player); - break; -<<<<<<< HEAD - case MT_BLUEBALL: - if (!(P_CanPickupItem(player, 0))) -======= - case MT_BOMBSPHERE: - if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) ->>>>>>> srb2/next - return; - - special->momx = special->momy = special->momz = 0; - P_DamageMobj(toucher, special, special, 1, 0); - break; - case MT_AUTOPICKUP: - case MT_BOUNCEPICKUP: - case MT_SCATTERPICKUP: - case MT_GRENADEPICKUP: - case MT_EXPLODEPICKUP: - case MT_RAILPICKUP: - if (!(P_CanPickupItem(player, 1))) - return; - - // Give the power and ringweapon - if (special->info->mass >= pw_infinityring && special->info->mass <= pw_railring) - { - INT32 pindex = special->info->mass - (INT32)pw_infinityring; - - player->powers[special->info->mass] += (UINT16)special->reactiontime; - player->ringweapons |= 1 << (pindex-1); - - if (player->powers[special->info->mass] > rw_maximums[pindex]) - player->powers[special->info->mass] = rw_maximums[pindex]; - } - break; - - // Ammo pickups - case MT_INFINITYRING: - case MT_AUTOMATICRING: - case MT_BOUNCERING: - case MT_SCATTERRING: - case MT_GRENADERING: - case MT_EXPLOSIONRING: - case MT_RAILRING: - if (!(P_CanPickupItem(player, 1))) - return; - - if (special->info->mass >= pw_infinityring && special->info->mass <= pw_railring) - { - INT32 pindex = special->info->mass - (INT32)pw_infinityring; - - player->powers[special->info->mass] += (UINT16)special->health; - if (player->powers[special->info->mass] > rw_maximums[pindex]) - player->powers[special->info->mass] = rw_maximums[pindex]; - } - break; - -// ***************************** // -// Gameplay related collectibles // -// ***************************** // - // Special Stage Token -<<<<<<< HEAD - case MT_EMMY: -======= - case MT_TOKEN: - if (player->bot) - return; - - P_AddPlayerScore(player, 1000); - - if (!(gametyperules & GTR_SPECIALSTAGES) || modeattacking) // score only? - { - S_StartSound(toucher, sfx_chchng); - break; - } - ->>>>>>> srb2/next - tokenlist += special->health; - - if (ALL7EMERALDS(emeralds)) // Got all 7 - { - if (continuesInSession) - { - player->continues += 1; - player->gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_s3kac); - else - S_StartSound(toucher, sfx_chchng); - } - else - { - P_GiveCoopLives(player, 1, true); // if continues are disabled, a life is a reasonable substitute - S_StartSound(toucher, sfx_chchng); - } - } - else - { - token++; - S_StartSound(toucher, sfx_token); - } - - break; - - // Emerald Hunt - case MT_EMERHUNT: - if (hunt1 == special) - hunt1 = NULL; - else if (hunt2 == special) - hunt2 = NULL; - else if (hunt3 == special) - hunt3 = NULL; - - if (!hunt1 && !hunt2 && !hunt3) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - - players[i].exiting = raceexittime+1; - } - //S_StartSound(NULL, sfx_lvpass); - } - break; - - // Collectible emeralds - case MT_EMERALD1: - case MT_EMERALD2: - case MT_EMERALD3: - case MT_EMERALD4: - case MT_EMERALD5: - case MT_EMERALD6: - case MT_EMERALD7: - if (special->threshold) - { - player->powers[pw_emeralds] |= special->info->speed; - P_DoMatchSuper(player); - } - else - { - emeralds |= special->info->speed; - stagefailed = false; - } - - if (special->target && special->target->type == MT_EMERALDSPAWN) - { - if (special->target->target) - P_SetTarget(&special->target->target, NULL); - - special->target->threshold = 0; - - P_SetTarget(&special->target, NULL); - } - break; - - // Power stones / Match emeralds - case MT_FLINGEMERALD: - if (!(P_CanPickupItem(player, 1)) || player->tossdelay) - return; - - player->powers[pw_emeralds] |= special->threshold; - P_DoMatchSuper(player); - break; - // Secret emblem thingy case MT_EMBLEM: { @@ -1240,870 +718,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; -// ********************************** // -// NiGHTS gameplay items and powerups // -// ********************************** // -<<<<<<< HEAD - /*case MT_NIGHTSDRONE: - if (player->exiting) - return; - if (player->bonustime) -======= - case MT_NIGHTSDRONE: ->>>>>>> srb2/next - { - boolean spec = G_IsSpecialStage(gamemap); - boolean cangiveemmy = false; - if (player->bot) - return; - if (player->exiting) - return; - if (player->bonustime) - { - if (spec) //After-mare bonus time/emerald reward in special stages. - { - // only allow the player with the emerald in-hand to leave. - if (toucher->tracer - && toucher->tracer->type == MT_GOTEMERALD) - {} - else // Make sure that SOMEONE has the emerald, at least! - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].playerstate == PST_LIVE - && players[i].mo->tracer - && players[i].mo->tracer->type == MT_GOTEMERALD) - return; - // Well no one has an emerald, so exit anyway! - } - cangiveemmy = true; - // Don't play Ideya sound in special stage mode - } - else - S_StartSound(toucher, special->info->activesound); - } - else //Initial transformation. Don't allow second chances in special stages! - { - if (player->powers[pw_carry] == CR_NIGHTSMODE) - return; - - S_StartSound(toucher, sfx_supert); - } - P_SwitchSpheresBonusMode(false); - if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) - P_SetTarget(&special->tracer, toucher); - P_SetTarget(&player->drone, special); // Mark the player as 'center into the drone' - P_NightserizePlayer(player, special->health); // Transform! - if (!spec) - { - if (toucher->tracer) // Move the Ideya to an anchor! - { - mobj_t *orbittarget = special->target ? special->target : special; - mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL, *anchorpoint2 = NULL; - mobj_t *mo2; - thinker_t *th; - - // The player might have two Ideyas: toucher->tracer and toucher->tracer->hnext - // so handle their anchorpoints accordingly. - // scan the thinkers to find the corresponding anchorpoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_IDEYAANCHOR) - continue; - - if (mo2->health == toucher->tracer->health) // do ideya numberes match? - anchorpoint = mo2; - else if (toucher->tracer->hnext && mo2->health == toucher->tracer->hnext->health) - anchorpoint2 = mo2; - - if ((!toucher->tracer->hnext && anchorpoint) - || (toucher->tracer->hnext && anchorpoint && anchorpoint2)) - break; - } - - if (anchorpoint) - { - toucher->tracer->flags |= MF_GRENADEBOUNCE; // custom radius factors - toucher->tracer->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 - } - - if (anchorpoint2) - { - toucher->tracer->hnext->flags |= MF_GRENADEBOUNCE; // custom radius factors - toucher->tracer->hnext->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 - } - - P_SetTarget(&orbittarget->hnext, toucher->tracer); - if (!orbittarget->hnext->hnext) - P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - else - P_SetTarget(&orbittarget->hnext->hnext->target, anchorpoint2 ? anchorpoint2 : orbittarget); - P_SetTarget(&orbittarget->hnext->target, anchorpoint ? anchorpoint : orbittarget); - P_SetTarget(&toucher->tracer, NULL); - - if (hnext) - { - orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); - if (orbittarget->hnext->extravalue1 > hnext->extravalue1) - orbittarget->hnext->extravalue1 -= (72*ANG1)/orbittarget->hnext->extravalue1; - } - } - if (player->exiting) // ...then move it back? - { - mobj_t *hnext = special->target ? special->target : special; // goalpost - while ((hnext = hnext->hnext)) - { - hnext->flags &= ~MF_GRENADEBOUNCE; - hnext->threshold = 0; - P_SetTarget(&hnext->target, toucher); - } - } - return; - } - - if (!cangiveemmy) - return; - - if (player->exiting) - P_GiveEmerald(false); - else if (player->mo->tracer && player->mare) - { - P_KillMobj(toucher->tracer, NULL, NULL, 0); // No emerald for you just yet! - S_StartSound(NULL, sfx_ghosty); - special->flags2 |= MF2_DONTDRAW; - } - - return; - } - case MT_NIGHTSLOOPHELPER: - // One second delay - if (special->fuse < toucher->fuse - TICRATE) - { - thinker_t *th; - mobj_t *mo2; - INT32 count; - fixed_t x,y,z, gatherradius; - angle_t d; - statenum_t sparklestate = S_NULL; - - if (special->target != toucher) // These ain't your helpers, pal! - return; - - x = special->x>>FRACBITS; - y = special->y>>FRACBITS; - z = special->z>>FRACBITS; - count = 1; - - // scan the remaining thinkers - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2 == special) - continue; - - // Not our stuff! - if (mo2->target != toucher) - continue; - - if (mo2->type == MT_NIGHTSPARKLE) - mo2->tics = 1; - else if (mo2->type == MT_NIGHTSLOOPHELPER) - { - if (mo2->fuse >= special->fuse) - { - count++; - x += mo2->x>>FRACBITS; - y += mo2->y>>FRACBITS; - z += mo2->z>>FRACBITS; - } - P_RemoveMobj(mo2); - } - } - x = (x/count)<x - x, special->y - y), special->z - z); - P_RemoveMobj(special); - - if (player->powers[pw_nights_superloop]) - { - gatherradius *= 2; - sparklestate = mobjinfo[MT_NIGHTSPARKLE].seestate; - } - - if (gatherradius < 30*FRACUNIT) // Player is probably just sitting there. - return; - - for (d = 0; d < 16; d++) - P_SpawnParaloop(x, y, z, gatherradius, 16, MT_NIGHTSPARKLE, sparklestate, d*ANGLE_22h, false); - - S_StartSound(toucher, sfx_prloop); - - // Now we RE-scan all the thinkers to find close objects to pull - // in from the paraloop. Isn't this just so efficient? - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) - continue; - - if (mo2->flags & MF_SHOOTABLE) - { - P_DamageMobj(mo2, toucher, toucher, 1, 0); - continue; - } - - // Make these APPEAR! - // Tails 12-15-2003 - if (mo2->flags & MF_NIGHTSITEM) - { - // Requires Bonus Time - if ((mo2->flags2 & MF2_STRONGBOX) && !player->bonustime) - continue; - - if (!(mo2->flags & MF_SPECIAL) && mo2->health) - { - mo2->flags2 &= ~MF2_DONTDRAW; - mo2->flags |= MF_SPECIAL; - mo2->flags &= ~MF_NIGHTSITEM; - S_StartSound(toucher, sfx_hidden); - continue; - } - } - - if (!(mo2->type == MT_RING || mo2->type == MT_COIN - || mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE - || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR - || ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL)))) - continue; - - // Yay! The thing's in reach! Pull it in! - mo2->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; - mo2->flags2 |= MF2_NIGHTSPULL; - // New NiGHTS attract speed dummied out because the older behavior - // is exploited as a mechanic. Uncomment to enable. - mo2->movefactor = 0; // 32*FRACUNIT; // initialize the NightsItemChase timer - P_SetTarget(&mo2->tracer, toucher); - } - } - return; - case MT_EGGCAPSULE: - // make sure everything is as it should be, THEN take rings from players in special stages - if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) - return; - - if (toucher->tracer && toucher->tracer->health > 0) - return; // Don't have multiple ideya, unless it's the first one given (health = 0) - - if (player->mare != special->threshold) // wrong mare - return; - - if (special->reactiontime > 0) // capsule already has a player attacking it, ignore - return; - - if (G_IsSpecialStage(gamemap) && !player->exiting) - { // In special stages, share spheres. Everyone gives up theirs to the player who touched the capsule - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].spheres > 0) - { - player->spheres += players[i].spheres; - players[i].spheres = 0; - } - } - - if (player->spheres <= 0 || player->exiting) - return; - - // Mark the player as 'pull into the capsule' - P_SetTarget(&player->capsule, special); - special->reactiontime = (player-players)+1; - P_SetTarget(&special->target, NULL); - - // Clear text - player->texttimer = 0; - return;*/ - case MT_NIGHTSBUMPER: - // Don't trigger if the stage is ended/failed - if (player->exiting) - return; - - if (player->bumpertime <= (TICRATE/2)-5) - { - S_StartSound(toucher, special->info->seesound); - if (player->powers[pw_carry] == CR_NIGHTSMODE) - { - player->bumpertime = TICRATE/2; - if (special->threshold > 0) - player->flyangle = (special->threshold*30)-1; - else - player->flyangle = special->threshold; - - player->speed = FixedMul(special->info->speed, special->scale); - P_SetTarget(&player->mo->hnext, special); // Reference bumper for position correction on next tic - } - else // More like a spring - { - angle_t fa; - fixed_t xspeed, yspeed; - const fixed_t speed = FixedMul(FixedDiv(special->info->speed*FRACUNIT,75*FRACUNIT), FixedSqrt(FixedMul(toucher->scale,special->scale))); - - player->bumpertime = TICRATE/2; - - P_UnsetThingPosition(toucher); - toucher->x = special->x; - toucher->y = special->y; - P_SetThingPosition(toucher); - toucher->z = special->z+(special->height/4); - - if (special->threshold > 0) - fa = (FixedAngle(((special->threshold*30)-1)*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK; - else - fa = 0; - - xspeed = FixedMul(FINECOSINE(fa),speed); - yspeed = FixedMul(FINESINE(fa),speed); - - P_InstaThrust(toucher, special->angle, xspeed/10); - toucher->momz = yspeed/11; - - toucher->angle = special->angle; - - if (player == &players[consoleplayer]) - localangle[0] = toucher->angle; - else if (player == &players[displayplayers[1]]) - localangle[1] = toucher->angle; - else if (player == &players[displayplayers[2]]) - localangle[2] = toucher->angle; - else if (player == &players[displayplayers[3]]) - localangle[3] = toucher->angle; - - P_ResetPlayer(player); - -<<<<<<< HEAD - P_SetPlayerMobjState(toucher, S_KART_STILL1); // SRB2kart - was S_PLAY_FALL1 - } - } - return; - /*case MT_NIGHTSSUPERLOOP: - if (!(player->pflags & PF_NIGHTSMODE)) -======= - P_SetPlayerMobjState(toucher, S_PLAY_FALL); - } - } - return; - case MT_NIGHTSSUPERLOOP: - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) ->>>>>>> srb2/next - return; - if (!G_IsSpecialStage(gamemap)) - player->powers[pw_nights_superloop] = (UINT16)special->info->speed; - else - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) - players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed; - if (special->info->deathsound != sfx_None) - S_StartSound(NULL, special->info->deathsound); - } - - // CECHO showing you what this item is - if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap)) - { - HU_SetCEchoFlags(V_AUTOFADEOUT); - HU_SetCEchoDuration(4); - HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Super Paraloop")); - } - break; - case MT_NIGHTSDRILLREFILL: -<<<<<<< HEAD - if (!(player->pflags & PF_NIGHTSMODE)) -======= - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) ->>>>>>> srb2/next - return; - if (!G_IsSpecialStage(gamemap)) - player->drillmeter = special->info->speed; - else - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) - players[i].drillmeter = special->info->speed; - if (special->info->deathsound != sfx_None) - S_StartSound(NULL, special->info->deathsound); - } - - // CECHO showing you what this item is - if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap)) - { - HU_SetCEchoFlags(V_AUTOFADEOUT); - HU_SetCEchoDuration(4); - HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Drill Refill")); - } - break; - case MT_NIGHTSHELPER: -<<<<<<< HEAD - if (!(player->pflags & PF_NIGHTSMODE)) -======= - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) ->>>>>>> srb2/next - return; - if (!G_IsSpecialStage(gamemap)) - { - // A flicky orbits us now - mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER); - P_SetTarget(&flickyobj->target, toucher); - - player->powers[pw_nights_helper] = (UINT16)special->info->speed; - } - else - { - mobj_t *flickyobj; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) { - players[i].powers[pw_nights_helper] = (UINT16)special->info->speed; - flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER); - P_SetTarget(&flickyobj->target, players[i].mo); - } - if (special->info->deathsound != sfx_None) - S_StartSound(NULL, special->info->deathsound); - } - - // CECHO showing you what this item is - if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap)) - { - HU_SetCEchoFlags(V_AUTOFADEOUT); - HU_SetCEchoDuration(4); - HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Nightopian Helper")); - } - break; - case MT_NIGHTSEXTRATIME: -<<<<<<< HEAD - if (!(player->pflags & PF_NIGHTSMODE)) -======= - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) ->>>>>>> srb2/next - return; - if (!G_IsSpecialStage(gamemap)) - { - player->nightstime += special->info->speed; - player->startedtime += special->info->speed; - player->lapstartedtime += special->info->speed; - P_RestoreMusic(player); - } - else - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - players[i].nightstime += special->info->speed; - players[i].startedtime += special->info->speed; - players[i].lapstartedtime += special->info->speed; - P_RestoreMusic(&players[i]); - } - if (special->info->deathsound != sfx_None) - S_StartSound(NULL, special->info->deathsound); - } - - // CECHO showing you what this item is - if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap)) - { - HU_SetCEchoFlags(V_AUTOFADEOUT); - HU_SetCEchoDuration(4); - HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Extra Time")); - } - break; - case MT_NIGHTSLINKFREEZE: -<<<<<<< HEAD - if (!(player->pflags & PF_NIGHTSMODE)) -======= - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) ->>>>>>> srb2/next - return; - if (!G_IsSpecialStage(gamemap)) - { - player->powers[pw_nights_linkfreeze] = (UINT16)special->info->speed; - player->linktimer = nightslinktics; - } - else - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed; - players[i].linktimer = nightslinktics; - } - if (special->info->deathsound != sfx_None) - S_StartSound(NULL, special->info->deathsound); - } - - // CECHO showing you what this item is - if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap)) - { - HU_SetCEchoFlags(V_AUTOFADEOUT); - HU_SetCEchoDuration(4); - HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Link Freeze")); - } -<<<<<<< HEAD - break;*/ - case MT_NIGHTSWING: - if (G_IsSpecialStage(gamemap) && useNightsSS) - { // Pseudo-ring. - S_StartSound(toucher, special->info->painsound); - player->totalring++; - } - else - S_StartSound(toucher, special->info->activesound); - - P_DoNightsScore(player); -======= ->>>>>>> srb2/next - break; - case MT_HOOPCOLLIDE: - // This produces a kind of 'domino effect' with the hoop's pieces. - for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop - i = 0; - for (; special->type == MT_HOOP; special = special->hnext) - { - special->fuse = 11; - special->movedir = i; - special->extravalue1 = special->target->extravalue1; - special->extravalue2 = special->target->extravalue2; - special->target->threshold = 4242; - i++; - } - // Make the collision detectors disappear. - { - mobj_t *hnext; - for (; special != NULL; special = hnext) - { - hnext = special->hnext; - P_RemoveMobj(special); - } - } - - P_DoNightsScore(player); - - // Hoops are the only things that should add to the drill meter - // Also, one tic's worth of drill is too much. - if (G_IsSpecialStage(gamemap)) - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) - players[i].drillmeter += TICRATE/2; - } - else - player->drillmeter += TICRATE/2; - - // Play hoop sound -- pick one depending on the current link. - if (player->linkcount <= 5) - S_StartSound(toucher, sfx_hoop1); - else if (player->linkcount <= 10) - S_StartSound(toucher, sfx_hoop2); - else - S_StartSound(toucher, sfx_hoop3); - return; - -// ***** // -// Mario // -// ***** // - case MT_SHELL: - { - boolean bounceon = ((P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)); - if (special->threshold == TICRATE) // it's moving - { - if (bounceon) - { - // Stop it! - special->momx = special->momy = 0; - S_StartSound(toucher, sfx_mario2); - P_SetTarget(&special->target, NULL); - special->threshold = TICRATE - 1; - toucher->momz = -toucher->momz; - } - else // can't handle in PIT_CheckThing because of landing-on causing it to stop - P_DamageMobj(toucher, special, special->target, 1, 0); - } - else if (special->threshold == 0) - { - // Kick that sucker around! - special->movedir = ((special->movedir == 1) ? -1 : 1); - P_InstaThrust(special, toucher->angle, (special->info->speed*special->scale)); - S_StartSound(toucher, sfx_mario2); - P_SetTarget(&special->target, toucher); - special->threshold = (3*TICRATE)/2; - if (bounceon) - toucher->momz = -toucher->momz; - } - } - return; - case MT_AXE: - { - line_t junk; - thinker_t *th; - mobj_t *mo2; - -<<<<<<< HEAD - junk.tag = 649; -======= - if (player->bot) - return; - - junk.tag = LE_AXE; ->>>>>>> srb2/next - EV_DoElevator(&junk, bridgeFall, false); - - // scan the remaining thinkers to find koopa - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_KOOPA) - continue; - - mo2->momz = 5*FRACUNIT; - break; - } - } - break; - case MT_LETTER: - { - if (special->health && !player->bot) - { - F_StartTextPrompt(199, 0, toucher, 0, true, false); - special->health = 0; - if (ultimatemode && player->continues < 99) - player->continues++; - } - return; - } - case MT_FIREFLOWER: -<<<<<<< HEAD - player->powers[pw_shield] |= SH_FIREFLOWER; - toucher->color = SKINCOLOR_WHITE; - G_GhostAddColor(player - players, GHC_FIREFLOWER); - break; - -// *************** // -// Misc touchables // -// *************** // - case MT_STARPOST: - // SRB2kart: make sure the player will have enough checkpoints to touch - if (circuitmap && special->health - player->starpostnum > 1) - { - // blatant reuse of a variable that's normally unused in circuit - if (!player->tossdelay) - S_StartSound(toucher, sfx_s26d); - player->tossdelay = 3; - return; - } - - // We could technically have 91.1 Star Posts. 90 is cleaner. - if (special->health > 90) - { - CONS_Debug(DBG_GAMELOGIC, "Bad Starpost Number!\n"); - return; - } -======= - if (player->bot) - return; ->>>>>>> srb2/next - - S_StartSound(toucher, sfx_mario3); - -<<<<<<< HEAD - // Save the player's time and position. - player->starposttime = player->realtime; //this makes race mode's timers work correctly whilst not affecting sp -x - player->starpostnum = special->health; - - //S_StartSound(toucher, special->info->painsound); -======= - player->powers[pw_shield] = (player->powers[pw_shield] & SH_NOSTACK)|SH_FIREFLOWER; - - if (!(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability]))) - { - player->mo->color = SKINCOLOR_WHITE; - G_GhostAddColor(GHC_FIREFLOWER); - } - - break; - -// *************** // -// Misc touchables // -// *************** // case MT_STARPOST: P_TouchStarPost(special, player, special->spawnpoint && (special->spawnpoint->options & MTF_OBJECTSPECIAL)); ->>>>>>> srb2/next - return; - - case MT_FAKEMOBILE: - { - fixed_t touchx, touchy, touchspeed; - angle_t angle; - - if (P_AproxDistance(toucher->x-special->x, toucher->y-special->y) > - P_AproxDistance((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) - { - touchx = toucher->x + toucher->momx; - touchy = toucher->y + toucher->momy; - } - else - { - touchx = toucher->x; - touchy = toucher->y; - } - - angle = R_PointToAngle2(special->x, special->y, touchx, touchy); - touchspeed = P_AproxDistance(toucher->momx, toucher->momy); - - toucher->momx = P_ReturnThrustX(special, angle, touchspeed); - toucher->momy = P_ReturnThrustY(special, angle, touchspeed); - toucher->momz = -toucher->momz; - if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) - { -<<<<<<< HEAD - player->pflags &= ~(PF_GLIDING|PF_JUMPED); - P_SetPlayerMobjState(toucher, S_KART_STILL1); // SRB2kart - was S_PLAY_FALL1 -======= - player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); - toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); - toucher->momx = 7*toucher->momx>>3; - toucher->momy = 7*toucher->momy>>3; ->>>>>>> srb2/next - } - player->homing = 0; - - // Play a bounce sound? - S_StartSound(toucher, special->info->painsound); - } - return; - - case MT_BLACKEGGMAN_GOOPFIRE: -<<<<<<< HEAD - if (!player->powers[pw_flashing]) // SRB2kart -======= - if (!player->powers[pw_flashing]) ->>>>>>> srb2/next - { - toucher->momx = 0; - toucher->momy = 0; - - if (toucher->momz != 0) - special->momz = toucher->momz; - - player->powers[pw_carry] = CR_BRAKGOOP; - P_SetTarget(&toucher->tracer, special); - - P_ResetPlayer(player); - - if (special->target && special->target->state == &states[S_BLACKEGG_SHOOT1]) - { - if (special->target->health <= 2 && P_RandomChance(FRACUNIT/2)) - P_SetMobjState(special->target, special->target->info->missilestate); - else - P_SetMobjState(special->target, special->target->info->raisestate); - } - } - return; - case MT_EGGSHIELD: - { - angle_t angle = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->angle; - fixed_t touchspeed = P_AproxDistance(toucher->momx, toucher->momy); - if (touchspeed < special->scale) - touchspeed = special->scale; - - // Blocked by the shield? - if (!(angle > ANGLE_90 && angle < ANGLE_270)) - { - toucher->momx = P_ReturnThrustX(special, special->angle, touchspeed); - toucher->momy = P_ReturnThrustY(special, special->angle, touchspeed); - toucher->momz = -toucher->momz; - if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) - { -<<<<<<< HEAD - player->pflags &= ~(PF_GLIDING|PF_JUMPED); - P_SetPlayerMobjState(toucher, S_KART_STILL1); // SRB2kart - was S_PLAY_FALL1 -======= - player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); - toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); - toucher->momx = 7*toucher->momx>>3; - toucher->momy = 7*toucher->momy>>3; ->>>>>>> srb2/next - } - player->homing = 0; - - // Play a bounce sound? - S_StartSound(toucher, special->info->painsound); - - // experimental bounce - if (special->target) - special->target->extravalue1 = -special->target->info->speed; - } - else - { - // Shatter the shield! - toucher->momx = -toucher->momx/2; - toucher->momy = -toucher->momy/2; - toucher->momz = -toucher->momz; - break; - } - } - return; - - case MT_EGGROBO1: - if (special->state == &states[special->info->deathstate]) - return; - if (P_PlayerInPain(player)) - return; - - P_SetMobjState(special, special->info->meleestate); - special->angle = special->movedir; - special->momx = special->momy = 0; - - // Buenos Dias Mandy - P_SetPlayerMobjState(toucher, S_PLAY_STUN); - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_ResetPlayer(player); - player->drawangle = special->angle + ANGLE_180; - P_InstaThrust(toucher, special->angle, FixedMul(3*special->info->speed, special->scale/2)); - toucher->z += P_MobjFlip(toucher); - if (toucher->eflags & MFE_UNDERWATER) // unlikely. - P_SetObjectMomZ(toucher, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); - else - P_SetObjectMomZ(toucher, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); - if (P_IsLocalPlayer(player)) - { - quake.intensity = 9*FRACUNIT; - quake.time = TICRATE/2; - quake.epicenter = NULL; - } - -#if 0 // camera redirection - deemed unnecessary - toucher->angle = special->angle; - if (player == &players[consoleplayer]) - localangle = toucher->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = toucher->angle; -#endif - - S_StartSound(toucher, special->info->attacksound); // home run - return; case MT_BIGTUMBLEWEED: @@ -2120,142 +736,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetMobjState(special, special->info->seestate); } return; - case MT_SMALLGRABCHAIN: - case MT_BIGGRABCHAIN: - if (P_MobjFlip(toucher)*toucher->momz > 0 - || (player->powers[pw_carry])) - return; - - if (toucher->z > special->z + special->height/2) - return; - - if (toucher->z + toucher->height/2 < special->z) - return; - - if (player->powers[pw_flashing]) - return; - - if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270) - { // I don't expect you to understand this, Mr Bond... - angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle; - if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270)) - ang += ANGLE_180; - if (ang < ANGLE_180) - return; // I expect you to die. - } - - P_ResetPlayer(player); - P_SetTarget(&toucher->tracer, special); - - if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) - { - player->powers[pw_carry] = CR_MACESPIN; - S_StartSound(toucher, sfx_spin); -<<<<<<< HEAD - P_SetPlayerMobjState(toucher, S_KART_STILL1); // SRB2kart - was S_PLAY_ATK1 -======= - P_SetPlayerMobjState(toucher, S_PLAY_ROLL); ->>>>>>> srb2/next - } - else - player->powers[pw_carry] = CR_GENERIC; - - // Can't jump first frame - player->pflags |= PF_JUMPSTASIS; - -<<<<<<< HEAD - if (player->powers[pw_invulnerability] || player->powers[pw_flashing] - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds])))) - return; - if (player->powers[pw_shield]) //If One-Hit Shield - { - P_RemoveShield(player); - S_StartSound(toucher, sfx_shldls); // Ba-Dum! Shield loss. - } - else - { - P_PlayRinglossSound(toucher); - if (toucher->health > 10) - toucher->health -= 10; - else - toucher->health = 1; - player->health = toucher->health; - } - - P_DoPlayerPain(player, special, NULL); -======= ->>>>>>> srb2/next - return; - case MT_EGGMOBILE2_POGO: - // sanity checks - if (!special->target || !special->target->health) - return; - // Goomba Stomp'd! - if (special->target->momz < 0) - { - P_DamageMobj(toucher, special, special->target, 1, 0); - //special->target->momz = -special->target->momz; - special->target->momx = special->target->momy = 0; - special->target->momz = 0; - special->target->flags |= MF_NOGRAVITY; - P_SetMobjState(special->target, special->info->raisestate); - S_StartSound(special->target, special->info->activesound); - P_RemoveMobj(special); - } - return; - - case MT_EXTRALARGEBUBBLE: -<<<<<<< HEAD - return; // SRB2kart - don't need bubbles mucking with the player - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) -======= - if (player->powers[pw_shield] & SH_PROTECTWATER) ->>>>>>> srb2/next - return; - if (maptol & TOL_NIGHTS) - return; - if (mariomode) - return; - if (special->state-states != S_EXTRALARGEBUBBLE) - return; // Don't grab the bubble during its spawn animation - else if (toucher->eflags & MFE_VERTICALFLIP) - { - if (special->z+special->height < toucher->z - || special->z+special->height > toucher->z + (toucher->height*2/3)) - return; // Only go in the mouth - } - else if (special->z < toucher->z - || special->z > toucher->z + (toucher->height*2/3)) - return; // Only go in the mouth - - /* // SRB2kart - Can't drown. - // Eaten by player! - if ((!player->bot) && (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)) - { - player->powers[pw_underwater] = underwatertics + 1; - P_RestoreMusic(player); - } - - if (player->powers[pw_underwater] < underwatertics + 1) - player->powers[pw_underwater] = underwatertics + 1; - */ - - /* - if (!player->climbing) - { - if (player->bot && toucher->state-states != S_PLAY_GASP) - S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots - P_SetPlayerMobjState(toucher, S_PLAY_GASP); - P_ResetPlayer(player); - } - */ - - toucher->momx = toucher->momy = toucher->momz = 0; - - if (player->bot) - return; - else - break; case MT_WATERDROP: if (special->state == &states[special->info->spawnstate]) @@ -2268,91 +748,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; - case MT_CANARIVORE_GAS: - // if player and gas touch, attach gas to player (overriding any gas that already attached) and apply slowdown effect - special->flags |= MF_NOGRAVITY|MF_NOCLIPHEIGHT; - P_UnsetThingPosition(special); - special->x = toucher->x - toucher->momx/2; - special->y = toucher->y - toucher->momy/2; - special->z = toucher->z - toucher->momz/2; - P_SetThingPosition(special); - toucher->momx = FixedMul(toucher->momx, 50*FRACUNIT/51); - toucher->momy = FixedMul(toucher->momy, 50*FRACUNIT/51); - special->momx = toucher->momx; - special->momy = toucher->momy; - special->momz = toucher->momz; - return; - - case MT_MINECARTSPAWNER: - if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART) - { - mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); - P_SetTarget(&mcart->target, toucher); - mcart->angle = toucher->angle = player->drawangle = special->angle; - mcart->friction = FRACUNIT; - - P_ResetPlayer(player); - player->pflags |= PF_JUMPDOWN; - player->powers[pw_carry] = CR_MINECART; - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetTarget(&toucher->tracer, mcart); - toucher->momx = toucher->momy = toucher->momz = 0; - - special->fuse = 3*TICRATE; - special->flags2 |= MF2_DONTDRAW; - } - return; - - case MT_MINECARTEND: - if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) - { - fixed_t maxz = max(toucher->z, special->z + 35*special->scale); - - toucher->momx = toucher->tracer->momx/2; - toucher->momy = toucher->tracer->momy/2; - toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; - P_ResetPlayer(player); - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetPlayerMobjState(toucher, S_PLAY_FALL); - P_SetTarget(&toucher->tracer->target, NULL); - P_KillMobj(toucher->tracer, toucher, special, 0); - P_SetTarget(&toucher->tracer, NULL); - player->powers[pw_carry] = CR_NONE; - P_UnsetThingPosition(toucher); - toucher->x = special->x; - toucher->y = special->y; - toucher->z = maxz; - P_SetThingPosition(toucher); - } - return; - - case MT_MINECARTSWITCHPOINT: - if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) - { - mobjflag2_t destambush = special->flags2 & MF2_AMBUSH; - angle_t angdiff = toucher->tracer->angle - special->angle; - if (angdiff > ANGLE_90 && angdiff < ANGLE_270) - destambush ^= MF2_AMBUSH; - toucher->tracer->flags2 = (toucher->tracer->flags2 & ~MF2_AMBUSH) | destambush; - } - return; default: // SOC or script pickup P_SetTarget(&special->target, toucher); break; } } -<<<<<<< HEAD - if (!P_MobjWasRemoved(special)) - { - S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings - P_KillMobj(special, NULL, toucher); - } -} - -// Easily make it so that overtime works offline -//#define TESTOVERTIMEINFREEPLAY -======= S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings P_KillMobj(special, NULL, toucher, 0); special->shadowscale = 0; @@ -2372,9 +773,9 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) if (player->bot) return; - // In circuit, player must have touched all previous starposts - if (circuitmap - && post->health - player->starpostnum > 1) + + // Player must have touched all previous starposts + if (post->health - player->starpostnum > 1) { // blatant reuse of a variable that's normally unused in circuit if (!player->tossdelay) @@ -2393,75 +794,22 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) if (player->starpostnum >= post->health) return; // Already hit this post - if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer)) + // Save the player's time and position. + player->starposttime = leveltime; + player->starpostx = checkbase->x>>FRACBITS; + player->starposty = checkbase->y>>FRACBITS; + player->starpostz = post->z>>FRACBITS; + player->starpostangle = post->angle; + player->starpostscale = player->mo->destscale; + if (post->flags2 & MF2_OBJECTFLIP) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - { - if (players[i].bot) // ignore dumb, stupid tails - continue; - - players[i].starposttime = leveltime; - players[i].starpostx = checkbase->x>>FRACBITS; - players[i].starposty = checkbase->y>>FRACBITS; - players[i].starpostz = post->z>>FRACBITS; - players[i].starpostangle = post->angle; - players[i].starpostscale = player->mo->destscale; - if (post->flags2 & MF2_OBJECTFLIP) - { - players[i].starpostscale *= -1; - players[i].starpostz += post->height>>FRACBITS; - } - players[i].starpostnum = post->health; - - if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) - P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; - } - } - S_StartSound(NULL, post->info->painsound); - } - else - { - // Save the player's time and position. - player->starposttime = leveltime; - player->starpostx = checkbase->x>>FRACBITS; - player->starposty = checkbase->y>>FRACBITS; - player->starpostz = post->z>>FRACBITS; - player->starpostangle = post->angle; - player->starpostscale = player->mo->destscale; - if (post->flags2 & MF2_OBJECTFLIP) - { - player->starpostscale *= -1; - player->starpostz += post->height>>FRACBITS; - } - player->starpostnum = post->health; - S_StartSound(toucher, post->info->painsound); + player->starpostscale *= -1; + player->starpostz += post->height>>FRACBITS; } + player->starpostnum = post->health; + //S_StartSound(toucher, post->info->painsound); P_ClearStarPost(post->health); - - // Find all starposts in the level with this value - INCLUDING this one! - if (!(netgame && circuitmap && player != &players[consoleplayer])) - { - thinker_t *th; - mobj_t *mo2; - - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_STARPOST) - continue; - if (mo2->health != post->health) - continue; - - P_SetMobjState(mo2, mo2->info->painstate); - } - } } /** Prints death messages relating to a dying or hit player. @@ -2665,7 +1013,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour else CONS_Printf(str, targetname, deadtarget ? M_GetText("killed") : M_GetText("hit")); } ->>>>>>> srb2/next + +// Easily make it so that overtime works offline +//#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -2685,11 +1035,10 @@ void P_CheckTimeLimit(void) if (!(multiplayer || netgame)) return; -<<<<<<< HEAD - if (G_RaceGametype() || battlecapsules) -======= + if (battlecapsules) // capsules override any time limit settings + return; + if (!(gametyperules & GTR_TIMELIMIT)) ->>>>>>> srb2/next return; if (leveltime < (timelimitintics + starttime)) @@ -2698,31 +1047,7 @@ void P_CheckTimeLimit(void) if (gameaction == ga_completed) return; - //Tagmode round end but only on the tic before the - //XD_EXITLEVEL packet is received by all players. - /*if (G_TagGametype()) - { - if (leveltime == (timelimitintics + 1)) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator - || (players[i].pflags & PF_GAMETYPEOVER) || (players[i].pflags & PF_TAGIT)) - continue; - - CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]); - P_AddPlayerScore(&players[i], players[i].score); - } - } - } - else*/ - - //Optional tie-breaker for Match/CTF -<<<<<<< HEAD - if (cv_overtime.value) -======= - else if ((cv_overtime.value) && (gametyperules & GTR_OVERTIME)) ->>>>>>> srb2/next + if ((cv_overtime.value) && (gametyperules & GTR_OVERTIME)) { #ifndef TESTOVERTIMEINFREEPLAY boolean foundone = false; // Overtime is used for closing off down to a specific item. @@ -2817,15 +1142,11 @@ void P_CheckPointLimit(void) if (!(multiplayer || netgame)) return; -<<<<<<< HEAD - if (G_RaceGametype()) -======= if (!(gametyperules & GTR_POINTLIMIT)) ->>>>>>> srb2/next return; // pointlimit is nonzero, check if it's been reached by this player - /*if (G_GametypeHasTeams()) + if (G_GametypeHasTeams()) { // Just check both teams if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore) @@ -2834,7 +1155,7 @@ void P_CheckPointLimit(void) SendNetXCmd(XD_EXITLEVEL, NULL, 0); } } - else*/ + else { for (i = 0; i < MAXPLAYERS; i++) { @@ -2860,91 +1181,6 @@ void P_CheckPointLimit(void) } } -/*Checks for untagged remaining players in both tag derivitave modes. - *If no untagged players remain, end the round. - *Also serves as error checking if the only IT player leaves.*/ -/*void P_CheckSurvivors(void) -{ - INT32 i; - INT32 survivors = 0; - INT32 taggers = 0; - INT32 spectators = 0; - INT32 survivorarray[MAXPLAYERS]; - - if (!D_NumPlayers()) //no players in the game, no check performed. - return; - - for (i=0; i < MAXPLAYERS; i++) //figure out counts of taggers, survivors and spectators. - { - if (playeringame[i]) - { - if (players[i].spectator) - spectators++; - else if ((players[i].pflags & PF_TAGIT) && players[i].quittime < 30 * TICRATE) - taggers++; - else if (!(players[i].pflags & PF_GAMETYPEOVER) && players[i].quittime < 30 * TICRATE) - { - survivorarray[survivors] = i; - survivors++; - } - } - } - - if (!taggers) //If there are no taggers, pick a survivor at random to be it. - { - // Exception for hide and seek. If a round has started and the IT player leaves, end the round. - if (gametype == GT_HIDEANDSEEK && (leveltime >= (hidetime * TICRATE))) - { - CONS_Printf(M_GetText("The IT player has left the game.\n")); - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); - - return; - } - - if (survivors) - { - INT32 newtagger = survivorarray[P_RandomKey(survivors)]; - - CONS_Printf(M_GetText("%s is now IT!\n"), player_names[newtagger]); // Tell everyone who is it! - players[newtagger].pflags |= PF_TAGIT; - - survivors--; //Get rid of the guy we just made IT. - - //Yeah, we have an eligible tagger, but we may not have anybody for him to tag! - //If there is only one guy waiting on the game to fill or spectators to enter game, don't bother. - if (!survivors && (D_NumPlayers() - spectators) > 1) - { - CONS_Printf(M_GetText("All players have been tagged!\n")); - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); - } - - return; - } - - //If we reach this point, no player can replace the one that was IT. - //Unless it is one player waiting on a game, end the round. - if ((D_NumPlayers() - spectators) > 1) - { - CONS_Printf(M_GetText("There are no players able to become IT.\n")); - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); - } - - return; - } - - //If there are taggers, but no survivors, end the round. - //Except when the tagger is by himself and the rest of the game are spectators. - if (!survivors && (D_NumPlayers() - spectators) > 1) - { - CONS_Printf(M_GetText("All players have been tagged!\n")); - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); - } -}*/ - // Checks whether or not to end a race netgame. boolean P_CheckRacers(void) { @@ -3113,21 +1349,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player && !target->player->spectator) { if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording! -<<<<<<< HEAD - G_StopMetalRecording(); - /*if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty -======= G_StopMetalRecording(true); - if ((gametyperules & GTR_DEATHPENALTY) // note, no team match suicide penalty ->>>>>>> srb2/next - && ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player))) - { // Suicide penalty - Not in Kart - if (target->player->score >= 50) - target->player->score -= 50; - else - target->player->score = 0; - }*/ - target->flags2 &= ~MF2_DONTDRAW; } @@ -3138,91 +1360,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { P_SetTarget(&target->target, source); source->player->numboxes++; -<<<<<<< HEAD + if (cv_itemrespawn.value && (netgame || multiplayer)) { -======= - if (cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer)) ->>>>>>> srb2/next target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation } } - - // Award Score Tails - /*{ // Enemies shouldn't award points in Kart - INT32 score = 0; - - if (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything. - { - if ((target->flags & MF_ENEMY) && !(target->flags & (MF_MISSILE|MF_BOSS))) - { - score = 200; - - if (source->player->bonustime) - score *= 2; - - // Also, add to the link. - // I don't know if NiGHTS did this, but - // Sonic Time Attacked did and it seems like a good enough incentive - // to make people want to actually dash towards/paraloop enemies - if (++source->player->linkcount > source->player->maxlink) - source->player->maxlink = source->player->linkcount; - source->player->linktimer = nightslinktics; - } - } - else - { - if (target->flags & MF_BOSS) - score = 1000; - else if ((target->flags & MF_ENEMY) && !(target->flags & MF_MISSILE) && target->info->spawnhealth) - { - UINT8 locscoreadd = source->player->scoreadd + target->info->spawnhealth; - mobj_t *scoremobj; - UINT32 scorestate = mobjinfo[MT_SCORE].spawnstate; - - scoremobj = P_SpawnMobj(target->x, target->y, target->z + (target->height / 2), MT_SCORE); - - // More Sonic-like point system - if (!mariomode) switch (locscoreadd) - { - case 1: score = 100; break; - case 2: score = 200; scorestate += 1; break; - case 3: score = 500; scorestate += 2; break; - case 4: case 5: case 6: case 7: case 8: case 9: - case 10: case 11: case 12: case 13: case 14: - score = 1000; scorestate += 3; break; - default: score = 10000; scorestate += 4; break; - } - // Mario Mode has Mario-like chain point values - else switch (locscoreadd) - { - case 1: score = 100; break; - case 2: score = 200; scorestate += 1; break; - case 3: score = 400; scorestate += 5; break; - case 4: score = 800; scorestate += 6; break; - case 5: score = 1000; scorestate += 3; break; - case 6: score = 2000; scorestate += 7; break; - case 7: score = 4000; scorestate += 8; break; - case 8: score = 8000; scorestate += 9; break; - default: // 1up for a chain this long - if (modeattacking) // but 1ups don't exist in record attack! - { // So we just go back to 10k points. - score = 10000; scorestate += 4; break; - } - P_GivePlayerLives(source->player, 1); - P_PlayLivesJingle(source->player); - scorestate += 10; - break; - } - - P_SetMobjState(scoremobj, scorestate); - - source->player->scoreadd = locscoreadd; - } - } - - P_AddPlayerScore(source->player, score); - }*/ } // if a player avatar dies... @@ -3230,45 +1373,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { target->flags &= ~(MF_SOLID|MF_SHOOTABLE); // does not block P_UnsetThingPosition(target); -<<<<<<< HEAD - target->flags |= MF_NOBLOCKMAP|MF_NOCLIPHEIGHT; -======= target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; ->>>>>>> srb2/next P_SetThingPosition(target); target->standingslope = NULL; target->pmomz = 0; -<<<<<<< HEAD if (!target->player->bot && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) -======= - if (target->player->powers[pw_super]) - { - target->player->powers[pw_super] = 0; - if (P_IsLocalPlayer(target->player)) - { - music_stack_noposition = true; // HACK: Do not reposition next music - music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music - } - P_RestoreMusic(target->player); - - if (gametype != GT_COOP) - { - HU_SetCEchoFlags(0); - HU_SetCEchoDuration(5); - HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[target->player-players])); - } - } - - target->color = target->player->skincolor; - target->colorized = false; - G_GhostAddColor(GHC_NORMAL); - - if ((target->player->lives <= 1) && (netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value == 0)) - ; - else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES) - && G_GametypeUsesLives()) ->>>>>>> srb2/next { if (!(target->player->pflags & PF_FINISHED)) target->player->lives -= 1; // Lose a life Tails 03-11-2000 @@ -3318,52 +1428,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget //added : 22-02-98: recenter view for next life... localaiming[0] = 0; } - if (target->player == &players[displayplayers[1]]) - { - // added : 22-02-98: recenter view for next life... - localaiming[1] = 0; - } - if (target->player == &players[displayplayers[2]]) - localaiming[2] = 0; - if (target->player == &players[displayplayers[3]]) - localaiming[3] = 0; - //tag deaths handled differently in suicide cases. Don't count spectators! - /*if (G_TagGametype() - && !(target->player->pflags & PF_TAGIT) && (!source || !source->player) && !(target->player->spectator)) - { - // if you accidentally die before you run out of time to hide, ignore it. - // allow them to try again, rather than sitting the whole thing out. - if (leveltime >= hidetime * TICRATE) - { - if (gametype == GT_TAG)//suiciding in survivor makes you IT. - { - target->player->pflags |= PF_TAGIT; - CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it! - P_CheckSurvivors(); - } - else - { - if (!(target->player->pflags & PF_GAMETYPEOVER)) - { - //otherwise, increment the tagger's score. - //in hide and seek, suiciding players are counted as found. - INT32 w; + if (target->player == &players[displayplayers[1]]) localaiming[1] = 0; + if (target->player == &players[displayplayers[2]]) localaiming[2] = 0; + if (target->player == &players[displayplayers[3]]) localaiming[3] = 0; - for (w=0; w < MAXPLAYERS; w++) - { - if (players[w].pflags & PF_TAGIT) - P_AddPlayerScore(&players[w], 1); - } - - target->player->pflags |= PF_GAMETYPEOVER; - CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]); - P_CheckSurvivors(); - } - } - } - } - else*/ if (G_BattleGametype()) + if (G_BattleGametype()) K_CheckBumpers(); target->player->kartstuff[k_pogospring] = 0; @@ -3512,30 +1582,21 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = TICRATE; break; -<<<<<<< HEAD - case MT_PLAYER: - target->momx = target->momy = target->momz = 0; - - if (target->player && target->player->pflags & PF_TIMEOVER) - break; - - target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) - if (!(source && source->type == MT_NULL && source->threshold == 42)) // Don't jump up when drowning - P_SetObjectMomZ(target, 14*FRACUNIT, false); -======= case MT_MINECART: A_Scream(target); target->momx = target->momy = target->momz = 0; if (target->target && target->target->health) P_KillMobj(target->target, target, source, 0); break; ->>>>>>> srb2/next case MT_PLAYER: { target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) target->momx = target->momy = target->momz = 0; + if (target->player && target->player->pflags & PF_TIMEOVER) + break; + if (damagetype == DMG_DROWNED) // drowned { target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack. @@ -3555,6 +1616,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } break; + case MT_METALSONIC_RACE: target->fuse = TICRATE*3; target->momx = target->momy = target->momz = 0; @@ -3575,6 +1637,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget S_StartSound(target, sfx_s3k80); } break; + case MT_BATTLECAPSULE: { mobj_t *cur; @@ -3619,43 +1682,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget break; } - // Final state setting - do something instead of P_SetMobjState; - if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) - { - const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; - const fixed_t scale = target->scale; - const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale); - const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); - mobj_t *chunk; - fixed_t momz; - - S_StartSound(target, target->info->deathsound); - - if (target->info->xdeathstate != S_NULL) - { - momz = 6*scale; - if (flip) - momz *= -1; -#define makechunk(angtweak, xmov, ymov) \ - chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\ - P_SetMobjState(chunk, target->info->xdeathstate);\ - chunk->health = 0;\ - chunk->angle = angtweak;\ - P_UnsetThingPosition(chunk);\ - chunk->flags = MF_NOCLIP;\ - chunk->x += xmov;\ - chunk->y += ymov;\ - P_SetThingPosition(chunk);\ - P_InstaThrust(chunk,chunk->angle, 4*scale);\ - chunk->momz = momz - - makechunk(ang + ANGLE_180, -xoffs, -yoffs); - makechunk(ang, xoffs, yoffs); - -#undef makechunk - } - -<<<<<<< HEAD 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; @@ -3695,33 +1721,41 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_InstaThrust(target, R_PointToAngle2(inflictor->x, inflictor->y, target->x, target->y)+ANGLE_90, 16<type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL) + // Final state setting - do something instead of P_SetMobjState; + if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) { - const fixed_t x=target->x,y=target->y,z=target->z; - const fixed_t scale=target->scale; - const boolean flip=(target->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP; - S_StartSound(target,target->info->deathsound); -======= - momz = 7*scale; - if (flip) - momz *= -1; + const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + fixed_t momz; - chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE); - P_SetMobjState(chunk, target->info->deathstate); - chunk->health = 0; - chunk->angle = ang + ANGLE_180; - P_UnsetThingPosition(chunk); - chunk->flags = MF_NOCLIP; - chunk->x -= xoffs; - chunk->y -= yoffs; - if (flip) - chunk->z -= 12*scale; - else - chunk->z += 12*scale; - P_SetThingPosition(chunk); - P_InstaThrust(chunk, chunk->angle, 2*scale); - chunk->momz = momz; ->>>>>>> srb2/next + S_StartSound(target, target->info->deathsound); + + if (target->info->xdeathstate != S_NULL) + { + momz = 6*scale; + if (flip) + momz *= -1; +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = angtweak;\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov;\ + chunk->y += ymov;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk,chunk->angle, 4*scale);\ + chunk->momz = momz + + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + makechunk(ang, xoffs, yoffs); + +#undef makechunk + } P_SetMobjState(target, target->info->deathstate); target->health = 0; @@ -3828,209 +1862,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget Graue 12-22-2003 */ } -static void P_NiGHTSDamage(mobj_t *target, mobj_t *source) -{ - player_t *player = target->player; - tic_t oldnightstime = player->nightstime; - - (void)source; // unused - - if (!player->powers[pw_flashing]) - { - angle_t fa; - - player->angle_pos = player->old_angle_pos; - player->speed /= 5; - player->flyangle += 180; // Shuffle's BETTERNIGHTSMOVEMENT? - player->flyangle %= 360; - -<<<<<<< HEAD - if (G_RaceGametype()) -======= - if (gametyperules & GTR_RACE) ->>>>>>> srb2/next - player->drillmeter -= 5*20; - else - { - if (player->nightstime > 5*TICRATE) - player->nightstime -= 5*TICRATE; - else - player->nightstime = 1; - } - - if (player->pflags & PF_TRANSFERTOCLOSEST) - { - target->momx = -target->momx; - target->momy = -target->momy; - } - else - { - fa = player->old_angle_pos>>ANGLETOFINESHIFT; - - target->momx = FixedMul(FINECOSINE(fa),target->target->radius); - target->momy = FixedMul(FINESINE(fa),target->target->radius); - } - -<<<<<<< HEAD - player->powers[pw_flashing] = K_GetKartFlashing(player); - P_SetMobjState(target->tracer, S_NIGHTSHURT1); -======= - player->powers[pw_flashing] = flashingtics; - P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN); ->>>>>>> srb2/next - S_StartSound(target, sfx_nghurt); - - player->mo->rollangle = 0; - - if (oldnightstime > 10*TICRATE - && player->nightstime < 10*TICRATE) - { - if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) -#ifdef _WIN32 - // win32 MIDI volume hack means we cannot fade down the music - && S_MusicType() != MU_MID -#endif - ) - { - S_FadeMusic(0, 10*MUSICRATE); - S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. - } - else - P_PlayJingle(player, ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? JT_NIGHTSTIMEOUT : JT_SSTIMEOUT); - } - } -} - -static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) -{ - player_t *player = target->player; - (void)damage; //unused parm - - // If flashing or invulnerable, ignore the tag, - if (player->powers[pw_flashing] || player->powers[pw_invulnerability]) - return false; - - // Don't allow any damage before the round starts. - if (leveltime <= hidetime * TICRATE) - return false; - - // Ignore IT players shooting each other, unless friendlyfire is on. - if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && - source && source->player && source->player->pflags & PF_TAGIT))) - { - if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) - { - if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. - { - P_SwitchShield(player, SH_PINK); - S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound); - } - } - return false; - } - - // Don't allow players on the same team to hurt one another, - // unless cv_friendlyfire is on. - if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT)) - { - if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) - { - if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. - { - P_SwitchShield(player, SH_PINK); - S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound); - } - } - else if (!(inflictor->flags & MF_FIRE)) - P_GivePlayerRings(player, 1); - if (inflictor->flags2 & MF2_BOUNCERING) - inflictor->fuse = 0; // bounce ring disappears at -1 not 0 - return false; - } - - if (inflictor->type == MT_LHRT) - return false; - - // The tag occurs so long as you aren't shooting another tagger with friendlyfire on. - /*if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT)) - { -<<<<<<< HEAD - P_AddPlayerScore(source->player, 1); //award points to tagger. -======= - P_AddPlayerScore(source->player, 100); //award points to tagger. - P_HitDeathMessages(player, inflictor, source, 0); ->>>>>>> srb2/next - - if (gametype == GT_TAG) //survivor - { - player->pflags |= PF_TAGIT; //in survivor, the player becomes IT and helps hunt down the survivors. - CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it! - } - else - { - player->pflags |= PF_GAMETYPEOVER; //in hide and seek, the player is tagged and stays stationary. - CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it! - } - - //checks if tagger has tagged all players, if so, end round early. - P_CheckSurvivors(); - }*/ - - P_DoPlayerPain(player, source, inflictor); - - // Check for a shield - if (player->powers[pw_shield]) - { - P_RemoveShield(player); - S_StartSound(target, sfx_shldls); - return true; - } - -<<<<<<< HEAD - P_PlayRinglossSound(target); - P_PlayerRingBurst(player, 5); - - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) -======= - if (player->powers[pw_carry] == CR_NIGHTSFALL) - { - if (player->spheres > 0) - { - P_PlayRinglossSound(target); - P_PlayerRingBurst(player, player->spheres); - player->spheres = 0; - } - } - else if (player->rings > 0) // Ring loss - { - P_PlayRinglossSound(target); - P_PlayerRingBurst(player, player->rings); - player->rings = 0; - } - else // Death ->>>>>>> srb2/next - { - P_PlayDeathSound(target); - P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!! - } - return true; -} - static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { player_t *player = target->player; -<<<<<<< HEAD - // You can't kill yourself, idiot... // Unless it's Mario kart. Which it is. In this mod. All the time. - //if (source == target) - // return false; - - // In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on - // ...But in SRB2kart, you can! - //if (!cv_friendlyfire.value && (G_RaceGametype())) - // return false; -======= - if (!(damagetype & DMG_CANHURTSELF)) + // SRB2Kart: We want to hurt ourselves + if (damagetype & DMG_CANTHURTSELF) { // You can't kill yourself, idiot... if (source == target) @@ -4050,76 +1887,21 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; } } ->>>>>>> srb2/next - - // Tag handling - if (G_TagGametype()) - return P_TagDamage(target, inflictor, source, damage, damagetype); - else if (damagetype & DMG_CANHURTSELF) - return true; - else if (G_GametypeHasTeams()) // CTF + Team Match - { - // Don't allow players on the same team to hurt one another, - // unless cv_friendlyfire is on. - if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && target->player->ctfteam == source->player->ctfteam) - { - if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) - { - if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. - { - P_SwitchShield(player, SH_PINK); - S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound); - } - } - else if (!(inflictor->flags & MF_FIRE)) - P_GivePlayerRings(target->player, 1); - if (inflictor->flags2 & MF2_BOUNCERING) - inflictor->fuse = 0; // bounce ring disappears at -1 not 0 - - return false; - } - } - - if (inflictor->type == MT_LHRT) - return false; - - // Add pity. - if (!player->powers[pw_flashing] && !player->powers[pw_invulnerability] && !player->powers[pw_super] - && source->player->score > player->score) - player->pity++; return true; } static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) { -<<<<<<< HEAD - (void)source; - - player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE); -======= player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; - // Burst weapons and emeralds in Match/CTF only - if (source) - { - if ((gametyperules & GTR_RINGSLINGER) && !(gametyperules & GTR_TAG)) - P_PlayerRingBurst(player, player->rings); - if (gametyperules & GTR_POWERSTONES) - P_PlayerEmeraldBurst(player, false); - } ->>>>>>> srb2/next - // Get rid of shield player->powers[pw_shield] = SH_NONE; player->mo->color = player->skincolor; player->mo->colorized = false; - // Get rid of emeralds - player->powers[pw_emeralds] = 0; - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); P_ResetPlayer(player); @@ -4128,25 +1910,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) player->mo->flags2 &= ~MF2_DONTDRAW; P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); -<<<<<<< HEAD -======= - if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - { - P_PlayerFlagBurst(player, false); - if (source && source->player) - { - // Award no points when players shoot each other when cv_friendlyfire is on. - if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 25); - } - } - if (source && source->player && !player->powers[pw_super]) //don't score points against super players - { - // Award no points when players shoot each other when cv_friendlyfire is on. - if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 100); - } ->>>>>>> srb2/next if (player->pflags & PF_TIMEOVER) { @@ -4178,29 +1941,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) K_CheckBumpers(); } -<<<<<<< HEAD -======= - else if (inflictor->flags2 & MF2_EXPLOSION) - { - if (inflictor->flags2 & MF2_RAILRING) - fallbackspeed = FixedMul(28*FRACUNIT, inflictor->scale); // 7x - else - fallbackspeed = FixedMul(20*FRACUNIT, inflictor->scale); // 5x - } - else if (inflictor->flags2 & MF2_RAILRING) - fallbackspeed = FixedMul(16*FRACUNIT, inflictor->scale); // 4x - else - fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force - - P_InstaThrust(player->mo, ang, fallbackspeed); - - P_SetPlayerMobjState(player->mo, S_PLAY_STUN); - - P_ResetPlayer(player); - - if (player->timeshit != UINT8_MAX) - ++player->timeshit; ->>>>>>> srb2/next } void P_RemoveShield(player_t *player) @@ -4233,150 +1973,6 @@ void P_RemoveShield(player_t *player) } } -<<<<<<< HEAD -======= -static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) -{ - // Must do pain first to set flashing -- P_RemoveShield can cause damage - P_DoPlayerPain(player, source, inflictor); - - P_RemoveShield(player); - - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - - if (damagetype == DMG_SPIKE) // spikes - S_StartSound(player->mo, sfx_spkdth); - else - S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. - - if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - { - P_PlayerFlagBurst(player, false); - if (source && source->player) - { - // Award no points when players shoot each other when cv_friendlyfire is on. - if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 25); - } - } - if (source && source->player && !player->powers[pw_super]) //don't score points against super players - { - // Award no points when players shoot each other when cv_friendlyfire is on. - if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 50); - } -} - -static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype, boolean dospheres) -{ - P_DoPlayerPain(player, source, inflictor); - - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - - if (damagetype == DMG_SPIKE) // spikes - S_StartSound(player->mo, sfx_spkdth); - - if (source && source->player && !player->powers[pw_super]) //don't score points against super players - { - // Award no points when players shoot each other when cv_friendlyfire is on. - if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 50); - } - - if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - { - P_PlayerFlagBurst(player, false); - if (source && source->player) - { - // Award no points when players shoot each other when cv_friendlyfire is on. - if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 25); - } - } - - // Ring loss sound plays despite hitting spikes - P_PlayRinglossSound(player->mo); // Ringledingle! - P_PlayerRingBurst(player, damage); - - if (dospheres) - { - player->spheres -= damage; - if (player->spheres < 0) - player->spheres = 0; - } - else - { - player->rings -= damage; - if (player->rings < 0) - player->rings = 0; - } -} - -// -// P_SpecialStageDamage -// -// Do old special stage-style damaging -// Removes 5 seconds from the player, or knocks off their shield if they have one. -// If they don't have anything, just knock the player back anyway (this doesn't kill them). -// -void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) -{ - tic_t oldnightstime = player->nightstime; - - if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) - return; - - if (!cv_friendlyfire.value && source && source->player) - { - if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) - { - if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. - { - P_SwitchShield(player, SH_PINK); - S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound); - } - } - - if (source->player->ctfteam == player->ctfteam) - return; - } - - if (inflictor && inflictor->type == MT_LHRT) - return; - - if (player->powers[pw_shield] || player->bot) //If One-Hit Shield - { - P_RemoveShield(player); - S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. - } - else - { - S_StartSound(player->mo, sfx_nghurt); - if (player->nightstime > 5*TICRATE) - player->nightstime -= 5*TICRATE; - else - player->nightstime = 0; - } - - P_DoPlayerPain(player, inflictor, source); - - if ((gametyperules & GTR_TEAMFLAGS) && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) - P_PlayerFlagBurst(player, false); - - if (oldnightstime > 10*TICRATE - && player->nightstime < 10*TICRATE) - { - if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) - { - S_FadeMusic(0, 10*MUSICRATE); - S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. - } - else - S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); - } -} ->>>>>>> srb2/next - /** Damages an object, which may or may not be a player. * For melee attacks, source and inflictor are the same. * @@ -4432,32 +2028,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (!(target->flags & MF_SHOOTABLE)) return false; // shouldn't happen... - if (target->type == MT_BLACKEGGMAN) - return false; - // Make sure that boxes cannot be popped by enemies, red rings, etc. -<<<<<<< HEAD if (target->flags & MF_MONITOR && ((!source || !source->player) || (inflictor && !inflictor->player))) -======= - if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot) - || (inflictor && (inflictor->type == MT_REDRING || (inflictor->type >= MT_THROWNBOUNCE && inflictor->type <= MT_THROWNGRENADE))))) ->>>>>>> srb2/next return false; } if (target->flags2 & MF2_SKULLFLY) target->momx = target->momy = target->momz = 0; - if (!force) - { - // Special case for team ring boxes - if (target->type == MT_RING_REDBOX && !(source->player->ctfteam == 1)) - return false; - - if (target->type == MT_RING_BLUEBOX && !(source->player->ctfteam == 2)) - return false; - } - if (target->flags & (MF_ENEMY|MF_BOSS)) { if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit @@ -4484,75 +2062,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if ((maptol & TOL_NIGHTS) && target->player->powers[pw_carry] != CR_NIGHTSMODE && target->player->powers[pw_carry] != CR_NIGHTSFALL) return false; - - switch (damagetype) - { -#define DAMAGECASE(type)\ - case DMG_##type:\ - if (player->powers[pw_shield] & SH_PROTECT##type)\ - return false;\ - break - DAMAGECASE(WATER); - DAMAGECASE(FIRE); - DAMAGECASE(ELECTRIC); - DAMAGECASE(SPIKE); -#undef DAMAGECASE - default: - break; - } - } - - if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS damage handling - { - if (!force) - { - if (source == target) - return false; // Don't hit yourself with your own paraloop, baka - if (source && source->player && !(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) - && (gametype == GT_COOP - || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) - return false; // Don't run eachother over in special stages and team games and such - } - if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) - return true; - P_NiGHTSDamage(target, source); // -5s :( - return true; - } - -<<<<<<< HEAD -#ifdef HAVE_BLUA // Add this back here for ACTUAL NORMAL DAMAGE. The funny shit is that the player is barely ever "actually" damaged. - if (LUAh_MobjDamage(target, inflictor, source, damage)) - return true; -#endif - - if (!force && inflictor && (inflictor->flags & MF_FIRE)) - { - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) - return false; // Invincible to fire objects - - if (G_RaceGametype() && source && source->player) - return false; // Don't get hurt by fire generated from friends. -======= - if (G_IsSpecialStage(gamemap) && !(damagetype & DMG_DEATHMASK)) - { - P_SpecialStageDamage(player, inflictor, source); - return true; ->>>>>>> srb2/next - } - - if (!force && inflictor && inflictor->flags & MF_FIRE) - { -<<<<<<< HEAD - if ((G_BattleGametype()) && cv_suddendeath.value - && !player->powers[pw_flashing] && !player->powers[pw_invulnerability]) - damage = 10000; -======= - if (player->powers[pw_shield] & SH_PROTECTFIRE) - return false; // Invincible to fire objects - - if (G_PlatformGametype() && inflictor && source && source->player) - return false; // Don't get hurt by fire generated from friends. ->>>>>>> srb2/next } // Player hits another player @@ -4565,115 +2074,35 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Instant-Death if (damagetype & DMG_DEATHMASK) P_KillPlayer(player, source, damage); - else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing]) - { -<<<<<<< HEAD - if (!force) // shoulddamage bypasses all of that. - { - K_DoInstashield(player); - return false; - } -======= - if (!inflictor) - inflictor = source; - if (inflictor && inflictor->flags & MF_ENEMY) - { // Metal Sonic destroy enemy !! - P_KillMobj(inflictor, NULL, target, damagetype); - return false; - } - else if (inflictor && inflictor->flags & MF_MISSILE) - return false; // Metal Sonic walk through flame !! - else if (!player->powers[pw_flashing]) - { // Oh no! Metal Sonic is hit !! - P_ShieldDamage(player, inflictor, source, damage, damagetype); - return true; - } - return false; - } - else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) // ignore bouncing & such in invulnerability - { - if (force - || (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned! - { - if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) - P_SuperDamage(player, inflictor, source, damage); - return true; - } - return false; - } else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; - else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield - { - P_ShieldDamage(player, inflictor, source, damage, damagetype); - damage = 0; - } - else if (player->powers[pw_carry] == CR_NIGHTSFALL) - { - // always damage so we can recoil upon losing points - damage = player->spheres; - P_RingDamage(player, inflictor, source, damage, damagetype, true); - damage = 0; - } - else if (player->rings > 0) // No shield but have rings. - { - damage = player->rings; - P_RingDamage(player, inflictor, source, damage, damagetype, false); - damage = 0; - } - // To reduce griefing potential, don't allow players to be killed - // by friendly fire. Spilling their rings and other items is enough. - else if (!force && G_GametypeHasTeams() - && source && source->player && (source->player->ctfteam == player->ctfteam) - && (cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE))) - { - damage = 0; - P_ShieldDamage(player, inflictor, source, damage, damagetype); ->>>>>>> srb2/next - } - else // No shield, no rings, no invincibility. - { -<<<<<<< HEAD - 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_SMK_THWOMP || inflictor->player)) - { - player->kartstuff[k_sneakertimer] = 0; - K_SpinPlayer(player, source, 1, inflictor, false); - K_KartPainEnergyFling(player); + 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_SMK_THWOMP || inflictor->player)) + { + player->kartstuff[k_sneakertimer] = 0; - if (P_IsDisplayPlayer(player)) - P_StartQuake(32<>>>>>> srb2/next + return true; } - // Killing dead. Just for kicks. - // Require source and inflictor be player. Don't hurt for firing rings. - if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_RandomChance(5*FRACUNIT/16)) - P_DamageMobj(source, target, target, 1, 0); - // do the damage if (damagetype & DMG_DEATHMASK) target->health = 0; else target->health -= damage; - if (player) - P_HitDeathMessages(player, inflictor, source, damagetype); - if (source && source->player && target) G_GhostAddHit((INT32) (source->player - players), target); @@ -4685,41 +2114,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player) P_ResetPlayer(target->player); - else if ((target->type == MT_EGGMOBILE2) // egg slimer - && (target->health < target->info->damage)) // in pinch phase - P_SetMobjState(target, target->info->meleestate); // go to pinch pain state else P_SetMobjState(target, target->info->painstate); - if (target->type == MT_HIVEELEMENTAL) - target->extravalue1 += 3; - if (!P_MobjWasRemoved(target)) { -<<<<<<< HEAD - target->reactiontime = 0; // we're awake now... - - if (source && source != target) - { - // if not intent on another player, - // chase after this one - P_SetTarget(&target->target, source); - if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) - { - if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); - } - else - P_SetMobjState(target, target->info->seestate); - } - } -======= // if not intent on another player, // chase after this one P_SetTarget(&target->target, source); ->>>>>>> srb2/next } return true; @@ -4739,21 +2141,16 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) angle_t fa, va; fixed_t ns; fixed_t z; -<<<<<<< HEAD fixed_t momxy = 5<>>>>>> srb2/next // Better safe than sorry. if (!player) return; -<<<<<<< HEAD // Have a shield? You get hit, but don't lose your rings! if (K_GetShieldFromItem(player->kartstuff[k_itemtype]) != KSHIELD_NONE) return; @@ -4763,44 +2160,19 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) num_rings = 20; else if (num_rings <= 0) return; -======= - // If no health, don't spawn ring! - if (((maptol & TOL_NIGHTS) && player->spheres <= 0) || (!(maptol & TOL_NIGHTS) && player->rings <= 0)) - num_rings = 0; - - if (num_rings > 32 && player->powers[pw_carry] != CR_NIGHTSFALL) - num_rings = 32; ->>>>>>> srb2/next // Cap the maximum loss automatically to 2 in ring debt if (player->kartstuff[k_rings] <= 0 && num_rings > 2) num_rings = 2; -<<<<<<< HEAD P_GivePlayerRings(player, -num_rings); // determine first angle fa = player->mo->angle + ((P_RandomByte() & 1) ? -ANGLE_90 : ANGLE_90); -======= - // Spill weapons first - P_PlayerWeaponPanelOrAmmoBurst(player); - - if (abs(player->mo->momx) > player->mo->scale || abs(player->mo->momy) > player->mo->scale) - va = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0)>>ANGLETOFINESHIFT; - else - va = player->mo->angle>>ANGLETOFINESHIFT; ->>>>>>> srb2/next for (i = 0; i < num_rings; i++) { INT32 objType = mobjinfo[MT_RING].reactiontime; -<<<<<<< HEAD -======= - if (mariomode) - objType = mobjinfo[MT_COIN].reactiontime; - else if (player->powers[pw_carry] == CR_NIGHTSFALL) - objType = mobjinfo[(nightsreplace ? MT_NIGHTSCHIP : MT_BLUESPHERE)].reactiontime; ->>>>>>> srb2/next z = player->mo->z; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -4815,114 +2187,16 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) mo->destscale = player->mo->scale; P_SetScale(mo, player->mo->scale); -<<<<<<< HEAD // Angle / height offset changes every other ring if (i != 0) -======= - // Angle offset by player angle, then slightly offset by amount of rings - fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK; - - // Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2. - // Technically a non-SA way of spilling rings. They just so happen to be a little similar. - if (player->powers[pw_carry] == CR_NIGHTSFALL) - { - ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale); - mo->momx = FixedMul(FINECOSINE(fa),ns); - - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) - mo->momy = FixedMul(FINESINE(fa),ns); - - P_SetObjectMomZ(mo, 8*FRACUNIT, false); - mo->fuse = 20*TICRATE; // Adjust fuse for NiGHTS - - // Toggle bonus time colors - P_SetMobjState(mo, (player->bonustime ? mo->info->raisestate : mo->info->spawnstate)); - } - else ->>>>>>> srb2/next { if (i & 1) { momxy -= FRACUNIT; momz += 2<losstime<scale); - mo->momx = FixedMul(FINECOSINE(fa),ns); - - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) - mo->momy = FixedMul(FINESINE(fa),ns); - - ns = FixedMul(momz, FRACUNIT + FixedDiv(player->losstime<mo->eflags & MFE_VERTICALFLIP) - mo->momz *= -1; - } - - player->losstime += 10*TICRATE; - - return; -} - -void P_PlayerWeaponPanelBurst(player_t *player) -{ - mobj_t *mo; - angle_t fa; - fixed_t ns; - INT32 i; - fixed_t z; - - INT32 num_weapons = M_CountBits((UINT32)player->ringweapons, NUM_WEAPONS-1); - UINT16 ammoamt = 0; - - for (i = 0; i < num_weapons; i++) - { - mobjtype_t weptype = 0; - powertype_t power = 0; - - if (player->ringweapons & RW_BOUNCE) // Bounce - { - weptype = MT_BOUNCEPICKUP; - player->ringweapons &= ~RW_BOUNCE; - power = pw_bouncering; - } - else if (player->ringweapons & RW_RAIL) // Rail - { - weptype = MT_RAILPICKUP; - player->ringweapons &= ~RW_RAIL; - power = pw_railring; - } - else if (player->ringweapons & RW_AUTO) // Auto - { - weptype = MT_AUTOPICKUP; - player->ringweapons &= ~RW_AUTO; - power = pw_automaticring; - } - else if (player->ringweapons & RW_EXPLODE) // Explode - { - weptype = MT_EXPLODEPICKUP; - player->ringweapons &= ~RW_EXPLODE; - power = pw_explosionring; - } - else if (player->ringweapons & RW_SCATTER) // Scatter - { - weptype = MT_SCATTERPICKUP; - player->ringweapons &= ~RW_SCATTER; - power = pw_scatterring; - } - else if (player->ringweapons & RW_GRENADE) // Grenade - { - weptype = MT_GRENADEPICKUP; - player->ringweapons &= ~RW_GRENADE; - power = pw_grenadering; ->>>>>>> srb2/next } ns = FixedMul(momxy, mo->scale); @@ -4933,411 +2207,6 @@ void P_PlayerWeaponPanelBurst(player_t *player) P_SetObjectMomZ(mo, (mo->target->momz/2) + ns, false); if (player->mo->eflags & MFE_VERTICALFLIP) -<<<<<<< HEAD mo->momz *= -1; -======= - z += player->mo->height - mobjinfo[weptype].height; - - mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype); - mo->reactiontime = ammoamt; - mo->flags2 |= MF2_DONTRESPAWN; - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); - P_SetTarget(&mo->target, player->mo); - mo->fuse = 12*TICRATE; - mo->destscale = player->mo->scale; - P_SetScale(mo, player->mo->scale); - - // Angle offset by player angle - fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; - - // Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2. - // Technically a non-SA way of spilling rings. They just so happen to be a little similar. - - // >16 ring type spillout - ns = FixedMul(3*FRACUNIT, mo->scale); - mo->momx = FixedMul(FINECOSINE(fa),ns); - - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) - mo->momy = FixedMul(FINESINE(fa),ns); - - P_SetObjectMomZ(mo, 4*FRACUNIT, false); - - if (i & 1) - P_SetObjectMomZ(mo, 4*FRACUNIT, true); } } - -void P_PlayerWeaponAmmoBurst(player_t *player) -{ - mobj_t *mo; - angle_t fa; - fixed_t ns; - INT32 i = 0; - fixed_t z; - - mobjtype_t weptype = 0; - powertype_t power = 0; - - while (true) - { - if (player->powers[pw_bouncering]) - { - weptype = MT_BOUNCERING; - power = pw_bouncering; - } - else if (player->powers[pw_railring]) - { - weptype = MT_RAILRING; - power = pw_railring; - } - else if (player->powers[pw_infinityring]) - { - weptype = MT_INFINITYRING; - power = pw_infinityring; - } - else if (player->powers[pw_automaticring]) - { - weptype = MT_AUTOMATICRING; - power = pw_automaticring; - } - else if (player->powers[pw_explosionring]) - { - weptype = MT_EXPLOSIONRING; - power = pw_explosionring; - } - else if (player->powers[pw_scatterring]) - { - weptype = MT_SCATTERRING; - power = pw_scatterring; - } - else if (player->powers[pw_grenadering]) - { - weptype = MT_GRENADERING; - power = pw_grenadering; - } - else - break; // All done! - - z = player->mo->z; - if (player->mo->eflags & MFE_VERTICALFLIP) - z += player->mo->height - mobjinfo[weptype].height; - - mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype); - mo->health = player->powers[power]; - mo->flags2 |= MF2_DONTRESPAWN; - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); - P_SetTarget(&mo->target, player->mo); - - player->powers[power] = 0; - mo->fuse = 12*TICRATE; - - mo->destscale = player->mo->scale; - P_SetScale(mo, player->mo->scale); - - // Angle offset by player angle - fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; - - // Spill them! - ns = FixedMul(2*FRACUNIT, mo->scale); - mo->momx = FixedMul(FINECOSINE(fa), ns); - - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) - mo->momy = FixedMul(FINESINE(fa),ns); - - P_SetObjectMomZ(mo, 3*FRACUNIT, false); - - if (i & 1) - P_SetObjectMomZ(mo, 3*FRACUNIT, true); - - i++; - } -} - -void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) -{ - mobj_t *mo; - angle_t fa; - fixed_t ns; - INT32 i = 0; - fixed_t z; - - #define SETUP_DROP(thingtype) \ - z = player->mo->z; \ - if (player->mo->eflags & MFE_VERTICALFLIP) \ - z += player->mo->height - mobjinfo[thingtype].height; \ - fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; \ - ns = FixedMul(3*FRACUNIT, player->mo->scale); \ - - #define DROP_WEAPON(rwflag, pickup, ammo, power) \ - if (player->ringweapons & rwflag) \ - { \ - player->ringweapons &= ~rwflag; \ - SETUP_DROP(pickup) \ - mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ - mo->reactiontime = 0; \ - mo->flags2 |= MF2_DONTRESPAWN; \ - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ - P_SetTarget(&mo->target, player->mo); \ - mo->fuse = 12*TICRATE; \ - mo->destscale = player->mo->scale; \ - P_SetScale(mo, player->mo->scale); \ - mo->momx = FixedMul(FINECOSINE(fa),ns); \ - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ - mo->momy = FixedMul(FINESINE(fa),ns); \ - P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ - if (i & 1) \ - P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ - ++i; \ - } \ - else if (player->powers[power] > 0) \ - { \ - SETUP_DROP(ammo) \ - mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ - mo->health = player->powers[power]; \ - mo->flags2 |= MF2_DONTRESPAWN; \ - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ - P_SetTarget(&mo->target, player->mo); \ - mo->fuse = 12*TICRATE; \ - mo->destscale = player->mo->scale; \ - P_SetScale(mo, player->mo->scale); \ - mo->momx = FixedMul(FINECOSINE(fa),ns); \ - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ - mo->momy = FixedMul(FINESINE(fa),ns); \ - P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ - if (i & 1) \ - P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ - player->powers[power] = 0; \ - ++i; \ - } - - DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); - DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); - DROP_WEAPON(RW_AUTO, MT_AUTOPICKUP, MT_AUTOMATICRING, pw_automaticring); - DROP_WEAPON(RW_EXPLODE, MT_EXPLODEPICKUP, MT_EXPLOSIONRING, pw_explosionring); - DROP_WEAPON(RW_SCATTER, MT_SCATTERPICKUP, MT_SCATTERRING, pw_scatterring); - DROP_WEAPON(RW_GRENADE, MT_GRENADEPICKUP, MT_GRENADERING, pw_grenadering); - DROP_WEAPON(0, 0, MT_INFINITYRING, pw_infinityring); - - #undef DROP_WEAPON - #undef SETUP_DROP -} - -// -// P_PlayerEmeraldBurst -// -// Spills ONLY emeralds. -// -void P_PlayerEmeraldBurst(player_t *player, boolean toss) -{ - INT32 i; - angle_t fa; - fixed_t ns; - fixed_t z = 0, momx = 0, momy = 0; - - // Better safe than sorry. - if (!player) - return; - - // Spill power stones - if (player->powers[pw_emeralds]) - { - INT32 num_stones = 0; - - if (player->powers[pw_emeralds] & EMERALD1) - num_stones++; - if (player->powers[pw_emeralds] & EMERALD2) - num_stones++; - if (player->powers[pw_emeralds] & EMERALD3) - num_stones++; - if (player->powers[pw_emeralds] & EMERALD4) - num_stones++; - if (player->powers[pw_emeralds] & EMERALD5) - num_stones++; - if (player->powers[pw_emeralds] & EMERALD6) - num_stones++; - if (player->powers[pw_emeralds] & EMERALD7) - num_stones++; - - for (i = 0; i < num_stones; i++) - { - INT32 stoneflag = 0; - statenum_t statenum = S_CEMG1; - mobj_t *mo; - - if (player->powers[pw_emeralds] & EMERALD1) - { - stoneflag = EMERALD1; - statenum = S_CEMG1; - } - else if (player->powers[pw_emeralds] & EMERALD2) - { - stoneflag = EMERALD2; - statenum = S_CEMG2; - } - else if (player->powers[pw_emeralds] & EMERALD3) - { - stoneflag = EMERALD3; - statenum = S_CEMG3; - } - else if (player->powers[pw_emeralds] & EMERALD4) - { - stoneflag = EMERALD4; - statenum = S_CEMG4; - } - else if (player->powers[pw_emeralds] & EMERALD5) - { - stoneflag = EMERALD5; - statenum = S_CEMG5; - } - else if (player->powers[pw_emeralds] & EMERALD6) - { - stoneflag = EMERALD6; - statenum = S_CEMG6; - } - else if (player->powers[pw_emeralds] & EMERALD7) - { - stoneflag = EMERALD7; - statenum = S_CEMG7; - } - - if (!stoneflag) // ??? - continue; - - player->powers[pw_emeralds] &= ~stoneflag; - - if (toss) - { - fa = player->mo->angle>>ANGLETOFINESHIFT; - - z = player->mo->z + player->mo->height; - if (player->mo->eflags & MFE_VERTICALFLIP) - z -= mobjinfo[MT_FLINGEMERALD].height + player->mo->height; - ns = FixedMul(8*FRACUNIT, player->mo->scale); - } - else - { - fa = ((255 / num_stones) * i) * FINEANGLES/256; - - z = player->mo->z + (player->mo->height / 2); - if (player->mo->eflags & MFE_VERTICALFLIP) - z -= mobjinfo[MT_FLINGEMERALD].height; - ns = FixedMul(4*FRACUNIT, player->mo->scale); - } - - momx = FixedMul(FINECOSINE(fa), ns); - - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) - momy = FixedMul(FINESINE(fa),ns); - else - momy = 0; - - mo = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_FLINGEMERALD); - mo->health = 1; - mo->threshold = stoneflag; - mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH); - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); - P_SetTarget(&mo->target, player->mo); - mo->fuse = 12*TICRATE; - P_SetMobjState(mo, statenum); - - mo->momx = momx; - mo->momy = momy; - - P_SetObjectMomZ(mo, 3*FRACUNIT, false); - - if (player->mo->eflags & MFE_VERTICALFLIP) - mo->momz = -mo->momz; - - if (toss) - player->tossdelay = 2*TICRATE; - } ->>>>>>> srb2/next - } -} - -/** Makes an injured or dead player lose possession of the flag. - * - * \param player The player with the flag, about to lose it. - * \sa P_PlayerRingBurst - */ -void P_PlayerFlagBurst(player_t *player, boolean toss) -{ - mobj_t *flag; - mobjtype_t type; - - if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - return; - - if (player->gotflag & GF_REDFLAG) - type = MT_REDFLAG; - else - type = MT_BLUEFLAG; - - flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type); - - if (player->mo->eflags & MFE_VERTICALFLIP) - flag->z += player->mo->height - flag->height; - - if (toss) - P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); - else - { - angle_t fa = P_RandomByte()*FINEANGLES/256; - flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) - flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); - } - - flag->momz = FixedMul(8*FRACUNIT, player->mo->scale); - if (player->mo->eflags & MFE_VERTICALFLIP) - flag->momz = -flag->momz; - - if (type == MT_REDFLAG) - flag->spawnpoint = rflagpoint; - else - flag->spawnpoint = bflagpoint; - - flag->fuse = cv_flagtime.value * TICRATE; - P_SetTarget(&flag->target, player->mo); - - // Flag text - { - char plname[MAXPLAYERNAME+4]; - const char *flagtext; - char flagcolor; - - snprintf(plname, sizeof(plname), "%s%s%s", - CTFTEAMCODE(player), - player_names[player - players], - CTFTEAMENDCODE(player)); - - if (type == MT_REDFLAG) - { - flagtext = M_GetText("Red flag"); - flagcolor = '\x85'; - } - else - { - flagtext = M_GetText("Blue flag"); - flagcolor = '\x84'; - } - - if (toss) - CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80); - else - CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80); - } - - player->gotflag = 0; - - // Pointers set for displaying time value and for consistency restoration. - if (type == MT_REDFLAG) - redflag = flag; - else - blueflag = flag; - - if (toss) - player->tossdelay = 2*TICRATE; - - return; -}