diff --git a/zone/bot.cpp b/zone/bot.cpp index 976af64cd..e2ffd9e5b 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -4142,7 +4142,7 @@ bool Bot::AddBotToGroup(Bot* bot, Group* group) { } // Completes a trade with a client bot owner -void Bot::FinishTrade(Client* client, BotTradeType trade_type) +void Bot::FinishTrade(Client* client, BotTradeType trade_type, int16 chosen_slot) { if ( !client || @@ -4166,7 +4166,7 @@ void Bot::FinishTrade(Client* client, BotTradeType trade_type) else if (trade_type == BotTradeClientNoDropNoTrade) { // Items being traded are found on the Client's cursor slot, slot id 30. This item can be either a single item or it can be a bag. // If it is a bag, then we have to search for items in slots 331 thru 340 - PerformTradeWithClient(EQ::invslot::slotCursor, EQ::invslot::slotCursor, client); + PerformTradeWithClient(EQ::invslot::slotCursor, EQ::invslot::slotCursor, client, chosen_slot); // TODO: Add logic here to test if the item in SLOT_CURSOR is a container type, if it is then we need to call the following: // PerformTradeWithClient(331, 340, client); @@ -4174,7 +4174,7 @@ void Bot::FinishTrade(Client* client, BotTradeType trade_type) } // Perfoms the actual trade action with a client bot owner -void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* client) +void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* client, int16 chosen_slot) { using namespace EQ; @@ -4194,14 +4194,16 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* ClientReturn(ItemInstance* item, int16 from) : return_item_instance(item), from_bot_slot(from) { } }; - static const int16 bot_equip_order[invslot::EQUIPMENT_COUNT] = { - invslot::slotCharm, invslot::slotEar1, invslot::slotHead, invslot::slotFace, - invslot::slotEar2, invslot::slotNeck, invslot::slotShoulders, invslot::slotArms, - invslot::slotBack, invslot::slotWrist1, invslot::slotWrist2, invslot::slotRange, - invslot::slotHands, invslot::slotPrimary, invslot::slotSecondary, invslot::slotFinger1, - invslot::slotFinger2, invslot::slotChest, invslot::slotLegs, invslot::slotFeet, - invslot::slotWaist, invslot::slotPowerSource, invslot::slotAmmo - }; + std::vector bot_equip_order; + + if (chosen_slot != INVALID_INDEX) { + bot_equip_order.emplace_back(chosen_slot); + } + else { + for (int16 i = 0; i < invslot::EQUIPMENT_COUNT; ++i) { + bot_equip_order.push_back(i); + } + } enum { stageStackable = 0, stageEmpty, stageReplaceable }; diff --git a/zone/bot.h b/zone/bot.h index bebef8d5d..cb03f4403 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -281,7 +281,7 @@ public: void SetLevel(uint8 in_level, bool command = false) override; void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) override; bool Process() override; - void FinishTrade(Client* client, BotTradeType trade_type); + void FinishTrade(Client* client, BotTradeType trade_type, int16 chosen_slot = INVALID_INDEX); bool Save() override; void Depop(); void CalcBotStats(bool showtext = true); @@ -1068,7 +1068,7 @@ protected: void BotMeditate(bool is_sitting); bool CheckBotDoubleAttack(bool triple_attack = false); bool CheckTripleAttack(); - void PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* client); + void PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* client, int16 chosen_slot = INVALID_INDEX); bool AIDoSpellCast(int32 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = nullptr) override; BotCastingRoles& GetCastingRoles() { return m_CastingRoles; } diff --git a/zone/bot_commands/inventory.cpp b/zone/bot_commands/inventory.cpp index 48e5f4879..c9b2de3f0 100644 --- a/zone/bot_commands/inventory.cpp +++ b/zone/bot_commands/inventory.cpp @@ -25,7 +25,7 @@ void bot_command_inventory_give(Client* c, const Seperator* sep) c->Message( Chat::White, fmt::format( - "Usage: {} ([actionable: target | byname] ([actionable_name]))", + "Usage: {} ([actionable: target | byname] ([actionable_name])) [optional: slot ID]", sep->arg[0] ).c_str() ); @@ -33,19 +33,45 @@ void bot_command_inventory_give(Client* c, const Seperator* sep) } int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName); + int ab_arg = 1; + int slot_arg = 1; + int16 chosen_slot = INVALID_INDEX; + bool byname = false; + + std::string byname_arg = sep->arg[ab_arg]; + + if (!byname_arg.compare("byname")) { + byname = true; + slot_arg = ab_arg + 2; + } + + if (sep->IsNumber(slot_arg)) { + chosen_slot = atoi(sep->arg[slot_arg]); + + if (!byname) { + ++ab_arg; + } + + if (!EQ::ValueWithin(chosen_slot, EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END)) { + c->Message(Chat::Yellow, "Please enter a valid inventory slot."); + + return; + } + } std::vector sbl; - if (ActionableBots::PopulateSBL(c, sep->arg[1], sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None) { + if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, sep->arg[ab_arg + 1]) == ActionableBots::ABT_None) { return; } auto my_bot = sbl.front(); if (!my_bot) { - c->Message(Chat::White, "ActionableBots returned 'nullptr'"); + c->Message(Chat::Yellow, "ActionableBots returned 'nullptr'"); + return; } - my_bot->FinishTrade(c, Bot::BotTradeClientNoDropNoTrade); + my_bot->FinishTrade(c, Bot::BotTradeClientNoDropNoTrade, chosen_slot); } void bot_command_inventory_list(Client* c, const Seperator* sep)