Heres where I'm at, this uses its own code for bots movement while leaving haynars untouched for use with all other mob entities. I applied this to code pulled on 3 Oct 2015 and ran ok.
At least can have ok movement until someone is able to fix bots to work with haynar's movement code. Also, I did get my toilet fixed..
Code:
diff --git a/zone/bot.cpp b/zone/bot.cpp
index cbc951c..4a6e8af 100644
--- a/zone/bot.cpp
+++ b/zone/bot.cpp
@@ -242,8 +242,10 @@ void Bot::ChangeBotArcherWeapons(bool isArcher) {
void Bot::Sit() {
if(IsMoving()) {
+ //SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget->GetY()));
moved = false;
- SetCurrentSpeed(0);
+ SendPosition(); //rencro -- revert haynar on bots
+ SetMoving(false); //rencro -- revert haynar on bots
tar_ndx = 0;
}
@@ -318,7 +320,7 @@ NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::str
BotNPCType.d_melee_texture2 = 0;
BotNPCType.qglobal = false;
BotNPCType.attack_speed = 0;
- BotNPCType.runspeed = 0.7f;
+ BotNPCType.runspeed = 1.25; //rencro -- revert haynar on bots
BotNPCType.bodytype = 1;
BotNPCType.findable = 0;
BotNPCType.hp_regen = 1;
@@ -349,7 +351,7 @@ NPCType Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string b
Result.drakkin_details = 0;
Result.drakkin_heritage = 0;
Result.drakkin_tattoo = 0;
- Result.runspeed = 0.7f;
+ Result.runspeed = 1.25; //rencro revert haynar on bots
Result.bodytype = 1;
Result.findable = 0;
Result.hp_regen = 1;
@@ -2403,7 +2405,7 @@ void Bot::AI_Process() {
} else if(!IsRooted()) {
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
Log.Out(Logs::Detail, Logs::AI, "Returning to location prior to being summoned.");
- CalculateNewPosition2(m_PreSummonLocation.x, m_PreSummonLocation.y, m_PreSummonLocation.z, GetRunspeed());
+ CalculateNewPosition2(m_PreSummonLocation.x, m_PreSummonLocation.y, m_PreSummonLocation.z, GetBotRunspeed()); //rencro
SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.x, m_PreSummonLocation.y));
return;
}
@@ -2478,9 +2480,11 @@ void Bot::AI_Process() {
if(IsMoving()) {
SetHeading(0);
SetRunAnimSpeed(0);
- SetCurrentSpeed(GetRunspeed());
- if(moved)
- SetCurrentSpeed(0);
+ if (moved) {
+ moved = false; //rencro -- revert haynar on bots
+ SendPosition(); //rencro -- revert haynar on bots
+ SetMoving(false); //rencro -- revert haynar on bots
+ }
}
return;
}
@@ -2516,10 +2520,10 @@ void Bot::AI_Process() {
if(IsMoving()) {
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
SetRunAnimSpeed(0);
- SetCurrentSpeed(0);
if(moved) {
moved = false;
- SetCurrentSpeed(0);
+ SendPosition(); //rencro -- revert haynar on bots
+ SetMoving(false); //rencro -- revert haynar on bots
}
}
atCombatRange = true;
@@ -2533,10 +2537,10 @@ void Bot::AI_Process() {
if(atCombatRange) {
if(IsMoving()) {
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
- SetCurrentSpeed(0);
if(moved) {
moved = false;
- SetCurrentSpeed(0);
+ SendPosition(); //rencro -- revert haynar on bots
+ SetMoving(false); //rencro -- revert haynar on bots
}
}
@@ -2547,7 +2551,7 @@ void Bot::AI_Process() {
float newY = 0;
float newZ = 0;
if(PlotPositionAroundTarget(GetTarget(), newX, newY, newZ)) {
- CalculateNewPosition2(newX, newY, newZ, GetRunspeed());
+ CalculateNewPosition2(newX, newY, newZ, GetBotRunspeed()); //rencro
return;
}
}
@@ -2557,7 +2561,7 @@ void Bot::AI_Process() {
float newY = 0;
float newZ = 0;
if(PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) {
- CalculateNewPosition2(newX, newY, newZ, GetRunspeed());
+ CalculateNewPosition2(newX, newY, newZ, GetBotRunspeed()); //rencro
return;
}
}
@@ -2679,7 +2683,7 @@ void Bot::AI_Process() {
if (AImovement_timer->Check()) {
if(!IsRooted()) {
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
- CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
+ CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetBotRunspeed()); //rencro
return;
}
@@ -2718,9 +2722,9 @@ void Bot::AI_Process() {
Mob* follow = entity_list.GetMob(GetFollowID());
if(follow) {
float dist = DistanceSquared(m_Position, follow->GetPosition());
- int speed = follow->GetRunspeed();
+ float speed = follow->GetBotRunspeed(); //rencro -- revert haynar on bots 0.6999..
if(dist < GetFollowDistance() + 1000)
- speed = follow->GetWalkspeed();
+ speed = follow->GetBotWalkspeed();
if(dist > GetFollowDistance()) {
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
@@ -2730,7 +2734,8 @@ void Bot::AI_Process() {
} else {
if(moved) {
moved = false;
- SetCurrentSpeed(0);
+ SendPosition(); //rencro --revert haynar on bots
+ SetMoving(false); //rencro -- revert haynar on bots
}
}
}
@@ -2797,14 +2802,14 @@ void Bot::PetAIProcess() {
if(botPet->GetClass() == ROGUE && !petHasAggro && !botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY())) {
// Move the rogue to behind the mob
if(botPet->PlotPositionAroundTarget(botPet->GetTarget(), newX, newY, newZ)) {
- botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetRunspeed());
+ botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetBotRunspeed()); //rencro
return;
}
}
else if(GetTarget() == botPet->GetTarget() && !petHasAggro && !botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY())) {
// If the bot owner and the bot are fighting the same mob, then move the pet to the rear arc of the mob
if(botPet->PlotPositionAroundTarget(botPet->GetTarget(), newX, newY, newZ)) {
- botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetRunspeed());
+ botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetBotRunspeed()); //rencro
return;
}
}
@@ -2819,7 +2824,7 @@ void Bot::PetAIProcess() {
moveBehindMob = true;
if(botPet->PlotPositionAroundTarget(botPet->GetTarget(), newX, newY, newZ, moveBehindMob)) {
- botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetRunspeed());
+ botPet->CalculateNewPosition2(newX, newY, newZ, botPet->GetBotRunspeed()); //rencro
return;
}
}
@@ -2902,13 +2907,13 @@ void Bot::PetAIProcess() {
botPet->SetRunAnimSpeed(0);
if(!botPet->IsRooted()) {
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", botPet->GetTarget()->GetCleanName());
- botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetOwner()->GetRunspeed());
+ botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetOwner()->GetBotRunspeed()); //rencro
return;
} else {
botPet->SetHeading(botPet->GetTarget()->GetHeading());
if(moved) {
moved = false;
- SetCurrentSpeed(0);
+ //SetCurrentSpeed(0);
botPet->SendPosition();
botPet->SetMoving(false);
}
@@ -2930,13 +2935,13 @@ void Bot::PetAIProcess() {
float dist = DistanceSquared(botPet->GetPosition(), botPet->GetTarget()->GetPosition());
botPet->SetRunAnimSpeed(0);
if(dist > 184) {
- botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetTarget()->GetRunspeed());
+ botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetTarget()->GetBotRunspeed()); //rencro
return;
} else {
botPet->SetHeading(botPet->GetTarget()->GetHeading());
if(moved) {
moved = false;
- SetCurrentSpeed(0);
+ //SetCurrentSpeed(0);
botPet->SendPosition();
botPet->SetMoving(false);
}
@@ -8043,7 +8048,53 @@ bool Bot::CanHeal() {
}
bool Bot::CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ) {
- return MakeNewPositionAndSendUpdate(x, y, z, speed, checkZ);
+ // 2.5625 is the inverse of 0.3902439. The only difference is in implementation.
+ // NOTE: You can not change just one of the constants below. They are the same number, just expressed inversly of each other.
+ // const float clientOverServerRatio = 2.5625f;
+ const float serverOverClientRatio = 0.3902439f;
+
+ // Use this block if using 2.5625 as the ratio.
+ // const int clientAnimationMovementRateTypeMultiple = 8;
+
+ // WildcardX: These are valid rates and observations based on painstaking testing of the client response to these values
+ //
+ //
+ // 0 * 8 = 0 : No Movement
+ // 1 * 8 = 8 : Death Walk
+ // 2 * 8 = 16 : Slow Walk
+ // 3 * 8 = 24 : Normal Walk
+ // 4 * 8 = 32 : Jog
+ // 5 * 8 = 40 : Normal Run
+ // 6 * 8 = 48 : Faster Run
+ // 7 * 8 = 56 : Even Faster Run
+ // 8 * 8 = 64 : Fastest Yet Run (Bard Song Speed?)
+ // 9 * 8 = 72 : Faster Fastest Yet Run
+ // 10 * 8 = 80 : .... you get the idea, this is pretty fast
+ // 11 * 8 = 88 : .... warp speed anyone?
+ // 12 * 8 = 96 : .... transwarp drive was invented by gnomes in Norrath
+ // 13 * 8 = 104 : ... who needs warp drives when you can just displace through time and space?
+ //
+ //
+ // You get the idea here with these... These seem to be "benchmark values" of animation movement and how fast
+ // the client thinks the Mob is moving so it can make it all look seemless between updates from the server.
+ // This chart is scalable by the client so you can pass an animation rate of 50 and get a "faster run" but not quite a "even faster run"
+
+ // Convert the Bot movement rate to a value the client understands based on the chart above
+ // Use this block if using 2.5625 as the ratio.
+ // speed *= clientMovementRateTypeMultiple;
+
+
+ // This sets the movement animation rate with the client
+ // Use this block if using 2.5625 as the ratio.
+ // pRunAnimSpeed = speed;
+ pRunAnimSpeed = ((serverOverClientRatio * 10.0f) * speed) * 10.0f;
+
+ // Now convert our "speed" from the value necessary for the client to animate the correct movement type rate to the server side speed
+ // Use this block if using 2.5625 as the ratio.
+ // speed *= serverOverClientRatio;
+ speed = pRunAnimSpeed / serverOverClientRatio;
+
+ return MakeNewBotPositionAndSendUpdate(x, y, z, speed, checkZ);
}
void Bot::BotGroupOrderFollow(Group* group, Client* client) {
diff --git a/zone/mob.cpp b/zone/mob.cpp
index 24f17a5..5251bbd 100644
--- a/zone/mob.cpp
+++ b/zone/mob.cpp
@@ -559,6 +555,66 @@ bool Mob::IsInvisible(Mob* other) const
return(false);
}
+/* rencro -- bots with haynar need to walk through this part of code and remove non bot stuff*/
+float Mob::_GetMovementSpeed(int mod) const
+{
+ /*
+ if (mod >= 0) {
+ return 0.6f;
+ }
+ else {
+ return 0.4f;
+ } */
+ if (IsRooted())
+ return 0.0f;
+ else if (IsPseudoRooted())
+ return 0.00001f;
+
+ float speed_mod = 0.6f; //seems to work ok so far
+
+ int aa_mod = 0;
+ int spell_mod = 0;
+ int runspeedcap = RuleI(Character, BaseRunSpeedCap);
+ int movemod = 0;
+ float frunspeedcap = 0.0f;
+
+ runspeedcap += itembonuses.IncreaseRunSpeedCap + spellbonuses.IncreaseRunSpeedCap + aabonuses.IncreaseRunSpeedCap;
+ aa_mod += itembonuses.BaseMovementSpeed + spellbonuses.BaseMovementSpeed + aabonuses.BaseMovementSpeed;
+ spell_mod += spellbonuses.movementspeed + itembonuses.movementspeed;
+
+ //hard cap
+ if (runspeedcap > 225)
+ runspeedcap = 225;
+
+ if (spell_mod < 0)
+ movemod += spell_mod;
+ else if (spell_mod > aa_mod)
+ movemod = spell_mod;
+ else
+ movemod = aa_mod;
+
+ // cap negative movemods from snares mostly
+ if (movemod < -85)
+ movemod = -85;
+
+ if (movemod != 0)
+ speed_mod += speed_mod * static_cast<float>(movemod) / 100.0f;
+
+ //runspeed caps
+ frunspeedcap = static_cast<float>(runspeedcap) / 100.0f;
+
+ //apply final mod such as the -47 for walking
+ // use runspeed since it should stack with snares
+ // blah blah blah
+ if (mod != 0)
+ speed_mod += runspeed * static_cast<float>(mod) / 100.0f;
+
+ if (speed_mod <= 0.0f)
+ speed_mod = 0.0f;
+
+ return speed_mod;
+}
+
int Mob::_GetWalkSpeed() const {
if (IsRooted() || IsStunned() || IsMezzed())
@@ -1384,6 +1440,8 @@ void Mob::SendPosition()
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
MakeSpawnUpdateNoDelta(spu);
move_tic_count = 0;
+ if (IsBot())
+ tar_ndx = 20; //rencro -- bots with haynar
entity_list.QueueClients(this, app, true);
safe_delete(app);
}
diff --git a/zone/mob.h b/zone/mob.h
index 6510652..d134022 100644
--- a/zone/mob.h
+++ b/zone/mob.h
@@ -464,6 +464,11 @@ public:
virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); }
virtual void GoToBind(uint8 bindnum = 0) { }
virtual void Gate();
+ /* rencro -- add bots around haynar */
+ float GetBotWalkspeed() const { return(_GetMovementSpeed(-47)); }
+ float GetBotRunspeed() const { return(_GetMovementSpeed(0)); }
+ float GetBotBaseRunspeed() const { return runspeed; }
+ /* rencro -- add bots around haynar */
int GetWalkspeed() const { return(_GetWalkSpeed()); }
int GetRunspeed() const { return(_GetRunSpeed()); }
void SetCurrentSpeed(int in);
@@ -998,6 +1003,7 @@ protected:
int _GetRunSpeed() const;
int _GetFearSpeed() const;
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ);
+ virtual bool MakeNewBotPositionAndSendUpdate(float x, float y, float z, float speed, bool checkZ); //rencro -- add bots around haynar code
virtual bool AI_EngagedCastCheck() { return(false); }
virtual bool AI_PursueCastCheck() { return(false); }
diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp
index e900c68..cf04ecf 100644
--- a/zone/waypoints.cpp
+++ b/zone/waypoints.cpp
@@ -708,6 +708,212 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
pLastChange = Timer::GetCurrentTime();
return true;
}
+/* rencro add bots around haynar */
+bool Mob::MakeNewBotPositionAndSendUpdate(float x, float y, float z, float speed, bool checkZ) {
+ if(GetID()==0)
+ return true;
+
+ 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.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
+ return true;
+ }
+ Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
+ return false;
+ } else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) {
+ Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z);
+
+ m_Position.x = x;
+ m_Position.y = y;
+ m_Position.z = z;
+ return true;
+ }
+
+ bool send_update = false;
+ int compare_steps = 20;
+ 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_y = m_Position.y + m_TargetV.y*tar_vector;
+ float new_z = m_Position.z + m_TargetV.z*tar_vector;
+ if(IsNPC()) {
+ entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
+ }
+
+ m_Position.x = new_x;
+ m_Position.y = new_y;
+ m_Position.z = new_z;
+
+ Log.Out(Logs::Detail, Logs::AI, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z);
+
+ //fix up pathing Z
+ if(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.Out(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;
+ }
+ }
+ }
+
+ tar_ndx++;
+ return true;
+ }
+
+
+ if (tar_ndx>50) {
+ tar_ndx--;
+ } else {
+ tar_ndx=0;
+ }
+ m_TargetLocation = glm::vec3(x, y, z);
+
+ float nx = this->m_Position.x;
+ float ny = this->m_Position.y;
+ float nz = this->m_Position.z;
+// float nh = this->heading;
+
+ m_TargetV.x = x - nx;
+ m_TargetV.y = y - ny;
+ m_TargetV.z = z - nz;
+ //pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
+ //speed *= NPC_SPEED_MULTIPLIER;
+
+ Log.Out(Logs::Detail, Logs::AI, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z, speed, pRunAnimSpeed);
+
+ // --------------------------------------------------------------------------
+ // 2: get unit vector
+ // --------------------------------------------------------------------------
+ float mag = sqrtf (m_TargetV.x*m_TargetV.x + m_TargetV.y*m_TargetV.y + m_TargetV.z*m_TargetV.z);
+ tar_vector = speed / mag;
+
+// mob move fix
+ int numsteps = (int) ( mag * 16.0f / (float)speed + 0.5f);
+
+// mob move fix
+
+ if (numsteps<20)
+ {
+ if (numsteps>1)
+ {
+ tar_vector=1.0f ;
+ m_TargetV.x = m_TargetV.x / numsteps;
+ m_TargetV.y = m_TargetV.y / numsteps;
+ m_TargetV.z = m_TargetV.z / numsteps;
+
+ float new_x = m_Position.x + m_TargetV.x;
+ float new_y = m_Position.y + m_TargetV.y;
+ float new_z = m_Position.z + m_TargetV.z;
+ if(IsNPC()) {
+ entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
+ }
+
+ m_Position.x = new_x;
+ m_Position.y = new_y;
+ m_Position.z = new_z;
+ m_Position.w = CalculateHeadingToTarget(x, y);
+ tar_ndx = 20 - numsteps;
+ Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps);
+ }
+ else
+ {
+ m_Position.x = x;
+ m_Position.y = y;
+ m_Position.z = z;
+
+ tar_ndx = 20;
+ Log.Out(Logs::Detail, Logs::AI, "Only a single step to get there... jumping.");
+ }
+ }
+
+ else {
+ tar_vector /= 20.0f;
+ float dur = Timer::GetCurrentTime() - pLastChange;
+ if(dur < 1.0f) {
+ dur = 1.0f;
+ }
+ tar_vector = (tar_vector * AImovement_duration) / 100.0f;
+
+ float new_x = m_Position.x + m_TargetV.x*tar_vector;
+ float new_y = m_Position.y + m_TargetV.y*tar_vector;
+ float new_z = m_Position.z + m_TargetV.z*tar_vector;
+ if(IsNPC()) {
+ entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
+ }
+
+ m_Position.x = new_x;
+ m_Position.y = new_y;
+ m_Position.z = new_z;
+ m_Position.w = CalculateHeadingToTarget(x, y);
+ Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps);
+ }
+
+ //fix up pathing Z
+ if(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);
+
+ Log.Out(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;
+ }
+ }
+ }
+
+ SetMoving(true);
+ moved=true;
+
+ m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f);
+
+ if (IsClient())
+ {
+ SendPosUpdate(1);
+ CastToClient()->ResetPositionTimer();
+ }
+ else
+ {
+ move_tic_count = RuleI(Zone, NPCPositonUpdateTicCount); //wtf is Positon??
+ SendPosUpdate();
+ SetAppearance(eaStanding, false);
+ }
+ pLastChange = Timer::GetCurrentTime();
+ return true;
+}
bool Mob::CalculateNewPosition2(float x, float y, float z, int speed, bool checkZ, bool calcHeading) {
return MakeNewPositionAndSendUpdate(x, y, z, speed, checkZ);