mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 13:41:31 +00:00
Fix, cleanup and simplify the roambox logic and cleanup a bunch of other related code
This commit is contained in:
parent
7cc5b143fc
commit
4b6ab34fd9
@ -90,6 +90,7 @@ enum LogCategory {
|
|||||||
FixZ,
|
FixZ,
|
||||||
Food,
|
Food,
|
||||||
Traps,
|
Traps,
|
||||||
|
NPCRoamBox,
|
||||||
MaxCategoryID /* Don't Remove this*/
|
MaxCategoryID /* Don't Remove this*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,7 +145,8 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
|
|||||||
"HP Update",
|
"HP Update",
|
||||||
"FixZ",
|
"FixZ",
|
||||||
"Food",
|
"Food",
|
||||||
"Traps"
|
"Traps",
|
||||||
|
"NPC Roam Box"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3425,15 +3425,16 @@ 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_x = n->GetX();
|
||||||
float last_y = n->GetY();
|
float last_y = n->GetY();
|
||||||
float last_z = n->GetZ();
|
float last_z = n->GetZ();
|
||||||
|
|
||||||
std::list<quest_proximity_event> events;
|
std::list<quest_proximity_event> events;
|
||||||
|
|
||||||
for (auto iter = area_list.begin(); iter != area_list.end(); ++iter) {
|
for (auto iter = area_list.begin(); iter != area_list.end(); ++iter) {
|
||||||
Area& a = (*iter);
|
|
||||||
|
Area &a = (*iter);
|
||||||
bool old_in = true;
|
bool old_in = true;
|
||||||
bool new_in = true;
|
bool new_in = true;
|
||||||
if (last_x < a.min_x || last_x > a.max_x ||
|
if (last_x < a.min_x || last_x > a.max_x ||
|
||||||
@ -3457,7 +3458,8 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z)
|
|||||||
evt.area_id = a.id;
|
evt.area_id = a.id;
|
||||||
evt.area_type = a.type;
|
evt.area_type = a.type;
|
||||||
events.push_back(evt);
|
events.push_back(evt);
|
||||||
} else if (!old_in && new_in) {
|
}
|
||||||
|
else if (!old_in && new_in) {
|
||||||
//were not in but now are
|
//were not in but now are
|
||||||
quest_proximity_event evt;
|
quest_proximity_event evt;
|
||||||
evt.event_id = EVENT_ENTER_AREA;
|
evt.event_id = EVENT_ENTER_AREA;
|
||||||
@ -3470,7 +3472,7 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto iter = events.begin(); iter != events.end(); ++iter) {
|
for (auto iter = events.begin(); iter != events.end(); ++iter) {
|
||||||
quest_proximity_event& evt = (*iter);
|
quest_proximity_event &evt = (*iter);
|
||||||
std::vector<EQEmu::Any> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&evt.area_id);
|
args.push_back(&evt.area_id);
|
||||||
args.push_back(&evt.area_type);
|
args.push_back(&evt.area_type);
|
||||||
|
|||||||
@ -1481,8 +1481,14 @@ void Merc::AI_Process() {
|
|||||||
if (RuleB(Mercs, MercsUsePathing) && zone->pathing) {
|
if (RuleB(Mercs, MercsUsePathing) && zone->pathing) {
|
||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
glm::vec3 Goal = UpdatePath(
|
||||||
GetRunspeed(), WaypointChanged, NodeReached);
|
GetTarget()->GetX(),
|
||||||
|
GetTarget()->GetY(),
|
||||||
|
GetTarget()->GetZ(),
|
||||||
|
GetRunspeed(),
|
||||||
|
WaypointChanged,
|
||||||
|
NodeReached
|
||||||
|
);
|
||||||
|
|
||||||
if (WaypointChanged)
|
if (WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
@ -1588,7 +1594,7 @@ void Merc::AI_Process() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsMoving())
|
if (IsMoving())
|
||||||
SendPositionUpdate();
|
SendPositionUpdate();
|
||||||
else
|
else
|
||||||
SendPosition();
|
SendPosition();
|
||||||
|
|||||||
@ -981,7 +981,7 @@ public:
|
|||||||
|
|
||||||
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
|
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
|
||||||
float CalculateHeadingToTarget(float in_x, float in_y) { return HeadingAngleToMob(in_x, in_y); }
|
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 CalculateDistance(float x, float y, float z);
|
||||||
float GetGroundZ(float new_x, float new_y, float z_offset=0.0);
|
float GetGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||||
void SendTo(float new_x, float new_y, float new_z);
|
void SendTo(float new_x, float new_y, float new_z);
|
||||||
@ -989,7 +989,7 @@ public:
|
|||||||
float GetZOffset() const;
|
float GetZOffset() const;
|
||||||
float GetDefaultRaceSize() const;
|
float GetDefaultRaceSize() const;
|
||||||
void FixZ(int32 z_find_offset = 5);
|
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);
|
void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false);
|
||||||
inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; }
|
inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; }
|
||||||
@ -1165,7 +1165,7 @@ protected:
|
|||||||
int _GetWalkSpeed() const;
|
int _GetWalkSpeed() const;
|
||||||
int _GetRunSpeed() const;
|
int _GetRunSpeed() const;
|
||||||
int _GetFearSpeed() 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_EngagedCastCheck() { return(false); }
|
||||||
virtual bool AI_PursueCastCheck() { return(false); }
|
virtual bool AI_PursueCastCheck() { return(false); }
|
||||||
@ -1443,7 +1443,7 @@ protected:
|
|||||||
std::unique_ptr<Timer> AI_feign_remember_timer;
|
std::unique_ptr<Timer> AI_feign_remember_timer;
|
||||||
std::unique_ptr<Timer> AI_check_signal_timer;
|
std::unique_ptr<Timer> AI_check_signal_timer;
|
||||||
std::unique_ptr<Timer> AI_scan_door_open_timer;
|
std::unique_ptr<Timer> AI_scan_door_open_timer;
|
||||||
uint32 pLastFightingDelayMoving;
|
uint32 time_until_can_move;
|
||||||
HateList hate_list;
|
HateList hate_list;
|
||||||
std::set<uint32> feign_memory_list;
|
std::set<uint32> feign_memory_list;
|
||||||
// This is to keep track of mobs we cast faction mod spells on
|
// This is to keep track of mobs we cast faction mod spells on
|
||||||
|
|||||||
443
zone/mob_ai.cpp
443
zone/mob_ai.cpp
@ -30,6 +30,7 @@
|
|||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
#include "fastmath.h"
|
#include "fastmath.h"
|
||||||
|
#include "../common/data_verification.h"
|
||||||
|
|
||||||
#include <glm/gtx/projection.hpp>
|
#include <glm/gtx/projection.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -459,8 +460,8 @@ void NPC::AI_Init()
|
|||||||
roambox_min_x = 0;
|
roambox_min_x = 0;
|
||||||
roambox_min_y = 0;
|
roambox_min_y = 0;
|
||||||
roambox_distance = 0;
|
roambox_distance = 0;
|
||||||
roambox_movingto_x = 0;
|
roambox_destination_x = 0;
|
||||||
roambox_movingto_y = 0;
|
roambox_destination_y = 0;
|
||||||
roambox_min_delay = 2500;
|
roambox_min_delay = 2500;
|
||||||
roambox_delay = 2500;
|
roambox_delay = 2500;
|
||||||
}
|
}
|
||||||
@ -476,9 +477,9 @@ void Mob::AI_Start(uint32 iMoveDelay) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (iMoveDelay)
|
if (iMoveDelay)
|
||||||
pLastFightingDelayMoving = Timer::GetCurrentTime() + iMoveDelay;
|
time_until_can_move = Timer::GetCurrentTime() + iMoveDelay;
|
||||||
else
|
else
|
||||||
pLastFightingDelayMoving = 0;
|
time_until_can_move = 0;
|
||||||
|
|
||||||
pAIControlled = true;
|
pAIControlled = true;
|
||||||
AI_think_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
|
AI_think_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
|
||||||
@ -1096,39 +1097,46 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
// Begin: Additions for Wiz Fear Code
|
// Begin: Additions for Wiz Fear Code
|
||||||
//
|
//
|
||||||
if(RuleB(Combat, EnableFearPathing)){
|
if (RuleB(Combat, EnableFearPathing)) {
|
||||||
if(currently_fleeing) {
|
if (currently_fleeing) {
|
||||||
if((IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) && !IsPetStop() && !IsPetRegroup()) {
|
if ((IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) && !IsPetStop() &&
|
||||||
|
!IsPetRegroup()) {
|
||||||
//make sure everybody knows were not moving, for appearance sake
|
//make sure everybody knows were not moving, for appearance sake
|
||||||
if(IsMoving())
|
if (IsMoving()) {
|
||||||
{
|
if (target)
|
||||||
if(target)
|
|
||||||
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
moved=false;
|
moved = false;
|
||||||
}
|
}
|
||||||
//continue on to attack code, ensuring that we execute the engaged code
|
//continue on to attack code, ensuring that we execute the engaged code
|
||||||
engaged = true;
|
engaged = true;
|
||||||
} else {
|
}
|
||||||
if(AI_movement_timer->Check()) {
|
else {
|
||||||
|
if (AI_movement_timer->Check()) {
|
||||||
// Check if we have reached the last fear point
|
// Check if we have reached the last fear point
|
||||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
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
|
// Calculate a new point to run to
|
||||||
CalculateNewFearpoint();
|
CalculateNewFearpoint();
|
||||||
}
|
}
|
||||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
if (!RuleB(Pathing, Fear) || !zone->pathing) {
|
||||||
{
|
CalculateNewPosition(
|
||||||
CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
m_FearWalkTarget.x,
|
||||||
|
m_FearWalkTarget.y,
|
||||||
|
m_FearWalkTarget.z,
|
||||||
|
GetFearSpeed(),
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
glm::vec3 Goal = UpdatePath(
|
||||||
GetFearSpeed(), WaypointChanged, NodeReached);
|
m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||||
|
GetFearSpeed(), WaypointChanged, NodeReached
|
||||||
|
);
|
||||||
|
|
||||||
if(WaypointChanged)
|
if (WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetFearSpeed());
|
CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetFearSpeed());
|
||||||
@ -1154,7 +1162,7 @@ void Mob::AI_Process() {
|
|||||||
this->FixZ();
|
this->FixZ();
|
||||||
|
|
||||||
if (target_distance <= 15 && !this->CheckLosFN(this->GetTarget())) {
|
if (target_distance <= 15 && !this->CheckLosFN(this->GetTarget())) {
|
||||||
Mob* target = this->GetTarget();
|
Mob *target = this->GetTarget();
|
||||||
|
|
||||||
m_Position.x = target->GetX();
|
m_Position.x = target->GetX();
|
||||||
m_Position.y = target->GetY();
|
m_Position.y = target->GetY();
|
||||||
@ -1183,10 +1191,8 @@ void Mob::AI_Process() {
|
|||||||
// from above, so no extra blind checks needed
|
// from above, so no extra blind checks needed
|
||||||
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
|
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
|
||||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||||
else
|
else {
|
||||||
{
|
if (AI_target_check_timer->Check()) {
|
||||||
if (AI_target_check_timer->Check())
|
|
||||||
{
|
|
||||||
if (IsFocused()) {
|
if (IsFocused()) {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
||||||
@ -1248,21 +1254,16 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
bool is_combat_range = CombatRange(target);
|
bool is_combat_range = CombatRange(target);
|
||||||
|
|
||||||
if (is_combat_range)
|
if (is_combat_range) {
|
||||||
{
|
if (AI_movement_timer->Check()) {
|
||||||
if (AI_movement_timer->Check())
|
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) {
|
||||||
{
|
|
||||||
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
|
||||||
{
|
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SendPosition();
|
SendPosition();
|
||||||
}
|
}
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
if (IsMoving())
|
if (IsMoving()) {
|
||||||
{
|
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) {
|
||||||
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
|
||||||
{
|
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SendPosition();
|
SendPosition();
|
||||||
}
|
}
|
||||||
@ -1330,16 +1331,17 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
|
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) {
|
||||||
if (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] ||
|
||||||
int chance = spellbonuses.PC_Pet_Rampage[0] + itembonuses.PC_Pet_Rampage[0] + aabonuses.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)) {
|
if (zone->random.Roll(chance)) {
|
||||||
Rampage(nullptr);
|
Rampage(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed)
|
if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed) {
|
||||||
{
|
|
||||||
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
|
int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0);
|
||||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||||
if (zone->random.Roll(rampage_chance)) {
|
if (zone->random.Roll(rampage_chance)) {
|
||||||
@ -1373,8 +1375,7 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed)
|
if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed) {
|
||||||
{
|
|
||||||
int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0);
|
int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0);
|
||||||
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
rampage_chance = rampage_chance > 0 ? rampage_chance : 20;
|
||||||
if (zone->random.Roll(rampage_chance)) {
|
if (zone->random.Roll(rampage_chance)) {
|
||||||
@ -1434,7 +1435,7 @@ void Mob::AI_Process() {
|
|||||||
Heal();
|
Heal();
|
||||||
BuffFadeAll();
|
BuffFadeAll();
|
||||||
AI_walking_timer->Start(100);
|
AI_walking_timer->Start(100);
|
||||||
pLastFightingDelayMoving = Timer::GetCurrentTime();
|
time_until_can_move = Timer::GetCurrentTime();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (tar != nullptr) {
|
else if (tar != nullptr) {
|
||||||
@ -1445,8 +1446,7 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See if we can summon the mob to us
|
// See if we can summon the mob to us
|
||||||
if (!HateSummon())
|
if (!HateSummon()) {
|
||||||
{
|
|
||||||
//could not summon them, check ranged...
|
//could not summon them, check ranged...
|
||||||
if (GetSpecialAbility(SPECATK_RANGED_ATK))
|
if (GetSpecialAbility(SPECATK_RANGED_ATK))
|
||||||
doranged = true;
|
doranged = true;
|
||||||
@ -1456,18 +1456,18 @@ void Mob::AI_Process() {
|
|||||||
if (AI_PursueCastCheck()) {
|
if (AI_PursueCastCheck()) {
|
||||||
//we did something, so do not process movement.
|
//we did something, so do not process movement.
|
||||||
}
|
}
|
||||||
else if (AI_movement_timer->Check() && target)
|
else if (AI_movement_timer->Check() && target) {
|
||||||
{
|
|
||||||
if (!IsRooted()) {
|
if (!IsRooted()) {
|
||||||
Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName());
|
Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName());
|
||||||
if (!RuleB(Pathing, Aggro) || !zone->pathing)
|
if (!RuleB(Pathing, Aggro) || !zone->pathing)
|
||||||
CalculateNewPosition(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed());
|
CalculateNewPosition(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed());
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(),
|
glm::vec3 Goal = UpdatePath(
|
||||||
GetRunspeed(), WaypointChanged, NodeReached);
|
target->GetX(), target->GetY(), target->GetZ(),
|
||||||
|
GetRunspeed(), WaypointChanged, NodeReached
|
||||||
|
);
|
||||||
|
|
||||||
if (WaypointChanged)
|
if (WaypointChanged)
|
||||||
tar_ndx = 20;
|
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
|
if (IsPetStop()) // pet stop won't be engaged, so we will always get here and we want the above branch to execute
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(zone->CanDoCombat() && AI_feign_remember_timer->Check()) {
|
if (zone->CanDoCombat() && AI_feign_remember_timer->Check()) {
|
||||||
// 6/14/06
|
// 6/14/06
|
||||||
// Improved Feign Death Memory
|
// Improved Feign Death Memory
|
||||||
// check to see if any of our previous feigned targets have gotten up.
|
// check to see if any of our previous feigned targets have gotten up.
|
||||||
std::set<uint32>::iterator RememberedCharID;
|
std::set<uint32>::iterator RememberedCharID;
|
||||||
RememberedCharID = feign_memory_list.begin();
|
RememberedCharID = feign_memory_list.begin();
|
||||||
while (RememberedCharID != feign_memory_list.end()) {
|
while (RememberedCharID != feign_memory_list.end()) {
|
||||||
Client* remember_client = entity_list.GetClientByCharID(*RememberedCharID);
|
Client *remember_client = entity_list.GetClientByCharID(*RememberedCharID);
|
||||||
if (remember_client == nullptr) {
|
if (remember_client == nullptr) {
|
||||||
//they are gone now...
|
//they are gone now...
|
||||||
RememberedCharID = feign_memory_list.erase(RememberedCharID);
|
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);
|
RememberedCharID = feign_memory_list.erase(RememberedCharID);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
//they are still feigned, carry on...
|
//they are still feigned, carry on...
|
||||||
++RememberedCharID;
|
++RememberedCharID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (AI_IdleCastCheck())
|
if (AI_IdleCastCheck()) {
|
||||||
{
|
|
||||||
//we processed a spell action, so do nothing else.
|
//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
|
* NPC to NPC aggro checking, npc needs npc_aggro flag
|
||||||
*/
|
*/
|
||||||
|
Mob *temp_target = entity_list.AICheckNPCtoNPCAggro(this, GetAggroRange(), GetAssistRange());
|
||||||
Mob* temp_target = entity_list.AICheckNPCtoNPCAggro(this, GetAggroRange(), GetAssistRange());
|
if (temp_target) {
|
||||||
if (temp_target){
|
|
||||||
AddToHateList(temp_target);
|
AddToHateList(temp_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_scan_area_timer->Disable();
|
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())
|
else if (AI_movement_timer->Check() && !IsRooted()) {
|
||||||
{
|
if (IsPet()) {
|
||||||
if (IsPet())
|
|
||||||
{
|
|
||||||
// we're a pet, do as we're told
|
// we're a pet, do as we're told
|
||||||
switch (pStandingPetOrder)
|
switch (pStandingPetOrder) {
|
||||||
{
|
case SPO_Follow: {
|
||||||
case SPO_Follow:
|
|
||||||
{
|
|
||||||
|
|
||||||
Mob* owner = GetOwner();
|
Mob *owner = GetOwner();
|
||||||
if(owner == nullptr)
|
if (owner == nullptr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//if(owner->IsClient())
|
|
||||||
// printf("Pet start pos: (%f, %f, %f)\n", GetX(), GetY(), GetZ());
|
|
||||||
|
|
||||||
glm::vec4 ownerPos = owner->GetPosition();
|
glm::vec4 ownerPos = owner->GetPosition();
|
||||||
float dist = DistanceSquared(m_Position, ownerPos);
|
float dist = DistanceSquared(m_Position, ownerPos);
|
||||||
float distz = ownerPos.z - m_Position.z;
|
float distz = ownerPos.z - m_Position.z;
|
||||||
|
|
||||||
if (dist >= 400 || distz > 100)
|
if (dist >= 400 || distz > 100) {
|
||||||
{
|
|
||||||
int speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
if (dist >= 1225) // 35
|
if (dist >= 1225) // 35
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
@ -1565,46 +1560,27 @@ void Mob::AI_Process() {
|
|||||||
SendPositionUpdate();
|
SendPositionUpdate();
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if (moved) {
|
||||||
if(moved)
|
|
||||||
{
|
|
||||||
this->FixZ();
|
this->FixZ();
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
moved = false;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case SPO_Sit:
|
case SPO_Sit: {
|
||||||
{
|
|
||||||
SetAppearance(eaSitting, false);
|
SetAppearance(eaSitting, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPO_Guard:
|
case SPO_Guard: {
|
||||||
{
|
|
||||||
//only NPCs can guard stuff. (forced by where the guard movement code is in the AI)
|
//only NPCs can guard stuff. (forced by where the guard movement code is in the AI)
|
||||||
if(IsNPC()) {
|
if (IsNPC()) {
|
||||||
CastToNPC()->NextGuardPosition();
|
CastToNPC()->NextGuardPosition();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1614,24 +1590,22 @@ void Mob::AI_Process() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Entity has been assigned another entity to follow */
|
/* Entity has been assigned another entity to follow */
|
||||||
else if (GetFollowID())
|
else if (GetFollowID()) {
|
||||||
{
|
Mob *follow = entity_list.GetMob(GetFollowID());
|
||||||
Mob* follow = entity_list.GetMob(GetFollowID());
|
if (!follow) { SetFollowID(0); }
|
||||||
if (!follow) SetFollowID(0);
|
else {
|
||||||
else
|
|
||||||
{
|
|
||||||
float dist2 = DistanceSquared(m_Position, follow->GetPosition());
|
float dist2 = DistanceSquared(m_Position, follow->GetPosition());
|
||||||
int followdist = GetFollowDistance();
|
int followdist = GetFollowDistance();
|
||||||
|
|
||||||
if (dist2 >= followdist) // Default follow distance is 100
|
if (dist2 >= followdist) // Default follow distance is 100
|
||||||
{
|
{
|
||||||
int speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
if (dist2 >= followdist + 150)
|
if (dist2 >= followdist + 150) {
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
|
}
|
||||||
CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
moved = false;
|
moved = false;
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
@ -1640,20 +1614,21 @@ void Mob::AI_Process() {
|
|||||||
else //not a pet, and not following somebody...
|
else //not a pet, and not following somebody...
|
||||||
{
|
{
|
||||||
// dont move till a bit after you last fought
|
// dont move till a bit after you last fought
|
||||||
if (pLastFightingDelayMoving < Timer::GetCurrentTime())
|
if (time_until_can_move < Timer::GetCurrentTime()) {
|
||||||
{
|
if (this->IsClient()) {
|
||||||
if (this->IsClient())
|
|
||||||
{
|
/**
|
||||||
// LD timer expired, drop out of world
|
* LD timer expired, drop out of world
|
||||||
if (this->CastToClient()->IsLD())
|
*/
|
||||||
|
if (this->CastToClient()->IsLD()) {
|
||||||
this->CastToClient()->Disconnect();
|
this->CastToClient()->Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsNPC())
|
if (IsNPC()) {
|
||||||
{
|
if (RuleB(NPC, SmartLastFightingDelayMoving) && !feign_memory_list.empty()) {
|
||||||
if(RuleB(NPC, SmartLastFightingDelayMoving) && !feign_memory_list.empty())
|
|
||||||
{
|
|
||||||
minLastFightingDelayMoving = 0;
|
minLastFightingDelayMoving = 0;
|
||||||
maxLastFightingDelayMoving = 0;
|
maxLastFightingDelayMoving = 0;
|
||||||
}
|
}
|
||||||
@ -1661,92 +1636,83 @@ void Mob::AI_Process() {
|
|||||||
CastToNPC()->AI_DoMovement();
|
CastToNPC()->AI_DoMovement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} // else if (AImovement_timer->Check())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Do Ranged attack here
|
//Do Ranged attack here
|
||||||
if(doranged)
|
if (doranged) {
|
||||||
{
|
|
||||||
RangedAttack(target);
|
RangedAttack(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::AI_DoMovement() {
|
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.
|
|
||||||
|
|
||||||
|
float move_speed = GetMovespeed();
|
||||||
|
|
||||||
|
if (move_speed <= 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roambox logic sets precedence
|
||||||
|
*/
|
||||||
if (roambox_distance > 0) {
|
if (roambox_distance > 0) {
|
||||||
if (
|
|
||||||
roambox_movingto_x > roambox_max_x
|
if (!IsMoving()) {
|
||||||
|| roambox_movingto_x < roambox_min_x
|
auto move_x = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
|
||||||
|| roambox_movingto_y > roambox_max_y
|
auto move_y = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
|
||||||
|| roambox_movingto_y < roambox_min_y
|
|
||||||
)
|
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);
|
||||||
float movedist = roambox_distance*roambox_distance;
|
|
||||||
float movex = zone->random.Real(0, movedist);
|
this->FixZ();
|
||||||
float movey = movedist - movex;
|
|
||||||
movex = sqrtf(movex);
|
Log(Logs::Detail,
|
||||||
movey = sqrtf(movey);
|
Logs::NPCRoamBox,
|
||||||
movex *= zone->random.Int(0, 1) ? 1 : -1;
|
"Calculate | NPC: %s distance %.3f | min_x %.3f | max_x %.3f | final_x %.3f | min_y %.3f | max_y %.3f | final_y %.3f",
|
||||||
movey *= zone->random.Int(0, 1) ? 1 : -1;
|
this->GetCleanName(),
|
||||||
roambox_movingto_x = GetX() + movex;
|
roambox_distance,
|
||||||
roambox_movingto_y = GetY() + movey;
|
roambox_min_x,
|
||||||
//Try to calculate new coord using distance.
|
roambox_max_x,
|
||||||
if (roambox_movingto_x > roambox_max_x || roambox_movingto_x < roambox_min_x)
|
roambox_destination_x,
|
||||||
roambox_movingto_x -= movex * 2;
|
roambox_min_y,
|
||||||
if (roambox_movingto_y > roambox_max_y || roambox_movingto_y < roambox_min_y)
|
roambox_max_y,
|
||||||
roambox_movingto_y -= movey * 2;
|
roambox_destination_y);
|
||||||
//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)",
|
if (!CalculateNewPosition(roambox_destination_x, roambox_destination_y, GetFixedZ(m_Position), move_speed, true)) {
|
||||||
roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y);
|
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
||||||
|
|
||||||
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);
|
SetMoving(false);
|
||||||
SendPosition(); // makes mobs stop clientside
|
this->FixZ();
|
||||||
|
SendPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (roamer)
|
else if (roamer) {
|
||||||
{
|
if (AI_walking_timer->Check()) {
|
||||||
if (AI_walking_timer->Check())
|
movetimercompleted = true;
|
||||||
{
|
|
||||||
movetimercompleted=true;
|
|
||||||
AI_walking_timer->Disable();
|
AI_walking_timer->Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32 gridno = CastToNPC()->GetGrid();
|
int32 gridno = CastToNPC()->GetGrid();
|
||||||
|
|
||||||
if (gridno > 0 || cur_wp==-2) {
|
if (gridno > 0 || cur_wp == -2) {
|
||||||
if (movetimercompleted==true) { // time to pause at wp is over
|
if (movetimercompleted == true) { // time to pause at wp is over
|
||||||
AI_SetupNextWaypoint();
|
AI_SetupNextWaypoint();
|
||||||
} // endif (movetimercompleted==true)
|
} // endif (movetimercompleted==true)
|
||||||
else if (!(AI_walking_timer->Enabled()))
|
else if (!(AI_walking_timer->Enabled())) { // currently moving
|
||||||
{ // currently moving
|
|
||||||
bool doMove = true;
|
bool doMove = true;
|
||||||
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY())
|
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY()) { // are we there yet? then stop
|
||||||
{ // are we there yet? then stop
|
Log(Logs::Detail,
|
||||||
Log(Logs::Detail, Logs::AI, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
|
Logs::AI,
|
||||||
|
"We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d",
|
||||||
|
cur_wp,
|
||||||
|
GetX(),
|
||||||
|
GetY(),
|
||||||
|
GetZ(),
|
||||||
|
GetGrid());
|
||||||
|
|
||||||
SetWaypointPause();
|
SetWaypointPause();
|
||||||
SetAppearance(eaStanding, false);
|
SetAppearance(eaStanding, false);
|
||||||
@ -1773,36 +1739,45 @@ void NPC::AI_DoMovement() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wipe feign memory since we reached our first waypoint
|
// wipe feign memory since we reached our first waypoint
|
||||||
if(cur_wp == 1)
|
if (cur_wp == 1)
|
||||||
ClearFeignMemory();
|
ClearFeignMemory();
|
||||||
}
|
}
|
||||||
if (doMove)
|
if (doMove) { // not at waypoint yet or at 0 pause WP, so keep moving
|
||||||
{ // not at waypoint yet or at 0 pause WP, so keep moving
|
if (!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0))
|
||||||
if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0))
|
CalculateNewPosition(
|
||||||
CalculateNewPosition(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true);
|
m_CurrentWayPoint.x,
|
||||||
else
|
m_CurrentWayPoint.y,
|
||||||
{
|
m_CurrentWayPoint.z,
|
||||||
|
move_speed,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
else {
|
||||||
bool WaypointChanged;
|
bool WaypointChanged;
|
||||||
bool NodeReached;
|
bool NodeReached;
|
||||||
glm::vec3 Goal = UpdatePath(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, WaypointChanged, NodeReached);
|
glm::vec3 Goal = UpdatePath(
|
||||||
if(WaypointChanged)
|
m_CurrentWayPoint.x,
|
||||||
|
m_CurrentWayPoint.y,
|
||||||
|
m_CurrentWayPoint.z,
|
||||||
|
move_speed,
|
||||||
|
WaypointChanged,
|
||||||
|
NodeReached
|
||||||
|
);
|
||||||
|
if (WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
if(NodeReached)
|
if (NodeReached)
|
||||||
entity_list.OpenDoorsNear(CastToNPC());
|
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)
|
} // endif (gridno > 0)
|
||||||
// handle new quest grid command processing
|
// handle new quest grid command processing
|
||||||
else if (gridno < 0)
|
else if (gridno < 0) { // this mob is under quest control
|
||||||
{ // this mob is under quest control
|
if (movetimercompleted == true) { // time to pause has ended
|
||||||
if (movetimercompleted==true)
|
SetGrid(0 - GetGrid()); // revert to AI control
|
||||||
{ // 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());
|
Log(Logs::Detail, Logs::Pathing, "Quest pathing is finished. Resuming on grid %d", GetGrid());
|
||||||
|
|
||||||
SetAppearance(eaStanding, false);
|
SetAppearance(eaStanding, false);
|
||||||
@ -1812,39 +1787,55 @@ void NPC::AI_DoMovement() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (IsGuarding())
|
else if (IsGuarding()) {
|
||||||
{
|
|
||||||
bool CP2Moved;
|
bool CP2Moved;
|
||||||
if(!RuleB(Pathing, Guard) || !zone->pathing)
|
if (!RuleB(Pathing, Guard) || !zone->pathing) {
|
||||||
CP2Moved = CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp);
|
CP2Moved = CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, move_speed);
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
if(!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)))
|
if (!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) &&
|
||||||
{
|
(m_Position.z == m_GuardPoint.z))) {
|
||||||
|
|
||||||
bool WaypointChanged, NodeReached;
|
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;
|
tar_ndx = 20;
|
||||||
|
}
|
||||||
|
|
||||||
if(NodeReached)
|
if (NodeReached) {
|
||||||
entity_list.OpenDoorsNear(CastToNPC());
|
entity_list.OpenDoorsNear(CastToNPC());
|
||||||
|
|
||||||
CP2Moved = CalculateNewPosition(Goal.x, Goal.y, Goal.z, walksp);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
CP2Moved = CalculateNewPosition(Goal.x, Goal.y, Goal.z, move_speed);
|
||||||
|
}
|
||||||
|
else {
|
||||||
CP2Moved = false;
|
CP2Moved = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!CP2Moved)
|
if (!CP2Moved) {
|
||||||
{
|
if (moved) {
|
||||||
if(moved) {
|
Log(Logs::Detail,
|
||||||
Log(Logs::Detail, Logs::AI, "Reached guard point (%.3f,%.3f,%.3f)", m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z);
|
Logs::AI,
|
||||||
|
"Reached guard point (%.3f,%.3f,%.3f)",
|
||||||
|
m_GuardPoint.x,
|
||||||
|
m_GuardPoint.y,
|
||||||
|
m_GuardPoint.z);
|
||||||
|
|
||||||
ClearFeignMemory();
|
ClearFeignMemory();
|
||||||
moved=false;
|
moved = false;
|
||||||
if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5*5 )
|
if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5 * 5) {
|
||||||
{
|
|
||||||
SetHeading(m_GuardPoint.w);
|
SetHeading(m_GuardPoint.w);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
FaceTarget(GetTarget());
|
FaceTarget(GetTarget());
|
||||||
}
|
}
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
@ -1968,11 +1959,11 @@ void Mob::AI_Event_NoLongerEngaged() {
|
|||||||
if (!IsAIControlled())
|
if (!IsAIControlled())
|
||||||
return;
|
return;
|
||||||
this->AI_walking_timer->Start(RandomTimer(3000,20000));
|
this->AI_walking_timer->Start(RandomTimer(3000,20000));
|
||||||
pLastFightingDelayMoving = Timer::GetCurrentTime();
|
time_until_can_move = Timer::GetCurrentTime();
|
||||||
if (minLastFightingDelayMoving == maxLastFightingDelayMoving)
|
if (minLastFightingDelayMoving == maxLastFightingDelayMoving)
|
||||||
pLastFightingDelayMoving += minLastFightingDelayMoving;
|
time_until_can_move += minLastFightingDelayMoving;
|
||||||
else
|
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
|
// So mobs don't keep running as a ghost until AIwalking_timer fires
|
||||||
// if they were moving prior to losing all hate
|
// 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
|
// except if we're a pet, then we might run into some issues with pets backing off when they should immediately be moving
|
||||||
|
|||||||
@ -242,8 +242,8 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
|||||||
roambox_max_y = -2;
|
roambox_max_y = -2;
|
||||||
roambox_min_x = -2;
|
roambox_min_x = -2;
|
||||||
roambox_min_y = -2;
|
roambox_min_y = -2;
|
||||||
roambox_movingto_x = -2;
|
roambox_destination_x = -2;
|
||||||
roambox_movingto_y = -2;
|
roambox_destination_y = -2;
|
||||||
roambox_min_delay = 1000;
|
roambox_min_delay = 1000;
|
||||||
roambox_delay = 1000;
|
roambox_delay = 1000;
|
||||||
p_depop = false;
|
p_depop = false;
|
||||||
|
|||||||
16
zone/npc.h
16
zone/npc.h
@ -311,9 +311,17 @@ public:
|
|||||||
void SaveGuardSpot(bool iClearGuardSpot = false);
|
void SaveGuardSpot(bool iClearGuardSpot = false);
|
||||||
inline bool IsGuarding() const { return(m_GuardPoint.w != 0); }
|
inline bool IsGuarding() const { return(m_GuardPoint.w != 0); }
|
||||||
void SaveGuardSpotCharm();
|
void SaveGuardSpotCharm();
|
||||||
|
|
||||||
void RestoreGuardSpotCharm();
|
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 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
|
//mercenary stuff
|
||||||
void LoadMercTypes();
|
void LoadMercTypes();
|
||||||
@ -530,8 +538,8 @@ protected:
|
|||||||
float roambox_min_x;
|
float roambox_min_x;
|
||||||
float roambox_min_y;
|
float roambox_min_y;
|
||||||
float roambox_distance;
|
float roambox_distance;
|
||||||
float roambox_movingto_x;
|
float roambox_destination_x;
|
||||||
float roambox_movingto_y;
|
float roambox_destination_y;
|
||||||
uint32 roambox_delay;
|
uint32 roambox_delay;
|
||||||
uint32 roambox_min_delay;
|
uint32 roambox_min_delay;
|
||||||
|
|
||||||
|
|||||||
158
zone/spawn2.cpp
158
zone/spawn2.cpp
@ -141,14 +141,15 @@ uint32 Spawn2::despawnTimer(uint32 despawn_timer)
|
|||||||
bool Spawn2::Process() {
|
bool Spawn2::Process() {
|
||||||
IsDespawned = false;
|
IsDespawned = false;
|
||||||
|
|
||||||
if(!Enabled())
|
if (!Enabled())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
//grab our spawn group
|
//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;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (timer.Check()) {
|
if (timer.Check()) {
|
||||||
timer.Disable();
|
timer.Disable();
|
||||||
@ -157,102 +158,164 @@ bool Spawn2::Process() {
|
|||||||
|
|
||||||
//first check our spawn condition, if this isnt active
|
//first check our spawn condition, if this isnt active
|
||||||
//then we reset the timer and try again next time.
|
//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)) {
|
&& !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();
|
Reset();
|
||||||
return(true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sg == nullptr) {
|
if (spawn_group == nullptr) {
|
||||||
database.LoadSpawnGroupsByID(spawngroup_id_,&zone->spawn_group_list);
|
database.LoadSpawnGroupsByID(spawngroup_id_, &zone->spawn_group_list);
|
||||||
sg = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_);
|
spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sg == nullptr) {
|
if (spawn_group == nullptr) {
|
||||||
Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Unable to locate spawn group %d. Disabling.", spawn2_id, spawngroup_id_);
|
Log(Logs::Detail,
|
||||||
|
Logs::Spawns,
|
||||||
|
"Spawn2 %d: Unable to locate spawn group %d. Disabling.",
|
||||||
|
spawn2_id,
|
||||||
|
spawngroup_id_);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//have the spawn group pick an NPC for us
|
//have the spawn group pick an NPC for us
|
||||||
uint32 npcid = sg->GetNPCType();
|
uint32 npcid = spawn_group->GetNPCType();
|
||||||
if (npcid == 0) {
|
if (npcid == 0) {
|
||||||
Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", spawn2_id, spawngroup_id_);
|
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?)
|
Reset(); //try again later (why?)
|
||||||
return(true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to find our NPC type.
|
//try to find our NPC type.
|
||||||
const NPCType* tmp = database.LoadNPCTypesData(npcid);
|
const NPCType *tmp = database.LoadNPCTypesData(npcid);
|
||||||
if (tmp == nullptr) {
|
if (tmp == nullptr) {
|
||||||
Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", spawn2_id, spawngroup_id_, npcid);
|
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
|
Reset(); //try again later
|
||||||
return(true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tmp->unique_spawn_by_name)
|
if (tmp->unique_spawn_by_name) {
|
||||||
{
|
if (!entity_list.LimitCheckName(tmp->name)) {
|
||||||
if(!entity_list.LimitCheckName(tmp->name))
|
Log(Logs::Detail,
|
||||||
{
|
Logs::Spawns,
|
||||||
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);
|
"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.
|
timer.Start(5000); //try again in five seconds.
|
||||||
return(true);
|
return (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tmp->spawn_limit > 0) {
|
if (tmp->spawn_limit > 0) {
|
||||||
if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) {
|
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);
|
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.
|
timer.Start(5000); //try again in five seconds.
|
||||||
return(true);
|
return (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ignore_despawn = false;
|
bool ignore_despawn = false;
|
||||||
if (npcthis)
|
if (npcthis) {
|
||||||
{
|
|
||||||
ignore_despawn = npcthis->IgnoreDespawn();
|
ignore_despawn = npcthis->IgnoreDespawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore_despawn)
|
if (ignore_despawn) {
|
||||||
{
|
|
||||||
return true;
|
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);
|
zone->Despawn(spawn2_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDespawned)
|
if (IsDespawned) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentnpcid = npcid;
|
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);
|
npc->mod_prespawn(this);
|
||||||
|
|
||||||
npcthis = npc;
|
npcthis = npc;
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
if (npc->DropsGlobalLoot())
|
if (npc->DropsGlobalLoot()) {
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
|
}
|
||||||
npc->SetSp2(spawngroup_id_);
|
npc->SetSp2(spawngroup_id_);
|
||||||
npc->SaveGuardPointAnim(anim);
|
npc->SaveGuardPointAnim(anim);
|
||||||
npc->SetAppearance((EmuAppearance)anim);
|
npc->SetAppearance((EmuAppearance) anim);
|
||||||
entity_list.AddNPC(npc);
|
entity_list.AddNPC(npc);
|
||||||
//this limit add must be done after the AddNPC since we need the entity ID.
|
//this limit add must be done after the AddNPC since we need the entity ID.
|
||||||
entity_list.LimitAddNPC(npc);
|
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()) {
|
* Roambox init
|
||||||
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);
|
*/
|
||||||
|
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();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,11 +329,11 @@ void Spawn2::Disable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Spawn2::LoadGrid() {
|
void Spawn2::LoadGrid() {
|
||||||
if(!npcthis)
|
if (!npcthis)
|
||||||
return;
|
return;
|
||||||
if(grid_ < 1)
|
if (grid_ < 1)
|
||||||
return;
|
return;
|
||||||
if(!entity_list.IsMobInZone(npcthis))
|
if (!entity_list.IsMobInZone(npcthis))
|
||||||
return;
|
return;
|
||||||
//dont set an NPC's grid until its loaded for them.
|
//dont set an NPC's grid until its loaded for them.
|
||||||
npcthis->SetGrid(grid_);
|
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());
|
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
|
All three of these actions basically say that the mob which was
|
||||||
associated with this spawn point is no longer relavent.
|
associated with this spawn point is no longer relavent.
|
||||||
|
|||||||
@ -42,19 +42,27 @@ struct wp_distance
|
|||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
void NPC::AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay, uint32 iMinDelay) {
|
void NPC::AI_SetRoambox(float max_distance, float roam_distance_variance, uint32 delay, uint32 min_delay) {
|
||||||
AI_SetRoambox(iDist, GetX() + iRoamDist, GetX() - iRoamDist, GetY() + iRoamDist, GetY() - iRoamDist, iDelay, iMinDelay);
|
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) {
|
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 = iDist;
|
roambox_distance = distance;
|
||||||
roambox_max_x = iMaxX;
|
roambox_max_x = max_x;
|
||||||
roambox_min_x = iMinX;
|
roambox_min_x = min_x;
|
||||||
roambox_max_y = iMaxY;
|
roambox_max_y = max_y;
|
||||||
roambox_min_y = iMinY;
|
roambox_min_y = min_y;
|
||||||
roambox_movingto_x = roambox_max_x + 1; // this will trigger a recalc
|
roambox_destination_x = roambox_max_x + 1; // this will trigger a recalc
|
||||||
roambox_delay = iDelay;
|
roambox_delay = delay;
|
||||||
roambox_min_delay = iMinDelay;
|
roambox_min_delay = min_delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::DisplayWaypointInfo(Client *c) {
|
void NPC::DisplayWaypointInfo(Client *c) {
|
||||||
@ -199,7 +207,7 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_wp_pause = 0;
|
cur_wp_pause = 0;
|
||||||
pLastFightingDelayMoving = 0;
|
time_until_can_move = 0;
|
||||||
if (AI_walking_timer->Enabled())
|
if (AI_walking_timer->Enabled())
|
||||||
AI_walking_timer->Start(100);
|
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)));
|
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)
|
if (GetID() == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (speed <= 0)
|
if (speed <= 0) {
|
||||||
{
|
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
return true;
|
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
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) {
|
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.x = x;
|
||||||
m_Position.y = y;
|
m_Position.y = y;
|
||||||
m_Position.z = z;
|
m_Position.z = z;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool send_update = false;
|
|
||||||
int compare_steps = 20;
|
int compare_steps = 20;
|
||||||
if (tar_ndx < compare_steps && m_TargetLocation.x == x && m_TargetLocation.y == y) {
|
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_x = m_Position.x + m_TargetV.x * tar_vector;
|
||||||
float new_y = m_Position.y + m_TargetV.y*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_z = m_Position.z + m_TargetV.z * tar_vector;
|
||||||
|
|
||||||
if (IsNPC()) {
|
if (IsNPC()) {
|
||||||
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
|
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.y = new_y;
|
||||||
m_Position.z = new_z;
|
m_Position.z = new_z;
|
||||||
|
|
||||||
if(checkZ && fix_z_timer.Check() &&
|
if (check_z && fix_z_timer.Check() && (!this->IsEngaged() || flee_mode || currently_fleeing)) {
|
||||||
(!this->IsEngaged() || flee_mode || currently_fleeing))
|
|
||||||
this->FixZ();
|
this->FixZ();
|
||||||
|
}
|
||||||
|
|
||||||
tar_ndx++;
|
tar_ndx++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tar_ndx > 50) {
|
||||||
if (tar_ndx>50) {
|
|
||||||
tar_ndx--;
|
tar_ndx--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tar_ndx = 0;
|
tar_ndx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_TargetLocation = glm::vec3(x, y, z);
|
m_TargetLocation = glm::vec3(x, y, z);
|
||||||
|
|
||||||
float nx = this->m_Position.x;
|
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
|
// mob move fix
|
||||||
|
|
||||||
if (numsteps<20)
|
if (numsteps < 20) {
|
||||||
{
|
if (numsteps > 1) {
|
||||||
if (numsteps>1)
|
|
||||||
{
|
|
||||||
tar_vector = 1.0f;
|
tar_vector = 1.0f;
|
||||||
m_TargetV.x = m_TargetV.x / (float)numsteps;
|
m_TargetV.x = m_TargetV.x / (float) numsteps;
|
||||||
m_TargetV.y = m_TargetV.y / (float)numsteps;
|
m_TargetV.y = m_TargetV.y / (float) numsteps;
|
||||||
m_TargetV.z = m_TargetV.z / (float)numsteps;
|
m_TargetV.z = m_TargetV.z / (float) numsteps;
|
||||||
|
|
||||||
float new_x = m_Position.x + m_TargetV.x;
|
float new_x = m_Position.x + m_TargetV.x;
|
||||||
float new_y = m_Position.y + m_TargetV.y;
|
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.x = new_x;
|
||||||
m_Position.y = new_y;
|
m_Position.y = new_y;
|
||||||
m_Position.z = new_z;
|
m_Position.z = new_z;
|
||||||
if (calcHeading)
|
if (calculate_heading) {
|
||||||
m_Position.w = CalculateHeadingToTarget(x, y);
|
m_Position.w = CalculateHeadingToTarget(x, y);
|
||||||
|
}
|
||||||
tar_ndx = 20 - numsteps;
|
tar_ndx = 20 - numsteps;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (IsNPC()) {
|
if (IsNPC()) {
|
||||||
entity_list.ProcessMove(CastToNPC(), x, y, z);
|
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);
|
tar_vector *= (dur / 100.0f);
|
||||||
|
|
||||||
float new_x = m_Position.x + m_TargetV.x*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_y = m_Position.y + m_TargetV.y * tar_vector;
|
||||||
float new_z = m_Position.z + m_TargetV.z*tar_vector;
|
float new_z = m_Position.z + m_TargetV.z * tar_vector;
|
||||||
|
|
||||||
if (IsNPC()) {
|
if (IsNPC()) {
|
||||||
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
|
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.x = new_x;
|
||||||
m_Position.y = new_y;
|
m_Position.y = new_y;
|
||||||
m_Position.z = new_z;
|
m_Position.z = new_z;
|
||||||
if (calcHeading)
|
if (calculate_heading) {
|
||||||
m_Position.w = CalculateHeadingToTarget(x, y);
|
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();
|
this->FixZ();
|
||||||
|
|
||||||
SetMoving(true);
|
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);
|
m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f);
|
||||||
|
|
||||||
if (IsClient())
|
if (IsClient()) {
|
||||||
{
|
|
||||||
SendPositionUpdate(1);
|
SendPositionUpdate(1);
|
||||||
CastToClient()->ResetPositionTimer();
|
CastToClient()->ResetPositionTimer();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
SendPositionUpdate();
|
SendPositionUpdate();
|
||||||
SetAppearance(eaStanding, false);
|
SetAppearance(eaStanding, false);
|
||||||
}
|
}
|
||||||
@ -615,8 +617,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ, bool calcHeading) {
|
bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool check_z, bool calculate_heading) {
|
||||||
return MakeNewPositionAndSendUpdate(x, y, z, speed);
|
return MakeNewPositionAndSendUpdate(x, y, z, speed, check_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::AssignWaypoints(int32 grid)
|
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;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
float new_z = dest.z;
|
|
||||||
|
float new_z = destination.z;
|
||||||
|
|
||||||
if (zone->HasMap() && RuleB(Map, FixZWhenMoving)) {
|
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
|
* 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) {
|
if (new_z != BEST_Z_INVALID) {
|
||||||
new_z += this->GetZOffset();
|
new_z += this->GetZOffset();
|
||||||
|
|
||||||
@ -776,9 +779,15 @@ float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) {
|
|||||||
|
|
||||||
auto duration = timer.elapsed();
|
auto duration = timer.elapsed();
|
||||||
|
|
||||||
Log(Logs::Moderate, Logs::FixZ,
|
Log(Logs::Moderate,
|
||||||
|
Logs::FixZ,
|
||||||
"Mob::GetFixedZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf",
|
"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);
|
this->GetCleanName(),
|
||||||
|
new_z,
|
||||||
|
destination.x,
|
||||||
|
destination.y,
|
||||||
|
destination.z,
|
||||||
|
duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_z;
|
return new_z;
|
||||||
@ -790,13 +799,16 @@ void Mob::FixZ(int32 z_find_offset /*= 5*/) {
|
|||||||
|
|
||||||
if (!IsClient() && new_z != m_Position.z) {
|
if (!IsClient() && new_z != m_Position.z) {
|
||||||
if ((new_z > -2000) && new_z != BEST_Z_INVALID) {
|
if ((new_z > -2000) && new_z != BEST_Z_INVALID) {
|
||||||
if (RuleB(Map, MobZVisualDebug))
|
if (RuleB(Map, MobZVisualDebug)) {
|
||||||
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
m_Position.z = new_z;
|
m_Position.z = new_z;
|
||||||
} else {
|
}
|
||||||
if (RuleB(Map, MobZVisualDebug))
|
else {
|
||||||
|
if (RuleB(Map, MobZVisualDebug)) {
|
||||||
this->SendAppearanceEffect(103, 0, 0, 0, 0);
|
this->SendAppearanceEffect(103, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f",
|
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));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user