Core/Spells: Allow skipping automatic removal of auras from spell_area when condition is no longer met (mostly used for cosmetic cutscenes after quest completion)
This commit is contained in:
@@ -2425,4 +2425,10 @@ namespace Framework.Constants
|
||||
IncludeGCD = 0x1, // Starts GCD in addition to normal cooldown specified in the packet
|
||||
IncludeEventCooldowns = 0x2 // Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set
|
||||
}
|
||||
|
||||
public enum SpellAreaFlag
|
||||
{
|
||||
AutoCast = 0x1, // if has autocast, spell is applied on enter
|
||||
AutoRemove = 0x2, // if has autoremove, spell is remove automatically inside zone/area (allways removed on leaving area or zone)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ namespace Game.DataStorage
|
||||
foreach (var areaGroupMember in CliDB.AreaGroupMemberStorage.Values)
|
||||
_areaGroupMembers.Add(areaGroupMember.AreaGroupID, areaGroupMember.AreaID);
|
||||
|
||||
CliDB.AreaGroupMemberStorage.Clear();
|
||||
|
||||
foreach (ArtifactPowerRecord artifactPower in CliDB.ArtifactPowerStorage.Values)
|
||||
_artifactPowers.Add(artifactPower.ArtifactID, artifactPower);
|
||||
|
||||
@@ -56,21 +58,29 @@ namespace Game.DataStorage
|
||||
_artifactPowerLinks.Add(artifactPowerLink.ToArtifactPowerID, artifactPowerLink.FromArtifactPowerID);
|
||||
}
|
||||
|
||||
CliDB.ArtifactPowerLinkStorage.Clear();
|
||||
|
||||
foreach (ArtifactPowerRankRecord artifactPowerRank in CliDB.ArtifactPowerRankStorage.Values)
|
||||
_artifactPowerRanks[Tuple.Create((uint)artifactPowerRank.ArtifactPowerID, artifactPowerRank.Rank)] = artifactPowerRank;
|
||||
|
||||
CliDB.ArtifactPowerRankStorage.Clear();
|
||||
|
||||
foreach (CharacterFacialHairStylesRecord characterFacialStyle in CliDB.CharacterFacialHairStylesStorage.Values)
|
||||
_characterFacialHairStyles.Add(Tuple.Create(characterFacialStyle.RaceID, characterFacialStyle.SexID, (uint)characterFacialStyle.VariationID));
|
||||
|
||||
CliDB.CharacterFacialHairStylesStorage.Clear();
|
||||
|
||||
CharBaseSectionVariation[] sectionToBase = new CharBaseSectionVariation[(int)CharSectionType.Max];
|
||||
foreach (CharBaseSectionRecord charBaseSection in CliDB.CharBaseSectionStorage.Values)
|
||||
{
|
||||
Contract.Assert(charBaseSection.ResolutionVariation < (byte)CharSectionType.Max, $"SECTION_TYPE_MAX ({(byte)CharSectionType.Max}) must be equal to or greater than {charBaseSection.ResolutionVariation + 1}");
|
||||
Contract.Assert(charBaseSection.Variation < CharBaseSectionVariation.Max, $"CharBaseSectionVariation.Max {(byte)CharBaseSectionVariation.Max} must be equal to or greater than {charBaseSection.Variation + 1}");
|
||||
|
||||
sectionToBase[charBaseSection.ResolutionVariation] = (CharBaseSectionVariation)charBaseSection.Variation;
|
||||
sectionToBase[charBaseSection.ResolutionVariation] = charBaseSection.Variation;
|
||||
}
|
||||
|
||||
CliDB.CharBaseSectionStorage.Clear();
|
||||
|
||||
MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, Tuple<byte, byte>> addedSections = new MultiMap<Tuple<byte, byte, CharBaseSectionVariation>, Tuple<byte, byte>>();
|
||||
foreach (CharSectionsRecord charSection in CliDB.CharSectionsStorage.Values)
|
||||
{
|
||||
@@ -85,6 +95,8 @@ namespace Game.DataStorage
|
||||
_charSections.Add(sectionKey, charSection);
|
||||
}
|
||||
|
||||
CliDB.CharSectionsStorage.Clear();
|
||||
|
||||
foreach (var outfit in CliDB.CharStartOutfitStorage.Values)
|
||||
_charStartOutfits[(uint)(outfit.RaceID | (outfit.ClassID << 8) | (outfit.GenderID << 16))] = outfit;
|
||||
|
||||
@@ -92,6 +104,8 @@ namespace Game.DataStorage
|
||||
foreach (var chrClasses in CliDB.ChrClassesXPowerTypesStorage.Values)
|
||||
powers.Add(chrClasses);
|
||||
|
||||
CliDB.ChrClassesXPowerTypesStorage.Clear();
|
||||
|
||||
powers.Sort(new ChrClassesXPowerTypesRecordComparer());
|
||||
foreach (var power in powers)
|
||||
{
|
||||
@@ -129,12 +143,16 @@ namespace Game.DataStorage
|
||||
_curvePoints.Add(curvePoint.CurveID, curvePoint);
|
||||
}
|
||||
|
||||
CliDB.CurvePointStorage.Clear();
|
||||
|
||||
foreach (var key in _curvePoints.Keys.ToList())
|
||||
_curvePoints[key] = _curvePoints[key].OrderBy(point => point.Index).ToList();
|
||||
|
||||
foreach (EmotesTextSoundRecord emoteTextSound in CliDB.EmotesTextSoundStorage.Values)
|
||||
_emoteTextSounds[Tuple.Create((uint)emoteTextSound.EmotesTextId, emoteTextSound.RaceId, emoteTextSound.SexId, emoteTextSound.ClassId)] = emoteTextSound;
|
||||
|
||||
CliDB.EmotesTextSoundStorage.Clear();
|
||||
|
||||
foreach (FactionRecord faction in CliDB.FactionStorage.Values)
|
||||
if (faction.ParentFactionID != 0)
|
||||
_factionTeams.Add(faction.ParentFactionID, faction.Id);
|
||||
@@ -152,18 +170,28 @@ namespace Game.DataStorage
|
||||
foreach (HeirloomRecord heirloom in CliDB.HeirloomStorage.Values)
|
||||
_heirlooms[heirloom.ItemID] = heirloom;
|
||||
|
||||
CliDB.HeirloomStorage.Clear();
|
||||
|
||||
foreach (GlyphBindableSpellRecord glyphBindableSpell in CliDB.GlyphBindableSpellStorage.Values)
|
||||
_glyphBindableSpells.Add(glyphBindableSpell.GlyphPropertiesID, glyphBindableSpell.SpellID);
|
||||
|
||||
CliDB.GlyphBindableSpellStorage.Clear();
|
||||
|
||||
foreach (GlyphRequiredSpecRecord glyphRequiredSpec in CliDB.GlyphRequiredSpecStorage.Values)
|
||||
_glyphRequiredSpecs.Add(glyphRequiredSpec.GlyphPropertiesID, glyphRequiredSpec.ChrSpecializationID);
|
||||
|
||||
CliDB.GlyphRequiredSpecStorage.Clear();
|
||||
|
||||
foreach (var bonus in CliDB.ItemBonusStorage.Values)
|
||||
_itemBonusLists.Add(bonus.BonusListID, bonus);
|
||||
|
||||
CliDB.ItemBonusStorage.Clear();
|
||||
|
||||
foreach (ItemBonusListLevelDeltaRecord itemBonusListLevelDelta in CliDB.ItemBonusListLevelDeltaStorage.Values)
|
||||
_itemLevelDeltaToBonusListContainer[itemBonusListLevelDelta.Delta] = itemBonusListLevelDelta.Id;
|
||||
|
||||
CliDB.ItemBonusListLevelDeltaStorage.Clear();
|
||||
|
||||
foreach (var key in CliDB.ItemBonusTreeNodeStorage.Keys)
|
||||
{
|
||||
ItemBonusTreeNodeRecord bonusTreeNode = CliDB.ItemBonusTreeNodeStorage[key];
|
||||
@@ -175,12 +203,16 @@ namespace Game.DataStorage
|
||||
}
|
||||
}
|
||||
|
||||
CliDB.ItemBonusTreeNodeStorage.Clear();
|
||||
|
||||
foreach (ItemChildEquipmentRecord itemChildEquipment in CliDB.ItemChildEquipmentStorage.Values)
|
||||
{
|
||||
//ASSERT(_itemChildEquipment.find(itemChildEquipment.ItemID) == _itemChildEquipment.end(), "Item must have max 1 child item.");
|
||||
_itemChildEquipment[itemChildEquipment.ItemID] = itemChildEquipment;
|
||||
}
|
||||
|
||||
CliDB.ItemChildEquipmentStorage.Clear();
|
||||
|
||||
foreach (ItemClassRecord itemClass in CliDB.ItemClassStorage.Values)
|
||||
{
|
||||
//ASSERT(itemClass->OldEnumValue < _itemClassByOldEnum.size());
|
||||
@@ -188,12 +220,18 @@ namespace Game.DataStorage
|
||||
_itemClassByOldEnum[itemClass.OldEnumValue] = itemClass;
|
||||
}
|
||||
|
||||
CliDB.ItemClassStorage.Clear();
|
||||
|
||||
foreach (ItemCurrencyCostRecord itemCurrencyCost in CliDB.ItemCurrencyCostStorage.Values)
|
||||
_itemsWithCurrencyCost.Add(itemCurrencyCost.ItemId);
|
||||
|
||||
CliDB.ItemCurrencyCostStorage.Clear();
|
||||
|
||||
foreach (ItemLevelSelectorQualityRecord itemLevelSelectorQuality in CliDB.ItemLevelSelectorQualityStorage.Values)
|
||||
_itemLevelQualitySelectorQualities.Add(itemLevelSelectorQuality.ItemLevelSelectorQualitySetID, itemLevelSelectorQuality);
|
||||
|
||||
|
||||
CliDB.ItemLevelSelectorQualityStorage.Clear();
|
||||
|
||||
foreach (var appearanceMod in CliDB.ItemModifiedAppearanceStorage.Values)
|
||||
{
|
||||
//ASSERT(appearanceMod.ItemID <= 0xFFFFFF);
|
||||
@@ -203,12 +241,18 @@ namespace Game.DataStorage
|
||||
foreach (ItemSetSpellRecord itemSetSpell in CliDB.ItemSetSpellStorage.Values)
|
||||
_itemSetSpells.Add(itemSetSpell.ItemSetID, itemSetSpell);
|
||||
|
||||
CliDB.ItemSetSpellStorage.Clear();
|
||||
|
||||
foreach (var itemSpecOverride in CliDB.ItemSpecOverrideStorage.Values)
|
||||
_itemSpecOverrides.Add(itemSpecOverride.ItemID, itemSpecOverride);
|
||||
|
||||
CliDB.ItemSpecOverrideStorage.Clear();
|
||||
|
||||
foreach (var itemBonusTreeAssignment in CliDB.ItemXBonusTreeStorage.Values)
|
||||
_itemToBonusTree.Add(itemBonusTreeAssignment.ItemID, itemBonusTreeAssignment.BonusTreeID);
|
||||
|
||||
CliDB.ItemXBonusTreeStorage.Clear();
|
||||
|
||||
foreach (MapDifficultyRecord entry in CliDB.MapDifficultyStorage.Values)
|
||||
{
|
||||
if (!_mapDifficulties.ContainsKey(entry.MapID))
|
||||
@@ -218,18 +262,24 @@ namespace Game.DataStorage
|
||||
}
|
||||
_mapDifficulties[0][0] = _mapDifficulties[1][0]; // map 0 is missing from MapDifficulty.dbc so we cheat a bit
|
||||
|
||||
CliDB.MapDifficultyStorage.Clear();
|
||||
|
||||
foreach (var mount in CliDB.MountStorage.Values)
|
||||
_mountsBySpellId[mount.SpellId] = mount;
|
||||
|
||||
foreach (MountTypeXCapabilityRecord mountTypeCapability in CliDB.MountTypeXCapabilityStorage.Values)
|
||||
_mountCapabilitiesByType.Add(mountTypeCapability.MountTypeID, mountTypeCapability);
|
||||
|
||||
CliDB.MountTypeXCapabilityStorage.Clear();
|
||||
|
||||
foreach (var key in _mountCapabilitiesByType.Keys)
|
||||
_mountCapabilitiesByType[key].Sort(new MountTypeXCapabilityRecordComparer());
|
||||
|
||||
foreach (MountXDisplayRecord mountDisplay in CliDB.MountXDisplayStorage.Values)
|
||||
_mountDisplays.Add(mountDisplay.MountID, mountDisplay);
|
||||
|
||||
CliDB.MountXDisplayStorage.Clear();
|
||||
|
||||
foreach (var entry in CliDB.NameGenStorage.Values)
|
||||
{
|
||||
if (!_nameGenData.ContainsKey(entry.Race))
|
||||
@@ -242,6 +292,8 @@ namespace Game.DataStorage
|
||||
_nameGenData[entry.Race][entry.Sex].Add(entry);
|
||||
}
|
||||
|
||||
CliDB.NameGenStorage.Clear();
|
||||
|
||||
foreach (var namesProfanity in CliDB.NamesProfanityStorage.Values)
|
||||
{
|
||||
Contract.Assert(namesProfanity.Language < (int)LocaleConstant.Total || namesProfanity.Language == -1);
|
||||
@@ -257,9 +309,13 @@ namespace Game.DataStorage
|
||||
}
|
||||
}
|
||||
|
||||
CliDB.NamesProfanityStorage.Clear();
|
||||
|
||||
foreach (var namesReserved in CliDB.NamesReservedStorage.Values)
|
||||
_nameValidators[(int)LocaleConstant.Total].Add(new Regex(namesReserved.Name, RegexOptions.IgnoreCase | RegexOptions.Compiled));
|
||||
|
||||
CliDB.NamesReservedStorage.Clear();
|
||||
|
||||
foreach (var namesReserved in CliDB.NamesReservedLocaleStorage.Values)
|
||||
{
|
||||
Contract.Assert(!Convert.ToBoolean(namesReserved.LocaleMask & ~((1 << (int)LocaleConstant.Total) - 1)));
|
||||
@@ -272,6 +328,7 @@ namespace Game.DataStorage
|
||||
_nameValidators[i].Add(new Regex(namesReserved.Name, RegexOptions.IgnoreCase | RegexOptions.Compiled));
|
||||
}
|
||||
}
|
||||
CliDB.NamesReservedLocaleStorage.Clear();
|
||||
|
||||
foreach (var group in CliDB.PhaseXPhaseGroupStorage.Values)
|
||||
{
|
||||
@@ -279,6 +336,7 @@ namespace Game.DataStorage
|
||||
if (phase != null)
|
||||
_phasesByGroup.Add(group.PhaseGroupID, phase.Id);
|
||||
}
|
||||
CliDB.PhaseXPhaseGroupStorage.Clear();
|
||||
|
||||
foreach (PowerTypeRecord powerType in CliDB.PowerTypeStorage.Values)
|
||||
{
|
||||
@@ -290,6 +348,8 @@ namespace Game.DataStorage
|
||||
foreach (PvpRewardRecord pvpReward in CliDB.PvpRewardStorage.Values)
|
||||
_pvpRewardPack[Tuple.Create(pvpReward.Prestige, pvpReward.HonorLevel)] = pvpReward.RewardPackID;
|
||||
|
||||
CliDB.PvpRewardStorage.Clear();
|
||||
|
||||
foreach (QuestPackageItemRecord questPackageItem in CliDB.QuestPackageItemStorage.Values)
|
||||
{
|
||||
if (!_questPackages.ContainsKey(questPackageItem.QuestPackageID))
|
||||
@@ -301,12 +361,18 @@ namespace Game.DataStorage
|
||||
_questPackages[questPackageItem.QuestPackageID].Item2.Add(questPackageItem);
|
||||
}
|
||||
|
||||
CliDB.QuestPackageItemStorage.Clear();
|
||||
|
||||
foreach (RewardPackXItemRecord rewardPackXItem in CliDB.RewardPackXItemStorage.Values)
|
||||
_rewardPackItems.Add(rewardPackXItem.RewardPackID, rewardPackXItem);
|
||||
|
||||
CliDB.RewardPackXItemStorage.Clear();
|
||||
|
||||
foreach (RulesetItemUpgradeRecord rulesetItemUpgrade in CliDB.RulesetItemUpgradeStorage.Values)
|
||||
_rulesetItemUpgrade[rulesetItemUpgrade.ItemID] = rulesetItemUpgrade.ItemUpgradeID;
|
||||
|
||||
CliDB.RulesetItemUpgradeStorage.Clear();
|
||||
|
||||
foreach (SkillRaceClassInfoRecord entry in CliDB.SkillRaceClassInfoStorage.Values)
|
||||
{
|
||||
if (CliDB.SkillLineStorage.ContainsKey(entry.SkillID))
|
||||
@@ -316,10 +382,12 @@ namespace Game.DataStorage
|
||||
foreach (var specSpells in CliDB.SpecializationSpellsStorage.Values)
|
||||
_specializationSpellsBySpec.Add(specSpells.SpecID, specSpells);
|
||||
|
||||
CliDB.SpecializationSpellsStorage.Clear();
|
||||
|
||||
foreach (SpellClassOptionsRecord classOption in CliDB.SpellClassOptionsStorage.Values)
|
||||
_spellFamilyNames.Add(classOption.SpellClassSet);
|
||||
|
||||
foreach (var power in CliDB.SpellPowerStorage.Values)
|
||||
foreach (SpellPowerRecord power in CliDB.SpellPowerStorage.Values)
|
||||
{
|
||||
SpellPowerDifficultyRecord powerDifficulty = CliDB.SpellPowerDifficultyStorage.LookupByKey(power.Id);
|
||||
if (powerDifficulty != null)
|
||||
@@ -341,9 +409,13 @@ namespace Game.DataStorage
|
||||
}
|
||||
}
|
||||
|
||||
CliDB.SpellPowerStorage.Clear();
|
||||
|
||||
foreach (SpellProcsPerMinuteModRecord ppmMod in CliDB.SpellProcsPerMinuteModStorage.Values)
|
||||
_spellProcsPerMinuteMods.Add(ppmMod.SpellProcsPerMinuteID, ppmMod);
|
||||
|
||||
CliDB.SpellProcsPerMinuteModStorage.Clear();
|
||||
|
||||
for (var i = 0; i < (int)Class.Max; ++i)
|
||||
{
|
||||
_talentsByPosition[i] = new List<TalentRecord>[PlayerConst.MaxTalentTiers][];
|
||||
@@ -355,6 +427,7 @@ namespace Game.DataStorage
|
||||
_talentsByPosition[i][x][c] = new List<TalentRecord>();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (TalentRecord talentInfo in CliDB.TalentStorage.Values)
|
||||
{
|
||||
//ASSERT(talentInfo.ClassID < MAX_CLASSES);
|
||||
@@ -366,6 +439,8 @@ namespace Game.DataStorage
|
||||
foreach (ToyRecord toy in CliDB.ToyStorage.Values)
|
||||
_toys.Add(toy.ItemID);
|
||||
|
||||
CliDB.ToyStorage.Clear();
|
||||
|
||||
foreach (TransmogSetItemRecord transmogSetItem in CliDB.TransmogSetItemStorage.Values)
|
||||
{
|
||||
TransmogSetRecord set = CliDB.TransmogSetStorage.LookupByKey(transmogSetItem.TransmogSetID);
|
||||
@@ -376,56 +451,17 @@ namespace Game.DataStorage
|
||||
_transmogSetItemsByTransmogSet.Add(transmogSetItem.TransmogSetID, transmogSetItem);
|
||||
}
|
||||
|
||||
CliDB.TransmogSetItemStorage.Clear();
|
||||
|
||||
foreach (WMOAreaTableRecord entry in CliDB.WMOAreaTableStorage.Values)
|
||||
_wmoAreaTableLookup[Tuple.Create(entry.WMOID, entry.NameSet, entry.WMOGroupID)] = entry;
|
||||
|
||||
CliDB.WMOAreaTableStorage.Clear();
|
||||
|
||||
foreach (WorldMapAreaRecord worldMapArea in CliDB.WorldMapAreaStorage.Values)
|
||||
_worldMapAreaByAreaID[worldMapArea.AreaID] = worldMapArea;
|
||||
|
||||
ClearNotUsedTables();
|
||||
}
|
||||
|
||||
void ClearNotUsedTables()
|
||||
{
|
||||
CliDB.AreaGroupMemberStorage = null;
|
||||
CliDB.ArtifactPowerLinkStorage = null;
|
||||
CliDB.ArtifactPowerRankStorage = null;
|
||||
CliDB.CharSectionsStorage = null;
|
||||
CliDB.ChrClassesXPowerTypesStorage = null;
|
||||
CliDB.CurvePointStorage = null;
|
||||
CliDB.EmotesTextSoundStorage = null;
|
||||
CliDB.GlyphBindableSpellStorage = null;
|
||||
CliDB.GlyphRequiredSpecStorage = null;
|
||||
CliDB.HeirloomStorage = null;
|
||||
CliDB.ItemBonusStorage = null;
|
||||
CliDB.ItemBonusListLevelDeltaStorage = null;
|
||||
CliDB.ItemBonusTreeNodeStorage = null;
|
||||
CliDB.ItemClassStorage = null;
|
||||
CliDB.ItemChildEquipmentStorage = null;
|
||||
CliDB.ItemCurrencyCostStorage = null;
|
||||
CliDB.ItemSetSpellStorage = null;
|
||||
CliDB.ItemSpecOverrideStorage = null;
|
||||
CliDB.ItemXBonusTreeStorage = null;
|
||||
CliDB.MapDifficultyStorage = null;
|
||||
CliDB.MountTypeXCapabilityStorage = null;
|
||||
CliDB.MountXDisplayStorage = null;
|
||||
CliDB.NameGenStorage = null;
|
||||
CliDB.NamesProfanityStorage = null;
|
||||
CliDB.NamesReservedStorage = null;
|
||||
CliDB.NamesReservedLocaleStorage = null;
|
||||
CliDB.PhaseXPhaseGroupStorage = null;
|
||||
CliDB.PowerTypeStorage = null;
|
||||
CliDB.PvpRewardStorage = null;
|
||||
CliDB.QuestPackageItemStorage = null;
|
||||
CliDB.RewardPackXItemStorage = null;
|
||||
CliDB.RulesetItemUpgradeStorage = null;
|
||||
CliDB.SpecializationSpellsStorage = null;
|
||||
CliDB.SpellPowerDifficultyStorage = null;
|
||||
CliDB.SpellPowerStorage = null;
|
||||
CliDB.SpellProcsPerMinuteModStorage = null;
|
||||
CliDB.ToyStorage = null;
|
||||
CliDB.WMOAreaTableStorage = null;
|
||||
CliDB.WorldMapAreaStorage = null;
|
||||
CliDB.WorldMapAreaStorage.Clear();
|
||||
}
|
||||
|
||||
public IDB2Storage GetStorage(uint type)
|
||||
|
||||
@@ -1802,9 +1802,9 @@ namespace Game.Entities
|
||||
{
|
||||
foreach (var spell in saBounds)
|
||||
{
|
||||
if (!spell.IsFitToRequirements(this, zone, area))
|
||||
if (spell.flags.HasAnyFlag(SpellAreaFlag.AutoRemove) && !spell.IsFitToRequirements(this, zone, area))
|
||||
RemoveAurasDueToSpell(spell.spellId);
|
||||
else if (spell.autocast)
|
||||
else if (spell.flags.HasAnyFlag(SpellAreaFlag.AutoCast))
|
||||
if (!HasAura(spell.spellId))
|
||||
CastSpell(this, spell.spellId, true);
|
||||
}
|
||||
|
||||
@@ -1765,7 +1765,7 @@ namespace Game.Entities
|
||||
// Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone.area update
|
||||
var saBounds = Global.SpellMgr.GetSpellAreaForAreaMapBounds(newZone);
|
||||
foreach (var spell in saBounds)
|
||||
if (spell.autocast && spell.IsFitToRequirements(this, newZone, 0))
|
||||
if (spell.flags.HasAnyFlag(SpellAreaFlag.AutoCast) && spell.IsFitToRequirements(this, newZone, 0))
|
||||
if (!HasAura(spell.spellId))
|
||||
CastSpell(this, spell.spellId, true);
|
||||
}
|
||||
@@ -1783,7 +1783,7 @@ namespace Game.Entities
|
||||
// some auras applied at subzone enter
|
||||
var saBounds = Global.SpellMgr.GetSpellAreaForAreaMapBounds(newArea);
|
||||
foreach (var spell in saBounds)
|
||||
if (spell.autocast && spell.IsFitToRequirements(this, m_zoneUpdateId, newArea))
|
||||
if (spell.flags.HasAnyFlag(SpellAreaFlag.AutoCast) && spell.IsFitToRequirements(this, m_zoneUpdateId, newArea))
|
||||
if (!HasAura(spell.spellId))
|
||||
CastSpell(this, spell.spellId, true);
|
||||
}
|
||||
|
||||
@@ -1132,16 +1132,16 @@ namespace Game.Spells
|
||||
uint zone, area;
|
||||
target.GetZoneAndAreaId(out zone, out area);
|
||||
|
||||
foreach (var bound in saBounds)
|
||||
foreach (var spellArea in saBounds)
|
||||
{
|
||||
// some auras remove at aura remove
|
||||
if (!bound.IsFitToRequirements((Player)target, zone, area))
|
||||
target.RemoveAurasDueToSpell(bound.spellId);
|
||||
if (spellArea.flags.HasAnyFlag(SpellAreaFlag.AutoRemove) && !spellArea.IsFitToRequirements((Player)target, zone, area))
|
||||
target.RemoveAurasDueToSpell(spellArea.spellId);
|
||||
// some auras applied at aura apply
|
||||
else if (bound.autocast)
|
||||
else if (spellArea.flags.HasAnyFlag(SpellAreaFlag.AutoCast))
|
||||
{
|
||||
if (!target.HasAura(bound.spellId))
|
||||
target.CastSpell(target, bound.spellId, true);
|
||||
if (!target.HasAura(spellArea.spellId))
|
||||
target.CastSpell(target, spellArea.spellId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1742,8 +1742,8 @@ namespace Game.Entities
|
||||
mSpellAreaForQuestEndMap.Clear();
|
||||
mSpellAreaForAuraMap.Clear();
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
SQLResult result = DB.World.Query("SELECT spell, area, quest_start, quest_start_status, quest_end_status, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
SQLResult result = DB.World.Query("SELECT spell, area, quest_start, quest_start_status, quest_end_status, quest_end, aura_spell, racemask, gender, flags FROM spell_area");
|
||||
if (result.IsEmpty())
|
||||
{
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 spell area requirements. DB table `spell_area` is empty.");
|
||||
@@ -1766,12 +1766,12 @@ namespace Game.Entities
|
||||
spellArea.auraSpell = result.Read<int>(6);
|
||||
spellArea.raceMask = result.Read<uint>(7);
|
||||
spellArea.gender = (Gender)result.Read<uint>(8);
|
||||
spellArea.autocast = result.Read<bool>(9);
|
||||
spellArea.flags = (SpellAreaFlag)result.Read<byte>(9);
|
||||
|
||||
SpellInfo spellInfo = GetSpellInfo(spell);
|
||||
if (spellInfo != null)
|
||||
{
|
||||
if (spellArea.autocast)
|
||||
if (spellArea.flags.HasAnyFlag(SpellAreaFlag.AutoCast))
|
||||
spellInfo.Attributes |= SpellAttr0.CantCancel;
|
||||
}
|
||||
else
|
||||
@@ -1847,13 +1847,13 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// not allow autocast chains by auraSpell field (but allow use as alternative if not present)
|
||||
if (spellArea.autocast && spellArea.auraSpell > 0)
|
||||
if (spellArea.flags.HasAnyFlag(SpellAreaFlag.AutoCast) && spellArea.auraSpell > 0)
|
||||
{
|
||||
bool chain = false;
|
||||
var saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
|
||||
foreach (var bound in saBound)
|
||||
{
|
||||
if (bound.autocast && bound.auraSpell > 0)
|
||||
if (bound.flags.HasAnyFlag(SpellAreaFlag.AutoCast) && bound.auraSpell > 0)
|
||||
{
|
||||
chain = true;
|
||||
break;
|
||||
@@ -1869,7 +1869,7 @@ namespace Game.Entities
|
||||
var saBound2 = GetSpellAreaMapBounds((uint)spellArea.auraSpell);
|
||||
foreach (var bound in saBound2)
|
||||
{
|
||||
if (bound.autocast && bound.auraSpell > 0)
|
||||
if (bound.flags.HasAnyFlag(SpellAreaFlag.AutoCast) && bound.auraSpell > 0)
|
||||
{
|
||||
chain = true;
|
||||
break;
|
||||
@@ -1947,11 +1947,6 @@ namespace Game.Entities
|
||||
if (!effectsBySpell.ContainsKey(effect.SpellID))
|
||||
effectsBySpell[effect.SpellID] = new Dictionary<uint, SpellEffectRecord[]>();
|
||||
|
||||
if(effect.DifficultyID > (int)Difficulty.Max)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (!effectsBySpell[effect.SpellID].ContainsKey(effect.DifficultyID))
|
||||
effectsBySpell[effect.SpellID][effect.DifficultyID] = new SpellEffectRecord[SpellConst.MaxEffects];
|
||||
|
||||
@@ -1965,54 +1960,89 @@ namespace Game.Entities
|
||||
if (auraOptions.DifficultyID == 0) // TODO: implement
|
||||
loadData[auraOptions.SpellID].AuraOptions = auraOptions;
|
||||
|
||||
CliDB.SpellAuraOptionsStorage.Clear();
|
||||
|
||||
foreach (SpellAuraRestrictionsRecord auraRestrictions in CliDB.SpellAuraRestrictionsStorage.Values)
|
||||
{
|
||||
if (auraRestrictions.DifficultyID == 0) // TODO: implement
|
||||
loadData[auraRestrictions.SpellID].AuraRestrictions = auraRestrictions;
|
||||
}
|
||||
CliDB.SpellAuraRestrictionsStorage.Clear();
|
||||
|
||||
foreach (SpellCastingRequirementsRecord castingRequirements in CliDB.SpellCastingRequirementsStorage.Values)
|
||||
loadData[castingRequirements.SpellID].CastingRequirements = castingRequirements;
|
||||
|
||||
CliDB.SpellCastingRequirementsStorage.Clear();
|
||||
|
||||
foreach (SpellCategoriesRecord categories in CliDB.SpellCategoriesStorage.Values)
|
||||
{
|
||||
if (categories.DifficultyID == 0) // TODO: implement
|
||||
loadData[categories.SpellID].Categories = categories;
|
||||
}
|
||||
CliDB.SpellCategoriesStorage.Clear();
|
||||
|
||||
foreach (SpellClassOptionsRecord classOptions in CliDB.SpellClassOptionsStorage.Values)
|
||||
loadData[classOptions.SpellID].ClassOptions = classOptions;
|
||||
|
||||
CliDB.SpellClassOptionsStorage.Clear();
|
||||
|
||||
foreach (SpellCooldownsRecord cooldowns in CliDB.SpellCooldownsStorage.Values)
|
||||
{
|
||||
if (cooldowns.DifficultyID == 0) // TODO: implement
|
||||
loadData[cooldowns.SpellID].Cooldowns = cooldowns;
|
||||
}
|
||||
CliDB.SpellCooldownsStorage.Clear();
|
||||
|
||||
foreach (SpellEffectScalingRecord spellEffectScaling in CliDB.SpellEffectScalingStorage.Values)
|
||||
spellEffectScallingByEffectId[spellEffectScaling.SpellEffectID] = spellEffectScaling;
|
||||
|
||||
CliDB.SpellEffectScalingStorage.Clear();
|
||||
|
||||
foreach (SpellEquippedItemsRecord equippedItems in CliDB.SpellEquippedItemsStorage.Values)
|
||||
loadData[equippedItems.SpellID].EquippedItems = equippedItems;
|
||||
|
||||
CliDB.SpellEquippedItemsStorage.Clear();
|
||||
|
||||
foreach (SpellInterruptsRecord interrupts in CliDB.SpellInterruptsStorage.Values)
|
||||
{
|
||||
if (interrupts.DifficultyID == 0) // TODO: implement
|
||||
loadData[interrupts.SpellID].Interrupts = interrupts;
|
||||
}
|
||||
CliDB.SpellInterruptsStorage.Clear();
|
||||
|
||||
foreach (SpellLevelsRecord levels in CliDB.SpellLevelsStorage.Values)
|
||||
{
|
||||
if (levels.DifficultyID == 0) // TODO: implement
|
||||
loadData[levels.SpellID].Levels = levels;
|
||||
}
|
||||
|
||||
foreach (SpellReagentsRecord reagents in CliDB.SpellReagentsStorage.Values)
|
||||
loadData[reagents.SpellID].Reagents = reagents;
|
||||
|
||||
CliDB.SpellReagentsStorage.Clear();
|
||||
|
||||
foreach (SpellScalingRecord scaling in CliDB.SpellScalingStorage.Values)
|
||||
loadData[scaling.SpellID].Scaling = scaling;
|
||||
|
||||
CliDB.SpellScalingStorage.Clear();
|
||||
|
||||
foreach (SpellShapeshiftRecord shapeshift in CliDB.SpellShapeshiftStorage.Values)
|
||||
loadData[shapeshift.SpellID].Shapeshift = shapeshift;
|
||||
|
||||
CliDB.SpellShapeshiftStorage.Clear();
|
||||
|
||||
foreach (SpellTargetRestrictionsRecord targetRestrictions in CliDB.SpellTargetRestrictionsStorage.Values)
|
||||
{
|
||||
if (targetRestrictions.DifficultyID == 0) // TODO: implement
|
||||
loadData[targetRestrictions.SpellID].TargetRestrictions = targetRestrictions;
|
||||
}
|
||||
CliDB.SpellTargetRestrictionsStorage.Clear();
|
||||
|
||||
foreach (SpellTotemsRecord totems in CliDB.SpellTotemsStorage.Values)
|
||||
loadData[totems.SpellID].Totems = totems;
|
||||
|
||||
CliDB.SpellTotemsStorage.Clear();
|
||||
|
||||
foreach (var visual in CliDB.SpellXSpellVisualStorage.Values)
|
||||
{
|
||||
if (!visualsBySpell.ContainsKey(visual.SpellID))
|
||||
@@ -2028,6 +2058,8 @@ namespace Game.Entities
|
||||
mSpellInfoMap[spellEntry.Id] = new SpellInfo(loadData[spellEntry.Id], effectsBySpell.LookupByKey(spellEntry.Id), visualsBySpell.LookupByKey(spellEntry.Id), spellEffectScallingByEffectId);
|
||||
}
|
||||
|
||||
CliDB.SpellStorage.Clear();
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo store in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
@@ -3161,15 +3193,15 @@ namespace Game.Entities
|
||||
public class SpellArea
|
||||
{
|
||||
public uint spellId;
|
||||
public uint areaId; // zone/subzone/or 0 is not limited to zone
|
||||
public uint questStart; // quest start (quest must be active or rewarded for spell apply)
|
||||
public uint questEnd; // quest end (quest must not be rewarded for spell apply)
|
||||
public uint areaId; // zone/subzone/or 0 is not limited to zone
|
||||
public uint questStart; // quest start (quest must be active or rewarded for spell apply)
|
||||
public uint questEnd; // quest end (quest must not be rewarded for spell apply)
|
||||
public int auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case
|
||||
public uint raceMask; // can be applied only to races
|
||||
public Gender gender; // can be applied only to gender
|
||||
public uint questStartStatus; // QuestStatus that quest_start must have in order to keep the spell
|
||||
public uint questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped)
|
||||
public bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
|
||||
public uint raceMask; // can be applied only to races
|
||||
public Gender gender; // can be applied only to gender
|
||||
public uint questStartStatus; // QuestStatus that quest_start must have in order to keep the spell
|
||||
public uint questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped)
|
||||
public SpellAreaFlag flags; // if SPELL_AREA_FLAG_AUTOCAST then auto applied at area enter, in other case just allowed to cast || if SPELL_AREA_FLAG_AUTOREMOVE then auto removed inside area (will allways be removed on leaved even without flag)
|
||||
|
||||
// helpers
|
||||
public bool IsFitToRequirements(Player player, uint newZone, uint newArea)
|
||||
|
||||
Reference in New Issue
Block a user