* Some shield constants renamed.

* Some shield sounds swapped (can be reverted later).
* Partial implementation of S3K shield abilities.
* The ability to elemental-groundpound onto gold monitors without going straight through them.
* Force shield ability removed because nobody could agree on it, we'll keep it blank until another idea can get through the disagreement juggernaut.
This commit is contained in:
toasterbabe 2016-10-13 15:13:33 +01:00
parent 2acfc72d86
commit 5ff507213b
11 changed files with 150 additions and 183 deletions

View file

@ -185,22 +185,22 @@ typedef enum
// Shield flags
SH_PROTECTFIRE = 0x400,
SH_PROTECTWATER = 0x800,
SH_PROTECTELECTRICITY = 0x1000,
SH_PROTECTELECTRIC = 0x1000,
// Indivisible shields
SH_PITY = 1,
SH_JUMP,
SH_BOMB,
SH_WHIRLWIND,
SH_ARMAGEDDON,
SH_FIREFLOWER,
// normal shields that use flags
SH_ATTRACT = SH_PROTECTELECTRICITY,
SH_ATTRACT = SH_PROTECTELECTRIC,
SH_ELEMENTAL = SH_PROTECTFIRE|SH_PROTECTWATER,
// Sonic 3 shields
SH_FLAMEAURA = SH_PROTECTFIRE,
SH_BUBBLEWRAP = SH_PROTECTWATER,
SH_THUNDERCOIN = SH_JUMP|SH_PROTECTELECTRICITY,
SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC,
// The force shield uses the lower 8 bits to count how many extra hits are left.
SH_FORCE = 0x100,

View file

