Maintenance command

This commit is contained in:
Yunfan Li
2024-03-04 17:13:05 +08:00
parent 6ea696d8a1
commit 3db6f05eb7
11 changed files with 58 additions and 11 deletions

View File

@@ -155,6 +155,9 @@ AiPlayerbot.AutoInitEquipLevelLimitRatio = 1.0
# default: 1 (enable) # default: 1 (enable)
AiPlayerbot.AddClassCommand = 1 AiPlayerbot.AddClassCommand = 1
# Enable/Disable maintenance command, learn all available spells and skills, supplement consumables, repair, etc.
# default: 1 (enable)
AiPlayerbot.MaintenanceCommand = 1
# Automation # Automation

View File

@@ -259,6 +259,7 @@ bool PlayerbotAIConfig::Initialize()
autoInitOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoInitOnly", false); autoInitOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoInitOnly", false);
autoInitEquipLevelLimitRatio = sConfigMgr->GetOption<float>("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0); autoInitEquipLevelLimitRatio = sConfigMgr->GetOption<float>("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0);
addClassCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.AddClassCommand", 1); addClassCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.AddClassCommand", 1);
maintenanceCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.MaintenanceCommand", 1);
playerbotsXPrate = sConfigMgr->GetOption<int32>("AiPlayerbot.KillXPRate", 1); playerbotsXPrate = sConfigMgr->GetOption<int32>("AiPlayerbot.KillXPRate", 1);
botActiveAlone = sConfigMgr->GetOption<int32>("AiPlayerbot.BotActiveAlone", 10); botActiveAlone = sConfigMgr->GetOption<int32>("AiPlayerbot.BotActiveAlone", 10);

View File

@@ -193,6 +193,7 @@ class PlayerbotAIConfig
bool autoInitOnly; bool autoInitOnly;
float autoInitEquipLevelLimitRatio; float autoInitEquipLevelLimitRatio;
int32 addClassCommand; int32 addClassCommand;
int32 maintenanceCommand;
std::string const GetTimestampStr(); std::string const GetTimestampStr();
bool hasLog(std::string const fileName) { return std::find(allowedLogFiles.begin(), allowedLogFiles.end(), fileName) != allowedLogFiles.end(); }; bool hasLog(std::string const fileName) { return std::find(allowedLogFiles.begin(), allowedLogFiles.end(), fileName) != allowedLogFiles.end(); };

View File

