diff --git a/Source/Framework/Constants/CreatureConst.cs b/Source/Framework/Constants/CreatureConst.cs index afef32ac1..01e610262 100644 --- a/Source/Framework/Constants/CreatureConst.cs +++ b/Source/Framework/Constants/CreatureConst.cs @@ -287,7 +287,7 @@ namespace Framework.Constants CombatPing = 0x00020000, Aquatic = 0x00040000, // Aka Water Only, CreatureTemplateMovement.Ground = 0 Amphibious = 0x00080000, // CreatureTemplateMovement.Swim = 1 - NoMeleeFlee = 0x00100000, // Prevents Melee(Does Not Prevent Chasing, Does Not Make Creature Passive). Not Sure What 'Flee' Means But Another Flag Is Named NoMeleeApproach + NoMelee = 0x00100000, // Prevents Melee(Does Not Prevent Chasing, Does Not Make Creature Passive). Not Sure What 'Flee' Means But Another Flag Is Named NoMeleeApproach VisibleToGhosts = 0x00200000, // CreatureTypeFlagVisibleToGhosts PvpEnabling = 0x00400000, // Old UnitFlagPvpEnabling, Now UnitBytes2OffsetPvpFlag From UnitFieldBytes2 DoNotPlayWoundAnim = 0x00800000, // CreatureTypeFlagDoNotPlayWoundAnim diff --git a/Source/Game/AI/CoreAI/UnitAI.cs b/Source/Game/AI/CoreAI/UnitAI.cs index f604d3d7b..2eb61bb58 100644 --- a/Source/Game/AI/CoreAI/UnitAI.cs +++ b/Source/Game/AI/CoreAI/UnitAI.cs @@ -54,7 +54,7 @@ namespace Game.AI public void DoMeleeAttackIfReady() { - if (me.HasUnitState(UnitState.Casting)) + if (me.HasUnitState(UnitState.Casting) || (me.IsCreature() && !me.ToCreature().CanMelee())) return; Unit victim = me.GetVictim(); diff --git a/Source/Game/AI/SmartScripts/SmartAI.cs b/Source/Game/AI/SmartScripts/SmartAI.cs index 91fea6e11..1bcf949a1 100644 --- a/Source/Game/AI/SmartScripts/SmartAI.cs +++ b/Source/Game/AI/SmartScripts/SmartAI.cs @@ -44,7 +44,6 @@ namespace Game.AI bool _run; bool _evadeDisabled; - bool _canAutoAttack; bool _canCombatMove; uint _invincibilityHpLevel; @@ -62,7 +61,6 @@ namespace Game.AI { _escortInvokerCheckTimer = 1000; _run = true; - _canAutoAttack = true; _canCombatMove = true; _hasConditions = Global.ConditionMgr.HasConditionsForNotGroupedEntry(ConditionSourceType.CreatureTemplateVehicle, creature.GetEntry()); @@ -338,9 +336,8 @@ namespace Game.AI if (!hasVictim) return; - - if (_canAutoAttack) - DoMeleeAttackIfReady(); + + DoMeleeAttackIfReady(); } bool IsEscortInvokerInRange() @@ -629,11 +626,11 @@ namespace Game.AI if (!IsAIControlled()) { if (who != null) - me.Attack(who, _canAutoAttack); + me.Attack(who, true); return; } - if (who != null && me.Attack(who, _canAutoAttack)) + if (who != null && me.Attack(who, true)) { me.GetMotionMaster().Clear(MovementGeneratorPriority.Normal); me.PauseMovement(); @@ -1074,7 +1071,6 @@ namespace Game.AI public bool HasEscortState(SmartEscortState escortState) { return (_escortState & escortState) != 0; } public void AddEscortState(SmartEscortState escortState) { _escortState |= escortState; } public void RemoveEscortState(SmartEscortState escortState) { _escortState &= ~escortState; } - public void SetAutoAttack(bool on) { _canAutoAttack = on; } public bool CanCombatMove() { return _canCombatMove; } diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index f6021d1d7..836547b64 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -615,10 +615,7 @@ namespace Game.AI } case SmartActions.AutoAttack: { - if (!IsSmart()) - break; - - ((SmartAI)_me.GetAI()).SetAutoAttack(e.Action.autoAttack.attack != 0); + _me.SetCanMelee(e.Action.autoAttack.attack != 0); Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_AUTO_ATTACK: Creature: {0} bool on = {1}", _me.GetGUID().ToString(), e.Action.autoAttack.attack); break; diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index 77d495b20..017a2a86a 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -3246,6 +3246,10 @@ namespace Game.Entities public override SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = WeaponAttackType.BaseAttack) { return m_meleeDamageSchoolMask; } public void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = (SpellSchoolMask)(1 << (int)school); } + public bool CanMelee() { return !_staticFlags.HasFlag(CreatureStaticFlags.NoMelee); } + + public void SetCanMelee(bool canMelee) { _staticFlags.ApplyFlag(CreatureStaticFlags.NoMelee, !canMelee); } + public sbyte GetOriginalEquipmentId() { return m_originalEquipmentId; } public byte GetCurrentEquipmentId() { return m_equipmentId; } public void SetCurrentEquipmentId(byte id) { m_equipmentId = id; } diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index 0aa3b6ebc..c591473d5 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -258,8 +258,14 @@ namespace Game.Entities Creature creature = ToCreature(); // creatures cannot attack while evading - if (creature != null && creature.IsInEvadeMode()) - return false; + if (creature != null) + { + if (creature.IsInEvadeMode()) + return false; + + if (!creature.CanMelee()) + meleeAttack = false; + } // nobody can attack GM in GM-mode if (victim.IsTypeId(TypeId.Player)) diff --git a/Source/Game/Scripting/ScriptManager.cs b/Source/Game/Scripting/ScriptManager.cs index 01da8b2ca..e8db7e682 100644 --- a/Source/Game/Scripting/ScriptManager.cs +++ b/Source/Game/Scripting/ScriptManager.cs @@ -1295,9 +1295,9 @@ namespace Game.Scripting return ScriptMap.Empty(); } - public List GetStorage() + public ICollection GetStorage() { - return ScriptMap.Values.ToList(); + return ScriptMap.Values; } public void Unload()