@ -5459,6 +5459,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_BUBSB1",
"S_BUBSB2",
"S_BUBSB3",
"S_BUBSB4",
"S_ZAPS1",
"S_ZAPS2",
@ -6509,8 +6511,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_ELEMENTAL_ORB", // Elemental shield mobj
"MT_ATTRACT_ORB", // Attract shield mobj
"MT_FORCE_ORB", // Force shield mobj
"MT_BOMB_ORB", // Armageddon shield mobj
"MT_JUMP_ORB", // Whirlwind shield mobj
"MT_ARMAGEDDON_ORB", // Armageddon shield mobj
"MT_WHIRLWIND_ORB", // Whirlwind shield mobj
"MT_PITY_ORB", // Pity shield mobj
"MT_FLAMEAURA_ORB", // Flame shield mobj
"MT_BUBBLEWRAP_ORB", // Bubble shield mobj
@ -7178,11 +7180,11 @@ struct {
// Shield flags
{"SH_PROTECTFIRE",SH_PROTECTFIRE},
{"SH_PROTECTWATER",SH_PROTECTWATER},
{"SH_PROTECTELECTRICITY",SH_PROTECTELECTRICITY},
{"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC},
// Indivisible shields
{"SH_PITY",SH_PITY},
{"SH_JUMP",SH_JUMP},
{"SH_BOMB",SH_BOMB},
{"SH_WHIRLWIND",SH_WHIRLWIND},
{"SH_ARMAGEDDON",SH_ARMAGEDDON},
{"SH_FIREFLOWER",SH_FIREFLOWER},
// normal shields that use flags
{"SH_ATTRACT",SH_ATTRACT},

View file

@ -2175,18 +2175,20 @@ state_t states[NUMSTATES] =
{SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|16, 2, {NULL}, 0, 0, S_FIRSB9}, // S_FIRSB8
{SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|17, 2, {NULL}, 0, 0, S_FIRSB1}, // S_FIRSB9
{SPR_BUBS, FF_TRANS30| 2, 2, {NULL}, 0, 0, S_BUBS2}, // S_BUBS1
{SPR_BUBS, FF_TRANS30| 3, 2, {NULL}, 0, 0, S_BUBS3}, // S_BUBS2
{SPR_BUBS, FF_TRANS30| 4, 2, {NULL}, 0, 0, S_BUBS4}, // S_BUBS3
{SPR_BUBS, FF_TRANS30| 5, 2, {NULL}, 0, 0, S_BUBS5}, // S_BUBS4
{SPR_BUBS, FF_TRANS30| 6, 2, {NULL}, 0, 0, S_BUBS6}, // S_BUBS5
{SPR_BUBS, FF_TRANS30| 7, 2, {NULL}, 0, 0, S_BUBS7}, // S_BUBS6
{SPR_BUBS, FF_TRANS30| 8, 2, {NULL}, 0, 0, S_BUBS8}, // S_BUBS7
{SPR_BUBS, FF_TRANS30| 9, 2, {NULL}, 0, 0, S_BUBS9}, // S_BUBS8
{SPR_BUBS, FF_TRANS30|10, 2, {NULL}, 0, 0, S_BUBS1}, // S_BUBS9
{SPR_BUBS, FF_TRANS30 , 2, {NULL}, 0, 0, S_BUBS2}, // S_BUBS1
{SPR_BUBS, FF_TRANS30|1, 2, {NULL}, 0, 0, S_BUBS3}, // S_BUBS2
{SPR_BUBS, FF_TRANS30|2, 2, {NULL}, 0, 0, S_BUBS4}, // S_BUBS3
{SPR_BUBS, FF_TRANS30|3, 2, {NULL}, 0, 0, S_BUBS5}, // S_BUBS4
{SPR_BUBS, FF_TRANS30|4, 2, {NULL}, 0, 0, S_BUBS6}, // S_BUBS5
{SPR_BUBS, FF_TRANS30|5, 2, {NULL}, 0, 0, S_BUBS7}, // S_BUBS6
{SPR_BUBS, FF_TRANS30|6, 2, {NULL}, 0, 0, S_BUBS8}, // S_BUBS7
{SPR_BUBS, FF_TRANS30|7, 2, {NULL}, 0, 0, S_BUBS9}, // S_BUBS8
{SPR_BUBS, FF_TRANS30|8, 2, {NULL}, 0, 0, S_BUBS1}, // S_BUBS9
{SPR_BUBS, FF_TRANS30 , 2, {NULL}, 0, 0, S_BUBSB2}, // S_BUBSB1
{SPR_BUBS, FF_TRANS30|1, 2, {NULL}, 0, 0, S_BUBSB1}, // S_BUBSB2
{SPR_BUBS, FF_TRANS30| 9, 2, {NULL}, 0, 0, S_BUBSB2}, // S_BUBSB1
{SPR_BUBS, FF_TRANS30|10, 2, {NULL}, 0, 0, S_BUBSB3}, // S_BUBSB2
{SPR_BUBS, FF_TRANS30|11, 2, {NULL}, 0, 0, S_BUBSB4}, // S_BUBSB3
{SPR_BUBS, FF_TRANS30|10, 2, {NULL}, 0, 0, S_BUBSB1}, // S_BUBSB4
{SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20 , 2, {NULL}, 0, 0, S_ZAPS2 }, // S_ZAPS1
{SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 1, 2, {NULL}, 0, 0, S_ZAPS3 }, // S_ZAPS2
@ -7057,7 +7059,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_ATTRACT_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_shield, // seesound
sfx_s3k41, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7111,7 +7113,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_ARMAGEDDON_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_shield, // seesound
sfx_s3k3e, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7165,7 +7167,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_ELEMENTAL_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_shield, // seesound
sfx_s3k3f, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7435,7 +7437,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_FLAMEAURA_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_shield, // seesound
sfx_s3k3e, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7462,7 +7464,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_BUBBLEWRAP_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_shield, // seesound
sfx_s3k3f, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7489,7 +7491,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_THUNDERCOIN_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_shield, // seesound
sfx_s3k41, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -10762,7 +10764,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_ELEMF9, // painstate
S_NULL, // painstate
SKINCOLOR_NONE, // painchance
sfx_None, // painsound
S_NULL, // meleestate
@ -10778,7 +10780,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
S_ELEMF9 // raisestate
},
{ // MT_ATTRACT_ORB
@ -10835,7 +10837,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_BOMB_ORB
{ // MT_ARMAGEDDON_ORB
-1, // doomednum
S_ARMA1, // spawnstate
1000, // spawnhealth
@ -10851,7 +10853,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
SH_BOMB, // speed
SH_ARMAGEDDON, // speed
64*FRACUNIT, // radius
64*FRACUNIT, // height
2, // display offset
@ -10862,7 +10864,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_JUMP_ORB
{ // MT_WHIRLWIND_ORB
-1, // doomednum
S_WIND1, // spawnstate
1000, // spawnhealth
@ -10878,7 +10880,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
SH_JUMP, // speed
SH_WHIRLWIND, // speed
64*FRACUNIT, // radius
64*FRACUNIT, // height
2, // display offset
@ -10978,7 +10980,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
S_ZAPSB11, // painstate
SKINCOLOR_NONE, // painchance
sfx_None, // painsound
S_NULL, // meleestate
@ -10994,7 +10996,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
S_ZAPS14 // raisestate
},
{ // MT_IVSP

View file

@ -2373,6 +2373,8 @@ typedef enum state
S_BUBSB1,
S_BUBSB2,
S_BUBSB3,
S_BUBSB4,
S_ZAPS1,
S_ZAPS2,
@ -3442,8 +3444,8 @@ typedef enum mobj_type
MT_ELEMENTAL_ORB, // Elemental shield mobj
MT_ATTRACT_ORB, // Attract shield mobj
MT_FORCE_ORB, // Force shield mobj
MT_BOMB_ORB, // Armageddon shield mobj
MT_JUMP_ORB, // Whirlwind shield mobj
MT_ARMAGEDDON_ORB, // Armageddon shield mobj
MT_WHIRLWIND_ORB, // Whirlwind shield mobj
MT_PITY_ORB, // Pity shield mobj
MT_FLAMEAURA_ORB, // Flame shield mobj
MT_BUBBLEWRAP_ORB, // Bubble shield mobj

View file

@ -741,7 +741,7 @@ static boolean P_LookForShield(mobj_t *actor)
(actor->type == MT_BLUETEAMRING && player->ctfteam != 2))
continue;
if ((player->powers[pw_shield] & SH_PROTECTELECTRICITY)
if ((player->powers[pw_shield] & SH_PROTECTELECTRIC)
&& (P_AproxDistance(P_AproxDistance(actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale)))
{
P_SetTarget(&actor->tracer, player->mo);
@ -3061,7 +3061,7 @@ void A_JumpShield(mobj_t *actor)
player = actor->target->player;
if (P_SwitchShield(player, SH_JUMP))
if (P_SwitchShield(player, SH_WHIRLWIND))
S_StartSound(player->mo, actor->info->seesound);
else
S_StartSound(player->mo, sfx_itemup);
@ -3289,11 +3289,11 @@ void A_BombShield(mobj_t *actor)
player = actor->target->player;
// If you already have a bomb shield, use it!
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB)
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON)
P_BlackOw(player);
// Now we know for certain that we don't have a bomb shield, so add one. :3
P_SwitchShield(player, SH_BOMB); // will never return false, so no need for sound test
P_SwitchShield(player, SH_ARMAGEDDON); // will never return false, so no need for sound test
S_StartSound(player->mo, actor->info->seesound);
}
@ -3774,7 +3774,7 @@ void A_AttractChase(mobj_t *actor)
// Turn flingrings back into regular rings if attracted.
if (actor->tracer && actor->tracer->player
&& !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRICITY) && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
&& !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
{
mobj_t *newring;
newring = P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->reactiontime);
@ -3979,7 +3979,7 @@ void A_ThrownRing(mobj_t *actor)
// A non-homing ring getting attracted by a
// magnetic player. If he gets too far away, make
// sure to stop the attraction!
if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRICITY)
if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC)
&& P_AproxDistance(P_AproxDistance(actor->tracer->x-actor->x,
actor->tracer->y-actor->y), actor->tracer->z-actor->z) > FixedMul(RING_DIST/4, actor->tracer->scale)))
{
@ -3987,7 +3987,7 @@ void A_ThrownRing(mobj_t *actor)
}
if (actor->tracer && (actor->tracer->health)
&& (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRICITY))// Already found someone to follow.
&& (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC))// Already found someone to follow.
{
const INT32 temp = actor->threshold;
actor->threshold = 32000;
@ -4055,7 +4055,7 @@ void A_ThrownRing(mobj_t *actor)
if (!P_CheckSight(actor, player->mo))
continue; // out of sight
if ((player->powers[pw_shield] & SH_PROTECTELECTRICITY)
if ((player->powers[pw_shield] & SH_PROTECTELECTRIC)
&& dist < FixedMul(RING_DIST/4, player->mo->scale))
P_SetTarget(&actor->tracer, player->mo);
return;

View file

@ -1751,8 +1751,8 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
case MT_ELEMENTAL_ORB:
case MT_ATTRACT_ORB:
case MT_FORCE_ORB:
case MT_BOMB_ORB:
case MT_JUMP_ORB:
case MT_ARMAGEDDON_ORB:
case MT_WHIRLWIND_ORB:
case MT_PITY_ORB:
case MT_FLAMEAURA_ORB:
case MT_BUBBLEWRAP_ORB:

View file

@ -1582,7 +1582,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
else switch (inflictor->type)
{
case MT_PLAYER:
if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB)
if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON)
str = M_GetText("%s%s's armageddon blast %s %s.\n");
else if (inflictor->player->powers[pw_invulnerability])
str = M_GetText("%s%s's invincibility aura %s %s.\n");
@ -2791,7 +2791,7 @@ void P_RemoveShield(player_t *player)
{ // Second layer shields
player->powers[pw_shield] = SH_NONE;
}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) // Give them what's coming to them!
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) // Give them what's coming to them!
{
P_BlackOw(player); // BAM!
player->pflags |= PF_JUMPDOWN;
@ -3033,7 +3033,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false; // Invincible to fire damage
break;
case DMG_ELECTRIC:
if (player->powers[pw_shield] & SH_PROTECTELECTRICITY)
if (player->powers[pw_shield] & SH_PROTECTELECTRIC)
return false; // Invincible to electric damage
break;
default:

View file

@ -1052,6 +1052,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{
boolean elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
&& (tmthing->player->pflags & PF_SHIELDABILITY));
if (thing->flags & MF_MONITOR
&& (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED)
@ -1059,11 +1061,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))))
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|| elementalpierce))
{
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
boolean elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (tmthing->player->pflags & PF_SHIELDABILITY));
fixed_t *z = &tmthing->z; // aau.
P_DamageMobj(thing, tmthing, tmthing, 1, 0); // break the monitor
// Going down? Then bounce back up.
if ((P_MobjWasRemoved(thing) // Monitor was removed
@ -1071,7 +1074,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up
&& !elementalpierce) // you're not piercing through the monitor...
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
return false;
if (!(elementalpierce && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough.
return false;
else
*z -= *momz; // to ensure proper collision.
}
}
}

