From 4b6ab34fd9a04cba18dac9d2da6e6d99721c602c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 18 Aug 2018 18:12:18 -0500 Subject: [PATCH] Fix, cleanup and simplify the roambox logic and cleanup a bunch of other related code --- common/eqemu_logsys.h | 4 +- zone/entity.cpp | 36 ++-- zone/merc.cpp | 12 +- zone/mob.h | 8 +- zone/mob_ai.cpp | 491 +++++++++++++++++++++--------------------- zone/npc.cpp | 4 +- zone/npc.h | 18 +- zone/spawn2.cpp | 172 ++++++++++----- zone/waypoints.cpp | 130 ++++++----- 9 files changed, 479 insertions(+), 396 deletions(-) diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index a54edc234..b0afa72f2 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -90,6 +90,7 @@ enum LogCategory { FixZ, Food, Traps, + NPCRoamBox, MaxCategoryID /* Don't Remove this*/ }; @@ -144,7 +145,8 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = { "HP Update", "FixZ", "Food", - "Traps" + "Traps", + "NPC Roam Box" }; } diff --git a/zone/entity.cpp b/zone/entity.cpp index 264b8cfc9..f61acda94 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3425,52 +3425,54 @@ void EntityList::ProcessMove(Client *c, const glm::vec3& location) } } -void EntityList::ProcessMove(NPC *n, float x, float y, float z) -{ +void EntityList::ProcessMove(NPC *n, float x, float y, float z) { float last_x = n->GetX(); float last_y = n->GetY(); float last_z = n->GetZ(); std::list events; + for (auto iter = area_list.begin(); iter != area_list.end(); ++iter) { - Area& a = (*iter); + + Area &a = (*iter); bool old_in = true; bool new_in = true; if (last_x < a.min_x || last_x > a.max_x || - last_y < a.min_y || last_y > a.max_y || - last_z < a.min_z || last_z > a.max_z) { + last_y < a.min_y || last_y > a.max_y || + last_z < a.min_z || last_z > a.max_z) { old_in = false; } if (x < a.min_x || x > a.max_x || - y < a.min_y || y > a.max_y || - z < a.min_z || z > a.max_z) { + y < a.min_y || y > a.max_y || + z < a.min_z || z > a.max_z) { new_in = false; } if (old_in && !new_in) { //were in but are no longer. quest_proximity_event evt; - evt.event_id = EVENT_LEAVE_AREA; - evt.client = nullptr; - evt.npc = n; - evt.area_id = a.id; + evt.event_id = EVENT_LEAVE_AREA; + evt.client = nullptr; + evt.npc = n; + evt.area_id = a.id; evt.area_type = a.type; events.push_back(evt); - } else if (!old_in && new_in) { + } + else if (!old_in && new_in) { //were not in but now are quest_proximity_event evt; - evt.event_id = EVENT_ENTER_AREA; - evt.client = nullptr; - evt.npc = n; - evt.area_id = a.id; + evt.event_id = EVENT_ENTER_AREA; + evt.client = nullptr; + evt.npc = n; + evt.area_id = a.id; evt.area_type = a.type; events.push_back(evt); } } for (auto iter = events.begin(); iter != events.end(); ++iter) { - quest_proximity_event& evt = (*iter); + quest_proximity_event &evt = (*iter); std::vector args; args.push_back(&evt.area_id); args.push_back(&evt.area_type); diff --git a/zone/merc.cpp b/zone/merc.cpp index 82d66878a..834b96e44 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1481,8 +1481,14 @@ void Merc::AI_Process() { if (RuleB(Mercs, MercsUsePathing) && zone->pathing) { bool WaypointChanged, NodeReached; - glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), - GetRunspeed(), WaypointChanged, NodeReached); + glm::vec3 Goal = UpdatePath( + GetTarget()->GetX(), + GetTarget()->GetY(), + GetTarget()->GetZ(), + GetRunspeed(), + WaypointChanged, + NodeReached + ); if (WaypointChanged) tar_ndx = 20; @@ -1588,7 +1594,7 @@ void Merc::AI_Process() { } } - if(IsMoving()) + if (IsMoving()) SendPositionUpdate(); else SendPosition(); diff --git a/zone/mob.h b/zone/mob.h index 422c76cd3..bdfbd31bc 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -981,7 +981,7 @@ public: inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);} float CalculateHeadingToTarget(float in_x, float in_y) { return HeadingAngleToMob(in_x, in_y); } - virtual bool CalculateNewPosition(float x, float y, float z, int speed, bool checkZ = true, bool calcheading = true); + virtual bool CalculateNewPosition(float x, float y, float z, float speed, bool check_z = true, bool calculate_heading = true); float CalculateDistance(float x, float y, float z); float GetGroundZ(float new_x, float new_y, float z_offset=0.0); void SendTo(float new_x, float new_y, float new_z); @@ -989,7 +989,7 @@ public: float GetZOffset() const; float GetDefaultRaceSize() const; void FixZ(int32 z_find_offset = 5); - float GetFixedZ(glm::vec3 position, int32 z_find_offset = 5); + float GetFixedZ(glm::vec3 destination, int32 z_find_offset = 5); void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false); inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; } @@ -1165,7 +1165,7 @@ protected: int _GetWalkSpeed() const; int _GetRunSpeed() const; int _GetFearSpeed() const; - virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ = true, bool calcHeading = true); + virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, bool check_z = true, bool calculate_heading = true); virtual bool AI_EngagedCastCheck() { return(false); } virtual bool AI_PursueCastCheck() { return(false); } @@ -1443,7 +1443,7 @@ protected: std::unique_ptr AI_feign_remember_timer; std::unique_ptr AI_check_signal_timer; std::unique_ptr AI_scan_door_open_timer; - uint32 pLastFightingDelayMoving; + uint32 time_until_can_move; HateList hate_list; std::set feign_memory_list; // This is to keep track of mobs we cast faction mod spells on diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index e769bda95..0579fd60d 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -30,6 +30,7 @@ #include "string_ids.h" #include "water_map.h" #include "fastmath.h" +#include "../common/data_verification.h" #include #include @@ -459,8 +460,8 @@ void NPC::AI_Init() roambox_min_x = 0; roambox_min_y = 0; roambox_distance = 0; - roambox_movingto_x = 0; - roambox_movingto_y = 0; + roambox_destination_x = 0; + roambox_destination_y = 0; roambox_min_delay = 2500; roambox_delay = 2500; } @@ -476,9 +477,9 @@ void Mob::AI_Start(uint32 iMoveDelay) { return; if (iMoveDelay) - pLastFightingDelayMoving = Timer::GetCurrentTime() + iMoveDelay; + time_until_can_move = Timer::GetCurrentTime() + iMoveDelay; else - pLastFightingDelayMoving = 0; + time_until_can_move = 0; pAIControlled = true; AI_think_timer = std::unique_ptr(new Timer(AIthink_duration)); @@ -1053,7 +1054,7 @@ void Mob::AI_Process() { if (IsCasting()) return; - bool engaged = IsEngaged(); + bool engaged = IsEngaged(); bool doranged = false; if (!zone->CanDoCombat() || IsPetStop() || IsPetRegroup()) { @@ -1063,7 +1064,7 @@ void Mob::AI_Process() { if (moving) { if (AI_scan_door_open_timer->Check()) { - auto &door_list = entity_list.GetDoorsList(); + auto &door_list = entity_list.GetDoorsList(); for (auto itr : door_list) { Doors *door = itr.second; @@ -1096,39 +1097,46 @@ void Mob::AI_Process() { // Begin: Additions for Wiz Fear Code // - if(RuleB(Combat, EnableFearPathing)){ - if(currently_fleeing) { - if((IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) && !IsPetStop() && !IsPetRegroup()) { + if (RuleB(Combat, EnableFearPathing)) { + if (currently_fleeing) { + if ((IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) && !IsPetStop() && + !IsPetRegroup()) { //make sure everybody knows were not moving, for appearance sake - if(IsMoving()) - { - if(target) + if (IsMoving()) { + if (target) SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY())); SetCurrentSpeed(0); - moved=false; + moved = false; } //continue on to attack code, ensuring that we execute the engaged code engaged = true; - } else { - if(AI_movement_timer->Check()) { + } + else { + if (AI_movement_timer->Check()) { // Check if we have reached the last fear point if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) && - (std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) { + (std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) { // Calculate a new point to run to CalculateNewFearpoint(); } - if(!RuleB(Pathing, Fear) || !zone->pathing) - { - CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true); + if (!RuleB(Pathing, Fear) || !zone->pathing) { + CalculateNewPosition( + m_FearWalkTarget.x, + m_FearWalkTarget.y, + m_FearWalkTarget.z, + GetFearSpeed(), + true + ); } - else - { + else { bool WaypointChanged, NodeReached; - glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, - GetFearSpeed(), WaypointChanged, NodeReached); + glm::vec3 Goal = UpdatePath( + m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, + GetFearSpeed(), WaypointChanged, NodeReached + ); - if(WaypointChanged) + if (WaypointChanged) tar_ndx = 20; CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetFearSpeed()); @@ -1154,7 +1162,7 @@ void Mob::AI_Process() { this->FixZ(); if (target_distance <= 15 && !this->CheckLosFN(this->GetTarget())) { - Mob* target = this->GetTarget(); + Mob *target = this->GetTarget(); m_Position.x = target->GetX(); m_Position.y = target->GetY(); @@ -1183,10 +1191,8 @@ void Mob::AI_Process() { // from above, so no extra blind checks needed if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind()) SetTarget(hate_list.GetClosestEntOnHateList(this)); - else - { - if (AI_target_check_timer->Check()) - { + else { + if (AI_target_check_timer->Check()) { if (IsFocused()) { if (!target) { SetTarget(hate_list.GetEntWithMostHateOnList(this)); @@ -1248,21 +1254,16 @@ void Mob::AI_Process() { bool is_combat_range = CombatRange(target); - if (is_combat_range) - { - if (AI_movement_timer->Check()) - { - if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) - { + if (is_combat_range) { + if (AI_movement_timer->Check()) { + if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) { SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); SendPosition(); } SetCurrentSpeed(0); } - if (IsMoving()) - { - if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) - { + if (IsMoving()) { + if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) { SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); SendPosition(); } @@ -1287,7 +1288,7 @@ void Mob::AI_Process() { if (zone->random.Roll(flurry_chance)) { ExtraAttackOptions opts; - int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2); + int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2); if (cur > 0) opts.damage_percent = cur / 100.0f; @@ -1322,7 +1323,7 @@ void Mob::AI_Process() { if (owner) { int16 flurry_chance = owner->aabonuses.PetFlurry + - owner->spellbonuses.PetFlurry + owner->itembonuses.PetFlurry; + owner->spellbonuses.PetFlurry + owner->itembonuses.PetFlurry; if (flurry_chance && zone->random.Roll(flurry_chance)) Flurry(nullptr); @@ -1330,21 +1331,22 @@ void Mob::AI_Process() { } if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { - if (spellbonuses.PC_Pet_Rampage[0] || itembonuses.PC_Pet_Rampage[0] || aabonuses.PC_Pet_Rampage[0]) { - int chance = spellbonuses.PC_Pet_Rampage[0] + itembonuses.PC_Pet_Rampage[0] + aabonuses.PC_Pet_Rampage[0]; + if (spellbonuses.PC_Pet_Rampage[0] || itembonuses.PC_Pet_Rampage[0] || + aabonuses.PC_Pet_Rampage[0]) { + int chance = spellbonuses.PC_Pet_Rampage[0] + itembonuses.PC_Pet_Rampage[0] + + aabonuses.PC_Pet_Rampage[0]; if (zone->random.Roll(chance)) { Rampage(nullptr); } } } - if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed) - { + if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed) { int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0); rampage_chance = rampage_chance > 0 ? rampage_chance : 20; if (zone->random.Roll(rampage_chance)) { ExtraAttackOptions opts; - int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3); + int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3); if (cur > 0) { opts.damage_flat = cur; } @@ -1373,13 +1375,12 @@ void Mob::AI_Process() { } } - if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed) - { + if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed) { int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0); rampage_chance = rampage_chance > 0 ? rampage_chance : 20; if (zone->random.Roll(rampage_chance)) { ExtraAttackOptions opts; - int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3); + int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3); if (cur > 0) { opts.damage_flat = cur; } @@ -1421,7 +1422,7 @@ void Mob::AI_Process() { } AI_EngagedCastCheck(); - } //end is within combat rangepet + } //end is within combat rangepet else { //we cannot reach our target... //underwater stuff only works with water maps in the zone! @@ -1434,7 +1435,7 @@ void Mob::AI_Process() { Heal(); BuffFadeAll(); AI_walking_timer->Start(100); - pLastFightingDelayMoving = Timer::GetCurrentTime(); + time_until_can_move = Timer::GetCurrentTime(); return; } else if (tar != nullptr) { @@ -1445,8 +1446,7 @@ void Mob::AI_Process() { } // See if we can summon the mob to us - if (!HateSummon()) - { + if (!HateSummon()) { //could not summon them, check ranged... if (GetSpecialAbility(SPECATK_RANGED_ATK)) doranged = true; @@ -1456,18 +1456,18 @@ void Mob::AI_Process() { if (AI_PursueCastCheck()) { //we did something, so do not process movement. } - else if (AI_movement_timer->Check() && target) - { + else if (AI_movement_timer->Check() && target) { if (!IsRooted()) { Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName()); if (!RuleB(Pathing, Aggro) || !zone->pathing) CalculateNewPosition(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed()); - else - { + else { bool WaypointChanged, NodeReached; - glm::vec3 Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(), - GetRunspeed(), WaypointChanged, NodeReached); + glm::vec3 Goal = UpdatePath( + target->GetX(), target->GetY(), target->GetZ(), + GetRunspeed(), WaypointChanged, NodeReached + ); if (WaypointChanged) tar_ndx = 20; @@ -1492,69 +1492,64 @@ void Mob::AI_Process() { if (IsPetStop()) // pet stop won't be engaged, so we will always get here and we want the above branch to execute return; - if(zone->CanDoCombat() && AI_feign_remember_timer->Check()) { + if (zone->CanDoCombat() && AI_feign_remember_timer->Check()) { // 6/14/06 // Improved Feign Death Memory // check to see if any of our previous feigned targets have gotten up. std::set::iterator RememberedCharID; RememberedCharID = feign_memory_list.begin(); while (RememberedCharID != feign_memory_list.end()) { - Client* remember_client = entity_list.GetClientByCharID(*RememberedCharID); + Client *remember_client = entity_list.GetClientByCharID(*RememberedCharID); if (remember_client == nullptr) { //they are gone now... RememberedCharID = feign_memory_list.erase(RememberedCharID); - } else if (!remember_client->GetFeigned()) { - AddToHateList(remember_client->CastToMob(),1); + } + else if (!remember_client->GetFeigned()) { + AddToHateList(remember_client->CastToMob(), 1); RememberedCharID = feign_memory_list.erase(RememberedCharID); break; - } else { + } + else { //they are still feigned, carry on... ++RememberedCharID; } } } - if (AI_IdleCastCheck()) - { + if (AI_IdleCastCheck()) { //we processed a spell action, so do nothing else. } - else if (zone->CanDoCombat() && CastToNPC()->WillAggroNPCs() && AI_scan_area_timer->Check()) - { + else if (zone->CanDoCombat() && CastToNPC()->WillAggroNPCs() && AI_scan_area_timer->Check()) { + /* * NPC to NPC aggro checking, npc needs npc_aggro flag */ - - Mob* temp_target = entity_list.AICheckNPCtoNPCAggro(this, GetAggroRange(), GetAssistRange()); - if (temp_target){ + Mob *temp_target = entity_list.AICheckNPCtoNPCAggro(this, GetAggroRange(), GetAssistRange()); + if (temp_target) { AddToHateList(temp_target); } AI_scan_area_timer->Disable(); - AI_scan_area_timer->Start(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)), false); + AI_scan_area_timer->Start( + RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)), + false + ); } - else if (AI_movement_timer->Check() && !IsRooted()) - { - if (IsPet()) - { + else if (AI_movement_timer->Check() && !IsRooted()) { + if (IsPet()) { // we're a pet, do as we're told - switch (pStandingPetOrder) - { - case SPO_Follow: - { + switch (pStandingPetOrder) { + case SPO_Follow: { - Mob* owner = GetOwner(); - if(owner == nullptr) + Mob *owner = GetOwner(); + if (owner == nullptr) break; - //if(owner->IsClient()) - // printf("Pet start pos: (%f, %f, %f)\n", GetX(), GetY(), GetZ()); - glm::vec4 ownerPos = owner->GetPosition(); - float dist = DistanceSquared(m_Position, ownerPos); - float distz = ownerPos.z - m_Position.z; + float dist = DistanceSquared(m_Position, ownerPos); + float distz = ownerPos.z - m_Position.z; - if (dist >= 400 || distz > 100) - { + if (dist >= 400 || distz > 100) { int speed = GetWalkspeed(); if (dist >= 1225) // 35 speed = GetRunspeed(); @@ -1565,46 +1560,27 @@ void Mob::AI_Process() { SendPositionUpdate(); moved = true; } - else - { - CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), speed); + else { + CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), speed); } } - else - { - if(moved) - { + else { + if (moved) { this->FixZ(); SetCurrentSpeed(0); moved = false; } } - /* - //fix up Z - float zdiff = GetZ() - owner->GetZ(); - if(zdiff < 0) - zdiff = 0 - zdiff; - if(zdiff > 2.0f) { - SendTo(GetX(), GetY(), owner->GetZ()); - SendPosition(); - } - - if(owner->IsClient()) - printf("Pet pos: (%f, %f, %f)\n", GetX(), GetY(), GetZ()); - */ - break; } - case SPO_Sit: - { + case SPO_Sit: { SetAppearance(eaSitting, false); break; } - case SPO_Guard: - { + case SPO_Guard: { //only NPCs can guard stuff. (forced by where the guard movement code is in the AI) - if(IsNPC()) { + if (IsNPC()) { CastToNPC()->NextGuardPosition(); } break; @@ -1613,25 +1589,23 @@ void Mob::AI_Process() { if (IsPetRegroup()) return; } - /* Entity has been assigned another entity to follow */ - else if (GetFollowID()) - { - Mob* follow = entity_list.GetMob(GetFollowID()); - if (!follow) SetFollowID(0); - else - { - float dist2 = DistanceSquared(m_Position, follow->GetPosition()); - int followdist = GetFollowDistance(); + /* Entity has been assigned another entity to follow */ + else if (GetFollowID()) { + Mob *follow = entity_list.GetMob(GetFollowID()); + if (!follow) { SetFollowID(0); } + else { + float dist2 = DistanceSquared(m_Position, follow->GetPosition()); + int followdist = GetFollowDistance(); - if (dist2 >= followdist) // Default follow distance is 100 + if (dist2 >= followdist) // Default follow distance is 100 { int speed = GetWalkspeed(); - if (dist2 >= followdist + 150) + if (dist2 >= followdist + 150) { speed = GetRunspeed(); + } CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), speed); } - else - { + else { moved = false; SetCurrentSpeed(0); } @@ -1640,20 +1614,21 @@ void Mob::AI_Process() { else //not a pet, and not following somebody... { // dont move till a bit after you last fought - if (pLastFightingDelayMoving < Timer::GetCurrentTime()) - { - if (this->IsClient()) - { - // LD timer expired, drop out of world - if (this->CastToClient()->IsLD()) + if (time_until_can_move < Timer::GetCurrentTime()) { + if (this->IsClient()) { + + /** + * LD timer expired, drop out of world + */ + if (this->CastToClient()->IsLD()) { this->CastToClient()->Disconnect(); + } + return; } - if(IsNPC()) - { - if(RuleB(NPC, SmartLastFightingDelayMoving) && !feign_memory_list.empty()) - { + if (IsNPC()) { + if (RuleB(NPC, SmartLastFightingDelayMoving) && !feign_memory_list.empty()) { minLastFightingDelayMoving = 0; maxLastFightingDelayMoving = 0; } @@ -1661,93 +1636,84 @@ void Mob::AI_Process() { CastToNPC()->AI_DoMovement(); } } - } - } // else if (AImovement_timer->Check()) + } } //Do Ranged attack here - if(doranged) - { + if (doranged) { RangedAttack(target); } } void NPC::AI_DoMovement() { - float walksp = GetMovespeed(); - if(walksp <= 0.0f) - return; //this is idle movement at walk speed, and we are unable to walk right now. - if (roambox_distance > 0) { - if ( - roambox_movingto_x > roambox_max_x - || roambox_movingto_x < roambox_min_x - || roambox_movingto_y > roambox_max_y - || roambox_movingto_y < roambox_min_y - ) - { - float movedist = roambox_distance*roambox_distance; - float movex = zone->random.Real(0, movedist); - float movey = movedist - movex; - movex = sqrtf(movex); - movey = sqrtf(movey); - movex *= zone->random.Int(0, 1) ? 1 : -1; - movey *= zone->random.Int(0, 1) ? 1 : -1; - roambox_movingto_x = GetX() + movex; - roambox_movingto_y = GetY() + movey; - //Try to calculate new coord using distance. - if (roambox_movingto_x > roambox_max_x || roambox_movingto_x < roambox_min_x) - roambox_movingto_x -= movex * 2; - if (roambox_movingto_y > roambox_max_y || roambox_movingto_y < roambox_min_y) - roambox_movingto_y -= movey * 2; - //New coord is still invalid, ignore distance and just pick a new random coord. - //If we're here we may have a roambox where one side is shorter than the specified distance. Commons, Wkarana, etc. - if (roambox_movingto_x > roambox_max_x || roambox_movingto_x < roambox_min_x) - roambox_movingto_x = zone->random.Real(roambox_min_x+1,roambox_max_x-1); - if (roambox_movingto_y > roambox_max_y || roambox_movingto_y < roambox_min_y) - roambox_movingto_y = zone->random.Real(roambox_min_y+1,roambox_max_y-1); - Log(Logs::Detail, Logs::AI, - "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)", - roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, - roambox_max_y, roambox_movingto_x, roambox_movingto_y); - } - - Log(Logs::Detail, Logs::AI, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)", - roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y); + float move_speed = GetMovespeed(); - float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 5) + GetZOffset(); - - if (!CalculateNewPosition(roambox_movingto_x, roambox_movingto_y, new_z, walksp, true)) - { - this->FixZ(); // FixZ on final arrival point. - roambox_movingto_x = roambox_max_x + 1; // force update - pLastFightingDelayMoving = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); - SetMoving(false); - SendPosition(); // makes mobs stop clientside - } + if (move_speed <= 0.0f) { + return; } - else if (roamer) - { - if (AI_walking_timer->Check()) - { - movetimercompleted=true; + + /** + * Roambox logic sets precedence + */ + if (roambox_distance > 0) { + + if (!IsMoving()) { + 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_y = EQEmu::Clamp((GetY() + move_y), roambox_min_y, roambox_max_y); + + this->FixZ(); + + Log(Logs::Detail, + Logs::NPCRoamBox, + "Calculate | NPC: %s distance %.3f | min_x %.3f | max_x %.3f | final_x %.3f | min_y %.3f | max_y %.3f | final_y %.3f", + this->GetCleanName(), + roambox_distance, + roambox_min_x, + roambox_max_x, + roambox_destination_x, + roambox_min_y, + roambox_max_y, + roambox_destination_y); + } + + if (!CalculateNewPosition(roambox_destination_x, roambox_destination_y, GetFixedZ(m_Position), move_speed, true)) { + time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); + SetMoving(false); + this->FixZ(); + SendPosition(); + } + + return; + } + else if (roamer) { + if (AI_walking_timer->Check()) { + movetimercompleted = true; AI_walking_timer->Disable(); } - int32 gridno = CastToNPC()->GetGrid(); - if (gridno > 0 || cur_wp==-2) { - if (movetimercompleted==true) { // time to pause at wp is over + if (gridno > 0 || cur_wp == -2) { + if (movetimercompleted == true) { // time to pause at wp is over AI_SetupNextWaypoint(); - } // endif (movetimercompleted==true) - else if (!(AI_walking_timer->Enabled())) - { // currently moving + } // endif (movetimercompleted==true) + else if (!(AI_walking_timer->Enabled())) { // currently moving bool doMove = true; - if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY()) - { // are we there yet? then stop - Log(Logs::Detail, Logs::AI, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid()); - + if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY()) { // are we there yet? then stop + Log(Logs::Detail, + Logs::AI, + "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", + cur_wp, + GetX(), + GetY(), + GetZ(), + GetGrid()); + SetWaypointPause(); SetAppearance(eaStanding, false); SetMoving(false); @@ -1773,36 +1739,45 @@ void NPC::AI_DoMovement() { } // wipe feign memory since we reached our first waypoint - if(cur_wp == 1) + if (cur_wp == 1) ClearFeignMemory(); } - if (doMove) - { // not at waypoint yet or at 0 pause WP, so keep moving - if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0)) - CalculateNewPosition(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true); - else - { - bool WaypointChanged; - bool NodeReached; - glm::vec3 Goal = UpdatePath(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, WaypointChanged, NodeReached); - if(WaypointChanged) + if (doMove) { // not at waypoint yet or at 0 pause WP, so keep moving + if (!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0)) + CalculateNewPosition( + m_CurrentWayPoint.x, + m_CurrentWayPoint.y, + m_CurrentWayPoint.z, + move_speed, + true + ); + else { + bool WaypointChanged; + bool NodeReached; + glm::vec3 Goal = UpdatePath( + m_CurrentWayPoint.x, + m_CurrentWayPoint.y, + m_CurrentWayPoint.z, + move_speed, + WaypointChanged, + NodeReached + ); + if (WaypointChanged) tar_ndx = 20; - if(NodeReached) + if (NodeReached) entity_list.OpenDoorsNear(CastToNPC()); - CalculateNewPosition(Goal.x, Goal.y, Goal.z, walksp, true); + CalculateNewPosition(Goal.x, Goal.y, Goal.z, move_speed, true); } } } - } // endif (gridno > 0) - // handle new quest grid command processing - else if (gridno < 0) - { // this mob is under quest control - if (movetimercompleted==true) - { // time to pause has ended - SetGrid( 0 - GetGrid()); // revert to AI control + } // endif (gridno > 0) + // handle new quest grid command processing + else if (gridno < 0) { // this mob is under quest control + if (movetimercompleted == true) { // time to pause has ended + SetGrid(0 - GetGrid()); // revert to AI control Log(Logs::Detail, Logs::Pathing, "Quest pathing is finished. Resuming on grid %d", GetGrid()); SetAppearance(eaStanding, false); @@ -1812,39 +1787,55 @@ void NPC::AI_DoMovement() { } } - else if (IsGuarding()) - { + else if (IsGuarding()) { bool CP2Moved; - if(!RuleB(Pathing, Guard) || !zone->pathing) - CP2Moved = CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp); - else - { - if(!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z))) - { + if (!RuleB(Pathing, Guard) || !zone->pathing) { + CP2Moved = CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, move_speed); + } + else { + if (!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && + (m_Position.z == m_GuardPoint.z))) { + bool WaypointChanged, NodeReached; - glm::vec3 Goal = UpdatePath(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp, WaypointChanged, NodeReached); - if(WaypointChanged) + + glm::vec3 Goal = UpdatePath( + m_GuardPoint.x, + m_GuardPoint.y, + m_GuardPoint.z, + move_speed, + WaypointChanged, + NodeReached + ); + if (WaypointChanged) { tar_ndx = 20; + } - if(NodeReached) + if (NodeReached) { entity_list.OpenDoorsNear(CastToNPC()); + } - CP2Moved = CalculateNewPosition(Goal.x, Goal.y, Goal.z, walksp); + CP2Moved = CalculateNewPosition(Goal.x, Goal.y, Goal.z, move_speed); } - else + else { CP2Moved = false; + } } - if (!CP2Moved) - { - if(moved) { - Log(Logs::Detail, Logs::AI, "Reached guard point (%.3f,%.3f,%.3f)", m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z); + if (!CP2Moved) { + if (moved) { + Log(Logs::Detail, + Logs::AI, + "Reached guard point (%.3f,%.3f,%.3f)", + m_GuardPoint.x, + m_GuardPoint.y, + m_GuardPoint.z); + ClearFeignMemory(); - moved=false; - if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5*5 ) - { + moved = false; + if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5 * 5) { SetHeading(m_GuardPoint.w); - } else { + } + else { FaceTarget(GetTarget()); } SetCurrentSpeed(0); @@ -1968,11 +1959,11 @@ void Mob::AI_Event_NoLongerEngaged() { if (!IsAIControlled()) return; this->AI_walking_timer->Start(RandomTimer(3000,20000)); - pLastFightingDelayMoving = Timer::GetCurrentTime(); + time_until_can_move = Timer::GetCurrentTime(); if (minLastFightingDelayMoving == maxLastFightingDelayMoving) - pLastFightingDelayMoving += minLastFightingDelayMoving; + time_until_can_move += minLastFightingDelayMoving; else - pLastFightingDelayMoving += zone->random.Int(minLastFightingDelayMoving, maxLastFightingDelayMoving); + time_until_can_move += zone->random.Int(minLastFightingDelayMoving, maxLastFightingDelayMoving); // So mobs don't keep running as a ghost until AIwalking_timer fires // if they were moving prior to losing all hate // except if we're a pet, then we might run into some issues with pets backing off when they should immediately be moving diff --git a/zone/npc.cpp b/zone/npc.cpp index 7cf31b617..bf1508858 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -242,8 +242,8 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if roambox_max_y = -2; roambox_min_x = -2; roambox_min_y = -2; - roambox_movingto_x = -2; - roambox_movingto_y = -2; + roambox_destination_x = -2; + roambox_destination_y = -2; roambox_min_delay = 1000; roambox_delay = 1000; p_depop = false; diff --git a/zone/npc.h b/zone/npc.h index 471b47557..52c8b2171 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -311,9 +311,17 @@ public: void SaveGuardSpot(bool iClearGuardSpot = false); inline bool IsGuarding() const { return(m_GuardPoint.w != 0); } void SaveGuardSpotCharm(); - void RestoreGuardSpotCharm(); - void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500); - void AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, uint32 iDelay = 2500, uint32 iMinDelay = 2500); + + void RestoreGuardSpotCharm(); + + void AI_SetRoambox( + float max_distance, + float roam_distance_variance, + uint32 delay = 2500, + uint32 min_delay = 2500 + ); + + void AI_SetRoambox(float distance, float max_x, float min_x, float max_y, float min_y, uint32 delay = 2500, uint32 min_delay = 2500); //mercenary stuff void LoadMercTypes(); @@ -530,8 +538,8 @@ protected: float roambox_min_x; float roambox_min_y; float roambox_distance; - float roambox_movingto_x; - float roambox_movingto_y; + float roambox_destination_x; + float roambox_destination_y; uint32 roambox_delay; uint32 roambox_min_delay; diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index bfc474721..71101dff8 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -141,118 +141,181 @@ uint32 Spawn2::despawnTimer(uint32 despawn_timer) bool Spawn2::Process() { IsDespawned = false; - if(!Enabled()) + if (!Enabled()) return true; //grab our spawn group - SpawnGroup* sg = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); + SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); - if(NPCPointerValid() && (sg->despawn == 0 || condition_id != 0)) + if (NPCPointerValid() && (spawn_group->despawn == 0 || condition_id != 0)) { return true; + } - if (timer.Check()) { + if (timer.Check()) { timer.Disable(); Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Timer has triggered", spawn2_id); //first check our spawn condition, if this isnt active //then we reset the timer and try again next time. - if(condition_id != SC_AlwaysEnabled + if (condition_id != SC_AlwaysEnabled && !zone->spawn_conditions.Check(condition_id, condition_min_value)) { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: spawning prevented by spawn condition %d", spawn2_id, condition_id); + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: spawning prevented by spawn condition %d", + spawn2_id, + condition_id); Reset(); - return(true); + return (true); } - if (sg == nullptr) { - database.LoadSpawnGroupsByID(spawngroup_id_,&zone->spawn_group_list); - sg = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); + if (spawn_group == nullptr) { + database.LoadSpawnGroupsByID(spawngroup_id_, &zone->spawn_group_list); + spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); } - if (sg == nullptr) { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Unable to locate spawn group %d. Disabling.", spawn2_id, spawngroup_id_); + if (spawn_group == nullptr) { + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Unable to locate spawn group %d. Disabling.", + spawn2_id, + spawngroup_id_); + return false; } //have the spawn group pick an NPC for us - uint32 npcid = sg->GetNPCType(); + uint32 npcid = spawn_group->GetNPCType(); if (npcid == 0) { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", spawn2_id, spawngroup_id_); - Reset(); //try again later (why?) - return(true); + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", + spawn2_id, + spawngroup_id_); + + Reset(); //try again later (why?) + return (true); } //try to find our NPC type. - const NPCType* tmp = database.LoadNPCTypesData(npcid); + const NPCType *tmp = database.LoadNPCTypesData(npcid); if (tmp == nullptr) { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", spawn2_id, spawngroup_id_, npcid); - Reset(); //try again later - return(true); + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", + spawn2_id, + spawngroup_id_, + npcid); + Reset(); //try again later + return (true); } - if(tmp->unique_spawn_by_name) - { - if(!entity_list.LimitCheckName(tmp->name)) - { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.", spawn2_id, spawngroup_id_, npcid); - timer.Start(5000); //try again in five seconds. - return(true); + if (tmp->unique_spawn_by_name) { + if (!entity_list.LimitCheckName(tmp->name)) { + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.", + spawn2_id, + spawngroup_id_, + npcid); + timer.Start(5000); //try again in five seconds. + return (true); } } - if(tmp->spawn_limit > 0) { - if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)", spawn2_id, spawngroup_id_, npcid, tmp->spawn_limit); - timer.Start(5000); //try again in five seconds. - return(true); + if (tmp->spawn_limit > 0) { + if (!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) { + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)", + spawn2_id, + spawngroup_id_, + npcid, + tmp->spawn_limit); + timer.Start(5000); //try again in five seconds. + return (true); } } bool ignore_despawn = false; - if (npcthis) - { + if (npcthis) { ignore_despawn = npcthis->IgnoreDespawn(); } - - if (ignore_despawn) - { + + if (ignore_despawn) { return true; } - - if (sg->despawn != 0 && condition_id == 0 && !ignore_despawn) - { + + if (spawn_group->despawn != 0 && condition_id == 0 && !ignore_despawn) { zone->Despawn(spawn2_id); } - if (IsDespawned) - { + if (IsDespawned) { return true; } currentnpcid = npcid; - NPC* npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), FlyMode3); + NPC *npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), FlyMode3); npc->mod_prespawn(this); npcthis = npc; npc->AddLootTable(); - if (npc->DropsGlobalLoot()) + if (npc->DropsGlobalLoot()) { npc->CheckGlobalLootTables(); + } npc->SetSp2(spawngroup_id_); npc->SaveGuardPointAnim(anim); - npc->SetAppearance((EmuAppearance)anim); + npc->SetAppearance((EmuAppearance) anim); entity_list.AddNPC(npc); //this limit add must be done after the AddNPC since we need the entity ID. entity_list.LimitAddNPC(npc); - if(sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay && sg->min_delay) - npc->AI_SetRoambox(sg->roamdist,sg->roambox[0],sg->roambox[1],sg->roambox[2],sg->roambox[3],sg->delay,sg->min_delay); - if(zone->InstantGrids()) { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f).", spawn2_id, spawngroup_id_, npc->GetName(), npcid, x, y, z); + + /** + * Roambox init + */ + if (spawn_group->roamdist && spawn_group->roambox[0] && spawn_group->roambox[1] && spawn_group->roambox[2] && + spawn_group->roambox[3] && spawn_group->delay && spawn_group->min_delay) { + + npc->AI_SetRoambox( + spawn_group->roamdist, + spawn_group->roambox[0], + spawn_group->roambox[1], + spawn_group->roambox[2], + spawn_group->roambox[3], + spawn_group->delay, + spawn_group->min_delay + ); + } + + if (zone->InstantGrids()) { + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f).", + spawn2_id, + spawngroup_id_, + npc->GetName(), + npcid, + x, + y, + z); + LoadGrid(); - } else { - Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f). Grid loading delayed.", spawn2_id, spawngroup_id_, tmp->name, npcid, x, y, z); + } + else { + Log(Logs::Detail, + Logs::Spawns, + "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f). Grid loading delayed.", + spawn2_id, + spawngroup_id_, + tmp->name, + npcid, + x, + y, + z); } } + return true; } @@ -266,11 +329,11 @@ void Spawn2::Disable() } void Spawn2::LoadGrid() { - if(!npcthis) + if (!npcthis) return; - if(grid_ < 1) + if (grid_ < 1) return; - if(!entity_list.IsMobInZone(npcthis)) + if (!entity_list.IsMobInZone(npcthis)) return; //dont set an NPC's grid until its loaded for them. npcthis->SetGrid(grid_); @@ -278,7 +341,6 @@ void Spawn2::LoadGrid() { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Loading grid %d for %s", spawn2_id, grid_, npcthis->GetName()); } - /* All three of these actions basically say that the mob which was associated with this spawn point is no longer relavent. diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 2351e2686..083cc38ba 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -42,19 +42,27 @@ struct wp_distance int index; }; -void NPC::AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay, uint32 iMinDelay) { - AI_SetRoambox(iDist, GetX() + iRoamDist, GetX() - iRoamDist, GetY() + iRoamDist, GetY() - iRoamDist, iDelay, iMinDelay); +void NPC::AI_SetRoambox(float max_distance, float roam_distance_variance, uint32 delay, uint32 min_delay) { + AI_SetRoambox( + max_distance, + GetX() + roam_distance_variance, + GetX() - roam_distance_variance, + GetY() + roam_distance_variance, + GetY() - roam_distance_variance, + delay, + min_delay + ); } -void NPC::AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, uint32 iDelay, uint32 iMinDelay) { - roambox_distance = iDist; - roambox_max_x = iMaxX; - roambox_min_x = iMinX; - roambox_max_y = iMaxY; - roambox_min_y = iMinY; - roambox_movingto_x = roambox_max_x + 1; // this will trigger a recalc - roambox_delay = iDelay; - roambox_min_delay = iMinDelay; +void NPC::AI_SetRoambox(float distance, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 min_delay) { + roambox_distance = distance; + roambox_max_x = max_x; + roambox_min_x = min_x; + roambox_max_y = max_y; + roambox_min_y = min_y; + roambox_destination_x = roambox_max_x + 1; // this will trigger a recalc + roambox_delay = delay; + roambox_min_delay = min_delay; } void NPC::DisplayWaypointInfo(Client *c) { @@ -199,7 +207,7 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) } cur_wp_pause = 0; - pLastFightingDelayMoving = 0; + time_until_can_move = 0; if (AI_walking_timer->Enabled()) AI_walking_timer->Start(100); } @@ -438,22 +446,16 @@ float Mob::CalculateDistance(float x, float y, float z) { return (float)sqrtf(((m_Position.x - x)*(m_Position.x - x)) + ((m_Position.y - y)*(m_Position.y - y)) + ((m_Position.z - z)*(m_Position.z - z))); } -bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ, bool calcHeading) { +bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, bool check_z, bool calculate_heading) { if (GetID() == 0) return true; - if (speed <= 0) - { + if (speed <= 0) { SetCurrentSpeed(0); return true; } if ((m_Position.x - x == 0) && (m_Position.y - y == 0)) {//spawn is at target coords - if (m_Position.z - z != 0) { - m_Position.z = z; - Log(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z); - return true; - } return false; } else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) { @@ -464,16 +466,17 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Position.x = x; m_Position.y = y; m_Position.z = z; + return true; } - bool send_update = false; int compare_steps = 20; if (tar_ndx < compare_steps && m_TargetLocation.x == x && m_TargetLocation.y == y) { - float new_x = m_Position.x + m_TargetV.x*tar_vector; - float new_y = m_Position.y + m_TargetV.y*tar_vector; - float new_z = m_Position.z + m_TargetV.z*tar_vector; + float new_x = m_Position.x + m_TargetV.x * tar_vector; + float new_y = m_Position.y + m_TargetV.y * tar_vector; + float new_z = m_Position.z + m_TargetV.z * tar_vector; + if (IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } @@ -482,21 +485,22 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Position.y = new_y; m_Position.z = new_z; - if(checkZ && fix_z_timer.Check() && - (!this->IsEngaged() || flee_mode || currently_fleeing)) + if (check_z && fix_z_timer.Check() && (!this->IsEngaged() || flee_mode || currently_fleeing)) { this->FixZ(); + } tar_ndx++; + return true; } - - if (tar_ndx>50) { + if (tar_ndx > 50) { tar_ndx--; } else { tar_ndx = 0; } + m_TargetLocation = glm::vec3(x, y, z); float nx = this->m_Position.x; @@ -530,14 +534,12 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo // mob move fix - if (numsteps<20) - { - if (numsteps>1) - { + if (numsteps < 20) { + if (numsteps > 1) { tar_vector = 1.0f; - m_TargetV.x = m_TargetV.x / (float)numsteps; - m_TargetV.y = m_TargetV.y / (float)numsteps; - m_TargetV.z = m_TargetV.z / (float)numsteps; + m_TargetV.x = m_TargetV.x / (float) numsteps; + m_TargetV.y = m_TargetV.y / (float) numsteps; + m_TargetV.z = m_TargetV.z / (float) numsteps; float new_x = m_Position.x + m_TargetV.x; float new_y = m_Position.y + m_TargetV.y; @@ -549,12 +551,12 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Position.x = new_x; m_Position.y = new_y; m_Position.z = new_z; - if (calcHeading) + if (calculate_heading) { m_Position.w = CalculateHeadingToTarget(x, y); + } tar_ndx = 20 - numsteps; } - else - { + else { if (IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } @@ -578,9 +580,10 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo tar_vector *= (dur / 100.0f); - float new_x = m_Position.x + m_TargetV.x*tar_vector; - float new_y = m_Position.y + m_TargetV.y*tar_vector; - float new_z = m_Position.z + m_TargetV.z*tar_vector; + float new_x = m_Position.x + m_TargetV.x * tar_vector; + float new_y = m_Position.y + m_TargetV.y * tar_vector; + float new_z = m_Position.z + m_TargetV.z * tar_vector; + if (IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } @@ -588,11 +591,12 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Position.x = new_x; m_Position.y = new_y; m_Position.z = new_z; - if (calcHeading) + if (calculate_heading) { m_Position.w = CalculateHeadingToTarget(x, y); + } } - if (checkZ && fix_z_timer.Check() && !this->IsEngaged()) + if (check_z && fix_z_timer.Check() && !this->IsEngaged()) this->FixZ(); SetMoving(true); @@ -600,13 +604,11 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f); - if (IsClient()) - { + if (IsClient()) { SendPositionUpdate(1); CastToClient()->ResetPositionTimer(); } - else - { + else { SendPositionUpdate(); SetAppearance(eaStanding, false); } @@ -615,8 +617,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo return true; } -bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ, bool calcHeading) { - return MakeNewPositionAndSendUpdate(x, y, z, speed); +bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool check_z, bool calculate_heading) { + return MakeNewPositionAndSendUpdate(x, y, z, speed, check_z); } void NPC::AssignWaypoints(int32 grid) @@ -746,10 +748,11 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) { } } -float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) { +float Mob::GetFixedZ(glm::vec3 destination, int32 z_find_offset) { BenchTimer timer; timer.reset(); - float new_z = dest.z; + + float new_z = destination.z; if (zone->HasMap() && RuleB(Map, FixZWhenMoving)) { @@ -765,7 +768,7 @@ float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) { /* * Any more than 5 in the offset makes NPC's hop/snap to ceiling in small corridors */ - new_z = this->FindDestGroundZ(dest, z_find_offset); + new_z = this->FindDestGroundZ(destination, z_find_offset); if (new_z != BEST_Z_INVALID) { new_z += this->GetZOffset(); @@ -776,9 +779,15 @@ float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) { auto duration = timer.elapsed(); - Log(Logs::Moderate, Logs::FixZ, - "Mob::GetFixedZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", - this->GetCleanName(), new_z, dest.x, dest.y, dest.z, duration); + Log(Logs::Moderate, + Logs::FixZ, + "Mob::GetFixedZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", + this->GetCleanName(), + new_z, + destination.x, + destination.y, + destination.z, + duration); } return new_z; @@ -790,16 +799,19 @@ void Mob::FixZ(int32 z_find_offset /*= 5*/) { if (!IsClient() && new_z != m_Position.z) { if ((new_z > -2000) && new_z != BEST_Z_INVALID) { - if (RuleB(Map, MobZVisualDebug)) + if (RuleB(Map, MobZVisualDebug)) { this->SendAppearanceEffect(78, 0, 0, 0, 0); + } m_Position.z = new_z; - } else { - if (RuleB(Map, MobZVisualDebug)) + } + else { + if (RuleB(Map, MobZVisualDebug)) { this->SendAppearanceEffect(103, 0, 0, 0, 0); + } Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f", - this->GetCleanName(), std::abs(m_Position.z - new_z)); + this->GetCleanName(), std::abs(m_Position.z - new_z)); } } }