mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 12:41:30 +00:00
[Cleanup] Cleanup Special Ability Code (#4365)
* [Cleanup] Cleanup Special Ability-based Code * Update emu_constants.cpp * Update emu_constants.cpp * Update emu_constants.cpp * Update special_ability.cpp * Cleanup * Update emu_constants.cpp
This commit is contained in:
parent
d01d091b47
commit
76b9ce0ac1
@ -640,79 +640,14 @@ std::string EQ::constants::GetAppearanceTypeName(uint32 appearance_type)
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetSpecialAbilityMap()
|
||||
std::string SpecialAbility::GetName(int ability_id)
|
||||
{
|
||||
static const std::map<uint32, std::string> special_ability_map = {
|
||||
{ SPECATK_SUMMON, "Summon" },
|
||||
{ SPECATK_ENRAGE, "Enrage" },
|
||||
{ SPECATK_RAMPAGE, "Rampage" },
|
||||
{ SPECATK_AREA_RAMPAGE, "Area Rampage" },
|
||||
{ SPECATK_FLURRY, "Flurry" },
|
||||
{ SPECATK_TRIPLE, "Triple Attack" },
|
||||
{ SPECATK_QUAD, "Quadruple Attack" },
|
||||
{ SPECATK_INNATE_DW, "Dual Wield" },
|
||||
{ SPECATK_BANE, "Bane Attack" },
|
||||
{ SPECATK_MAGICAL, "Magical Attack" },
|
||||
{ SPECATK_RANGED_ATK, "Ranged Attack" },
|
||||
{ UNSLOWABLE, "Immune to Slow" },
|
||||
{ UNMEZABLE, "Immune to Mesmerize" },
|
||||
{ UNCHARMABLE, "Immune to Charm" },
|
||||
{ UNSTUNABLE, "Immune to Stun" },
|
||||
{ UNSNAREABLE, "Immune to Snare" },
|
||||
{ UNFEARABLE, "Immune to Fear" },
|
||||
{ UNDISPELLABLE, "Immune to Dispell" },
|
||||
{ IMMUNE_MELEE, "Immune to Melee" },
|
||||
{ IMMUNE_MAGIC, "Immune to Magic" },
|
||||
{ IMMUNE_FLEEING, "Immune to Fleeing" },
|
||||
{ IMMUNE_MELEE_EXCEPT_BANE, "Immune to Melee except Bane" },
|
||||
{ IMMUNE_MELEE_NONMAGICAL, "Immune to Non-Magical Melee" },
|
||||
{ IMMUNE_AGGRO, "Immune to Aggro" },
|
||||
{ IMMUNE_AGGRO_ON, "Immune to Being Aggro" },
|
||||
{ IMMUNE_CASTING_FROM_RANGE, "Immune to Ranged Spells" },
|
||||
{ IMMUNE_FEIGN_DEATH, "Immune to Feign Death" },
|
||||
{ IMMUNE_TAUNT, "Immune to Taunt" },
|
||||
{ NPC_TUNNELVISION, "Tunnel Vision" },
|
||||
{ NPC_NO_BUFFHEAL_FRIENDS, "Does Not Heal of Buff Allies" },
|
||||
{ IMMUNE_PACIFY, "Immune to Pacify" },
|
||||
{ LEASH, "Leashed" },
|
||||
{ TETHER, "Tethered" },
|
||||
{ DESTRUCTIBLE_OBJECT, "Destructible Object" },
|
||||
{ NO_HARM_FROM_CLIENT, "Immune to Harm from Client" },
|
||||
{ ALWAYS_FLEE, "Always Flees" },
|
||||
{ FLEE_PERCENT, "Flee Percentage" },
|
||||
{ ALLOW_BENEFICIAL, "Allows Beneficial Spells" },
|
||||
{ DISABLE_MELEE, "Melee is Disabled" },
|
||||
{ NPC_CHASE_DISTANCE, "Chase Distance" },
|
||||
{ ALLOW_TO_TANK, "Allowed to Tank" },
|
||||
{ IGNORE_ROOT_AGGRO_RULES, "Ignores Root Aggro" },
|
||||
{ CASTING_RESIST_DIFF, "Casting Resist Difficulty" },
|
||||
{ COUNTER_AVOID_DAMAGE, "Counter Damage Avoidance" },
|
||||
{ PROX_AGGRO, "Proximity Aggro" },
|
||||
{ IMMUNE_RANGED_ATTACKS, "Immune to Ranged Attacks" },
|
||||
{ IMMUNE_DAMAGE_CLIENT, "Immune to Client Damage" },
|
||||
{ IMMUNE_DAMAGE_NPC, "Immune to NPC Damage" },
|
||||
{ IMMUNE_AGGRO_CLIENT, "Immune to Client Aggro" },
|
||||
{ IMMUNE_AGGRO_NPC, "Immune to NPC Aggro" },
|
||||
{ MODIFY_AVOID_DAMAGE, "Modify Damage Avoidance" },
|
||||
{ IMMUNE_FADING_MEMORIES, "Immune to Memory Fades" },
|
||||
{ IMMUNE_OPEN, "Immune to Open" },
|
||||
{ IMMUNE_ASSASSINATE, "Immune to Assassinate" },
|
||||
{ IMMUNE_HEADSHOT, "Immune to Headshot" },
|
||||
{ IMMUNE_AGGRO_BOT, "Immune to Bot Aggro" },
|
||||
{ IMMUNE_DAMAGE_BOT, "Immune to Bot Damage" },
|
||||
};
|
||||
|
||||
return special_ability_map;
|
||||
return IsValid(ability_id) ? special_ability_names[ability_id] : "UNKNOWN SPECIAL ABILITY";
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetSpecialAbilityName(uint32 ability_id)
|
||||
bool SpecialAbility::IsValid(int ability_id)
|
||||
{
|
||||
const auto& a = EQ::constants::GetSpecialAbilityMap().find(ability_id);
|
||||
if (a != EQ::constants::GetSpecialAbilityMap().end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
return special_ability_names.find(ability_id) != special_ability_names.end();
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetConsiderColorMap()
|
||||
|
||||
@ -401,9 +401,6 @@ namespace EQ
|
||||
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
||||
std::string GetAppearanceTypeName(uint32 animation_type);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetSpecialAbilityMap();
|
||||
std::string GetSpecialAbilityName(uint32 ability_id);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetConsiderColorMap();
|
||||
std::string GetConsiderColorName(uint32 consider_color);
|
||||
|
||||
@ -614,67 +611,131 @@ enum class ApplySpellType {
|
||||
Raid
|
||||
};
|
||||
|
||||
enum {
|
||||
SPECATK_SUMMON = 1,
|
||||
SPECATK_ENRAGE = 2,
|
||||
SPECATK_RAMPAGE = 3,
|
||||
SPECATK_AREA_RAMPAGE = 4,
|
||||
SPECATK_FLURRY = 5,
|
||||
SPECATK_TRIPLE = 6,
|
||||
SPECATK_QUAD = 7,
|
||||
SPECATK_INNATE_DW = 8,
|
||||
SPECATK_BANE = 9,
|
||||
SPECATK_MAGICAL = 10,
|
||||
SPECATK_RANGED_ATK = 11,
|
||||
UNSLOWABLE = 12,
|
||||
UNMEZABLE = 13,
|
||||
UNCHARMABLE = 14,
|
||||
UNSTUNABLE = 15,
|
||||
UNSNAREABLE = 16,
|
||||
UNFEARABLE = 17,
|
||||
UNDISPELLABLE = 18,
|
||||
IMMUNE_MELEE = 19,
|
||||
IMMUNE_MAGIC = 20,
|
||||
IMMUNE_FLEEING = 21,
|
||||
IMMUNE_MELEE_EXCEPT_BANE = 22,
|
||||
IMMUNE_MELEE_NONMAGICAL = 23,
|
||||
IMMUNE_AGGRO = 24,
|
||||
IMMUNE_AGGRO_ON = 25,
|
||||
IMMUNE_CASTING_FROM_RANGE = 26,
|
||||
IMMUNE_FEIGN_DEATH = 27,
|
||||
IMMUNE_TAUNT = 28,
|
||||
NPC_TUNNELVISION = 29,
|
||||
NPC_NO_BUFFHEAL_FRIENDS = 30,
|
||||
IMMUNE_PACIFY = 31,
|
||||
LEASH = 32,
|
||||
TETHER = 33,
|
||||
DESTRUCTIBLE_OBJECT = 34,
|
||||
NO_HARM_FROM_CLIENT = 35,
|
||||
ALWAYS_FLEE = 36,
|
||||
FLEE_PERCENT = 37,
|
||||
ALLOW_BENEFICIAL = 38,
|
||||
DISABLE_MELEE = 39,
|
||||
NPC_CHASE_DISTANCE = 40,
|
||||
ALLOW_TO_TANK = 41,
|
||||
IGNORE_ROOT_AGGRO_RULES = 42,
|
||||
CASTING_RESIST_DIFF = 43,
|
||||
COUNTER_AVOID_DAMAGE = 44, // Modify by percent NPC's opponents chance to riposte, block, parry or dodge individually, or for all skills
|
||||
PROX_AGGRO = 45,
|
||||
IMMUNE_RANGED_ATTACKS = 46,
|
||||
IMMUNE_DAMAGE_CLIENT = 47,
|
||||
IMMUNE_DAMAGE_NPC = 48,
|
||||
IMMUNE_AGGRO_CLIENT = 49,
|
||||
IMMUNE_AGGRO_NPC = 50,
|
||||
MODIFY_AVOID_DAMAGE = 51, // Modify by percent the NPCs chance to riposte, block, parry or dodge individually, or for all skills
|
||||
IMMUNE_FADING_MEMORIES = 52,
|
||||
IMMUNE_OPEN = 53,
|
||||
IMMUNE_ASSASSINATE = 54,
|
||||
IMMUNE_HEADSHOT = 55,
|
||||
IMMUNE_AGGRO_BOT = 56,
|
||||
IMMUNE_DAMAGE_BOT = 57,
|
||||
MAX_SPECIAL_ATTACK = 58
|
||||
};
|
||||
namespace SpecialAbility {
|
||||
constexpr int Summon = 1;
|
||||
constexpr int Enrage = 2;
|
||||
constexpr int Rampage = 3;
|
||||
constexpr int AreaRampage = 4;
|
||||
constexpr int Flurry = 5;
|
||||
constexpr int TripleAttack = 6;
|
||||
constexpr int QuadrupleAttack = 7;
|
||||
constexpr int DualWield = 8;
|
||||
constexpr int BaneAttack = 9;
|
||||
constexpr int MagicalAttack = 10;
|
||||
constexpr int RangedAttack = 11;
|
||||
constexpr int SlowImmunity = 12;
|
||||
constexpr int MesmerizeImmunity = 13;
|
||||
constexpr int CharmImmunity = 14;
|
||||
constexpr int StunImmunity = 15;
|
||||
constexpr int SnareImmunity = 16;
|
||||
constexpr int FearImmunity = 17;
|
||||
constexpr int DispellImmunity = 18;
|
||||
constexpr int MeleeImmunity = 19;
|
||||
constexpr int MagicImmunity = 20;
|
||||
constexpr int FleeingImmunity = 21;
|
||||
constexpr int MeleeImmunityExceptBane = 22;
|
||||
constexpr int MeleeImmunityExceptMagical = 23;
|
||||
constexpr int AggroImmunity = 24;
|
||||
constexpr int BeingAggroImmunity = 25;
|
||||
constexpr int CastingFromRangeImmunity = 26;
|
||||
constexpr int FeignDeathImmunity = 27;
|
||||
constexpr int TauntImmunity = 28;
|
||||
constexpr int TunnelVision = 29;
|
||||
constexpr int NoBuffHealFriends = 30;
|
||||
constexpr int PacifyImmunity = 31;
|
||||
constexpr int Leash = 32;
|
||||
constexpr int Tether = 33;
|
||||
constexpr int DestructibleObject = 34;
|
||||
constexpr int HarmFromClientImmunity = 35;
|
||||
constexpr int AlwaysFlee = 36;
|
||||
constexpr int FleePercent = 37;
|
||||
constexpr int AllowBeneficial = 38;
|
||||
constexpr int DisableMelee = 39;
|
||||
constexpr int NPCChaseDistance = 40;
|
||||
constexpr int AllowedToTank = 41;
|
||||
constexpr int IgnoreRootAggroRules = 42;
|
||||
constexpr int CastingResistDifficulty = 43;
|
||||
constexpr int CounterAvoidDamage = 44;
|
||||
constexpr int ProximityAggro = 45;
|
||||
constexpr int RangedAttackImmunity = 46;
|
||||
constexpr int ClientDamageImmunity = 47;
|
||||
constexpr int NPCDamageImmunity = 48;
|
||||
constexpr int ClientAggroImmunity = 49;
|
||||
constexpr int NPCAggroImmunity = 50;
|
||||
constexpr int ModifyAvoidDamage = 51;
|
||||
constexpr int MemoryFadeImmunity = 52;
|
||||
constexpr int OpenImmunity = 53;
|
||||
constexpr int AssassinateImmunity = 54;
|
||||
constexpr int HeadshotImmunity = 55;
|
||||
constexpr int BotAggroImmunity = 56;
|
||||
constexpr int BotDamageImmunity = 57;
|
||||
constexpr int Max = 58;
|
||||
|
||||
constexpr int MaxParameters = 9;
|
||||
|
||||
std::string GetName(int ability_id);
|
||||
bool IsValid(int ability_id);
|
||||
}
|
||||
|
||||
static std::map<int, std::string> special_ability_names = {
|
||||
{ SpecialAbility::Summon, "Summon" },
|
||||
{ SpecialAbility::Enrage, "Enrage" },
|
||||
{ SpecialAbility::Rampage, "Rampage" },
|
||||
{ SpecialAbility::AreaRampage, "Area Rampage" },
|
||||
{ SpecialAbility::Flurry, "Flurry" },
|
||||
{ SpecialAbility::TripleAttack, "Triple Attack" },
|
||||
{ SpecialAbility::QuadrupleAttack, "Quadruple Attack" },
|
||||
{ SpecialAbility::DualWield, "Dual Wield" },
|
||||
{ SpecialAbility::BaneAttack, "Bane Attack" },
|
||||
{ SpecialAbility::MagicalAttack, "Magical Attack" },
|
||||
{ SpecialAbility::RangedAttack, "Ranged Attack" },
|
||||
{ SpecialAbility::SlowImmunity, "Immune to Slow" },
|
||||
{ SpecialAbility::MesmerizeImmunity, "Immune to Mesmerize" },
|
||||
{ SpecialAbility::CharmImmunity, "Immune to Charm" },
|
||||
{ SpecialAbility::StunImmunity, "Immune to Stun" },
|
||||
{ SpecialAbility::SnareImmunity, "Immune to Snare" },
|
||||
{ SpecialAbility::FearImmunity, "Immune to Fear" },
|
||||
{ SpecialAbility::DispellImmunity, "Immune to Dispell" },
|
||||
{ SpecialAbility::MeleeImmunity, "Immune to Melee" },
|
||||
{ SpecialAbility::MagicImmunity, "Immune to Magic" },
|
||||
{ SpecialAbility::FleeingImmunity, "Immune to Fleeing" },
|
||||
{ SpecialAbility::MeleeImmunityExceptBane, "Immune to Melee except Bane" },
|
||||
{ SpecialAbility::MeleeImmunityExceptMagical, "Immune to Non-Magical Melee" },
|
||||
{ SpecialAbility::AggroImmunity, "Immune to Aggro" },
|
||||
{ SpecialAbility::BeingAggroImmunity, "Immune to Being Aggro" },
|
||||
{ SpecialAbility::CastingFromRangeImmunity, "Immune to Ranged Spells" },
|
||||
{ SpecialAbility::FeignDeathImmunity, "Immune to Feign Death" },
|
||||
{ SpecialAbility::TauntImmunity, "Immune to Taunt" },
|
||||
{ SpecialAbility::TunnelVision, "Tunnel Vision" },
|
||||
{ SpecialAbility::NoBuffHealFriends, "Does Not Heal or Buff Allies" },
|
||||
{ SpecialAbility::PacifyImmunity, "Immune to Pacify" },
|
||||
{ SpecialAbility::Leash, "Leashed" },
|
||||
{ SpecialAbility::Tether, "Tethered" },
|
||||
{ SpecialAbility::DestructibleObject, "Destructible Object" },
|
||||
{ SpecialAbility::HarmFromClientImmunity, "Immune to Harm from Client" },
|
||||
{ SpecialAbility::AlwaysFlee, "Always Flees" },
|
||||
{ SpecialAbility::FleePercent, "Flee Percentage" },
|
||||
{ SpecialAbility::AllowBeneficial, "Allows Beneficial Spells" },
|
||||
{ SpecialAbility::DisableMelee, "Melee is Disabled" },
|
||||
{ SpecialAbility::NPCChaseDistance, "Chase Distance" },
|
||||
{ SpecialAbility::AllowedToTank, "Allowed to Tank" },
|
||||
{ SpecialAbility::IgnoreRootAggroRules, "Ignores Root Aggro" },
|
||||
{ SpecialAbility::CastingResistDifficulty, "Casting Resist Difficulty" },
|
||||
{ SpecialAbility::CounterAvoidDamage, "Counter Damage Avoidance" },
|
||||
{ SpecialAbility::ProximityAggro, "Proximity Aggro" },
|
||||
{ SpecialAbility::RangedAttackImmunity, "Immune to Ranged Attacks" },
|
||||
{ SpecialAbility::ClientDamageImmunity, "Immune to Client Damage" },
|
||||
{ SpecialAbility::NPCDamageImmunity, "Immune to NPC Damage" },
|
||||
{ SpecialAbility::ClientAggroImmunity, "Immune to Client Aggro" },
|
||||
{ SpecialAbility::NPCAggroImmunity, "Immune to NPC Aggro" },
|
||||
{ SpecialAbility::ModifyAvoidDamage, "Modify Damage Avoidance" },
|
||||
{ SpecialAbility::MemoryFadeImmunity, "Immune to Memory Fades" },
|
||||
{ SpecialAbility::OpenImmunity, "Immune to Open" },
|
||||
{ SpecialAbility::AssassinateImmunity, "Immune to Assassinate" },
|
||||
{ SpecialAbility::HeadshotImmunity, "Immune to Headshot" },
|
||||
{ SpecialAbility::BotAggroImmunity, "Immune to Bot Aggro" },
|
||||
{ SpecialAbility::BotDamageImmunity, "Immune to Bot Damage" },
|
||||
};
|
||||
|
||||
namespace HeroicBonusBucket
|
||||
{
|
||||
|
||||
@ -61,6 +61,7 @@ public:
|
||||
{.parent_command = "find", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrace"},
|
||||
{.parent_command = "find", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrecipe"},
|
||||
{.parent_command = "find", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findskill"},
|
||||
{.parent_command = "find", .sub_command = "special_ability", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fsa|findspecialability"},
|
||||
{.parent_command = "find", .sub_command = "spell", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fs|findspell"},
|
||||
{.parent_command = "find", .sub_command = "task", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findtask"},
|
||||
{.parent_command = "find", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fz|findzone"},
|
||||
|
||||
@ -167,7 +167,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) {
|
||||
swarm_pet_npc->GetSwarmInfo()->target = targ->GetID();
|
||||
swarm_pet_npc->SetPetTargetLockID(targ->GetID());
|
||||
swarm_pet_npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
|
||||
swarm_pet_npc->SetSpecialAbility(SpecialAbility::AggroImmunity, 1);
|
||||
}
|
||||
else {
|
||||
swarm_pet_npc->GetSwarmInfo()->target = 0;
|
||||
@ -272,7 +272,7 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
||||
if (RuleB(Spells, SwarmPetTargetLock) || sticktarg) {
|
||||
swarm_pet_npc->GetSwarmInfo()->target = targ->GetID();
|
||||
swarm_pet_npc->SetPetTargetLockID(targ->GetID());
|
||||
swarm_pet_npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
|
||||
swarm_pet_npc->SetSpecialAbility(SpecialAbility::AggroImmunity, 1);
|
||||
}
|
||||
else {
|
||||
swarm_pet_npc->GetSwarmInfo()->target = 0;
|
||||
@ -401,7 +401,7 @@ void Mob::WakeTheDead(uint16 spell_id, Corpse *corpse_to_use, Mob *tar, uint32 d
|
||||
made_npc->npc_spells_id = 7;
|
||||
break;
|
||||
case Class::Paladin:
|
||||
//SPECATK_TRIPLE
|
||||
//SpecialAbility::TripleAttack
|
||||
strcpy(made_npc->special_abilities, "6,1");
|
||||
made_npc->current_hp = made_npc->current_hp * 150 / 100;
|
||||
made_npc->max_hp = made_npc->max_hp * 150 / 100;
|
||||
|
||||
@ -412,13 +412,13 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
(
|
||||
!RuleB(Aggro, AggroPlayerPets) ||
|
||||
pet_owner->CastToClient()->GetGM() ||
|
||||
mob->GetSpecialAbility(IMMUNE_AGGRO)
|
||||
mob->GetSpecialAbility(SpecialAbility::AggroImmunity)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsNPC() && mob->IsNPC() && mob->GetSpecialAbility(IMMUNE_AGGRO_NPC)) {
|
||||
if (IsNPC() && mob->IsNPC() && mob->GetSpecialAbility(SpecialAbility::NPCAggroImmunity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -452,8 +452,8 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't aggro new clients if we are already engaged unless PROX_AGGRO is set
|
||||
if (IsEngaged() && (!GetSpecialAbility(PROX_AGGRO) || (GetSpecialAbility(PROX_AGGRO) && !CombatRange(mob)))) {
|
||||
// Don't aggro new clients if we are already engaged unless SpecialAbility::ProximityAggro is set
|
||||
if (IsEngaged() && (!GetSpecialAbility(SpecialAbility::ProximityAggro) || (GetSpecialAbility(SpecialAbility::ProximityAggro) && !CombatRange(mob)))) {
|
||||
LogAggro(
|
||||
"[{}] is in combat, and does not have prox_aggro, or does and is out of combat range with [{}]",
|
||||
GetName(),
|
||||
@ -634,19 +634,19 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target->GetSpecialAbility(NO_HARM_FROM_CLIENT)) {
|
||||
if (target->GetSpecialAbility(SpecialAbility::HarmFromClientImmunity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsBot() && target->GetSpecialAbility(IMMUNE_DAMAGE_BOT)) {
|
||||
if (IsBot() && target->GetSpecialAbility(SpecialAbility::BotDamageImmunity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsClient() && target->GetSpecialAbility(IMMUNE_DAMAGE_CLIENT)) {
|
||||
if (IsClient() && target->GetSpecialAbility(SpecialAbility::ClientDamageImmunity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsNPC() && target->GetSpecialAbility(IMMUNE_DAMAGE_NPC)) {
|
||||
if (IsNPC() && target->GetSpecialAbility(SpecialAbility::NPCDamageImmunity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1053,13 +1053,13 @@ bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage, ExtraAtt
|
||||
float _zDist = m_Position.z - other->GetZ();
|
||||
_zDist *= _zDist;
|
||||
|
||||
if (GetSpecialAbility(NPC_CHASE_DISTANCE)) {
|
||||
if (GetSpecialAbility(SpecialAbility::NPCChaseDistance)) {
|
||||
|
||||
bool DoLoSCheck = true;
|
||||
float max_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 0));
|
||||
float min_distance = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 1));
|
||||
float max_dist = static_cast<float>(GetSpecialAbilityParam(SpecialAbility::NPCChaseDistance, 0));
|
||||
float min_distance = static_cast<float>(GetSpecialAbilityParam(SpecialAbility::NPCChaseDistance, 1));
|
||||
|
||||
if (GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 2)) {
|
||||
if (GetSpecialAbilityParam(SpecialAbility::NPCChaseDistance, 2)) {
|
||||
DoLoSCheck = false; //Ignore line of sight check
|
||||
}
|
||||
|
||||
|
||||
124
zone/attack.cpp
124
zone/attack.cpp
@ -438,12 +438,12 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
int counter_parry = 0;
|
||||
int counter_dodge = 0;
|
||||
|
||||
if (attacker->GetSpecialAbility(COUNTER_AVOID_DAMAGE)) {
|
||||
counter_all = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 0);
|
||||
counter_riposte = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 1);
|
||||
counter_block = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 2);
|
||||
counter_parry = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 3);
|
||||
counter_dodge = attacker->GetSpecialAbilityParam(COUNTER_AVOID_DAMAGE, 4);
|
||||
if (attacker->GetSpecialAbility(SpecialAbility::CounterAvoidDamage)) {
|
||||
counter_all = attacker->GetSpecialAbilityParam(SpecialAbility::CounterAvoidDamage, 0);
|
||||
counter_riposte = attacker->GetSpecialAbilityParam(SpecialAbility::CounterAvoidDamage, 1);
|
||||
counter_block = attacker->GetSpecialAbilityParam(SpecialAbility::CounterAvoidDamage, 2);
|
||||
counter_parry = attacker->GetSpecialAbilityParam(SpecialAbility::CounterAvoidDamage, 3);
|
||||
counter_dodge = attacker->GetSpecialAbilityParam(SpecialAbility::CounterAvoidDamage, 4);
|
||||
}
|
||||
|
||||
int modify_all = 0;
|
||||
@ -452,12 +452,12 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
int modify_parry = 0;
|
||||
int modify_dodge = 0;
|
||||
|
||||
if (GetSpecialAbility(MODIFY_AVOID_DAMAGE)) {
|
||||
modify_all = GetSpecialAbilityParam(MODIFY_AVOID_DAMAGE, 0);
|
||||
modify_riposte = GetSpecialAbilityParam(MODIFY_AVOID_DAMAGE, 1);
|
||||
modify_block = GetSpecialAbilityParam(MODIFY_AVOID_DAMAGE, 2);
|
||||
modify_parry = GetSpecialAbilityParam(MODIFY_AVOID_DAMAGE, 3);
|
||||
modify_dodge = GetSpecialAbilityParam(MODIFY_AVOID_DAMAGE, 4);
|
||||
if (GetSpecialAbility(SpecialAbility::ModifyAvoidDamage)) {
|
||||
modify_all = GetSpecialAbilityParam(SpecialAbility::ModifyAvoidDamage, 0);
|
||||
modify_riposte = GetSpecialAbilityParam(SpecialAbility::ModifyAvoidDamage, 1);
|
||||
modify_block = GetSpecialAbilityParam(SpecialAbility::ModifyAvoidDamage, 2);
|
||||
modify_parry = GetSpecialAbilityParam(SpecialAbility::ModifyAvoidDamage, 3);
|
||||
modify_dodge = GetSpecialAbilityParam(SpecialAbility::ModifyAvoidDamage, 4);
|
||||
}
|
||||
|
||||
/* Heroic Strikethrough Implementation per Dev Quotes (2018):
|
||||
@ -1129,13 +1129,13 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item) {
|
||||
int64 banedmg = 0;
|
||||
|
||||
//can't hit invulnerable stuff with weapons.
|
||||
if (against->GetInvul() || against->GetSpecialAbility(IMMUNE_MELEE)) {
|
||||
if (against->GetInvul() || against->GetSpecialAbility(SpecialAbility::MeleeImmunity)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//check to see if our weapons or fists are magical.
|
||||
if (against->GetSpecialAbility(IMMUNE_MELEE_NONMAGICAL)) {
|
||||
if (GetSpecialAbility(SPECATK_MAGICAL)) {
|
||||
if (against->GetSpecialAbility(SpecialAbility::MeleeImmunityExceptMagical)) {
|
||||
if (GetSpecialAbility(SpecialAbility::MagicalAttack)) {
|
||||
dmg = 1;
|
||||
}
|
||||
//On live this occurs for ALL NPC's >= 10
|
||||
@ -1178,7 +1178,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item) {
|
||||
}
|
||||
|
||||
int eledmg = 0;
|
||||
if (!against->GetSpecialAbility(IMMUNE_MAGIC)) {
|
||||
if (!against->GetSpecialAbility(SpecialAbility::MagicImmunity)) {
|
||||
if (weapon_item && weapon_item->ElemDmgAmt) {
|
||||
//we don't check resist for npcs here
|
||||
eledmg = weapon_item->ElemDmgAmt;
|
||||
@ -1186,7 +1186,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item) {
|
||||
}
|
||||
}
|
||||
|
||||
if (against->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) {
|
||||
if (against->GetSpecialAbility(SpecialAbility::MeleeImmunityExceptBane)) {
|
||||
if (weapon_item) {
|
||||
if (weapon_item->BaneDmgBody == against->GetBodyType()) {
|
||||
banedmg += weapon_item->BaneDmgAmt;
|
||||
@ -1198,7 +1198,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item) {
|
||||
}
|
||||
|
||||
if (!banedmg) {
|
||||
if (!GetSpecialAbility(SPECATK_BANE))
|
||||
if (!GetSpecialAbility(SpecialAbility::BaneAttack))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@ -1233,7 +1233,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
||||
int64 banedmg = 0;
|
||||
int x = 0;
|
||||
|
||||
if (!against || against->GetInvul() || against->GetSpecialAbility(IMMUNE_MELEE))
|
||||
if (!against || against->GetInvul() || against->GetSpecialAbility(SpecialAbility::MeleeImmunity))
|
||||
return 0;
|
||||
|
||||
// check for items being illegally attained
|
||||
@ -1261,7 +1261,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
||||
}
|
||||
}
|
||||
|
||||
if (against->GetSpecialAbility(IMMUNE_MELEE_NONMAGICAL)) {
|
||||
if (against->GetSpecialAbility(SpecialAbility::MeleeImmunityExceptMagical)) {
|
||||
if (weapon_item) {
|
||||
// check to see if the weapon is magic
|
||||
bool MagicWeapon = weapon_item->GetItemMagical(true) || spellbonuses.MagicWeapon || itembonuses.MagicWeapon;
|
||||
@ -1298,7 +1298,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
||||
RuleI(Combat, PetAttackMagicLevel)) { // pets wouldn't actually use this but...
|
||||
dmg = 1; // it gives us an idea if we can hit
|
||||
}
|
||||
else if (MagicGloves || GetSpecialAbility(SPECATK_MAGICAL)) {
|
||||
else if (MagicGloves || GetSpecialAbility(SpecialAbility::MagicalAttack)) {
|
||||
dmg = 1;
|
||||
}
|
||||
else
|
||||
@ -1328,7 +1328,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
||||
}
|
||||
|
||||
int eledmg = 0;
|
||||
if (!against->GetSpecialAbility(IMMUNE_MAGIC)) {
|
||||
if (!against->GetSpecialAbility(SpecialAbility::MagicImmunity)) {
|
||||
if (weapon_item && weapon_item->GetItem() && weapon_item->GetItemElementalFlag(true))
|
||||
// the client actually has the way this is done, it does not appear to check req!
|
||||
eledmg = against->ResistElementalWeaponDmg(weapon_item);
|
||||
@ -1338,9 +1338,9 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
||||
(weapon_item->GetItemBaneDamageBody(true) || weapon_item->GetItemBaneDamageRace(true)))
|
||||
banedmg = against->CheckBaneDamage(weapon_item);
|
||||
|
||||
if (against->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) {
|
||||
if (against->GetSpecialAbility(SpecialAbility::MeleeImmunityExceptBane)) {
|
||||
if (!banedmg) {
|
||||
if (!GetSpecialAbility(SPECATK_BANE))
|
||||
if (!GetSpecialAbility(SpecialAbility::BaneAttack))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@ -3190,19 +3190,19 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO)) {
|
||||
if (IsFamiliar() || GetSpecialAbility(SpecialAbility::AggroImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->IsBot() && GetSpecialAbility(IMMUNE_AGGRO_BOT)) {
|
||||
if (other->IsBot() && GetSpecialAbility(SpecialAbility::BotAggroImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->IsClient() && GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) {
|
||||
if (other->IsClient() && GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->IsNPC() && GetSpecialAbility(IMMUNE_AGGRO_NPC)) {
|
||||
if (other->IsNPC() && GetSpecialAbility(SpecialAbility::NPCAggroImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3214,12 +3214,12 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->GetSpecialAbility(IMMUNE_AGGRO_ON)) {
|
||||
if (other->GetSpecialAbility(SpecialAbility::BeingAggroImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetSpecialAbility(NPC_TUNNELVISION)) {
|
||||
int tv_mod = GetSpecialAbilityParam(NPC_TUNNELVISION, 0);
|
||||
if (GetSpecialAbility(SpecialAbility::TunnelVision)) {
|
||||
int tv_mod = GetSpecialAbilityParam(SpecialAbility::TunnelVision, 0);
|
||||
|
||||
Mob *top = GetTarget();
|
||||
if (top && top != other) {
|
||||
@ -3299,10 +3299,10 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
|
||||
// cb:2007-08-17
|
||||
// owner must get on list, but he's not actually gained any hate yet
|
||||
if (
|
||||
!owner->GetSpecialAbility(IMMUNE_AGGRO) &&
|
||||
!(owner->IsBot() && GetSpecialAbility(IMMUNE_AGGRO_BOT)) &&
|
||||
!(owner->IsClient() && GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) &&
|
||||
!(owner->IsNPC() && GetSpecialAbility(IMMUNE_AGGRO_NPC))
|
||||
!owner->GetSpecialAbility(SpecialAbility::AggroImmunity) &&
|
||||
!(owner->IsBot() && GetSpecialAbility(SpecialAbility::BotAggroImmunity)) &&
|
||||
!(owner->IsClient() && GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) &&
|
||||
!(owner->IsNPC() && GetSpecialAbility(SpecialAbility::NPCAggroImmunity))
|
||||
) {
|
||||
if (owner->IsClient() && !CheckAggro(owner)) {
|
||||
owner->CastToClient()->AddAutoXTarget(this);
|
||||
@ -3315,10 +3315,10 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
|
||||
if (mypet && !mypet->IsHeld() && !mypet->IsPetStop()) { // I have a pet, add other to it
|
||||
if (
|
||||
!mypet->IsFamiliar() &&
|
||||
!mypet->GetSpecialAbility(IMMUNE_AGGRO) &&
|
||||
!(IsBot() && mypet->GetSpecialAbility(IMMUNE_AGGRO_BOT)) &&
|
||||
!(IsClient() && mypet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) &&
|
||||
!(IsNPC() && mypet->GetSpecialAbility(IMMUNE_AGGRO_NPC))
|
||||
!mypet->GetSpecialAbility(SpecialAbility::AggroImmunity) &&
|
||||
!(IsBot() && mypet->GetSpecialAbility(SpecialAbility::BotAggroImmunity)) &&
|
||||
!(IsClient() && mypet->GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) &&
|
||||
!(IsNPC() && mypet->GetSpecialAbility(SpecialAbility::NPCAggroImmunity))
|
||||
) {
|
||||
mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
}
|
||||
@ -3326,10 +3326,10 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
|
||||
else if (myowner) { // I am a pet, add other to owner if it's NPC/LD
|
||||
if (
|
||||
myowner->IsAIControlled() &&
|
||||
!myowner->GetSpecialAbility(IMMUNE_AGGRO) &&
|
||||
!(myowner->IsBot() && GetSpecialAbility(IMMUNE_AGGRO_BOT)) &&
|
||||
!(myowner->IsClient() && GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) &&
|
||||
!(myowner->IsNPC() && GetSpecialAbility(IMMUNE_AGGRO_NPC))
|
||||
!myowner->GetSpecialAbility(SpecialAbility::AggroImmunity) &&
|
||||
!(myowner->IsBot() && GetSpecialAbility(SpecialAbility::BotAggroImmunity)) &&
|
||||
!(myowner->IsClient() && GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) &&
|
||||
!(myowner->IsNPC() && GetSpecialAbility(SpecialAbility::NPCAggroImmunity))
|
||||
) {
|
||||
myowner->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
}
|
||||
@ -4095,8 +4095,8 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
}
|
||||
|
||||
// this should actually happen MUCH sooner, need to investigate though -- good enough for now
|
||||
if ((skill_used == EQ::skills::SkillArchery || skill_used == EQ::skills::SkillThrowing) && GetSpecialAbility(IMMUNE_RANGED_ATTACKS)) {
|
||||
LogCombat("Avoiding [{}] damage due to IMMUNE_RANGED_ATTACKS", damage);
|
||||
if ((skill_used == EQ::skills::SkillArchery || skill_used == EQ::skills::SkillThrowing) && GetSpecialAbility(SpecialAbility::RangedAttackImmunity)) {
|
||||
LogCombat("Avoiding [{}] damage due to SpecialAbility::RangedAttackImmunity", damage);
|
||||
damage = DMG_INVULNERABLE;
|
||||
}
|
||||
|
||||
@ -4174,12 +4174,12 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
Mob* pet = GetPet();
|
||||
pet &&
|
||||
!pet->IsFamiliar() &&
|
||||
!pet->GetSpecialAbility(IMMUNE_AGGRO) &&
|
||||
!pet->GetSpecialAbility(SpecialAbility::AggroImmunity) &&
|
||||
!pet->IsEngaged() &&
|
||||
attacker &&
|
||||
!(attacker->IsBot() && pet->GetSpecialAbility(IMMUNE_AGGRO_BOT)) &&
|
||||
!(attacker->IsClient() && pet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) &&
|
||||
!(attacker->IsNPC() && pet->GetSpecialAbility(IMMUNE_AGGRO_NPC)) &&
|
||||
!(attacker->IsBot() && pet->GetSpecialAbility(SpecialAbility::BotAggroImmunity)) &&
|
||||
!(attacker->IsClient() && pet->GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) &&
|
||||
!(attacker->IsNPC() && pet->GetSpecialAbility(SpecialAbility::NPCAggroImmunity)) &&
|
||||
attacker != this &&
|
||||
!attacker->IsCorpse() &&
|
||||
!pet->IsGHeld() &&
|
||||
@ -4463,7 +4463,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
can_stun = false;
|
||||
}
|
||||
|
||||
if (GetSpecialAbility(UNSTUNABLE)) {
|
||||
if (GetSpecialAbility(SpecialAbility::StunImmunity)) {
|
||||
can_stun = false;
|
||||
}
|
||||
}
|
||||
@ -5188,7 +5188,7 @@ void Mob::TrySpellProc(const EQ::ItemInstance *inst, const EQ::ItemData *weapon,
|
||||
}
|
||||
}
|
||||
|
||||
if (!weapon && hand == EQ::invslot::slotRange && GetSpecialAbility(SPECATK_RANGED_ATK)) {
|
||||
if (!weapon && hand == EQ::invslot::slotRange && GetSpecialAbility(SpecialAbility::RangedAttack)) {
|
||||
rangedattk = true;
|
||||
}
|
||||
|
||||
@ -5593,7 +5593,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
||||
// Crippling blows also have a chance to stun
|
||||
// Kayen: Crippling Blow would cause a chance to interrupt for npcs < 55, with a
|
||||
// staggers message.
|
||||
if (defender->GetLevel() <= RuleI(Combat, MaximumLevelStunsCripplingBlow) && !defender->GetSpecialAbility(UNSTUNABLE)) {
|
||||
if (defender->GetLevel() <= RuleI(Combat, MaximumLevelStunsCripplingBlow) && !defender->GetSpecialAbility(SpecialAbility::StunImmunity)) {
|
||||
entity_list.MessageCloseString(
|
||||
defender,
|
||||
true,
|
||||
@ -6485,7 +6485,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
||||
// this appears where they do special attack dmg mods
|
||||
int spec_mod = 0;
|
||||
if (IsSpecialAttack(eSpecialAttacks::Rampage)) {
|
||||
int mod = GetSpecialAbilityParam(SPECATK_RAMPAGE, 2);
|
||||
int mod = GetSpecialAbilityParam(SpecialAbility::Rampage, 2);
|
||||
if (mod > 0)
|
||||
spec_mod = mod;
|
||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
|
||||
@ -6496,7 +6496,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
||||
}
|
||||
}
|
||||
else if (IsSpecialAttack(eSpecialAttacks::AERampage)) {
|
||||
int mod = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2);
|
||||
int mod = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 2);
|
||||
if (mod > 0)
|
||||
spec_mod = mod;
|
||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
|
||||
@ -6799,8 +6799,8 @@ void NPC::SetAttackTimer()
|
||||
|
||||
//special offhand stuff
|
||||
if (i == EQ::invslot::slotSecondary) {
|
||||
// SPECATK_QUAD is uncheesable
|
||||
if (!CanThisClassDualWield() || (HasTwoHanderEquipped() && !GetSpecialAbility(SPECATK_QUAD))) {
|
||||
// SpecialAbility::QuadrupleAttack is uncheesable
|
||||
if (!CanThisClassDualWield() || (HasTwoHanderEquipped() && !GetSpecialAbility(SpecialAbility::QuadrupleAttack))) {
|
||||
attack_dw_timer.Disable();
|
||||
continue;
|
||||
}
|
||||
@ -6958,18 +6958,18 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts, bool ram
|
||||
// thresholds, and if its truely random, then this should work
|
||||
// out reasonably and will save us compute resources.
|
||||
int32 RandRoll = zone->random.Int(0, 99);
|
||||
if ((CanThisClassDoubleAttack() || GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD))
|
||||
if ((CanThisClassDoubleAttack() || GetSpecialAbility(SpecialAbility::TripleAttack) || GetSpecialAbility(SpecialAbility::QuadrupleAttack))
|
||||
// check double attack, this is NOT the same rules that clients use...
|
||||
&&
|
||||
RandRoll < (GetLevel() + NPCDualAttackModifier)) {
|
||||
Attack(target, EQ::invslot::slotPrimary, false, false, false, opts);
|
||||
// lets see if we can do a triple attack with the main hand
|
||||
// pets are excluded from triple and quads...
|
||||
if ((GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD)) && !IsPet() &&
|
||||
if ((GetSpecialAbility(SpecialAbility::TripleAttack) || GetSpecialAbility(SpecialAbility::QuadrupleAttack)) && !IsPet() &&
|
||||
RandRoll < (GetLevel() + NPCTripleAttackModifier)) {
|
||||
Attack(target, EQ::invslot::slotPrimary, false, false, false, opts);
|
||||
// now lets check the quad attack
|
||||
if (GetSpecialAbility(SPECATK_QUAD) && RandRoll < (GetLevel() + NPCQuadAttackModifier)) {
|
||||
if (GetSpecialAbility(SpecialAbility::QuadrupleAttack) && RandRoll < (GetLevel() + NPCQuadAttackModifier)) {
|
||||
Attack(target, EQ::invslot::slotPrimary, false, false, false, opts);
|
||||
}
|
||||
}
|
||||
@ -6983,9 +6983,9 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts, bool ramp
|
||||
}
|
||||
|
||||
// Mobs will only dual wield w/ the flag or have a secondary weapon
|
||||
// For now, SPECATK_QUAD means innate DW when Combat:UseLiveCombatRounds is true
|
||||
if ((GetSpecialAbility(SPECATK_INNATE_DW) ||
|
||||
(RuleB(Combat, UseLiveCombatRounds) && GetSpecialAbility(SPECATK_QUAD))) ||
|
||||
// For now, SpecialAbility::QuadrupleAttack means innate DW when Combat:UseLiveCombatRounds is true
|
||||
if ((GetSpecialAbility(SpecialAbility::DualWield) ||
|
||||
(RuleB(Combat, UseLiveCombatRounds) && GetSpecialAbility(SpecialAbility::QuadrupleAttack))) ||
|
||||
GetEquippedItemFromTextureSlot(EQ::textures::weaponSecondary) != 0) {
|
||||
if (CheckDualWield()) {
|
||||
Attack(target, EQ::invslot::slotSecondary, false, false, false, opts);
|
||||
|
||||
@ -2220,7 +2220,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
{
|
||||
// These don't generate the IMMUNE_ATKSPEED message and the icon shows up
|
||||
// but have no effect on the mobs attack speed
|
||||
if (GetSpecialAbility(UNSLOWABLE))
|
||||
if (GetSpecialAbility(SpecialAbility::SlowImmunity))
|
||||
break;
|
||||
|
||||
if (effect_value < 0) //A few spells use negative values(Descriptions all indicate it should be a slow)
|
||||
|
||||
@ -2418,14 +2418,14 @@ bool Bot::TryPrimaryWeaponAttacks(Mob* tar, const EQ::ItemInstance* p_item) {
|
||||
}
|
||||
|
||||
if (GetAppearance() == eaDead) { return false; }
|
||||
if (GetSpecialAbility(SPECATK_TRIPLE) && CheckBotDoubleAttack(true)) {
|
||||
if (GetSpecialAbility(SpecialAbility::TripleAttack) && CheckBotDoubleAttack(true)) {
|
||||
|
||||
Attack(tar, EQ::invslot::slotPrimary, true);
|
||||
}
|
||||
|
||||
if (GetAppearance() == eaDead) { return false; }
|
||||
// quad attack, does this belong here??
|
||||
if (GetSpecialAbility(SPECATK_QUAD) && CheckBotDoubleAttack(true)) {
|
||||
if (GetSpecialAbility(SpecialAbility::QuadrupleAttack) && CheckBotDoubleAttack(true)) {
|
||||
Attack(tar, EQ::invslot::slotPrimary, true);
|
||||
}
|
||||
}
|
||||
@ -5635,7 +5635,7 @@ int32 Bot::GenerateBaseManaPoints()
|
||||
|
||||
void Bot::GenerateSpecialAttacks() {
|
||||
if (((GetClass() == Class::Monk) || (GetClass() == Class::Warrior) || (GetClass() == Class::Ranger) || (GetClass() == Class::Berserker)) && (GetLevel() >= 60))
|
||||
SetSpecialAbility(SPECATK_TRIPLE, 1);
|
||||
SetSpecialAbility(SpecialAbility::TripleAttack, 1);
|
||||
}
|
||||
|
||||
bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
||||
|
||||
@ -784,7 +784,7 @@ bool Bot::BotCastNuke(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
|
||||
stunChance = 50;
|
||||
}
|
||||
|
||||
if (!tar->GetSpecialAbility(UNSTUNABLE) && !tar->IsStunned() && (zone->random.Int(1, 100) <= stunChance)) {
|
||||
if (!tar->GetSpecialAbility(SpecialAbility::StunImmunity) && !tar->IsStunned() && (zone->random.Int(1, 100) <= stunChance)) {
|
||||
botSpell = GetBestBotSpellForStunByTargetType(this, ST_Target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2671,8 +2671,8 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who,
|
||||
|
||||
if (against_who) {
|
||||
if (
|
||||
against_who->GetSpecialAbility(IMMUNE_AGGRO) ||
|
||||
against_who->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) ||
|
||||
against_who->GetSpecialAbility(SpecialAbility::AggroImmunity) ||
|
||||
against_who->GetSpecialAbility(SpecialAbility::ClientAggroImmunity) ||
|
||||
against_who->IsClient() ||
|
||||
GetLevelCon(against_who->GetLevel()) == ConsiderColor::Gray
|
||||
) {
|
||||
@ -5060,7 +5060,7 @@ void Client::HandleLDoNOpen(NPC *target)
|
||||
return;
|
||||
}
|
||||
|
||||
if (target->GetSpecialAbility(IMMUNE_OPEN))
|
||||
if (target->GetSpecialAbility(SpecialAbility::OpenImmunity))
|
||||
{
|
||||
LogDebug("[{}] tried to open [{}] but it was immune", GetName(), target->GetName());
|
||||
return;
|
||||
|
||||
@ -5807,7 +5807,7 @@ void Client::Handle_OP_DeleteItem(const EQApplicationPacket *app)
|
||||
RecordPlayerEventLog(PlayerEvent::ITEM_DESTROY, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeleteItemInInventory(alc->from_slot, 1);
|
||||
}
|
||||
|
||||
@ -11536,8 +11536,8 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
entity_list.MessageCloseString(this, false, 200, 10, STRING_FEIGNFAILED, mypet->GetCleanName());
|
||||
}
|
||||
else {
|
||||
bool immune_aggro = GetSpecialAbility(IMMUNE_AGGRO);
|
||||
mypet->SetSpecialAbility(IMMUNE_AGGRO, 1);
|
||||
bool has_aggro_immunity = GetSpecialAbility(SpecialAbility::AggroImmunity);
|
||||
mypet->SetSpecialAbility(SpecialAbility::AggroImmunity, 1);
|
||||
mypet->WipeHateList();
|
||||
mypet->SetPetOrder(SPO_FeignDeath);
|
||||
mypet->SetRunAnimSpeed(0);
|
||||
@ -11549,8 +11549,8 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
mypet->InterruptSpell();
|
||||
}
|
||||
|
||||
if (!immune_aggro) {
|
||||
mypet->SetSpecialAbility(IMMUNE_AGGRO, 0);
|
||||
if (!has_aggro_immunity) {
|
||||
mypet->SetSpecialAbility(SpecialAbility::AggroImmunity, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1544,7 +1544,7 @@ void EntityList::RemoveFromTargetsFadingMemories(Mob *spell_target, bool RemoveF
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mob->GetSpecialAbility(IMMUNE_FADING_MEMORIES)) {
|
||||
if (mob->GetSpecialAbility(SpecialAbility::MemoryFadeImmunity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3638,7 +3638,7 @@ void EntityList::ClearFeignAggro(Mob *targ)
|
||||
while (it != npc_list.end()) {
|
||||
// add Feign Memory check because sometimes weird stuff happens
|
||||
if (it->second->CheckAggro(targ) || (targ->IsClient() && it->second->IsOnFeignMemory(targ))) {
|
||||
if (it->second->GetSpecialAbility(IMMUNE_FEIGN_DEATH)) {
|
||||
if (it->second->GetSpecialAbility(SpecialAbility::FeignDeathImmunity)) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
@ -3667,7 +3667,7 @@ void EntityList::ClearFeignAggro(Mob *targ)
|
||||
|
||||
it->second->RemoveFromHateList(targ);
|
||||
|
||||
if (it->second->GetSpecialAbility(SPECATK_RAMPAGE)) {
|
||||
if (it->second->GetSpecialAbility(SpecialAbility::Rampage)) {
|
||||
it->second->RemoveFromRampageList(targ, true);
|
||||
}
|
||||
|
||||
@ -4384,10 +4384,10 @@ void EntityList::AddTempPetsToHateList(Mob *owner, Mob* other, bool bFrenzy)
|
||||
if (n && n->GetSwarmInfo()) {
|
||||
if (n->GetSwarmInfo()->owner_id == owner->GetID()) {
|
||||
if (
|
||||
!n->GetSpecialAbility(IMMUNE_AGGRO) &&
|
||||
!(other->IsBot() && n->GetSpecialAbility(IMMUNE_AGGRO_BOT)) &&
|
||||
!(other->IsClient() && n->GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) &&
|
||||
!(other->IsNPC() && n->GetSpecialAbility(IMMUNE_AGGRO_NPC))
|
||||
!n->GetSpecialAbility(SpecialAbility::AggroImmunity) &&
|
||||
!(other->IsBot() && n->GetSpecialAbility(SpecialAbility::BotAggroImmunity)) &&
|
||||
!(other->IsClient() && n->GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) &&
|
||||
!(other->IsNPC() && n->GetSpecialAbility(SpecialAbility::NPCAggroImmunity))
|
||||
) {
|
||||
n->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
}
|
||||
@ -4411,10 +4411,10 @@ void EntityList::AddTempPetsToHateListOnOwnerDamage(Mob *owner, Mob* attacker, i
|
||||
attacker &&
|
||||
attacker != n &&
|
||||
!n->IsEngaged() &&
|
||||
!n->GetSpecialAbility(IMMUNE_AGGRO) &&
|
||||
!(attacker->IsBot() && n->GetSpecialAbility(IMMUNE_AGGRO_BOT)) &&
|
||||
!(attacker->IsClient() && n->GetSpecialAbility(IMMUNE_AGGRO_CLIENT)) &&
|
||||
!(attacker->IsNPC() && n->GetSpecialAbility(IMMUNE_AGGRO_NPC)) &&
|
||||
!n->GetSpecialAbility(SpecialAbility::AggroImmunity) &&
|
||||
!(attacker->IsBot() && n->GetSpecialAbility(SpecialAbility::BotAggroImmunity)) &&
|
||||
!(attacker->IsClient() && n->GetSpecialAbility(SpecialAbility::ClientAggroImmunity)) &&
|
||||
!(attacker->IsNPC() && n->GetSpecialAbility(SpecialAbility::NPCAggroImmunity)) &&
|
||||
!attacker->IsTrap() &&
|
||||
!attacker->IsCorpse()
|
||||
) {
|
||||
|
||||
@ -44,7 +44,7 @@ void Mob::CheckFlee()
|
||||
}
|
||||
|
||||
//dont bother if we are immune to fleeing
|
||||
if (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) {
|
||||
if (GetSpecialAbility(SpecialAbility::FleeingImmunity) || spellbonuses.ImmuneToFlee) {
|
||||
LogFlee("Mob [{}] is immune to fleeing via special ability or spell bonus", GetCleanName());
|
||||
return;
|
||||
}
|
||||
@ -60,7 +60,7 @@ void Mob::CheckFlee()
|
||||
}
|
||||
|
||||
int hp_ratio = GetIntHPRatio();
|
||||
int flee_ratio = GetSpecialAbility(FLEE_PERCENT); // if a special flee_percent exists
|
||||
int flee_ratio = GetSpecialAbility(SpecialAbility::FleePercent); // if a special SpecialAbility::FleePercent exists
|
||||
Mob *hate_top = GetHateTop();
|
||||
|
||||
LogFlee("Mob [{}] hp_ratio [{}] flee_ratio [{}]", GetCleanName(), hp_ratio, flee_ratio);
|
||||
@ -137,10 +137,10 @@ void Mob::CheckFlee()
|
||||
);
|
||||
|
||||
// If we got here we are allowed to roll on flee chance if there is not other hated NPC's in the area.
|
||||
// ALWAYS_FLEE, skip roll
|
||||
// SpecialAbility::AlwaysFlee, skip roll
|
||||
// if FleeIfNotAlone is true, we skip alone check
|
||||
// roll chance
|
||||
if (GetSpecialAbility(ALWAYS_FLEE) ||
|
||||
if (GetSpecialAbility(SpecialAbility::AlwaysFlee) ||
|
||||
((RuleB(Combat, FleeIfNotAlone) || entity_list.GetHatedCount(hate_top, this, true) == 0) &&
|
||||
zone->random.Roll(flee_chance))) {
|
||||
|
||||
@ -164,14 +164,14 @@ void Mob::ProcessFlee()
|
||||
|
||||
//Stop fleeing if effect is applied after they start to run.
|
||||
//When ImmuneToFlee effect fades it will turn fear back on and check if it can still flee.
|
||||
if (flee_mode && (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) &&
|
||||
if (flee_mode && (GetSpecialAbility(SpecialAbility::FleeingImmunity) || spellbonuses.ImmuneToFlee) &&
|
||||
!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
|
||||
currently_fleeing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int hpratio = GetIntHPRatio();
|
||||
int fleeratio = GetSpecialAbility(FLEE_PERCENT); // if a special flee_percent exists
|
||||
int fleeratio = GetSpecialAbility(SpecialAbility::FleePercent); // if a special SpecialAbility::FleePercent exists
|
||||
Mob *hate_top = GetHateTop();
|
||||
|
||||
// If no special flee_percent check for Gray or Other con rates
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "find/recipe.cpp"
|
||||
#include "find/skill.cpp"
|
||||
#include "find/spell.cpp"
|
||||
#include "find/special_ability.cpp"
|
||||
#include "find/task.cpp"
|
||||
#include "find/zone.cpp"
|
||||
|
||||
@ -48,6 +49,7 @@ void command_find(Client *c, const Seperator *sep)
|
||||
Cmd{.cmd = "race", .u = "race [Search Criteria]", .fn = FindRace, .a = {"#findrace"}},
|
||||
Cmd{.cmd = "recipe", .u = "recipe [Search Criteria]", .fn = FindRecipe, .a = {"#findrecipe"}},
|
||||
Cmd{.cmd = "skill", .u = "skill [Search Criteria]", .fn = FindSkill, .a = {"#findskill"}},
|
||||
Cmd{.cmd = "special_ability", .u = "special_ability [Search Criteria]", .fn = FindSpecialAbility, .a = {"#fsa", "#findspecialability"}},
|
||||
Cmd{.cmd = "spell", .u = "spell [Search Criteria]", .fn = FindSpell, .a = {"#fs", "#findspell"}},
|
||||
Cmd{.cmd = "task", .u = "task [Search Criteria]", .fn = FindTask, .a = {"#findtask"}},
|
||||
Cmd{.cmd = "zone", .u = "zone [Search Criteria]", .fn = FindZone, .a = {"#fz", "#findzone"}},
|
||||
|
||||
62
zone/gm_commands/find/special_ability.cpp
Normal file
62
zone/gm_commands/find/special_ability.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void FindSpecialAbility(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->IsNumber(2)) {
|
||||
const int ability_id = Strings::ToInt(sep->arg[2]);
|
||||
const std::string& ability_name = SpecialAbility::GetName(ability_id);
|
||||
if (Strings::EqualFold(ability_name, "UNKNOWN SPECIAL ABILITY")) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Ability ID {} does not exist.",
|
||||
ability_id
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Ability {} | {}",
|
||||
ability_id,
|
||||
ability_name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& search_criteria = Strings::ToLower(sep->argplus[2]);
|
||||
|
||||
uint32 found_count = 0;
|
||||
|
||||
for (const auto& e : special_ability_names) {
|
||||
const std::string& ability_name_lower = Strings::ToLower(e.second);
|
||||
if (!Strings::Contains(ability_name_lower, search_criteria)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Ability {} | {}",
|
||||
e.first,
|
||||
e.second
|
||||
).c_str()
|
||||
);
|
||||
|
||||
found_count++;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} Abilit{} found matching '{}'.",
|
||||
found_count,
|
||||
found_count != 1 ? "ies" : "y",
|
||||
sep->argplus[2]
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@ -496,7 +496,7 @@ Mob *HateList::GetMobWithMostHateOnList(
|
||||
}
|
||||
|
||||
if (!is_top_client_type) {
|
||||
if (top_hate->GetSpecialAbility(ALLOW_TO_TANK)) {
|
||||
if (top_hate->GetSpecialAbility(SpecialAbility::AllowedToTank)) {
|
||||
is_top_client_type = true;
|
||||
top_client_type_in_range = top_hate;
|
||||
}
|
||||
|
||||
117
zone/lua_mob.cpp
117
zone/lua_mob.cpp
@ -3942,65 +3942,64 @@ luabind::scope lua_register_mob() {
|
||||
|
||||
luabind::scope lua_register_special_abilities() {
|
||||
return luabind::class_<SpecialAbilities>("SpecialAbility")
|
||||
|
||||
.enum_("constants")
|
||||
[(
|
||||
luabind::value("summon", static_cast<int>(SPECATK_SUMMON)),
|
||||
luabind::value("enrage", static_cast<int>(SPECATK_ENRAGE)),
|
||||
luabind::value("rampage", static_cast<int>(SPECATK_RAMPAGE)),
|
||||
luabind::value("area_rampage", static_cast<int>(SPECATK_AREA_RAMPAGE)),
|
||||
luabind::value("flurry", static_cast<int>(SPECATK_FLURRY)),
|
||||
luabind::value("triple_attack", static_cast<int>(SPECATK_TRIPLE)),
|
||||
luabind::value("quad_attack", static_cast<int>(SPECATK_QUAD)),
|
||||
luabind::value("innate_dual_wield", static_cast<int>(SPECATK_INNATE_DW)),
|
||||
luabind::value("bane_attack", static_cast<int>(SPECATK_BANE)),
|
||||
luabind::value("magical_attack", static_cast<int>(SPECATK_MAGICAL)),
|
||||
luabind::value("ranged_attack", static_cast<int>(SPECATK_RANGED_ATK)),
|
||||
luabind::value("unslowable", static_cast<int>(UNSLOWABLE)),
|
||||
luabind::value("unmezable", static_cast<int>(UNMEZABLE)),
|
||||
luabind::value("uncharmable", static_cast<int>(UNCHARMABLE)),
|
||||
luabind::value("unstunable", static_cast<int>(UNSTUNABLE)),
|
||||
luabind::value("unsnareable", static_cast<int>(UNSNAREABLE)),
|
||||
luabind::value("unfearable", static_cast<int>(UNFEARABLE)),
|
||||
luabind::value("undispellable", static_cast<int>(UNDISPELLABLE)),
|
||||
luabind::value("immune_melee", static_cast<int>(IMMUNE_MELEE)),
|
||||
luabind::value("immune_magic", static_cast<int>(IMMUNE_MAGIC)),
|
||||
luabind::value("immune_fleeing", static_cast<int>(IMMUNE_FLEEING)),
|
||||
luabind::value("immune_melee_except_bane", static_cast<int>(IMMUNE_MELEE_EXCEPT_BANE)),
|
||||
luabind::value("immune_melee_except_magical", static_cast<int>(IMMUNE_MELEE_NONMAGICAL)),
|
||||
luabind::value("immune_aggro", static_cast<int>(IMMUNE_AGGRO)),
|
||||
luabind::value("immune_aggro_on", static_cast<int>(IMMUNE_AGGRO_ON)),
|
||||
luabind::value("immune_casting_from_range", static_cast<int>(IMMUNE_CASTING_FROM_RANGE)),
|
||||
luabind::value("immune_feign_death", static_cast<int>(IMMUNE_FEIGN_DEATH)),
|
||||
luabind::value("immune_taunt", static_cast<int>(IMMUNE_TAUNT)),
|
||||
luabind::value("tunnelvision", static_cast<int>(NPC_TUNNELVISION)),
|
||||
luabind::value("dont_buff_friends", static_cast<int>(NPC_NO_BUFFHEAL_FRIENDS)),
|
||||
luabind::value("immune_pacify", static_cast<int>(IMMUNE_PACIFY)),
|
||||
luabind::value("leash", static_cast<int>(LEASH)),
|
||||
luabind::value("tether", static_cast<int>(TETHER)),
|
||||
luabind::value("destructible_object", static_cast<int>(DESTRUCTIBLE_OBJECT)),
|
||||
luabind::value("no_harm_from_client", static_cast<int>(NO_HARM_FROM_CLIENT)),
|
||||
luabind::value("always_flee", static_cast<int>(ALWAYS_FLEE)),
|
||||
luabind::value("flee_percent", static_cast<int>(FLEE_PERCENT)),
|
||||
luabind::value("allow_beneficial", static_cast<int>(ALLOW_BENEFICIAL)),
|
||||
luabind::value("disable_melee", static_cast<int>(DISABLE_MELEE)),
|
||||
luabind::value("npc_chase_distance", static_cast<int>(NPC_CHASE_DISTANCE)),
|
||||
luabind::value("allow_to_tank", static_cast<int>(ALLOW_TO_TANK)),
|
||||
luabind::value("ignore_root_aggro_rules", static_cast<int>(IGNORE_ROOT_AGGRO_RULES)),
|
||||
luabind::value("casting_resist_diff", static_cast<int>(CASTING_RESIST_DIFF)),
|
||||
luabind::value("counter_avoid_damage", static_cast<int>(COUNTER_AVOID_DAMAGE)),
|
||||
luabind::value("immune_ranged_attacks", static_cast<int>(IMMUNE_RANGED_ATTACKS)),
|
||||
luabind::value("immune_damage_client", static_cast<int>(IMMUNE_DAMAGE_CLIENT)),
|
||||
luabind::value("immune_damage_npc", static_cast<int>(IMMUNE_DAMAGE_NPC)),
|
||||
luabind::value("immune_aggro_client", static_cast<int>(IMMUNE_AGGRO_CLIENT)),
|
||||
luabind::value("immune_aggro_npc", static_cast<int>(IMMUNE_AGGRO_NPC)),
|
||||
luabind::value("modify_avoid_damage", static_cast<int>(MODIFY_AVOID_DAMAGE)),
|
||||
luabind::value("immune_open", static_cast<int>(IMMUNE_OPEN)),
|
||||
luabind::value("immune_assassinate", static_cast<int>(IMMUNE_ASSASSINATE)),
|
||||
luabind::value("immune_headshot", static_cast<int>(IMMUNE_HEADSHOT)),
|
||||
luabind::value("immune_aggro_bot", static_cast<int>(IMMUNE_AGGRO_BOT)),
|
||||
luabind::value("immune_damage_bot", static_cast<int>(IMMUNE_DAMAGE_BOT))
|
||||
)];
|
||||
.enum_("constants")
|
||||
[(
|
||||
luabind::value("summon", SpecialAbility::Summon),
|
||||
luabind::value("enrage", SpecialAbility::Enrage),
|
||||
luabind::value("rampage", SpecialAbility::Rampage),
|
||||
luabind::value("area_rampage", SpecialAbility::AreaRampage),
|
||||
luabind::value("flurry", SpecialAbility::Flurry),
|
||||
luabind::value("triple_attack", SpecialAbility::TripleAttack),
|
||||
luabind::value("quad_attack", SpecialAbility::QuadrupleAttack),
|
||||
luabind::value("innate_dual_wield", SpecialAbility::DualWield),
|
||||
luabind::value("bane_attack", SpecialAbility::BaneAttack),
|
||||
luabind::value("magical_attack", SpecialAbility::MagicalAttack),
|
||||
luabind::value("ranged_attack", SpecialAbility::RangedAttack),
|
||||
luabind::value("unslowable", SpecialAbility::SlowImmunity),
|
||||
luabind::value("unmezable", SpecialAbility::MesmerizeImmunity),
|
||||
luabind::value("uncharmable", SpecialAbility::CharmImmunity),
|
||||
luabind::value("unstunable", SpecialAbility::StunImmunity),
|
||||
luabind::value("unsnareable", SpecialAbility::SnareImmunity),
|
||||
luabind::value("unfearable", SpecialAbility::FearImmunity),
|
||||
luabind::value("undispellable", SpecialAbility::DispellImmunity),
|
||||
luabind::value("immune_melee", SpecialAbility::MeleeImmunity),
|
||||
luabind::value("immune_magic", SpecialAbility::MagicImmunity),
|
||||
luabind::value("immune_fleeing", SpecialAbility::FleeingImmunity),
|
||||
luabind::value("immune_melee_except_bane", SpecialAbility::MeleeImmunityExceptBane),
|
||||
luabind::value("immune_melee_except_magical", SpecialAbility::MeleeImmunityExceptMagical),
|
||||
luabind::value("immune_aggro", SpecialAbility::AggroImmunity),
|
||||
luabind::value("immune_aggro_on", SpecialAbility::BeingAggroImmunity),
|
||||
luabind::value("immune_casting_from_range", SpecialAbility::CastingFromRangeImmunity),
|
||||
luabind::value("immune_feign_death", SpecialAbility::FeignDeathImmunity),
|
||||
luabind::value("immune_taunt", SpecialAbility::TauntImmunity),
|
||||
luabind::value("tunnelvision", SpecialAbility::TunnelVision),
|
||||
luabind::value("dont_buff_friends", SpecialAbility::NoBuffHealFriends),
|
||||
luabind::value("immune_pacify", SpecialAbility::PacifyImmunity),
|
||||
luabind::value("leash", SpecialAbility::Leash),
|
||||
luabind::value("tether", SpecialAbility::Tether),
|
||||
luabind::value("destructible_object", SpecialAbility::DestructibleObject),
|
||||
luabind::value("no_harm_from_client", SpecialAbility::HarmFromClientImmunity),
|
||||
luabind::value("always_flee", SpecialAbility::AlwaysFlee),
|
||||
luabind::value("flee_percent", SpecialAbility::FleePercent),
|
||||
luabind::value("allow_beneficial", SpecialAbility::AllowBeneficial),
|
||||
luabind::value("disable_melee", SpecialAbility::DisableMelee),
|
||||
luabind::value("npc_chase_distance", SpecialAbility::NPCChaseDistance),
|
||||
luabind::value("allow_to_tank", SpecialAbility::AllowedToTank),
|
||||
luabind::value("ignore_root_aggro_rules", SpecialAbility::IgnoreRootAggroRules),
|
||||
luabind::value("casting_resist_diff", SpecialAbility::CastingResistDifficulty),
|
||||
luabind::value("counter_avoid_damage", SpecialAbility::CounterAvoidDamage),
|
||||
luabind::value("immune_ranged_attacks", SpecialAbility::RangedAttackImmunity),
|
||||
luabind::value("immune_damage_client", SpecialAbility::ClientDamageImmunity),
|
||||
luabind::value("immune_damage_npc", SpecialAbility::NPCDamageImmunity),
|
||||
luabind::value("immune_aggro_client", SpecialAbility::ClientAggroImmunity),
|
||||
luabind::value("immune_aggro_npc", SpecialAbility::NPCAggroImmunity),
|
||||
luabind::value("modify_avoid_damage", SpecialAbility::ModifyAvoidDamage),
|
||||
luabind::value("immune_open", SpecialAbility::OpenImmunity),
|
||||
luabind::value("immune_assassinate", SpecialAbility::AssassinateImmunity),
|
||||
luabind::value("immune_headshot", SpecialAbility::HeadshotImmunity),
|
||||
luabind::value("immune_aggro_bot", SpecialAbility::BotAggroImmunity),
|
||||
luabind::value("immune_damage_bot", SpecialAbility::BotDamageImmunity)
|
||||
)];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -1191,13 +1191,13 @@ void Merc::AI_Process() {
|
||||
Attack(GetTarget(), EQ::invslot::slotPrimary, true);
|
||||
}
|
||||
|
||||
if(GetOwner() && GetTarget() && GetSpecialAbility(SPECATK_TRIPLE)) {
|
||||
if(GetOwner() && GetTarget() && GetSpecialAbility(SpecialAbility::TripleAttack)) {
|
||||
tripleSuccess = true;
|
||||
Attack(GetTarget(), EQ::invslot::slotPrimary, true);
|
||||
}
|
||||
|
||||
//quad attack, does this belong here??
|
||||
if(GetOwner() && GetTarget() && GetSpecialAbility(SPECATK_QUAD)) {
|
||||
if(GetOwner() && GetTarget() && GetSpecialAbility(SpecialAbility::QuadrupleAttack)) {
|
||||
Attack(GetTarget(), EQ::invslot::slotPrimary, true);
|
||||
}
|
||||
}
|
||||
@ -1888,7 +1888,7 @@ bool Merc::AICastSpell(int8 iChance, uint32 iSpellTypes) {
|
||||
|
||||
selectedMercSpell = GetBestMercSpellForAENuke(this, tar);
|
||||
|
||||
if(selectedMercSpell.spellid == 0 && !tar->GetSpecialAbility(UNSTUNABLE) && !tar->IsStunned()) {
|
||||
if(selectedMercSpell.spellid == 0 && !tar->GetSpecialAbility(SpecialAbility::StunImmunity) && !tar->IsStunned()) {
|
||||
uint8 stunChance = 15;
|
||||
if(zone->random.Roll(stunChance)) {
|
||||
selectedMercSpell = GetBestMercSpellForStun(this);
|
||||
|
||||
50
zone/mob.cpp
50
zone/mob.cpp
@ -4803,7 +4803,7 @@ bool Mob::HateSummon() {
|
||||
if (IsCharmed())
|
||||
return false;
|
||||
|
||||
int summon_level = GetSpecialAbility(SPECATK_SUMMON);
|
||||
int summon_level = GetSpecialAbility(SpecialAbility::Summon);
|
||||
if(summon_level == 1 || summon_level == 2) {
|
||||
if(!GetTarget()) {
|
||||
return false;
|
||||
@ -4814,19 +4814,19 @@ bool Mob::HateSummon() {
|
||||
}
|
||||
|
||||
// validate hp
|
||||
int hp_ratio = GetSpecialAbilityParam(SPECATK_SUMMON, 1);
|
||||
int hp_ratio = GetSpecialAbilityParam(SpecialAbility::Summon, 1);
|
||||
hp_ratio = hp_ratio > 0 ? hp_ratio : 97;
|
||||
if(GetHPRatio() > static_cast<float>(hp_ratio)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// now validate the timer
|
||||
int summon_timer_duration = GetSpecialAbilityParam(SPECATK_SUMMON, 0);
|
||||
int summon_timer_duration = GetSpecialAbilityParam(SpecialAbility::Summon, 0);
|
||||
summon_timer_duration = summon_timer_duration > 0 ? summon_timer_duration : 6000;
|
||||
Timer *timer = GetSpecialAbilityTimer(SPECATK_SUMMON);
|
||||
Timer *timer = GetSpecialAbilityTimer(SpecialAbility::Summon);
|
||||
if (!timer)
|
||||
{
|
||||
StartSpecialAbilityTimer(SPECATK_SUMMON, summon_timer_duration);
|
||||
StartSpecialAbilityTimer(SpecialAbility::Summon, summon_timer_duration);
|
||||
} else {
|
||||
if(!timer->Check())
|
||||
return false;
|
||||
@ -5261,20 +5261,20 @@ void Mob::ExecWeaponProc(const EQ::ItemInstance* inst, uint16 spell_id, Mob* on,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsValidSpell(spell_id) || on->GetSpecialAbility(NO_HARM_FROM_CLIENT)) {
|
||||
if (!IsValidSpell(spell_id) || on->GetSpecialAbility(SpecialAbility::HarmFromClientImmunity)) {
|
||||
//This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging.
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsBot() && on->GetSpecialAbility(IMMUNE_DAMAGE_BOT)) {
|
||||
if (IsBot() && on->GetSpecialAbility(SpecialAbility::BotDamageImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsClient() && on->GetSpecialAbility(IMMUNE_DAMAGE_CLIENT)) {
|
||||
if (IsClient() && on->GetSpecialAbility(SpecialAbility::ClientDamageImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsNPC() && on->GetSpecialAbility(IMMUNE_DAMAGE_NPC)) {
|
||||
if (IsNPC() && on->GetSpecialAbility(SpecialAbility::NPCDamageImmunity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6148,7 +6148,7 @@ void Mob::SetBottomRampageList()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mob->GetSpecialAbility(SPECATK_RAMPAGE)) {
|
||||
if (!mob->GetSpecialAbility(SpecialAbility::Rampage)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -6175,7 +6175,7 @@ void Mob::SetTopRampageList()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mob->GetSpecialAbility(SPECATK_RAMPAGE)) {
|
||||
if (!mob->GetSpecialAbility(SpecialAbility::Rampage)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -7501,7 +7501,7 @@ bool Mob::HasSpellEffect(int effect_id)
|
||||
|
||||
int Mob::GetSpecialAbility(int ability)
|
||||
{
|
||||
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if (ability >= SpecialAbility::Max || ability < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7510,7 +7510,7 @@ int Mob::GetSpecialAbility(int ability)
|
||||
|
||||
bool Mob::HasSpecialAbilities()
|
||||
{
|
||||
for (int i = 0; i < MAX_SPECIAL_ATTACK; ++i) {
|
||||
for (int i = 0; i < SpecialAbility::Max; ++i) {
|
||||
if (GetSpecialAbility(i)) {
|
||||
return true;
|
||||
}
|
||||
@ -7520,7 +7520,7 @@ bool Mob::HasSpecialAbilities()
|
||||
}
|
||||
|
||||
int Mob::GetSpecialAbilityParam(int ability, int param) {
|
||||
if(param >= MAX_SPECIAL_ATTACK_PARAMS || param < 0 || ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if(param >= SpecialAbility::MaxParameters || param < 0 || ability >= SpecialAbility::Max || ability < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7528,7 +7528,7 @@ int Mob::GetSpecialAbilityParam(int ability, int param) {
|
||||
}
|
||||
|
||||
void Mob::SetSpecialAbility(int ability, int level) {
|
||||
if(ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if(ability >= SpecialAbility::Max || ability < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7536,7 +7536,7 @@ void Mob::SetSpecialAbility(int ability, int level) {
|
||||
}
|
||||
|
||||
void Mob::SetSpecialAbilityParam(int ability, int param, int value) {
|
||||
if(param >= MAX_SPECIAL_ATTACK_PARAMS || param < 0 || ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if(param >= SpecialAbility::MaxParameters || param < 0 || ability >= SpecialAbility::Max || ability < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7544,7 +7544,7 @@ void Mob::SetSpecialAbilityParam(int ability, int param, int value) {
|
||||
}
|
||||
|
||||
void Mob::StartSpecialAbilityTimer(int ability, uint32 time) {
|
||||
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if (ability >= SpecialAbility::Max || ability < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7557,7 +7557,7 @@ void Mob::StartSpecialAbilityTimer(int ability, uint32 time) {
|
||||
}
|
||||
|
||||
void Mob::StopSpecialAbilityTimer(int ability) {
|
||||
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if (ability >= SpecialAbility::Max || ability < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7565,7 +7565,7 @@ void Mob::StopSpecialAbilityTimer(int ability) {
|
||||
}
|
||||
|
||||
Timer *Mob::GetSpecialAbilityTimer(int ability) {
|
||||
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
|
||||
if (ability >= SpecialAbility::Max || ability < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -7573,10 +7573,10 @@ Timer *Mob::GetSpecialAbilityTimer(int ability) {
|
||||
}
|
||||
|
||||
void Mob::ClearSpecialAbilities() {
|
||||
for(int a = 0; a < MAX_SPECIAL_ATTACK; ++a) {
|
||||
for(int a = 0; a < SpecialAbility::Max; ++a) {
|
||||
SpecialAbilities[a].level = 0;
|
||||
safe_delete(SpecialAbilities[a].timer);
|
||||
for(int p = 0; p < MAX_SPECIAL_ATTACK_PARAMS; ++p) {
|
||||
for(int p = 0; p < SpecialAbility::MaxParameters; ++p) {
|
||||
SpecialAbilities[a].params[p] = 0;
|
||||
}
|
||||
}
|
||||
@ -7599,12 +7599,12 @@ void Mob::ProcessSpecialAbilities(const std::string &str) {
|
||||
SetSpecialAbility(ability_id, value);
|
||||
|
||||
switch (ability_id) {
|
||||
case SPECATK_QUAD:
|
||||
case SpecialAbility::QuadrupleAttack:
|
||||
if (value > 0) {
|
||||
SetSpecialAbility(SPECATK_TRIPLE, 1);
|
||||
SetSpecialAbility(SpecialAbility::TripleAttack, 1);
|
||||
}
|
||||
break;
|
||||
case DESTRUCTIBLE_OBJECT:
|
||||
case SpecialAbility::DestructibleObject:
|
||||
if (value == 0) {
|
||||
SetDestructibleObject(false);
|
||||
} else {
|
||||
@ -7616,7 +7616,7 @@ void Mob::ProcessSpecialAbilities(const std::string &str) {
|
||||
}
|
||||
|
||||
for (size_t i = 2, param_id = 0; i < sub_sp.size(); ++i, ++param_id) {
|
||||
if (param_id >= MAX_SPECIAL_ATTACK_PARAMS) {
|
||||
if (param_id >= SpecialAbility::MaxParameters) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
22
zone/mob.h
22
zone/mob.h
@ -41,8 +41,6 @@
|
||||
|
||||
char* strn0cpy(char* dest, const char* source, uint32 size);
|
||||
|
||||
#define MAX_SPECIAL_ATTACK_PARAMS 9
|
||||
|
||||
class Client;
|
||||
class EQApplicationPacket;
|
||||
class Group;
|
||||
@ -102,22 +100,22 @@ public:
|
||||
CLIENT_KICKED, DISCONNECTED, CLIENT_ERROR, CLIENT_CONNECTINGALL };
|
||||
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard, SPO_FeignDeath };
|
||||
|
||||
struct SpecialAbility {
|
||||
SpecialAbility() {
|
||||
struct MobSpecialAbility {
|
||||
MobSpecialAbility() {
|
||||
level = 0;
|
||||
timer = nullptr;
|
||||
for(int i = 0; i < MAX_SPECIAL_ATTACK_PARAMS; ++i) {
|
||||
for (int i = 0; i < SpecialAbility::MaxParameters; ++i) {
|
||||
params[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~SpecialAbility() {
|
||||
~MobSpecialAbility() {
|
||||
safe_delete(timer);
|
||||
}
|
||||
|
||||
int level;
|
||||
Timer *timer;
|
||||
int params[MAX_SPECIAL_ATTACK_PARAMS];
|
||||
int params[SpecialAbility::MaxParameters];
|
||||
};
|
||||
|
||||
struct AuraInfo {
|
||||
@ -1026,15 +1024,15 @@ public:
|
||||
int16 GetModVulnerability(const uint8 resist);
|
||||
|
||||
void SetAllowBeneficial(bool value) { m_AllowBeneficial = value; }
|
||||
bool GetAllowBeneficial() { if (m_AllowBeneficial || GetSpecialAbility(ALLOW_BENEFICIAL)){return true;} return false; }
|
||||
bool GetAllowBeneficial() { if (m_AllowBeneficial || GetSpecialAbility(SpecialAbility::AllowBeneficial)){return true;} return false; }
|
||||
void SetDisableMelee(bool value) { m_DisableMelee = value; }
|
||||
bool IsMeleeDisabled() { if (m_DisableMelee || GetSpecialAbility(DISABLE_MELEE)){return true;} return false; }
|
||||
bool IsMeleeDisabled() { if (m_DisableMelee || GetSpecialAbility(SpecialAbility::DisableMelee)){return true;} return false; }
|
||||
|
||||
bool IsOffHandAtk() const { return offhand; }
|
||||
inline void OffHandAtk(bool val) { offhand = val; }
|
||||
|
||||
void SetFlurryChance(uint8 value) { SetSpecialAbilityParam(SPECATK_FLURRY, 0, value); }
|
||||
uint8 GetFlurryChance() { return GetSpecialAbilityParam(SPECATK_FLURRY, 0); }
|
||||
void SetFlurryChance(uint8 value) { SetSpecialAbilityParam(SpecialAbility::Flurry, 0, value); }
|
||||
uint8 GetFlurryChance() { return GetSpecialAbilityParam(SpecialAbility::Flurry, 0); }
|
||||
|
||||
static uint32 GetAppearanceValue(EmuAppearance in_appearance);
|
||||
void SendAppearancePacket(uint32 type, uint32 value, bool whole_zone = true, bool ignore_self = false, Client* target = nullptr);
|
||||
@ -1870,7 +1868,7 @@ protected:
|
||||
void InsertQuestGlobal(int charid, int npcid, int zoneid, const char *name, const char *value, int expdate);
|
||||
uint32 emoteid;
|
||||
|
||||
SpecialAbility SpecialAbilities[MAX_SPECIAL_ATTACK];
|
||||
MobSpecialAbility SpecialAbilities[SpecialAbility::Max];
|
||||
bool bEnraged;
|
||||
bool destructibleobject;
|
||||
|
||||
|
||||
@ -570,7 +570,7 @@ void Mob::AI_ShutDown() {
|
||||
viral_timer.Disable();
|
||||
flee_timer.Disable();
|
||||
|
||||
for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) {
|
||||
for (int sat = 0; sat < SpecialAbility::Max; ++sat) {
|
||||
if (SpecialAbilities[sat].timer)
|
||||
SpecialAbilities[sat].timer->Disable();
|
||||
}
|
||||
@ -1062,7 +1062,7 @@ void Mob::AI_Process() {
|
||||
}
|
||||
// we are prevented from getting here if we are blind and don't have a target in range
|
||||
// from above, so no extra blind checks needed
|
||||
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
|
||||
if ((IsRooted() && !GetSpecialAbility(SpecialAbility::IgnoreRootAggroRules)) || IsBlind())
|
||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||
else {
|
||||
if (AI_target_check_timer->Check()) {
|
||||
@ -1125,16 +1125,16 @@ void Mob::AI_Process() {
|
||||
}
|
||||
|
||||
auto npcSpawnPoint = CastToNPC()->GetSpawnPoint();
|
||||
if (GetSpecialAbility(TETHER)) {
|
||||
float tether_range = static_cast<float>(GetSpecialAbilityParam(TETHER, 0));
|
||||
if (GetSpecialAbility(SpecialAbility::Tether)) {
|
||||
float tether_range = static_cast<float>(GetSpecialAbilityParam(SpecialAbility::Tether, 0));
|
||||
tether_range = tether_range > 0.0f ? tether_range * tether_range : pAggroRange * pAggroRange;
|
||||
|
||||
if (DistanceSquaredNoZ(m_Position, npcSpawnPoint) > tether_range) {
|
||||
GMMove(npcSpawnPoint.x, npcSpawnPoint.y, npcSpawnPoint.z, npcSpawnPoint.w);
|
||||
}
|
||||
}
|
||||
else if (GetSpecialAbility(LEASH)) {
|
||||
float leash_range = static_cast<float>(GetSpecialAbilityParam(LEASH, 0));
|
||||
else if (GetSpecialAbility(SpecialAbility::Leash)) {
|
||||
float leash_range = static_cast<float>(GetSpecialAbilityParam(SpecialAbility::Leash, 0));
|
||||
leash_range = leash_range > 0.0f ? leash_range * leash_range : pAggroRange * pAggroRange;
|
||||
|
||||
if (DistanceSquaredNoZ(m_Position, npcSpawnPoint) > leash_range) {
|
||||
@ -1169,33 +1169,33 @@ void Mob::AI_Process() {
|
||||
TriggerDefensiveProcs(target, EQ::invslot::slotPrimary, false);
|
||||
|
||||
bool specialed = false; // NPCs can only do one of these a round
|
||||
if (GetSpecialAbility(SPECATK_FLURRY)) {
|
||||
int flurry_chance = GetSpecialAbilityParam(SPECATK_FLURRY, 0);
|
||||
if (GetSpecialAbility(SpecialAbility::Flurry)) {
|
||||
int flurry_chance = GetSpecialAbilityParam(SpecialAbility::Flurry, 0);
|
||||
flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance);
|
||||
|
||||
if (zone->random.Roll(flurry_chance)) {
|
||||
ExtraAttackOptions opts;
|
||||
int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2);
|
||||
int cur = GetSpecialAbilityParam(SpecialAbility::Flurry, 2);
|
||||
if (cur > 0)
|
||||
opts.damage_percent = cur / 100.0f;
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 3);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Flurry, 3);
|
||||
if (cur > 0)
|
||||
opts.damage_flat = cur;
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 4);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Flurry, 4);
|
||||
if (cur > 0)
|
||||
opts.armor_pen_percent = cur / 100.0f;
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 5);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Flurry, 5);
|
||||
if (cur > 0)
|
||||
opts.armor_pen_flat = cur;
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 6);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Flurry, 6);
|
||||
if (cur > 0)
|
||||
opts.crit_percent = cur / 100.0f;
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_FLURRY, 7);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Flurry, 7);
|
||||
if (cur > 0)
|
||||
opts.crit_flat = cur;
|
||||
|
||||
@ -1227,32 +1227,32 @@ void Mob::AI_Process() {
|
||||
}
|
||||
|
||||
|
||||
if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed) {
|
||||
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
|
||||
if (GetSpecialAbility(SpecialAbility::Rampage) && !specialed) {
|
||||
int rampage_chance = GetSpecialAbilityParam(SpecialAbility::Rampage, 0);
|
||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||
if (zone->random.Roll(rampage_chance)) {
|
||||
ExtraAttackOptions opts;
|
||||
int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3);
|
||||
int cur = GetSpecialAbilityParam(SpecialAbility::Rampage, 3);
|
||||
if (cur > 0) {
|
||||
opts.damage_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 4);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Rampage, 4);
|
||||
if (cur > 0) {
|
||||
opts.armor_pen_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 5);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Rampage, 5);
|
||||
if (cur > 0) {
|
||||
opts.armor_pen_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 6);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Rampage, 6);
|
||||
if (cur > 0) {
|
||||
opts.crit_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 7);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::Rampage, 7);
|
||||
if (cur > 0) {
|
||||
opts.crit_flat = cur;
|
||||
}
|
||||
@ -1269,37 +1269,37 @@ void Mob::AI_Process() {
|
||||
}
|
||||
}
|
||||
|
||||
if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed) {
|
||||
int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0);
|
||||
if (GetSpecialAbility(SpecialAbility::AreaRampage) && !specialed) {
|
||||
int rampage_chance = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 0);
|
||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||
if (zone->random.Roll(rampage_chance)) {
|
||||
ExtraAttackOptions opts;
|
||||
int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3);
|
||||
int cur = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 3);
|
||||
if (cur > 0) {
|
||||
opts.damage_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 4);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 4);
|
||||
if (cur > 0) {
|
||||
opts.armor_pen_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 5);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 5);
|
||||
if (cur > 0) {
|
||||
opts.armor_pen_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 6);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 6);
|
||||
if (cur > 0) {
|
||||
opts.crit_percent = cur / 100.0f;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 7);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 7);
|
||||
if (cur > 0) {
|
||||
opts.crit_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 8);
|
||||
cur = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 8);
|
||||
if (cur > 0) {
|
||||
opts.range_percent = cur;
|
||||
}
|
||||
@ -1328,7 +1328,7 @@ void Mob::AI_Process() {
|
||||
if (!HateSummon()) {
|
||||
|
||||
//could not summon them, check ranged...
|
||||
if (GetSpecialAbility(SPECATK_RANGED_ATK) || HasBowAndArrowEquipped()) {
|
||||
if (GetSpecialAbility(SpecialAbility::RangedAttack) || HasBowAndArrowEquipped()) {
|
||||
doranged = true;
|
||||
}
|
||||
|
||||
@ -1961,10 +1961,10 @@ void Mob::StartEnrage()
|
||||
if (bEnraged)
|
||||
return;
|
||||
|
||||
if(!GetSpecialAbility(SPECATK_ENRAGE))
|
||||
if(!GetSpecialAbility(SpecialAbility::Enrage))
|
||||
return;
|
||||
|
||||
int hp_ratio = GetSpecialAbilityParam(SPECATK_ENRAGE, 0);
|
||||
int hp_ratio = GetSpecialAbilityParam(SpecialAbility::Enrage, 0);
|
||||
hp_ratio = hp_ratio > 0 ? hp_ratio : RuleI(NPC, StartEnrageValue);
|
||||
if(GetHPRatio() > static_cast<float>(hp_ratio)) {
|
||||
return;
|
||||
@ -1975,13 +1975,13 @@ void Mob::StartEnrage()
|
||||
return;
|
||||
}
|
||||
|
||||
Timer *timer = GetSpecialAbilityTimer(SPECATK_ENRAGE);
|
||||
Timer *timer = GetSpecialAbilityTimer(SpecialAbility::Enrage);
|
||||
if (timer && !timer->Check())
|
||||
return;
|
||||
|
||||
int enraged_duration = GetSpecialAbilityParam(SPECATK_ENRAGE, 1);
|
||||
int enraged_duration = GetSpecialAbilityParam(SpecialAbility::Enrage, 1);
|
||||
enraged_duration = enraged_duration > 0 ? enraged_duration : EnragedDurationTimer;
|
||||
StartSpecialAbilityTimer(SPECATK_ENRAGE, enraged_duration);
|
||||
StartSpecialAbilityTimer(SpecialAbility::Enrage, enraged_duration);
|
||||
|
||||
// start the timer. need to call IsEnraged frequently since we dont have callback timers :-/
|
||||
bEnraged = true;
|
||||
@ -1990,13 +1990,13 @@ void Mob::StartEnrage()
|
||||
|
||||
void Mob::ProcessEnrage(){
|
||||
if(IsEnraged()){
|
||||
Timer *timer = GetSpecialAbilityTimer(SPECATK_ENRAGE);
|
||||
Timer *timer = GetSpecialAbilityTimer(SpecialAbility::Enrage);
|
||||
if(timer && timer->Check()){
|
||||
entity_list.MessageCloseString(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_END, GetCleanName());
|
||||
|
||||
int enraged_cooldown = GetSpecialAbilityParam(SPECATK_ENRAGE, 2);
|
||||
int enraged_cooldown = GetSpecialAbilityParam(SpecialAbility::Enrage, 2);
|
||||
enraged_cooldown = enraged_cooldown > 0 ? enraged_cooldown : EnragedTimer;
|
||||
StartSpecialAbilityTimer(SPECATK_ENRAGE, enraged_cooldown);
|
||||
StartSpecialAbilityTimer(SpecialAbility::Enrage, enraged_cooldown);
|
||||
bEnraged = false;
|
||||
}
|
||||
}
|
||||
@ -2032,7 +2032,7 @@ bool Mob::Flurry(ExtraAttackOptions *opts)
|
||||
target->GetCleanName());
|
||||
}
|
||||
|
||||
int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1);
|
||||
int num_attacks = GetSpecialAbilityParam(SpecialAbility::Flurry, 1);
|
||||
num_attacks = num_attacks > 0 ? num_attacks : RuleI(Combat, MaxFlurryHits);
|
||||
for (int i = 0; i < num_attacks; i++)
|
||||
Attack(target, EQ::invslot::slotPrimary, false, false, false, opts);
|
||||
@ -2046,7 +2046,7 @@ bool Mob::AddRampage(Mob *mob)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetSpecialAbility(SPECATK_RAMPAGE)) {
|
||||
if (!GetSpecialAbility(SpecialAbility::Rampage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2073,7 +2073,7 @@ void Mob::RemoveFromRampageList(Mob* mob, bool remove_feigned)
|
||||
|
||||
if (
|
||||
IsNPC() &&
|
||||
GetSpecialAbility(SPECATK_RAMPAGE) &&
|
||||
GetSpecialAbility(SpecialAbility::Rampage) &&
|
||||
(
|
||||
remove_feigned ||
|
||||
mob->IsNPC() ||
|
||||
@ -2100,7 +2100,7 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
|
||||
entity_list.MessageCloseString(this, true, 200, Chat::NPCRampage, NPC_RAMPAGE, GetCleanName());
|
||||
}
|
||||
|
||||
int rampage_targets = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1);
|
||||
int rampage_targets = GetSpecialAbilityParam(SpecialAbility::Rampage, 1);
|
||||
|
||||
if (rampage_targets == 0) { // if set to 0 or not set in the DB
|
||||
rampage_targets = RuleI(Combat, DefaultRampageTargets);
|
||||
@ -2173,7 +2173,7 @@ void Mob::AreaRampage(ExtraAttackOptions *opts)
|
||||
entity_list.MessageCloseString(this, true, 200, Chat::NPCRampage, AE_RAMPAGE, GetCleanName());
|
||||
}
|
||||
|
||||
int rampage_targets = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1);
|
||||
int rampage_targets = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 1);
|
||||
rampage_targets = rampage_targets > 0 ? rampage_targets : -1;
|
||||
m_specialattacks = eSpecialAttacks::AERampage;
|
||||
index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts);
|
||||
|
||||
282
zone/npc.cpp
282
zone/npc.cpp
@ -767,7 +767,7 @@ bool NPC::Process()
|
||||
ProcessEnrage();
|
||||
|
||||
/* Don't keep running the check every second if we don't have enrage */
|
||||
if (!GetSpecialAbility(SPECATK_ENRAGE)) {
|
||||
if (!GetSpecialAbility(SpecialAbility::Enrage)) {
|
||||
enraged_timer.Disable();
|
||||
}
|
||||
}
|
||||
@ -1220,7 +1220,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
e.walkspeed = n->GetWalkspeed();
|
||||
e.prim_melee_type = n->GetPrimSkill();
|
||||
e.sec_melee_type = n->GetSecSkill();
|
||||
|
||||
|
||||
e.bodytype = n->GetBodyType();
|
||||
e.npc_faction_id = n->GetNPCFactionID();
|
||||
e.aggroradius = n->GetAggroRange();
|
||||
@ -1235,7 +1235,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
e.WIS = n->GetWIS();
|
||||
e._INT = n->GetINT();
|
||||
e.CHA = n->GetCHA();
|
||||
|
||||
|
||||
e.PR = n->GetPR();
|
||||
e.MR = n->GetMR();
|
||||
e.DR = n->GetDR();
|
||||
@ -1255,7 +1255,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
e.healscale = n->GetHealScale();
|
||||
e.Avoidance = n->GetAvoidanceRating();
|
||||
e.heroic_strikethrough = n->GetHeroicStrikethrough();
|
||||
|
||||
|
||||
e.see_hide = n->SeeHide();
|
||||
e.see_improved_hide = n->SeeImprovedHide();
|
||||
e.see_invis = n->SeeInvisible();
|
||||
@ -1863,127 +1863,127 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem
|
||||
switch(*parse)
|
||||
{
|
||||
case 'E':
|
||||
SetSpecialAbility(SPECATK_ENRAGE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::Enrage, remove ? 0 : 1);
|
||||
break;
|
||||
case 'F':
|
||||
SetSpecialAbility(SPECATK_FLURRY, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::Flurry, remove ? 0 : 1);
|
||||
break;
|
||||
case 'R':
|
||||
SetSpecialAbility(SPECATK_RAMPAGE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::Rampage, remove ? 0 : 1);
|
||||
break;
|
||||
case 'r':
|
||||
SetSpecialAbility(SPECATK_AREA_RAMPAGE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::AreaRampage, remove ? 0 : 1);
|
||||
break;
|
||||
case 'S':
|
||||
if(remove) {
|
||||
SetSpecialAbility(SPECATK_SUMMON, 0);
|
||||
StopSpecialAbilityTimer(SPECATK_SUMMON);
|
||||
SetSpecialAbility(SpecialAbility::Summon, 0);
|
||||
StopSpecialAbilityTimer(SpecialAbility::Summon);
|
||||
} else {
|
||||
SetSpecialAbility(SPECATK_SUMMON, 1);
|
||||
SetSpecialAbility(SpecialAbility::Summon, 1);
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
SetSpecialAbility(SPECATK_TRIPLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::TripleAttack, remove ? 0 : 1);
|
||||
break;
|
||||
case 'Q':
|
||||
//quad requires triple to work properly
|
||||
if(remove) {
|
||||
SetSpecialAbility(SPECATK_QUAD, 0);
|
||||
SetSpecialAbility(SpecialAbility::QuadrupleAttack, 0);
|
||||
} else {
|
||||
SetSpecialAbility(SPECATK_TRIPLE, 1);
|
||||
SetSpecialAbility(SPECATK_QUAD, 1);
|
||||
SetSpecialAbility(SpecialAbility::TripleAttack, 1);
|
||||
SetSpecialAbility(SpecialAbility::QuadrupleAttack, 1);
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
SetSpecialAbility(SPECATK_BANE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::BaneAttack, remove ? 0 : 1);
|
||||
break;
|
||||
case 'm':
|
||||
SetSpecialAbility(SPECATK_MAGICAL, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::MagicalAttack, remove ? 0 : 1);
|
||||
break;
|
||||
case 'U':
|
||||
SetSpecialAbility(UNSLOWABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::SlowImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'M':
|
||||
SetSpecialAbility(UNMEZABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::MesmerizeImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'C':
|
||||
SetSpecialAbility(UNCHARMABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::CharmImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'N':
|
||||
SetSpecialAbility(UNSTUNABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::StunImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'I':
|
||||
SetSpecialAbility(UNSNAREABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::SnareImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'D':
|
||||
SetSpecialAbility(UNFEARABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::FearImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'K':
|
||||
SetSpecialAbility(UNDISPELLABLE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::DispellImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'A':
|
||||
SetSpecialAbility(IMMUNE_MELEE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::MeleeImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'B':
|
||||
SetSpecialAbility(IMMUNE_MAGIC, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::MagicImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'f':
|
||||
SetSpecialAbility(IMMUNE_FLEEING, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::FleeingImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'O':
|
||||
SetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::MeleeImmunityExceptBane, remove ? 0 : 1);
|
||||
break;
|
||||
case 'W':
|
||||
SetSpecialAbility(IMMUNE_MELEE_NONMAGICAL, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::MeleeImmunityExceptMagical, remove ? 0 : 1);
|
||||
break;
|
||||
case 'H':
|
||||
SetSpecialAbility(IMMUNE_AGGRO, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::AggroImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'G':
|
||||
SetSpecialAbility(IMMUNE_AGGRO_ON, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::BeingAggroImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'g':
|
||||
SetSpecialAbility(IMMUNE_CASTING_FROM_RANGE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::CastingFromRangeImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'd':
|
||||
SetSpecialAbility(IMMUNE_FEIGN_DEATH, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::FeignDeathImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'Y':
|
||||
SetSpecialAbility(SPECATK_RANGED_ATK, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::RangedAttack, remove ? 0 : 1);
|
||||
break;
|
||||
case 'L':
|
||||
SetSpecialAbility(SPECATK_INNATE_DW, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::DualWield, remove ? 0 : 1);
|
||||
break;
|
||||
case 't':
|
||||
SetSpecialAbility(NPC_TUNNELVISION, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::TunnelVision, remove ? 0 : 1);
|
||||
break;
|
||||
case 'n':
|
||||
SetSpecialAbility(NPC_NO_BUFFHEAL_FRIENDS, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::NoBuffHealFriends, remove ? 0 : 1);
|
||||
break;
|
||||
case 'p':
|
||||
SetSpecialAbility(IMMUNE_PACIFY, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::PacifyImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'J':
|
||||
SetSpecialAbility(LEASH, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::Leash, remove ? 0 : 1);
|
||||
break;
|
||||
case 'j':
|
||||
SetSpecialAbility(TETHER, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::Tether, remove ? 0 : 1);
|
||||
break;
|
||||
case 'o':
|
||||
SetSpecialAbility(DESTRUCTIBLE_OBJECT, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::DestructibleObject, remove ? 0 : 1);
|
||||
SetDestructibleObject(remove ? true : false);
|
||||
break;
|
||||
case 'Z':
|
||||
SetSpecialAbility(NO_HARM_FROM_CLIENT, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::HarmFromClientImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'i':
|
||||
SetSpecialAbility(IMMUNE_TAUNT, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::TauntImmunity, remove ? 0 : 1);
|
||||
break;
|
||||
case 'e':
|
||||
SetSpecialAbility(ALWAYS_FLEE, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::AlwaysFlee, remove ? 0 : 1);
|
||||
break;
|
||||
case 'h':
|
||||
SetSpecialAbility(FLEE_PERCENT, remove ? 0 : 1);
|
||||
SetSpecialAbility(SpecialAbility::FleePercent, remove ? 0 : 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2010,147 +2010,147 @@ bool Mob::HasNPCSpecialAtk(const char* parse) {
|
||||
switch(*parse)
|
||||
{
|
||||
case 'E':
|
||||
if (!GetSpecialAbility(SPECATK_ENRAGE))
|
||||
if (!GetSpecialAbility(SpecialAbility::Enrage))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'F':
|
||||
if (!GetSpecialAbility(SPECATK_FLURRY))
|
||||
if (!GetSpecialAbility(SpecialAbility::Flurry))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'R':
|
||||
if (!GetSpecialAbility(SPECATK_RAMPAGE))
|
||||
if (!GetSpecialAbility(SpecialAbility::Rampage))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'r':
|
||||
if (!GetSpecialAbility(SPECATK_AREA_RAMPAGE))
|
||||
if (!GetSpecialAbility(SpecialAbility::AreaRampage))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'S':
|
||||
if (!GetSpecialAbility(SPECATK_SUMMON))
|
||||
if (!GetSpecialAbility(SpecialAbility::Summon))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'T':
|
||||
if (!GetSpecialAbility(SPECATK_TRIPLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::TripleAttack))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'Q':
|
||||
if (!GetSpecialAbility(SPECATK_QUAD))
|
||||
if (!GetSpecialAbility(SpecialAbility::QuadrupleAttack))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'b':
|
||||
if (!GetSpecialAbility(SPECATK_BANE))
|
||||
if (!GetSpecialAbility(SpecialAbility::BaneAttack))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'm':
|
||||
if (!GetSpecialAbility(SPECATK_MAGICAL))
|
||||
if (!GetSpecialAbility(SpecialAbility::MagicalAttack))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'U':
|
||||
if (!GetSpecialAbility(UNSLOWABLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::SlowImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'M':
|
||||
if (!GetSpecialAbility(UNMEZABLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::MesmerizeImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'C':
|
||||
if (!GetSpecialAbility(UNCHARMABLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::CharmImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'N':
|
||||
if (!GetSpecialAbility(UNSTUNABLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::StunImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'I':
|
||||
if (!GetSpecialAbility(UNSNAREABLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::SnareImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'D':
|
||||
if (!GetSpecialAbility(UNFEARABLE))
|
||||
if (!GetSpecialAbility(SpecialAbility::FearImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'A':
|
||||
if (!GetSpecialAbility(IMMUNE_MELEE))
|
||||
if (!GetSpecialAbility(SpecialAbility::MeleeImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'B':
|
||||
if (!GetSpecialAbility(IMMUNE_MAGIC))
|
||||
if (!GetSpecialAbility(SpecialAbility::MagicImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'f':
|
||||
if (!GetSpecialAbility(IMMUNE_FLEEING))
|
||||
if (!GetSpecialAbility(SpecialAbility::FleeingImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'O':
|
||||
if (!GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE))
|
||||
if (!GetSpecialAbility(SpecialAbility::MeleeImmunityExceptBane))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'W':
|
||||
if (!GetSpecialAbility(IMMUNE_MELEE_NONMAGICAL))
|
||||
if (!GetSpecialAbility(SpecialAbility::MeleeImmunityExceptMagical))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'H':
|
||||
if (!GetSpecialAbility(IMMUNE_AGGRO))
|
||||
if (!GetSpecialAbility(SpecialAbility::AggroImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'G':
|
||||
if (!GetSpecialAbility(IMMUNE_AGGRO_ON))
|
||||
if (!GetSpecialAbility(SpecialAbility::BeingAggroImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'g':
|
||||
if (!GetSpecialAbility(IMMUNE_CASTING_FROM_RANGE))
|
||||
if (!GetSpecialAbility(SpecialAbility::CastingFromRangeImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'd':
|
||||
if (!GetSpecialAbility(IMMUNE_FEIGN_DEATH))
|
||||
if (!GetSpecialAbility(SpecialAbility::FeignDeathImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'Y':
|
||||
if (!GetSpecialAbility(SPECATK_RANGED_ATK))
|
||||
if (!GetSpecialAbility(SpecialAbility::RangedAttack))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'L':
|
||||
if (!GetSpecialAbility(SPECATK_INNATE_DW))
|
||||
if (!GetSpecialAbility(SpecialAbility::DualWield))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 't':
|
||||
if (!GetSpecialAbility(NPC_TUNNELVISION))
|
||||
if (!GetSpecialAbility(SpecialAbility::TunnelVision))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'n':
|
||||
if (!GetSpecialAbility(NPC_NO_BUFFHEAL_FRIENDS))
|
||||
if (!GetSpecialAbility(SpecialAbility::NoBuffHealFriends))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'p':
|
||||
if(!GetSpecialAbility(IMMUNE_PACIFY))
|
||||
if(!GetSpecialAbility(SpecialAbility::PacifyImmunity))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'J':
|
||||
if(!GetSpecialAbility(LEASH))
|
||||
if(!GetSpecialAbility(SpecialAbility::Leash))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'j':
|
||||
if(!GetSpecialAbility(TETHER))
|
||||
if(!GetSpecialAbility(SpecialAbility::Tether))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'o':
|
||||
if(!GetSpecialAbility(DESTRUCTIBLE_OBJECT))
|
||||
if(!GetSpecialAbility(SpecialAbility::DestructibleObject))
|
||||
{
|
||||
HasAllAttacks = false;
|
||||
SetDestructibleObject(false);
|
||||
}
|
||||
break;
|
||||
case 'Z':
|
||||
if(!GetSpecialAbility(NO_HARM_FROM_CLIENT)){
|
||||
if(!GetSpecialAbility(SpecialAbility::HarmFromClientImmunity)){
|
||||
HasAllAttacks = false;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
if(!GetSpecialAbility(ALWAYS_FLEE))
|
||||
if(!GetSpecialAbility(SpecialAbility::AlwaysFlee))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
case 'h':
|
||||
if(!GetSpecialAbility(FLEE_PERCENT))
|
||||
if(!GetSpecialAbility(SpecialAbility::FleePercent))
|
||||
HasAllAttacks = false;
|
||||
break;
|
||||
default:
|
||||
@ -3060,7 +3060,7 @@ int NPC::GetScore()
|
||||
if(HasNPCSpecialAtk("S")) { spccontrib++; } //Summon
|
||||
if(HasNPCSpecialAtk("T")) { spccontrib += 2; } //Triple
|
||||
if(HasNPCSpecialAtk("Q")) { spccontrib += 3; } //Quad
|
||||
if(HasNPCSpecialAtk("U")) { spccontrib += 5; } //Unslowable
|
||||
if(HasNPCSpecialAtk("U")) { spccontrib += 5; } //SpecialAbility::SlowImmunity
|
||||
if(HasNPCSpecialAtk("L")) { spccontrib++; } //Innate Dual Wield
|
||||
}
|
||||
|
||||
@ -3294,7 +3294,7 @@ bool NPC::AICheckCloseBeneficialSpells(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (caster->GetSpecialAbility(NPC_NO_BUFFHEAL_FRIENDS)) {
|
||||
if (caster->GetSpecialAbility(SpecialAbility::NoBuffHealFriends)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3802,56 +3802,56 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
|
||||
// These abilities are simple on/off flags
|
||||
static const std::vector<uint32> toggleable_special_abilities = {
|
||||
SPECATK_TRIPLE,
|
||||
SPECATK_QUAD,
|
||||
SPECATK_INNATE_DW,
|
||||
SPECATK_BANE,
|
||||
SPECATK_MAGICAL,
|
||||
UNSLOWABLE,
|
||||
UNMEZABLE,
|
||||
UNCHARMABLE,
|
||||
UNSTUNABLE,
|
||||
UNSNAREABLE,
|
||||
UNFEARABLE,
|
||||
UNDISPELLABLE,
|
||||
IMMUNE_MELEE,
|
||||
IMMUNE_MAGIC,
|
||||
IMMUNE_FLEEING,
|
||||
IMMUNE_MELEE_EXCEPT_BANE,
|
||||
IMMUNE_MELEE_NONMAGICAL,
|
||||
IMMUNE_AGGRO,
|
||||
IMMUNE_AGGRO_ON,
|
||||
IMMUNE_CASTING_FROM_RANGE,
|
||||
IMMUNE_FEIGN_DEATH,
|
||||
IMMUNE_TAUNT,
|
||||
NPC_NO_BUFFHEAL_FRIENDS,
|
||||
IMMUNE_PACIFY,
|
||||
DESTRUCTIBLE_OBJECT,
|
||||
NO_HARM_FROM_CLIENT,
|
||||
ALWAYS_FLEE,
|
||||
ALLOW_BENEFICIAL,
|
||||
DISABLE_MELEE,
|
||||
ALLOW_TO_TANK,
|
||||
IGNORE_ROOT_AGGRO_RULES,
|
||||
PROX_AGGRO,
|
||||
IMMUNE_RANGED_ATTACKS,
|
||||
IMMUNE_DAMAGE_CLIENT,
|
||||
IMMUNE_DAMAGE_NPC,
|
||||
IMMUNE_AGGRO_CLIENT,
|
||||
IMMUNE_AGGRO_NPC,
|
||||
IMMUNE_FADING_MEMORIES,
|
||||
IMMUNE_OPEN,
|
||||
IMMUNE_ASSASSINATE,
|
||||
IMMUNE_HEADSHOT,
|
||||
IMMUNE_AGGRO_BOT,
|
||||
IMMUNE_DAMAGE_BOT
|
||||
SpecialAbility::TripleAttack,
|
||||
SpecialAbility::QuadrupleAttack,
|
||||
SpecialAbility::DualWield,
|
||||
SpecialAbility::BaneAttack,
|
||||
SpecialAbility::MagicalAttack,
|
||||
SpecialAbility::SlowImmunity,
|
||||
SpecialAbility::MesmerizeImmunity,
|
||||
SpecialAbility::CharmImmunity,
|
||||
SpecialAbility::StunImmunity,
|
||||
SpecialAbility::SnareImmunity,
|
||||
SpecialAbility::FearImmunity,
|
||||
SpecialAbility::DispellImmunity,
|
||||
SpecialAbility::MeleeImmunity,
|
||||
SpecialAbility::MagicImmunity,
|
||||
SpecialAbility::FleeingImmunity,
|
||||
SpecialAbility::MeleeImmunityExceptBane,
|
||||
SpecialAbility::MeleeImmunityExceptMagical,
|
||||
SpecialAbility::AggroImmunity,
|
||||
SpecialAbility::BeingAggroImmunity,
|
||||
SpecialAbility::CastingFromRangeImmunity,
|
||||
SpecialAbility::FeignDeathImmunity,
|
||||
SpecialAbility::TauntImmunity,
|
||||
SpecialAbility::NoBuffHealFriends,
|
||||
SpecialAbility::PacifyImmunity,
|
||||
SpecialAbility::DestructibleObject,
|
||||
SpecialAbility::HarmFromClientImmunity,
|
||||
SpecialAbility::AlwaysFlee,
|
||||
SpecialAbility::AllowBeneficial,
|
||||
SpecialAbility::DisableMelee,
|
||||
SpecialAbility::AllowedToTank,
|
||||
SpecialAbility::IgnoreRootAggroRules,
|
||||
SpecialAbility::ProximityAggro,
|
||||
SpecialAbility::RangedAttackImmunity,
|
||||
SpecialAbility::ClientDamageImmunity,
|
||||
SpecialAbility::NPCDamageImmunity,
|
||||
SpecialAbility::ClientAggroImmunity,
|
||||
SpecialAbility::NPCAggroImmunity,
|
||||
SpecialAbility::MemoryFadeImmunity,
|
||||
SpecialAbility::OpenImmunity,
|
||||
SpecialAbility::AssassinateImmunity,
|
||||
SpecialAbility::HeadshotImmunity,
|
||||
SpecialAbility::BotAggroImmunity,
|
||||
SpecialAbility::BotDamageImmunity
|
||||
};
|
||||
|
||||
// These abilities have parameters that need to be parsed out individually
|
||||
static const std::map<uint32, std::vector<std::string>> parameter_special_abilities = {
|
||||
{ SPECATK_SUMMON, { "Cooldown in Milliseconds", "Health Percentage" } },
|
||||
{ SpecialAbility::Summon, { "Cooldown in Milliseconds", "Health Percentage" } },
|
||||
{
|
||||
SPECATK_ENRAGE,
|
||||
SpecialAbility::Enrage,
|
||||
{
|
||||
"Health Percentage",
|
||||
"Duration in Milliseconds",
|
||||
@ -3859,7 +3859,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
}
|
||||
},
|
||||
{
|
||||
SPECATK_RAMPAGE,
|
||||
SpecialAbility::Rampage,
|
||||
{
|
||||
"Chance",
|
||||
"Targets",
|
||||
@ -3871,7 +3871,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
}
|
||||
},
|
||||
{
|
||||
SPECATK_AREA_RAMPAGE,
|
||||
SpecialAbility::AreaRampage,
|
||||
{
|
||||
"Targets",
|
||||
"Normal Attack Damage Percentage",
|
||||
@ -3883,7 +3883,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
}
|
||||
},
|
||||
{
|
||||
SPECATK_FLURRY,
|
||||
SpecialAbility::Flurry,
|
||||
{
|
||||
"Attacks",
|
||||
"Normal Attack Damage Percentage",
|
||||
@ -3895,7 +3895,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
}
|
||||
},
|
||||
{
|
||||
SPECATK_RANGED_ATK,
|
||||
SpecialAbility::RangedAttack,
|
||||
{
|
||||
"Attacks",
|
||||
"Maximum Range",
|
||||
@ -3904,21 +3904,21 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
"Minimum Range"
|
||||
}
|
||||
},
|
||||
{ NPC_TUNNELVISION, { "Aggro Modifier on Non-Tanks" } },
|
||||
{ LEASH, { "Range" } },
|
||||
{ TETHER, { "Range" } },
|
||||
{ FLEE_PERCENT, { "Health Percentage", "Chance" } },
|
||||
{ SpecialAbility::TunnelVision, { "Aggro Modifier on Non-Tanks" } },
|
||||
{ SpecialAbility::Leash, { "Range" } },
|
||||
{ SpecialAbility::Tether, { "Range" } },
|
||||
{ SpecialAbility::FleePercent, { "Health Percentage", "Chance" } },
|
||||
{
|
||||
NPC_CHASE_DISTANCE,
|
||||
SpecialAbility::NPCChaseDistance,
|
||||
{
|
||||
"Maximum Distance",
|
||||
"Minimum Distance",
|
||||
"Ignore Line of Sight"
|
||||
}
|
||||
},
|
||||
{ CASTING_RESIST_DIFF, { "Resist Difficulty Value" } },
|
||||
{ SpecialAbility::CastingResistDifficulty, { "Resist Difficulty Value" } },
|
||||
{
|
||||
COUNTER_AVOID_DAMAGE,
|
||||
SpecialAbility::CounterAvoidDamage,
|
||||
{
|
||||
"Reduction Percentage for Block, Dodge, Parry, and Riposte",
|
||||
"Reduction Percentage for Riposte",
|
||||
@ -3928,7 +3928,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
}
|
||||
},
|
||||
{
|
||||
MODIFY_AVOID_DAMAGE,
|
||||
SpecialAbility::ModifyAvoidDamage,
|
||||
{
|
||||
"Addition Percentage for Block, Dodge, Parry, and Riposte",
|
||||
"Addition Percentage for Riposte",
|
||||
@ -3946,7 +3946,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
messages.emplace_back(
|
||||
fmt::format(
|
||||
"{} ({})",
|
||||
EQ::constants::GetSpecialAbilityName(e),
|
||||
SpecialAbility::GetName(e),
|
||||
e
|
||||
)
|
||||
);
|
||||
@ -3963,7 +3963,7 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
messages.emplace_back(
|
||||
fmt::format(
|
||||
"{} ({}) | {}: {}",
|
||||
EQ::constants::GetSpecialAbilityName(e.first),
|
||||
SpecialAbility::GetName(e.first),
|
||||
e.first,
|
||||
a,
|
||||
GetSpecialAbilityParam(e.first, slot_id)
|
||||
|
||||
@ -306,7 +306,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
if (activiate_pet){
|
||||
npc->AddToHateList(m_target, 1);
|
||||
npc->SetPetTargetLockID(m_target->GetID());
|
||||
npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
|
||||
npc->SetSpecialAbility(SpecialAbility::AggroImmunity, 1);
|
||||
}
|
||||
else {
|
||||
npc->CastSpell(SPELL_UNSUMMON_SELF, npc->GetID()); //Live like behavior, damages self for 20K
|
||||
|
||||
@ -232,10 +232,10 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 bas
|
||||
if (base_damage == DMG_INVULNERABLE)
|
||||
my_hit.damage_done = DMG_INVULNERABLE;
|
||||
|
||||
if (who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE))
|
||||
if (who->GetInvul() || who->GetSpecialAbility(SpecialAbility::MeleeImmunity))
|
||||
my_hit.damage_done = DMG_INVULNERABLE;
|
||||
|
||||
if (who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE) && skill != EQ::skills::SkillBackstab)
|
||||
if (who->GetSpecialAbility(SpecialAbility::MeleeImmunityExceptBane) && skill != EQ::skills::SkillBackstab)
|
||||
my_hit.damage_done = DMG_INVULNERABLE;
|
||||
|
||||
int64 hate = my_hit.base_damage;
|
||||
@ -969,7 +969,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co
|
||||
{
|
||||
if ((other == nullptr ||
|
||||
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
||||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
|
||||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(SpecialAbility::MeleeImmunity)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1350,7 +1350,7 @@ void NPC::RangedAttack(Mob *other)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasBowAndArrowEquipped() && !GetSpecialAbility(SPECATK_RANGED_ATK))
|
||||
if (!HasBowAndArrowEquipped() && !GetSpecialAbility(SpecialAbility::RangedAttack))
|
||||
return;
|
||||
|
||||
if (!CheckLosFN(other))
|
||||
@ -1360,12 +1360,12 @@ void NPC::RangedAttack(Mob *other)
|
||||
float min_range = static_cast<float>(RuleI(Combat, MinRangedAttackDist));
|
||||
float max_range = 250.0f; // needs to be longer than 200(most spells)
|
||||
|
||||
if (GetSpecialAbility(SPECATK_RANGED_ATK)) {
|
||||
int temp_attacks = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 0);
|
||||
if (GetSpecialAbility(SpecialAbility::RangedAttack)) {
|
||||
int temp_attacks = GetSpecialAbilityParam(SpecialAbility::RangedAttack, 0);
|
||||
attacks = temp_attacks > 0 ? temp_attacks : 1;
|
||||
|
||||
int temp_min_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 4); // Min Range of NPC attack
|
||||
int temp_max_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 1); // Max Range of NPC attack
|
||||
int temp_min_range = GetSpecialAbilityParam(SpecialAbility::RangedAttack, 4); // Min Range of NPC attack
|
||||
int temp_max_range = GetSpecialAbilityParam(SpecialAbility::RangedAttack, 1); // Max Range of NPC attack
|
||||
if (temp_max_range)
|
||||
max_range = static_cast<float>(temp_max_range);
|
||||
if (temp_min_range)
|
||||
@ -1401,7 +1401,7 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha
|
||||
HasDied() ||
|
||||
(!IsAttackAllowed(other)) ||
|
||||
(other->GetInvul() ||
|
||||
other->GetSpecialAbility(IMMUNE_MELEE)))
|
||||
other->GetSpecialAbility(SpecialAbility::MeleeImmunity)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1430,14 +1430,14 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha
|
||||
}
|
||||
|
||||
if (!chance_mod)
|
||||
chance_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2);
|
||||
chance_mod = GetSpecialAbilityParam(SpecialAbility::RangedAttack, 2);
|
||||
|
||||
int TotalDmg = 0;
|
||||
int MaxDmg = GetBaseDamage() * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
|
||||
int MinDmg = GetMinDamage() * RuleR(Combat, ArcheryNPCMultiplier);
|
||||
|
||||
if (!damage_mod)
|
||||
damage_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3);//Damage modifier
|
||||
damage_mod = GetSpecialAbilityParam(SpecialAbility::RangedAttack, 3);//Damage modifier
|
||||
|
||||
DamageHitInfo my_hit;
|
||||
my_hit.base_damage = MaxDmg;
|
||||
@ -1573,7 +1573,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c
|
||||
{
|
||||
if ((other == nullptr ||
|
||||
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
||||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
|
||||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(SpecialAbility::MeleeImmunity)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2204,7 +2204,7 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool from_spell
|
||||
if (
|
||||
!RuleB(Combat, TauntOverLevel) &&
|
||||
level_difference < 0 ||
|
||||
who->GetSpecialAbility(IMMUNE_TAUNT)
|
||||
who->GetSpecialAbility(SpecialAbility::TauntImmunity)
|
||||
) {
|
||||
MessageString(Chat::SpellFailure, FAILED_TAUNT);
|
||||
return;
|
||||
@ -2404,7 +2404,7 @@ int Mob::TryHeadShot(Mob *defender, EQ::skills::SkillType skillInUse)
|
||||
skillInUse == EQ::skills::SkillArchery &&
|
||||
GetTarget() == defender &&
|
||||
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, HeadshotOnlyHumanoids)) &&
|
||||
!defender->GetSpecialAbility(IMMUNE_HEADSHOT)
|
||||
!defender->GetSpecialAbility(SpecialAbility::HeadshotImmunity)
|
||||
) {
|
||||
uint32 HeadShot_Dmg = aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG];
|
||||
uint8 HeadShot_Level = 0; // Get Highest Headshot Level
|
||||
@ -2441,7 +2441,7 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
|
||||
GetLevel() >= RuleI(Combat, AssassinateLevelRequirement) &&
|
||||
(skillInUse == EQ::skills::SkillBackstab || skillInUse == EQ::skills::SkillThrowing) &&
|
||||
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids)) &&
|
||||
!defender->GetSpecialAbility(IMMUNE_ASSASSINATE)
|
||||
!defender->GetSpecialAbility(SpecialAbility::AssassinateImmunity)
|
||||
) {
|
||||
int chance = GetDEX();
|
||||
if (skillInUse == EQ::skills::SkillBackstab) {
|
||||
@ -2574,7 +2574,7 @@ bool Mob::CanDoSpecialAttack(Mob *other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE))
|
||||
if(other->GetInvul() || other->GetSpecialAbility(SpecialAbility::MeleeImmunity))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@ -747,7 +747,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
max_level = RuleI(Spells, BaseImmunityLevel);
|
||||
// NPCs get to ignore max_level for their spells.
|
||||
// Ignore if spell is beneficial (ex. Harvest)
|
||||
if (IsDetrimentalSpell(spell.id) && (GetSpecialAbility(UNSTUNABLE) ||
|
||||
if (IsDetrimentalSpell(spell.id) && (GetSpecialAbility(SpecialAbility::StunImmunity) ||
|
||||
((GetLevel() > max_level) && caster && (!caster->IsNPC() ||
|
||||
(caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity))))))
|
||||
{
|
||||
@ -1103,7 +1103,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Cancel Magic: %d", effect_value);
|
||||
#endif
|
||||
if(GetSpecialAbility(UNDISPELLABLE)){
|
||||
if(GetSpecialAbility(SpecialAbility::DispellImmunity)){
|
||||
if (caster) {
|
||||
caster->MessageString(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name);
|
||||
}
|
||||
@ -1119,7 +1119,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Dispel Detrimental: %d", effect_value);
|
||||
#endif
|
||||
if(GetSpecialAbility(UNDISPELLABLE)){
|
||||
if(GetSpecialAbility(SpecialAbility::DispellImmunity)){
|
||||
if (caster)
|
||||
caster->MessageString(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name);
|
||||
break;
|
||||
@ -1150,7 +1150,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Dispel Beneficial: %d", effect_value);
|
||||
#endif
|
||||
if(GetSpecialAbility(UNDISPELLABLE)){
|
||||
if(GetSpecialAbility(SpecialAbility::DispellImmunity)){
|
||||
if (caster)
|
||||
caster->MessageString(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name);
|
||||
break;
|
||||
@ -1551,7 +1551,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
max_level = RuleI(Spells, BaseImmunityLevel); // Default max is 55 level limit
|
||||
|
||||
// NPCs ignore level limits in their spells
|
||||
if(GetSpecialAbility(UNSTUNABLE) ||
|
||||
if(GetSpecialAbility(SpecialAbility::StunImmunity) ||
|
||||
((GetLevel() > max_level)
|
||||
&& caster && (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))))
|
||||
{
|
||||
@ -3043,12 +3043,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
if (!caster)
|
||||
break;
|
||||
|
||||
if (IsNPC() && GetSpecialAbility(UNSTUNABLE)) {
|
||||
if (IsNPC() && GetSpecialAbility(SpecialAbility::StunImmunity)) {
|
||||
caster->MessageString(Chat::SpellFailure, IMMUNE_STUN);
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsNPC() && GetSpecialAbility(UNFEARABLE)) {
|
||||
if (IsNPC() && GetSpecialAbility(SpecialAbility::FearImmunity)) {
|
||||
caster->MessageString(Chat::SpellFailure, IMMUNE_FEAR);
|
||||
break;
|
||||
}
|
||||
@ -4461,8 +4461,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
}
|
||||
//If owner dead, briefly setting Immmune Aggro while hatelists wipe for both pet and targets is needed to ensure no reaggroing.
|
||||
else if (IsNPC()){
|
||||
bool immune_aggro = GetSpecialAbility(IMMUNE_AGGRO); //check if already immune aggro
|
||||
SetSpecialAbility(IMMUNE_AGGRO, 1);
|
||||
bool has_aggro_immunity = GetSpecialAbility(SpecialAbility::AggroImmunity); //check if already immune aggro
|
||||
SetSpecialAbility(SpecialAbility::AggroImmunity, 1);
|
||||
WipeHateList();
|
||||
if (IsCasting()) {
|
||||
InterruptSpell(CastingSpellID());
|
||||
@ -4478,8 +4478,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
}
|
||||
}
|
||||
|
||||
if (!immune_aggro) {
|
||||
SetSpecialAbility(IMMUNE_AGGRO, 0);
|
||||
if (!has_aggro_immunity) {
|
||||
SetSpecialAbility(SpecialAbility::AggroImmunity, 0);
|
||||
}
|
||||
}
|
||||
SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||
@ -9904,7 +9904,7 @@ bool Mob::HarmonySpellLevelCheck(int32 spell_id, Mob *target)
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
// not important to check limit on SE_Lull as it doesnt have one and if the other components won't land, then SE_Lull wont either
|
||||
if (spells[spell_id].effect_id[i] == SE_ChangeFrenzyRad || spells[spell_id].effect_id[i] == SE_Harmony) {
|
||||
if ((spells[spell_id].max_value[i] != 0 && target->GetLevel() > spells[spell_id].max_value[i]) || target->GetSpecialAbility(IMMUNE_PACIFY)) {
|
||||
if ((spells[spell_id].max_value[i] != 0 && target->GetLevel() > spells[spell_id].max_value[i]) || target->GetSpecialAbility(SpecialAbility::PacifyImmunity)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3675,7 +3675,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
|
||||
if (!will_overwrite && !IsDisciplineBuff(spell_id)) {
|
||||
emptyslot = buffslot;
|
||||
}
|
||||
|
||||
|
||||
will_overwrite = true;
|
||||
overwrite_slots.push_back(buffslot);
|
||||
} else if (ret == 2) {
|
||||
@ -5041,7 +5041,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
|
||||
if(IsMesmerizeSpell(spell_id))
|
||||
{
|
||||
if(GetSpecialAbility(UNMEZABLE)) {
|
||||
if(GetSpecialAbility(SpecialAbility::MesmerizeImmunity)) {
|
||||
LogSpells("We are immune to Mez spells");
|
||||
caster->MessageString(Chat::SpellFailure, CANNOT_MEZ);
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
@ -5068,7 +5068,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
}
|
||||
|
||||
// slow and haste spells
|
||||
if(GetSpecialAbility(UNSLOWABLE) && IsEffectInSpell(spell_id, SE_AttackSpeed))
|
||||
if(GetSpecialAbility(SpecialAbility::SlowImmunity) && IsEffectInSpell(spell_id, SE_AttackSpeed))
|
||||
{
|
||||
LogSpells("We are immune to Slow spells");
|
||||
caster->MessageString(Chat::Red, IMMUNE_ATKSPEED);
|
||||
@ -5085,7 +5085,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(IsEffectInSpell(spell_id, SE_Fear))
|
||||
{
|
||||
effect_index = GetSpellEffectIndex(spell_id, SE_Fear);
|
||||
if(GetSpecialAbility(UNFEARABLE)) {
|
||||
if(GetSpecialAbility(SpecialAbility::FearImmunity)) {
|
||||
LogSpells("We are immune to Fear spells");
|
||||
caster->MessageString(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
@ -5124,7 +5124,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
|
||||
if(IsCharmSpell(spell_id))
|
||||
{
|
||||
if(GetSpecialAbility(UNCHARMABLE))
|
||||
if(GetSpecialAbility(SpecialAbility::CharmImmunity))
|
||||
{
|
||||
LogSpells("We are immune to Charm spells");
|
||||
caster->MessageString(Chat::Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up
|
||||
@ -5173,7 +5173,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
IsEffectInSpell(spell_id, SE_MovementSpeed)
|
||||
)
|
||||
{
|
||||
if(GetSpecialAbility(UNSNAREABLE)) {
|
||||
if(GetSpecialAbility(SpecialAbility::SnareImmunity)) {
|
||||
LogSpells("We are immune to Snare spells");
|
||||
caster->MessageString(Chat::Red, IMMUNE_MOVEMENT);
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
@ -5263,7 +5263,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(GetSpecialAbility(IMMUNE_CASTING_FROM_RANGE))
|
||||
if(GetSpecialAbility(SpecialAbility::CastingFromRangeImmunity))
|
||||
{
|
||||
if(!caster->CombatRange(this))
|
||||
{
|
||||
@ -5271,7 +5271,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
|
||||
}
|
||||
}
|
||||
|
||||
if(GetSpecialAbility(IMMUNE_MAGIC))
|
||||
if(GetSpecialAbility(SpecialAbility::MagicImmunity))
|
||||
{
|
||||
LogSpells("We are immune to magic, so we fully resist the spell [{}]", spell_id);
|
||||
return(0);
|
||||
@ -5291,8 +5291,8 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
|
||||
}
|
||||
}
|
||||
|
||||
if(caster->GetSpecialAbility(CASTING_RESIST_DIFF))
|
||||
resist_modifier += caster->GetSpecialAbilityParam(CASTING_RESIST_DIFF, 0);
|
||||
if(caster->GetSpecialAbility(SpecialAbility::CastingResistDifficulty))
|
||||
resist_modifier += caster->GetSpecialAbilityParam(SpecialAbility::CastingResistDifficulty, 0);
|
||||
|
||||
int64 focus_resist = caster->GetFocusEffect(focusResistRate, spell_id);
|
||||
|
||||
|
||||
@ -1553,7 +1553,7 @@ void Mob::TuneCommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraA
|
||||
// this appears where they do special attack dmg mods
|
||||
int spec_mod = 0;
|
||||
if (IsSpecialAttack(eSpecialAttacks::Rampage)) {
|
||||
int mod = GetSpecialAbilityParam(SPECATK_RAMPAGE, 2);
|
||||
int mod = GetSpecialAbilityParam(SpecialAbility::Rampage, 2);
|
||||
if (mod > 0)
|
||||
spec_mod = mod;
|
||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
|
||||
@ -1564,7 +1564,7 @@ void Mob::TuneCommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraA
|
||||
}
|
||||
}
|
||||
else if (IsSpecialAttack(eSpecialAttacks::AERampage)) {
|
||||
int mod = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2);
|
||||
int mod = GetSpecialAbilityParam(SpecialAbility::AreaRampage, 2);
|
||||
if (mod > 0)
|
||||
spec_mod = mod;
|
||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user