mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[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:
parent
f710cc3c24
commit
ef0f63e05b
31 changed files with 418 additions and 160 deletions
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`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';
|
||||
|
||||
--
|
||||
|
|
@ -1020,11 +1020,11 @@ UNLOCK TABLES;
|
|||
DROP TABLE IF EXISTS `creature_loot_template`;
|
||||
CREATE TABLE `creature_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `disenchant_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
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)',
|
||||
`item` mediumint(8) unsigned NOT NULL default '0',
|
||||
`item` mediumint(8) NOT NULL default '0',
|
||||
`ChanceOrQuestChance` float NOT NULL default '100',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `gameobject_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `item_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `mail_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `milling_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `pickpocketing_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `prospecting_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `reference_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `skinning_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` 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`;
|
||||
CREATE TABLE `spell_loot_template` (
|
||||
`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',
|
||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||
`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',
|
||||
`condition_value1` mediumint(8) unsigned NOT NULL default '0',
|
||||
`condition_value2` mediumint(8) unsigned NOT NULL default '0',
|
||||
|
|
|
|||
4
sql/updates/12216_01_mangos_creature_loot_template.sql
Normal file
4
sql/updates/12216_01_mangos_creature_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_02_mangos_disenchant_loot_template.sql
Normal file
4
sql/updates/12216_02_mangos_disenchant_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_03_mangos_fishing_loot_template.sql
Normal file
4
sql/updates/12216_03_mangos_fishing_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_04_mangos_gameobject_loot_template.sql
Normal file
4
sql/updates/12216_04_mangos_gameobject_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_05_mangos_item_loot_template.sql
Normal file
4
sql/updates/12216_05_mangos_item_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_06_mangos_mail_loot_template.sql
Normal file
4
sql/updates/12216_06_mangos_mail_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_07_mangos_milling_loot_template.sql
Normal file
4
sql/updates/12216_07_mangos_milling_loot_template.sql
Normal 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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
4
sql/updates/12216_10_mangos_reference_loot_template.sql
Normal file
4
sql/updates/12216_10_mangos_reference_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_11_mangos_skinning_loot_template.sql
Normal file
4
sql/updates/12216_11_mangos_skinning_loot_template.sql
Normal 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';
|
||||
4
sql/updates/12216_12_mangos_spell_loot_template.sql
Normal file
4
sql/updates/12216_12_mangos_spell_loot_template.sql
Normal 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';
|
||||
|
|
@ -380,6 +380,11 @@ enum AbilitySkillFlags
|
|||
|
||||
#define CURRENCY_PRECISION 100.0f
|
||||
|
||||
enum CurrencyCategory
|
||||
{
|
||||
CURRENCY_CATEGORY_ARCHAEOLOGY = 82,
|
||||
};
|
||||
|
||||
enum CurrencyFlags
|
||||
{
|
||||
CURRENCY_FLAG_HAS_PRECISION = 0x08,
|
||||
|
|
|
|||
|
|
@ -817,7 +817,7 @@ struct CreatureTypeEntry
|
|||
struct CurrencyTypesEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
//uint32 Category; // 1
|
||||
uint32 Category; // 1
|
||||
DBCString name; // 2
|
||||
//char* iconName; // 3
|
||||
//char* iconName2; // 4
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const char CreatureFamilyfmt[]="nfifiiiiixsx";
|
|||
const char CreatureSpellDatafmt[]="niiiixxxx";
|
||||
const char DungeonEncounterfmt[]="niiiisxx";
|
||||
const char CreatureTypefmt[]="nxx";
|
||||
const char CurrencyTypesfmt[]="nxsxxxxiiix";
|
||||
const char CurrencyTypesfmt[]="nisxxxxiiix";
|
||||
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
const char DurabilityQualityfmt[]="nf";
|
||||
const char EmotesEntryfmt[]="nxxiiixx";
|
||||
|
|
|
|||
|
|
@ -500,6 +500,7 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r)
|
|||
|
||||
size_t voteMaskPos = data.wpos();
|
||||
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)
|
||||
{
|
||||
|
|
@ -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));
|
||||
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.itemRandomSuffix); // randomSuffix
|
||||
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(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));
|
||||
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.itemRandomPropId); // Item random property
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
LootItem& lootItem = loot->items[itemSlot];
|
||||
if (lootItem.currency)
|
||||
continue;
|
||||
|
||||
ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(lootItem.itemid);
|
||||
if (!itemProto)
|
||||
{
|
||||
|
|
@ -614,6 +618,9 @@ void Group::NeedBeforeGreed(WorldObject* pSource, Loot* loot)
|
|||
for (uint8 itemSlot = 0; itemSlot < loot->items.size(); ++itemSlot)
|
||||
{
|
||||
LootItem& lootItem = loot->items[itemSlot];
|
||||
if (lootItem.currency)
|
||||
continue;
|
||||
|
||||
ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(lootItem.itemid);
|
||||
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)
|
||||
{
|
||||
if (i->currency)
|
||||
continue;
|
||||
|
||||
ItemPrototype const* item = ObjectMgr::GetItemPrototype(i->itemid);
|
||||
if (!item)
|
||||
continue;
|
||||
|
|
@ -704,7 +714,7 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI,
|
|||
{
|
||||
case ROLL_PASS: // Player choose pass
|
||||
{
|
||||
SendLootRoll(playerGUID, 128, 128, *roll);
|
||||
SendLootRoll(playerGUID, uint32(-1), ROLL_PASS, *roll);
|
||||
++roll->totalPass;
|
||||
itr->second = ROLL_PASS;
|
||||
break;
|
||||
|
|
@ -718,14 +728,14 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI,
|
|||
}
|
||||
case ROLL_GREED: // player choose Greed
|
||||
{
|
||||
SendLootRoll(playerGUID, 128, ROLL_GREED, *roll);
|
||||
SendLootRoll(playerGUID, uint32(-1), ROLL_GREED, *roll);
|
||||
++roll->totalGreed;
|
||||
itr->second = ROLL_GREED;
|
||||
break;
|
||||
}
|
||||
case ROLL_DISENCHANT: // player choose Disenchant
|
||||
{
|
||||
SendLootRoll(playerGUID, 128, ROLL_DISENCHANT, *roll);
|
||||
SendLootRoll(playerGUID, uint32(-1), ROLL_DISENCHANT, *roll);
|
||||
++roll->totalGreed;
|
||||
itr->second = ROLL_DISENCHANT;
|
||||
break;
|
||||
|
|
@ -749,6 +759,8 @@ void Group::StartLootRoll(WorldObject* lootTarget, LootMethod method, Loot* loot
|
|||
return;
|
||||
|
||||
LootItem const& lootItem = loot->items[itemSlot];
|
||||
if (lootItem.currency)
|
||||
return;
|
||||
|
||||
Roll* r = new Roll(lootTarget->GetObjectGuid(), method, lootItem);
|
||||
|
||||
|
|
@ -821,7 +833,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
|||
{
|
||||
if (!roll->playerVote.empty())
|
||||
{
|
||||
uint8 maxresul = 0;
|
||||
uint32 maxresul = 0;
|
||||
ObjectGuid maxguid = (*roll->playerVote.begin()).first;
|
||||
Player* player;
|
||||
|
||||
|
|
@ -830,7 +842,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
|||
if (itr->second != ROLL_NEED)
|
||||
continue;
|
||||
|
||||
uint8 randomN = urand(1, 100);
|
||||
uint32 randomN = urand(1, 100);
|
||||
SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
|
||||
if (maxresul < randomN)
|
||||
{
|
||||
|
|
@ -870,7 +882,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
|||
{
|
||||
if (!roll->playerVote.empty())
|
||||
{
|
||||
uint8 maxresul = 0;
|
||||
uint32 maxresul = 0;
|
||||
ObjectGuid maxguid = (*roll->playerVote.begin()).first;
|
||||
Player* player;
|
||||
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)
|
||||
continue;
|
||||
|
||||
uint8 randomN = urand(1, 100);
|
||||
uint32 randomN = urand(1, 100);
|
||||
SendLootRoll(itr->first, randomN, itr->second, *roll);
|
||||
if (maxresul < randomN)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -369,8 +369,8 @@ class MANGOS_DLL_SPEC Group
|
|||
/*********************************************************/
|
||||
|
||||
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r);
|
||||
void SendLootRoll(ObjectGuid const& targetGuid, uint8 rollNumber, uint8 rollType, const Roll& r);
|
||||
void SendLootRollWon(ObjectGuid const& targetGuid, uint8 rollNumber, RollVote rollType, const Roll& r);
|
||||
void SendLootRoll(ObjectGuid const& targetGuid, uint32 rollNumber, uint8 rollType, const Roll& r);
|
||||
void SendLootRollWon(ObjectGuid const& targetGuid, uint32 rollNumber, RollVote rollType, const Roll& r);
|
||||
void SendLootAllPassed(const Roll& r);
|
||||
void GroupLoot(WorldObject* pSource, Loot* loot);
|
||||
void NeedBeforeGreed(WorldObject* pSource, Loot* loot);
|
||||
|
|
|
|||
|
|
@ -648,7 +648,8 @@ bool Item::LoadFromDB(uint32 guidLow, Field* fields, ObjectGuid ownerGuid)
|
|||
|
||||
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_suffix = fields[3].GetUInt32();
|
||||
int32 item_propid = fields[4].GetInt32();
|
||||
|
|
@ -662,16 +663,32 @@ void Item::LoadLootFromDB(Field* fields)
|
|||
}
|
||||
|
||||
// normal item case
|
||||
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item_id);
|
||||
|
||||
if (!proto)
|
||||
if (type == LOOT_ITEM_TYPE_ITEM)
|
||||
{
|
||||
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;
|
||||
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item_id);
|
||||
if (!proto)
|
||||
{
|
||||
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;
|
||||
|
||||
SetLootState(ITEM_LOOT_UNCHANGED);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM");
|
||||
DEBUG_LOG("WORLD: %s", LookupOpcodeName(recv_data.GetOpcode()));
|
||||
Player* player = GetPlayer();
|
||||
ObjectGuid lguid = player->GetLootGuid();
|
||||
Loot* loot;
|
||||
|
|
@ -109,8 +109,9 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
|
|||
QuestItem* qitem = NULL;
|
||||
QuestItem* ffaitem = 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, ¤cy);
|
||||
|
||||
if (!item)
|
||||
{
|
||||
|
|
@ -128,6 +129,17 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
|
|||
if (pItem)
|
||||
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;
|
||||
InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item->itemid, item->count);
|
||||
if (msg == EQUIP_ERR_OK)
|
||||
|
|
@ -261,8 +273,6 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/)
|
|||
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
|
||||
data << uint32(money_per_player);
|
||||
data << uint8(playersNear.size() > 1 ? 0 : 1); // 0 is "you share of loot..."
|
||||
data << uint32(0); // guild share
|
||||
|
||||
(*i)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
|
@ -274,7 +284,6 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/)
|
|||
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
|
||||
data << uint32(pLoot->gold);
|
||||
data << uint8(1); // 1 is "you loot..."
|
||||
data << uint32(0); // guild share
|
||||
player->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
|
|
@ -555,11 +564,16 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recv_data)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
|
||||
|
|
|
|||
|
|
@ -113,16 +113,17 @@ void LootStore::LoadLootTable()
|
|||
bar.step();
|
||||
|
||||
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();
|
||||
uint8 group = fields[3].GetUInt8();
|
||||
int32 mincountOrRef = fields[4].GetInt32();
|
||||
uint32 maxcount = fields[5].GetUInt32();
|
||||
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.
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
continue;
|
||||
|
|
@ -253,11 +254,18 @@ bool LootStoreItem::Roll(bool rate) const
|
|||
if (mincountOrRef < 0) // reference case
|
||||
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
|
||||
|
|
@ -269,6 +277,12 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
|
|||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
|
||||
if (!proto)
|
||||
if (type == LOOT_ITEM_TYPE_ITEM)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else // mincountOrRef < 0
|
||||
{
|
||||
|
|
@ -327,32 +357,39 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
|
|||
LootItem::LootItem(LootStoreItem const& li)
|
||||
{
|
||||
itemid = li.itemid;
|
||||
type = li.type;
|
||||
conditionId = li.conditionId;
|
||||
|
||||
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
|
||||
freeforall = proto && (proto->Flags & ITEM_FLAG_PARTY_LOOT);
|
||||
|
||||
needs_quest = li.needs_quest;
|
||||
|
||||
currency = type == LOOT_ITEM_TYPE_CURRENCY;
|
||||
count = urand(li.mincountOrRef, li.maxcount); // constructor called for mincountOrRef > 0 only
|
||||
randomSuffix = GenerateEnchSuffixFactor(itemid);
|
||||
randomPropertyId = Item::GenerateItemRandomPropertyId(itemid);
|
||||
|
||||
is_looted = 0;
|
||||
is_blocked = 0;
|
||||
is_underthreshold = 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_;
|
||||
type = type_;
|
||||
conditionId = 0;
|
||||
|
||||
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemid);
|
||||
freeforall = proto && (proto->Flags & ITEM_FLAG_PARTY_LOOT);
|
||||
|
||||
needs_quest = false;
|
||||
|
||||
count = count_;
|
||||
randomSuffix = randomSuffix_;
|
||||
randomPropertyId = randomPropertyId_;
|
||||
|
|
@ -360,6 +397,16 @@ LootItem::LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_, int32 ra
|
|||
is_blocked = 0;
|
||||
is_underthreshold = 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
|
||||
|
|
@ -369,28 +416,46 @@ bool LootItem::AllowedForPlayer(Player const* player) const
|
|||
if (conditionId && !sObjectMgr.IsPlayerMeetToNEWCondition(player, conditionId))
|
||||
return false;
|
||||
|
||||
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);
|
||||
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)
|
||||
if (type == LOOT_ITEM_TYPE_ITEM)
|
||||
{
|
||||
// Checking quests for quest-only drop (check only quests requirements in this case)
|
||||
if (!player->HasQuestForItem(itemid))
|
||||
ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);
|
||||
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)
|
||||
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)
|
||||
if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid))
|
||||
CurrencyTypesEntry const * currency = sCurrencyTypesStore.LookupEntry(itemid);
|
||||
if (!itemid)
|
||||
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;
|
||||
|
|
@ -398,8 +463,8 @@ bool LootItem::AllowedForPlayer(Player const* player) 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
|
||||
if (is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer))
|
||||
// ignore currencies, looted items, FFA (each player get own copy) and not allowed items
|
||||
if (currency || is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer))
|
||||
return MAX_LOOT_SLOT_TYPE;
|
||||
|
||||
switch (permission)
|
||||
|
|
@ -434,9 +499,10 @@ void Loot::AddItem(LootStoreItem const& item)
|
|||
items.push_back(LootItem(item));
|
||||
|
||||
// non-conditional one-player only items are counted here,
|
||||
// currencies are counter in FillCurrencyLoot,
|
||||
// free for all items are counted in FillFFALoot(),
|
||||
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
|
||||
if (!item.conditionId)
|
||||
// non-ffa conditionals are counted in FillNonQuestNonFFANonCurrencyConditionalLoot()
|
||||
if (!item.conditionId && item.type == LOOT_ITEM_TYPE_ITEM)
|
||||
{
|
||||
ItemPrototype const* proto = ObjectMgr::GetItemPrototype(item.itemid);
|
||||
if (!proto || !(proto->Flags & ITEM_FLAG_PARTY_LOOT))
|
||||
|
|
@ -485,7 +551,11 @@ void Loot::FillNotNormalLootFor(Player* pl)
|
|||
{
|
||||
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())
|
||||
FillQuestLoot(pl);
|
||||
|
||||
|
|
@ -493,9 +563,32 @@ void Loot::FillNotNormalLootFor(Player* pl)
|
|||
if (qmapitr == m_playerFFAItems.end())
|
||||
FillFFALoot(pl);
|
||||
|
||||
qmapitr = m_playerNonQuestNonFFAConditionalItems.find(plguid);
|
||||
if (qmapitr == m_playerNonQuestNonFFAConditionalItems.end())
|
||||
FillNonQuestNonFFAConditionalLoot(pl);
|
||||
qmapitr = m_playerNonQuestNonFFANonCurrencyConditionalItems.find(plguid);
|
||||
if (qmapitr == m_playerNonQuestNonFFANonCurrencyConditionalItems.end())
|
||||
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)
|
||||
|
|
@ -556,14 +649,14 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
|
|||
return ql;
|
||||
}
|
||||
|
||||
QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
|
||||
QuestItemList* Loot::FillNonQuestNonFFANonCurrencyConditionalLoot(Player* player)
|
||||
{
|
||||
QuestItemList* ql = new QuestItemList();
|
||||
|
||||
for (uint8 i = 0; i < items.size(); ++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));
|
||||
if (!item.is_counted)
|
||||
|
|
@ -579,7 +672,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
m_playerNonQuestNonFFAConditionalItems[player->GetGUIDLow()] = ql;
|
||||
m_playerNonQuestNonFFANonCurrencyConditionalItems[player->GetGUIDLow()] = 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;
|
||||
bool is_looted = true;
|
||||
|
|
@ -684,7 +777,25 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem** qite
|
|||
{
|
||||
item = &items[lootSlot];
|
||||
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());
|
||||
if (itr != m_playerFFAItems.end())
|
||||
|
|
@ -702,8 +813,8 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem** qite
|
|||
}
|
||||
else if (item->conditionId)
|
||||
{
|
||||
QuestItemMap::const_iterator itr = m_playerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow());
|
||||
if (itr != m_playerNonQuestNonFFAConditionalItems.end())
|
||||
QuestItemMap::const_iterator itr = m_playerNonQuestNonFFANonCurrencyConditionalItems.find(player->GetGUIDLow());
|
||||
if (itr != m_playerNonQuestNonFFANonCurrencyConditionalItems.end())
|
||||
{
|
||||
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)
|
||||
{
|
||||
b << uint32(li.itemid);
|
||||
b << uint32(li.count); // nr of items of this type
|
||||
b << uint32(ObjectMgr::GetItemPrototype(li.itemid)->DisplayInfoID);
|
||||
b << uint32(li.randomSuffix);
|
||||
b << uint32(li.randomPropertyId);
|
||||
if (li.type == LOOT_ITEM_TYPE_ITEM)
|
||||
{
|
||||
b << uint32(li.itemid);
|
||||
b << uint32(li.count); // nr of items of this type
|
||||
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
|
||||
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
|
||||
b << uint8(0); // currency count placeholder
|
||||
|
||||
if (lv.permission == NONE_PERMISSION)
|
||||
return b;
|
||||
|
||||
|
||||
for (uint8 i = 0; i < l.items.size(); ++i)
|
||||
{
|
||||
LootSlotType slot_type = l.items[i].GetSlotTypeForSharedLoot(lv.permission, lv.viewer);
|
||||
|
|
@ -780,7 +895,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
|||
++itemsShown;
|
||||
}
|
||||
|
||||
QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
|
||||
QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFANonCurrencyConditionalItems();
|
||||
QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow());
|
||||
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
|
||||
b.put<uint8>(count_pos, itemsShown);
|
||||
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))
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ enum PermissionTypes
|
|||
NONE_PERMISSION = 4
|
||||
};
|
||||
|
||||
enum LootItemType
|
||||
{
|
||||
LOOT_ITEM_TYPE_ITEM = 0,
|
||||
LOOT_ITEM_TYPE_CURRENCY = 1,
|
||||
};
|
||||
|
||||
enum LootType
|
||||
{
|
||||
LOOT_CORPSE = 1,
|
||||
|
|
@ -75,17 +81,18 @@ class LootStore;
|
|||
struct LootStoreItem
|
||||
{
|
||||
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
|
||||
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;
|
||||
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
|
||||
|
||||
// Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
|
||||
// displayid is filled in IsValid() which must be called after
|
||||
LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint16 _conditionId, int32 _mincountOrRef, uint8 _maxcount)
|
||||
: itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
|
||||
LootStoreItem(uint32 _itemid, uint8 _type, float _chanceOrQuestChance, int8 _group, uint16 _conditionId, int32 _mincountOrRef, uint32 _maxcount)
|
||||
: itemid(_itemid), type(_type), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
|
||||
group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId)
|
||||
{}
|
||||
|
||||
|
|
@ -97,10 +104,12 @@ struct LootStoreItem
|
|||
struct LootItem
|
||||
{
|
||||
uint32 itemid;
|
||||
uint8 type; // 0 = item, 1 = currency
|
||||
uint32 randomSuffix;
|
||||
int32 randomPropertyId;
|
||||
uint32 count;
|
||||
uint16 conditionId : 16; // allow compiler pack structure
|
||||
uint8 count : 8;
|
||||
bool currency : 1;
|
||||
bool is_looted : 1;
|
||||
bool is_blocked : 1;
|
||||
bool freeforall : 1; // free for all
|
||||
|
|
@ -112,7 +121,7 @@ struct LootItem
|
|||
// Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0)
|
||||
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
|
||||
bool AllowedForPlayer(Player const* player) const;
|
||||
|
|
@ -236,9 +245,10 @@ struct Loot
|
|||
{
|
||||
friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
|
||||
|
||||
QuestItemMap const& GetPlayerCurrencies() const { return m_playerCurrencies; }
|
||||
QuestItemMap const& GetPlayerQuestItems() const { return m_playerQuestItems; }
|
||||
QuestItemMap const& GetPlayerFFAItems() const { return m_playerFFAItems; }
|
||||
QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return m_playerNonQuestNonFFAConditionalItems; }
|
||||
QuestItemMap const& GetPlayerNonQuestNonFFANonCurrencyConditionalItems() const { return m_playerNonQuestNonFFANonCurrencyConditionalItems; }
|
||||
|
||||
LootItemList items;
|
||||
uint32 gold;
|
||||
|
|
@ -257,6 +267,10 @@ struct Loot
|
|||
// 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)
|
||||
delete itr->second;
|
||||
m_playerQuestItems.clear();
|
||||
|
|
@ -265,9 +279,9 @@ struct Loot
|
|||
delete itr->second;
|
||||
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;
|
||||
m_playerNonQuestNonFFAConditionalItems.clear();
|
||||
m_playerNonQuestNonFFANonCurrencyConditionalItems.clear();
|
||||
|
||||
m_playersLooting.clear();
|
||||
items.clear();
|
||||
|
|
@ -292,22 +306,24 @@ struct Loot
|
|||
// Inserts the item into the loot (called by LootTemplate processors)
|
||||
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;
|
||||
|
||||
private:
|
||||
void FillNotNormalLootFor(Player* player);
|
||||
QuestItemList* FillCurrencyLoot(Player* player);
|
||||
QuestItemList* FillFFALoot(Player* player);
|
||||
QuestItemList* FillQuestLoot(Player* player);
|
||||
QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
|
||||
QuestItemList* FillNonQuestNonFFANonCurrencyConditionalLoot(Player* player);
|
||||
|
||||
LootItemList m_questItems;
|
||||
|
||||
GuidSet m_playersLooting;
|
||||
|
||||
QuestItemMap m_playerCurrencies;
|
||||
QuestItemMap m_playerQuestItems;
|
||||
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
|
||||
LootValidatorRefManager m_LootValidatorRefManager;
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@ void InitializeOpcodes()
|
|||
//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_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_AUTOEQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode );
|
||||
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_RELEASE_RESPONSE, 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_ITEM_NOTIFY, 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(SMSG_CANCEL_AUTO_REPEAT, 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_ROLL_WON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
//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_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
//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_ALL_PASSED, 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(SMSG_LOOT_START_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(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_SPELL_FAILED_OTHER, 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(CMSG_SET_TITLE_SUFFIX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
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_SAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
//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(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
|
||||
//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(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText );
|
||||
//OPCODE(CMSG_SET_GRANTABLE_LEVELS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
|
|
|
|||
|
|
@ -402,11 +402,13 @@ enum Opcodes
|
|||
SMSG_RESURRECT_REQUEST = 0x2905, // 4.3.4 15595
|
||||
CMSG_RESURRECT_RESPONSE = 0x6827, // 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_RELEASE = 0x2007, // 4.3.4 15595
|
||||
SMSG_LOOT_RESPONSE = 0x4C16, // 4.3.4 15595
|
||||
SMSG_LOOT_RELEASE_RESPONSE = 0x6D25, // 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_ITEM_NOTIFY = 0x6D15, // 4.3.4 15595
|
||||
SMSG_LOOT_CLEAR_MONEY = 0x2B37, // 4.3.4 15595
|
||||
|
|
@ -717,13 +719,13 @@ enum Opcodes
|
|||
CMSG_CANCEL_GROWTH_AURA = 0x129C,
|
||||
SMSG_CANCEL_AUTO_REPEAT = 0x6436, // 4.3.4 15595
|
||||
SMSG_STANDSTATE_UPDATE = 0x6F04, // 4.3.4 15595
|
||||
SMSG_LOOT_ALL_PASSED = 0x129F,
|
||||
SMSG_LOOT_ROLL_WON = 0x12A0,
|
||||
CMSG_LOOT_ROLL = 0x12A1,
|
||||
SMSG_LOOT_START_ROLL = 0x12A2,
|
||||
SMSG_LOOT_ROLL = 0x12A3,
|
||||
CMSG_LOOT_MASTER_GIVE = 0x12A4,
|
||||
SMSG_LOOT_MASTER_LIST = 0x12A5,
|
||||
SMSG_LOOT_ALL_PASSED = 0x6237, // 4.3.4 15595
|
||||
SMSG_LOOT_ROLL_WON = 0x6617, // 4.3.4 15595
|
||||
CMSG_LOOT_ROLL = 0x6934, // 4.3.4 15595
|
||||
SMSG_LOOT_START_ROLL = 0x2227, // 4.3.4 15595
|
||||
SMSG_LOOT_ROLL = 0x6507, // 4.3.4 15595
|
||||
CMSG_LOOT_MASTER_GIVE = 0x4F35, // 4.3.4 15595
|
||||
SMSG_LOOT_MASTER_LIST = 0x0325, // 4.3.4 15595
|
||||
SMSG_SET_FORCED_REACTIONS = 0x12A6,
|
||||
SMSG_SPELL_FAILED_OTHER = 0x4535, // 4.3.4 15595
|
||||
SMSG_GAMEOBJECT_RESET_STATE = 0x12A8,
|
||||
|
|
@ -1063,7 +1065,7 @@ enum Opcodes
|
|||
SMSG_ECHO_PARTY_SQUELCH = 0x13F7,
|
||||
CMSG_SET_TITLE_SUFFIX = 0x13F8,
|
||||
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_SAVE = 0x13FC,
|
||||
SMSG_VOICESESSION_FULL = 0x13FD,
|
||||
|
|
@ -1079,7 +1081,7 @@ enum Opcodes
|
|||
SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x1407,
|
||||
CMSG_KEEP_ALIVE = 0x0015, // 4.3.4 15595
|
||||
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,
|
||||
CMSG_SET_GUILD_BANK_TEXT = 0x3023, // 4.3.4 15595
|
||||
CMSG_SET_GRANTABLE_LEVELS = 0x140D,
|
||||
|
|
|
|||
|
|
@ -8318,9 +8318,9 @@ void Player::SendNotifyLootMoneyRemoved()
|
|||
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);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2063,7 +2063,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
void SendLoot(ObjectGuid guid, LootType loot_type);
|
||||
void SendLootRelease(ObjectGuid guid);
|
||||
void SendNotifyLootItemRemoved(uint8 lootSlot);
|
||||
void SendNotifyLootItemRemoved(uint8 lootSlot, bool currency = false);
|
||||
void SendNotifyLootMoneyRemoved();
|
||||
|
||||
/*********************************************************/
|
||||
|
|
|
|||
|
|
@ -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_REFERENCED, "Rate.Drop.Item.Referenced", 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_QUEST, "Rate.XP.Quest", 1.0f);
|
||||
setConfig(CONFIG_FLOAT_RATE_XP_EXPLORE, "Rate.XP.Explore", 1.0f);
|
||||
|
|
|
|||
|
|
@ -224,6 +224,8 @@ enum eConfigFloatValues
|
|||
CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT,
|
||||
CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED,
|
||||
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_QUEST,
|
||||
CONFIG_FLOAT_RATE_XP_EXPLORE,
|
||||
|
|
|
|||
|
|
@ -1215,7 +1215,12 @@ Visibility.AIRelocationNotifyDelay = 1000
|
|||
# Rate.Drop.Item.Artifact
|
||||
# Rate.Drop.Item.Referenced
|
||||
# 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
|
||||
#
|
||||
# Rate.XP.Kill
|
||||
|
|
@ -1361,8 +1366,10 @@ Rate.Drop.Item.Legendary = 1
|
|||
Rate.Drop.Item.Artifact = 1
|
||||
Rate.Drop.Item.Referenced = 1
|
||||
Rate.Drop.Money = 1
|
||||
Rate.XP.Kill = 1
|
||||
Rate.XP.Quest = 1
|
||||
Rate.Drop.Currency = 1
|
||||
Rate.Drop.Currency.Amount = 1
|
||||
Rate.XP.Kill = 1
|
||||
Rate.XP.Quest = 1
|
||||
Rate.XP.Explore = 1
|
||||
Rate.Rest.InGame = 1
|
||||
Rate.Rest.Offline.InTavernOrCity = 1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "12215"
|
||||
#define REVISION_NR "12216"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#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"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue