aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNay <dnpd.dd@gmail.com>2012-08-14 18:11:06 +0100
committerNay <dnpd.dd@gmail.com>2012-08-14 18:11:06 +0100
commitc0adf370e5ac3166bb74abb6d824556fbae54f6f (patch)
tree2b2b5aacb2e539acbbf58e92964fd6edc6529a88
parente761458b249b8f2a128867ea0bd7adf5eaec4769 (diff)
Core/Vendors: Add currencies to vendors
npc_vendor table gets a new field, type (1 is item, 2 is currency) for type 1 fields still mean the same, for type 2 maxcount is buycount (without any "precision") changed structure of SMSG_UPDATE_CURRENCY(_WEEK_LIMIT) but not enabled, wrong values are being wrongly calculated
-rw-r--r--sql/updates/world/2012_08_14_02_world_npc_vendor.sql6
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp8
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h15
-rwxr-xr-xsrc/server/game/Entities/Item/ItemPrototype.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp233
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h5
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp4
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h2
-rwxr-xr-xsrc/server/game/Events/GameEventMgr.cpp14
-rwxr-xr-xsrc/server/game/Events/GameEventMgr.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp83
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h10
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp125
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp10
-rwxr-xr-xsrc/server/shared/Database/Implementation/WorldDatabase.cpp6
-rwxr-xr-xsrc/server/shared/Database/Implementation/WorldDatabase.h2
16 files changed, 345 insertions, 185 deletions
diff --git a/sql/updates/world/2012_08_14_02_world_npc_vendor.sql b/sql/updates/world/2012_08_14_02_world_npc_vendor.sql
new file mode 100644
index 00000000000..de00be694fc
--- /dev/null
+++ b/sql/updates/world/2012_08_14_02_world_npc_vendor.sql
@@ -0,0 +1,6 @@
+ALTER TABLE `npc_vendor` ADD `type` tinyint(3) unsigned NOT NULL DEFAULT '1';
+ALTER TABLE `game_event_npc_vendor` ADD `type` tinyint(3) unsigned NOT NULL DEFAULT '1';
+ALTER TABLE `npc_vendor` CHANGE `maxcount` `maxcount` mediumint(8) unsigned NOT NULL DEFAULT '0';
+ALTER TABLE `game_event_npc_vendor` CHANGE `maxcount` `maxcount` mediumint(8) unsigned NOT NULL DEFAULT '0';
+UPDATE `trinity_string` SET `content_default` = 'Item \'%u\' (type %u) not found in database.' WHERE `entry`=207;
+UPDATE `trinity_string` SET `content_default` = 'Item \'%u\' (with extended cost %u, type %u) already in vendor list' WHERE `entry`=210;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index de5d0a0303c..642c7e45a74 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -61,12 +61,12 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
return NULL;
}
-bool VendorItemData::RemoveItem(uint32 item_id)
+bool VendorItemData::RemoveItem(uint32 item_id, uint8 type)
{
bool found = false;
for (VendorItemList::iterator i = m_items.begin(); i != m_items.end();)
{
- if ((*i)->item == item_id)
+ if ((*i)->item == item_id && (*i)->Type == type)
{
i = m_items.erase(i++);
found = true;
@@ -77,10 +77,10 @@ bool VendorItemData::RemoveItem(uint32 item_id)
return found;
}
-VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost) const
+VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const
{
for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i)
- if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost)
+ if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost && (*i)->Type == type)
return *i;
return NULL;
}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 61982026933..14a680d62d1 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -317,13 +317,14 @@ enum ChatType
// Vendors
struct VendorItem
{
- VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
- : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
+ VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost, uint8 _Type)
+ : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost), Type(_Type) {}
uint32 item;
- uint32 maxcount; // 0 for infinity item amount
+ uint32 maxcount; // 0 for infinity item amount
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
+ uint8 Type;
//helpers
bool IsGoldRequired(ItemTemplate const* pProto) const { return pProto->Flags2 & ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD || !ExtendedCost; }
@@ -343,12 +344,12 @@ struct VendorItemData
}
bool Empty() const { return m_items.empty(); }
uint8 GetItemCount() const { return m_items.size(); }
- void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
+ void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type)
{
- m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
+ m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost, type));
}
- bool RemoveItem(uint32 item_id);
- VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const;
+ bool RemoveItem(uint32 item_id, uint8 type);
+ VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const;
void Clear()
{
for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 1fd46a2d879..87647a36f70 100755
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -218,6 +218,12 @@ enum CurrencyFlags
// ...
};
+enum ItemVendorType
+{
+ ITEM_VENDOR_TYPE_ITEM = 1,
+ ITEM_VENDOR_TYPE_CURRENCY = 2,
+};
+
enum BAG_FAMILY_MASK
{
BAG_FAMILY_MASK_NONE = 0x00000000,
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index bd835db1ca6..6f948c774fb 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7281,96 +7281,105 @@ void Player::SendCurrencies() const
uint32 Player::GetCurrency(uint32 id) const
{
- PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id);
- return itr != m_currencies.end() ? itr->second.totalCount : 0;
+ PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id);
+ return itr != m_currencies.end() ? itr->second.totalCount : 0;
}
bool Player::HasCurrency(uint32 id, uint32 count) const
{
- PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id);
- return itr != m_currencies.end() && itr->second.totalCount >= count;
+ PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id);
+ return itr != m_currencies.end() && itr->second.totalCount >= count;
}
-void Player::ModifyCurrency(uint32 id, int32 count)
+void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/)
{
- if (!count)
- return;
+ if (!count)
+ return;
- CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
- ASSERT(currency);
+ CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
+ ASSERT(currency);
- int32 precision = currency->Flags & CURRENCY_FLAG_HIGH_PRECISION ? 100 : 1;
- uint32 oldTotalCount = 0;
- uint32 oldWeekCount = 0;
- PlayerCurrenciesMap::iterator itr = m_currencies.find(id);
- if (itr == m_currencies.end())
- {
- PlayerCurrency cur;
- cur.state = PLAYERCURRENCY_NEW;
- cur.totalCount = 0;
- cur.weekCount = 0;
- m_currencies[id] = cur;
- itr = m_currencies.find(id);
- }
- else
- {
- oldTotalCount = itr->second.totalCount;
- oldWeekCount = itr->second.weekCount;
- }
+ int32 precision = currency->Flags & CURRENCY_FLAG_HIGH_PRECISION ? 100 : 1;
+ uint32 oldTotalCount = 0;
+ uint32 oldWeekCount = 0;
+ PlayerCurrenciesMap::iterator itr = m_currencies.find(id);
+ if (itr == m_currencies.end())
+ {
+ PlayerCurrency cur;
+ cur.state = PLAYERCURRENCY_NEW;
+ cur.totalCount = 0;
+ cur.weekCount = 0;
+ m_currencies[id] = cur;
+ itr = m_currencies.find(id);
+ }
+ else
+ {
+ oldTotalCount = itr->second.totalCount;
+ oldWeekCount = itr->second.weekCount;
+ }
- int32 newTotalCount = int32(oldTotalCount) + count;
- if (newTotalCount < 0)
- newTotalCount = 0;
+ int32 newTotalCount = int32(oldTotalCount) + count;
+ if (newTotalCount < 0)
+ newTotalCount = 0;
- int32 newWeekCount = int32(oldWeekCount) + (count > 0 ? count : 0);
- if (newWeekCount < 0)
- newWeekCount = 0;
+ int32 newWeekCount = int32(oldWeekCount) + (count > 0 ? count : 0);
+ if (newWeekCount < 0)
+ newWeekCount = 0;
- if (currency->TotalCap && int32(currency->TotalCap) < newTotalCount)
- {
- int32 delta = newTotalCount - int32(currency->TotalCap);
- newTotalCount = int32(currency->TotalCap);
- newWeekCount -= delta;
- }
+ if (currency->TotalCap && int32(currency->TotalCap) < newTotalCount)
+ {
+ int32 delta = newTotalCount - int32(currency->TotalCap);
+ newTotalCount = int32(currency->TotalCap);
+ newWeekCount -= delta;
+ }
- // TODO: fix conquest points
- uint32 weekCap = _GetCurrencyWeekCap(currency);
- if (weekCap && int32(weekCap) < newTotalCount)
- {
- int32 delta = newWeekCount - int32(weekCap);
- newWeekCount = int32(weekCap);
- newTotalCount -= delta;
- }
+ // TODO: fix conquest points
+ uint32 weekCap = _GetCurrencyWeekCap(currency);
+ if (weekCap && int32(weekCap) < newTotalCount)
+ {
+ int32 delta = newWeekCount - int32(weekCap);
+ newWeekCount = int32(weekCap);
+ newTotalCount -= delta;
+ }
- // if we change total, we must change week
- ASSERT(((newTotalCount-oldTotalCount) != 0) == ((newWeekCount-oldWeekCount) != 0));
+ // if we change total, we must change week
+ ASSERT(((newTotalCount-oldTotalCount) != 0) == ((newWeekCount-oldWeekCount) != 0));
- if (newTotalCount != oldTotalCount)
- {
- if(itr->second.state != PLAYERCURRENCY_NEW)
- itr->second.state = PLAYERCURRENCY_CHANGED;
+ if (newTotalCount != oldTotalCount)
+ {
+ if (itr->second.state != PLAYERCURRENCY_NEW)
+ itr->second.state = PLAYERCURRENCY_CHANGED;
- itr->second.totalCount = newTotalCount;
- itr->second.weekCount = newWeekCount;
+ itr->second.totalCount = newTotalCount;
+ itr->second.weekCount = newWeekCount;
- // probably excessive checks
- if (IsInWorld() && !GetSession()->PlayerLoading())
- {
- if (count > 0)
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count);
-
- WorldPacket packet(SMSG_UPDATE_CURRENCY, 12);
- packet << uint32(id);
- packet << uint32(weekCap ? (newWeekCount / precision) : 0);
- packet << uint32(newTotalCount / precision);
- GetSession()->SendPacket(&packet);
- }
- }
+ // probably excessive checks
+ if (IsInWorld() && !GetSession()->PlayerLoading())
+ {
+ if (count > 0)
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count);
+
+ WorldPacket packet(SMSG_UPDATE_CURRENCY, 12);
+
+ packet.WriteBit(weekCap != 0);
+ packet.WriteBit(0); // hasSeasonCount
+ packet.WriteBit(printLog); // print in log
+
+ // if hasSeasonCount packet << uint32(seasontotalearned); TODO: save this in character DB and use it
+
+ packet << uint32(newTotalCount / precision);
+ packet << uint32(id);
+ if (weekCap)
+ packet << uint32(newWeekCount / precision);
+
+ GetSession()->SendPacket(&packet);
+ }
+ }
}
-void Player::SetCurrency(uint32 id, uint32 count)
+void Player::SetCurrency(uint32 id, uint32 count, bool printLog /*= true*/)
{
- ModifyCurrency(id, int32(count) - GetCurrency(id));
+ ModifyCurrency(id, int32(count) - GetCurrency(id), printLog);
}
uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const
@@ -20991,6 +21000,90 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
return true;
}
+bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count)
+{
+ vendorSlot += 1;
+
+ // cheating attempt
+ if (count < 1) count = 1;
+
+ if (!isAlive())
+ return false;
+
+ CurrencyTypesEntry const* proto = sCurrencyTypesStore.LookupEntry(currency);
+ if (!proto)
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, currency, 0);
+ return false;
+ }
+
+ Creature* creature = GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
+ if (!creature)
+ {
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: BuyCurrencyFromVendorSlot - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
+ SendBuyError(BUY_ERR_DISTANCE_TOO_FAR, NULL, currency, 0);
+ return false;
+ }
+
+ VendorItemData const* vItems = creature->GetVendorItems();
+ if (!vItems || vItems->Empty())
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0);
+ return false;
+ }
+
+ if (vendorSlot >= vItems->GetItemCount())
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0);
+ return false;
+ }
+
+ VendorItem const* crItem = vItems->GetItem(vendorSlot);
+ // store diff item (cheating)
+ if (!crItem || crItem->item != currency || crItem->Type != 2)
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0);
+ return false;
+ }
+
+ if (crItem->ExtendedCost)
+ {
+ ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
+ if (!iece)
+ {
+ sLog->outError(LOG_FILTER_PLAYER, "Currency %u have wrong ExtendedCost field value %u", currency, crItem->ExtendedCost);
+ return false;
+ }
+
+ // item base price
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ {
+ if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], (iece->RequiredItemCount[i] * count)))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
+ return false;
+ }
+ }
+
+ // check for personal arena rating requirement
+ if (GetMaxPersonalArenaRatingRequirement(iece->RequiredArenaSlot) < iece->RequiredPersonalArenaRating)
+ {
+ // probably not the proper equip err
+ SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
+ return false;
+ }
+ }
+ else // currencies have no price defined, can only be bought with ExtendedCost
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, currency, 0);
+ return false;
+ }
+
+ ModifyCurrency(currency, crItem->maxcount);
+
+ return true;
+}
+
// Return true is the bought item has a max count to force refresh of window by caller
bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index a8e9e5ed407..933c702a5aa 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1328,8 +1328,8 @@ class Player : public Unit, public GridObject<Player>
void SendCurrencies() const;
uint32 GetCurrency(uint32 id) const;
bool HasCurrency(uint32 id, uint32 count) const;
- void SetCurrency(uint32 id, uint32 count);
- void ModifyCurrency(uint32 id, int32 count);
+ void SetCurrency(uint32 id, uint32 count, bool printLog = true);
+ void ModifyCurrency(uint32 id, int32 count, bool printLog = true);
void ApplyEquipCooldown(Item* pItem);
void QuickEquipItem(uint16 pos, Item* pItem);
@@ -1375,6 +1375,7 @@ class Player : public Unit, public GridObject<Player>
}
void SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast = false);
bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
+ bool BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count);
bool _StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
float GetReputationPriceDiscount(Creature const* creature) const;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 03de01795f7..eda39dcefd1 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -5628,7 +5628,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(EFFECT_1);
if (!counter)
return true;
-
+
// Count spell criticals in a row in second aura
if (procEx & PROC_EX_CRITICAL_HIT)
{
@@ -6935,7 +6935,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// custom cooldown processing case
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(spell))
ToPlayer()->RemoveSpellCooldown(spell);
-
+
CastSpell(target, spell, true, castItem, triggeredByAura);
return true;
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 57b56ff6e55..addf99a03ac 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1483,7 +1483,7 @@ class Unit : public WorldObject
}
virtual uint32 GetBlockPercent() { return 30; }
-
+
uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
uint32 GetDefenseSkillValue(Unit const* target = NULL) const;
uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const;
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 0936275e90c..6af90dd85eb 100755
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -808,14 +808,11 @@ void GameEventMgr::LoadFromDB()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5
- QueryResult result = WorldDatabase.Query("SELECT eventEntry, guid, item, maxcount, incrtime, ExtendedCost FROM game_event_npc_vendor ORDER BY guid, slot ASC");
+ // 0 1 2 3 4 5 6
+ QueryResult result = WorldDatabase.Query("SELECT eventEntry, guid, item, maxcount, incrtime, ExtendedCost, type FROM game_event_npc_vendor ORDER BY guid, slot ASC");
if (!result)
- {
sLog->outInfo(LOG_FILTER_GAMEEVENTS, ">> Loaded 0 vendor additions in game events. DB table `game_event_npc_vendor` is empty.");
-
- }
else
{
uint32 count = 0;
@@ -838,6 +835,7 @@ void GameEventMgr::LoadFromDB()
newEntry.maxcount = fields[3].GetUInt32();
newEntry.incrtime = fields[4].GetUInt32();
newEntry.ExtendedCost = fields[5].GetUInt32();
+ newEntry.Type = fields[6].GetUInt8();
// get the event npc flag for checking if the npc will be vendor during the event or not
uint32 event_npc_flag = 0;
NPCFlagList& flist = mGameEventNPCFlags[event_id];
@@ -856,7 +854,7 @@ void GameEventMgr::LoadFromDB()
newEntry.entry = data->id;
// check validity with event's npcflag
- if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, NULL, NULL, event_npc_flag))
+ if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, newEntry.Type, NULL, NULL, event_npc_flag))
continue;
vendors.push_back(newEntry);
@@ -1199,9 +1197,9 @@ void GameEventMgr::UpdateEventNPCVendor(uint16 event_id, bool activate)
for (NPCVendorList::iterator itr = mGameEventVendors[event_id].begin(); itr != mGameEventVendors[event_id].end(); ++itr)
{
if (activate)
- sObjectMgr->AddVendorItem(itr->entry, itr->item, itr->maxcount, itr->incrtime, itr->ExtendedCost, false);
+ sObjectMgr->AddVendorItem(itr->entry, itr->item, itr->maxcount, itr->incrtime, itr->ExtendedCost, itr->Type, false);
else
- sObjectMgr->RemoveVendorItem(itr->entry, itr->item, false);
+ sObjectMgr->RemoveVendorItem(itr->entry, itr->item, itr->Type, false);
}
}
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index d9b5890bfe5..ce1d10e327a 100755
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -85,6 +85,7 @@ struct NPCVendorEntry
int32 maxcount; // 0 for infinite
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
+ uint8 Type; // 1 item, 2 currency
};
class Player;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 6dbe7574cd2..ab78566ae0e 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -8026,11 +8026,12 @@ void ObjectMgr::LoadTrainerSpell()
}
-int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *skip_vendors)
+int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, uint8 type, std::set<uint32> *skip_vendors)
{
// find all items from the reference vendor
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_NPC_VENDOR_REF);
stmt->setUInt32(0, uint32(item));
+ stmt->setUInt8(1, type);
PreparedQueryResult result = WorldDatabase.Query(stmt);
if (!result)
@@ -8045,19 +8046,20 @@ int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *s
// if item is a negative, its a reference
if (item_id < 0)
- count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
+ count += LoadReferenceVendor(vendor, -item_id, type, skip_vendors);
else
{
- int32 maxcount = fields[1].GetUInt8();
+ int32 maxcount = fields[1].GetUInt32();
uint32 incrtime = fields[2].GetUInt32();
uint32 ExtendedCost = fields[3].GetUInt32();
+ uint8 type = fields[4].GetUInt8();
- if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, NULL, skip_vendors))
+ if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, type, NULL, skip_vendors))
continue;
VendorItemData& vList = _cacheVendorItemStore[vendor];
- vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
+ vList.AddItem(item_id, maxcount, incrtime, ExtendedCost, type);
++count;
}
} while (result->NextRow());
@@ -8076,7 +8078,7 @@ void ObjectMgr::LoadVendors()
std::set<uint32> skip_vendors;
- QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC");
+ QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost, type FROM npc_vendor ORDER BY entry, slot ASC");
if (!result)
{
@@ -8095,19 +8097,20 @@ void ObjectMgr::LoadVendors()
// if item is a negative, its a reference
if (item_id < 0)
- count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
+ count += LoadReferenceVendor(entry, -item_id, 0, &skip_vendors);
else
{
- uint32 maxcount = fields[2].GetUInt8();
+ uint32 maxcount = fields[2].GetUInt32();
uint32 incrtime = fields[3].GetUInt32();
uint32 ExtendedCost = fields[4].GetUInt32();
+ uint8 type = fields[5].GetUInt8();
- if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, NULL, &skip_vendors))
+ if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, type, NULL, &skip_vendors))
continue;
VendorItemData& vList = _cacheVendorItemStore[entry];
- vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
+ vList.AddItem(item_id, maxcount, incrtime, ExtendedCost, type);
++count;
}
}
@@ -8223,32 +8226,33 @@ void ObjectMgr::LoadGossipMenuItems()
}
-void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist /*= true*/)
+void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, uint8 type, bool persist /*= true*/)
{
VendorItemData& vList = _cacheVendorItemStore[entry];
- vList.AddItem(item, maxcount, incrtime, extendedCost);
+ vList.AddItem(item, maxcount, incrtime, extendedCost, type);
if (persist)
{
- PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_NPC_VENODR);
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_NPC_VENDOR);
stmt->setUInt32(0, entry);
stmt->setUInt32(1, item);
stmt->setUInt8(2, maxcount);
stmt->setUInt32(3, incrtime);
stmt->setUInt32(4, extendedCost);
+ stmt->setUInt8(5, type);
WorldDatabase.Execute(stmt);
}
}
-bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= true*/)
+bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist /*= true*/)
{
CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
if (iter == _cacheVendorItemStore.end())
return false;
- if (!iter->second.RemoveItem(item))
+ if (!iter->second.RemoveItem(item, type))
return false;
if (persist)
@@ -8257,6 +8261,7 @@ bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= tru
stmt->setUInt32(0, entry);
stmt->setUInt32(1, item);
+ stmt->setUInt8(2, type);
WorldDatabase.Execute(stmt);
}
@@ -8264,7 +8269,7 @@ bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= tru
return true;
}
-bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* player, std::set<uint32>* skip_vendors, uint32 ORnpcflag) const
+bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 incrtime, uint32 ExtendedCost, uint8 type, Player* player, std::set<uint32>* skip_vendors, uint32 ORnpcflag) const
{
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(vendor_entry);
if (!cInfo)
@@ -8291,12 +8296,13 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 max
return false;
}
- if (!sObjectMgr->GetItemTemplate(item_id))
+ if ((type == ITEM_VENDOR_TYPE_ITEM && !sObjectMgr->GetItemTemplate(id)) ||
+ (type == ITEM_VENDOR_TYPE_CURRENCY && !sCurrencyTypesStore.LookupEntry(id)))
{
if (player)
- ChatHandler(player).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
+ ChatHandler(player).PSendSysMessage(LANG_ITEM_NOT_FOUND, id, type);
else
- sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore", vendor_entry, item_id);
+ sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u, type %u), ignore", vendor_entry, id, type);
return false;
}
@@ -8305,37 +8311,40 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 max
if (player)
ChatHandler(player).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost);
else
- sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore", item_id, ExtendedCost, vendor_entry);
+ sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore", id, ExtendedCost, vendor_entry);
return false;
}
- if (maxcount > 0 && incrtime == 0)
+ if (type == ITEM_VENDOR_TYPE_ITEM) // not applicable to currencies
{
- if (player)
- ChatHandler(player).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount);
- else
- sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry);
- return false;
- }
- else if (maxcount == 0 && incrtime > 0)
- {
- if (player)
- ChatHandler(player).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
- else
- sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry);
- return false;
+ if (maxcount > 0 && incrtime == 0)
+ {
+ if (player)
+ ChatHandler(player).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount);
+ else
+ sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, id, vendor_entry);
+ return false;
+ }
+ else if (maxcount == 0 && incrtime > 0)
+ {
+ if (player)
+ ChatHandler(player).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
+ else
+ sLog->outError(LOG_FILTER_SQL, "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", id, vendor_entry);
+ return false;
+ }
}
VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
if (!vItems)
return true; // later checks for non-empty lists
- if (vItems->FindItemCostPair(item_id, ExtendedCost))
+ if (vItems->FindItemCostPair(id, ExtendedCost, type))
{
if (player)
- ChatHandler(player).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
+ ChatHandler(player).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, id, ExtendedCost, type);
else
- sLog->outError(LOG_FILTER_SQL, "Table `npc_vendor` has duplicate items %u (with extended cost %u) for vendor (Entry: %u), ignoring", item_id, ExtendedCost, vendor_entry);
+ sLog->outError(LOG_FILTER_SQL, "Table `npc_vendor` has duplicate items %u (with extended cost %u, type %u) for vendor (Entry: %u), ignoring", id, ExtendedCost, type, vendor_entry);
return false;
}
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 7850eda6c83..0456b800a29 100755
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -622,7 +622,7 @@ class ObjectMgr
GameObjectTemplate const* GetGameObjectTemplate(uint32 entry);
GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; }
- int LoadReferenceVendor(int32 vendor, int32 item_id, std::set<uint32> *skip_vendors);
+ int LoadReferenceVendor(int32 vendor, int32 item, uint8 type, std::set<uint32> *skip_vendors);
void LoadGameObjectTemplate();
void AddGameobjectInfo(GameObjectTemplate* goinfo);
@@ -1075,15 +1075,15 @@ class ObjectMgr
VendorItemData const* GetNpcVendorItemList(uint32 entry) const
{
- CacheVendorItemContainer::const_iterator iter = _cacheVendorItemStore.find(entry);
+ CacheVendorItemContainer::const_iterator iter = _cacheVendorItemStore.find(entry);
if (iter == _cacheVendorItemStore.end())
return NULL;
return &iter->second;
}
- void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist = true); // for event
- bool RemoveVendorItem(uint32 entry, uint32 item, bool persist = true); // for event
- bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
+ void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, uint8 type, bool persist = true); // for event
+ bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist = true); // for event
+ bool IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
void LoadScriptNames();
ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; }
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 765adbda101..640d6996bdf 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -673,7 +673,7 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUY_ITEM");
uint64 vendorguid, bagGuid;
uint32 item, slot, count;
- uint8 itemType; // 1 = item, 2 = currency (not implemented)
+ uint8 itemType; // 1 = item, 2 = currency
uint8 bagSlot;
recvData >> vendorguid >> itemType >> item >> slot >> count >> bagGuid >> bagSlot;
@@ -684,13 +684,20 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
else
return; // cheating
- Item* bagItem = _player->GetItemByGuid(bagGuid);
+ if (itemType == ITEM_VENDOR_TYPE_ITEM)
+ {
+ Item* bagItem = _player->GetItemByGuid(bagGuid);
- uint8 bag = NULL_BAG;
- if (bagItem && bagItem->IsBag())
- bag = bagItem->GetSlot();
+ uint8 bag = NULL_BAG;
+ if (bagItem && bagItem->IsBag())
+ bag = bagItem->GetSlot();
- GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagSlot);
+ GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagSlot);
+ }
+ else if (itemType == ITEM_VENDOR_TYPE_CURRENCY)
+ GetPlayer()->BuyCurrencyFromVendorSlot(vendorguid, slot, item, count);
+ else
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType);
}
void WorldSession::HandleListInventoryOpcode(WorldPacket & recvData)
@@ -744,52 +751,86 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
VendorItem const* vendorItem = vendorItems->GetItem(slot);
if (!vendorItem) continue;
- ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item);
- if (!itemTemplate) continue;
-
- if (!_player->isGameMaster()) // ignore conditions if GM on
+ if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM)
{
- // Respect allowed class
- if (!(itemTemplate->AllowableClass & _player->getClassMask()))
- continue;
+ ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item);
+ if (!itemTemplate) continue;
+
+ if (!_player->isGameMaster()) // ignore conditions if GM on
+ {
+ // Respect allowed class
+ if (!(itemTemplate->AllowableClass & _player->getClassMask()))
+ continue;
- // Do not sell BOP items
- if (itemTemplate->Bonding == BIND_WHEN_PICKED_UP)
- continue;
+ // Do not sell BOP items
+ if (itemTemplate->Bonding == BIND_WHEN_PICKED_UP)
+ continue;
- // Only display items in vendor lists for the team the player is on
- if ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) ||
- (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))
- continue;
+ // Only display items in vendor lists for the team the player is on
+ if ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) ||
+ (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))
+ continue;
+
+ // Items sold out are not displayed in list
+ uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
+ if (leftInStock == 0)
+ continue;
+ }
- // Items sold out are not displayed in list
+ int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
- if (leftInStock == 0)
- continue;
+
+ itemsData << uint32(count++ + 1); // client expects counting to start at 1
+ itemsData << uint32(itemTemplate->MaxDurability);
+
+ if (vendorItem->ExtendedCost != 0)
+ {
+ enablers.push_back(0);
+ itemsData << uint32(vendorItem->ExtendedCost);
+ }
+ else
+ enablers.push_back(1);
+ enablers.push_back(1); // unk bit
+
+ itemsData << uint32(vendorItem->item);
+ itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
+ itemsData << uint32(price);
+ itemsData << uint32(itemTemplate->DisplayInfoID);
+ // if (!unk "enabler") data << uint32(something);
+ itemsData << int32(leftInStock);
+ itemsData << uint32(itemTemplate->BuyCount);
}
+ else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY)
+ {
+ CurrencyTypesEntry const* currencyTemplate = sCurrencyTypesStore.LookupEntry(vendorItem->item);
- int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
- uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
+ if (!currencyTemplate) continue;
- itemsData << uint32(count++ + 1); // client expects counting to start at 1
- itemsData << uint32(itemTemplate->MaxDurability);
+ if (vendorItem->ExtendedCost == 0) continue; // there's no price defined for currencies, only extendedcost is used
- if (vendorItem->ExtendedCost != 0)
- {
- enablers.push_back(0);
- itemsData << uint32(vendorItem->ExtendedCost);
+ uint32 precision = (currencyTemplate->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? 100 : 1;
+
+ itemsData << uint32(count++ + 1); // client expects counting to start at 1
+ itemsData << uint32(0); // max durability
+
+ if (vendorItem->ExtendedCost != 0)
+ {
+ enablers.push_back(0);
+ itemsData << uint32(vendorItem->ExtendedCost);
+ }
+ else
+ enablers.push_back(1);
+ enablers.push_back(1); // unk bit
+
+ itemsData << uint32(vendorItem->item);
+ itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
+ itemsData << uint32(0); // price, only seen currency types that have Extended cost
+ itemsData << uint32(0); // displayId
+ // if (!unk "enabler") data << uint32(something);
+ itemsData << int32(-1);
+ itemsData << uint32(vendorItem->maxcount * precision);
}
- else
- enablers.push_back(1);
- enablers.push_back(1); // unk bit
-
- itemsData << uint32(vendorItem->item);
- itemsData << uint32(1); // 1 is items, 2 is currency (FIXME: currency isn't implemented)
- itemsData << uint32(price);
- itemsData << uint32(itemTemplate->DisplayInfoID);
- // if (!unk "enabler") data << uint32(something);
- itemsData << int32(leftInStock);
- itemsData << uint32(itemTemplate->BuyCount);
+ // else error
}
uint8* guidBytes = (uint8*)&vendorGuid;
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 77fc2918e0b..e43760191df 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -178,6 +178,8 @@ public:
if (!*args)
return false;
+ const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
+
char* pitem = handler->extractKeyFromLink((char*)args, "Hitem");
if (!pitem)
{
@@ -214,13 +216,13 @@ public:
uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
- if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, handler->GetSession()->GetPlayer()))
+ if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, type, handler->GetSession()->GetPlayer()))
{
handler->SetSentErrorMessage(true);
return false;
}
- sObjectMgr->AddVendorItem(vendor_entry, itemId, maxcount, incrtime, extendedcost);
+ sObjectMgr->AddVendorItem(vendor_entry, itemId, maxcount, incrtime, type, extendedcost);
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
@@ -435,7 +437,9 @@ public:
}
uint32 itemId = atol(pitem);
- if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId))
+ const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
+
+ if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId, type))
{
handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId);
handler->SetSentErrorMessage(true);
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index fe2a9f7906c..74cd57f74c0 100755
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -34,9 +34,9 @@ void WorldDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM game_graveyard_zone WHERE id = ? AND ghost_zone = ? AND faction = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(WORLD_INS_GAME_TELE, "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PREPARE_STATEMENT(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC);
- PREPARE_STATEMENT(WORLD_INS_NPC_VENODR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PREPARE_STATEMENT(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ?", CONNECTION_ASYNC);
- PREPARE_STATEMENT(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry = ? ORDER BY slot ASC", CONNECTION_SYNCH);
+ PREPARE_STATEMENT(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost, type) VALUES(?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ? AND type = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost, type FROM npc_vendor WHERE entry = ? AND type = ? ORDER BY slot ASC", CONNECTION_SYNCH);
PREPARE_STATEMENT(WORLD_UPD_CREATURE_MOVEMENT_TYPE, "UPDATE creature SET MovementType = ? WHERE guid = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(WORLD_UPD_CREATURE_FACTION, "UPDATE creature_template SET faction_A = ?, faction_H = ? WHERE entry = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(WORLD_UPD_CREATURE_NPCFLAG, "UPDATE creature_template SET npcflag = ? WHERE entry = ?", CONNECTION_ASYNC);
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 6d7df87cc80..ceaad6f68e3 100755
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -54,7 +54,7 @@ enum WorldDatabaseStatements
WORLD_DEL_GRAVEYARD_ZONE,
WORLD_INS_GAME_TELE,
WORLD_DEL_GAME_TELE,
- WORLD_INS_NPC_VENODR,
+ WORLD_INS_NPC_VENDOR,
WORLD_DEL_NPC_VENDOR,
WORLD_SEL_NPC_VENDOR_REF,
WORLD_UPD_CREATURE_MOVEMENT_TYPE,