mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-25 12:42:25 +00:00
Fixed issues with Z correctness when NPCs are pathing on normal grids
Fixed issues with Z correctness when NPCs are engaged with players following NPC corpses should fall into the ground far less
This commit is contained in:
parent
592bbd3180
commit
539fa8b262
@ -1,5 +1,16 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 6/28/2017 ==
|
||||||
|
Akkadius: Fixed issues with Z correctness when NPCs are pathing on normal grids
|
||||||
|
Akkadius: Fixed issues with Z correctness when NPCs are engaged with players following
|
||||||
|
Akkadius: NPC corpses should fall into the ground far less
|
||||||
|
|
||||||
|
== 6/25/2017 ==
|
||||||
|
Akkadius: New rules made by developers are now automatically created when world boots up, this keeps
|
||||||
|
from having to issue schema SQL updates every time rules are added.
|
||||||
|
- Whenever a rule isn't present in the database, it will be automatically created
|
||||||
|
Akkadius: Sped up saylink retrieval x1000 helpful for dialogues, plugins with many saylinks
|
||||||
|
|
||||||
== 4/16/2017 ==
|
== 4/16/2017 ==
|
||||||
KLS: Merge eqstream branch
|
KLS: Merge eqstream branch
|
||||||
- UDP client stack completely rewritten should both have better throughput and recover better (peq has had far fewer reports of desyncs).
|
- UDP client stack completely rewritten should both have better throughput and recover better (peq has had far fewer reports of desyncs).
|
||||||
|
|||||||
@ -274,6 +274,7 @@ RULE_BOOL(Map, FixPathingZWhenLoading, true) //increases zone boot times a bit
|
|||||||
RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, accomplishes the same thing but does it at each waypoint instead of once at boot time.
|
RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, accomplishes the same thing but does it at each waypoint instead of once at boot time.
|
||||||
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
|
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, 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_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
|
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, 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.
|
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.
|
||||||
|
|||||||
@ -2388,6 +2388,13 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
|||||||
|
|
||||||
entity_list.UnMarkNPC(GetID());
|
entity_list.UnMarkNPC(GetID());
|
||||||
entity_list.RemoveNPC(GetID());
|
entity_list.RemoveNPC(GetID());
|
||||||
|
|
||||||
|
/* Fix Z on Corpse Creation */
|
||||||
|
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);
|
||||||
|
|
||||||
this->SetID(0);
|
this->SetID(0);
|
||||||
|
|
||||||
if (killer != 0 && emoteid != 0)
|
if (killer != 0 && emoteid != 0)
|
||||||
|
|||||||
@ -112,7 +112,9 @@ Mob::Mob(const char* in_name,
|
|||||||
m_Position(position),
|
m_Position(position),
|
||||||
tmHidden(-1),
|
tmHidden(-1),
|
||||||
mitigation_ac(0),
|
mitigation_ac(0),
|
||||||
m_specialattacks(eSpecialAttacks::None)
|
m_specialattacks(eSpecialAttacks::None),
|
||||||
|
fix_z_timer(1000),
|
||||||
|
fix_z_timer_engaged(100)
|
||||||
{
|
{
|
||||||
targeted = 0;
|
targeted = 0;
|
||||||
tar_ndx=0;
|
tar_ndx=0;
|
||||||
|
|||||||
@ -913,6 +913,7 @@ public:
|
|||||||
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);
|
||||||
void SendToFixZ(float new_x, float new_y, float new_z);
|
void SendToFixZ(float new_x, float new_y, float new_z);
|
||||||
|
void FixZ();
|
||||||
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; }
|
||||||
@ -1373,6 +1374,8 @@ protected:
|
|||||||
|
|
||||||
bool flee_mode;
|
bool flee_mode;
|
||||||
Timer flee_timer;
|
Timer flee_timer;
|
||||||
|
Timer fix_z_timer;
|
||||||
|
Timer fix_z_timer_engaged;
|
||||||
|
|
||||||
bool pAIControlled;
|
bool pAIControlled;
|
||||||
bool roamer;
|
bool roamer;
|
||||||
|
|||||||
@ -991,6 +991,9 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
if (engaged) {
|
if (engaged) {
|
||||||
|
|
||||||
|
if (moving && fix_z_timer_engaged.Check())
|
||||||
|
this->FixZ();
|
||||||
|
|
||||||
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
||||||
SendAddPlayerState(PlayerState::Aggressive);
|
SendAddPlayerState(PlayerState::Aggressive);
|
||||||
// we are prevented from getting here if we are blind and don't have a target in range
|
// we are prevented from getting here if we are blind and don't have a target in range
|
||||||
|
|||||||
@ -513,39 +513,8 @@ 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;
|
||||||
|
|
||||||
uint8 NPCFlyMode = 0;
|
if(fix_z_timer.Check())
|
||||||
|
this->FixZ();
|
||||||
if (IsNPC()) {
|
|
||||||
if (CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
|
|
||||||
NPCFlyMode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fix up pathing Z
|
|
||||||
if (!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
|
|
||||||
{
|
|
||||||
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 newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;
|
|
||||||
|
|
||||||
if ((newz > -2000) &&
|
|
||||||
std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
|
|
||||||
{
|
|
||||||
if ((std::abs(x - m_Position.x) < 0.5) &&
|
|
||||||
(std::abs(y - m_Position.y) < 0.5)) {
|
|
||||||
if (std::abs(z - m_Position.z) <=
|
|
||||||
RuleR(Map, FixPathingZMaxDeltaMoving))
|
|
||||||
m_Position.z = z;
|
|
||||||
else
|
|
||||||
m_Position.z = newz + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_Position.z = newz + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tar_ndx++;
|
tar_ndx++;
|
||||||
return true;
|
return true;
|
||||||
@ -651,37 +620,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
m_Position.w = CalculateHeadingToTarget(x, y);
|
m_Position.w = CalculateHeadingToTarget(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 NPCFlyMode = 0;
|
if (fix_z_timer.Check())
|
||||||
|
this->FixZ();
|
||||||
if (IsNPC()) {
|
|
||||||
if (CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
|
|
||||||
NPCFlyMode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fix up pathing Z
|
|
||||||
if (!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) {
|
|
||||||
|
|
||||||
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 newz = zone->zonemap->FindBestZ(dest, nullptr);
|
|
||||||
|
|
||||||
if ((newz > -2000) &&
|
|
||||||
std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
|
|
||||||
{
|
|
||||||
if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) {
|
|
||||||
if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
|
|
||||||
m_Position.z = z;
|
|
||||||
else
|
|
||||||
m_Position.z = newz + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_Position.z = newz + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetMoving(true);
|
SetMoving(true);
|
||||||
moved = true;
|
moved = true;
|
||||||
@ -769,39 +709,8 @@ bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ
|
|||||||
Log(Logs::Detail, Logs::AI, "Next position (%.3f, %.3f, %.3f)", m_Position.x, m_Position.y, m_Position.z);
|
Log(Logs::Detail, Logs::AI, "Next position (%.3f, %.3f, %.3f)", m_Position.x, m_Position.y, m_Position.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 NPCFlyMode = 0;
|
if (fix_z_timer.Check())
|
||||||
|
this->FixZ();
|
||||||
if (IsNPC()) {
|
|
||||||
if (CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
|
|
||||||
NPCFlyMode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fix up pathing Z
|
|
||||||
if (!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
|
|
||||||
{
|
|
||||||
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 newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;
|
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz, m_Position.x, m_Position.y, m_Position.z);
|
|
||||||
|
|
||||||
if ((newz > -2000) &&
|
|
||||||
std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
|
|
||||||
{
|
|
||||||
if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) {
|
|
||||||
if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
|
|
||||||
m_Position.z = z;
|
|
||||||
else
|
|
||||||
m_Position.z = newz + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_Position.z = newz + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//OP_MobUpdate
|
//OP_MobUpdate
|
||||||
if ((old_test_vector != test_vector) || tar_ndx>20) { //send update
|
if ((old_test_vector != test_vector) || tar_ndx>20) { //send update
|
||||||
@ -943,9 +852,6 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
|||||||
m_Position.y = new_y;
|
m_Position.y = new_y;
|
||||||
m_Position.z = new_z + 0.1;
|
m_Position.z = new_z + 0.1;
|
||||||
|
|
||||||
//fix up pathing Z, this shouldent be needed IF our waypoints
|
|
||||||
//are corrected instead
|
|
||||||
|
|
||||||
if (zone->HasMap() && RuleB(Map, FixPathingZOnSendTo))
|
if (zone->HasMap() && RuleB(Map, FixPathingZOnSendTo))
|
||||||
{
|
{
|
||||||
if (!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
|
if (!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
|
||||||
@ -955,7 +861,7 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
|||||||
|
|
||||||
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz, m_Position.x, m_Position.y, m_Position.z);
|
Log(Logs::Moderate, Logs::Pathing, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz, m_Position.x, m_Position.y, m_Position.z);
|
||||||
|
|
||||||
if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check.
|
if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check.
|
||||||
m_Position.z = newz + 1;
|
m_Position.z = newz + 1;
|
||||||
@ -963,6 +869,39 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::FixZ() {
|
||||||
|
BenchTimer timer;
|
||||||
|
timer.reset();
|
||||||
|
|
||||||
|
if (zone->HasMap() && RuleB(Map, FixZWhenMoving) && (flymode != 1 && flymode != 2))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
auto duration = timer.elapsed();
|
||||||
|
|
||||||
|
Log(
|
||||||
|
Logs::Moderate,
|
||||||
|
Logs::Pathing,
|
||||||
|
"Mob::FixZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf",
|
||||||
|
this->GetCleanName(),
|
||||||
|
new_z,
|
||||||
|
m_Position.x,
|
||||||
|
m_Position.y,
|
||||||
|
m_Position.z,
|
||||||
|
duration
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((new_z > -2000) && std::abs(new_z - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving))
|
||||||
|
m_Position.z = new_z + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
|
int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);
|
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user