From f261b9f0e118d6b6ac7216514423b06e888ab0e1 Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Wed, 5 Jul 2023 17:05:47 +0000 Subject: [PATCH] Add player->powers[pw_strong], refactor attacks and busting conditions, and allow breaking floors and ceilings separately --- src/d_player.h | 35 +++++++++++++++++ src/deh_tables.c | 28 +++++++++++++- src/p_inter.c | 34 ++++++++--------- src/p_map.c | 90 +++++++++++++++++--------------------------- src/p_saveg.c | 2 + src/p_user.c | 97 ++++++++++++++++++++++++++++++++---------------- 6 files changed, 179 insertions(+), 107 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 6df6689c5..1b2c99743 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -249,6 +249,38 @@ typedef enum CR_FAN } carrytype_t; // pw_carry +typedef enum +{ + STR_NONE = 0, // All strong powers can stack onto each other + + // Attack powers + STR_ANIM = 0x1, // remove powers when leaving current animation + STR_PUNCH = 0x2, // frontal attack (knuckles glide) + STR_TAIL = 0x4, // rear attack + STR_STOMP = 0x8, // falling onto object (fang bounce) + STR_UPPER = 0x10, // moving upwards into object (tails fly) + STR_GUARD = 0x20, //protect against damage + STR_HEAVY = 0x40, // ignore vertical rebound + STR_DASH = 0x80, // special type for machine dashmode, automatically removes your powers when leaving dashmode + + // Environment powers + STR_WALL = 0x100, // fof busting + STR_FLOOR = 0x200, + STR_CEILING = 0x400, + STR_SPRING = 0x800, // power up hit springs + STR_SPIKE = 0x1000, // break spikes + + // Shortcuts + STR_ATTACK = STR_PUNCH|STR_TAIL|STR_STOMP|STR_UPPER, + STR_BUST = STR_WALL|STR_FLOOR|STR_CEILING, + STR_FLY = STR_ANIM|STR_UPPER, + STR_GLIDE = STR_ANIM|STR_PUNCH, + STR_TWINSPIN = STR_ANIM|STR_ATTACK|STR_BUST|STR_SPRING|STR_SPIKE, + STR_MELEE = STR_ANIM|STR_PUNCH|STR_HEAVY|STR_WALL|STR_FLOOR|STR_SPRING|STR_SPIKE, + STR_BOUNCE = STR_ANIM|STR_STOMP|STR_FLOOR, + STR_METAL = STR_DASH|STR_SPIKE +} strongtype_t; // pw_strong + // Player powers. (don't edit this comment) typedef enum { @@ -293,6 +325,8 @@ typedef enum pw_ignorelatch, // Don't grab onto CR_GENERIC, add 32768 (powers[pw_ignorelatch] & 1<<15) to avoid ALL not-NiGHTS CR_ types + pw_strong, // Additional properties for powerful attacks + NUMPOWERS } powertype_t; @@ -405,6 +439,7 @@ typedef struct player_s // playing animation. panim_t panim; + UINT8 stronganim; // For screen flashing (bright). UINT16 flashcount; diff --git a/src/deh_tables.c b/src/deh_tables.c index 11d8b1a01..c7c53f650 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4768,7 +4768,9 @@ const char *const POWERS_LIST[] = { "JUSTLAUNCHED", - "IGNORELATCH" + "IGNORELATCH", + + "STRONG" }; const char *const HUDITEMS_LIST[] = { @@ -5121,6 +5123,30 @@ struct int_const_s const INT_CONST[] = { {"CR_DUSTDEVIL",CR_DUSTDEVIL}, {"CR_FAN",CR_FAN}, + // Strong powers + {"STR_NONE",STR_NONE}, + {"STR_ANIM",STR_ANIM}, + {"STR_PUNCH",STR_PUNCH}, + {"STR_TAIL",STR_TAIL}, + {"STR_STOMP",STR_STOMP}, + {"STR_UPPER",STR_UPPER}, + {"STR_GUARD",STR_GUARD}, + {"STR_HEAVY",STR_HEAVY}, + {"STR_DASH",STR_DASH}, + {"STR_WALL",STR_WALL}, + {"STR_FLOOR",STR_FLOOR}, + {"STR_CEILING",STR_CEILING}, + {"STR_SPRING",STR_SPRING}, + {"STR_SPIKE",STR_SPIKE}, + {"STR_ATTACK",STR_ATTACK}, + {"STR_BUST",STR_BUST}, + {"STR_FLY",STR_FLY}, + {"STR_GLIDE",STR_GLIDE}, + {"STR_TWINSPIN",STR_TWINSPIN}, + {"STR_MELEE",STR_MELEE}, + {"STR_BOUNCE",STR_BOUNCE}, + {"STR_METAL",STR_METAL}, + // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon {"RW_AUTO",RW_AUTO}, diff --git a/src/p_inter.c b/src/p_inter.c index c230ce178..cc8a1d2b9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -465,23 +465,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) 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 ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) + if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1) && (!(player->powers[pw_strong] & STR_HEAVY))) { - if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + fixed_t setmomz = -toucher->momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce + + if (elementalpierce == 2) // Reset bubblewrap, part 1 + P_DoBubbleBounce(player); + toucher->momz = setmomz; + if (elementalpierce == 2) // Reset bubblewrap, part 2 { - fixed_t setmomz = -toucher->momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce - - if (elementalpierce == 2) // Reset bubblewrap, part 1 - P_DoBubbleBounce(player); - toucher->momz = setmomz; - if (elementalpierce == 2) // Reset bubblewrap, part 2 - { - boolean underwater = toucher->eflags & MFE_UNDERWATER; - - if (underwater) - toucher->momz /= 2; - toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height! - } + boolean underwater = toucher->eflags & MFE_UNDERWATER; + + if (underwater) + toucher->momz /= 2; + toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height! } } if (player->pflags & PF_BOUNCING) @@ -500,8 +497,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) 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) + else if ((player->powers[pw_strong] & STR_DASH) && player->panim == PA_DASH) P_DoPlayerPain(player, special, special); } P_DamageMobj(special, toucher, toucher, 1, 0); @@ -3213,7 +3209,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; // Add pity. - if (!player->powers[pw_flashing] && !player->powers[pw_invulnerability] && !player->powers[pw_super] + if (!player->powers[pw_flashing] && !player->powers[pw_invulnerability] && !player->powers[pw_super] && !(player->powers[pw_strong] & STR_GUARD) && source->player->score > player->score) player->pity++; @@ -3683,7 +3679,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } return false; } - else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) // ignore bouncing & such in invulnerability + else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || (player->powers[pw_strong] & STR_GUARD)) // ignore bouncing & such in invulnerability { if (force || (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned! diff --git a/src/p_map.c b/src/p_map.c index 2bb02503f..3dc913435 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -152,10 +152,8 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { if (spring->info->painchance == 3) ; - else if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY) + else if (object->player->powers[pw_strong] & STR_SPRING) strong = 1; - else if (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2) - strong = 2; } if (spring->info->painchance == -1) // Pinball bumper mode. @@ -455,7 +453,8 @@ springstate: if (strong) { - P_TwinSpinRejuvenate(object->player, (strong == 1 ? object->player->thokitem : object->player->revitem)); + if (object->player->charability == CA_TWINSPIN || object->player->charability2 == CA2_MELEE) + P_TwinSpinRejuvenate(object->player, (object->player->charability == CA_TWINSPIN ? object->player->thokitem : object->player->revitem)); S_StartSound(object, sfx_sprong); // strong spring. sprong. } } @@ -796,43 +795,25 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. - if ((tmthing->player) - && ((((tmthing->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (tmthing->player->dashmode >= DASHMODE_THRESHOLD) - && (thing->flags & (MF_MONITOR) - || (thing->type == MT_SPIKE - || thing->type == MT_WALLSPIKE))) - || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) - && (thing->type == MT_SPIKE - || thing->type == MT_WALLSPIKE)))) + // STR_SPIKE users destroy spikes + if ((tmthing->player) && ((tmthing->player->powers[pw_strong] & STR_SPIKE) && (thing->type == MT_SPIKE || thing->type == MT_WALLSPIKE))) { - if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) - return true; - blockdist = thing->radius + tmthing->radius; - if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) - return true; // didn't hit it - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) - return true; // underneath - if (thing->type == MT_SPIKE - || thing->type == MT_WALLSPIKE) - { - mobj_t *iter; - if (thing->flags & MF_SOLID) - S_StartSound(tmthing, thing->info->deathsound); - for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) - if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) - P_KillMobj(iter, tmthing, tmthing, 0); - return true; - } - else - { - if (P_DamageMobj(thing, tmthing, tmthing, 1, 0)) - return true; - } + mobj_t *iter; + blockdist = thing->radius + tmthing->radius; + if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) + return true; // didn't hit it + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (thing->flags & MF_SOLID) + S_StartSound(tmthing, thing->info->deathsound); + for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) + if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) + P_KillMobj(iter, tmthing, tmthing, 0); + return true; } // vectorise metal - done in a special case as at this point neither has the right flags for touching @@ -1687,25 +1668,22 @@ static boolean PIT_CheckThing(mobj_t *thing) // Going down? Then bounce back up. if (P_DamageMobj(thing, tmthing, tmthing, 1, 0) // break the monitor && (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up - && (elementalpierce != 1)) // you're not piercing through the monitor... + && (elementalpierce != 1) && (!(player->powers[pw_strong] & STR_HEAVY))) // you're not piercing through the monitor... { - if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce + + if (elementalpierce == 2) // Reset bubblewrap, part 1 + P_DoBubbleBounce(player); + *momz = setmomz; // Therefore, you should be thrust in the opposite direction, vertically. + if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) + P_TwinSpinRejuvenate(player, player->thokitem); + if (elementalpierce == 2) // Reset bubblewrap, part 2 { - fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce + boolean underwater = tmthing->eflags & MFE_UNDERWATER; - if (elementalpierce == 2) // Reset bubblewrap, part 1 - P_DoBubbleBounce(player); - *momz = setmomz; // Therefore, you should be thrust in the opposite direction, vertically. - if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) - P_TwinSpinRejuvenate(player, player->thokitem); - if (elementalpierce == 2) // Reset bubblewrap, part 2 - { - boolean underwater = tmthing->eflags & MFE_UNDERWATER; - - if (underwater) - *momz /= 2; - *momz -= (*momz/(underwater ? 8 : 4)); // Cap the height! - } + if (underwater) + *momz /= 2; + *momz -= (*momz/(underwater ? 8 : 4)); // Cap the height! } } if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough. diff --git a/src/p_saveg.c b/src/p_saveg.c index 07b3d8640..b5907cfb8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -167,6 +167,7 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].playerstate); WRITEUINT32(save_p, players[i].pflags); WRITEUINT8(save_p, players[i].panim); + WRITEUINT8(save_p, players[i].stronganim); WRITEUINT8(save_p, players[i].spectator); WRITEUINT16(save_p, players[i].flashpal); @@ -394,6 +395,7 @@ static void P_NetUnArchivePlayers(void) players[i].playerstate = READUINT8(save_p); players[i].pflags = READUINT32(save_p); players[i].panim = READUINT8(save_p); + players[i].stronganim = READUINT8(save_p); players[i].spectator = READUINT8(save_p); players[i].flashpal = READUINT16(save_p); diff --git a/src/p_user.c b/src/p_user.c index 2f522ad4b..464cc521d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -988,6 +988,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) if (player->powers[pw_carry] == CR_ROPEHANG) P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_strong] = STR_NONE; + { angle_t ang; fixed_t fallbackspeed; @@ -1105,6 +1107,7 @@ void P_ResetPlayer(player_t *player) boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) { fixed_t bottomheight, topheight; + boolean allatk = ((player->powers[pw_strong] & STR_PUNCH) && (player->powers[pw_strong] & STR_TAIL) && (player->powers[pw_strong] & STR_STOMP) && (player->powers[pw_strong] & STR_UPPER)); if (!player->mo || player->spectator || !thing || P_MobjWasRemoved(thing)) return false; @@ -1129,22 +1132,33 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) // Jumping. if ((player->pflags & PF_JUMPED) - && (!(player->pflags & PF_NOJUMPDAMAGE) - || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) + && (!(player->pflags & PF_NOJUMPDAMAGE))) return true; // Spinning. if (player->pflags & PF_SPINNING) return true; - if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) + // Shield stomp. + if (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)) + return true; + + // pw_strong checks below here + + // Omnidirectional attacks. + if (allatk || (player->powers[pw_strong] & STR_DASH)) return true; // From the front. - if (((player->pflags & PF_GLIDING) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + if ((player->powers[pw_strong] & STR_PUNCH) && (player->drawangle - R_PointToAngle2(player->mo->x - player->mo->momx, player->mo->y - player->mo->momy, thing->x, thing->y) + + ANGLE_90) < ANGLE_180) return true; + // From the back. + if ((player->powers[pw_strong] & STR_TAIL) + && (player->drawangle - R_PointToAngle2(player->mo->x - player->mo->momx, player->mo->y - player->mo->momy, thing->x, thing->y) + + ANGLE_90) >= ANGLE_180) + return true; + // From the top/bottom. bottomheight = player->mo->z; topheight = player->mo->z + player->mo->height; @@ -1158,19 +1172,15 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) if (P_MobjFlip(player->mo)*(bottomheight - (thing->z + thing->height/2)) > 0) { - if ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) < 0)) + if ((player->charflags & SF_STOMPDAMAGE || player->powers[pw_strong] & STR_STOMP) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) < 0)) return true; } else if (P_MobjFlip(player->mo)*(topheight - (thing->z + thing->height/2)) < 0) { - if (player->charability == CA_FLY && player->panim == PA_ABILITY && !(player->mo->eflags & MFE_UNDERWATER) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) > 0)) + if ((player->powers[pw_strong] & STR_UPPER) && (player->mo->sprite2 != SPR2_SWIM) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) > 0)) return true; } - // Shield stomp. - if (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)) - return true; - return false; } @@ -2324,6 +2334,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_s3k8b); player->pflags |= PF_FULLSTASIS; + player->powers[pw_strong] = STR_MELEE; // hearticles if (type) @@ -2513,17 +2524,13 @@ static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) return true; // Passive wall breaking - if (player->charflags & SF_CANBUSTWALLS) + if (player->charflags & SF_CANBUSTWALLS || player->powers[pw_strong] & (STR_WALL|STR_FLOOR|STR_CEILING|STR_DASH)) return true; // Super if (player->powers[pw_super]) return true; - // Dashmode - if ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) && player->dashmode >= DASHMODE_THRESHOLD) - return true; - // NiGHTS drill if (player->pflags & PF_DRILLING) return true; @@ -2534,21 +2541,11 @@ static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) /* FALLTHRU */ case BT_STRONG: // Requires a "strong ability" - if (player->charflags & SF_CANBUSTWALLS) - return true; - - if (player->pflags & PF_BOUNCING) - return true; - - if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) - return true; - - if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) + if (player->charflags & SF_CANBUSTWALLS || player->powers[pw_strong] & (STR_WALL|STR_FLOOR|STR_CEILING)) return true; break; } - return false; } @@ -2564,7 +2561,7 @@ static void P_CheckBustableBlocks(player_t *player) oldx = player->mo->x; oldy = player->mo->y; - if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways + if (!((player->powers[pw_strong] & (STR_FLOOR|STR_CEILING)) && (!(player->powers[pw_strong] & STR_WALL)) && (!(player->charflags & SF_CANBUSTWALLS)))) // Don't break sideways without wall powers { P_UnsetThingPosition(player->mo); player->mo->x += player->mo->momx; @@ -2591,8 +2588,24 @@ static void P_CheckBustableBlocks(player_t *player) topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) + // Height checks + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if ((player->powers[pw_strong] & STR_FLOOR) && (!(player->powers[pw_strong] & STR_CEILING)) && player->mo->z > topheight) + continue; + + if ((player->powers[pw_strong] & STR_CEILING) && (!(player->powers[pw_strong] & STR_FLOOR)) && player->mo->z + player->mo->height < bottomheight) + continue; + } + else + { + if ((player->powers[pw_strong] & STR_FLOOR) && (!(player->powers[pw_strong] & STR_CEILING)) && player->mo->z < bottomheight) + continue; + + if ((player->powers[pw_strong] & STR_CEILING) && (!(player->powers[pw_strong] & STR_FLOOR)) && player->mo->z + player->mo->height > topheight) + continue; + } + if (player->powers[pw_strong] & (STR_FLOOR|STR_CEILING)) { topheight -= player->mo->momz; bottomheight -= player->mo->momz; @@ -2660,7 +2673,7 @@ static void P_CheckBustableBlocks(player_t *player) } } bustupdone: - if (!(player->pflags & PF_BOUNCING)) + if (!((player->powers[pw_strong] & (STR_FLOOR|STR_CEILING)) && (!(player->powers[pw_strong] & STR_WALL)) && (!(player->charflags & SF_CANBUSTWALLS)))) { P_UnsetThingPosition(player->mo); player->mo->x = oldx; @@ -4690,6 +4703,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momx += player->cmomx; player->mo->momy += player->cmomy; P_SetPlayerMobjState(player->mo, S_PLAY_MELEE); + player->powers[pw_strong] = STR_MELEE; S_StartSound(player->mo, sfx_s3k42); } player->pflags |= PF_SPINDOWN; @@ -4937,6 +4951,7 @@ static void P_DoTwinSpin(player_t *player) S_StartSound(player->mo, sfx_s3k42); player->mo->frame = 0; P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + player->powers[pw_strong] = STR_TWINSPIN; } // @@ -5300,6 +5315,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_THOKKED; else player->pflags |= (PF_THOKKED|PF_CANCARRY); + player->powers[pw_strong] = STR_FLY; } break; case CA_GLIDEANDCLIMB: @@ -5326,7 +5342,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); if (playerspeed < glidespeed) P_Thrust(player->mo, player->mo->angle, glidespeed - playerspeed); - player->pflags &= ~(PF_SPINNING|PF_STARTDASH); + player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH); + player->powers[pw_strong] = STR_GLIDE; } break; case CA_DOUBLEJUMP: // Double-Jump @@ -5383,6 +5400,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); player->pflags |= PF_THOKKED|PF_BOUNCING; + player->powers[pw_strong] = STR_BOUNCE; player->mo->momx >>= 1; player->mo->momy >>= 1; player->mo->momz >>= 1; @@ -12070,6 +12088,16 @@ void P_PlayerThink(player_t *player) else player->powers[pw_ignorelatch] = 0; + if (player->powers[pw_strong] & STR_ANIM) + { + if (!(player->stronganim)) + player->stronganim = player->panim; + else if (player->panim != player->stronganim) + player->powers[pw_strong] = STR_NONE; + } + else if (player->stronganim) + player->stronganim = 0; + //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] @@ -12164,6 +12192,8 @@ void P_PlayerThink(player_t *player) { player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode. player->jumpfactor = skins[player->skin].jumpfactor; + if (player->powers[pw_strong] & STR_DASH) + player->powers[pw_strong] = STR_NONE; } } else if (P_IsObjectOnGround(player->mo)) // Activate dash mode if we're on the ground. @@ -12173,6 +12203,9 @@ void P_PlayerThink(player_t *player) if (player->jumpfactor < FixedMul(skins[player->skin].jumpfactor, 5*FRACUNIT/4)) // Boost jump height. player->jumpfactor += FRACUNIT/300; + + if ((player->charflags & SF_MACHINE) && (!(player->powers[pw_strong] == STR_METAL))) + player->powers[pw_strong] = STR_METAL; } if (player->normalspeed >= skins[player->skin].normalspeed*2) @@ -12190,6 +12223,8 @@ void P_PlayerThink(player_t *player) player->normalspeed = skins[player->skin].normalspeed; player->jumpfactor = skins[player->skin].jumpfactor; S_StartSound(player->mo, sfx_kc65); + if (player->powers[pw_strong] & STR_DASH) + player->powers[pw_strong] = STR_NONE; } dashmode = 0; }