[Quest API] Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. (#2810)

* [Quest API] Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua.

# Perl
- Add `EVENT_ITEM_CLICK_CLIENT`.
- Add `EVENT_ITEM_CLICK_CAST_CLIENT`.
- Both events export `$item_id`, `$item_name`, `$slot_id`, and `$spell_id`.

# Lua
- Add `event_item_click_client`.
- Add `event_item_click_cast_client`.
- Both events export `e.item_id`, `e.item_name`, `e.slot_id`, `e.spell_id`, and `e.item`.

# Notes
- Allows operators to handle item clicks in player scripts instead of item-specific scripts.

* Update lua_parser_events.cpp

* Remove optional bool.
This commit is contained in:
Alex King 2023-01-30 06:01:12 -05:00 committed by GitHub
parent 66896a3121
commit a25952910a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 298 additions and 154 deletions

View File

@ -4168,8 +4168,26 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
{ {
if (GetLevel() >= item->Click.Level2) if (GetLevel() >= item->Click.Level2)
{ {
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst; auto* p_inst = (EQ::ItemInstance*) inst;
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot); int i = 0;
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
i = parse->EventItem(
EVENT_ITEM_CLICK_CAST,
this,
p_inst,
nullptr,
"",
castspell->inventoryslot
);
}
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
std::vector<std::any> args;
args.emplace_back(p_inst);
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(castspell->inventoryslot), 0, &args);
}
if (i == 0) { if (i == 0) {
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot); CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
} }
@ -4187,8 +4205,26 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
} }
else else
{ {
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst; auto* p_inst = (EQ::ItemInstance*) inst;
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot);
int i = 0;
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
i = parse->EventItem(
EVENT_ITEM_CLICK_CAST,
this,
p_inst,
nullptr,
"",
castspell->inventoryslot
);
}
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
std::vector<std::any> args;
args.emplace_back(p_inst);
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(castspell->inventoryslot), 0, &args);
}
if (i == 0) { if (i == 0) {
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot); CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
@ -8836,9 +8872,18 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == EQ::item::ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == EQ::item::ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check
{ {
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst; auto* p_inst = (EQ::ItemInstance*) inst;
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK)) {
parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id);
}
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CLIENT)) {
std::vector<std::any> args;
args.emplace_back(p_inst);
parse->EventPlayer(EVENT_ITEM_CLICK_CLIENT, this, std::to_string(slot_id), 0, &args);
}
parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id);
inst = m_inv[slot_id]; inst = m_inv[slot_id];
if (!inst) if (!inst)
{ {
@ -8940,7 +8985,25 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
} }
} }
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", slot_id); int i = 0;
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
i = parse->EventItem(
EVENT_ITEM_CLICK_CAST,
this,
p_inst,
nullptr,
"",
slot_id
);
}
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
std::vector<std::any> args;
args.emplace_back(p_inst);
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(slot_id), 0, &args);
}
inst = m_inv[slot_id]; inst = m_inv[slot_id];
if (!inst) if (!inst)
{ {
@ -8989,7 +9052,25 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
} }
} }
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, clickaug, nullptr, "", slot_id); int i = 0;
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
i = parse->EventItem(
EVENT_ITEM_CLICK_CAST,
this,
clickaug,
nullptr,
"",
slot_id
);
}
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
std::vector<std::any> args;
args.emplace_back(clickaug);
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(slot_id), 0, &args);
}
inst = m_inv[slot_id]; inst = m_inv[slot_id];
if (!inst) if (!inst)
{ {

View File

@ -173,6 +173,8 @@ const char *QuestEventSubroutines[_LargestEventID] = {
"EVENT_UNEQUIP_ITEM_BOT", "EVENT_UNEQUIP_ITEM_BOT",
"EVENT_DAMAGE_GIVEN", "EVENT_DAMAGE_GIVEN",
"EVENT_DAMAGE_TAKEN", "EVENT_DAMAGE_TAKEN",
"EVENT_ITEM_CLICK_CLIENT",
"EVENT_ITEM_CLICK_CAST_CLIENT",
// Add new events before these or Lua crashes // Add new events before these or Lua crashes
"EVENT_SPELL_EFFECT_BOT", "EVENT_SPELL_EFFECT_BOT",
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT" "EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
@ -1713,6 +1715,20 @@ void PerlembParser::ExportEventVariables(
break; break;
} }
case EVENT_ITEM_CLICK_CAST_CLIENT:
case EVENT_ITEM_CLICK_CLIENT: {
ExportVar(package_name.c_str(), "slot_id", data);
if (extra_pointers && extra_pointers->size() == 1) {
auto* item = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0));
if (item) {
ExportVar(package_name.c_str(), "item_id", item->GetID());
ExportVar(package_name.c_str(), "item_name", item->GetItem()->Name);
ExportVar(package_name.c_str(), "spell_id", item->GetItem()->Click.Effect);
}
}
break;
}
case EVENT_GROUP_CHANGE: { case EVENT_GROUP_CHANGE: {
if (mob && mob->IsClient()) { if (mob && mob->IsClient()) {
ExportVar(package_name.c_str(), "grouped", mob->IsGrouped()); ExportVar(package_name.c_str(), "grouped", mob->IsGrouped());

View File

@ -118,6 +118,8 @@ typedef enum {
EVENT_UNEQUIP_ITEM_BOT, EVENT_UNEQUIP_ITEM_BOT,
EVENT_DAMAGE_GIVEN, EVENT_DAMAGE_GIVEN,
EVENT_DAMAGE_TAKEN, EVENT_DAMAGE_TAKEN,
EVENT_ITEM_CLICK_CLIENT,
EVENT_ITEM_CLICK_CAST_CLIENT,
// Add new events before these or Lua crashes // Add new events before these or Lua crashes
EVENT_SPELL_EFFECT_BOT, EVENT_SPELL_EFFECT_BOT,
EVENT_SPELL_EFFECT_BUFF_TIC_BOT, EVENT_SPELL_EFFECT_BUFF_TIC_BOT,

View File

@ -4627,7 +4627,11 @@ luabind::scope lua_register_events() {
luabind::value("augment_insert_client", static_cast<int>(EVENT_AUGMENT_INSERT_CLIENT)), luabind::value("augment_insert_client", static_cast<int>(EVENT_AUGMENT_INSERT_CLIENT)),
luabind::value("augment_remove_client", static_cast<int>(EVENT_AUGMENT_REMOVE_CLIENT)), luabind::value("augment_remove_client", static_cast<int>(EVENT_AUGMENT_REMOVE_CLIENT)),
luabind::value("equip_item_bot", static_cast<int>(EVENT_EQUIP_ITEM_BOT)), luabind::value("equip_item_bot", static_cast<int>(EVENT_EQUIP_ITEM_BOT)),
luabind::value("unequip_item_bot", static_cast<int>(EVENT_UNEQUIP_ITEM_BOT)) luabind::value("unequip_item_bot", static_cast<int>(EVENT_UNEQUIP_ITEM_BOT)),
luabind::value("damage_given", static_cast<int>(EVENT_DAMAGE_GIVEN)),
luabind::value("damage_taken", static_cast<int>(EVENT_DAMAGE_TAKEN)),
luabind::value("item_click_client", static_cast<int>(EVENT_ITEM_CLICK_CLIENT)),
luabind::value("item_click_cast_client", static_cast<int>(EVENT_ITEM_CLICK_CAST_CLIENT))
)]; )];
} }

