From 0d689847171fe16971bd4c5b2ac61962a62b0264 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 5 Jan 2022 13:11:32 -0500 Subject: [PATCH] Misc fixes, and added GetDebugInfo() which was missed. --- Source/Framework/Constants/Language.cs | 16 +++---- Source/Framework/Util/Time.cs | 2 +- Source/Game/AI/CoreAI/CreatureAI.cs | 4 +- Source/Game/AI/CoreAI/PetAI.cs | 2 +- Source/Game/AI/CoreAI/UnitAI.cs | 47 ++++++++++--------- Source/Game/Chat/Channels/Channel.cs | 6 +-- Source/Game/Chat/Commands/GoCommands.cs | 2 +- Source/Game/Entities/Creature/Creature.cs | 11 +++-- Source/Game/Entities/GameObject/GameObject.cs | 5 ++ Source/Game/Entities/Item/Item.cs | 5 ++ Source/Game/Entities/Object/Position.cs | 8 ++++ Source/Game/Entities/Object/WorldObject.cs | 5 ++ Source/Game/Entities/Pet.cs | 5 ++ Source/Game/Entities/Player/Player.cs | 2 +- Source/Game/Entities/TemporarySummon.cs | 10 ++++ Source/Game/Entities/Unit/Unit.Combat.cs | 2 +- Source/Game/Entities/Unit/Unit.cs | 8 +++- Source/Game/Handlers/MiscHandler.cs | 2 +- Source/Game/Maps/Map.cs | 12 ++++- .../Generators/FlightPathMovementGenerator.cs | 18 +++++++ .../Movement/Generators/MovementGenerators.cs | 7 ++- .../Game/Movement/Generators/PathGenerator.cs | 4 +- .../Movement/Generators/WaypointMovement.cs | 5 ++ Source/Game/Server/WorldConfig.cs | 11 ++++- Source/Game/Spells/Auras/Aura.cs | 4 ++ Source/Game/Spells/Spell.cs | 5 ++ Source/Game/Spells/SpellManager.cs | 9 ++++ Source/Scripts/Spells/Druid.cs | 6 +-- 28 files changed, 170 insertions(+), 53 deletions(-) diff --git a/Source/Framework/Constants/Language.cs b/Source/Framework/Constants/Language.cs index 3cb0566b7..2adb9c570 100644 --- a/Source/Framework/Constants/Language.cs +++ b/Source/Framework/Constants/Language.cs @@ -940,7 +940,7 @@ namespace Framework.Constants CommandNoInstancesMatch = 1189, CommandMultipleInstancesMatch = 1190, CommandMultipleInstancesEntry = 1191, - CommandMapNotInstance = 1192, + // 1192 unused, CommandInstanceNoEntrance = 1193, CommandInstanceNoExit = 1194, CommandWentToInstanceGate = 1195, @@ -956,13 +956,13 @@ namespace Framework.Constants DebugAreatriggerOff = 1203, DebugAreatriggerEntered = 1204, - CommandNoBossesMatch = 1205, // 3.3.5 Reserved - CommandMultipleBossesMatch = 1206, // 3.3.5 Reserved - CommandMultipleBossesEntry = 1207, // 3.3.5 Reserved - CommandBossMultipleSpawns = 1208, // 3.3.5 Reserved - CommandBossMultipleSpawnEty = 1209, // 3.3.5 Reserved - CommandGoBossFailed = 1210, // 3.3.5 Reserved - CommandWentToBoss = 1211, // 3.3.5 Reserved + CommandNoBossesMatch = 1205, + CommandMultipleBossesMatch = 1206, + CommandMultipleBossesEntry = 1207, + CommandBossMultipleSpawns = 1208, + CommandBossMultipleSpawnEty = 1209, + CommandGoBossFailed = 1210, + CommandWentToBoss = 1211, GuildInfoLevel = 1212, AccountBnetLinked = 1213, AccountOrBnetDoesNotExist = 1214, diff --git a/Source/Framework/Util/Time.cs b/Source/Framework/Util/Time.cs index d86adb839..e446bd649 100644 --- a/Source/Framework/Util/Time.cs +++ b/Source/Framework/Util/Time.cs @@ -127,7 +127,7 @@ public static class Time long midnightLocal = DateTimeToUnixTime(timeLocal); long hourLocal = midnightLocal + hour * Hour; - if (onlyAfterTime && hourLocal < time) + if (onlyAfterTime && hourLocal <= time) hourLocal += Day; return hourLocal; diff --git a/Source/Game/AI/CoreAI/CreatureAI.cs b/Source/Game/AI/CoreAI/CreatureAI.cs index 130a75ec0..7b5ebdde5 100644 --- a/Source/Game/AI/CoreAI/CreatureAI.cs +++ b/Source/Game/AI/CoreAI/CreatureAI.cs @@ -274,7 +274,7 @@ namespace Game.AI { if (_isEngaged) { - //Log.outError(LogFilter.ScriptsAi, $"CreatureAI::EngagementStart called even though creature is already engaged. Creature debug info:\n{me.GetDebugInfo()}"); + Log.outError(LogFilter.ScriptsAi, $"CreatureAI::EngagementStart called even though creature is already engaged. Creature debug info:\n{me.GetDebugInfo()}"); return; } _isEngaged = true; @@ -286,7 +286,7 @@ namespace Game.AI { if (!_isEngaged) { - //Log.outError(LogFilter.ScriptsAi, $"CreatureAI::EngagementOver called even though creature is not currently engaged. Creature debug info:\n{me.GetDebugInfo()}"); + Log.outError(LogFilter.ScriptsAi, $"CreatureAI::EngagementOver called even though creature is not currently engaged. Creature debug info:\n{me.GetDebugInfo()}"); return; } _isEngaged = false; diff --git a/Source/Game/AI/CoreAI/PetAI.cs b/Source/Game/AI/CoreAI/PetAI.cs index cb8382f76..9ec93dd6a 100644 --- a/Source/Game/AI/CoreAI/PetAI.cs +++ b/Source/Game/AI/CoreAI/PetAI.cs @@ -478,7 +478,7 @@ namespace Game.AI if (me.GetCharmInfo() == null) { - //Log.outError(LogFilter.ScriptsAi, $"me.GetCharmInfo() is NULL in PetAI::CanAttack(). Debug info: {}", GetDebugInfo()); + Log.outError(LogFilter.ScriptsAi, $"me.GetCharmInfo() is NULL in PetAI::CanAttack(). Debug info: {GetDebugInfo()}"); return false; } diff --git a/Source/Game/AI/CoreAI/UnitAI.cs b/Source/Game/AI/CoreAI/UnitAI.cs index 391ed173a..c0875cc0e 100644 --- a/Source/Game/AI/CoreAI/UnitAI.cs +++ b/Source/Game/AI/CoreAI/UnitAI.cs @@ -260,36 +260,36 @@ namespace Game.AI target = me.GetVictim(); break; case AITarget.Enemy: + { + var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID()); + if (spellInfo != null) { - var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID()); - if (spellInfo != null) - { - bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers); - target = SelectTarget(SelectAggroTarget.Random, 0, spellInfo.GetMaxRange(false), playerOnly); - } - break; + bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers); + target = SelectTarget(SelectAggroTarget.Random, 0, spellInfo.GetMaxRange(false), playerOnly); } + break; + } case AITarget.Ally: case AITarget.Buff: target = me; break; case AITarget.Debuff: + { + var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID()); + if (spellInfo != null) { - var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID()); - if (spellInfo != null) - { - bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers); - float range = spellInfo.GetMaxRange(false); + bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers); + float range = spellInfo.GetMaxRange(false); - DefaultTargetSelector targetSelector = new(me, range, playerOnly, true, -(int)spellId); - if (!spellInfo.HasAuraInterruptFlag(SpellAuraInterruptFlags.NotVictim) - && targetSelector.Invoke(me.GetVictim())) - target = me.GetVictim(); - else - target = SelectTarget(SelectAggroTarget.Random, 0, targetSelector); - } - break; + DefaultTargetSelector targetSelector = new(me, range, playerOnly, true, -(int)spellId); + if (!spellInfo.HasAuraInterruptFlag(SpellAuraInterruptFlags.NotVictim) + && targetSelector.Invoke(me.GetVictim())) + target = me.GetVictim(); + else + target = SelectTarget(SelectAggroTarget.Random, 0, targetSelector); } + break; + } } if (target != null) @@ -318,7 +318,7 @@ namespace Game.AI } public SpellCastResult DoCastAOE(uint spellId, CastSpellExtraArgs args = null) { return DoCast(null, spellId, args); } - + public static void FillAISpellInfo() { Global.SpellMgr.ForEachSpellInfo(spellInfo => @@ -502,6 +502,11 @@ namespace Game.AI /// public virtual void OnGameEvent(bool start, ushort eventId) { } + public virtual string GetDebugInfo() + { + return $"Me: {(me != null ? me.GetDebugInfo() : "NULL")}"; + } + public static AISpellInfoType GetAISpellInfo(uint spellId, Difficulty difficulty) { return _aiSpellInfo.LookupByKey((spellId, difficulty)); diff --git a/Source/Game/Chat/Channels/Channel.cs b/Source/Game/Chat/Channels/Channel.cs index 5a23c3494..96753174d 100644 --- a/Source/Game/Chat/Channels/Channel.cs +++ b/Source/Game/Chat/Channels/Channel.cs @@ -301,7 +301,7 @@ namespace Game.Chat Player bad = Global.ObjAccessor.FindPlayerByName(badname); ObjectGuid victim = bad ? bad.GetGUID() : ObjectGuid.Empty; - if (victim.IsEmpty() || !IsOn(victim)) + if (bad == null || victim.IsEmpty() || !IsOn(victim)) { ChannelNameBuilder builder = new(this, new PlayerNotFoundAppend(badname)); SendToOne(builder, good); @@ -434,7 +434,7 @@ namespace Game.Chat Player newp = Global.ObjAccessor.FindPlayerByName(p2n); ObjectGuid victim = newp ? newp.GetGUID() : ObjectGuid.Empty; - if (victim.IsEmpty() || !IsOn(victim) || + if (newp == null || victim.IsEmpty() || !IsOn(victim) || (player.GetTeam() != newp.GetTeam() && (!player.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel) || !newp.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel)))) @@ -490,7 +490,7 @@ namespace Game.Chat Player newp = Global.ObjAccessor.FindPlayerByName(newname); ObjectGuid victim = newp ? newp.GetGUID() : ObjectGuid.Empty; - if (victim.IsEmpty() || !IsOn(victim) || + if (newp == null || victim.IsEmpty() || !IsOn(victim) || (player.GetTeam() != newp.GetTeam() && (!player.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel) || !newp.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel)))) diff --git a/Source/Game/Chat/Commands/GoCommands.cs b/Source/Game/Chat/Commands/GoCommands.cs index 6dce164e4..40589c59a 100644 --- a/Source/Game/Chat/Commands/GoCommands.cs +++ b/Source/Game/Chat/Commands/GoCommands.cs @@ -159,7 +159,7 @@ namespace Game.Chat.Commands InstanceTemplate temp = Global.ObjectMgr.GetInstanceTemplate(mapId); if (temp == null) { - handler.SendSysMessage(CypherStrings.CommandMapNotInstance, mapId); + //handler.SendSysMessage(CypherStrings.CommandMapNotInstance, mapId); return false; } string scriptname = Global.ObjectMgr.GetScriptName(temp.ScriptId); diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index 5308272e6..9f1e43ee0 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -1098,6 +1098,11 @@ namespace Game.Entities return false; } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nAIName: {GetAIName()} ScriptName: {GetScriptName()} WaypointPath: {GetWaypointPath()} SpawnId: {GetSpawnId()}"; + } + public override bool IsMovementPreventedByCasting() { // first check if currently a movement allowed channel is active and we're not casting @@ -3022,7 +3027,7 @@ namespace Game.Entities { if (!HasSpellFocus()) { - //Log.outError(LogFilter.Unit, $"Creature::ReacquireSpellFocusTarget() being called with HasSpellFocus() returning false. {GetDebugInfo()}"); + Log.outError(LogFilter.Unit, $"Creature::ReacquireSpellFocusTarget() being called with HasSpellFocus() returning false. {GetDebugInfo()}"); return; } @@ -3170,7 +3175,7 @@ namespace Game.Entities // @todo pools need fixing! this is just a temporary thing, but they violate dynspawn principles if (Global.PoolMgr.IsPartOfAPool(spawnId) == 0) { - Log.outError(LogFilter.Unit, $"Creature (SpawnID {spawnId}) trying to load in inactive spawn group '{data.spawnGroupData.name}'"); + Log.outError(LogFilter.Unit, $"Creature (SpawnID {spawnId}) trying to load in inactive spawn group '{data.spawnGroupData.name}':\n{GetDebugInfo()}"); return false; } } @@ -3185,7 +3190,7 @@ namespace Game.Entities // @todo same as above if (Global.PoolMgr.IsPartOfAPool(spawnId) == 0) { - Log.outError(LogFilter.Unit, $"Creature (SpawnID {spawnId}) trying to load despite a respawn timer in progress"); + Log.outError(LogFilter.Unit, $"Creature (SpawnID {spawnId}) trying to load despite a respawn timer in progress:\n{GetDebugInfo()}"); return false; } } diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index 37a2d1f62..e5b1a1426 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -2292,6 +2292,11 @@ namespace Game.Entities return localRotation; } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nSpawnId: {GetSpawnId()} GoState: {GetGoState()} ScriptId: {GetScriptId()} AIName: {GetAIName()}"; + } + public bool IsAtInteractDistance(Player player, SpellInfo spell = null) { if (spell != null || (spell = GetSpellForLock(player)) != null) diff --git a/Source/Game/Entities/Item/Item.cs b/Source/Game/Entities/Item/Item.cs index b3e6c2dcc..9e28bdba6 100644 --- a/Source/Game/Entities/Item/Item.cs +++ b/Source/Game/Entities/Item/Item.cs @@ -2340,6 +2340,11 @@ namespace Game.Entities return _bonusData.RequiredLevel; } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nOwner: {GetOwnerGUID()} Count: {GetCount()} BagSlot: {GetBagSlot()} Slot: {GetSlot()} Equipped: {IsEquipped()}"; + } + public static Item NewItemOrBag(ItemTemplate proto) { if (proto.GetInventoryType() == InventoryType.Bag) diff --git a/Source/Game/Entities/Object/Position.cs b/Source/Game/Entities/Object/Position.cs index f285c56a3..c0dbcf2fe 100644 --- a/Source/Game/Entities/Object/Position.cs +++ b/Source/Game/Entities/Object/Position.cs @@ -15,8 +15,10 @@ * along with this program. If not, see . */ +using Game.DataStorage; using Game.Maps; using System; +using System.Collections.Generic; using System.Numerics; namespace Game.Entities @@ -409,6 +411,12 @@ namespace Game.Entities return this; } + public virtual string GetDebugInfo() + { + var mapEntry = CliDB.MapStorage.LookupByKey(_mapId); + return $"MapID: {_mapId} Map name: '{(mapEntry != null ? mapEntry.MapName[Global.WorldMgr.GetDefaultDbcLocale()] : "")}' {base.ToString()}"; + } + public override string ToString() { return $"X: {posX} Y: {posY} Z: {posZ} O: {Orientation} MapId: {_mapId}"; diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index f2a707a87..285978b9c 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -750,6 +750,11 @@ namespace Game.Entities BuildValuesUpdateBlockForPlayer(data_map[player], player); } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\n{GetGUID()} Entry: {GetEntry()}\nName: { GetName()}"; + } + public abstract void BuildValuesCreate(WorldPacket data, Player target); public abstract void BuildValuesUpdate(WorldPacket data, Player target); diff --git a/Source/Game/Entities/Pet.cs b/Source/Game/Entities/Pet.cs index 68284d3c8..f64988de8 100644 --- a/Source/Game/Entities/Pet.cs +++ b/Source/Game/Entities/Pet.cs @@ -1598,6 +1598,11 @@ namespace Game.Entities return ss.ToString(); } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nPetType: {GetPetType()}"; + } + public DeclinedName GetDeclinedNames() { return _declinedname; } public new Dictionary m_spells = new(); diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 19d555217..9a0deb0e0 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -5076,7 +5076,7 @@ namespace Game.Entities return area.HasFlag2(AreaFlags2.CanEnableWarMode); } - + // Used in triggers for check "Only to targets that grant experience or honor" req public bool IsHonorOrXPTarget(Unit victim) { diff --git a/Source/Game/Entities/TemporarySummon.cs b/Source/Game/Entities/TemporarySummon.cs index 504e03dc7..3d7c621a4 100644 --- a/Source/Game/Entities/TemporarySummon.cs +++ b/Source/Game/Entities/TemporarySummon.cs @@ -300,6 +300,11 @@ namespace Game.Entities base.RemoveFromWorld(); } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nTempSummonType : {GetSummonType()} Summoner: {GetSummonerGUID()}"; + } + public override void SaveToDB(uint mapid, List spawnDifficulties) { } public ObjectGuid GetSummonerGUID() { return m_summonerGUID; } @@ -380,6 +385,11 @@ namespace Game.Entities return IsPet() || (m_Properties != null && m_Properties.Control == SummonCategory.Pet); } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nOwner: {(GetOwner() ? GetOwner().GetGUID() : "")}"; + } + public override Unit GetOwner() { return m_owner; } public override float GetFollowAngle() { return m_followAngle; } diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index 383e058ba..e62589d91 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -817,7 +817,7 @@ namespace Game.Entities if (pet.IsAIEnabled()) pet.GetAI().KilledUnit(victim); else - Log.outError(LogFilter.Unit, "Pet doesn't have any AI in Unit.Kill()"); + Log.outError(LogFilter.Unit, $"Pet doesn't have any AI in Unit.Kill() {pet.GetDebugInfo()}"); } } diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index c0822a893..f2ceafb5f 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -847,6 +847,12 @@ namespace Game.Entities return collisionHeight1 == 0.0f ? MapConst.DefaultCollesionHeight : collisionHeight1; } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nIsAIEnabled: {IsAIEnabled()} DeathState: {GetDeathState()} UnitMovementFlags: {GetUnitMovementFlags()} UnitMovementFlags2: {GetUnitMovementFlags2()} Class: {GetClass()}\n" + + $" {(MoveSpline != null ? MoveSpline.ToString() : "Movespline: ")}"; + } + public Guardian GetGuardianPet() { ObjectGuid pet_guid = GetPetGUID(); @@ -1424,7 +1430,7 @@ namespace Game.Entities // this can happen if OnEffectHitTarget() script hook killed the unit or the aura owner (which can be different) if (aura.IsRemoved()) { - Log.outError(LogFilter.Spells, "Unit::_CreateAuraApplication() called with a removed aura. Check if OnEffectHitTarget() is triggering any spell with apply aura effect (that's not allowed!)");//\nUnit: {}\nAura: {}", GetDebugInfo().c_str(), aura->GetDebugInfo().c_str()); + Log.outError(LogFilter.Spells, $"Unit::_CreateAuraApplication() called with a removed aura. Check if OnEffectHitTarget() is triggering any spell with apply aura effect (that's not allowed!)\nUnit: {GetDebugInfo()}\nAura: {aura.GetDebugInfo()}"); return null; } diff --git a/Source/Game/Handlers/MiscHandler.cs b/Source/Game/Handlers/MiscHandler.cs index 540aef0f9..f39812148 100644 --- a/Source/Game/Handlers/MiscHandler.cs +++ b/Source/Game/Handlers/MiscHandler.cs @@ -59,7 +59,7 @@ namespace Game [WorldPacketHandler(ClientOpcodes.UpdateAccountData, Status = SessionStatus.Authed)] void HandleUpdateAccountData(UserClientUpdateAccountData packet) { - if (packet.DataType > AccountDataTypes.Max) + if (packet.DataType >= AccountDataTypes.Max) return; if (packet.Size == 0) diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index d24708c4b..94e8ec110 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -202,7 +202,7 @@ namespace Game.Maps if (Global.MMapMgr.LoadMap(Global.WorldMgr.GetDataPath(), GetId(), gx, gy)) Log.outInfo(LogFilter.Maps, "MMAP loaded name:{0}, id:{1}, x:{2}, y:{3} (mmap rep.: x:{4}, y:{5})", GetMapName(), GetId(), gx, gy, gx, gy); else - Log.outInfo(LogFilter.Maps, "Could not load MMAP name:{0}, id:{1}, x:{2}, y:{3} (mmap rep.: x:{4}, y:{5})", GetMapName(), GetId(), gx, gy, gx, gy); + Log.outWarn(LogFilter.Maps, "Could not load MMAP name:{0}, id:{1}, x:{2}, y:{3} (mmap rep.: x:{4}, y:{5})", GetMapName(), GetId(), gx, gy, gx, gy); } void LoadVMap(uint gx, uint gy) @@ -3488,6 +3488,11 @@ namespace Game.Maps } } + public virtual string GetDebugInfo() + { + return $"Id: {GetId()} InstanceId: {GetInstanceId()} Difficulty: {GetDifficultyID()} HasPlayers: {HavePlayers()}"; + } + public MapRecord GetEntry() { return i_mapRecord; @@ -5432,6 +5437,11 @@ namespace Game.Maps return i_script_id; } + public override string GetDebugInfo() + { + return $"{base.GetDebugInfo()}\nScriptId: {GetScriptId()} ScriptName: {GetScriptName()}"; + } + public InstanceScript GetInstanceScript() { return i_data; diff --git a/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs b/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs index b38a0710b..5f2b1263a 100644 --- a/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs +++ b/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs @@ -81,6 +81,8 @@ namespace Game.Movement bool departureEvent = true; do { + Cypher.Assert(_currentNode < _path.Count, $"Point Id: {pointId}\n{owner.GetDebugInfo()}"); + DoEventIfAny(owner, _path[_currentNode], departureEvent); while (!_pointsForPathSwitch.Empty() && _pointsForPathSwitch[0].PathIndex <= _currentNode) { @@ -226,6 +228,8 @@ namespace Game.Movement void DoEventIfAny(Player owner, TaxiPathNodeRecord node, bool departure) { + Cypher.Assert(node != null, owner.GetDebugInfo()); + uint eventid = departure ? node.DepartureEventID : node.ArrivalEventID; if (eventid != 0) { @@ -263,6 +267,20 @@ namespace Game.Movement Log.outDebug(LogFilter.Server, "FlightPathMovementGenerator::PreloadEndGrid: Unable to determine map to preload flightmaster grid"); } + uint GetPathId(int index) + { + if (index >= _path.Count) + return 0; + + return _path[index].PathID; + } + + public override string GetDebugInfo() + { + return $"Current Node: {GetCurrentNode()}\n{base.GetDebugInfo()}\nStart Path Id: {GetPathId(0)} Path Size: {_path.Count} HasArrived: {HasArrived()} End Grid X: {_endGridX} " + + $"End Grid Y: {_endGridY} End Map Id: {_endMapId} Preloaded Target Node: {_preloadTargetNode}"; + } + public override bool GetResetPosition(Unit u, out float x, out float y, out float z) { var node = _path[_currentNode]; diff --git a/Source/Game/Movement/Generators/MovementGenerators.cs b/Source/Game/Movement/Generators/MovementGenerators.cs index df239735e..6e12c3ac5 100644 --- a/Source/Game/Movement/Generators/MovementGenerators.cs +++ b/Source/Game/Movement/Generators/MovementGenerators.cs @@ -76,8 +76,13 @@ namespace Game.Movement { return obj.Mode.GetHashCode() ^ obj.Priority.GetHashCode(); } - } + public virtual string GetDebugInfo() + { + return $"Mode: {Mode} Priority: {Priority} Flags: {Flags} BaseUniteState: {BaseUnitState}"; + } + } + public abstract class MovementGeneratorMedium : MovementGenerator where T : Unit { public override void Initialize(Unit owner) diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index 66cc0e0f5..3ddbe7b3f 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -384,7 +384,7 @@ namespace Game.Movement // this is probably an error state, but we'll leave it // and hopefully recover on the next Update // we still need to copy our preffix - Log.outError(LogFilter.Maps, "{0}'s Path Build failed: 0 length path", _sourceUnit.GetGUID().ToString()); + Log.outError(LogFilter.Maps, $"Path Build failed\n{_sourceUnit.GetDebugInfo()}"); } Log.outDebug(LogFilter.Maps, "m_polyLength={0} prefixPolyLength={1} suffixPolyLength={2} \n", _polyLength, prefixPolyLength, suffixPolyLength); @@ -709,7 +709,7 @@ namespace Game.Movement npolys = FixupCorridor(polys, npolys, 74, visited, nvisited); if (Detour.dtStatusFailed(_navMeshQuery.getPolyHeight(polys[0], result, ref result[1]))) - Log.outDebug(LogFilter.Maps, $"Cannot find height at position X: {result[2]} Y: {result[0]} Z: {result[1]} for ");// {_sourceUnit.GetDebugInfo()}"); + Log.outDebug(LogFilter.Maps, $"Cannot find height at position X: {result[2]} Y: {result[0]} Z: {result[1]} for {_sourceUnit.GetDebugInfo()}"); result[1] += 0.5f; Detour.dtVcopy(iterPos, result); diff --git a/Source/Game/Movement/Generators/WaypointMovement.cs b/Source/Game/Movement/Generators/WaypointMovement.cs index ee679ef76..0e3230ef5 100644 --- a/Source/Game/Movement/Generators/WaypointMovement.cs +++ b/Source/Game/Movement/Generators/WaypointMovement.cs @@ -397,6 +397,11 @@ namespace Game.Movement return true; } + public override string GetDebugInfo() + { + return $"Current Node: {_currentNode}\n{base.GetDebugInfo()}"; + } + bool UpdateTimer(uint diff) { _nextMoveTime.Update((int)diff); diff --git a/Source/Game/Server/WorldConfig.cs b/Source/Game/Server/WorldConfig.cs index 543ea17a9..335a1743a 100644 --- a/Source/Game/Server/WorldConfig.cs +++ b/Source/Game/Server/WorldConfig.cs @@ -542,14 +542,14 @@ namespace Game Values[WorldCfg.InstanceResetTimeHour] = GetDefaultValue("Instance.ResetTimeHour", 4); Values[WorldCfg.InstanceUnloadDelay] = GetDefaultValue("Instance.UnloadDelay", 30 * Time.Minute * Time.InMilliseconds); Values[WorldCfg.DailyQuestResetTimeHour] = GetDefaultValue("Quests.DailyResetTime", 3); - if ((int)Values[WorldCfg.DailyQuestResetTimeHour] < 0 || (int)Values[WorldCfg.DailyQuestResetTimeHour] > 23) + if ((int)Values[WorldCfg.DailyQuestResetTimeHour] > 23) { Log.outError(LogFilter.ServerLoading, $"Quests.DailyResetTime ({Values[WorldCfg.DailyQuestResetTimeHour]}) must be in range 0..23. Set to 3."); Values[WorldCfg.DailyQuestResetTimeHour] = 3; } Values[WorldCfg.WeeklyQuestResetTimeWDay] = GetDefaultValue("Quests.WeeklyResetWDay", 3); - if ((int)Values[WorldCfg.WeeklyQuestResetTimeWDay] < 0 || (int)Values[WorldCfg.WeeklyQuestResetTimeWDay] > 6) + if ((int)Values[WorldCfg.WeeklyQuestResetTimeWDay] > 6) { Log.outError(LogFilter.ServerLoading, $"Quests.WeeklyResetDay ({Values[WorldCfg.WeeklyQuestResetTimeWDay]}) must be in range 0..6. Set to 3 (Wednesday)."); Values[WorldCfg.WeeklyQuestResetTimeWDay] = 3; @@ -682,6 +682,13 @@ namespace Game Values[WorldCfg.RandomBgResetHour] = 6; } + Values[WorldCfg.CalendarDeleteOldEventsHour] = GetDefaultValue("Calendar.DeleteOldEventsHour", 6); + if ((int)Values[WorldCfg.CalendarDeleteOldEventsHour] > 23) + { + Log.outError(LogFilter.Misc, $"Calendar.DeleteOldEventsHour ({Values[WorldCfg.CalendarDeleteOldEventsHour]}) can't be load. Set to 6."); + Values[WorldCfg.CalendarDeleteOldEventsHour] = 6; + } + Values[WorldCfg.GuildResetHour] = GetDefaultValue("Guild.ResetHour", 6); if ((int)Values[WorldCfg.GuildResetHour] > 23) { diff --git a/Source/Game/Spells/Auras/Aura.cs b/Source/Game/Spells/Auras/Aura.cs index 7547b48e6..d21cf49cc 100644 --- a/Source/Game/Spells/Auras/Aura.cs +++ b/Source/Game/Spells/Auras/Aura.cs @@ -2285,6 +2285,10 @@ namespace Game.Spells } } + public virtual string GetDebugInfo() + { + return $"Id: {GetId()} Name: '{GetSpellInfo().SpellName[Global.WorldMgr.GetDefaultDbcLocale()]}' Caster: {GetCasterGUID()}\nOwner: {(GetOwner() != null ? GetOwner().GetDebugInfo() : "NULL")}"; + } #endregion public SpellInfo GetSpellInfo() { return m_spellInfo; } diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 1dfa88b66..945361a39 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -7350,6 +7350,11 @@ namespace Game.Spells m_caster.ToUnit().GetSpellHistory().CancelGlobalCooldown(m_spellInfo); } + string GetDebugInfo() + { + return $"Id: {GetSpellInfo().Id} Name: '{GetSpellInfo().SpellName[Global.WorldMgr.GetDefaultDbcLocale()]}' OriginalCaster: {m_originalCasterGUID} State: {GetState()}"; + } + List m_loadedScripts = new(); int CalculateDamage(SpellEffectInfo spellEffectInfo, Unit target) diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index e7e7c1259..e83396a14 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -4266,6 +4266,15 @@ namespace Game.Entities spellInfo.AttributesEx2 |= SpellAttr2.CanTargetDead; }); + // Soul Sickness (Forge of Souls) + ApplySpellFix(new[] { 69131 }, spellInfo => + { + ApplySpellEffectFix(spellInfo, 1, spellEffectInfo => + { + spellEffectInfo.ApplyAuraName = AuraType.ModDecreaseSpeed; + }); + }); + // // FIRELANDS SPELLS // diff --git a/Source/Scripts/Spells/Druid.cs b/Source/Scripts/Spells/Druid.cs index 7ed5746be..70222b4c0 100644 --- a/Source/Scripts/Spells/Druid.cs +++ b/Source/Scripts/Spells/Druid.cs @@ -238,7 +238,7 @@ namespace Scripts.Spells.Druid } } - // 48517 Eclipse (Solar) + 48518 Eclipse (Lunar) + [Script] // 48517 Eclipse (Solar) + 48518 Eclipse (Lunar) class spell_dru_eclipse_aura : AuraScript { public override bool Validate(SpellInfo spellInfo) @@ -262,7 +262,7 @@ namespace Scripts.Spells.Druid } } - // 79577 - Eclipse - SPELL_DRUID_ECLIPSE_DUMMY + [Script] // 79577 - Eclipse - SPELL_DRUID_ECLIPSE_DUMMY class spell_dru_eclipse_dummy : AuraScript { class InitializeEclipseCountersEvent : BasicEvent @@ -353,7 +353,7 @@ namespace Scripts.Spells.Druid } } - // 329910 - Eclipse out of combat - SPELL_DRUID_ECLIPSE_OOC + [Script] // 329910 - Eclipse out of combat - SPELL_DRUID_ECLIPSE_OOC class spell_dru_eclipse_ooc : AuraScript { public override bool Validate(SpellInfo spellInfo)