mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
[Fix] Parcel Delivery Updates (#4688)
* Fix two parcel bugs Fix two Parcel Bugs - If a player was at their parcel limit and perform a bazaar purchase via parcel delivery, their money would be lost - If a container with items was delivered via parcel, the parcel under certain inventory conditions could be delivered into an incorrect slot resulting in the container being lost. * Incorrect field used for BagSize vs ItemSize. Silly mistake. * Remove duplicate check and reorder stacking check * Fix edge case when Parcel Window remains open and Bazaar purchases are made. * Repair - bazaar purchase of items with charges reverting to 1 charge in error - bazaar visual error with selling price. Was caused by the parcel fee not being properly reflected in the client - corrected a type mismatch with parcel fee uint32 vs uin64 - corrected a few TraderPurchase and TraderSell event data points by splitting quantity and charges * Formatting * Use pre-existing AddMoney and TakeMoney and remove unnecessary routines * Updates after rebase
This commit is contained in:
parent
c09fad5a75
commit
ab4e1191ef
@ -882,8 +882,9 @@ namespace PlayerEvent {
|
|||||||
uint32 trader_id;
|
uint32 trader_id;
|
||||||
std::string trader_name;
|
std::string trader_name;
|
||||||
uint32 price;
|
uint32 price;
|
||||||
uint32 charges;
|
uint32 quantity;
|
||||||
uint32 total_cost;
|
int32 charges;
|
||||||
|
uint64 total_cost;
|
||||||
uint64 player_money_balance;
|
uint64 player_money_balance;
|
||||||
|
|
||||||
|
|
||||||
@ -903,6 +904,7 @@ namespace PlayerEvent {
|
|||||||
CEREAL_NVP(trader_id),
|
CEREAL_NVP(trader_id),
|
||||||
CEREAL_NVP(trader_name),
|
CEREAL_NVP(trader_name),
|
||||||
CEREAL_NVP(price),
|
CEREAL_NVP(price),
|
||||||
|
CEREAL_NVP(quantity),
|
||||||
CEREAL_NVP(charges),
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(total_cost),
|
CEREAL_NVP(total_cost),
|
||||||
CEREAL_NVP(player_money_balance)
|
CEREAL_NVP(player_money_balance)
|
||||||
@ -922,8 +924,9 @@ namespace PlayerEvent {
|
|||||||
uint32 buyer_id;
|
uint32 buyer_id;
|
||||||
std::string buyer_name;
|
std::string buyer_name;
|
||||||
uint32 price;
|
uint32 price;
|
||||||
uint32 charges;
|
uint32 quantity;
|
||||||
uint32 total_cost;
|
int32 charges;
|
||||||
|
uint64 total_cost;
|
||||||
uint64 player_money_balance;
|
uint64 player_money_balance;
|
||||||
|
|
||||||
|
|
||||||
@ -943,6 +946,7 @@ namespace PlayerEvent {
|
|||||||
CEREAL_NVP(buyer_id),
|
CEREAL_NVP(buyer_id),
|
||||||
CEREAL_NVP(buyer_name),
|
CEREAL_NVP(buyer_name),
|
||||||
CEREAL_NVP(price),
|
CEREAL_NVP(price),
|
||||||
|
CEREAL_NVP(quantity),
|
||||||
CEREAL_NVP(charges),
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(total_cost),
|
CEREAL_NVP(total_cost),
|
||||||
CEREAL_NVP(player_money_balance)
|
CEREAL_NVP(player_money_balance)
|
||||||
@ -1152,6 +1156,7 @@ namespace PlayerEvent {
|
|||||||
uint32 augment_5_id;
|
uint32 augment_5_id;
|
||||||
uint32 augment_6_id;
|
uint32 augment_6_id;
|
||||||
uint32 quantity;
|
uint32 quantity;
|
||||||
|
int32 charges;
|
||||||
std::string from_player_name;
|
std::string from_player_name;
|
||||||
std::string to_player_name;
|
std::string to_player_name;
|
||||||
uint32 sent_date;
|
uint32 sent_date;
|
||||||
@ -1169,6 +1174,7 @@ namespace PlayerEvent {
|
|||||||
CEREAL_NVP(augment_5_id),
|
CEREAL_NVP(augment_5_id),
|
||||||
CEREAL_NVP(augment_6_id),
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(quantity),
|
CEREAL_NVP(quantity),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(from_player_name),
|
CEREAL_NVP(from_player_name),
|
||||||
CEREAL_NVP(to_player_name),
|
CEREAL_NVP(to_player_name),
|
||||||
CEREAL_NVP(sent_date)
|
CEREAL_NVP(sent_date)
|
||||||
|
|||||||
@ -2028,3 +2028,57 @@ int16 EQ::InventoryProfile::_HasEvolvingItem(ItemInstQueue &iqueue, uint64 evolv
|
|||||||
|
|
||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int16 EQ::InventoryProfile::FindFirstFreeSlotThatFitsItemWithStacking(ItemInstance *item_inst) const
|
||||||
|
{
|
||||||
|
auto item_data = item_inst->GetItem();
|
||||||
|
if (!item_data) {
|
||||||
|
return INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) {
|
||||||
|
auto const inv_item = GetItem(i);
|
||||||
|
if (!inv_item) {
|
||||||
|
// Found available slot in personal inventory
|
||||||
|
// Anything will fit here
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item_data->IsClassBag() && item_inst->IsNoneEmptyContainer()) {
|
||||||
|
// If the inbound item is a bag with items, it cannot be stored within a bag
|
||||||
|
// Move to next potential slot
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inv_item->GetID() == item_data->ID && item_data->Stackable) {
|
||||||
|
if (item_inst->GetCharges() + inv_item->GetCharges() <= item_data->StackSize) {
|
||||||
|
// Found a personal inventory slot that has room for a stackable addition
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inv_item->IsClassBag() && CanItemFitInContainer(item_data, inv_item->GetItem())) {
|
||||||
|
int16 const base_slot_id = CalcSlotId(i, invbag::SLOT_BEGIN);
|
||||||
|
uint8 const bag_size = inv_item->GetItem()->BagSlots;
|
||||||
|
uint8 const item_size = item_data->Size;
|
||||||
|
|
||||||
|
for (uint8 bag_slot = invbag::SLOT_BEGIN; bag_slot < bag_size; bag_slot++) {
|
||||||
|
auto bag_item = GetItem(base_slot_id + bag_slot);
|
||||||
|
if (!bag_item) {
|
||||||
|
// Found available slot within bag that will hold inbound item
|
||||||
|
return base_slot_id + bag_slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bag_item && item_data->Stackable && bag_item->GetID() == item_data->ID) {
|
||||||
|
if (item_inst->GetCharges() + bag_item->GetCharges() <= item_data->StackSize) {
|
||||||
|
// Found a bag slot has room for a stackable addition
|
||||||
|
return base_slot_id + bag_slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|||||||
@ -179,6 +179,7 @@ namespace EQ
|
|||||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
||||||
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
|
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
|
||||||
|
int16 FindFirstFreeSlotThatFitsItemWithStacking(ItemInstance *inst) const;
|
||||||
|
|
||||||
// Calculate slot_id for an item within a bag
|
// Calculate slot_id for an item within a bag
|
||||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||||
|
|||||||
101
zone/client.cpp
101
zone/client.cpp
@ -12969,107 +12969,6 @@ void Client::RemoveItemBySerialNumber(uint32 serial_number, uint32 quantity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddMoneyToPPWithOverflow(uint64 copper, bool update_client)
|
|
||||||
{
|
|
||||||
//I noticed in the ROF2 client that the client auto updates the currency values using overflow
|
|
||||||
//Therefore, I created this method to ensure that the db matches and clients don't see 10 pp 5 gp
|
|
||||||
//becoming 9pp 15 gold with the current AddMoneyToPP method.
|
|
||||||
|
|
||||||
auto add_pp = copper / 1000;
|
|
||||||
auto add_gp = (copper - add_pp * 1000) / 100;
|
|
||||||
auto add_sp = (copper - add_pp * 1000 - add_gp * 100) / 10;
|
|
||||||
auto add_cp = copper - add_pp * 1000 - add_gp * 100 - add_sp * 10;
|
|
||||||
|
|
||||||
m_pp.copper += add_cp;
|
|
||||||
if (m_pp.copper >= 10) {
|
|
||||||
m_pp.silver += m_pp.copper / 10;
|
|
||||||
m_pp.copper = m_pp.copper % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.silver += add_sp;
|
|
||||||
if (m_pp.silver >= 10) {
|
|
||||||
m_pp.gold += m_pp.silver / 10;
|
|
||||||
m_pp.silver = m_pp.silver % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.gold += add_gp;
|
|
||||||
if (m_pp.gold >= 10) {
|
|
||||||
m_pp.platinum += m_pp.gold / 10;
|
|
||||||
m_pp.gold = m_pp.gold % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.platinum += add_pp;
|
|
||||||
|
|
||||||
if (update_client) {
|
|
||||||
SendMoneyUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
RecalcWeight();
|
|
||||||
SaveCurrency();
|
|
||||||
|
|
||||||
LogDebug("Client::AddMoneyToPPWithOverflow() [{}] should have: plat:[{}] gold:[{}] silver:[{}] copper:[{}]",
|
|
||||||
GetName(),
|
|
||||||
m_pp.platinum,
|
|
||||||
m_pp.gold,
|
|
||||||
m_pp.silver,
|
|
||||||
m_pp.copper
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::TakeMoneyFromPPWithOverFlow(uint64 copper, bool update_client)
|
|
||||||
{
|
|
||||||
int32 remove_pp = copper / 1000;
|
|
||||||
int32 remove_gp = (copper - remove_pp * 1000) / 100;
|
|
||||||
int32 remove_sp = (copper - remove_pp * 1000 - remove_gp * 100) / 10;
|
|
||||||
int32 remove_cp = copper - remove_pp * 1000 - remove_gp * 100 - remove_sp * 10;
|
|
||||||
|
|
||||||
uint64 current_money = GetCarriedMoney();
|
|
||||||
|
|
||||||
if (copper > current_money) {
|
|
||||||
return false; //client does not have enough money on them
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.copper -= remove_cp;
|
|
||||||
if (m_pp.copper < 0) {
|
|
||||||
m_pp.silver -= 1;
|
|
||||||
m_pp.copper = m_pp.copper + 10;
|
|
||||||
if (m_pp.copper >= 10) {
|
|
||||||
m_pp.silver += m_pp.copper / 10;
|
|
||||||
m_pp.copper = m_pp.copper % 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.silver -= remove_sp;
|
|
||||||
if (m_pp.silver < 0) {
|
|
||||||
m_pp.gold -= 1;
|
|
||||||
m_pp.silver = m_pp.silver + 10;
|
|
||||||
if (m_pp.silver >= 10) {
|
|
||||||
m_pp.gold += m_pp.silver / 10;
|
|
||||||
m_pp.silver = m_pp.silver % 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.gold -= remove_gp;
|
|
||||||
if (m_pp.gold < 0) {
|
|
||||||
m_pp.platinum -= 1;
|
|
||||||
m_pp.gold = m_pp.gold + 10;
|
|
||||||
if (m_pp.gold >= 10) {
|
|
||||||
m_pp.platinum += m_pp.gold / 10;
|
|
||||||
m_pp.gold = m_pp.gold % 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pp.platinum -= remove_pp;
|
|
||||||
|
|
||||||
if (update_client) {
|
|
||||||
SendMoneyUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveCurrency();
|
|
||||||
RecalcWeight();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::SendTopLevelInventory()
|
void Client::SendTopLevelInventory()
|
||||||
{
|
{
|
||||||
EQ::ItemInstance* inst = nullptr;
|
EQ::ItemInstance* inst = nullptr;
|
||||||
|
|||||||
@ -879,11 +879,9 @@ public:
|
|||||||
void QuestReadBook(const char* text, uint8 type);
|
void QuestReadBook(const char* text, uint8 type);
|
||||||
void SendMoneyUpdate();
|
void SendMoneyUpdate();
|
||||||
bool TakeMoneyFromPP(uint64 copper, bool update_client = false);
|
bool TakeMoneyFromPP(uint64 copper, bool update_client = false);
|
||||||
bool TakeMoneyFromPPWithOverFlow(uint64 copper, bool update_client);
|
|
||||||
bool TakePlatinum(uint32 platinum, bool update_client = false);
|
bool TakePlatinum(uint32 platinum, bool update_client = false);
|
||||||
void AddMoneyToPP(uint64 copper, bool update_client = false);
|
void AddMoneyToPP(uint64 copper, bool update_client = false);
|
||||||
void AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool update_client = false);
|
void AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool update_client = false);
|
||||||
void AddMoneyToPPWithOverflow(uint64 copper, bool update_client);
|
|
||||||
void AddPlatinum(uint32 platinu, bool update_client = false);
|
void AddPlatinum(uint32 platinu, bool update_client = false);
|
||||||
bool HasMoney(uint64 copper);
|
bool HasMoney(uint64 copper);
|
||||||
uint64 GetCarriedMoney();
|
uint64 GetCarriedMoney();
|
||||||
|
|||||||
204
zone/parcels.cpp
204
zone/parcels.cpp
@ -632,7 +632,13 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto p = m_parcels.find(parcel_in.parcel_slot_id);
|
auto p = std::find_if(
|
||||||
|
m_parcels.begin(),
|
||||||
|
m_parcels.end(),
|
||||||
|
[&](const std::pair<uint32, CharacterParcelsRepository::CharacterParcels> &x) {
|
||||||
|
return x.first == parcel_in.parcel_slot_id && x.second.item_id == parcel_in.parcel_item_id;
|
||||||
|
}
|
||||||
|
);
|
||||||
if (p != m_parcels.end()) {
|
if (p != m_parcels.end()) {
|
||||||
uint32 item_id = parcel_in.parcel_item_id;
|
uint32 item_id = parcel_in.parcel_item_id;
|
||||||
uint32 item_quantity = p->second.quantity;
|
uint32 item_quantity = p->second.quantity;
|
||||||
@ -656,25 +662,70 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
p->second.aug_slot_6
|
p->second.aug_slot_6
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
SendParcelRetrieveAck();
|
SendParcelRetrieveAck();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inst->IsStackable()) {
|
||||||
|
inst->SetCharges(item_quantity > 0 ? item_quantity : 1);
|
||||||
|
}
|
||||||
|
|
||||||
switch (parcel_in.parcel_item_id) {
|
switch (parcel_in.parcel_item_id) {
|
||||||
case PARCEL_MONEY_ITEM_ID: {
|
case PARCEL_MONEY_ITEM_ID: {
|
||||||
AddMoneyToPP(p->second.quantity, true);
|
AddMoneyToPP(p->second.quantity, true);
|
||||||
MessageString(
|
MessageString(
|
||||||
Chat::Yellow,
|
Chat::Yellow, PARCEL_DELIVERED, merchant->GetCleanName(), "Money", p->second.from_name.c_str()
|
||||||
PARCEL_DELIVERED,
|
|
||||||
merchant->GetCleanName(),
|
|
||||||
"Money",
|
|
||||||
p->second.from_name.c_str()
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
auto free_id = GetInv().FindFreeSlot(false, false);
|
std::vector<CharacterParcelsContainersRepository::CharacterParcelsContainers> results{};
|
||||||
|
if (inst->IsClassBag() && inst->GetItem()->BagSlots > 0) {
|
||||||
|
auto contents = inst->GetContents();
|
||||||
|
results = CharacterParcelsContainersRepository::GetWhere(
|
||||||
|
database, fmt::format("`parcels_id` = {}", p->second.id)
|
||||||
|
);
|
||||||
|
for (auto i: results) {
|
||||||
|
auto item = database.CreateItem(
|
||||||
|
i.item_id,
|
||||||
|
i.quantity,
|
||||||
|
i.aug_slot_1,
|
||||||
|
i.aug_slot_2,
|
||||||
|
i.aug_slot_3,
|
||||||
|
i.aug_slot_4,
|
||||||
|
i.aug_slot_5,
|
||||||
|
i.aug_slot_6
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
SendParcelRetrieveAck();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckLoreConflict(item->GetItem())) {
|
||||||
|
if (RuleB(Parcel, DeleteOnDuplicate)) {
|
||||||
|
MessageString(Chat::Yellow, PARCEL_DUPLICATE_DELETE, inst->GetItem()->Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageString(Chat::Yellow, DUP_LORE);
|
||||||
|
SendParcelRetrieveAck();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
contents->emplace(i.slot_id, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const free_id = GetInv().FindFirstFreeSlotThatFitsItemWithStacking(inst.get());
|
||||||
|
if (free_id == INVALID_INDEX) {
|
||||||
|
SendParcelRetrieveAck();
|
||||||
|
MessageString(Chat::White, PARCEL_INV_FULL, merchant->GetCleanName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (CheckLoreConflict(inst->GetItem())) {
|
if (CheckLoreConflict(inst->GetItem())) {
|
||||||
if (RuleB(Parcel, DeleteOnDuplicate)) {
|
if (RuleB(Parcel, DeleteOnDuplicate)) {
|
||||||
MessageString(Chat::Yellow, PARCEL_DUPLICATE_DELETE, inst->GetItem()->Name);
|
MessageString(Chat::Yellow, PARCEL_DUPLICATE_DELETE, inst->GetItem()->Name);
|
||||||
@ -685,108 +736,33 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (inst->IsStackable()) {
|
|
||||||
inst->SetCharges(item_quantity);
|
if (AutoPutLootInInventory(*inst.get(), false, true)) {
|
||||||
if (TryStacking(inst.get(), ItemPacketTrade, true, false)) {
|
MessageString(
|
||||||
MessageString(
|
Chat::Yellow,
|
||||||
Chat::Yellow,
|
PARCEL_DELIVERED_2,
|
||||||
PARCEL_DELIVERED_2,
|
merchant->GetCleanName(),
|
||||||
merchant->GetCleanName(),
|
std::to_string(item_quantity).c_str(),
|
||||||
std::to_string(item_quantity).c_str(),
|
inst->GetItem()->Name,
|
||||||
inst->GetItem()->Name,
|
p->second.from_name.c_str()
|
||||||
p->second.from_name.c_str()
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (free_id != INVALID_INDEX) {
|
|
||||||
inst->SetCharges(item_quantity);
|
|
||||||
if (PutItemInInventory(free_id, *inst, true)) {
|
|
||||||
MessageString(
|
|
||||||
Chat::Yellow,
|
|
||||||
PARCEL_DELIVERED_2,
|
|
||||||
merchant->GetCleanName(),
|
|
||||||
std::to_string(item_quantity).c_str(),
|
|
||||||
inst->GetItem()->Name,
|
|
||||||
p->second.from_name.c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MessageString(Chat::Yellow, PARCEL_INV_FULL, merchant->GetCleanName());
|
|
||||||
SendParcelRetrieveAck();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (free_id != INVALID_INDEX) {
|
|
||||||
std::vector<CharacterParcelsContainersRepository::CharacterParcelsContainers> results{};
|
|
||||||
|
|
||||||
if (inst->IsClassBag() && inst->GetItem()->BagSlots > 0) {
|
if (player_event_logs.IsEventEnabled(PlayerEvent::PARCEL_RETRIEVE)) {
|
||||||
results = CharacterParcelsContainersRepository::GetWhere(database, fmt::format("`parcels_id` = {}", p->second.id));
|
PlayerEvent::ParcelRetrieve e{};
|
||||||
for (auto const &i : results) {
|
e.from_player_name = p->second.from_name;
|
||||||
std::unique_ptr<EQ::ItemInstance> item(
|
e.item_id = p->second.item_id;
|
||||||
database.CreateItem(
|
e.augment_1_id = p->second.aug_slot_1;
|
||||||
i.item_id,
|
e.augment_2_id = p->second.aug_slot_2;
|
||||||
i.quantity,
|
e.augment_3_id = p->second.aug_slot_3;
|
||||||
i.aug_slot_1,
|
e.augment_4_id = p->second.aug_slot_4;
|
||||||
i.aug_slot_2,
|
e.augment_5_id = p->second.aug_slot_5;
|
||||||
i.aug_slot_3,
|
e.augment_6_id = p->second.aug_slot_6;
|
||||||
i.aug_slot_4,
|
e.quantity = p->second.quantity;
|
||||||
i.aug_slot_5,
|
e.sent_date = p->second.sent_date;
|
||||||
i.aug_slot_6
|
RecordPlayerEventLog(PlayerEvent::PARCEL_RETRIEVE, e);
|
||||||
)
|
|
||||||
);
|
|
||||||
if (CheckLoreConflict(item->GetItem())) {
|
|
||||||
Message(
|
|
||||||
Chat::Yellow,
|
|
||||||
fmt::format("Lore Item Found in Inventory: {}", item->GetItem()->Name).c_str());
|
|
||||||
MessageString(Chat::Yellow, DUP_LORE);
|
|
||||||
Message(Chat::Red, "Unable to retrieve parcel.");
|
|
||||||
SendParcelRetrieveAck();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inst->SetCharges(item_quantity > 0 ? item_quantity : 1);
|
|
||||||
if (PutItemInInventory(free_id, *inst.get(), true)) {
|
|
||||||
if (inst->IsClassBag() && inst->GetItem()->BagSlots > 0) {
|
|
||||||
for (auto const &i: results) {
|
|
||||||
std::unique_ptr<EQ::ItemInstance> item(
|
|
||||||
database.CreateItem(
|
|
||||||
i.item_id,
|
|
||||||
i.quantity,
|
|
||||||
i.aug_slot_1,
|
|
||||||
i.aug_slot_2,
|
|
||||||
i.aug_slot_3,
|
|
||||||
i.aug_slot_4,
|
|
||||||
i.aug_slot_5,
|
|
||||||
i.aug_slot_6
|
|
||||||
)
|
|
||||||
);
|
|
||||||
auto bag_slot = EQ::InventoryProfile::CalcSlotId(free_id, i.slot_id);
|
|
||||||
PutItemInInventory(bag_slot, *item.get(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MessageString(
|
|
||||||
Chat::Yellow,
|
|
||||||
PARCEL_DELIVERED,
|
|
||||||
merchant->GetCleanName(),
|
|
||||||
inst->GetItem()->Name,
|
|
||||||
p->second.from_name.c_str()
|
|
||||||
);
|
|
||||||
if (player_event_logs.IsEventEnabled(PlayerEvent::PARCEL_RETRIEVE)) {
|
|
||||||
PlayerEvent::ParcelRetrieve e{};
|
|
||||||
e.from_player_name = p->second.from_name;
|
|
||||||
e.item_id = p->second.item_id;
|
|
||||||
e.augment_1_id = p->second.aug_slot_1;
|
|
||||||
e.augment_2_id = p->second.aug_slot_2;
|
|
||||||
e.augment_3_id = p->second.aug_slot_3;
|
|
||||||
e.augment_4_id = p->second.aug_slot_4;
|
|
||||||
e.augment_5_id = p->second.aug_slot_5;
|
|
||||||
e.augment_6_id = p->second.aug_slot_6;
|
|
||||||
e.quantity = p->second.quantity;
|
|
||||||
e.sent_date = p->second.sent_date;
|
|
||||||
RecordPlayerEventLog(PlayerEvent::PARCEL_RETRIEVE, e);
|
|
||||||
|
|
||||||
for (auto const &i:results) {
|
for (auto const &i:results) {
|
||||||
e.from_player_name = p->second.from_name;
|
e.from_player_name = p->second.from_name;
|
||||||
e.item_id = i.item_id;
|
e.item_id = i.item_id;
|
||||||
e.augment_1_id = i.aug_slot_1;
|
e.augment_1_id = i.aug_slot_1;
|
||||||
@ -798,19 +774,9 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
e.quantity = i.quantity;
|
e.quantity = i.quantity;
|
||||||
e.sent_date = p->second.sent_date;
|
e.sent_date = p->second.sent_date;
|
||||||
RecordPlayerEventLog(PlayerEvent::PARCEL_RETRIEVE, e);
|
RecordPlayerEventLog(PlayerEvent::PARCEL_RETRIEVE, e);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
MessageString(Chat::Yellow, PARCEL_INV_FULL, merchant->GetCleanName());
|
|
||||||
SendParcelRetrieveAck();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MessageString(Chat::Yellow, PARCEL_INV_FULL, merchant->GetCleanName());
|
|
||||||
SendParcelRetrieveAck();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -819,6 +785,7 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
SendParcelDelete(parcel_in);
|
SendParcelDelete(parcel_in);
|
||||||
m_parcels.erase(p);
|
m_parcels.erase(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendParcelRetrieveAck();
|
SendParcelRetrieveAck();
|
||||||
SendParcelIconStatus();
|
SendParcelIconStatus();
|
||||||
}
|
}
|
||||||
@ -831,7 +798,6 @@ bool Client::DeleteParcel(uint32 parcel_id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = std::find_if(m_parcels.cbegin(), m_parcels.cend(), [&](const auto &x) { return x.second.id == parcel_id; });
|
|
||||||
SetParcelCount(GetParcelCount() - 1);
|
SetParcelCount(GetParcelCount() - 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -1458,12 +1458,13 @@ void Client::BuyTraderItem(TraderBuy_Struct *tbs, Client *Trader, const EQApplic
|
|||||||
.trader_id = Trader->CharacterID(),
|
.trader_id = Trader->CharacterID(),
|
||||||
.trader_name = Trader->GetCleanName(),
|
.trader_name = Trader->GetCleanName(),
|
||||||
.price = tbs->price,
|
.price = tbs->price,
|
||||||
.charges = outtbs->quantity,
|
.quantity = outtbs->quantity,
|
||||||
|
.charges = buy_item->GetCharges(),
|
||||||
.total_cost = (tbs->price * outtbs->quantity),
|
.total_cost = (tbs->price * outtbs->quantity),
|
||||||
.player_money_balance = GetCarriedMoney(),
|
.player_money_balance = GetCarriedMoney(),
|
||||||
};
|
};
|
||||||
|
|
||||||
RecordPlayerEventLog(PlayerEvent::TRADER_PURCHASE, e);
|
RecordPlayerEventLog(PlayerEvent::TRADER_PURCHASE, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player_event_logs.IsEventEnabled(PlayerEvent::TRADER_SELL)) {
|
if (player_event_logs.IsEventEnabled(PlayerEvent::TRADER_SELL)) {
|
||||||
@ -1479,7 +1480,8 @@ void Client::BuyTraderItem(TraderBuy_Struct *tbs, Client *Trader, const EQApplic
|
|||||||
.buyer_id = CharacterID(),
|
.buyer_id = CharacterID(),
|
||||||
.buyer_name = GetCleanName(),
|
.buyer_name = GetCleanName(),
|
||||||
.price = tbs->price,
|
.price = tbs->price,
|
||||||
.charges = outtbs->quantity,
|
.quantity = outtbs->quantity,
|
||||||
|
.charges = buy_item->GetCharges(),
|
||||||
.total_cost = (tbs->price * outtbs->quantity),
|
.total_cost = (tbs->price * outtbs->quantity),
|
||||||
.player_money_balance = Trader->GetCarriedMoney(),
|
.player_money_balance = Trader->GetCarriedMoney(),
|
||||||
};
|
};
|
||||||
@ -1960,8 +1962,8 @@ void Client::SellToBuyer(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64 total_cost = (uint64) sell_line.item_cost * (uint64) sell_line.seller_quantity;
|
uint64 total_cost = (uint64) sell_line.item_cost * (uint64) sell_line.seller_quantity;
|
||||||
AddMoneyToPPWithOverflow(total_cost, false);
|
AddMoneyToPP(total_cost, false);
|
||||||
buyer->TakeMoneyFromPPWithOverFlow(total_cost, false);
|
buyer->TakeMoneyFromPP(total_cost, false);
|
||||||
|
|
||||||
if (player_event_logs.IsEventEnabled(PlayerEvent::BARTER_TRANSACTION)) {
|
if (player_event_logs.IsEventEnabled(PlayerEvent::BARTER_TRANSACTION)) {
|
||||||
PlayerEvent::BarterTransaction e{};
|
PlayerEvent::BarterTransaction e{};
|
||||||
@ -2879,6 +2881,21 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto next_slot = FindNextFreeParcelSlot(CharacterID());
|
||||||
|
if (next_slot == INVALID_INDEX) {
|
||||||
|
LogTrading(
|
||||||
|
"{} attempted to purchase {} from the bazaar with parcel delivery. Unfortunately their parcel limit was reached. "
|
||||||
|
"Purchase unsuccessful.",
|
||||||
|
GetCleanName(),
|
||||||
|
buy_item->GetItem()->Name
|
||||||
|
);
|
||||||
|
in->method = BazaarByParcel;
|
||||||
|
in->sub_action = TooManyParcels;
|
||||||
|
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
||||||
|
TradeRequestFailed(app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LogTrading(
|
LogTrading(
|
||||||
"Name: <green>[{}] IsStackable: <green>[{}] Requested Quantity: <green>[{}] Charges on Item <green>[{}]",
|
"Name: <green>[{}] IsStackable: <green>[{}] Requested Quantity: <green>[{}] Charges on Item <green>[{}]",
|
||||||
buy_item->GetItem()->Name,
|
buy_item->GetItem()->Name,
|
||||||
@ -2888,23 +2905,24 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Determine the actual quantity for the purchase
|
// Determine the actual quantity for the purchase
|
||||||
|
int32 charges = static_cast<int32>(tbs->quantity);
|
||||||
if (!buy_item->IsStackable()) {
|
if (!buy_item->IsStackable()) {
|
||||||
tbs->quantity = 1;
|
if (buy_item->GetCharges() <= 0) {
|
||||||
}
|
charges = 1;
|
||||||
else {
|
|
||||||
int32 item_charges = buy_item->GetCharges();
|
|
||||||
if (item_charges <= 0) {
|
|
||||||
tbs->quantity = 1;
|
|
||||||
}
|
}
|
||||||
else if (static_cast<uint32>(item_charges) < tbs->quantity) {
|
else {
|
||||||
tbs->quantity = item_charges;
|
charges = buy_item->GetCharges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogTrading("Actual quantity that will be traded is <green>[{}]", tbs->quantity);
|
LogTrading(
|
||||||
|
"Actual quantity that will be traded is <green>[{}] {}",
|
||||||
|
tbs->quantity,
|
||||||
|
buy_item->GetCharges() ? fmt::format("with {} charges", buy_item->GetCharges()) : ""
|
||||||
|
);
|
||||||
|
|
||||||
uint64 total_transaction_value = static_cast<uint64>(tbs->price) * static_cast<uint64>(tbs->quantity);
|
uint64 total_cost = static_cast<uint64>(tbs->price) * static_cast<uint64>(tbs->quantity);
|
||||||
if (total_transaction_value > MAX_TRANSACTION_VALUE) {
|
if (total_cost > MAX_TRANSACTION_VALUE) {
|
||||||
Message(
|
Message(
|
||||||
Chat::Red,
|
Chat::Red,
|
||||||
"That would exceed the single transaction limit of %u platinum.",
|
"That would exceed the single transaction limit of %u platinum.",
|
||||||
@ -2915,9 +2933,8 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 total_cost = tbs->price * tbs->quantity;
|
uint64 fee = std::round(total_cost * RuleR(Bazaar, ParcelDeliveryCostMod));
|
||||||
uint32 fee = static_cast<uint32>(std::round((uint32) total_cost * RuleR(Bazaar, ParcelDeliveryCostMod)));
|
if (!TakeMoneyFromPP(total_cost + fee, false)) {
|
||||||
if (!TakeMoneyFromPP(total_cost + fee)) {
|
|
||||||
RecordPlayerEventLog(
|
RecordPlayerEventLog(
|
||||||
PlayerEvent::POSSIBLE_HACK,
|
PlayerEvent::POSSIBLE_HACK,
|
||||||
PlayerEvent::PossibleHackEvent{
|
PlayerEvent::PossibleHackEvent{
|
||||||
@ -2951,7 +2968,8 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
.trader_id = tbs->trader_id,
|
.trader_id = tbs->trader_id,
|
||||||
.trader_name = tbs->seller_name,
|
.trader_name = tbs->seller_name,
|
||||||
.price = tbs->price,
|
.price = tbs->price,
|
||||||
.charges = tbs->quantity,
|
.quantity = tbs->quantity,
|
||||||
|
.charges = buy_item->IsStackable() ? 1 : charges,
|
||||||
.total_cost = total_cost,
|
.total_cost = total_cost,
|
||||||
.player_money_balance = GetCarriedMoney(),
|
.player_money_balance = GetCarriedMoney(),
|
||||||
};
|
};
|
||||||
@ -2960,24 +2978,10 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
}
|
}
|
||||||
|
|
||||||
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
||||||
auto next_slot = FindNextFreeParcelSlot(CharacterID());
|
|
||||||
if (next_slot == INVALID_INDEX) {
|
|
||||||
LogTrading(
|
|
||||||
"{} attempted to purchase {} from the bazaar with parcel delivery. Unfortunately their parcel limit was reached. "
|
|
||||||
"Purchase unsuccessful.",
|
|
||||||
GetCleanName(),
|
|
||||||
buy_item->GetItem()->Name
|
|
||||||
);
|
|
||||||
in->method = BazaarByParcel;
|
|
||||||
in->sub_action = TooManyParcels;
|
|
||||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
|
||||||
TradeRequestFailed(app);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parcel_out.from_name = tbs->seller_name;
|
parcel_out.from_name = tbs->seller_name;
|
||||||
parcel_out.note = "Delivered from a Bazaar Purchase";
|
parcel_out.note = "Delivered from a Bazaar Purchase";
|
||||||
parcel_out.sent_date = time(nullptr);
|
parcel_out.sent_date = time(nullptr);
|
||||||
parcel_out.quantity = buy_item->IsStackable() ? tbs->quantity : buy_item->GetCharges();
|
parcel_out.quantity = charges;
|
||||||
parcel_out.item_id = buy_item->GetItem()->ID;
|
parcel_out.item_id = buy_item->GetItem()->ID;
|
||||||
parcel_out.aug_slot_1 = buy_item->GetAugmentItemID(0);
|
parcel_out.aug_slot_1 = buy_item->GetAugmentItemID(0);
|
||||||
parcel_out.aug_slot_2 = buy_item->GetAugmentItemID(1);
|
parcel_out.aug_slot_2 = buy_item->GetAugmentItemID(1);
|
||||||
@ -3017,7 +3021,8 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
e.augment_4_id = parcel_out.aug_slot_4;
|
e.augment_4_id = parcel_out.aug_slot_4;
|
||||||
e.augment_5_id = parcel_out.aug_slot_5;
|
e.augment_5_id = parcel_out.aug_slot_5;
|
||||||
e.augment_6_id = parcel_out.aug_slot_6;
|
e.augment_6_id = parcel_out.aug_slot_6;
|
||||||
e.quantity = parcel_out.quantity;
|
e.quantity = tbs->quantity;
|
||||||
|
e.charges = buy_item->IsStackable() ? 1 : charges;
|
||||||
e.sent_date = parcel_out.sent_date;
|
e.sent_date = parcel_out.sent_date;
|
||||||
|
|
||||||
RecordPlayerEventLog(PlayerEvent::PARCEL_SEND, e);
|
RecordPlayerEventLog(PlayerEvent::PARCEL_SEND, e);
|
||||||
@ -3060,6 +3065,8 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
strn0cpy(out_data->trader_buy_struct.buyer_name, GetCleanName(), sizeof(out_data->trader_buy_struct.buyer_name));
|
strn0cpy(out_data->trader_buy_struct.buyer_name, GetCleanName(), sizeof(out_data->trader_buy_struct.buyer_name));
|
||||||
|
|
||||||
worldserver.SendPacket(out_server.get());
|
worldserver.SendPacket(out_server.get());
|
||||||
|
|
||||||
|
SendMoneyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetBuyerWelcomeMessage(const char *welcome_message)
|
void Client::SetBuyerWelcomeMessage(const char *welcome_message)
|
||||||
|
|||||||
@ -4002,21 +4002,23 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
|
|
||||||
TraderRepository::UpdateActiveTransaction(database, in->id, false);
|
TraderRepository::UpdateActiveTransaction(database, in->id, false);
|
||||||
|
|
||||||
|
auto item = trader_pc->FindTraderItemBySerialNumber(item_sn);
|
||||||
|
|
||||||
if (player_event_logs.IsEventEnabled(PlayerEvent::TRADER_SELL)) {
|
if (player_event_logs.IsEventEnabled(PlayerEvent::TRADER_SELL)) {
|
||||||
auto buy_item = trader_pc->FindTraderItemBySerialNumber(item_sn);
|
auto e = PlayerEvent::TraderSellEvent{
|
||||||
auto e = PlayerEvent::TraderSellEvent{
|
.item_id = item ? item->GetID() : 0,
|
||||||
.item_id = in->trader_buy_struct.item_id,
|
.augment_1_id = item->GetAugmentItemID(0),
|
||||||
.augment_1_id = buy_item->GetAugmentItemID(0),
|
.augment_2_id = item->GetAugmentItemID(1),
|
||||||
.augment_2_id = buy_item->GetAugmentItemID(1),
|
.augment_3_id = item->GetAugmentItemID(2),
|
||||||
.augment_3_id = buy_item->GetAugmentItemID(2),
|
.augment_4_id = item->GetAugmentItemID(3),
|
||||||
.augment_4_id = buy_item->GetAugmentItemID(3),
|
.augment_5_id = item->GetAugmentItemID(4),
|
||||||
.augment_5_id = buy_item->GetAugmentItemID(4),
|
.augment_6_id = item->GetAugmentItemID(5),
|
||||||
.augment_6_id = buy_item->GetAugmentItemID(5),
|
|
||||||
.item_name = in->trader_buy_struct.item_name,
|
.item_name = in->trader_buy_struct.item_name,
|
||||||
.buyer_id = in->buyer_id,
|
.buyer_id = in->buyer_id,
|
||||||
.buyer_name = in->trader_buy_struct.buyer_name,
|
.buyer_name = in->trader_buy_struct.buyer_name,
|
||||||
.price = in->trader_buy_struct.price,
|
.price = in->trader_buy_struct.price,
|
||||||
.charges = in->trader_buy_struct.quantity,
|
.quantity = in->trader_buy_struct.quantity,
|
||||||
|
.charges = item ? item->IsStackable() ? 1 : item->GetCharges() : 0,
|
||||||
.total_cost = (in->trader_buy_struct.price * in->trader_buy_struct.quantity),
|
.total_cost = (in->trader_buy_struct.price * in->trader_buy_struct.quantity),
|
||||||
.player_money_balance = trader_pc->GetCarriedMoney(),
|
.player_money_balance = trader_pc->GetCarriedMoney(),
|
||||||
};
|
};
|
||||||
@ -4121,7 +4123,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
sell_line.seller_quantity,
|
sell_line.seller_quantity,
|
||||||
sell_line.item_name,
|
sell_line.item_name,
|
||||||
buyer->GetCleanName());
|
buyer->GetCleanName());
|
||||||
buyer->AddMoneyToPPWithOverflow(total_cost, true);
|
buyer->AddMoneyToPP(total_cost, true);
|
||||||
buyer->RemoveItem(sell_line.item_id, sell_line.seller_quantity);
|
buyer->RemoveItem(sell_line.item_id, sell_line.seller_quantity);
|
||||||
|
|
||||||
buyer->Message(
|
buyer->Message(
|
||||||
@ -4220,7 +4222,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
if (inst->IsStackable()) {
|
if (inst->IsStackable()) {
|
||||||
if (!buyer->PutItemInInventoryWithStacking(inst.get())) {
|
if (!buyer->PutItemInInventoryWithStacking(inst.get())) {
|
||||||
buyer->Message(Chat::Red, "Error putting item in your inventory.");
|
buyer->Message(Chat::Red, "Error putting item in your inventory.");
|
||||||
buyer->AddMoneyToPPWithOverflow(total_cost, true);
|
buyer->AddMoneyToPP(total_cost, true);
|
||||||
in->action = Barter_FailedTransaction;
|
in->action = Barter_FailedTransaction;
|
||||||
in->sub_action = Barter_FailedBuyerChecks;
|
in->sub_action = Barter_FailedBuyerChecks;
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
@ -4232,7 +4234,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
inst->SetCharges(1);
|
inst->SetCharges(1);
|
||||||
if (!buyer->PutItemInInventoryWithStacking(inst.get())) {
|
if (!buyer->PutItemInInventoryWithStacking(inst.get())) {
|
||||||
buyer->Message(Chat::Red, "Error putting item in your inventory.");
|
buyer->Message(Chat::Red, "Error putting item in your inventory.");
|
||||||
buyer->AddMoneyToPPWithOverflow(total_cost, true);
|
buyer->AddMoneyToPP(total_cost, true);
|
||||||
in->action = Barter_FailedTransaction;
|
in->action = Barter_FailedTransaction;
|
||||||
in->sub_action = Barter_FailedBuyerChecks;
|
in->sub_action = Barter_FailedBuyerChecks;
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
@ -4241,7 +4243,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buyer->TakeMoneyFromPPWithOverFlow(total_cost, false)) {
|
if (!buyer->TakeMoneyFromPP(total_cost, false)) {
|
||||||
in->action = Barter_FailedTransaction;
|
in->action = Barter_FailedTransaction;
|
||||||
in->sub_action = Barter_FailedBuyerChecks;
|
in->sub_action = Barter_FailedBuyerChecks;
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
@ -4306,7 +4308,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
|
|
||||||
uint64 total_cost = (uint64) sell_line.item_cost * (uint64) sell_line.seller_quantity;
|
uint64 total_cost = (uint64) sell_line.item_cost * (uint64) sell_line.seller_quantity;
|
||||||
seller->RemoveItem(in->buy_item_id, in->seller_quantity);
|
seller->RemoveItem(in->buy_item_id, in->seller_quantity);
|
||||||
seller->AddMoneyToPPWithOverflow(total_cost, false);
|
seller->AddMoneyToPP(total_cost, false);
|
||||||
seller->SendBarterBuyerClientMessage(
|
seller->SendBarterBuyerClientMessage(
|
||||||
sell_line,
|
sell_line,
|
||||||
Barter_SellerTransactionComplete,
|
Barter_SellerTransactionComplete,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user