Merge branch 'master' into bot-rewrite

This commit is contained in:
nytmyr
2025-01-20 00:29:12 -06:00
62 changed files with 5065 additions and 1412 deletions
+1
View File
@@ -17,6 +17,7 @@ SET(zone_sources
botspellsai.cpp
cheat_manager.cpp
client.cpp
client_evolving_items.cpp
client_bot.cpp
client_mods.cpp
client_packet.cpp
+1 -1
View File
@@ -2812,7 +2812,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
if (con_level != ConsiderColor::Gray) {
if (!GetOwner() || (GetOwner() && !GetOwner()->IsClient())) {
give_exp_client->AddEXP(ExpSource::Kill, final_exp, con_level);
give_exp_client->AddEXP(ExpSource::Kill, final_exp, con_level, false, this);
if (
killer_mob &&
+17
View File
@@ -13419,3 +13419,20 @@ void Client::SendSpellTypePrompts(bool commanded_types, bool client_only_types)
return;
}
void Client::SetAAEXPPercentage(uint8 percentage)
{
const uint32 before_percentage = m_epp.perAA;
if (before_percentage > 0 && percentage == 0) {
MessageString(Chat::White, AA_OFF);
}
else if (before_percentage == 0 && percentage > 0) {
MessageString(Chat::White, AA_ON);
}
m_epp.perAA = EQ::Clamp(static_cast<int>(percentage), 0, 100);
SendAlternateAdvancementStats();
SendAlternateAdvancementTable();
}
+25 -3
View File
@@ -72,6 +72,7 @@ namespace EQ
#include "../common/repositories/trader_repository.h"
#include "../common/guild_base.h"
#include "../common/repositories/buyer_buy_lines_repository.h"
#include "../common/repositories/character_evolving_items_repository.h"
#ifdef _WINDOWS
// since windows defines these within windef.h (which windows.h include)
@@ -294,7 +295,7 @@ public:
void SendBazaarDone(uint32 trader_id);
void SendBulkBazaarTraders();
void SendBulkBazaarBuyers();
void DoBazaarInspect(const BazaarInspect_Struct &in);
void DoBazaarInspect(BazaarInspect_Struct &in);
void SendBazaarDeliveryCosts();
static std::string DetermineMoneyString(uint64 copper);
@@ -692,6 +693,8 @@ public:
void SetAAEXPModifier(uint32 zone_id, float aa_modifier, int16 instance_version = -1);
void SetEXPModifier(uint32 zone_id, float exp_modifier, int16 instance_version = -1);
void SetAAEXPPercentage(uint8 percentage);
bool UpdateLDoNPoints(uint32 theme_id, int points);
void SetLDoNPoints(uint32 theme_id, uint32 points);
void SetPVPPoints(uint32 Points) { m_pp.PVPCurrentPoints = Points; }
@@ -708,13 +711,13 @@ public:
void SendCrystalCounts();
uint64 GetExperienceForKill(Mob *against);
void AddEXP(ExpSource exp_source, uint64 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
void AddEXP(ExpSource exp_source, uint64 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false, NPC* npc = nullptr);
uint64 CalcEXP(uint8 conlevel = 0xFF, bool ignore_mods = false);
void CalculateNormalizedAAExp(uint64 &add_aaxp, uint8 conlevel, bool resexp);
void CalculateStandardAAExp(uint64 &add_aaxp, uint8 conlevel, bool resexp);
void CalculateLeadershipExp(uint64 &add_exp, uint8 conlevel);
void CalculateExp(uint64 in_add_exp, uint64 &add_exp, uint64 &add_aaxp, uint8 conlevel, bool resexp);
void SetEXP(ExpSource exp_source, uint64 set_exp, uint64 set_aaxp, bool resexp = false);
void SetEXP(ExpSource exp_source, uint64 set_exp, uint64 set_aaxp, bool resexp = false, NPC* npc = nullptr);
void AddLevelBasedExp(ExpSource exp_source, uint8 exp_percentage, uint8 max_level = 0, bool ignore_mods = false);
void SetLeadershipEXP(uint64 group_exp, uint64 raid_exp);
void AddLeadershipEXP(uint64 group_exp, uint64 raid_exp);
@@ -1128,6 +1131,10 @@ public:
void SetTrader(bool status) { trader = status; }
uint16 GetTraderID() { return trader_id; }
void SetTraderID(uint16 id) { trader_id = id; }
void SetTraderCount(uint32 no) { m_trader_count = no; }
uint32 GetTraderCount() { return m_trader_count; }
void IncrementTraderCount() { m_trader_count += 1; }
void DecrementTraderCount() { m_trader_count > 0 ? m_trader_count -= 1 : m_trader_count = 0; }
eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; }
void SetFilter(eqFilterType filter_id, eqFilterMode filter_mode) { ClientFilters[filter_id] = filter_mode; }
@@ -1825,6 +1832,18 @@ public:
void RecordKilledNPCEvent(NPC *n);
uint32 GetEXPForLevel(uint16 check_level);
// Evolving Item Info
void ProcessEvolvingItem(const uint64 exp, const Mob* mob);
void SendEvolvingPacket(int8 action, const CharacterEvolvingItemsRepository::CharacterEvolvingItems &item);
void DoEvolveItemToggle(const EQApplicationPacket* app);
void DoEvolveItemDisplayFinalResult(const EQApplicationPacket* app);
bool DoEvolveCheckProgression(const EQ::ItemInstance &inst);
void SendEvolveXPWindowDetails(const EQApplicationPacket* app);
void DoEvolveTransferXP(const EQApplicationPacket* app);
void SendEvolveXPTransferWindow();
void SendEvolveTransferResults(const EQ::ItemInstance &inst_from, const EQ::ItemInstance &inst_to, const EQ::ItemInstance &inst_from_new, const EQ::ItemInstance &inst_to_new, const uint32 compatibility, const uint32 max_transfer_level);
protected:
friend class Mob;
void CalcEdibleBonuses(StatBonuses* newbon);
@@ -1961,6 +1980,7 @@ private:
uint8 firstlogon;
uint32 mercid; // current merc
uint8 mercSlot; // selected merc slot
uint32 m_trader_count{};
uint32 m_buyer_id;
uint32 m_barter_time;
int32 m_parcel_platinum;
@@ -1983,6 +2003,8 @@ private:
uint16 m_door_tool_entity_id;
uint16 m_object_tool_entity_id;
public:
uint16 GetDoorToolEntityId() const;
void SetDoorToolEntityId(uint16 door_tool_entity_id);
+451
View File
@@ -0,0 +1,451 @@
#include "../common/evolving_items.h"
#include "../common/events/player_event_logs.h"
#include "../common/global_define.h"
#include "client.h"
#include "string_ids.h"
#include "worldserver.h"
extern WorldServer worldserver;
void Client::DoEvolveItemToggle(const EQApplicationPacket *app)
{
const auto in = reinterpret_cast<EvolveItemToggle *>(app->pBuffer);
auto item = CharacterEvolvingItemsRepository::FindOne(database, in->unique_id);
LogEvolveItemDetail(
"Character ID <green>[{}] requested to set evolve item with unique id <yellow>[{}] to status <yellow>[{}]",
CharacterID(),
in->unique_id,
in->activated
);
if (!item.id) {
LogEvolveItemDetail(
"Character ID <green>[{}] toggle evolve item unique id <yellow>[{}] failed", CharacterID(), in->unique_id);
return;
}
item.activated = in->activated;
const auto inst = GetInv().GetItem(GetInv().HasItem(item.item_id));
inst->SetEvolveActivated(item.activated ? true : false);
CharacterEvolvingItemsRepository::ReplaceOne(database, item);
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, item);
}
void Client::SendEvolvingPacket(const int8 action, const CharacterEvolvingItemsRepository::CharacterEvolvingItems &item)
{
auto out = std::make_unique<EQApplicationPacket>(OP_EvolveItem, sizeof(EvolveItemToggle));
const auto data = reinterpret_cast<EvolveItemToggle *>(out->pBuffer);
LogEvolveItemDetail(
"Character ID <green>[{}] requested info for evolving item with unique id <yellow>[{}] status <yellow>[{}] "
"percentage <yellow>[{}]",
CharacterID(),
item.id,
item.activated,
item.progression
);
data->action = action;
data->unique_id = item.id;
data->percentage = item.progression;
data->activated = item.activated;
QueuePacket(out.get());
LogEvolveItem(
"Sent evolve item with unique id <yellow>[{}] status <yellow>[{}] percentage <yellow>[{}] to Character ID "
"<green>[{}]",
data->unique_id,
data->activated,
data->percentage,
CharacterID()
);
}
void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
{
std::vector<const EQ::ItemInstance *> queue{};
for (auto &[key, inst]: GetInv().GetWorn()) {
LogEvolveItemDetail(
"CharacterID <green>[{}] found equipped item ID <yellow>[{}]", CharacterID(), inst->GetID());
if (!inst->IsEvolving() || !inst->GetEvolveActivated()) {
LogEvolveItemDetail(
"CharacterID <green>[{}], item ID <yellow>[{}] not an evolving item.", CharacterID(), inst->GetID());
continue;
}
if (inst->GetTimers().contains("evolve") && !inst->GetTimers().at("evolve").Check()) {
LogEvolveItemDetail(
"CharacterID <green>[{}], item ID <yellow>[{}] timer not yet expired. <red>[{}] secs remaining.",
CharacterID(),
inst->GetID(),
inst->GetTimers().at("evolve").GetRemainingTime() / 1000);
continue;
}
auto const type = evolving_items_manager.GetEvolvingItemsCache().at(inst->GetID()).type;
auto const sub_type = evolving_items_manager.GetEvolvingItemsCache().at(inst->GetID()).sub_type;
LogEvolveItemDetail(
"CharacterID <green>[{}] item id <green>[{}] type {} sub_type {} is Evolving. Continue processing...",
CharacterID(),
inst->GetID(),
type,
sub_type);
switch (type) {
case EvolvingItems::Types::AMOUNT_OF_EXP: {
LogEvolveItemDetail("Type <green>[{}] Processing sub_type", type);
if (sub_type == EvolvingItems::SubTypes::ALL_EXP ||
(sub_type == EvolvingItems::SubTypes::GROUP_EXP && IsGrouped())) {
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
inst->SetEvolveAddToCurrentAmount(exp * RuleR(EvolvingItems, PercentOfGroupExperience) / 100);
}
else if (
sub_type == EvolvingItems::SubTypes::ALL_EXP ||
(sub_type == EvolvingItems::SubTypes::RAID_EXP && IsRaidGrouped())) {
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
inst->SetEvolveAddToCurrentAmount(exp * RuleR(EvolvingItems, PercentOfRaidExperience) / 100);
}
else if (
sub_type == EvolvingItems::SubTypes::ALL_EXP || sub_type == EvolvingItems::SubTypes::SOLO_EXP) {
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
inst->SetEvolveAddToCurrentAmount(exp * RuleR(EvolvingItems, PercentOfSoloExperience) / 100);
}
inst->CalculateEvolveProgression();
auto e = CharacterEvolvingItemsRepository::SetCurrentAmountAndProgression(
database, inst->GetEvolveUniqueID(), inst->GetEvolveCurrentAmount(), inst->GetEvolveProgression());
if (!e.id) {
break;
}
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, e);
LogEvolveItem(
"Processing Complete for item id <green>[{1}] Type 1 Amount of EXP - SubType <yellow>[{0}] - "
"Assigned <yellow>[{2}] of exp to <green>[{1}]",
sub_type,
inst->GetID(),
exp * 0.001
);
if (inst->GetEvolveProgression() >= 100) {
queue.push_back(inst);
}
break;
}
case EvolvingItems::Types::SPECIFIC_MOB_RACE: {
LogEvolveItemDetail("Type <green>[{}] Processing sub type", type);
if (mob && mob->GetRace() == sub_type) {
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
inst->SetEvolveAddToCurrentAmount(1);
inst->CalculateEvolveProgression();
auto e = CharacterEvolvingItemsRepository::SetCurrentAmountAndProgression(
database,
inst->GetEvolveUniqueID(),
inst->GetEvolveCurrentAmount(),
inst->GetEvolveProgression());
if (!e.id) {
break;
}
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, e);
LogEvolveItem(
"Processing Complete for item id <green>[{1}] Type 3 Specific Mob Race - SubType <yellow>[{0}] "
"- Increased count by 1 for <green>[{1}]",
sub_type,
inst->GetID()
);
}
if (inst->GetEvolveProgression() >= 100) {
queue.push_back(inst);
}
break;
}
case EvolvingItems::Types::SPECIFIC_ZONE_ID: {
LogEvolveItemDetail("Type <green>[{}] Processing sub type", type);
if (mob && mob->GetZoneID() == sub_type) {
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
inst->SetEvolveAddToCurrentAmount(1);
inst->CalculateEvolveProgression();
auto e = CharacterEvolvingItemsRepository::SetCurrentAmountAndProgression(
database,
inst->GetEvolveUniqueID(),
inst->GetEvolveCurrentAmount(),
inst->GetEvolveProgression());
if (!e.id) {
break;
}
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, e);
LogEvolveItem(
"Processing Complete for item id <green>[{1}] Type 4 Specific Zone ID - SubType <yellow>[{0}] "
"- Increased count by 1 for <green>[{1}]",
sub_type,
inst->GetID()
);
}
if (inst->GetEvolveProgression() >= 100) {
queue.push_back(inst);
}
break;
}
default: {
}
}
}
if (!queue.empty()) {
for (auto const &i: queue) {
DoEvolveCheckProgression(*i);
}
}
}
void Client::DoEvolveItemDisplayFinalResult(const EQApplicationPacket *app)
{
const auto in = reinterpret_cast<EvolveItemToggle *>(app->pBuffer);
const uint32 item_id = static_cast<uint32>(in->unique_id & 0xFFFFFFFF);
if (item_id == 0) {
LogEvolveItem("Error - Item ID of final evolve item is blank.");
return;
}
std::unique_ptr<EQ::ItemInstance> const inst(database.CreateItem(item_id));
LogEvolveItemDetail(
"Character ID <green>[{}] requested to view final evolve item id <yellow>[{}] for evolve item id <yellow>[{}]",
CharacterID(),
item_id,
evolving_items_manager.GetFirstItemInLoreGroupByItemID(item_id));
inst->SetEvolveProgression(100);
if (inst) {
LogEvolveItemDetail(
"Sending final result for item id <yellow>[{}] to Character ID <green>[{}]", item_id, CharacterID());
SendItemPacket(0, inst.get(), ItemPacketViewLink);
}
}
bool Client::DoEvolveCheckProgression(const EQ::ItemInstance &inst)
{
if (inst.GetEvolveProgression() < 100 || inst.GetEvolveLvl() == inst.GetMaxEvolveLvl()) {
return false;
}
const auto new_item_id = evolving_items_manager.GetNextEvolveItemID(inst);
if (!new_item_id) {
return false;
}
std::unique_ptr<EQ::ItemInstance> const new_inst(database.CreateItem(new_item_id));
PlayerEvent::EvolveItem e{};
RemoveItemBySerialNumber(inst.GetSerialNumber());
evolving_items_manager.LoadPlayerEvent(inst, e);
e.status = "Evolved Item due to obtaining progression - Old Evolve Item removed from inventory.";
RecordPlayerEventLog(PlayerEvent::EVOLVE_ITEM, e);
PushItemOnCursor(*new_inst, true);
evolving_items_manager.LoadPlayerEvent(*new_inst, e);
e.status = "Evolved Item due to obtaining progression - New Evolve Item placed in inventory.";
RecordPlayerEventLog(PlayerEvent::EVOLVE_ITEM, e);
MessageString(Chat::Yellow, EVOLVE_ITEM_EVOLVED, inst.GetItem()->Name);
LogEvolveItem(
"Evolved item id <red>[{}] into item id <green>[{}] for Character ID <green>[{}]",
inst.GetID(),
new_inst->GetID(),
CharacterID());
return true;
}
void Client::SendEvolveXPTransferWindow()
{
auto out = std::make_unique<EQApplicationPacket>(OP_EvolveItem, sizeof(EvolveItemToggle));
const auto data = reinterpret_cast<EvolveItemToggle *>(out->pBuffer);
data->action = 1;
QueuePacket(out.get());
}
void Client::SendEvolveXPWindowDetails(const EQApplicationPacket *app)
{
const auto in = reinterpret_cast<EvolveXPWindowReceive *>(app->pBuffer);
const auto item_1_slot =
GetInv().HasEvolvingItem(in->item1_unique_id, 1, invWherePersonal | invWhereWorn | invWhereCursor);
const auto item_2_slot =
GetInv().HasEvolvingItem(in->item2_unique_id, 1, invWherePersonal | invWhereWorn | invWhereCursor);
if (item_1_slot == INVALID_INDEX || item_2_slot == INVALID_INDEX) {
return;
}
const auto inst_from = GetInv().GetItem(item_1_slot);
const auto inst_to = GetInv().GetItem(item_2_slot);
if (!inst_from || !inst_to) {
return;
}
const auto results = evolving_items_manager.DetermineTransferResults(*inst_from, *inst_to);
if (!results.item_from_id || !results.item_to_id) {
SendEvolveTransferResults(*inst_from, *inst_to, *inst_from, *inst_to, 0, 0);
return;
}
std::unique_ptr<EQ::ItemInstance> const inst_from_new(database.CreateItem(results.item_from_id));
std::unique_ptr<EQ::ItemInstance> const inst_to_new(database.CreateItem(results.item_to_id));
if (!inst_from_new || !inst_to_new) {
SendEvolveTransferResults(*inst_from, *inst_to, *inst_from, *inst_to, 0, 0);
return;
}
inst_from_new->SetEvolveCurrentAmount(results.item_from_current_amount);
inst_from_new->CalculateEvolveProgression();
inst_to_new->SetEvolveCurrentAmount(results.item_to_current_amount);
inst_to_new->CalculateEvolveProgression();
SendEvolveTransferResults(
*inst_from, *inst_to, *inst_from_new, *inst_to_new, results.compatibility, results.max_transfer_level);
}
void Client::DoEvolveTransferXP(const EQApplicationPacket *app)
{
const auto in = reinterpret_cast<EvolveXPWindowReceive *>(app->pBuffer);
const auto item_1_slot =
GetInv().HasEvolvingItem(in->item1_unique_id, 1, invWherePersonal | invWhereWorn | invWhereCursor);
const auto item_2_slot =
GetInv().HasEvolvingItem(in->item2_unique_id, 1, invWherePersonal | invWhereWorn | invWhereCursor);
if (item_1_slot == INVALID_INDEX || item_2_slot == INVALID_INDEX) {
return;
}
const auto inst_from = GetInv().GetItem(item_1_slot);
const auto inst_to = GetInv().GetItem(item_2_slot);
if (!inst_from || !inst_to) {
Message(Chat::Red, "Transfer Failed. Incompatible Items.");
LogEvolveItem("Transfer Failed for Character ID <green>[{}]", CharacterID());
return;
}
const auto results = evolving_items_manager.DetermineTransferResults(*inst_from, *inst_to);
if (!results.item_from_id || !results.item_to_id) {
Message(Chat::Red, "Transfer Failed. Incompatible Items.");
LogEvolveItem("Transfer Failed for Character ID <green>[{}]", CharacterID());
return;
}
std::unique_ptr<const EQ::ItemInstance> const inst_from_new(database.CreateItem(results.item_from_id));
std::unique_ptr<const EQ::ItemInstance> const inst_to_new(database.CreateItem(results.item_to_id));
if (!inst_from_new || !inst_to_new) {
Message(Chat::Red, "Transfer Failed. Incompatible Items.");
LogEvolveItem("Transfer Failed for Character ID <green>[{}]", CharacterID());
return;
}
inst_from_new->SetEvolveCurrentAmount(results.item_from_current_amount);
inst_from_new->CalculateEvolveProgression();
inst_to_new->SetEvolveCurrentAmount(results.item_to_current_amount);
inst_to_new->CalculateEvolveProgression();
PlayerEvent::EvolveItem e{};
RemoveItemBySerialNumber(inst_from->GetSerialNumber());
evolving_items_manager.LoadPlayerEvent(*inst_from, e);
e.status = "Transfer XP - Original FROM Evolve Item removed from inventory.";
RecordPlayerEventLog(PlayerEvent::EVOLVE_ITEM, e);
PushItemOnCursor(*inst_from_new, true);
evolving_items_manager.LoadPlayerEvent(*inst_from_new, e);
e.status = "Transfer XP - Updated FROM item placed in inventory.";
RecordPlayerEventLog(PlayerEvent::EVOLVE_ITEM, e);
RemoveItemBySerialNumber(inst_to->GetSerialNumber());
evolving_items_manager.LoadPlayerEvent(*inst_to, e);
e.status = "Transfer XP - Original TO Evolve Item removed from inventory.";
RecordPlayerEventLog(PlayerEvent::EVOLVE_ITEM, e);
PushItemOnCursor(*inst_to_new, true);
evolving_items_manager.LoadPlayerEvent(*inst_to_new, e);
e.status = "Transfer XP - Updated TO Evolve item placed in inventory.";
RecordPlayerEventLog(PlayerEvent::EVOLVE_ITEM, e);
LogEvolveItem(
"Evolve Transfer XP resulted in evolved item id <red>[{}] into item id <green>[{}] for Character ID "
"<green>[{}]",
inst_to->GetID(),
inst_to_new->GetID(),
CharacterID()
);
}
void Client::SendEvolveTransferResults(
const EQ::ItemInstance &inst_from,
const EQ::ItemInstance &inst_to,
const EQ::ItemInstance &inst_from_new,
const EQ::ItemInstance &inst_to_new,
const uint32 compatibility,
const uint32 max_transfer_level)
{
std::stringstream ss;
cereal::BinaryOutputArchive ar(ss);
EvolveXPWindowSend e{};
e.action = EvolvingItems::Actions::TRANSFER_WINDOW_DETAILS;
e.compatibility = compatibility;
e.item1_unique_id = inst_from.GetEvolveUniqueID();
e.item2_unique_id = inst_to.GetEvolveUniqueID();
e.max_transfer_level = max_transfer_level;
e.item1_present = 1;
e.item2_present = 1;
e.serialize_item_1 = inst_from_new.Serialize(0);
e.serialize_item_2 = inst_to_new.Serialize(0);
{
ar(e);
}
uint32 packet_size = sizeof(EvolveItemMessaging) + ss.str().length();
std::unique_ptr<EQApplicationPacket> out(new EQApplicationPacket(OP_EvolveItem, packet_size));
const auto data = reinterpret_cast<EvolveItemMessaging *>(out->pBuffer);
data->action = EvolvingItems::Actions::TRANSFER_WINDOW_DETAILS;
memcpy(data->serialized_data, ss.str().data(), ss.str().length());
QueuePacket(out.get());
ss.str("");
ss.clear();
}
+89 -4
View File
@@ -80,7 +80,6 @@ extern PetitionList petition_list;
extern EntityList entity_list;
typedef void (Client::*ClientPacketProc)(const EQApplicationPacket *app);
//Use a map for connecting opcodes since it dosent get used a lot and is sparse
std::map<uint32, ClientPacketProc> ConnectingOpcodes;
//Use a static array for connected, for speed
@@ -208,6 +207,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_Emote] = &Client::Handle_OP_Emote;
ConnectedOpcodes[OP_EndLootRequest] = &Client::Handle_OP_EndLootRequest;
ConnectedOpcodes[OP_EnvDamage] = &Client::Handle_OP_EnvDamage;
ConnectedOpcodes[OP_EvolveItem] = &Client::Handle_OP_EvolveItem;
ConnectedOpcodes[OP_FaceChange] = &Client::Handle_OP_FaceChange;
ConnectedOpcodes[OP_FeignDeath] = &Client::Handle_OP_FeignDeath;
ConnectedOpcodes[OP_FindPersonRequest] = &Client::Handle_OP_FindPersonRequest;
@@ -283,6 +283,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_ItemLinkResponse] = &Client::Handle_OP_ItemLinkResponse;
ConnectedOpcodes[OP_ItemName] = &Client::Handle_OP_ItemName;
ConnectedOpcodes[OP_ItemPreview] = &Client::Handle_OP_ItemPreview;
ConnectedOpcodes[OP_ItemPreviewRequest] = &Client::Handle_OP_ItemPreviewRequest;
ConnectedOpcodes[OP_ItemVerifyRequest] = &Client::Handle_OP_ItemVerifyRequest;
ConnectedOpcodes[OP_ItemViewUnknown] = &Client::Handle_OP_Ignore;
ConnectedOpcodes[OP_Jump] = &Client::Handle_OP_Jump;
@@ -1313,7 +1314,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
// set to full support in case they're a gm with items in disabled expansion slots...but, have their gm flag off...
// item loss will occur when they use the 'empty' slots, if this is not done
m_inv.SetGMInventory(true);
loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */
loaditems = database.GetInventory(this); /* Load Character Inventory */
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */
@@ -1873,8 +1874,9 @@ void Client::Handle_OP_AAAction(const EQApplicationPacket *app)
PurchaseAlternateAdvancementRank(action->ability);
}
else if (action->action == aaActionDisableEXP) { //Turn Off AA Exp
if (m_epp.perAA > 0)
if (m_epp.perAA > 0) {
MessageString(Chat::White, AA_OFF);
}
m_epp.perAA = 0;
SendAlternateAdvancementStats();
@@ -9309,6 +9311,30 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)
return;
}
void Client::Handle_OP_ItemPreviewRequest(const EQApplicationPacket* app)
{
VERIFY_PACKET_LENGTH(OP_ItemPreviewRequest, app, ItemPreview_Struct);
auto ips = (ItemPreview_Struct*) app->pBuffer;
const EQ::ItemData* item = database.GetItem(ips->itemid);
if (item) {
EQ::ItemInstance* inst = database.CreateItem(item);
if (inst) {
std::string packet = inst->Serialize(-1);
auto outapp = new EQApplicationPacket(OP_ItemPreviewRequest, packet.length());
memcpy(outapp->pBuffer, packet.c_str(), packet.length());
#if EQDEBUG >= 9
DumpPacket(outapp);
#endif
QueuePacket(outapp);
safe_delete(outapp);
safe_delete(inst);
}
}
}
void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
{
using EQ::spells::CastingSlot;
@@ -10757,7 +10783,12 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
InterrogateInventory(this, true, false, true, error);
}
return;
for (int slot : {mi->to_slot, mi->from_slot}) {
auto item = GetInv().GetItem(slot);
if (item && item->IsEvolving()) {
CharacterEvolvingItemsRepository::UpdateOne(database, item->GetEvolvingDetails());
}
}
}
void Client::Handle_OP_MoveMultipleItems(const EQApplicationPacket *app)
@@ -15540,6 +15571,26 @@ void Client::Handle_OP_TraderBuy(const EQApplicationPacket *app)
// Client has elected to buy an item from a Trader
//
auto in = (TraderBuy_Struct *) app->pBuffer;
if (RuleB(Bazaar, UseAlternateBazaarSearch) && in->trader_id >= TraderRepository::TRADER_CONVERT_ID) {
auto trader = TraderRepository::GetTraderByInstanceAndSerialnumber(
database,
in->trader_id - TraderRepository::TRADER_CONVERT_ID,
in->serial_number
);
if (!trader.trader_id) {
LogTrading("Unable to convert trader id for {} and serial number {}. Trader Buy aborted.",
in->trader_id - TraderRepository::TRADER_CONVERT_ID,
in->serial_number
);
return;
}
in->trader_id = trader.trader_id;
strn0cpy(in->seller_name, trader.trader_name.c_str(), sizeof(in->seller_name));
}
auto trader = entity_list.GetClientByID(in->trader_id);
switch (in->method) {
@@ -17175,3 +17226,37 @@ void Client::Handle_OP_ShopRetrieveParcel(const EQApplicationPacket *app)
auto parcel_in = (ParcelRetrieve_Struct *)app->pBuffer;
DoParcelRetrieve(*parcel_in);
}
void Client::Handle_OP_EvolveItem(const EQApplicationPacket *app)
{
if (app->size != sizeof(EvolveItemToggle)) {
LogError(
"Received Handle_OP_EvolveItem packet. Expected size {}, received size {}.",
sizeof(EvolveItemToggle),
app->size
);
return;
}
auto in = reinterpret_cast<EvolveItemToggle *>(app->pBuffer);
switch (in->action) {
case EvolvingItems::Actions::UPDATE_ITEMS: {
DoEvolveItemToggle(app);
break;
}
case EvolvingItems::Actions::FINAL_RESULT: {
DoEvolveItemDisplayFinalResult(app);
break;
}
case EvolvingItems::Actions::TRANSFER_XP: {
DoEvolveTransferXP(app);
break;
}
case EvolvingItems::Actions::TRANSFER_WINDOW_DETAILS: {
SendEvolveXPWindowDetails(app);
}
default: {
}
}
}
+2
View File
@@ -114,6 +114,7 @@
void Handle_OP_Emote(const EQApplicationPacket *app);
void Handle_OP_EndLootRequest(const EQApplicationPacket *app);
void Handle_OP_EnvDamage(const EQApplicationPacket *app);
void Handle_OP_EvolveItem(const EQApplicationPacket *app);
void Handle_OP_FaceChange(const EQApplicationPacket *app);
void Handle_OP_FeignDeath(const EQApplicationPacket *app);
void Handle_OP_FindPersonRequest(const EQApplicationPacket *app);
@@ -188,6 +189,7 @@
void Handle_OP_ItemLinkResponse(const EQApplicationPacket *app);
void Handle_OP_ItemName(const EQApplicationPacket *app);
void Handle_OP_ItemPreview(const EQApplicationPacket *app);
void Handle_OP_ItemPreviewRequest(const EQApplicationPacket *app);
void Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app);
void Handle_OP_Jump(const EQApplicationPacket *app);
void Handle_OP_KeyRing(const EQApplicationPacket *app);
+2
View File
@@ -126,6 +126,7 @@ int command_init(void)
command_add("enablerecipe", "[Recipe ID] - Enables a Recipe", AccountStatus::QuestTroupe, command_enablerecipe) ||
command_add("entityvariable", "[clear|delete|set|view] - Modify entity variables for yourself or your target", AccountStatus::GMAdmin, command_entityvariable) ||
command_add("exptoggle", "[Toggle] - Toggle your or your target's experience gain.", AccountStatus::QuestTroupe, command_exptoggle) ||
command_add("evolve", "Evolving Item manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_evolvingitems) ||
command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", AccountStatus::QuestTroupe, command_faction) ||
command_add("factionassociation", "[factionid] [amount] - triggers a faction hits via association", AccountStatus::GMLeadAdmin, command_faction_association) ||
command_add("feature", "Change your or your target's feature's temporarily", AccountStatus::QuestTroupe, command_feature) ||
@@ -831,6 +832,7 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/entityvariable.cpp"
#include "gm_commands/exptoggle.cpp"
#include "gm_commands/faction.cpp"
#include "gm_commands/evolving_items.cpp"
#include "gm_commands/feature.cpp"
#include "gm_commands/find.cpp"
#include "gm_commands/fish.cpp"
+2
View File
@@ -38,6 +38,7 @@ void SendShowInventorySubCommands(Client *c);
void SendFixMobSubCommands(Client *c);
void SendDataBucketsSubCommands(Client *c);
void SendParcelsSubCommands(Client *c);
void SendEvolvingItemsSubCommands(Client *c);
// Commands
void command_acceptrules(Client *c, const Seperator *sep);
@@ -80,6 +81,7 @@ void command_emptyinventory(Client *c, const Seperator *sep);
void command_enablerecipe(Client *c, const Seperator *sep);
void command_entityvariable(Client *c, const Seperator *sep);
void command_exptoggle(Client *c, const Seperator *sep);
void command_evolvingitems(Client *c, const Seperator *sep);
void command_faction(Client *c, const Seperator *sep);
void command_faction_association(Client *c, const Seperator *sep);
void command_feature(Client *c, const Seperator *sep);
+5
View File
@@ -30,6 +30,7 @@
#include "string_ids.h"
#include "worldserver.h"
#include "zonedb.h"
#include "../common/evolving_items.h"
#include "../common/repositories/criteria/content_filter_criteria.h"
#include <string.h>
@@ -610,6 +611,10 @@ void Doors::HandleClick(Client *sender, uint8 trigger)
}
}
}
if (GetOpenType() == 40 && GetZone(GetDoorZone(),0)) {
sender->SendEvolveXPTransferWindow();
}
}
void Doors::Open(Mob *sender, bool alt_mode)
+2
View File
@@ -77,6 +77,8 @@ public:
bool IsDoorBlacklisted();
const char* GetDoorZone() const { return m_zone_name; }
private:
bool GetIsDoorBlacklisted();
+6 -5
View File
@@ -497,7 +497,7 @@ void Client::CalculateExp(uint64 in_add_exp, uint64 &add_exp, uint64 &add_aaxp,
add_exp = GetEXP() + add_exp;
}
void Client::AddEXP(ExpSource exp_source, uint64 in_add_exp, uint8 conlevel, bool resexp) {
void Client::AddEXP(ExpSource exp_source, uint64 in_add_exp, uint8 conlevel, bool resexp, NPC* npc) {
if (!IsEXPEnabled()) {
return;
}
@@ -574,10 +574,10 @@ void Client::AddEXP(ExpSource exp_source, uint64 in_add_exp, uint8 conlevel, boo
}
// Now update our character's normal and AA xp
SetEXP(exp_source, exp, aaexp, resexp);
SetEXP(exp_source, exp, aaexp, resexp, npc);
}
void Client::SetEXP(ExpSource exp_source, uint64 set_exp, uint64 set_aaxp, bool isrezzexp) {
void Client::SetEXP(ExpSource exp_source, uint64 set_exp, uint64 set_aaxp, bool isrezzexp, NPC* npc) {
uint64 current_exp = GetEXP();
uint64 current_aa_exp = GetAAXP();
uint64 total_current_exp = current_exp + current_aa_exp;
@@ -677,6 +677,7 @@ void Client::SetEXP(ExpSource exp_source, uint64 set_exp, uint64 set_aaxp, bool
}
}
}
ProcessEvolvingItem(exp_gained, npc);
} else if(total_add_exp < total_current_exp) { //only loss message if you lose exp, no message if you gained/lost nothing.
uint64 exp_lost = current_exp - set_exp;
float exp_percent = (float)((float)exp_lost / (float)(GetEXPForLevel(GetLevel() + 1) - GetEXPForLevel(GetLevel())))*(float)100;
@@ -1205,7 +1206,7 @@ void Group::SplitExp(ExpSource exp_source, const uint64 exp, Mob* other) {
if (diff >= max_diff) {
const uint64 tmp = (m->GetLevel() + 3) * (m->GetLevel() + 3) * 75 * 35 / 10;
const uint64 tmp2 = group_experience / member_count;
m->CastToClient()->AddEXP(exp_source, tmp < tmp2 ? tmp : tmp2, consider_level);
m->CastToClient()->AddEXP(exp_source, tmp < tmp2 ? tmp : tmp2, consider_level, false, other->CastToNPC());
}
}
}
@@ -1256,7 +1257,7 @@ void Raid::SplitExp(ExpSource exp_source, const uint64 exp, Mob* other) {
if (diff >= max_diff) {
const uint64 tmp = (m.member->GetLevel() + 3) * (m.member->GetLevel() + 3) * 75 * 35 / 10;
const uint64 tmp2 = (raid_experience / member_modifier) + 1;
m.member->AddEXP(exp_source, tmp < tmp2 ? tmp : tmp2, consider_level);
m.member->AddEXP(exp_source, tmp < tmp2 ? tmp : tmp2, consider_level, false, other->CastToNPC());
}
}
}
+301
View File
@@ -0,0 +1,301 @@
#include "../client.h"
#include "../command.h"
#include "../../common/evolving_items.h"
void command_evolvingitems(Client *c, const Seperator *sep)
{
const uint16 arguments = sep->argnum;
if (!arguments) {
SendEvolvingItemsSubCommands(c);
return;
}
Client* t = c;
if (c->GetTarget() && c->GetTarget()->IsClient()) {
t = c->GetTarget()->CastToClient();
}
const bool is_item = !strcasecmp(sep->arg[1], "item");
const bool is_target = !strcasecmp(sep->arg[1], "target");
if (!is_item && !is_target) {
SendEvolvingItemsSubCommands(c);
return;
}
if (is_target) {
if (arguments > 1) {
c->Message(Chat::White, "Usage: #evolve target");
} else {
c->Message(Chat::Red, "Worn Items");
for (auto const &[key, value]: t->GetInv().GetWorn()) {
if (!value->IsEvolving()) {
continue;
}
auto item = evolving_items_manager.GetEvolvingItemsCache().at(value->GetID());
c->Message(
Chat::Yellow,
fmt::format(
"Evolving Items | {:0d}",
value->GetID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Unique ID | {:0d}",
value->GetEvolveUniqueID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Final Item ID | {:0d}",
value->GetEvolveFinalItemID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Activated | {}",
value->GetEvolveActivated() ? "Yes" : "No"
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Equipped | {}",
value->GetEvolveEquipped() ? "Yes" : "No"
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Current Amount | {:0d}",
value->GetEvolveCurrentAmount()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Required Amount | {:0d}",
item.required_amount
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Progression (%) | {:.2f}",
value->GetEvolveProgression()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Type | {}",
item.type
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Subtype | {}",
item.sub_type
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Timer | {}",
value->GetTimers().at("evolve").Enabled()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Timer Remaining | {}",
value->GetTimers().at("evolve").GetRemainingTime()
).c_str()
);
}
c->Message(Chat::Red, "Personal Items");
for (auto const &[key, value]: t->GetInv().GetPersonal()) {
if (!value->IsEvolving()) {
continue;
}
auto item = evolving_items_manager.GetEvolvingItemsCache().at(value->GetID());
c->Message(
Chat::Yellow,
fmt::format(
"Evolving Items | {:0d}",
value->GetID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Unique ID | {:0d}",
value->GetEvolveUniqueID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Final Item ID | {:0d}",
value->GetEvolveFinalItemID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Activated | {}",
value->GetEvolveActivated() ? "Yes" : "No"
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Equipped | {}",
value->GetEvolveEquipped() ? "Yes" : "No"
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Current Amount | {:0d}",
value->GetEvolveCurrentAmount()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Required Amount | {:0d}",
item.required_amount
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Progression (%) | {:.2f}",
value->GetEvolveProgression()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Type | {}",
item.type
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Subtype | {}",
item.sub_type
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Timer | {}",
value->GetTimers().at("evolve").Enabled()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Timer Remaining | {}",
value->GetTimers().at("evolve").GetRemainingTime()
).c_str()
);
}
}
} else if (is_item) {
if (arguments > 2) {
c->Message(Chat::White, "Usage: #evolve item item_id");
} else if (sep->IsNumber(2)) {
auto item_id = Strings::ToUnsignedInt(sep->arg[2]);
auto item = c->GetInv().GetItem(c->GetInv().HasItem(item_id));
if (item) {
c->Message(
Chat::Yellow,
fmt::format(
"Evolving Items | {:0d}",
item->GetID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Slot | {:0d}",
c->GetInv().HasItem(item_id)
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Activated | {}",
item->GetEvolveActivated() ? "Yes" : "No"
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Equipped | {}",
item->GetEvolveEquipped() ? "Yes" : "No"
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Unique ID | {:0d}",
item->GetEvolveUniqueID()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Progression (%) | {:.2f}",
item->GetEvolveProgression()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Timer | {}",
item->GetTimers().at("evolve").Enabled()
).c_str()
);
c->Message(
Chat::Yellow,
fmt::format(
"Timer Remaining | {}",
item->GetTimers().at("evolve").GetRemainingTime()
).c_str()
);
} else {
c->Message(
Chat::Red,
fmt::format(
"Item {} could not be found in your inventory.",
item_id
).c_str()
);
}
} else {
SendEvolvingItemsSubCommands(c);
}
}
}
void SendEvolvingItemsSubCommands(Client *c)
{
c->Message(Chat::White, "#evolve item item_id (Shows evolve values within the iteminstance)");
c->Message(
Chat::White,
"#evolve target (Shows evolve values within the target's cache - Must have a player target selected.)"
);
}
+18 -8
View File
@@ -25,6 +25,7 @@
#include "zonedb.h"
#include "../common/events/player_event_logs.h"
#include "bot.h"
#include "../common/evolving_items.h"
#include "../common/repositories/character_corpse_items_repository.h"
extern WorldServer worldserver;
@@ -1091,7 +1092,11 @@ void Client::DeleteItemInInventory(int16 slot_id, int16 quantity, bool client_up
}
// end QS code
bool isDeleted = m_inv.DeleteItem(slot_id, quantity);
uint64 evolve_id = m_inv[slot_id]->GetEvolveUniqueID();
bool isDeleted = m_inv.DeleteItem(slot_id, quantity);
if (isDeleted && evolve_id && (slot_id > EQ::invslot::TRADE_END || slot_id < EQ::invslot::TRADE_BEGIN)) {
CharacterEvolvingItemsRepository::SoftDelete(database, evolve_id);
}
const EQ::ItemInstance* inst = nullptr;
if (slot_id == EQ::invslot::slotCursor) {
@@ -1143,6 +1148,8 @@ void Client::DeleteItemInInventory(int16 slot_id, int16 quantity, bool client_up
bool Client::PushItemOnCursor(const EQ::ItemInstance& inst, bool client_update)
{
LogInventory("Putting item [{}] ([{}]) on the cursor", inst.GetItem()->Name, inst.GetItem()->ID);
evolving_items_manager.DoLootChecks(CharacterID(), EQ::invslot::slotCursor, inst);
m_inv.PushCursor(inst);
if (client_update) {
@@ -1163,9 +1170,9 @@ bool Client::PutItemInInventory(int16 slot_id, const EQ::ItemInstance& inst, boo
if (slot_id == EQ::invslot::slotCursor) { // don't trust macros before conditional statements...
return PushItemOnCursor(inst, client_update);
}
else {
m_inv.PutItem(slot_id, inst);
}
evolving_items_manager.DoLootChecks(CharacterID(), slot_id, inst);
m_inv.PutItem(slot_id, inst);
if (client_update)
{
@@ -1173,15 +1180,16 @@ bool Client::PutItemInInventory(int16 slot_id, const EQ::ItemInstance& inst, boo
//SendWearChange(EQ::InventoryProfile::CalcMaterialFromSlot(slot_id));
}
CalcBonuses();
if (slot_id == EQ::invslot::slotCursor) {
auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend();
return database.SaveCursor(CharacterID(), s, e);
}
else {
return database.SaveInventory(CharacterID(), &inst, slot_id);
}
CalcBonuses();
return database.SaveInventory(CharacterID(), &inst, slot_id);
//CalcBonuses(); // this never fires??
// a lot of wasted checks and calls coded above...
}
@@ -1191,6 +1199,8 @@ void Client::PutLootInInventory(int16 slot_id, const EQ::ItemInstance &inst, Loo
bool cursor_empty = m_inv.CursorEmpty();
evolving_items_manager.DoLootChecks(CharacterID(), slot_id, inst);
if (slot_id == EQ::invslot::slotCursor) {
m_inv.PushCursor(inst);
auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend();
+7
View File
@@ -3458,6 +3458,12 @@ void Lua_Client::ShowZoneShardMenu()
self->ShowZoneShardMenu();
}
void Lua_Client::SetAAEXPPercentage(uint8 percentage)
{
Lua_Safe_Call_Void();
self->SetAAEXPPercentage(percentage);
}
luabind::scope lua_register_client() {
return luabind::class_<Lua_Client, Lua_Mob>("Client")
.def(luabind::constructor<>())
@@ -3890,6 +3896,7 @@ luabind::scope lua_register_client() {
.def("SetAAEXPModifier", (void(Lua_Client::*)(float))&Lua_Client::SetAAEXPModifier)
.def("SetAAEXPModifier", (void(Lua_Client::*)(uint32,float))&Lua_Client::SetAAEXPModifier)
.def("SetAAEXPModifier", (void(Lua_Client::*)(uint32,float,int16))&Lua_Client::SetAAEXPModifier)
.def("SetAAEXPPercentage", (void(Lua_Client::*)(uint8))&Lua_Client::SetAAEXPPercentage)
.def("SetAAPoints", (void(Lua_Client::*)(int))&Lua_Client::SetAAPoints)
.def("SetAATitle", (void(Lua_Client::*)(std::string))&Lua_Client::SetAATitle)
.def("SetAATitle", (void(Lua_Client::*)(std::string,bool))&Lua_Client::SetAATitle)
+1
View File
@@ -510,6 +510,7 @@ public:
void AreaTaunt(float range);
void AreaTaunt(float range, int bonus_hate);
luabind::object GetInventorySlots(lua_State* L);
void SetAAEXPPercentage(uint8 percentage);
void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration);
+105 -6
View File
@@ -255,11 +255,6 @@ int8 Lua_ItemInst::GetMaxEvolveLvl() {
return self->GetMaxEvolveLvl();
}
uint32 Lua_ItemInst::GetKillsNeeded(uint8 current_level) {
Lua_Safe_Call_Int();
return self->GetKillsNeeded(current_level);
}
Lua_ItemInst Lua_ItemInst::Clone() {
Lua_Safe_Call_Class(Lua_ItemInst);
return Lua_ItemInst(self->Clone(), true);
@@ -348,6 +343,96 @@ std::string Lua_ItemInst::GetItemLink()
return linker.GenerateLink();
}
void Lua_ItemInst::AddEvolveAmount(uint64 amount)
{
Lua_Safe_Call_Void();
self->SetEvolveAddToCurrentAmount(amount);
}
uint32 Lua_ItemInst::GetAugmentEvolveUniqueID(uint8 slot_id)
{
Lua_Safe_Call_Int();
return self->GetAugmentEvolveUniqueID(slot_id);
}
bool Lua_ItemInst::GetEvolveActivated()
{
Lua_Safe_Call_Bool();
return self->GetEvolveActivated();
}
uint64 Lua_ItemInst::GetEvolveAmount()
{
Lua_Safe_Call_Int();
return self->GetEvolveCurrentAmount();
}
uint32 Lua_ItemInst::GetEvolveCharacterID()
{
Lua_Safe_Call_Int();
return self->GetEvolveCharID();
}
bool Lua_ItemInst::GetEvolveEquipped()
{
Lua_Safe_Call_Bool();
return self->GetEvolveEquipped();
}
uint32 Lua_ItemInst::GetEvolveFinalItemID()
{
Lua_Safe_Call_Int();
return self->GetEvolveFinalItemID();
}
uint32 Lua_ItemInst::GetEvolveItemID()
{
Lua_Safe_Call_Int();
return self->GetEvolveItemID();
}
int8 Lua_ItemInst::GetEvolveLevel()
{
Lua_Safe_Call_Int();
return self->GetEvolveLvl();
}
uint32 Lua_ItemInst::GetEvolveLoreID()
{
Lua_Safe_Call_Int();
return self->GetEvolveLoreID();
}
float Lua_ItemInst::GetEvolveProgression()
{
Lua_Safe_Call_Real();
return self->GetEvolveProgression();
}
uint64 Lua_ItemInst::GetEvolveUniqueID()
{
Lua_Safe_Call_Int();
return self->GetEvolveUniqueID();
}
bool Lua_ItemInst::IsEvolving()
{
Lua_Safe_Call_Bool();
return self->IsEvolving();
}
void Lua_ItemInst::SetEvolveAmount(uint64 amount)
{
Lua_Safe_Call_Void();
self->SetEvolveCurrentAmount(amount);
}
void Lua_ItemInst::SetEvolveProgression(float amount)
{
Lua_Safe_Call_Void();
self->SetEvolveProgression(amount);
}
luabind::scope lua_register_iteminst() {
return luabind::class_<Lua_ItemInst>("ItemInst")
.def(luabind::constructor<>())
@@ -356,12 +441,14 @@ luabind::scope lua_register_iteminst() {
.property("null", &Lua_ItemInst::Null)
.property("valid", &Lua_ItemInst::Valid)
.def("AddExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::AddExp)
.def("AddEvolveAmount", (void(Lua_ItemInst::*)(uint64))&Lua_ItemInst::AddEvolveAmount)
.def("ClearTimers", (void(Lua_ItemInst::*)(void))&Lua_ItemInst::ClearTimers)
.def("Clone", (Lua_ItemInst(Lua_ItemInst::*)(void))&Lua_ItemInst::Clone)
.def("ContainsAugmentByID", (bool(Lua_ItemInst::*)(uint32))&Lua_ItemInst::ContainsAugmentByID)
.def("CountAugmentByID", (int(Lua_ItemInst::*)(uint32))&Lua_ItemInst::CountAugmentByID)
.def("DeleteCustomData", (void(Lua_ItemInst::*)(const std::string &))&Lua_ItemInst::DeleteCustomData)
.def("GetAugment", (Lua_ItemInst(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugment)
.def("GetAugmentEvolveUniqueID", (uint32(Lua_ItemInst::*)(uint8))&Lua_ItemInst::GetAugmentEvolveUniqueID)
.def("GetAugmentIDs", (luabind::object(Lua_ItemInst::*)(lua_State*))&Lua_ItemInst::GetAugmentIDs)
.def("GetAugmentItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugmentItemID)
.def("GetAugmentType", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetAugmentType)
@@ -370,13 +457,22 @@ luabind::scope lua_register_iteminst() {
.def("GetCustomData", (std::string(Lua_ItemInst::*)(const std::string &))&Lua_ItemInst::GetCustomData)
.def("GetCustomDataString", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetCustomDataString)
.def("GetExp", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetExp)
.def("GetEvolveActivated", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveActivated)
.def("GetEvolveAmount", (uint64(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveAmount)
.def("GetEvolveCharacterID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveCharacterID)
.def("GetEvolveEquipped", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveEquipped)
.def("GetEvolveFinalItemID", (uint64(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveFinalItemID)
.def("GetEvolveItemID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveItemID)
.def("GetEvolveLevel", (int8(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveLevel)
.def("GetEvolveLoreID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveLoreID)
.def("GetEvolveProgression", (float(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveProgression)
.def("GetEvolveUniqueID", (uint64(Lua_ItemInst::*)(void))&Lua_ItemInst::GetEvolveUniqueID)
.def("GetID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetID)
.def("GetItem", (Lua_Item(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItem)
.def("GetItem", (Lua_ItemInst(Lua_ItemInst::*)(uint8))&Lua_ItemInst::GetItem)
.def("GetItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetItemID)
.def("GetItemLink", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemLink)
.def("GetItemScriptID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetItemScriptID)
.def("GetKillsNeeded", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetKillsNeeded)
.def("GetMaxEvolveLvl", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetMaxEvolveLvl)
.def("GetName", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetName)
.def("GetPrice", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetPrice)
@@ -389,6 +485,7 @@ luabind::scope lua_register_iteminst() {
.def("IsAugmented", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsAugmented)
.def("IsEquipable", (bool(Lua_ItemInst::*)(int16))&Lua_ItemInst::IsEquipable)
.def("IsEquipable", (bool(Lua_ItemInst::*)(uint16,uint16))&Lua_ItemInst::IsEquipable)
.def("IsEvolving", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsEvolving)
.def("IsExpendable", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsExpendable)
.def("IsInstNoDrop", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsInstNoDrop)
.def("IsStackable", (bool(Lua_ItemInst::*)(void))&Lua_ItemInst::IsStackable)
@@ -404,6 +501,8 @@ luabind::scope lua_register_iteminst() {
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,float))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,int))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,const std::string&))&Lua_ItemInst::SetCustomData)
.def("SetEvolveAmount", (void(Lua_ItemInst::*)(uint64))&Lua_ItemInst::SetEvolveAmount)
.def("SetEvolveProgression", (void(Lua_ItemInst::*)(float))&Lua_ItemInst::SetEvolveProgression)
.def("SetExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetExp)
.def("SetInstNoDrop", (void(Lua_ItemInst::*)(bool))&Lua_ItemInst::SetInstNoDrop)
.def("SetPrice", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetPrice)
+15 -1
View File
@@ -77,7 +77,6 @@ public:
void SetExp(uint32 exp);
void AddExp(uint32 exp);
int8 GetMaxEvolveLvl();
uint32 GetKillsNeeded(uint8 current_level);
Lua_ItemInst Clone();
void SetTimer(std::string name, uint32 time);
void StopTimer(std::string name);
@@ -91,6 +90,21 @@ public:
void ItemSay(const char* text, uint8 language_id);
luabind::object GetAugmentIDs(lua_State* L);
std::string GetItemLink();
void AddEvolveAmount(uint64 amount);
uint32 GetAugmentEvolveUniqueID(uint8 slot_id);
bool GetEvolveActivated();
uint64 GetEvolveAmount();
uint32 GetEvolveCharacterID();
bool GetEvolveEquipped();
uint32 GetEvolveFinalItemID();
uint32 GetEvolveItemID();
int8 GetEvolveLevel();
uint32 GetEvolveLoreID();
float GetEvolveProgression();
uint64 GetEvolveUniqueID();
bool IsEvolving();
void SetEvolveAmount(uint64 amount);
void SetEvolveProgression(float amount);
private:
bool cloned_;
+1
View File
@@ -896,6 +896,7 @@ luabind::scope lua_register_packet_opcodes() {
luabind::value("Weblink", static_cast<int>(OP_Weblink)),
luabind::value("InspectMessageUpdate", static_cast<int>(OP_InspectMessageUpdate)),
luabind::value("ItemPreview", static_cast<int>(OP_ItemPreview)),
luabind::value("ItemPreviewRequest", static_cast<int>(OP_ItemPreviewRequest)),
luabind::value("MercenaryDataRequest", static_cast<int>(OP_MercenaryDataRequest)),
luabind::value("MercenaryDataResponse", static_cast<int>(OP_MercenaryDataResponse)),
luabind::value("MercenaryHire", static_cast<int>(OP_MercenaryHire)),
+7
View File
@@ -52,6 +52,7 @@
#include "task_manager.h"
#include "quest_parser_collection.h"
#include "embparser.h"
#include "../common/evolving_items.h"
#include "lua_parser.h"
#include "questmgr.h"
#include "npc_scale_manager.h"
@@ -110,6 +111,7 @@ PathManager path;
PlayerEventLogs player_event_logs;
DatabaseUpdate database_update;
SkillCaps skill_caps;
EvolvingItemsManager evolving_items_manager;
const SPDat_Spell_Struct* spells;
int32 SPDAT_RECORDS = -1;
@@ -387,6 +389,11 @@ int main(int argc, char **argv)
title_manager.LoadTitles();
content_db.LoadTributes();
// Load evolving item data
evolving_items_manager.SetDatabase(&database);
evolving_items_manager.SetContentDatabase(&content_db);
evolving_items_manager.LoadEvolvingItems();
database.GetDecayTimes(npcCorpseDecayTimes);
if (!EQ::ProfanityManager::LoadProfanityList(&database)) {
+6
View File
@@ -3229,6 +3229,11 @@ perl::array Perl_Client_GetInventorySlots(Client* self)
return result;
}
void Perl_Client_SetAAEXPPercentage(Client* self, uint8 percentage)
{
self->SetAAEXPPercentage(percentage);
}
void perl_register_client()
{
perl::interpreter perl(PERL_GET_THX);
@@ -3657,6 +3662,7 @@ void perl_register_client()
package.add("SetAAEXPModifier", (void(*)(Client*, float))&Perl_Client_SetAAEXPModifier);
package.add("SetAAEXPModifier", (void(*)(Client*, uint32, float))&Perl_Client_SetAAEXPModifier);
package.add("SetAAEXPModifier", (void(*)(Client*, uint32, float, int16))&Perl_Client_SetAAEXPModifier);
package.add("SetAAEXPPercentage", &Perl_Client_SetAAEXPPercentage);
package.add("SetAAPoints", &Perl_Client_SetAAPoints);
package.add("SetAATitle", (void(*)(Client*, std::string))&Perl_Client_SetAATitle);
package.add("SetAATitle", (void(*)(Client*, std::string, bool))&Perl_Client_SetAATitle);
+90 -6
View File
@@ -152,11 +152,6 @@ uint32 Perl_QuestItem_GetItemScriptID(EQ::ItemInstance* self)
return self->GetItemScriptID();
}
uint32 Perl_QuestItem_GetKillsNeeded(EQ::ItemInstance* self, uint8 current_level)
{
return self->GetKillsNeeded(current_level);
}
int8 Perl_QuestItem_GetMaxEvolveLevel(EQ::ItemInstance* self)
{
return self->GetMaxEvolveLvl();
@@ -297,12 +292,88 @@ std::string Perl_QuestItem_GetItemLink(EQ::ItemInstance* self)
return linker.GenerateLink();
}
void Perl_QuestItem_AddEvolveAmount(EQ::ItemInstance* self, uint64 amount)
{
self->SetEvolveAddToCurrentAmount(amount);
}
uint32 Perl_QuestItem_GetAugmentEvolveUniqueID(EQ::ItemInstance* self, uint8 slot_id)
{
return self->GetAugmentEvolveUniqueID(slot_id);
}
bool Perl_QuestItem_GetEvolveActivated(EQ::ItemInstance* self)
{
return self->GetEvolveActivated();
}
uint64 Perl_QuestItem_GetEvolveAmount(EQ::ItemInstance* self)
{
return self->GetEvolveCurrentAmount();
}
uint32 Perl_QuestItem_GetEvolveCharacterID(EQ::ItemInstance* self)
{
return self->GetEvolveCharID();
}
bool Perl_QuestItem_GetEvolveEquipped(EQ::ItemInstance* self)
{
return self->GetEvolveEquipped();
}
uint32 Perl_QuestItem_GetEvolveItemID(EQ::ItemInstance* self)
{
return self->GetEvolveItemID();
}
uint32 Perl_QuestItem_GetEvolveFinalItemID(EQ::ItemInstance* self)
{
return self->GetEvolveFinalItemID();
}
int8 Perl_QuestItem_GetEvolveLevel(EQ::ItemInstance* self)
{
return self->GetEvolveLvl();
}
uint32 Perl_QuestItem_GetEvolveLoreID(EQ::ItemInstance* self)
{
return self->GetEvolveLoreID();
}
double Perl_QuestItem_GetEvolveProgression(EQ::ItemInstance* self)
{
return self->GetEvolveProgression();
}
uint64 Perl_QuestItem_GetEvolveUniqueID(EQ::ItemInstance* self)
{
return self->GetEvolveUniqueID();
}
bool Perl_QuestItem_IsEvolving(EQ::ItemInstance* self)
{
return self->IsEvolving();
}
void Perl_QuestItem_SetEvolveProgression(EQ::ItemInstance* self, float amount)
{
self->SetEvolveProgression(amount);
}
void Perl_QuestItem_SetEvolveAmount(EQ::ItemInstance* self, uint64 amount)
{
self->SetEvolveCurrentAmount(amount);
}
void perl_register_questitem()
{
perl::interpreter perl(PERL_GET_THX);
auto package = perl.new_class<EQ::ItemInstance>("QuestItem");
package.add("AddEvolveAmount", &Perl_QuestItem_AddEvolveAmount);
package.add("AddEXP", &Perl_QuestItem_AddEXP);
package.add("ClearTimers", &Perl_QuestItem_ClearTimers);
package.add("Clone", &Perl_QuestItem_Clone);
@@ -310,6 +381,7 @@ void perl_register_questitem()
package.add("CountAugmentByID", &Perl_QuestItem_CountAugmentByID);
package.add("DeleteCustomData", &Perl_QuestItem_DeleteCustomData);
package.add("GetAugment", &Perl_QuestItem_GetAugment);
package.add("GetAugmentEvolveUniqueID", &Perl_QuestItem_GetAugmentEvolveUniqueID);
package.add("GetAugmentIDs", &Perl_QuestItem_GetAugmentIDs);
package.add("GetAugmentItemID", &Perl_QuestItem_GetAugmentItemID);
package.add("GetAugmentType", &Perl_QuestItem_GetAugmentType);
@@ -317,6 +389,16 @@ void perl_register_questitem()
package.add("GetColor", &Perl_QuestItem_GetColor);
package.add("GetCustomData", &Perl_QuestItem_GetCustomData);
package.add("GetCustomDataString", &Perl_QuestItem_GetCustomDataString);
package.add("GetEvolveActivated", &Perl_QuestItem_GetEvolveActivated);
package.add("GetEvolveAmount", &Perl_QuestItem_GetEvolveAmount);
package.add("GetEvolveCharacterID", &Perl_QuestItem_GetEvolveCharacterID);
package.add("GetEvolveEquipped", &Perl_QuestItem_GetEvolveEquipped);
package.add("GetEvolveFinalItemID", &Perl_QuestItem_GetEvolveFinalItemID);
package.add("GetEvolveItemID", &Perl_QuestItem_GetEvolveItemID);
package.add("GetEvolveLevel", &Perl_QuestItem_GetEvolveLevel);
package.add("GetEvolveLoreID", &Perl_QuestItem_GetEvolveLoreID);
package.add("GetEvolveProgression", &Perl_QuestItem_GetEvolveProgression);
package.add("GetEvolveUniqueID", &Perl_QuestItem_GetEvolveUniqueID);
package.add("GetEXP", &Perl_QuestItem_GetEXP);
package.add("GetID", &Perl_QuestItem_GetID);
package.add("GetItem", (EQ::ItemData*(*)(EQ::ItemInstance*))&Perl_QuestItem_GetItem);
@@ -324,7 +406,6 @@ void perl_register_questitem()
package.add("GetItemID", &Perl_QuestItem_GetItemID);
package.add("GetItemLink", &Perl_QuestItem_GetItemLink);
package.add("GetItemScriptID", &Perl_QuestItem_GetItemScriptID);
package.add("GetKillsNeeded", &Perl_QuestItem_GetKillsNeeded);
package.add("GetMaxEvolveLevel", &Perl_QuestItem_GetMaxEvolveLevel);
package.add("GetName", &Perl_QuestItem_GetName);
package.add("GetPrice", &Perl_QuestItem_GetPrice);
@@ -337,6 +418,7 @@ void perl_register_questitem()
package.add("IsAugmented", &Perl_QuestItem_IsAugmented);
package.add("IsEquipable", (bool(*)(EQ::ItemInstance*, int16))&Perl_QuestItem_IsEquipable);
package.add("IsEquipable", (bool(*)(EQ::ItemInstance*, uint16, uint16))&Perl_QuestItem_IsEquipable);
package.add("IsEvolving", &Perl_QuestItem_IsEvolving);
package.add("IsExpendable", &Perl_QuestItem_IsExpendable);
package.add("IsInstanceNoDrop", &Perl_QuestItem_IsInstanceNoDrop);
package.add("IsStackable", &Perl_QuestItem_IsStackable);
@@ -352,6 +434,8 @@ void perl_register_questitem()
package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, float))&Perl_QuestItem_SetCustomData);
package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, int))&Perl_QuestItem_SetCustomData);
package.add("SetCustomData", (void(*)(EQ::ItemInstance*, std::string, std::string))&Perl_QuestItem_SetCustomData);
package.add("SetEvolveAmount", &Perl_QuestItem_SetEvolveAmount);
package.add("SetEvolveProgression", &Perl_QuestItem_SetEvolveProgression);
package.add("SetEXP", &Perl_QuestItem_SetEXP);
package.add("SetInstanceNoDrop", &Perl_QuestItem_SetInstanceNoDrop);
package.add("SetPrice", &Perl_QuestItem_SetPrice);
+5
View File
@@ -419,6 +419,11 @@
#define GUILD_BANK_FULL 6098 // There is no more room in the Guild Bank.
#define GUILD_BANK_TRANSFERRED 6100 // '%1' transferred to Guild Bank from Deposits.
#define GUILD_BANK_EMPTY_HANDS 6108 // You must empty your hands to withdraw from the Guild Bank.
#define EVOLVE_ITEM_EVOLVED 6145 //Your %1 has evolved!
#define EVOLVE_DETAILS 6146 //Evolving: Level %1/%2 %3%% %4
#define EVOLVE_LEVEL_LIMIT 6147 //Your %1 can not evolve until you reach level %2.
#define EVOLVE_XP_TXFR_CONFIRM 6148 //Are you sure you want to transfer experience between these two items?
#define EVOLVE_XP_TXFRD 6149 //Your item's experience has been transferred!
#define TRADESKILL_COMBINE_LORE 6199 // Combine would result in a LORE item (%1) you already possess.
#define TRANSFORM_FAILED 6326 //This mold cannot be applied to your %1.
#define TRANSFORM_COMPLETE 6327 //You have successfully transformed your %1.
+62 -6
View File
@@ -371,6 +371,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
if (free_slot != INVALID_INDEX) {
if (other->PutItemInInventory(free_slot, *inst, true)) {
inst->TransferOwnership(database, other->CharacterID());
LogTrading("Container [{}] ([{}]) successfully transferred, deleting from trade slot", inst->GetItem()->Name, inst->GetItem()->ID);
if (qs_log) {
auto detail = new PlayerLogTradeItemsEntry_Struct;
@@ -482,6 +483,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
if (other->PutItemInInventory(partial_slot, *partial_inst, true)) {
LogTrading("Partial stack [{}] ([{}]) successfully transferred, deleting [{}] charges from trade slot",
inst->GetItem()->Name, inst->GetItem()->ID, (old_charges - inst->GetCharges()));
inst->TransferOwnership(database, other->CharacterID());
if (qs_log) {
auto detail = new PlayerLogTradeItemsEntry_Struct;
@@ -589,6 +591,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
if (free_slot != INVALID_INDEX) {
if (other->PutItemInInventory(free_slot, *inst, true)) {
inst->TransferOwnership(database, other->CharacterID());
LogTrading("Item [{}] ([{}]) successfully transferred, deleting from trade slot", inst->GetItem()->Name, inst->GetItem()->ID);
if (qs_log) {
auto detail = new PlayerLogTradeItemsEntry_Struct;
@@ -3219,11 +3222,44 @@ void Client::SendBulkBazaarTraders()
return;
}
auto results = TraderRepository::GetDistinctTraders(
database,
GetInstanceID(),
EQ::constants::StaticLookup(ClientVersion())->BazaarTraderLimit
);
TraderRepository::BulkTraders_Struct results{};
if (RuleB(Bazaar, UseAlternateBazaarSearch))
{
if (GetZoneID() == Zones::BAZAAR) {
results = TraderRepository::GetDistinctTraders(database, GetInstanceID());
}
uint32 number = 1;
auto shards = CharacterDataRepository::GetInstanceZonePlayerCounts(database, Zones::BAZAAR);
for (auto const &shard: shards) {
if (GetZoneID() != Zones::BAZAAR || (GetZoneID() == Zones::BAZAAR && GetInstanceID() != shard.instance_id)) {
TraderRepository::DistinctTraders_Struct t{};
t.entity_id = 0;
t.trader_id = TraderRepository::TRADER_CONVERT_ID + shard.instance_id;
t.trader_name = fmt::format("Bazaar Shard {}", number);
t.zone_id = Zones::BAZAAR;
t.zone_instance_id = shard.instance_id;
results.count += 1;
results.name_length += t.trader_name.length() + 1;
results.traders.push_back(t);
}
number++;
}
}
else {
results = TraderRepository::GetDistinctTraders(
database,
GetInstanceID(),
EQ::constants::StaticLookup(ClientVersion())->BazaarTraderLimit
);
}
SetTraderCount(results.count);
SetTraderCount(results.count);
auto p_size = 4 + 12 * results.count + results.name_length;
auto buffer = std::make_unique<char[]>(p_size);
@@ -3246,8 +3282,28 @@ void Client::SendBulkBazaarTraders()
QueuePacket(outapp.get());
}
void Client::DoBazaarInspect(const BazaarInspect_Struct &in)
void Client::DoBazaarInspect(BazaarInspect_Struct &in)
{
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
if (in.trader_id >= TraderRepository::TRADER_CONVERT_ID) {
auto trader = TraderRepository::GetTraderByInstanceAndSerialnumber(
database,
in.trader_id - TraderRepository::TRADER_CONVERT_ID,
fmt::format("{}", in.serial_number).c_str()
);
if (!trader.trader_id) {
LogTrading("Unable to convert trader id for {} and serial number {}. Trader Buy aborted.",
in.trader_id - TraderRepository::TRADER_CONVERT_ID,
in.serial_number
);
return;
}
in.trader_id = trader.trader_id;
}
}
auto items = TraderRepository::GetWhere(
database, fmt::format("`char_id` = '{}' AND `item_sn` = '{}'", in.trader_id, in.serial_number)
);
+45 -16
View File
@@ -3912,21 +3912,8 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
auto in = (TraderMessaging_Struct *) pack->pBuffer;
for (auto const &c: entity_list.GetClientList()) {
if (c.second->ClientVersion() >= EQ::versions::ClientVersion::RoF2) {
auto outapp = new EQApplicationPacket(OP_BecomeTrader, sizeof(BecomeTrader_Struct));
auto out = (BecomeTrader_Struct *) outapp->pBuffer;
switch (in->action) {
case TraderOn: {
out->action = AddTraderToBazaarWindow;
break;
}
case TraderOff: {
out->action = RemoveTraderFromBazaarWindow;
break;
}
default: {
out->action = 0;
}
}
auto outapp = new EQApplicationPacket(OP_BecomeTrader, sizeof(BecomeTrader_Struct));
auto out = (BecomeTrader_Struct *) outapp->pBuffer;
out->entity_id = in->entity_id;
out->zone_id = in->zone_id;
@@ -3934,7 +3921,49 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
out->trader_id = in->trader_id;
strn0cpy(out->trader_name, in->trader_name, sizeof(out->trader_name));
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
switch (in->action) {
case TraderOn: {
out->action = AddTraderToBazaarWindow;
if (c.second->GetTraderCount() <
EQ::constants::StaticLookup(c.second->ClientVersion())->BazaarTraderLimit) {
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
if (out->zone_id == Zones::BAZAAR &&
out->zone_instance_id == c.second->GetInstanceID()) {
c.second->IncrementTraderCount();
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
}
}
else {
c.second->IncrementTraderCount();
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
}
}
break;
}
case TraderOff: {
out->action = RemoveTraderFromBazaarWindow;
if (c.second->GetTraderCount() <=
EQ::constants::StaticLookup(c.second->ClientVersion())->BazaarTraderLimit) {
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
if (out->zone_id == Zones::BAZAAR &&
out->zone_instance_id == c.second->GetInstanceID()) {
c.second->DecrementTraderCount();
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
}
}
else {
c.second->DecrementTraderCount();
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
}
}
break;
}
default: {
out->action = 0;
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
}
}
safe_delete(outapp);
}
if (zone && zone->GetZoneID() == Zones::BAZAAR && in->instance_id == zone->GetInstanceID()) {
+1 -1
View File
@@ -52,7 +52,7 @@
#include "../common/repositories/zone_repository.h"
#include "../common/repositories/trader_repository.h"
#include "../common/repositories/character_evolving_items_repository.h"
#include <ctime>
#include <iostream>