From ddac3262399c18e4aeece136011accbaa7b54757 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Sun, 30 Jul 2023 01:35:44 -0500 Subject: [PATCH] [Doors] Add door blacklist (#3516) * [Doors] Add door blacklist * Renaming to simplify --- zone/doors.cpp | 26 ++++++++++++++++++++++++++ zone/doors.h | 4 ++++ zone/mob.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ zone/mob.h | 1 + zone/mob_ai.cpp | 47 +---------------------------------------------- 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index 8b7a227c7..70ae6671a 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -83,6 +83,8 @@ Doors::Doors(const DoorsRepository::Doors &door) : m_close_timer.Disable(); m_disable_timer = (door.disable_timer == 1 ? true : false); + + m_is_blacklisted_to_open = GetIsDoorBlacklisted(); } Doors::Doors(const char *model, const glm::vec4 &position, uint8 open_type, uint16 size) : @@ -901,3 +903,27 @@ bool Doors::IsDestinationZoneSame() const { return m_same_destination_zone; } + +// IsDoorBlacklisted has a static list of doors that are blacklisted +// from being opened by NPCs. This is used to prevent NPCs from opening +// doors that are not meant to be opened by NPCs. +bool Doors::GetIsDoorBlacklisted() +{ + std::vector blacklist = { + "TOGGLE", + "PNDRESSER101", + }; + + for (auto& name : blacklist) { + std::string door_name = GetDoorName(); + if (name == door_name) { + return true; + } + } + + return false; +} + +bool Doors::IsDoorBlacklisted() { + return m_is_blacklisted_to_open; +} diff --git a/zone/doors.h b/zone/doors.h index 0ea60843d..903c3aed2 100644 --- a/zone/doors.h +++ b/zone/doors.h @@ -69,7 +69,10 @@ public: bool HasDestinationZone() const; bool IsDestinationZoneSame() const; + bool IsDoorBlacklisted(); + private: + bool GetIsDoorBlacklisted(); bool m_has_destination_zone = false; bool m_same_destination_zone = false; @@ -99,5 +102,6 @@ private: uint8 m_is_ldon_door; int m_dz_switch_id = 0; uint32 m_client_version_mask; + bool m_is_blacklisted_to_open = false; // is door blacklisted to open by npcs }; #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index d84633166..1c5ceee22 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -8365,3 +8365,48 @@ uint32 Mob::GetMobTypeIdentifier() return 0; } + +void Mob::HandleDoorOpen() +{ + for (auto e : entity_list.GetDoorsList()) { + Doors *d = e.second; + if (d->GetKeyItem()) { + continue; + } + if (d->GetLockpick()) { + continue; + } + if (d->IsDoorOpen()) { + continue; + } + if (d->IsDoorBlacklisted()) { + continue; + } + + // If the door is a trigger door, check if the trigger door is open + if (d->GetTriggerDoorID() > 0) { + auto td = entity_list.GetDoorsByDoorID(d->GetTriggerDoorID()); + if (td) { + if (Strings::RemoveNumbers(d->GetDoorName()) != Strings::RemoveNumbers(td->GetDoorName())) { + continue; + } + } + } + + if (d->GetDoorParam() > 0) { + continue; + } + + float distance = DistanceSquared(m_Position, d->GetPosition()); + float distance_scan_door_open = 20; + + if (distance <= (distance_scan_door_open * distance_scan_door_open)) { + // Make sure we're opening a door within height relevance and not platforms above or below us + if (std::abs(m_Position.z - d->GetPosition().z) > 10) { + continue; + } + + d->ForceOpen(this); + } + } +} diff --git a/zone/mob.h b/zone/mob.h index b186c646e..eb5d5267b 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1866,6 +1866,7 @@ private: void SetHeroicWisBonuses(StatBonuses* n); void DoSpellInterrupt(uint16 spell_id, int32 mana_cost, int my_curmana); + void HandleDoorOpen(); }; #endif diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index da71debf3..ea1e951eb 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -981,52 +981,7 @@ void Mob::AI_Process() { if (moving && CanOpenDoors()) { if (AI_scan_door_open_timer->Check()) { - auto &door_list = entity_list.GetDoorsList(); - for (auto itr : door_list) { - Doors *door = itr.second; - - if (door->GetKeyItem()) { - continue; - } - - if (door->GetLockpick()) { - continue; - } - - if (door->IsDoorOpen()) { - continue; - } - - if (door->GetTriggerDoorID() > 0) { - auto trigger_door = entity_list.GetDoorsByDoorID(door->GetTriggerDoorID()); - if (trigger_door) { - if (Strings::RemoveNumbers(door->GetDoorName()) != - Strings::RemoveNumbers(trigger_door->GetDoorName())) { - continue; - } - } - } - - if (door->GetDoorParam() > 0) { - continue; - } - - float distance = DistanceSquared(m_Position, door->GetPosition()); - float distance_scan_door_open = 20; - - if (distance <= (distance_scan_door_open * distance_scan_door_open)) { - - /** - * Make sure we're opening a door within height relevance and not platforms - * above or below - */ - if (std::abs(m_Position.z - door->GetPosition().z) > 10) { - continue; - } - - door->ForceOpen(this); - } - } + HandleDoorOpen(); } }