improved
This commit is contained in:
@@ -11,6 +11,19 @@
|
|||||||
<Button x:Name="StartButton" Content="Start Bot" Width="120"/>
|
<Button x:Name="StartButton" Content="Start Bot" Width="120"/>
|
||||||
<Button x:Name="StopButton" Content="Stop Bot" Width="120" IsEnabled="False"/>
|
<Button x:Name="StopButton" Content="Stop Bot" Width="120" IsEnabled="False"/>
|
||||||
<CheckBox x:Name="MultiplayerCheckBox" Content="Multiplayer" VerticalAlignment="Center"/>
|
<CheckBox x:Name="MultiplayerCheckBox" Content="Multiplayer" VerticalAlignment="Center"/>
|
||||||
|
<TextBlock Text="Aggro:" VerticalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="AggressivenessProfileBox" Width="150" SelectedIndex="2">
|
||||||
|
<ComboBoxItem Content="Conservative"/>
|
||||||
|
<ComboBoxItem Content="Balanced"/>
|
||||||
|
<ComboBoxItem Content="Aggressive"/>
|
||||||
|
<ComboBoxItem Content="Extreme"/>
|
||||||
|
</ComboBox>
|
||||||
|
<TextBlock Text="Mode Profile:" VerticalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="ModeOptimizationProfileBox" Width="200" SelectedIndex="0">
|
||||||
|
<ComboBoxItem Content="Auto"/>
|
||||||
|
<ComboBoxItem Content="Singleplayer Optimized"/>
|
||||||
|
<ComboBoxItem Content="Multiplayer Optimized"/>
|
||||||
|
</ComboBox>
|
||||||
<TextBlock Text="API Key:" VerticalAlignment="Center"/>
|
<TextBlock Text="API Key:" VerticalAlignment="Center"/>
|
||||||
<TextBox x:Name="ApiKeyBox" Width="360" Watermark="GUID player token"/>
|
<TextBox x:Name="ApiKeyBox" Width="360" Watermark="GUID player token"/>
|
||||||
<TextBlock x:Name="StatusText" VerticalAlignment="Center" Text="Idle"/>
|
<TextBlock x:Name="StatusText" VerticalAlignment="Center" Text="Idle"/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Layout;
|
using Avalonia.Layout;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
|
||||||
namespace DDApplication;
|
namespace DDApplication;
|
||||||
@@ -77,6 +78,9 @@ public partial class MainWindow : Window
|
|||||||
private bool _lastUnderPressure;
|
private bool _lastUnderPressure;
|
||||||
private int _pressureStreak;
|
private int _pressureStreak;
|
||||||
private LevelProfile _currentLevelProfile = LevelProfile.Unknown;
|
private LevelProfile _currentLevelProfile = LevelProfile.Unknown;
|
||||||
|
private bool _isMultiplayerMode;
|
||||||
|
private AggressivenessProfile _selectedAggressiveness = AggressivenessProfile.Aggressive;
|
||||||
|
private ModeOptimizationProfile _selectedModeOptimization = ModeOptimizationProfile.Auto;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
@@ -87,6 +91,20 @@ public partial class MainWindow : Window
|
|||||||
|
|
||||||
ApiKeyBox.Text = _configuredApiKey;
|
ApiKeyBox.Text = _configuredApiKey;
|
||||||
MultiplayerCheckBox.IsChecked = _multiplayerModeDefault;
|
MultiplayerCheckBox.IsChecked = _multiplayerModeDefault;
|
||||||
|
AggressivenessProfileBox.SelectedIndex = 2;
|
||||||
|
ModeOptimizationProfileBox.SelectedIndex = 0;
|
||||||
|
SyncProfileSelectionState();
|
||||||
|
|
||||||
|
MultiplayerCheckBox.PropertyChanged += (_, e) =>
|
||||||
|
{
|
||||||
|
if (e.Property == ToggleButton.IsCheckedProperty)
|
||||||
|
{
|
||||||
|
SyncProfileSelectionState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AggressivenessProfileBox.SelectionChanged += (_, _) => SyncProfileSelectionState();
|
||||||
|
ModeOptimizationProfileBox.SelectionChanged += (_, _) => SyncProfileSelectionState();
|
||||||
|
|
||||||
LogList.ItemsSource = _logEntries;
|
LogList.ItemsSource = _logEntries;
|
||||||
|
|
||||||
StartButton.Click += async (_, _) => await StartBotAsync();
|
StartButton.Click += async (_, _) => await StartBotAsync();
|
||||||
@@ -125,6 +143,8 @@ public partial class MainWindow : Window
|
|||||||
StopButton.IsEnabled = true;
|
StopButton.IsEnabled = true;
|
||||||
ApiKeyBox.IsEnabled = false;
|
ApiKeyBox.IsEnabled = false;
|
||||||
MultiplayerCheckBox.IsEnabled = false;
|
MultiplayerCheckBox.IsEnabled = false;
|
||||||
|
AggressivenessProfileBox.IsEnabled = false;
|
||||||
|
ModeOptimizationProfileBox.IsEnabled = false;
|
||||||
|
|
||||||
ResetKnowledgeState();
|
ResetKnowledgeState();
|
||||||
|
|
||||||
@@ -189,6 +209,8 @@ public partial class MainWindow : Window
|
|||||||
StopButton.IsEnabled = false;
|
StopButton.IsEnabled = false;
|
||||||
ApiKeyBox.IsEnabled = true;
|
ApiKeyBox.IsEnabled = true;
|
||||||
MultiplayerCheckBox.IsEnabled = true;
|
MultiplayerCheckBox.IsEnabled = true;
|
||||||
|
AggressivenessProfileBox.IsEnabled = true;
|
||||||
|
ModeOptimizationProfileBox.IsEnabled = true;
|
||||||
SetStatus("Stopped.");
|
SetStatus("Stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +503,7 @@ public partial class MainWindow : Window
|
|||||||
_pressureStreak = Math.Max(_pressureStreak - 1, 0);
|
_pressureStreak = Math.Max(_pressureStreak - 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var underPressure = hpRatio < PressureHpThreshold(profile) || _recentDamageTicks > 0 || closeThreats >= PressureThreatThreshold(profile) || _survivalTicks > 0 || _pressureStreak >= 2;
|
var underPressure = hpRatio < PressureHpThresholdAdjusted(profile) || _recentDamageTicks > 0 || closeThreats >= PressureThreatThresholdAdjusted(profile) || _survivalTicks > 0 || _pressureStreak >= 2;
|
||||||
_lastUnderPressure = underPressure;
|
_lastUnderPressure = underPressure;
|
||||||
var predictedEnemy = PredictEnemyRelative();
|
var predictedEnemy = PredictEnemyRelative();
|
||||||
|
|
||||||
@@ -575,8 +597,8 @@ public partial class MainWindow : Window
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var specialThreatThreshold = SpecialThreatThreshold(profile);
|
var specialThreatThreshold = SpecialThreatThresholdAdjusted(profile);
|
||||||
var specialHpFloor = SpecialHpFloor(profile);
|
var specialHpFloor = SpecialHpFloorAdjusted(profile);
|
||||||
|
|
||||||
if (Ready(BotAction.Special) && closeThreats >= specialThreatThreshold && (hpRatio >= specialHpFloor || closeThreats > specialThreatThreshold))
|
if (Ready(BotAction.Special) && closeThreats >= specialThreatThreshold && (hpRatio >= specialHpFloor || closeThreats > specialThreatThreshold))
|
||||||
{
|
{
|
||||||
@@ -609,7 +631,7 @@ public partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
var retreatDirection = Opposite(immediateDir.Value);
|
var retreatDirection = Opposite(immediateDir.Value);
|
||||||
|
|
||||||
if (Ready(BotAction.Dash) && (hpRatio < DashHpThreshold(profile) || _pressureStreak >= 3 || _survivalTicks > 0))
|
if (Ready(BotAction.Dash) && (hpRatio < DashHpThresholdAdjusted(profile) || _pressureStreak >= 3 || _survivalTicks > 0))
|
||||||
{
|
{
|
||||||
return new BotDecision(
|
return new BotDecision(
|
||||||
"dash-retreat",
|
"dash-retreat",
|
||||||
@@ -1001,23 +1023,143 @@ public partial class MainWindow : Window
|
|||||||
_ => 2,
|
_ => 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
private bool ShouldUseImmediateHit(LevelProfile profile, double hpRatio, int closeThreats, bool underPressure) => profile switch
|
private bool ShouldUseImmediateHit(LevelProfile profile, double hpRatio, int closeThreats, bool underPressure)
|
||||||
{
|
{
|
||||||
LevelProfile.Default => hpRatio >= 0.05,
|
var hpFloor = SelectedAggressiveness switch
|
||||||
LevelProfile.BiggerMap => hpRatio >= 0.05,
|
{
|
||||||
LevelProfile.MoreBots => hpRatio >= 0.05,
|
AggressivenessProfile.Conservative => 0.30,
|
||||||
LevelProfile.NewBots => hpRatio >= 0.05,
|
AggressivenessProfile.Balanced => 0.16,
|
||||||
_ => hpRatio >= 0.05,
|
AggressivenessProfile.Aggressive => 0.05,
|
||||||
};
|
AggressivenessProfile.Extreme => 0.01,
|
||||||
|
_ => 0.05,
|
||||||
|
};
|
||||||
|
|
||||||
private bool ShouldRetreatOnImmediate(LevelProfile profile, double hpRatio, int closeThreats) => profile switch
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
hpFloor = Math.Max(hpFloor, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hpRatio >= hpFloor || (!underPressure && closeThreats <= 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldRetreatOnImmediate(LevelProfile profile, double hpRatio, int closeThreats)
|
||||||
{
|
{
|
||||||
LevelProfile.Default => hpRatio < 0.02,
|
var hpRetreat = SelectedAggressiveness switch
|
||||||
LevelProfile.BiggerMap => hpRatio < 0.02,
|
{
|
||||||
LevelProfile.MoreBots => hpRatio < 0.02,
|
AggressivenessProfile.Conservative => 0.30,
|
||||||
LevelProfile.NewBots => hpRatio < 0.02,
|
AggressivenessProfile.Balanced => 0.18,
|
||||||
_ => hpRatio < 0.02,
|
AggressivenessProfile.Aggressive => 0.02,
|
||||||
};
|
AggressivenessProfile.Extreme => 0.01,
|
||||||
|
_ => 0.02,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
hpRetreat = Math.Max(hpRetreat, 0.20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hpRatio < hpRetreat || (IsMultiplayerOptimized && closeThreats >= 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double PressureHpThresholdAdjusted(LevelProfile profile)
|
||||||
|
{
|
||||||
|
var value = PressureHpThreshold(profile);
|
||||||
|
value += SelectedAggressiveness switch
|
||||||
|
{
|
||||||
|
AggressivenessProfile.Conservative => 0.20,
|
||||||
|
AggressivenessProfile.Balanced => 0.08,
|
||||||
|
AggressivenessProfile.Aggressive => 0.00,
|
||||||
|
AggressivenessProfile.Extreme => -0.05,
|
||||||
|
_ => 0.00,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
value += 0.08;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Clamp(value, 0.01, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int PressureThreatThresholdAdjusted(LevelProfile profile)
|
||||||
|
{
|
||||||
|
var value = PressureThreatThreshold(profile);
|
||||||
|
value += SelectedAggressiveness switch
|
||||||
|
{
|
||||||
|
AggressivenessProfile.Conservative => -2,
|
||||||
|
AggressivenessProfile.Balanced => -1,
|
||||||
|
AggressivenessProfile.Aggressive => 0,
|
||||||
|
AggressivenessProfile.Extreme => 1,
|
||||||
|
_ => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
value -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Clamp(value, 1, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int SpecialThreatThresholdAdjusted(LevelProfile profile)
|
||||||
|
{
|
||||||
|
var value = SpecialThreatThreshold(profile);
|
||||||
|
value += SelectedAggressiveness switch
|
||||||
|
{
|
||||||
|
AggressivenessProfile.Conservative => 1,
|
||||||
|
AggressivenessProfile.Balanced => 0,
|
||||||
|
AggressivenessProfile.Aggressive => 0,
|
||||||
|
AggressivenessProfile.Extreme => -1,
|
||||||
|
_ => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
value += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Clamp(value, 1, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double SpecialHpFloorAdjusted(LevelProfile profile)
|
||||||
|
{
|
||||||
|
var value = SpecialHpFloor(profile);
|
||||||
|
value += SelectedAggressiveness switch
|
||||||
|
{
|
||||||
|
AggressivenessProfile.Conservative => 0.20,
|
||||||
|
AggressivenessProfile.Balanced => 0.10,
|
||||||
|
AggressivenessProfile.Aggressive => 0.00,
|
||||||
|
AggressivenessProfile.Extreme => -0.05,
|
||||||
|
_ => 0.00,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
value += 0.10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Clamp(value, 0.01, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double DashHpThresholdAdjusted(LevelProfile profile)
|
||||||
|
{
|
||||||
|
var value = DashHpThreshold(profile);
|
||||||
|
value += SelectedAggressiveness switch
|
||||||
|
{
|
||||||
|
AggressivenessProfile.Conservative => 0.18,
|
||||||
|
AggressivenessProfile.Balanced => 0.10,
|
||||||
|
AggressivenessProfile.Aggressive => 0.00,
|
||||||
|
AggressivenessProfile.Extreme => -0.03,
|
||||||
|
_ => 0.00,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
value += 0.10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Clamp(value, 0.01, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
private (int X, int Y)? PredictEnemyRelative()
|
private (int X, int Y)? PredictEnemyRelative()
|
||||||
{
|
{
|
||||||
@@ -1121,7 +1263,21 @@ public partial class MainWindow : Window
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeathHeatFor(direction) >= 4.0;
|
var deathHeatLimit = SelectedAggressiveness switch
|
||||||
|
{
|
||||||
|
AggressivenessProfile.Conservative => 2.5,
|
||||||
|
AggressivenessProfile.Balanced => 3.2,
|
||||||
|
AggressivenessProfile.Aggressive => 4.0,
|
||||||
|
AggressivenessProfile.Extreme => 5.0,
|
||||||
|
_ => 4.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsMultiplayerOptimized)
|
||||||
|
{
|
||||||
|
deathHeatLimit -= 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeathHeatFor(direction) >= deathHeatLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MarkVisit(int x, int y, double amount)
|
private void MarkVisit(int x, int y, double amount)
|
||||||
@@ -1235,7 +1391,7 @@ public partial class MainWindow : Window
|
|||||||
$"Level: {_levelName} | Kills: {_kills} | Deaths: {_deaths} | K/D: {kdr} | " +
|
$"Level: {_levelName} | Kills: {_kills} | Deaths: {_deaths} | K/D: {kdr} | " +
|
||||||
$"HP: {_currentHealth.ToString("0.0", CultureInfo.InvariantCulture)}/{_maxHealth.ToString("0.0", CultureInfo.InvariantCulture)} ({hpPercent.ToString("0", CultureInfo.InvariantCulture)}%) | " +
|
$"HP: {_currentHealth.ToString("0.0", CultureInfo.InvariantCulture)}/{_maxHealth.ToString("0.0", CultureInfo.InvariantCulture)} ({hpPercent.ToString("0", CultureInfo.InvariantCulture)}%) | " +
|
||||||
$"Progress: {_progress.ToString("0.0", CultureInfo.InvariantCulture)}% | Remaining: {_remainingTime.ToString("0.00", CultureInfo.InvariantCulture)} min | " +
|
$"Progress: {_progress.ToString("0.0", CultureInfo.InvariantCulture)}% | Remaining: {_remainingTime.ToString("0.00", CultureInfo.InvariantCulture)} min | " +
|
||||||
$"Pos (estimated): ({_x}, {_y}) | Profile: {_currentLevelProfile} | SurvivalMode: {(_survivalTicks > 0 ? "ON" : "OFF")}";
|
$"Pos (estimated): ({_x}, {_y}) | Profile: {_currentLevelProfile} | Aggro: {SelectedAggressiveness} | Mode: {SelectedModeOptimization} | SurvivalMode: {(_survivalTicks > 0 ? "ON" : "OFF")}";
|
||||||
|
|
||||||
var nearest = _nearestEnemy.HasValue ? $"({_nearestEnemy.Value.X}, {_nearestEnemy.Value.Y})" : "none";
|
var nearest = _nearestEnemy.HasValue ? $"({_nearestEnemy.Value.X}, {_nearestEnemy.Value.Y})" : "none";
|
||||||
var radar = _lastRadar.Count == 0
|
var radar = _lastRadar.Count == 0
|
||||||
@@ -1276,7 +1432,38 @@ public partial class MainWindow : Window
|
|||||||
Dispatcher.UIThread.Post(() => StatusText.Text = text);
|
Dispatcher.UIThread.Post(() => StatusText.Text = text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsMultiplayerMode => MultiplayerCheckBox.IsChecked == true;
|
private bool IsMultiplayerMode => _isMultiplayerMode;
|
||||||
|
|
||||||
|
private AggressivenessProfile SelectedAggressiveness => _selectedAggressiveness;
|
||||||
|
|
||||||
|
private ModeOptimizationProfile SelectedModeOptimization => _selectedModeOptimization;
|
||||||
|
|
||||||
|
private bool IsMultiplayerOptimized => SelectedModeOptimization switch
|
||||||
|
{
|
||||||
|
ModeOptimizationProfile.SingleplayerOptimized => false,
|
||||||
|
ModeOptimizationProfile.MultiplayerOptimized => true,
|
||||||
|
_ => _isMultiplayerMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
private void SyncProfileSelectionState()
|
||||||
|
{
|
||||||
|
_isMultiplayerMode = MultiplayerCheckBox.IsChecked == true;
|
||||||
|
_selectedAggressiveness = AggressivenessProfileBox.SelectedIndex switch
|
||||||
|
{
|
||||||
|
0 => AggressivenessProfile.Conservative,
|
||||||
|
1 => AggressivenessProfile.Balanced,
|
||||||
|
2 => AggressivenessProfile.Aggressive,
|
||||||
|
3 => AggressivenessProfile.Extreme,
|
||||||
|
_ => AggressivenessProfile.Aggressive,
|
||||||
|
};
|
||||||
|
|
||||||
|
_selectedModeOptimization = ModeOptimizationProfileBox.SelectedIndex switch
|
||||||
|
{
|
||||||
|
1 => ModeOptimizationProfile.SingleplayerOptimized,
|
||||||
|
2 => ModeOptimizationProfile.MultiplayerOptimized,
|
||||||
|
_ => ModeOptimizationProfile.Auto,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void AppendLog(string message)
|
private void AppendLog(string message)
|
||||||
{
|
{
|
||||||
@@ -1382,6 +1569,21 @@ public partial class MainWindow : Window
|
|||||||
NewBots,
|
NewBots,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum AggressivenessProfile
|
||||||
|
{
|
||||||
|
Conservative,
|
||||||
|
Balanced,
|
||||||
|
Aggressive,
|
||||||
|
Extreme,
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ModeOptimizationProfile
|
||||||
|
{
|
||||||
|
Auto,
|
||||||
|
SingleplayerOptimized,
|
||||||
|
MultiplayerOptimized,
|
||||||
|
}
|
||||||
|
|
||||||
private enum Direction
|
private enum Direction
|
||||||
{
|
{
|
||||||
North = 0,
|
North = 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user