[Pathing] Improve roambox logic (#2983)

* [Pathing] Improve roambox logic

* Cleanup roambox logic
This commit is contained in:
Chris Miles
2023-02-24 14:07:34 -06:00
committed by GitHub
parent 5cfdeb928e
commit 889e57a5af
5 changed files with 216 additions and 174 deletions
+13 -127
View File
@@ -404,16 +404,16 @@ void NPC::AI_Init()
AIautocastspell_timer.reset(nullptr);
casting_spell_AIindex = static_cast<uint8>(AIspells.size());
roambox_max_x = 0;
roambox_max_y = 0;
roambox_min_x = 0;
roambox_min_y = 0;
roambox_distance = 0;
roambox_destination_x = 0;
roambox_destination_y = 0;
roambox_destination_z = 0;
roambox_min_delay = 2500;
roambox_delay = 2500;
m_roambox.max_x = 0;
m_roambox.max_y = 0;
m_roambox.min_x = 0;
m_roambox.min_y = 0;
m_roambox.distance = 0;
m_roambox.dest_x = 0;
m_roambox.dest_y = 0;
m_roambox.dest_z = 0;
m_roambox.delay = 2500;
m_roambox.min_delay = 2500;
}
void Client::AI_Init()
@@ -1592,123 +1592,9 @@ void NPC::AI_DoMovement() {
return;
}
/**
* Roambox logic sets precedence
*/
if (roambox_distance > 0) {
// Check if we're already moving to a WP
// If so, if we're not moving we have arrived and need to set delay
if (GetCWP() == EQ::WaypointStatus::RoamBoxPauseInProgress && !IsMoving()) {
// We have arrived
int roambox_move_delay = EQ::ClampLower(GetRoamboxDelay(), GetRoamboxMinDelay());
int move_delay_max = (roambox_move_delay > 0 ? roambox_move_delay : (int) GetRoamboxMinDelay() * 4);
int random_timer = RandomTimer(
GetRoamboxMinDelay(),
move_delay_max
);
LogNPCRoamBoxDetail(
"({}) Timer calc | random_timer [{}] roambox_move_delay [{}] move_min [{}] move_max [{}]",
GetCleanName(),
random_timer,
roambox_move_delay,
(int) GetRoamboxMinDelay(),
move_delay_max
);
time_until_can_move = Timer::GetCurrentTime() + random_timer;
SetCurrentWP(0);
return;
}
// Set a new destination
if (!IsMoving() && time_until_can_move < Timer::GetCurrentTime()) {
auto move_x = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
auto move_y = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
roambox_destination_x = EQ::Clamp((GetX() + move_x), roambox_min_x, roambox_max_x);
roambox_destination_y = EQ::Clamp((GetY() + move_y), roambox_min_y, roambox_max_y);
/**
* If our roambox was configured with large distances, chances of hitting the min or max end of
* the clamp is high, this causes NPC's to gather on the border of a box, to reduce clustering
* either lower the roambox distance or the code will do a simple random between min - max when it
* hits the min or max of the clamp
*/
if (roambox_destination_x == roambox_min_x || roambox_destination_x == roambox_max_x) {
roambox_destination_x = static_cast<float>(zone->random.Real(roambox_min_x, roambox_max_x));
}
if (roambox_destination_y == roambox_min_y || roambox_destination_y == roambox_max_y) {
roambox_destination_y = static_cast<float>(zone->random.Real(roambox_min_y, roambox_max_y));
}
/**
* If mob was not spawned in water, let's not randomly roam them into water
* if the roam box was sloppily configured
*/
if (!GetWasSpawnedInWater()) {
roambox_destination_z = GetGroundZ(roambox_destination_x, roambox_destination_y);
if (zone->HasMap() && zone->HasWaterMap()) {
auto position = glm::vec3(
roambox_destination_x,
roambox_destination_y,
roambox_destination_z
);
/**
* If someone brought us into water when we naturally wouldn't path there, return to spawn
*/
if (zone->watermap->InLiquid(position) && zone->watermap->InLiquid(m_Position)) {
roambox_destination_x = m_SpawnPoint.x;
roambox_destination_y = m_SpawnPoint.y;
}
if (zone->watermap->InLiquid(position)) {
LogNPCRoamBoxDetail("[{}] | My destination is in water and I don't belong there!", GetCleanName());
return;
}
}
}
else { // Mob was in water, make sure new spot is in water also
roambox_destination_z = m_Position.z;
auto position = glm::vec3(
roambox_destination_x,
roambox_destination_y,
m_Position.z + 15
);
if (zone->HasWaterMap() && !zone->watermap->InLiquid(position)) {
roambox_destination_x = m_SpawnPoint.x;
roambox_destination_y = m_SpawnPoint.y;
roambox_destination_z = m_SpawnPoint.z;
}
}
LogNPCRoamBox("[{}] | Pathing to [{}] [{}] [{}]", GetCleanName(),
roambox_destination_x, roambox_destination_y,
roambox_destination_z);
LogNPCRoamBox(
"NPC ({}) distance [{}] X (min/max) [{} / {}] Y (min/max) [{} / {}] | Dest x/y/z [{} / {} / {}]",
GetCleanName(),
roambox_distance,
roambox_min_x,
roambox_max_x,
roambox_min_y,
roambox_max_y,
roambox_destination_x,
roambox_destination_y,
roambox_destination_z
);
SetCurrentWP(EQ::WaypointStatus::RoamBoxPauseInProgress);
NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z);
}
// Roambox logic sets precedence
if (m_roambox.distance > 0) {
HandleRoambox();
return;
}
else if (roamer) {