mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Hunter Pet Chat Command (#1448)
Hello everyone, I was working with hunter bots and I feel like I didn't have enough control over their pets. So I started working on a chat command for the hunter pets, and it's been a blast. Below is a description of what the commands do: pet name <name> Summons a tameable pet by its creature name (case-insensitive). The bot checks if the pet is exotic and requires the Beast Mastery talent if so. If successful, the bot announces the pet's new name and creature ID. If not found or not tameable, an error message is given. pet id <id> Summons a tameable pet by its database creature ID. The same exotic pet checks apply. Success is announced with the pet's name and ID. Errors are given for invalid IDs or untameable pets. pet family <family> Randomly selects and summons a tameable pet from the specified family (e.g., "cat", "wolf"). Only families with tameable pets are considered. Exotic pet checks and talent requirements apply. Success is announced with the pet's name and ID. Errors are given if no suitable pet is found. pet rename <new name> Renames the hunter's current summoned pet to a new name. The name must be 1-12 alphabetic characters (A-Z, a-z) and is automatically formatted (first letter capitalized, rest lowercased). Forbidden or reserved names are disallowed. After renaming, the bot sets the new name, saves the pet, and updates the client. The bot dismisses and attempts to recall the pet using "Call Pet" (if the hunter knows it) to update the UI. If the new name isn't visible immediately, the bot instructs the player to dismiss and recall the pet manually. Confirmation and guidance messages are provided. Additional Details: All commands display errors if requirements are not met (wrong name/id/family, forbidden name, lack of Beast Mastery, or hunter below level 10). After changing or summoning a pet (except renaming), the bot initializes the pet and its talents, then announces the result. TLDR: pet name <name> Summon a tameable pet by name pet id <id> Summon a tameable pet by database creature ID pet family <family> Randomly summon a tameable pet of the given family pet rename <new name> Rename the current pet and refresh its name in the client UI Description of files changed: src\strategy\actions\ChatActionContext.h: Added the "pet" action for the whisper command. src\strategy\actions\PetAction.cpp: New chat actions for all things related to hunter pets. src\strategy\actions\PetAction.h: New header for the PetAction.cpp. src\strategy\generic\ChatCommandHandlerStrategy.cpp: Linked the trigger and action in the chatcommandhandlerstrategy, for the bot to take action when whispered "pet" (trigger). src\strategy\triggers\ChatTriggerContext.h: Added the "pet" trigger.
This commit is contained in:
@@ -78,6 +78,7 @@
|
|||||||
#include "OpenItemAction.h"
|
#include "OpenItemAction.h"
|
||||||
#include "UnlockItemAction.h"
|
#include "UnlockItemAction.h"
|
||||||
#include "UnlockTradedItemAction.h"
|
#include "UnlockTradedItemAction.h"
|
||||||
|
#include "PetAction.h"
|
||||||
|
|
||||||
class ChatActionContext : public NamedObjectContext<Action>
|
class ChatActionContext : public NamedObjectContext<Action>
|
||||||
{
|
{
|
||||||
@@ -187,6 +188,7 @@ public:
|
|||||||
creators["lfg"] = &ChatActionContext::lfg;
|
creators["lfg"] = &ChatActionContext::lfg;
|
||||||
creators["calc"] = &ChatActionContext::calc;
|
creators["calc"] = &ChatActionContext::calc;
|
||||||
creators["wipe"] = &ChatActionContext::wipe;
|
creators["wipe"] = &ChatActionContext::wipe;
|
||||||
|
creators["pet"] = &ChatActionContext::pet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -293,6 +295,7 @@ private:
|
|||||||
static Action* join(PlayerbotAI* ai) { return new JoinGroupAction(ai); }
|
static Action* join(PlayerbotAI* ai) { return new JoinGroupAction(ai); }
|
||||||
static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); }
|
static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); }
|
||||||
static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); }
|
static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); }
|
||||||
|
static Action* pet(PlayerbotAI* botAI) { return new PetAction(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
376
src/strategy/actions/PetAction.cpp
Normal file
376
src/strategy/actions/PetAction.cpp
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PetAction.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include "Pet.h"
|
||||||
|
#include "SpellMgr.h"
|
||||||
|
#include "DBCStructure.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "ObjectMgr.h"
|
||||||
|
#include "Player.h"
|
||||||
|
#include "PlayerbotAI.h"
|
||||||
|
#include "PlayerbotFactory.h"
|
||||||
|
#include <random>
|
||||||
|
#include <cctype>
|
||||||
|
#include "WorldSession.h"
|
||||||
|
|
||||||
|
bool IsExoticPet(const CreatureTemplate* creature)
|
||||||
|
{
|
||||||
|
// Use the IsExotic() method from CreatureTemplate
|
||||||
|
return creature && creature->IsExotic();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasBeastMastery(Player* bot)
|
||||||
|
{
|
||||||
|
// Beast Mastery talent aura ID for WotLK is 53270
|
||||||
|
return bot->HasAura(53270);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
std::string param = event.getParam();
|
||||||
|
std::istringstream iss(param);
|
||||||
|
std::string mode, value;
|
||||||
|
iss >> mode;
|
||||||
|
std::getline(iss, value);
|
||||||
|
value.erase(0, value.find_first_not_of(" ")); // trim leading spaces
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
// Reset lastPetName/Id each time
|
||||||
|
lastPetName = "";
|
||||||
|
lastPetId = 0;
|
||||||
|
|
||||||
|
if (mode == "name" && !value.empty())
|
||||||
|
{
|
||||||
|
found = SetPetByName(value);
|
||||||
|
}
|
||||||
|
else if (mode == "id" && !value.empty())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uint32 id = std::stoul(value);
|
||||||
|
found = SetPetById(id);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
botAI->TellError("Invalid pet id.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == "family" && !value.empty())
|
||||||
|
{
|
||||||
|
found = SetPetByFamily(value);
|
||||||
|
}
|
||||||
|
else if (mode == "rename" && !value.empty())
|
||||||
|
{
|
||||||
|
found = RenamePet(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
botAI->TellError("Usage: pet name <name> | pet id <id> | pet family <family> | pet rename <new name> ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// For non-rename commands, initialize pet and give feedback
|
||||||
|
if (mode != "rename")
|
||||||
|
{
|
||||||
|
Player* bot = botAI->GetBot();
|
||||||
|
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||||
|
factory.InitPet();
|
||||||
|
factory.InitPetTalents();
|
||||||
|
|
||||||
|
if (!lastPetName.empty() && lastPetId != 0)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Pet changed to " << lastPetName << ", ID: " << lastPetId << ".";
|
||||||
|
botAI->TellMaster(oss.str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
botAI->TellMaster("Pet changed and initialized!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetAction::SetPetByName(const std::string& name)
|
||||||
|
{
|
||||||
|
// Convert the input to lowercase for case-insensitive comparison
|
||||||
|
std::string lowerName = name;
|
||||||
|
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
|
||||||
|
|
||||||
|
CreatureTemplateContainer const* creatures = sObjectMgr->GetCreatureTemplates();
|
||||||
|
Player* bot = botAI->GetBot();
|
||||||
|
|
||||||
|
for (auto itr = creatures->begin(); itr != creatures->end(); ++itr)
|
||||||
|
{
|
||||||
|
const CreatureTemplate& creature = itr->second;
|
||||||
|
std::string creatureName = creature.Name;
|
||||||
|
std::transform(creatureName.begin(), creatureName.end(), creatureName.begin(), ::tolower);
|
||||||
|
|
||||||
|
// Only match if names match (case-insensitive)
|
||||||
|
if (creatureName == lowerName)
|
||||||
|
{
|
||||||
|
// Check if the pet is tameable at all
|
||||||
|
if (!creature.IsTameable(true))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Exotic pet check with talent requirement
|
||||||
|
if (IsExoticPet(&creature) && !HasBeastMastery(bot))
|
||||||
|
{
|
||||||
|
botAI->TellError("I cannot use exotic pets unless I have the Beast Mastery talent.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final tameable check based on hunter's actual ability
|
||||||
|
if (!creature.IsTameable(bot->CanTameExoticPets()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lastPetName = creature.Name;
|
||||||
|
lastPetId = creature.Entry;
|
||||||
|
return CreateAndSetPet(creature.Entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
botAI->TellError("No tameable pet found with name: " + name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetAction::SetPetById(uint32 id)
|
||||||
|
{
|
||||||
|
CreatureTemplate const* creature = sObjectMgr->GetCreatureTemplate(id);
|
||||||
|
Player* bot = botAI->GetBot();
|
||||||
|
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
// Check if the pet is tameable at all
|
||||||
|
if (!creature->IsTameable(true))
|
||||||
|
{
|
||||||
|
botAI->TellError("No tameable pet found with id: " + std::to_string(id));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exotic pet check with talent requirement
|
||||||
|
if (IsExoticPet(creature) && !HasBeastMastery(bot))
|
||||||
|
{
|
||||||
|
botAI->TellError("I cannot use exotic pets unless I have the Beast Mastery talent.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final tameable check based on hunter's actual ability
|
||||||
|
if (!creature->IsTameable(bot->CanTameExoticPets()))
|
||||||
|
{
|
||||||
|
botAI->TellError("No tameable pet found with id: " + std::to_string(id));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPetName = creature->Name;
|
||||||
|
lastPetId = creature->Entry;
|
||||||
|
return CreateAndSetPet(creature->Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
botAI->TellError("No tameable pet found with id: " + std::to_string(id));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetAction::SetPetByFamily(const std::string& family)
|
||||||
|
{
|
||||||
|
std::string lowerFamily = family;
|
||||||
|
std::transform(lowerFamily.begin(), lowerFamily.end(), lowerFamily.begin(), ::tolower);
|
||||||
|
|
||||||
|
CreatureTemplateContainer const* creatures = sObjectMgr->GetCreatureTemplates();
|
||||||
|
Player* bot = botAI->GetBot();
|
||||||
|
|
||||||
|
std::vector<const CreatureTemplate*> candidates;
|
||||||
|
bool foundExotic = false;
|
||||||
|
|
||||||
|
for (auto itr = creatures->begin(); itr != creatures->end(); ++itr)
|
||||||
|
{
|
||||||
|
const CreatureTemplate& creature = itr->second;
|
||||||
|
|
||||||
|
if (!creature.IsTameable(true)) // allow exotics for search
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CreatureFamilyEntry const* familyEntry = sCreatureFamilyStore.LookupEntry(creature.family);
|
||||||
|
if (!familyEntry)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string familyName = familyEntry->Name[0];
|
||||||
|
std::transform(familyName.begin(), familyName.end(), familyName.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (familyName != lowerFamily)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Exotic/BM check
|
||||||
|
if (IsExoticPet(&creature))
|
||||||
|
{
|
||||||
|
foundExotic = true;
|
||||||
|
if (!HasBeastMastery(bot))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!creature.IsTameable(bot->CanTameExoticPets()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
candidates.push_back(&creature);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidates.empty())
|
||||||
|
{
|
||||||
|
if (foundExotic && !HasBeastMastery(bot))
|
||||||
|
botAI->TellError("I cannot use exotic pets unless I have the Beast Mastery talent.");
|
||||||
|
else
|
||||||
|
botAI->TellError("No tameable pet found with family: " + family);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Randomly select one from candidates
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
std::uniform_int_distribution<> dis(0, candidates.size() - 1);
|
||||||
|
|
||||||
|
const CreatureTemplate* selected = candidates[dis(gen)];
|
||||||
|
|
||||||
|
lastPetName = selected->Name;
|
||||||
|
lastPetId = selected->Entry;
|
||||||
|
return CreateAndSetPet(selected->Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetAction::RenamePet(const std::string& newName)
|
||||||
|
{
|
||||||
|
Player* bot = botAI->GetBot();
|
||||||
|
Pet* pet = bot->GetPet();
|
||||||
|
if (!pet)
|
||||||
|
{
|
||||||
|
botAI->TellError("You have no pet to rename.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length check (WoW max pet name is 12 characters)
|
||||||
|
if (newName.empty() || newName.length() > 12)
|
||||||
|
{
|
||||||
|
botAI->TellError("Pet name must be between 1 and 12 alphabetic characters.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alphabetic character check
|
||||||
|
for (char c : newName)
|
||||||
|
{
|
||||||
|
if (!std::isalpha(static_cast<unsigned char>(c)))
|
||||||
|
{
|
||||||
|
botAI->TellError("Pet name must only contain alphabetic characters (A-Z, a-z).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize case: capitalize first letter, lower the rest
|
||||||
|
std::string normalized = newName;
|
||||||
|
normalized[0] = std::toupper(normalized[0]);
|
||||||
|
for (size_t i = 1; i < normalized.size(); ++i)
|
||||||
|
normalized[i] = std::tolower(normalized[i]);
|
||||||
|
|
||||||
|
// Forbidden name check
|
||||||
|
if (sObjectMgr->IsReservedName(normalized))
|
||||||
|
{
|
||||||
|
botAI->TellError("That pet name is forbidden. Please choose another name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the pet's name, save to DB, and send instant client update
|
||||||
|
pet->SetName(normalized);
|
||||||
|
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||||
|
bot->GetSession()->SendPetNameQuery(pet->GetGUID(), pet->GetEntry());
|
||||||
|
|
||||||
|
botAI->TellMaster("Your pet has been renamed to " + normalized + "!");
|
||||||
|
botAI->TellMaster("If you do not see the new name, please dismiss and recall your pet.");
|
||||||
|
|
||||||
|
// Dismiss pet
|
||||||
|
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
|
||||||
|
// Recall pet using Hunter's Call Pet spell (spellId 883)
|
||||||
|
if (bot->getClass() == CLASS_HUNTER && bot->HasSpell(883))
|
||||||
|
{
|
||||||
|
bot->CastSpell(bot, 883, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetAction::CreateAndSetPet(uint32 creatureEntry)
|
||||||
|
{
|
||||||
|
Player* bot = botAI->GetBot();
|
||||||
|
if (bot->getClass() != CLASS_HUNTER || bot->GetLevel() < 10)
|
||||||
|
{
|
||||||
|
botAI->TellError("Only level 10+ hunters can have pets.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreatureTemplate const* creature = sObjectMgr->GetCreatureTemplate(creatureEntry);
|
||||||
|
if (!creature)
|
||||||
|
{
|
||||||
|
botAI->TellError("Creature template not found.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove current pet(s)
|
||||||
|
if (bot->GetPetStable() && bot->GetPetStable()->CurrentPet)
|
||||||
|
{
|
||||||
|
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT);
|
||||||
|
bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT);
|
||||||
|
}
|
||||||
|
if (bot->GetPetStable() && bot->GetPetStable()->GetUnslottedHunterPet())
|
||||||
|
{
|
||||||
|
bot->GetPetStable()->UnslottedPets.clear();
|
||||||
|
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT);
|
||||||
|
bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually create the new pet
|
||||||
|
Pet* pet = bot->CreateTamedPetFrom(creatureEntry, 0);
|
||||||
|
if (!pet)
|
||||||
|
{
|
||||||
|
botAI->TellError("Failed to create pet.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set pet level and add to world
|
||||||
|
pet->SetUInt32Value(UNIT_FIELD_LEVEL, bot->GetLevel() - 1);
|
||||||
|
pet->GetMap()->AddToMap(pet->ToCreature());
|
||||||
|
pet->SetUInt32Value(UNIT_FIELD_LEVEL, bot->GetLevel());
|
||||||
|
bot->SetMinion(pet, true);
|
||||||
|
pet->InitTalentForLevel();
|
||||||
|
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||||
|
bot->PetSpellInitialize();
|
||||||
|
|
||||||
|
// Set stats
|
||||||
|
pet->InitStatsForLevel(bot->GetLevel());
|
||||||
|
pet->SetLevel(bot->GetLevel());
|
||||||
|
pet->SetPower(POWER_HAPPINESS, pet->GetMaxPower(Powers(POWER_HAPPINESS)));
|
||||||
|
pet->SetHealth(pet->GetMaxHealth());
|
||||||
|
|
||||||
|
// Enable autocast for active spells
|
||||||
|
for (PetSpellMap::const_iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
|
||||||
|
{
|
||||||
|
if (itr->second.state == PETSPELL_REMOVED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
|
||||||
|
if (!spellInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (spellInfo->IsPassive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pet->ToggleAutocast(spellInfo, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
34
src/strategy/actions/PetAction.h
Normal file
34
src/strategy/actions/PetAction.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLAYERBOT_PETACTION_H
|
||||||
|
#define _PLAYERBOT_PETACTION_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "PlayerbotFactory.h"
|
||||||
|
|
||||||
|
class PlayerbotAI;
|
||||||
|
|
||||||
|
class PetAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PetAction(PlayerbotAI* botAI) : Action(botAI, "pet") {}
|
||||||
|
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool SetPetByName(const std::string& name);
|
||||||
|
bool SetPetById(uint32 id);
|
||||||
|
bool SetPetByFamily(const std::string& family);
|
||||||
|
bool RenamePet(const std::string& newName);
|
||||||
|
|
||||||
|
bool CreateAndSetPet(uint32 creatureEntry);
|
||||||
|
|
||||||
|
std::string lastPetName;
|
||||||
|
uint32 lastPetId = 0;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -102,6 +102,7 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
|
|||||||
new TriggerNode("unlock traded item", NextAction::array(0, new NextAction("unlock traded item", relevance), nullptr)));
|
new TriggerNode("unlock traded item", NextAction::array(0, new NextAction("unlock traded item", relevance), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("wipe", NextAction::array(0, new NextAction("wipe", relevance), nullptr)));
|
new TriggerNode("wipe", NextAction::array(0, new NextAction("wipe", relevance), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("pet", NextAction::array(0, new NextAction("pet", relevance), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
||||||
@@ -181,4 +182,5 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas
|
|||||||
supported.push_back("qi");
|
supported.push_back("qi");
|
||||||
supported.push_back("unlock items");
|
supported.push_back("unlock items");
|
||||||
supported.push_back("unlock traded item");
|
supported.push_back("unlock traded item");
|
||||||
|
supported.push_back("pet");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ public:
|
|||||||
creators["calc"] = &ChatTriggerContext::calc;
|
creators["calc"] = &ChatTriggerContext::calc;
|
||||||
creators["qi"] = &ChatTriggerContext::qi;
|
creators["qi"] = &ChatTriggerContext::qi;
|
||||||
creators["wipe"] = &ChatTriggerContext::wipe;
|
creators["wipe"] = &ChatTriggerContext::wipe;
|
||||||
|
creators["pet"] = &ChatTriggerContext::pet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -245,6 +246,7 @@ private:
|
|||||||
static Trigger* calc(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "calc"); }
|
static Trigger* calc(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "calc"); }
|
||||||
static Trigger* qi(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "qi"); }
|
static Trigger* qi(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "qi"); }
|
||||||
static Trigger* wipe(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "wipe"); }
|
static Trigger* wipe(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "wipe"); }
|
||||||
|
static Trigger* pet(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "pet"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user