From 834062fbf957c17a5492a1c3628d8af610ef5618 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 18 Aug 2018 22:01:46 -0500 Subject: [PATCH] Add another layer of randomization to roam box logic, npc's who weren't originally spawned in water won't roambox into water --- zone/attack.cpp | 8 ++++++++ zone/entity.cpp | 10 ++++++++++ zone/mob.h | 7 +++++++ zone/mob_ai.cpp | 32 ++++++++++++++++++++++++++++++-- zone/water_map_v2.cpp | 2 +- zone/waypoints.cpp | 2 +- zone/zone.h | 8 ++++---- 7 files changed, 61 insertions(+), 8 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index a48d68934..d6cf4227f 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -5455,3 +5455,11 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts) } } } + +bool Mob::GetWasSpawnedInWater() const { + return spawned_in_water; +} + +void Mob::SetSpawnedInWater(bool spawned_in_water) { + Mob::spawned_in_water = spawned_in_water; +} diff --git a/zone/entity.cpp b/zone/entity.cpp index f61acda94..2523c7d96 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -39,6 +39,7 @@ #include "raids.h" #include "string_ids.h" #include "worldserver.h" +#include "water_map.h" #ifdef _WINDOWS #define snprintf _snprintf @@ -686,6 +687,15 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) } } + /** + * Set whether NPC was spawned in or out of water + */ + if (zone->HasMap() && zone->HasWaterMap()) { + npc->SetSpawnedInWater(false); + if (zone->watermap->InLiquid(npc->GetPosition())) { + npc->SetSpawnedInWater(true); + } + } } void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue) diff --git a/zone/mob.h b/zone/mob.h index bdfbd31bc..763fa61b7 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1414,6 +1414,13 @@ protected: bool pseudo_rooted; bool endur_upkeep; bool degenerating_effects; // true if we have a buff that needs to be recalced every tick + bool spawned_in_water; +public: + bool GetWasSpawnedInWater() const; + + void SetSpawnedInWater(bool spawned_in_water); + +protected: // Bind wound Timer bindwound_timer; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 0579fd60d..9c16dc9b6 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1663,9 +1663,35 @@ void NPC::AI_DoMovement() { auto move_x = static_cast(zone->random.Real(-roambox_distance, roambox_distance)); auto move_y = static_cast(zone->random.Real(-roambox_distance, roambox_distance)); - roambox_destination_x = EQEmu::Clamp((GetX() + move_x), roambox_min_x, roambox_min_y); + roambox_destination_x = EQEmu::Clamp((GetX() + move_x), roambox_min_x, roambox_max_x); roambox_destination_y = EQEmu::Clamp((GetY() + move_y), roambox_min_y, roambox_max_y); + if (roambox_destination_x == roambox_min_x || roambox_destination_x == roambox_max_x) { + roambox_destination_x = static_cast(zone->random.Real(roambox_min_x, roambox_max_y)); + } + + if (roambox_destination_y == roambox_min_y || roambox_destination_y == roambox_max_y) { + roambox_destination_y = static_cast(zone->random.Real(roambox_min_y, roambox_max_y)); + } + + /** + * If mob was not spawned in water, let's not randomly roam them into water + * if the roam box was sloppily configured + */ + if (!this->GetWasSpawnedInWater()) { + if (zone->zonemap != nullptr && zone->watermap != nullptr) { + auto position = glm::vec3( + roambox_destination_x, + roambox_destination_y, + this->FindGroundZ(roambox_destination_x, roambox_destination_y, 5) + ); + + if (zone->watermap->InLiquid(position)) { + return; + } + } + } + this->FixZ(); Log(Logs::Detail, @@ -1681,7 +1707,9 @@ void NPC::AI_DoMovement() { roambox_destination_y); } - if (!CalculateNewPosition(roambox_destination_x, roambox_destination_y, GetFixedZ(m_Position), move_speed, true)) { + float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 5) + GetZOffset(); + + if (!CalculateNewPosition(roambox_destination_x, roambox_destination_y, new_z, move_speed, true)) { time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); SetMoving(false); this->FixZ(); diff --git a/zone/water_map_v2.cpp b/zone/water_map_v2.cpp index 939b9be97..03ae76fa4 100644 --- a/zone/water_map_v2.cpp +++ b/zone/water_map_v2.cpp @@ -30,7 +30,7 @@ bool WaterMapV2::InLava(const glm::vec3& location) const { } bool WaterMapV2::InLiquid(const glm::vec3& location) const { - return InWater(location) || InLava(location); + return InWater(location) || InLava(location) || InVWater(location); } bool WaterMapV2::InPvP(const glm::vec3& location) const { diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 083cc38ba..5e1f0dd82 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -455,7 +455,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b return true; } - if ((m_Position.x - x == 0) && (m_Position.y - y == 0)) {//spawn is at target coords + if ((m_Position.x - x == 0) && (m_Position.y - y == 0)) { //spawn is at target coords return false; } else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) { diff --git a/zone/zone.h b/zone/zone.h index c3d5fe8a6..5f8651d8b 100644 --- a/zone/zone.h +++ b/zone/zone.h @@ -212,10 +212,10 @@ public: void ReloadWorld(uint32 Option); void ReloadMerchants(); - Map* zonemap; - WaterMap* watermap; - IPathfinder *pathing; - NewZone_Struct newzone_data; + Map *zonemap; + WaterMap *watermap; + IPathfinder *pathing; + NewZone_Struct newzone_data; SpawnConditionManager spawn_conditions;