🚀 Added (New Features)

• Random Offset feature: Applies random X/Y offset values on each set activation (both mouse buttons pressed)
• Each axis gets independent random values within configurable range (e.g., 0.003 and 0.008)
• New random values generated on every activation
• Toggle to enable/disable the feature

🛠️ Fixed (Bugs resolved)
• Replaced jitter system (burst/cooldown) with simpler random offset system

📂 File-Level Changes Summary
• ConfigLoader.cs: Added randomOffsetEnabled, randomOffsetMin, randomOffsetMax settings
• RecoilEngine.cs: Implemented random offset logic with activation detection
• MainWindow.xaml: Replaced Jitter Settings with Random Offset Settings UI
• MainWindow.xaml.cs: Updated LoadSettingsToUI, GenerateConfigContent, ResetSettings_Click
• helper.cs: Added ParseDoubleFromAssignment helper method
This commit is contained in:
TJhost
2026-09-03 16:00:27 -04:00
parent 86c231773d
commit ae3b4164f3
5 changed files with 96 additions and 85 deletions
+13 -13
View File
@@ -42,11 +42,11 @@ namespace Lua
public static string userName = null;
// AA0013
public static bool jitterEnabled = false;
public static bool randomOffsetEnabled = false;
// AA0014
public static int jitterBurstTime = 1800;
public static double randomOffsetMin = 0.0001;
// AA0015
public static int jitterCooldown = 3000;
public static double randomOffsetMax = 0.001;
// AA0016
public static ConsoleColor textColor = ConsoleColor.Magenta;
@@ -63,9 +63,9 @@ namespace Lua
favoriteAttackers = null;
favoriteDefenders = null;
userName = null;
jitterEnabled = false;
jitterBurstTime = 1800;
jitterCooldown = 3000;
randomOffsetEnabled = false;
randomOffsetMin = 0.0001;
randomOffsetMax = 0.001;
textColor = ConsoleColor.Magenta;
quickSwaps.Clear();
@@ -108,13 +108,13 @@ namespace Lua
favoriteDefenders = s2;
else if (Helper.ParseStringFromAssignment(line, "userName", out var s3))
userName = s3;
// AA0025
else if (Helper.ParseBoolFromAssignment(line, "jitterEnabled", out var jb))
jitterEnabled = jb;
else if (Helper.ParseIntFromAssignment(line, "jitterBurstTime", out var jbT))
jitterBurstTime = jbT;
else if (Helper.ParseIntFromAssignment(line, "jitterCooldown", out var jbC))
jitterCooldown = jbC;
// AA0025 - Random Offset Settings
else if (Helper.ParseBoolFromAssignment(line, "randomOffsetEnabled", out var roe))
randomOffsetEnabled = roe;
else if (Helper.ParseDoubleFromAssignment(line, "randomOffsetMin", out var rom))
randomOffsetMin = rom;
else if (Helper.ParseDoubleFromAssignment(line, "randomOffsetMax", out var roM))
randomOffsetMax = roM;
// AA0026
else if (Helper.ParseConsoleColorFromAssignment(line, "textColor", out var col))
textColor = col;
+27 -18
View File
@@ -239,25 +239,34 @@
</Grid>
</GroupBox>
<!-- Jitter Settings -->
<GroupBox Grid.Row="2" Grid.ColumnSpan="2" Header="Jitter Settings" Foreground="White" Margin="5" BorderBrush="#444">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Random Offset Settings -->
<GroupBox Grid.Row="2" Grid.ColumnSpan="2" Header="Random Offset Settings" Foreground="White" Margin="5" BorderBrush="#444">
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal" Margin="0,5">
<CheckBox x:Name="RandomOffsetEnabledCheckBox" Content="Random Offset Enabled" Foreground="White" VerticalAlignment="Center"/>
<TextBlock Text="(Applies random X/Y offset on each set activation)" Foreground="Gray" FontSize="11" Margin="10,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
<Grid Margin="0,5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Burst Time (ms):" Foreground="White" Margin="0,5,10,5" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" x:Name="JitterBurstTimeTextBox" Margin="0,5" Width="80" HorizontalAlignment="Left" Background="#2D2D2D" Foreground="White" BorderBrush="#444"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="Cooldown (ms):" Foreground="White" Margin="20,5,10,5" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="3" x:Name="JitterCooldownTextBox" Margin="0,5" Width="80" HorizontalAlignment="Left" Background="#2D2D2D" Foreground="White" BorderBrush="#444"/>
</Grid>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Min Offset:" Foreground="White" Margin="0,5,10,5" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" x:Name="RandomOffsetMinTextBox" Margin="0,5" Width="80" HorizontalAlignment="Left" Background="#2D2D2D" Foreground="White" BorderBrush="#444"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="Max Offset:" Foreground="White" Margin="20,5,10,5" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="3" x:Name="RandomOffsetMaxTextBox" Margin="0,5" Width="80" HorizontalAlignment="Left" Background="#2D2D2D" Foreground="White" BorderBrush="#444"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="(e.g. 0.0001)" Foreground="Gray" FontSize="11" Margin="0,0,10,0" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="(e.g. 0.001)" Foreground="Gray" FontSize="11" Margin="20,0,10,0" VerticalAlignment="Center"/>
</Grid>
</StackPanel>
</GroupBox>
<!-- User & Favorites -->
+16 -16
View File
@@ -122,7 +122,7 @@ namespace Lithium
DebitFlagCheckBox.IsChecked = ConfigLoader.debitFlag1;
BetaTestCheckBox.IsChecked = ConfigLoader.betaTest;
TtsEnabledCheckBox.IsChecked = ConfigLoader.ttsEnabled;
JitterEnabledCheckBox.IsChecked = ConfigLoader.jitterEnabled;
RandomOffsetEnabledCheckBox.IsChecked = ConfigLoader.randomOffsetEnabled;
// AA0123
NextSetKeyTextBox.Text = $"0x{ConfigLoader.nextSetKey:X2}";
@@ -130,9 +130,9 @@ namespace Lithium
RefreshKeyTextBox.Text = $"0x{ConfigLoader.refreshKey:X2}";
SwitchSideKeyTextBox.Text = $"0x{ConfigLoader.switchSideKey:X2}";
// AA0124
JitterBurstTimeTextBox.Text = ConfigLoader.jitterBurstTime.ToString();
JitterCooldownTextBox.Text = ConfigLoader.jitterCooldown.ToString();
// AA0124 - Random Offset Settings
RandomOffsetMinTextBox.Text = ConfigLoader.randomOffsetMin.ToString("0.0000", System.Globalization.CultureInfo.InvariantCulture);
RandomOffsetMaxTextBox.Text = ConfigLoader.randomOffsetMax.ToString("0.0000", System.Globalization.CultureInfo.InvariantCulture);
// AA0125
UserNameTextBox.Text = ConfigLoader.userName ?? "";
@@ -230,13 +230,13 @@ namespace Lithium
ConfigLoader.debitFlag1 = false;
ConfigLoader.betaTest = false;
ConfigLoader.ttsEnabled = true;
ConfigLoader.jitterEnabled = false;
ConfigLoader.randomOffsetEnabled = false;
ConfigLoader.randomOffsetMin = 0.0001;
ConfigLoader.randomOffsetMax = 0.001;
ConfigLoader.nextSetKey = 0x05;
ConfigLoader.prevSetKey = 0x06;
ConfigLoader.refreshKey = 0x50;
ConfigLoader.switchSideKey = 0x4D;
ConfigLoader.jitterBurstTime = 1800;
ConfigLoader.jitterCooldown = 3000;
ConfigLoader.userName = null;
ConfigLoader.favoriteAttackers = null;
ConfigLoader.favoriteDefenders = null;
@@ -252,15 +252,15 @@ namespace Lithium
// AA0134
private string GenerateConfigContent()
{
// Validate and parse jitter times
if (!int.TryParse(JitterBurstTimeTextBox.Text, out int jitterBurstTime))
// Validate and parse random offset values
if (!double.TryParse(RandomOffsetMinTextBox.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out double randomOffsetMin))
{
AppendConsole("Error: Invalid jitter burst time value");
AppendConsole("Error: Invalid random offset min value");
return null;
}
if (!int.TryParse(JitterCooldownTextBox.Text, out int jitterCooldown))
if (!double.TryParse(RandomOffsetMaxTextBox.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out double randomOffsetMax))
{
AppendConsole("Error: Invalid jitter cooldown value");
AppendConsole("Error: Invalid random offset max value");
return null;
}
@@ -296,7 +296,7 @@ namespace Lithium
sb.AppendLine($"debitFlag1 = {DebitFlagCheckBox.IsChecked.ToString().ToLower()}");
sb.AppendLine($"betaTest = {BetaTestCheckBox.IsChecked.ToString().ToLower()}");
sb.AppendLine($"ttsEnabled = {TtsEnabledCheckBox.IsChecked.ToString().ToLower()}");
sb.AppendLine($"jitterEnabled = {JitterEnabledCheckBox.IsChecked.ToString().ToLower()}");
sb.AppendLine($"randomOffsetEnabled = {RandomOffsetEnabledCheckBox.IsChecked.ToString().ToLower()}");
sb.AppendLine();
sb.AppendLine("-- Key Bindings (Virtual Key Codes)");
sb.AppendLine($"nextSetKey = {ParseKeyCode(NextSetKeyTextBox.Text)}");
@@ -304,9 +304,9 @@ namespace Lithium
sb.AppendLine($"refreshKey = {ParseKeyCode(RefreshKeyTextBox.Text)}");
sb.AppendLine($"switchSideKey = {ParseKeyCode(SwitchSideKeyTextBox.Text)}");
sb.AppendLine();
sb.AppendLine("-- Jitter Settings");
sb.AppendLine($"jitterBurstTime = {jitterBurstTime}");
sb.AppendLine($"jitterCooldown = {jitterCooldown}");
sb.AppendLine("-- Random Offset Settings");
sb.AppendLine($"randomOffsetMin = {randomOffsetMin.ToString("0.0000", System.Globalization.CultureInfo.InvariantCulture)}");
sb.AppendLine($"randomOffsetMax = {randomOffsetMax.ToString("0.0000", System.Globalization.CultureInfo.InvariantCulture)}");
sb.AppendLine();
sb.AppendLine("-- User & Favorites");
sb.AppendLine($"userName = \"{UserNameTextBox.Text}\"");
+25 -37
View File
@@ -14,11 +14,10 @@ namespace Lua
private static extern short GetAsyncKeyState(int vKey);
private static readonly Random _rng = new Random();
private static bool _jitterActive = false;
private static int _jitterStart = 0;
private static int _lastJitterEnd = 0;
private static bool _wasBothDown = false;
private static double _randomOffsetX = 0;
private static double _randomOffsetY = 0;
private static double _remainderX, _remainderY;
private static double _jitterMultiplierX, _jitterMultiplierY;
public static bool CustomModeActive = false;
public static double CustomRecoilX = 0;
@@ -38,18 +37,24 @@ namespace Lua
{
while (!_cancellationSource.Token.IsCancellationRequested)
{
// FIX: Perform key checks once and reuse the results
bool leftDown = IsDown(VK_LBUTTON);
bool rightDown = IsDown(VK_RBUTTON);
bool bothDown = leftDown && rightDown;
if (window.IsRecoilEnabled && leftDown && rightDown)
// Detect new activation (transition from not both down to both down)
if (bothDown && !_wasBothDown)
{
OnSetActivated();
}
_wasBothDown = bothDown;
if (window.IsRecoilEnabled && bothDown)
{
HandleRecoilTick();
}
else
{
_remainderX = _remainderY = 0;
_jitterActive = false;
}
Thread.Sleep(2);
@@ -61,15 +66,23 @@ namespace Lua
}
}
private static void OnSetActivated()
{
if (!ConfigLoader.randomOffsetEnabled) return;
double range = ConfigLoader.randomOffsetMax - ConfigLoader.randomOffsetMin;
if (range <= 0) return;
_randomOffsetX = ConfigLoader.randomOffsetMin + _rng.NextDouble() * range;
_randomOffsetY = ConfigLoader.randomOffsetMin + _rng.NextDouble() * range;
}
private static void HandleRecoilTick()
{
try
{
int now = Environment.TickCount;
if (CustomModeActive)
{
HandleJitter(now);
ApplyRecoil((CustomRecoilX, CustomRecoilY));
return;
}
@@ -78,7 +91,6 @@ namespace Lua
if (!OperatorSets.mergedSets.TryGetValue(setName, out var recoil)) return;
HandleJitter(now);
ApplyRecoil(recoil);
}
catch (Exception ex)
@@ -87,34 +99,10 @@ namespace Lua
}
}
private static void HandleJitter(int now)
{
if (!ConfigLoader.jitterEnabled) return;
if (!_jitterActive && now - _lastJitterEnd >= ConfigLoader.jitterCooldown)
{
_jitterActive = true;
_jitterStart = now;
_jitterMultiplierX = (_rng.NextDouble() - 0.5) * 0.2;
_jitterMultiplierY = (_rng.NextDouble() - 0.5) * 0.2;
}
if (_jitterActive && now - _jitterStart >= ConfigLoader.jitterBurstTime)
{
_jitterActive = false;
_lastJitterEnd = now;
_jitterMultiplierX = _jitterMultiplierY = 0;
}
}
private static void ApplyRecoil((double recoilX, double recoilY) recoil)
{
double moveX = recoil.recoilX;
double moveY = recoil.recoilY;
moveX += recoil.recoilX * _jitterMultiplierX;
moveY += recoil.recoilY * _jitterMultiplierY;
double moveX = recoil.recoilX + _randomOffsetX;
double moveY = recoil.recoilY + _randomOffsetY;
if (ConfigLoader.debitFlag1)
{
+14
View File
@@ -66,6 +66,20 @@ namespace Lua
return int.TryParse(rhs, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
}
// AA0034b
public static bool ParseDoubleFromAssignment(string line, string key, out double result)
{
result = 0;
var idx = line.IndexOf('=');
if (idx < 0) return false;
var lhs = line.Substring(0, idx).Trim();
if (!string.Equals(lhs, key, StringComparison.OrdinalIgnoreCase)) return false;
var rhs = line.Substring(idx + 1).Trim();
return double.TryParse(rhs, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
}
// AA0035
public static bool ParseStringFromAssignment(string line, string key, out string result)
{