View file

@ -3250,14 +3250,6 @@ static void P_PlayerZMovement(mobj_t *mo)
P_SetPlayerMobjState(mo, S_PLAY_FALL);
clipmomz = false;
}
else if (mo->player->powers[pw_shield] & SH_FORCE) // Force shield's dodge dash.
{
P_SetPlayerMobjState(mo, S_PLAY_WALK);
mo->flags &= ~MF_NOGRAVITY;
mo->player->pflags &= ~(PF_FULLSTASIS|PF_SPINNING);
mo->momx >>= 3;
mo->momy >>= 3;
}
}
mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY/*|PF_GLIDING*/);
mo->player->jumping = 0;
@ -3619,7 +3611,7 @@ void P_MobjCheckWater(mobj_t *mobj)
{
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
{
if (p->powers[pw_shield] & SH_PROTECTELECTRICITY)
if (p->powers[pw_shield] & SH_PROTECTELECTRIC)
{ // Water removes electric shields...
p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK;
P_FlashPal(p, PAL_WHITE, 1);
@ -6774,14 +6766,25 @@ void P_MobjThinker(mobj_t *mobj)
&& (mobj->target->target->player)
&& ((mobj->target->target->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
&& (mobj->target->target->player->pflags & PF_SHIELDABILITY)
&& (mobj->state->nextstate < mobj->target->info->painstate)) // Special casing for elemental shield piercing attack.
&& (mobj->state->nextstate < mobj->target->info->raisestate)) // Special casing for elemental shield piercing attack.
{
P_SetMobjState(mobj, mobj->target->info->painstate);
P_SetMobjState(mobj, mobj->target->info->raisestate);
mobj->tics++;
}
else if ((mobj->target->type == MT_THUNDERCOIN_ORB)
&& (mobj->target->target)
&& (mobj->target->target->player)
&& ((mobj->target->target->player->powers[pw_shield] & SH_NOSTACK) == SH_THUNDERCOIN)
&& (mobj->target->target->player->pflags & PF_SHIELDABILITY)) // Special casing for thundercoin shield jump..
{
P_SetMobjState(mobj, mobj->target->info->raisestate);
P_SetMobjState(mobj->target, mobj->target->info->painstate);
mobj->target->target->player->pflags &= ~PF_SHIELDABILITY;
mobj->tics++;
}
break;
case MT_BOMB_ORB:
case MT_JUMP_ORB:
case MT_ARMAGEDDON_ORB:
case MT_WHIRLWIND_ORB:
case MT_ELEMENTAL_ORB:
case MT_FORCE_ORB:
case MT_PITY_ORB:

View file

@ -877,15 +877,6 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
// Useful when you want to kill everything the player is doing.
void P_ResetPlayer(player_t *player)
{
if (player->mo
&& player->powers[pw_shield] & SH_FORCE // Dash.
&& player->pflags & PF_SHIELDABILITY)
{
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
player->mo->flags &= ~MF_NOGRAVITY;
player->pflags &= ~PF_FULLSTASIS;
}
player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY);
player->powers[pw_carry] = CR_NONE;
player->jumping = 0;
@ -1351,8 +1342,8 @@ void P_SpawnShieldOrb(player_t *player)
orbtype = MT_FORCE_ORB;
else switch (player->powers[pw_shield] & SH_NOSTACK)
{
case SH_JUMP:
orbtype = MT_JUMP_ORB;
case SH_WHIRLWIND:
orbtype = MT_WHIRLWIND_ORB;
break;
case SH_ATTRACT:
orbtype = MT_ATTRACT_ORB;
@ -1360,8 +1351,8 @@ void P_SpawnShieldOrb(player_t *player)
case SH_ELEMENTAL:
orbtype = MT_ELEMENTAL_ORB;
break;
case SH_BOMB:
orbtype = MT_BOMB_ORB;
case SH_ARMAGEDDON:
orbtype = MT_ARMAGEDDON_ORB;
break;
case SH_PITY:
orbtype = MT_PITY_ORB;
@ -1473,14 +1464,6 @@ boolean P_SwitchShield(player_t *player, UINT16 shieldtype)
{
player->pflags &= ~(PF_SPINNING|PF_SHIELDABILITY); // They'll still have PF_THOKKED...
player->homing = 0;
if (player->powers[pw_shield] & SH_FORCE) // Dash.
{
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
player->mo->flags &= ~MF_NOGRAVITY;
player->pflags &= ~PF_FULLSTASIS;
player->mo->momx >>= 3;
player->mo->momy >>= 3;
}
}
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_FIREFLOWER // it's implicit that the new shield isn't a fireflower
@ -3944,18 +3927,27 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
//
void P_DoJumpShield(player_t *player)
{
boolean electric = ((player->powers[pw_shield] & SH_PROTECTELECTRIC) == SH_PROTECTELECTRIC);
if (player->pflags & PF_THOKKED)
return;
player->pflags &= ~PF_JUMPED;
P_DoJump(player, false);
player->pflags &= ~PF_JUMPED;
player->secondjump = 0;
player->jumping = 0;
player->secondjump = 0;
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->pflags &= ~PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
S_StartSound(player->mo, sfx_wdjump);
if (electric)
{
S_StartSound(player->mo, sfx_s3k45);
}
else
{
player->pflags &= ~PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
S_StartSound(player->mo, sfx_wdjump);
}
}
//
@ -4026,7 +4018,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{}
else if (onground || player->climbing || (player->mo->tracer && player->powers[pw_carry]))
{}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND
&& !(player->pflags & PF_JUMPED)
&& !(player->pflags & PF_USEDOWN))
P_DoJumpShield(player);
@ -4307,7 +4299,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break;
}
}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP && !player->powers[pw_super])
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super])
P_DoJumpShield(player);
}
@ -6993,79 +6985,58 @@ static void P_MovePlayer(player_t *player)
{
if (player->pflags & PF_JUMPED) // If the player is jumping
{
if (!(player->pflags & PF_USEDOWN)) // If the player is not holding down BT_USE
pflags_t check = (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_THOKKED);
if (!(player->pflags & check)) // If the player is not holding down BT_USE, or having used an ability previously
{
// Jump shield activation
if (!P_PlayerInPain(player) // If the player is not in pain
&& !player->climbing // If the player is not climbing
&& !(player->pflags & (PF_GLIDING|PF_SLIDING|PF_THOKKED)) // If the player is not gliding or sliding and hasn't used their ability
&& !onground) // If the player isn't on the ground
{
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP && !player->powers[pw_super])
P_DoJumpShield(player);
else if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_FLY)
{
P_DoJumpShield(player);
player->mo->momz *= 2;
}
}
// Bomb shield activation
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB)
{
// Don't let Super Sonic or invincibility use it
if (!(player->powers[pw_super] || player->powers[pw_invulnerability]))
P_BlackOw(player);
}
// Attract shield activation
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
{
if (!(player->pflags & PF_THOKKED))
{
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->homing = 2;
if (P_LookForEnemies(player, false) && player->mo->tracer)
{
S_StartSound(player->mo, sfx_s3k40);
player->homing = 3*TICRATE;
}
else
S_StartSound(player->mo, sfx_s3k41);
}
}
// Elemental shield activation
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
{
if (!(player->pflags & PF_THOKKED))
{
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
S_StartSound(player->mo, sfx_s3k43);
player->mo->momx = player->mo->momy = 0;
P_SetObjectMomZ(player->mo, -24*FRACUNIT, false);
}
}
// Force shield activation
if (player->powers[pw_shield] & SH_FORCE)
; // TODO
else
{
if (!(player->pflags & PF_THOKKED))
switch (player->powers[pw_shield] & SH_NOSTACK)
{
angle_t dashangle = player->mo->angle;
#if 1 // shadow.wad style redirection - hold down directional keys to set your path, go backwards by default
if (!(player->pflags & PF_ANALOGMODE) && (player->cmd.forwardmove || player->cmd.sidemove))
dashangle += R_PointToAngle2(0, 0, player->cmd.forwardmove<<FRACBITS, -player->cmd.sidemove<<FRACBITS);
else
#else // go backwards from your current momentum direction
if (player->mo->momx || player->mo->momy)
dashangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
#endif
dashangle += ANGLE_180;
P_ResetPlayer(player);
player->homing = 2 + (player->powers[pw_shield] & SH_FORCEHP); // might get ridiculous with 256 hitpoints, don't you think?
S_StartSound(player->mo, sfx_s3k47);
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
player->pflags |= PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY;
player->mo->flags |= MF_NOGRAVITY;
P_InstaThrust(player->mo, dashangle, 64*FRACUNIT);
player->mo->momz = 0;
// Whirlwind/Thundercoin shield activation
case SH_WHIRLWIND:
case SH_THUNDERCOIN:
if (!player->powers[pw_super])
P_DoJumpShield(player);
break;
// Armageddon shield activation
case SH_ARMAGEDDON:
// Don't let Super Sonic or invincibility use it
if (!(player->powers[pw_super] || player->powers[pw_invulnerability]))
P_BlackOw(player);
break;
// Attract shield activation
case SH_ATTRACT:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->homing = 2;
if (P_LookForEnemies(player, false) && player->mo->tracer)
{
S_StartSound(player->mo, sfx_s3k40);
player->homing = 3*TICRATE;
}
else
S_StartSound(player->mo, sfx_s3k45);
break;
// Elemental/Bubblewrap shield activation
case SH_ELEMENTAL:
case SH_BUBBLEWRAP:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->mo->momx = player->mo->momy = 0;
P_SetObjectMomZ(player->mo, -24*FRACUNIT, false);
S_StartSound(player->mo,
((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
? sfx_s3k43
: sfx_s3k44);
break;
// Flame shield activation
case SH_FLAMEAURA:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
P_Thrust(player->mo, player->mo->angle, 30*player->mo->scale - FixedMul(FixedSqrt(player->speed), FixedSqrt(player->mo->scale)));
S_StartSound(player->mo, sfx_s3k43);
default:
break;
}
}
}
@ -7084,26 +7055,7 @@ static void P_MovePlayer(player_t *player)
}
// HOMING option.
if (player->powers[pw_shield] & SH_FORCE // Dash.
&& player->pflags & PF_SHIELDABILITY)
{
if (player->homing)
{
player->pflags |= PF_FULLSTASIS;
player->mo->momz = 0;
if (!(player->pflags & PF_SPINNING))
player->homing = 0;
}
if (player->homing == 0)
{
P_ResetPlayer(player);
player->pflags |= PF_THOKKED; // silly silly
player->mo->momx >>= 3;
player->mo->momy >>= 3;
}
}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT // Sonic 3D Blast.
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT // Sonic 3D Blast.
&& player->pflags & PF_SHIELDABILITY)
{
if (player->homing && player->mo->tracer)

View file

@ -811,9 +811,9 @@ static void ST_drawFirstPersonHUD(void)
}
else switch (player->powers[pw_shield] & SH_NOSTACK)
{
case SH_JUMP: p = jumpshield; break;
case SH_WHIRLWIND: p = jumpshield; break;
case SH_ELEMENTAL: p = watershield; break;
case SH_BOMB: p = bombshield; break;
case SH_ARMAGEDDON: p = bombshield; break;
case SH_ATTRACT: p = ringshield; break;
case SH_PITY: p = pityshield; break;
case SH_FLAMEAURA: p = flameshield; break;