Kill Streaks and Multikills.

Implemented kill streaks and multikills. Need to do some cleaning up but should work great.
This commit is contained in:
Heavy Bob 2025-04-13 04:58:31 +10:00
parent ad773f6790
commit 36cfdaba8a
25 changed files with 240 additions and 14 deletions

View file

@ -38,4 +38,14 @@
</Resource> </Resource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="sounds\*.mp3">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="NAudio" Version="2.2.1" />
</ItemGroup>
</Project> </Project>

View file

@ -154,13 +154,25 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Kill Streak Test Button -->
<Button Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="2"
Content="Test Kill Streak Sounds"
Height="30"
FontFamily="{StaticResource Orbitron}"
Margin="0,0,0,10"
Style="{StaticResource ButtonStyle}"
Click="TestKillStreakButton_Click"/>
<!-- Left Column Controls --> <!-- Left Column Controls -->
<!-- Visor Wipe Toggle --> <!-- Visor Wipe Toggle -->
<StackPanel Grid.Column="0" <StackPanel Grid.Column="0"
Grid.Row="0" Grid.Row="1"
Orientation="Horizontal" Orientation="Horizontal"
Margin="0,0,5,5"> Margin="0,0,5,5">
<TextBlock Text="ⓘ" <TextBlock Text="ⓘ"
@ -186,7 +198,7 @@
<!-- Video Record Toggle --> <!-- Video Record Toggle -->
<StackPanel Grid.Column="0" <StackPanel Grid.Column="0"
Grid.Row="1" Grid.Row="2"
Orientation="Horizontal" Orientation="Horizontal"
Margin="0,0,5,5"> Margin="0,0,5,5">
<TextBlock Text="ⓘ" <TextBlock Text="ⓘ"
@ -212,7 +224,7 @@
<!-- Offline Mode Toggle --> <!-- Offline Mode Toggle -->
<StackPanel Grid.Column="0" <StackPanel Grid.Column="0"
Grid.Row="2" Grid.Row="3"
Orientation="Horizontal" Orientation="Horizontal"
Margin="0,0,5,5"> Margin="0,0,5,5">
<TextBlock Text="ⓘ" <TextBlock Text="ⓘ"
@ -240,7 +252,7 @@
<!-- Streamlink Toggle --> <!-- Streamlink Toggle -->
<StackPanel Grid.Column="1" <StackPanel Grid.Column="1"
Grid.Row="0" Grid.Row="1"
Orientation="Horizontal" Orientation="Horizontal"
Margin="5,0,0,5"> Margin="5,0,0,5">
<TextBlock Text="ⓘ" <TextBlock Text="ⓘ"
@ -266,7 +278,7 @@
<!-- Streamlink Duration --> <!-- Streamlink Duration -->
<StackPanel Grid.Column="1" <StackPanel Grid.Column="1"
Grid.Row="1" Grid.Row="2"
Orientation="Horizontal" Orientation="Horizontal"
Margin="5,0,0,5"> Margin="5,0,0,5">
<TextBlock Text="ⓘ" <TextBlock Text="ⓘ"
@ -297,7 +309,7 @@
<!-- Test Streamlink Button --> <!-- Test Streamlink Button -->
<Button Grid.Column="1" <Button Grid.Column="1"
Grid.Row="2" Grid.Row="3"
Content="Test Streamlink" Content="Test Streamlink"
Width="120" Width="120"
Height="30" Height="30"
@ -308,7 +320,7 @@
<!-- Theme Slider --> <!-- Theme Slider -->
<StackPanel Grid.Column="0" <StackPanel Grid.Column="0"
Grid.Row="3" Grid.Row="5"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Orientation="Horizontal" Orientation="Horizontal"
Margin="0,0,0,5"> Margin="0,0,0,5">

View file

