From 3db6f05eb77e1113fab12f4d8dbcca9d816b06dd Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Mon, 4 Mar 2024 17:13:05 +0800 Subject: [PATCH] Maintenance command --- conf/playerbots.conf.dist | 3 +++ src/PlayerbotAIConfig.cpp | 1 + src/PlayerbotAIConfig.h | 1 + src/PlayerbotFactory.cpp | 15 +++++++++---- src/PlayerbotFactory.h | 12 +++++----- src/strategy/actions/ChatActionContext.h | 2 ++ src/strategy/actions/TrainerAction.cpp | 22 +++++++++++++++++++ src/strategy/actions/TrainerAction.h | 6 +++++ .../generic/ChatCommandHandlerStrategy.cpp | 1 + src/strategy/paladin/PaladinTriggers.cpp | 4 ++-- src/strategy/triggers/ChatTriggerContext.h | 2 ++ 11 files changed, 58 insertions(+), 11 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index e075affe..e3cc07a8 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -155,6 +155,9 @@ AiPlayerbot.AutoInitEquipLevelLimitRatio = 1.0 # default: 1 (enable) AiPlayerbot.AddClassCommand = 1 +# Enable/Disable maintenance command, learn all available spells and skills, supplement consumables, repair, etc. +# default: 1 (enable) +AiPlayerbot.MaintenanceCommand = 1 # Automation diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 5f940fe8..e3b0f2bd 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -259,6 +259,7 @@ bool PlayerbotAIConfig::Initialize() autoInitOnly = sConfigMgr->GetOption("AiPlayerbot.AutoInitOnly", false); autoInitEquipLevelLimitRatio = sConfigMgr->GetOption("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0); addClassCommand = sConfigMgr->GetOption("AiPlayerbot.AddClassCommand", 1); + maintenanceCommand = sConfigMgr->GetOption("AiPlayerbot.MaintenanceCommand", 1); playerbotsXPrate = sConfigMgr->GetOption("AiPlayerbot.KillXPRate", 1); botActiveAlone = sConfigMgr->GetOption("AiPlayerbot.BotActiveAlone", 10); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 3a3982f6..2dc450d7 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -193,6 +193,7 @@ class PlayerbotAIConfig bool autoInitOnly; float autoInitEquipLevelLimitRatio; int32 addClassCommand; + int32 maintenanceCommand; std::string const GetTimestampStr(); bool hasLog(std::string const fileName) { return std::find(allowedLogFiles.begin(), allowedLogFiles.end(), fileName) != allowedLogFiles.end(); }; diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 0e907336..d719358a 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -369,6 +369,7 @@ void PlayerbotFactory::Refresh() InitClassSpells(); InitAvailableSpells(); InitSkills(); + InitMounts(); bot->DurabilityRepairAll(false, 1.0f, false); if (bot->isDead()) 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) { @@ -1641,9 +1642,12 @@ void PlayerbotFactory::InitBags() if (!CanEquipUnseenItem(slot, dest, newItemId)) continue; - if (old_bag) { + if (old_bag && destroyOld) { bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true); } + if (old_bag) { + return; + } Item* newItem = bot->EquipNewItem(dest, newItemId, true); if (newItem) { @@ -2435,7 +2439,7 @@ void PlayerbotFactory::InitAmmo() uint32 entry = sRandomItemMgr->GetAmmo(level, subClass); uint32 count = bot->GetItemCount(entry); - uint32 maxCount = 10000; + uint32 maxCount = 5000; if (count < maxCount / 2) { @@ -2726,7 +2730,9 @@ void PlayerbotFactory::InitReagents() break; } 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); } // botAI->EnchantItemT((*itr).SpellId, (*itr).SlotId); + // const SpellItemEnchantmentEntry* a = sSpellItemEnchantmentStore.LookupEntry(1); } std::vector PlayerbotFactory::GetPossibleInventoryTypeListBySlot(EquipmentSlots slot) { diff --git a/src/PlayerbotFactory.h b/src/PlayerbotFactory.h index b654dcd2..d3b1bb71 100644 --- a/src/PlayerbotFactory.h +++ b/src/PlayerbotFactory.h @@ -126,6 +126,12 @@ class PlayerbotFactory void InitAmmo(); static uint32 CalcMixedGearScore(uint32 gs, uint32 quality); void InitPetTalents(); + + void InitReagents(); + void InitGlyphs(); + void InitFood(); + void InitMounts(); + void InitBags(bool destroyOld = true); private: void Prepare(); // void InitSecondEquipmentSet(); @@ -146,11 +152,8 @@ class PlayerbotFactory void ClearInventory(); void ClearAllItems(); void ResetQuests(); - void InitMounts(); void InitPotions(); - void InitFood(); - void InitReagents(); - void InitGlyphs(); + bool CanEquipArmor(ItemTemplate const* proto); bool CanEquipWeapon(ItemTemplate const* proto); void EnchantItem(Item* item); @@ -158,7 +161,6 @@ class PlayerbotFactory bool CheckItemStats(uint8 sp, uint8 ap, uint8 tank); void CancelAuras(); bool IsDesiredReplacement(Item* item); - void InitBags(); void InitInventory(); void InitInventoryTrade(); void InitInventoryEquip(); diff --git a/src/strategy/actions/ChatActionContext.h b/src/strategy/actions/ChatActionContext.h index a2faa178..cec70a7e 100644 --- a/src/strategy/actions/ChatActionContext.h +++ b/src/strategy/actions/ChatActionContext.h @@ -114,6 +114,7 @@ class ChatActionContext : public NamedObjectContext creators["nc"] = &ChatActionContext::nc; creators["de"] = &ChatActionContext::dead; creators["trainer"] = &ChatActionContext::trainer; + creators["maintenance"] = &ChatActionContext::maintenance; creators["attack my target"] = &ChatActionContext::attack_my_target; creators["chat"] = &ChatActionContext::chat; creators["home"] = &ChatActionContext::home; @@ -211,6 +212,7 @@ class ChatActionContext : public NamedObjectContext static Action* chat(PlayerbotAI* botAI) { return new ChangeChatAction(botAI); } static Action* attack_my_target(PlayerbotAI* botAI) { return new AttackMyTargetAction(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* nc(PlayerbotAI* botAI) { return new ChangeNonCombatStrategyAction(botAI); } static Action* dead(PlayerbotAI* botAI) { return new ChangeDeadStrategyAction(botAI); } diff --git a/src/strategy/actions/TrainerAction.cpp b/src/strategy/actions/TrainerAction.cpp index e77d5d39..f5c88617 100644 --- a/src/strategy/actions/TrainerAction.cpp +++ b/src/strategy/actions/TrainerAction.cpp @@ -5,6 +5,7 @@ #include "TrainerAction.h" #include "BudgetValues.h" #include "Event.h" +#include "PlayerbotFactory.h" #include "Playerbots.h" void TrainerAction::Learn(uint32 cost, TrainerSpell const* tSpell, std::ostringstream& msg) @@ -146,3 +147,24 @@ void TrainerAction::TellFooter(uint32 totalCost) 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; +} \ No newline at end of file diff --git a/src/strategy/actions/TrainerAction.h b/src/strategy/actions/TrainerAction.h index 6aa87766..079c2f52 100644 --- a/src/strategy/actions/TrainerAction.h +++ b/src/strategy/actions/TrainerAction.h @@ -28,4 +28,10 @@ class TrainerAction : public Action void TellFooter(uint32 totalCost); }; +class MaintenanceAction : public Action +{ + public: + MaintenanceAction(PlayerbotAI* botAI) : Action(botAI, "maintenance") { } + bool Execute(Event event) override; +}; #endif diff --git a/src/strategy/generic/ChatCommandHandlerStrategy.cpp b/src/strategy/generic/ChatCommandHandlerStrategy.cpp index d35ad0c8..0a838231 100644 --- a/src/strategy/generic/ChatCommandHandlerStrategy.cpp +++ b/src/strategy/generic/ChatCommandHandlerStrategy.cpp @@ -88,6 +88,7 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas supported.push_back("nc"); supported.push_back("de"); supported.push_back("trainer"); + supported.push_back("maintenance"); supported.push_back("chat"); supported.push_back("home"); supported.push_back("destroy"); diff --git a/src/strategy/paladin/PaladinTriggers.cpp b/src/strategy/paladin/PaladinTriggers.cpp index 79c0e730..1a7f1faf 100644 --- a/src/strategy/paladin/PaladinTriggers.cpp +++ b/src/strategy/paladin/PaladinTriggers.cpp @@ -11,8 +11,8 @@ bool SealTrigger::IsActive() { Unit* target = GetTarget(); 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) && - AI_VALUE2(bool, "combat", "self 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); } bool CrusaderAuraTrigger::IsActive() diff --git a/src/strategy/triggers/ChatTriggerContext.h b/src/strategy/triggers/ChatTriggerContext.h index 830eb983..61cc9793 100644 --- a/src/strategy/triggers/ChatTriggerContext.h +++ b/src/strategy/triggers/ChatTriggerContext.h @@ -54,6 +54,7 @@ class ChatTriggerContext : public NamedObjectContext creators["nc"] = &ChatTriggerContext::nc; creators["de"] = &ChatTriggerContext::dead; creators["trainer"] = &ChatTriggerContext::trainer; + creators["maintenance"] = &ChatTriggerContext::maintenance; creators["attack"] = &ChatTriggerContext::attack; creators["chat"] = &ChatTriggerContext::chat; creators["accept"] = &ChatTriggerContext::accept; @@ -164,6 +165,7 @@ class ChatTriggerContext : public NamedObjectContext static Trigger* chat(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "chat"); } static Trigger* attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "attack"); } 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* nc(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "nc"); } static Trigger* dead(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "de"); }