MoveTo while saving guard position no longer hops.

This commit is contained in:
Paul Coene 2017-11-17 13:12:26 -05:00
parent ceadb1325d
commit 5880593cb1
4 changed files with 79 additions and 46 deletions

View File

@ -123,8 +123,6 @@ Mob::Mob(const char* in_name,
tar_vector=0; tar_vector=0;
currently_fleeing = false; currently_fleeing = false;
last_z = 0;
last_major_update_position = m_Position; last_major_update_position = m_Position;
AI_Init(); AI_Init();
@ -3439,6 +3437,19 @@ void Mob::SetTarget(Mob* mob) {
this->GetTarget()->SendHPUpdate(false, true); this->GetTarget()->SendHPUpdate(false, true);
} }
// For when we want a Ground Z at a location we are not at yet
// Like MoveTo.
float Mob::FindDestGroundZ(glm::vec3 dest, float z_offset)
{
float best_z = BEST_Z_INVALID;
if (zone->zonemap != nullptr)
{
dest.z += z_offset;
best_z = zone->zonemap->FindBestZ(dest, nullptr);
}
return best_z;
}
float Mob::FindGroundZ(float new_x, float new_y, float z_offset) float Mob::FindGroundZ(float new_x, float new_y, float z_offset)
{ {
float ret = BEST_Z_INVALID; float ret = BEST_Z_INVALID;

View File

@ -955,6 +955,7 @@ public:
void SendToFixZ(float new_x, float new_y, float new_z); void SendToFixZ(float new_x, float new_y, float new_z);
float GetZOffset() const; float GetZOffset() 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);
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; }
inline uint32 DontBuffMeBefore() const { return pDontBuffMeBefore; } inline uint32 DontBuffMeBefore() const { return pDontBuffMeBefore; }
@ -1108,8 +1109,6 @@ public:
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item); int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr); int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr);
float last_z;
// Bots HealRotation methods // Bots HealRotation methods
#ifdef BOTS #ifdef BOTS
bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); } bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); }
@ -1267,6 +1266,7 @@ protected:
virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; } virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
void CalculateNewFearpoint(); void CalculateNewFearpoint();
float FindGroundZ(float new_x, float new_y, float z_offset=0.0); float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
float FindDestGroundZ(glm::vec3 dest, float z_offset=0.0);
glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached); glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
void PrintRoute(); void PrintRoute();

View File

@ -503,7 +503,7 @@ void NPC::AI_Start(uint32 iMoveDelay) {
AIautocastspell_timer->Disable(); AIautocastspell_timer->Disable();
} else { } else {
AIautocastspell_timer = std::unique_ptr<Timer>(new Timer(750)); AIautocastspell_timer = std::unique_ptr<Timer>(new Timer(750));
AIautocastspell_timer->Start(RandomTimer(0, 15000), false); AIautocastspell_timer->Start(RandomTimer(0, 300), false);
} }
if (NPCTypedata) { if (NPCTypedata) {
@ -1582,18 +1582,22 @@ void NPC::AI_DoMovement() {
} }
this->FixZ(); this->FixZ();
SendPosition(); SendPosition();
//kick off event_waypoint arrive //kick off event_waypoint arrive
char temp[16]; char temp[16];
sprintf(temp, "%d", cur_wp); sprintf(temp, "%d", cur_wp);
parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0); parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0);
// start moving directly to next waypoint if we're at a 0 pause waypoint and we didn't get quest halted. // No need to move as we are there. Next loop will
if (!AI_walking_timer->Enabled()) // take care of normal grids, even at pause 0.
AI_SetupNextWaypoint(); // We do need to call and setup a wp if we're cur_wp=-2
else // as that is where roamer is unset and we don't want
// the next trip through to move again based on grid stuff.
doMove = false; doMove = false;
if (cur_wp == -2) {
AI_SetupNextWaypoint();
}
// 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();
@ -2593,7 +2597,7 @@ void NPC::AddSpellToNPCList(int16 iPriority, int16 iSpellID, uint32 iType,
// If we're going from an empty list, we need to start the timer // If we're going from an empty list, we need to start the timer
if (AIspells.size() == 1) if (AIspells.size() == 1)
AIautocastspell_timer->Start(RandomTimer(0, 15000), false); AIautocastspell_timer->Start(RandomTimer(0, 300), false);
} }
void NPC::RemoveSpellFromNPCList(int16 spell_id) void NPC::RemoveSpellFromNPCList(int16 spell_id)

