Go Back   EQEmulator Home > EQEmulator Forums > Support > Support::Windows Servers

Support::Windows Servers Support forum for Windows EQEMu users.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #24  
Old 10-04-2015, 11:18 PM
rencro
Hill Giant
 
Join Date: Sep 2008
Location: So. California
Posts: 219
Default

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);
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 03:43 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3