[12216] Implement currency loot and update loot opcodes.

Now negative item value in loot tables represent currency id.

Signed-off-by: Yaki Khadafi <elsoldollo@gmail.com>
This commit is contained in:
Yaki Khadafi 2012-09-13 17:33:27 +03:00 committed by Antz
parent f710cc3c24
commit ef0f63e05b
31 changed files with 418 additions and 160 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_12195_02_mangos_mangos_string"` bit(1) default NULL `required_12216_12_mangos_spell_loot_template"` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -1020,11 +1020,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `creature_loot_template`; DROP TABLE IF EXISTS `creature_loot_template`;
CREATE TABLE `creature_loot_template` ( CREATE TABLE `creature_loot_template` (
`entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'entry 0 used for player insignia loot', `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'entry 0 used for player insignia loot',
`item` mediumint(8) unsigned NOT NULL default '0', `item` mediumint(8) NOT NULL default '0',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -1429,11 +1429,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `disenchant_loot_template`; DROP TABLE IF EXISTS `disenchant_loot_template`;
CREATE TABLE `disenchant_loot_template` ( CREATE TABLE `disenchant_loot_template` (
`entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Recommended id selection: item_level*100 + item_quality', `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Recommended id selection: item_level*100 + item_quality',
`item` mediumint(8) unsigned NOT NULL default '0', `item` mediumint(8) NOT NULL default '0',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -1684,11 +1684,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `fishing_loot_template`; DROP TABLE IF EXISTS `fishing_loot_template`;
CREATE TABLE `fishing_loot_template` ( CREATE TABLE `fishing_loot_template` (
`entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'entry 0 used for junk loot at fishing fail (if allowed by config option)', `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'entry 0 used for junk loot at fishing fail (if allowed by config option)',
`item` mediumint(8) unsigned NOT NULL default '0', `item` mediumint(8) NOT NULL default '0',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -2022,11 +2022,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `gameobject_loot_template`; DROP TABLE IF EXISTS `gameobject_loot_template`;
CREATE TABLE `gameobject_loot_template` ( CREATE TABLE `gameobject_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -2411,11 +2411,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `item_loot_template`; DROP TABLE IF EXISTS `item_loot_template`;
CREATE TABLE `item_loot_template` ( CREATE TABLE `item_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -3309,11 +3309,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `mail_loot_template`; DROP TABLE IF EXISTS `mail_loot_template`;
CREATE TABLE `mail_loot_template` ( CREATE TABLE `mail_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -4227,11 +4227,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `milling_loot_template`; DROP TABLE IF EXISTS `milling_loot_template`;
CREATE TABLE `milling_loot_template` ( CREATE TABLE `milling_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -4824,11 +4824,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `pickpocketing_loot_template`; DROP TABLE IF EXISTS `pickpocketing_loot_template`;
CREATE TABLE `pickpocketing_loot_template` ( CREATE TABLE `pickpocketing_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -20409,11 +20409,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `prospecting_loot_template`; DROP TABLE IF EXISTS `prospecting_loot_template`;
CREATE TABLE `prospecting_loot_template` ( CREATE TABLE `prospecting_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -20761,11 +20761,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `reference_loot_template`; DROP TABLE IF EXISTS `reference_loot_template`;
CREATE TABLE `reference_loot_template` ( CREATE TABLE `reference_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -20965,11 +20965,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `skinning_loot_template`; DROP TABLE IF EXISTS `skinning_loot_template`;
CREATE TABLE `skinning_loot_template` ( CREATE TABLE `skinning_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',
@ -23411,11 +23411,11 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `spell_loot_template`; DROP TABLE IF EXISTS `spell_loot_template`;
CREATE TABLE `spell_loot_template` ( CREATE TABLE `spell_loot_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',
`ChanceOrQuestChance` float NOT NULL default '100', `ChanceOrQuestChance` float NOT NULL default '100',
`groupid` tinyint(3) unsigned NOT NULL default '0', `groupid` tinyint(3) unsigned NOT NULL default '0',
`mincountOrRef` mediumint(9) NOT NULL default '1', `mincountOrRef` mediumint(9) NOT NULL default '1',
`maxcount` tinyint(3) unsigned NOT NULL default '1', `maxcount` smallint(5) unsigned NOT NULL default '1',
`lootcondition` tinyint(3) unsigned NOT NULL default '0', `lootcondition` tinyint(3) unsigned NOT NULL default '0',
`condition_value1` mediumint(8) unsigned NOT NULL default '0', `condition_value1` mediumint(8) unsigned NOT NULL default '0',
`condition_value2` mediumint(8) unsigned NOT NULL default '0', `condition_value2` mediumint(8) unsigned NOT NULL default '0',

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12195_02_mangos_mangos_string required_12216_01_mangos_creature_loot_template bit;
ALTER TABLE `creature_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `creature_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_01_mangos_creature_loot_template required_12216_02_mangos_disenchant_loot_template bit;
ALTER TABLE `disenchant_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `disenchant_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_02_mangos_disenchant_loot_template required_12216_03_mangos_fishing_loot_template bit;
ALTER TABLE `fishing_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `fishing_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_03_mangos_fishing_loot_template required_12216_04_mangos_gameobject_loot_template bit;
ALTER TABLE `gameobject_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `gameobject_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_04_mangos_gameobject_loot_template required_12216_05_mangos_item_loot_template bit;
ALTER TABLE `item_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `item_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_05_mangos_item_loot_template required_12216_06_mangos_mail_loot_template bit;
ALTER TABLE `mail_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `mail_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_06_mangos_mail_loot_template required_12216_07_mangos_milling_loot_template bit;
ALTER TABLE `milling_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `milling_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_07_mangos_milling_loot_template required_12216_08_mangos_pickpocketing_loot_template bit;
ALTER TABLE `pickpocketing_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `pickpocketing_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_08_mangos_pickpocketing_loot_template required_12216_09_mangos_prospecting_loot_template bit;
ALTER TABLE `prospecting_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `prospecting_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_09_mangos_prospecting_loot_template required_12216_10_mangos_reference_loot_template bit;
ALTER TABLE `reference_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `reference_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_10_mangos_reference_loot_template required_12216_11_mangos_skinning_loot_template bit;
ALTER TABLE `skinning_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `skinning_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_12216_11_mangos_skinning_loot_template required_12216_12_mangos_spell_loot_template bit;
ALTER TABLE `spell_loot_template` MODIFY COLUMN `item` mediumint(8) NOT NULL DEFAULT '0';
ALTER TABLE `spell_loot_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '1';

View file

@ -380,6 +380,11 @@ enum AbilitySkillFlags
#define CURRENCY_PRECISION 100.0f #define CURRENCY_PRECISION 100.0f
enum CurrencyCategory
{
CURRENCY_CATEGORY_ARCHAEOLOGY = 82,
};
enum CurrencyFlags enum CurrencyFlags
{ {
CURRENCY_FLAG_HAS_PRECISION = 0x08, CURRENCY_FLAG_HAS_PRECISION = 0x08,

View file

@ -817,7 +817,7 @@ struct CreatureTypeEntry
struct CurrencyTypesEntry struct CurrencyTypesEntry
{ {
uint32 ID; // 0 uint32 ID; // 0
//uint32 Category; // 1 uint32 Category; // 1
DBCString name; // 2 DBCString name; // 2
//char* iconName; // 3 //char* iconName; // 3
//char* iconName2; // 4 //char* iconName2; // 4

View file

@ -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[]="nxsxxxxiiix"; const char CurrencyTypesfmt[]="nisxxxxiiix";
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
const char DurabilityQualityfmt[]="nf"; const char DurabilityQualityfmt[]="nf";
const char EmotesEntryfmt[]="nxxiiixx"; const char EmotesEntryfmt[]="nxxiiixx";

View file

@ -500,6 +500,7 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r)
size_t voteMaskPos = data.wpos(); size_t voteMaskPos = data.wpos();
data << uint8(0); // roll type mask, allowed choices (placeholder) data << uint8(0); // roll type mask, allowed choices (placeholder)
data << uint8(r.totalPlayersRolling);
for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr) for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
{ {
@ -518,7 +519,7 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r)
} }
} }
void Group::SendLootRoll(ObjectGuid const& targetGuid, uint8 rollNumber, uint8 rollType, const Roll& r) void Group::SendLootRoll(ObjectGuid const& targetGuid, uint32 rollNumber, uint8 rollType, const Roll& r)
{ {
WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1)); WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1));
data << r.lootedTargetGUID; // creature guid what we're looting data << r.lootedTargetGUID; // creature guid what we're looting
@ -527,7 +528,7 @@ void Group::SendLootRoll(ObjectGuid const& targetGuid, uint8 rollNumber, uint8 r
data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
data << uint32(r.itemRandomSuffix); // randomSuffix data << uint32(r.itemRandomSuffix); // randomSuffix
data << uint32(r.itemRandomPropId); // Item random property ID data << uint32(r.itemRandomPropId); // Item random property ID
data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number data << uint32(rollNumber); // 0: "Need for: [item name]", -1: "you passed on: [item name]" Roll number
data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
data << uint8(0); // auto pass on loot data << uint8(0); // auto pass on loot
@ -542,7 +543,7 @@ void Group::SendLootRoll(ObjectGuid const& targetGuid, uint8 rollNumber, uint8 r
} }
} }
void Group::SendLootRollWon(ObjectGuid const& targetGuid, uint8 rollNumber, RollVote rollType, const Roll& r) void Group::SendLootRollWon(ObjectGuid const& targetGuid, uint32 rollNumber, RollVote rollType, const Roll& r)
{ {
WorldPacket data(SMSG_LOOT_ROLL_WON, (8 + 4 + 4 + 4 + 4 + 8 + 1 + 1)); WorldPacket data(SMSG_LOOT_ROLL_WON, (8 + 4 + 4 + 4 + 4 + 8 + 1 + 1));
data << r.lootedTargetGUID; // creature guid what we're looting data << r.lootedTargetGUID; // creature guid what we're looting
@ -551,7 +552,7 @@ void Group::SendLootRollWon(ObjectGuid const& targetGuid, uint8 rollNumber, Roll
data << uint32(r.itemRandomSuffix); // randomSuffix data << uint32(r.itemRandomSuffix); // randomSuffix
data << uint32(r.itemRandomPropId); // Item random property data << uint32(r.itemRandomPropId); // Item random property
data << targetGuid; // guid of the player who won. data << targetGuid; // guid of the player who won.
data << uint8(rollNumber); // rollnumber related to SMSG_LOOT_ROLL data << uint32(rollNumber); // rollnumber related to SMSG_LOOT_ROLL
data << uint8(rollType); // Rolltype related to SMSG_LOOT_ROLL data << uint8(rollType); // Rolltype related to SMSG_LOOT_ROLL
for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr) for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
@ -592,6 +593,9 @@ void Group::GroupLoot(WorldObject* pSource, Loot* loot)
for (uint8 itemSlot = 0; itemSlot < loot->items.size(); ++itemSlot) for (uint8 itemSlot = 0; itemSlot < loot->items.size(); ++itemSlot)
{ {
LootItem& lootItem = loot->items[itemSlot]; LootItem& lootItem = loot->items[itemSlot];
if (lootItem.currency)
continue;
ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(lootItem.itemid); ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(lootItem.itemid);
if (!itemProto) if (!itemProto)
{ {
@ -614,6 +618,9 @@ void Group::NeedBeforeGreed(WorldObject* pSource, Loot* loot)
for (uint8 itemSlot = 0; itemSlot < loot->items.size(); ++itemSlot) for (uint8 itemSlot = 0; itemSlot < loot->items.size(); ++itemSlot)
{ {
LootItem& lootItem = loot->items[itemSlot]; LootItem& lootItem = loot->items[itemSlot];
if (lootItem.currency)
continue;
ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(lootItem.itemid); ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(lootItem.itemid);
if (!itemProto) if (!itemProto)
{ {
@ -633,6 +640,9 @@ void Group::MasterLoot(WorldObject* pSource, Loot* loot)
{ {
for (LootItemList::iterator i = loot->items.begin(); i != loot->items.end(); ++i) for (LootItemList::iterator i = loot->items.begin(); i != loot->items.end(); ++i)
{ {
if (i->currency)
continue;
ItemPrototype const* item = ObjectMgr::GetItemPrototype(i->itemid); ItemPrototype const* item = ObjectMgr::GetItemPrototype(i->itemid);
if (!item) if (!item)
continue; continue;
@ -704,7 +714,7 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI,
{ {
case ROLL_PASS: // Player choose pass case ROLL_PASS: // Player choose pass
{ {
SendLootRoll(playerGUID, 128, 128, *roll); SendLootRoll(playerGUID, uint32(-1), ROLL_PASS, *roll);
++roll->totalPass; ++roll->totalPass;
itr->second = ROLL_PASS; itr->second = ROLL_PASS;
break; break;
@ -718,14 +728,14 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI,
} }
case ROLL_GREED: // player choose Greed case ROLL_GREED: // player choose Greed
{ {
SendLootRoll(playerGUID, 128, ROLL_GREED, *roll); SendLootRoll(playerGUID, uint32(-1), ROLL_GREED, *roll);
++roll->totalGreed; ++roll->totalGreed;
itr->second = ROLL_GREED; itr->second = ROLL_GREED;
break; break;
} }
case ROLL_DISENCHANT: // player choose Disenchant case ROLL_DISENCHANT: // player choose Disenchant
{ {
SendLootRoll(playerGUID, 128, ROLL_DISENCHANT, *roll); SendLootRoll(playerGUID, uint32(-1), ROLL_DISENCHANT, *roll);
++roll->totalGreed; ++roll->totalGreed;
itr->second = ROLL_DISENCHANT; itr->second = ROLL_DISENCHANT;
break; break;
@ -749,6 +759,8 @@ void Group::StartLootRoll(WorldObject* lootTarget, LootMethod method, Loot* loot
return; return;
LootItem const& lootItem = loot->items[itemSlot]; LootItem const& lootItem = loot->items[itemSlot];
if (lootItem.currency)
return;
Roll* r = new Roll(lootTarget->GetObjectGuid(), method, lootItem); Roll* r = new Roll(lootTarget->GetObjectGuid(), method, lootItem);
@ -821,7 +833,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
{ {
if (!roll->playerVote.empty()) if (!roll->playerVote.empty())
{ {
uint8 maxresul = 0; uint32 maxresul = 0;
ObjectGuid maxguid = (*roll->playerVote.begin()).first; ObjectGuid maxguid = (*roll->playerVote.begin()).first;
Player* player; Player* player;
@ -830,7 +842,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
if (itr->second != ROLL_NEED) if (itr->second != ROLL_NEED)
continue; continue;
uint8 randomN = urand(1, 100); uint32 randomN = urand(1, 100);
SendLootRoll(itr->first, randomN, ROLL_NEED, *roll); SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
if (maxresul < randomN) if (maxresul < randomN)
{ {
@ -870,7 +882,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
{ {
if (!roll->playerVote.empty()) if (!roll->playerVote.empty())
{ {
uint8 maxresul = 0; uint32 maxresul = 0;
ObjectGuid maxguid = (*roll->playerVote.begin()).first; ObjectGuid maxguid = (*roll->playerVote.begin()).first;
Player* player; Player* player;
RollVote rollvote = ROLL_PASS; // Fixed: Using uninitialized memory 'rollvote' RollVote rollvote = ROLL_PASS; // Fixed: Using uninitialized memory 'rollvote'
@ -881,7 +893,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
if (itr->second != ROLL_GREED && itr->second != ROLL_DISENCHANT) if (itr->second != ROLL_GREED && itr->second != ROLL_DISENCHANT)
continue; continue;
uint8 randomN = urand(1, 100); uint32 randomN = urand(1, 100);
SendLootRoll(itr->first, randomN, itr->second, *roll); SendLootRoll(itr->first, randomN, itr->second, *roll);
if (maxresul < randomN) if (maxresul < randomN)
{ {

View file

@ -369,8 +369,8 @@ class MANGOS_DLL_SPEC Group
/*********************************************************/ /*********************************************************/
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r); void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r);
void SendLootRoll(ObjectGuid const& targetGuid, uint8 rollNumber, uint8 rollType, const Roll& r); void SendLootRoll(ObjectGuid const& targetGuid, uint32 rollNumber, uint8 rollType, const Roll& r);
void SendLootRollWon(ObjectGuid const& targetGuid, uint8 rollNumber, RollVote rollType, const Roll& r); void SendLootRollWon(ObjectGuid const& targetGuid, uint32 rollNumber, RollVote rollType, const Roll& r);
void SendLootAllPassed(const Roll& r); void SendLootAllPassed(const Roll& r);
void GroupLoot(WorldObject* pSource, Loot* loot); void GroupLoot(WorldObject* pSource, Loot* loot);
void NeedBeforeGreed(WorldObject* pSource, Loot* loot); void NeedBeforeGreed(WorldObject* pSource, Loot* loot);

View file

@ -648,7 +648,8 @@ bool Item::LoadFromDB(uint32 guidLow, Field* fields, ObjectGuid ownerGuid)
void Item::LoadLootFromDB(Field* fields) void Item::LoadLootFromDB(Field* fields)
{ {
uint32 item_id = fields[1].GetUInt32(); uint32 item_id = abs(fields[1].GetInt32());
uint8 type = fields[1].GetInt32() > 0 ? LOOT_ITEM_TYPE_ITEM : LOOT_ITEM_TYPE_CURRENCY;
uint32 item_amount = fields[2].GetUInt32(); uint32 item_amount = fields[2].GetUInt32();
uint32 item_suffix = fields[3].GetUInt32(); uint32 item_suffix = fields[3].GetUInt32();
int32 item_propid = fields[4].GetInt32(); int32 item_propid = fields[4].GetInt32();
@ -662,16 +663,32 @@ void Item::LoadLootFromDB(Field* fields)
} }
// normal item case // normal item case
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item_id); if (type == LOOT_ITEM_TYPE_ITEM)
if (!proto)
{ {
CharacterDatabase.PExecute("DELETE FROM item_loot WHERE guid = '%u' AND itemid = '%u'", GetGUIDLow(), item_id); ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item_id);
sLog.outError("Item::LoadLootFromDB: %s has an unknown item (id: #%u) in item_loot, deleted.", GetOwnerGuid().GetString().c_str(), item_id); if (!proto)
return; {
CharacterDatabase.PExecute("DELETE FROM item_loot WHERE guid = '%u' AND itemid = '%u'", GetGUIDLow(), item_id);
sLog.outError("Item::LoadLootFromDB: %s has an unknown item (id: #%u) in item_loot, deleted.", GetOwnerGuid().GetString().c_str(), item_id);
return;
}
loot.items.push_back(LootItem(item_id, type, item_amount, item_suffix, item_propid));
}
// currency case
else //if (type == LOOT_ITEM_TYPE_CURRENCY)
{
CurrencyTypesEntry const* currencyEntry = sCurrencyTypesStore.LookupEntry(item_id);
if (!currencyEntry)
{
CharacterDatabase.PExecute("DELETE FROM item_loot WHERE guid = '%u' AND itemid = '%i'", GetGUIDLow(), -int32(item_id));
sLog.outError("Item::LoadLootFromDB: %s has an unknown currency (id: #%u) in item_loot, deleted.", GetOwnerGuid().GetString().c_str(), item_id);
return;
}
loot.items.push_back(LootItem(item_id, type, item_amount));
} }
loot.items.push_back(LootItem(item_id, item_amount, item_suffix, item_propid));
++loot.unlootedCount; ++loot.unlootedCount;
SetLootState(ITEM_LOOT_UNCHANGED); SetLootState(ITEM_LOOT_UNCHANGED);

View file

@ -34,7 +34,7 @@
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data) void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
{ {
DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); DEBUG_LOG("WORLD: %s", LookupOpcodeName(recv_data.GetOpcode()));
Player* player = GetPlayer(); Player* player = GetPlayer();
ObjectGuid lguid = player->GetLootGuid(); ObjectGuid lguid = player->GetLootGuid();
Loot* loot; Loot* loot;
@ -109,8 +109,9 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
QuestItem* qitem = NULL; QuestItem* qitem = NULL;
QuestItem* ffaitem = NULL; QuestItem* ffaitem = NULL;
QuestItem* conditem = NULL; QuestItem* conditem = NULL;
QuestItem* currency = NULL;
LootItem* item = loot->LootItemInSlot(lootSlot, player, &qitem, &ffaitem, &conditem); LootItem* item = loot->LootItemInSlot(lootSlot, player, &qitem, &ffaitem, &conditem, &currency);
if (!item) if (!item)
{ {
@ -128,6 +129,17 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
if (pItem) if (pItem)
pItem->SetLootState(ITEM_LOOT_CHANGED); pItem->SetLootState(ITEM_LOOT_CHANGED);
if (currency)
{
if (CurrencyTypesEntry const * currencyEntry = sCurrencyTypesStore.LookupEntry(item->itemid))
player->ModifyCurrencyCount(item->itemid, int32(item->count * currencyEntry->GetPrecision()));
player->SendNotifyLootItemRemoved(lootSlot, true);
currency->is_looted = true;
--loot->unlootedCount;
return;
}
ItemPosCountVec dest; ItemPosCountVec dest;
InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item->itemid, item->count); InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item->itemid, item->count);
if (msg == EQUIP_ERR_OK) if (msg == EQUIP_ERR_OK)
@ -261,8 +273,6 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/)
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(money_per_player); data << uint32(money_per_player);
data << uint8(playersNear.size() > 1 ? 0 : 1); // 0 is "you share of loot..." data << uint8(playersNear.size() > 1 ? 0 : 1); // 0 is "you share of loot..."
data << uint32(0); // guild share
(*i)->GetSession()->SendPacket(&data); (*i)->GetSession()->SendPacket(&data);
} }
} }
@ -274,7 +284,6 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/)
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(pLoot->gold); data << uint32(pLoot->gold);
data << uint8(1); // 1 is "you loot..." data << uint8(1); // 1 is "you loot..."
data << uint32(0); // guild share
player->GetSession()->SendPacket(&data); player->GetSession()->SendPacket(&data);
} }
@ -555,11 +564,16 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recv_data)
if (slotid > pLoot->items.size()) if (slotid > pLoot->items.size())
{ {
DEBUG_LOG("AutoLootItem: Player %s might be using a hack! (slot %d, size " SIZEFMTD ")", GetPlayer()->GetName(), slotid, pLoot->items.size()); DEBUG_LOG("WorldSession::HandleLootMasterGiveOpcode: Player %s might be using a hack! (slot %d, size " SIZEFMTD ")", GetPlayer()->GetName(), slotid, pLoot->items.size());
return; return;
} }
LootItem& item = pLoot->items[slotid]; LootItem& item = pLoot->items[slotid];
if (item.currency)
{
sLog.outError("WorldSession::HandleLootMasterGiveOpcode: player %s tried to give currency via master loot! Hack alert! Slot %u, currency id %u", GetPlayer()->GetName(), slotid, item.itemid);
return;
}
ItemPosCountVec dest; ItemPosCountVec dest;
InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count); InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);

View file

@ -113,16 +113,17 @@ void LootStore::LoadLootTable()
bar.step(); bar.step();
uint32 entry = fields[0].GetUInt32(); uint32 entry = fields[0].GetUInt32();
uint32 item = fields[1].GetUInt32(); uint32 item = abs(fields[1].GetInt32());
uint8 type = fields[1].GetInt32() > 0 ? LOOT_ITEM_TYPE_ITEM : LOOT_ITEM_TYPE_CURRENCY;
float chanceOrQuestChance = fields[2].GetFloat(); float chanceOrQuestChance = fields[2].GetFloat();
uint8 group = fields[3].GetUInt8(); uint8 group = fields[3].GetUInt8();
int32 mincountOrRef = fields[4].GetInt32(); int32 mincountOrRef = fields[4].GetInt32();
uint32 maxcount = fields[5].GetUInt32(); uint32 maxcount = fields[5].GetUInt32();
uint16 conditionId = fields[6].GetUInt16(); uint16 conditionId = fields[6].GetUInt16();
if (maxcount > std::numeric_limits<uint8>::max()) if (type == LOOT_ITEM_TYPE_ITEM && maxcount > std::numeric_limits<uint8>::max())
{ {
sLog.outErrorDb("Table '%s' entry %d item %d: maxcount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount, std::numeric_limits<uint8>::max()); sLog.outErrorDb("Table '%s' entry %d item %d: maxcount value (%u) too large. must be less than %u - skipped", GetName(), entry, item, maxcount, std::numeric_limits<uint8>::max());
continue; // error already printed to log/console. continue; // error already printed to log/console.
} }
@ -142,7 +143,7 @@ void LootStore::LoadLootTable()
} }
} }
LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount); LootStoreItem storeitem = LootStoreItem(item, type, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount);
if (!storeitem.IsValid(*this, entry)) // Validity checks if (!storeitem.IsValid(*this, entry)) // Validity checks
continue; continue;
@ -253,11 +254,18 @@ bool LootStoreItem::Roll(bool rate) const
if (mincountOrRef < 0) // reference case if (mincountOrRef < 0) // reference case
return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED) : 1.0f)); return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED) : 1.0f));
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid); if (type == LOOT_ITEM_TYPE_ITEM)
{
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);
float qualityModifier = pProto && rate ? sWorld.getConfig(qualityToRate[pProto->Quality]) : 1.0f; float qualityModifier = pProto && rate ? sWorld.getConfig(qualityToRate[pProto->Quality]) : 1.0f;
return roll_chance_f(chance * qualityModifier); return roll_chance_f(chance * qualityModifier);
}
else if (type == LOOT_ITEM_TYPE_CURRENCY)
return roll_chance_f(chance * (rate ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_CURRENCY) : 1.0f));
return false;
} }
// Checks correctness of values // Checks correctness of values
@ -269,6 +277,12 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
return false; return false;
} }
if (group && type == LOOT_ITEM_TYPE_CURRENCY)
{
sLog.outErrorDb("Table '%s' entry %d currency %d: group is set, but currencies must not have group - skipped", store.GetName(), entry, itemid, group, 1 << 7);
return false;
}
if (mincountOrRef == 0) if (mincountOrRef == 0)
{ {
sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef); sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef);
@ -277,10 +291,27 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
if (mincountOrRef > 0) // item (quest or non-quest) entry, maybe grouped if (mincountOrRef > 0) // item (quest or non-quest) entry, maybe grouped
{ {
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid); if (type == LOOT_ITEM_TYPE_ITEM)
if (!proto)
{ {
sLog.outErrorDb("Table '%s' entry %d item %d: item entry not listed in `item_template` - skipped", store.GetName(), entry, itemid); ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
if (!proto)
{
sLog.outErrorDb("Table '%s' entry %d item %d: item entry not listed in `item_template` - skipped", store.GetName(), entry, itemid);
return false;
}
}
else if (type == LOOT_ITEM_TYPE_CURRENCY)
{
CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(itemid);
if (!currency)
{
sLog.outErrorDb("Table '%s' entry %d: currency entry %u not exists - skipped", store.GetName(), entry, itemid);
return false;
}
}
else
{
sLog.outErrorDb("Table '%s' entry %d: has unknown item %u with type %u - skipped", store.GetName(), entry, itemid, type);
return false; return false;
} }
@ -301,7 +332,6 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, uint32(maxcount), mincountOrRef); sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, uint32(maxcount), mincountOrRef);
return false; return false;
} }
} }
else // mincountOrRef < 0 else // mincountOrRef < 0
{ {
@ -327,32 +357,39 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
LootItem::LootItem(LootStoreItem const& li) LootItem::LootItem(LootStoreItem const& li)
{ {
itemid = li.itemid; itemid = li.itemid;
type = li.type;
conditionId = li.conditionId; conditionId = li.conditionId;
currency = type == LOOT_ITEM_TYPE_CURRENCY;
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
freeforall = proto && (proto->Flags & ITEM_FLAG_PARTY_LOOT);
needs_quest = li.needs_quest;
count = urand(li.mincountOrRef, li.maxcount); // constructor called for mincountOrRef > 0 only count = urand(li.mincountOrRef, li.maxcount); // constructor called for mincountOrRef > 0 only
randomSuffix = GenerateEnchSuffixFactor(itemid);
randomPropertyId = Item::GenerateItemRandomPropertyId(itemid);
is_looted = 0; is_looted = 0;
is_blocked = 0; is_blocked = 0;
is_underthreshold = 0; is_underthreshold = 0;
is_counted = 0; is_counted = 0;
if (currency)
{
freeforall = false;
needs_quest = false;
randomSuffix = 0;
randomPropertyId = 0;
count = uint32(count * sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_CURRENCY_AMOUNT));
}
else
{
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
freeforall = proto && (proto->Flags & ITEM_FLAG_PARTY_LOOT);
needs_quest = li.needs_quest;
randomSuffix = GenerateEnchSuffixFactor(itemid);
randomPropertyId = Item::GenerateItemRandomPropertyId(itemid);
}
} }
LootItem::LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_, int32 randomPropertyId_) LootItem::LootItem(uint32 itemid_, uint8 type_, uint32 count_, uint32 randomSuffix_, int32 randomPropertyId_)
{ {
itemid = itemid_; itemid = itemid_;
type = type_;
conditionId = 0; conditionId = 0;
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
freeforall = proto && (proto->Flags & ITEM_FLAG_PARTY_LOOT);
needs_quest = false;
count = count_; count = count_;
randomSuffix = randomSuffix_; randomSuffix = randomSuffix_;
randomPropertyId = randomPropertyId_; randomPropertyId = randomPropertyId_;
@ -360,6 +397,16 @@ LootItem::LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_, int32 ra
is_blocked = 0; is_blocked = 0;
is_underthreshold = 0; is_underthreshold = 0;
is_counted = 0; is_counted = 0;
currency = type == LOOT_ITEM_TYPE_CURRENCY;
needs_quest = false;
if (currency)
freeforall = false;
else
{
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
freeforall = proto && (proto->Flags & ITEM_FLAG_PARTY_LOOT);
}
} }
// Basic checks for player/item compatibility - if false no chance to see the item in the loot // Basic checks for player/item compatibility - if false no chance to see the item in the loot
@ -369,28 +416,46 @@ bool LootItem::AllowedForPlayer(Player const* player) const
if (conditionId && !sObjectMgr.IsPlayerMeetToNEWCondition(player, conditionId)) if (conditionId && !sObjectMgr.IsPlayerMeetToNEWCondition(player, conditionId))
return false; return false;
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid); if (type == LOOT_ITEM_TYPE_ITEM)
if (!pProto)
return false;
// not show loot for not own team
if ((pProto->Flags2 & ITEM_FLAG2_HORDE_ONLY) && player->GetTeam() != HORDE)
return false;
if ((pProto->Flags2 & ITEM_FLAG2_ALLIANCE_ONLY) && player->GetTeam() != ALLIANCE)
return false;
if (needs_quest)
{ {
// Checking quests for quest-only drop (check only quests requirements in this case) ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);
if (!player->HasQuestForItem(itemid)) if (!pProto)
return false; return false;
// not show loot for not own team
if ((pProto->Flags2 & ITEM_FLAG2_HORDE_ONLY) && player->GetTeam() != HORDE)
return false;
if ((pProto->Flags2 & ITEM_FLAG2_ALLIANCE_ONLY) && player->GetTeam() != ALLIANCE)
return false;
if (needs_quest)
{
// Checking quests for quest-only drop (check only quests requirements in this case)
if (!player->HasQuestForItem(itemid))
return false;
}
else
{
// Not quest only drop (check quest starting items for already accepted non-repeatable quests)
if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid))
return false;
}
} }
else else if (type == LOOT_ITEM_TYPE_CURRENCY)
{ {
// Not quest only drop (check quest starting items for already accepted non-repeatable quests) CurrencyTypesEntry const * currency = sCurrencyTypesStore.LookupEntry(itemid);
if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid)) if (!itemid)
return false; return false;
if (!player->isGameMaster())
{
if (currency->ID == CURRENCY_CONQUEST_ARENA_META || currency->ID == CURRENCY_CONQUEST_BG_META)
return false;
if (currency->Category == CURRENCY_CATEGORY_ARCHAEOLOGY && !player->HasSkill(SKILL_ARCHAEOLOGY))
return false;
}
} }
return true; return true;
@ -398,8 +463,8 @@ bool LootItem::AllowedForPlayer(Player const* player) const
LootSlotType LootItem::GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, bool condition_ok /*= false*/) const LootSlotType LootItem::GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, bool condition_ok /*= false*/) const
{ {
// ignore looted, FFA (each player get own copy) and not allowed items // ignore currencies, looted items, FFA (each player get own copy) and not allowed items
if (is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer)) if (currency || is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer))
return MAX_LOOT_SLOT_TYPE; return MAX_LOOT_SLOT_TYPE;
switch (permission) switch (permission)
@ -434,9 +499,10 @@ void Loot::AddItem(LootStoreItem const& item)
items.push_back(LootItem(item)); items.push_back(LootItem(item));
// non-conditional one-player only items are counted here, // non-conditional one-player only items are counted here,
// currencies are counter in FillCurrencyLoot,
// free for all items are counted in FillFFALoot(), // free for all items are counted in FillFFALoot(),
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() // non-ffa conditionals are counted in FillNonQuestNonFFANonCurrencyConditionalLoot()
if (!item.conditionId) if (!item.conditionId && item.type == LOOT_ITEM_TYPE_ITEM)
{ {
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item.itemid); ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item.itemid);
if (!proto || !(proto->Flags & ITEM_FLAG_PARTY_LOOT)) if (!proto || !(proto->Flags & ITEM_FLAG_PARTY_LOOT))
@ -485,7 +551,11 @@ void Loot::FillNotNormalLootFor(Player* pl)
{ {
uint32 plguid = pl->GetGUIDLow(); uint32 plguid = pl->GetGUIDLow();
QuestItemMap::const_iterator qmapitr = m_playerQuestItems.find(plguid); QuestItemMap::const_iterator qmapitr = m_playerCurrencies.find(plguid);
if (qmapitr == m_playerCurrencies.end())
FillCurrencyLoot(pl);
qmapitr = m_playerQuestItems.find(plguid);
if (qmapitr == m_playerQuestItems.end()) if (qmapitr == m_playerQuestItems.end())
FillQuestLoot(pl); FillQuestLoot(pl);
@ -493,9 +563,32 @@ void Loot::FillNotNormalLootFor(Player* pl)
if (qmapitr == m_playerFFAItems.end()) if (qmapitr == m_playerFFAItems.end())
FillFFALoot(pl); FillFFALoot(pl);
qmapitr = m_playerNonQuestNonFFAConditionalItems.find(plguid); qmapitr = m_playerNonQuestNonFFANonCurrencyConditionalItems.find(plguid);
if (qmapitr == m_playerNonQuestNonFFAConditionalItems.end()) if (qmapitr == m_playerNonQuestNonFFANonCurrencyConditionalItems.end())
FillNonQuestNonFFAConditionalLoot(pl); FillNonQuestNonFFANonCurrencyConditionalLoot(pl);
}
QuestItemList* Loot::FillCurrencyLoot(Player* player)
{
QuestItemList* ql = new QuestItemList();
for (uint8 i = 0; i < items.size(); ++i)
{
LootItem& item = items[i];
if (!item.is_looted && item.currency && item.AllowedForPlayer(player))
{
ql->push_back(QuestItem(i));
++unlootedCount;
}
}
if (ql->empty())
{
delete ql;
return NULL;
}
m_playerCurrencies[player->GetGUIDLow()] = ql;
return ql;
} }
QuestItemList* Loot::FillFFALoot(Player* player) QuestItemList* Loot::FillFFALoot(Player* player)
@ -556,14 +649,14 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
return ql; return ql;
} }
QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player) QuestItemList* Loot::FillNonQuestNonFFANonCurrencyConditionalLoot(Player* player)
{ {
QuestItemList* ql = new QuestItemList(); QuestItemList* ql = new QuestItemList();
for (uint8 i = 0; i < items.size(); ++i) for (uint8 i = 0; i < items.size(); ++i)
{ {
LootItem& item = items[i]; LootItem& item = items[i];
if (!item.is_looted && !item.freeforall && item.conditionId && item.AllowedForPlayer(player)) if (!item.is_looted && !item.freeforall && !item.currency && item.conditionId && item.AllowedForPlayer(player))
{ {
ql->push_back(QuestItem(i)); ql->push_back(QuestItem(i));
if (!item.is_counted) if (!item.is_counted)
@ -579,7 +672,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
return NULL; return NULL;
} }
m_playerNonQuestNonFFAConditionalItems[player->GetGUIDLow()] = ql; m_playerNonQuestNonFFANonCurrencyConditionalItems[player->GetGUIDLow()] = ql;
return ql; return ql;
} }
@ -663,7 +756,7 @@ void Loot::generateMoneyLoot(uint32 minAmount, uint32 maxAmount)
} }
} }
LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem** qitem, QuestItem** ffaitem, QuestItem** conditem) LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem** qitem, QuestItem** ffaitem, QuestItem** conditem, QuestItem** currency)
{ {
LootItem* item = NULL; LootItem* item = NULL;
bool is_looted = true; bool is_looted = true;
@ -684,7 +777,25 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem** qite
{ {
item = &items[lootSlot]; item = &items[lootSlot];
is_looted = item->is_looted; is_looted = item->is_looted;
if (item->freeforall) if (item->currency)
{
QuestItemMap::const_iterator itr = m_playerCurrencies.find(player->GetGUIDLow());
if (itr != m_playerCurrencies.end())
{
for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
{
if (iter->index == lootSlot)
{
QuestItem* currency2 = (QuestItem*) & (*iter);
if (currency)
*currency = currency2;
is_looted = currency2->is_looted;
break;
}
}
}
}
else if (item->freeforall)
{ {
QuestItemMap::const_iterator itr = m_playerFFAItems.find(player->GetGUIDLow()); QuestItemMap::const_iterator itr = m_playerFFAItems.find(player->GetGUIDLow());
if (itr != m_playerFFAItems.end()) if (itr != m_playerFFAItems.end())
@ -702,8 +813,8 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem** qite
} }
else if (item->conditionId) else if (item->conditionId)
{ {
QuestItemMap::const_iterator itr = m_playerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow()); QuestItemMap::const_iterator itr = m_playerNonQuestNonFFANonCurrencyConditionalItems.find(player->GetGUIDLow());
if (itr != m_playerNonQuestNonFFAConditionalItems.end()) if (itr != m_playerNonQuestNonFFANonCurrencyConditionalItems.end())
{ {
for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter) for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
{ {
@ -734,11 +845,19 @@ uint32 Loot::GetMaxSlotInLootFor(Player* player) const
ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li) ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li)
{ {
b << uint32(li.itemid); if (li.type == LOOT_ITEM_TYPE_ITEM)
b << uint32(li.count); // nr of items of this type {
b << uint32(ObjectMgr::GetItemPrototype(li.itemid)->DisplayInfoID); b << uint32(li.itemid);
b << uint32(li.randomSuffix); b << uint32(li.count); // nr of items of this type
b << uint32(li.randomPropertyId); b << uint32(ObjectMgr::GetItemPrototype(li.itemid)->DisplayInfoID);
b << uint32(li.randomSuffix);
b << uint32(li.randomPropertyId);
}
else if (li.type == LOOT_ITEM_TYPE_CURRENCY)
{
b << uint32(li.itemid);
b << uint32(li.count);
}
// b << uint8(0); // slot type - will send after this function call // b << uint8(0); // slot type - will send after this function call
return b; return b;
} }
@ -765,10 +884,6 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
size_t currency_count_pos = b.wpos(); // pos of currency count byte size_t currency_count_pos = b.wpos(); // pos of currency count byte
b << uint8(0); // currency count placeholder b << uint8(0); // currency count placeholder
if (lv.permission == NONE_PERMISSION)
return b;
for (uint8 i = 0; i < l.items.size(); ++i) for (uint8 i = 0; i < l.items.size(); ++i)
{ {
LootSlotType slot_type = l.items[i].GetSlotTypeForSharedLoot(lv.permission, lv.viewer); LootSlotType slot_type = l.items[i].GetSlotTypeForSharedLoot(lv.permission, lv.viewer);
@ -780,7 +895,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
++itemsShown; ++itemsShown;
} }
QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems(); QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFANonCurrencyConditionalItems();
QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow()); QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow());
if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
{ {
@ -837,6 +952,22 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
} }
} }
QuestItemMap const& lootPlayerCurrencies = l.GetPlayerCurrencies();
QuestItemMap::const_iterator currency_itr = lootPlayerCurrencies.find(lv.viewer->GetGUIDLow());
if (currency_itr != lootPlayerCurrencies.end())
{
QuestItemList* currency_list = currency_itr->second;
for (QuestItemList::const_iterator ci = currency_list->begin() ; ci != currency_list->end(); ++ci)
{
LootItem& item = l.items[ci->index];
if (!ci->is_looted && !item.is_looted)
{
b << uint8(ci->index) << item;
++currenciesShown;
}
}
}
// update number of items and currencies shown // update number of items and currencies shown
b.put<uint8>(count_pos, itemsShown); b.put<uint8>(count_pos, itemsShown);
b.put<uint8>(currency_count_pos, currenciesShown); b.put<uint8>(currency_count_pos, currenciesShown);
@ -1009,7 +1140,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8
if (!i->Roll(rate)) if (!i->Roll(rate))
continue; // Bad luck for the entry continue; // Bad luck for the entry
if (i->mincountOrRef < 0) // References processing if (i->mincountOrRef < 0 && i->type == LOOT_ITEM_TYPE_ITEM) // References processing
{ {
LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-i->mincountOrRef); LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-i->mincountOrRef);

View file

@ -41,6 +41,12 @@ enum PermissionTypes
NONE_PERMISSION = 4 NONE_PERMISSION = 4
}; };
enum LootItemType
{
LOOT_ITEM_TYPE_ITEM = 0,
LOOT_ITEM_TYPE_CURRENCY = 1,
};
enum LootType enum LootType
{ {
LOOT_CORPSE = 1, LOOT_CORPSE = 1,
@ -75,17 +81,18 @@ class LootStore;
struct LootStoreItem struct LootStoreItem
{ {
uint32 itemid; // id of the item uint32 itemid; // id of the item
uint8 type; // 0 = item, 1 = currency
float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs
int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative) int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative)
uint32 maxcount; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
uint8 group : 7; uint8 group : 7;
bool needs_quest : 1; // quest drop (negative ChanceOrQuestChance in DB) bool needs_quest : 1; // quest drop (negative ChanceOrQuestChance in DB)
uint8 maxcount : 8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
uint16 conditionId : 16; // additional loot condition Id uint16 conditionId : 16; // additional loot condition Id
// Constructor, converting ChanceOrQuestChance -> (chance, needs_quest) // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
// displayid is filled in IsValid() which must be called after // displayid is filled in IsValid() which must be called after
LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint16 _conditionId, int32 _mincountOrRef, uint8 _maxcount) LootStoreItem(uint32 _itemid, uint8 _type, float _chanceOrQuestChance, int8 _group, uint16 _conditionId, int32 _mincountOrRef, uint32 _maxcount)
: itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), : itemid(_itemid), type(_type), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId) group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId)
{} {}
@ -97,10 +104,12 @@ struct LootStoreItem
struct LootItem struct LootItem
{ {
uint32 itemid; uint32 itemid;
uint8 type; // 0 = item, 1 = currency
uint32 randomSuffix; uint32 randomSuffix;
int32 randomPropertyId; int32 randomPropertyId;
uint32 count;
uint16 conditionId : 16; // allow compiler pack structure uint16 conditionId : 16; // allow compiler pack structure
uint8 count : 8; bool currency : 1;
bool is_looted : 1; bool is_looted : 1;
bool is_blocked : 1; bool is_blocked : 1;
bool freeforall : 1; // free for all bool freeforall : 1; // free for all
@ -112,7 +121,7 @@ struct LootItem
// Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0) // Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0)
explicit LootItem(LootStoreItem const& li); explicit LootItem(LootStoreItem const& li);
LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_ = 0, int32 randomPropertyId_ = 0); LootItem(uint32 itemid_, uint8 type_, uint32 count_, uint32 randomSuffix_ = 0, int32 randomPropertyId_ = 0);
// Basic checks for player/item compatibility - if false no chance to see the item in the loot // Basic checks for player/item compatibility - if false no chance to see the item in the loot
bool AllowedForPlayer(Player const* player) const; bool AllowedForPlayer(Player const* player) const;
@ -236,9 +245,10 @@ struct Loot
{ {
friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
QuestItemMap const& GetPlayerCurrencies() const { return m_playerCurrencies; }
QuestItemMap const& GetPlayerQuestItems() const { return m_playerQuestItems; } QuestItemMap const& GetPlayerQuestItems() const { return m_playerQuestItems; }
QuestItemMap const& GetPlayerFFAItems() const { return m_playerFFAItems; } QuestItemMap const& GetPlayerFFAItems() const { return m_playerFFAItems; }
QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return m_playerNonQuestNonFFAConditionalItems; } QuestItemMap const& GetPlayerNonQuestNonFFANonCurrencyConditionalItems() const { return m_playerNonQuestNonFFANonCurrencyConditionalItems; }
LootItemList items; LootItemList items;
uint32 gold; uint32 gold;
@ -257,6 +267,10 @@ struct Loot
// void clear(); // void clear();
void clear() void clear()
{ {
for (QuestItemMap::const_iterator itr = m_playerCurrencies.begin(); itr != m_playerCurrencies.end(); ++itr)
delete itr->second;
m_playerCurrencies.clear();
for (QuestItemMap::const_iterator itr = m_playerQuestItems.begin(); itr != m_playerQuestItems.end(); ++itr) for (QuestItemMap::const_iterator itr = m_playerQuestItems.begin(); itr != m_playerQuestItems.end(); ++itr)
delete itr->second; delete itr->second;
m_playerQuestItems.clear(); m_playerQuestItems.clear();
@ -265,9 +279,9 @@ struct Loot
delete itr->second; delete itr->second;
m_playerFFAItems.clear(); m_playerFFAItems.clear();
for (QuestItemMap::const_iterator itr = m_playerNonQuestNonFFAConditionalItems.begin(); itr != m_playerNonQuestNonFFAConditionalItems.end(); ++itr) for (QuestItemMap::const_iterator itr = m_playerNonQuestNonFFANonCurrencyConditionalItems.begin(); itr != m_playerNonQuestNonFFANonCurrencyConditionalItems.end(); ++itr)
delete itr->second; delete itr->second;
m_playerNonQuestNonFFAConditionalItems.clear(); m_playerNonQuestNonFFANonCurrencyConditionalItems.clear();
m_playersLooting.clear(); m_playersLooting.clear();
items.clear(); items.clear();
@ -292,22 +306,24 @@ struct Loot
// Inserts the item into the loot (called by LootTemplate processors) // Inserts the item into the loot (called by LootTemplate processors)
void AddItem(LootStoreItem const& item); void AddItem(LootStoreItem const& item);
LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL); LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL, QuestItem** currency = NULL);
uint32 GetMaxSlotInLootFor(Player* player) const; uint32 GetMaxSlotInLootFor(Player* player) const;
private: private:
void FillNotNormalLootFor(Player* player); void FillNotNormalLootFor(Player* player);
QuestItemList* FillCurrencyLoot(Player* player);
QuestItemList* FillFFALoot(Player* player); QuestItemList* FillFFALoot(Player* player);
QuestItemList* FillQuestLoot(Player* player); QuestItemList* FillQuestLoot(Player* player);
QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player); QuestItemList* FillNonQuestNonFFANonCurrencyConditionalLoot(Player* player);
LootItemList m_questItems; LootItemList m_questItems;
GuidSet m_playersLooting; GuidSet m_playersLooting;
QuestItemMap m_playerCurrencies;
QuestItemMap m_playerQuestItems; QuestItemMap m_playerQuestItems;
QuestItemMap m_playerFFAItems; QuestItemMap m_playerFFAItems;
QuestItemMap m_playerNonQuestNonFFAConditionalItems; QuestItemMap m_playerNonQuestNonFFANonCurrencyConditionalItems;
// All rolls are registered here. They need to know, when the loot is not valid anymore // All rolls are registered here. They need to know, when the loot is not valid anymore
LootValidatorRefManager m_LootValidatorRefManager; LootValidatorRefManager m_LootValidatorRefManager;

View file

@ -332,6 +332,7 @@ void InitializeOpcodes()
//OPCODE(CMSG_AUTOEQUIP_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_AUTOEQUIP_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_AUTOSTORE_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_AUTOSTORE_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
OPCODE(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode ); OPCODE(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode );
OPCODE(CMSG_LOOT_CURRENCY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode );
//OPCODE(CMSG_STORE_LOOT_IN_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_STORE_LOOT_IN_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
OPCODE(CMSG_AUTOEQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode ); OPCODE(CMSG_AUTOEQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode );
OPCODE(CMSG_AUTOSTORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode ); OPCODE(CMSG_AUTOSTORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode );
@ -422,6 +423,7 @@ void InitializeOpcodes()
OPCODE(SMSG_LOOT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_LOOT_RELEASE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_RELEASE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_LOOT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_LOOT_CURRENCY_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_LOOT_MONEY_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_MONEY_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_LOOT_ITEM_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_ITEM_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_LOOT_CLEAR_MONEY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_CLEAR_MONEY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -732,13 +734,13 @@ void InitializeOpcodes()
//OPCODE(CMSG_CANCEL_GROWTH_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode ); //OPCODE(CMSG_CANCEL_GROWTH_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode );
OPCODE(SMSG_CANCEL_AUTO_REPEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_CANCEL_AUTO_REPEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_STANDSTATE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_STANDSTATE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_LOOT_ALL_PASSED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_ALL_PASSED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_LOOT_ROLL_WON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_ROLL_WON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_LOOT_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootRoll ); OPCODE(CMSG_LOOT_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootRoll );
//OPCODE(SMSG_LOOT_START_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_START_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_LOOT_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_LOOT_MASTER_GIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode ); OPCODE(CMSG_LOOT_MASTER_GIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode );
//OPCODE(SMSG_LOOT_MASTER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_MASTER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_GAMEOBJECT_RESET_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_GAMEOBJECT_RESET_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -1078,7 +1080,7 @@ void InitializeOpcodes()
//OPCODE(SMSG_ECHO_PARTY_SQUELCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_ECHO_PARTY_SQUELCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_SET_TITLE_SUFFIX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_SET_TITLE_SUFFIX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
OPCODE(CMSG_SPELLCLICK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick ); OPCODE(CMSG_SPELLCLICK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick );
//OPCODE(SMSG_LOOT_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_LOOT_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_GM_CHARACTER_RESTORE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_GM_CHARACTER_RESTORE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_GM_CHARACTER_SAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_GM_CHARACTER_SAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_VOICESESSION_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_VOICESESSION_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -1094,7 +1096,7 @@ void InitializeOpcodes()
//OPCODE(SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess ); OPCODE(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
//OPCODE(SMSG_RAID_READY_CHECK_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_RAID_READY_CHECK_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_OPT_OUT_OF_LOOT, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode ); OPCODE(CMSG_OPT_OUT_OF_LOOT, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode );
//OPCODE(MSG_QUERY_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText ); //OPCODE(MSG_QUERY_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText );
OPCODE(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText ); OPCODE(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText );
//OPCODE(CMSG_SET_GRANTABLE_LEVELS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(CMSG_SET_GRANTABLE_LEVELS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );

View file

@ -402,11 +402,13 @@ enum Opcodes
SMSG_RESURRECT_REQUEST = 0x2905, // 4.3.4 15595 SMSG_RESURRECT_REQUEST = 0x2905, // 4.3.4 15595
CMSG_RESURRECT_RESPONSE = 0x6827, // 4.3.4 15595 CMSG_RESURRECT_RESPONSE = 0x6827, // 4.3.4 15595
CMSG_LOOT = 0x0127, // 4.3.4 15595 CMSG_LOOT = 0x0127, // 4.3.4 15595
CMSG_LOOT_CURRENCY = 0x781C, // 4.3.4 15595
CMSG_LOOT_MONEY = 0x6227, // 4.3.4 15595 CMSG_LOOT_MONEY = 0x6227, // 4.3.4 15595
CMSG_LOOT_RELEASE = 0x2007, // 4.3.4 15595 CMSG_LOOT_RELEASE = 0x2007, // 4.3.4 15595
SMSG_LOOT_RESPONSE = 0x4C16, // 4.3.4 15595 SMSG_LOOT_RESPONSE = 0x4C16, // 4.3.4 15595
SMSG_LOOT_RELEASE_RESPONSE = 0x6D25, // 4.3.4 15595 SMSG_LOOT_RELEASE_RESPONSE = 0x6D25, // 4.3.4 15595
SMSG_LOOT_REMOVED = 0x6817, // 4.3.4 15595 SMSG_LOOT_REMOVED = 0x6817, // 4.3.4 15595
SMSG_LOOT_CURRENCY_REMOVED = 0x1DB4, // 4.3.4 15595
SMSG_LOOT_MONEY_NOTIFY = 0x2836, // 4.3.4 15595 SMSG_LOOT_MONEY_NOTIFY = 0x2836, // 4.3.4 15595
SMSG_LOOT_ITEM_NOTIFY = 0x6D15, // 4.3.4 15595 SMSG_LOOT_ITEM_NOTIFY = 0x6D15, // 4.3.4 15595
SMSG_LOOT_CLEAR_MONEY = 0x2B37, // 4.3.4 15595 SMSG_LOOT_CLEAR_MONEY = 0x2B37, // 4.3.4 15595
@ -717,13 +719,13 @@ enum Opcodes
CMSG_CANCEL_GROWTH_AURA = 0x129C, CMSG_CANCEL_GROWTH_AURA = 0x129C,
SMSG_CANCEL_AUTO_REPEAT = 0x6436, // 4.3.4 15595 SMSG_CANCEL_AUTO_REPEAT = 0x6436, // 4.3.4 15595
SMSG_STANDSTATE_UPDATE = 0x6F04, // 4.3.4 15595 SMSG_STANDSTATE_UPDATE = 0x6F04, // 4.3.4 15595
SMSG_LOOT_ALL_PASSED = 0x129F, SMSG_LOOT_ALL_PASSED = 0x6237, // 4.3.4 15595
SMSG_LOOT_ROLL_WON = 0x12A0, SMSG_LOOT_ROLL_WON = 0x6617, // 4.3.4 15595
CMSG_LOOT_ROLL = 0x12A1, CMSG_LOOT_ROLL = 0x6934, // 4.3.4 15595
SMSG_LOOT_START_ROLL = 0x12A2, SMSG_LOOT_START_ROLL = 0x2227, // 4.3.4 15595
SMSG_LOOT_ROLL = 0x12A3, SMSG_LOOT_ROLL = 0x6507, // 4.3.4 15595
CMSG_LOOT_MASTER_GIVE = 0x12A4, CMSG_LOOT_MASTER_GIVE = 0x4F35, // 4.3.4 15595
SMSG_LOOT_MASTER_LIST = 0x12A5, SMSG_LOOT_MASTER_LIST = 0x0325, // 4.3.4 15595
SMSG_SET_FORCED_REACTIONS = 0x12A6, SMSG_SET_FORCED_REACTIONS = 0x12A6,
SMSG_SPELL_FAILED_OTHER = 0x4535, // 4.3.4 15595 SMSG_SPELL_FAILED_OTHER = 0x4535, // 4.3.4 15595
SMSG_GAMEOBJECT_RESET_STATE = 0x12A8, SMSG_GAMEOBJECT_RESET_STATE = 0x12A8,
@ -1063,7 +1065,7 @@ enum Opcodes
SMSG_ECHO_PARTY_SQUELCH = 0x13F7, SMSG_ECHO_PARTY_SQUELCH = 0x13F7,
CMSG_SET_TITLE_SUFFIX = 0x13F8, CMSG_SET_TITLE_SUFFIX = 0x13F8,
CMSG_SPELLCLICK = 0x0805, // 4.3.4 15595 CMSG_SPELLCLICK = 0x0805, // 4.3.4 15595
SMSG_LOOT_LIST = 0x13FA, SMSG_LOOT_LIST = 0x6807, // 4.3.4 15595
CMSG_GM_CHARACTER_RESTORE = 0x13FB, CMSG_GM_CHARACTER_RESTORE = 0x13FB,
CMSG_GM_CHARACTER_SAVE = 0x13FC, CMSG_GM_CHARACTER_SAVE = 0x13FC,
SMSG_VOICESESSION_FULL = 0x13FD, SMSG_VOICESESSION_FULL = 0x13FD,
@ -1079,7 +1081,7 @@ enum Opcodes
SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x1407, SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x1407,
CMSG_KEEP_ALIVE = 0x0015, // 4.3.4 15595 CMSG_KEEP_ALIVE = 0x0015, // 4.3.4 15595
SMSG_RAID_READY_CHECK_ERROR = 0x1409, SMSG_RAID_READY_CHECK_ERROR = 0x1409,
CMSG_OPT_OUT_OF_LOOT = 0x140A, CMSG_OPT_OUT_OF_LOOT = 0x6B16, // 4.3.4 15595
MSG_QUERY_GUILD_BANK_TEXT = 0x140B, MSG_QUERY_GUILD_BANK_TEXT = 0x140B,
CMSG_SET_GUILD_BANK_TEXT = 0x3023, // 4.3.4 15595 CMSG_SET_GUILD_BANK_TEXT = 0x3023, // 4.3.4 15595
CMSG_SET_GRANTABLE_LEVELS = 0x140D, CMSG_SET_GRANTABLE_LEVELS = 0x140D,

View file

@ -8318,9 +8318,9 @@ void Player::SendNotifyLootMoneyRemoved()
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }
void Player::SendNotifyLootItemRemoved(uint8 lootSlot) void Player::SendNotifyLootItemRemoved(uint8 lootSlot, bool currency)
{ {
WorldPacket data(SMSG_LOOT_REMOVED, 1); WorldPacket data(currency ? SMSG_LOOT_CURRENCY_REMOVED : SMSG_LOOT_REMOVED, 1);
data << uint8(lootSlot); data << uint8(lootSlot);
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }

View file

@ -2063,7 +2063,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SendLoot(ObjectGuid guid, LootType loot_type); void SendLoot(ObjectGuid guid, LootType loot_type);
void SendLootRelease(ObjectGuid guid); void SendLootRelease(ObjectGuid guid);
void SendNotifyLootItemRemoved(uint8 lootSlot); void SendNotifyLootItemRemoved(uint8 lootSlot, bool currency = false);
void SendNotifyLootMoneyRemoved(); void SendNotifyLootMoneyRemoved();
/*********************************************************/ /*********************************************************/

View file

@ -476,6 +476,8 @@ void World::LoadConfigSettings(bool reload)
setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT, "Rate.Drop.Item.Artifact", 1.0f); setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT, "Rate.Drop.Item.Artifact", 1.0f);
setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED, "Rate.Drop.Item.Referenced", 1.0f); setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED, "Rate.Drop.Item.Referenced", 1.0f);
setConfigPos(CONFIG_FLOAT_RATE_DROP_MONEY, "Rate.Drop.Money", 1.0f); setConfigPos(CONFIG_FLOAT_RATE_DROP_MONEY, "Rate.Drop.Money", 1.0f);
setConfigPos(CONFIG_FLOAT_RATE_DROP_CURRENCY, "Rate.Drop.Currency", 1.0f);
setConfigPos(CONFIG_FLOAT_RATE_DROP_CURRENCY_AMOUNT, "Rate.Drop.Currency.Amount", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_KILL, "Rate.XP.Kill", 1.0f); setConfig(CONFIG_FLOAT_RATE_XP_KILL, "Rate.XP.Kill", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_QUEST, "Rate.XP.Quest", 1.0f); setConfig(CONFIG_FLOAT_RATE_XP_QUEST, "Rate.XP.Quest", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_EXPLORE, "Rate.XP.Explore", 1.0f); setConfig(CONFIG_FLOAT_RATE_XP_EXPLORE, "Rate.XP.Explore", 1.0f);

