diff --git a/Source/Framework/Util/CollectionExtensions.cs b/Source/Framework/Util/CollectionExtensions.cs index 224332773..a6a819932 100644 --- a/Source/Framework/Util/CollectionExtensions.cs +++ b/Source/Framework/Util/CollectionExtensions.cs @@ -180,6 +180,12 @@ namespace System.Collections.Generic { Array.Clear(array, 0, array.Length); } + + public static void EnsureWritableListIndex(this List list, uint index, T defaultValue) + { + while (list.Count <= index) + list.Add(defaultValue); + } } public interface ICheck diff --git a/Source/Game/Collision/Callbacks.cs b/Source/Game/Collision/Callbacks.cs index df50af6b2..e2760b20e 100644 --- a/Source/Game/Collision/Callbacks.cs +++ b/Source/Game/Collision/Callbacks.cs @@ -282,7 +282,7 @@ namespace Game.Collision public GameObjectModel GetHitModel() { return _hitModel; } PhaseShift _phaseShift; - LocationInfo _locationInfo; - GameObjectModel _hitModel; + LocationInfo _locationInfo = new(); + GameObjectModel _hitModel = new(); } } diff --git a/Source/Game/Collision/DynamicTree.cs b/Source/Game/Collision/DynamicTree.cs index a982d5de2..798753c8a 100644 --- a/Source/Game/Collision/DynamicTree.cs +++ b/Source/Game/Collision/DynamicTree.cs @@ -152,7 +152,7 @@ namespace Game.Collision { AreaAndLiquidData data = new(); - Vector3 v = new(x, y, z +0.5f); + Vector3 v = new(x, y, z + 0.5f); DynamicTreeLocationInfoCallback intersectionCallBack = new(phaseShift); impl.IntersectPoint(v, intersectionCallBack); if (intersectionCallBack.GetLocationInfo().hitModel != null) diff --git a/Source/Game/DataStorage/AreaTriggerDataStorage.cs b/Source/Game/DataStorage/AreaTriggerDataStorage.cs index 4bc42763a..4efc180ee 100644 --- a/Source/Game/DataStorage/AreaTriggerDataStorage.cs +++ b/Source/Game/DataStorage/AreaTriggerDataStorage.cs @@ -286,7 +286,7 @@ namespace Game.DataStorage uint oldMSTime = Time.GetMSTime(); // Load area trigger positions (to put them on the server) // 0 1 2 3 4 5 6 7 8 9 10 - SQLResult templates = DB.World.Query("SELECT SpawnId, AreaTriggerId, IsServerSide, MapId, PosX, PosY, PosZ, Orientation, PhaseUseFlags, PhaseId, PhaseGroup " + + SQLResult templates = DB.World.Query("SELECT SpawnId, AreaTriggerId, IsServerSide, MapId, PosX, PosY, PosZ, Orientation, PhaseUseFlags, PhaseId, PhaseGroup, " + //11 12 13 14 15 16 17 "Shape, ShapeData0, ShapeData1, ShapeData2, ShapeData3, ShapeData4, ShapeData5 FROM `areatrigger`"); if (!templates.IsEmpty()) diff --git a/Source/Game/Entities/AreaTrigger/AreaTriggerTemplate.cs b/Source/Game/Entities/AreaTrigger/AreaTriggerTemplate.cs index 84bfdd057..7b733cb30 100644 --- a/Source/Game/Entities/AreaTrigger/AreaTriggerTemplate.cs +++ b/Source/Game/Entities/AreaTrigger/AreaTriggerTemplate.cs @@ -311,7 +311,7 @@ namespace Game.Entities public AreaTriggerScaleInfo OverrideScale = new(); public AreaTriggerScaleInfo ExtraScale = new(); - public AreaTriggerShapeInfo Shape; + public AreaTriggerShapeInfo Shape = new(); public List PolygonVertices = new(); public List PolygonVerticesTarget = new(); public List SplinePoints = new(); @@ -327,7 +327,7 @@ namespace Game.Entities public uint PhaseGroup; public byte PhaseUseFlags; - public AreaTriggerShapeInfo Shape; + public AreaTriggerShapeInfo Shape = new(); } public struct AreaTriggerAction diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index 0bd87aa64..71f28990b 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -41,7 +41,8 @@ namespace Game.Spells if (spellEffect == null) continue; - _effects.Add(new SpellEffectInfo(this, spellEffect)); + _effects.EnsureWritableListIndex(spellEffect.EffectIndex, new SpellEffectInfo(this)); + _effects[(int)spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); } SpellName = spellName.Name; @@ -252,7 +253,10 @@ namespace Game.Spells SpellName = spellName.Name; foreach (SpellEffectRecord spellEffect in effects) - _effects.Add(new SpellEffectInfo(this, spellEffect)); + { + _effects.EnsureWritableListIndex(spellEffect.EffectIndex, new SpellEffectInfo(this)); + _effects[(int)spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); + } } public bool HasEffect(SpellEffectName effect) @@ -307,6 +311,9 @@ namespace Game.Spells public bool IsExplicitDiscovery() { + if (GetEffects().Count < 2) + return false; + return ((GetEffect(0).Effect == SpellEffectName.CreateRandomItem || GetEffect(0).Effect == SpellEffectName.CreateLoot) && GetEffect(1).Effect == SpellEffectName.ScriptEffect) @@ -3917,37 +3924,40 @@ namespace Game.Spells public class SpellEffectInfo { - public SpellEffectInfo(SpellInfo spellInfo, SpellEffectRecord effect) + public SpellEffectInfo(SpellInfo spellInfo, SpellEffectRecord effect = null) { _spellInfo = spellInfo; - EffectIndex = effect.EffectIndex; - Effect = (SpellEffectName)effect.Effect; - ApplyAuraName = (AuraType)effect.EffectAura; - ApplyAuraPeriod = effect.EffectAuraPeriod; - BasePoints = (int)effect.EffectBasePoints; - RealPointsPerLevel = effect.EffectRealPointsPerLevel; - PointsPerResource = effect.EffectPointsPerResource; - Amplitude = effect.EffectAmplitude; - ChainAmplitude = effect.EffectChainAmplitude; - BonusCoefficient = effect.EffectBonusCoefficient; - MiscValue = effect.EffectMiscValue[0]; - MiscValueB = effect.EffectMiscValue[1]; - Mechanic = (Mechanics)effect.EffectMechanic; - PositionFacing = effect.EffectPosFacing; - TargetA = new SpellImplicitTargetInfo((Targets)effect.ImplicitTarget[0]); - TargetB = new SpellImplicitTargetInfo((Targets)effect.ImplicitTarget[1]); - RadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(effect.EffectRadiusIndex[0]); - MaxRadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(effect.EffectRadiusIndex[1]); - ChainTargets = effect.EffectChainTargets; - ItemType = effect.EffectItemType; - TriggerSpell = effect.EffectTriggerSpell; - SpellClassMask = effect.EffectSpellClassMask; - BonusCoefficientFromAP = effect.BonusCoefficientFromAP; - Scaling.Class = effect.ScalingClass; - Scaling.Coefficient = effect.Coefficient; - Scaling.Variance = effect.Variance; - Scaling.ResourceCoefficient = effect.ResourceCoefficient; - EffectAttributes = effect.EffectAttributes; + if (effect != null) + { + EffectIndex = effect.EffectIndex; + Effect = (SpellEffectName)effect.Effect; + ApplyAuraName = (AuraType)effect.EffectAura; + ApplyAuraPeriod = effect.EffectAuraPeriod; + BasePoints = (int)effect.EffectBasePoints; + RealPointsPerLevel = effect.EffectRealPointsPerLevel; + PointsPerResource = effect.EffectPointsPerResource; + Amplitude = effect.EffectAmplitude; + ChainAmplitude = effect.EffectChainAmplitude; + BonusCoefficient = effect.EffectBonusCoefficient; + MiscValue = effect.EffectMiscValue[0]; + MiscValueB = effect.EffectMiscValue[1]; + Mechanic = (Mechanics)effect.EffectMechanic; + PositionFacing = effect.EffectPosFacing; + TargetA = new SpellImplicitTargetInfo((Targets)effect.ImplicitTarget[0]); + TargetB = new SpellImplicitTargetInfo((Targets)effect.ImplicitTarget[1]); + RadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(effect.EffectRadiusIndex[0]); + MaxRadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(effect.EffectRadiusIndex[1]); + ChainTargets = effect.EffectChainTargets; + ItemType = effect.EffectItemType; + TriggerSpell = effect.EffectTriggerSpell; + SpellClassMask = effect.EffectSpellClassMask; + BonusCoefficientFromAP = effect.BonusCoefficientFromAP; + Scaling.Class = effect.ScalingClass; + Scaling.Coefficient = effect.Coefficient; + Scaling.Variance = effect.Variance; + Scaling.ResourceCoefficient = effect.ResourceCoefficient; + EffectAttributes = effect.EffectAttributes; + } ImplicitTargetConditions = null; @@ -4669,8 +4679,8 @@ namespace Game.Spells public int MiscValueB; public Mechanics Mechanic; public float PositionFacing; - public SpellImplicitTargetInfo TargetA; - public SpellImplicitTargetInfo TargetB; + public SpellImplicitTargetInfo TargetA = new(); + public SpellImplicitTargetInfo TargetB = new(); public SpellRadiusRecord RadiusEntry; public SpellRadiusRecord MaxRadiusEntry; public int ChainTargets; diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index 55d42c107..ea1769deb 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -2462,7 +2462,7 @@ namespace Game.Entities Log.outError(LogFilter.Sql, $"Serverside spell {spellId} difficulty {difficulty} has invalid max radius id {effect.EffectRadiusIndex[1]} at index {effect.EffectIndex}, set to 0"); } - spellEffects[(spellId, difficulty)].Add(effect); + spellEffects.Add((spellId, difficulty), effect); } while (effectsResult.NextRow()); }