View File

@ -159,7 +159,9 @@ const char *LuaEvents[_LargestEventID] = {
"event_equip_item_bot", "event_equip_item_bot",
"event_unequip_item_bot", "event_unequip_item_bot",
"event_damage_given", "event_damage_given",
"event_damage_taken" "event_damage_taken",
"event_item_click_client",
"event_item_click_cast_client"
}; };
extern Zone *zone; extern Zone *zone;
@ -175,151 +177,153 @@ std::map<std::string, bool> lua_encounters_loaded;
std::map<std::string, Encounter *> lua_encounters; std::map<std::string, Encounter *> lua_encounters;
LuaParser::LuaParser() { LuaParser::LuaParser() {
for(int i = 0; i < _LargestEventID; ++i) { for (int i = 0; i < _LargestEventID; ++i) {
NPCArgumentDispatch[i] = handle_npc_null; NPCArgumentDispatch[i] = handle_npc_null;
PlayerArgumentDispatch[i] = handle_player_null; PlayerArgumentDispatch[i] = handle_player_null;
ItemArgumentDispatch[i] = handle_item_null; ItemArgumentDispatch[i] = handle_item_null;
SpellArgumentDispatch[i] = handle_spell_null; SpellArgumentDispatch[i] = handle_spell_null;
EncounterArgumentDispatch[i] = handle_encounter_null; EncounterArgumentDispatch[i] = handle_encounter_null;
BotArgumentDispatch[i] = handle_bot_null; BotArgumentDispatch[i] = handle_bot_null;
} }
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say; NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
NPCArgumentDispatch[EVENT_AGGRO_SAY] = handle_npc_event_say; NPCArgumentDispatch[EVENT_AGGRO_SAY] = handle_npc_event_say;
NPCArgumentDispatch[EVENT_PROXIMITY_SAY] = handle_npc_event_say; NPCArgumentDispatch[EVENT_PROXIMITY_SAY] = handle_npc_event_say;
NPCArgumentDispatch[EVENT_TRADE] = handle_npc_event_trade; NPCArgumentDispatch[EVENT_TRADE] = handle_npc_event_trade;
NPCArgumentDispatch[EVENT_HP] = handle_npc_event_hp; NPCArgumentDispatch[EVENT_HP] = handle_npc_event_hp;
NPCArgumentDispatch[EVENT_TARGET_CHANGE] = handle_npc_single_mob; NPCArgumentDispatch[EVENT_TARGET_CHANGE] = handle_npc_single_mob;
NPCArgumentDispatch[EVENT_CAST_ON] = handle_npc_cast; NPCArgumentDispatch[EVENT_CAST_ON] = handle_npc_cast;
NPCArgumentDispatch[EVENT_KILLED_MERIT] = handle_npc_single_client; NPCArgumentDispatch[EVENT_KILLED_MERIT] = handle_npc_single_client;
NPCArgumentDispatch[EVENT_SLAY] = handle_npc_single_mob; NPCArgumentDispatch[EVENT_SLAY] = handle_npc_single_mob;
NPCArgumentDispatch[EVENT_ENTER] = handle_npc_single_client; NPCArgumentDispatch[EVENT_ENTER] = handle_npc_single_client;
NPCArgumentDispatch[EVENT_EXIT] = handle_npc_single_client; NPCArgumentDispatch[EVENT_EXIT] = handle_npc_single_client;
NPCArgumentDispatch[EVENT_TASK_ACCEPTED] = handle_npc_task_accepted; NPCArgumentDispatch[EVENT_TASK_ACCEPTED] = handle_npc_task_accepted;
NPCArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_npc_popup; NPCArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_npc_popup;
NPCArgumentDispatch[EVENT_WAYPOINT_ARRIVE] = handle_npc_waypoint; NPCArgumentDispatch[EVENT_WAYPOINT_ARRIVE] = handle_npc_waypoint;
NPCArgumentDispatch[EVENT_WAYPOINT_DEPART] = handle_npc_waypoint; NPCArgumentDispatch[EVENT_WAYPOINT_DEPART] = handle_npc_waypoint;
NPCArgumentDispatch[EVENT_HATE_LIST] = handle_npc_hate; NPCArgumentDispatch[EVENT_HATE_LIST] = handle_npc_hate;
NPCArgumentDispatch[EVENT_COMBAT] = handle_npc_hate; NPCArgumentDispatch[EVENT_COMBAT] = handle_npc_hate;
NPCArgumentDispatch[EVENT_SIGNAL] = handle_npc_signal; NPCArgumentDispatch[EVENT_SIGNAL] = handle_npc_signal;
NPCArgumentDispatch[EVENT_TIMER] = handle_npc_timer; NPCArgumentDispatch[EVENT_TIMER] = handle_npc_timer;
NPCArgumentDispatch[EVENT_DEATH] = handle_npc_death; NPCArgumentDispatch[EVENT_DEATH] = handle_npc_death;
NPCArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_npc_death; NPCArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_npc_death;
NPCArgumentDispatch[EVENT_DEATH_ZONE] = handle_npc_death; NPCArgumentDispatch[EVENT_DEATH_ZONE] = handle_npc_death;
NPCArgumentDispatch[EVENT_CAST] = handle_npc_cast; NPCArgumentDispatch[EVENT_CAST] = handle_npc_cast;
NPCArgumentDispatch[EVENT_CAST_BEGIN] = handle_npc_cast; NPCArgumentDispatch[EVENT_CAST_BEGIN] = handle_npc_cast;
NPCArgumentDispatch[EVENT_FEIGN_DEATH] = handle_npc_single_client; NPCArgumentDispatch[EVENT_FEIGN_DEATH] = handle_npc_single_client;
NPCArgumentDispatch[EVENT_ENTER_AREA] = handle_npc_area; NPCArgumentDispatch[EVENT_ENTER_AREA] = handle_npc_area;
NPCArgumentDispatch[EVENT_LEAVE_AREA] = handle_npc_area; NPCArgumentDispatch[EVENT_LEAVE_AREA] = handle_npc_area;
NPCArgumentDispatch[EVENT_LOOT_ZONE] = handle_npc_loot_zone; NPCArgumentDispatch[EVENT_LOOT_ZONE] = handle_npc_loot_zone;
NPCArgumentDispatch[EVENT_SPAWN_ZONE] = handle_npc_spawn_zone; NPCArgumentDispatch[EVENT_SPAWN_ZONE] = handle_npc_spawn_zone;
NPCArgumentDispatch[EVENT_PAYLOAD] = handle_npc_payload; NPCArgumentDispatch[EVENT_PAYLOAD] = handle_npc_payload;
NPCArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_npc_despawn_zone; NPCArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_npc_despawn_zone;
NPCArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_npc_damage; NPCArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_npc_damage;
NPCArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_npc_damage; NPCArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_npc_damage;
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say; PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage; PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
PlayerArgumentDispatch[EVENT_DEATH] = handle_player_death; PlayerArgumentDispatch[EVENT_DEATH] = handle_player_death;
PlayerArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_player_death; PlayerArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_player_death;
PlayerArgumentDispatch[EVENT_TIMER] = handle_player_timer; PlayerArgumentDispatch[EVENT_TIMER] = handle_player_timer;
PlayerArgumentDispatch[EVENT_DISCOVER_ITEM] = handle_player_discover_item; PlayerArgumentDispatch[EVENT_DISCOVER_ITEM] = handle_player_discover_item;
PlayerArgumentDispatch[EVENT_FISH_SUCCESS] = handle_player_fish_forage_success; PlayerArgumentDispatch[EVENT_FISH_SUCCESS] = handle_player_fish_forage_success;
PlayerArgumentDispatch[EVENT_FORAGE_SUCCESS] = handle_player_fish_forage_success; PlayerArgumentDispatch[EVENT_FORAGE_SUCCESS] = handle_player_fish_forage_success;
PlayerArgumentDispatch[EVENT_CLICK_OBJECT] = handle_player_click_object; PlayerArgumentDispatch[EVENT_CLICK_OBJECT] = handle_player_click_object;
PlayerArgumentDispatch[EVENT_CLICK_DOOR] = handle_player_click_door; PlayerArgumentDispatch[EVENT_CLICK_DOOR] = handle_player_click_door;
PlayerArgumentDispatch[EVENT_SIGNAL] = handle_player_signal; PlayerArgumentDispatch[EVENT_SIGNAL] = handle_player_signal;
PlayerArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_player_popup_response; PlayerArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_player_popup_response;
PlayerArgumentDispatch[EVENT_PLAYER_PICKUP] = handle_player_pick_up; PlayerArgumentDispatch[EVENT_PLAYER_PICKUP] = handle_player_pick_up;
PlayerArgumentDispatch[EVENT_CAST] = handle_player_cast; PlayerArgumentDispatch[EVENT_CAST] = handle_player_cast;
PlayerArgumentDispatch[EVENT_CAST_BEGIN] = handle_player_cast; PlayerArgumentDispatch[EVENT_CAST_BEGIN] = handle_player_cast;
PlayerArgumentDispatch[EVENT_CAST_ON] = handle_player_cast; PlayerArgumentDispatch[EVENT_CAST_ON] = handle_player_cast;
PlayerArgumentDispatch[EVENT_TASK_FAIL] = handle_player_task_fail; PlayerArgumentDispatch[EVENT_TASK_FAIL] = handle_player_task_fail;
PlayerArgumentDispatch[EVENT_ZONE] = handle_player_zone; PlayerArgumentDispatch[EVENT_ZONE] = handle_player_zone;
PlayerArgumentDispatch[EVENT_DUEL_WIN] = handle_player_duel_win; PlayerArgumentDispatch[EVENT_DUEL_WIN] = handle_player_duel_win;
PlayerArgumentDispatch[EVENT_DUEL_LOSE] = handle_player_duel_loss; PlayerArgumentDispatch[EVENT_DUEL_LOSE] = handle_player_duel_loss;
PlayerArgumentDispatch[EVENT_LOOT] = handle_player_loot; PlayerArgumentDispatch[EVENT_LOOT] = handle_player_loot;
PlayerArgumentDispatch[EVENT_TASK_STAGE_COMPLETE] = handle_player_task_stage_complete; PlayerArgumentDispatch[EVENT_TASK_STAGE_COMPLETE] = handle_player_task_stage_complete;
PlayerArgumentDispatch[EVENT_TASK_COMPLETE] = handle_player_task_update; PlayerArgumentDispatch[EVENT_TASK_COMPLETE] = handle_player_task_update;
PlayerArgumentDispatch[EVENT_TASK_UPDATE] = handle_player_task_update; PlayerArgumentDispatch[EVENT_TASK_UPDATE] = handle_player_task_update;
PlayerArgumentDispatch[EVENT_TASK_BEFORE_UPDATE] = handle_player_task_update; PlayerArgumentDispatch[EVENT_TASK_BEFORE_UPDATE] = handle_player_task_update;
PlayerArgumentDispatch[EVENT_COMMAND] = handle_player_command; PlayerArgumentDispatch[EVENT_COMMAND] = handle_player_command;
PlayerArgumentDispatch[EVENT_COMBINE_SUCCESS] = handle_player_combine; PlayerArgumentDispatch[EVENT_COMBINE_SUCCESS] = handle_player_combine;
PlayerArgumentDispatch[EVENT_COMBINE_FAILURE] = handle_player_combine; PlayerArgumentDispatch[EVENT_COMBINE_FAILURE] = handle_player_combine;
PlayerArgumentDispatch[EVENT_FEIGN_DEATH] = handle_player_feign; PlayerArgumentDispatch[EVENT_FEIGN_DEATH] = handle_player_feign;
PlayerArgumentDispatch[EVENT_ENTER_AREA] = handle_player_area; PlayerArgumentDispatch[EVENT_ENTER_AREA] = handle_player_area;
PlayerArgumentDispatch[EVENT_LEAVE_AREA] = handle_player_area; PlayerArgumentDispatch[EVENT_LEAVE_AREA] = handle_player_area;
PlayerArgumentDispatch[EVENT_RESPAWN] = handle_player_respawn; PlayerArgumentDispatch[EVENT_RESPAWN] = handle_player_respawn;
PlayerArgumentDispatch[EVENT_UNHANDLED_OPCODE] = handle_player_packet; PlayerArgumentDispatch[EVENT_UNHANDLED_OPCODE] = handle_player_packet;
PlayerArgumentDispatch[EVENT_USE_SKILL] = handle_player_use_skill; PlayerArgumentDispatch[EVENT_USE_SKILL] = handle_player_use_skill;
PlayerArgumentDispatch[EVENT_TEST_BUFF] = handle_test_buff; PlayerArgumentDispatch[EVENT_TEST_BUFF] = handle_test_buff;
PlayerArgumentDispatch[EVENT_COMBINE_VALIDATE] = handle_player_combine_validate; PlayerArgumentDispatch[EVENT_COMBINE_VALIDATE] = handle_player_combine_validate;
PlayerArgumentDispatch[EVENT_BOT_COMMAND] = handle_player_bot_command; PlayerArgumentDispatch[EVENT_BOT_COMMAND] = handle_player_bot_command;
PlayerArgumentDispatch[EVENT_WARP] = handle_player_warp; PlayerArgumentDispatch[EVENT_WARP] = handle_player_warp;
PlayerArgumentDispatch[EVENT_COMBINE] = handle_player_quest_combine; PlayerArgumentDispatch[EVENT_COMBINE] = handle_player_quest_combine;
PlayerArgumentDispatch[EVENT_CONSIDER] = handle_player_consider; PlayerArgumentDispatch[EVENT_CONSIDER] = handle_player_consider;
PlayerArgumentDispatch[EVENT_CONSIDER_CORPSE] = handle_player_consider_corpse; PlayerArgumentDispatch[EVENT_CONSIDER_CORPSE] = handle_player_consider_corpse;
PlayerArgumentDispatch[EVENT_EQUIP_ITEM_CLIENT] = handle_player_equip_item; PlayerArgumentDispatch[EVENT_EQUIP_ITEM_CLIENT] = handle_player_equip_item;
PlayerArgumentDispatch[EVENT_UNEQUIP_ITEM_CLIENT] = handle_player_equip_item; PlayerArgumentDispatch[EVENT_UNEQUIP_ITEM_CLIENT] = handle_player_equip_item;
PlayerArgumentDispatch[EVENT_SKILL_UP] = handle_player_skill_up; PlayerArgumentDispatch[EVENT_SKILL_UP] = handle_player_skill_up;
PlayerArgumentDispatch[EVENT_LANGUAGE_SKILL_UP] = handle_player_skill_up; PlayerArgumentDispatch[EVENT_LANGUAGE_SKILL_UP] = handle_player_skill_up;
PlayerArgumentDispatch[EVENT_ALT_CURRENCY_MERCHANT_BUY] = handle_player_alt_currency_merchant; PlayerArgumentDispatch[EVENT_ALT_CURRENCY_MERCHANT_BUY] = handle_player_alt_currency_merchant;
PlayerArgumentDispatch[EVENT_ALT_CURRENCY_MERCHANT_SELL] = handle_player_alt_currency_merchant; PlayerArgumentDispatch[EVENT_ALT_CURRENCY_MERCHANT_SELL] = handle_player_alt_currency_merchant;
PlayerArgumentDispatch[EVENT_MERCHANT_BUY] = handle_player_merchant; PlayerArgumentDispatch[EVENT_MERCHANT_BUY] = handle_player_merchant;
PlayerArgumentDispatch[EVENT_MERCHANT_SELL] = handle_player_merchant; PlayerArgumentDispatch[EVENT_MERCHANT_SELL] = handle_player_merchant;
PlayerArgumentDispatch[EVENT_INSPECT] = handle_player_inspect; PlayerArgumentDispatch[EVENT_INSPECT] = handle_player_inspect;
PlayerArgumentDispatch[EVENT_AA_BUY] = handle_player_aa_buy; PlayerArgumentDispatch[EVENT_AA_BUY] = handle_player_aa_buy;
PlayerArgumentDispatch[EVENT_AA_GAIN] = handle_player_aa_gain; PlayerArgumentDispatch[EVENT_AA_GAIN] = handle_player_aa_gain;
PlayerArgumentDispatch[EVENT_PAYLOAD] = handle_player_payload; PlayerArgumentDispatch[EVENT_PAYLOAD] = handle_player_payload;
PlayerArgumentDispatch[EVENT_LEVEL_UP] = handle_player_level_up; PlayerArgumentDispatch[EVENT_LEVEL_UP] = handle_player_level_up;
PlayerArgumentDispatch[EVENT_LEVEL_DOWN] = handle_player_level_down; PlayerArgumentDispatch[EVENT_LEVEL_DOWN] = handle_player_level_down;
PlayerArgumentDispatch[EVENT_GM_COMMAND] = handle_player_gm_command; PlayerArgumentDispatch[EVENT_GM_COMMAND] = handle_player_gm_command;
PlayerArgumentDispatch[EVENT_BOT_CREATE] = handle_player_bot_create; PlayerArgumentDispatch[EVENT_BOT_CREATE] = handle_player_bot_create;
PlayerArgumentDispatch[EVENT_AUGMENT_INSERT_CLIENT] = handle_player_augment_insert; PlayerArgumentDispatch[EVENT_AUGMENT_INSERT_CLIENT] = handle_player_augment_insert;
PlayerArgumentDispatch[EVENT_AUGMENT_REMOVE_CLIENT] = handle_player_augment_remove; PlayerArgumentDispatch[EVENT_AUGMENT_REMOVE_CLIENT] = handle_player_augment_remove;
PlayerArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_player_damage; PlayerArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_player_damage;
PlayerArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_player_damage; PlayerArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_player_damage;
PlayerArgumentDispatch[EVENT_ITEM_CLICK_CAST_CLIENT] = handle_player_item_click;
PlayerArgumentDispatch[EVENT_ITEM_CLICK_CLIENT] = handle_player_item_click;
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
ItemArgumentDispatch[EVENT_TIMER] = handle_item_timer; ItemArgumentDispatch[EVENT_TIMER] = handle_item_timer;
ItemArgumentDispatch[EVENT_WEAPON_PROC] = handle_item_proc; ItemArgumentDispatch[EVENT_WEAPON_PROC] = handle_item_proc;
ItemArgumentDispatch[EVENT_LOOT] = handle_item_loot; ItemArgumentDispatch[EVENT_LOOT] = handle_item_loot;
ItemArgumentDispatch[EVENT_EQUIP_ITEM] = handle_item_equip; ItemArgumentDispatch[EVENT_EQUIP_ITEM] = handle_item_equip;
ItemArgumentDispatch[EVENT_UNEQUIP_ITEM] = handle_item_equip; ItemArgumentDispatch[EVENT_UNEQUIP_ITEM] = handle_item_equip;
ItemArgumentDispatch[EVENT_AUGMENT_ITEM] = handle_item_augment; ItemArgumentDispatch[EVENT_AUGMENT_ITEM] = handle_item_augment;
ItemArgumentDispatch[EVENT_UNAUGMENT_ITEM] = handle_item_augment; ItemArgumentDispatch[EVENT_UNAUGMENT_ITEM] = handle_item_augment;
ItemArgumentDispatch[EVENT_AUGMENT_INSERT] = handle_item_augment_insert; ItemArgumentDispatch[EVENT_AUGMENT_INSERT] = handle_item_augment_insert;
ItemArgumentDispatch[EVENT_AUGMENT_REMOVE] = handle_item_augment_remove; ItemArgumentDispatch[EVENT_AUGMENT_REMOVE] = handle_item_augment_remove;
SpellArgumentDispatch[EVENT_SPELL_EFFECT_CLIENT] = handle_spell_event; SpellArgumentDispatch[EVENT_SPELL_EFFECT_CLIENT] = handle_spell_event;
SpellArgumentDispatch[EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT] = handle_spell_event; SpellArgumentDispatch[EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT] = handle_spell_event;
SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_event; SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_event;
SpellArgumentDispatch[EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE] = handle_translocate_finish; SpellArgumentDispatch[EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE] = handle_translocate_finish;
EncounterArgumentDispatch[EVENT_TIMER] = handle_encounter_timer; EncounterArgumentDispatch[EVENT_TIMER] = handle_encounter_timer;
EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load; EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load;
EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload; EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload;
BotArgumentDispatch[EVENT_CAST] = handle_bot_cast; BotArgumentDispatch[EVENT_CAST] = handle_bot_cast;
BotArgumentDispatch[EVENT_CAST_BEGIN] = handle_bot_cast; BotArgumentDispatch[EVENT_CAST_BEGIN] = handle_bot_cast;
BotArgumentDispatch[EVENT_CAST_ON] = handle_bot_cast; BotArgumentDispatch[EVENT_CAST_ON] = handle_bot_cast;
BotArgumentDispatch[EVENT_COMBAT] = handle_bot_combat; BotArgumentDispatch[EVENT_COMBAT] = handle_bot_combat;
BotArgumentDispatch[EVENT_DEATH] = handle_bot_death; BotArgumentDispatch[EVENT_DEATH] = handle_bot_death;
BotArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_bot_death; BotArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_bot_death;
BotArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_bot_popup_response; BotArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_bot_popup_response;
BotArgumentDispatch[EVENT_SAY] = handle_bot_say; BotArgumentDispatch[EVENT_SAY] = handle_bot_say;
BotArgumentDispatch[EVENT_SIGNAL] = handle_bot_signal; BotArgumentDispatch[EVENT_SIGNAL] = handle_bot_signal;
BotArgumentDispatch[EVENT_SLAY] = handle_bot_slay; BotArgumentDispatch[EVENT_SLAY] = handle_bot_slay;
BotArgumentDispatch[EVENT_TARGET_CHANGE] = handle_bot_target_change; BotArgumentDispatch[EVENT_TARGET_CHANGE] = handle_bot_target_change;
BotArgumentDispatch[EVENT_TIMER] = handle_bot_timer; BotArgumentDispatch[EVENT_TIMER] = handle_bot_timer;
BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade; BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade;
BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill; BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill;
BotArgumentDispatch[EVENT_PAYLOAD] = handle_bot_payload; BotArgumentDispatch[EVENT_PAYLOAD] = handle_bot_payload;
BotArgumentDispatch[EVENT_EQUIP_ITEM_BOT] = handle_bot_equip_item; BotArgumentDispatch[EVENT_EQUIP_ITEM_BOT] = handle_bot_equip_item;
BotArgumentDispatch[EVENT_UNEQUIP_ITEM_BOT] = handle_bot_equip_item; BotArgumentDispatch[EVENT_UNEQUIP_ITEM_BOT] = handle_bot_equip_item;
BotArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_bot_damage; BotArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_bot_damage;
BotArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_bot_damage; BotArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_bot_damage;
#endif #endif
L = nullptr; L = nullptr;

View File

@ -1235,13 +1235,41 @@ void handle_player_damage(
lua_setfield(L, -2, "special_attack"); lua_setfield(L, -2, "special_attack");
if (extra_pointers && extra_pointers->size() >= 1) { if (extra_pointers && extra_pointers->size() >= 1) {
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(1))); Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(0)));
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
l_mob_o.push(L); l_mob_o.push(L);
lua_setfield(L, -2, "other"); lua_setfield(L, -2, "other");
} }
} }
void handle_player_item_click(
QuestInterface *parse,
lua_State* L,
Client* client,
const std::string& data,
uint32 extra_data,
std::vector<std::any> *extra_pointers
) {
lua_pushnumber(L, std::stoi(data));
lua_setfield(L, -2, "slot_id");
if (extra_pointers && extra_pointers->size() >= 1) {
lua_pushnumber(L, std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0))->GetID());
lua_setfield(L, -2, "item_id");
lua_pushstring(L, std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0))->GetItem()->Name);
lua_setfield(L, -2, "item_name");
lua_pushnumber(L, std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0))->GetItem()->Click.Effect);
lua_setfield(L, -2, "spell_id");
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");
}
}
// Item // Item
void handle_item_click( void handle_item_click(
QuestInterface *parse, QuestInterface *parse,

View File

@ -661,6 +661,15 @@ void handle_player_damage(
std::vector<std::any> *extra_pointers std::vector<std::any> *extra_pointers
); );
void handle_player_item_click(
QuestInterface *parse,
lua_State* L,
Client* client,
const std::string& data,
uint32 extra_data,
std::vector<std::any> *extra_pointers
);
// Item // Item
void handle_item_click( void handle_item_click(
QuestInterface *parse, QuestInterface *parse,

View File

@ -103,8 +103,8 @@ void QuestParserCollection::RemoveEncounter(const std::string name) {
} }
} }
bool QuestParserCollection::HasQuestSub(uint32 npcid, QuestEventID evt, bool check_encounters) { bool QuestParserCollection::HasQuestSub(uint32 npcid, QuestEventID evt) {
return HasQuestSubLocal(npcid, evt) || HasQuestSubGlobal(evt) || (check_encounters && NPCHasEncounterSub(npcid, evt)); return HasQuestSubLocal(npcid, evt) || HasQuestSubGlobal(evt) || NPCHasEncounterSub(npcid, evt);
} }
bool QuestParserCollection::NPCHasEncounterSub(uint32 npc_id, QuestEventID evt) { bool QuestParserCollection::NPCHasEncounterSub(uint32 npc_id, QuestEventID evt) {
@ -162,8 +162,8 @@ bool QuestParserCollection::HasQuestSubGlobal(QuestEventID evt) {
return false; return false;
} }
bool QuestParserCollection::PlayerHasQuestSub(QuestEventID evt, bool check_encounters) { bool QuestParserCollection::PlayerHasQuestSub(QuestEventID evt) {
return PlayerHasQuestSubLocal(evt) || PlayerHasQuestSubGlobal(evt) || (check_encounters && PlayerHasEncounterSub(evt)); return PlayerHasQuestSubLocal(evt) || PlayerHasQuestSubGlobal(evt) || PlayerHasEncounterSub(evt);
} }
bool QuestParserCollection::PlayerHasEncounterSub(QuestEventID evt) { bool QuestParserCollection::PlayerHasEncounterSub(QuestEventID evt) {
@ -207,8 +207,8 @@ bool QuestParserCollection::SpellHasEncounterSub(uint32 spell_id, QuestEventID e
return HasEncounterSub(evt, package_name); return HasEncounterSub(evt, package_name);
} }
bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt, bool check_encounters) { bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) {
if (check_encounters && SpellHasEncounterSub(spell_id, evt)) { if (SpellHasEncounterSub(spell_id, evt)) {
return true; return true;
} }
@ -241,11 +241,11 @@ bool QuestParserCollection::ItemHasEncounterSub(EQ::ItemInstance* item, QuestEve
return false; return false;
} }
bool QuestParserCollection::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt, bool check_encounters) { bool QuestParserCollection::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt) {
if (itm == nullptr) if (itm == nullptr)
return false; return false;
if (check_encounters && ItemHasEncounterSub(itm, evt)) { if (ItemHasEncounterSub(itm, evt)) {
return true; return true;
} }

View File

@ -67,10 +67,10 @@ public:
void ReloadQuests(bool reset_timers = true); void ReloadQuests(bool reset_timers = true);
void RemoveEncounter(const std::string name); void RemoveEncounter(const std::string name);
bool HasQuestSub(uint32 npcid, QuestEventID evt, bool check_encounters = false); bool HasQuestSub(uint32 npcid, QuestEventID evt);
bool PlayerHasQuestSub(QuestEventID evt, bool check_encounters = false); bool PlayerHasQuestSub(QuestEventID evt);
bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt, bool check_encounters = false); bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt);
bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt, bool check_encounters = false); bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt);
bool BotHasQuestSub(QuestEventID evt); bool BotHasQuestSub(QuestEventID evt);
int EventNPC(QuestEventID evt, NPC* npc, Mob *init, const std::string& data, uint32 extra_data, int EventNPC(QuestEventID evt, NPC* npc, Mob *init, const std::string& data, uint32 extra_data,

View File

@ -875,7 +875,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
} }
bool quest_npc = false; bool quest_npc = false;
if (parse->HasQuestSub(tradingWith->GetNPCTypeID(), EVENT_TRADE, true)) { if (parse->HasQuestSub(tradingWith->GetNPCTypeID(), EVENT_TRADE)) {
// This is a quest NPC // This is a quest NPC
quest_npc = true; quest_npc = true;
} }