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>
</ItemGroup>
<ItemGroup>
<None Include="sounds\*.mp3">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="NAudio" Version="2.2.1" />
</ItemGroup>
</Project>

View file

@ -154,13 +154,25 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</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 -->
<!-- Visor Wipe Toggle -->
<StackPanel Grid.Column="0"
Grid.Row="0"
Grid.Row="1"
Orientation="Horizontal"
Margin="0,0,5,5">
<TextBlock Text="ⓘ"
@ -186,7 +198,7 @@
<!-- Video Record Toggle -->
<StackPanel Grid.Column="0"
Grid.Row="1"
Grid.Row="2"
Orientation="Horizontal"
Margin="0,0,5,5">
<TextBlock Text="ⓘ"
@ -212,7 +224,7 @@
<!-- Offline Mode Toggle -->
<StackPanel Grid.Column="0"
Grid.Row="2"
Grid.Row="3"
Orientation="Horizontal"
Margin="0,0,5,5">
<TextBlock Text="ⓘ"
@ -240,7 +252,7 @@
<!-- Streamlink Toggle -->
<StackPanel Grid.Column="1"
Grid.Row="0"
Grid.Row="1"
Orientation="Horizontal"
Margin="5,0,0,5">
<TextBlock Text="ⓘ"
@ -266,7 +278,7 @@
<!-- Streamlink Duration -->
<StackPanel Grid.Column="1"
Grid.Row="1"
Grid.Row="2"
Orientation="Horizontal"
Margin="5,0,0,5">
<TextBlock Text="ⓘ"
@ -297,7 +309,7 @@
<!-- Test Streamlink Button -->
<Button Grid.Column="1"
Grid.Row="2"
Grid.Row="3"
Content="Test Streamlink"
Width="120"
Height="30"
@ -308,7 +320,7 @@
<!-- Theme Slider -->
<StackPanel Grid.Column="0"
Grid.Row="3"
Grid.Row="5"
Grid.ColumnSpan="2"
Orientation="Horizontal"
Margin="0,0,0,5">

View file

@ -24,6 +24,10 @@ public partial class ConfigPage : UserControl
Dictionary<string, Theme>? _themes = null;
private KillStreakManager? _testKillStreakManager;
private bool _isTestRunning = false;
private int _currentTestStep = 0;
public ConfigPage(MainWindow mainWindow)
{
InitializeComponent();
@ -215,7 +219,7 @@ public partial class ConfigPage : UserControl
dialog.CheckFileExists = false;
dialog.CheckPathExists = true;
dialog.FileName = "Folder Selection";
if (dialog.ShowDialog() == true)
{
string? selectedFolder = Path.GetDirectoryName(dialog.FileName);
@ -338,7 +342,7 @@ public partial class ConfigPage : UserControl
ConfigManager.VideoRecord = (int)VideoRecordSlider.Value;
ConfigManager.OfflineMode = (int)OfflineModeSlider.Value;
ConfigManager.Theme = (int)ThemeSlider.Value;
// Save the current config values
ConfigManager.SaveConfig();
// Start the flashing effect
@ -562,6 +566,26 @@ public partial class ConfigPage : UserControl
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

View file

@ -37,7 +37,7 @@ public partial class HomePage : UserControl
{
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
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

View file

@ -8,11 +8,13 @@ public class KillHistoryManager
{
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 KillStreakManager _killStreakManager;
public KillHistoryManager(string logPath)
public KillHistoryManager(string logPath, string soundsPath)
{
_killHistoryPath = logPath;
_killStreakManager = new KillStreakManager(soundsPath);
if (!File.Exists(_killHistoryPath))
{
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 writer = new StreamWriter(fileStream);
writer.Write(csv.ToString());
// Trigger kill streak sound
_killStreakManager.OnKill();
}
catch (IOException ex)
{
@ -104,7 +109,12 @@ public class KillHistoryManager
Console.WriteLine($"Error writing to file: {ex.Message}");
}
}
public void ResetKillStreak()
{
_killStreakManager.OnDeath();
}
public List<KillData> GetKills()
{
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
Thread.Sleep(1000);
Thread.Sleep(500);
}
}
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.