mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-15 01:49:09 +00:00
Tame Chat Action / Pet Chat Action (stances/commands)
Hello everyone, I am on a quest to make bot's pets completely functional, focuses on solving issues #1351 , #1230 , and #1137 . This PR achieves the following: 1. Changes the current "pet" chat command to "tame", which is more intuitive that only hunters can use it. The modes are "tame name (name)", "tame id (id)", "tame family (family)", "tame rename (new name)", and "tame abandon". Tame abandon is new - it simply abandons the current pet. Also, now, if you type in "tame family" by itself, it will list the available families. See pictures below for examples. 2. Added new "pet" chat command, with the following modes: "pet passive", "pet aggressive", "pet defensive", "pet stance" (shows current pet stance), "pet attack", "pet follow", and "pet stay". Previously, the pet's stance was not changeable, and there were some less than desired effects from summonable pets - see the issues above. 3. New config option: AiPlayerbot.DefaultPetStance, which changes the stance that all bot's pets are summoned as. This makes sure when feral spirits or treants are summoned by shamans and druids, they are immediately set to this configured stance. Set as 1 as default, which is defensive. (0 = Passive, 1 = Defensive, 2 = Aggressive) 4. New config option: AiPlayerbot.PetChatCommandDebug, which enables debug messages for the "pet" chat command. By default it is set to 0, which is disabled, but if you would like to see when pet's stances are changed, or when you tell the pet to attack/follow/stay, and when pet spells are auto-toggled, this is an option. I made this for myself mainly to test the command - if anyone notices any wierd pet behavior, this will be an option to help them report it as well. 5. Modified FollowActions to not constantly execute the petfollow action, overriding any stay or attack commands issued. 6. Modified GenericActions to have TogglePetSpellAutoCastAction optionally log when spells are toggled based on AiPlayerbot.PetChatCommandDebug. 7. Modified PetAttackAction to not attack if the pet is set to passive, and not override the pet's stance to passive every time it was executed. 8. Modified CombatStrategy.cpp to not constantly issue the petattack command, respecting the "pet stay" and "pet follow" commands. Pets will still automatically attack the enemy if set to aggressive or defensive. 9. Warlocks, Priests, Hunters, Shamans, Mages, Druids, and DKs (all classes that have summons): Added a "new pet" trigger that executes the "set pet stance" action. The "new pet" trigger happens only once, upon summoning a pet. It sets the pet's stance from AiPlayerbot.DefaultPetStance's value.
This commit is contained in:
@@ -4,9 +4,19 @@
|
||||
*/
|
||||
|
||||
#include "GenericActions.h"
|
||||
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "CharmInfo.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
enum PetSpells
|
||||
{
|
||||
@@ -100,6 +110,11 @@ bool TogglePetSpellAutoCastAction::Execute(Event event)
|
||||
toggled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug message if pet spells have been toggled and debug is enabled
|
||||
if (toggled && sPlayerbotAIConfig->petChatCommandDebug == 1)
|
||||
botAI->TellMaster("Pet autocast spells have been toggled.");
|
||||
|
||||
return toggled;
|
||||
}
|
||||
|
||||
@@ -107,22 +122,23 @@ bool PetAttackAction::Execute(Event event)
|
||||
{
|
||||
Guardian* pet = bot->GetGuardianPet();
|
||||
if (!pet)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not attack if the pet's stance is set to "passive".
|
||||
if (pet->GetReactState() == REACT_PASSIVE)
|
||||
return false;
|
||||
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bot->IsValidAttackTarget(target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pet->SetReactState(REACT_PASSIVE);
|
||||
// This section has been commented because it was overriding the
|
||||
// pet's stance to "passive" every time the attack action was executed.
|
||||
// pet->SetReactState(REACT_PASSIVE);
|
||||
|
||||
pet->ClearUnitState(UNIT_STATE_FOLLOW);
|
||||
pet->AttackStop();
|
||||
pet->SetTarget(target->GetGUID());
|
||||
@@ -136,3 +152,79 @@ bool PetAttackAction::Execute(Event event)
|
||||
pet->ToCreature()->AI()->AttackStart(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetPetStanceAction::Execute(Event /*event*/)
|
||||
{
|
||||
// Get the bot player object from the AI
|
||||
Player* bot = botAI->GetBot();
|
||||
|
||||
// Prepare a list to hold all controlled pet and guardian creatures
|
||||
std::vector<Creature*> targets;
|
||||
|
||||
// Add the bot's main pet (if it exists) to the target list
|
||||
Pet* pet = bot->GetPet();
|
||||
if (pet)
|
||||
targets.push_back(pet);
|
||||
|
||||
// Loop through all units controlled by the bot (could be pets, guardians, etc.)
|
||||
for (Unit::ControlSet::const_iterator itr = bot->m_Controlled.begin(); itr != bot->m_Controlled.end(); ++itr)
|
||||
{
|
||||
// Only add creatures (skip players, vehicles, etc.)
|
||||
Creature* creature = dynamic_cast<Creature*>(*itr);
|
||||
if (!creature)
|
||||
continue;
|
||||
// Avoid adding the main pet twice
|
||||
if (pet && creature == pet)
|
||||
continue;
|
||||
targets.push_back(creature);
|
||||
}
|
||||
|
||||
// If there are no controlled pets or guardians, notify the player and exit
|
||||
if (targets.empty())
|
||||
{
|
||||
botAI->TellError("You have no pet or guardian pet.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the default pet stance from the configuration
|
||||
int32 stance = sPlayerbotAIConfig->defaultPetStance;
|
||||
ReactStates react = REACT_DEFENSIVE;
|
||||
std::string stanceText = "defensive (from config, fallback)";
|
||||
|
||||
// Map the config stance integer to a ReactStates value and a message
|
||||
switch (stance)
|
||||
{
|
||||
case 0:
|
||||
react = REACT_PASSIVE;
|
||||
stanceText = "passive (from config)";
|
||||
break;
|
||||
case 1:
|
||||
react = REACT_DEFENSIVE;
|
||||
stanceText = "defensive (from config)";
|
||||
break;
|
||||
case 2:
|
||||
react = REACT_AGGRESSIVE;
|
||||
stanceText = "aggressive (from config)";
|
||||
break;
|
||||
default:
|
||||
react = REACT_DEFENSIVE;
|
||||
stanceText = "defensive (from config, fallback)";
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply the stance to all target creatures (pets/guardians)
|
||||
for (Creature* target : targets)
|
||||
{
|
||||
target->SetReactState(react);
|
||||
CharmInfo* charmInfo = target->GetCharmInfo();
|
||||
// If the creature has a CharmInfo, set the player-visible stance as well
|
||||
if (charmInfo)
|
||||
charmInfo->SetPlayerReactState(react);
|
||||
}
|
||||
|
||||
// If debug is enabled in config, inform the master of the new stance
|
||||
if (sPlayerbotAIConfig->petChatCommandDebug == 1)
|
||||
botAI->TellMaster("Pet stance set to " + stanceText + " (applied to all pets/guardians).");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user