@@ -369,6 +369,7 @@ void PlayerbotFactory::Refresh()
InitClassSpells(); InitClassSpells();
InitAvailableSpells(); InitAvailableSpells();
InitSkills(); InitSkills();
InitMounts();
bot->DurabilityRepairAll(false, 1.0f, false); bot->DurabilityRepairAll(false, 1.0f, false);
if (bot->isDead()) if (bot->isDead())
bot->ResurrectPlayer(1.0f, false); bot->ResurrectPlayer(1.0f, false);
@@ -1628,7 +1629,7 @@ inline Item* StoreNewItemInInventorySlot(Player* player, uint32 newItemId, uint3
// } // }
// } // }
void PlayerbotFactory::InitBags() void PlayerbotFactory::InitBags(bool destroyOld)
{ {
for (uint8 slot = INVENTORY_SLOT_BAG_START; slot < INVENTORY_SLOT_BAG_END; ++slot) for (uint8 slot = INVENTORY_SLOT_BAG_START; slot < INVENTORY_SLOT_BAG_END; ++slot)
{ {
@@ -1641,9 +1642,12 @@ void PlayerbotFactory::InitBags()
if (!CanEquipUnseenItem(slot, dest, newItemId)) if (!CanEquipUnseenItem(slot, dest, newItemId))
continue; continue;
if (old_bag) { if (old_bag && destroyOld) {
bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true); bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
} }
if (old_bag) {
return;
}
Item* newItem = bot->EquipNewItem(dest, newItemId, true); Item* newItem = bot->EquipNewItem(dest, newItemId, true);
if (newItem) if (newItem)
{ {
@@ -2435,7 +2439,7 @@ void PlayerbotFactory::InitAmmo()
uint32 entry = sRandomItemMgr->GetAmmo(level, subClass); uint32 entry = sRandomItemMgr->GetAmmo(level, subClass);
uint32 count = bot->GetItemCount(entry); uint32 count = bot->GetItemCount(entry);
uint32 maxCount = 10000; uint32 maxCount = 5000;
if (count < maxCount / 2) if (count < maxCount / 2)
{ {
@@ -2726,7 +2730,9 @@ void PlayerbotFactory::InitReagents()
break; break;
} }
for (std::pair item : items) { for (std::pair item : items) {
StoreItem(item.first, item.second); int count = (int)item.second - (int)bot->GetItemCount(item.first);
if (count > 0)
StoreItem(item.first, count);
} }
} }
@@ -3233,6 +3239,7 @@ void PlayerbotFactory::ApplyEnchantTemplate(uint8 spec)
bot->ApplyEnchantment(pItem, PERM_ENCHANTMENT_SLOT, true); bot->ApplyEnchantment(pItem, PERM_ENCHANTMENT_SLOT, true);
} }
// botAI->EnchantItemT((*itr).SpellId, (*itr).SlotId); // botAI->EnchantItemT((*itr).SpellId, (*itr).SlotId);
// const SpellItemEnchantmentEntry* a = sSpellItemEnchantmentStore.LookupEntry(1);
} }
std::vector<InventoryType> PlayerbotFactory::GetPossibleInventoryTypeListBySlot(EquipmentSlots slot) { std::vector<InventoryType> PlayerbotFactory::GetPossibleInventoryTypeListBySlot(EquipmentSlots slot) {

View File

@@ -126,6 +126,12 @@ class PlayerbotFactory
void InitAmmo(); void InitAmmo();
static uint32 CalcMixedGearScore(uint32 gs, uint32 quality); static uint32 CalcMixedGearScore(uint32 gs, uint32 quality);
void InitPetTalents(); void InitPetTalents();
void InitReagents();
void InitGlyphs();
void InitFood();
void InitMounts();
void InitBags(bool destroyOld = true);
private: private:
void Prepare(); void Prepare();
// void InitSecondEquipmentSet(); // void InitSecondEquipmentSet();
@@ -146,11 +152,8 @@ class PlayerbotFactory
void ClearInventory(); void ClearInventory();
void ClearAllItems(); void ClearAllItems();
void ResetQuests(); void ResetQuests();
void InitMounts();
void InitPotions(); void InitPotions();
void InitFood();
void InitReagents();
void InitGlyphs();
bool CanEquipArmor(ItemTemplate const* proto); bool CanEquipArmor(ItemTemplate const* proto);
bool CanEquipWeapon(ItemTemplate const* proto); bool CanEquipWeapon(ItemTemplate const* proto);
void EnchantItem(Item* item); void EnchantItem(Item* item);
@@ -158,7 +161,6 @@ class PlayerbotFactory
bool CheckItemStats(uint8 sp, uint8 ap, uint8 tank); bool CheckItemStats(uint8 sp, uint8 ap, uint8 tank);
void CancelAuras(); void CancelAuras();
bool IsDesiredReplacement(Item* item); bool IsDesiredReplacement(Item* item);
void InitBags();
void InitInventory(); void InitInventory();
void InitInventoryTrade(); void InitInventoryTrade();
void InitInventoryEquip(); void InitInventoryEquip();

View File

@@ -114,6 +114,7 @@ class ChatActionContext : public NamedObjectContext<Action>
creators["nc"] = &ChatActionContext::nc; creators["nc"] = &ChatActionContext::nc;
creators["de"] = &ChatActionContext::dead; creators["de"] = &ChatActionContext::dead;
creators["trainer"] = &ChatActionContext::trainer; creators["trainer"] = &ChatActionContext::trainer;
creators["maintenance"] = &ChatActionContext::maintenance;
creators["attack my target"] = &ChatActionContext::attack_my_target; creators["attack my target"] = &ChatActionContext::attack_my_target;
creators["chat"] = &ChatActionContext::chat; creators["chat"] = &ChatActionContext::chat;
creators["home"] = &ChatActionContext::home; creators["home"] = &ChatActionContext::home;
@@ -211,6 +212,7 @@ class ChatActionContext : public NamedObjectContext<Action>
static Action* chat(PlayerbotAI* botAI) { return new ChangeChatAction(botAI); } static Action* chat(PlayerbotAI* botAI) { return new ChangeChatAction(botAI); }
static Action* attack_my_target(PlayerbotAI* botAI) { return new AttackMyTargetAction(botAI); } static Action* attack_my_target(PlayerbotAI* botAI) { return new AttackMyTargetAction(botAI); }
static Action* trainer(PlayerbotAI* botAI) { return new TrainerAction(botAI); } static Action* trainer(PlayerbotAI* botAI) { return new TrainerAction(botAI); }
static Action* maintenance(PlayerbotAI* botAI) { return new MaintenanceAction(botAI); }
static Action* co(PlayerbotAI* botAI) { return new ChangeCombatStrategyAction(botAI); } static Action* co(PlayerbotAI* botAI) { return new ChangeCombatStrategyAction(botAI); }
static Action* nc(PlayerbotAI* botAI) { return new ChangeNonCombatStrategyAction(botAI); } static Action* nc(PlayerbotAI* botAI) { return new ChangeNonCombatStrategyAction(botAI); }
static Action* dead(PlayerbotAI* botAI) { return new ChangeDeadStrategyAction(botAI); } static Action* dead(PlayerbotAI* botAI) { return new ChangeDeadStrategyAction(botAI); }

View File

@@ -5,6 +5,7 @@
#include "TrainerAction.h" #include "TrainerAction.h"
#include "BudgetValues.h" #include "BudgetValues.h"
#include "Event.h" #include "Event.h"
#include "PlayerbotFactory.h"
#include "Playerbots.h" #include "Playerbots.h"
void TrainerAction::Learn(uint32 cost, TrainerSpell const* tSpell, std::ostringstream& msg) void TrainerAction::Learn(uint32 cost, TrainerSpell const* tSpell, std::ostringstream& msg)
@@ -146,3 +147,24 @@ void TrainerAction::TellFooter(uint32 totalCost)
botAI->TellMaster(out); botAI->TellMaster(out);
} }
} }
bool MaintenanceAction::Execute(Event event)
{
if (!sPlayerbotAIConfig->maintenanceCommand)
return false;
botAI->TellMaster("maintenance");
PlayerbotFactory factory(bot, bot->GetLevel());
factory.InitBags(false);
factory.InitAmmo();
factory.InitFood();
factory.InitReagents();
factory.InitTalentsTree(true);
factory.InitPet();
factory.InitPetTalents();
factory.InitClassSpells();
factory.InitAvailableSpells();
factory.InitSkills();
factory.InitMounts();
bot->DurabilityRepairAll(false, 1.0f, false);
return true;
}

