mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-22 11:38:29 +00:00
Merge master in, with fixes
This commit is contained in:
@@ -88,7 +88,7 @@ jobs:
|
|||||||
- name: Configure
|
- name: Configure
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
|
cmake -S . -B build -G "Visual Studio 18 2026" -A x64 `
|
||||||
-DCMAKE_BUILD_TYPE=Release `
|
-DCMAKE_BUILD_TYPE=Release `
|
||||||
-DEQEMU_BUILD_TESTS=ON `
|
-DEQEMU_BUILD_TESTS=ON `
|
||||||
-DEQEMU_BUILD_LOGIN=ON `
|
-DEQEMU_BUILD_LOGIN=ON `
|
||||||
|
|||||||
@@ -5335,6 +5335,12 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
|||||||
if (ma_time) {
|
if (ma_time) {
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case Class::Monk: {
|
case Class::Monk: {
|
||||||
|
|
||||||
|
if (!GetSkill(EQ::skills::SkillTigerClaw)) {
|
||||||
|
monkattack_timer.Disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int reuse = (MonkSpecialAttack(target, EQ::skills::SkillTigerClaw) - 1);
|
int reuse = (MonkSpecialAttack(target, EQ::skills::SkillTigerClaw) - 1);
|
||||||
|
|
||||||
// Live AA - Technique of Master Wu
|
// Live AA - Technique of Master Wu
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ bool BotDatabase::SaveNewBot(Bot* b, uint32& bot_id)
|
|||||||
e.poison = b->GetBasePR();
|
e.poison = b->GetBasePR();
|
||||||
e.disease = b->GetBaseDR();
|
e.disease = b->GetBaseDR();
|
||||||
e.corruption = b->GetBaseCorrup();
|
e.corruption = b->GetBaseCorrup();
|
||||||
e.expansion_bitmask = b->GetExpansionBitmask();
|
e.expansion_bitmask = RuleI(Bots, BotExpansionSettings);
|
||||||
|
|
||||||
e = BotDataRepository::InsertOne(database, e);
|
e = BotDataRepository::InsertOne(database, e);
|
||||||
|
|
||||||
|
|||||||
+39
-16
@@ -14361,9 +14361,8 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
sizeof(Merchant_Purchase_Struct), app->size);
|
sizeof(Merchant_Purchase_Struct), app->size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RDTSC_Timer t1(true);
|
|
||||||
Merchant_Purchase_Struct* mp = (Merchant_Purchase_Struct*)app->pBuffer;
|
|
||||||
|
|
||||||
|
Merchant_Purchase_Struct* mp = (Merchant_Purchase_Struct*)app->pBuffer;
|
||||||
Mob* vendor = entity_list.GetMob(mp->npcid);
|
Mob* vendor = entity_list.GetMob(mp->npcid);
|
||||||
|
|
||||||
if (vendor == 0 || !vendor->IsNPC() || vendor->GetClass() != Class::Merchant)
|
if (vendor == 0 || !vendor->IsNPC() || vendor->GetClass() != Class::Merchant)
|
||||||
@@ -14373,35 +14372,51 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
if (DistanceSquared(m_Position, vendor->GetPosition()) > USE_NPC_RANGE2)
|
if (DistanceSquared(m_Position, vendor->GetPosition()) > USE_NPC_RANGE2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 price = 0;
|
|
||||||
uint32 itemid = GetItemIDAt(mp->itemslot);
|
uint32 itemid = GetItemIDAt(mp->itemslot);
|
||||||
if (itemid == 0)
|
if (itemid == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const EQ::ItemData* item = database.GetItem(itemid);
|
const EQ::ItemData* item = database.GetItem(itemid);
|
||||||
EQ::ItemInstance* inst = GetInv().GetItem(mp->itemslot);
|
EQ::ItemInstance* inst = GetInv().GetItem(mp->itemslot);
|
||||||
if (!item || !inst) {
|
if (!item || !inst) {
|
||||||
Message(Chat::Red, "You seemed to have misplaced that item..");
|
Message(Chat::Red, "You seem to have misplaced that item..");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mp->quantity > 1)
|
|
||||||
{
|
if (!item->NoDrop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp->quantity > 1) {
|
||||||
if ((inst->GetCharges() < 0) || (mp->quantity > (uint32)inst->GetCharges()))
|
if ((inst->GetCharges() < 0) || (mp->quantity > (uint32)inst->GetCharges()))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item->NoDrop) {
|
// Check for veto from script
|
||||||
//Message(Chat::Red,"%s tells you, 'LOL NOPE'", vendor->GetName());
|
if (parse->PlayerHasQuestSub(EVENT_MERCHANT_PRESELL)) {
|
||||||
return;
|
std::string export_string = fmt::format("{} {} {}", mp->itemslot, itemid, inst->GetItemType());
|
||||||
|
std::vector<std::any> extra_pointers = { vendor, inst };
|
||||||
|
|
||||||
|
int result = parse->EventPlayer(EVENT_MERCHANT_PRESELL, this, export_string, 0, &extra_pointers);
|
||||||
|
// CANCEL: If a script returns -1 for this event, the sale wil be cancelled. Sends a dummy packet sent to satisfy the client
|
||||||
|
if (result == -1) {
|
||||||
|
auto outapp = new EQApplicationPacket(OP_ShopPlayerSell, sizeof(Merchant_Purchase_Struct));
|
||||||
|
Merchant_Purchase_Struct* mco = (Merchant_Purchase_Struct*)outapp->pBuffer;
|
||||||
|
mco->npcid = vendor->GetID();
|
||||||
|
mco->itemslot = -1; // Critical or the client will remove the item visually
|
||||||
|
mco->quantity = 0;
|
||||||
|
mco->price = 0;
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 cost_quantity = mp->quantity;
|
uint32 cost_quantity = inst->IsCharged() ? 1 : mp->quantity;
|
||||||
if (inst->IsCharged())
|
uint32 price = 0;
|
||||||
uint32 cost_quantity = 1;
|
|
||||||
|
|
||||||
uint32 i;
|
|
||||||
|
|
||||||
if (RuleB(Merchant, UsePriceMod)) {
|
if (RuleB(Merchant, UsePriceMod)) {
|
||||||
for (i = 1; i <= cost_quantity; i++) {
|
for (uint32 i = 1; i <= cost_quantity; i++) {
|
||||||
price = (uint32)(item->Price * i) * Client::CalcPriceMod(vendor, true);
|
price = (uint32)(item->Price * i) * Client::CalcPriceMod(vendor, true);
|
||||||
|
|
||||||
// Don't use SellCostMod if using UseClassicPriceMod
|
// Don't use SellCostMod if using UseClassicPriceMod
|
||||||
@@ -14419,7 +14434,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 1; i <= cost_quantity; i++) {
|
for (uint32 i = 1; i <= cost_quantity; i++) {
|
||||||
price = (uint32)((item->Price * i)*(RuleR(Merchant, BuyCostMod)) + 0.5); // need to round up, because client does it automatically when displaying price
|
price = (uint32)((item->Price * i)*(RuleR(Merchant, BuyCostMod)) + 0.5); // need to round up, because client does it automatically when displaying price
|
||||||
if (price > 4000000000) {
|
if (price > 4000000000) {
|
||||||
cost_quantity = i;
|
cost_quantity = i;
|
||||||
@@ -14431,6 +14446,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
AddMoneyToPP(price);
|
AddMoneyToPP(price);
|
||||||
|
|
||||||
|
// Update merchant stock and refresh client
|
||||||
if (inst->IsStackable() || inst->IsCharged())
|
if (inst->IsStackable() || inst->IsCharged())
|
||||||
{
|
{
|
||||||
unsigned int i_quan = inst->GetCharges();
|
unsigned int i_quan = inst->GetCharges();
|
||||||
@@ -14544,6 +14560,8 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
SendMoneyUpdate();
|
SendMoneyUpdate();
|
||||||
|
|
||||||
|
RDTSC_Timer t1(true);
|
||||||
t1.start();
|
t1.start();
|
||||||
Save(1);
|
Save(1);
|
||||||
t1.stop();
|
t1.stop();
|
||||||
@@ -14665,6 +14683,11 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app)
|
|||||||
if ((tabs_to_display & Parcel) == Parcel) {
|
if ((tabs_to_display & Parcel) == Parcel) {
|
||||||
SendBulkParcels();
|
SendBulkParcels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_MERCHANT_OPEN)) {
|
||||||
|
std::vector<std::any> extra_pointers = { tmp };
|
||||||
|
parse->EventPlayer(EVENT_MERCHANT_OPEN, this, "", 0, &extra_pointers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -163,8 +163,10 @@ const char* QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_LANGUAGE_SKILL_UP",
|
"EVENT_LANGUAGE_SKILL_UP",
|
||||||
"EVENT_ALT_CURRENCY_MERCHANT_BUY",
|
"EVENT_ALT_CURRENCY_MERCHANT_BUY",
|
||||||
"EVENT_ALT_CURRENCY_MERCHANT_SELL",
|
"EVENT_ALT_CURRENCY_MERCHANT_SELL",
|
||||||
|
"EVENT_MERCHANT_OPEN",
|
||||||
"EVENT_MERCHANT_BUY",
|
"EVENT_MERCHANT_BUY",
|
||||||
"EVENT_MERCHANT_SELL",
|
"EVENT_MERCHANT_SELL",
|
||||||
|
"EVENT_MERCHANT_PRESELL",
|
||||||
"EVENT_INSPECT",
|
"EVENT_INSPECT",
|
||||||
"EVENT_TASK_BEFORE_UPDATE",
|
"EVENT_TASK_BEFORE_UPDATE",
|
||||||
"EVENT_AA_BUY",
|
"EVENT_AA_BUY",
|
||||||
@@ -2289,6 +2291,33 @@ void PerlembParser::ExportEventVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EVENT_MERCHANT_OPEN: {
|
||||||
|
if (!extra_pointers || extra_pointers->size() < 1) break;
|
||||||
|
|
||||||
|
auto mob_ptr = std::any_cast<Mob*>(extra_pointers->at(0));
|
||||||
|
if (!mob_ptr) break;
|
||||||
|
|
||||||
|
ExportVar(package_name.c_str(), "other", "Mob", mob_ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EVENT_MERCHANT_PRESELL: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "slot_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "item_id", sep.arg[1]);
|
||||||
|
ExportVar(package_name.c_str(), "item_type", sep.arg[2]);
|
||||||
|
|
||||||
|
if (!extra_pointers || extra_pointers->size() < 2) break;
|
||||||
|
|
||||||
|
auto mob_ptr = std::any_cast<Mob*>(extra_pointers->at(0));
|
||||||
|
auto inst_ptr = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(1));
|
||||||
|
if (!mob_ptr || !inst_ptr) break;
|
||||||
|
|
||||||
|
ExportVar(package_name.c_str(), "other", "Mob", mob_ptr);
|
||||||
|
ExportVar(package_name.c_str(), "item", "ItemInstance", inst_ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EVENT_AA_BUY: {
|
case EVENT_AA_BUY: {
|
||||||
Seperator sep(data);
|
Seperator sep(data);
|
||||||
ExportVar(package_name.c_str(), "aa_cost", sep.arg[0]);
|
ExportVar(package_name.c_str(), "aa_cost", sep.arg[0]);
|
||||||
|
|||||||
@@ -116,8 +116,10 @@ enum QuestEventID {
|
|||||||
EVENT_LANGUAGE_SKILL_UP,
|
EVENT_LANGUAGE_SKILL_UP,
|
||||||
EVENT_ALT_CURRENCY_MERCHANT_BUY,
|
EVENT_ALT_CURRENCY_MERCHANT_BUY,
|
||||||
EVENT_ALT_CURRENCY_MERCHANT_SELL,
|
EVENT_ALT_CURRENCY_MERCHANT_SELL,
|
||||||
|
EVENT_MERCHANT_OPEN,
|
||||||
EVENT_MERCHANT_BUY,
|
EVENT_MERCHANT_BUY,
|
||||||
EVENT_MERCHANT_SELL,
|
EVENT_MERCHANT_SELL,
|
||||||
|
EVENT_MERCHANT_PRESELL,
|
||||||
EVENT_INSPECT,
|
EVENT_INSPECT,
|
||||||
EVENT_TASK_BEFORE_UPDATE,
|
EVENT_TASK_BEFORE_UPDATE,
|
||||||
EVENT_AA_BUY,
|
EVENT_AA_BUY,
|
||||||
|
|||||||
@@ -6968,8 +6968,10 @@ luabind::scope lua_register_events() {
|
|||||||
luabind::value("language_skill_up", static_cast<int>(EVENT_LANGUAGE_SKILL_UP)),
|
luabind::value("language_skill_up", static_cast<int>(EVENT_LANGUAGE_SKILL_UP)),
|
||||||
luabind::value("alt_currency_merchant_buy", static_cast<int>(EVENT_ALT_CURRENCY_MERCHANT_BUY)),
|
luabind::value("alt_currency_merchant_buy", static_cast<int>(EVENT_ALT_CURRENCY_MERCHANT_BUY)),
|
||||||
luabind::value("alt_currency_merchant_sell", static_cast<int>(EVENT_ALT_CURRENCY_MERCHANT_SELL)),
|
luabind::value("alt_currency_merchant_sell", static_cast<int>(EVENT_ALT_CURRENCY_MERCHANT_SELL)),
|
||||||
|
luabind::value("merchant_open", static_cast<int>(EVENT_MERCHANT_OPEN)),
|
||||||
luabind::value("merchant_buy", static_cast<int>(EVENT_MERCHANT_BUY)),
|
luabind::value("merchant_buy", static_cast<int>(EVENT_MERCHANT_BUY)),
|
||||||
luabind::value("merchant_sell", static_cast<int>(EVENT_MERCHANT_SELL)),
|
luabind::value("merchant_sell", static_cast<int>(EVENT_MERCHANT_SELL)),
|
||||||
|
luabind::value("merchant_presell", static_cast<int>(EVENT_MERCHANT_PRESELL)),
|
||||||
luabind::value("inspect", static_cast<int>(EVENT_INSPECT)),
|
luabind::value("inspect", static_cast<int>(EVENT_INSPECT)),
|
||||||
luabind::value("task_before_update", static_cast<int>(EVENT_TASK_BEFORE_UPDATE)),
|
luabind::value("task_before_update", static_cast<int>(EVENT_TASK_BEFORE_UPDATE)),
|
||||||
luabind::value("aa_buy", static_cast<int>(EVENT_AA_BUY)),
|
luabind::value("aa_buy", static_cast<int>(EVENT_AA_BUY)),
|
||||||
|
|||||||
@@ -158,6 +158,11 @@ uint32 Lua_ItemInst::GetItemScriptID() {
|
|||||||
return self->GetItemScriptID();
|
return self->GetItemScriptID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 Lua_ItemInst::GetItemType() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetItemType();
|
||||||
|
}
|
||||||
|
|
||||||
int Lua_ItemInst::GetCharges() {
|
int Lua_ItemInst::GetCharges() {
|
||||||
Lua_Safe_Call_Int();
|
Lua_Safe_Call_Int();
|
||||||
return self->GetCharges();
|
return self->GetCharges();
|
||||||
@@ -497,6 +502,7 @@ luabind::scope lua_register_iteminst() {
|
|||||||
.def("GetItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetItemID)
|
.def("GetItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetItemID)
|
||||||
.def("GetItemLink", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemLink)
|
.def("GetItemLink", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemLink)
|
||||||
.def("GetItemScriptID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemScriptID)
|
.def("GetItemScriptID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemScriptID)
|
||||||
|
.def("GetItemType", (uint8(Lua_ItemInst::*)(void)) & Lua_ItemInst::GetItemType)
|
||||||
.def("GetMaxEvolveLvl", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetMaxEvolveLvl)
|
.def("GetMaxEvolveLvl", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetMaxEvolveLvl)
|
||||||
.def("GetName", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetName)
|
.def("GetName", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetName)
|
||||||
.def("GetSerialNumber", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetSerialNumber)
|
.def("GetSerialNumber", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetSerialNumber)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public:
|
|||||||
bool IsAmmo();
|
bool IsAmmo();
|
||||||
uint32 GetID();
|
uint32 GetID();
|
||||||
uint32 GetItemScriptID();
|
uint32 GetItemScriptID();
|
||||||
|
uint8 GetItemType();
|
||||||
int GetCharges();
|
int GetCharges();
|
||||||
void SetCharges(int charges);
|
void SetCharges(int charges);
|
||||||
uint32 GetPrice();
|
uint32 GetPrice();
|
||||||
|
|||||||
@@ -160,8 +160,10 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_language_skill_up",
|
"event_language_skill_up",
|
||||||
"event_alt_currency_merchant_buy",
|
"event_alt_currency_merchant_buy",
|
||||||
"event_alt_currency_merchant_sell",
|
"event_alt_currency_merchant_sell",
|
||||||
|
"event_merchant_open",
|
||||||
"event_merchant_buy",
|
"event_merchant_buy",
|
||||||
"event_merchant_sell",
|
"event_merchant_sell",
|
||||||
|
"event_merchant_presell",
|
||||||
"event_inspect",
|
"event_inspect",
|
||||||
"event_task_before_update",
|
"event_task_before_update",
|
||||||
"event_aa_buy",
|
"event_aa_buy",
|
||||||
@@ -335,8 +337,10 @@ LuaParser::LuaParser() {
|
|||||||
PlayerArgumentDispatch[EVENT_LANGUAGE_SKILL_UP] = handle_player_language_skill_up;
|
PlayerArgumentDispatch[EVENT_LANGUAGE_SKILL_UP] = handle_player_language_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_OPEN] = handle_player_merchant_open;
|
||||||
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_MERCHANT_PRESELL] = handle_player_merchant_presell;
|
||||||
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;
|
||||||
|
|||||||
@@ -2340,6 +2340,53 @@ void handle_player_merchant(
|
|||||||
lua_setfield(L, -2, "item_cost");
|
lua_setfield(L, -2, "item_cost");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_player_merchant_open(
|
||||||
|
QuestInterface* parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any>* extra_pointers
|
||||||
|
) {
|
||||||
|
if (!extra_pointers || extra_pointers->size() < 1) return;
|
||||||
|
|
||||||
|
auto mob_ptr = std::any_cast<Mob*>(extra_pointers->at(0));
|
||||||
|
if (!mob_ptr) return;
|
||||||
|
|
||||||
|
Lua_Mob l_mob(mob_ptr);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_player_merchant_presell(
|
||||||
|
QuestInterface* parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any>* extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0])); lua_setfield(L, -2, "slot_id");
|
||||||
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1])); lua_setfield(L, -2, "item_id");
|
||||||
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2])); lua_setfield(L, -2, "item_type");
|
||||||
|
|
||||||
|
if (!extra_pointers || extra_pointers->size() < 2) return;
|
||||||
|
|
||||||
|
auto mob_ptr = std::any_cast<Mob*>(extra_pointers->at(0));
|
||||||
|
auto inst_ptr = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(1));
|
||||||
|
if (!mob_ptr || !inst_ptr) return;
|
||||||
|
|
||||||
|
Lua_Mob l_mob(mob_ptr);
|
||||||
|
luabind::adl::object(L, l_mob).push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
|
Lua_ItemInst l_iteminst(inst_ptr);
|
||||||
|
luabind::adl::object(L, l_iteminst).push(L);
|
||||||
|
lua_setfield(L, -2, "item");
|
||||||
|
}
|
||||||
|
|
||||||
void handle_player_augment_insert(
|
void handle_player_augment_insert(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
lua_State* L,
|
lua_State* L,
|
||||||
|
|||||||
@@ -671,6 +671,24 @@ void handle_player_merchant(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void handle_player_merchant_open(
|
||||||
|
QuestInterface* parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any>* extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_player_merchant_presell(
|
||||||
|
QuestInterface* parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any>* extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
void handle_player_inspect(
|
void handle_player_inspect(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
lua_State* L,
|
lua_State* L,
|
||||||
|
|||||||
+20
-32
@@ -711,48 +711,36 @@ void UpdateWindowTitle(char *iNewTitle)
|
|||||||
|
|
||||||
bool CheckForCompatibleQuestPlugins()
|
bool CheckForCompatibleQuestPlugins()
|
||||||
{
|
{
|
||||||
const std::vector<std::pair<std::string, bool *>> directories = {
|
|
||||||
{"lua_modules", nullptr},
|
|
||||||
{"plugins", nullptr}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool lua_found = false;
|
bool lua_found = false;
|
||||||
bool perl_found = false;
|
bool perl_found = false;
|
||||||
|
|
||||||
try {
|
auto check_dir = [&](const std::string& dir_path, bool& found) {
|
||||||
for (const auto &[directory, flag]: directories) {
|
if (!File::Exists(dir_path)) { return; }
|
||||||
std::string dir_path = PathManager::Instance()->GetServerPath() + "/" + directory;
|
try {
|
||||||
if (!File::Exists(dir_path)) { continue; }
|
for (const auto& file : fs::directory_iterator(dir_path)) {
|
||||||
|
|
||||||
for (const auto &file: fs::directory_iterator(dir_path)) {
|
|
||||||
if (!file.is_regular_file()) { continue; }
|
if (!file.is_regular_file()) { continue; }
|
||||||
|
auto r = File::GetContents(file.path().string());
|
||||||
std::string file_path = file.path().string();
|
if (Strings::Contains(r.contents, "CheckHandin")) {
|
||||||
if (!File::Exists(file_path)) { continue; }
|
found = true;
|
||||||
|
return;
|
||||||
auto r = File::GetContents(file_path);
|
|
||||||
if (!Strings::Contains(r.contents, "CheckHandin")) { continue; }
|
|
||||||
|
|
||||||
if (directory == "lua_modules") {
|
|
||||||
lua_found = true;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
perl_found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lua_found && perl_found) { return true; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const fs::filesystem_error &ex) {
|
catch (const fs::filesystem_error& ex) {
|
||||||
LogError("Failed to check for compatible quest plugins: {}", ex.what());
|
LogError("Failed to check for compatible quest plugins: {}", ex.what());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& path : PathManager::Instance()->GetLuaModulePaths()) {
|
||||||
|
check_dir(path, lua_found);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lua_found) {
|
for (const auto& path : PathManager::Instance()->GetPluginPaths()) {
|
||||||
LogError("Failed to find CheckHandin in lua_modules");
|
check_dir(path, perl_found);
|
||||||
}
|
|
||||||
if (!perl_found) {
|
|
||||||
LogError("Failed to find CheckHandin in plugins");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!lua_found) { LogError("Failed to find CheckHandin in the Lua module quest directories"); }
|
||||||
|
if (!perl_found) { LogError("Failed to find CheckHandin in the Perl plugins quest directories");}
|
||||||
|
|
||||||
return lua_found && perl_found;
|
return lua_found && perl_found;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-23
@@ -512,29 +512,6 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk)
|
|||||||
|
|
||||||
bool found_skill = false;
|
bool found_skill = false;
|
||||||
|
|
||||||
if (
|
|
||||||
ca_atk->m_atk == 100 &&
|
|
||||||
ca_atk->m_skill == EQ::skills::SkillKick &&
|
|
||||||
can_use_kick
|
|
||||||
) {
|
|
||||||
if (GetTarget() != this) {
|
|
||||||
CheckIncreaseSkill(EQ::skills::SkillKick, GetTarget(), 10);
|
|
||||||
DoAnim(animKick, 0, false);
|
|
||||||
|
|
||||||
int hate_override = 0;
|
|
||||||
if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotFeet)) <= 0) {
|
|
||||||
damage = -5;
|
|
||||||
} else {
|
|
||||||
hate_override = damage = GetBaseSkillDamage(EQ::skills::SkillKick, GetTarget());
|
|
||||||
}
|
|
||||||
|
|
||||||
reuse_time = KickReuseTime - 1 - skill_reduction;
|
|
||||||
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillKick, damage, 0, hate_override, reuse_time);
|
|
||||||
|
|
||||||
found_skill = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (class_id == Class::Monk) {
|
if (class_id == Class::Monk) {
|
||||||
reuse_time = MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction;
|
reuse_time = MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction;
|
||||||
|
|
||||||
@@ -596,6 +573,30 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk)
|
|||||||
|
|
||||||
found_skill = true;
|
found_skill = true;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (
|
||||||
|
ca_atk->m_atk == 100 &&
|
||||||
|
ca_atk->m_skill == EQ::skills::SkillKick &&
|
||||||
|
can_use_kick
|
||||||
|
) {
|
||||||
|
if (GetTarget() != this) {
|
||||||
|
CheckIncreaseSkill(EQ::skills::SkillKick, GetTarget(), 10);
|
||||||
|
DoAnim(animKick, 0, false);
|
||||||
|
|
||||||
|
int hate_override = 0;
|
||||||
|
if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotFeet)) <= 0) {
|
||||||
|
damage = -5;
|
||||||
|
} else {
|
||||||
|
hate_override = damage = GetBaseSkillDamage(EQ::skills::SkillKick, GetTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
reuse_time = KickReuseTime - 1 - skill_reduction;
|
||||||
|
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillKick, damage, 0, hate_override, reuse_time);
|
||||||
|
|
||||||
|
found_skill = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ca_atk->m_atk == 100 &&
|
ca_atk->m_atk == 100 &&
|
||||||
|
|||||||
Reference in New Issue
Block a user