Browse Source

/bot follow id and /bot stopfollow id added

Allows to stop the bot from following you or continue following when in group.  Also fixed the default runspeed on NPC's to be set to MaxSpeed.  Should resolve any unexpected stationary npc's/bots.
Image 3 years ago
parent
commit
517ae12865

+ 11 - 11
EQ2/source/WorldServer/Bots/BotBrain.cpp

@@ -29,9 +29,6 @@ void BotBrain::Think() {
 	if (Body->IsMezzedOrStunned())
 		return;
 
-	Entity* target = 0;
-	bool result;
-	
 	// If combat was processed we can return out
 	if (ProcessCombat())
 		return;
@@ -45,14 +42,17 @@ void BotBrain::Think() {
 		return;
 
 	// Set target to owner
-	target = GetBody()->GetOwner();	
+	Spawn* target = GetBody()->GetFollowTarget();
 
-	// Get distance from the owner
-	float distance = GetBody()->GetDistance(target);
+	if(target)
+	{
+		// Get distance from the owner
+		float distance = GetBody()->GetDistance(target);
 
-	// If out of melee range then move closer
-	if (distance > rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat())
-		MoveCloser(target);
+		// If out of melee range then move closer
+		if (distance > rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat())
+			MoveCloser(target);
+	}
 }
 
 bool BotBrain::ProcessCombat() {
@@ -137,7 +137,7 @@ bool BotBrain::ProcessSpell(Entity* target, float distance) {
 		float distance = Body->GetDistance(Body->GetTarget());
 		if (distance > spell->GetSpellData()->range) {
 			if (Body->GetTarget()->IsEntity())
-				MoveCloser((Entity*)Body->GetTarget());
+				MoveCloser((Spawn*)Body->GetTarget());
 		}
 		else {
 			// stop movement if spell can't be cast while moving
@@ -185,7 +185,7 @@ bool BotBrain::ProcessOutOfCombatSpells() {
 		float distance = Body->GetDistance(Body->GetTarget());
 		if (distance > spell->GetSpellData()->range) {
 			if (Body->GetTarget()->IsEntity())
-				MoveCloser((Entity*)Body->GetTarget());
+				MoveCloser((Spawn*)Body->GetTarget());
 		}
 		else {
 			Body->GetZone()->ProcessSpell(spell, Body, Body->GetTarget());

+ 35 - 0
EQ2/source/WorldServer/Bots/BotCommands.cpp

@@ -139,6 +139,40 @@ void Commands::Command_Bot(Client* client, Seperator* sep) {
 				return;
 			}
 		}
+		else if (strncasecmp("follow", sep->arg[0], 6) == 0) {
+			if (sep->IsSet(1) && sep->IsNumber(1)) {
+				int32 index = atoi(sep->arg[1]);
+
+				// Check if bot is currently spawned and if so camp it out
+				if (client->GetPlayer()->SpawnedBots.count(index) > 0) {
+					Spawn* bot = client->GetCurrentZone()->GetSpawnByID(client->GetPlayer()->SpawnedBots[index]);
+					if (bot && bot->IsBot())
+						((Bot*)bot)->SetFollowTarget(client->GetPlayer(), 5);
+				}
+				return;
+			}
+			else {
+				client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You must give the id (from /bot list) to have a bot follow you");
+				return;
+			}
+		}
+		else if (strncasecmp("stopfollow", sep->arg[0], 10) == 0) {
+			if (sep->IsSet(1) && sep->IsNumber(1)) {
+				int32 index = atoi(sep->arg[1]);
+
+				// Check if bot is currently spawned and if so camp it out
+				if (client->GetPlayer()->SpawnedBots.count(index) > 0) {
+					Spawn* bot = client->GetCurrentZone()->GetSpawnByID(client->GetPlayer()->SpawnedBots[index]);
+					if (bot && bot->IsBot())
+						((Bot*)bot)->SetFollowTarget(nullptr);
+				}
+				return;
+			}
+			else {
+				client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You must give the id (from /bot list) to stop a following bot");
+				return;
+			}
+		}
 		else if (strncasecmp("summon", sep->arg[0], 6) == 0) {
 			if (sep->IsSet(1) && strncasecmp("group", sep->arg[1], 5) == 0) {
 				GroupMemberInfo* gmi = client->GetPlayer()->GetGroupMemberInfo();
@@ -469,6 +503,7 @@ void Commands::Command_Bot_Spawn(Client* client, Seperator* sep) {
 		memset(&bot->appearance, 0, sizeof(bot->appearance));
 
 		if (database.LoadBot(client->GetCharacterID(), bot_id, bot)) {
+			bot->SetFollowTarget(client->GetPlayer(), 5);
 			bot->appearance.pos.collision_radius = 32;
 			bot->secondary_command_list_id = 0;
 			bot->primary_command_list_id = 0;

+ 3 - 1
EQ2/source/WorldServer/NPC.cpp

@@ -36,7 +36,9 @@ extern Races races;
 extern Appearance master_appearance_list;
 
 NPC::NPC(){	
-	Initialize();	
+	Initialize();
+	if (GetMaxSpeed() > 0)
+		SetSpeed(GetMaxSpeed());
 }
 
 NPC::NPC(NPC* old_npc){

+ 4 - 4
EQ2/source/WorldServer/NPC_AI.cpp

@@ -320,7 +320,7 @@ vector<Entity*>* Brain::GetHateList() {
 	return ret;
 }
 
-void Brain::MoveCloser(Entity* target) {
+void Brain::MoveCloser(Spawn* target) {
 	if (target && m_body->GetFollowTarget() != target)
 		m_body->SetFollowTarget(target);
 
@@ -376,7 +376,7 @@ bool Brain::CheckBuffs() {
 
 void Brain::ProcessMelee(Entity* target, float distance) {
 	if(distance > rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat())
-		MoveCloser(target);
+		MoveCloser((Spawn*)target);
 	else {
 		if (target) {
 			LogWrite(NPC_AI__DEBUG, 7, "NPC_AI", "%s is within melee range of %s.", m_body->GetName(), target->GetName());
@@ -559,7 +559,7 @@ void CombatPetBrain::Think() {
 
 	// If out of melee range then move closer
 	if (distance > rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat())
-		MoveCloser(target);
+		MoveCloser((Spawn*)target);
 }
 
 /* Example of how to override the default AI */
@@ -591,7 +591,7 @@ void NonCombatPetBrain::Think() {
 
 	// If out of melee range then move closer
 	if (distance > rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat())
-		MoveCloser(target);
+		MoveCloser((Spawn*)target);
 }
 
 BlankBrain::BlankBrain(NPC* body) : Brain(body) {

+ 1 - 1
EQ2/source/WorldServer/NPC_AI.h

@@ -120,7 +120,7 @@ public:
 	bool HasRecovered();
 	/// <summary>Tells the NPC to move closer to the given target</summary>
 	/// <param name="target">The target to move closer to</param>
-	void MoveCloser(Entity* target);
+	void MoveCloser(Spawn* target);
 
 protected:
 	// m_body = the npc this brain controls

+ 1 - 1
EQ2/source/WorldServer/Spawn.cpp

@@ -2782,7 +2782,7 @@ void Spawn::ProcessMovement(bool isSpawnListLocked){
 				}
 			}
 			else {
-				MoveToLocation(followTarget, rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat());
+				MoveToLocation(followTarget, rule_manager.GetGlobalRule(R_Combat, MaxCombatRange)->GetFloat(), false);
 				CalculateRunningLocation();
 			}
 		}