diff --git a/common/emu_constants.h b/common/emu_constants.h index d5a133d3e..0d18f1179 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -580,11 +580,17 @@ enum BucketComparison : uint8 { BucketIsNotBetween }; -enum EntityFilterTypes : uint8 { +enum class EntityFilterType { All, Bots, Clients, NPCs }; +enum class ApplySpellType { + Solo, + Group, + Raid +}; + #endif /*COMMON_EMU_CONSTANTS_H*/ diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 295bedde5..4d9aee111 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -1518,7 +1518,7 @@ bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) { void Mob::RogueEvade(Mob *other) { int64 amount = other->GetHateAmount(this) * zone->random.Int(40, 70) / 100; - other->SetHateAmountOnEnt(this, std::max((int64)100, amount)); + other->SetHateAmountOnEnt(this, std::max(static_cast(100), amount)); return; } diff --git a/zone/client.cpp b/zone/client.cpp index 2ff07ed0b..930d5103e 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -11810,3 +11810,108 @@ void Client::AddAAPoints(uint32 points) bool Client::SendGMCommand(std::string message, bool ignore_status) { return command_dispatch(this, message, ignore_status) >= 0 ? true : false; } + +std::vector Client::GetApplySpellList( + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only, + bool allow_bots +) { + std::vector l; + + if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) { + auto* r = GetRaid(); + auto group_id = r->GetGroup(this); + if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { + for (auto i = 0; i < MAX_RAID_MEMBERS; i++) { + auto* m = r->members[i].member; + if (m && m->IsClient() && (!is_raid_group_only || r->GetGroup(m) == group_id)) { + l.push_back(m); + + if (allow_pets && m->HasPet()) { + l.push_back(m->GetPet()); + } + +#ifdef BOTS + if (allow_bots) { + const auto& sbl = entity_list.GetBotListByCharacterID(m->CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } + } +#endif + } + } + } + } else if (apply_type == ApplySpellType::Group && IsGrouped()) { + auto* g = GetGroup(); + if (g) { + for (auto i = 0; i < MAX_GROUP_MEMBERS; i++) { + auto* m = g->members[i]; + if (m && m->IsClient()) { + l.push_back(m->CastToClient()); + + if (allow_pets && m->HasPet()) { + l.push_back(m->GetPet()); + } + +#ifdef BOTS + if (allow_bots) { + const auto& sbl = entity_list.GetBotListByCharacterID(m->CastToClient()->CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } + } +#endif + } + } + } + } else { + l.push_back(this); + + if (allow_pets && HasPet()) { + l.push_back(GetPet()); + } + +#ifdef BOTS + if (allow_bots) { + const auto& sbl = entity_list.GetBotListByCharacterID(CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } + } +#endif + } + + return l; +} + +void Client::ApplySpell( + int spell_id, + int duration, + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only, + bool allow_bots +) { + const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only, allow_bots); + + for (const auto& m : l) { + m->ApplySpellBuff(spell_id, duration); + } +} + +void Client::SetSpellDuration( + int spell_id, + int duration, + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only, + bool allow_bots +) { + const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only, allow_bots); + + for (const auto& m : l) { + m->SetBuffDuration(spell_id, duration); + } +} diff --git a/zone/client.h b/zone/client.h index 9c616acc1..a3758999c 100644 --- a/zone/client.h +++ b/zone/client.h @@ -910,6 +910,31 @@ public: bool SendGMCommand(std::string message, bool ignore_status = false); + std::vector GetApplySpellList( + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only, + bool allow_bots + ); + + void ApplySpell( + int spell_id, + int duration = 0, + ApplySpellType apply_type = ApplySpellType::Solo, + bool allow_pets = false, + bool is_raid_group_only = true, + bool allow_bots = false + ); + + void SetSpellDuration( + int spell_id, + int duration = 0, + ApplySpellType apply_type = ApplySpellType::Solo, + bool allow_pets = false, + bool is_raid_group_only = true, + bool allow_bots = false + ); + //old AA methods that we still use void ResetAA(); void RefundAA(); diff --git a/zone/entity.cpp b/zone/entity.cpp index 649334a96..624a678e8 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -5858,9 +5858,9 @@ void EntityList::Marquee( } } -std::vector EntityList::GetFilteredEntityList(Mob* sender, uint32 distance, uint8 filter_type) +std::vector EntityList::GetFilteredEntityList(Mob* sender, uint32 distance, EntityFilterType filter_type) { - std::vector l; + std::vector l; if (!sender) { return l; } @@ -5887,9 +5887,9 @@ std::vector EntityList::GetFilteredEntityList(Mob* sender, uint32 distance } if ( - (filter_type == EntityFilterTypes::Bots && !m.second->IsBot()) || - (filter_type == EntityFilterTypes::Clients && !m.second->IsClient()) || - (filter_type == EntityFilterTypes::NPCs && !m.second->IsNPC()) + (filter_type == EntityFilterType::Bots && !m.second->IsBot()) || + (filter_type == EntityFilterType::Clients && !m.second->IsClient()) || + (filter_type == EntityFilterType::NPCs && !m.second->IsNPC()) ) { continue; } @@ -5900,8 +5900,13 @@ std::vector EntityList::GetFilteredEntityList(Mob* sender, uint32 distance return l; } -void EntityList::DamageArea(Mob* sender, int64 damage, uint32 distance, uint8 filter_type, bool is_percentage) -{ +void EntityList::DamageArea( + Mob* sender, + int64 damage, + uint32 distance, + EntityFilterType filter_type, + bool is_percentage +) { if (!sender) { return; } diff --git a/zone/entity.h b/zone/entity.h index d207d6caf..bf1986de4 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -340,8 +340,19 @@ public: void DescribeAggro(Client *to_who, NPC *from_who, float dist, bool verbose); - std::vector GetFilteredEntityList(Mob* sender, uint32 distance = 0, uint8 filter_type = EntityFilterTypes::All); - void DamageArea(Mob* sender, int64 damage, uint32 distance = 0, uint8 filter_type = EntityFilterTypes::All, bool is_percentage = false); + std::vector GetFilteredEntityList( + Mob* sender, + uint32 distance = 0, + EntityFilterType filter_type = EntityFilterType::All + ); + + void DamageArea( + Mob* sender, + int64 damage, + uint32 distance = 0, + EntityFilterType filter_type = EntityFilterType::All, + bool is_percentage = false + ); void Marquee(uint32 type, std::string message, uint32 duration = 3000); void Marquee(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string message); diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index d16c82219..57f0a8018 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -999,13 +999,13 @@ NPC* HateList::GetRandomNPCOnHateList(bool skip_mezzed) return nullptr; } -void HateList::DamageHateList(int64 damage, uint32 distance, uint8 filter_type, bool is_percentage) +void HateList::DamageHateList(int64 damage, uint32 distance, EntityFilterType filter_type, bool is_percentage) { if (damage <= 0) { return; } - const auto& l = GetFilteredHateList(distance, filter_type); + const auto& l = GetFilteredHateList(filter_type, distance); for (const auto& h : l) { auto e = h->entity_on_hatelist; if (is_percentage) { @@ -1018,7 +1018,7 @@ void HateList::DamageHateList(int64 damage, uint32 distance, uint8 filter_type, } } -std::list HateList::GetFilteredHateList(uint32 distance, uint8 filter_type) +std::list HateList::GetFilteredHateList(EntityFilterType filter_type, uint32 distance) { std::list l; const auto squared_distance = (distance * distance); @@ -1039,9 +1039,9 @@ std::list HateList::GetFilteredHateList(uint32 distance, uint8 } if ( - (filter_type == EntityFilterTypes::Bots && !e->IsBot()) || - (filter_type == EntityFilterTypes::Clients && !e->IsClient()) || - (filter_type == EntityFilterTypes::NPCs && !e->IsNPC()) + (filter_type == EntityFilterType::Bots && !e->IsBot()) || + (filter_type == EntityFilterType::Clients && !e->IsClient()) || + (filter_type == EntityFilterType::NPCs && !e->IsNPC()) ) { continue; } diff --git a/zone/hate_list.h b/zone/hate_list.h index ab4f9235d..e9ba77243 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -66,15 +66,16 @@ public: int64 GetEntHateAmount(Mob *ent, bool in_damage = false); std::list &GetHateList() { return list; } + std::list GetFilteredHateList( - uint32 distance = 0, - uint8 filter_type = EntityFilterTypes::All + EntityFilterType filter_type = EntityFilterType::All, + uint32 distance = 0 ); void DamageHateList( int64 damage, uint32 distance = 0, - uint8 filter_type = EntityFilterTypes::All, + EntityFilterType filter_type = EntityFilterType::All, bool is_percentage = false ); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 9d0e35bfd..9dbe972f7 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -2613,6 +2613,148 @@ void Lua_Client::SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in self->SendMarqueeMessage(type, priority, fade_in, fade_out, duration, message); } +void Lua_Client::ApplySpell(int spell_id) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id); +} + +void Lua_Client::ApplySpell(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration); +} + +void Lua_Client::ApplySpell(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +#ifdef BOTS +void Lua_Client::ApplySpell(int spell_id, int duration, bool allow_pets, bool allow_bots) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots); +} +#endif + +void Lua_Client::ApplySpellGroup(int spell_id) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, 0, ApplySpellType::Group); +} + +void Lua_Client::ApplySpellGroup(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Group); +} + +void Lua_Client::ApplySpellGroup(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets); +} + +#ifdef BOTS +void Lua_Client::ApplySpellGroup(int spell_id, int duration, bool allow_pets, bool allow_bots) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots); +} +#endif + +void Lua_Client::ApplySpellRaid(int spell_id) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, 0, ApplySpellType::Raid); +} + +void Lua_Client::ApplySpellRaid(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Raid); +} + +void Lua_Client::ApplySpellRaid(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets); +} + +void Lua_Client::ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only); +} + +#ifdef BOTS +void Lua_Client::ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots); +} +#endif + +void Lua_Client::SetSpellDuration(int spell_id) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id); +} + +void Lua_Client::SetSpellDuration(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration); +} + +void Lua_Client::SetSpellDuration(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +#ifdef BOTS +void Lua_Client::SetSpellDuration(int spell_id, int duration, bool allow_pets, bool allow_bots) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots); +} +#endif + +void Lua_Client::SetSpellDurationGroup(int spell_id) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, 0, ApplySpellType::Group); +} + +void Lua_Client::SetSpellDurationGroup(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group); +} + +void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets); +} + +#ifdef BOTS +void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, bool allow_pets, bool allow_bots) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots); +} +#endif + +void Lua_Client::SetSpellDurationRaid(int spell_id) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, 0, ApplySpellType::Raid); +} + +void Lua_Client::SetSpellDurationRaid(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid); +} + +void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets); +} + +void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only); +} + +#ifdef BOTS +void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets, is_raid_group_only, allow_bots); +} +#endif + void Lua_Client::UpdateAdmin() { Lua_Safe_Call_Void(); self->UpdateAdmin(); @@ -2727,6 +2869,25 @@ luabind::scope lua_register_client() { .def("AddPVPPoints", (void(Lua_Client::*)(uint32))&Lua_Client::AddPVPPoints) .def("AddSkill", (void(Lua_Client::*)(int,int))&Lua_Client::AddSkill) .def("Admin", (int16(Lua_Client::*)(void))&Lua_Client::Admin) + .def("ApplySpell", (void(Lua_Client::*)(int))&Lua_Client::ApplySpell) + .def("ApplySpell", (void(Lua_Client::*)(int,int))&Lua_Client::ApplySpell) + .def("ApplySpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ApplySpell) +#ifdef BOTS + .def("ApplySpell", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::ApplySpell) +#endif + .def("ApplySpellGroup", (void(Lua_Client::*)(int))&Lua_Client::ApplySpellGroup) + .def("ApplySpellGroup", (void(Lua_Client::*)(int,int))&Lua_Client::ApplySpellGroup) + .def("ApplySpellGroup", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ApplySpellGroup) +#ifdef BOTS + .def("ApplySpellGroup", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::ApplySpellGroup) +#endif + .def("ApplySpellRaid", (void(Lua_Client::*)(int))&Lua_Client::ApplySpellRaid) + .def("ApplySpellRaid", (void(Lua_Client::*)(int,int))&Lua_Client::ApplySpellRaid) + .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ApplySpellRaid) + .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::ApplySpellRaid) +#ifdef BOTS + .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,bool,bool,bool))&Lua_Client::ApplySpellRaid) +#endif .def("AssignTask", (void(Lua_Client::*)(int))&Lua_Client::AssignTask) .def("AssignTask", (void(Lua_Client::*)(int,int))&Lua_Client::AssignTask) .def("AssignTask", (void(Lua_Client::*)(int,int,bool))&Lua_Client::AssignTask) @@ -3109,6 +3270,25 @@ luabind::scope lua_register_client() { .def("SetSecondaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetSecondaryWeaponOrnamentation) .def("SetSkill", (void(Lua_Client::*)(int,int))&Lua_Client::SetSkill) .def("SetSkillPoints", (void(Lua_Client::*)(int))&Lua_Client::SetSkillPoints) + .def("SetSpellDuration", (void(Lua_Client::*)(int))&Lua_Client::SetSpellDuration) + .def("SetSpellDuration", (void(Lua_Client::*)(int,int))&Lua_Client::SetSpellDuration) + .def("SetSpellDuration", (void(Lua_Client::*)(int,int,bool))&Lua_Client::SetSpellDuration) +#ifdef BOTS + .def("SetSpellDuration", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::SetSpellDuration) +#endif + .def("SetSpellDurationGroup", (void(Lua_Client::*)(int))&Lua_Client::SetSpellDurationGroup) + .def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int))&Lua_Client::SetSpellDurationGroup) + .def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,bool))&Lua_Client::SetSpellDurationGroup) +#ifdef BOTS + .def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::SetSpellDurationGroup) +#endif + .def("SetSpellDurationRaid", (void(Lua_Client::*)(int))&Lua_Client::SetSpellDurationRaid) + .def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int))&Lua_Client::SetSpellDurationRaid) + .def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,bool))&Lua_Client::SetSpellDurationRaid) + .def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::SetSpellDurationRaid) +#ifdef BOTS + .def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,bool,bool,bool))&Lua_Client::SetSpellDurationRaid) +#endif .def("SetStartZone", (void(Lua_Client::*)(int))&Lua_Client::SetStartZone) .def("SetStartZone", (void(Lua_Client::*)(int,float))&Lua_Client::SetStartZone) .def("SetStartZone", (void(Lua_Client::*)(int,float,float))&Lua_Client::SetStartZone) @@ -3118,7 +3298,7 @@ luabind::scope lua_register_client() { .def("SetTint", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetTint) .def("SetTitleSuffix", (void(Lua_Client::*)(const char *))&Lua_Client::SetTitleSuffix) .def("SetZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetZoneFlag) - .def("Signal", (void(Lua_Client::*)(int))&Lua_Client::Signal) + .def("Signal", (void(Lua_Client::*)(uint32))&Lua_Client::Signal) .def("Sit", (void(Lua_Client::*)(void))&Lua_Client::Sit) .def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand) .def("SummonBaggedItems", (void(Lua_Client::*)(uint32,luabind::adl::object))&Lua_Client::SummonBaggedItems) diff --git a/zone/lua_client.h b/zone/lua_client.h index ba869a218..e3e09c894 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -437,6 +437,51 @@ public: void UpdateAdmin(); void UpdateAdmin(bool from_database); + void ApplySpell(int spell_id); + void ApplySpell(int spell_id, int duration); + void ApplySpell(int spell_id, int duration, bool allow_pets); +#ifdef BOTS + void ApplySpell(int spell_id, int duration, bool allow_pets, bool allow_bots); +#endif + + void ApplySpellGroup(int spell_id); + void ApplySpellGroup(int spell_id, int duration); + void ApplySpellGroup(int spell_id, int duration, bool allow_pets); +#ifdef BOTS + void ApplySpellGroup(int spell_id, int duration, bool allow_pets, bool allow_bots); +#endif + + void ApplySpellRaid(int spell_id); + void ApplySpellRaid(int spell_id, int duration); + void ApplySpellRaid(int spell_id, int duration, bool allow_pets); + void ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only); +#ifdef BOTS + void ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots); +#endif + + void SetSpellDuration(int spell_id); + void SetSpellDuration(int spell_id, int duration); + void SetSpellDuration(int spell_id, int duration, bool allow_pets); +#ifdef BOTS + void SetSpellDuration(int spell_id, int duration, bool allow_pets, bool allow_bots); +#endif + + void SetSpellDurationGroup(int spell_id); + void SetSpellDurationGroup(int spell_id, int duration); + void SetSpellDurationGroup(int spell_id, int duration, bool allow_pets); +#ifdef BOTS + void SetSpellDurationGroup(int spell_id, int duration, bool allow_pets, bool allow_bots); +#endif + + void SetSpellDurationRaid(int spell_id); + void SetSpellDurationRaid(int spell_id, int duration); + void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets); + void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only); +#ifdef BOTS + void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots); +#endif + + int GetEnvironmentDamageModifier(); void SetEnvironmentDamageModifier(int value); bool GetInvulnerableEnvironmentDamage(); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index a7ba56c3f..0a0a6a66c 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1382,7 +1382,7 @@ void Lua_Mob::Signal(int signal_id) { #ifdef BOTS } else if (self->IsBot()) { self->CastToBot()->SignalBot(signal_id); -#endif +#endif } } @@ -2376,7 +2376,7 @@ Lua_HateList Lua_Mob::GetHateListByDistance(uint32 distance) { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(distance); + auto h_list = self->GetFilteredHateList(EntityFilterType::All, distance); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); @@ -2524,59 +2524,59 @@ void Lua_Mob::DamageHateList(int64 damage, uint32 distance) { void Lua_Mob::DamageHateListClients(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::Clients); + self->DamageHateList(damage, 0, EntityFilterType::Clients); } void Lua_Mob::DamageHateListClients(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::Clients); + self->DamageHateList(damage, distance, EntityFilterType::Clients); } void Lua_Mob::DamageHateListNPCs(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::NPCs); + self->DamageHateList(damage, 0, EntityFilterType::NPCs); } void Lua_Mob::DamageHateListNPCs(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::NPCs); + self->DamageHateList(damage, distance, EntityFilterType::NPCs); } void Lua_Mob::DamageHateListPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::All, true); + self->DamageHateList(damage, 0, EntityFilterType::All, true); } void Lua_Mob::DamageHateListPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::All, true); + self->DamageHateList(damage, distance, EntityFilterType::All, true); } void Lua_Mob::DamageHateListClientsPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::Clients, true); + self->DamageHateList(damage, 0, EntityFilterType::Clients, true); } void Lua_Mob::DamageHateListClientsPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::Clients, true); + self->DamageHateList(damage, distance, EntityFilterType::Clients, true); } void Lua_Mob::DamageHateListNPCsPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::NPCs, true); + self->DamageHateList(damage, 0, EntityFilterType::NPCs, true); } void Lua_Mob::DamageHateListNPCsPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::NPCs, true); + self->DamageHateList(damage, distance, EntityFilterType::NPCs, true); } Lua_HateList Lua_Mob::GetHateListClients() { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::Clients); + auto h_list = self->GetFilteredHateList(EntityFilterType::Clients); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); @@ -2589,7 +2589,7 @@ Lua_HateList Lua_Mob::GetHateListClients(uint32 distance) { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::Clients, distance); + auto h_list = self->GetFilteredHateList(EntityFilterType::Clients, distance); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); @@ -2602,7 +2602,7 @@ Lua_HateList Lua_Mob::GetHateListNPCs() { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::NPCs); + auto h_list = self->GetFilteredHateList(EntityFilterType::NPCs); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); @@ -2615,7 +2615,7 @@ Lua_HateList Lua_Mob::GetHateListNPCs(uint32 distance) { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::NPCs, distance); + auto h_list = self->GetFilteredHateList(EntityFilterType::NPCs, distance); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); @@ -2636,100 +2636,100 @@ void Lua_Mob::DamageArea(int64 damage, uint32 distance) { void Lua_Mob::DamageAreaPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::All, true); + self->DamageArea(damage, 0, EntityFilterType::All, true); } void Lua_Mob::DamageAreaPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::All, true); + self->DamageArea(damage, distance, EntityFilterType::All, true); } void Lua_Mob::DamageAreaClients(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::Clients); + self->DamageArea(damage, 0, EntityFilterType::Clients); } void Lua_Mob::DamageAreaClients(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::Clients); + self->DamageArea(damage, distance, EntityFilterType::Clients); } void Lua_Mob::DamageAreaClientsPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::Clients, true); + self->DamageArea(damage, 0, EntityFilterType::Clients, true); } void Lua_Mob::DamageAreaClientsPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::Clients, true); + self->DamageArea(damage, distance, EntityFilterType::Clients, true); } void Lua_Mob::DamageAreaNPCs(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::NPCs); + self->DamageArea(damage, 0, EntityFilterType::NPCs); } void Lua_Mob::DamageAreaNPCs(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::NPCs); + self->DamageArea(damage, distance, EntityFilterType::NPCs); } void Lua_Mob::DamageAreaNPCsPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::NPCs, true); + self->DamageArea(damage, 0, EntityFilterType::NPCs, true); } void Lua_Mob::DamageAreaNPCsPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::NPCs, true); + self->DamageArea(damage, distance, EntityFilterType::NPCs, true); } #ifdef BOTS void Lua_Mob::DamageAreaBots(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::Bots); + self->DamageArea(damage, 0, EntityFilterType::Bots); } void Lua_Mob::DamageAreaBots(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::Bots); + self->DamageArea(damage, distance, EntityFilterType::Bots); } void Lua_Mob::DamageAreaBotsPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageArea(damage, 0, EntityFilterTypes::Bots, true); + self->DamageArea(damage, 0, EntityFilterType::Bots, true); } void Lua_Mob::DamageAreaBotsPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageArea(damage, distance, EntityFilterTypes::Bots, true); + self->DamageArea(damage, distance, EntityFilterType::Bots, true); } void Lua_Mob::DamageHateListBots(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::Bots); + self->DamageHateList(damage, 0, EntityFilterType::Bots); } void Lua_Mob::DamageHateListBots(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::Bots); + self->DamageHateList(damage, distance, EntityFilterType::Bots); } void Lua_Mob::DamageHateListBotsPercentage(int64 damage) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, 0, EntityFilterTypes::Bots, true); + self->DamageHateList(damage, 0, EntityFilterType::Bots, true); } void Lua_Mob::DamageHateListBotsPercentage(int64 damage, uint32 distance) { Lua_Safe_Call_Void(); - self->DamageHateList(damage, distance, EntityFilterTypes::Bots, true); + self->DamageHateList(damage, distance, EntityFilterType::Bots, true); } Lua_HateList Lua_Mob::GetHateListBots() { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::Bots); + auto h_list = self->GetFilteredHateList(EntityFilterType::Bots); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); @@ -2742,7 +2742,7 @@ Lua_HateList Lua_Mob::GetHateListBots(uint32 distance) { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::Bots, distance); + auto h_list = self->GetFilteredHateList(EntityFilterType::Bots, distance); for (auto h : h_list) { Lua_HateEntry e(h); ret.entries.push_back(e); diff --git a/zone/mob.h b/zone/mob.h index 16c79d75c..6ff172248 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -351,9 +351,18 @@ public: bool SpellFinished(uint16 spell_id, Mob *target, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, int mana_used = 0, uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, bool from_casted_spell = false, uint32 aa_id = 0); void SendBeginCast(uint16 spell_id, uint32 casttime); - virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, int reflect_effectiveness = 0, - bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, int32 duration_override = 0, bool disable_buff_overrwrite = false); - virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1, int reflect_effectiveness = 0, int32 duration_override = 0, bool disable_buff_overrwrite = false); + virtual bool SpellOnTarget( + uint16 spell_id, + Mob* spelltar, + int reflect_effectiveness = 0, + bool use_resist_adjust = false, + int16 resist_adjust = 0, + bool isproc = false, + int level_override = -1, + int duration_override = 0, + bool disable_buff_overwrite = false + ); + virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1, int reflect_effectiveness = 0, int32 duration_override = 0, bool disable_buff_overwrite = false); virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQ::spells::CastingSlot slot, bool isproc = false); bool DoCastingChecksOnCaster(int32 spell_id, EQ::spells::CastingSlot slot); @@ -409,7 +418,7 @@ public: bool IsAffectedByBuff(uint16 spell_id); bool IsAffectedByBuffByGlobalGroup(GlobalGroup group); void BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration); - int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1, bool disable_buff_overrwrite = false); + int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1, bool disable_buff_overwrite = false); int CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite = false); int CalcBuffDuration(Mob *caster, Mob *target, uint16 spell_id, int32 caster_level_override = -1); void SendPetBuffsToClient(); @@ -464,8 +473,8 @@ public: void GetAppearenceEffects(); void ClearAppearenceEffects(); void SendSavedAppearenceEffects(Client *receiver); - void SetBuffDuration(int32 spell_id, int32 duration = 0); - void ApplySpellBuff(int32 spell_id, int32 duration = 0); + void SetBuffDuration(int spell_id, int duration = 0); + void ApplySpellBuff(int spell_id, int duration = 0); int GetBuffStatValueBySpell(int32 spell_id, const char* stat_identifier); int GetBuffStatValueBySlot(uint8 slot, const char* stat_identifier); @@ -727,9 +736,6 @@ public: bool IsOnFeignMemory(Mob *attacker) const; void PrintHateListToClient(Client *who) { hate_list.PrintHateListToClient(who); } std::list& GetHateList() { return hate_list.GetHateList(); } - std::list GetFilteredHateList(uint8 filter_type = EntityFilterTypes::All, uint32 distance = 0) { return hate_list.GetFilteredHateList(distance, filter_type); } - void DamageHateList(int64 damage, uint32 distance = 0, uint8 filter_type = EntityFilterTypes::All, bool is_percentage = false) { hate_list.DamageHateList(damage, distance, filter_type, is_percentage); } - void DamageArea(int64 damage, uint32 distance = 0, uint8 filter_type = EntityFilterTypes::All, bool is_percentage = false) { entity_list.DamageArea(this, damage, distance, filter_type, is_percentage); } bool CheckLosFN(Mob* other); bool CheckLosFN(float posX, float posY, float posZ, float mobSize); static bool CheckLosFN(glm::vec3 posWatcher, float sizeWatcher, glm::vec3 posTarget, float sizeTarget); @@ -737,6 +743,31 @@ public: inline bool CheckLastLosState() const { return last_los_check; } std::string GetMobDescription(); + std::list GetFilteredHateList( + EntityFilterType filter_type = EntityFilterType::All, + uint32 distance = 0 + ) { + return hate_list.GetFilteredHateList(filter_type, distance); + } + + void DamageHateList( + int64 damage, + uint32 distance = 0, + EntityFilterType filter_type = EntityFilterType::All, + bool is_percentage = false + ) { + hate_list.DamageHateList(damage, distance, filter_type, is_percentage); + } + + void DamageArea( + int64 damage, + uint32 distance = 0, + EntityFilterType filter_type = EntityFilterType::All, + bool is_percentage = false + ) { + entity_list.DamageArea(this, damage, distance, filter_type, is_percentage); + } + //Quest void CameraEffect(uint32 duration, float intensity, Client *c = nullptr, bool global = false); inline bool GetQglobal() const { return qglobal; } diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index c7451ece6..43115b966 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -2506,6 +2506,148 @@ void Perl_Client_SendMarqueeMessage(Client* self, uint32 type, uint32 priority, self->SendMarqueeMessage(type, priority, fade_in, fade_out, duration, message); } +void Perl_Client_ApplySpell(Client* self, int spell_id) +{ + self->ApplySpell(spell_id); +} + +void Perl_Client_ApplySpell(Client* self, int spell_id, int duration) +{ + self->ApplySpell(spell_id, duration); +} + +void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, bool allow_pets) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +#ifdef BOTS +void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots); +} +#endif + +void Perl_Client_ApplySpellGroup(Client* self, int spell_id) +{ + self->ApplySpell(spell_id, 0, ApplySpellType::Group); +} + +void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Group); +} + +void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, bool allow_pets) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets); +} + +#ifdef BOTS +void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots); +} +#endif + +void Perl_Client_ApplySpellRaid(Client* self, int spell_id) +{ + self->ApplySpell(spell_id, 0, ApplySpellType::Raid); +} + +void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Raid); +} + +void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, bool allow_pets) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets); +} + +void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only); +} + +#ifdef BOTS +void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots); +} +#endif + +void Perl_Client_SetSpellDuration(Client* self, int spell_id) +{ + self->SetSpellDuration(spell_id); +} + +void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration) +{ + self->SetSpellDuration(spell_id, duration); +} + +void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, bool allow_pets) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +#ifdef BOTS +void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots); +} +#endif + +void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id) +{ + self->SetSpellDuration(spell_id, 0, ApplySpellType::Group); +} + +void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group); +} + +void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, bool allow_pets) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets); +} + +#ifdef BOTS +void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots); +} +#endif + +void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id) +{ + self->ApplySpell(spell_id, 0, ApplySpellType::Raid); +} + +void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Raid); +} + +void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, bool allow_pets) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets); +} + +void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only); +} + +#ifdef BOTS +void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots); +} +#endif + #ifdef BOTS int Perl_Client_GetBotRequiredLevel(Client* self) @@ -2601,6 +2743,25 @@ void perl_register_client() package.add("AddPVPPoints", &Perl_Client_AddPVPPoints); package.add("AddSkill", &Perl_Client_AddSkill); package.add("Admin", &Perl_Client_Admin); + package.add("ApplySpell", (void(*)(Client*, int))&Perl_Client_ApplySpell); + package.add("ApplySpell", (void(*)(Client*, int, int))&Perl_Client_ApplySpell); + package.add("ApplySpell", (void(*)(Client*, int, int, bool))&Perl_Client_ApplySpell); +#ifdef BOTS + package.add("ApplySpell", (void(*)(Client*, int, int, bool, bool))&Perl_Client_ApplySpell); +#endif + package.add("ApplySpellGroup", (void(*)(Client*, int))&Perl_Client_ApplySpellGroup); + package.add("ApplySpellGroup", (void(*)(Client*, int, int))&Perl_Client_ApplySpellGroup); + package.add("ApplySpellGroup", (void(*)(Client*, int, int, bool))&Perl_Client_ApplySpellGroup); +#ifdef BOTS + package.add("ApplySpellGroup", (void(*)(Client*, int, int, bool, bool))&Perl_Client_ApplySpellGroup); +#endif + package.add("ApplySpellRaid", (void(*)(Client*, int))&Perl_Client_ApplySpellRaid); + package.add("ApplySpellRaid", (void(*)(Client*, int, int))&Perl_Client_ApplySpellRaid); + package.add("ApplySpellRaid", (void(*)(Client*, int, int, bool))&Perl_Client_ApplySpellRaid); + package.add("ApplySpellRaid", (void(*)(Client*, int, int, bool, bool))&Perl_Client_ApplySpellRaid); +#ifdef BOTS + package.add("ApplySpellRaid", (void(*)(Client*, int, int, bool, bool, bool))&Perl_Client_ApplySpellRaid); +#endif package.add("AssignTask", (void(*)(Client*, int))&Perl_Client_AssignTask); package.add("AssignTask", (void(*)(Client*, int, int))&Perl_Client_AssignTask); package.add("AssignTask", (void(*)(Client*, int, int, bool))&Perl_Client_AssignTask); @@ -2983,6 +3144,25 @@ void perl_register_client() package.add("SetSecondaryWeaponOrnamentation", &Perl_Client_SetSecondaryWeaponOrnamentation); package.add("SetSkill", &Perl_Client_SetSkill); package.add("SetSkillPoints", &Perl_Client_SetSkillPoints); + package.add("SetSpellDuration", (void(*)(Client*, int))&Perl_Client_SetSpellDuration); + package.add("SetSpellDuration", (void(*)(Client*, int, int))&Perl_Client_SetSpellDuration); + package.add("SetSpellDuration", (void(*)(Client*, int, int, bool))&Perl_Client_SetSpellDuration); +#ifdef BOTS + package.add("SetSpellDuration", (void(*)(Client*, int, int, bool, bool))&Perl_Client_SetSpellDuration); +#endif + package.add("SetSpellDurationGroup", (void(*)(Client*, int))&Perl_Client_SetSpellDurationGroup); + package.add("SetSpellDurationGroup", (void(*)(Client*, int, int))&Perl_Client_SetSpellDurationGroup); + package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, bool))&Perl_Client_SetSpellDurationGroup); +#ifdef BOTS + package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, bool, bool))&Perl_Client_SetSpellDurationGroup); +#endif + package.add("SetSpellDurationRaid", (void(*)(Client*, int))&Perl_Client_SetSpellDurationRaid); + package.add("SetSpellDurationRaid", (void(*)(Client*, int, int))&Perl_Client_SetSpellDurationRaid); + package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, bool))&Perl_Client_SetSpellDurationRaid); + package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, bool, bool))&Perl_Client_SetSpellDurationRaid); +#ifdef BOTS + package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, bool, bool, bool))&Perl_Client_SetSpellDurationRaid); +#endif package.add("SetStartZone", (void(*)(Client*, uint32))&Perl_Client_SetStartZone); package.add("SetStartZone", (void(*)(Client*, uint32, float, float, float))&Perl_Client_SetStartZone); package.add("SetStartZone", (void(*)(Client*, uint32, float, float, float, float))&Perl_Client_SetStartZone); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 008c31a8e..ea67a1927 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -2346,7 +2346,7 @@ perl::array Perl_Mob_GetHateListByDistance(Mob* self, uint32 distance) // @categ { perl::array result; - auto h_list = self->GetFilteredHateList(distance, EntityFilterTypes::All); + auto h_list = self->GetFilteredHateList(EntityFilterType::All, distance); for (auto h : h_list) { result.push_back(h); } @@ -2491,57 +2491,57 @@ void Perl_Mob_DamageArea(Mob* self, int64 damage) // @categories Hate and Aggro void Perl_Mob_DamageArea(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::All); + self->DamageArea(damage, distance, EntityFilterType::All); } void Perl_Mob_DamageAreaPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::All, true); + self->DamageArea(damage, 0, EntityFilterType::All, true); } void Perl_Mob_DamageAreaPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::All, true); + self->DamageArea(damage, distance, EntityFilterType::All, true); } void Perl_Mob_DamageAreaClients(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::Clients); + self->DamageArea(damage, 0, EntityFilterType::Clients); } void Perl_Mob_DamageAreaClients(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::Clients); + self->DamageArea(damage, distance, EntityFilterType::Clients); } void Perl_Mob_DamageAreaClientsPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::Clients, true); + self->DamageArea(damage, 0, EntityFilterType::Clients, true); } void Perl_Mob_DamageAreaClientsPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::Clients, true); + self->DamageArea(damage, distance, EntityFilterType::Clients, true); } void Perl_Mob_DamageAreaNPCs(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::NPCs); + self->DamageArea(damage, 0, EntityFilterType::NPCs); } void Perl_Mob_DamageAreaNPCs(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::NPCs); + self->DamageArea(damage, distance, EntityFilterType::NPCs); } void Perl_Mob_DamageAreaNPCsPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::NPCs, true); + self->DamageArea(damage, 0, EntityFilterType::NPCs, true); } void Perl_Mob_DamageAreaNPCsPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::NPCs, true); + self->DamageArea(damage, distance, EntityFilterType::NPCs, true); } void Perl_Mob_DamageHateList(Mob* self, int64 damage) // @categories Hate and Aggro @@ -2551,64 +2551,64 @@ void Perl_Mob_DamageHateList(Mob* self, int64 damage) // @categories Hate and Ag void Perl_Mob_DamageHateList(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::All); + self->DamageHateList(damage, distance, EntityFilterType::All); } void Perl_Mob_DamageHateListPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::All, true); + self->DamageHateList(damage, 0, EntityFilterType::All, true); } void Perl_Mob_DamageHateListPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::All, true); + self->DamageHateList(damage, distance, EntityFilterType::All, true); } void Perl_Mob_DamageHateListClients(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::Clients); + self->DamageHateList(damage, 0, EntityFilterType::Clients); } void Perl_Mob_DamageHateListClients(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::Clients); + self->DamageHateList(damage, distance, EntityFilterType::Clients); } void Perl_Mob_DamageHateListClientsPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::Clients, true); + self->DamageHateList(damage, 0, EntityFilterType::Clients, true); } void Perl_Mob_DamageHateListClientsPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::Clients, true); + self->DamageHateList(damage, distance, EntityFilterType::Clients, true); } void Perl_Mob_DamageHateListNPCs(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::NPCs); + self->DamageHateList(damage, 0, EntityFilterType::NPCs); } void Perl_Mob_DamageHateListNPCs(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::NPCs); + self->DamageHateList(damage, distance, EntityFilterType::NPCs); } void Perl_Mob_DamageHateListNPCsPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::NPCs, true); + self->DamageHateList(damage, 0, EntityFilterType::NPCs, true); } void Perl_Mob_DamageHateListNPCsPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::NPCs, true); + self->DamageHateList(damage, distance, EntityFilterType::NPCs, true); } perl::array Perl_Mob_GetHateListClients(Mob* self) { perl::array result; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::Clients); + auto h_list = self->GetFilteredHateList(EntityFilterType::Clients); for (auto h : h_list) { result.push_back(h); } @@ -2620,7 +2620,7 @@ perl::array Perl_Mob_GetHateListClients(Mob* self, uint32 distance) { perl::array result; - auto h_list = self->GetFilteredHateList(distance, EntityFilterTypes::Clients); + auto h_list = self->GetFilteredHateList(EntityFilterType::Clients, distance); for (auto h : h_list) { result.push_back(h); } @@ -2632,7 +2632,7 @@ perl::array Perl_Mob_GetHateListNPCs(Mob* self) { perl::array result; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::NPCs); + auto h_list = self->GetFilteredHateList(EntityFilterType::NPCs); for (auto h : h_list) { result.push_back(h); } @@ -2644,7 +2644,7 @@ perl::array Perl_Mob_GetHateListNPCs(Mob* self, uint32 distance) { perl::array result; - auto h_list = self->GetFilteredHateList(distance, EntityFilterTypes::NPCs); + auto h_list = self->GetFilteredHateList(EntityFilterType::NPCs, distance); for (auto h : h_list) { result.push_back(h); } @@ -2655,49 +2655,49 @@ perl::array Perl_Mob_GetHateListNPCs(Mob* self, uint32 distance) #ifdef BOTS void Perl_Mob_DamageAreaBots(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::Bots); + self->DamageArea(damage, 0, EntityFilterType::Bots); } void Perl_Mob_DamageAreaBots(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::Bots); + self->DamageArea(damage, distance, EntityFilterType::Bots); } void Perl_Mob_DamageAreaBotsPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageArea(damage, 0, EntityFilterTypes::Bots, true); + self->DamageArea(damage, 0, EntityFilterType::Bots, true); } void Perl_Mob_DamageAreaBotsPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageArea(damage, distance, EntityFilterTypes::Bots, true); + self->DamageArea(damage, distance, EntityFilterType::Bots, true); } void Perl_Mob_DamageHateListBots(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::Bots); + self->DamageHateList(damage, 0, EntityFilterType::Bots); } void Perl_Mob_DamageHateListBots(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::Bots); + self->DamageHateList(damage, distance, EntityFilterType::Bots); } void Perl_Mob_DamageHateListBotsPercentage(Mob* self, int64 damage) // @categories Hate and Aggro { - self->DamageHateList(damage, 0, EntityFilterTypes::Bots, true); + self->DamageHateList(damage, 0, EntityFilterType::Bots, true); } void Perl_Mob_DamageHateListBotsPercentage(Mob* self, int64 damage, uint32 distance) // @categories Hate and Aggro { - self->DamageHateList(damage, distance, EntityFilterTypes::Bots, true); + self->DamageHateList(damage, distance, EntityFilterType::Bots, true); } perl::array Perl_Mob_GetHateListBots(Mob* self) { perl::array result; - auto h_list = self->GetFilteredHateList(EntityFilterTypes::Bots); + auto h_list = self->GetFilteredHateList(EntityFilterType::Bots); for (auto h : h_list) { result.push_back(h); } @@ -2709,7 +2709,7 @@ perl::array Perl_Mob_GetHateListBots(Mob* self, uint32 distance) { perl::array result; - auto h_list = self->GetFilteredHateList(distance, EntityFilterTypes::Bots); + auto h_list = self->GetFilteredHateList(EntityFilterType::Bots, distance); for (auto h : h_list) { result.push_back(h); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 06a2aedac..7aaf7a61e 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -46,7 +46,7 @@ extern WorldServer worldserver; // the spell can still fail here, if the buff can't stack // in this case false will be returned, true otherwise -bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_override, int reflect_effectiveness, int32 duration_override, bool disable_buff_overrwrite) +bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_override, int reflect_effectiveness, int32 duration_override, bool disable_buff_overwrite) { int caster_level, buffslot, effect, effect_value, i; EQ::ItemInstance *SummonedItem=nullptr; @@ -119,7 +119,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove } else { - buffslot = AddBuff(caster, spell_id, duration_override, -1, disable_buff_overrwrite); + buffslot = AddBuff(caster, spell_id, duration_override, -1, disable_buff_overwrite); } if(buffslot == -1) // stacking failure return false; @@ -186,7 +186,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove return true; } #endif - } + } if(IsVirusSpell(spell_id)) { @@ -8091,7 +8091,7 @@ bool Mob::PassCastRestriction(int value) } else if (!IsNonSpellFighterClass(GetClass()) && GetManaRatio() <= 10) { return true; - } + } else if (IsHybridClass(GetClass()) && CastToClient()->GetEndurancePercent() <= 10) { return true; } @@ -10292,7 +10292,7 @@ bool Mob::HasPersistDeathIllusion(int32 spell_id) { return false; } -void Mob::SetBuffDuration(int32 spell_id, int32 duration) { +void Mob::SetBuffDuration(int spell_id, int duration) { /* Will refresh the buff with specified spell_id to the specified duration @@ -10331,7 +10331,7 @@ void Mob::SetBuffDuration(int32 spell_id, int32 duration) { } } -void Mob::ApplySpellBuff(int32 spell_id, int32 duration) +void Mob::ApplySpellBuff(int spell_id, int duration) { /* Used for quest command to apply a new buff with custom duration. @@ -10340,11 +10340,12 @@ void Mob::ApplySpellBuff(int32 spell_id, int32 duration) if (!IsValidSpell(spell_id)) { return; } + if (!spells[spell_id].buff_duration) { return; } - if (duration < -1) { + if (duration <= -1) { duration = PERMANENT_BUFF_DURATION; } diff --git a/zone/spells.cpp b/zone/spells.cpp index 03b4b7d95..2a05f2764 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3274,7 +3274,7 @@ bool Mob::HasDiscBuff() // stacking problems, and -2 if this is not a buff // if caster is null, the buff will be added with the caster level being // the level of the mob -int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_override, bool disable_buff_overrwrite) +int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_override, bool disable_buff_overwrite) { int buffslot, ret, caster_level, emptyslot = -1; bool will_overwrite = false; @@ -3370,7 +3370,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid // at this point we know that this buff will stick, but we have // to remove some other buffs already worn if will_overwrite is true - if (will_overwrite && !disable_buff_overrwrite) { + if (will_overwrite && !disable_buff_overwrite) { std::vector::iterator cur, end; cur = overwrite_slots.begin(); end = overwrite_slots.end(); @@ -3515,14 +3515,21 @@ int Mob::CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite) // and if you don't want effects just return false. interrupting here will // break stuff // -bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectiveness, bool use_resist_adjust, int16 resist_adjust, - bool isproc, int level_override, int32 duration_override, bool disable_buff_overrwrite) -{ +bool Mob::SpellOnTarget( + uint16 spell_id, + Mob *spelltar, + int reflect_effectiveness, + bool use_resist_adjust, + int16 resist_adjust, + bool isproc, + int level_override, + int duration_override, + bool disable_buff_overwrite +) { auto spellOwner = GetOwnerOrSelf(); // well we can't cast a spell on target without a target - if(!spelltar) - { + if (!spelltar) { LogSpells("Unable to apply spell [{}] without a target", spell_id); Message(Chat::Red, "SOT: You must have a target for this spell."); return false; @@ -3532,11 +3539,17 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes return false; } - if (!IsValidSpell(spell_id)) + if (!IsValidSpell(spell_id)) { return false; + } - if(IsDetrimentalSpell(spell_id) && !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id) && !IsEffectInSpell(spell_id, SE_BindSight)) { - if(!IsClient() || !CastToClient()->GetGM()) { + if ( + IsDetrimentalSpell(spell_id) && + !IsAttackAllowed(spelltar, true) && + !IsResurrectionEffects(spell_id) && + !IsEffectInSpell(spell_id, SE_BindSight) + ) { + if (!IsClient() || !CastToClient()->GetGM()) { MessageString(Chat::SpellFailure, SPELL_NO_HOLD); return false; } @@ -3548,12 +3561,28 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes // these target types skip pcnpc only check (according to dev quotes) // other AE spells this is redundant, oh well // 1 = PCs, 2 = NPCs - if (spells[spell_id].pcnpc_only_flag && spells[spell_id].target_type != ST_AETargetHateList && - spells[spell_id].target_type != ST_HateList) { - if (spells[spell_id].pcnpc_only_flag == 1 && !spelltar->IsClient() && !spelltar->IsMerc() && !spelltar->IsBot()) + if ( + spells[spell_id].pcnpc_only_flag && + spells[spell_id].target_type != ST_AETargetHateList && + spells[spell_id].target_type != ST_HateList + ) { + if ( + spells[spell_id].pcnpc_only_flag == 1 && + !spelltar->IsClient() && + !spelltar->IsMerc() && + !spelltar->IsBot() + ) { return false; - else if (spells[spell_id].pcnpc_only_flag == 2 && (spelltar->IsClient() || spelltar->IsMerc() || spelltar->IsBot())) + } else if ( + spells[spell_id].pcnpc_only_flag == 2 && + ( + spelltar->IsClient() || + spelltar->IsMerc() || + spelltar->IsBot() + ) + ) { return false; + } } uint16 caster_level = level_override > 0 ? level_override : GetCasterLevel(spell_id); @@ -3570,12 +3599,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes Action_Struct* action = (Action_Struct*) action_packet->pBuffer; // select source - if(IsClient() && CastToClient()->GMHideMe()) - { + if (IsClient() && CastToClient()->GMHideMe()) { action->source = spelltar->GetID(); - } - else - { + } else { action->source = GetID(); // this is a hack that makes detrimental buffs work client to client // TODO figure out how to do this right @@ -3591,12 +3617,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes } // select target - if (IsEffectInSpell(spell_id, SE_BindSight)) - { + if (IsEffectInSpell(spell_id, SE_BindSight)) { action->target = GetID(); - } - else - { + } else { action->target = spelltar->GetID(); } @@ -3609,10 +3632,13 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes action->instrument_mod = GetInstrumentMod(spell_id); action->effect_flag = 0; - if(spelltar != this && spelltar->IsClient()) // send to target + if (spelltar != this && spelltar->IsClient()) { // send to target spelltar->CastToClient()->QueuePacket(action_packet); - if(IsClient()) // send to caster + } + + if (IsClient()) { // send to caster CastToClient()->QueuePacket(action_packet); + } // send to people in the area, ignoring caster and target entity_list.QueueCloseClients( @@ -3626,12 +3652,13 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes ); /* Send the EVENT_CAST_ON event */ - std::string export_string = fmt::format( + const auto export_string = fmt::format( "{} {} {}", spell_id, GetID(), caster_level ); + if (spelltar->IsNPC()) { parse->EventNPC(EVENT_CAST_ON, spelltar->CastToNPC(), this, export_string, 0); } else if (spelltar->IsClient()) { @@ -3642,7 +3669,6 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes #endif } - mod_spell_cast(spell_id, spelltar, reflect_effectiveness, use_resist_adjust, resist_adjust, isproc); if (!DoCastingChecksOnTarget(false, spell_id, spelltar)) { @@ -3654,25 +3680,37 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes if (RuleB(Spells, EnableBlockedBuffs)) { // We return true here since the caster's client should act like normal if (spelltar->IsBlockedBuff(spell_id)) { - LogSpells("Spell [{}] not applied to [{}] as it is a Blocked Buff", - spell_id, spelltar->GetName()); + LogSpells( + "Spell [{}] not applied to [{}] as it is a Blocked Buff", + spell_id, + spelltar->GetName() + ); safe_delete(action_packet); return true; } - if (spelltar->IsPet() && spelltar->GetOwner() && - spelltar->GetOwner()->IsBlockedPetBuff(spell_id)) { - LogSpells("Spell [{}] not applied to [{}] ([{}]'s pet) as it is a Pet Blocked Buff", - spell_id, spelltar->GetName(), spelltar->GetOwner()->GetName()); + if ( + spelltar->IsPet() && + spelltar->GetOwner() && + spelltar->GetOwner()->IsBlockedPetBuff(spell_id) + ) { + LogSpells( + "Spell [{}] not applied to [{}] ([{}]'s pet) as it is a Pet Blocked Buff", + spell_id, + spelltar->GetName(), + spelltar->GetOwner()->GetName() + ); safe_delete(action_packet); return true; } } // invuln mobs can't be affected by any spells, good or bad, except if caster is casting a spell with 'cast_not_standing' on self. - if ((spelltar->GetInvul() && !spelltar->DivineAura()) || + if ( + (spelltar->GetInvul() && !spelltar->DivineAura()) || (spelltar != this && spelltar->DivineAura()) || - (spelltar == this && spelltar->DivineAura() && !IgnoreCastingRestriction(spell_id))) { + (spelltar == this && spelltar->DivineAura() && !IgnoreCastingRestriction(spell_id)) + ) { LogSpells("Casting spell [{}] on [{}] aborted: they are invulnerable", spell_id, spelltar->GetName()); safe_delete(action_packet); return false; @@ -3680,7 +3718,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes //cannot hurt untargetable mobs bodyType bt = spelltar->GetBodyType(); - if(bt == BT_NoTarget || bt == BT_NoTarget2) { + if (bt == BT_NoTarget || bt == BT_NoTarget2) { if (RuleB(Pets, UnTargetableSwarmPet)) { if (spelltar->IsNPC()) { if (!spelltar->CastToNPC()->GetSwarmOwner()) { @@ -3704,30 +3742,24 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes // Not sure if all 3 should be stacking //This is not live like behavior (~Kayen confirmed 2/2/22) if (!RuleB(Spells, AllowDoubleInvis)) { - if (IsEffectInSpell(spell_id, SE_Invisibility)) - { - if (spelltar->invisible) - { + if (IsEffectInSpell(spell_id, SE_Invisibility)) { + if (spelltar->invisible) { spelltar->MessageString(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } } - if (IsEffectInSpell(spell_id, SE_InvisVsUndead)) - { - if (spelltar->invisible_undead) - { + if (IsEffectInSpell(spell_id, SE_InvisVsUndead)) { + if (spelltar->invisible_undead) { spelltar->MessageString(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } } - if (IsEffectInSpell(spell_id, SE_InvisVsAnimals)) - { - if (spelltar->invisible_animals) - { + if (IsEffectInSpell(spell_id, SE_InvisVsAnimals)) { + if (spelltar->invisible_animals) { spelltar->MessageString(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; @@ -3735,15 +3767,10 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes } } - if(!(IsClient() && CastToClient()->GetGM()) && !IsHarmonySpell(spell_id)) // GMs can cast on anything - { + if (!(IsClient() && CastToClient()->GetGM()) && !IsHarmonySpell(spell_id)) {// GMs can cast on anything // Beneficial spells check - if(IsBeneficialSpell(spell_id)) - { - if(IsClient() && //let NPCs do beneficial spells on anybody if they want, should be the job of the AI, not the spell code to prevent this from going wrong - spelltar != this) - { - + if (IsBeneficialSpell(spell_id)) { + if (IsClient() && spelltar != this) {//let NPCs do beneficial spells on anybody if they want, should be the job of the AI, not the spell code to prevent this from going wrong Client* pClient = nullptr; Raid* pRaid = nullptr; Group* pBasicGroup = nullptr; @@ -3765,60 +3792,89 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes pClient = CastToClient(); pRaid = entity_list.GetRaidByClient(pClient); pBasicGroup = entity_list.GetGroupByMob(this); - if(pRaid) + if (pRaid) { nGroup = pRaid->GetGroup(pClient) + 1; + } //Target client pointers - if(spelltar->IsClient()) - { + if (spelltar->IsClient()) { pClientTarget = spelltar->CastToClient(); pRaidTarget = entity_list.GetRaidByClient(pClientTarget); pBasicGroupTarget = entity_list.GetGroupByMob(spelltar); - if(pRaidTarget) + if (pRaidTarget) { nGroupTarget = pRaidTarget->GetGroup(pClientTarget) + 1; + } } - if(spelltar->IsPet()) - { + if (spelltar->IsPet()) { Mob *owner = spelltar->GetOwner(); - if(owner->IsClient()) - { + if (owner->IsClient()) { pClientTargetPet = owner->CastToClient(); pRaidTargetPet = entity_list.GetRaidByClient(pClientTargetPet); pBasicGroupTargetPet = entity_list.GetGroupByMob(owner); - if(pRaidTargetPet) + if (pRaidTargetPet) { nGroupTargetPet = pRaidTargetPet->GetGroup(pClientTargetPet) + 1; + } } } - if((!IsAllianceSpellLine(spell_id) && !IsBeneficialAllowed(spelltar)) || + if ( + (!IsAllianceSpellLine(spell_id) && !IsBeneficialAllowed(spelltar)) || (IsGroupOnlySpell(spell_id) && !( - (pBasicGroup && ((pBasicGroup == pBasicGroupTarget) || (pBasicGroup == pBasicGroupTargetPet))) || //Basic Group - - ((nGroup != cnWTF) && ((nGroup == nGroupTarget) || (nGroup == nGroupTargetPet))) || //Raid group - - (spelltar == GetPet()) //should be able to cast grp spells on self and pet despite grped status. + ( + pBasicGroup && + ( + pBasicGroup == pBasicGroupTarget || + pBasicGroup == pBasicGroupTargetPet + ) + ) || //Basic Group + ( + nGroup != cnWTF && + ( + nGroup == nGroupTarget || + nGroup == nGroupTargetPet + ) + ) || //Raid group + spelltar == GetPet() //should be able to cast grp spells on self and pet despite grped status. ) ) - ) - { - if(spells[spell_id].target_type == ST_AEBard) { + ) { + if (spells[spell_id].target_type == ST_AEBard) { //if it was a beneficial AE bard song don't spam the window that it would not hold - LogSpells("Beneficial ae bard song [{}] can't take hold [{}] -> [{}], IBA? [{}]", spell_id, GetName(), spelltar->GetName(), IsBeneficialAllowed(spelltar)); + LogSpells( + "Beneficial ae bard song [{}] can't take hold [{}] -> [{}], IBA? [{}]", + spell_id, + GetName(), + spelltar->GetName(), + IsBeneficialAllowed(spelltar) + ); } else { - LogSpells("Beneficial spell [{}] can't take hold [{}] -> [{}], IBA? [{}]", spell_id, GetName(), spelltar->GetName(), IsBeneficialAllowed(spelltar)); + LogSpells( + "Beneficial spell [{}] can't take hold [{}] -> [{}], IBA? [{}]", + spell_id, + GetName(), + spelltar->GetName(), + IsBeneficialAllowed(spelltar) + ); MessageString(Chat::SpellFailure, SPELL_NO_HOLD); } safe_delete(action_packet); return false; } } - } - else if ( !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id) && !IsEffectInSpell(spell_id, SE_BindSight)) // Detrimental spells - PVP check - { - LogSpells("Detrimental spell [{}] can't take hold [{}] -> [{}]", spell_id, GetName(), spelltar->GetName()); + } else if ( + !IsAttackAllowed(spelltar, true) && + !IsResurrectionEffects(spell_id) && + !IsEffectInSpell(spell_id, SE_BindSight) + ) { // Detrimental spells - PVP check + LogSpells( + "Detrimental spell [{}] can't take hold [{}] -> [{}]", + spell_id, + GetName(), + spelltar->GetName() + ); spelltar->MessageString(Chat::SpellFailure, YOU_ARE_PROTECTED, GetCleanName()); safe_delete(action_packet); return false; @@ -3829,8 +3885,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes // but we need to check special cases and resists // check immunities - if(spelltar->IsImmuneToSpell(spell_id, this)) - { + if (spelltar->IsImmuneToSpell(spell_id, this)) { //the above call does the message to the client if needed LogSpells("Spell [{}] can't take hold due to immunity [{}] -> [{}]", spell_id, GetName(), spelltar->GetName()); safe_delete(action_packet); @@ -3838,30 +3893,36 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes } //check for AE_Undead - if(spells[spell_id].target_type == ST_UndeadAE){ - if(spelltar->GetBodyType() != BT_SummonedUndead && + if (spells[spell_id].target_type == ST_UndeadAE){ + if ( + spelltar->GetBodyType() != BT_SummonedUndead && spelltar->GetBodyType() != BT_Undead && - spelltar->GetBodyType() != BT_Vampire) - { + spelltar->GetBodyType() != BT_Vampire + ) { safe_delete(action_packet); return false; } } + //Need this to account for special AOE cases. - if (IsClient() && IsHarmonySpell(spell_id) && !HarmonySpellLevelCheck(spell_id, spelltar)) { + if ( + IsClient() && + IsHarmonySpell(spell_id) && + !HarmonySpellLevelCheck(spell_id, spelltar) + ) { MessageString(Chat::SpellFailure, SPELL_NO_EFFECT); safe_delete(action_packet); return false; } // Block next spell effect should be used up first(since its blocking the next spell) - if(CanBlockSpell()) { + if (CanBlockSpell()) { int buff_count = GetMaxTotalSlots(); int focus = 0; - for (int b=0; b < buff_count; b++) { - if(IsEffectInSpell(buffs[b].spellid, SE_BlockNextSpellFocus)) { + for (int b = 0; b < buff_count; b++) { + if (IsEffectInSpell(buffs[b].spellid, SE_BlockNextSpellFocus)) { focus = CalcFocusEffect(focusBlockNextSpell, buffs[b].spellid, spell_id); - if(focus) { + if (focus) { CheckNumHitsRemaining(NumHit::MatchingSpells, b); MessageString(Chat::SpellFailure, SPELL_WOULDNT_HOLD); safe_delete(action_packet); @@ -3883,67 +3944,83 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes There are a few spells in database that are not detrimental that have Reflectable field set, however from testing, they do not actually reflect. */ - if(spells[spell_id].reflectable && !reflect_effectiveness && spelltar && this != spelltar && IsDetrimentalSpell(spell_id) && - (spelltar->spellbonuses.reflect[SBIndex::REFLECT_CHANCE] || spelltar->aabonuses.reflect[SBIndex::REFLECT_CHANCE] || spelltar->itembonuses.reflect[SBIndex::REFLECT_CHANCE])) { + if ( + spells[spell_id].reflectable && + !reflect_effectiveness && + spelltar && + this != spelltar && + IsDetrimentalSpell(spell_id) && + ( + spelltar->spellbonuses.reflect[SBIndex::REFLECT_CHANCE] || + spelltar->aabonuses.reflect[SBIndex::REFLECT_CHANCE] || + spelltar->itembonuses.reflect[SBIndex::REFLECT_CHANCE] + ) + ) { bool can_spell_reflect = false; - switch(RuleI(Spells, ReflectType)) - { - case REFLECT_DISABLED: - break; - - case REFLECT_SINGLE_TARGET_SPELLS_ONLY: - { - if(spells[spell_id].target_type == ST_Target) { - for(int y = 0; y < 16; y++) { + switch (RuleI(Spells, ReflectType)) { + case REFLECT_SINGLE_TARGET_SPELLS_ONLY: { + if (spells[spell_id].target_type == ST_Target) { + for (int y = 0; y < 16; y++) { if (spells[spell_id].classes[y] < 255) { can_spell_reflect = true; } } } + break; } - case REFLECT_ALL_PLAYER_SPELLS: - { - for(int y = 0; y < 16; y++) { + case REFLECT_ALL_PLAYER_SPELLS: { + for (int y = 0; y < 16; y++) { if (spells[spell_id].classes[y] < 255) { can_spell_reflect = true; } } + break; } - case RELFECT_ALL_SINGLE_TARGET_SPELLS: - { + case RELFECT_ALL_SINGLE_TARGET_SPELLS: { if (spells[spell_id].target_type == ST_Target) { can_spell_reflect = true; } + break; } - case REFLECT_ALL_SPELLS: //This is live like behavior + case REFLECT_ALL_SPELLS: {//This is live like behavior can_spell_reflect = true; - - default: + } + case REFLECT_DISABLED: + default: { break; + } } - if (can_spell_reflect) { + if (can_spell_reflect) { int reflect_resist_adjust = 0; int reflect_effectiveness_mod = 0; //Need value of 100 to do baseline unmodified damage. - if (spelltar->spellbonuses.reflect[SBIndex::REFLECT_CHANCE] && zone->random.Roll(spelltar->spellbonuses.reflect[SBIndex::REFLECT_CHANCE])) { - reflect_resist_adjust = spelltar->spellbonuses.reflect[SBIndex::REFLECT_RESISTANCE_MOD]; - reflect_effectiveness_mod = spelltar->spellbonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] ? spelltar->spellbonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] : 100; - } - else if (spelltar->aabonuses.reflect[SBIndex::REFLECT_CHANCE] && zone->random.Roll(spelltar->aabonuses.reflect[SBIndex::REFLECT_CHANCE])) { + if ( + spelltar->spellbonuses.reflect[SBIndex::REFLECT_CHANCE] && + zone->random.Roll(spelltar->spellbonuses.reflect[SBIndex::REFLECT_CHANCE]) + ) { + reflect_resist_adjust = spelltar->spellbonuses.reflect[SBIndex::REFLECT_RESISTANCE_MOD]; + reflect_effectiveness_mod = spelltar->spellbonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] + ? spelltar->spellbonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] : 100; + } else if ( + spelltar->aabonuses.reflect[SBIndex::REFLECT_CHANCE] && + zone->random.Roll(spelltar->aabonuses.reflect[SBIndex::REFLECT_CHANCE]) + ) { reflect_effectiveness_mod = 100; reflect_resist_adjust = spelltar->aabonuses.reflect[SBIndex::REFLECT_RESISTANCE_MOD]; - } - else if (spelltar->itembonuses.reflect[SBIndex::REFLECT_CHANCE] && zone->random.Roll(spelltar->itembonuses.reflect[SBIndex::REFLECT_CHANCE])) { - reflect_resist_adjust = spelltar->itembonuses.reflect[SBIndex::REFLECT_RESISTANCE_MOD]; - reflect_effectiveness_mod = spelltar->itembonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] ? spelltar->itembonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] : 100; + } else if ( + spelltar->itembonuses.reflect[SBIndex::REFLECT_CHANCE] && + zone->random.Roll(spelltar->itembonuses.reflect[SBIndex::REFLECT_CHANCE]) + ) { + reflect_resist_adjust = spelltar->itembonuses.reflect[SBIndex::REFLECT_RESISTANCE_MOD]; + reflect_effectiveness_mod = spelltar->itembonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] + ? spelltar->itembonuses.reflect[SBIndex::REFLECT_DMG_EFFECTIVENESS] : 100; } if (reflect_effectiveness_mod) { - if (RuleB(Spells, ReflectMessagesClose)) { entity_list.MessageCloseString( this, /* Sender */ @@ -3954,8 +4031,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes GetCleanName(), /* Message 1 */ spelltar->GetCleanName() /* Message 2 */ ); - } - else { + } else { MessageString(Chat::Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); } @@ -3971,40 +4047,62 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes // resist check - every spell can be resisted, beneficial or not // add: ok this isn't true, eqlive's spell data is fucked up, buffs are // not all unresistable, so changing this to only check certain spells - if(IsResistableSpell(spell_id)) - { + if (IsResistableSpell(spell_id)) { spelltar->BreakInvisibleSpells(); //Any detrimental spell cast on you will drop invisible (can be AOE, non damage ect). - if (IsCharmSpell(spell_id) || IsMezSpell(spell_id) || IsFearSpell(spell_id)) - spell_effectiveness = spelltar->ResistSpell(spells[spell_id].resist_type, spell_id, this, use_resist_adjust, resist_adjust, true, false, false, level_override); - else - spell_effectiveness = spelltar->ResistSpell(spells[spell_id].resist_type, spell_id, this, use_resist_adjust, resist_adjust, false, false, false, level_override); + if ( + IsCharmSpell(spell_id) || + IsMezSpell(spell_id) || + IsFearSpell(spell_id) + ) { + spell_effectiveness = spelltar->ResistSpell( + spells[spell_id].resist_type, + spell_id, + this, + use_resist_adjust, + resist_adjust, + true, + false, + false, + level_override + ); + } else { + spell_effectiveness = spelltar->ResistSpell( + spells[spell_id].resist_type, + spell_id, + this, + use_resist_adjust, + resist_adjust, + false, + false, + false, + level_override + ); + } - if(spell_effectiveness < 100) - { - if(spell_effectiveness == 0 || !IsPartialCapableSpell(spell_id) ) - { + if (spell_effectiveness < 100) { + if (spell_effectiveness == 0 || !IsPartialCapableSpell(spell_id)) { LogSpells("Spell [{}] was completely resisted by [{}]", spell_id, spelltar->GetName()); if (spells[spell_id].resist_type == RESIST_PHYSICAL){ MessageString(Chat::SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); - } - else { + } else { MessageString(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name); spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); } if (spelltar->IsAIControlled()) { - int32 aggro = CheckAggroAmount(spell_id, spelltar); + auto aggro = CheckAggroAmount(spell_id, spelltar); if (aggro > 0) { - if (!IsHarmonySpell(spell_id)) + if (!IsHarmonySpell(spell_id)) { spelltar->AddToHateList(this, aggro); - else if (!spelltar->PassCharismaCheck(this, spell_id)) + } else if (!spelltar->PassCharismaCheck(this, spell_id)) { spelltar->AddToHateList(this, aggro); + } } else { - int newhate = spelltar->GetHateAmount(this) + aggro; - spelltar->SetHateAmountOnEnt(this, std::max(1, newhate)); + int64 newhate = spelltar->GetHateAmount(this) + aggro; + spelltar->SetHateAmountOnEnt(this, std::max(static_cast(1), newhate)); } } @@ -4025,33 +4123,41 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes spelltar->CastToClient()->BreakSneakWhenCastOn(this, false); spelltar->CastToClient()->BreakFeignDeathWhenCastOn(false); } - } - else - { + } else { spell_effectiveness = 100; } - if (spells[spell_id].feedbackable && (spelltar->spellbonuses.SpellDamageShield || spelltar->itembonuses.SpellDamageShield || spelltar->aabonuses.SpellDamageShield)) { + if ( + spells[spell_id].feedbackable && + ( + spelltar->spellbonuses.SpellDamageShield || + spelltar->itembonuses.SpellDamageShield || + spelltar->aabonuses.SpellDamageShield + ) + ) { spelltar->DamageShield(this, true); } - if (spelltar->IsAIControlled() && IsDetrimentalSpell(spell_id) && !IsHarmonySpell(spell_id)) { - int32 aggro_amount = CheckAggroAmount(spell_id, spelltar, isproc); + if ( + spelltar->IsAIControlled() && + IsDetrimentalSpell(spell_id) && + !IsHarmonySpell(spell_id) + ) { + auto aggro_amount = CheckAggroAmount(spell_id, spelltar, isproc); LogSpells("Spell [{}] cast on [{}] generated [{}] hate", spell_id, spelltar->GetName(), aggro_amount); if (aggro_amount > 0) { spelltar->AddToHateList(this, aggro_amount); } else { - int32 newhate = spelltar->GetHateAmount(this) + aggro_amount; - spelltar->SetHateAmountOnEnt(this, std::max(newhate, 1)); + int64 newhate = spelltar->GetHateAmount(this) + aggro_amount; + spelltar->SetHateAmountOnEnt(this, std::max(newhate, static_cast(1))); } } else if (IsBeneficialSpell(spell_id) && !IsSummonPCSpell(spell_id)) { if (this != spelltar && IsClient()){ if (spelltar->IsClient()) { CastToClient()->UpdateRestTimer(spelltar->CastToClient()->GetRestTimer()); - } - else if (spelltar->IsPet()) { - Mob *owner = spelltar->GetOwner(); + } else if (spelltar->IsPet()) { + auto* owner = spelltar->GetOwner(); if (owner && owner != this && owner->IsClient()) { CastToClient()->UpdateRestTimer(owner->CastToClient()->GetRestTimer()); } @@ -4059,23 +4165,39 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes } entity_list.AddHealAggro( - spelltar, this, - CheckHealAggroAmount(spell_id, spelltar, (spelltar->GetMaxHP() - spelltar->GetHP()))); + spelltar, + this, + CheckHealAggroAmount( + spell_id, + spelltar, + (spelltar->GetMaxHP() - spelltar->GetHP()) + ) + ); } // make sure spelltar is high enough level for the buff - if(RuleB(Spells, BuffLevelRestrictions) && !spelltar->CheckSpellLevelRestriction(spell_id)) - { + if (RuleB(Spells, BuffLevelRestrictions) && !spelltar->CheckSpellLevelRestriction(spell_id)) { LogSpells("Spell [{}] failed: recipient did not meet the level restrictions", spell_id); - if(!IsBardSong(spell_id)) + if (!IsBardSong(spell_id)) { MessageString(Chat::SpellFailure, SPELL_TOO_POWERFUL); + } + safe_delete(action_packet); return false; } // cause the effects to the target - if(!spelltar->SpellEffect(this, spell_id, spell_effectiveness, level_override, reflect_effectiveness, duration_override, disable_buff_overrwrite)) - { + if ( + !spelltar->SpellEffect( + this, + spell_id, + spell_effectiveness, + level_override, + reflect_effectiveness, + duration_override, + disable_buff_overwrite + ) + ) { // if SpellEffect returned false there's a problem applying the // spell. It's most likely a buff that can't stack. LogSpells("Spell [{}] could not apply its effects [{}] -> [{}]\n", spell_id, GetName(), spelltar->GetName()); @@ -4087,18 +4209,27 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes } //Check SE_Fc_Cast_Spell_On_Land SPA 481 on target, if hit by this spell and Conditions are Met then target will cast the specified spell. - if (spelltar) + if (spelltar) { spelltar->CastSpellOnLand(this, spell_id); + } - if (IsValidSpell(spells[spell_id].recourse_link) && spells[spell_id].recourse_link != spell_id) - SpellFinished(spells[spell_id].recourse_link, this, CastingSlot::Item, 0, -1, spells[spells[spell_id].recourse_link].resist_difficulty); + if (IsValidSpell(spells[spell_id].recourse_link) && spells[spell_id].recourse_link != spell_id) { + SpellFinished( + spells[spell_id].recourse_link, + this, + CastingSlot::Item, + 0, + -1, + spells[spells[spell_id].recourse_link].resist_difficulty + ); + } if (IsDetrimentalSpell(spell_id)) { - CheckNumHitsRemaining(NumHit::OutgoingSpells); - if (spelltar) + if (spelltar) { spelltar->CheckNumHitsRemaining(NumHit::IncomingSpells); + } } // send the action packet again now that the spell is successful @@ -4107,16 +4238,17 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes // the complete sequence is 2 actions and 1 damage message action->effect_flag = 0x04; // this is a success flag - if(spells[spell_id].push_back != 0.0f || spells[spell_id].push_up != 0.0f) - { - if (spelltar->IsClient()) - { - if (!IsBuffSpell(spell_id)) - { + if (spells[spell_id].push_back != 0.0f || spells[spell_id].push_up != 0.0f) { + if (spelltar->IsClient()) { + if (!IsBuffSpell(spell_id)) { spelltar->CastToClient()->cheat_manager.SetExemptStatus(KnockBack, true); } - } - else if (RuleB(Spells, NPCSpellPush) && !spelltar->IsPermaRooted() && !spelltar->IsPseudoRooted() && spelltar->ForcedMovement == 0) { + } else if ( + RuleB(Spells, NPCSpellPush) && + !spelltar->IsPermaRooted() && + !spelltar->IsPseudoRooted() && + !spelltar->ForcedMovement + ) { spelltar->m_Delta.x += action->force * g_Math.FastSin(action->hit_heading); spelltar->m_Delta.y += action->force * g_Math.FastCos(action->hit_heading); spelltar->m_Delta.z += action->hit_pitch; @@ -4124,17 +4256,18 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes } } - if (spelltar->IsClient() && IsEffectInSpell(spell_id, SE_ShadowStep)) - { + if (spelltar->IsClient() && IsEffectInSpell(spell_id, SE_ShadowStep)) { spelltar->CastToClient()->cheat_manager.SetExemptStatus(ShadowStep, true); } - if(!IsEffectInSpell(spell_id, SE_BindAffinity)) - { - if(spelltar != this && spelltar->IsClient()) // send to target + if (!IsEffectInSpell(spell_id, SE_BindAffinity)) { + if (spelltar != this && spelltar->IsClient()) {// send to target spelltar->CastToClient()->QueuePacket(action_packet); - if(IsClient()) // send to caster + } + + if(IsClient()) {// send to caster CastToClient()->QueuePacket(action_packet); + } } message_packet = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); @@ -4148,7 +4281,12 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes cd->hit_pitch = action->hit_pitch; cd->damage = 0; - if (!IsLifetapSpell(spell_id) && !IsEffectInSpell(spell_id, SE_BindAffinity) && !IsAENukeSpell(spell_id) && !IsDamageSpell(spell_id)) { + if ( + !IsLifetapSpell(spell_id) && + !IsEffectInSpell(spell_id, SE_BindAffinity) && + !IsAENukeSpell(spell_id) && + !IsDamageSpell(spell_id) + ) { entity_list.QueueCloseClients( spelltar, /* Sender */ message_packet, /* Packet */ @@ -4159,6 +4297,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes (spellOwner->IsClient() ? FilterPCSpells : FilterNPCSpells) /* Message Filter Type: (8 or 9) */ ); } + safe_delete(action_packet); safe_delete(message_packet);