* Force shield force stop completed

* Bubblewrap shield bounce now no longer allows thokking post-bounce, but still allows bouncing
* plus a bunch of tiny changes to clean up code around the place.
This commit is contained in:
toasterbabe 2016-10-20 00:33:12 +01:00
parent 9b4c81ed0b
commit 8fe932b0e7
5 changed files with 66 additions and 24 deletions

View file

@ -188,7 +188,7 @@ typedef enum
SH_PROTECTELECTRIC = 0x1000, SH_PROTECTELECTRIC = 0x1000,
// Indivisible shields // Indivisible shields
SH_PITY = 1, SH_PITY = 1, // the world's most basic shield ever, given to players who suck at Match
SH_WHIRLWIND, SH_WHIRLWIND,
SH_ARMAGEDDON, SH_ARMAGEDDON,
SH_FIREFLOWER, SH_FIREFLOWER,
@ -377,8 +377,8 @@ typedef struct player_s
UINT8 gotcontinue; // Got continue from this stage? UINT8 gotcontinue; // Got continue from this stage?
fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values) fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values)
UINT8 jumping; // Jump counter UINT8 jumping; // Holding down jump button
UINT8 secondjump; UINT8 secondjump; // Jump counter
UINT8 fly1; // Tails flying UINT8 fly1; // Tails flying
UINT8 scoreadd; // Used for multiple enemy attack bonus UINT8 scoreadd; // Used for multiple enemy attack bonus

View file

@ -3348,7 +3348,7 @@ void A_ForceShield(mobj_t *actor)
return; return;
} }
if (locvar1 < 0 || locvar1 > SH_FORCEHP) if (locvar1 & ~SH_FORCEHP)
{ {
CONS_Debug(DBG_GAMELOGIC, "Invalid number of additional hitpoints.\n"); CONS_Debug(DBG_GAMELOGIC, "Invalid number of additional hitpoints.\n");
return; return;

View file

@ -2784,7 +2784,7 @@ void P_RemoveShield(player_t *player)
if (player->powers[pw_shield] & SH_FORCE) if (player->powers[pw_shield] & SH_FORCE)
{ // Multi-hit { // Multi-hit
if ((player->powers[pw_shield] & SH_FORCEHP) == 0) if ((player->powers[pw_shield] & SH_FORCEHP) == 0)
player->powers[pw_shield] &= ~SH_FORCE; player->powers[pw_shield] &= SH_STACK;
else else
player->powers[pw_shield]--; player->powers[pw_shield]--;
} }

View file

@ -3235,8 +3235,16 @@ static void P_PlayerZMovement(mobj_t *mo)
if (!(mo->player->pflags & PF_GLIDING)) if (!(mo->player->pflags & PF_GLIDING))
mo->player->pflags &= ~PF_JUMPED; mo->player->pflags &= ~PF_JUMPED;
mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
mo->player->secondjump = 0;
mo->player->glidetime = 0;
mo->player->climbing = 0;
mo->player->powers[pw_tailsfly] = 0;
if (mo->player->pflags & PF_SHIELDABILITY) if (mo->player->pflags & PF_SHIELDABILITY)
{ {
mo->player->pflags &= ~PF_SHIELDABILITY;
if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack. if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack.
{ {
if (mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound if (mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound
@ -3259,16 +3267,14 @@ static void P_PlayerZMovement(mobj_t *mo)
{ {
S_StartSound(mo, sfx_s3k44); S_StartSound(mo, sfx_s3k44);
P_DoJump(mo->player, false); P_DoJump(mo->player, false);
mo->player->pflags |= PF_THOKKED;
mo->player->secondjump = UINT8_MAX;
mo->momz = FixedMul(mo->momz, 5*FRACUNIT/4); mo->momz = FixedMul(mo->momz, 5*FRACUNIT/4);
clipmomz = false; clipmomz = false;
} }
} }
mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY/*|PF_GLIDING*/);
mo->player->jumping = 0; mo->player->jumping = 0; // done down here because of bubblewrap
mo->player->secondjump = 0;
mo->player->glidetime = 0;
mo->player->climbing = 0;
mo->player->powers[pw_tailsfly] = 0;
} }
} }
if (!(mo->player->pflags & PF_SPINNING)) if (!(mo->player->pflags & PF_SPINNING))
@ -3623,15 +3629,19 @@ void P_MobjCheckWater(mobj_t *mobj)
{ {
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability]))) if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
{ {
if (p->powers[pw_shield] & SH_PROTECTELECTRIC) boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
{ // Water removes electric shields... #define SH_OP (SH_PROTECTFIRE|SH_PROTECTWATER|SH_PROTECTELECTRIC)
if ((p->powers[pw_shield] & SH_OP) == SH_OP) // No.
P_KillMobj(mobj, NULL, NULL, DMG_INSTAKILL);
#undef SH_OP
else if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER)))
{ // Water removes electric and non-water fire shields...
P_FlashPal(p,
electric
? PAL_WHITE
: PAL_NUKE,
1);
p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK; p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK;
P_FlashPal(p, PAL_WHITE, 1);
}
else if ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER))
{ // ...and fire-only shields.
p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK;
P_FlashPal(p, PAL_NUKE, 1);
} }
} }
@ -3651,7 +3661,10 @@ void P_MobjCheckWater(mobj_t *mobj)
} }
if ((mobj->eflags & MFE_GOOWATER) && ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (p->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (p->pflags & PF_SHIELDABILITY)) if ((mobj->eflags & MFE_GOOWATER) && ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (p->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (p->pflags & PF_SHIELDABILITY))
{
p->pflags &= ~PF_SHIELDABILITY; p->pflags &= ~PF_SHIELDABILITY;
mobj->momz >>= 1;
}
} }
// The rest of this code only executes on a water state change. // The rest of this code only executes on a water state change.
@ -6683,7 +6696,7 @@ void P_MobjThinker(mobj_t *mobj)
fixed_t oldheight = mobj->height; fixed_t oldheight = mobj->height;
UINT8 correctionType = 0; // Don't correct Z position, just gain height UINT8 correctionType = 0; // Don't correct Z position, just gain height
if (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz))
&& mobj->type != MT_EGGMOBILE_FIRE) && mobj->type != MT_EGGMOBILE_FIRE)
correctionType = 1; // Correct Z position by centering correctionType = 1; // Correct Z position by centering
else if (mobj->eflags & MFE_VERTICALFLIP) else if (mobj->eflags & MFE_VERTICALFLIP)
@ -6787,7 +6800,6 @@ void P_MobjThinker(mobj_t *mobj)
case MT_PITY_ORB: case MT_PITY_ORB:
case MT_WHIRLWIND_ORB: case MT_WHIRLWIND_ORB:
case MT_ARMAGEDDON_ORB: case MT_ARMAGEDDON_ORB:
case MT_FORCE_ORB:
case MT_FLAMEAURA_ORB: case MT_FLAMEAURA_ORB:
if (!P_AddShield(mobj)) if (!P_AddShield(mobj))
return; return;
@ -6818,6 +6830,25 @@ void P_MobjThinker(mobj_t *mobj)
mobj->tracer->tics++; mobj->tracer->tics++;
} }
break; break;
case MT_FORCE_ORB:
if (!P_AddShield(mobj))
return;
if (/*
&& mobj->target -- the following is implicit by P_AddShield
&& mobj->target->player
&& (mobj->target->player->powers[pw_shield] & SH_FORCE)
&& */ (mobj->target->player->pflags & PF_SHIELDABILITY))
{
mobj_t *whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST);
whoosh->sprite = SPR_FORC;
whoosh->frame = 20|(tr_trans50<<FF_TRANSSHIFT); // U at 50% transparency
whoosh->destscale = whoosh->scale<<1;
whoosh->fuse = 10;
whoosh->tics = -1;
whoosh->flags |= MF_NOCLIPHEIGHT;
whoosh->height = 42*FRACUNIT;
mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh
}
case MT_BUBBLEWRAP_ORB: case MT_BUBBLEWRAP_ORB:
if (!P_AddShield(mobj)) if (!P_AddShield(mobj))
return; return;

