test
This commit is contained in:
parent
aee3a7f22c
commit
152c74fa15
5 changed files with 122 additions and 26 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 MiB After Width: | Height: | Size: 7.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.3 MiB After Width: | Height: | Size: 5.9 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 338 KiB After Width: | Height: | Size: 332 KiB |
|
|
@ -351,12 +351,18 @@ public class BossRunExecutor : GameExecutor
|
|||
for (var phase = 1; phase <= 3; phase++)
|
||||
{
|
||||
if (_stopped) return;
|
||||
Log.Information("=== Boss phase {Phase}/4 ===", phase);
|
||||
var preWp = _nav.WorldPosition;
|
||||
Log.Information("=== Boss phase {Phase}/4 === fightArea=({FX:F0},{FY:F0}) charPos=({CX:F1},{CY:F1})",
|
||||
phase, fightWorldX, fightWorldY, preWp.X, preWp.Y);
|
||||
|
||||
var lastBossPos = await AttackBossUntilGone(fightWorldX, fightWorldY);
|
||||
if (_stopped) return;
|
||||
|
||||
// Update fight area to where the boss was last seen
|
||||
var postWp = _nav.WorldPosition;
|
||||
Log.Information("Phase {Phase} ended: charPos=({CX:F1},{CY:F1}) lastBossPos={Boss}",
|
||||
phase, postWp.X, postWp.Y,
|
||||
lastBossPos != null ? $"({lastBossPos.Value.X:F1},{lastBossPos.Value.Y:F1})" : "null");
|
||||
if (lastBossPos != null)
|
||||
{
|
||||
fightWorldX = lastBossPos.Value.X;
|
||||
|
|
@ -380,16 +386,27 @@ public class BossRunExecutor : GameExecutor
|
|||
|
||||
// 4th fight - no well after
|
||||
if (_stopped) return;
|
||||
Log.Information("=== Boss phase 4/4 ===");
|
||||
{
|
||||
var p4wp = _nav.WorldPosition;
|
||||
Log.Information("=== Boss phase 4/4 === fightArea=({FX:F0},{FY:F0}) charPos=({CX:F1},{CY:F1})",
|
||||
fightWorldX, fightWorldY, p4wp.X, p4wp.Y);
|
||||
}
|
||||
var finalBossPos = await AttackBossUntilGone(fightWorldX, fightWorldY);
|
||||
if (_stopped) return;
|
||||
|
||||
// Update fight area from phase 4 if we got detections
|
||||
{
|
||||
var p4postWp = _nav.WorldPosition;
|
||||
Log.Information("Phase 4 ended: charPos=({CX:F1},{CY:F1}) finalBossPos={Boss}",
|
||||
p4postWp.X, p4postWp.Y,
|
||||
finalBossPos != null ? $"({finalBossPos.Value.X:F1},{finalBossPos.Value.Y:F1})" : "null");
|
||||
}
|
||||
if (finalBossPos != null)
|
||||
{
|
||||
fightWorldX = finalBossPos.Value.X;
|
||||
fightWorldY = finalBossPos.Value.Y;
|
||||
}
|
||||
Log.Information("Ring phase: using fightArea=({FX:F0},{FY:F0})", fightWorldX, fightWorldY);
|
||||
|
||||
// Walk to known ring position and look for the template
|
||||
await WalkToWorldPosition(-440, -330);
|
||||
|
|
@ -606,6 +623,19 @@ public class BossRunExecutor : GameExecutor
|
|||
const int screenCy = 720;
|
||||
const double screenToWorld = 97.0 / 835.0;
|
||||
(double X, double Y)? lastBossWorldPos = null;
|
||||
var yoloLogCount = 0;
|
||||
|
||||
// Subscribe to YOLO events for real-time chase updates
|
||||
// (main loop is too slow due to template matching to effectively track boss)
|
||||
void OnBossDetected(BossSnapshot snapshot)
|
||||
{
|
||||
if (snapshot.Bosses.Count == 0) return;
|
||||
var boss = snapshot.Bosses[0];
|
||||
_combatTargetX = boss.Cx;
|
||||
_combatTargetY = boss.Cy;
|
||||
_combat.SetChaseTarget(boss.Cx, boss.Cy);
|
||||
}
|
||||
_bossDetector.BossDetected += OnBossDetected;
|
||||
|
||||
Log.Information("Boss is alive, engaging");
|
||||
var (combatTask, cts) = StartCombatLoop(screenCx, screenCy);
|
||||
|
|
@ -620,39 +650,22 @@ public class BossRunExecutor : GameExecutor
|
|||
{
|
||||
if (_stopped) return lastBossWorldPos;
|
||||
|
||||
// Update attack target from YOLO (fast, no capture)
|
||||
// Update lastBossWorldPos from latest YOLO (for phase tracking)
|
||||
var snapshot = _bossDetector.Latest;
|
||||
if (snapshot.Bosses.Count > 0)
|
||||
{
|
||||
var boss = snapshot.Bosses[0];
|
||||
_combatTargetX = boss.Cx;
|
||||
_combatTargetY = boss.Cy;
|
||||
|
||||
var wp = _nav.WorldPosition;
|
||||
lastBossWorldPos = (
|
||||
wp.X + (boss.Cx - screenCx) * screenToWorld,
|
||||
wp.Y + (boss.Cy - screenCy) * screenToWorld);
|
||||
|
||||
// Walk toward boss to stay as close as possible
|
||||
var bossDx = boss.Cx - screenCx;
|
||||
var bossDy = boss.Cy - screenCy;
|
||||
var bossDist = Math.Sqrt(bossDx * bossDx + bossDy * bossDy);
|
||||
|
||||
if (bossDist > 50)
|
||||
{
|
||||
var dirX = bossDx / bossDist;
|
||||
var dirY = bossDy / bossDist;
|
||||
|
||||
var keys = new List<int>();
|
||||
if (dirY < -0.3) keys.Add(InputSender.VK.W);
|
||||
if (dirY > 0.3) keys.Add(InputSender.VK.S);
|
||||
if (dirX < -0.3) keys.Add(InputSender.VK.A);
|
||||
if (dirX > 0.3) keys.Add(InputSender.VK.D);
|
||||
|
||||
foreach (var k in keys) await _game.KeyDown(k);
|
||||
await Helpers.Sleep(150);
|
||||
foreach (var k in keys) await _game.KeyUp(k);
|
||||
}
|
||||
yoloLogCount++;
|
||||
if (yoloLogCount % 5 == 1) // log every 5th detection
|
||||
Log.Information("YOLO boss: screen=({Sx},{Sy}) charWorld=({Cx:F1},{Cy:F1}) bossWorld=({Bx:F1},{By:F1}) conf={Conf:F2}",
|
||||
boss.Cx, boss.Cy, wp.X, wp.Y,
|
||||
lastBossWorldPos.Value.X, lastBossWorldPos.Value.Y, boss.Confidence);
|
||||
}
|
||||
|
||||
// Check death + healthbar (combat keeps running in background)
|
||||
|
|
@ -686,6 +699,8 @@ public class BossRunExecutor : GameExecutor
|
|||
}
|
||||
finally
|
||||
{
|
||||
_bossDetector.BossDetected -= OnBossDetected;
|
||||
_combat.ClearChaseTarget();
|
||||
await StopCombatLoop(combatTask, cts);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ public class CombatManager
|
|||
private long _lastOrbitMs;
|
||||
private int _nextOrbitMs = OrbitStepMinMs;
|
||||
|
||||
// Chase — walks toward a screen position instead of orbiting
|
||||
private volatile int _chaseX = -1;
|
||||
private volatile int _chaseY = -1;
|
||||
private readonly HashSet<int> _chaseKeys = new();
|
||||
|
||||
// Smoothed mouse position — lerps toward target to avoid jitter
|
||||
private double _smoothX = 1280;
|
||||
private double _smoothY = 720;
|
||||
|
|
@ -39,6 +44,18 @@ public class CombatManager
|
|||
|
||||
public bool IsHolding => _holding;
|
||||
|
||||
public void SetChaseTarget(int screenX, int screenY)
|
||||
{
|
||||
_chaseX = screenX;
|
||||
_chaseY = screenY;
|
||||
}
|
||||
|
||||
public void ClearChaseTarget()
|
||||
{
|
||||
_chaseX = -1;
|
||||
_chaseY = -1;
|
||||
}
|
||||
|
||||
public CombatManager(IGameController game, HudReader hudReader, FlaskManager flasks)
|
||||
{
|
||||
_game = game;
|
||||
|
|
@ -52,7 +69,16 @@ public class CombatManager
|
|||
public async Task Tick(int x, int y, int jitter = 30)
|
||||
{
|
||||
await _flasks.Tick();
|
||||
|
||||
if (_chaseX >= 0)
|
||||
{
|
||||
await UpdateChase();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_chaseKeys.Count > 0) await ReleaseChaseKeys();
|
||||
await UpdateOrbit();
|
||||
}
|
||||
|
||||
// Lerp smoothed position toward target
|
||||
_smoothX += (x - _smoothX) * SmoothFactor;
|
||||
|
|
@ -106,6 +132,55 @@ public class CombatManager
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Walk toward chase target using held WASD keys. Replaces orbit when active.
|
||||
/// </summary>
|
||||
private async Task UpdateChase()
|
||||
{
|
||||
// Release orbit key when entering chase mode
|
||||
if (_orbitIndex >= 0)
|
||||
{
|
||||
await _game.KeyUp(OrbitKeys[_orbitIndex]);
|
||||
_orbitIndex = -1;
|
||||
}
|
||||
|
||||
const int screenCx = 1280, screenCy = 720;
|
||||
var cx = _chaseX;
|
||||
var cy = _chaseY;
|
||||
var dx = cx - screenCx;
|
||||
var dy = cy - screenCy;
|
||||
var dist = Math.Sqrt(dx * dx + dy * dy);
|
||||
|
||||
var wanted = new HashSet<int>();
|
||||
if (dist > 100)
|
||||
{
|
||||
var dirX = dx / dist;
|
||||
var dirY = dy / dist;
|
||||
if (dirY < -0.3) wanted.Add(InputSender.VK.W);
|
||||
if (dirY > 0.3) wanted.Add(InputSender.VK.S);
|
||||
if (dirX < -0.3) wanted.Add(InputSender.VK.A);
|
||||
if (dirX > 0.3) wanted.Add(InputSender.VK.D);
|
||||
}
|
||||
|
||||
foreach (var k in _chaseKeys.Except(wanted).ToList())
|
||||
{
|
||||
await _game.KeyUp(k);
|
||||
_chaseKeys.Remove(k);
|
||||
}
|
||||
foreach (var k in wanted.Except(_chaseKeys).ToList())
|
||||
{
|
||||
await _game.KeyDown(k);
|
||||
_chaseKeys.Add(k);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReleaseChaseKeys()
|
||||
{
|
||||
foreach (var k in _chaseKeys)
|
||||
await _game.KeyUp(k);
|
||||
_chaseKeys.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cycle WASD directions to orbit in a small circle while attacking.
|
||||
/// </summary>
|
||||
|
|
@ -150,6 +225,9 @@ public class CombatManager
|
|||
_smoothX = 1280;
|
||||
_smoothY = 720;
|
||||
await ReleaseOrbit();
|
||||
await ReleaseChaseKeys();
|
||||
_chaseX = -1;
|
||||
_chaseY = -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -164,5 +242,8 @@ public class CombatManager
|
|||
_holding = false;
|
||||
}
|
||||
await ReleaseOrbit();
|
||||
await ReleaseChaseKeys();
|
||||
_chaseX = -1;
|
||||
_chaseY = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue