diff --git a/common/ruletypes.h b/common/ruletypes.h index ab6c7073d..684d71651 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -479,6 +479,10 @@ RULE_BOOL(Combat, Classic2HBAnimation, false, "2HB will use the 2 hand piercing RULE_BOOL(Combat, ArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption") RULE_BOOL(Combat, ThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption") RULE_BOOL(Combat, UseLiveRiposteMechanics, false, "Set to true to disable SPA 173 SE_RiposteChance from making those with the effect on them immune to enrage, can longer riposte from a riposte.") +RULE_INT(Combat, FrontalStunImmunityClasses, 0, "Bitmask for Classes than have frontal stun immunity, No Races (0) by default.") +RULE_BOOL(Combat, NPCsUseFrontalStunImmunityClasses, false, "Enable or disable NPCs using frontal stun immunity Classes from Combat:FrontalStunImmunityClasses, false by default.") +RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have frontal stun immunity, Ogre (512) only by default.") +RULE_BOOL(Combat, NPCsUseFrontalStunImmunityRaces, true, "Enable or disable NPCs using frontal stun immunity Races from Combat:FrontalStunImmunityRaces, true by default.") RULE_CATEGORY_END() RULE_CATEGORY(NPC) diff --git a/zone/attack.cpp b/zone/attack.cpp index 37ece0419..4ce86b393 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3832,11 +3832,59 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons can_stun = true; } - if ((GetBaseRace() == OGRE || GetBaseRace() == OGGOK_CITIZEN) && - !attacker->BehindMob(this, attacker->GetX(), attacker->GetY())) + bool is_immune_to_frontal_stun = false; + + if (IsBot() || IsClient() || IsMerc()) { + if ( + IsPlayerClass(GetClass()) && + RuleI(Combat, FrontalStunImmunityClasses) & GetPlayerClassBit(GetClass()) + ) { + is_immune_to_frontal_stun = true; + } + + + if ( + ( + IsPlayerRace(GetBaseRace()) && + RuleI(Combat, FrontalStunImmunityRaces) & GetPlayerRaceBit(GetBaseRace()) + ) || + GetBaseRace() == RACE_OGGOK_CITIZEN_93 + ) { + is_immune_to_frontal_stun = true; + } + } else if (IsNPC()) { + if ( + RuleB(Combat, NPCsUseFrontalStunImmunityClasses) && + IsPlayerClass(GetClass()) && + RuleI(Combat, FrontalStunImmunityClasses) & GetPlayerClassBit(GetClass()) + ) { + is_immune_to_frontal_stun = true; + } + + if ( + RuleB(Combat, NPCsUseFrontalStunImmunityRaces) && + ( + ( + IsPlayerRace(GetBaseRace()) && + RuleI(Combat, FrontalStunImmunityRaces) & GetPlayerRaceBit(GetBaseRace()) + ) || + GetBaseRace() == RACE_OGGOK_CITIZEN_93 + ) + ) { + is_immune_to_frontal_stun = true; + } + } + + if ( + is_immune_to_frontal_stun && + !attacker->BehindMob(this, attacker->GetX(), attacker->GetY()) + ) { can_stun = false; - if (GetSpecialAbility(UNSTUNABLE)) + } + + if (GetSpecialAbility(UNSTUNABLE)) { can_stun = false; + } } if (can_stun) { int bashsave_roll = zone->random.Int(0, 100); diff --git a/zone/mob.cpp b/zone/mob.cpp index 1e3b74d9b..3f420d972 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2872,6 +2872,7 @@ uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) { in_race == RACE_FAYGUARD_112 || in_race == RACE_ERUDITE_GHOST_118 || in_race == RACE_IKSAR_CITIZEN_139 || + in_race == RACE_SHADE_224 || in_race == RACE_TROLL_CREW_MEMBER_331 || in_race == RACE_PIRATE_DECKHAND_332 || in_race == RACE_GNOME_PIRATE_338 || @@ -2884,7 +2885,12 @@ uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) { in_race == RACE_WARLOCK_OF_HATE_352 || in_race == RACE_UNDEAD_VAMPIRE_359 || in_race == RACE_VAMPIRE_360 || + in_race == RACE_SAND_ELF_364 || + in_race == RACE_TAELOSIAN_NATIVE_385 || + in_race == RACE_TAELOSIAN_EVOKER_386 || + in_race == RACE_DRACHNID_461 || in_race == RACE_ZOMBIE_471 || + in_race == RACE_ELDDAR_489 || in_race == RACE_VAMPIRE_497 || in_race == RACE_KERRAN_562 || in_race == RACE_BROWNIE_568 || @@ -2911,11 +2917,22 @@ uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) { in_race == RACE_SPECTRAL_IKSAR_147 || in_race == RACE_INVISIBLE_MAN_127 || in_race == RACE_VAMPYRE_208 || + in_race == RACE_RECUSO_237 || in_race == RACE_BROKEN_SKULL_PIRATE_333 || + in_race == RACE_INVISIBLE_MAN_OF_ZOMM_600 || + in_race == RACE_OGRE_NPC_MALE_624 || + in_race == RACE_BEEFEATER_667 || in_race == RACE_ERUDITE_678 ) { // Male only races return 0; - } else if (in_race == RACE_FAIRY_25 || in_race == RACE_PIXIE_56) { // Female only races + } else if ( + in_race == RACE_FAIRY_25 || + in_race == RACE_PIXIE_56 || + in_race == RACE_BANSHEE_487 || + in_race == RACE_BANSHEE_488 || + in_race == RACE_AYONAE_RO_498 || + in_race == RACE_SULLON_ZEK_499 + ) { // Female only races return 1; } else { // Neutral default for NPC Races return 2;