mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-24 11:42:03 +00:00
Turning some shield attributes into flags means that environmental protection and ring-pulling can be more elegantly handled. As a consequence, the S3 shields now have all their passives, and are just waiting on me to give them actives (two of which don't have the necessary sprites for...)
This commit is contained in:
parent
3aa9d2a1b1
commit
aa8a454ea9
7 changed files with 60 additions and 43 deletions
|
@ -181,25 +181,35 @@ typedef enum
|
|||
typedef enum
|
||||
{
|
||||
SH_NONE = 0,
|
||||
// Standard shields
|
||||
|
||||
// Shield flags
|
||||
SH_PROTECTFIRE = 0x400,
|
||||
SH_PROTECTWATER = 0x800,
|
||||
SH_PROTECTELECTRICITY = 0x1000,
|
||||
|
||||
// Indivisible shields
|
||||
SH_PITY = 1,
|
||||
SH_JUMP,
|
||||
SH_ATTRACT,
|
||||
SH_ELEMENTAL,
|
||||
SH_BOMB,
|
||||
// Pity shield: the world's most basic shield ever, given to players who suck at Match
|
||||
SH_PITY,
|
||||
// Sonic 3 shields
|
||||
SH_FLAMEAURA,
|
||||
SH_BUBBLEWRAP,
|
||||
SH_THUNDERCOIN,
|
||||
// The fireflower used to be stackable with other shields. Not anymore.
|
||||
SH_FIREFLOWER,
|
||||
|
||||
// normal shields that use flags
|
||||
SH_ATTRACT = SH_PROTECTELECTRICITY,
|
||||
SH_ELEMENTAL = SH_PROTECTFIRE|SH_PROTECTWATER,
|
||||
|
||||
// Sonic 3 shields
|
||||
SH_FLAMEAURA = SH_PROTECTFIRE,
|
||||
SH_BUBBLEWRAP = SH_PROTECTWATER,
|
||||
SH_THUNDERCOIN = SH_JUMP|SH_PROTECTELECTRICITY,
|
||||
|
||||
// The force shield uses the lower 8 bits to count how many extra hits are left.
|
||||
SH_FORCE = 0x100,
|
||||
SH_FORCEHP = 0xFF, // to be used as a bitmask only
|
||||
// The mushroom CAN stack with other shields.
|
||||
|
||||
// Mostly for use with Mario mode.
|
||||
SH_MUSHROOM = 0x200,
|
||||
SH_STACK = SH_MUSHROOM, //|SH_FIREFLOWER,
|
||||
|
||||
SH_STACK = SH_MUSHROOM, // second-layer shields
|
||||
SH_NOSTACK = ~SH_STACK
|
||||
} shieldtype_t; // pw_shield
|
||||
|
||||
|
|
|
@ -7174,21 +7174,28 @@ struct {
|
|||
{"PRECIP_STORM_NOSTRIKES",PRECIP_STORM_NOSTRIKES},
|
||||
|
||||
// Shields
|
||||
// These ones use the lower 8 bits
|
||||
{"SH_NONE",SH_NONE},
|
||||
// Shield flags
|
||||
{"SH_PROTECTFIRE",SH_PROTECTFIRE},
|
||||
{"SH_PROTECTWATER",SH_PROTECTWATER},
|
||||
{"SH_PROTECTELECTRICITY",SH_PROTECTELECTRICITY},
|
||||
// Indivisible shields
|
||||
{"SH_PITY",SH_PITY},
|
||||
{"SH_JUMP",SH_JUMP},
|
||||
{"SH_BOMB",SH_BOMB},
|
||||
{"SH_FIREFLOWER",SH_FIREFLOWER},
|
||||
// normal shields that use flags
|
||||
{"SH_ATTRACT",SH_ATTRACT},
|
||||
{"SH_ELEMENTAL",SH_ELEMENTAL},
|
||||
{"SH_BOMB",SH_BOMB},
|
||||
// Sonic 3 shields
|
||||
{"SH_FLAMEAURA",SH_FLAMEAURA},
|
||||
{"SH_BUBBLEWRAP",SH_BUBBLEWRAP},
|
||||
{"SH_THUNDERCOIN",SH_THUNDERCOIN},
|
||||
{"SH_FLAMEAURA",SH_FLAMEAURA},
|
||||
{"SH_PITY",SH_PITY},
|
||||
{"SH_FIREFLOWER",SH_FIREFLOWER},
|
||||
// These ones are special and use the upper bits
|
||||
{"SH_FORCE",SH_FORCE}, // Lower bits are how many hits left, 0 is the last hit
|
||||
{"SH_MUSHROOM", SH_MUSHROOM}, // Can stack with other shields
|
||||
// Stack masks
|
||||
// The force shield uses the lower 8 bits to count how many extra hits are left.
|
||||
{"SH_FORCE",SH_FORCE},
|
||||
{"SH_FORCEHP",SH_FORCEHP}, // to be used as a bitmask only
|
||||
// Mostly for use with Mario mode.
|
||||
{"SH_MUSHROOM", SH_MUSHROOM},
|
||||
{"SH_STACK",SH_STACK},
|
||||
{"SH_NOSTACK",SH_NOSTACK},
|
||||
|
||||
|
|
|
@ -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_NOSTACK) == SH_ATTRACT
|
||||
if ((player->powers[pw_shield] & SH_PROTECTELECTRICITY)
|
||||
&& (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);
|
||||
|
@ -3817,7 +3817,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_NOSTACK) != SH_ATTRACT && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
|
||||
&& !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRICITY) && 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);
|
||||
|
@ -4022,7 +4022,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_NOSTACK) == SH_ATTRACT
|
||||
if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRICITY)
|
||||
&& 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)))
|
||||
{
|
||||
|
@ -4030,7 +4030,7 @@ void A_ThrownRing(mobj_t *actor)
|
|||
}
|
||||
|
||||
if (actor->tracer && (actor->tracer->health)
|
||||
&& (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)// Already found someone to follow.
|
||||
&& (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRICITY))// Already found someone to follow.
|
||||
{
|
||||
const INT32 temp = actor->threshold;
|
||||
actor->threshold = 32000;
|
||||
|
@ -4098,7 +4098,7 @@ void A_ThrownRing(mobj_t *actor)
|
|||
if (!P_CheckSight(actor, player->mo))
|
||||
continue; // out of sight
|
||||
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT
|
||||
if ((player->powers[pw_shield] & SH_PROTECTELECTRICITY)
|
||||
&& dist < FixedMul(RING_DIST/4, player->mo->scale))
|
||||
P_SetTarget(&actor->tracer, player->mo);
|
||||
return;
|
||||
|
|
|
@ -1459,7 +1459,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
case MT_EXTRALARGEBUBBLE:
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
|
||||
if (player->powers[pw_shield] & SH_PROTECTWATER)
|
||||
return;
|
||||
if (maptol & TOL_NIGHTS)
|
||||
return;
|
||||
|
@ -3022,28 +3022,23 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
|
||||
return false;
|
||||
|
||||
#define shieldtype (player->powers[pw_shield] & SH_NOSTACK)
|
||||
switch (damagetype)
|
||||
{
|
||||
case DMG_WATER:
|
||||
if (shieldtype == SH_BUBBLEWRAP
|
||||
|| shieldtype == SH_ELEMENTAL)
|
||||
if (player->powers[pw_shield] & SH_PROTECTWATER)
|
||||
return false; // Invincible to water damage
|
||||
break;
|
||||
case DMG_FIRE:
|
||||
if (shieldtype == SH_FLAMEAURA
|
||||
|| shieldtype == SH_ELEMENTAL)
|
||||
if (player->powers[pw_shield] & SH_PROTECTFIRE)
|
||||
return false; // Invincible to fire damage
|
||||
break;
|
||||
case DMG_ELECTRIC:
|
||||
if (shieldtype == SH_ATTRACT
|
||||
|| shieldtype == SH_THUNDERCOIN)
|
||||
if (player->powers[pw_shield] & SH_PROTECTELECTRICITY)
|
||||
return false; // Invincible to electric damage
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#undef shieldtype
|
||||
}
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling
|
||||
|
@ -3067,7 +3062,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (!force && inflictor && inflictor->flags & MF_FIRE)
|
||||
{
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
|
||||
if (player->powers[pw_shield] & SH_PROTECTFIRE)
|
||||
return false; // Invincible to fire objects
|
||||
|
||||
if (G_PlatformGametype() && inflictor && source && source->player)
|
||||
|
|
11
src/p_mobj.c
11
src/p_mobj.c
|
@ -3619,15 +3619,20 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
{
|
||||
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
|
||||
{
|
||||
if ((p->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
|
||||
{ // Water removes attract shield.
|
||||
if (p->powers[pw_shield] & SH_PROTECTELECTRICITY)
|
||||
{ // Water removes electric shields...
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Drown timer setting
|
||||
if ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL // Has elemental
|
||||
if ((p->powers[pw_shield] & SH_PROTECTWATER) // Has water protection
|
||||
|| (p->exiting) // Or exiting
|
||||
|| (maptol & TOL_NIGHTS) // Or in NiGHTS mode
|
||||
|| (mariomode)) // Or in Mario mode...
|
||||
|
|
|
@ -3562,7 +3562,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
P_PlayerFlagBurst(player, false);
|
||||
break;
|
||||
case 12: // Space Countdown
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL && !player->powers[pw_spacetime])
|
||||
if (!(player->powers[pw_shield] & SH_PROTECTWATER) && !player->powers[pw_spacetime])
|
||||
player->powers[pw_spacetime] = spacetimetics + 1;
|
||||
break;
|
||||
case 13: // Ramp Sector (Increase step-up/down)
|
||||
|
|
|
@ -2229,7 +2229,7 @@ static void P_DoBubbleBreath(player_t *player)
|
|||
fixed_t z = player->mo->z;
|
||||
mobj_t *bubble = NULL;
|
||||
|
||||
if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator)
|
||||
if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_PROTECTWATER) && !(player->pflags & PF_NIGHTSMODE)) || player->spectator)
|
||||
return;
|
||||
|
||||
if (player->charflags & SF_MACHINE)
|
||||
|
@ -9242,7 +9242,7 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter
|
||||
player->powers[pw_tailsfly]--;
|
||||
|
||||
if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL))
|
||||
if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
||||
{
|
||||
if (player->powers[pw_underwater] <= 12*TICRATE+1)
|
||||
P_RestoreMusic(player); //incase they were about to drown
|
||||
|
@ -9252,7 +9252,7 @@ void P_PlayerThink(player_t *player)
|
|||
else if (player->powers[pw_underwater] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer
|
||||
player->powers[pw_underwater]--;
|
||||
|
||||
if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL))
|
||||
if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
||||
player->powers[pw_spacetime] = 0;
|
||||
else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer
|
||||
player->powers[pw_spacetime]--;
|
||||
|
|
Loading…
Reference in a new issue