View File

@@ -28,4 +28,10 @@ class TrainerAction : public Action
void TellFooter(uint32 totalCost); void TellFooter(uint32 totalCost);
}; };
class MaintenanceAction : public Action
{
public:
MaintenanceAction(PlayerbotAI* botAI) : Action(botAI, "maintenance") { }
bool Execute(Event event) override;
};
#endif #endif

View File

@@ -88,6 +88,7 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas
supported.push_back("nc"); supported.push_back("nc");
supported.push_back("de"); supported.push_back("de");
supported.push_back("trainer"); supported.push_back("trainer");
supported.push_back("maintenance");
supported.push_back("chat"); supported.push_back("chat");
supported.push_back("home"); supported.push_back("home");
supported.push_back("destroy"); supported.push_back("destroy");

View File

@@ -11,8 +11,8 @@ bool SealTrigger::IsActive()
{ {
Unit* target = GetTarget(); Unit* target = GetTarget();
return !botAI->HasAura("seal of justice", target) && !botAI->HasAura("seal of command", target) && !botAI->HasAura("seal of vengeance", target) && return !botAI->HasAura("seal of justice", target) && !botAI->HasAura("seal of command", target) && !botAI->HasAura("seal of vengeance", target) &&
!botAI->HasAura("seal of corruption", target) && !botAI->HasAura("seal of righteousness", target) && !botAI->HasAura("seal of light", target) && (!botAI->HasAura("seal of wisdom", target) || AI_VALUE2(uint8, "mana", "self target") > 70) && !botAI->HasAura("seal of corruption", target) && !botAI->HasAura("seal of righteousness", target) && !botAI->HasAura("seal of light", target) &&
AI_VALUE2(bool, "combat", "self target"); (!botAI->HasAura("seal of wisdom", target) || AI_VALUE2(uint8, "mana", "self target") > 70);
} }
bool CrusaderAuraTrigger::IsActive() bool CrusaderAuraTrigger::IsActive()

View File

@@ -54,6 +54,7 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
creators["nc"] = &ChatTriggerContext::nc; creators["nc"] = &ChatTriggerContext::nc;
creators["de"] = &ChatTriggerContext::dead; creators["de"] = &ChatTriggerContext::dead;
creators["trainer"] = &ChatTriggerContext::trainer; creators["trainer"] = &ChatTriggerContext::trainer;
creators["maintenance"] = &ChatTriggerContext::maintenance;
creators["attack"] = &ChatTriggerContext::attack; creators["attack"] = &ChatTriggerContext::attack;
creators["chat"] = &ChatTriggerContext::chat; creators["chat"] = &ChatTriggerContext::chat;
creators["accept"] = &ChatTriggerContext::accept; creators["accept"] = &ChatTriggerContext::accept;
@@ -164,6 +165,7 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
static Trigger* chat(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "chat"); } static Trigger* chat(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "chat"); }
static Trigger* attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "attack"); } static Trigger* attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "attack"); }
static Trigger* trainer(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "trainer"); } static Trigger* trainer(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "trainer"); }
static Trigger* maintenance(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "maintenance"); }
static Trigger* co(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "co"); } static Trigger* co(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "co"); }
static Trigger* nc(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "nc"); } static Trigger* nc(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "nc"); }
static Trigger* dead(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "de"); } static Trigger* dead(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "de"); }