View file

@ -224,6 +224,8 @@ enum eConfigFloatValues
CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT, CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT,
CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED, CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED,
CONFIG_FLOAT_RATE_DROP_MONEY, CONFIG_FLOAT_RATE_DROP_MONEY,
CONFIG_FLOAT_RATE_DROP_CURRENCY,
CONFIG_FLOAT_RATE_DROP_CURRENCY_AMOUNT,
CONFIG_FLOAT_RATE_XP_KILL, CONFIG_FLOAT_RATE_XP_KILL,
CONFIG_FLOAT_RATE_XP_QUEST, CONFIG_FLOAT_RATE_XP_QUEST,
CONFIG_FLOAT_RATE_XP_EXPLORE, CONFIG_FLOAT_RATE_XP_EXPLORE,

View file

@ -1215,7 +1215,12 @@ Visibility.AIRelocationNotifyDelay = 1000
# Rate.Drop.Item.Artifact # Rate.Drop.Item.Artifact
# Rate.Drop.Item.Referenced # Rate.Drop.Item.Referenced
# Rate.Drop.Money # Rate.Drop.Money
# Drop rates (items by quality and money) # Rate.Drop.Currency
# Drop rates (items by quality, money and currency drop chance)
# Default: 1
#
# Rate.Drop.Currency.Amount
# Drop rate for currency amount
# Default: 1 # Default: 1
# #
# Rate.XP.Kill # Rate.XP.Kill
@ -1361,8 +1366,10 @@ Rate.Drop.Item.Legendary = 1
Rate.Drop.Item.Artifact = 1 Rate.Drop.Item.Artifact = 1
Rate.Drop.Item.Referenced = 1 Rate.Drop.Item.Referenced = 1
Rate.Drop.Money = 1 Rate.Drop.Money = 1
Rate.XP.Kill = 1 Rate.Drop.Currency = 1
Rate.XP.Quest = 1 Rate.Drop.Currency.Amount = 1
Rate.XP.Kill = 1
Rate.XP.Quest = 1
Rate.XP.Explore = 1 Rate.XP.Explore = 1
Rate.Rest.InGame = 1 Rate.Rest.InGame = 1
Rate.Rest.Offline.InTavernOrCity = 1 Rate.Rest.Offline.InTavernOrCity = 1

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "12215" #define REVISION_NR "12216"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -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_12161_01_characters_characters" #define REVISION_DB_CHARACTERS "required_12161_01_characters_characters"
#define REVISION_DB_MANGOS "required_12195_02_mangos_mangos_string" #define REVISION_DB_MANGOS "required_12216_12_mangos_spell_loot_template"
#define REVISION_DB_REALMD "required_12112_01_realmd_account_access" #define REVISION_DB_REALMD "required_12112_01_realmd_account_access"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__