diff --git a/common/emu_constants.h b/common/emu_constants.h index 823f5468e..6edba139d 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -751,4 +751,9 @@ static std::map stance_names = { { Stance::AEBurn, "AE Burn" } }; +namespace PCNPCOnlyFlagType { + constexpr int PC = 1; + constexpr int NPC = 2; +} + #endif /*COMMON_EMU_CONSTANTS_H*/ diff --git a/zone/effects.cpp b/zone/effects.cpp index fd521e2e0..9a3fb9279 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -1028,24 +1028,15 @@ void Client::SendDisciplineTimer(uint32 timer_id, uint32 duration) } } -/** - * @param taunter - * @param range - * @param bonus_hate - */ -void EntityList::AETaunt(Client *taunter, float range, int32 bonus_hate) +void EntityList::AETaunt(Client* taunter, float range, int bonus_hate) { - - /** - * Live AE taunt range - Hardcoded. - */ if (range == 0) { range = 40; } float range_squared = range * range; - for (auto &it : entity_list.GetCloseMobList(taunter, range)) { + for (auto& it: entity_list.GetCloseMobList(taunter, range)) { Mob *them = it.second; if (!them) { continue; @@ -1060,9 +1051,11 @@ void EntityList::AETaunt(Client *taunter, float range, int32 bonus_hate) z_difference *= -1; } - if (z_difference < 10 - && taunter->IsAttackAllowed(them) - && DistanceSquaredNoZ(taunter->GetPosition(), them->GetPosition()) <= range_squared) { + if ( + z_difference < 10 && + taunter->IsAttackAllowed(them) && + DistanceSquaredNoZ(taunter->GetPosition(), them->GetPosition()) <= range_squared + ) { if (taunter->CheckLosFN(them)) { taunter->Taunt(them->CastToNPC(), true, 0, true, bonus_hate); } @@ -1070,38 +1063,31 @@ void EntityList::AETaunt(Client *taunter, float range, int32 bonus_hate) } } -/** - * Causes caster to hit every mob within dist range of center with spell_id - * - * @param caster_mob - * @param center_mob - * @param spell_id - * @param affect_caster - * @param resist_adjust - * @param max_targets - */ void EntityList::AESpell( - Mob *caster_mob, - Mob *center_mob, + Mob* caster_mob, + Mob* center_mob, uint16 spell_id, bool affect_caster, int16 resist_adjust, - int *max_targets + int* max_targets, + bool is_scripted ) { - const auto &cast_target_position = - spells[spell_id].target_type == ST_Ring ? - caster_mob->GetTargetRingLocation() : - static_cast(center_mob->GetPosition()); + const auto& cast_target_position = ( + (!is_scripted && spells[spell_id].target_type == ST_Ring) ? + caster_mob->GetTargetRingLocation() : + static_cast(center_mob->GetPosition()) + ); + + Mob* current_mob = nullptr; - Mob *current_mob = nullptr; bool is_detrimental_spell = IsDetrimentalSpell(spell_id); bool is_npc = caster_mob->IsNPC(); float distance = caster_mob->GetAOERange(spell_id); float distance_squared = distance * distance; - float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range; - glm::vec2 min = {cast_target_position.x - distance, cast_target_position.y - distance}; - glm::vec2 max = {cast_target_position.x + distance, cast_target_position.y + distance}; + float min_range_squared = spells[spell_id].min_range * spells[spell_id].min_range; + glm::vec2 min = { cast_target_position.x - distance, cast_target_position.y - distance }; + glm::vec2 max = { cast_target_position.x + distance, cast_target_position.y + distance }; /** * If using Old Rain Targets - there is no max target limitation @@ -1110,17 +1096,18 @@ void EntityList::AESpell( max_targets = nullptr; } - /** - * Max AOE targets - */ int max_targets_allowed = RuleI(Range, AOEMaxTargets); // unlimited if (max_targets) { // rains pass this in since they need to preserve the count through waves max_targets_allowed = *max_targets; - } - else if (spells[spell_id].aoe_max_targets) { + } else if (spells[spell_id].aoe_max_targets) { max_targets_allowed = spells[spell_id].aoe_max_targets; - } - else if (IsTargetableAESpell(spell_id) && is_detrimental_spell && !is_npc && !IsEffectInSpell(spell_id, SE_Lull) && !IsEffectInSpell(spell_id, SE_Mez)) { + } else if ( + IsTargetableAESpell(spell_id) && + is_detrimental_spell && + !is_npc && + !IsEffectInSpell(spell_id, SE_Lull) && + !IsEffectInSpell(spell_id, SE_Mez) + ) { max_targets_allowed = 4; } @@ -1133,7 +1120,7 @@ void EntityList::AESpell( distance ); - for (auto &it : entity_list.GetCloseMobList(caster_mob, distance)) { + for (auto& it: entity_list.GetCloseMobList(caster_mob, distance)) { current_mob = it.second; if (!current_mob) { continue; @@ -1161,16 +1148,11 @@ void EntityList::AESpell( continue; } - /** - * Check PC / NPC - * 1 = PC - * 2 = NPC - */ - if (spells[spell_id].pcnpc_only_flag == 1 && !current_mob->IsOfClientBotMerc()) { + if (spells[spell_id].pcnpc_only_flag == PCNPCOnlyFlagType::PC && !current_mob->IsOfClientBotMerc()) { continue; } - if (spells[spell_id].pcnpc_only_flag == 2 && current_mob->IsOfClientBotMerc()) { + if (spells[spell_id].pcnpc_only_flag == PCNPCOnlyFlagType::NPC && current_mob->IsOfClientBotMerc()) { continue; } @@ -1184,41 +1166,40 @@ void EntityList::AESpell( continue; } - if (distance_to_target < min_range2) { + if (distance_to_target < min_range_squared) { continue; } - if (is_npc && current_mob->IsNPC() && - spells[spell_id].target_type != ST_AreaNPCOnly) { //check npc->npc casting - FACTION_VALUE faction_value = current_mob->GetReverseFactionCon(caster_mob); + if ( + is_npc && + current_mob->IsNPC() && + spells[spell_id].target_type != ST_AreaNPCOnly + ) { + const auto faction_value = current_mob->GetReverseFactionCon(caster_mob); if (is_detrimental_spell) { - //affect mobs that are on our hate list, or - //which have bad faction with us if ( !(caster_mob->CheckAggro(current_mob) || - faction_value == FACTION_THREATENINGLY || - faction_value == FACTION_SCOWLS)) { + faction_value == FACTION_THREATENINGLY || + faction_value == FACTION_SCOWLS) + ) { continue; } - } - else { - //only affect mobs we would assist. + } else { if (!(faction_value <= FACTION_AMIABLY)) { continue; } } } - /** - * Finally, make sure they are within range - */ if (is_detrimental_spell) { if (!caster_mob->IsAttackAllowed(current_mob, true)) { continue; } + if (center_mob && !spells[spell_id].npc_no_los && !center_mob->CheckLosFN(current_mob)) { continue; } + if (!center_mob && !spells[spell_id].npc_no_los && !caster_mob->CheckLosFN( caster_mob->GetTargetRingX(), caster_mob->GetTargetRingY(), @@ -1226,9 +1207,7 @@ void EntityList::AESpell( current_mob->GetSize())) { continue; } - } - else { - + } else { /** * Check to stop casting beneficial ae buffs (to wit: bard songs) on enemies... * This does not check faction for beneficial AE buffs... only agro and attackable. @@ -1238,6 +1217,7 @@ void EntityList::AESpell( if (caster_mob->IsAttackAllowed(current_mob, true)) { continue; } + if (caster_mob->CheckAggro(current_mob)) { continue; } @@ -1264,40 +1244,29 @@ void EntityList::AESpell( } } -/** - * @param caster - * @param center - * @param spell_id - * @param affect_caster - */ void EntityList::MassGroupBuff( - Mob *caster, - Mob *center, + Mob* caster, + Mob* center, uint16 spell_id, - bool affect_caster) + bool affect_caster +) { - Mob *current_mob = nullptr; + Mob* current_mob = nullptr; float distance = caster->GetAOERange(spell_id); float distance_squared = distance * distance; bool is_detrimental_spell = IsDetrimentalSpell(spell_id); - for (auto &it : entity_list.GetCloseMobList(caster, distance)) { + for (auto& it: entity_list.GetCloseMobList(caster, distance)) { current_mob = it.second; if (!current_mob) { continue; } - /** - * Skip center - */ - if (current_mob == center) { + if (current_mob == center) { // Skip Center continue; } - /** - * Skip self - */ - if (current_mob == caster && !affect_caster) { + if (current_mob == caster && !affect_caster) { // Skip Caster continue; } @@ -1305,17 +1274,13 @@ void EntityList::MassGroupBuff( continue; } - /** - * Pets - */ if (current_mob->IsNPC()) { - Mob *owner = current_mob->GetOwner(); + Mob* owner = current_mob->GetOwner(); if (owner) { if (!owner->IsOfClientBot()) { continue; } - } - else { + } else { continue; } } @@ -1328,55 +1293,48 @@ void EntityList::MassGroupBuff( } } -/** - * Rampage - Normal and Duration rampages - * NPCs handle it differently in Mob::Rampage - * - * @param attacker - * @param distance - * @param Hand - * @param count - * @param is_from_spell - */ void EntityList::AEAttack( - Mob *attacker, + Mob* attacker, float distance, - int Hand, - int count, + int16 slot_id, + int hit_count, bool is_from_spell, - int attack_rounds) + int attack_rounds +) { - Mob *current_mob = nullptr; + Mob* current_mob = nullptr; float distance_squared = distance * distance; - int hit_count = 0; + int current_hits = 0; - for (auto &it : entity_list.GetCloseMobList(attacker, distance)) { + for (auto& it: entity_list.GetCloseMobList(attacker, distance)) { current_mob = it.second; if (!current_mob) { continue; } - if (current_mob->IsNPC() - && current_mob != attacker //this is not needed unless NPCs can use this - && (attacker->IsAttackAllowed(current_mob)) - && !current_mob->IsHorse() /* dont attack mounts */ - && (DistanceSquared(current_mob->GetPosition(), attacker->GetPosition()) <= distance_squared) - ) { - + if ( + current_mob->IsNPC() && + current_mob != attacker && + attacker->IsAttackAllowed(current_mob) && + !current_mob->IsHorse() && + DistanceSquared(current_mob->GetPosition(), attacker->GetPosition()) <= distance_squared + ) { for (int i = 0; i < attack_rounds; i++) { - if (!attacker->IsClient() || attacker->GetClass() == Class::Monk || attacker->GetClass() == Class::Ranger) { - attacker->Attack(current_mob, Hand, false, false, is_from_spell); + if ( + !attacker->IsClient() || + attacker->GetClass() == Class::Monk || + attacker->GetClass() == Class::Ranger + ) { + attacker->Attack(current_mob, slot_id, false, false, is_from_spell); } else { - attacker->CastToClient()->DoAttackRounds(current_mob, Hand, is_from_spell); + attacker->CastToClient()->DoAttackRounds(current_mob, slot_id, is_from_spell); } } - hit_count++; - if (count != 0 && hit_count >= count) { + current_hits++; + if (hit_count != 0 && current_hits >= hit_count) { return; } } } } - - diff --git a/zone/entity.h b/zone/entity.h index 47fb00c9a..dc3f8a791 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -436,23 +436,24 @@ public: void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app); void AEAttack( - Mob *attacker, + Mob* attacker, float distance, - int Hand = EQ::invslot::slotPrimary, - int count = 0, + int16 slot_id = EQ::invslot::slotPrimary, + int hit_count = 0, bool is_from_spell = false, int attack_rounds = 1 ); - void AETaunt(Client *caster, float range = 0, int32 bonus_hate = 0); + void AETaunt(Client* caster, float range = 0, int bonus_hate = 0); void AESpell( - Mob *caster, - Mob *center, + Mob* caster, + Mob* center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0, - int *max_targets = nullptr + int* max_targets = nullptr, + bool is_scripted = false ); - void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true); + void MassGroupBuff(Mob* caster, Mob* center, uint16 spell_id, bool affect_caster = true); //trap stuff Mob* GetTrapTrigger(Trap* trap); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 7534c0e14..9dc1a1226 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -3412,6 +3412,24 @@ bool Lua_Client::AreTasksCompleted(luabind::object task_ids) return self->AreTasksCompleted(v); } +void Lua_Client::AreaTaunt() +{ + Lua_Safe_Call_Void(); + entity_list.AETaunt(self); +} + +void Lua_Client::AreaTaunt(float range) +{ + Lua_Safe_Call_Void(); + entity_list.AETaunt(self, range); +} + +void Lua_Client::AreaTaunt(float range, int bonus_hate) +{ + Lua_Safe_Call_Void(); + entity_list.AETaunt(self, range, bonus_hate); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3459,6 +3477,9 @@ luabind::scope lua_register_client() { .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::ApplySpellRaid) .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool,bool,bool))&Lua_Client::ApplySpellRaid) .def("AreTasksCompleted", (bool(Lua_Client::*)(luabind::object))&Lua_Client::AreTasksCompleted) + .def("AreaTaunt", (void(Lua_Client::*)(void))&Lua_Client::AreaTaunt) + .def("AreaTaunt", (void(Lua_Client::*)(float))&Lua_Client::AreaTaunt) + .def("AreaTaunt", (void(Lua_Client::*)(float, int))&Lua_Client::AreaTaunt) .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) diff --git a/zone/lua_client.h b/zone/lua_client.h index f36a20e3d..0e30eeb59 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -505,6 +505,9 @@ public: void DescribeSpecialAbilities(Lua_NPC n); void ResetLeadershipAA(); uint8 GetSkillTrainLevel(int skill_id); + void AreaTaunt(); + void AreaTaunt(float range); + void AreaTaunt(float range, int bonus_hate); void ApplySpell(int spell_id); void ApplySpell(int spell_id, int duration); diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index 4d52c7e75..adf9ef34f 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -680,11 +680,107 @@ Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob, float distance, bool i return ret; } +void Lua_EntityList::AreaAttack(Lua_Mob attacker, float distance) +{ + Lua_Safe_Call_Void(); + self->AEAttack(attacker, distance); +} + +void Lua_EntityList::AreaAttack(Lua_Mob attacker, float distance, int16 slot_id) +{ + Lua_Safe_Call_Void(); + self->AEAttack(attacker, distance, slot_id); +} + +void Lua_EntityList::AreaAttack(Lua_Mob attacker, float distance, int16 slot_id, int count) +{ + Lua_Safe_Call_Void(); + self->AEAttack(attacker, distance, slot_id, count); +} + +void Lua_EntityList::AreaAttack(Lua_Mob attacker, float distance, int16 slot_id, int count, bool is_from_spell) +{ + Lua_Safe_Call_Void(); + self->AEAttack(attacker, distance, slot_id, count, is_from_spell); +} + +void Lua_EntityList::AreaAttack(Lua_Mob attacker, float distance, int16 slot_id, int count, bool is_from_spell, int attack_rounds) +{ + Lua_Safe_Call_Void(); + self->AEAttack(attacker, distance, slot_id, count, is_from_spell, attack_rounds); +} + +void Lua_EntityList::AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id) +{ + Lua_Safe_Call_Void(); + self->AESpell(caster, center, spell_id); +} + +void Lua_EntityList::AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster) +{ + Lua_Safe_Call_Void(); + self->AESpell(caster, center, spell_id, affect_caster); +} + +void Lua_EntityList::AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust) +{ + Lua_Safe_Call_Void(); + self->AESpell(caster, center, spell_id, affect_caster, resist_adjust); +} + +void Lua_EntityList::AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int max_targets) +{ + Lua_Safe_Call_Void(); + self->AESpell(caster, center, spell_id, affect_caster, resist_adjust, &max_targets); +} + +void Lua_EntityList::AreaTaunt(Lua_Client caster) +{ + Lua_Safe_Call_Void(); + self->AETaunt(caster); +} + +void Lua_EntityList::AreaTaunt(Lua_Client caster, float range) +{ + Lua_Safe_Call_Void(); + self->AETaunt(caster, range); +} + +void Lua_EntityList::AreaTaunt(Lua_Client caster, float range, int bonus_hate) +{ + Lua_Safe_Call_Void(); + self->AETaunt(caster, range, bonus_hate); +} + +void Lua_EntityList::MassGroupBuff(Lua_Mob caster, Lua_Mob center, uint16 spell_id) +{ + Lua_Safe_Call_Void(); + self->MassGroupBuff(caster, center, spell_id); +} + +void Lua_EntityList::MassGroupBuff(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster) +{ + Lua_Safe_Call_Void(); + self->MassGroupBuff(caster, center, spell_id, affect_caster); +} + luabind::scope lua_register_entity_list() { return luabind::class_("EntityList") .def(luabind::constructor<>()) .property("null", &Lua_EntityList::Null) .property("valid", &Lua_EntityList::Valid) + .def("AreaAttack", (void(Lua_EntityList::*)(Lua_Mob, float))&Lua_EntityList::AreaAttack) + .def("AreaAttack", (void(Lua_EntityList::*)(Lua_Mob, float, int16))&Lua_EntityList::AreaAttack) + .def("AreaAttack", (void(Lua_EntityList::*)(Lua_Mob, float, int16, int))&Lua_EntityList::AreaAttack) + .def("AreaAttack", (void(Lua_EntityList::*)(Lua_Mob, float, int16, int, bool))&Lua_EntityList::AreaAttack) + .def("AreaAttack", (void(Lua_EntityList::*)(Lua_Mob, float, int16, int, bool, int))&Lua_EntityList::AreaAttack) + .def("AreaSpell", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob, uint16))&Lua_EntityList::AreaSpell) + .def("AreaSpell", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob, uint16, bool))&Lua_EntityList::AreaSpell) + .def("AreaSpell", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob, uint16, bool, int16))&Lua_EntityList::AreaSpell) + .def("AreaSpell", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob, uint16, bool, int16, int))&Lua_EntityList::AreaSpell) + .def("AreaTaunt", (void(Lua_EntityList::*)(Lua_Client))&Lua_EntityList::AreaTaunt) + .def("AreaTaunt", (void(Lua_EntityList::*)(Lua_Client, float))&Lua_EntityList::AreaTaunt) + .def("AreaTaunt", (void(Lua_EntityList::*)(Lua_Client, float, int))&Lua_EntityList::AreaTaunt) .def("CanAddHateForMob", (bool(Lua_EntityList::*)(Lua_Mob))&Lua_EntityList::CanAddHateForMob) .def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob, int, uint8, const char*))&Lua_EntityList::ChannelMessage) .def("ClearClientPetitionQueue", (void(Lua_EntityList::*)(void))&Lua_EntityList::ClearClientPetitionQueue) @@ -759,6 +855,8 @@ luabind::scope lua_register_entity_list() { .def("Marquee", (void(Lua_EntityList::*)(uint32, std::string))&Lua_EntityList::Marquee) .def("Marquee", (void(Lua_EntityList::*)(uint32, std::string, uint32))&Lua_EntityList::Marquee) .def("Marquee", (void(Lua_EntityList::*)(uint32, uint32, uint32, uint32, uint32, std::string))&Lua_EntityList::Marquee) + .def("MassGroupBuff", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob, uint16))&Lua_EntityList::MassGroupBuff) + .def("MassGroupBuff", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob, uint16, bool))&Lua_EntityList::MassGroupBuff) .def("Message", (void(Lua_EntityList::*)(uint32, uint32, const char*))&Lua_EntityList::Message) .def("MessageClose", (void(Lua_EntityList::*)(Lua_Mob, bool, float, uint32, const char*))&Lua_EntityList::MessageClose) .def("MessageGroup", (void(Lua_EntityList::*)(Lua_Mob, bool, uint32, const char*))&Lua_EntityList::MessageGroup) diff --git a/zone/lua_entity_list.h b/zone/lua_entity_list.h index 5f0e99794..eb986b67b 100644 --- a/zone/lua_entity_list.h +++ b/zone/lua_entity_list.h @@ -142,6 +142,21 @@ public: Lua_Mob_List GetCloseMobList(Lua_Mob mob); Lua_Mob_List GetCloseMobList(Lua_Mob mob, float distance); Lua_Mob_List GetCloseMobList(Lua_Mob mob, float distance, bool ignore_self); + void AreaAttack(Lua_Mob attacker, float distance); + void AreaAttack(Lua_Mob attacker, float distance, int16 slot_id); + void AreaAttack(Lua_Mob attacker, float distance, int16 slot_id, int count); + void AreaAttack(Lua_Mob attacker, float distance, int16 slot_id, int count, bool is_from_spell); + void AreaAttack(Lua_Mob attacker, float distance, int16 slot_id, int count, bool is_from_spell, int attack_rounds); + void AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id); + void AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster); + void AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust); + void AreaSpell(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int max_targets); + void AreaTaunt(Lua_Client caster); + void AreaTaunt(Lua_Client caster, float range); + void AreaTaunt(Lua_Client caster, float range, int bonus_hate); + void MassGroupBuff(Lua_Mob caster, Lua_Mob center, uint16 spell_id); + void MassGroupBuff(Lua_Mob caster, Lua_Mob center, uint16 spell_id, bool affect_caster); + }; #endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 1922b420c..641340e54 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -3380,6 +3380,72 @@ int Lua_Mob::GetExtraHaste() return self->GetExtraHaste(); } +void Lua_Mob::AreaAttack(float distance) +{ + Lua_Safe_Call_Void(); + entity_list.AEAttack(self, distance); +} + +void Lua_Mob::AreaAttack(float distance, int16 slot_id) +{ + Lua_Safe_Call_Void(); + entity_list.AEAttack(self, distance, slot_id); +} + +void Lua_Mob::AreaAttack(float distance, int16 slot_id, int count) +{ + Lua_Safe_Call_Void(); + entity_list.AEAttack(self, distance, slot_id, count); +} + +void Lua_Mob::AreaAttack(float distance, int16 slot_id, int count, bool is_from_spell) +{ + Lua_Safe_Call_Void(); + entity_list.AEAttack(self, distance, slot_id, count, is_from_spell); +} + +void Lua_Mob::AreaAttack(float distance, int16 slot_id, int count, bool is_from_spell, int attack_rounds) +{ + Lua_Safe_Call_Void(); + entity_list.AEAttack(self, distance, slot_id, count, is_from_spell, attack_rounds); +} + +void Lua_Mob::AreaSpell(Lua_Mob center, uint16 spell_id) +{ + Lua_Safe_Call_Void(); + entity_list.AESpell(self, center, spell_id); +} + +void Lua_Mob::AreaSpell(Lua_Mob center, uint16 spell_id, bool affect_caster) +{ + Lua_Safe_Call_Void(); + entity_list.AESpell(self, center, spell_id, affect_caster); +} + +void Lua_Mob::AreaSpell(Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust) +{ + Lua_Safe_Call_Void(); + entity_list.AESpell(self, center, spell_id, affect_caster, resist_adjust); +} + +void Lua_Mob::AreaSpell(Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int max_targets) +{ + Lua_Safe_Call_Void(); + entity_list.AESpell(self, center, spell_id, affect_caster, resist_adjust, &max_targets); +} + +void Lua_Mob::MassGroupBuff(Lua_Mob center, uint16 spell_id) +{ + Lua_Safe_Call_Void(); + entity_list.MassGroupBuff(self, center, spell_id); +} + +void Lua_Mob::MassGroupBuff(Lua_Mob center, uint16 spell_id, bool affect_caster) +{ + Lua_Safe_Call_Void(); + entity_list.MassGroupBuff(self, center, spell_id, affect_caster); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -3393,6 +3459,15 @@ luabind::scope lua_register_mob() { .def("ApplySpellBuff", (void(Lua_Mob::*)(int))&Lua_Mob::ApplySpellBuff) .def("ApplySpellBuff", (void(Lua_Mob::*)(int,int))&Lua_Mob::ApplySpellBuff) .def("ApplySpellBuff", (void(Lua_Mob::*)(int,int,int))&Lua_Mob::ApplySpellBuff) + .def("AreaAttack", (void(Lua_Mob::*)(float))&Lua_Mob::AreaAttack) + .def("AreaAttack", (void(Lua_Mob::*)(float, int16))&Lua_Mob::AreaAttack) + .def("AreaAttack", (void(Lua_Mob::*)(float, int16, int))&Lua_Mob::AreaAttack) + .def("AreaAttack", (void(Lua_Mob::*)(float, int16, int, bool))&Lua_Mob::AreaAttack) + .def("AreaAttack", (void(Lua_Mob::*)(float, int16, int, bool, int))&Lua_Mob::AreaAttack) + .def("AreaSpell", (void(Lua_Mob::*)(Lua_Mob, uint16))&Lua_Mob::AreaSpell) + .def("AreaSpell", (void(Lua_Mob::*)(Lua_Mob, uint16, bool))&Lua_Mob::AreaSpell) + .def("AreaSpell", (void(Lua_Mob::*)(Lua_Mob, uint16, bool, int16))&Lua_Mob::AreaSpell) + .def("AreaSpell", (void(Lua_Mob::*)(Lua_Mob, uint16, bool, int16, int))&Lua_Mob::AreaSpell) .def("Attack", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::Attack) .def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int))&Lua_Mob::Attack) .def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool))&Lua_Mob::Attack) @@ -3808,6 +3883,8 @@ luabind::scope lua_register_mob() { .def("IsWarriorClass", &Lua_Mob::IsWarriorClass) .def("IsWisdomCasterClass", &Lua_Mob::IsWisdomCasterClass) .def("Kill", (void(Lua_Mob::*)(void))&Lua_Mob::Kill) + .def("MassGroupBuff", (void(Lua_Mob::*)(Lua_Mob, uint16))&Lua_Mob::MassGroupBuff) + .def("MassGroupBuff", (void(Lua_Mob::*)(Lua_Mob, uint16, bool))&Lua_Mob::MassGroupBuff) .def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize) .def("Message", &Lua_Mob::Message) .def("MessageString", &Lua_Mob::MessageString) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 4d8b67c55..d3fae9f1b 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -594,6 +594,17 @@ public: int GetExtraHaste(); void SetExtraHaste(int haste); void SetExtraHaste(int haste, bool need_to_save); + void AreaAttack(float distance); + void AreaAttack(float distance, int16 slot_id); + void AreaAttack(float distance, int16 slot_id, int count); + void AreaAttack(float distance, int16 slot_id, int count, bool is_from_spell); + void AreaAttack(float distance, int16 slot_id, int count, bool is_from_spell, int attack_rounds); + void AreaSpell(Lua_Mob center, uint16 spell_id); + void AreaSpell(Lua_Mob center, uint16 spell_id, bool affect_caster); + void AreaSpell(Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust); + void AreaSpell(Lua_Mob center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int max_targets); + void MassGroupBuff(Lua_Mob center, uint16 spell_id); + void MassGroupBuff(Lua_Mob center, uint16 spell_id, bool affect_caster); }; #endif diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index cf90ef024..bb429c15f 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -3187,6 +3187,21 @@ bool Perl_Client_AreTasksCompleted(Client* self, perl::array task_ids) return self->AreTasksCompleted(v); } +void Perl_Client_AreaTaunt(Client* self) +{ + entity_list.AETaunt(self); +} + +void Perl_Client_AreaTaunt(Client* self, float range) +{ + entity_list.AETaunt(self, range); +} + +void Perl_Client_AreaTaunt(Client* self, float range, int bonus_hate) +{ + entity_list.AETaunt(self, range, bonus_hate); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -3237,6 +3252,9 @@ void perl_register_client() package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_ApplySpellRaid); package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool, bool, bool))&Perl_Client_ApplySpellRaid); package.add("AreTasksCompleted", (bool(*)(Client*, perl::array))&Perl_Client_AreTasksCompleted); + package.add("AreaTaunt", (void(*)(Client*))&Perl_Client_AreaTaunt); + package.add("AreaTaunt", (void(*)(Client*, float))&Perl_Client_AreaTaunt); + package.add("AreaTaunt", (void(*)(Client*, float, int))&Perl_Client_AreaTaunt); 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); diff --git a/zone/perl_entity.cpp b/zone/perl_entity.cpp index 42baee9f8..765767a15 100644 --- a/zone/perl_entity.cpp +++ b/zone/perl_entity.cpp @@ -669,11 +669,93 @@ perl::array Perl_EntityList_GetSpawnList(EntityList* self) { return ret; } +void Perl_EntityList_AreaAttack(EntityList* self, Mob* attacker, float distance) +{ + self->AEAttack(attacker, distance); +} + +void Perl_EntityList_AreaAttack(EntityList* self, Mob* attacker, float distance, int16 slot_id) +{ + self->AEAttack(attacker, distance, slot_id); +} + +void Perl_EntityList_AreaAttack(EntityList* self, Mob* attacker, float distance, int16 slot_id, int count) +{ + self->AEAttack(attacker, distance, slot_id, count); +} + +void Perl_EntityList_AreaAttack(EntityList* self, Mob* attacker, float distance, int16 slot_id, int count, bool is_from_spell) +{ + self->AEAttack(attacker, distance, slot_id, count, is_from_spell); +} + +void Perl_EntityList_AreaAttack(EntityList* self, Mob* attacker, float distance, int16 slot_id, int count, bool is_from_spell, int attack_rounds) +{ + self->AEAttack(attacker, distance, slot_id, count, is_from_spell, attack_rounds); +} + +void Perl_EntityList_AreaSpell(EntityList* self, Mob* caster, Mob* center, uint16 spell_id) +{ + self->AESpell(caster, center, spell_id); +} + +void Perl_EntityList_AreaSpell(EntityList* self, Mob* caster, Mob* center, uint16 spell_id, bool affect_caster) +{ + self->AESpell(caster, center, spell_id, affect_caster); +} + +void Perl_EntityList_AreaSpell(EntityList* self, Mob* caster, Mob* center, uint16 spell_id, bool affect_caster, int16 resist_adjust) +{ + self->AESpell(caster, center, spell_id, affect_caster, resist_adjust); +} + +void Perl_EntityList_AreaSpell(EntityList* self, Mob* caster, Mob* center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int max_targets) +{ + self->AESpell(caster, center, spell_id, affect_caster, resist_adjust, &max_targets); +} + +void Perl_EntityList_AreaTaunt(EntityList* self, Client* caster) +{ + self->AETaunt(caster); +} + +void Perl_EntityList_AreaTaunt(EntityList* self, Client* caster, float range) +{ + self->AETaunt(caster, range); +} + +void Perl_EntityList_AreaTaunt(EntityList* self, Client* caster, float range, int bonus_hate) +{ + self->AETaunt(caster, range, bonus_hate); +} + +void Perl_EntityList_MassGroupBuff(EntityList* self, Mob* caster, Mob* center, uint16 spell_id) +{ + self->MassGroupBuff(caster, center, spell_id); +} + +void Perl_EntityList_MassGroupBuff(EntityList* self, Mob* caster, Mob* center, uint16 spell_id, bool affect_caster) +{ + self->MassGroupBuff(caster, center, spell_id, affect_caster); +} + void perl_register_entitylist() { perl::interpreter perl(PERL_GET_THX); auto package = perl.new_class("EntityList"); + package.add("AreaAttack", (void(*)(EntityList*, Mob*, float))&Perl_EntityList_AreaAttack); + package.add("AreaAttack", (void(*)(EntityList*, Mob*, float, int16))&Perl_EntityList_AreaAttack); + package.add("AreaAttack", (void(*)(EntityList*, Mob*, float, int16, int))&Perl_EntityList_AreaAttack); + package.add("AreaAttack", (void(*)(EntityList*, Mob*, float, int16, int, bool))&Perl_EntityList_AreaAttack); + package.add("AreaAttack", (void(*)(EntityList*, Mob*, float, int16, int, bool, int))&Perl_EntityList_AreaAttack); + package.add("AreaSpell", (void(*)(EntityList*, Mob*, Mob*, uint16))&Perl_EntityList_AreaSpell); + package.add("AreaSpell", (void(*)(EntityList*, Mob*, Mob*, uint16, bool))&Perl_EntityList_AreaSpell); + package.add("AreaSpell", (void(*)(EntityList*, Mob*, Mob*, uint16, bool, int16))&Perl_EntityList_AreaSpell); + package.add("AreaSpell", (void(*)(EntityList*, Mob*, Mob*, uint16, bool, int16, int))&Perl_EntityList_AreaSpell); + package.add("AreaTaunt", (void(*)(EntityList*, Client*))&Perl_EntityList_AreaTaunt); + package.add("AreaTaunt", (void(*)(EntityList*, Client*, float))&Perl_EntityList_AreaTaunt); + package.add("AreaTaunt", (void(*)(EntityList*, Client*, float, int))&Perl_EntityList_AreaTaunt); package.add("CanAddHateForMob", &Perl_EntityList_CanAddHateForMob); package.add("Clear", &Perl_EntityList_Clear); package.add("ClearClientPetitionQueue", &Perl_EntityList_ClearClientPetitionQueue); @@ -747,6 +829,8 @@ void perl_register_entitylist() package.add("Marquee", (void(*)(EntityList*, uint32, std::string))&Perl_EntityList_Marquee); package.add("Marquee", (void(*)(EntityList*, uint32, std::string, uint32))&Perl_EntityList_Marquee); package.add("Marquee", (void(*)(EntityList*, uint32, uint32, uint32, uint32, uint32, std::string))&Perl_EntityList_Marquee); + package.add("MassGroupBuff", (void(*)(EntityList*, Mob*, Mob*, uint16))&Perl_EntityList_MassGroupBuff); + package.add("MassGroupBuff", (void(*)(EntityList*, Mob*, Mob*, uint16, bool))&Perl_EntityList_MassGroupBuff); package.add("Message", &Perl_EntityList_Message); package.add("MessageClose", &Perl_EntityList_MessageClose); package.add("MessageGroup", &Perl_EntityList_MessageGroup); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 36be985c9..045ea4600 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -3488,6 +3488,61 @@ std::string Perl_Mob_GetConsiderColor(Mob* self, uint8 other_level) return EQ::constants::GetConsiderColorName(self->GetLevelCon(other_level)); } +void Perl_Mob_AreaAttack(Mob* self, float distance) +{ + entity_list.AEAttack(self, distance); +} + +void Perl_Mob_AreaAttack(Mob* self, float distance, int16 slot_id) +{ + entity_list.AEAttack(self, distance, slot_id); +} + +void Perl_Mob_AreaAttack(Mob* self, float distance, int16 slot_id, int count) +{ + entity_list.AEAttack(self, distance, slot_id, count); +} + +void Perl_Mob_AreaAttack(Mob* self, float distance, int16 slot_id, int count, bool is_from_spell) +{ + entity_list.AEAttack(self, distance, slot_id, count, is_from_spell); +} + +void Perl_Mob_AreaAttack(Mob* self, float distance, int16 slot_id, int count, bool is_from_spell, int attack_rounds) +{ + entity_list.AEAttack(self, distance, slot_id, count, is_from_spell, attack_rounds); +} + +void Perl_Mob_AreaSpell(Mob* self, Mob* center, uint16 spell_id) +{ + entity_list.AESpell(self, center, spell_id, true, 0, nullptr, true); +} + +void Perl_Mob_AreaSpell(Mob* self, Mob* center, uint16 spell_id, bool affect_caster) +{ + entity_list.AESpell(self, center, spell_id, affect_caster, 0, nullptr, true); +} + +void Perl_Mob_AreaSpell(Mob* self, Mob* center, uint16 spell_id, bool affect_caster, int16 resist_adjust) +{ + entity_list.AESpell(self, center, spell_id, affect_caster, resist_adjust, nullptr, true); +} + +void Perl_Mob_AreaSpell(Mob* self, Mob* center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int max_targets) +{ + entity_list.AESpell(self, center, spell_id, affect_caster, resist_adjust, &max_targets, true); +} + +void Perl_Mob_MassGroupBuff(Mob* self, Mob* center, uint16 spell_id) +{ + entity_list.MassGroupBuff(self, center, spell_id); +} + +void Perl_Mob_MassGroupBuff(Mob* self, Mob* center, uint16 spell_id, bool affect_caster) +{ + entity_list.MassGroupBuff(self, center, spell_id, affect_caster); +} + void perl_register_mob() { perl::interpreter perl(PERL_GET_THX); @@ -3504,6 +3559,15 @@ void perl_register_mob() package.add("ApplySpellBuff", (void(*)(Mob*, int))&Perl_Mob_ApplySpellBuff); package.add("ApplySpellBuff", (void(*)(Mob*, int, int))&Perl_Mob_ApplySpellBuff); package.add("ApplySpellBuff", (void(*)(Mob*, int, int, int))&Perl_Mob_ApplySpellBuff); + package.add("AreaAttack", (void(*)(Mob*, float))&Perl_Mob_AreaAttack); + package.add("AreaAttack", (void(*)(Mob*, float, int16))&Perl_Mob_AreaAttack); + package.add("AreaAttack", (void(*)(Mob*, float, int16, int))&Perl_Mob_AreaAttack); + package.add("AreaAttack", (void(*)(Mob*, float, int16, int, bool))&Perl_Mob_AreaAttack); + package.add("AreaAttack", (void(*)(Mob*, float, int16, int, bool, int))&Perl_Mob_AreaAttack); + package.add("AreaSpell", (void(*)(Mob*, Mob*, uint16))&Perl_Mob_AreaSpell); + package.add("AreaSpell", (void(*)(Mob*, Mob*, uint16, bool))&Perl_Mob_AreaSpell); + package.add("AreaSpell", (void(*)(Mob*, Mob*, uint16, bool, int16))&Perl_Mob_AreaSpell); + package.add("AreaSpell", (void(*)(Mob*, Mob*, uint16, bool, int16, int))&Perl_Mob_AreaSpell); package.add("Attack", (bool(*)(Mob*, Mob*))&Perl_Mob_Attack); package.add("Attack", (bool(*)(Mob*, Mob*, int))&Perl_Mob_Attack); package.add("Attack", (bool(*)(Mob*, Mob*, int, bool))&Perl_Mob_Attack); @@ -3928,6 +3992,8 @@ void perl_register_mob() package.add("MakeTempPet", (void(*)(Mob*, uint16, const char*, uint32))&Perl_Mob_MakeTempPet); package.add("MakeTempPet", (void(*)(Mob*, uint16, const char*, uint32, Mob*))&Perl_Mob_MakeTempPet); package.add("MakeTempPet", (void(*)(Mob*, uint16, const char*, uint32, Mob*, bool))&Perl_Mob_MakeTempPet); + package.add("MassGroupBuff", (void(*)(Mob*, Mob*, uint16))&Perl_Mob_MassGroupBuff); + package.add("MassGroupBuff", (void(*)(Mob*, Mob*, uint16, bool))&Perl_Mob_MassGroupBuff); package.add("Mesmerize", &Perl_Mob_Mesmerize); package.add("Message", &Perl_Mob_Message); package.add("Message_StringID", (void(*)(Mob*, uint32, uint32))&Perl_Mob_Message_StringID); diff --git a/zone/spells.cpp b/zone/spells.cpp index afd31bd7c..2da02fe12 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -886,13 +886,13 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp */ if (!ignore_on_casting) { 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 && !spell_target->IsClient() && !spell_target->IsMerc() && !spell_target->IsBot()) { + if (spells[spell_id].pcnpc_only_flag == PCNPCOnlyFlagType::PC && !spell_target->IsClient() && !spell_target->IsMerc() && !spell_target->IsBot()) { if (check_on_casting) { Message(Chat::SpellFailure, "This spell only works on other PCs"); } return false; } - else if (spells[spell_id].pcnpc_only_flag == 2 && (spell_target->IsClient() || spell_target->IsMerc() || spell_target->IsBot())) { + else if (spells[spell_id].pcnpc_only_flag == PCNPCOnlyFlagType::NPC && (spell_target->IsClient() || spell_target->IsMerc() || spell_target->IsBot())) { if (check_on_casting) { Message(Chat::SpellFailure, "This spell only works on NPCs."); } @@ -3947,12 +3947,12 @@ bool Mob::SpellOnTarget( spells[spell_id].target_type != ST_HateList ) { if ( - spells[spell_id].pcnpc_only_flag == 1 && + spells[spell_id].pcnpc_only_flag == PCNPCOnlyFlagType::PC && !spelltar->IsOfClientBotMerc() ) { return false; } else if ( - spells[spell_id].pcnpc_only_flag == 2 && + spells[spell_id].pcnpc_only_flag == PCNPCOnlyFlagType::NPC && ( spelltar->IsOfClientBotMerc() )