Core/Items: Implement azerite empowered items

This commit is contained in:
Shauren
2019-12-05 00:12:35 +01:00
parent 65b91375e0
commit d934824421
30 changed files with 1036 additions and 37 deletions
+30 -1
View File
@@ -1694,6 +1694,7 @@ CREATE TABLE `characters` (
`rest_bonus` float NOT NULL DEFAULT '0', `rest_bonus` float NOT NULL DEFAULT '0',
`resettalents_cost` int(10) unsigned NOT NULL DEFAULT '0', `resettalents_cost` int(10) unsigned NOT NULL DEFAULT '0',
`resettalents_time` int(10) unsigned NOT NULL DEFAULT '0', `resettalents_time` int(10) unsigned NOT NULL DEFAULT '0',
`numRespecs` tinyint(3) unsigned NOT NULL DEFAULT '0',
`primarySpecialization` int(10) unsigned NOT NULL DEFAULT '0', `primarySpecialization` int(10) unsigned NOT NULL DEFAULT '0',
`trans_x` float NOT NULL DEFAULT '0', `trans_x` float NOT NULL DEFAULT '0',
`trans_y` float NOT NULL DEFAULT '0', `trans_y` float NOT NULL DEFAULT '0',
@@ -2897,6 +2898,33 @@ LOCK TABLES `item_instance_azerite` WRITE;
/*!40000 ALTER TABLE `item_instance_azerite` ENABLE KEYS */; /*!40000 ALTER TABLE `item_instance_azerite` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
--
-- Table structure for table `item_instance_azerite_empowered`
--
DROP TABLE IF EXISTS `item_instance_azerite_empowered`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `item_instance_azerite_empowered` (
`itemGuid` bigint(20) unsigned NOT NULL,
`azeritePowerId1` int(11) NOT NULL,
`azeritePowerId2` int(11) NOT NULL,
`azeritePowerId3` int(11) NOT NULL,
`azeritePowerId4` int(11) NOT NULL,
`azeritePowerId5` int(11) NOT NULL,
PRIMARY KEY (`itemGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `item_instance_azerite_empowered`
--
LOCK TABLES `item_instance_azerite_empowered` WRITE;
/*!40000 ALTER TABLE `item_instance_azerite_empowered` DISABLE KEYS */;
/*!40000 ALTER TABLE `item_instance_azerite_empowered` ENABLE KEYS */;
UNLOCK TABLES;
-- --
-- Table structure for table `item_instance_azerite_milestone_power` -- Table structure for table `item_instance_azerite_milestone_power`
-- --
@@ -3662,7 +3690,8 @@ INSERT INTO `updates` VALUES
('2019_11_03_00_characters.sql','DC789597F85B890E9A7901B4443DAD9CAEE2A02A','RELEASED','2019-11-03 14:13:27',0), ('2019_11_03_00_characters.sql','DC789597F85B890E9A7901B4443DAD9CAEE2A02A','RELEASED','2019-11-03 14:13:27',0),
('2019_11_12_00_characters.sql','D4C642B4D48DAE9F56329BDE51C258323A132A91','RELEASED','2019-11-12 16:31:29',0), ('2019_11_12_00_characters.sql','D4C642B4D48DAE9F56329BDE51C258323A132A91','RELEASED','2019-11-12 16:31:29',0),
('2019_11_22_00_characters.sql','95DFA71DBD75542C098CD86E9C0051C9690902F0','RELEASED','2019-11-20 15:10:12',0), ('2019_11_22_00_characters.sql','95DFA71DBD75542C098CD86E9C0051C9690902F0','RELEASED','2019-11-20 15:10:12',0),
('2019_11_30_00_characters.sql','D0678E62B651AECA60C2DD6989BF80BD999AD12B','RELEASED','2019-11-29 22:42:01',0); ('2019_11_30_00_characters.sql','D0678E62B651AECA60C2DD6989BF80BD999AD12B','RELEASED','2019-11-29 22:42:01',0),
('2019_12_05_00_characters.sql','EA381C9634A5646A3168F15DF4E06A708A622762','RELEASED','2019-12-05 20:56:58',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */; /*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -0,0 +1,15 @@
ALTER TABLE `characters` ADD `numRespecs` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `resettalents_time`;
--
-- Table structure for table `item_instance_azerite_empowered`
--
DROP TABLE IF EXISTS `item_instance_azerite_empowered`;
CREATE TABLE `item_instance_azerite_empowered` (
`itemGuid` bigint(20) unsigned NOT NULL,
`azeritePowerId1` int(11) NOT NULL,
`azeritePowerId2` int(11) NOT NULL,
`azeritePowerId3` int(11) NOT NULL,
`azeritePowerId4` int(11) NOT NULL,
`azeritePowerId5` int(11) NOT NULL,
PRIMARY KEY (`itemGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -0,0 +1,67 @@
--
-- Table structure for table `azerite_empowered_item`
--
DROP TABLE IF EXISTS `azerite_empowered_item`;
CREATE TABLE `azerite_empowered_item` (
`ID` int(10) unsigned NOT NULL DEFAULT '0',
`ItemID` int(11) NOT NULL DEFAULT '0',
`AzeriteTierUnlockSetID` int(10) unsigned NOT NULL DEFAULT '0',
`AzeritePowerSetID` int(10) unsigned NOT NULL DEFAULT '0',
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `azerite_power_set_member`
--
DROP TABLE IF EXISTS `azerite_power_set_member`;
CREATE TABLE `azerite_power_set_member` (
`ID` int(10) unsigned NOT NULL DEFAULT '0',
`AzeritePowerSetID` int(11) NOT NULL DEFAULT '0',
`AzeritePowerID` int(11) NOT NULL DEFAULT '0',
`Class` int(11) NOT NULL DEFAULT '0',
`Tier` int(11) NOT NULL DEFAULT '0',
`OrderIndex` int(11) NOT NULL DEFAULT '0',
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `azerite_tier_unlock`
--
DROP TABLE IF EXISTS `azerite_tier_unlock`;
CREATE TABLE `azerite_tier_unlock` (
`ID` int(10) unsigned NOT NULL DEFAULT '0',
`ItemCreationContext` tinyint(3) unsigned NOT NULL DEFAULT '0',
`Tier` tinyint(3) unsigned NOT NULL DEFAULT '0',
`AzeriteLevel` tinyint(3) unsigned NOT NULL DEFAULT '0',
`AzeriteTierUnlockSetID` int(10) unsigned NOT NULL DEFAULT '0',
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `azerite_tier_unlock_set`
--
DROP TABLE IF EXISTS `azerite_tier_unlock_set`;
CREATE TABLE `azerite_tier_unlock_set` (
`ID` int(10) unsigned NOT NULL DEFAULT '0',
`Flags` int(11) NOT NULL DEFAULT '0',
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `azerite_unlock_mapping`
--
DROP TABLE IF EXISTS `azerite_unlock_mapping`;
CREATE TABLE `azerite_unlock_mapping` (
`ID` int(10) unsigned NOT NULL DEFAULT '0',
`ItemLevel` int(11) NOT NULL DEFAULT '0',
`ItemBonusListHead` int(11) NOT NULL DEFAULT '0',
`ItemBonusListShoulders` int(11) NOT NULL DEFAULT '0',
`ItemBonusListChest` int(11) NOT NULL DEFAULT '0',
`AzeriteUnlockMappingSetID` int(10) unsigned NOT NULL DEFAULT '0',
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -81,7 +81,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " "resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, "
"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
"health, power1, power2, power3, power4, power5, power6, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, raidDifficulty, legacyRaidDifficulty, fishingSteps, " "health, power1, power2, power3, power4, power5, power6, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, raidDifficulty, legacyRaidDifficulty, fishingSteps, "
"honor, honorLevel, honorRestState, honorRestBonus " "honor, honorLevel, honorRestState, honorRestBonus, numRespecs "
"FROM characters c LEFT JOIN character_fishingsteps cfs ON c.guid = cfs.guid WHERE c.guid = ?", CONNECTION_ASYNC); "FROM characters c LEFT JOIN character_fishingsteps cfs ON c.guid = cfs.guid WHERE c.guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
@@ -154,6 +154,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"FROM item_instance_azerite iz INNER JOIN mail_items mi ON iz.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH); "FROM item_instance_azerite iz INNER JOIN mail_items mi ON iz.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAILITEMS_AZERITE_MILESTONE_POWER, "SELECT iamp.itemGuid, iamp.azeriteItemMilestonePowerId FROM item_instance_azerite_milestone_power iamp INNER JOIN mail_items mi ON iamp.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_MAILITEMS_AZERITE_MILESTONE_POWER, "SELECT iamp.itemGuid, iamp.azeriteItemMilestonePowerId FROM item_instance_azerite_milestone_power iamp INNER JOIN mail_items mi ON iamp.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE, "SELECT iaue.itemGuid, iaue.azeriteEssenceId, iaue.`rank` FROM item_instance_azerite_unlocked_essence iaue INNER JOIN mail_items mi ON iaue.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE, "SELECT iaue.itemGuid, iaue.azeriteEssenceId, iaue.`rank` FROM item_instance_azerite_unlocked_essence iaue INNER JOIN mail_items mi ON iaue.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAILITEMS_AZERITE_EMPOWERED, "SELECT iae.itemGuid, iae.azeritePowerId1, iae.azeritePowerId2, iae.azeritePowerId3, iae.azeritePowerId4, iae.azeritePowerId5 FROM item_instance_azerite_empowered iae INNER JOIN mail_items mi ON iae.itemGuid = mi.item_guid INNER JOIN mail m ON mi.mail_id = m.id WHERE m.receiver = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, auctioneerguid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, auctioneerguid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
@@ -218,6 +219,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE, "INSERT INTO item_instance_azerite_unlocked_essence (itemGuid, azeriteEssenceId, `rank`) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE, "INSERT INTO item_instance_azerite_unlocked_essence (itemGuid, azeriteEssenceId, `rank`) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE, "DELETE FROM item_instance_azerite_unlocked_essence WHERE itemGuid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE, "DELETE FROM item_instance_azerite_unlocked_essence WHERE itemGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE_BY_OWNER, "DELETE iaue FROM item_instance_azerite_unlocked_essence iaue LEFT JOIN item_instance ii ON iaue.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE_BY_OWNER, "DELETE iaue FROM item_instance_azerite_unlocked_essence iaue LEFT JOIN item_instance ii ON iaue.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_ITEM_INSTANCE_AZERITE_EMPOWERED, "SELECT iae.itemGuid, iae.azeritePowerId1, iae.azeritePowerId2, iae.azeritePowerId3, iae.azeritePowerId4, iae.azeritePowerId5 FROM item_instance_azerite_empowered iae INNER JOIN character_inventory ci ON iae.itemGuid = ci.item WHERE ci.guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ITEM_INSTANCE_AZERITE_EMPOWERED, "INSERT INTO item_instance_azerite_empowered (itemGuid, azeritePowerId1, azeritePowerId2, azeritePowerId3, azeritePowerId4, azeritePowerId5) VALUES (?, ?, ?, ? ,? ,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ITEM_INSTANCE_AZERITE_EMPOWERED, "UPDATE item_instance_azerite_empowered SET azeritePowerId1 = ?, azeritePowerId2 = ?, azeritePowerId3 = ?, azeritePowerId4 = ?, azeritePowerId5 = ? WHERE itemGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED, "DELETE FROM item_instance_azerite_empowered WHERE itemGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED_BY_OWNER, "DELETE iae FROM item_instance_azerite_empowered iae LEFT JOIN item_instance ii ON iae.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC);
@@ -458,7 +464,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,customDisplay1=?,customDisplay2=?,customDisplay3=?,inventorySlots=?,bankSlots=?,restState=?,playerFlags=?,playerFlagsEx=?," PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,customDisplay1=?,customDisplay2=?,customDisplay3=?,inventorySlots=?,bankSlots=?,restState=?,playerFlags=?,playerFlagsEx=?,"
"map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," "map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,primarySpecialization=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,numRespecs=?,primarySpecialization=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," "totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
"watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,latency=?,activeTalentGroup=?,lootSpecId=?,exploredZones=?," "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,latency=?,activeTalentGroup=?,lootSpecId=?,exploredZones=?,"
"equipmentCache=?,knownTitles=?,actionBars=?,online=?,honor=?,honorLevel=?,honorRestState=?,honorRestBonus=?,lastLoginBuild=? WHERE guid=?", CONNECTION_ASYNC); "equipmentCache=?,knownTitles=?,actionBars=?,online=?,honor=?,honorLevel=?,honorRestState=?,honorRestBonus=?,lastLoginBuild=? WHERE guid=?", CONNECTION_ASYNC);
@@ -120,6 +120,7 @@ enum CharacterDatabaseStatements : uint32
CHAR_SEL_MAILITEMS_AZERITE, CHAR_SEL_MAILITEMS_AZERITE,
CHAR_SEL_MAILITEMS_AZERITE_MILESTONE_POWER, CHAR_SEL_MAILITEMS_AZERITE_MILESTONE_POWER,
CHAR_SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE, CHAR_SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE,
CHAR_SEL_MAILITEMS_AZERITE_EMPOWERED,
CHAR_SEL_AUCTION_ITEMS, CHAR_SEL_AUCTION_ITEMS,
CHAR_INS_AUCTION, CHAR_INS_AUCTION,
CHAR_DEL_AUCTION, CHAR_DEL_AUCTION,
@@ -175,6 +176,11 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE, CHAR_INS_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE,
CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE, CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE,
CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE_BY_OWNER, CHAR_DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE_BY_OWNER,
CHAR_SEL_ITEM_INSTANCE_AZERITE_EMPOWERED,
CHAR_INS_ITEM_INSTANCE_AZERITE_EMPOWERED,
CHAR_UPD_ITEM_INSTANCE_AZERITE_EMPOWERED,
CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED,
CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED_BY_OWNER,
CHAR_UPD_GIFT_OWNER, CHAR_UPD_GIFT_OWNER,
CHAR_DEL_GIFT, CHAR_DEL_GIFT,
CHAR_SEL_CHARACTER_GIFT_BY_ITEM, CHAR_SEL_CHARACTER_GIFT_BY_ITEM,
@@ -110,6 +110,10 @@ void HotfixDatabaseConnection::DoPrepareStatements()
PrepareStatement(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, Name, FactionID, DepositRate, ConsignmentRate FROM auction_house ORDER BY ID DESC", CONNECTION_SYNCH); PrepareStatement(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, Name, FactionID, DepositRate, ConsignmentRate FROM auction_house ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, Name_lang FROM auction_house_locale WHERE locale = ?", CONNECTION_SYNCH); PREPARE_LOCALE_STMT(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, Name_lang FROM auction_house_locale WHERE locale = ?", CONNECTION_SYNCH);
// AzeriteEmpoweredItem.db2
PrepareStatement(HOTFIX_SEL_AZERITE_EMPOWERED_ITEM, "SELECT ID, ItemID, AzeriteTierUnlockSetID, AzeritePowerSetID FROM azerite_empowered_item"
" ORDER BY ID DESC", CONNECTION_SYNCH);
// AzeriteEssence.db2 // AzeriteEssence.db2
PrepareStatement(HOTFIX_SEL_AZERITE_ESSENCE, "SELECT Name, Description, ID, SpecSetID FROM azerite_essence ORDER BY ID DESC", CONNECTION_SYNCH); PrepareStatement(HOTFIX_SEL_AZERITE_ESSENCE, "SELECT Name, Description, ID, SpecSetID FROM azerite_essence ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_AZERITE_ESSENCE, "SELECT ID, Name_lang, Description_lang FROM azerite_essence_locale WHERE locale = ?", CONNECTION_SYNCH); PREPARE_LOCALE_STMT(HOTFIX_SEL_AZERITE_ESSENCE, "SELECT ID, Name_lang, Description_lang FROM azerite_essence_locale WHERE locale = ?", CONNECTION_SYNCH);
@@ -137,6 +141,21 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// AzeritePower.db2 // AzeritePower.db2
PrepareStatement(HOTFIX_SEL_AZERITE_POWER, "SELECT ID, SpellID, ItemBonusListID, SpecSetID, Flags FROM azerite_power ORDER BY ID DESC", CONNECTION_SYNCH); PrepareStatement(HOTFIX_SEL_AZERITE_POWER, "SELECT ID, SpellID, ItemBonusListID, SpecSetID, Flags FROM azerite_power ORDER BY ID DESC", CONNECTION_SYNCH);
// AzeritePowerSetMember.db2
PrepareStatement(HOTFIX_SEL_AZERITE_POWER_SET_MEMBER, "SELECT ID, AzeritePowerSetID, AzeritePowerID, Class, Tier, OrderIndex"
" FROM azerite_power_set_member ORDER BY ID DESC", CONNECTION_SYNCH);
// AzeriteTierUnlock.db2
PrepareStatement(HOTFIX_SEL_AZERITE_TIER_UNLOCK, "SELECT ID, ItemCreationContext, Tier, AzeriteLevel, AzeriteTierUnlockSetID"
" FROM azerite_tier_unlock ORDER BY ID DESC", CONNECTION_SYNCH);
// AzeriteTierUnlockSet.db2
PrepareStatement(HOTFIX_SEL_AZERITE_TIER_UNLOCK_SET, "SELECT ID, Flags FROM azerite_tier_unlock_set ORDER BY ID DESC", CONNECTION_SYNCH);
// AzeriteUnlockMapping.db2
PrepareStatement(HOTFIX_SEL_AZERITE_UNLOCK_MAPPING, "SELECT ID, ItemLevel, ItemBonusListHead, ItemBonusListShoulders, ItemBonusListChest, "
"AzeriteUnlockMappingSetID FROM azerite_unlock_mapping ORDER BY ID DESC", CONNECTION_SYNCH);
// BankBagSlotPrices.db2 // BankBagSlotPrices.db2
PrepareStatement(HOTFIX_SEL_BANK_BAG_SLOT_PRICES, "SELECT ID, Cost FROM bank_bag_slot_prices ORDER BY ID DESC", CONNECTION_SYNCH); PrepareStatement(HOTFIX_SEL_BANK_BAG_SLOT_PRICES, "SELECT ID, Cost FROM bank_bag_slot_prices ORDER BY ID DESC", CONNECTION_SYNCH);
@@ -75,6 +75,8 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_AUCTION_HOUSE, HOTFIX_SEL_AUCTION_HOUSE,
HOTFIX_SEL_AUCTION_HOUSE_LOCALE, HOTFIX_SEL_AUCTION_HOUSE_LOCALE,
HOTFIX_SEL_AZERITE_EMPOWERED_ITEM,
HOTFIX_SEL_AZERITE_ESSENCE, HOTFIX_SEL_AZERITE_ESSENCE,
HOTFIX_SEL_AZERITE_ESSENCE_LOCALE, HOTFIX_SEL_AZERITE_ESSENCE_LOCALE,
@@ -91,6 +93,14 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_AZERITE_POWER, HOTFIX_SEL_AZERITE_POWER,
HOTFIX_SEL_AZERITE_POWER_SET_MEMBER,
HOTFIX_SEL_AZERITE_TIER_UNLOCK,
HOTFIX_SEL_AZERITE_TIER_UNLOCK_SET,
HOTFIX_SEL_AZERITE_UNLOCK_MAPPING,
HOTFIX_SEL_BANK_BAG_SLOT_PRICES, HOTFIX_SEL_BANK_BAG_SLOT_PRICES,
HOTFIX_SEL_BANNED_ADDONS, HOTFIX_SEL_BANNED_ADDONS,
+83
View File
@@ -418,6 +418,22 @@ struct AuctionHouseLoadInfo
} }
}; };
struct AzeriteEmpoweredItemLoadInfo
{
static DB2LoadInfo const* Instance()
{
static DB2FieldMeta const fields[] =
{
{ false, FT_INT, "ID" },
{ true, FT_INT, "ItemID" },
{ false, FT_INT, "AzeriteTierUnlockSetID" },
{ false, FT_INT, "AzeritePowerSetID" },
};
static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, AzeriteEmpoweredItemMeta::Instance(), HOTFIX_SEL_AZERITE_EMPOWERED_ITEM);
return &loadInfo;
}
};
struct AzeriteEssenceLoadInfo struct AzeriteEssenceLoadInfo
{ {
static DB2LoadInfo const* Instance() static DB2LoadInfo const* Instance()
@@ -533,6 +549,73 @@ struct AzeritePowerLoadInfo
} }
}; };
struct AzeritePowerSetMemberLoadInfo
{
static DB2LoadInfo const* Instance()
{
static DB2FieldMeta const fields[] =
{
{ false, FT_INT, "ID" },
{ true, FT_INT, "AzeritePowerSetID" },
{ true, FT_INT, "AzeritePowerID" },
{ true, FT_INT, "Class" },
{ true, FT_INT, "Tier" },
{ true, FT_INT, "OrderIndex" },
};
static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, AzeritePowerSetMemberMeta::Instance(), HOTFIX_SEL_AZERITE_POWER_SET_MEMBER);
return &loadInfo;
}
};
struct AzeriteTierUnlockLoadInfo
{
static DB2LoadInfo const* Instance()
{
static DB2FieldMeta const fields[] =
{
{ false, FT_INT, "ID" },
{ false, FT_BYTE, "ItemCreationContext" },
{ false, FT_BYTE, "Tier" },
{ false, FT_BYTE, "AzeriteLevel" },
{ false, FT_INT, "AzeriteTierUnlockSetID" },
};
static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, AzeriteTierUnlockMeta::Instance(), HOTFIX_SEL_AZERITE_TIER_UNLOCK);
return &loadInfo;
}
};
struct AzeriteTierUnlockSetLoadInfo
{
static DB2LoadInfo const* Instance()
{
static DB2FieldMeta const fields[] =
{
{ false, FT_INT, "ID" },
{ true, FT_INT, "Flags" },
};
static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, AzeriteTierUnlockSetMeta::Instance(), HOTFIX_SEL_AZERITE_TIER_UNLOCK_SET);
return &loadInfo;
}
};
struct AzeriteUnlockMappingLoadInfo
{
static DB2LoadInfo const* Instance()
{
static DB2FieldMeta const fields[] =
{
{ false, FT_INT, "ID" },
{ true, FT_INT, "ItemLevel" },
{ true, FT_INT, "ItemBonusListHead" },
{ true, FT_INT, "ItemBonusListShoulders" },
{ true, FT_INT, "ItemBonusListChest" },
{ false, FT_INT, "AzeriteUnlockMappingSetID" },
};
static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, AzeriteUnlockMappingMeta::Instance(), HOTFIX_SEL_AZERITE_UNLOCK_MAPPING);
return &loadInfo;
}
};
struct BankBagSlotPricesLoadInfo struct BankBagSlotPricesLoadInfo
{ {
static DB2LoadInfo const* Instance() static DB2LoadInfo const* Instance()
+112 -1
View File
@@ -20,6 +20,7 @@
#include "DatabaseEnv.h" #include "DatabaseEnv.h"
#include "DB2LoadInfo.h" #include "DB2LoadInfo.h"
#include "Hash.h" #include "Hash.h"
#include "ItemTemplate.h"
#include "IteratorPair.h" #include "IteratorPair.h"
#include "Log.h" #include "Log.h"
#include "ObjectDefines.h" #include "ObjectDefines.h"
@@ -55,6 +56,7 @@ DB2Storage<ArtifactQuestXPEntry> sArtifactQuestXPStore("ArtifactQ
DB2Storage<ArtifactTierEntry> sArtifactTierStore("ArtifactTier.db2", ArtifactTierLoadInfo::Instance()); DB2Storage<ArtifactTierEntry> sArtifactTierStore("ArtifactTier.db2", ArtifactTierLoadInfo::Instance());
DB2Storage<ArtifactUnlockEntry> sArtifactUnlockStore("ArtifactUnlock.db2", ArtifactUnlockLoadInfo::Instance()); DB2Storage<ArtifactUnlockEntry> sArtifactUnlockStore("ArtifactUnlock.db2", ArtifactUnlockLoadInfo::Instance());
DB2Storage<AuctionHouseEntry> sAuctionHouseStore("AuctionHouse.db2", AuctionHouseLoadInfo::Instance()); DB2Storage<AuctionHouseEntry> sAuctionHouseStore("AuctionHouse.db2", AuctionHouseLoadInfo::Instance());
DB2Storage<AzeriteEmpoweredItemEntry> sAzeriteEmpoweredItemStore("AzeriteEmpoweredItem.db2", AzeriteEmpoweredItemLoadInfo::Instance());
DB2Storage<AzeriteEssenceEntry> sAzeriteEssenceStore("AzeriteEssence.db2", AzeriteEssenceLoadInfo::Instance()); DB2Storage<AzeriteEssenceEntry> sAzeriteEssenceStore("AzeriteEssence.db2", AzeriteEssenceLoadInfo::Instance());
DB2Storage<AzeriteEssencePowerEntry> sAzeriteEssencePowerStore("AzeriteEssencePower.db2", AzeriteEssencePowerLoadInfo::Instance()); DB2Storage<AzeriteEssencePowerEntry> sAzeriteEssencePowerStore("AzeriteEssencePower.db2", AzeriteEssencePowerLoadInfo::Instance());
DB2Storage<AzeriteItemEntry> sAzeriteItemStore("AzeriteItem.db2", AzeriteItemLoadInfo::Instance()); DB2Storage<AzeriteItemEntry> sAzeriteItemStore("AzeriteItem.db2", AzeriteItemLoadInfo::Instance());
@@ -62,6 +64,10 @@ DB2Storage<AzeriteItemMilestonePowerEntry> sAzeriteItemMilestonePowerStore(
DB2Storage<AzeriteKnowledgeMultiplierEntry> sAzeriteKnowledgeMultiplierStore("AzeriteKnowledgeMultiplier.db2", AzeriteKnowledgeMultiplierLoadInfo::Instance()); DB2Storage<AzeriteKnowledgeMultiplierEntry> sAzeriteKnowledgeMultiplierStore("AzeriteKnowledgeMultiplier.db2", AzeriteKnowledgeMultiplierLoadInfo::Instance());
DB2Storage<AzeriteLevelInfoEntry> sAzeriteLevelInfoStore("AzeriteLevelInfo.db2", AzeriteLevelInfoLoadInfo::Instance()); DB2Storage<AzeriteLevelInfoEntry> sAzeriteLevelInfoStore("AzeriteLevelInfo.db2", AzeriteLevelInfoLoadInfo::Instance());
DB2Storage<AzeritePowerEntry> sAzeritePowerStore("AzeritePower.db2", AzeritePowerLoadInfo::Instance()); DB2Storage<AzeritePowerEntry> sAzeritePowerStore("AzeritePower.db2", AzeritePowerLoadInfo::Instance());
DB2Storage<AzeritePowerSetMemberEntry> sAzeritePowerSetMemberStore("AzeritePowerSetMember.db2", AzeritePowerSetMemberLoadInfo::Instance());
DB2Storage<AzeriteTierUnlockEntry> sAzeriteTierUnlockStore("AzeriteTierUnlock.db2", AzeriteTierUnlockLoadInfo::Instance());
DB2Storage<AzeriteTierUnlockSetEntry> sAzeriteTierUnlockSetStore("AzeriteTierUnlockSet.db2", AzeriteTierUnlockSetLoadInfo::Instance());
DB2Storage<AzeriteUnlockMappingEntry> sAzeriteUnlockMappingStore("AzeriteUnlockMapping.db2", AzeriteUnlockMappingLoadInfo::Instance());
DB2Storage<BankBagSlotPricesEntry> sBankBagSlotPricesStore("BankBagSlotPrices.db2", BankBagSlotPricesLoadInfo::Instance()); DB2Storage<BankBagSlotPricesEntry> sBankBagSlotPricesStore("BankBagSlotPrices.db2", BankBagSlotPricesLoadInfo::Instance());
DB2Storage<BannedAddonsEntry> sBannedAddonsStore("BannedAddons.db2", BannedAddonsLoadInfo::Instance()); DB2Storage<BannedAddonsEntry> sBannedAddonsStore("BannedAddons.db2", BannedAddonsLoadInfo::Instance());
DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore("BarberShopStyle.db2", BarberShopStyleLoadInfo::Instance()); DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore("BarberShopStyle.db2", BarberShopStyleLoadInfo::Instance());
@@ -299,6 +305,8 @@ struct ItemLevelSelectorQualityEntryComparator
static bool Compare(ItemLevelSelectorQualityEntry const* left, ItemLevelSelectorQualityEntry const* right); static bool Compare(ItemLevelSelectorQualityEntry const* left, ItemLevelSelectorQualityEntry const* right);
}; };
void LoadAzeriteEmpoweredItemUnlockMappings(std::unordered_map<int32, std::vector<AzeriteUnlockMappingEntry const*>> const& azeriteUnlockMappingsBySet, uint32 itemId);
typedef std::map<uint32 /*hash*/, DB2StorageBase*> StorageMap; typedef std::map<uint32 /*hash*/, DB2StorageBase*> StorageMap;
typedef std::unordered_map<uint32 /*areaGroupId*/, std::vector<uint32/*areaId*/>> AreaGroupMemberContainer; typedef std::unordered_map<uint32 /*areaGroupId*/, std::vector<uint32/*areaId*/>> AreaGroupMemberContainer;
typedef std::unordered_map<uint32, std::vector<ArtifactPowerEntry const*>> ArtifactPowersContainer; typedef std::unordered_map<uint32, std::vector<ArtifactPowerEntry const*>> ArtifactPowersContainer;
@@ -360,9 +368,13 @@ namespace
ArtifactPowersContainer _artifactPowers; ArtifactPowersContainer _artifactPowers;
ArtifactPowerLinksContainer _artifactPowerLinks; ArtifactPowerLinksContainer _artifactPowerLinks;
ArtifactPowerRanksContainer _artifactPowerRanks; ArtifactPowerRanksContainer _artifactPowerRanks;
std::unordered_map<std::pair<uint32, uint32>, AzeriteEssencePowerEntry const*> _azeriteEssencePowersByIdAndRank; std::unordered_map<uint32 /*itemId*/, AzeriteEmpoweredItemEntry const*> _azeriteEmpoweredItems;
std::unordered_map<std::pair<uint32 /*azeriteEssenceId*/, uint32 /*rank*/>, AzeriteEssencePowerEntry const*> _azeriteEssencePowersByIdAndRank;
std::vector<AzeriteItemMilestonePowerEntry const*> _azeriteItemMilestonePowers; std::vector<AzeriteItemMilestonePowerEntry const*> _azeriteItemMilestonePowers;
std::array<AzeriteItemMilestonePowerEntry const*, MAX_AZERITE_ESSENCE_SLOT> _azeriteItemMilestonePowerByEssenceSlot; std::array<AzeriteItemMilestonePowerEntry const*, MAX_AZERITE_ESSENCE_SLOT> _azeriteItemMilestonePowerByEssenceSlot;
std::unordered_map<uint32 /*azeritePowerSetId*/, std::vector<AzeritePowerSetMemberEntry const*>> _azeritePowers;
std::unordered_map<std::pair<uint32 /*azeriteUnlockSetId*/, ItemContext>, std::array<uint8, MAX_AZERITE_EMPOWERED_TIER>> _azeriteTierUnlockLevels;
std::unordered_map<std::pair<uint32 /*itemId*/, ItemContext>, AzeriteUnlockMappingEntry const*> _azeriteUnlockMappings;
std::set<std::tuple<uint8, uint8, uint32>> _characterFacialHairStyles; std::set<std::tuple<uint8, uint8, uint32>> _characterFacialHairStyles;
std::multimap<std::tuple<uint8, uint8, CharBaseSectionVariation>, CharSectionsEntry const*> _charSections; std::multimap<std::tuple<uint8, uint8, CharBaseSectionVariation>, CharSectionsEntry const*> _charSections;
CharStartOutfitContainer _charStartOutfits; CharStartOutfitContainer _charStartOutfits;
@@ -532,6 +544,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
LOAD_DB2(sArtifactTierStore); LOAD_DB2(sArtifactTierStore);
LOAD_DB2(sArtifactUnlockStore); LOAD_DB2(sArtifactUnlockStore);
LOAD_DB2(sAuctionHouseStore); LOAD_DB2(sAuctionHouseStore);
LOAD_DB2(sAzeriteEmpoweredItemStore);
LOAD_DB2(sAzeriteEssenceStore); LOAD_DB2(sAzeriteEssenceStore);
LOAD_DB2(sAzeriteEssencePowerStore); LOAD_DB2(sAzeriteEssencePowerStore);
LOAD_DB2(sAzeriteItemStore); LOAD_DB2(sAzeriteItemStore);
@@ -539,6 +552,10 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
LOAD_DB2(sAzeriteKnowledgeMultiplierStore); LOAD_DB2(sAzeriteKnowledgeMultiplierStore);
LOAD_DB2(sAzeriteLevelInfoStore); LOAD_DB2(sAzeriteLevelInfoStore);
LOAD_DB2(sAzeritePowerStore); LOAD_DB2(sAzeritePowerStore);
LOAD_DB2(sAzeritePowerSetMemberStore);
LOAD_DB2(sAzeriteTierUnlockStore);
LOAD_DB2(sAzeriteTierUnlockSetStore);
LOAD_DB2(sAzeriteUnlockMappingStore);
LOAD_DB2(sBankBagSlotPricesStore); LOAD_DB2(sBankBagSlotPricesStore);
LOAD_DB2(sBannedAddonsStore); LOAD_DB2(sBannedAddonsStore);
LOAD_DB2(sBarberShopStyleStore); LOAD_DB2(sBarberShopStyleStore);
@@ -776,6 +793,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
for (ArtifactPowerRankEntry const* artifactPowerRank : sArtifactPowerRankStore) for (ArtifactPowerRankEntry const* artifactPowerRank : sArtifactPowerRankStore)
_artifactPowerRanks[std::pair<uint32, uint8>{ artifactPowerRank->ArtifactPowerID, artifactPowerRank->RankIndex }] = artifactPowerRank; _artifactPowerRanks[std::pair<uint32, uint8>{ artifactPowerRank->ArtifactPowerID, artifactPowerRank->RankIndex }] = artifactPowerRank;
for (AzeriteEmpoweredItemEntry const* azeriteEmpoweredItem : sAzeriteEmpoweredItemStore)
_azeriteEmpoweredItems[azeriteEmpoweredItem->ItemID] = azeriteEmpoweredItem;
for (AzeriteEssencePowerEntry const* azeriteEssencePower : sAzeriteEssencePowerStore) for (AzeriteEssencePowerEntry const* azeriteEssencePower : sAzeriteEssencePowerStore)
_azeriteEssencePowersByIdAndRank[std::pair<uint32, uint32>{ azeriteEssencePower->AzeriteEssenceID, azeriteEssencePower->Tier }] = azeriteEssencePower; _azeriteEssencePowersByIdAndRank[std::pair<uint32, uint32>{ azeriteEssencePower->AzeriteEssenceID, azeriteEssencePower->Tier }] = azeriteEssencePower;
@@ -801,6 +821,17 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
} }
} }
for (AzeritePowerSetMemberEntry const* azeritePowerSetMember : sAzeritePowerSetMemberStore)
if (sAzeritePowerStore.LookupEntry(azeritePowerSetMember->AzeritePowerID))
_azeritePowers[azeritePowerSetMember->AzeritePowerSetID].push_back(azeritePowerSetMember);
for (AzeriteTierUnlockEntry const* azeriteTierUnlock : sAzeriteTierUnlockStore)
_azeriteTierUnlockLevels[std::pair<uint32, ItemContext>{ azeriteTierUnlock->AzeriteTierUnlockSetID, ItemContext(azeriteTierUnlock->ItemCreationContext) }][azeriteTierUnlock->Tier] = azeriteTierUnlock->AzeriteLevel;
std::unordered_map<int32, std::vector<AzeriteUnlockMappingEntry const*>> azeriteUnlockMappings;
for (AzeriteUnlockMappingEntry const* azeriteUnlockMapping : sAzeriteUnlockMappingStore)
azeriteUnlockMappings[azeriteUnlockMapping->AzeriteUnlockMappingSetID].push_back(azeriteUnlockMapping);
ASSERT(BATTLE_PET_SPECIES_MAX_ID >= sBattlePetSpeciesStore.GetNumRows(), ASSERT(BATTLE_PET_SPECIES_MAX_ID >= sBattlePetSpeciesStore.GetNumRows(),
"BATTLE_PET_SPECIES_MAX_ID (%d) must be equal to or greater than %u", BATTLE_PET_SPECIES_MAX_ID, sBattlePetSpeciesStore.GetNumRows()); "BATTLE_PET_SPECIES_MAX_ID (%d) must be equal to or greater than %u", BATTLE_PET_SPECIES_MAX_ID, sBattlePetSpeciesStore.GetNumRows());
@@ -973,6 +1004,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
for (ItemXBonusTreeEntry const* itemBonusTreeAssignment : sItemXBonusTreeStore) for (ItemXBonusTreeEntry const* itemBonusTreeAssignment : sItemXBonusTreeStore)
_itemToBonusTree.insert({ itemBonusTreeAssignment->ItemID, itemBonusTreeAssignment->ItemBonusTreeID }); _itemToBonusTree.insert({ itemBonusTreeAssignment->ItemID, itemBonusTreeAssignment->ItemBonusTreeID });
for (auto&& kvp : _azeriteEmpoweredItems)
LoadAzeriteEmpoweredItemUnlockMappings(azeriteUnlockMappings, kvp.first);
for (MapDifficultyEntry const* entry : sMapDifficultyStore) for (MapDifficultyEntry const* entry : sMapDifficultyStore)
_mapDifficulties[entry->MapID][entry->DifficultyID] = entry; _mapDifficulties[entry->MapID][entry->DifficultyID] = entry;
_mapDifficulties[0][0] = _mapDifficulties[1][0]; // map 0 is missing from MapDifficulty.dbc so we cheat a bit _mapDifficulties[0][0] = _mapDifficulties[1][0]; // map 0 is missing from MapDifficulty.dbc so we cheat a bit
@@ -1493,6 +1527,11 @@ ArtifactPowerRankEntry const* DB2Manager::GetArtifactPowerRank(uint32 artifactPo
return nullptr; return nullptr;
} }
AzeriteEmpoweredItemEntry const* DB2Manager::GetAzeriteEmpoweredItem(uint32 itemId) const
{
return Trinity::Containers::MapGetValuePtr(_azeriteEmpoweredItems, itemId);
}
bool DB2Manager::IsAzeriteItem(uint32 itemId) const bool DB2Manager::IsAzeriteItem(uint32 itemId) const
{ {
return std::find_if(sAzeriteItemStore.begin(), sAzeriteItemStore.end(), return std::find_if(sAzeriteItemStore.begin(), sAzeriteItemStore.end(),
@@ -1515,6 +1554,28 @@ AzeriteItemMilestonePowerEntry const* DB2Manager::GetAzeriteItemMilestonePower(u
return _azeriteItemMilestonePowerByEssenceSlot[slot]; return _azeriteItemMilestonePowerByEssenceSlot[slot];
} }
std::vector<AzeritePowerSetMemberEntry const*> const* DB2Manager::GetAzeritePowers(uint32 itemId) const
{
if (AzeriteEmpoweredItemEntry const* azeriteEmpoweredItem = GetAzeriteEmpoweredItem(itemId))
return Trinity::Containers::MapGetValuePtr(_azeritePowers, azeriteEmpoweredItem->AzeritePowerSetID);
return nullptr;
}
uint32 DB2Manager::GetRequiredAzeriteLevelForAzeritePowerTier(uint32 azeriteUnlockSetId, ItemContext context, uint32 tier) const
{
ASSERT(tier < MAX_AZERITE_EMPOWERED_TIER);
if (std::array<uint8, MAX_AZERITE_EMPOWERED_TIER> const* levels = Trinity::Containers::MapGetValuePtr(_azeriteTierUnlockLevels, std::make_pair(azeriteUnlockSetId, context)))
return (*levels)[tier];
AzeriteTierUnlockSetEntry const* azeriteTierUnlockSet = sAzeriteTierUnlockSetStore.LookupEntry(azeriteUnlockSetId);
if (azeriteTierUnlockSet && azeriteTierUnlockSet->Flags & AZERITE_TIER_UNLOCK_SET_FLAG_DEFAULT)
if (std::array<uint8, MAX_AZERITE_EMPOWERED_TIER> const* levels = Trinity::Containers::MapGetValuePtr(_azeriteTierUnlockLevels, std::make_pair(azeriteUnlockSetId, ItemContext::NONE)))
return (*levels)[tier];
return sAzeriteLevelInfoStore.GetNumRows();
}
char const* DB2Manager::GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale /*= DEFAULT_LOCALE*/, uint8 gender /*= GENDER_MALE*/, bool forceGender /*= false*/) char const* DB2Manager::GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale /*= DEFAULT_LOCALE*/, uint8 gender /*= GENDER_MALE*/, bool forceGender /*= false*/)
{ {
if ((gender == GENDER_FEMALE || gender == GENDER_NONE) && (forceGender || broadcastText->Text1->Str[DEFAULT_LOCALE][0] != '\0')) if ((gender == GENDER_FEMALE || gender == GENDER_NONE) && (forceGender || broadcastText->Text1->Str[DEFAULT_LOCALE][0] != '\0'))
@@ -2017,12 +2078,62 @@ std::set<uint32> DB2Manager::GetItemBonusTree(uint32 itemId, ItemContext itemCon
bonusListIDs.insert((*itemSelectorQuality)->QualityItemBonusListID); bonusListIDs.insert((*itemSelectorQuality)->QualityItemBonusListID);
} }
} }
if (AzeriteUnlockMappingEntry const* azeriteUnlockMapping = Trinity::Containers::MapGetValuePtr(_azeriteUnlockMappings, std::make_pair(proto->ID, itemContext)))
{
switch (proto->InventoryType)
{
case INVTYPE_HEAD:
bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListHead);
break;
case INVTYPE_SHOULDERS:
bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListShoulders);
break;
case INVTYPE_CHEST:
case INVTYPE_ROBE:
bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListChest);
break;
}
}
} }
}); });
return bonusListIDs; return bonusListIDs;
} }
void LoadAzeriteEmpoweredItemUnlockMappings(std::unordered_map<int32, std::vector<AzeriteUnlockMappingEntry const*>> const& azeriteUnlockMappingsBySet, uint32 itemId)
{
ItemSparseEntry const* proto = sItemSparseStore.LookupEntry(itemId);
if (!proto)
return;
VisitItemBonusTree(itemId, [&azeriteUnlockMappingsBySet, proto](ItemBonusTreeNodeEntry const* bonusTreeNode)
{
if (!bonusTreeNode->ChildItemBonusListID && bonusTreeNode->ChildItemLevelSelectorID)
{
ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(bonusTreeNode->ChildItemLevelSelectorID);
if (!selector)
return;
if (std::vector<AzeriteUnlockMappingEntry const*> const* azeriteUnlockMappings = Trinity::Containers::MapGetValuePtr(azeriteUnlockMappingsBySet, selector->AzeriteUnlockMappingSet))
{
AzeriteUnlockMappingEntry const* selectedAzeriteUnlockMapping = nullptr;
for (AzeriteUnlockMappingEntry const* azeriteUnlockMapping : *azeriteUnlockMappings)
{
if (azeriteUnlockMapping->ItemLevel > selector->MinItemLevel ||
(selectedAzeriteUnlockMapping != nullptr && selectedAzeriteUnlockMapping->ItemLevel > azeriteUnlockMapping->ItemLevel))
continue;
selectedAzeriteUnlockMapping = azeriteUnlockMapping;
}
if (selectedAzeriteUnlockMapping)
_azeriteUnlockMappings[std::make_pair(proto->ID, ItemContext(bonusTreeNode->ItemContext))] = selectedAzeriteUnlockMapping;
}
}
});
}
ItemChildEquipmentEntry const* DB2Manager::GetItemChildEquipment(uint32 itemId) const ItemChildEquipmentEntry const* DB2Manager::GetItemChildEquipment(uint32 itemId) const
{ {
auto itr = _itemChildEquipment.find(itemId); auto itr = _itemChildEquipment.find(itemId);
+3
View File
@@ -274,10 +274,13 @@ public:
std::vector<ArtifactPowerEntry const*> GetArtifactPowers(uint8 artifactId) const; std::vector<ArtifactPowerEntry const*> GetArtifactPowers(uint8 artifactId) const;
std::unordered_set<uint32> const* GetArtifactPowerLinks(uint32 artifactPowerId) const; std::unordered_set<uint32> const* GetArtifactPowerLinks(uint32 artifactPowerId) const;
ArtifactPowerRankEntry const* GetArtifactPowerRank(uint32 artifactPowerId, uint8 rank) const; ArtifactPowerRankEntry const* GetArtifactPowerRank(uint32 artifactPowerId, uint8 rank) const;
AzeriteEmpoweredItemEntry const* GetAzeriteEmpoweredItem(uint32 itemId) const;
bool IsAzeriteItem(uint32 itemId) const; bool IsAzeriteItem(uint32 itemId) const;
AzeriteEssencePowerEntry const* GetAzeriteEssencePower(uint32 azeriteEssenceId, uint32 rank) const; AzeriteEssencePowerEntry const* GetAzeriteEssencePower(uint32 azeriteEssenceId, uint32 rank) const;
std::vector<AzeriteItemMilestonePowerEntry const*> const& GetAzeriteItemMilestonePowers() const; std::vector<AzeriteItemMilestonePowerEntry const*> const& GetAzeriteItemMilestonePowers() const;
AzeriteItemMilestonePowerEntry const* GetAzeriteItemMilestonePower(uint8 slot) const; AzeriteItemMilestonePowerEntry const* GetAzeriteItemMilestonePower(uint8 slot) const;
std::vector<AzeritePowerSetMemberEntry const*> const* GetAzeritePowers(uint32 itemId) const;
uint32 GetRequiredAzeriteLevelForAzeritePowerTier(uint32 azeriteUnlockSetId, ItemContext context, uint32 tier) const;
static char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); static char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false);
bool HasCharacterFacialHairStyle(uint8 race, uint8 gender, uint8 variationId) const; bool HasCharacterFacialHairStyle(uint8 race, uint8 gender, uint8 variationId) const;
bool HasCharSections(uint8 race, uint8 gender, CharBaseSectionVariation variation) const; bool HasCharSections(uint8 race, uint8 gender, CharBaseSectionVariation variation) const;
+43
View File
@@ -259,6 +259,14 @@ struct AuctionHouseEntry
uint8 ConsignmentRate; uint8 ConsignmentRate;
}; };
struct AzeriteEmpoweredItemEntry
{
uint32 ID;
int32 ItemID;
uint32 AzeriteTierUnlockSetID;
uint32 AzeritePowerSetID;
};
struct AzeriteEssenceEntry struct AzeriteEssenceEntry
{ {
LocalizedString* Name; LocalizedString* Name;
@@ -318,6 +326,41 @@ struct AzeritePowerEntry
int32 Flags; int32 Flags;
}; };
struct AzeritePowerSetMemberEntry
{
uint32 ID;
int32 AzeritePowerSetID;
int32 AzeritePowerID;
int32 Class;
int32 Tier;
int32 OrderIndex;
};
struct AzeriteTierUnlockEntry
{
uint32 ID;
uint8 ItemCreationContext;
uint8 Tier;
uint8 AzeriteLevel;
uint32 AzeriteTierUnlockSetID;
};
struct AzeriteTierUnlockSetEntry
{
uint32 ID;
int32 Flags;
};
struct AzeriteUnlockMappingEntry
{
uint32 ID;
int32 ItemLevel;
int32 ItemBonusListHead;
int32 ItemBonusListShoulders;
int32 ItemBonusListChest;
uint32 AzeriteUnlockMappingSetID;
};
struct BankBagSlotPricesEntry struct BankBagSlotPricesEntry
{ {
uint32 ID; uint32 ID;
+10 -1
View File
@@ -166,6 +166,8 @@ enum ArtifactPowerFlag : uint8
#define MAX_ARTIFACT_TIER 1 #define MAX_ARTIFACT_TIER 1
#define MAX_AZERITE_EMPOWERED_TIER 5
#define MAX_AZERITE_ESSENCE_SLOT 3 #define MAX_AZERITE_ESSENCE_SLOT 3
#define MAX_AZERITE_ESSENCE_RANK 4 #define MAX_AZERITE_ESSENCE_RANK 4
@@ -176,6 +178,11 @@ enum class AzeriteItemMilestoneType : int32
BonusStamina = 2 BonusStamina = 2
}; };
enum AzeriteTierUnlockSetFlags
{
AZERITE_TIER_UNLOCK_SET_FLAG_DEFAULT = 0x1
};
#define BATTLE_PET_SPECIES_MAX_ID 2796 #define BATTLE_PET_SPECIES_MAX_ID 2796
enum ChrSpecializationFlag enum ChrSpecializationFlag
@@ -801,7 +808,8 @@ enum CharSectionType
enum Curves enum Curves
{ {
CURVE_ID_ARTIFACT_RELIC_ITEM_LEVEL_BONUS = 1718 CURVE_ID_ARTIFACT_RELIC_ITEM_LEVEL_BONUS = 1718,
CURVE_ID_AZERITE_EMPOWERED_ITEM_RESPEC_COST = 6785
}; };
enum Difficulty : uint8 enum Difficulty : uint8
@@ -991,6 +999,7 @@ enum ItemBonusType
ITEM_BONUS_BONDING = 16, ITEM_BONUS_BONDING = 16,
ITEM_BONUS_RELIC_TYPE = 17, ITEM_BONUS_RELIC_TYPE = 17,
ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18, ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18,
ITEM_BONUS_AZERITE_TIER_UNLOCK_SET = 19,
ITEM_BONUS_OVERRIDE_CAN_DISENCHANT = 21, ITEM_BONUS_OVERRIDE_CAN_DISENCHANT = 21,
ITEM_BONUS_OVERRIDE_CAN_SCRAP = 22 ITEM_BONUS_OVERRIDE_CAN_SCRAP = 22
}; };
@@ -0,0 +1,192 @@
/*
* Copyright (C) 2008-2019 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AzeriteEmpoweredItem.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "Player.h"
AzeriteEmpoweredItem::AzeriteEmpoweredItem()
{
m_objectType |= TYPEMASK_AZERITE_EMPOWERED_ITEM;
m_objectTypeId = TYPEID_AZERITE_EMPOWERED_ITEM;
m_azeritePowers = nullptr;
m_maxTier = 0;
}
bool AzeriteEmpoweredItem::Create(ObjectGuid::LowType guidlow, uint32 itemId, ItemContext context, Player const* owner)
{
if (!Item::Create(guidlow, itemId, context, owner))
return false;
InitAzeritePowerData();
return true;
}
void AzeriteEmpoweredItem::SaveToDB(CharacterDatabaseTransaction& trans)
{
Item::SaveToDB(trans);
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED);
stmt->setUInt64(0, GetGUID().GetCounter());
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_INSTANCE_AZERITE_EMPOWERED);
stmt->setUInt64(0, GetGUID().GetCounter());
for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i)
stmt->setInt32(1 + i, m_azeriteEmpoweredItemData->Selections[i]);
trans->Append(stmt);
}
void AzeriteEmpoweredItem::LoadAzeriteEmpoweredItemData(Player const* owner, AzeriteEmpoweredItemData& azeriteEmpoweredItem)
{
InitAzeritePowerData();
bool needSave = false;
if (m_azeritePowers)
{
for (int32 i = MAX_AZERITE_EMPOWERED_TIER; --i >= 0; )
{
int32 selection = azeriteEmpoweredItem.SelectedAzeritePowers[i];
if (GetTierForAzeritePower(Classes(owner->getClass()), selection) != i)
{
needSave = true;
break;
}
SetSelectedAzeritePower(i, selection);
}
}
else
needSave = true;
if (needSave)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_INSTANCE_AZERITE_EMPOWERED);
for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i)
stmt->setInt32(i, m_azeriteEmpoweredItemData->Selections[i]);
stmt->setUInt64(5, GetGUID().GetCounter());
CharacterDatabase.Execute(stmt);
}
}
void AzeriteEmpoweredItem::DeleteFromDB(CharacterDatabaseTransaction& trans, ObjectGuid::LowType itemGuid)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED);
stmt->setUInt64(0, itemGuid);
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
void AzeriteEmpoweredItem::DeleteFromDB(CharacterDatabaseTransaction& trans)
{
AzeriteEmpoweredItem::DeleteFromDB(trans, GetGUID().GetCounter());
Item::DeleteFromDB(trans);
}
uint32 AzeriteEmpoweredItem::GetRequiredAzeriteLevelForTier(uint32 tier) const
{
return sDB2Manager.GetRequiredAzeriteLevelForAzeritePowerTier(_bonusData.AzeriteTierUnlockSetId, GetContext(), tier);
}
int32 AzeriteEmpoweredItem::GetTierForAzeritePower(Classes playerClass, int32 azeritePowerId) const
{
auto azeritePowerItr = std::find_if(m_azeritePowers->begin(), m_azeritePowers->end(), [&](AzeritePowerSetMemberEntry const* power)
{
return power->AzeritePowerID == azeritePowerId && power->Class == playerClass;
});
if (azeritePowerItr != m_azeritePowers->end())
return (*azeritePowerItr)->Tier;
return MAX_AZERITE_EMPOWERED_TIER;
}
void AzeriteEmpoweredItem::SetSelectedAzeritePower(int32 tier, int32 azeritePowerId)
{
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData).ModifyValue(&UF::AzeriteEmpoweredItemData::Selections, uint32(tier)), azeritePowerId);
// Not added to UF::ItemData::BonusListIDs, client fakes it on its own too
_bonusData.AddBonusList(sAzeritePowerStore.AssertEntry(azeritePowerId)->ItemBonusListID);
}
void AzeriteEmpoweredItem::ClearSelectedAzeritePowers()
{
for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i)
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData).ModifyValue(&UF::AzeriteEmpoweredItemData::Selections, i), 0);
_bonusData.Initialize(GetTemplate());
for (int32 bonusListID : *m_itemData->BonusListIDs)
_bonusData.AddBonusList(bonusListID);
}
int64 AzeriteEmpoweredItem::GetRespecCost() const
{
if (Player const* owner = GetOwner())
return int64(GOLD * sDB2Manager.GetCurveValueAt(CURVE_ID_AZERITE_EMPOWERED_ITEM_RESPEC_COST, float(owner->GetNumRespecs())));
return MAX_MONEY_AMOUNT + 1;
}
void AzeriteEmpoweredItem::BuildValuesCreate(ByteBuffer* data, Player const* target) const
{
UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
std::size_t sizePos = data->wpos();
*data << uint32(0);
*data << uint8(flags);
m_objectData->WriteCreate(*data, flags, this, target);
m_itemData->WriteCreate(*data, flags, this, target);
m_azeriteEmpoweredItemData->WriteCreate(*data, flags, this, target);
data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
}
void AzeriteEmpoweredItem::BuildValuesUpdate(ByteBuffer* data, Player const* target) const
{
UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
std::size_t sizePos = data->wpos();
*data << uint32(0);
*data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
if (m_values.HasChanged(TYPEID_ITEM))
m_itemData->WriteUpdate(*data, flags, this, target);
if (m_values.HasChanged(TYPEID_AZERITE_EMPOWERED_ITEM))
m_azeriteEmpoweredItemData->WriteUpdate(*data, flags, this, target);
data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
}
void AzeriteEmpoweredItem::ClearUpdateMask(bool remove)
{
m_values.ClearChangesMask(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData);
Item::ClearUpdateMask(remove);
}
void AzeriteEmpoweredItem::InitAzeritePowerData()
{
m_azeritePowers = sDB2Manager.GetAzeritePowers(GetEntry());
if (m_azeritePowers)
{
m_maxTier = (*std::max_element(m_azeritePowers->begin(), m_azeritePowers->end(), [](AzeritePowerSetMemberEntry const* a1, AzeritePowerSetMemberEntry const* a2)
{
return a1->Tier < a2->Tier;
}))->Tier;
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2008-2019 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef AzeriteEmpoweredItem_h__
#define AzeriteEmpoweredItem_h__
#include "Item.h"
class TC_GAME_API AzeriteEmpoweredItem : public Item
{
public:
AzeriteEmpoweredItem();
bool Create(ObjectGuid::LowType guidlow, uint32 itemId, ItemContext context, Player const* owner) override;
void SaveToDB(CharacterDatabaseTransaction& trans) override;
void LoadAzeriteEmpoweredItemData(Player const* owner, AzeriteEmpoweredItemData& azeriteEmpoweredItem);
static void DeleteFromDB(CharacterDatabaseTransaction& trans, ObjectGuid::LowType itemGuid);
void DeleteFromDB(CharacterDatabaseTransaction& trans) override;
uint32 GetRequiredAzeriteLevelForTier(uint32 tier) const;
int32 GetTierForAzeritePower(Classes playerClass, int32 azeritePowerId) const;
int32 GetMaxAzeritePowerTier() const { return m_maxTier; }
uint32 GetSelectedAzeritePower(int32 tier) const { return uint32(m_azeriteEmpoweredItemData->Selections[uint32(tier)]); }
void SetSelectedAzeritePower(int32 tier, int32 azeritePowerId);
void ClearSelectedAzeritePowers();
int64 GetRespecCost() const;
void BuildValuesCreate(ByteBuffer* data, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
UF::UpdateField<UF::AzeriteEmpoweredItemData, 0, TYPEID_AZERITE_EMPOWERED_ITEM> m_azeriteEmpoweredItemData;
private:
void InitAzeritePowerData();
std::vector<AzeritePowerSetMemberEntry const*> const* m_azeritePowers;
int32 m_maxTier;
};
#endif // AzeriteEmpoweredItem_h__
+46 -10
View File
@@ -18,6 +18,7 @@
#include "Item.h" #include "Item.h"
#include "ArtifactPackets.h" #include "ArtifactPackets.h"
#include "AzeriteEmpoweredItem.h"
#include "AzeriteItem.h" #include "AzeriteItem.h"
#include "Bag.h" #include "Bag.h"
#include "CollectionMgr.h" #include "CollectionMgr.h"
@@ -51,6 +52,9 @@ Item* NewItemOrBag(ItemTemplate const* proto)
if (sDB2Manager.IsAzeriteItem(proto->GetId())) if (sDB2Manager.IsAzeriteItem(proto->GetId()))
return new AzeriteItem(); return new AzeriteItem();
if (sDB2Manager.GetAzeriteEmpoweredItem(proto->GetId()))
return new AzeriteEmpoweredItem();
return new Item(); return new Item();
} }
@@ -285,7 +289,8 @@ static uint32 const IllusionModifierMaskSpecSpecific =
void ItemAdditionalLoadInfo::Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo, void ItemAdditionalLoadInfo::Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo,
PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult,
PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult) PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult,
PreparedQueryResult azeriteEmpoweredItemResult)
{ {
// 0 1 2 3 4 5 // 0 1 2 3 4 5
// SELECT a.itemGuid, a.xp, a.artifactAppearanceId, a.artifactTierId, ap.artifactPowerId, ap.purchasedRank FROM item_instance_artifact_powers ap LEFT JOIN item_instance_artifact a ON ap.itemGuid = a.itemGuid ... // SELECT a.itemGuid, a.xp, a.artifactAppearanceId, a.artifactTierId, ap.artifactPowerId, ap.purchasedRank FROM item_instance_artifact_powers ap LEFT JOIN item_instance_artifact a ON ap.itemGuid = a.itemGuid ...
@@ -396,6 +401,24 @@ void ItemAdditionalLoadInfo::Init(std::unordered_map<ObjectGuid::LowType, ItemAd
} }
while (azeriteItemUnlockedEssencesResult->NextRow()); while (azeriteItemUnlockedEssencesResult->NextRow());
} }
// 0 1 2 3 4 5
// SELECT iae.itemGuid, iae.azeritePowerId1, iae.azeritePowerId2, iae.azeritePowerId3, iae.azeritePowerId4, iae.azeritePowerId5 FROM item_instance_azerite_empowered iae INNER JOIN ...
if (azeriteEmpoweredItemResult)
{
do
{
Field* fields = azeriteEmpoweredItemResult->Fetch();
ItemAdditionalLoadInfo& info = (*loadInfo)[fields[0].GetUInt64()];
if (!info.AzeriteEmpoweredItem)
info.AzeriteEmpoweredItem = boost::in_place();
for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i)
if (sAzeritePowerStore.LookupEntry(fields[1 + i].GetInt32()))
info.AzeriteEmpoweredItem->SelectedAzeritePowers[i] = fields[1 + i].GetInt32();
} while (azeriteEmpoweredItemResult->NextRow());
}
} }
Item::Item() Item::Item()
@@ -1358,9 +1381,7 @@ void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem, uint32 gemScalin
BonusData gemBonus; BonusData gemBonus;
gemBonus.Initialize(gemTemplate); gemBonus.Initialize(gemTemplate);
for (uint16 bonusListId : gem->BonusListIDs) for (uint16 bonusListId : gem->BonusListIDs)
if (DB2Manager::ItemBonusList const* bonuses = sDB2Manager.GetItemBonusList(bonusListId)) gemBonus.AddBonusList(bonusListId);
for (ItemBonusEntry const* itemBonus : *bonuses)
gemBonus.AddBonus(itemBonus->Type, itemBonus->Value);
uint32 gemBaseItemLevel = gemTemplate->GetBaseItemLevel(); uint32 gemBaseItemLevel = gemTemplate->GetBaseItemLevel();
if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(gemBonus.ScalingStatDistribution)) if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(gemBonus.ScalingStatDistribution))
@@ -2508,9 +2529,7 @@ void Item::SetBonuses(std::vector<int32> bonusListIDs)
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::BonusListIDs), std::move(bonusListIDs)); SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::BonusListIDs), std::move(bonusListIDs));
for (int32 bonusListID : *m_itemData->BonusListIDs) for (int32 bonusListID : *m_itemData->BonusListIDs)
if (DB2Manager::ItemBonusList const* bonuses = sDB2Manager.GetItemBonusList(bonusListID)) _bonusData.AddBonusList(bonusListID);
for (ItemBonusEntry const* bonus : *bonuses)
_bonusData.AddBonus(bonus->Type, bonus->Value);
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), _bonusData.AppearanceModID); SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), _bonusData.AppearanceModID);
} }
@@ -2785,11 +2804,16 @@ void BonusData::Initialize(ItemTemplate const* proto)
RelicType = -1; RelicType = -1;
HasFixedLevel = false; HasFixedLevel = false;
RequiredLevelOverride = 0; RequiredLevelOverride = 0;
AzeriteTierUnlockSetId = 0;
if (AzeriteEmpoweredItemEntry const* azeriteEmpoweredItem = sDB2Manager.GetAzeriteEmpoweredItem(proto->GetId()))
AzeriteTierUnlockSetId = azeriteEmpoweredItem->AzeriteTierUnlockSetID;
CanDisenchant = (proto->GetFlags() & ITEM_FLAG_NO_DISENCHANT) == 0; CanDisenchant = (proto->GetFlags() & ITEM_FLAG_NO_DISENCHANT) == 0;
CanScrap = (proto->GetFlags4() & ITEM_FLAG4_SCRAPABLE) != 0; CanScrap = (proto->GetFlags4() & ITEM_FLAG4_SCRAPABLE) != 0;
_state.AppearanceModPriority = std::numeric_limits<int32>::max(); _state.AppearanceModPriority = std::numeric_limits<int32>::max();
_state.ScalingStatDistributionPriority = std::numeric_limits<int32>::max(); _state.ScalingStatDistributionPriority = std::numeric_limits<int32>::max();
_state.AzeriteTierUnlockSetPriority = std::numeric_limits<int32>::max();
_state.HasQualityBonus = false; _state.HasQualityBonus = false;
} }
@@ -2803,9 +2827,14 @@ void BonusData::Initialize(WorldPackets::Item::ItemInstance const& itemInstance)
if (itemInstance.ItemBonus) if (itemInstance.ItemBonus)
for (uint32 bonusListID : itemInstance.ItemBonus->BonusListIDs) for (uint32 bonusListID : itemInstance.ItemBonus->BonusListIDs)
if (DB2Manager::ItemBonusList const* bonuses = sDB2Manager.GetItemBonusList(bonusListID)) AddBonusList(bonusListID);
for (ItemBonusEntry const* bonus : *bonuses) }
AddBonus(bonus->Type, bonus->Value);
void BonusData::AddBonusList(uint32 bonusListId)
{
if (DB2Manager::ItemBonusList const* bonuses = sDB2Manager.GetItemBonusList(bonusListId))
for (ItemBonusEntry const* bonus : *bonuses)
AddBonus(bonus->Type, bonus->Value);
} }
void BonusData::AddBonus(uint32 type, int32 const (&values)[3]) void BonusData::AddBonus(uint32 type, int32 const (&values)[3])
@@ -2883,6 +2912,13 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[3])
case ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL: case ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL:
RequiredLevelOverride = values[0]; RequiredLevelOverride = values[0];
break; break;
case ITEM_BONUS_AZERITE_TIER_UNLOCK_SET:
if (values[1] < _state.AzeriteTierUnlockSetPriority)
{
AzeriteTierUnlockSetId = values[0];
_state.AzeriteTierUnlockSetPriority = values[1];
}
break;
case ITEM_BONUS_OVERRIDE_CAN_DISENCHANT: case ITEM_BONUS_OVERRIDE_CAN_DISENCHANT:
CanDisenchant = values[0] != 0; CanDisenchant = values[0] != 0;
break; break;
+16 -3
View File
@@ -92,12 +92,14 @@ struct BonusData
uint16 GemRelicRankBonus[MAX_ITEM_PROTO_SOCKETS]; uint16 GemRelicRankBonus[MAX_ITEM_PROTO_SOCKETS];
int32 RelicType; int32 RelicType;
int32 RequiredLevelOverride; int32 RequiredLevelOverride;
int32 AzeriteTierUnlockSetId;
bool CanDisenchant; bool CanDisenchant;
bool CanScrap; bool CanScrap;
bool HasFixedLevel; bool HasFixedLevel;
void Initialize(ItemTemplate const* proto); void Initialize(ItemTemplate const* proto);
void Initialize(WorldPackets::Item::ItemInstance const& itemInstance); void Initialize(WorldPackets::Item::ItemInstance const& itemInstance);
void AddBonusList(uint32 bonusListId);
void AddBonus(uint32 type, int32 const (&values)[3]); void AddBonus(uint32 type, int32 const (&values)[3]);
private: private:
@@ -105,6 +107,7 @@ private:
{ {
int32 AppearanceModPriority; int32 AppearanceModPriority;
int32 ScalingStatDistributionPriority; int32 ScalingStatDistributionPriority;
int32 AzeriteTierUnlockSetPriority;
bool HasQualityBonus; bool HasQualityBonus;
} _state; } _state;
}; };
@@ -140,13 +143,19 @@ struct AzeriteItemData
std::array<AzeriteItemSelectedEssencesData, MAX_SPECIALIZATIONS> SelectedAzeriteEssences = { }; std::array<AzeriteItemSelectedEssencesData, MAX_SPECIALIZATIONS> SelectedAzeriteEssences = { };
}; };
struct AzeriteEmpoweredItemData
{
std::array<int32, MAX_AZERITE_EMPOWERED_TIER> SelectedAzeritePowers;
};
struct ItemAdditionalLoadInfo struct ItemAdditionalLoadInfo
{ {
static void Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult, static void Init(std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo>* loadInfo, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult,
PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult); PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult, PreparedQueryResult azeriteEmpoweredItemResult);
Optional<ArtifactData> Artifact; Optional<ArtifactData> Artifact;
Optional<AzeriteItemData> AzeriteItem; Optional<AzeriteItemData> AzeriteItem;
Optional<AzeriteEmpoweredItemData> AzeriteEmpoweredItem;
}; };
struct ItemDynamicFieldGems struct ItemDynamicFieldGems
@@ -231,14 +240,17 @@ class TC_GAME_API Item : public Object
void SaveRefundDataToDB(); void SaveRefundDataToDB();
void DeleteRefundDataFromDB(CharacterDatabaseTransaction* trans); void DeleteRefundDataFromDB(CharacterDatabaseTransaction* trans);
Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return NULL; } Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return nullptr; }
const Bag* ToBag() const { if (IsBag()) return reinterpret_cast<const Bag*>(this); else return NULL; } Bag const* ToBag() const { if (IsBag()) return reinterpret_cast<Bag const*>(this); else return nullptr; }
AzeriteItem* ToAzeriteItem() { return IsAzeriteItem() ? reinterpret_cast<AzeriteItem*>(this) : nullptr; } AzeriteItem* ToAzeriteItem() { return IsAzeriteItem() ? reinterpret_cast<AzeriteItem*>(this) : nullptr; }
AzeriteItem const* ToAzeriteItem() const { return IsAzeriteItem() ? reinterpret_cast<AzeriteItem const*>(this) : nullptr; } AzeriteItem const* ToAzeriteItem() const { return IsAzeriteItem() ? reinterpret_cast<AzeriteItem const*>(this) : nullptr; }
AzeriteEmpoweredItem* ToAzeriteEmpoweredItem() { return IsAzeriteEmpoweredItem() ? reinterpret_cast<AzeriteEmpoweredItem*>(this) : nullptr; }
AzeriteEmpoweredItem const* ToAzeriteEmpoweredItem() const { return IsAzeriteEmpoweredItem() ? reinterpret_cast<AzeriteEmpoweredItem const*>(this) : nullptr; }
bool IsLocked() const { return !HasItemFlag(ITEM_FIELD_FLAG_UNLOCKED); } bool IsLocked() const { return !HasItemFlag(ITEM_FIELD_FLAG_UNLOCKED); }
bool IsBag() const { return GetTemplate()->GetInventoryType() == INVTYPE_BAG; } bool IsBag() const { return GetTemplate()->GetInventoryType() == INVTYPE_BAG; }
bool IsAzeriteItem() const { return GetTypeId() == TYPEID_AZERITE_ITEM; } bool IsAzeriteItem() const { return GetTypeId() == TYPEID_AZERITE_ITEM; }
bool IsAzeriteEmpoweredItem() const { return GetTypeId() == TYPEID_AZERITE_EMPOWERED_ITEM; }
bool IsCurrencyToken() const { return GetTemplate()->IsCurrencyToken(); } bool IsCurrencyToken() const { return GetTemplate()->IsCurrencyToken(); }
bool IsNotEmptyBag() const; bool IsNotEmptyBag() const;
bool IsBroken() const { return *m_itemData->MaxDurability > 0 && *m_itemData->Durability == 0; } bool IsBroken() const { return *m_itemData->MaxDurability > 0 && *m_itemData->Durability == 0; }
@@ -411,6 +423,7 @@ class TC_GAME_API Item : public Object
UF::UpdateField<UF::ItemData, 0, TYPEID_ITEM> m_itemData; UF::UpdateField<UF::ItemData, 0, TYPEID_ITEM> m_itemData;
protected: protected:
void ApplyBonusList(uint32 itemBonusListId);
BonusData _bonusData; BonusData _bonusData;
private: private:
+2 -2
View File
@@ -157,7 +157,7 @@ enum ItemFieldFlags : uint32
ITEM_FIELD_FLAG_CHILD = 0x00080000, ITEM_FIELD_FLAG_CHILD = 0x00080000,
ITEM_FIELD_FLAG_UNK15 = 0x00100000, ITEM_FIELD_FLAG_UNK15 = 0x00100000,
ITEM_FIELD_FLAG_NEW_ITEM = 0x00200000, // Item glows in inventory ITEM_FIELD_FLAG_NEW_ITEM = 0x00200000, // Item glows in inventory
ITEM_FIELD_FLAG_UNK17 = 0x00400000, ITEM_FIELD_FLAG_AZERITE_EMPOWERED_ITEM_VIEWED = 0x00400000, // Won't play azerite powers animation when viewing it
ITEM_FIELD_FLAG_UNK18 = 0x00800000, ITEM_FIELD_FLAG_UNK18 = 0x00800000,
ITEM_FIELD_FLAG_UNK19 = 0x01000000, ITEM_FIELD_FLAG_UNK19 = 0x01000000,
ITEM_FIELD_FLAG_UNK20 = 0x02000000, ITEM_FIELD_FLAG_UNK20 = 0x02000000,
@@ -171,7 +171,7 @@ enum ItemFieldFlags : uint32
enum ItemFieldFlags2 : uint32 enum ItemFieldFlags2 : uint32
{ {
ITEM_FIELD_FLAG2_HEART_OF_AZEROTH_EQUIPPED = 0x1 ITEM_FIELD_FLAG2_EQUIPPED = 0x1
}; };
enum ItemFlags : uint32 enum ItemFlags : uint32
+81 -6
View File
@@ -22,6 +22,7 @@
#include "AchievementMgr.h" #include "AchievementMgr.h"
#include "ArenaTeam.h" #include "ArenaTeam.h"
#include "ArenaTeamMgr.h" #include "ArenaTeamMgr.h"
#include "AzeriteEmpoweredItem.h"
#include "AzeriteItem.h" #include "AzeriteItem.h"
#include "Bag.h" #include "Bag.h"
#include "Battlefield.h" #include "Battlefield.h"
@@ -3853,8 +3854,13 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid); stmt->setUInt64(0, guid);
PreparedQueryResult azeriteItemUnlockedEssencesResult = CharacterDatabase.Query(stmt); PreparedQueryResult azeriteItemUnlockedEssencesResult = CharacterDatabase.Query(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_EMPOWERED);
stmt->setUInt64(0, guid);
PreparedQueryResult azeriteEmpoweredItemResult = CharacterDatabase.Query(stmt);
std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData; std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData;
ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult); ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult,
azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult);
do do
{ {
@@ -4078,6 +4084,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid); stmt->setUInt64(0, guid);
trans->Append(stmt); trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED_BY_OWNER);
stmt->setUInt64(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER);
stmt->setUInt64(0, guid); stmt->setUInt64(0, guid);
trans->Append(stmt); trans->Append(stmt);
@@ -7934,6 +7944,13 @@ void Player::ApplyAzeritePowers(Item* item, bool apply)
ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[slot], azeriteItem->GetEssenceRank(selectedEssences->AzeriteEssenceID[slot]), ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[slot], azeriteItem->GetEssenceRank(selectedEssences->AzeriteEssenceID[slot]),
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(slot)->Type) == AzeriteItemMilestoneType::MajorEssence, apply); AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(slot)->Type) == AzeriteItemMilestoneType::MajorEssence, apply);
} }
else if (AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem())
{
if (!apply || GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_IN_EQUIPMENT))
for (int32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i)
if (AzeritePowerEntry const* azeritePower = sAzeritePowerStore.LookupEntry(azeriteEmpoweredItem->GetSelectedAzeritePower(i)))
ApplyAzeritePower(azeriteEmpoweredItem, azeritePower, apply);
}
} }
void Player::ApplyAzeriteItemMilestonePower(AzeriteItem* item, AzeriteItemMilestonePowerEntry const* azeriteItemMilestonePower, bool apply) void Player::ApplyAzeriteItemMilestonePower(AzeriteItem* item, AzeriteItemMilestonePowerEntry const* azeriteItemMilestonePower, bool apply)
@@ -8001,6 +8018,17 @@ void Player::ApplyAzeriteEssencePower(AzeriteItem* item, AzeriteEssencePowerEntr
} }
} }
void Player::ApplyAzeritePower(AzeriteEmpoweredItem* item, AzeritePowerEntry const* azeritePower, bool apply)
{
if (apply)
{
if (!azeritePower->SpecSetID || sDB2Manager.IsSpecSetMember(azeritePower->SpecSetID, GetPrimarySpecialization()))
CastSpell(this, azeritePower->SpellID, true, item);
}
else
RemoveAurasDueToItemSpell(azeritePower->SpellID, item->GetGUID());
}
void Player::CastItemCombatSpell(DamageInfo const& damageInfo) void Player::CastItemCombatSpell(DamageInfo const& damageInfo)
{ {
Unit* target = damageInfo.GetVictim(); Unit* target = damageInfo.GetVictim();
@@ -8393,6 +8421,20 @@ void Player::ApplyAllAzeriteItemMods(bool apply)
} }
} }
void Player::ApplyAllAzeriteEmpoweredItemMods(bool apply)
{
for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
{
if (m_items[i])
{
if (!m_items[i]->IsAzeriteEmpoweredItem() || m_items[i]->IsBroken() || !CanUseAttackType(Player::GetAttackBySlot(i, m_items[i]->GetTemplate()->GetInventoryType())))
continue;
ApplyAzeritePowers(m_items[i], apply);
}
}
}
ObjectGuid Player::GetLootWorldObjectGUID(ObjectGuid const& lootObjectGuid) const ObjectGuid Player::GetLootWorldObjectGUID(ObjectGuid const& lootObjectGuid) const
{ {
auto itr = m_AELootView.find(lootObjectGuid); auto itr = m_AELootView.find(lootObjectGuid);
@@ -12158,6 +12200,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
} }
} }
pItem->AddItemFlag2(ITEM_FIELD_FLAG2_EQUIPPED);
if (IsInWorld() && update) if (IsInWorld() && update)
{ {
pItem->AddToWorld(); pItem->AddToWorld();
@@ -12331,6 +12375,8 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem)
uint8 slot = pos & 255; uint8 slot = pos & 255;
VisualizeItem(slot, pItem); VisualizeItem(slot, pItem);
pItem->AddItemFlag2(ITEM_FIELD_FLAG2_EQUIPPED);
if (IsInWorld()) if (IsInWorld())
{ {
pItem->AddToWorld(); pItem->AddToWorld();
@@ -12425,6 +12471,8 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update)
_ApplyItemMods(pItem, slot, false, update); _ApplyItemMods(pItem, slot, false, update);
pItem->RemoveItemFlag2(ITEM_FIELD_FLAG2_EQUIPPED);
// remove item dependent auras and casts (only weapon and armor slots) // remove item dependent auras and casts (only weapon and armor slots)
if (slot < EQUIPMENT_SLOT_END) if (slot < EQUIPMENT_SLOT_END)
{ {
@@ -17744,8 +17792,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
//"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " //"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
// 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 // 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
//"health, power1, power2, power3, power4, power5, power6, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, raidDifficulty, legacyRaidDifficulty, fishing_steps " //"health, power1, power2, power3, power4, power5, power6, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, raidDifficulty, legacyRaidDifficulty, fishing_steps "
// 72 73 74 75 76 // 72 73 74 75 76
//"honor, honorLevel, prestigeLevel, honor_rest_state, honor_rest_bonus " //"honor, honorLevel, honor_rest_state, honor_rest_bonus, numRespecs "
// //
//"FROM characters WHERE guid = ?", CONNECTION_ASYNC); //"FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM); PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
@@ -18270,6 +18318,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
_LoadSkills(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SKILLS)); _LoadSkills(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SKILLS));
UpdateSkillsForLevel(); //update skills after load, to make sure they are correctly update at player load UpdateSkillsForLevel(); //update skills after load, to make sure they are correctly update at player load
SetNumRespecs(fields[76].GetUInt8());
SetPrimarySpecialization(fields[36].GetUInt32()); SetPrimarySpecialization(fields[36].GetUInt32());
SetActiveTalentGroup(fields[64].GetUInt8()); SetActiveTalentGroup(fields[64].GetUInt8());
ChrSpecializationEntry const* primarySpec = sChrSpecializationStore.LookupEntry(GetPrimarySpecialization()); ChrSpecializationEntry const* primarySpec = sChrSpecializationStore.LookupEntry(GetPrimarySpecialization());
@@ -18324,6 +18373,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE),
holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE_MILESTONE_POWERS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE_MILESTONE_POWERS),
holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES),
holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AZERITE_EMPOWERED),
time_diff); time_diff);
if (IsVoidStorageUnlocked()) if (IsVoidStorageUnlocked())
@@ -18723,7 +18773,8 @@ void Player::LoadCorpse(PreparedQueryResult result)
} }
void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, PreparedQueryResult azeriteResult, void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, PreparedQueryResult azeriteResult,
PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult, uint32 timeDiff) PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult,
PreparedQueryResult azeriteEmpoweredItemResult, uint32 timeDiff)
{ {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 // 0 1 2 3 4 5 6 7 8 9 10 11 12
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text,
@@ -18754,7 +18805,8 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
//expected to be equipped before offhand items (@todo fixme) //expected to be equipped before offhand items (@todo fixme)
std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData; std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData;
ItemAdditionalLoadInfo::Init(&additionalData, artifactsResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult); ItemAdditionalLoadInfo::Init(&additionalData, artifactsResult, azeriteResult, azeriteItemMilestonePowersResult,
azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult);
if (result) if (result)
{ {
@@ -18781,6 +18833,10 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
if (addionalDataPtr->AzeriteItem) if (addionalDataPtr->AzeriteItem)
if (AzeriteItem* azeriteItem = item->ToAzeriteItem()) if (AzeriteItem* azeriteItem = item->ToAzeriteItem())
azeriteItem->LoadAzeriteItemData(this, *addionalDataPtr->AzeriteItem); azeriteItem->LoadAzeriteItemData(this, *addionalDataPtr->AzeriteItem);
if (addionalDataPtr->AzeriteEmpoweredItem)
if (AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem())
azeriteEmpoweredItem->LoadAzeriteEmpoweredItemData(this, *addionalDataPtr->AzeriteEmpoweredItem);
} }
ObjectGuid bagGuid = fields[43].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[43].GetUInt64()) : ObjectGuid::Empty; ObjectGuid bagGuid = fields[43].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[43].GetUInt64()) : ObjectGuid::Empty;
@@ -19087,6 +19143,7 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction& trans, uint32 zoneId, uint
Item::DeleteFromInventoryDB(trans, itemGuid); Item::DeleteFromInventoryDB(trans, itemGuid);
Item::DeleteFromDB(trans, itemGuid); Item::DeleteFromDB(trans, itemGuid);
AzeriteItem::DeleteFromDB(trans, itemGuid); AzeriteItem::DeleteFromDB(trans, itemGuid);
AzeriteEmpoweredItem::DeleteFromDB(trans, itemGuid);
} }
return item; return item;
} }
@@ -19111,6 +19168,7 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint
Item::DeleteFromDB(trans, itemGuid); Item::DeleteFromDB(trans, itemGuid);
AzeriteItem::DeleteFromDB(trans, itemGuid); AzeriteItem::DeleteFromDB(trans, itemGuid);
AzeriteEmpoweredItem::DeleteFromDB(trans, itemGuid);
CharacterDatabase.CommitTransaction(trans); CharacterDatabase.CommitTransaction(trans);
return nullptr; return nullptr;
@@ -19143,6 +19201,10 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint
if (addionalData->AzeriteItem) if (addionalData->AzeriteItem)
if (AzeriteItem* azeriteItem = item->ToAzeriteItem()) if (AzeriteItem* azeriteItem = item->ToAzeriteItem())
azeriteItem->LoadAzeriteItemData(player, *addionalData->AzeriteItem); azeriteItem->LoadAzeriteItemData(player, *addionalData->AzeriteItem);
if (addionalData->AzeriteEmpoweredItem)
if (AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem())
azeriteEmpoweredItem->LoadAzeriteEmpoweredItemData(player, *addionalData->AzeriteEmpoweredItem);
} }
if (mail) if (mail)
@@ -19234,8 +19296,13 @@ void Player::_LoadMail()
stmt->setUInt64(0, GetGUID().GetCounter()); stmt->setUInt64(0, GetGUID().GetCounter());
PreparedQueryResult azeriteItemUnlockedEssencesResult = CharacterDatabase.Query(stmt); PreparedQueryResult azeriteItemUnlockedEssencesResult = CharacterDatabase.Query(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_EMPOWERED);
stmt->setUInt64(0, GetGUID().GetCounter());
PreparedQueryResult azeriteEmpoweredItemResult = CharacterDatabase.Query(stmt);
std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData; std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData;
ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult); ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult,
azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult);
do do
{ {
@@ -20328,6 +20395,7 @@ void Player::SaveToDB(bool create /*=false*/)
//save, but in tavern/city //save, but in tavern/city
stmt->setUInt32(index++, GetTalentResetCost()); stmt->setUInt32(index++, GetTalentResetCost());
stmt->setUInt32(index++, GetTalentResetTime()); stmt->setUInt32(index++, GetTalentResetTime());
stmt->setUInt8(index++, GetNumRespecs());
stmt->setUInt32(index++, GetPrimarySpecialization()); stmt->setUInt32(index++, GetPrimarySpecialization());
stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots); stmt->setUInt8(index++, m_stableSlots);
@@ -20849,6 +20917,7 @@ void Player::_SaveMail(CharacterDatabaseTransaction& trans)
{ {
Item::DeleteFromDB(trans, itr2->item_guid); Item::DeleteFromDB(trans, itr2->item_guid);
AzeriteItem::DeleteFromDB(trans, itr2->item_guid); AzeriteItem::DeleteFromDB(trans, itr2->item_guid);
AzeriteEmpoweredItem::DeleteFromDB(trans, itr2->item_guid);
} }
} }
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
@@ -27226,12 +27295,18 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec)
if (AzeriteItem* azeriteItem = item->ToAzeriteItem()) if (AzeriteItem* azeriteItem = item->ToAzeriteItem())
{ {
if (azeriteItem->IsEquipped()) if (azeriteItem->IsEquipped())
{
ApplyAllAzeriteEmpoweredItemMods(false);
ApplyAzeritePowers(azeriteItem, false); ApplyAzeritePowers(azeriteItem, false);
}
azeriteItem->SetSelectedAzeriteEssences(spec->ID); azeriteItem->SetSelectedAzeriteEssences(spec->ID);
if (azeriteItem->IsEquipped()) if (azeriteItem->IsEquipped())
{
ApplyAzeritePowers(azeriteItem, true); ApplyAzeritePowers(azeriteItem, true);
ApplyAllAzeriteEmpoweredItemMods(true);
}
azeriteItem->SetState(ITEM_CHANGED, this); azeriteItem->SetState(ITEM_CHANGED, this);
} }
+9 -1
View File
@@ -41,6 +41,7 @@ struct AreaTriggerEntry;
struct ArtifactPowerRankEntry; struct ArtifactPowerRankEntry;
struct AzeriteEssencePowerEntry; struct AzeriteEssencePowerEntry;
struct AzeriteItemMilestonePowerEntry; struct AzeriteItemMilestonePowerEntry;
struct AzeritePowerEntry;
struct BarberShopStyleEntry; struct BarberShopStyleEntry;
struct CharTitlesEntry; struct CharTitlesEntry;
struct ChatChannelsEntry; struct ChatChannelsEntry;
@@ -766,6 +767,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_AZERITE, PLAYER_LOGIN_QUERY_LOAD_AZERITE,
PLAYER_LOGIN_QUERY_LOAD_AZERITE_MILESTONE_POWERS, PLAYER_LOGIN_QUERY_LOAD_AZERITE_MILESTONE_POWERS,
PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES, PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES,
PLAYER_LOGIN_QUERY_LOAD_AZERITE_EMPOWERED,
PLAYER_LOGIN_QUERY_LOAD_ACTIONS, PLAYER_LOGIN_QUERY_LOAD_ACTIONS,
PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT, PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT,
PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE, PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE,
@@ -2015,6 +2017,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _ApplyAllItemMods(); void _ApplyAllItemMods();
void _ApplyAllLevelScaleItemMods(bool apply); void _ApplyAllLevelScaleItemMods(bool apply);
void ApplyAllAzeriteItemMods(bool apply); void ApplyAllAzeriteItemMods(bool apply);
void ApplyAllAzeriteEmpoweredItemMods(bool apply);
void _ApplyItemBonuses(Item* item, uint8 slot, bool apply); void _ApplyItemBonuses(Item* item, uint8 slot, bool apply);
void _ApplyWeaponDamage(uint8 slot, Item* item, bool apply); void _ApplyWeaponDamage(uint8 slot, Item* item, bool apply);
bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) const; bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) const;
@@ -2032,6 +2035,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void ApplyAzeriteItemMilestonePower(AzeriteItem* item, AzeriteItemMilestonePowerEntry const* azeriteItemMilestonePower, bool apply); void ApplyAzeriteItemMilestonePower(AzeriteItem* item, AzeriteItemMilestonePowerEntry const* azeriteItemMilestonePower, bool apply);
void ApplyAzeriteEssence(AzeriteItem* item, uint32 azeriteEssenceId, uint32 rank, bool major, bool apply); void ApplyAzeriteEssence(AzeriteItem* item, uint32 azeriteEssenceId, uint32 rank, bool major, bool apply);
void ApplyAzeriteEssencePower(AzeriteItem* item, AzeriteEssencePowerEntry const* azeriteEssencePower, bool major, bool apply); void ApplyAzeriteEssencePower(AzeriteItem* item, AzeriteEssencePowerEntry const* azeriteEssencePower, bool major, bool apply);
void ApplyAzeritePower(AzeriteEmpoweredItem* item, AzeritePowerEntry const* azeritePower, bool apply);
void CastItemCombatSpell(DamageInfo const& damageInfo); void CastItemCombatSpell(DamageInfo const& damageInfo);
void CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto); void CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto);
@@ -2450,6 +2454,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void RemovePlayerLocalFlag(PlayerLocalFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::LocalFlags), flags); } void RemovePlayerLocalFlag(PlayerLocalFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::LocalFlags), flags); }
void SetPlayerLocalFlags(PlayerLocalFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::LocalFlags), flags); } void SetPlayerLocalFlags(PlayerLocalFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::LocalFlags), flags); }
uint8 GetNumRespecs() const { return m_activePlayerData->NumRespecs; }
void SetNumRespecs(uint8 numRespecs) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::NumRespecs), numRespecs); }
void SetWatchedFactionIndex(int32 index) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::WatchedFactionIndex), index); } void SetWatchedFactionIndex(int32 index) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::WatchedFactionIndex), index); }
void AddAuraVision(PlayerFieldByte2Flags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::AuraVision), flags); } void AddAuraVision(PlayerFieldByte2Flags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::AuraVision), flags); }
@@ -2510,7 +2517,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadGlyphAuras(); void _LoadGlyphAuras();
void _LoadBoundInstances(PreparedQueryResult result); void _LoadBoundInstances(PreparedQueryResult result);
void _LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, PreparedQueryResult azeriteResult, void _LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, PreparedQueryResult azeriteResult,
PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult, uint32 timeDiff); PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult,
PreparedQueryResult azeriteEmpoweredItemResult, uint32 timeDiff);
void _LoadVoidStorage(PreparedQueryResult result); void _LoadVoidStorage(PreparedQueryResult result);
void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery); void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery);
void _LoadMail(); void _LoadMail();
+2
View File
@@ -18,6 +18,7 @@
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "ArenaTeamMgr.h" #include "ArenaTeamMgr.h"
#include "AzeriteEmpoweredItem.h"
#include "AzeriteItem.h" #include "AzeriteItem.h"
#include "Chat.h" #include "Chat.h"
#include "Containers.h" #include "Containers.h"
@@ -5874,6 +5875,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
{ {
Item::DeleteFromDB(nonTransactional, itr2->item_guid); Item::DeleteFromDB(nonTransactional, itr2->item_guid);
AzeriteItem::DeleteFromDB(nonTransactional, itr2->item_guid); AzeriteItem::DeleteFromDB(nonTransactional, itr2->item_guid);
AzeriteEmpoweredItem::DeleteFromDB(nonTransactional, itr2->item_guid);
} }
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
@@ -16,6 +16,7 @@
*/ */
#include "WorldSession.h" #include "WorldSession.h"
#include "AzeriteEmpoweredItem.h"
#include "AzeriteItem.h" #include "AzeriteItem.h"
#include "AzeritePackets.h" #include "AzeritePackets.h"
#include "DB2Stores.h" #include "DB2Stores.h"
@@ -168,3 +169,67 @@ void WorldSession::HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::Az
azeriteItem->SetState(ITEM_CHANGED, _player); azeriteItem->SetState(ITEM_CHANGED, _player);
} }
void WorldSession::HandleAzeriteEmpoweredItemViewed(WorldPackets::Azerite::AzeriteEmpoweredItemViewed& azeriteEmpoweredItemViewed)
{
Item* item = _player->GetItemByGuid(azeriteEmpoweredItemViewed.ItemGUID);
if (!item || !item->IsAzeriteEmpoweredItem())
return;
item->AddItemFlag(ITEM_FIELD_FLAG_AZERITE_EMPOWERED_ITEM_VIEWED);
item->SetState(ITEM_CHANGED, _player);
}
void WorldSession::HandleAzeriteEmpoweredItemSelectPower(WorldPackets::Azerite::AzeriteEmpoweredItemSelectPower& azeriteEmpoweredItemSelectPower)
{
Item* item = _player->GetItemByPos(azeriteEmpoweredItemSelectPower.ContainerSlot, azeriteEmpoweredItemSelectPower.Slot);
if (!item)
return;
AzeritePowerEntry const* azeritePower = sAzeritePowerStore.LookupEntry(azeriteEmpoweredItemSelectPower.AzeritePowerID);
if (!azeritePower)
return;
AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem();
if (!azeriteEmpoweredItem)
return;
// Validate tier
int32 actualTier = azeriteEmpoweredItem->GetTierForAzeritePower(Classes(_player->getClass()), azeriteEmpoweredItemSelectPower.AzeritePowerID);
if (azeriteEmpoweredItemSelectPower.Tier > MAX_AZERITE_EMPOWERED_TIER || azeriteEmpoweredItemSelectPower.Tier != actualTier)
return;
uint32 azeriteLevel = 0;
Item const* heartOfAzeroth = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ITEM_SEARCH_EVERYWHERE);
if (!heartOfAzeroth)
return;
if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem())
azeriteLevel = azeriteItem->GetEffectiveLevel();
// Check required heart of azeroth level
if (azeriteLevel < azeriteEmpoweredItem->GetRequiredAzeriteLevelForTier(uint32(actualTier)))
return;
// tiers are ordered backwards, you first select the highest one
for (int32 i = actualTier + 1; i < azeriteEmpoweredItem->GetMaxAzeritePowerTier(); ++i)
if (!azeriteEmpoweredItem->GetSelectedAzeritePower(i))
return;
bool activateAzeritePower = azeriteEmpoweredItem->IsEquipped() && heartOfAzeroth->IsEquipped();
if (azeritePower->ItemBonusListID && activateAzeritePower)
_player->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), false);
azeriteEmpoweredItem->SetSelectedAzeritePower(actualTier, azeriteEmpoweredItemSelectPower.AzeritePowerID);
if (activateAzeritePower)
{
// apply all item mods when azerite power grants a bonus, item level changes and that affects stats and auras that scale with item level
if (azeritePower->ItemBonusListID)
_player->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), true);
else
_player->ApplyAzeritePower(azeriteEmpoweredItem, azeritePower, true);
}
azeriteEmpoweredItem->SetState(ITEM_CHANGED, _player);
}
@@ -164,6 +164,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(0, lowGuid); stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES, stmt); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES, stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEM_INSTANCE_AZERITE_EMPOWERED);
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_AZERITE_EMPOWERED, stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_VOID_STORAGE); stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_VOID_STORAGE);
stmt->setUInt64(0, lowGuid); stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE, stmt); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE, stmt);
@@ -55,3 +55,31 @@ WorldPacket const* WorldPackets::Azerite::AzeriteEssenceSelectionResult::Write()
return &_worldPacket; return &_worldPacket;
} }
void WorldPackets::Azerite::AzeriteEmpoweredItemViewed::Read()
{
_worldPacket >> ItemGUID;
}
void WorldPackets::Azerite::AzeriteEmpoweredItemSelectPower::Read()
{
_worldPacket >> Tier;
_worldPacket >> AzeritePowerID;
_worldPacket >> ContainerSlot;
_worldPacket >> Slot;
}
WorldPacket const* WorldPackets::Azerite::AzeriteEmpoweredItemEquippedStatusChanged::Write()
{
_worldPacket.WriteBit(IsHeartEquipped);
_worldPacket.FlushBits();
return &_worldPacket;
}
WorldPacket const* WorldPackets::Azerite::AzeriteEmpoweredItemRespecOpen::Write()
{
_worldPacket << NpcGUID;
return &_worldPacket;
}
@@ -89,6 +89,49 @@ namespace WorldPackets
int32 AzeriteEssenceID = 0; int32 AzeriteEssenceID = 0;
Optional<uint8> Slot; Optional<uint8> Slot;
}; };
class AzeriteEmpoweredItemViewed final : public ClientPacket
{
public:
AzeriteEmpoweredItemViewed(WorldPacket&& packet) : ClientPacket(CMSG_AZERITE_EMPOWERED_ITEM_VIEWED, std::move(packet)) { }
void Read() override;
ObjectGuid ItemGUID;
};
class AzeriteEmpoweredItemSelectPower final : public ClientPacket
{
public:
AzeriteEmpoweredItemSelectPower(WorldPacket&& packet) : ClientPacket(CMSG_AZERITE_EMPOWERED_ITEM_SELECT_POWER, std::move(packet)) { }
void Read() override;
int32 Tier = 0;
int32 AzeritePowerID = 0;
uint8 ContainerSlot = 0;
uint8 Slot = 0;
};
class AzeriteEmpoweredItemEquippedStatusChanged final : public ServerPacket
{
public:
AzeriteEmpoweredItemEquippedStatusChanged() : ServerPacket(SMSG_AZERITE_EMPOWERED_ITEM_EQUIPPED_STATUS_CHANGED, 1) { }
WorldPacket const* Write() override;
bool IsHeartEquipped = false;
};
class AzeriteEmpoweredItemRespecOpen final : public ServerPacket
{
public:
AzeriteEmpoweredItemRespecOpen(ObjectGuid npcGuid) : ServerPacket(SMSG_AZERITE_EMPOWERED_ITEM_RESPEC_OPEN, 1), NpcGUID(npcGuid) { }
WorldPacket const* Write() override;
ObjectGuid NpcGUID;
};
} }
} }
+4 -4
View File
@@ -182,8 +182,8 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode); DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode);
DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode); DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode);
DEFINE_HANDLER(CMSG_AUTO_STORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode); DEFINE_HANDLER(CMSG_AUTO_STORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode);
DEFINE_HANDLER(CMSG_AZERITE_EMPOWERED_ITEM_SELECT_POWER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_AZERITE_EMPOWERED_ITEM_SELECT_POWER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAzeriteEmpoweredItemSelectPower);
DEFINE_HANDLER(CMSG_AZERITE_EMPOWERED_ITEM_VIEWED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_AZERITE_EMPOWERED_ITEM_VIEWED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAzeriteEmpoweredItemViewed);
DEFINE_HANDLER(CMSG_AZERITE_ESSENCE_ACTIVATE_ESSENCE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAzeriteEssenceActivateEssence); DEFINE_HANDLER(CMSG_AZERITE_ESSENCE_ACTIVATE_ESSENCE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAzeriteEssenceActivateEssence);
DEFINE_HANDLER(CMSG_AZERITE_ESSENCE_UNLOCK_MILESTONE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAzeriteEssenceUnlockMilestone); DEFINE_HANDLER(CMSG_AZERITE_ESSENCE_UNLOCK_MILESTONE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAzeriteEssenceUnlockMilestone);
DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode); DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode);
@@ -947,8 +947,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AVAILABLE_HOTFIXES, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AVAILABLE_HOTFIXES, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_EMPOWERED_ITEM_EQUIPPED_STATUS_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_EMPOWERED_ITEM_EQUIPPED_STATUS_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_EMPOWERED_ITEM_RESPEC_OPEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_EMPOWERED_ITEM_RESPEC_OPEN, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_ESSENCE_FORGE_CLOSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_ESSENCE_FORGE_CLOSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_ESSENCE_FORGE_OPENED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_ESSENCE_FORGE_OPENED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_ESSENCE_SELECTION_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AZERITE_ESSENCE_SELECTION_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+4
View File
@@ -111,6 +111,8 @@ namespace WorldPackets
namespace Azerite namespace Azerite
{ {
class AzeriteEmpoweredItemSelectPower;
class AzeriteEmpoweredItemViewed;
class AzeriteEssenceUnlockMilestone; class AzeriteEssenceUnlockMilestone;
class AzeriteEssenceActivateEssence; class AzeriteEssenceActivateEssence;
} }
@@ -1727,6 +1729,8 @@ class TC_GAME_API WorldSession
// Azerite // Azerite
void HandleAzeriteEssenceUnlockMilestone(WorldPackets::Azerite::AzeriteEssenceUnlockMilestone& azeriteEssenceUnlockMilestone); void HandleAzeriteEssenceUnlockMilestone(WorldPackets::Azerite::AzeriteEssenceUnlockMilestone& azeriteEssenceUnlockMilestone);
void HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::AzeriteEssenceActivateEssence& azeriteEssenceActivateEssence); void HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::AzeriteEssenceActivateEssence& azeriteEssenceActivateEssence);
void HandleAzeriteEmpoweredItemViewed(WorldPackets::Azerite::AzeriteEmpoweredItemViewed& azeriteEmpoweredItemViewed);
void HandleAzeriteEmpoweredItemSelectPower(WorldPackets::Azerite::AzeriteEmpoweredItemSelectPower& azeriteEmpoweredItemSelectPower);
union ConnectToKey union ConnectToKey
{ {
+32
View File
@@ -17,6 +17,7 @@
*/ */
#include "Spell.h" #include "Spell.h"
#include "AzeriteEmpoweredItem.h"
#include "Battlefield.h" #include "Battlefield.h"
#include "BattlefieldMgr.h" #include "BattlefieldMgr.h"
#include "Battleground.h" #include "Battleground.h"
@@ -6717,6 +6718,37 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
} }
break; break;
} }
case SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM:
{
Item const* item = m_targets.GetItemTarget();
if (!item)
return SPELL_FAILED_AZERITE_EMPOWERED_ONLY;
if (item->GetOwnerGUID() != m_caster->GetGUID())
return SPELL_FAILED_DONT_REPORT;
AzeriteEmpoweredItem const* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem();
if (!azeriteEmpoweredItem)
return SPELL_FAILED_AZERITE_EMPOWERED_ONLY;
bool hasSelections = false;
for (int32 tier = 0; tier < azeriteEmpoweredItem->GetMaxAzeritePowerTier(); ++tier)
{
if (azeriteEmpoweredItem->GetSelectedAzeritePower(tier))
{
hasSelections = true;
break;
}
}
if (!hasSelections)
return SPELL_FAILED_AZERITE_EMPOWERED_NO_CHOICES_TO_UNDO;
if (!m_caster->ToPlayer()->HasEnoughMoney(azeriteEmpoweredItem->GetRespecCost()))
return SPELL_FAILED_DONT_REPORT;
break;
}
default: default:
break; break;
} }
+1
View File
@@ -484,6 +484,7 @@ class TC_GAME_API Spell
void EffectPlayScene(SpellEffIndex effIndex); void EffectPlayScene(SpellEffIndex effIndex);
void EffectGiveHonor(SpellEffIndex effIndex); void EffectGiveHonor(SpellEffIndex effIndex);
void EffectLearnTransmogSet(SpellEffIndex effIndex); void EffectLearnTransmogSet(SpellEffIndex effIndex);
void EffectRespecAzeriteEmpoweredItem(SpellEffIndex effIndex);
void EffectLearnAzeriteEssencePower(SpellEffIndex effIndex); void EffectLearnAzeriteEssencePower(SpellEffIndex effIndex);
typedef std::unordered_set<Aura*> UsedSpellMods; typedef std::unordered_set<Aura*> UsedSpellMods;
+30 -1
View File
@@ -19,6 +19,7 @@
#include "Spell.h" #include "Spell.h"
#include "AccountMgr.h" #include "AccountMgr.h"
#include "AreaTrigger.h" #include "AreaTrigger.h"
#include "AzeriteEmpoweredItem.h"
#include "AzeriteItem.h" #include "AzeriteItem.h"
#include "Battleground.h" #include "Battleground.h"
#include "BattlegroundMgr.h" #include "BattlegroundMgr.h"
@@ -337,7 +338,7 @@ NonDefaultConstructible<pEffect> SpellEffects[TOTAL_SPELL_EFFECTS] =
&Spell::EffectNULL, //256 SPELL_EFFECT_256 &Spell::EffectNULL, //256 SPELL_EFFECT_256
&Spell::EffectNULL, //257 SPELL_EFFECT_257 &Spell::EffectNULL, //257 SPELL_EFFECT_257
&Spell::EffectNULL, //258 SPELL_EFFECT_MODIFY_KEYSTONE &Spell::EffectNULL, //258 SPELL_EFFECT_MODIFY_KEYSTONE
&Spell::EffectNULL, //259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM &Spell::EffectRespecAzeriteEmpoweredItem, //259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM
&Spell::EffectNULL, //260 SPELL_EFFECT_SUMMON_STABLED_PET &Spell::EffectNULL, //260 SPELL_EFFECT_SUMMON_STABLED_PET
&Spell::EffectNULL, //261 SPELL_EFFECT_SCRAP_ITEM &Spell::EffectNULL, //261 SPELL_EFFECT_SCRAP_ITEM
&Spell::EffectNULL, //262 SPELL_EFFECT_262 &Spell::EffectNULL, //262 SPELL_EFFECT_262
@@ -5821,6 +5822,34 @@ void Spell::EffectLearnTransmogSet(SpellEffIndex /*effIndex*/)
unitTarget->ToPlayer()->GetSession()->GetCollectionMgr()->AddTransmogSet(effectInfo->MiscValue); unitTarget->ToPlayer()->GetSession()->GetCollectionMgr()->AddTransmogSet(effectInfo->MiscValue);
} }
void Spell::EffectRespecAzeriteEmpoweredItem(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
if (!itemTarget || !itemTarget->IsAzeriteEmpoweredItem())
return;
Player* owner = m_caster->ToPlayer();
if (!owner)
return;
AzeriteEmpoweredItem* azeriteEmpoweredItem = itemTarget->ToAzeriteEmpoweredItem();
owner->ModifyMoney(-azeriteEmpoweredItem->GetRespecCost());
// reapply all item mods - item level change affects stats and auras
if (azeriteEmpoweredItem->IsEquipped())
owner->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), false);
azeriteEmpoweredItem->ClearSelectedAzeritePowers();
if (azeriteEmpoweredItem->IsEquipped())
owner->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), true);
azeriteEmpoweredItem->SetState(ITEM_CHANGED, owner);
owner->SetNumRespecs(owner->GetNumRespecs() + 1);
}
void Spell::EffectLearnAzeriteEssencePower(SpellEffIndex /*effIndex*/) void Spell::EffectLearnAzeriteEssencePower(SpellEffIndex /*effIndex*/)
{ {
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+14 -5
View File
@@ -22,6 +22,7 @@
*/ */
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "AzeritePackets.h"
#include "Battleground.h" #include "Battleground.h"
#include "CreatureAIImpl.h" #include "CreatureAIImpl.h"
#include "DB2Stores.h" #include "DB2Stores.h"
@@ -4776,16 +4777,24 @@ class spell_item_heart_of_azeroth : public AuraScript
void SetEquippedFlag(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/) void SetEquippedFlag(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/)
{ {
if (Player* target = GetTarget()->ToPlayer()) SetState(true);
if (Item* item = target->GetItemByGuid(GetAura()->GetCastItemGUID()))
item->AddItemFlag2(ITEM_FIELD_FLAG2_HEART_OF_AZEROTH_EQUIPPED);
} }
void ClearEquippedFlag(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/) void ClearEquippedFlag(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/)
{
SetState(false);
}
void SetState(bool equipped)
{ {
if (Player* target = GetTarget()->ToPlayer()) if (Player* target = GetTarget()->ToPlayer())
if (Item* item = target->GetItemByGuid(GetAura()->GetCastItemGUID())) {
item->RemoveItemFlag2(ITEM_FIELD_FLAG2_HEART_OF_AZEROTH_EQUIPPED); target->ApplyAllAzeriteEmpoweredItemMods(equipped);
WorldPackets::Azerite::AzeriteEmpoweredItemEquippedStatusChanged statusChanged;
statusChanged.IsHeartEquipped = equipped;
target->SendDirectMessage(statusChanged.Write());
}
} }
void Register() void Register()