View File

@ -176,9 +176,15 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
cur_wp = -2; // flag as quest controlled w/no grid cur_wp = -2; // flag as quest controlled w/no grid
Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast<glm::vec3>(position)).c_str()); Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast<glm::vec3>(position)).c_str());
} }
glm::vec3 dest(position);
m_CurrentWayPoint = position;
m_CurrentWayPoint.z = GetFixedZ(dest);
if (saveguardspot) if (saveguardspot)
{ {
m_GuardPoint = position; m_GuardPoint = m_CurrentWayPoint;
if (m_GuardPoint.w == 0) if (m_GuardPoint.w == 0)
m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler
@ -189,7 +195,6 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
Log(Logs::Detail, Logs::AI, "Setting guard position to %s", to_string(static_cast<glm::vec3>(m_GuardPoint)).c_str()); Log(Logs::Detail, Logs::AI, "Setting guard position to %s", to_string(static_cast<glm::vec3>(m_GuardPoint)).c_str());
} }
m_CurrentWayPoint = position;
cur_wp_pause = 0; cur_wp_pause = 0;
pLastFightingDelayMoving = 0; pLastFightingDelayMoving = 0;
if (AI_walking_timer->Enabled()) if (AI_walking_timer->Enabled())
@ -838,35 +843,50 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
} }
} }
void Mob::FixZ(int32 z_find_offset /*= 5*/) float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset)
{ {
BenchTimer timer; BenchTimer timer;
timer.reset(); timer.reset();
float new_z = dest.z;
if (zone->HasMap() && RuleB(Map, FixZWhenMoving) && (flymode != 1 && flymode != 2)) if (zone->HasMap() && RuleB(Map, FixZWhenMoving) &&
(flymode != 1 && flymode != 2))
{ {
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap()
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position)))) || (zone->HasWaterMap() &&
!zone->watermap->InWater(glm::vec3(m_Position))))
{ {
/* 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 */
float new_z = this->FindGroundZ(m_Position.x, m_Position.y, z_find_offset); new_z = this->FindDestGroundZ(dest,z_find_offset);
if (new_z != BEST_Z_INVALID)
{
new_z += this->GetZOffset(); new_z += this->GetZOffset();
// If bad new Z restore old one
if (new_z < -2000) {
new_z = m_Position.z;
}
}
}
auto duration = timer.elapsed(); auto duration = timer.elapsed();
Log( Log(Logs::Moderate, Logs::FixZ,
Logs::Moderate,
Logs::FixZ,
"Mob::FixZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", "Mob::FixZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf",
this->GetCleanName(), this->GetCleanName(), new_z, m_Position.x, m_Position.y,
new_z, m_Position.z, duration);
m_Position.x, }
m_Position.y,
m_Position.z,
duration
);
return new_z;
}
void Mob::FixZ(int32 z_find_offset /*= 5*/)
{
glm::vec3 current_loc(m_Position);
float new_z=GetFixedZ(current_loc, z_find_offset);
if (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);
@ -877,10 +897,8 @@ void Mob::FixZ(int32 z_find_offset /*= 5*/)
if (RuleB(Map, MobZVisualDebug)) 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", this->GetCleanName(), std::abs(m_Position.z - new_z)); Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f",
} this->GetCleanName(), std::abs(m_Position.z - new_z));
last_z = m_Position.z;
} }
} }
} }