From 1cab08e39f195a00b3690caef5debe7216466622 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 9 Aug 2017 20:56:31 +0100 Subject: [PATCH] * 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. --- src/d_player.h | 20 +++++++++++++++----- src/dehacked.c | 1 + src/p_inter.c | 32 ++++++++++++++++---------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 4e4a53a08..f8b38ded9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -181,6 +181,14 @@ typedef enum PA_RIDE } 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 { SH_NONE = 0, @@ -189,19 +197,21 @@ typedef enum SH_PROTECTFIRE = 0x400, SH_PROTECTWATER = 0x800, SH_PROTECTELECTRIC = 0x1000, + SH_PROTECTSPIKE = 0x2000, // cactus shield one day? thanks, subarashii + //SH_PROTECTNUKE = 0x4000, // intentionally no hardcoded defense against nukes // Indivisible shields SH_PITY = 1, // the world's most basic shield ever, given to players who suck at Match SH_WHIRLWIND, SH_ARMAGEDDON, - // normal shields that use flags - SH_ATTRACT = SH_PROTECTELECTRIC, - SH_ELEMENTAL = SH_PROTECTFIRE|SH_PROTECTWATER, + // Normal shields that use flags + SH_ATTRACT = SH_PITY|SH_PROTECTELECTRIC, + SH_ELEMENTAL = SH_PITY|SH_PROTECTFIRE|SH_PROTECTWATER, // Sonic 3 shields - SH_FLAMEAURA = SH_PROTECTFIRE, - SH_BUBBLEWRAP = SH_PROTECTWATER, + SH_FLAMEAURA = SH_PITY|SH_PROTECTFIRE, + SH_BUBBLEWRAP = SH_PITY|SH_PROTECTWATER, SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC, // The force shield uses the lower 8 bits to count how many extra hits are left. diff --git a/src/dehacked.c b/src/dehacked.c index 3a40b64a5..56f3014f1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7146,6 +7146,7 @@ struct { {"SH_PROTECTFIRE",SH_PROTECTFIRE}, {"SH_PROTECTWATER",SH_PROTECTWATER}, {"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC}, + {"SH_PROTECTSPIKE",SH_PROTECTSPIKE}, // Indivisible shields {"SH_PITY",SH_PITY}, {"SH_WHIRLWIND",SH_WHIRLWIND}, diff --git a/src/p_inter.c b/src/p_inter.c index fc3bd080e..07165d2cc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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)) || 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 - P_DamageMobj(toucher, special, special, 1, 0); + P_DamageMobj(toucher, special, special, 1, DMG_SPIKE); } 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) { @@ -428,7 +430,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DoAbilityBounce(player, false); } 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)) || ((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) { - case DMG_WATER: - if (player->powers[pw_shield] & SH_PROTECTWATER) - return false; // Invincible to water damage - break; - case DMG_FIRE: - if (player->powers[pw_shield] & SH_PROTECTFIRE) - return false; // Invincible to fire damage - break; - case DMG_ELECTRIC: - if (player->powers[pw_shield] & SH_PROTECTELECTRIC) - return false; // Invincible to electric damage - break; +#define DAMAGECASE(type)\ + case DMG_##type:\ + if (player->powers[pw_shield] & SH_PROTECT##type)\ + return false;\ + break + DAMAGECASE(WATER); + DAMAGECASE(FIRE); + DAMAGECASE(ELECTRIC); + DAMAGECASE(SPIKE); +#undef DAMAGECASE default: break; }