From d4f0afa0d1689d91dccc1a85552ac73613c3d034 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 12 Oct 2016 17:55:07 +0100 Subject: [PATCH] A Heckloada Mario Stuff https://gfycat.com/MasculineSatisfiedAfricanwilddog and https://gfycat.com/PastCompetentGypsymoth describe this all in varying states of completion --- src/d_player.h | 1 + src/p_enemy.c | 6 +++ src/p_inter.c | 27 ++++++++-- src/p_local.h | 2 + src/p_mobj.c | 43 +++++++++++++++- src/p_user.c | 130 +++++++++++++++++++++++++++---------------------- src/r_things.c | 14 +++--- 7 files changed, 154 insertions(+), 69 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 91520293d..1fa101e12 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -227,6 +227,7 @@ typedef enum pw_underwater, // underwater timer pw_spacetime, // In space, no one can hear you spin! pw_extralife, // Extra Life timer + pw_marioflashing, // Getting/losing powerup pw_super, // Are you super? pw_gravityboots, // gravity boots diff --git a/src/p_enemy.c b/src/p_enemy.c index 80372ce5f..104e53f1e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3359,6 +3359,12 @@ void A_ForceShield(mobj_t *actor) //can't use P_SwitchShield(player, SH_FORCE) - special case + if (mariomode && player->mo) + { + player->mo->movecount = player->powers[pw_shield]; + player->powers[pw_marioflashing] = MARIOFLASHINGTICS; + } + if (!(player->powers[pw_shield] & SH_FORCE)) { // Just in case. diff --git a/src/p_inter.c b/src/p_inter.c index 8ae97b831..9c8885411 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -142,7 +142,7 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) if (player->bot && weapon) return false; - if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics) + if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] < UINT16_MAX) return false; return true; @@ -1138,6 +1138,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_FIREFLOWER: if (player->bot) return; + if (mariomode) + { + toucher->movecount = player->powers[pw_shield]; + player->powers[pw_marioflashing] = MARIOFLASHINGTICS; + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_PITY) + player->powers[pw_shield] &= SH_NOSTACK; + } player->powers[pw_shield] |= SH_FIREFLOWER; toucher->color = SKINCOLOR_WHITE; G_GhostAddColor(GHC_FIREFLOWER); @@ -1204,6 +1211,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(toucher, special->info->painsound); + if (mariomode && !player->powers[pw_shield]) + { + S_StartSound(toucher, sfx_mario3); + player->mo->movecount = player->powers[pw_shield]; + player->powers[pw_marioflashing] = MARIOFLASHINGTICS; + player->powers[pw_shield] = SH_PITY; + P_SpawnShieldOrb(player); + } + if (!(netgame && circuitmap && player != &players[consoleplayer])) P_SetMobjState(special, special->info->painstate); return; @@ -1997,6 +2013,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } target->flags2 &= ~MF2_DONTDRAW; + + if (mariomode) + target->player->powers[pw_marioflashing] = MARIOFLASHINGTICS; } // if killed by a player @@ -2773,7 +2792,9 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes + if (mariomode) + S_StartSound(player->mo, sfx_mario8); + else if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes S_StartSound(player->mo, sfx_spkdth); else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -3134,7 +3155,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else { player->health -= damage; // mirror mobj health here - target->player->powers[pw_flashing] = flashingtics; + //target->player->powers[pw_flashing] = flashingtics; if (damage > 0) // don't spill emeralds/ammo/panels for shield damage P_PlayerRingBurst(player, damage); } diff --git a/src/p_local.h b/src/p_local.h index 09848aa51..041a2150d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -64,6 +64,8 @@ #define mariomode (maptol & TOL_MARIO) #define shortmario(player) ((player && mariomode && !player->powers[pw_shield]) ? 1 : 0) +#define MARIOFLASHINGTICS 19 + #define P_GetPlayerHeight(player) (FixedMul(player->height, player->mo->scale) >> shortmario(player)) #define P_GetPlayerSpinHeight(player) (FixedMul(player->spinheight, player->mo->scale) >> shortmario(player)) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1ae64bc60..95403995b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4061,6 +4061,40 @@ static void P_PlayerMobjThinker(mobj_t *mobj) I_Assert(mobj->player != NULL); I_Assert(!P_MobjWasRemoved(mobj)); + if (mobj->player->powers[pw_marioflashing]) + { + if (!mobj->player->powers[pw_nocontrol]++) + mobj->player->powers[pw_nocontrol]++; + + if (!(mobj->player->powers[pw_marioflashing] % 4)) + { + UINT16 shieldswitch = mobj->player->powers[pw_shield]; + mobj->player->powers[pw_shield] = mobj->movecount; + mobj->movecount = shieldswitch; + if ((mobj->player->powers[pw_shield] & SH_FIREFLOWER) != (mobj->movecount & SH_FIREFLOWER)) + { + if (mobj->player->powers[pw_shield] & SH_FIREFLOWER) + { + mobj->color = SKINCOLOR_WHITE; + G_GhostAddColor(GHC_FIREFLOWER); + } + else + { + mobj->color = mobj->player->skincolor; + G_GhostAddColor(GHC_NORMAL); + } + } + if (mobj->player->powers[pw_shield] & SH_NOSTACK && (mobj->player->powers[pw_shield] & SH_NOSTACK) != (mobj->movecount & SH_NOSTACK)) + P_SpawnShieldOrb(mobj->player); + } + + mobj->player->powers[pw_marioflashing]--; + if (mobj->player->powers[pw_flashing] && mobj->player->powers[pw_flashing] < UINT16_MAX && mobj->player->powers[pw_flashing] > flashingtics) + if (--(mobj->player->powers[pw_flashing]) == flashingtics) + mobj->player->powers[pw_flashing]--; + return; + } + P_MobjCheckWater(mobj); #ifdef ESLOPE @@ -6380,9 +6414,9 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) thing->x = thing->target->x; thing->y = thing->target->y; if (thing->eflags & MFE_VERTICALFLIP) - thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); + thing->z = thing->target->z + ((thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT)) << shortmario(thing->target->player)) - FixedMul(2*FRACUNIT, thing->target->scale); else - thing->z = thing->target->z - FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) + FixedMul(2*FRACUNIT, thing->target->scale); + thing->z = thing->target->z - ((FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT)) << shortmario(thing->target->player)) + FixedMul(2*FRACUNIT, thing->target->scale); P_SetThingPosition(thing); P_CheckPosition(thing, thing->x, thing->y); @@ -7091,6 +7125,11 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_PLAYER: /// \todo Have the player's dead body completely finish its animation even if they've already respawned. + if (mobj->player && mobj->player->powers[pw_marioflashing]) + { + mobj->player->powers[pw_marioflashing]--; + return; // don't do any momz + } if (!(mobj->flags2 & MF2_DONTDRAW)) { if (!mobj->fuse) diff --git a/src/p_user.c b/src/p_user.c index 2f076f59b..1589d308a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -790,59 +790,65 @@ boolean P_PlayerInPain(player_t *player) // void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) { - angle_t ang; - fixed_t fallbackspeed; - - if (player->mo->eflags & MFE_VERTICALFLIP) - player->mo->z--; - else - player->mo->z++; - - if (player->mo->eflags & MFE_UNDERWATER) - P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); - else - P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); - - if (inflictor) - { - ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy); - - // explosion and rail rings send you farther back, making it more difficult - // to recover - if ((inflictor->flags2 & MF2_SCATTER) && source) - { - fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); - - dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; - - if (dist < FixedMul(4*FRACUNIT, inflictor->scale)) - dist = FixedMul(4*FRACUNIT, inflictor->scale); - - fallbackspeed = dist; - } - else if (inflictor->flags2 & MF2_EXPLOSION) - { - if (inflictor->flags2 & MF2_RAILRING) - fallbackspeed = FixedMul(38*FRACUNIT, inflictor->scale); // 7x - else - fallbackspeed = FixedMul(30*FRACUNIT, inflictor->scale); // 5x - } - else if (inflictor->flags2 & MF2_RAILRING) - fallbackspeed = FixedMul(45*FRACUNIT, inflictor->scale); // 4x - else - fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force - } - else - { - ang = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0); - fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale); - } - - P_InstaThrust(player->mo, ang, fallbackspeed); - if (player->powers[pw_carry] == CR_ROPEHANG) P_SetTarget(&player->mo->tracer, NULL); + if (!mariomode) + { + angle_t ang; + fixed_t fallbackspeed; + + P_ResetPlayer(player); + P_SetPlayerMobjState(player->mo, player->mo->info->painstate); + + if (player->mo->eflags & MFE_VERTICALFLIP) + player->mo->z--; + else + player->mo->z++; + + if (player->mo->eflags & MFE_UNDERWATER) + P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); + else + P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); + + if (inflictor) + { + ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy); + + // explosion and rail rings send you farther back, making it more difficult + // to recover + if ((inflictor->flags2 & MF2_SCATTER) && source) + { + fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); + + dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; + + if (dist < FixedMul(4*FRACUNIT, inflictor->scale)) + dist = FixedMul(4*FRACUNIT, inflictor->scale); + + fallbackspeed = dist; + } + else if (inflictor->flags2 & MF2_EXPLOSION) + { + if (inflictor->flags2 & MF2_RAILRING) + fallbackspeed = FixedMul(38*FRACUNIT, inflictor->scale); // 7x + else + fallbackspeed = FixedMul(30*FRACUNIT, inflictor->scale); // 5x + } + else if (inflictor->flags2 & MF2_RAILRING) + fallbackspeed = FixedMul(45*FRACUNIT, inflictor->scale); // 4x + else + fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force + } + else + { + ang = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0); + fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale); + } + + P_InstaThrust(player->mo, ang, fallbackspeed); + } + // Point penalty for hitting a hazard during tag. // Discourages players from intentionally hurting themselves to avoid being tagged. if (gametype == GT_TAG && (!(player->pflags & PF_TAGGED) && !(player->pflags & PF_TAGIT))) @@ -853,9 +859,13 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) player->score = 0; } - P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, player->mo->info->painstate); player->powers[pw_flashing] = flashingtics; + if (mariomode) + { + player->powers[pw_marioflashing] = MARIOFLASHINGTICS; + player->powers[pw_flashing] += MARIOFLASHINGTICS; + player->mo->movecount = player->powers[pw_shield]; + } if (player->timeshit != UINT8_MAX) ++player->timeshit; @@ -1416,6 +1426,12 @@ void P_SpawnShieldOrb(player_t *player) // void P_SwitchShield(player_t *player, UINT16 shieldtype) { + if (mariomode && player->mo) + { + player->mo->movecount = player->powers[pw_shield]; + player->powers[pw_marioflashing] = MARIOFLASHINGTICS; + player->powers[pw_nocontrol] += MARIOFLASHINGTICS; + } if ((player->powers[pw_shield] & SH_NOSTACK) != shieldtype) { // Just in case. @@ -8104,7 +8120,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camstill = cv_cam_still.value; camrotate = cv_cam_rotate.value; camdist = FixedMul(cv_cam_dist.value, FixedMul(player->camerascale, mo->scale)); - camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale >> shortmario(player), mo->scale)); + camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale, mo->scale)); } else // Camera 2 { @@ -8112,7 +8128,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camstill = cv_cam2_still.value; camrotate = cv_cam2_rotate.value; camdist = FixedMul(cv_cam2_dist.value, FixedMul(player->camerascale, mo->scale)); - camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale >> shortmario(player), mo->scale)); + camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale, mo->scale)); } if (player->powers[pw_shield] & SH_FORCE && player->pflags & PF_SHIELDABILITY) @@ -8532,9 +8548,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall dist = FixedHypot(f1, f2); if (mo->eflags & MFE_VERTICALFLIP) - angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); + angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - (P_GetPlayerHeight(player) << shortmario(player))); else - angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); + angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + (P_GetPlayerHeight(player) << shortmario(player))); if (player->playerstate != PST_DEAD) angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' @@ -9268,7 +9284,7 @@ void P_PlayerThink(player_t *player) player->losstime--; // Flash player after being hit. - if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) + if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1) && !player->powers[pw_marioflashing]) player->mo->flags2 |= MF2_DONTDRAW; else player->mo->flags2 &= ~MF2_DONTDRAW; diff --git a/src/r_things.c b/src/r_things.c index 13688740d..823dda3ac 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1319,12 +1319,6 @@ static void R_ProjectSprite(mobj_t *thing) xscale = FixedMul(xscale, ang_scale); - if (shortmarioshift) - { - yscale >>= shortmarioshift; - this_scale >>= shortmarioshift; - } - if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) { fixed_t linkscale; @@ -1370,6 +1364,12 @@ static void R_ProjectSprite(mobj_t *thing) return; } + if (shortmarioshift) // squish mario + { + yscale >>= shortmarioshift; + this_scale >>= shortmarioshift; + } + //SoM: 3/17/2000: Disregard sprites that are out of view.. if (vflip) { @@ -1385,7 +1385,7 @@ static void R_ProjectSprite(mobj_t *thing) gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale); } - if (shortmarioshift) + if (shortmarioshift) // unsquish the x component this_scale <<= shortmarioshift; if (thing->subsector->sector->cullheight)