Fix some NPC and Corpse falling through the ground issues

This commit is contained in:
Akkadius 2017-07-01 03:07:45 -05:00
parent 21ef83bcbe
commit 1f39a0cb3e
6 changed files with 43 additions and 6 deletions

View File

@ -275,6 +275,7 @@ RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, ac
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
RULE_BOOL(Map, FixPathingZOnSendTo, false) //try to repair Z coords in the SendTo routine as well.
RULE_BOOL(Map, FixZWhenMoving, true) // Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)
RULE_BOOL(Map, MobZVisualDebug, false) // Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)
RULE_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
RULE_REAL(Map, FixPathingZMaxDeltaWaypoint, 20) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply.
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.

View File

@ -2392,7 +2392,13 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
float new_z = zone->zonemap->FindBestZ(dest, nullptr);
corpse->SetFlyMode(1);
corpse->GMMove(m_Position.x, m_Position.y, new_z + 5, m_Position.w);
float size = GetSize();
if (size > 10)
size = 10;
new_z += size / 2;
corpse->GMMove(m_Position.x, m_Position.y, new_z, m_Position.w);
this->SetID(0);

View File

@ -48,6 +48,14 @@ void Mob::CalcBonuses()
SetAttackTimer();
CalcAC();
/* Fast walking NPC's are prone to disappear into walls/hills
We set this here because NPC's can cast spells to change walkspeed/runspeed
*/
float get_walk_speed = static_cast<float>(0.025f * this->GetWalkspeed());
if (get_walk_speed >= 0.9 && this->fix_z_timer.GetDuration() != 100) {
this->fix_z_timer.SetTimer(100);
}
rooted = FindType(SE_Root);
}

View File

@ -113,7 +113,7 @@ Mob::Mob(const char* in_name,
tmHidden(-1),
mitigation_ac(0),
m_specialattacks(eSpecialAttacks::None),
fix_z_timer(1000),
fix_z_timer(300),
fix_z_timer_engaged(100)
{
targeted = 0;
@ -121,6 +121,8 @@ Mob::Mob(const char* in_name,
tar_vector=0;
currently_fleeing = false;
last_z = 0;
AI_Init();
SetMoving(false);
moved=false;

View File

@ -1067,6 +1067,8 @@ public:
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr);
float last_z;
// Bots HealRotation methods
#ifdef BOTS
bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); }

View File

@ -870,6 +870,7 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
}
void Mob::FixZ() {
BenchTimer timer;
timer.reset();
@ -878,9 +879,8 @@ void Mob::FixZ() {
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
{
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
float new_z = zone->zonemap->FindBestZ(dest, nullptr);
float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 10);
auto duration = timer.elapsed();
@ -896,8 +896,26 @@ void Mob::FixZ() {
duration
);
if ((new_z > -2000) && std::abs(new_z - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving))
m_Position.z = new_z + 1;
float size = GetSize();
if (size > 10)
size = 10;
new_z += size / 2;
if ((new_z > -2000) && std::abs(m_Position.z - new_z) < 35) {
if (RuleB(Map, MobZVisualDebug))
this->SendAppearanceEffect(78, 0, 0, 0, 0);
m_Position.z = new_z;
}
else {
if (RuleB(Map, MobZVisualDebug))
this->SendAppearanceEffect(103, 0, 0, 0, 0);
Log(Logs::General, Logs::Debug, "%s is failing to find Z %f", this->GetCleanName(), std::abs(m_Position.z - new_z));
}
last_z = m_Position.z;
}
}
}