@ -24,6 +24,10 @@ public partial class ConfigPage : UserControl
Dictionary<string, Theme>? _themes = null; Dictionary<string, Theme>? _themes = null;
private KillStreakManager? _testKillStreakManager;
private bool _isTestRunning = false;
private int _currentTestStep = 0;
public ConfigPage(MainWindow mainWindow) public ConfigPage(MainWindow mainWindow)
{ {
InitializeComponent(); InitializeComponent();
@ -215,7 +219,7 @@ public partial class ConfigPage : UserControl
dialog.CheckFileExists = false; dialog.CheckFileExists = false;
dialog.CheckPathExists = true; dialog.CheckPathExists = true;
dialog.FileName = "Folder Selection"; dialog.FileName = "Folder Selection";
if (dialog.ShowDialog() == true) if (dialog.ShowDialog() == true)
{ {
string? selectedFolder = Path.GetDirectoryName(dialog.FileName); string? selectedFolder = Path.GetDirectoryName(dialog.FileName);
@ -338,7 +342,7 @@ public partial class ConfigPage : UserControl
ConfigManager.VideoRecord = (int)VideoRecordSlider.Value; ConfigManager.VideoRecord = (int)VideoRecordSlider.Value;
ConfigManager.OfflineMode = (int)OfflineModeSlider.Value; ConfigManager.OfflineMode = (int)OfflineModeSlider.Value;
ConfigManager.Theme = (int)ThemeSlider.Value; ConfigManager.Theme = (int)ThemeSlider.Value;
// Save the current config values // Save the current config values
ConfigManager.SaveConfig(); ConfigManager.SaveConfig();
// Start the flashing effect // Start the flashing effect
@ -562,6 +566,26 @@ public partial class ConfigPage : UserControl
MessageBox.Show("Directory does not exist.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("Directory does not exist.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
private async void TestKillStreakButton_Click(object sender, RoutedEventArgs e)
{
// Create a single KillStreakManager instance if it doesn't exist
if (_testKillStreakManager == null)
{
var soundsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sounds");
_testKillStreakManager = new KillStreakManager(soundsPath);
}
// Simulate 5 quick kills
for (int i = 0; i < 5; i++)
{
_testKillStreakManager.OnKill();
}
// Reset the streak after all sounds have played
await Task.Delay(1000);
_testKillStreakManager.OnDeath();
}
} }
public class Theme public class Theme

View file

@ -37,7 +37,7 @@ public partial class HomePage : UserControl
{ {
throw new InvalidOperationException("KillHistoryFile path is not configured."); throw new InvalidOperationException("KillHistoryFile path is not configured.");
} }
_killHistoryManager = new KillHistoryManager(ConfigManager.KillHistoryFile); _killHistoryManager = new KillHistoryManager(ConfigManager.KillHistoryFile, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sounds"));
// Set the TextBlock text // Set the TextBlock text
KillTallyTitle.Text = $"Kill Tally - {DateTime.Now.ToString("MMMM")}"; KillTallyTitle.Text = $"Kill Tally - {DateTime.Now.ToString("MMMM")}";
@ -279,6 +279,11 @@ public partial class HomePage : UserControl
}); });
} }
} }
else
{
// Player died, reset kill streak
_killHistoryManager.ResetKillStreak();
}
}; };
// Vehicle Destruction // Vehicle Destruction

View file