View file

@ -7002,12 +7002,22 @@ static void P_MovePlayer(player_t *player)
{ {
if (player->pflags & PF_JUMPED) // If the player is jumping if (player->pflags & PF_JUMPED) // If the player is jumping
{ {
pflags_t check = (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_THOKKED); if (!(player->pflags & (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player is not holding down BT_USE, or having used an ability previously
if (!(player->pflags & check)) // If the player is not holding down BT_USE, or having used an ability previously && (!(player->pflags & PF_THOKKED) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP && player->secondjump == UINT8_MAX))) // thokked is optional if you're bubblewrapped
{ {
// Force shield activation // Force shield activation
if (player->powers[pw_shield] & SH_FORCE) if (player->powers[pw_shield] & SH_FORCE)
; // TODO {
//#define PERFECTFORCESTOP
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->mo->momx = player->mo->momy = 0;
#if 1 // almost imperceptible hop for the purposes of aligning with the aura for as long as possible
P_SetObjectMomZ(player->mo, -4*P_GetMobjGravity(player->mo), false);
#else
player->mo->momz = 0;
#endif
S_StartSound(player->mo, sfx_ngskid);
}
else else
{ {
switch (player->powers[pw_shield] & SH_NOSTACK) switch (player->powers[pw_shield] & SH_NOSTACK)
@ -7040,6 +7050,7 @@ static void P_MovePlayer(player_t *player)
case SH_ELEMENTAL: case SH_ELEMENTAL:
case SH_BUBBLEWRAP: case SH_BUBBLEWRAP:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY; player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->secondjump = 0;
player->mo->momx = player->mo->momy = 0; player->mo->momx = player->mo->momy = 0;
P_SetObjectMomZ(player->mo, -24*FRACUNIT, false); P_SetObjectMomZ(player->mo, -24*FRACUNIT, false);
S_StartSound(player->mo, S_StartSound(player->mo,