mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Bot] Add EVENT_TRADE Support to Bots. (#2560)
* [Bot] Add EVENT_TRADE Support to Bots. * Fixed issue with duplicate items after Event Trade * Update logic * Add CalcBotStats call after Bot Trade Event * Fix Lua EVENT_TRADE. * Formatting. * More formatting. Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
This commit is contained in:
parent
45c4fe55f0
commit
99052aec8b
123
zone/bot.cpp
123
zone/bot.cpp
@ -4571,11 +4571,11 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
using namespace EQ;
|
||||
|
||||
struct ClientTrade {
|
||||
const ItemInstance* trade_item_instance;
|
||||
ItemInstance* trade_item_instance;
|
||||
int16 from_client_slot;
|
||||
int16 to_bot_slot;
|
||||
|
||||
ClientTrade(const ItemInstance* item, int16 from) : trade_item_instance(item), from_client_slot(from), to_bot_slot(invslot::SLOT_INVALID) { }
|
||||
ClientTrade(ItemInstance* item, int16 from) : trade_item_instance(item), from_client_slot(from), to_bot_slot(invslot::SLOT_INVALID) { }
|
||||
};
|
||||
|
||||
struct ClientReturn {
|
||||
@ -4639,11 +4639,19 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
}
|
||||
|
||||
std::list<ClientTrade> client_trade;
|
||||
std::list<ClientTrade> event_trade;
|
||||
std::list<ClientReturn> client_return;
|
||||
|
||||
bool trade_event_exists = false;
|
||||
if (parse->BotHasQuestSub(EVENT_TRADE)) {
|
||||
// There is a EVENT_TRADE, we will let the Event handle returning of items.
|
||||
trade_event_exists = true;
|
||||
}
|
||||
|
||||
// pre-checks for incoming illegal transfers
|
||||
EQ::InventoryProfile& user_inv = client->GetInv();
|
||||
for (int16 trade_index = begin_slot_id; trade_index <= end_slot_id; ++trade_index) {
|
||||
auto trade_instance = client->GetInv()[trade_index];
|
||||
auto trade_instance = user_inv.GetItem(trade_index);
|
||||
if (!trade_instance) {
|
||||
continue;
|
||||
}
|
||||
@ -4675,37 +4683,61 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
}
|
||||
|
||||
if (trade_instance->IsStackable() && trade_instance->GetCharges() < trade_instance->GetItem()->StackSize) { // temp until partial stacks are implemented
|
||||
client->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"{} is only a partially stacked item, the trade has been cancelled!",
|
||||
item_link
|
||||
).c_str()
|
||||
);
|
||||
client->ResetTrade();
|
||||
return;
|
||||
if (trade_event_exists) {
|
||||
event_trade.push_back(ClientTrade(trade_instance, trade_index));
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
client->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"{} is only a partially stacked item, the trade has been cancelled!",
|
||||
item_link
|
||||
).c_str()
|
||||
);
|
||||
client->ResetTrade();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckLoreConflict(trade_instance->GetItem())) {
|
||||
client->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"This bot already has {}, the trade has been cancelled!",
|
||||
item_link
|
||||
).c_str()
|
||||
);
|
||||
client->ResetTrade();
|
||||
return;
|
||||
if (trade_event_exists) {
|
||||
event_trade.push_back(ClientTrade(trade_instance, trade_index));
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
client->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"This bot already has {}, the trade has been cancelled!",
|
||||
item_link
|
||||
).c_str()
|
||||
);
|
||||
client->ResetTrade();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!trade_instance->IsType(item::ItemClassCommon)) {
|
||||
client_return.push_back(ClientReturn(trade_instance, trade_index));
|
||||
continue;
|
||||
if (trade_event_exists) {
|
||||
event_trade.push_back(ClientTrade(trade_instance, trade_index));
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
client->ResetTrade();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!trade_instance->IsEquipable(GetBaseRace(), GetClass()) || (GetLevel() < trade_instance->GetItem()->ReqLevel)) { // deity checks will be handled within IsEquipable()
|
||||
client_return.push_back(ClientReturn(trade_instance, trade_index));
|
||||
continue;
|
||||
if (trade_event_exists) {
|
||||
event_trade.push_back(ClientTrade(trade_instance, trade_index));
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
client->ResetTrade();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
client_trade.push_back(ClientTrade(trade_instance, trade_index));
|
||||
@ -4713,7 +4745,9 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
|
||||
// check for incoming lore hacks
|
||||
for (auto& trade_iterator : client_trade) {
|
||||
if (!trade_iterator.trade_item_instance->GetItem()->LoreFlag) {
|
||||
auto trade_instance = trade_iterator.trade_item_instance;
|
||||
auto trade_index = trade_iterator.from_client_slot;
|
||||
if (!trade_instance->GetItem()->LoreFlag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4726,14 +4760,14 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trade_iterator.trade_item_instance->GetItem()->LoreGroup == -1 && check_iterator.trade_item_instance->GetItem()->ID == trade_iterator.trade_item_instance->GetItem()->ID) {
|
||||
if (trade_instance->GetItem()->LoreGroup == -1 && check_iterator.trade_item_instance->GetItem()->ID == trade_instance->GetItem()->ID) {
|
||||
LogError("Bot::PerformTradeWithClient trade hack detected by {} with {}.", client->GetCleanName(), GetCleanName());
|
||||
client->Message(Chat::White, "Trade hack detected, the trade has been cancelled.");
|
||||
client->ResetTrade();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((trade_iterator.trade_item_instance->GetItem()->LoreGroup > 0) && (check_iterator.trade_item_instance->GetItem()->LoreGroup == trade_iterator.trade_item_instance->GetItem()->LoreGroup)) {
|
||||
if ((trade_instance->GetItem()->LoreGroup > 0) && (check_iterator.trade_item_instance->GetItem()->LoreGroup == trade_instance->GetItem()->LoreGroup)) {
|
||||
LogError("Bot::PerformTradeWithClient trade hack detected by {} with {}.", client->GetCleanName(), GetCleanName());
|
||||
client->Message(Chat::White, "Trade hack detected, the trade has been cancelled.");
|
||||
client->ResetTrade();
|
||||
@ -4833,12 +4867,19 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
}
|
||||
}
|
||||
|
||||
// move unassignable items from trade list to return list
|
||||
// move unassignable items from trade list to event list
|
||||
for (std::list<ClientTrade>::iterator trade_iterator = client_trade.begin(); trade_iterator != client_trade.end();) {
|
||||
if (trade_iterator->to_bot_slot == invslot::SLOT_INVALID) {
|
||||
client_return.push_back(ClientReturn(trade_iterator->trade_item_instance, trade_iterator->from_client_slot));
|
||||
trade_iterator = client_trade.erase(trade_iterator);
|
||||
continue;
|
||||
if (trade_event_exists) {
|
||||
event_trade.push_back(ClientTrade(trade_iterator->trade_item_instance, trade_iterator->from_client_slot));
|
||||
trade_iterator = client_trade.erase(trade_iterator);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
client_return.push_back(ClientReturn(trade_iterator->trade_item_instance, trade_iterator->from_client_slot));
|
||||
trade_iterator = client_trade.erase(trade_iterator);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++trade_iterator;
|
||||
}
|
||||
@ -5035,6 +5076,24 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
if (accepted_count) {
|
||||
CalcBotStats(client->GetBotOption(Client::booStatsUpdate));
|
||||
}
|
||||
|
||||
if (event_trade.size()) {
|
||||
// Get Traded Items
|
||||
EQ::ItemInstance* insts[8] = { 0 };
|
||||
EQ::InventoryProfile& user_inv = client->GetInv();
|
||||
for (int i = EQ::invslot::TRADE_BEGIN; i <= EQ::invslot::TRADE_END; ++i) {
|
||||
insts[i - EQ::invslot::TRADE_BEGIN] = user_inv.GetItem(i);
|
||||
client->DeleteItemInInventory(i);
|
||||
}
|
||||
|
||||
// copy to be filtered by task updates, null trade slots preserved for quest event arg
|
||||
std::vector<EQ::ItemInstance*> items(insts, insts + std::size(insts));
|
||||
|
||||
// Check if EVENT_TRADE accepts any items
|
||||
std::vector<std::any> item_list(items.begin(), items.end());
|
||||
parse->EventBot(EVENT_TRADE, this, client, "", 0, &item_list);
|
||||
CalcBotStats(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) {
|
||||
|
||||
@ -1116,12 +1116,12 @@ void PerlembParser::GetQuestTypes(
|
||||
if (
|
||||
event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
event == EVENT_SPELL_EFFECT_NPC ||
|
||||
#ifdef BOTS
|
||||
#ifdef BOTS
|
||||
event == EVENT_SPELL_EFFECT_BOT ||
|
||||
#endif
|
||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT ||
|
||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_NPC ||
|
||||
#ifdef BOTS
|
||||
#ifdef BOTS
|
||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_BOT ||
|
||||
#endif
|
||||
event == EVENT_SPELL_FADE ||
|
||||
@ -1241,7 +1241,7 @@ void PerlembParser::ExportQGlobals(
|
||||
if (
|
||||
!isPlayerQuest &&
|
||||
!isGlobalPlayerQuest &&
|
||||
!isBotQuest &&
|
||||
!isBotQuest &&
|
||||
!isGlobalBotQuest &&
|
||||
!isItemQuest &&
|
||||
!isSpellQuest
|
||||
@ -1427,7 +1427,7 @@ void PerlembParser::ExportMobVariables(
|
||||
if (
|
||||
!isPlayerQuest &&
|
||||
!isGlobalPlayerQuest &&
|
||||
!isBotQuest &&
|
||||
!isBotQuest &&
|
||||
!isGlobalBotQuest &&
|
||||
!isItemQuest &&
|
||||
!isSpellQuest
|
||||
@ -1525,56 +1525,55 @@ void PerlembParser::ExportEventVariables(
|
||||
|
||||
case EVENT_TRADE: {
|
||||
if (extra_pointers) {
|
||||
size_t sz = extra_pointers->size();
|
||||
size_t sz = extra_pointers->size();
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
EQ::ItemInstance *inst = std::any_cast<EQ::ItemInstance *>(extra_pointers->at(i));
|
||||
auto* inst = std::any_cast<EQ::ItemInstance *>(extra_pointers->at(i));
|
||||
const uint32 item_id = inst ? inst->GetItem()->ID : 0;
|
||||
const int16 item_charges = inst ? inst->GetCharges() : 0;
|
||||
const auto is_attuned = inst ? inst->IsAttuned() : false;
|
||||
|
||||
std::string var_name = "item";
|
||||
var_name += std::to_string(i + 1);
|
||||
auto var_name = fmt::format("item{}", i + 1);
|
||||
ExportVar(package_name.c_str(), var_name.c_str(), item_id);
|
||||
|
||||
auto temp_var_name = fmt::format("{}_charges", var_name);
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), item_charges);
|
||||
|
||||
temp_var_name = fmt::format("{}_attuned", var_name);
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), is_attuned);
|
||||
|
||||
temp_var_name = fmt::format("{}_inst", var_name);
|
||||
if (inst) {
|
||||
ExportVar(package_name.c_str(), var_name.c_str(), inst->GetItem()->ID);
|
||||
|
||||
std::string temp_var_name = var_name;
|
||||
temp_var_name += "_charges";
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), inst->GetCharges());
|
||||
|
||||
temp_var_name = var_name;
|
||||
temp_var_name += "_attuned";
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), inst->IsAttuned());
|
||||
|
||||
temp_var_name = var_name;
|
||||
temp_var_name += "_inst";
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), "QuestItem", inst);
|
||||
}
|
||||
else {
|
||||
ExportVar(package_name.c_str(), var_name.c_str(), 0);
|
||||
|
||||
std::string temp_var_name = var_name;
|
||||
temp_var_name += "_charges";
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), 0);
|
||||
|
||||
temp_var_name = var_name;
|
||||
temp_var_name += "_attuned";
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), 0);
|
||||
|
||||
temp_var_name = var_name;
|
||||
temp_var_name += "_inst";
|
||||
} else {
|
||||
ExportVar(package_name.c_str(), temp_var_name.c_str(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExportVar(package_name.c_str(), "copper", GetVar("copper." + std::string(itoa(objid))).c_str());
|
||||
ExportVar(package_name.c_str(), "silver", GetVar("silver." + std::string(itoa(objid))).c_str());
|
||||
ExportVar(package_name.c_str(), "gold", GetVar("gold." + std::string(itoa(objid))).c_str());
|
||||
ExportVar(package_name.c_str(), "platinum", GetVar("platinum." + std::string(itoa(objid))).c_str());
|
||||
std::string hashname = package_name + std::string("::itemcount");
|
||||
perl->eval(std::string("%").append(hashname).append(" = ();").c_str());
|
||||
perl->eval(std::string("++$").append(hashname).append("{$").append(package_name).append("::item1};").c_str());
|
||||
perl->eval(std::string("++$").append(hashname).append("{$").append(package_name).append("::item2};").c_str());
|
||||
perl->eval(std::string("++$").append(hashname).append("{$").append(package_name).append("::item3};").c_str());
|
||||
perl->eval(std::string("++$").append(hashname).append("{$").append(package_name).append("::item4};").c_str());
|
||||
auto unique_id = npcmob->GetNPCTypeID();
|
||||
if (npcmob->IsBot()) {
|
||||
unique_id = npcmob->CastToBot()->GetBotID();
|
||||
}
|
||||
|
||||
ExportVar(package_name.c_str(), "copper", GetVar(fmt::format("copper.{}", unique_id)).c_str());
|
||||
ExportVar(package_name.c_str(), "silver", GetVar(fmt::format("silver.{}", unique_id)).c_str());
|
||||
ExportVar(package_name.c_str(), "gold", GetVar(fmt::format("gold.{}", unique_id)).c_str());
|
||||
ExportVar(package_name.c_str(), "platinum", GetVar(fmt::format("platinum.{}", unique_id)).c_str());
|
||||
|
||||
auto hash_name = fmt::format("{}::itemcount", package_name);
|
||||
perl->eval(fmt::format("%{} = ();", hash_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item1}};", hash_name, package_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item2}};", hash_name, package_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item3}};", hash_name, package_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item4}};", hash_name, package_name).c_str());
|
||||
|
||||
if (npcmob->IsBot()) {
|
||||
perl->eval(fmt::format("++${}{{${}::item5}};", hash_name, package_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item6}};", hash_name, package_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item7}};", hash_name, package_name).c_str());
|
||||
perl->eval(fmt::format("++${}{{${}::item8}};", hash_name, package_name).c_str());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1744,7 +1743,7 @@ void PerlembParser::ExportEventVariables(
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BOTS
|
||||
case EVENT_SPELL_EFFECT_BUFF_TIC_BOT:
|
||||
#endif
|
||||
|
||||
@ -294,6 +294,7 @@ LuaParser::LuaParser() {
|
||||
BotArgumentDispatch[EVENT_SLAY] = handle_bot_slay;
|
||||
BotArgumentDispatch[EVENT_TARGET_CHANGE] = handle_bot_target_change;
|
||||
BotArgumentDispatch[EVENT_TIMER] = handle_bot_timer;
|
||||
BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade;
|
||||
BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill;
|
||||
#endif
|
||||
|
||||
|
||||
@ -49,16 +49,15 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
std::stringstream ident;
|
||||
ident << npc->GetNPCTypeID();
|
||||
|
||||
if(extra_pointers) {
|
||||
const auto npc_id = npc->GetNPCTypeID();
|
||||
|
||||
if (extra_pointers) {
|
||||
size_t sz = extra_pointers->size();
|
||||
for(size_t i = 0; i < sz; ++i) {
|
||||
std::string prefix = "item" + std::to_string(i + 1);
|
||||
EQ::ItemInstance *inst = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(i));
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
auto prefix = fmt::format("item{}", i + 1);
|
||||
auto* inst = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(i));
|
||||
|
||||
Lua_ItemInst l_inst = inst;
|
||||
luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst);
|
||||
@ -68,17 +67,30 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushinteger(L, std::stoul(parse->GetVar("platinum." + ident.str())));
|
||||
auto money_string = fmt::format("platinum.{}", npc_id);
|
||||
uint32 money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "platinum");
|
||||
|
||||
lua_pushinteger(L, std::stoul(parse->GetVar("gold." + ident.str())));
|
||||
money_string = fmt::format("gold.{}", npc_id);
|
||||
money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "gold");
|
||||
|
||||
lua_pushinteger(L, std::stoul(parse->GetVar("silver." + ident.str())));
|
||||
money_string = fmt::format("silver.{}", npc_id);
|
||||
money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "silver");
|
||||
|
||||
lua_pushinteger(L, std::stoul(parse->GetVar("copper." + ident.str())));
|
||||
money_string = fmt::format("copper.{}", npc_id);
|
||||
money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "copper");
|
||||
|
||||
lua_setfield(L, -2, "trade");
|
||||
}
|
||||
|
||||
@ -262,12 +274,12 @@ void handle_npc_loot_zone(QuestInterface *parse, lua_State* L, NPC* npc, Mob *in
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
|
||||
Lua_ItemInst l_item(std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||
l_item_o.push(L);
|
||||
lua_setfield(L, -2, "item");
|
||||
|
||||
|
||||
Lua_Corpse l_corpse(std::any_cast<Corpse*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||
l_corpse_o.push(L);
|
||||
@ -420,10 +432,10 @@ void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std
|
||||
}
|
||||
|
||||
lua_setfield(L, -2, "spell");
|
||||
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||
lua_setfield(L, -2, "caster_id");
|
||||
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
||||
lua_setfield(L, -2, "caster_level");
|
||||
}
|
||||
@ -534,7 +546,7 @@ void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client,
|
||||
lua_setfield(L, -2, "recipe_id");
|
||||
|
||||
lua_pushstring(L, data.c_str());
|
||||
lua_setfield(L, -2, "recipe_name");
|
||||
lua_setfield(L, -2, "recipe_name");
|
||||
}
|
||||
|
||||
void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
@ -650,7 +662,7 @@ void handle_player_quest_combine(QuestInterface* parse, lua_State* L, Client* cl
|
||||
lua_pushinteger(L, std::stoi(data));
|
||||
lua_setfield(L, -2, "container_slot");
|
||||
}
|
||||
|
||||
|
||||
void handle_player_consider(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
||||
lua_pushinteger(L, std::stoi(data));
|
||||
lua_setfield(L, -2, "entity_id");
|
||||
@ -817,7 +829,7 @@ void handle_spell_event(QuestInterface *parse, lua_State* L, Mob* mob, Client* c
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
||||
lua_setfield(L, -2, "buff_slot");
|
||||
|
||||
|
||||
Lua_Spell l_spell(spell_id);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
@ -853,7 +865,7 @@ void handle_player_equip_item(QuestInterface *parse, lua_State* L, Client* clien
|
||||
|
||||
lua_pushnumber(L, std::stoi(sep.arg[1]));
|
||||
lua_setfield(L, -2, "slot_id");
|
||||
|
||||
|
||||
Lua_ItemInst l_item(extra_data);
|
||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||
l_item_o.push(L);
|
||||
@ -995,10 +1007,10 @@ void handle_bot_cast(
|
||||
}
|
||||
|
||||
lua_setfield(L, -2, "spell");
|
||||
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||
lua_setfield(L, -2, "caster_id");
|
||||
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
||||
lua_setfield(L, -2, "caster_level");
|
||||
}
|
||||
@ -1153,6 +1165,64 @@ void handle_bot_timer(
|
||||
lua_setfield(L, -2, "timer");
|
||||
}
|
||||
|
||||
void handle_bot_trade(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Bot* bot,
|
||||
Mob *init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
const auto bot_id = bot->GetBotID();
|
||||
|
||||
if (extra_pointers) {
|
||||
size_t sz = extra_pointers->size();
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
auto prefix = fmt::format("item{}", i + 1);
|
||||
auto* inst = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(i));
|
||||
|
||||
Lua_ItemInst l_inst = inst;
|
||||
luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst);
|
||||
l_inst_o.push(L);
|
||||
|
||||
lua_setfield(L, -2, prefix.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
auto money_string = fmt::format("platinum.{}", bot_id);
|
||||
uint32 money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "platinum");
|
||||
|
||||
money_string = fmt::format("gold.{}", bot_id);
|
||||
money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "gold");
|
||||
|
||||
money_string = fmt::format("silver.{}", bot_id);
|
||||
money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "silver");
|
||||
|
||||
money_string = fmt::format("copper.{}", bot_id);
|
||||
money_value = !parse->GetVar(money_string).empty() ? std::stoul(parse->GetVar(money_string)) : 0;
|
||||
|
||||
lua_pushinteger(L, money_value);
|
||||
lua_setfield(L, -2, "copper");
|
||||
|
||||
lua_setfield(L, -2, "trade");
|
||||
}
|
||||
|
||||
void handle_bot_use_skill(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
|
||||
@ -276,6 +276,16 @@ void handle_bot_timer(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_bot_trade(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Bot* bot,
|
||||
Mob* init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_bot_use_skill(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
|
||||
@ -1234,6 +1234,10 @@ bool QuestParserCollection::BotHasQuestSubGlobal(QuestEventID evt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestParserCollection::BotHasQuestSub(QuestEventID evt) {
|
||||
return BotHasQuestSubLocal(evt) || BotHasQuestSubGlobal(evt);
|
||||
}
|
||||
|
||||
QuestInterface *QuestParserCollection::GetQIByBotQuest(std::string &filename) {
|
||||
if (!zone || !zone->IsLoaded()) {
|
||||
return nullptr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user