sami test
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal" Spacing="8">
|
||||
<Button x:Name="StartButton" Content="Start Bot" Width="120"/>
|
||||
<Button x:Name="StopButton" Content="Stop Bot" Width="120" IsEnabled="False"/>
|
||||
<CheckBox x:Name="MultiplayerCheckBox" Content="Multiplayer" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="API Key:" VerticalAlignment="Center"/>
|
||||
<TextBox x:Name="ApiKeyBox" Width="360" Watermark="GUID player token"/>
|
||||
<TextBlock x:Name="StatusText" VerticalAlignment="Center" Text="Idle"/>
|
||||
|
||||
@@ -32,6 +32,7 @@ public partial class MainWindow : Window
|
||||
};
|
||||
|
||||
private readonly string _configuredApiKey = Program.Configuration["APIKEY"] ?? string.Empty;
|
||||
private readonly bool _multiplayerModeDefault = bool.TryParse(Program.Configuration["MULTIPLAYER"], out var multiplayer) && multiplayer;
|
||||
private readonly HttpClient _httpClient = new() { Timeout = TimeSpan.FromSeconds(8) };
|
||||
private readonly DigitalDojoApiClient _client;
|
||||
private readonly ObservableCollection<string> _logEntries = [];
|
||||
@@ -85,6 +86,7 @@ public partial class MainWindow : Window
|
||||
BuildKnowledgeGrid();
|
||||
|
||||
ApiKeyBox.Text = _configuredApiKey;
|
||||
MultiplayerCheckBox.IsChecked = _multiplayerModeDefault;
|
||||
LogList.ItemsSource = _logEntries;
|
||||
|
||||
StartButton.Click += async (_, _) => await StartBotAsync();
|
||||
@@ -122,6 +124,7 @@ public partial class MainWindow : Window
|
||||
StartButton.IsEnabled = false;
|
||||
StopButton.IsEnabled = true;
|
||||
ApiKeyBox.IsEnabled = false;
|
||||
MultiplayerCheckBox.IsEnabled = false;
|
||||
|
||||
ResetKnowledgeState();
|
||||
|
||||
@@ -185,6 +188,7 @@ public partial class MainWindow : Window
|
||||
StartButton.IsEnabled = true;
|
||||
StopButton.IsEnabled = false;
|
||||
ApiKeyBox.IsEnabled = true;
|
||||
MultiplayerCheckBox.IsEnabled = true;
|
||||
SetStatus("Stopped.");
|
||||
}
|
||||
|
||||
@@ -211,6 +215,13 @@ public partial class MainWindow : Window
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsMultiplayerMode)
|
||||
{
|
||||
// In multiplayer, the lobby controls game creation/start.
|
||||
AppendLog("Multiplayer mode enabled; waiting for lobby game start (no create call).");
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var created = await _client.CreateAsync(_playerToken, ct);
|
||||
@@ -501,6 +512,12 @@ public partial class MainWindow : Window
|
||||
// Teleport closer to enemy for aggressive positioning
|
||||
var moveTowardX = targetX > 0 ? targetX - 1 : targetX + 1;
|
||||
var moveTowardY = targetY > 0 ? targetY - 1 : targetY + 1;
|
||||
var teleportDirection = DirectionFromVector(moveTowardX, moveTowardY);
|
||||
if (IsDirectionUnsafeForHighSpeedMove(teleportDirection))
|
||||
{
|
||||
moveTowardX = targetX;
|
||||
moveTowardY = targetY;
|
||||
}
|
||||
|
||||
return new BotDecision(
|
||||
"teleport-aggro",
|
||||
@@ -509,16 +526,26 @@ public partial class MainWindow : Window
|
||||
{
|
||||
var response = await _client.TeleportAsync(_playerToken, moveTowardX, moveTowardY, ct);
|
||||
MarkUsed(BotAction.Teleport);
|
||||
if (response.Executed)
|
||||
if (response.Executed && !response.LandedInWall)
|
||||
{
|
||||
_x = moveTowardX;
|
||||
_y = moveTowardY;
|
||||
}
|
||||
|
||||
if (response.LandedInWall)
|
||||
{
|
||||
var dir = DirectionFromVector(moveTowardX, moveTowardY);
|
||||
_blockedDirectionTicks.TryGetValue(dir, out var blocked);
|
||||
_blockedDirectionTicks[dir] = Math.Max(blocked, 14);
|
||||
_survivalTicks = Math.Max(_survivalTicks, 10);
|
||||
_sessionLogger?.LogEvent("teleport-wall", $"x={moveTowardX};y={moveTowardY}");
|
||||
}
|
||||
|
||||
return response.Executed;
|
||||
});
|
||||
}
|
||||
|
||||
if (Ready(BotAction.Dash) && TryGetAggressiveDashDirection(predictedEnemy, bestSight, out var dashDirection, out var dashReason))
|
||||
if (Ready(BotAction.Dash) && TryGetAggressiveDashDirection(predictedEnemy, bestSight.Key, bestSight.Value, out var dashDirection, out var dashReason))
|
||||
{
|
||||
return new BotDecision(
|
||||
"dash-aggro",
|
||||
@@ -529,7 +556,19 @@ public partial class MainWindow : Window
|
||||
MarkUsed(BotAction.Dash);
|
||||
if (response.Executed)
|
||||
{
|
||||
ApplyMovement(dashDirection, Math.Max(response.BlocksDashed, 1));
|
||||
var movedBlocks = Math.Max(response.BlocksDashed, 0);
|
||||
if (movedBlocks > 0)
|
||||
{
|
||||
ApplyMovement(dashDirection, movedBlocks);
|
||||
}
|
||||
|
||||
if (response.DamageTaken > 0)
|
||||
{
|
||||
_blockedDirectionTicks.TryGetValue(dashDirection, out var blocked);
|
||||
_blockedDirectionTicks[dashDirection] = Math.Max(blocked, 12);
|
||||
_survivalTicks = Math.Max(_survivalTicks, 8);
|
||||
_sessionLogger?.LogEvent("dash-self-damage", $"dir={dashDirection};damage={response.DamageTaken};blocks={response.BlocksDashed}");
|
||||
}
|
||||
}
|
||||
|
||||
return response.Executed;
|
||||
@@ -581,7 +620,20 @@ public partial class MainWindow : Window
|
||||
MarkUsed(BotAction.Dash);
|
||||
if (response.Executed)
|
||||
{
|
||||
ApplyMovement(retreatDirection, Math.Max(response.BlocksDashed, 1));
|
||||
var movedBlocks = Math.Max(response.BlocksDashed, 0);
|
||||
if (movedBlocks > 0)
|
||||
{
|
||||
ApplyMovement(retreatDirection, movedBlocks);
|
||||
}
|
||||
|
||||
if (response.DamageTaken > 0)
|
||||
{
|
||||
_blockedDirectionTicks.TryGetValue(retreatDirection, out var blocked);
|
||||
_blockedDirectionTicks[retreatDirection] = Math.Max(blocked, 12);
|
||||
_survivalTicks = Math.Max(_survivalTicks, 10);
|
||||
_sessionLogger?.LogEvent("dash-self-damage", $"dir={retreatDirection};damage={response.DamageTaken};blocks={response.BlocksDashed}");
|
||||
}
|
||||
|
||||
_escapeDirection = retreatDirection;
|
||||
_escapeLockTicks = Math.Max(_escapeLockTicks, EscapeLockTicks(profile));
|
||||
}
|
||||
@@ -1025,7 +1077,8 @@ public partial class MainWindow : Window
|
||||
|
||||
private bool TryGetAggressiveDashDirection(
|
||||
(int X, int Y)? predictedEnemy,
|
||||
KeyValuePair<Direction, PeekEntitiesAsyncResponse>? bestSight,
|
||||
Direction? sightDirection,
|
||||
PeekEntitiesAsyncResponse? sightResponse,
|
||||
out Direction direction,
|
||||
out string reason)
|
||||
{
|
||||
@@ -1033,20 +1086,24 @@ public partial class MainWindow : Window
|
||||
{
|
||||
var target = predictedEnemy ?? _nearestEnemy.Value;
|
||||
var dist = Math.Abs(target.X) + Math.Abs(target.Y);
|
||||
if (dist >= 2 && dist <= 6)
|
||||
if (dist >= 2 && dist <= 4)
|
||||
{
|
||||
direction = DirectionFromVector(target.X, target.Y);
|
||||
reason = $"Aggressive gap-close toward enemy at {direction} (predicted distance {dist}).";
|
||||
return true;
|
||||
var candidate = DirectionFromVector(target.X, target.Y);
|
||||
if (!IsDirectionUnsafeForHighSpeedMove(candidate))
|
||||
{
|
||||
direction = candidate;
|
||||
reason = $"Aggressive gap-close toward enemy at {direction} (predicted distance {dist}).";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestSight.HasValue && bestSight.Value.Value.Executed && bestSight.Value.Value.PlayersInSight > 0)
|
||||
if (sightDirection.HasValue && sightResponse is not null && sightResponse.Executed && sightResponse.PlayersInSight > 0)
|
||||
{
|
||||
var dist = bestSight.Value.Value.SightedPlayerDistance ?? 99;
|
||||
if (dist >= 2 && dist <= 5)
|
||||
var dist = sightResponse.SightedPlayerDistance ?? 99;
|
||||
if (dist >= 2 && dist <= 4 && !IsDirectionUnsafeForHighSpeedMove(sightDirection.Value))
|
||||
{
|
||||
direction = bestSight.Value.Key;
|
||||
direction = sightDirection.Value;
|
||||
reason = $"Enemy visible at {direction} ({dist} dist); dash to force close-range combat.";
|
||||
return true;
|
||||
}
|
||||
@@ -1057,6 +1114,16 @@ public partial class MainWindow : Window
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsDirectionUnsafeForHighSpeedMove(Direction direction)
|
||||
{
|
||||
if (_blockedDirectionTicks.TryGetValue(direction, out var blocked) && blocked > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return DeathHeatFor(direction) >= 4.0;
|
||||
}
|
||||
|
||||
private void MarkVisit(int x, int y, double amount)
|
||||
{
|
||||
var key = (x, y);
|
||||
@@ -1209,6 +1276,8 @@ public partial class MainWindow : Window
|
||||
Dispatcher.UIThread.Post(() => StatusText.Text = text);
|
||||
}
|
||||
|
||||
private bool IsMultiplayerMode => MultiplayerCheckBox.IsChecked == true;
|
||||
|
||||
private void AppendLog(string message)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
|
||||
Reference in New Issue
Block a user