Core/Items: Implement azerite essences

Port From (https://github.com/TrinityCore/TrinityCore/commit/ec9d624aec9e0a39b1bcee7d4077f46be358faad)
This commit is contained in:
hondacrx
2019-11-22 21:39:35 -05:00
parent c05d592f4c
commit 796c11795f
30 changed files with 1231 additions and 74 deletions
+4 -3
View File
@@ -1652,10 +1652,11 @@ namespace Game.Achievements
return false;
break;
case CriteriaAdditionalCondition.RewardedQuest: // 110
if (!referencePlayer.GetQuestRewardStatus(reqValue))
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(reqValue);
if (questBit != 0)
if ((referencePlayer.m_activePlayerData.QuestCompleted[((int)questBit - 1) >> 6] & (1ul << (((int)questBit - 1) & 63))) == 0)
return false;
break;
case CriteriaAdditionalCondition.CompletedQuest: // 111
if (referencePlayer.GetQuestStatus(reqValue) != QuestStatus.Complete)
return false;
@@ -2293,7 +2294,7 @@ namespace Game.Achievements
case CriteriaAdditionalCondition.AzeriteItemLevel: // 235
{
Item heartOfAzeroth = referencePlayer.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (!heartOfAzeroth || heartOfAzeroth.ToAzeriteItem().m_azeriteItemData.Level < reqValue)
if (!heartOfAzeroth || heartOfAzeroth.ToAzeriteItem().GetLevel() < reqValue)
return false;
break;
}
+10
View File
@@ -54,9 +54,13 @@ namespace Game.DataStorage
ArtifactTierStorage = DBReader.Read<ArtifactTierRecord>("ArtifactTier.db2", HotfixStatements.SEL_ARTIFACT_TIER);
ArtifactUnlockStorage = DBReader.Read<ArtifactUnlockRecord>("ArtifactUnlock.db2", HotfixStatements.SEL_ARTIFACT_UNLOCK);
AuctionHouseStorage = DBReader.Read<AuctionHouseRecord>("AuctionHouse.db2", HotfixStatements.SEL_AUCTION_HOUSE, HotfixStatements.SEL_AUCTION_HOUSE_LOCALE);
AzeriteEssenceStorage = DBReader.Read<AzeriteEssenceRecord>("AzeriteEssence.db2", HotfixStatements.SEL_AZERITE_ESSENCE, HotfixStatements.SEL_AZERITE_ESSENCE_LOCALE);
AzeriteEssencePowerStorage = DBReader.Read<AzeriteEssencePowerRecord>("AzeriteEssencePower.db2", HotfixStatements.SEL_AZERITE_ESSENCE_POWER, HotfixStatements.SEL_AZERITE_ESSENCE_POWER_LOCALE);
AzeriteItemStorage = DBReader.Read<AzeriteItemRecord>("AzeriteItem.db2", HotfixStatements.SEL_AZERITE_ITEM);
AzeriteItemMilestonePowerStorage = DBReader.Read<AzeriteItemMilestonePowerRecord>("AzeriteItemMilestonePower.db2", HotfixStatements.SEL_AZERITE_ITEM_MILESTONE_POWER);
AzeriteKnowledgeMultiplierStorage = DBReader.Read<AzeriteKnowledgeMultiplierRecord>("AzeriteKnowledgeMultiplier.db2", HotfixStatements.SEL_AZERITE_KNOWLEDGE_MULTIPLIER);
AzeriteLevelInfoStorage = DBReader.Read<AzeriteLevelInfoRecord>("AzeriteLevelInfo.db2", HotfixStatements.SEL_AZERITE_LEVEL_INFO);
AzeritePowerStorage = DBReader.Read<AzeritePowerRecord>("AzeritePower.db2", HotfixStatements.SEL_AZERITE_POWER);
BankBagSlotPricesStorage = DBReader.Read<BankBagSlotPricesRecord>("BankBagSlotPrices.db2", HotfixStatements.SEL_BANK_BAG_SLOT_PRICES);
//BannedAddOnsStorage = DBReader.Read<BannedAddOnsRecord>("BannedAddons.db2", HotfixStatements.SEL_BANNED_ADDONS);
BarberShopStyleStorage = DBReader.Read<BarberShopStyleRecord>("BarberShopStyle.db2", HotfixStatements.SEL_BARBER_SHOP_STYLE, HotfixStatements.SEL_BARBER_SHOP_STYLE_LOCALE);
@@ -218,6 +222,7 @@ namespace Game.DataStorage
SkillRaceClassInfoStorage = DBReader.Read<SkillRaceClassInfoRecord>("SkillRaceClassInfo.db2", HotfixStatements.SEL_SKILL_RACE_CLASS_INFO);
SoundKitStorage = DBReader.Read<SoundKitRecord>("SoundKit.db2", HotfixStatements.SEL_SOUND_KIT);
SpecializationSpellsStorage = DBReader.Read<SpecializationSpellsRecord>("SpecializationSpells.db2", HotfixStatements.SEL_SPECIALIZATION_SPELLS, HotfixStatements.SEL_SPECIALIZATION_SPELLS_LOCALE);
SpecSetMemberStorage = DBReader.Read<SpecSetMemberRecord>("SpecSetMember.db2", HotfixStatements.SEL_SPEC_SET_MEMBER);
SpellNameStorage = DBReader.Read<SpellNameRecord>("SpellName.db2", HotfixStatements.SEL_SPELL_NAME, HotfixStatements.SEL_SPELL_NAME_LOCALE);
SpellAuraOptionsStorage = DBReader.Read<SpellAuraOptionsRecord>("SpellAuraOptions.db2", HotfixStatements.SEL_SPELL_AURA_OPTIONS);
SpellAuraRestrictionsStorage = DBReader.Read<SpellAuraRestrictionsRecord>("SpellAuraRestrictions.db2", HotfixStatements.SEL_SPELL_AURA_RESTRICTIONS);
@@ -400,9 +405,13 @@ namespace Game.DataStorage
public static DB6Storage<ArtifactTierRecord> ArtifactTierStorage;
public static DB6Storage<ArtifactUnlockRecord> ArtifactUnlockStorage;
public static DB6Storage<AuctionHouseRecord> AuctionHouseStorage;
public static DB6Storage<AzeriteEssenceRecord> AzeriteEssenceStorage;
public static DB6Storage<AzeriteEssencePowerRecord> AzeriteEssencePowerStorage;
public static DB6Storage<AzeriteItemRecord> AzeriteItemStorage;
public static DB6Storage<AzeriteItemMilestonePowerRecord> AzeriteItemMilestonePowerStorage;
public static DB6Storage<AzeriteKnowledgeMultiplierRecord> AzeriteKnowledgeMultiplierStorage;
public static DB6Storage<AzeriteLevelInfoRecord> AzeriteLevelInfoStorage;
public static DB6Storage<AzeritePowerRecord> AzeritePowerStorage;
public static DB6Storage<BankBagSlotPricesRecord> BankBagSlotPricesStorage;
//public static DB6Storage<BannedAddOnsRecord> BannedAddOnsStorage;
public static DB6Storage<BarberShopStyleRecord> BarberShopStyleStorage;
@@ -564,6 +573,7 @@ namespace Game.DataStorage
public static DB6Storage<SkillRaceClassInfoRecord> SkillRaceClassInfoStorage;
public static DB6Storage<SoundKitRecord> SoundKitStorage;
public static DB6Storage<SpecializationSpellsRecord> SpecializationSpellsStorage;
public static DB6Storage<SpecSetMemberRecord> SpecSetMemberStorage;
public static DB6Storage<SpellAuraOptionsRecord> SpellAuraOptionsStorage;
public static DB6Storage<SpellAuraRestrictionsRecord> SpellAuraRestrictionsStorage;
public static DB6Storage<SpellCastTimesRecord> SpellCastTimesStorage;
+49 -1
View File
@@ -59,10 +59,30 @@ namespace Game.DataStorage
CliDB.ArtifactPowerLinkStorage.Clear();
foreach (ArtifactPowerRankRecord artifactPowerRank in CliDB.ArtifactPowerRankStorage.Values)
_artifactPowerRanks[Tuple.Create((uint)artifactPowerRank.ArtifactPowerID, artifactPowerRank.RankIndex)] = artifactPowerRank;
_artifactPowerRanks[Tuple.Create(artifactPowerRank.ArtifactPowerID, artifactPowerRank.RankIndex)] = artifactPowerRank;
CliDB.ArtifactPowerRankStorage.Clear();
foreach (AzeriteEssencePowerRecord azeriteEssencePower in CliDB.AzeriteEssencePowerStorage.Values)
_azeriteEssencePowersByIdAndRank[Tuple.Create((uint)azeriteEssencePower.AzeriteEssenceID, (uint)azeriteEssencePower.Tier)] = azeriteEssencePower;
foreach (AzeriteItemMilestonePowerRecord azeriteItemMilestonePower in CliDB.AzeriteItemMilestonePowerStorage.Values)
_azeriteItemMilestonePowers.Add(azeriteItemMilestonePower);
_azeriteItemMilestonePowers = _azeriteItemMilestonePowers.OrderBy(p => p.RequiredLevel).ToList();
uint azeriteEssenceSlot = 0;
foreach (AzeriteItemMilestonePowerRecord azeriteItemMilestonePower in _azeriteItemMilestonePowers)
{
AzeriteItemMilestoneType type = (AzeriteItemMilestoneType)azeriteItemMilestonePower.Type;
if (type == AzeriteItemMilestoneType.MajorEssence || type == AzeriteItemMilestoneType.MinorEssence)
{
//ASSERT(azeriteEssenceSlot < MAX_AZERITE_ESSENCE_SLOT);
_azeriteItemMilestonePowerByEssenceSlot[azeriteEssenceSlot] = azeriteItemMilestonePower;
++azeriteEssenceSlot;
}
}
foreach (CharacterFacialHairStylesRecord characterFacialStyle in CliDB.CharacterFacialHairStylesStorage.Values)
_characterFacialHairStyles.Add(Tuple.Create(characterFacialStyle.RaceID, characterFacialStyle.SexID, (uint)characterFacialStyle.VariationID));
@@ -417,6 +437,9 @@ namespace Game.DataStorage
CliDB.SpecializationSpellsStorage.Clear();
foreach (SpecSetMemberRecord specSetMember in CliDB.SpecSetMemberStorage.Values)
_specsBySpecSet.Add(Tuple.Create((int)specSetMember.SpecSetID, (uint)specSetMember.ChrSpecializationID));
foreach (SpellClassOptionsRecord classOption in CliDB.SpellClassOptionsStorage.Values)
_spellFamilyNames.Add(classOption.SpellClassSet);
@@ -727,6 +750,22 @@ namespace Game.DataStorage
return CliDB.AzeriteItemStorage.Any(pair => pair.Value.ItemID == itemId);
}
public AzeriteEssencePowerRecord GetAzeriteEssencePower(uint azeriteEssenceId, uint rank)
{
return _azeriteEssencePowersByIdAndRank.LookupByKey((azeriteEssenceId, rank));
}
public List<AzeriteItemMilestonePowerRecord> GetAzeriteItemMilestonePowers()
{
return _azeriteItemMilestonePowers;
}
public AzeriteItemMilestonePowerRecord GetAzeriteItemMilestonePower(int slot)
{
//ASSERT(slot < MAX_AZERITE_ESSENCE_SLOT, "Slot %u must be lower than MAX_AZERITE_ESSENCE_SLOT (%u)", uint32(slot), MAX_AZERITE_ESSENCE_SLOT);
return _azeriteItemMilestonePowerByEssenceSlot[slot];
}
public string GetBroadcastTextValue(BroadcastTextRecord broadcastText, LocaleConstant locale = LocaleConstant.enUS, Gender gender = Gender.Male, bool forceGender = false)
{
if ((gender == Gender.Female || gender == Gender.None) && (forceGender || broadcastText.Text1.HasString(SharedConst.DefaultLocale)))
@@ -1549,6 +1588,11 @@ namespace Game.DataStorage
return _specializationSpellsBySpec.LookupByKey(specId);
}
public bool IsSpecSetMember(int specSetId, uint specId)
{
return _specsBySpecSet.Contains(Tuple.Create(specSetId, specId));
}
bool IsValidSpellFamiliyName(SpellFamilyNames family)
{
return _spellFamilyNames.Contains((byte)family);
@@ -1938,6 +1982,9 @@ namespace Game.DataStorage
MultiMap<uint, ArtifactPowerRecord> _artifactPowers = new MultiMap<uint, ArtifactPowerRecord>();
MultiMap<uint, uint> _artifactPowerLinks = new MultiMap<uint, uint>();
Dictionary<Tuple<uint, byte>, ArtifactPowerRankRecord> _artifactPowerRanks = new Dictionary<Tuple<uint, byte>, ArtifactPowerRankRecord>();
Dictionary<Tuple<uint, uint>, AzeriteEssencePowerRecord> _azeriteEssencePowersByIdAndRank = new Dictionary<Tuple<uint, uint>, AzeriteEssencePowerRecord>();
List<AzeriteItemMilestonePowerRecord> _azeriteItemMilestonePowers = new List<AzeriteItemMilestonePowerRecord>();
AzeriteItemMilestonePowerRecord[] _azeriteItemMilestonePowerByEssenceSlot = new AzeriteItemMilestonePowerRecord[SharedConst.MaxAzeriteEssenceSlot];
List<Tuple<byte, byte, uint>> _characterFacialHairStyles = new List<Tuple<byte, byte, uint>>();
MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, CharSectionsRecord> _charSections = new MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, CharSectionsRecord>();
Dictionary<uint, CharStartOutfitRecord> _charStartOutfits = new Dictionary<uint, CharStartOutfitRecord>();
@@ -1981,6 +2028,7 @@ namespace Game.DataStorage
MultiMap<uint, SkillLineAbilityRecord> _skillLineAbilitiesBySkillupSkill = new MultiMap<uint, SkillLineAbilityRecord>();
MultiMap<uint, SkillRaceClassInfoRecord> _skillRaceClassInfoBySkill = new MultiMap<uint, SkillRaceClassInfoRecord>();
MultiMap<uint, SpecializationSpellsRecord> _specializationSpellsBySpec = new MultiMap<uint, SpecializationSpellsRecord>();
List<Tuple<int, uint>> _specsBySpecSet = new List<Tuple<int, uint>>();
List<byte> _spellFamilyNames = new List<byte>();
Dictionary<uint, List<SpellPowerRecord>> _spellPowers = new Dictionary<uint, List<SpellPowerRecord>>();
Dictionary<uint, Dictionary<uint, List<SpellPowerRecord>>> _spellPowerDifficulties = new Dictionary<uint, Dictionary<uint, List<SpellPowerRecord>>>();
@@ -254,12 +254,42 @@ namespace Game.DataStorage
public byte ConsignmentRate;
}
public sealed class AzeriteEssenceRecord
{
public string Name;
public string Description;
public uint ID;
public int SpecSetID;
}
public sealed class AzeriteEssencePowerRecord
{
public uint ID;
public string SourceAlliance;
public string SourceHorde;
public int AzeriteEssenceID;
public byte Tier;
public uint MajorPowerDescription;
public uint MinorPowerDescription;
public uint MajorPowerActual;
public uint MinorPowerActual;
}
public sealed class AzeriteItemRecord
{
public uint ID;
public uint ItemID;
}
public sealed class AzeriteItemMilestonePowerRecord
{
public uint ID;
public int RequiredLevel;
public int AzeritePowerID;
public int Type;
public int AutoUnlock;
}
public sealed class AzeriteKnowledgeMultiplierRecord
{
public uint ID;
@@ -273,4 +303,13 @@ namespace Game.DataStorage
public ulong MinimumExperienceToNextLevel;
public uint ItemLevel;
}
public sealed class AzeritePowerRecord
{
public uint ID;
public uint SpellID;
public int ItemBonusListID;
public int SpecSetID;
public int Flags;
}
}
@@ -166,6 +166,13 @@ namespace Game.DataStorage
public byte DisplayOrder;
}
public sealed class SpecSetMemberRecord
{
public uint ID;
public uint ChrSpecializationID;
public uint SpecSetID;
}
public sealed class SpellAuraOptionsRecord
{
public uint Id;
+33 -11
View File
@@ -1890,19 +1890,41 @@ namespace Game.Entities
if (!ConditionManager.IsPlayerMeetingCondition(player, playerCondition))
return;
Aura artifactAura = player.GetAura(PlayerConst.ArtifactsAllWeaponsGeneralWeaponEquippedPassive);
Item item = artifactAura != null ? player.GetItemByGuid(artifactAura.GetCastItemGUID()) : null;
if (!item)
switch (info.ItemForge.ForgeType)
{
player.SendPacket(new DisplayGameError(GameError.MustEquipArtifact));
return;
}
case 0: // Artifact Forge
case 1: // Relic Forge
{
ArtifactForgeOpened artifactForgeOpened = new ArtifactForgeOpened();
artifactForgeOpened.ArtifactGUID = item.GetGUID();
artifactForgeOpened.ForgeGUID = GetGUID();
player.SendPacket(artifactForgeOpened);
return;
Aura artifactAura = player.GetAura(PlayerConst.ArtifactsAllWeaponsGeneralWeaponEquippedPassive);
Item item = artifactAura != null ? player.GetItemByGuid(artifactAura.GetCastItemGUID()) : null;
if (!item)
{
player.SendPacket(new DisplayGameError(GameError.MustEquipArtifact));
return;
}
ArtifactForgeOpened artifactForgeOpened = new ArtifactForgeOpened();
artifactForgeOpened.ArtifactGUID = item.GetGUID();
artifactForgeOpened.ForgeGUID = GetGUID();
player.SendPacket(artifactForgeOpened);
break;
}
case 2: // Heart Forge
{
Item item = player.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (!item)
return;
AzeriteEssenceForgeOpened azeriteEssenceForgeOpened = new AzeriteEssenceForgeOpened();
azeriteEssenceForgeOpened.ForgeGUID = GetGUID();
player.SendPacket(azeriteEssenceForgeOpened);
break;
}
default:
break;
}
break;
}
case GameObjectTypes.UILink:
{
+235 -8
View File
@@ -47,6 +47,7 @@ namespace Game.Entities
SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.Level), 1u);
SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.KnowledgeLevel), GetCurrentKnowledgeLevel());
UnlockDefaultMilestones();
return true;
}
@@ -63,10 +64,49 @@ namespace Game.Entities
stmt.AddValue(1, m_azeriteItemData.Xp);
stmt.AddValue(2, m_azeriteItemData.Level);
stmt.AddValue(3, m_azeriteItemData.KnowledgeLevel);
int specIndex = 0;
for (; specIndex < m_azeriteItemData.SelectedEssences.Size(); ++specIndex)
{
stmt.AddValue(4 + specIndex * 4, m_azeriteItemData.SelectedEssences[specIndex].SpecializationID);
for (var j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j)
stmt.AddValue(5 + specIndex * 4 + j, m_azeriteItemData.SelectedEssences[specIndex].AzeriteEssenceID[j]);
}
for (; specIndex < PlayerConst.MaxSpecializations; ++specIndex)
{
stmt.AddValue(4 + specIndex * 4, 0);
for (var j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j)
stmt.AddValue(5 + specIndex * 4 + j, 0);
}
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_MILESTONE_POWER);
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
foreach (uint azeriteItemMilestonePowerId in m_azeriteItemData.UnlockedEssenceMilestones)
{
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEM_INSTANCE_AZERITE_MILESTONE_POWER);
stmt.AddValue(0, GetGUID().GetCounter());
stmt.AddValue(1, azeriteItemMilestonePowerId);
trans.Append(stmt);
}
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE);
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
foreach (UnlockedAzeriteEssence azeriteEssence in m_azeriteItemData.UnlockedEssences)
{
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE);
stmt.AddValue(0, GetGUID().GetCounter());
stmt.AddValue(1, azeriteEssence.AzeriteEssenceID);
stmt.AddValue(2, azeriteEssence.Rank);
trans.Append(stmt);
}
}
public void LoadAzeriteItemData(AzeriteData azeriteData)
public void LoadAzeriteItemData(Player owner, AzeriteData azeriteData)
{
bool needSave = false;
@@ -103,6 +143,40 @@ namespace Game.Entities
SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.Level), azeriteData.Level);
SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.KnowledgeLevel), azeriteData.KnowledgeLevel);
foreach (uint azeriteItemMilestonePowerId in azeriteData.AzeriteItemMilestonePowers)
AddUnlockedEssenceMilestone(azeriteItemMilestonePowerId);
UnlockDefaultMilestones();
foreach (AzeriteEssencePowerRecord unlockedAzeriteEssence in azeriteData.UnlockedAzeriteEssences)
SetEssenceRank((uint)unlockedAzeriteEssence.AzeriteEssenceID, unlockedAzeriteEssence.Tier);
foreach (AzeriteItemSelectedEssencesData selectedEssenceData in azeriteData.SelectedAzeriteEssences)
{
if (selectedEssenceData.SpecializationId == 0)
continue;
var selectedEssences = new SelectedAzeriteEssences();
selectedEssences.ModifyValue(selectedEssences.SpecializationID).SetValue(selectedEssenceData.SpecializationId);
for (int i = 0; i < SharedConst.MaxAzeriteEssenceSlot; ++i)
{
// Check if essence was unlocked
if (GetEssenceRank(selectedEssenceData.AzeriteEssenceId[i]) == 0)
continue;
selectedEssences.ModifyValue(selectedEssences.AzeriteEssenceID, i) = selectedEssenceData.AzeriteEssenceId[i];
}
if (owner.GetPrimarySpecialization() == selectedEssenceData.SpecializationId)
selectedEssences.ModifyValue(selectedEssences.Enabled).SetValue(1);
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.SelectedEssences), selectedEssences);
}
// add selected essences for current spec
if (GetSelectedAzeriteEssences() == null)
CreateSelectedAzeriteEssences(owner.GetPrimarySpecialization());
if (needSave)
{
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ITEM_INSTANCE_AZERITE_ON_LOAD);
@@ -119,16 +193,20 @@ namespace Game.Entities
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_MILESTONE_POWER);
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE);
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
base.DeleteFromDB(trans);
}
public override uint GetItemLevel(Player owner)
{
return CliDB.AzeriteLevelInfoStorage.LookupByKey(m_azeriteItemData.Level).ItemLevel;
}
public uint GetLevel() { return m_azeriteItemData.Level; }
uint GetLevel() { return m_azeriteItemData.Level; }
uint GetEffectiveLevel()
public uint GetEffectiveLevel()
{
uint level = m_azeriteItemData.AuraLevel;
if (level == 0)
@@ -193,7 +271,8 @@ namespace Game.Entities
if (IsEquipped())
owner._ApplyItemBonuses(this, GetSlot(), false);
SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData. Level), level);
SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.Level), level);
UnlockDefaultMilestones();
owner.UpdateCriteria(CriteriaTypes.HeartOfAzerothLevelReached, level);
if (IsEquipped())
@@ -209,6 +288,81 @@ namespace Game.Entities
owner.SendPacket(xpGain);
}
public static GameObject FindHeartForge(Player owner)
{
GameObject forge = owner.FindNearestGameObjectOfType(GameObjectTypes.ItemForge, 40.0f);
if (forge != null)
if (forge.GetGoInfo().ItemForge.ForgeType == 2)
return forge;
return null;
}
public bool CanUseEssences()
{
PlayerConditionRecord condition = CliDB.PlayerConditionStorage.LookupByKey(PlayerConst.PlayerConditionIdUnlockedAzeriteEssences);
if (condition != null)
return ConditionManager.IsPlayerMeetingCondition(GetOwner(), condition);
return false;
}
public bool HasUnlockedEssenceSlot(byte slot)
{
AzeriteItemMilestonePowerRecord milestone = Global.DB2Mgr.GetAzeriteItemMilestonePower(slot);
return m_azeriteItemData.UnlockedEssenceMilestones.FindIndex(milestone.ID) != -1;
}
public bool HasUnlockedEssenceMilestone(uint azeriteItemMilestonePowerId) { return m_azeriteItemData.UnlockedEssenceMilestones.FindIndex(azeriteItemMilestonePowerId) != -1; }
public void AddUnlockedEssenceMilestone(uint azeriteItemMilestonePowerId)
{
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.UnlockedEssenceMilestones), azeriteItemMilestonePowerId);
}
public uint GetEssenceRank(uint azeriteEssenceId)
{
int index = m_azeriteItemData.UnlockedEssences.FindIndexIf(essence =>
{
return essence.AzeriteEssenceID == azeriteEssenceId;
});
if (index < 0)
return 0;
return m_azeriteItemData.UnlockedEssences[index].Rank;
}
public void SetEssenceRank(uint azeriteEssenceId, uint rank)
{
int index = m_azeriteItemData.UnlockedEssences.FindIndexIf(essence =>
{
return essence.AzeriteEssenceID == azeriteEssenceId;
});
if (rank == 0 && index >= 0)
{
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.UnlockedEssences), index);
return;
}
if (Global.DB2Mgr.GetAzeriteEssencePower(azeriteEssenceId, rank) == null)
return;
if (index < 0)
{
UnlockedAzeriteEssence unlockedEssence = new UnlockedAzeriteEssence();
unlockedEssence.AzeriteEssenceID = azeriteEssenceId;
unlockedEssence.Rank = rank;
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.UnlockedEssences), unlockedEssence);
}
else
{
UnlockedAzeriteEssence actorField = m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.UnlockedEssences, index);
SetUpdateFieldValue(ref actorField.Rank, rank);
}
}
public SelectedAzeriteEssences GetSelectedAzeriteEssences()
{
foreach (SelectedAzeriteEssences essences in m_azeriteItemData.SelectedEssences)
@@ -218,6 +372,38 @@ namespace Game.Entities
return null;
}
public void SetSelectedAzeriteEssences(uint specializationId)
{
int index = m_azeriteItemData.SelectedEssences.FindIndexIf(essences => { return essences.Enabled == 1; });
if (index >= 0)
{
SelectedAzeriteEssences selectedEssences = m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.SelectedEssences, index);
SetUpdateFieldValue(selectedEssences.ModifyValue(selectedEssences.Enabled), 0u);
}
index = m_azeriteItemData.SelectedEssences.FindIndexIf(essences =>
{
return essences.SpecializationID == specializationId;
});
if (index >= 0)
{
SelectedAzeriteEssences selectedEssences = m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.SelectedEssences, index);
SetUpdateFieldValue(selectedEssences.ModifyValue(selectedEssences.Enabled), 1u);
}
else
CreateSelectedAzeriteEssences(specializationId);
}
public void SetSelectedAzeriteEssence(int slot, uint azeriteEssenceId)
{
//ASSERT(slot < MAX_AZERITE_ESSENCE_SLOT);
int index = m_azeriteItemData.SelectedEssences.FindIndexIf(essences => { return essences.Enabled == 1; });
//ASSERT(index >= 0);
SelectedAzeriteEssences selectedEssences = m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.SelectedEssences, index);
SetUpdateFieldValue(ref selectedEssences.ModifyValue(selectedEssences.AzeriteEssenceID, slot), azeriteEssenceId);
}
public override void BuildValuesCreate(WorldPacket data, Player target)
{
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
@@ -277,6 +463,44 @@ namespace Game.Entities
m_values.ClearChangesMask(m_azeriteItemData);
base.ClearUpdateMask(remove);
}
void UnlockDefaultMilestones()
{
bool hasPreviousMilestone = true;
foreach (AzeriteItemMilestonePowerRecord milestone in Global.DB2Mgr.GetAzeriteItemMilestonePowers())
{
if (!hasPreviousMilestone)
break;
if (milestone.RequiredLevel > GetLevel())
break;
if (HasUnlockedEssenceMilestone(milestone.ID))
continue;
if (milestone.AutoUnlock != 0)
{
AddUnlockedEssenceMilestone(milestone.ID);
hasPreviousMilestone = true;
}
else
hasPreviousMilestone = false;
}
}
void CreateSelectedAzeriteEssences(uint specializationId)
{
var selectedEssences = new SelectedAzeriteEssences();
selectedEssences.ModifyValue(selectedEssences.SpecializationID).SetValue(specializationId);
selectedEssences.ModifyValue(selectedEssences.Enabled).SetValue(1);
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.SelectedEssences), selectedEssences);
}
}
public class AzeriteItemSelectedEssencesData
{
public uint SpecializationId;
public uint[] AzeriteEssenceId = new uint[SharedConst.MaxAzeriteEssenceSlot];
}
public class AzeriteData
@@ -284,5 +508,8 @@ namespace Game.Entities
public ulong Xp;
public uint Level;
public uint KnowledgeLevel;
public List<uint> AzeriteItemMilestonePowers = new List<uint>();
public List<AzeriteEssencePowerRecord> UnlockedAzeriteEssences = new List<AzeriteEssencePowerRecord>();
public AzeriteItemSelectedEssencesData[] SelectedAzeriteEssences = new AzeriteItemSelectedEssencesData[PlayerConst.MaxSpecializations];
}
}
+72 -15
View File
@@ -1869,22 +1869,33 @@ namespace Game.Entities
ItemContainerDeleteLootItemsFromDB();
}
public virtual uint GetItemLevel(Player owner)
public uint GetItemLevel(Player owner)
{
ItemTemplate itemTemplate = GetTemplate();
uint minItemLevel = owner.m_unitData.MinItemLevel;
uint minItemLevelCutoff = owner.m_unitData.MinItemLevelCutoff;
uint maxItemLevel = GetTemplate().GetFlags3().HasAnyFlag(ItemFlags3.IgnoreItemLevelCapInPvp) ? 0u : owner.m_unitData.MaxItemLevel;
uint maxItemLevel = itemTemplate.GetFlags3().HasAnyFlag(ItemFlags3.IgnoreItemLevelCapInPvp) ? 0u : owner.m_unitData.MaxItemLevel;
bool pvpBonus = owner.IsUsingPvpItemLevels();
return GetItemLevel(GetTemplate(), _bonusData, owner.GetLevel(), GetModifier(ItemModifier.TimewalkerLevel),
minItemLevel, minItemLevelCutoff, maxItemLevel, pvpBonus);
uint azeriteLevel = 0;
AzeriteItem azeriteItem = ToAzeriteItem();
if (azeriteItem != null)
azeriteLevel = azeriteItem.GetEffectiveLevel();
return GetItemLevel(itemTemplate, _bonusData, owner.GetLevel(), GetModifier(ItemModifier.TimewalkerLevel),
minItemLevel, minItemLevelCutoff, maxItemLevel, pvpBonus, azeriteLevel);
}
public static uint GetItemLevel(ItemTemplate itemTemplate, BonusData bonusData, uint level, uint fixedLevel, uint minItemLevel, uint minItemLevelCutoff, uint maxItemLevel, bool pvpBonus)
public static uint GetItemLevel(ItemTemplate itemTemplate, BonusData bonusData, uint level, uint fixedLevel, uint minItemLevel, uint minItemLevelCutoff, uint maxItemLevel, bool pvpBonus, uint azeriteLevel)
{
if (itemTemplate == null)
return 1;
uint itemLevel = itemTemplate.GetBaseItemLevel();
AzeriteLevelInfoRecord azeriteLevelInfo = CliDB.AzeriteLevelInfoStorage.LookupByKey(azeriteLevel);
if (azeriteLevelInfo != null)
itemLevel = azeriteLevelInfo.ItemLevel;
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(bonusData.ScalingStatDistribution);
if (ssd != null)
{
@@ -2965,15 +2976,21 @@ namespace Game.Entities
public ArtifactData Artifact;
public AzeriteData AzeriteItem;
public static void Init(Dictionary<ulong, ItemAdditionalLoadInfo> loadInfo, SQLResult artifactResult, SQLResult azeriteItemResult)
public static void Init(Dictionary<ulong, ItemAdditionalLoadInfo> loadInfo, SQLResult artifactResult, SQLResult azeriteItemResult, SQLResult azeriteItemMilestonePowersResult, SQLResult azeriteItemUnlockedEssencesResult)
{
// 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 ...
ItemAdditionalLoadInfo GetOrCreateLoadInfo(ulong guid)
{
if (!loadInfo.ContainsKey(guid))
loadInfo[guid] = new ItemAdditionalLoadInfo();
return loadInfo[guid];
}
if (!artifactResult.IsEmpty())
{
do
{
ItemAdditionalLoadInfo info = new ItemAdditionalLoadInfo();
ItemAdditionalLoadInfo info = GetOrCreateLoadInfo(artifactResult.Read<ulong>(0));
if (info.Artifact == null)
info.Artifact = new ArtifactData();
@@ -3001,29 +3018,69 @@ namespace Game.Entities
info.Artifact.ArtifactPowers.Add(artifactPowerData);
}
loadInfo[artifactResult.Read<ulong>(0)] = info;
} while (artifactResult.NextRow());
}
// 0 1 2 3
// SELECT iz.itemGuid, iz.xp, iz.level, iz.knowledgeLevel FROM item_instance_azerite iz INNER JOIN ...
if (!azeriteItemResult.IsEmpty())
{
do
{
ItemAdditionalLoadInfo info = new ItemAdditionalLoadInfo();
ItemAdditionalLoadInfo info = GetOrCreateLoadInfo(azeriteItemResult.Read<ulong>(0));
if (info.AzeriteItem == null)
info.AzeriteItem = new AzeriteData();
info.AzeriteItem.Xp = azeriteItemResult.Read<ulong>(1);
info.AzeriteItem.Level = azeriteItemResult.Read<uint>(2);
info.AzeriteItem.KnowledgeLevel = azeriteItemResult.Read<uint>(3);
for (int i = 0; i < PlayerConst.MaxSpecializations; ++i)
{
uint specializationId = azeriteItemResult.Read<uint>(4 + i * 4);
if (!CliDB.ChrSpecializationStorage.ContainsKey(specializationId))
continue;
loadInfo[azeriteItemResult.Read<ulong>(0)] = info;
info.AzeriteItem.SelectedAzeriteEssences[i].SpecializationId = specializationId;
for (int j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j)
{
AzeriteEssenceRecord azeriteEssence = CliDB.AzeriteEssenceStorage.LookupByKey(azeriteItemResult.Read<uint>(5 + i * 4 + j));
if (azeriteEssence == null || !Global.DB2Mgr.IsSpecSetMember(azeriteEssence.SpecSetID, specializationId))
continue;
info.AzeriteItem.SelectedAzeriteEssences[i].AzeriteEssenceId[j] = azeriteEssence.ID;
}
}
} while (azeriteItemResult.NextRow());
}
if (!azeriteItemMilestonePowersResult.IsEmpty())
{
do
{
ItemAdditionalLoadInfo info = GetOrCreateLoadInfo(azeriteItemMilestonePowersResult.Read<ulong>(0));
if (info.AzeriteItem == null)
info.AzeriteItem = new AzeriteData();
info.AzeriteItem.AzeriteItemMilestonePowers.Add(azeriteItemMilestonePowersResult.Read<uint>(1));
}
while (azeriteItemMilestonePowersResult.NextRow());
}
if (!azeriteItemUnlockedEssencesResult.IsEmpty())
{
do
{
AzeriteEssencePowerRecord azeriteEssencePower = Global.DB2Mgr.GetAzeriteEssencePower(azeriteItemUnlockedEssencesResult.Read<uint>(1), azeriteItemUnlockedEssencesResult.Read<uint>(2));
if (azeriteEssencePower != null)
{
ItemAdditionalLoadInfo info = GetOrCreateLoadInfo(azeriteItemUnlockedEssencesResult.Read<ulong>(0));
if (info.AzeriteItem == null)
info.AzeriteItem = new AzeriteData();
info.AzeriteItem.UnlockedAzeriteEssences.Add(azeriteEssencePower);
}
}
while (azeriteItemUnlockedEssencesResult.NextRow());
}
}
}
@@ -160,6 +160,11 @@ namespace Game.Entities
return _values.IndexOf(value);
}
public int FindIndexIf(Predicate<T> blah)
{
return _values.FindIndex(blah);
}
public bool HasChanged(int index)
{
return (_updateMask[index / 32] & (1 << (index % 32))) != 0;
+23 -6
View File
@@ -38,10 +38,10 @@ namespace Game.Entities
{
public partial class Player
{
void _LoadInventory(SQLResult result, SQLResult artifactsResult, SQLResult azeriteResult, uint timeDiff)
void _LoadInventory(SQLResult result, SQLResult artifactsResult, SQLResult azeriteResult, SQLResult azeriteItemMilestonePowersResult, SQLResult azeriteItemUnlockedEssencesResult, uint timeDiff)
{
Dictionary<ulong, ItemAdditionalLoadInfo> additionalData = new Dictionary<ulong, ItemAdditionalLoadInfo>();
ItemAdditionalLoadInfo.Init(additionalData, artifactsResult, azeriteResult);
ItemAdditionalLoadInfo.Init(additionalData, artifactsResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult);
if (!result.IsEmpty())
{
@@ -68,7 +68,7 @@ namespace Game.Entities
{
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (azeriteItem != null)
azeriteItem.LoadAzeriteItemData(addionalData.AzeriteItem);
azeriteItem.LoadAzeriteItemData(this, addionalData.AzeriteItem);
}
}
@@ -1189,8 +1189,16 @@ namespace Game.Entities
stmt.AddValue(0, GetGUID().GetCounter());
SQLResult azeriteResult = DB.Characters.Query(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_MILESTONE_POWER);
stmt.AddValue(0, GetGUID().GetCounter());
SQLResult azeriteItemMilestonePowersResult = DB.Characters.Query(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE);
stmt.AddValue(0, GetGUID().GetCounter());
SQLResult azeriteItemUnlockedEssencesResult = DB.Characters.Query(stmt);
Dictionary<ulong, ItemAdditionalLoadInfo> additionalData = new Dictionary<ulong, ItemAdditionalLoadInfo>();
ItemAdditionalLoadInfo.Init(additionalData, artifactResult, azeriteResult);
ItemAdditionalLoadInfo.Init(additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult);
do
{
@@ -1250,7 +1258,7 @@ namespace Game.Entities
{
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (azeriteItem != null)
azeriteItem.LoadAzeriteItemData(additionalLoadInfo.AzeriteItem);
azeriteItem.LoadAzeriteItemData(this, additionalLoadInfo.AzeriteItem);
}
}
@@ -2898,7 +2906,8 @@ namespace Game.Entities
// must be before inventory (some items required reputation check)
reputationMgr.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.Reputation));
_LoadInventory(holder.GetResult(PlayerLoginQueryLoad.Inventory), holder.GetResult(PlayerLoginQueryLoad.Artifacts), holder.GetResult(PlayerLoginQueryLoad.LoadAzerite), time_diff);
_LoadInventory(holder.GetResult(PlayerLoginQueryLoad.Inventory), holder.GetResult(PlayerLoginQueryLoad.Artifacts), holder.GetResult(PlayerLoginQueryLoad.LoadAzerite),
holder.GetResult(PlayerLoginQueryLoad.LoadAzeriteMilestonePowers), holder.GetResult(PlayerLoginQueryLoad.LoadAzeriteUnlockedEssences), time_diff);
if (IsVoidStorageUnlocked())
_LoadVoidStorage(holder.GetResult(PlayerLoginQueryLoad.VoidStorage));
@@ -3846,6 +3855,14 @@ namespace Game.Entities
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_MILESTONE_POWER_BY_OWNER);
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE_BY_OWNER);
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_BY_OWNER);
stmt.AddValue(0, guid);
trans.Append(stmt);
@@ -3948,6 +3948,7 @@ namespace Game.Entities
if (updateItemAuras)
ApplyItemDependentAuras(item, apply);
ApplyArtifactPowers(item, apply);
ApplyAzeritePowers(item, apply);
ApplyEnchantment(item, apply);
Log.outDebug(LogFilter.Player, "_ApplyItemMods complete.");
@@ -4366,6 +4367,7 @@ namespace Game.Entities
ApplyItemEquipSpell(m_items[i], false);
ApplyEnchantment(m_items[i], false);
ApplyAzeritePowers(m_items[i], false);
ApplyArtifactPowers(m_items[i], false);
}
}
@@ -4418,6 +4420,7 @@ namespace Game.Entities
ApplyItemEquipSpell(m_items[i], true);
ApplyArtifactPowers(m_items[i], true);
ApplyAzeritePowers(m_items[i], true);
ApplyEnchantment(m_items[i], true);
}
}
@@ -5462,6 +5465,96 @@ namespace Game.Entities
}
}
void ApplyAzeritePowers(Item item, bool apply)
{
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (azeriteItem != null)
{
// milestone powers
foreach (uint azeriteItemMilestonePowerId in azeriteItem.m_azeriteItemData.UnlockedEssenceMilestones)
ApplyAzeriteItemMilestonePower(item, CliDB.AzeriteItemMilestonePowerStorage.LookupByKey(azeriteItemMilestonePowerId), apply);
// essences
SelectedAzeriteEssences selectedEssences = azeriteItem.GetSelectedAzeriteEssences();
if (selectedEssences != null)
{
for (byte slot = 0; slot < SharedConst.MaxAzeriteEssenceSlot; ++slot)
if (selectedEssences.AzeriteEssenceID[slot] != 0)
ApplyAzeriteEssence(item, selectedEssences.AzeriteEssenceID[slot], azeriteItem.GetEssenceRank(selectedEssences.AzeriteEssenceID[slot]),
(AzeriteItemMilestoneType)Global.DB2Mgr.GetAzeriteItemMilestonePower(slot).Type == AzeriteItemMilestoneType.MajorEssence, apply);
}
}
}
public void ApplyAzeriteItemMilestonePower(Item item, AzeriteItemMilestonePowerRecord azeriteItemMilestonePower, bool apply)
{
AzeriteItemMilestoneType type = (AzeriteItemMilestoneType)azeriteItemMilestonePower.Type;
if (type == AzeriteItemMilestoneType.BonusStamina)
{
AzeritePowerRecord azeritePower = CliDB.AzeritePowerStorage.LookupByKey(azeriteItemMilestonePower.AzeritePowerID);
if (azeritePower != null)
{
if (apply)
CastSpell(this, azeritePower.SpellID, true, item);
else
RemoveAurasDueToItemSpell(azeritePower.SpellID, item.GetGUID());
}
}
}
public void ApplyAzeriteEssence(Item item, uint azeriteEssenceId, uint rank, bool major, bool apply)
{
for (uint currentRank = 1; currentRank <= rank; ++currentRank)
{
AzeriteEssencePowerRecord azeriteEssencePower = Global.DB2Mgr.GetAzeriteEssencePower(azeriteEssenceId, currentRank);
if (azeriteEssencePower != null)
{
ApplyAzeriteEssencePower(item, azeriteEssencePower, major, apply);
if (major && currentRank == 1)
{
if (apply)
CastCustomSpell(PlayerConst.SpellIdHeartEssenceActionBarOverride, SpellValueMod.BasePoint0, (int)azeriteEssencePower.MajorPowerDescription, this, TriggerCastFlags.FullMask);
else
RemoveAurasDueToSpell(PlayerConst.SpellIdHeartEssenceActionBarOverride);
}
}
}
}
void ApplyAzeriteEssencePower(Item item, AzeriteEssencePowerRecord azeriteEssencePower, bool major, bool apply)
{
SpellInfo powerSpell = Global.SpellMgr.GetSpellInfo(azeriteEssencePower.MinorPowerDescription);
if (powerSpell != null)
{
if (apply)
CastSpell(this, powerSpell, true, item);
else
RemoveAurasDueToItemSpell(powerSpell.Id, item.GetGUID());
}
if (major)
{
powerSpell = Global.SpellMgr.GetSpellInfo(azeriteEssencePower.MajorPowerDescription);
if (powerSpell != null)
{
if (powerSpell.IsPassive())
{
if (apply)
CastSpell(this, powerSpell, true, item);
else
RemoveAurasDueToItemSpell(powerSpell.Id, item.GetGUID());
}
else
{
if (apply)
LearnSpell(powerSpell.Id, true, 0, true);
else
RemoveSpell(powerSpell.Id, false, false, true);
}
}
}
}
public bool HasItemOrGemWithIdEquipped(uint item, uint count, byte except_slot = ItemConst.NullSlot)
{
uint tempcount = 0;
+22 -20
View File
@@ -2010,7 +2010,7 @@ namespace Game.Entities
LearnSpellHighestRank(next);
}
public void LearnSpell(uint spellId, bool dependent, uint fromSkill = 0)
public void LearnSpell(uint spellId, bool dependent, uint fromSkill = 0, bool suppressMessaging = false)
{
PlayerSpell spell = m_spells.LookupByKey(spellId);
@@ -2024,6 +2024,7 @@ namespace Game.Entities
{
LearnedSpells packet = new LearnedSpells();
packet.SpellID.Add(spellId);
packet.SuppressMessaging = suppressMessaging;
SendPacket(packet);
}
@@ -2049,9 +2050,9 @@ namespace Game.Entities
}
public void RemoveSpell(uint spell_id, bool disabled = false, bool learn_low_rank = true)
public void RemoveSpell(uint spellId, bool disabled = false, bool learnLowRank = true, bool suppressMessaging = false)
{
var pSpell = m_spells.LookupByKey(spell_id);
var pSpell = m_spells.LookupByKey(spellId);
if (pSpell == null)
return;
@@ -2059,7 +2060,7 @@ namespace Game.Entities
return;
// unlearn non talent higher ranks (recursive)
uint nextSpell = Global.SpellMgr.GetNextSpellInChain(spell_id);
uint nextSpell = Global.SpellMgr.GetNextSpellInChain(spellId);
if (nextSpell != 0)
{
SpellInfo spellInfo1 = Global.SpellMgr.GetSpellInfo(nextSpell);
@@ -2067,12 +2068,12 @@ namespace Game.Entities
RemoveSpell(nextSpell, disabled, false);
}
//unlearn spells dependent from recently removed spells
var spellsRequiringSpell = Global.SpellMgr.GetSpellsRequiringSpellBounds(spell_id);
var spellsRequiringSpell = Global.SpellMgr.GetSpellsRequiringSpellBounds(spellId);
foreach (var id in spellsRequiringSpell)
RemoveSpell(id, disabled);
// re-search, it can be corrupted in prev loop
pSpell = m_spells.LookupByKey(spell_id);
pSpell = m_spells.LookupByKey(spellId);
if (pSpell == null)
return; // already unleared
@@ -2088,23 +2089,23 @@ namespace Game.Entities
else
{
if (pSpell.State == PlayerSpellState.New)
m_spells.Remove(spell_id);
m_spells.Remove(spellId);
else
pSpell.State = PlayerSpellState.Removed;
}
RemoveOwnedAura(spell_id, GetGUID());
RemoveOwnedAura(spellId, GetGUID());
// remove pet auras
for (byte i = 0; i < SpellConst.MaxEffects; ++i)
{
PetAura petSpell = Global.SpellMgr.GetPetAura(spell_id, i);
PetAura petSpell = Global.SpellMgr.GetPetAura(spellId, i);
if (petSpell != null)
RemovePetAura(petSpell);
}
// update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning)
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
if (spellInfo != null && spellInfo.IsPrimaryProfessionFirstRank())
{
uint freeProfs = GetFreePrimaryProfessionPoints() + 1;
@@ -2113,10 +2114,10 @@ namespace Game.Entities
}
// remove dependent skill
var spellLearnSkill = Global.SpellMgr.GetSpellLearnSkill(spell_id);
var spellLearnSkill = Global.SpellMgr.GetSpellLearnSkill(spellId);
if (spellLearnSkill != null)
{
uint prev_spell = Global.SpellMgr.GetPrevSpellInChain(spell_id);
uint prev_spell = Global.SpellMgr.GetPrevSpellInChain(spellId);
if (prev_spell == 0) // first rank, remove skill
SetSkill(spellLearnSkill.skill, 0, 0, 0);
else
@@ -2150,7 +2151,7 @@ namespace Game.Entities
}
// remove dependent spells
var spell_bounds = Global.SpellMgr.GetSpellLearnSpellMapBounds(spell_id);
var spell_bounds = Global.SpellMgr.GetSpellLearnSpellMapBounds(spellId);
foreach (var spellNode in spell_bounds)
{
@@ -2162,7 +2163,7 @@ namespace Game.Entities
// activate lesser rank in spellbook/action bar, and cast it if need
bool prev_activate = false;
uint prev_id = Global.SpellMgr.GetPrevSpellInChain(spell_id);
uint prev_id = Global.SpellMgr.GetPrevSpellInChain(spellId);
if (prev_id != 0)
{
// if ranked non-stackable spell: need activate lesser rank and update dendence state
@@ -2181,12 +2182,12 @@ namespace Game.Entities
}
// now re-learn if need re-activate
if (cur_active && !prevSpell.Active && learn_low_rank)
if (cur_active && !prevSpell.Active && learnLowRank)
{
if (AddSpell(prev_id, true, false, prevSpell.Dependent, prevSpell.Disabled))
{
// downgrade spell ranks in spellbook and action bar
SendSupercededSpell(spell_id, prev_id);
SendSupercededSpell(spellId, prev_id);
prev_activate = true;
}
}
@@ -2194,7 +2195,7 @@ namespace Game.Entities
}
}
m_overrideSpells.Remove(spell_id);
m_overrideSpells.Remove(spellId);
if (m_canTitanGrip)
{
@@ -2217,9 +2218,10 @@ namespace Game.Entities
// remove from spell book if not replaced by lesser rank
if (!prev_activate)
{
UnlearnedSpells removedSpells = new UnlearnedSpells();
removedSpells.SpellID.Add(spell_id);
SendPacket(removedSpells);
UnlearnedSpells unlearnedSpells = new UnlearnedSpells();
unlearnedSpells.SpellID.Add(spellId);
unlearnedSpells.SuppressMessaging = suppressMessaging;
SendPacket(unlearnedSpells);
}
}
bool IsNeedCastPassiveSpellAtLearn(SpellInfo spellInfo)
@@ -422,6 +422,24 @@ namespace Game.Entities
activeGlyphs.IsFullUpdate = true;
SendPacket(activeGlyphs);
Item item = GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (item != null)
{
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (azeriteItem != null)
{
if (azeriteItem.IsEquipped())
ApplyAzeritePowers(azeriteItem, false);
azeriteItem.SetSelectedAzeriteEssences(spec.Id);
if (azeriteItem.IsEquipped())
ApplyAzeritePowers(azeriteItem, true);
azeriteItem.SetState(ItemUpdateState.Changed, this);
}
}
var shapeshiftAuras = GetAuraEffectsByType(AuraType.ModShapeshift);
foreach (AuraEffect aurEff in shapeshiftAuras)
{
+1 -1
View File
@@ -2675,7 +2675,7 @@ namespace Game.Groups
BonusData bonusData = new BonusData(itemInstance);
ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(itemid);
uint itemLevel = Item.GetItemLevel(itemTemplate, bonusData, player.GetLevel(), 0, 0, 0, 0, false);
uint itemLevel = Item.GetItemLevel(itemTemplate, bonusData, player.GetLevel(), 0, 0, 0, 0, false, 0);
return Item.GetDisenchantLoot(itemTemplate, (uint)bonusData.Quality, itemLevel);
}
+173
View File
@@ -0,0 +1,173 @@
/*
* Copyright (C) 2012-2019 CypherCore <http://github.com/CypherCore>
*
* 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 3 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/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Network;
using Game.DataStorage;
using System.Collections.Generic;
using Game.Network.Packets;
namespace Game
{
public partial class WorldSession
{
[WorldPacketHandler(ClientOpcodes.AzeriteEssenceUnlockMilestone)]
void HandleAzeriteEssenceUnlockMilestone(AzeriteEssenceUnlockMilestone azeriteEssenceUnlockMilestone)
{
if (!AzeriteItem.FindHeartForge(_player))
return;
Item item = _player.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (!item)
return;
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (!azeriteItem || !azeriteItem.CanUseEssences())
return;
AzeriteItemMilestonePowerRecord milestonePower = CliDB.AzeriteItemMilestonePowerStorage.LookupByKey(azeriteEssenceUnlockMilestone.AzeriteItemMilestonePowerID);
if (milestonePower == null || milestonePower.RequiredLevel > azeriteItem.GetLevel())
return;
// check that all previous milestones are unlocked
foreach (AzeriteItemMilestonePowerRecord previousMilestone in Global.DB2Mgr.GetAzeriteItemMilestonePowers())
{
if (previousMilestone == milestonePower)
break;
if (!azeriteItem.HasUnlockedEssenceMilestone(previousMilestone.ID))
return;
}
azeriteItem.AddUnlockedEssenceMilestone(milestonePower.ID);
_player.ApplyAzeriteItemMilestonePower(azeriteItem, milestonePower, true);
azeriteItem.SetState(ItemUpdateState.Changed, _player);
}
[WorldPacketHandler(ClientOpcodes.AzeriteEssenceActivateEssence)]
void HandleAzeriteEssenceActivateEssence(AzeriteEssenceActivateEssence azeriteEssenceActivateEssence)
{
AzeriteEssenceSelectionResult activateEssenceResult = new AzeriteEssenceSelectionResult();
activateEssenceResult.AzeriteEssenceID = azeriteEssenceActivateEssence.AzeriteEssenceID;
Item item = _player.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (!item || !item.IsEquipped())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.NotEquipped;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult);
return;
}
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (azeriteItem == null || !azeriteItem.CanUseEssences())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.ConditionFailed;
SendPacket(activateEssenceResult);
return;
}
if (azeriteEssenceActivateEssence.Slot >= SharedConst.MaxAzeriteEssenceSlot || !azeriteItem.HasUnlockedEssenceSlot(azeriteEssenceActivateEssence.Slot))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.SlotLocked;
SendPacket(activateEssenceResult);
return;
}
SelectedAzeriteEssences selectedEssences = azeriteItem.GetSelectedAzeriteEssences();
// essence is already in that slot, nothing to do
if (selectedEssences.AzeriteEssenceID[azeriteEssenceActivateEssence.Slot] == azeriteEssenceActivateEssence.AzeriteEssenceID)
return;
uint rank = azeriteItem.GetEssenceRank(azeriteEssenceActivateEssence.AzeriteEssenceID);
if (rank == 0)
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.EssenceNotUnlocked;
activateEssenceResult.Arg = azeriteEssenceActivateEssence.AzeriteEssenceID;
SendPacket(activateEssenceResult);
return;
}
if (_player.IsInCombat())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.AffectingCombat;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult);
return;
}
if (_player.IsDead())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.CantDoThatRightNow;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult);
return;
}
if (!_player.HasPlayerFlag(PlayerFlags.Resting) && !_player.HasUnitFlag2(UnitFlags2.AllowChangingTalents))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.NotInRestArea;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult);
return;
}
// need to remove selected essence from another slot if selected
int removeEssenceFromSlot = -1;
for (int slot = 0; slot < SharedConst.MaxAzeriteEssenceSlot; ++slot)
if (azeriteEssenceActivateEssence.Slot != slot && selectedEssences.AzeriteEssenceID[slot] == azeriteEssenceActivateEssence.AzeriteEssenceID)
removeEssenceFromSlot = slot;
// check cooldown of major essence slot
if (selectedEssences.AzeriteEssenceID[0] != 0 && (azeriteEssenceActivateEssence.Slot == 0 || removeEssenceFromSlot == 0))
{
for (uint essenceRank = 1; essenceRank <= rank; ++essenceRank)
{
AzeriteEssencePowerRecord azeriteEssencePower = Global.DB2Mgr.GetAzeriteEssencePower(selectedEssences.AzeriteEssenceID[0], essenceRank);
if (_player.GetSpellHistory().HasCooldown(azeriteEssencePower.MajorPowerDescription))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult.CantRemoveEssence;
activateEssenceResult.Arg = azeriteEssencePower.MajorPowerDescription;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult);
return;
}
}
}
if (removeEssenceFromSlot != -1)
{
_player.ApplyAzeriteEssence(azeriteItem, selectedEssences.AzeriteEssenceID[removeEssenceFromSlot], SharedConst.MaxAzeriteEssenceRank,
(AzeriteItemMilestoneType)Global.DB2Mgr.GetAzeriteItemMilestonePower(removeEssenceFromSlot).Type == AzeriteItemMilestoneType.MajorEssence, false);
azeriteItem.SetSelectedAzeriteEssence(removeEssenceFromSlot, 0);
}
if (selectedEssences.AzeriteEssenceID[azeriteEssenceActivateEssence.Slot] != 0)
{
_player.ApplyAzeriteEssence(azeriteItem, selectedEssences.AzeriteEssenceID[azeriteEssenceActivateEssence.Slot], SharedConst.MaxAzeriteEssenceRank,
(AzeriteItemMilestoneType)Global.DB2Mgr.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot).Type == AzeriteItemMilestoneType.MajorEssence, false);
}
_player.ApplyAzeriteEssence(azeriteItem, azeriteEssenceActivateEssence.AzeriteEssenceID, rank,
(AzeriteItemMilestoneType)Global.DB2Mgr.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot).Type == AzeriteItemMilestoneType.MajorEssence, true);
azeriteItem.SetSelectedAzeriteEssence(azeriteEssenceActivateEssence.Slot, azeriteEssenceActivateEssence.AzeriteEssenceID);
azeriteItem.SetState(ItemUpdateState.Changed, _player);
}
}
}
+10
View File
@@ -2463,6 +2463,14 @@ namespace Game
stmt.AddValue(0, lowGuid);
SetQuery(PlayerLoginQueryLoad.LoadAzerite, stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_ITEM_INSTANCE_AZERITE_MILESTONE_POWER);
stmt.AddValue(0, lowGuid);
SetQuery(PlayerLoginQueryLoad.LoadAzeriteMilestonePowers, stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE);
stmt.AddValue(0, lowGuid);
SetQuery(PlayerLoginQueryLoad.LoadAzeriteUnlockedEssences, stmt);
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_VOID_STORAGE);
stmt.AddValue(0, lowGuid);
SetQuery(PlayerLoginQueryLoad.VoidStorage, stmt);
@@ -2626,6 +2634,8 @@ namespace Game
Inventory,
Artifacts,
LoadAzerite,
LoadAzeriteMilestonePowers,
LoadAzeriteUnlockedEssences,
Actions,
MailCount,
MailDate,
+9
View File
@@ -67,6 +67,15 @@ namespace Game
inspectResult.GuildData.Set(guildData);
}
Item heartOfAzeroth = player.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (heartOfAzeroth != null)
{
AzeriteItem azeriteItem = heartOfAzeroth.ToAzeriteItem();
if (azeriteItem != null)
inspectResult.AzeriteLevel = azeriteItem.GetEffectiveLevel();
}
inspectResult.ItemLevel = (int)player.GetAverageItemLevel();
inspectResult.LifetimeMaxRank = player.m_activePlayerData.LifetimeMaxRank;
inspectResult.TodayHK = player.m_activePlayerData.TodayHonorableKills;
inspectResult.YesterdayHK = player.m_activePlayerData.YesterdayHonorableKills;
@@ -17,6 +17,7 @@
using Framework.Constants;
using Game.Entities;
using Framework.Dynamic;
namespace Game.Network.Packets
{
@@ -33,4 +34,69 @@ namespace Game.Network.Packets
public ObjectGuid ItemGUID;
public ulong XP;
}
class AzeriteEssenceForgeOpened : ServerPacket
{
public AzeriteEssenceForgeOpened() : base(ServerOpcodes.AzeriteEssenceForgeOpened) { }
public override void Write()
{
_worldPacket.WritePackedGuid(ForgeGUID);
}
public ObjectGuid ForgeGUID;
}
class AzeriteEssenceForgeClose : ServerPacket
{
public AzeriteEssenceForgeClose() : base(ServerOpcodes.AzeriteEssenceForgeClose) { }
public override void Write() { }
}
class AzeriteEssenceUnlockMilestone : ClientPacket
{
public AzeriteEssenceUnlockMilestone(WorldPacket packet) : base(packet) { }
public override void Read()
{
AzeriteItemMilestonePowerID = _worldPacket.ReadInt32();
}
public int AzeriteItemMilestonePowerID;
}
class AzeriteEssenceActivateEssence : ClientPacket
{
public AzeriteEssenceActivateEssence(WorldPacket packet) : base(packet) { }
public override void Read()
{
AzeriteEssenceID = _worldPacket.ReadUInt32();
Slot = _worldPacket.ReadUInt8();
}
public uint AzeriteEssenceID;
public byte Slot;
}
class AzeriteEssenceSelectionResult : ServerPacket
{
public AzeriteEssenceSelectionResult() : base(ServerOpcodes.AzeriteEssenceSelectionResult) { }
public override void Write()
{
_worldPacket.WriteBits((int)Reason, 4);
_worldPacket.WriteBit(Slot.HasValue);
_worldPacket.WriteUInt32(Arg);
_worldPacket.WriteUInt32(AzeriteEssenceID);
if (Slot.HasValue)
_worldPacket.WriteUInt8(Slot.Value);
}
public AzeriteEssenceActivateResult Reason;
public uint Arg;
public uint AzeriteEssenceID;
public byte? Slot;
}
}
+26 -2
View File
@@ -75,7 +75,7 @@ namespace Game.Network.Packets
GuildData.Value.Write(_worldPacket);
if (AzeriteLevel.HasValue)
_worldPacket.WriteInt32(AzeriteLevel.Value);
_worldPacket.WriteUInt32((uint)AzeriteLevel);
}
public PlayerModelDisplayInfo DisplayInfo;
@@ -84,7 +84,7 @@ namespace Game.Network.Packets
public List<ushort> PvpTalents = new List<ushort>();
public Optional<InspectGuildData> GuildData = new Optional<InspectGuildData>();
public Array<PVPBracketData> Bracket = new Array<PVPBracketData>(6);
public Optional<int> AzeriteLevel;
public uint? AzeriteLevel;
public int ItemLevel;
public uint LifetimeHK;
public uint HonorLevel;
@@ -156,6 +156,30 @@ namespace Game.Network.Packets
}
++i;
}
AzeriteItem azeriteItem = item.ToAzeriteItem();
if (azeriteItem != null)
{
SelectedAzeriteEssences essences = azeriteItem.GetSelectedAzeriteEssences();
if (essences != null)
{
for (byte slot = 0; slot < essences.AzeriteEssenceID.GetSize(); ++slot)
{
AzeriteEssenceData essence = new AzeriteEssenceData();
essence.Index = slot;
essence.AzeriteEssenceID = essences.AzeriteEssenceID[slot];
if (essence.AzeriteEssenceID != 0)
{
essence.Rank = azeriteItem.GetEssenceRank(essence.AzeriteEssenceID);
essence.SlotUnlocked = true;
}
else
essence.SlotUnlocked = azeriteItem.HasUnlockedEssenceSlot(slot);
AzeriteEssences.Add(essence);
}
}
}
}
public void Write(WorldPacket data)
+2
View File
@@ -150,6 +150,8 @@ namespace Game.Spells
}
if (GetBase().GetSpellInfo().HasAttribute(SpellAttr8.AuraSendAmount) ||
GetBase().HasEffectType(AuraType.OverrideActionbarSpells) ||
GetBase().HasEffectType(AuraType.OverrideActionbarSpellsTriggered) ||
GetBase().HasEffectType(AuraType.ModSpellCategoryCooldown) ||
GetBase().HasEffectType(AuraType.ModMaxCharges) ||
GetBase().HasEffectType(AuraType.ChargeRecoveryMod) ||
+41
View File
@@ -5747,6 +5747,47 @@ namespace Game.Spells
unitTarget.ToPlayer().GetSession().GetCollectionMgr().AddTransmogSet((uint)effectInfo.MiscValue);
}
[SpellEffectHandler(SpellEffectName.LearnAzeriteEssencePower)]
void EffectLearnAzeriteEssencePower(uint effIndex)
{
if (effectHandleMode != SpellEffectHandleMode.HitTarget)
return;
Player playerTarget = unitTarget != null ? unitTarget.ToPlayer() : null;
if (!playerTarget)
return;
Item heartOfAzeroth = playerTarget.GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth);
if (heartOfAzeroth == null)
return;
AzeriteItem azeriteItem = heartOfAzeroth.ToAzeriteItem();
if (azeriteItem == null)
return;
// remove old rank and apply new one
if (azeriteItem.IsEquipped())
{
SelectedAzeriteEssences selectedEssences = azeriteItem.GetSelectedAzeriteEssences();
if (selectedEssences != null)
{
for (int slot = 0; slot < SharedConst.MaxAzeriteEssenceSlot; ++slot)
{
if (selectedEssences.AzeriteEssenceID[slot] == effectInfo.MiscValue)
{
bool major = (AzeriteItemMilestoneType)Global.DB2Mgr.GetAzeriteItemMilestonePower(slot).Type == AzeriteItemMilestoneType.MajorEssence;
playerTarget.ApplyAzeriteEssence(azeriteItem, (uint)effectInfo.MiscValue, SharedConst.MaxAzeriteEssenceRank, major, false);
playerTarget.ApplyAzeriteEssence(azeriteItem, (uint)effectInfo.MiscValue, (uint)effectInfo.MiscValueB, major, false);
break;
}
}
}
}
azeriteItem.SetEssenceRank((uint)effectInfo.MiscValue, (uint)effectInfo.MiscValueB);
azeriteItem.SetState(ItemUpdateState.Changed, playerTarget);
}
}
public class DispelableAura