mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
[0169] Implemented vendors selling currencies.
Also fix crash from recent master merge. Signed-off-by: Yaki Khadafi <ElSolDolLo@gmail.com>
This commit is contained in:
parent
d4af997fbd
commit
6dd0ba1d14
23 changed files with 550 additions and 194 deletions
|
|
@ -3406,8 +3406,8 @@ INSERT INTO `mangos_string` VALUES
|
||||||
(206,'Item \'%i\' \'%s\' added to list with maxcount \'%i\' and incrtime \'%i\' and extendedcost \'%i\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(206,'Item \'%i\' \'%s\' added to list with maxcount \'%i\' and incrtime \'%i\' and extendedcost \'%i\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(207,'Item \'%i\' not found in database.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(207,'Item \'%i\' not found in database.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(208,'Item \'%i\' \'%s\' deleted from vendor list',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(208,'Item \'%i\' \'%s\' deleted from vendor list',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(209,'Item \'%i\' not found in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(209,'Item \'%i\' (isCurrency: %u) not found in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(210,'Item \'%i\' (with extended cost %i) already in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(210,'Item \'%i\' (isCurrency: %u, with extended cost %i) already in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(211,'Spells of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(211,'Spells of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(212,'Spells of %s will reset at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(212,'Spells of %s will reset at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(213,'Talents of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(213,'Talents of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
|
@ -3466,6 +3466,7 @@ INSERT INTO `mangos_string` VALUES
|
||||||
(266,'Nothing found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(266,'Nothing found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(267,'Object not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(267,'Object not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(268,'Creature not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(268,'Creature not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(269,'Currency \'%i\' not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(270,'Creature Removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(270,'Creature Removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(271,'Creature moved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(271,'Creature moved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(272,'Creature (GUID:%u) must be on the same map as player!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(272,'Creature (GUID:%u) must be on the same map as player!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
|
@ -3479,6 +3480,7 @@ INSERT INTO `mangos_string` VALUES
|
||||||
(280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(283,'Meta currency \'%i\' is not allowed in vendors.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
|
@ -4080,6 +4082,8 @@ INSERT INTO `mangos_string` VALUES
|
||||||
(1506,'Current phase = %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1506,'Current phase = %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1507,'Combat-Movement is %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1507,'Combat-Movement is %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1508,'Melee attacking is %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1508,'Melee attacking is %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(1509,'Can\'t add item %u to vendor with unknown item type %u',,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(1510,'Currency %u has maxCount = 0, but for currencies maxCount = buyCount, so it can\'t be 0 or less than that\'s currency precision (%u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1600,'|cffffff00Northpass Tower has been taken by the Horde!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1600,'|cffffff00Northpass Tower has been taken by the Horde!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1601,'|cffffff00Northpass Tower has been taken by the Alliance!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1601,'|cffffff00Northpass Tower has been taken by the Alliance!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1602,'|cffffff00Crown Guard Tower has been taken by the Horde!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1602,'|cffffff00Crown Guard Tower has been taken by the Horde!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
|
@ -4346,8 +4350,8 @@ UNLOCK TABLES;
|
||||||
DROP TABLE IF EXISTS `npc_vendor`;
|
DROP TABLE IF EXISTS `npc_vendor`;
|
||||||
CREATE TABLE `npc_vendor` (
|
CREATE TABLE `npc_vendor` (
|
||||||
`entry` mediumint(8) unsigned NOT NULL default '0',
|
`entry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
`item` mediumint(8) unsigned NOT NULL default '0',
|
`item` mediumint(8) NOT NULL default '0',
|
||||||
`maxcount` tinyint(3) unsigned NOT NULL default '0',
|
`maxcount` smallint(5) unsigned NOT NULL default '0',
|
||||||
`incrtime` int(10) unsigned NOT NULL default '0',
|
`incrtime` int(10) unsigned NOT NULL default '0',
|
||||||
`ExtendedCost` mediumint(8) unsigned NOT NULL default '0',
|
`ExtendedCost` mediumint(8) unsigned NOT NULL default '0',
|
||||||
PRIMARY KEY (`entry`,`item`,`ExtendedCost`)
|
PRIMARY KEY (`entry`,`item`,`ExtendedCost`)
|
||||||
|
|
@ -4369,8 +4373,8 @@ UNLOCK TABLES;
|
||||||
DROP TABLE IF EXISTS `npc_vendor_template`;
|
DROP TABLE IF EXISTS `npc_vendor_template`;
|
||||||
CREATE TABLE `npc_vendor_template` (
|
CREATE TABLE `npc_vendor_template` (
|
||||||
`entry` mediumint(8) unsigned NOT NULL default '0',
|
`entry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
`item` mediumint(8) unsigned NOT NULL default '0',
|
`item` mediumint(8) NOT NULL default '0',
|
||||||
`maxcount` tinyint(3) unsigned NOT NULL default '0',
|
`maxcount` smallint(3) unsigned NOT NULL default '0',
|
||||||
`incrtime` int(10) unsigned NOT NULL default '0',
|
`incrtime` int(10) unsigned NOT NULL default '0',
|
||||||
`ExtendedCost` mediumint(8) unsigned NOT NULL default '0',
|
`ExtendedCost` mediumint(8) unsigned NOT NULL default '0',
|
||||||
PRIMARY KEY (`entry`,`item`,`ExtendedCost`)
|
PRIMARY KEY (`entry`,`item`,`ExtendedCost`)
|
||||||
|
|
|
||||||
4
sql/updates/0169_xxxxx_01_mangos_npc_vendor.sql
Normal file
4
sql/updates/0169_xxxxx_01_mangos_npc_vendor.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_0168_xxxxx_01_mangos_playercreateinfo_spell required_0169_xxxxx_01_mangos_npc_vendor bit;
|
||||||
|
|
||||||
|
ALTER TABLE `npc_vendor` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
|
||||||
|
ALTER TABLE `npc_vendor` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL default '0';
|
||||||
4
sql/updates/0169_xxxxx_02_mangos_npc_vendor_template.sql
Normal file
4
sql/updates/0169_xxxxx_02_mangos_npc_vendor_template.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_0169_xxxxx_01_mangos_npc_vendor required_0169_xxxxx_02_mangos_npc_vendor_template bit;
|
||||||
|
|
||||||
|
ALTER TABLE `npc_vendor_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
|
||||||
|
ALTER TABLE `npc_vendor_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL default '0';
|
||||||
9
sql/updates/0169_xxxxx_03_mangos_mangos_string.sql
Normal file
9
sql/updates/0169_xxxxx_03_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_0169_xxxxx_02_mangos_npc_vendor_template required_0169_xxxxx_03_mangos_mangos_string bit;
|
||||||
|
|
||||||
|
REPLACE INTO `mangos_string` (`entry`, `content_default`) VALUES
|
||||||
|
(209, 'Item \'%i\' (isCurrency: %u) not found in vendor list.'),
|
||||||
|
(210, 'Item \'%i\' (isCurrency: %u, with extended cost %i) already in vendor list.'),
|
||||||
|
(269, 'Currency \'%i\' not found.'),
|
||||||
|
(283, 'Meta currency \'%i\' is not allowed in vendors.'),
|
||||||
|
(1509, 'Can\'t add item %u to vendor with unknown item type %u'),
|
||||||
|
(1510, 'Currency %u has maxCount = 0, but for currencies maxCount = buyCount, so it can\'t be 0 or less than that\'s currency precision (%u).');
|
||||||
6
sql/updates/0169_xxxxx_04_mangos_command.sql
Normal file
6
sql/updates/0169_xxxxx_04_mangos_command.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_0169_xxxxx_03_mangos_mangos_string required_0169_xxxxx_04_mangos_command bit;
|
||||||
|
|
||||||
|
DELETE FROM `command` WHERE `name` IN ('npc addcurrency', 'npc delcurrency');
|
||||||
|
INSERT INTO `command` VALUES
|
||||||
|
('npc addcurrency',2,'Syntax: .npc addcurrency #currencyId #buycount #extendedcost\r\n\r\nAdd currency #currencyId to item list of selected vendor. '),
|
||||||
|
('npc delcurrency',2,'Syntax: .npc delcurrency #currencyId\r\n\r\nRemove currency #currencyId from item list of selected vendor.');
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
// |color|Hareatrigger_target:id|h[name]|h|r
|
// |color|Hareatrigger_target:id|h[name]|h|r
|
||||||
// |color|Hcreature:creature_guid|h[name]|h|r
|
// |color|Hcreature:creature_guid|h[name]|h|r
|
||||||
// |color|Hcreature_entry:creature_id|h[name]|h|r
|
// |color|Hcreature_entry:creature_id|h[name]|h|r
|
||||||
|
// |color|Hcurrency:currency_id||h[name]|h|r
|
||||||
// |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r - client, at shift click in recipes list dialog
|
// |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r - client, at shift click in recipes list dialog
|
||||||
// |color|Hgameevent:id|h[name]|h|r
|
// |color|Hgameevent:id|h[name]|h|r
|
||||||
// |color|Hgameobject:go_guid|h[name]|h|r
|
// |color|Hgameobject:go_guid|h[name]|h|r
|
||||||
|
|
@ -438,6 +439,7 @@ ChatCommand* ChatHandler::getCommandTable()
|
||||||
static ChatCommand npcCommandTable[] =
|
static ChatCommand npcCommandTable[] =
|
||||||
{
|
{
|
||||||
{ "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
|
{ "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
|
||||||
|
{ "addcurrency", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorCurrencyCommand,"", NULL },
|
||||||
{ "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorItemCommand, "", NULL },
|
{ "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorItemCommand, "", NULL },
|
||||||
{ "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
|
{ "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
|
||||||
{ "aiinfo", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAIInfoCommand, "", NULL },
|
{ "aiinfo", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAIInfoCommand, "", NULL },
|
||||||
|
|
@ -445,6 +447,7 @@ ChatCommand* ChatHandler::getCommandTable()
|
||||||
{ "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
|
{ "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
|
||||||
{ "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcChangeLevelCommand, "", NULL },
|
{ "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcChangeLevelCommand, "", NULL },
|
||||||
{ "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
|
{ "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
|
||||||
|
{ "delcurrency", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDelVendorCurrencyCommand,"", NULL },
|
||||||
{ "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDelVendorItemCommand, "", NULL },
|
{ "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDelVendorItemCommand, "", NULL },
|
||||||
{ "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
|
{ "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
|
||||||
{ "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
|
{ "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
|
||||||
|
|
@ -1447,6 +1450,7 @@ bool ChatHandler::isValidChatMessage(const char* message)
|
||||||
/*
|
/*
|
||||||
|
|
||||||
valid examples:
|
valid examples:
|
||||||
|
|cff00aa00|Hcurrency:391|h[Ðåêîìåíäàòåëüíûé çíà÷îê Òîë Áàðàäà]|h|r
|
||||||
|cffa335ee|Hitem:812:0:0:0:0:0:0:0:70|h[Glowing Brightwood Staff]|h|r
|
|cffa335ee|Hitem:812:0:0:0:0:0:0:0:70|h[Glowing Brightwood Staff]|h|r
|
||||||
|cff808080|Hquest:2278:47|h[The Platinum Discs]|h|r
|
|cff808080|Hquest:2278:47|h[The Platinum Discs]|h|r
|
||||||
|cffffd000|Htrade:4037:1:150:1:6AAAAAAAAAAAAAAAAAAAAAAOAADAAAAAAAAAAAAAAAAIAAAAAAAAA|h[Engineering]|h|r
|
|cffffd000|Htrade:4037:1:150:1:6AAAAAAAAAAAAAAAAAAAAAAOAADAAAAAAAAAAAAAAAAIAAAAAAAAA|h[Engineering]|h|r
|
||||||
|
|
@ -1506,6 +1510,7 @@ bool ChatHandler::isValidChatMessage(const char* message)
|
||||||
|
|
||||||
uint32 color = 0;
|
uint32 color = 0;
|
||||||
|
|
||||||
|
CurrencyTypesEntry const* linkedCurrency = NULL;
|
||||||
ItemPrototype const* linkedItem = NULL;
|
ItemPrototype const* linkedItem = NULL;
|
||||||
Quest const* linkedQuest = NULL;
|
Quest const* linkedQuest = NULL;
|
||||||
SpellEntry const* linkedSpell = NULL;
|
SpellEntry const* linkedSpell = NULL;
|
||||||
|
|
@ -1517,6 +1522,7 @@ bool ChatHandler::isValidChatMessage(const char* message)
|
||||||
{
|
{
|
||||||
if (validSequence == validSequenceIterator)
|
if (validSequence == validSequenceIterator)
|
||||||
{
|
{
|
||||||
|
linkedCurrency = NULL;
|
||||||
linkedItem = NULL;
|
linkedItem = NULL;
|
||||||
linkedQuest = NULL;
|
linkedQuest = NULL;
|
||||||
linkedSpell = NULL;
|
linkedSpell = NULL;
|
||||||
|
|
@ -1606,7 +1612,26 @@ bool ChatHandler::isValidChatMessage(const char* message)
|
||||||
if (reader.eof()) // : must be
|
if (reader.eof()) // : must be
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (strcmp(buffer, "item") == 0)
|
if (strcmp(buffer, "currency") == 0)
|
||||||
|
{
|
||||||
|
if (color != CHAT_LINK_COLOR_CURRENCY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 currencyEntry = 0;
|
||||||
|
// read currency entry
|
||||||
|
char c = reader.peek();
|
||||||
|
while (c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
reader.ignore(1);
|
||||||
|
currencyEntry *= 10;
|
||||||
|
currencyEntry += c - '0';
|
||||||
|
c = reader.peek();
|
||||||
|
}
|
||||||
|
linkedCurrency = sCurrencyTypesStore.LookupEntry(currencyEntry);
|
||||||
|
if (!linkedCurrency)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (strcmp(buffer, "item") == 0)
|
||||||
{
|
{
|
||||||
// read item entry
|
// read item entry
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
|
@ -1886,7 +1911,24 @@ bool ChatHandler::isValidChatMessage(const char* message)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// verify the link name
|
// verify the link name
|
||||||
if (linkedSpell)
|
if (linkedCurrency)
|
||||||
|
{
|
||||||
|
if (linkedCurrency->ID == CURRENCY_CONQUEST_ARENA_META || linkedCurrency->ID == CURRENCY_CONQUEST_BG_META)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool foundName = false;
|
||||||
|
for (uint8 i = 0; i < MAX_LOCALE; ++i)
|
||||||
|
{
|
||||||
|
if (*linkedCurrency->name[i] && strcmp(linkedCurrency->name[i], buffer) == 0)
|
||||||
|
{
|
||||||
|
foundName = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundName)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (linkedSpell)
|
||||||
{
|
{
|
||||||
// spells with that flag have a prefix of "$PROFESSION: "
|
// spells with that flag have a prefix of "$PROFESSION: "
|
||||||
if (linkedSpell->HasAttribute(SPELL_ATTR_TRADESPELL))
|
if (linkedSpell->HasAttribute(SPELL_ATTR_TRADESPELL))
|
||||||
|
|
|
||||||
|
|
@ -339,12 +339,14 @@ class MANGOS_DLL_SPEC ChatHandler
|
||||||
//-----------------------Npc Commands-----------------------
|
//-----------------------Npc Commands-----------------------
|
||||||
bool HandleNpcAddCommand(char* args);
|
bool HandleNpcAddCommand(char* args);
|
||||||
bool HandleNpcAddMoveCommand(char* args);
|
bool HandleNpcAddMoveCommand(char* args);
|
||||||
|
bool HandleNpcAddVendorCurrencyCommand(char* args);
|
||||||
bool HandleNpcAddVendorItemCommand(char* args);
|
bool HandleNpcAddVendorItemCommand(char* args);
|
||||||
bool HandleNpcAIInfoCommand(char* args);
|
bool HandleNpcAIInfoCommand(char* args);
|
||||||
bool HandleNpcAllowMovementCommand(char* args);
|
bool HandleNpcAllowMovementCommand(char* args);
|
||||||
bool HandleNpcChangeEntryCommand(char* args);
|
bool HandleNpcChangeEntryCommand(char* args);
|
||||||
bool HandleNpcChangeLevelCommand(char* args);
|
bool HandleNpcChangeLevelCommand(char* args);
|
||||||
bool HandleNpcDeleteCommand(char* args);
|
bool HandleNpcDeleteCommand(char* args);
|
||||||
|
bool HandleNpcDelVendorCurrencyCommand(char* args);
|
||||||
bool HandleNpcDelVendorItemCommand(char* args);
|
bool HandleNpcDelVendorItemCommand(char* args);
|
||||||
bool HandleNpcFactionIdCommand(char* args);
|
bool HandleNpcFactionIdCommand(char* args);
|
||||||
bool HandleNpcFlagCommand(char* args);
|
bool HandleNpcFlagCommand(char* args);
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,13 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VendorItemData::RemoveItem(uint32 item_id)
|
bool VendorItemData::RemoveItem(uint32 item_id, uint8 type)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (VendorItemList::iterator i = m_items.begin(); i != m_items.end();)
|
for (VendorItemList::iterator i = m_items.begin(); i != m_items.end();)
|
||||||
{
|
{
|
||||||
// can have many examples
|
// can have many examples
|
||||||
if ((*i)->item == item_id)
|
if ((*i)->item == item_id && (*i)->type == type)
|
||||||
{
|
{
|
||||||
i = m_items.erase(i);
|
i = m_items.erase(i);
|
||||||
found = true;
|
found = true;
|
||||||
|
|
@ -85,10 +85,10 @@ bool VendorItemData::RemoveItem(uint32 item_id)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost) const
|
VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint8 type, uint32 extendedCost) const
|
||||||
{
|
{
|
||||||
for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i)
|
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 *i;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -2544,6 +2544,8 @@ void Creature::SetWalk(bool enable)
|
||||||
else
|
else
|
||||||
m_movementInfo.RemoveMovementFlag(MOVEFLAG_WALK_MODE);
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_WALK_MODE);
|
||||||
|
|
||||||
|
if (IsInWorld())
|
||||||
|
{
|
||||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
|
|
@ -2557,6 +2559,7 @@ void Creature::SetWalk(bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::SetLevitate(bool enable)
|
void Creature::SetLevitate(bool enable)
|
||||||
|
|
@ -2566,6 +2569,8 @@ void Creature::SetLevitate(bool enable)
|
||||||
else
|
else
|
||||||
m_movementInfo.RemoveMovementFlag(MOVEFLAG_LEVITATING);
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_LEVITATING);
|
||||||
|
|
||||||
|
if (IsInWorld())
|
||||||
|
{
|
||||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
|
|
@ -2579,6 +2584,7 @@ void Creature::SetLevitate(bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::SetRoot(bool enable)
|
void Creature::SetRoot(bool enable)
|
||||||
|
|
@ -2588,6 +2594,8 @@ void Creature::SetRoot(bool enable)
|
||||||
else
|
else
|
||||||
m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT);
|
||||||
|
|
||||||
|
if (IsInWorld())
|
||||||
|
{
|
||||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_ROOT : SMSG_SPLINE_MOVE_UNROOT, 9);
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_ROOT : SMSG_SPLINE_MOVE_UNROOT, 9);
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
|
|
@ -2601,6 +2609,7 @@ void Creature::SetRoot(bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::SetWaterWalk(bool enable)
|
void Creature::SetWaterWalk(bool enable)
|
||||||
|
|
@ -2610,6 +2619,8 @@ void Creature::SetWaterWalk(bool enable)
|
||||||
else
|
else
|
||||||
m_movementInfo.RemoveMovementFlag(MOVEFLAG_WATERWALKING);
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_WATERWALKING);
|
||||||
|
|
||||||
|
if (IsInWorld())
|
||||||
|
{
|
||||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_WATER_WALK : SMSG_SPLINE_MOVE_LAND_WALK, 9);
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_WATER_WALK : SMSG_SPLINE_MOVE_LAND_WALK, 9);
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
|
|
@ -2623,5 +2634,5 @@ void Creature::SetWaterWalk(bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -310,15 +310,27 @@ enum SelectFlags
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vendors
|
// Vendors
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
VENDOR_ITEM_TYPE_NONE = 0,
|
||||||
|
VENDOR_ITEM_TYPE_ITEM = 1,
|
||||||
|
VENDOR_ITEM_TYPE_CURRENCY = 2,
|
||||||
|
VENDOR_ITEM_TYPE_MAX = 3,
|
||||||
|
};
|
||||||
|
|
||||||
struct VendorItem
|
struct VendorItem
|
||||||
{
|
{
|
||||||
VendorItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
|
VendorItem(uint32 _item, uint8 _type, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
|
||||||
: item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
|
: item(_item), type(_type), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
|
||||||
|
|
||||||
uint32 item;
|
uint32 item;
|
||||||
uint32 maxcount; // 0 for infinity item amount
|
uint8 type;
|
||||||
|
uint32 maxcount; // 0 for infinity item amount, for type = VENDOR_ITEM_TYPE_CURRENCY, maxcount = currency count
|
||||||
uint32 incrtime; // time for restore items amount if maxcount != 0
|
uint32 incrtime; // time for restore items amount if maxcount != 0
|
||||||
uint32 ExtendedCost; // index in ItemExtendedCost.dbc
|
uint32 ExtendedCost; // index in ItemExtendedCost.dbc
|
||||||
|
|
||||||
|
bool IsCurrency() const { return type == VENDOR_ITEM_TYPE_CURRENCY; }
|
||||||
};
|
};
|
||||||
typedef std::vector<VendorItem*> VendorItemList;
|
typedef std::vector<VendorItem*> VendorItemList;
|
||||||
|
|
||||||
|
|
@ -333,12 +345,12 @@ struct VendorItemData
|
||||||
}
|
}
|
||||||
bool Empty() const { return m_items.empty(); }
|
bool Empty() const { return m_items.empty(); }
|
||||||
uint8 GetItemCount() const { return m_items.size(); }
|
uint8 GetItemCount() const { return m_items.size(); }
|
||||||
void AddItem(uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost)
|
void AddItem(uint32 item, uint8 type, uint32 maxcount, uint32 ptime, uint32 ExtendedCost)
|
||||||
{
|
{
|
||||||
m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
|
m_items.push_back(new VendorItem(item, type, maxcount, ptime, ExtendedCost));
|
||||||
}
|
}
|
||||||
bool RemoveItem(uint32 item_id);
|
bool RemoveItem(uint32 item_id, uint8 type);
|
||||||
VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const;
|
VendorItem const* FindItemCostPair(uint32 item_id, uint8 type, uint32 extendedCost) const;
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,17 @@ enum CurrencyFlags
|
||||||
CURRENCY_FLAG_HAS_SEASON_COUNT = 0x80, // guessed
|
CURRENCY_FLAG_HAS_SEASON_COUNT = 0x80, // guessed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Currencies
|
||||||
|
{
|
||||||
|
CURRENCY_NONE = 0,
|
||||||
|
CURRENCY_CONQUEST_POINTS = 390,
|
||||||
|
CURRENCY_HONOR_POINTS = 392,
|
||||||
|
CURRENCY_JUSTICE_POINTS = 395,
|
||||||
|
CURRENCY_VALOR_POINTS = 396,
|
||||||
|
CURRENCY_CONQUEST_ARENA_META = 483,
|
||||||
|
CURRENCY_CONQUEST_BG_META = 484,
|
||||||
|
};
|
||||||
|
|
||||||
enum ItemEnchantmentType
|
enum ItemEnchantmentType
|
||||||
{
|
{
|
||||||
ITEM_ENCHANTMENT_TYPE_NONE = 0,
|
ITEM_ENCHANTMENT_TYPE_NONE = 0,
|
||||||
|
|
|
||||||
|
|
@ -811,7 +811,7 @@ struct CurrencyTypesEntry
|
||||||
{
|
{
|
||||||
uint32 ID; // 0
|
uint32 ID; // 0
|
||||||
//uint32 Category; // 1
|
//uint32 Category; // 1
|
||||||
//char* name; // 2
|
DBCString name; // 2
|
||||||
//char* iconName; // 3
|
//char* iconName; // 3
|
||||||
//uint32 unk4; // 4
|
//uint32 unk4; // 4
|
||||||
//uint32 unk5; // 5
|
//uint32 unk5; // 5
|
||||||
|
|
@ -819,7 +819,7 @@ struct CurrencyTypesEntry
|
||||||
uint32 TotalCount; // 7
|
uint32 TotalCount; // 7
|
||||||
uint32 WeekCount; // 8
|
uint32 WeekCount; // 8
|
||||||
uint32 Flags; // 9
|
uint32 Flags; // 9
|
||||||
//char* description; // 10
|
//DBCString description; // 10
|
||||||
|
|
||||||
bool HasPrecision() const { return Flags & CURRENCY_FLAG_HAS_PRECISION; }
|
bool HasPrecision() const { return Flags & CURRENCY_FLAG_HAS_PRECISION; }
|
||||||
bool HasSeasonCount() const { return Flags & CURRENCY_FLAG_HAS_SEASON_COUNT; }
|
bool HasSeasonCount() const { return Flags & CURRENCY_FLAG_HAS_SEASON_COUNT; }
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const char CreatureFamilyfmt[]="nfifiiiiixsx";
|
||||||
const char CreatureSpellDatafmt[]="niiiixxxx";
|
const char CreatureSpellDatafmt[]="niiiixxxx";
|
||||||
const char DungeonEncounterfmt[]="niiiisxx";
|
const char DungeonEncounterfmt[]="niiiisxx";
|
||||||
const char CreatureTypefmt[]="nxx";
|
const char CreatureTypefmt[]="nxx";
|
||||||
const char CurrencyTypesfmt[]="nxxxxxxiiix";
|
const char CurrencyTypesfmt[]="nxsxxxxiiix";
|
||||||
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||||
const char DurabilityQualityfmt[]="nf";
|
const char DurabilityQualityfmt[]="nf";
|
||||||
const char EmotesEntryfmt[]="nxxiiixx";
|
const char EmotesEntryfmt[]="nxxiiixx";
|
||||||
|
|
|
||||||
|
|
@ -483,15 +483,15 @@ void WorldSession::HandleBuybackItem(WorldPacket& recv_data)
|
||||||
_player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, 0, 0);
|
_player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recv_data)
|
void WorldSession::HandleBuyItemOpcode(WorldPacket& recv_data)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("WORLD: Received CMSG_BUY_ITEM_IN_SLOT");
|
ObjectGuid vendorGuid, bagGuid;
|
||||||
ObjectGuid vendorGuid;
|
|
||||||
ObjectGuid bagGuid;
|
|
||||||
uint32 item, slot, count;
|
uint32 item, slot, count;
|
||||||
uint8 bagslot;
|
uint8 type, bagSlot;
|
||||||
|
|
||||||
recv_data >> vendorGuid >> item >> slot >> bagGuid >> bagslot >> count;
|
recv_data >> vendorGuid >> type >> item >> slot >> count >> bagGuid >> bagSlot;
|
||||||
|
DEBUG_LOG("WORLD: Received CMSG_BUY_ITEM, vendorguid: %s, type: %u, item: %u, slot: %u, count: %u, bagGuid: %s, bagSlog: %u",
|
||||||
|
vendorGuid.GetString().c_str(), type, item, slot, count, bagGuid.GetString().c_str(), bagSlot);
|
||||||
|
|
||||||
// client side expected counting from 1, and we send to client vendorslot+1 already
|
// client side expected counting from 1, and we send to client vendorslot+1 already
|
||||||
if (slot > 0)
|
if (slot > 0)
|
||||||
|
|
@ -499,6 +499,12 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recv_data)
|
||||||
else
|
else
|
||||||
return; // cheating
|
return; // cheating
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case VENDOR_ITEM_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case VENDOR_ITEM_TYPE_ITEM:
|
||||||
|
{
|
||||||
uint8 bag = NULL_BAG; // init for case invalid bagGUID
|
uint8 bag = NULL_BAG; // init for case invalid bagGUID
|
||||||
|
|
||||||
// find bag slot by bag guid
|
// find bag slot by bag guid
|
||||||
|
|
@ -519,29 +525,15 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recv_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// bag not found, cheating?
|
GetPlayer()->BuyItemFromVendorSlot(vendorGuid, slot, item, count, bag, bagSlot);
|
||||||
if (bag == NULL_BAG)
|
break;
|
||||||
return;
|
}
|
||||||
|
case VENDOR_ITEM_TYPE_CURRENCY:
|
||||||
GetPlayer()->BuyItemFromVendorSlot(vendorGuid, slot, item, count, bag, bagslot);
|
{
|
||||||
}
|
GetPlayer()->BuyCurrencyFromVendorSlot(vendorGuid, slot, item, count);
|
||||||
|
break;
|
||||||
void WorldSession::HandleBuyItemOpcode(WorldPacket& recv_data)
|
}
|
||||||
{
|
}
|
||||||
DEBUG_LOG("WORLD: Received CMSG_BUY_ITEM");
|
|
||||||
ObjectGuid vendorGuid, otherGuid;
|
|
||||||
uint32 item, slot, count;
|
|
||||||
uint8 unk1, unk2;
|
|
||||||
|
|
||||||
recv_data >> vendorGuid >> unk1 >> item >> slot >> count >> otherGuid >> unk2;
|
|
||||||
|
|
||||||
// client side expected counting from 1, and we send to client vendorslot+1 already
|
|
||||||
if (slot > 0)
|
|
||||||
--slot;
|
|
||||||
else
|
|
||||||
return; // cheating
|
|
||||||
|
|
||||||
GetPlayer()->BuyItemFromVendorSlot(vendorGuid, slot, item, count, NULL_BAG, NULL_SLOT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleListInventoryOpcode(WorldPacket& recv_data)
|
void WorldSession::HandleListInventoryOpcode(WorldPacket& recv_data)
|
||||||
|
|
@ -597,10 +589,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorguid)
|
||||||
|
|
||||||
if (crItem)
|
if (crItem)
|
||||||
{
|
{
|
||||||
uint32 itemId = crItem->item;
|
uint32 price, displayId, buyCount, maxDurability;
|
||||||
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId);
|
int32 maxCount;
|
||||||
if (pProto)
|
|
||||||
|
if (crItem->type == VENDOR_ITEM_TYPE_ITEM)
|
||||||
{
|
{
|
||||||
|
ItemPrototype const * pProto = ObjectMgr::GetItemPrototype(crItem->item);
|
||||||
|
if (!pProto)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!_player->isGameMaster())
|
if (!_player->isGameMaster())
|
||||||
{
|
{
|
||||||
// class wrong item skip only for bindable case
|
// class wrong item skip only for bindable case
|
||||||
|
|
@ -625,35 +622,60 @@ void WorldSession::SendListInventory(ObjectGuid vendorguid)
|
||||||
if (pProto->RequiredReputationFaction && uint32(_player->GetReputationRank(pProto->RequiredReputationFaction)) >= pProto->RequiredReputationRank)
|
if (pProto->RequiredReputationFaction && uint32(_player->GetReputationRank(pProto->RequiredReputationFaction)) >= pProto->RequiredReputationRank)
|
||||||
{
|
{
|
||||||
// checked at convert data loading as existed
|
// checked at convert data loading as existed
|
||||||
if (uint32 newItemId = sObjectMgr.GetItemConvert(itemId, _player->getRaceMask()))
|
if (uint32 newItemId = sObjectMgr.GetItemConvert(crItem->item, _player->getRaceMask()))
|
||||||
pProto = ObjectMgr::GetItemPrototype(newItemId);
|
pProto = ObjectMgr::GetItemPrototype(newItemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
if (count >= MAX_VENDOR_ITEMS)
|
if (count >= MAX_VENDOR_ITEMS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// reputation discount
|
||||||
|
maxDurability = pProto->MaxDurability;
|
||||||
|
price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0;
|
||||||
|
displayId = pProto->DisplayInfoID;
|
||||||
|
maxCount = crItem->maxcount <= 0 ? -1 : int32(pCreature->GetVendorItemCurrentCount(crItem));
|
||||||
|
buyCount = pProto->BuyCount;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (crItem->type == VENDOR_ITEM_TYPE_CURRENCY)
|
||||||
|
{
|
||||||
|
CurrencyTypesEntry const * pCurrency = sCurrencyTypesStore.LookupEntry(crItem->item);
|
||||||
|
if (!pCurrency)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pCurrency->ID == CURRENCY_CONQUEST_ARENA_META || pCurrency->ID == CURRENCY_CONQUEST_BG_META)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
++count;
|
||||||
|
if (count >= MAX_VENDOR_ITEMS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
maxDurability = 0;
|
||||||
|
price = 0;
|
||||||
|
displayId = 0;
|
||||||
|
maxCount = -1;
|
||||||
|
buyCount = crItem->maxcount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
bitFlags.push_back(crItem->ExtendedCost == 0);
|
bitFlags.push_back(crItem->ExtendedCost == 0);
|
||||||
bitFlags.push_back(true); // unk
|
bitFlags.push_back(true); // unk
|
||||||
|
|
||||||
// reputation discount
|
|
||||||
uint32 price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0;
|
|
||||||
|
|
||||||
buffer << uint32(vendorslot + 1); // client size expected counting from 1
|
buffer << uint32(vendorslot + 1); // client size expected counting from 1
|
||||||
buffer << uint32(pProto->MaxDurability);
|
buffer << uint32(maxDurability);
|
||||||
|
|
||||||
if (crItem->ExtendedCost)
|
if (crItem->ExtendedCost)
|
||||||
buffer << uint32(crItem->ExtendedCost);
|
buffer << uint32(crItem->ExtendedCost);
|
||||||
|
|
||||||
buffer << uint32(itemId);
|
buffer << uint32(crItem->item);
|
||||||
buffer << uint32(1); // type == item
|
buffer << uint32(crItem->type);
|
||||||
buffer << uint32(price);
|
buffer << uint32(price);
|
||||||
buffer << uint32(pProto->DisplayInfoID);
|
buffer << uint32(displayId);
|
||||||
buffer << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem));
|
buffer << int32(maxCount);
|
||||||
buffer << uint32(pProto->BuyCount);
|
buffer << uint32(buyCount);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ enum MangosStrings
|
||||||
LANG_COMMAND_TARGETOBJNOTFOUND = 266,
|
LANG_COMMAND_TARGETOBJNOTFOUND = 266,
|
||||||
LANG_COMMAND_GOOBJNOTFOUND = 267,
|
LANG_COMMAND_GOOBJNOTFOUND = 267,
|
||||||
LANG_COMMAND_GOCREATNOTFOUND = 268,
|
LANG_COMMAND_GOCREATNOTFOUND = 268,
|
||||||
// 269, not used
|
LANG_CURRENCY_NOT_FOUND = 269,
|
||||||
LANG_COMMAND_DELCREATMESSAGE = 270,
|
LANG_COMMAND_DELCREATMESSAGE = 270,
|
||||||
LANG_COMMAND_CREATUREMOVED = 271,
|
LANG_COMMAND_CREATUREMOVED = 271,
|
||||||
LANG_COMMAND_CREATUREATSAMEMAP = 272,
|
LANG_COMMAND_CREATUREATSAMEMAP = 272,
|
||||||
|
|
@ -271,7 +271,7 @@ enum MangosStrings
|
||||||
LANG_COMMAND_ADDVENDORITEMITEMS = 280,
|
LANG_COMMAND_ADDVENDORITEMITEMS = 280,
|
||||||
LANG_COMMAND_KICKSELF = 281,
|
LANG_COMMAND_KICKSELF = 281,
|
||||||
LANG_COMMAND_KICKMESSAGE = 282,
|
LANG_COMMAND_KICKMESSAGE = 282,
|
||||||
// 283, not used
|
LANG_VENDOR_META_CURRENCY_NOT_ALLOWED = 283,
|
||||||
LANG_COMMAND_WHISPERACCEPTING = 284,
|
LANG_COMMAND_WHISPERACCEPTING = 284,
|
||||||
LANG_COMMAND_WHISPERON = 285,
|
LANG_COMMAND_WHISPERON = 285,
|
||||||
LANG_COMMAND_WHISPEROFF = 286,
|
LANG_COMMAND_WHISPEROFF = 286,
|
||||||
|
|
@ -965,6 +965,8 @@ enum MangosStrings
|
||||||
LANG_NPC_EVENTAI_PHASE = 1506,
|
LANG_NPC_EVENTAI_PHASE = 1506,
|
||||||
LANG_NPC_EVENTAI_MOVE = 1507,
|
LANG_NPC_EVENTAI_MOVE = 1507,
|
||||||
LANG_NPC_EVENTAI_COMBAT = 1508,
|
LANG_NPC_EVENTAI_COMBAT = 1508,
|
||||||
|
LANG_VENDOR_WRONG_ITEM_TYPE = 1509,
|
||||||
|
LANG_VENDOR_WRONG_CURRENCY_MAXCOUNT = 1510,
|
||||||
// Room for more Level 2 1509-1599 not used
|
// Room for more Level 2 1509-1599 not used
|
||||||
|
|
||||||
// Outdoor PvP
|
// Outdoor PvP
|
||||||
|
|
|
||||||
|
|
@ -1600,6 +1600,43 @@ bool ChatHandler::HandleNpcAddCommand(char* args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add currency in vendorlist
|
||||||
|
bool ChatHandler::HandleNpcAddVendorCurrencyCommand(char* args)
|
||||||
|
{
|
||||||
|
uint32 currencyId;
|
||||||
|
if (!ExtractUint32KeyFromLink(&args, "Hcurrency", currencyId))
|
||||||
|
{
|
||||||
|
SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 maxcount;
|
||||||
|
if (!ExtractUInt32(&args, maxcount))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 extendedcost;
|
||||||
|
if (!ExtractUInt32(&args, extendedcost))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Creature* vendor = getSelectedCreature();
|
||||||
|
|
||||||
|
uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
|
||||||
|
|
||||||
|
if (!sObjectMgr.IsVendorItemValid(false, "npc_vendor", vendor_entry, currencyId, VENDOR_ITEM_TYPE_CURRENCY, maxcount, 0, extendedcost, m_session->GetPlayer()))
|
||||||
|
{
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sObjectMgr.AddVendorItem(vendor_entry, currencyId, VENDOR_ITEM_TYPE_CURRENCY, maxcount, 0, extendedcost);
|
||||||
|
|
||||||
|
std::string name = sCurrencyTypesStore.LookupEntry(currencyId)->name[0];
|
||||||
|
|
||||||
|
PSendSysMessage(LANG_ITEM_ADDED_TO_LIST, currencyId, name.c_str(), maxcount, 0, extendedcost);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// add item in vendorlist
|
// add item in vendorlist
|
||||||
bool ChatHandler::HandleNpcAddVendorItemCommand(char* args)
|
bool ChatHandler::HandleNpcAddVendorItemCommand(char* args)
|
||||||
{
|
{
|
||||||
|
|
@ -1627,17 +1664,52 @@ bool ChatHandler::HandleNpcAddVendorItemCommand(char* args)
|
||||||
|
|
||||||
uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
|
uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
|
||||||
|
|
||||||
if (!sObjectMgr.IsVendorItemValid(false, "npc_vendor", vendor_entry, itemId, maxcount, incrtime, extendedcost, m_session->GetPlayer()))
|
if (!sObjectMgr.IsVendorItemValid(false, "npc_vendor", vendor_entry, itemId, VENDOR_ITEM_TYPE_ITEM, maxcount, incrtime, extendedcost, m_session->GetPlayer()))
|
||||||
{
|
{
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sObjectMgr.AddVendorItem(vendor_entry, itemId, maxcount, incrtime, extendedcost);
|
sObjectMgr.AddVendorItem(vendor_entry, itemId, VENDOR_ITEM_TYPE_ITEM, maxcount, incrtime, extendedcost);
|
||||||
|
|
||||||
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId);
|
std::string name = ObjectMgr::GetItemPrototype(itemId)->Name1;
|
||||||
|
|
||||||
PSendSysMessage(LANG_ITEM_ADDED_TO_LIST, itemId, pProto->Name1, maxcount, incrtime, extendedcost);
|
PSendSysMessage(LANG_ITEM_ADDED_TO_LIST, itemId, name.c_str(), maxcount, incrtime, extendedcost);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// del currency from vendor list
|
||||||
|
bool ChatHandler::HandleNpcDelVendorCurrencyCommand(char* args)
|
||||||
|
{
|
||||||
|
if (!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Creature* vendor = getSelectedCreature();
|
||||||
|
if (!vendor || !vendor->isVendor())
|
||||||
|
{
|
||||||
|
SendSysMessage(LANG_COMMAND_VENDORSELECTION);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 itemId;
|
||||||
|
if (!ExtractUint32KeyFromLink(&args, "Hcurrency", itemId))
|
||||||
|
{
|
||||||
|
SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sObjectMgr.RemoveVendorItem(vendor->GetEntry(), itemId, VENDOR_ITEM_TYPE_CURRENCY))
|
||||||
|
{
|
||||||
|
PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId, true);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = sCurrencyTypesStore.LookupEntry(itemId)->name[0];
|
||||||
|
|
||||||
|
PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST, itemId, name.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1663,16 +1735,16 @@ bool ChatHandler::HandleNpcDelVendorItemCommand(char* args)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sObjectMgr.RemoveVendorItem(vendor->GetEntry(), itemId))
|
if (!sObjectMgr.RemoveVendorItem(vendor->GetEntry(), itemId, VENDOR_ITEM_TYPE_ITEM))
|
||||||
{
|
{
|
||||||
PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId);
|
PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId, false);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId);
|
std::string name = ObjectMgr::GetItemPrototype(itemId)->Name1;
|
||||||
|
|
||||||
PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST, itemId, pProto->Name1);
|
PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST, itemId, name.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8746,17 +8746,18 @@ void ObjectMgr::LoadVendors(char const* tableName, bool isTemplates)
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
|
|
||||||
uint32 entry = fields[0].GetUInt32();
|
uint32 entry = fields[0].GetUInt32();
|
||||||
uint32 item_id = fields[1].GetUInt32();
|
uint32 item_id = abs(fields[1].GetInt32());
|
||||||
|
uint8 type = fields[1].GetInt32() > 0 ? VENDOR_ITEM_TYPE_ITEM : VENDOR_ITEM_TYPE_CURRENCY;
|
||||||
uint32 maxcount = fields[2].GetUInt32();
|
uint32 maxcount = fields[2].GetUInt32();
|
||||||
uint32 incrtime = fields[3].GetUInt32();
|
uint32 incrtime = fields[3].GetUInt32();
|
||||||
uint32 ExtendedCost = fields[4].GetUInt32();
|
uint32 ExtendedCost = fields[4].GetUInt32();
|
||||||
|
|
||||||
if (!IsVendorItemValid(isTemplates, tableName, entry, item_id, maxcount, incrtime, ExtendedCost, NULL, &skip_vendors))
|
if (!IsVendorItemValid(isTemplates, tableName, entry, item_id, type, maxcount, incrtime, ExtendedCost, NULL, &skip_vendors))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VendorItemData& vList = vendorList[entry];
|
VendorItemData& vList = vendorList[entry];
|
||||||
|
|
||||||
vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
|
vList.AddItem(item_id, type, maxcount, incrtime, ExtendedCost);
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -9183,30 +9184,31 @@ void ObjectMgr::LoadGossipMenus()
|
||||||
sLog.outErrorDb("Table `gossip_scripts` contains unused script, id %u.", *itr);
|
sLog.outErrorDb("Table `gossip_scripts` contains unused script, id %u.", *itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost)
|
void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, uint8 type, uint32 maxcount, uint32 incrtime, uint32 extendedcost)
|
||||||
{
|
{
|
||||||
VendorItemData& vList = m_mCacheVendorItemMap[entry];
|
VendorItemData& vList = m_mCacheVendorItemMap[entry];
|
||||||
vList.AddItem(item, maxcount, incrtime, extendedcost);
|
vList.AddItem(item, type, maxcount, incrtime, extendedcost);
|
||||||
|
|
||||||
WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')", entry, item, maxcount, incrtime, extendedcost);
|
WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%i','%u','%u','%u')", entry, type == VENDOR_ITEM_TYPE_CURRENCY ? -int32(item) : item, maxcount, incrtime, extendedcost);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item)
|
bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, uint8 type)
|
||||||
{
|
{
|
||||||
CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry);
|
CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry);
|
||||||
if (iter == m_mCacheVendorItemMap.end())
|
if (iter == m_mCacheVendorItemMap.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!iter->second.RemoveItem(item))
|
if (!iter->second.RemoveItem(item, type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'", entry, item);
|
WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%i'", entry, type == VENDOR_ITEM_TYPE_CURRENCY ? -int32(item) : item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set<uint32>* skip_vendors) const
|
bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item_id, uint8 type, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set<uint32>* skip_vendors) const
|
||||||
{
|
{
|
||||||
char const* idStr = isTemplate ? "vendor template" : "vendor";
|
char const* idStr = isTemplate ? "vendor template" : "vendor";
|
||||||
|
char const* nameStr = type == VENDOR_ITEM_TYPE_CURRENCY ? "Currency" : "Item";
|
||||||
CreatureInfo const* cInfo = NULL;
|
CreatureInfo const* cInfo = NULL;
|
||||||
|
|
||||||
if (!isTemplate)
|
if (!isTemplate)
|
||||||
|
|
@ -9237,33 +9239,72 @@ bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrencyTypesEntry const * currencyEntry;
|
||||||
|
if (type == VENDOR_ITEM_TYPE_ITEM)
|
||||||
|
{
|
||||||
if (!GetItemPrototype(item_id))
|
if (!GetItemPrototype(item_id))
|
||||||
{
|
{
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
|
ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` for %s %u contain nonexistent item (%u), ignoring",
|
sLog.outErrorDb("Table `%s` for %s %u contains nonexistent item (%u), ignoring",
|
||||||
tableName, idStr, vendor_entry, item_id);
|
tableName, idStr, vendor_entry, item_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (type == VENDOR_ITEM_TYPE_CURRENCY)
|
||||||
|
{
|
||||||
|
currencyEntry = sCurrencyTypesStore.LookupEntry(item_id);
|
||||||
|
if (!currencyEntry)
|
||||||
|
{
|
||||||
|
if (pl)
|
||||||
|
ChatHandler(pl).PSendSysMessage(LANG_CURRENCY_NOT_FOUND, item_id);
|
||||||
|
else
|
||||||
|
sLog.outErrorDb("Table `%s` for %s %u contains nonexistent currency (%u), ignoring",
|
||||||
|
tableName, idStr, vendor_entry, item_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currencyEntry->ID == CURRENCY_CONQUEST_ARENA_META || currencyEntry->ID == CURRENCY_CONQUEST_BG_META)
|
||||||
|
{
|
||||||
|
if (pl)
|
||||||
|
ChatHandler(pl).PSendSysMessage(LANG_VENDOR_META_CURRENCY_NOT_ALLOWED, item_id);
|
||||||
|
else
|
||||||
|
sLog.outErrorDb("Table `%s` for %s %u contains not allowed meta currency (%u), ignoring",
|
||||||
|
tableName, idStr, vendor_entry, item_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pl)
|
||||||
|
ChatHandler(pl).PSendSysMessage(LANG_VENDOR_WRONG_ITEM_TYPE, item_id, type);
|
||||||
|
else
|
||||||
|
sLog.outErrorDb("Table `%s` for %s %u contains nonexistent vendor item type %u (entry %u), ignoring",
|
||||||
|
tableName, idStr, vendor_entry, type, item_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
|
if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
|
||||||
{
|
{
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost);
|
ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` contain item (Entry: %u) with wrong ExtendedCost (%u) for %s %u, ignoring",
|
sLog.outErrorDb("Table `%s` contains %s (Entry: %u) with wrong ExtendedCost (%u) for %s %u, ignoring",
|
||||||
tableName, item_id, ExtendedCost, idStr, vendor_entry);
|
tableName, nameStr, item_id, ExtendedCost, idStr, vendor_entry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == VENDOR_ITEM_TYPE_ITEM)
|
||||||
|
{
|
||||||
if (maxcount > 0 && incrtime == 0)
|
if (maxcount > 0 && incrtime == 0)
|
||||||
{
|
{
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount);
|
ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` has `maxcount` (%u) for item %u of %s %u but `incrtime`=0, ignoring",
|
sLog.outErrorDb("Table `%s` has `maxcount` (%u) for %s %u of %s %u but `incrtime`=0, ignoring",
|
||||||
tableName, maxcount, item_id, idStr, vendor_entry);
|
tableName, maxcount, nameStr, item_id, idStr, vendor_entry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (maxcount == 0 && incrtime > 0)
|
else if (maxcount == 0 && incrtime > 0)
|
||||||
|
|
@ -9271,10 +9312,23 @@ bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0");
|
ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0");
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` has `maxcount`=0 for item %u of %s %u but `incrtime`<>0, ignoring",
|
sLog.outErrorDb("Table `%s` has `maxcount`=0 for %s %u of %s %u but `incrtime`<>0, ignoring",
|
||||||
tableName, item_id, idStr, vendor_entry);
|
tableName, nameStr, item_id, idStr, vendor_entry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (type == VENDOR_ITEM_TYPE_CURRENCY)
|
||||||
|
{
|
||||||
|
if (maxcount < uint32(currencyEntry->GetPrecision()))
|
||||||
|
{
|
||||||
|
if (pl)
|
||||||
|
ChatHandler(pl).PSendSysMessage(LANG_VENDOR_WRONG_CURRENCY_MAXCOUNT, item_id, uint32(currencyEntry->GetPrecision()));
|
||||||
|
else
|
||||||
|
sLog.outErrorDb("Table `%s` contains %s (Entry: %u) with too low maxcount. Maxcount for currencies is buycount, so it can't be 0 or less than that's currency precision (%u), ignoring",
|
||||||
|
tableName, nameStr, item_id, uint32(currencyEntry->GetPrecision()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VendorItemData const* vItems = isTemplate ? GetNpcVendorTemplateItemList(vendor_entry) : GetNpcVendorItemList(vendor_entry);
|
VendorItemData const* vItems = isTemplate ? GetNpcVendorTemplateItemList(vendor_entry) : GetNpcVendorItemList(vendor_entry);
|
||||||
VendorItemData const* tItems = isTemplate ? NULL : GetNpcVendorTemplateItemList(vendor_entry);
|
VendorItemData const* tItems = isTemplate ? NULL : GetNpcVendorTemplateItemList(vendor_entry);
|
||||||
|
|
@ -9282,30 +9336,30 @@ bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32
|
||||||
if (!vItems && !tItems)
|
if (!vItems && !tItems)
|
||||||
return true; // later checks for non-empty lists
|
return true; // later checks for non-empty lists
|
||||||
|
|
||||||
if (vItems && vItems->FindItemCostPair(item_id, ExtendedCost))
|
if (vItems && vItems->FindItemCostPair(item_id, type, ExtendedCost))
|
||||||
{
|
{
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
|
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, type == VENDOR_ITEM_TYPE_CURRENCY, ExtendedCost);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` has duplicate items %u (with extended cost %u) for %s %u, ignoring",
|
sLog.outErrorDb("Table `%s` has duplicate %s %u (with extended cost %u) for %s %u, ignoring",
|
||||||
tableName, item_id, ExtendedCost, idStr, vendor_entry);
|
tableName, nameStr, item_id, ExtendedCost, idStr, vendor_entry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTemplate)
|
if (!isTemplate)
|
||||||
{
|
{
|
||||||
if (tItems && tItems->FindItemCostPair(item_id, ExtendedCost))
|
if (tItems && tItems->FindItemCostPair(item_id, type, ExtendedCost))
|
||||||
{
|
{
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
|
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, type == VENDOR_ITEM_TYPE_CURRENCY, ExtendedCost);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!cInfo->vendorId)
|
if (!cInfo->vendorId)
|
||||||
sLog.outErrorDb("Table `%s` has duplicate items %u (with extended cost %u) for %s %u, ignoring",
|
sLog.outErrorDb("Table `%s` has duplicate %s %u (with extended cost %u) for %s %u, ignoring",
|
||||||
tableName, item_id, ExtendedCost, idStr, vendor_entry);
|
tableName, nameStr, item_id, ExtendedCost, idStr, vendor_entry);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` has duplicate items %u (with extended cost %u) for %s %u (or possible in vendor template %u), ignoring",
|
sLog.outErrorDb("Table `%s` has duplicate %s %u (with extended cost %u) for %s %u (or possible in vendor template %u), ignoring",
|
||||||
tableName, item_id, ExtendedCost, idStr, vendor_entry, cInfo->vendorId);
|
tableName, nameStr, item_id, ExtendedCost, idStr, vendor_entry, cInfo->vendorId);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -9319,7 +9373,7 @@ bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32
|
||||||
if (pl)
|
if (pl)
|
||||||
ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
|
ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Table `%s` has too many items (%u >= %i) for %s %u, ignoring",
|
sLog.outErrorDb("Table `%s` has too many entries (%u >= %i) for %s %u, ignoring",
|
||||||
tableName, countItems, MAX_VENDOR_ITEMS, idStr, vendor_entry);
|
tableName, countItems, MAX_VENDOR_ITEMS, idStr, vendor_entry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1017,9 +1017,9 @@ class ObjectMgr
|
||||||
return &iter->second;
|
return &iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddVendorItem(uint32 entry, uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost);
|
void AddVendorItem(uint32 entry, uint32 item, uint8 type, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost);
|
||||||
bool RemoveVendorItem(uint32 entry, uint32 item);
|
bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type);
|
||||||
bool IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL) const;
|
bool IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item, uint8 type, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL) const;
|
||||||
|
|
||||||
int GetOrNewIndexForLocale(LocaleConstant loc);
|
int GetOrNewIndexForLocale(LocaleConstant loc);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19635,6 +19635,106 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin
|
||||||
return crItem->maxcount != 0;
|
return crItem->maxcount != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Player::BuyCurrencyFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uint32 currencyId, uint8 count)
|
||||||
|
{
|
||||||
|
// cheating attempt
|
||||||
|
if (count < 1) count = 1;
|
||||||
|
|
||||||
|
if (!isAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CurrencyTypesEntry const* pCurrency = sCurrencyTypesStore.LookupEntry(currencyId);
|
||||||
|
if (!pCurrency)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (currencyId == CURRENCY_CONQUEST_ARENA_META || currencyId == CURRENCY_CONQUEST_BG_META)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Creature* pCreature = GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
|
||||||
|
if (!pCreature)
|
||||||
|
{
|
||||||
|
DEBUG_LOG("WORLD: BuyCurrencyFromVendorSlot - %s not found or you can't interact with him.", vendorGuid.GetString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VendorItemData const* vItems = pCreature->GetVendorItems();
|
||||||
|
VendorItemData const* tItems = pCreature->GetVendorTemplateItems();
|
||||||
|
if ((!vItems || vItems->Empty()) && (!tItems || tItems->Empty()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 vCount = vItems ? vItems->GetItemCount() : 0;
|
||||||
|
uint32 tCount = tItems ? tItems->GetItemCount() : 0;
|
||||||
|
|
||||||
|
if (vendorslot >= vCount + tCount)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VendorItem const* crItem = vendorslot < vCount ? vItems->GetItem(vendorslot) : tItems->GetItem(vendorslot - vCount);
|
||||||
|
if (!crItem) // store diff item (cheating)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (crItem->item != currencyId) // store diff item (cheating)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (crItem->maxcount != count)
|
||||||
|
{
|
||||||
|
DEBUG_LOG("WORLD: BuyCurrencyFromVendorSlot - %s: count (%u) != crItem->maxcount (%u) for currency %u and player %s.",
|
||||||
|
vendorGuid.GetString().c_str(), count, crItem->maxcount, currencyId, GetGuidStr().c_str());
|
||||||
|
|
||||||
|
count = crItem->maxcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uint32 extendedCostId = crItem->ExtendedCost)
|
||||||
|
{
|
||||||
|
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId);
|
||||||
|
if (!iece)
|
||||||
|
{
|
||||||
|
sLog.outError("WORLD: BuyCurrencyFromVendorSlot: Currency %u have wrong ExtendedCost field value %u for %s", currencyId, extendedCostId, vendorGuid.GetString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// honor points price
|
||||||
|
if (GetHonorPoints() < (iece->reqhonorpoints * count))
|
||||||
|
{
|
||||||
|
SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// arena points price
|
||||||
|
if (GetArenaPoints() < (iece->reqarenapoints * count))
|
||||||
|
{
|
||||||
|
SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// item base price
|
||||||
|
for (uint8 i = 0; i < MAX_EXTENDED_COST_ITEMS; ++i)
|
||||||
|
{
|
||||||
|
if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], iece->reqitemcount[i] * count))
|
||||||
|
{
|
||||||
|
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for personal arena rating requirement
|
||||||
|
if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating)
|
||||||
|
{
|
||||||
|
// probably not the proper equip err
|
||||||
|
SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check if player already has maximum currency
|
||||||
|
|
||||||
|
// TODO: modify currency
|
||||||
|
|
||||||
|
DEBUG_LOG("WORLD: BuyCurrencyFromVendorSlot - %s: Player %s buys currency %u amount %u.",
|
||||||
|
vendorGuid.GetString().c_str(), GetGuidStr().c_str(), currencyId, count);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 Player::GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot)
|
uint32 Player::GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot)
|
||||||
{
|
{
|
||||||
// returns the maximal personal arena rating that can be used to purchase items requiring this condition
|
// returns the maximal personal arena rating that can be used to purchase items requiring this condition
|
||||||
|
|
|
||||||
|
|
@ -1286,6 +1286,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
}
|
}
|
||||||
void SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast = false);
|
void SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast = false);
|
||||||
bool BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
|
bool BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
|
||||||
|
bool BuyCurrencyFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uint32 currencyId, uint8 count);
|
||||||
|
|
||||||
float GetReputationPriceDiscount(Creature const* pCreature) const;
|
float GetReputationPriceDiscount(Creature const* pCreature) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2758,6 +2758,7 @@ enum ChatMsg
|
||||||
|
|
||||||
enum ChatLinkColors
|
enum ChatLinkColors
|
||||||
{
|
{
|
||||||
|
CHAT_LINK_COLOR_CURRENCY = 0xff00aa00, // green
|
||||||
CHAT_LINK_COLOR_TRADE = 0xffffd000, // orange
|
CHAT_LINK_COLOR_TRADE = 0xffffd000, // orange
|
||||||
CHAT_LINK_COLOR_TALENT = 0xff4e96f7, // blue
|
CHAT_LINK_COLOR_TALENT = 0xff4e96f7, // blue
|
||||||
CHAT_LINK_COLOR_SPELL = 0xff71d5ff, // bright blue
|
CHAT_LINK_COLOR_SPELL = 0xff71d5ff, // bright blue
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,6 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
void HandleDestroyItemOpcode(WorldPacket& recvPacket);
|
void HandleDestroyItemOpcode(WorldPacket& recvPacket);
|
||||||
void HandleAutoEquipItemOpcode(WorldPacket& recvPacket);
|
void HandleAutoEquipItemOpcode(WorldPacket& recvPacket);
|
||||||
void HandleSellItemOpcode(WorldPacket& recvPacket);
|
void HandleSellItemOpcode(WorldPacket& recvPacket);
|
||||||
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
|
|
||||||
void HandleBuyItemOpcode(WorldPacket& recvPacket);
|
void HandleBuyItemOpcode(WorldPacket& recvPacket);
|
||||||
void HandleListInventoryOpcode(WorldPacket& recvPacket);
|
void HandleListInventoryOpcode(WorldPacket& recvPacket);
|
||||||
void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket);
|
void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "0168"
|
#define REVISION_NR "0169"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __REVISION_SQL_H__
|
#ifndef __REVISION_SQL_H__
|
||||||
#define __REVISION_SQL_H__
|
#define __REVISION_SQL_H__
|
||||||
#define REVISION_DB_CHARACTERS "required_0099_xxxxx_01_characters_character_phase_data"
|
#define REVISION_DB_CHARACTERS "required_0099_xxxxx_01_characters_character_phase_data"
|
||||||
#define REVISION_DB_MANGOS "required_0168_xxxxx_01_mangos_playercreateinfo_spell"
|
#define REVISION_DB_MANGOS "required_0169_xxxxx_04_mangos_command"
|
||||||
#define REVISION_DB_REALMD "required_0014_xxxxx_01_realmd_account_access"
|
#define REVISION_DB_REALMD "required_0014_xxxxx_01_realmd_account_access"
|
||||||
#endif // __REVISION_SQL_H__
|
#endif // __REVISION_SQL_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue