* Add SH_PROTECTSPIKE as a shield flag, because I kinda wanted to when I originally made shields, and SUBARASHII's cactus shield vindicated my desires.

* Tweaked the values of the shield constants slightly so that no base-game shield is made up of flags and only flags.
This commit is contained in:
toasterbabe 2017-08-09 20:56:31 +01:00
parent a3767fedac
commit 1cab08e39f
3 changed files with 32 additions and 21 deletions

View file

@ -181,6 +181,14 @@ typedef enum
PA_RIDE PA_RIDE
} panim_t; } panim_t;
//
// All of the base srb2 shields are either a single constant,
// or use damagetype-protecting flags applied to a constant,
// or are the force shield (which does everything weirdly).
//
// Base flags by themselves aren't used so modders can make
// abstract, ability-less shields should they so choose.
//
typedef enum typedef enum
{ {
SH_NONE = 0, SH_NONE = 0,
@ -189,19 +197,21 @@ typedef enum
SH_PROTECTFIRE = 0x400, SH_PROTECTFIRE = 0x400,
SH_PROTECTWATER = 0x800, SH_PROTECTWATER = 0x800,
SH_PROTECTELECTRIC = 0x1000, SH_PROTECTELECTRIC = 0x1000,
SH_PROTECTSPIKE = 0x2000, // cactus shield one day? thanks, subarashii
//SH_PROTECTNUKE = 0x4000, // intentionally no hardcoded defense against nukes
// Indivisible shields // Indivisible shields
SH_PITY = 1, // the world's most basic shield ever, given to players who suck at Match 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,
// normal shields that use flags // Normal shields that use flags
SH_ATTRACT = SH_PROTECTELECTRIC, SH_ATTRACT = SH_PITY|SH_PROTECTELECTRIC,
SH_ELEMENTAL = SH_PROTECTFIRE|SH_PROTECTWATER, SH_ELEMENTAL = SH_PITY|SH_PROTECTFIRE|SH_PROTECTWATER,
// Sonic 3 shields // Sonic 3 shields
SH_FLAMEAURA = SH_PROTECTFIRE, SH_FLAMEAURA = SH_PITY|SH_PROTECTFIRE,
SH_BUBBLEWRAP = SH_PROTECTWATER, SH_BUBBLEWRAP = SH_PITY|SH_PROTECTWATER,
SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC, SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC,
// The force shield uses the lower 8 bits to count how many extra hits are left. // The force shield uses the lower 8 bits to count how many extra hits are left.

View file

@ -7146,6 +7146,7 @@ struct {
{"SH_PROTECTFIRE",SH_PROTECTFIRE}, {"SH_PROTECTFIRE",SH_PROTECTFIRE},
{"SH_PROTECTWATER",SH_PROTECTWATER}, {"SH_PROTECTWATER",SH_PROTECTWATER},
{"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC}, {"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC},
{"SH_PROTECTSPIKE",SH_PROTECTSPIKE},
// Indivisible shields // Indivisible shields
{"SH_PITY",SH_PITY}, {"SH_PITY",SH_PITY},
{"SH_WHIRLWIND",SH_WHIRLWIND}, {"SH_WHIRLWIND",SH_WHIRLWIND},

View file

@ -414,13 +414,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
if (special->type == MT_GSNAPPER && !(((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) if (special->type == MT_GSNAPPER && !(((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce) || player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce)
&& toucher->z < special->z + special->height && toucher->z + toucher->height > special->z) && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z
&& !(player->powers[pw_shield] & SH_PROTECTSPIKE))
{ {
// Can only hit snapper from above // Can only hit snapper from above
P_DamageMobj(toucher, special, special, 1, 0); P_DamageMobj(toucher, special, special, 1, DMG_SPIKE);
} }
else if (special->type == MT_SHARP else if (special->type == MT_SHARP
&& ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2))) && ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2))
&& !(player->powers[pw_shield] & SH_PROTECTSPIKE))
{ {
if (player->pflags & PF_BOUNCING) if (player->pflags & PF_BOUNCING)
{ {
@ -428,7 +430,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_DoAbilityBounce(player, false); P_DoAbilityBounce(player, false);
} }
else // Cannot hit sharp from above or when red and angry else // Cannot hit sharp from above or when red and angry
P_DamageMobj(toucher, special, special, 1, 0); P_DamageMobj(toucher, special, special, 1, DMG_SPIKE);
} }
else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
@ -3164,18 +3166,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
switch (damagetype) switch (damagetype)
{ {
case DMG_WATER: #define DAMAGECASE(type)\
if (player->powers[pw_shield] & SH_PROTECTWATER) case DMG_##type:\
return false; // Invincible to water damage if (player->powers[pw_shield] & SH_PROTECT##type)\
break; return false;\
case DMG_FIRE: break
if (player->powers[pw_shield] & SH_PROTECTFIRE) DAMAGECASE(WATER);
return false; // Invincible to fire damage DAMAGECASE(FIRE);
break; DAMAGECASE(ELECTRIC);
case DMG_ELECTRIC: DAMAGECASE(SPIKE);
if (player->powers[pw_shield] & SH_PROTECTELECTRIC) #undef DAMAGECASE
return false; // Invincible to electric damage
break;
default: default:
break; break;
} }