diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 544200910..d9b2d9030 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -967,93 +967,96 @@ void Client::BulkSendInventoryItems() void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { const Item_Struct* handyitem = nullptr; - uint32 numItemSlots=80; //The max number of items passed in the transaction. + uint32 numItemSlots = 80; //The max number of items passed in the transaction. const Item_Struct *item; std::list merlist = zone->merchanttable[merchant_id]; std::list::const_iterator itr; Mob* merch = entity_list.GetMobByNpcTypeID(npcid); - if(merlist.size()==0){ //Attempt to load the data, it might have been missed if someone spawned the merchant after the zone was loaded + if (merlist.size() == 0) { //Attempt to load the data, it might have been missed if someone spawned the merchant after the zone was loaded zone->LoadNewMerchantData(merchant_id); merlist = zone->merchanttable[merchant_id]; - if(merlist.size()==0) + if (merlist.size() == 0) return; } std::list tmp_merlist = zone->tmpmerchanttable[npcid]; std::list::iterator tmp_itr; - uint32 i=1; + uint32 i = 1; uint8 handychance = 0; - for (itr = merlist.begin(); itr != merlist.end() && i < numItemSlots; ++itr) { + for (itr = merlist.begin(); itr != merlist.end() && i <= numItemSlots; ++itr) { MerchantList ml = *itr; if (merch->CastToNPC()->GetMerchantProbability() > ml.probability) continue; - - if(GetLevel() < ml.level_required) + + if (GetLevel() < ml.level_required) continue; if (!(ml.classes_required & (1 << (GetClass() - 1)))) continue; int32 fac = merch ? merch->GetPrimaryFaction() : 0; - if(fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required) + if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required) continue; - handychance = MakeRandomInt(0, merlist.size() + tmp_merlist.size() - 1 ); + handychance = MakeRandomInt(0, merlist.size() + tmp_merlist.size() - 1); item = database.GetItem(ml.item); - if(item) { - if(handychance==0) - handyitem=item; + if (item) { + if (handychance == 0) + handyitem = item; else handychance--; - int charges=1; - if(item->ItemClass==ItemClassCommon) - charges=item->MaxCharges; + int charges = 1; + if (item->ItemClass == ItemClassCommon) + charges = item->MaxCharges; ItemInst* inst = database.CreateItem(item, charges); if (inst) { - if (RuleB(Merchant, UsePriceMod)){ - inst->SetPrice((item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(merch,false))); + if (RuleB(Merchant, UsePriceMod)) { + inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false))); } else - inst->SetPrice((item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate)); + inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate)); inst->SetMerchantSlot(ml.slot); inst->SetMerchantCount(-1); //unlimited - if(charges > 0) + if (charges > 0) inst->SetCharges(charges); else inst->SetCharges(1); - SendItemPacket(ml.slot-1, inst, ItemPacketMerchant); + SendItemPacket(ml.slot - 1, inst, ItemPacketMerchant); safe_delete(inst); } } // Account for merchant lists with gaps. - if(ml.slot >= i) + if (ml.slot >= i) { + if (ml.slot > i) + LogFile->write(EQEMuLog::Debug, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid); i = ml.slot + 1; + } } std::list origtmp_merlist = zone->tmpmerchanttable[npcid]; tmp_merlist.clear(); - for(tmp_itr = origtmp_merlist.begin();tmp_itr != origtmp_merlist.end() && iItemClass==ItemClassCommon && (int16)ml.charges <= item->MaxCharges) // charges=ml.charges; //else charges = item->MaxCharges; ItemInst* inst = database.CreateItem(item, charges); if (inst) { - if (RuleB(Merchant, UsePriceMod)){ - inst->SetPrice((item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(merch,false))); + if (RuleB(Merchant, UsePriceMod)) { + inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false))); } else - inst->SetPrice((item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate)); + inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate)); inst->SetMerchantSlot(ml.slot); inst->SetMerchantCount(ml.charges); if(charges > 0) @@ -1069,32 +1072,32 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { } //this resets the slot zone->tmpmerchanttable[npcid] = tmp_merlist; - if(merch != nullptr && handyitem){ - char handy_id[8]={0}; - int greeting=MakeRandomInt(0, 4); - int greet_id=0; - switch(greeting){ + if (merch != nullptr && handyitem) { + char handy_id[8] = { 0 }; + int greeting = MakeRandomInt(0, 4); + int greet_id = 0; + switch (greeting) { case 1: - greet_id=MERCHANT_GREETING; + greet_id = MERCHANT_GREETING; break; case 2: - greet_id=MERCHANT_HANDY_ITEM1; + greet_id = MERCHANT_HANDY_ITEM1; break; case 3: - greet_id=MERCHANT_HANDY_ITEM2; + greet_id = MERCHANT_HANDY_ITEM2; break; case 4: - greet_id=MERCHANT_HANDY_ITEM3; + greet_id = MERCHANT_HANDY_ITEM3; break; default: - greet_id=MERCHANT_HANDY_ITEM4; + greet_id = MERCHANT_HANDY_ITEM4; } - sprintf(handy_id,"%i",greet_id); + sprintf(handy_id, "%i", greet_id); - if(greet_id!=MERCHANT_GREETING) - Message_StringID(10,GENERIC_STRINGID_SAY,merch->GetCleanName(),handy_id,this->GetName(),handyitem->Name); + if (greet_id != MERCHANT_GREETING) + Message_StringID(10, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName(), handyitem->Name); else - Message_StringID(10,GENERIC_STRINGID_SAY,merch->GetCleanName(),handy_id,this->GetName()); + Message_StringID(10, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName()); merch->CastToNPC()->FaceTarget(this->CastToMob()); } diff --git a/zone/zone.cpp b/zone/zone.cpp index 446110a4a..23aa95f2c 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -307,41 +307,40 @@ bool Zone::LoadGroundSpawns() { return(true); } -int Zone::SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold){ +int Zone::SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold) { int freeslot = 0; std::list merlist = merchanttable[merchantid]; std::list::const_iterator itr; uint32 i = 1; for (itr = merlist.begin(); itr != merlist.end(); ++itr) { MerchantList ml = *itr; - if(ml.item == item) + if (ml.item == item) return 0; // Account for merchant lists with gaps in them. - if(ml.slot >= i) + if (ml.slot >= i) i = ml.slot + 1; - } std::list tmp_merlist = tmpmerchanttable[npcid]; std::list::const_iterator tmp_itr; bool update_charges = false; TempMerchantList ml; - while(freeslot == 0 && !update_charges){ + while (freeslot == 0 && !update_charges) { freeslot = i; for (tmp_itr = tmp_merlist.begin(); tmp_itr != tmp_merlist.end(); ++tmp_itr) { ml = *tmp_itr; - if(ml.item == item){ + if (ml.item == item) { update_charges = true; freeslot = 0; break; } - if((ml.slot == i) || (ml.origslot==i)) { - freeslot=0; + if ((ml.slot == i) || (ml.origslot == i)) { + freeslot = 0; } } i++; } - if(update_charges){ + if (update_charges) { tmp_merlist.clear(); std::list oldtmp_merlist = tmpmerchanttable[npcid]; for (tmp_itr = oldtmp_merlist.begin(); tmp_itr != oldtmp_merlist.end(); ++tmp_itr) { @@ -349,27 +348,27 @@ int Zone::SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charg if(ml2.item != item) tmp_merlist.push_back(ml2); } - if(sold) + if (sold) ml.charges = ml.charges + charges; else ml.charges = charges; - if(!ml.origslot) + if (!ml.origslot) ml.origslot = ml.slot; - if(charges>0){ + if (charges > 0) { database.SaveMerchantTemp(npcid, ml.origslot, item, ml.charges); tmp_merlist.push_back(ml); } - else{ - database.DeleteMerchantTemp(npcid,ml.origslot); + else { + database.DeleteMerchantTemp(npcid, ml.origslot); } tmpmerchanttable[npcid] = tmp_merlist; - if(sold) + if (sold) return ml.slot; } - if(freeslot){ - if(charges<0) //sanity check only, shouldnt happen + if (freeslot) { + if (charges < 0) //sanity check only, shouldnt happen charges = 0x7FFF; database.SaveMerchantTemp(npcid, freeslot, item, charges); tmp_merlist = tmpmerchanttable[npcid]; @@ -391,13 +390,13 @@ uint32 Zone::GetTempMerchantQuantity(uint32 NPCID, uint32 Slot) { std::list::const_iterator Iterator; for (Iterator = TmpMerchantList.begin(); Iterator != TmpMerchantList.end(); ++Iterator) - if((*Iterator).slot == Slot) + if ((*Iterator).slot == Slot) return (*Iterator).charges; return 0; } -void Zone::LoadTempMerchantData(){ +void Zone::LoadTempMerchantData() { LogFile->write(EQEMuLog::Status, "Loading Temporary Merchant Lists..."); std::string query = StringFormat( "SELECT " @@ -412,7 +411,8 @@ void Zone::LoadTempMerchantData(){ "WHERE " "ml.npcid = se.npcid " "AND se.spawngroupid = s2.spawngroupid " - "AND s2.zone = '%s' AND s2.version = %i", GetShortName(), GetInstanceVersion()); + "AND s2.zone = '%s' AND s2.version = %i" + "ORDER BY ml.slot ", GetShortName(), GetInstanceVersion()); auto results = database.QueryDatabase(query); if (!results.Success()) { LogFile->write(EQEMuLog::Error, "Error in LoadTempMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); @@ -441,11 +441,11 @@ void Zone::LoadTempMerchantData(){ pQueuedMerchantsWorkID = 0; } -void Zone::LoadNewMerchantData(uint32 merchantid){ +void Zone::LoadNewMerchantData(uint32 merchantid) { std::list merlist; std::string query = StringFormat("SELECT item, slot, faction_required, level_required, alt_currency_cost, " - "classes_required FROM merchantlist WHERE merchantid=%d", merchantid); + "classes_required FROM merchantlist WHERE merchantid=%d ORDER BY slot", merchantid); auto results = database.QueryDatabase(query); if (!results.Success()) { LogFile->write(EQEMuLog::Error, "Error in LoadNewMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); @@ -467,7 +467,7 @@ void Zone::LoadNewMerchantData(uint32 merchantid){ merchanttable[merchantid] = merlist; } -void Zone::GetMerchantDataForZoneLoad(){ +void Zone::GetMerchantDataForZoneLoad() { LogFile->write(EQEMuLog::Status, "Loading Merchant Lists..."); std::string query = StringFormat( "SELECT " @@ -485,15 +485,19 @@ void Zone::GetMerchantDataForZoneLoad(){ "spawnentry AS se, " "spawn2 AS s2 " "WHERE nt.merchant_id = ml.merchantid AND nt.id = se.npcid " - "AND se.spawngroupid = s2.spawngroupid AND s2.zone = '%s' AND s2.version = %i ", GetShortName(), GetInstanceVersion()); + "AND se.spawngroupid = s2.spawngroupid AND s2.zone = '%s' AND s2.version = %i " + "ORDER BY ml.slot ", GetShortName(), GetInstanceVersion()); auto results = database.QueryDatabase(query); std::map >::iterator cur; uint32 npcid = 0; - if (results.RowCount() == 0){ LogFile->write(EQEMuLog::Error, "Error in loading Merchant Data for zone"); return; } + if (results.RowCount() == 0) { + LogFile->write(EQEMuLog::Error, "Error in loading Merchant Data for zone"); + return; + } for (auto row = results.begin(); row != results.end(); ++row) { MerchantList ml; ml.id = atoul(row[0]); - if (npcid != ml.id){ + if (npcid != ml.id) { cur = merchanttable.find(ml.id); if (cur == merchanttable.end()) { std::list empty;