mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
(RoF2) Bazaar Trading (Buying/Selling) is now fully functional. Bazaar (/bazaar) search is not yet functional.
This commit is contained in:
@@ -165,6 +165,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
Trader=false;
|
||||
Buyer = false;
|
||||
CustomerID = 0;
|
||||
TraderID = 0;
|
||||
TrackingID = 0;
|
||||
WID = 0;
|
||||
account_id = 0;
|
||||
|
||||
+4
-2
@@ -266,10 +266,11 @@ public:
|
||||
void SendBazaarResults(uint32 trader_id,uint32 class_,uint32 race,uint32 stat,uint32 slot,uint32 type,char name[64],uint32 minprice,uint32 maxprice);
|
||||
void SendTraderItem(uint32 item_id,uint16 quantity);
|
||||
uint16 FindTraderItem(int32 SerialNumber,uint16 Quantity);
|
||||
uint32 FindTraderItemSerialNumber(int32 ItemID);
|
||||
ItemInst* FindTraderItemBySerialNumber(int32 SerialNumber);
|
||||
void FindAndNukeTraderItem(int32 item_id,uint16 quantity,Client* customer,uint16 traderslot);
|
||||
void NukeTraderItem(uint16 slot,int16 charges,uint16 quantity,Client* customer,uint16 traderslot, int uniqueid);
|
||||
void ReturnTraderReq(const EQApplicationPacket* app,int16 traderitemcharges);
|
||||
void NukeTraderItem(uint16 slot, int16 charges, uint16 quantity, Client* customer, uint16 traderslot, int32 uniqueid, int32 itemid = 0);
|
||||
void ReturnTraderReq(const EQApplicationPacket* app,int16 traderitemcharges, uint32 itemid = 0);
|
||||
void TradeRequestFailed(const EQApplicationPacket* app);
|
||||
void BuyTraderItem(TraderBuy_Struct* tbs,Client* trader,const EQApplicationPacket* app);
|
||||
void TraderUpdate(uint16 slot_id,uint32 trader_id);
|
||||
@@ -1388,6 +1389,7 @@ private:
|
||||
uint16 BoatID;
|
||||
uint16 TrackingID;
|
||||
uint16 CustomerID;
|
||||
uint16 TraderID;
|
||||
uint32 account_creation;
|
||||
uint8 firstlogon;
|
||||
uint32 mercid; // current merc
|
||||
|
||||
+99
-57
@@ -11952,12 +11952,6 @@ void Client::Handle_OP_ShopEnd(const EQApplicationPacket *app)
|
||||
{
|
||||
EQApplicationPacket empty(OP_ShopEndConfirm);
|
||||
QueuePacket(&empty);
|
||||
//EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopEndConfirm, 2);
|
||||
//outapp->pBuffer[0] = 0x0a;
|
||||
//outapp->pBuffer[1] = 0x66;
|
||||
//QueuePacket(outapp);
|
||||
//safe_delete(outapp);
|
||||
//Save();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13443,23 +13437,22 @@ void Client::Handle_OP_TraderBuy(const EQApplicationPacket *app)
|
||||
//
|
||||
// Client has elected to buy an item from a Trader
|
||||
//
|
||||
if (app->size != sizeof(TraderBuy_Struct)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Wrong size: OP_TraderBuy, size=%i, expected %i", app->size, sizeof(TraderBuy_Struct));
|
||||
return;
|
||||
}
|
||||
|
||||
if (app->size == sizeof(TraderBuy_Struct)){
|
||||
TraderBuy_Struct* tbs = (TraderBuy_Struct*)app->pBuffer;
|
||||
|
||||
TraderBuy_Struct* tbs = (TraderBuy_Struct*)app->pBuffer;
|
||||
|
||||
if (Client* Trader = entity_list.GetClientByID(tbs->TraderID)){
|
||||
BuyTraderItem(tbs, Trader, app);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Buy Trader Item ");
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Null Client Pointer");
|
||||
}
|
||||
if (Client* Trader = entity_list.GetClientByID(tbs->TraderID)){
|
||||
BuyTraderItem(tbs, Trader, app);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Buy Trader Item ");
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Struct size mismatch");
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Null Client Pointer");
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13521,56 +13514,105 @@ void Client::Handle_OP_TradeRequestAck(const EQApplicationPacket *app)
|
||||
void Client::Handle_OP_TraderShop(const EQApplicationPacket *app)
|
||||
{
|
||||
// Bazaar Trader:
|
||||
//
|
||||
// This is when a potential purchaser right clicks on this client who is in Trader mode to
|
||||
// browse their goods.
|
||||
//
|
||||
|
||||
if (app->size != sizeof(TraderClick_Struct)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Wrong size: OP_TraderShop, size=%i, expected %i", app->size, sizeof(TraderClick_Struct));
|
||||
return;
|
||||
}
|
||||
|
||||
TraderClick_Struct* tcs = (TraderClick_Struct*)app->pBuffer;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderClick_Struct));
|
||||
|
||||
TraderClick_Struct* outtcs = (TraderClick_Struct*)outapp->pBuffer;
|
||||
|
||||
Client* Trader = entity_list.GetClientByID(tcs->TraderID);
|
||||
|
||||
if (Trader)
|
||||
if (app->size == sizeof(TraderClick_Struct))
|
||||
{
|
||||
outtcs->Approval = Trader->WithCustomer(GetID());
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Shop Request (%s) to (%s) with Approval: %d", GetCleanName(), Trader->GetCleanName(), outtcs->Approval);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: entity_list.GetClientByID(tcs->traderid)"
|
||||
" returned a nullptr pointer");
|
||||
// This is when a potential purchaser right clicks on this client who is in Trader mode to
|
||||
// browse their goods.
|
||||
TraderClick_Struct* tcs = (TraderClick_Struct*)app->pBuffer;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderClick_Struct));
|
||||
|
||||
TraderClick_Struct* outtcs = (TraderClick_Struct*)outapp->pBuffer;
|
||||
|
||||
Client* Trader = entity_list.GetClientByID(tcs->TraderID);
|
||||
|
||||
if (Trader)
|
||||
{
|
||||
outtcs->Approval = Trader->WithCustomer(GetID());
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Shop Request (%s) to (%s) with Approval: %d", GetCleanName(), Trader->GetCleanName(), outtcs->Approval);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: entity_list.GetClientByID(tcs->traderid)"
|
||||
" returned a nullptr pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
outtcs->TraderID = tcs->TraderID;
|
||||
|
||||
outtcs->Unknown008 = 0x3f800000;
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
|
||||
if (outtcs->Approval) {
|
||||
this->BulkSendTraderInventory(Trader->CharacterID());
|
||||
Trader->Trader_CustomerBrowsing(this);
|
||||
TraderID = tcs->TraderID;
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Inventory Sent");
|
||||
}
|
||||
else
|
||||
{
|
||||
Message_StringID(clientMessageYellow, TRADER_BUSY);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy");
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (app->size == sizeof(TraderBuy_Struct))
|
||||
{
|
||||
// RoF+
|
||||
// Customer has purchased an item from the Trader
|
||||
|
||||
outtcs->TraderID = tcs->TraderID;
|
||||
TraderBuy_Struct* tbs = (TraderBuy_Struct*)app->pBuffer;
|
||||
|
||||
outtcs->Unknown008 = 0x3f800000;
|
||||
if (Client* Trader = entity_list.GetClientByID(tbs->TraderID))
|
||||
{
|
||||
BuyTraderItem(tbs, Trader, app);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Handle_OP_TraderShop: Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||
tbs->Action, tbs->Price, tbs->TraderID, tbs->ItemID, tbs->Quantity, tbs->ItemName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "OP_TraderShop: Null Client Pointer");
|
||||
}
|
||||
}
|
||||
else if (app->size == 4)
|
||||
{
|
||||
// RoF+
|
||||
// Customer has closed the trade window
|
||||
uint32 Command = *((uint32 *)app->pBuffer);
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
|
||||
if (outtcs->Approval) {
|
||||
this->BulkSendTraderInventory(Trader->CharacterID());
|
||||
Trader->Trader_CustomerBrowsing(this);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Inventory Sent");
|
||||
if (Command == 4)
|
||||
{
|
||||
Client* c = entity_list.GetClientByID(TraderID);
|
||||
TraderID = 0;
|
||||
if (c)
|
||||
{
|
||||
c->WithCustomer(0);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: End Transaction - Code %d", Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Null Client Pointer for Trader - Code %d", Command);
|
||||
}
|
||||
EQApplicationPacket empty(OP_ShopEndConfirm);
|
||||
QueuePacket(&empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Unhandled Code %d", Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Message_StringID(clientMessageYellow, TRADER_BUSY);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy");
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Unknown size for OP_TraderShop: %i\n", app->size);
|
||||
Log.Out(Logs::General, Logs::Error, "Unknown size for OP_TraderShop: %i\n", app->size);
|
||||
DumpPacket(app);
|
||||
return;
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Client::Handle_OP_TradeSkillCombine(const EQApplicationPacket *app)
|
||||
|
||||
+167
-72
@@ -1098,7 +1098,15 @@ void Client::Trader_EndTrader() {
|
||||
for(int i = 0; i < 80; i++) {
|
||||
if(gis->Items[i] != 0) {
|
||||
|
||||
tdis->ItemID = gis->SerialNumber[i];
|
||||
if (Customer->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// RoF+ use Item IDs for now
|
||||
tdis->ItemID = gis->Items[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
tdis->ItemID = gis->SerialNumber[i];
|
||||
}
|
||||
|
||||
Customer->QueuePacket(outapp);
|
||||
}
|
||||
@@ -1220,6 +1228,29 @@ void Client::BulkSendTraderInventory(uint32 char_id) {
|
||||
safe_delete(TraderItems);
|
||||
}
|
||||
|
||||
uint32 Client::FindTraderItemSerialNumber(int32 ItemID) {
|
||||
|
||||
ItemInst* item = nullptr;
|
||||
uint16 SlotID = 0;
|
||||
for (int i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++){
|
||||
item = this->GetInv().GetItem(i);
|
||||
if (item && item->GetItem()->ID == 17899){ //Traders Satchel
|
||||
for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; x++) {
|
||||
// we already have the parent bag and a contents iterator..why not just iterate the bag!??
|
||||
SlotID = Inventory::CalcSlotId(i, x);
|
||||
item = this->GetInv().GetItem(SlotID);
|
||||
if (item) {
|
||||
if (item->GetID() == ItemID)
|
||||
return item->GetSerialNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::FindTraderItemSerialNumber Couldn't find item! Item ID %i", ItemID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemInst* Client::FindTraderItemBySerialNumber(int32 SerialNumber){
|
||||
|
||||
ItemInst* item = nullptr;
|
||||
@@ -1287,9 +1318,9 @@ uint16 Client::FindTraderItem(int32 SerialNumber, uint16 Quantity){
|
||||
|
||||
item = this->GetInv().GetItem(SlotID);
|
||||
|
||||
if(item && item->GetSerialNumber() == SerialNumber &&
|
||||
(item->GetCharges() >= Quantity || (item->GetCharges() <= 0 && Quantity == 1))){
|
||||
|
||||
if (item && item->GetSerialNumber() == SerialNumber &&
|
||||
(item->GetCharges() >= Quantity || (item->GetCharges() <= 0 && Quantity == 1)))
|
||||
{
|
||||
return SlotID;
|
||||
}
|
||||
}
|
||||
@@ -1301,21 +1332,34 @@ uint16 Client::FindTraderItem(int32 SerialNumber, uint16 Quantity){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Client::NukeTraderItem(uint16 Slot,int16 Charges,uint16 Quantity,Client* Customer,uint16 TraderSlot, int SerialNumber) {
|
||||
void Client::NukeTraderItem(uint16 Slot,int16 Charges,uint16 Quantity,Client* Customer,uint16 TraderSlot, int32 SerialNumber, int32 itemid) {
|
||||
|
||||
if(!Customer)
|
||||
return;
|
||||
|
||||
if(!Customer) return;
|
||||
Log.Out(Logs::Detail, Logs::Trading, "NukeTraderItem(Slot %i, Charges %i, Quantity %i", Slot, Charges, Quantity);
|
||||
if(Quantity < Charges) {
|
||||
|
||||
if(Quantity < Charges)
|
||||
{
|
||||
Customer->SendSingleTraderItem(this->CharacterID(), SerialNumber);
|
||||
m_inv.DeleteItem(Slot, Quantity);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderDelItem,sizeof(TraderDelItem_Struct));
|
||||
TraderDelItem_Struct* tdis = (TraderDelItem_Struct*)outapp->pBuffer;
|
||||
|
||||
tdis->Unknown000 = 0;
|
||||
tdis->TraderID = Customer->GetID();
|
||||
tdis->ItemID = SerialNumber;
|
||||
if (Customer->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// RoF+ use Item IDs for now
|
||||
tdis->ItemID = itemid;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdis->ItemID = SerialNumber;
|
||||
}
|
||||
tdis->Unknown012 = 0;
|
||||
|
||||
|
||||
@@ -1323,7 +1367,6 @@ void Client::NukeTraderItem(uint16 Slot,int16 Charges,uint16 Quantity,Client* Cu
|
||||
safe_delete(outapp);
|
||||
|
||||
m_inv.DeleteItem(Slot);
|
||||
|
||||
}
|
||||
// This updates the trader. Removes it from his trading bags.
|
||||
//
|
||||
@@ -1374,49 +1417,61 @@ void Client::FindAndNukeTraderItem(int32 SerialNumber, uint16 Quantity, Client*
|
||||
int16 Charges=0;
|
||||
|
||||
uint16 SlotID = FindTraderItem(SerialNumber, Quantity);
|
||||
if(SlotID > 0){
|
||||
|
||||
if(SlotID > 0) {
|
||||
|
||||
item = this->GetInv().GetItem(SlotID);
|
||||
|
||||
if(item) {
|
||||
Charges = this->GetInv().GetItem(SlotID)->GetCharges();
|
||||
|
||||
Stackable = item->IsStackable();
|
||||
|
||||
if(!Stackable)
|
||||
Quantity = (Charges > 0) ? Charges : 1;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "FindAndNuke %s, Charges %i, Quantity %i", item->GetItem()->Name, Charges, Quantity);
|
||||
if (!item)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Could not find Item: %i on Trader: %s", SerialNumber, Quantity, this->GetName());
|
||||
return;
|
||||
}
|
||||
if(item && (Charges <= Quantity || (Charges <= 0 && Quantity==1) || !Stackable)){
|
||||
|
||||
Charges = this->GetInv().GetItem(SlotID)->GetCharges();
|
||||
|
||||
Stackable = item->IsStackable();
|
||||
|
||||
if (!Stackable)
|
||||
Quantity = (Charges > 0) ? Charges : 1;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "FindAndNuke %s, Charges %i, Quantity %i", item->GetItem()->Name, Charges, Quantity);
|
||||
|
||||
if (Charges <= Quantity || (Charges <= 0 && Quantity==1) || !Stackable)
|
||||
{
|
||||
this->DeleteItemInInventory(SlotID, Quantity);
|
||||
|
||||
TraderCharges_Struct* GetSlot = database.LoadTraderItemWithCharges(this->CharacterID());
|
||||
TraderCharges_Struct* TraderItems = database.LoadTraderItemWithCharges(this->CharacterID());
|
||||
|
||||
uint8 Count = 0;
|
||||
|
||||
bool TestSlot = true;
|
||||
|
||||
for(int y = 0;y < 80;y++){
|
||||
for(int i = 0;i < 80;i++){
|
||||
|
||||
if(TestSlot && GetSlot->SerialNumber[y] == SerialNumber){
|
||||
|
||||
database.DeleteTraderItem(this->CharacterID(),y);
|
||||
NukeTraderItem(SlotID, Charges, Quantity, Customer, TraderSlot, GetSlot->SerialNumber[y]);
|
||||
if(TestSlot && TraderItems->SerialNumber[i] == SerialNumber)
|
||||
{
|
||||
database.DeleteTraderItem(this->CharacterID(),i);
|
||||
NukeTraderItem(SlotID, Charges, Quantity, Customer, TraderSlot, TraderItems->SerialNumber[i], TraderItems->ItemID[i]);
|
||||
TestSlot=false;
|
||||
}
|
||||
else if(GetSlot->ItemID[y] > 0)
|
||||
else if (TraderItems->ItemID[i] > 0)
|
||||
{
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
if(Count == 0)
|
||||
if (Count == 0)
|
||||
{
|
||||
Trader_EndTrader();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if(item) {
|
||||
else
|
||||
{
|
||||
database.UpdateTraderItemCharges(this->CharacterID(), item->GetSerialNumber(), Charges-Quantity);
|
||||
|
||||
NukeTraderItem(SlotID, Charges, Quantity, Customer, TraderSlot, item->GetSerialNumber());
|
||||
NukeTraderItem(SlotID, Charges, Quantity, Customer, TraderSlot, item->GetSerialNumber(), item->GetID());
|
||||
|
||||
return;
|
||||
|
||||
@@ -1426,22 +1481,38 @@ void Client::FindAndNukeTraderItem(int32 SerialNumber, uint16 Quantity, Client*
|
||||
Quantity,this->GetName());
|
||||
}
|
||||
|
||||
void Client::ReturnTraderReq(const EQApplicationPacket* app, int16 TraderItemCharges){
|
||||
void Client::ReturnTraderReq(const EQApplicationPacket* app, int16 TraderItemCharges, uint32 itemid){
|
||||
|
||||
TraderBuy_Struct* tbs = (TraderBuy_Struct*)app->pBuffer;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderBuy, sizeof(TraderBuy_Struct));
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderBuy_Struct));
|
||||
}
|
||||
else
|
||||
{
|
||||
outapp = new EQApplicationPacket(OP_TraderBuy, sizeof(TraderBuy_Struct));
|
||||
}
|
||||
|
||||
TraderBuy_Struct* outtbs = (TraderBuy_Struct*)outapp->pBuffer;
|
||||
|
||||
memcpy(outtbs, tbs, app->size);
|
||||
|
||||
outtbs->Price = (tbs->Price * static_cast<uint32>(TraderItemCharges));
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// Convert Serial Number back to Item ID for RoF+
|
||||
outtbs->ItemID = itemid;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RoF+ requires individual price, but older clients require total price
|
||||
outtbs->Price = (tbs->Price * static_cast<uint32>(TraderItemCharges));
|
||||
}
|
||||
|
||||
outtbs->Quantity = TraderItemCharges;
|
||||
|
||||
// This should probably be trader ID, not customer ID as it is below.
|
||||
outtbs->TraderID = this->GetID();
|
||||
|
||||
outtbs->AlreadySold = 0;
|
||||
|
||||
QueuePacket(outapp);
|
||||
@@ -1478,7 +1549,7 @@ static void BazaarAuditTrail(const char *seller, const char *buyer, const char *
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicationPacket* app){
|
||||
void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplicationPacket* app){
|
||||
|
||||
if(!Trader) return;
|
||||
|
||||
@@ -1487,13 +1558,34 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat
|
||||
return;
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Trader,sizeof(TraderBuy_Struct));
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
|
||||
if (Trader->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
//outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderBuy_Struct));
|
||||
}
|
||||
else
|
||||
{
|
||||
//outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
}
|
||||
|
||||
outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
|
||||
TraderBuy_Struct* outtbs = (TraderBuy_Struct*)outapp->pBuffer;
|
||||
|
||||
outtbs->ItemID = tbs->ItemID;
|
||||
|
||||
const ItemInst* BuyItem = Trader->FindTraderItemBySerialNumber(tbs->ItemID);
|
||||
const ItemInst* BuyItem = nullptr;
|
||||
uint32 ItemID = 0;
|
||||
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// Convert Item ID to Serial Number for RoF+
|
||||
ItemID = tbs->ItemID;
|
||||
tbs->ItemID = Trader->FindTraderItemSerialNumber(tbs->ItemID);
|
||||
}
|
||||
|
||||
BuyItem = Trader->FindTraderItemBySerialNumber(tbs->ItemID);
|
||||
|
||||
if(!BuyItem) {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Unable to find item on trader.");
|
||||
@@ -1543,12 +1635,10 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnTraderReq(app, outtbs->Quantity);
|
||||
ReturnTraderReq(app, outtbs->Quantity, ItemID);
|
||||
|
||||
outtbs->TraderID = this->GetID();
|
||||
|
||||
outtbs->Action = BazaarBuyItem;
|
||||
|
||||
strn0cpy(outtbs->ItemName, BuyItem->GetItem()->Name, 64);
|
||||
|
||||
int TraderSlot = 0;
|
||||
@@ -1558,54 +1648,50 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat
|
||||
else
|
||||
SendTraderItem(BuyItem->GetItem()->ID, BuyItem->GetCharges());
|
||||
|
||||
|
||||
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoneyUpdate,sizeof(MoneyUpdate_Struct));
|
||||
|
||||
MoneyUpdate_Struct* mus= (MoneyUpdate_Struct*)outapp2->pBuffer;
|
||||
|
||||
// This cannot overflow assuming MAX_TRANSACTION_VALUE, checked above, is the default of 2000000000
|
||||
uint32 TotalCost = tbs->Price * outtbs->Quantity;
|
||||
|
||||
outtbs->Price = TotalCost;
|
||||
if (Trader->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// RoF+ uses individual item price where older clients use total price
|
||||
outtbs->Price = tbs->Price;
|
||||
}
|
||||
else
|
||||
{
|
||||
outtbs->Price = TotalCost;
|
||||
}
|
||||
|
||||
this->TakeMoneyFromPP(TotalCost);
|
||||
|
||||
mus->platinum = TotalCost / 1000;
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Customer Paid: %d in Copper", TotalCost);
|
||||
|
||||
TotalCost -= (mus->platinum * 1000);
|
||||
uint32 platinum = TotalCost / 1000;
|
||||
TotalCost -= (platinum * 1000);
|
||||
uint32 gold = TotalCost / 100;
|
||||
TotalCost -= (gold * 100);
|
||||
uint32 silver = TotalCost / 10;
|
||||
TotalCost -= (silver * 10);
|
||||
uint32 copper = TotalCost;
|
||||
|
||||
mus->gold = TotalCost / 100;
|
||||
Trader->AddMoneyToPP(copper, silver, gold, platinum, true);
|
||||
|
||||
TotalCost -= (mus->gold * 100);
|
||||
|
||||
mus->silver = TotalCost / 10;
|
||||
|
||||
TotalCost -= (mus->silver * 10);
|
||||
|
||||
mus->copper = TotalCost;
|
||||
|
||||
Trader->AddMoneyToPP(mus->copper,mus->silver,mus->gold,mus->platinum,false);
|
||||
|
||||
mus->platinum = Trader->GetPlatinum();
|
||||
mus->gold = Trader->GetGold();
|
||||
mus->silver = Trader->GetSilver();
|
||||
mus->copper = Trader->GetCopper();
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Trader Received: %d Platinum, %d Gold, %d Silver, %d Copper", platinum, gold, silver, copper);
|
||||
|
||||
TraderSlot = Trader->FindTraderItem(tbs->ItemID, outtbs->Quantity);
|
||||
|
||||
Trader->QueuePacket(outapp2);
|
||||
|
||||
|
||||
if(RuleB(Bazaar, AuditTrail))
|
||||
BazaarAuditTrail(Trader->GetName(), GetName(), BuyItem->GetItem()->Name, outtbs->Quantity, outtbs->Price, 0);
|
||||
|
||||
Trader->FindAndNukeTraderItem(tbs->ItemID, outtbs->Quantity, this, 0);
|
||||
|
||||
if (ItemID > 0 && Trader->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// Convert Serial Number back to ItemID for RoF+
|
||||
outtbs->ItemID = ItemID;
|
||||
}
|
||||
|
||||
Trader->QueuePacket(outapp);
|
||||
|
||||
|
||||
safe_delete(outapp);
|
||||
safe_delete(outapp2);
|
||||
}
|
||||
|
||||
void Client::SendBazaarWelcome()
|
||||
@@ -1996,6 +2082,15 @@ static void UpdateTraderCustomerPriceChanged(uint32 CustomerID, TraderCharges_St
|
||||
for(int i = 0; i < 80; i++) {
|
||||
|
||||
if(gis->ItemID[i] == ItemID) {
|
||||
if (Customer->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// RoF+ use Item IDs for now
|
||||
tdis->ItemID = gis->ItemID[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
tdis->ItemID = gis->SerialNumber[i];
|
||||
}
|
||||
tdis->ItemID = gis->SerialNumber[i];
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Telling customer to remove item %i with %i charges and S/N %i",
|
||||
ItemID, Charges, gis->SerialNumber[i]);
|
||||
|
||||
Reference in New Issue
Block a user