diff --git a/Core/Goals/CombatGoal.cs b/Core/Goals/CombatGoal.cs index 5d37fd34..b0aa9d56 100644 --- a/Core/Goals/CombatGoal.cs +++ b/Core/Goals/CombatGoal.cs @@ -1,34 +1,46 @@ using Core.GOAP; using Microsoft.Extensions.Logging; - +using SharpDX.WIC; using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; using System.Numerics; +using System.Threading; +using System.Drawing; +using static System.MathF; +using SixLabors.ImageSharp.Formats; namespace Core.Goals; public sealed class CombatGoal : GoapGoal, IGoapEventListener { public override float Cost => 4f; + public DateTime LastSafeLocationTime = new DateTime(); + LinkedList safeLocations = new LinkedList(); + private bool runningAway; private readonly ILogger logger; private readonly ConfigurableInput input; private readonly ClassConfiguration classConfig; private readonly Wait wait; + private readonly Navigation playerNavigation; private readonly PlayerReader playerReader; private readonly AddonBits bits; private readonly StopMoving stopMoving; private readonly CastingHandler castingHandler; private readonly IMountHandler mountHandler; private readonly CombatLog combatLog; - + private const float minAngleToTurn = PI / 35f; // 5.14 degree + private const float minAngleToStopBeforeTurn = PI / 2f; // 90 degree private float lastDirection; private float lastMinDistance; private float lastMaxDistance; public CombatGoal(ILogger logger, ConfigurableInput input, Wait wait, PlayerReader playerReader, StopMoving stopMoving, AddonBits bits, - ClassConfiguration classConfiguration, ClassConfiguration classConfig, + Navigation playerNavigation, ClassConfiguration classConfiguration, ClassConfiguration classConfig, CastingHandler castingHandler, CombatLog combatLog, IMountHandler mountHandler) : base(nameof(CombatGoal)) @@ -40,7 +52,7 @@ public CombatGoal(ILogger logger, ConfigurableInput input, this.playerReader = playerReader; this.bits = bits; this.combatLog = combatLog; - + this.playerNavigation = playerNavigation; this.stopMoving = stopMoving; this.castingHandler = castingHandler; this.mountHandler = mountHandler; @@ -48,7 +60,7 @@ public CombatGoal(ILogger logger, ConfigurableInput input, AddPrecondition(GoapKey.incombat, true); AddPrecondition(GoapKey.hastarget, true); - AddPrecondition(GoapKey.targetisalive, true); + //AddPrecondition(GoapKey.targetisalive, true); AddPrecondition(GoapKey.targethostile, true); //AddPrecondition(GoapKey.targettargetsus, true); AddPrecondition(GoapKey.incombatrange, true); @@ -106,12 +118,7 @@ public override void OnExit() public override void Update() { wait.Update(); - - if (MathF.Abs(lastDirection - playerReader.Direction) > MathF.PI / 2) - { - logger.LogInformation("Turning too fast!"); - stopMoving.Stop(); - } + playerNavigation.Update(); lastDirection = playerReader.Direction; lastMinDistance = playerReader.MinRange(); @@ -123,6 +130,55 @@ public override void Update() return; } + if ((MathF.Abs(lastDirection - playerReader.Direction) > MathF.PI / 2)) + { + logger.LogInformation("Turning too fast!"); + stopMoving.Stop(); + + } + if (bits.Target() && !bits.Target_Alive()) + { + input.PressClearTarget(); + return; + } + + if (combatLog.DamageTaken.Count > 1 || (playerReader.HealthPercent() < 50 && playerReader.ManaPercent() < 20) || (playerReader.HealthPercent() < 30)) + { + // multiple mobs hitting us + // bail + Console.WriteLine("Multiple mob hits! OR HP and mana low"); + Console.WriteLine(safeLocations.Count); + if (safeLocations.Count >= 1) + { + bool foundPoint = false; + Console.WriteLine("Current Pos: " + playerReader.MapPos.ToString()); + Console.WriteLine("Safe Spots: " + safeLocations.Count); + for (LinkedListNode point = safeLocations.Last; point != null; point = point.Previous) + { + Vector2 p1 = new Vector2(point.Value.X, point.Value.Y); + Vector2 p2 = new Vector2(playerReader.MapPos.X, playerReader.MapPos.Y); + if (Vector2.Distance(p1, p2) >= 1.8) + { + // select the point far enough to lose the current mobs. + input.PressClearTarget(); + playerNavigation.Stop(); + playerNavigation.StuckResetTimeout = 500; + playerNavigation.ResetStuckParameters(); + playerNavigation.SetWayPoints(stackalloc Vector3[] { (Vector3)(point.Value) }); + playerNavigation.Update(); + Console.WriteLine("Found point " + point.Value.ToString()); + foundPoint = true; + break; + } + } + if (foundPoint) + { + Console.WriteLine("Running away to the last safe point!"); + return; + } + } + } + if (bits.Target()) { if (classConfig.AutoPetAttack && @@ -161,12 +217,36 @@ public override void Update() { stopMoving.Stop(); FindNewTarget(); + } else + { + if (LastSafeLocationTime == DateTime.MinValue) + { + LastSafeLocationTime = DateTime.UtcNow; + safeLocations.AddLast(playerReader.MapPos); + } + else + { + if ((DateTime.UtcNow - LastSafeLocationTime).TotalMilliseconds > 7_000 && !bits.Combat()) + { + safeLocations.AddLast(playerReader.MapPos); + LastSafeLocationTime = DateTime.UtcNow; + if (safeLocations.Count > 100) + { + safeLocations.RemoveFirst(); + } + } + } + Console.WriteLine("Target Dead2 -- saving safe pos " + playerReader.MapPos.ToString()); + safeLocations.AddLast(playerReader.MapPos); + logger.LogWarning("---- Target dead, clearing"); + input.PressClearTarget(); } } } private void FindNewTarget() { + playerNavigation.Stop(); if (playerReader.PetTarget() && combatLog.DeadGuid.Value != playerReader.PetTargetGuid) { ResetCooldowns(); @@ -177,7 +257,7 @@ private void FindNewTarget() if (!bits.Target_Dead()) { - logger.LogWarning("---- New targe from Pet target!"); + logger.LogWarning("---- New target from Pet target!"); return; } @@ -216,4 +296,4 @@ private Vector3 GetCorpseLocation(float distance) { return PointEstimator.GetPoint(playerReader.MapPos, playerReader.Direction, distance); } -} \ No newline at end of file +}