@ -8,11 +8,13 @@ public class KillHistoryManager
{ {
private string _killHistoryPath; private string _killHistoryPath;
private readonly string _headers = "KillTime,EnemyPilot,EnemyShip,Enlisted,RecordNumber,OrgAffiliation,Player,Weapon,Ship,Method,Mode,GameVersion,TrackRver,Logged,PFP,Hash\n"; private readonly string _headers = "KillTime,EnemyPilot,EnemyShip,Enlisted,RecordNumber,OrgAffiliation,Player,Weapon,Ship,Method,Mode,GameVersion,TrackRver,Logged,PFP,Hash\n";
private readonly KillStreakManager _killStreakManager;
public KillHistoryManager(string logPath) public KillHistoryManager(string logPath, string soundsPath)
{ {
_killHistoryPath = logPath; _killHistoryPath = logPath;
_killStreakManager = new KillStreakManager(soundsPath);
if (!File.Exists(_killHistoryPath)) if (!File.Exists(_killHistoryPath))
{ {
File.WriteAllText(_killHistoryPath, _headers); File.WriteAllText(_killHistoryPath, _headers);
@ -97,6 +99,9 @@ public class KillHistoryManager
using var fileStream = new FileStream(_killHistoryPath, FileMode.Append, FileAccess.Write, FileShare.None); using var fileStream = new FileStream(_killHistoryPath, FileMode.Append, FileAccess.Write, FileShare.None);
using var writer = new StreamWriter(fileStream); using var writer = new StreamWriter(fileStream);
writer.Write(csv.ToString()); writer.Write(csv.ToString());
// Trigger kill streak sound
_killStreakManager.OnKill();
} }
catch (IOException ex) catch (IOException ex)
{ {
@ -104,7 +109,12 @@ public class KillHistoryManager
Console.WriteLine($"Error writing to file: {ex.Message}"); Console.WriteLine($"Error writing to file: {ex.Message}");
} }
} }
public void ResetKillStreak()
{
_killStreakManager.OnDeath();
}
public List<KillData> GetKills() public List<KillData> GetKills()
{ {
var kills = new List<KillData>(); var kills = new List<KillData>();

View file

@ -0,0 +1,165 @@
using System.Media;
using System.Timers;
using System.IO;
using NAudio.Wave;
namespace AutoTrackR2;
public class KillStreakManager
{
private readonly Queue<string> _soundQueue = new();
private readonly System.Timers.Timer _killStreakTimer = new(5000); // 5 seconds between kills for streak
private int _currentKills = 0;
private int _totalKills = 0;
private readonly string _soundsPath;
private readonly object _lock = new();
private WaveOutEvent? _waveOut;
private bool _isPlaying = false;
public KillStreakManager(string soundsPath)
{
_soundsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sounds");
_killStreakTimer.Elapsed += OnKillStreakTimerElapsed;
Console.WriteLine($"KillStreakManager initialized with sounds path: {_soundsPath}");
}
public void OnKill()
{
lock (_lock)
{
_currentKills++;
_totalKills++;
_killStreakTimer.Stop();
_killStreakTimer.Start();
// Handle multi-kill announcements
string multiKillSound = _currentKills switch
{
2 => "double_kill.mp3",
3 => "triple_kill.mp3",
4 => "overkill.mp3",
5 => "killtacular.mp3",
6 => "killtrocity.mp3",
7 => "killimanjaro.mp3",
8 => "killtastrophe.mp3",
9 => "killpocalypse.mp3",
10 => "killionaire.mp3",
_ => null
};
// Handle spree announcements
string spreeSound = _totalKills switch
{
5 => "killing_spree.mp3",
10 => "killing_frenzy.mp3",
15 => "running_riot.mp3",
20 => "rampage.mp3",
25 => "untouchable.mp3",
30 => "invincible.mp3",
35 => "unstoppable.mp3",
40 => "hells_janitor.mp3",
45 => "perfection.mp3",
_ => null
};
// Queue up the sounds if they exist
if (multiKillSound != null)
{
string soundPath = Path.Combine(_soundsPath, multiKillSound);
Console.WriteLine($"Queueing multi-kill sound: {soundPath}");
_soundQueue.Enqueue(soundPath);
}
if (spreeSound != null)
{
string soundPath = Path.Combine(_soundsPath, spreeSound);
Console.WriteLine($"Queueing spree sound: {soundPath}");
_soundQueue.Enqueue(soundPath);
}
// Only start playing if not already playing
if (!_isPlaying && _soundQueue.Count > 0)
{
PlayNextSound();
}
}
}
public void OnDeath()
{
lock (_lock)
{
_totalKills = 0;
_currentKills = 0;
_killStreakTimer.Stop();
Console.WriteLine("Kill streak reset due to death");
}
}
private void OnKillStreakTimerElapsed(object? sender, ElapsedEventArgs e)
{
lock (_lock)
{
_currentKills = 0;
_killStreakTimer.Stop();
Console.WriteLine("Kill streak reset due to timeout");
}
}
private void PlayNextSound()
{
if (_soundQueue.Count > 0)
{
string soundPath = _soundQueue.Dequeue();
Console.WriteLine($"Attempting to play sound: {soundPath}");
try
{
if (File.Exists(soundPath))
{
// Stop any currently playing sound
_waveOut?.Stop();
_waveOut?.Dispose();
// Create a new WaveOutEvent
_waveOut = new WaveOutEvent();
// Create a new AudioFileReader for the MP3 file
using var audioFile = new AudioFileReader(soundPath);
_waveOut.Init(audioFile);
// Set up event handler for when playback finishes
_waveOut.PlaybackStopped += (sender, e) =>
{
_isPlaying = false;
if (_soundQueue.Count > 0)
{
PlayNextSound();
}
};
_isPlaying = true;
_waveOut.Play();
Console.WriteLine($"Successfully played sound: {soundPath}");
}
else
{
Console.WriteLine($"Sound file not found: {soundPath}");
_isPlaying = false;
if (_soundQueue.Count > 0)
{
PlayNextSound();
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error playing sound {soundPath}: {ex.Message}");
_isPlaying = false;
if (_soundQueue.Count > 0)
{
PlayNextSound();
}
}
}
}
}

View file

@ -181,7 +181,7 @@ public class LogHandler
{ {
// Wait for new lines to be written to the log file // Wait for new lines to be written to the log file
Thread.Sleep(1000); Thread.Sleep(500);
} }
} }
Console.WriteLine("Monitor thread stopped"); Console.WriteLine("Monitor thread stopped");

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.