From c6377b93d517a02b369b8881c8028823486adae8 Mon Sep 17 00:00:00 2001 From: cavedude00 Date: Sun, 23 Feb 2014 15:55:26 -0800 Subject: [PATCH] Merchants will now keep track of charges sold to them properly so it is no longer possible to recharge items using merchants. --- common/Item.cpp | 8 ++++++ common/Item.h | 1 + zone/client_packet.cpp | 60 +++++++++++++++++++++++------------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/common/Item.cpp b/common/Item.cpp index 2e43a6d75..82e3b5112 100644 --- a/common/Item.cpp +++ b/common/Item.cpp @@ -238,6 +238,14 @@ bool ItemInst::IsStackable() const return m_item->Stackable; } +bool ItemInst::IsCharged() const +{ + if(m_item->MaxCharges > 1) + return true; + else + return false; +} + // Can item be equipped? bool ItemInst::IsEquipable(uint16 race, uint16 class_) const diff --git a/common/Item.h b/common/Item.h index 33f0ff12f..d62d92bda 100644 --- a/common/Item.h +++ b/common/Item.h @@ -291,6 +291,7 @@ public: // Can item be stacked? bool IsStackable() const; + bool IsCharged() const; // Can item be equipped by/at? bool IsEquipable(uint16 race, uint16 class_) const; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index af17626fb..d304715e4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -5561,8 +5561,13 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) Message(15,"You can only have one of a lore item."); return; } - if(tmpmer_used && (mp->quantity > prevcharges)) - mp->quantity = prevcharges; + if(tmpmer_used && (mp->quantity > prevcharges || item->MaxCharges > 1)) + { + if(prevcharges > item->MaxCharges && item->MaxCharges > 1) + mp->quantity = item->MaxCharges; + else + mp->quantity = prevcharges; + } EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopPlayerBuy, sizeof(Merchant_Sell_Struct)); Merchant_Sell_Struct* mpo=(Merchant_Sell_Struct*)outapp->pBuffer; @@ -5573,13 +5578,11 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) int16 freeslotid=0; int16 charges = 0; - if (item->Stackable) { + if (item->Stackable || item->MaxCharges > 1) charges = mp->quantity; - } else { - // this needs expanded to handle varying charges from the merchant, - // but will require merchantlist_temp changes amonst other things. + else charges = item->MaxCharges; - } + ItemInst* inst = database.CreateItem(item, charges); int SinglePrice = 0; @@ -5588,7 +5591,10 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) else SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate); - mpo->price = SinglePrice * mp->quantity; + if(item->MaxCharges > 1) + mpo->price = SinglePrice; + else + mpo->price = SinglePrice * mp->quantity; if(mpo->price < 0 ) { safe_delete(outapp); @@ -5632,9 +5638,6 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) } std::string packet; - if(mp->quantity==1 && item->MaxCharges>0 && item->MaxCharges<255) - mp->quantity=item->MaxCharges; - if (!stacked && inst) { PutItemInInventory(freeslotid, *inst); SendItemPacket(freeslotid, inst, ItemPacketTrade); @@ -5756,37 +5759,36 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) //Message(13,"%s tells you, 'LOL NOPE'", vendor->GetName()); return; } - if (RuleB(Merchant, UsePriceMod)){ - price=(int)((item->Price*mp->quantity)*(RuleR(Merchant, BuyCostMod))*Client::CalcPriceMod(vendor,true)+0.5); // need to round up, because client does it automatically when displaying price - } + + int cost_quantity = mp->quantity; + if(inst->IsCharged()) + int cost_quantity = 1; + + if (RuleB(Merchant, UsePriceMod)) + price=(int)((item->Price*cost_quantity)*(RuleR(Merchant, BuyCostMod))*Client::CalcPriceMod(vendor,true)+0.5); // need to round up, because client does it automatically when displaying price else - price=(int)((item->Price*mp->quantity)*(RuleR(Merchant, BuyCostMod))+0.5); + price=(int)((item->Price*cost_quantity)*(RuleR(Merchant, BuyCostMod))+0.5); AddMoneyToPP(price,false); - if (inst->IsStackable()) + if (inst->IsStackable() || inst->IsCharged()) { unsigned int i_quan = inst->GetCharges(); - if (mp->quantity > i_quan) + if (mp->quantity > i_quan || inst->IsCharged()) mp->quantity = i_quan; } else - { mp->quantity = 1; - } if (RuleB(EventLog, RecordSellToMerchant)) LogMerchant(this, vendor, mp->quantity, price, item, false); - int freeslot = 0; - int charges = 0; - if(inst->IsStackable()) - charges = mp->quantity; - else - //charges = inst->GetCharges(); - //FIXME: Temp merchant table uses 'charges' as the quantity, so doesn't properly handle charged items. + int charges = mp->quantity; + //Hack workaround so usable items with 0 charges aren't simply deleted + if(charges == 0 && item->ItemType != 11 && item->ItemType != 17 && item->ItemType != 19 && item->ItemType != 21) charges = 1; - if((freeslot = zone->SaveTempItem(vendor->CastToNPC()->MerchantType, vendor->GetNPCTypeID(),itemid,charges,true)) > 0){ + int freeslot = 0; + if(charges > 0 && (freeslot = zone->SaveTempItem(vendor->CastToNPC()->MerchantType, vendor->GetNPCTypeID(),itemid,charges,true)) > 0){ ItemInst* inst2 = inst->Clone(); if (RuleB(Merchant, UsePriceMod)){ inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(vendor,false)); @@ -5846,6 +5848,10 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) else this->DeleteItemInInventory(mp->itemslot,mp->quantity,false); + //This forces the price to show up correctly for charged items. + if(inst->IsCharged()) + mp->quantity = 1; + EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopPlayerSell, sizeof(Merchant_Purchase_Struct)); Merchant_Purchase_Struct* mco=(Merchant_Purchase_Struct*)outapp->pBuffer; mco->npcid = vendor->GetID();