Add walk time for distance and other information

* Add simple time that it takes to walk distance while crouching/walking/running (later might have draw mode for adding a route)
* For above the ducking and walking speed multipliers have been added (as according to csgo source code)
* Add weapon info (running speed, base damage per minute, firing rate)
This commit is contained in:
MathiasL 2022-05-15 01:13:40 +02:00
parent 65959bff26
commit aac448d227
4 changed files with 142 additions and 76 deletions

View file

@ -82,6 +82,21 @@
<TextBlock x:Name="txtResult" Text="0" Foreground="IndianRed" FontSize="18" />
<TextBlock x:Name="txtResultArmor" Text="0" Foreground="CadetBlue" FontSize="14" />
</StackPanel>
<StackPanel Margin="0,20,0,0">
<TextBlock Text="Distance moved.." FontSize="14" FontWeight="Bold" />
<StackPanel Margin="0,10,0,0">
<TextBlock Text="..running:" FontSize="12" FontWeight="Bold" />
<TextBlock x:Name="txtTimeRunning" Text="None" TextWrapping="Wrap" />
</StackPanel>
<StackPanel>
<TextBlock Text="..walking:" FontSize="12" FontWeight="Bold" />
<TextBlock x:Name="txtTimeWalking" Text="None" TextWrapping="Wrap" />
</StackPanel>
<StackPanel>
<TextBlock Text="..crouching:" FontSize="12" FontWeight="Bold" />
<TextBlock x:Name="txtTimeCrouching" Text="None" TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</StackPanel>
</StackPanel>
<local:ZoomBorder x:Name="rightZoomBorder" Grid.Row="1" Grid.Column="1" Margin="10" ClipToBounds="True" SizeChanged="rightZoomBorder_SizeChanged">
@ -100,76 +115,42 @@
<GroupBox x:Name="groupWeaponName" Header="WEAPON-NAME">
<StackPanel Orientation="Horizontal">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Base damage:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Armor penetration:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Damage dropoff:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Max bullet range:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Headshot modifier:" />
</StackPanel>
<TextBlock Text="Base damage:" />
<TextBlock Text="... per minute:" />
<TextBlock Text="Firing rate per minute:" />
<TextBlock Text="Armor penetration:" />
<TextBlock Text="Damage dropoff:" />
<TextBlock Text="Max bullet range:" />
<TextBlock Text="Headshot modifier:" />
<TextBlock Text="Running speed:" />
</StackPanel>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtWeaponBaseDamage" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtWeaponArmorPenetration" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtWeaponDamageDropoff" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtWeaponMaxRange" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtWeaponHeadshotModifier" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel x:Name="stackWeaponInfo">
<TextBlock x:Name="txtWeaponBaseDamage" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponBaseDamagePerMinute" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponFireRate" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponArmorPenetration" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponDamageDropoff" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponMaxRange" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponHeadshotModifier" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtWeaponRunningSpeed" Text="None" Margin="10,0,0,0" />
</StackPanel>
</StackPanel>
</GroupBox>
<GroupBox Header="NAV info" Margin="0,10,0,0">
<StackPanel Orientation="Horizontal">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Current layer:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Average height:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Area ID:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Connections:" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name:" />
</StackPanel>
<TextBlock Text="Current layer:" />
<TextBlock Text="Average height:" />
<TextBlock Text="Area ID:" />
<TextBlock Text="Connections:" />
<TextBlock Text="Name:" />
</StackPanel>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtNavAreasAmount" Text="None" Margin="10,0,0,0" Foreground="IndianRed" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtNavAreaHeightPercentage" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtNavAreaID" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtNavAreaConnectionsAmount" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtNavAreaPlace" Text="None" Margin="10,0,0,0" />
</StackPanel>
<StackPanel x:Name="stackNavInfo">
<TextBlock x:Name="txtNavAreasAmount" Text="None" Margin="10,0,0,0" Foreground="IndianRed" />
<TextBlock x:Name="txtNavAreaHeightPercentage" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtNavAreaID" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtNavAreaConnectionsAmount" Text="None" Margin="10,0,0,0" />
<TextBlock x:Name="txtNavAreaPlace" Text="None" Margin="10,0,0,0" />
</StackPanel>
</StackPanel>
</GroupBox>

View file

@ -30,6 +30,8 @@ namespace Damage_Calculator
public static string FilesPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "CSGO Damage Calculator");
public static readonly string WeaponsFileExtension = ".wpd";
private readonly string placeholderText = "None";
/// <summary>
/// Holds current in-game mouse coordinates when hovering over the map
/// </summary>
@ -358,6 +360,9 @@ namespace Damage_Calculator
this.textDistanceUnits.Text = "0";
this.txtResult.Text = "0";
this.txtResultArmor.Text = "0";
this.txtTimeRunning.Text = "0";
this.txtTimeWalking.Text = "0";
this.txtTimeCrouching.Text = "0";
}
this.UpdateLayout();
this.canvasClear();
@ -1039,6 +1044,32 @@ namespace Damage_Calculator
return diffDistance3D;
}
private void calculateDistanceDuration()
{
double timeRunning = this.unitsDistance / this.selectedWeapon.RunningSpeed;
double timeWalking = this.unitsDistance / (this.selectedWeapon.RunningSpeed * Shared.CsgoHelper.WalkModifier);
double timeCrouching = this.unitsDistance / (this.selectedWeapon.RunningSpeed * Shared.CsgoHelper.DuckModifier);
this.txtTimeRunning.Text = getTimeStringFromSeconds(timeRunning);
this.txtTimeWalking.Text = getTimeStringFromSeconds(timeWalking);
this.txtTimeCrouching.Text = getTimeStringFromSeconds(timeCrouching);
}
private string getTimeStringFromSeconds(double seconds)
{
string timeString = string.Empty;
int separatedMinutes = (int)(seconds / 60);
double separatedSeconds = seconds % 60;
if (separatedMinutes > 0)
timeString += $"{separatedMinutes} min, ";
timeString += $"{Math.Round(separatedSeconds, 2).ToString(CultureInfo.InvariantCulture)} sec";
return timeString;
}
private void calculateAndUpdateShootingDamage()
{
double damage = this.selectedWeapon.BaseDamage;
@ -1404,11 +1435,7 @@ namespace Damage_Calculator
}
else
{
this.txtNavAreasAmount.Text = "None";
this.txtNavAreaHeightPercentage.Text = "None";
this.txtNavAreaID.Text = "None";
this.txtNavAreaConnectionsAmount.Text = "None";
this.txtNavAreaPlace.Text = "None";
this.resetNavInfo();
}
}
@ -1418,22 +1445,32 @@ namespace Damage_Calculator
{
this.groupWeaponName.Header = this.selectedWeapon.ClassName.Replace('_','-');
this.txtWeaponBaseDamage.Text = this.selectedWeapon.BaseDamage.ToString(CultureInfo.InvariantCulture);
this.txtWeaponArmorPenetration.Text = this.selectedWeapon.ArmorPenetration.ToString(CultureInfo.InvariantCulture);
this.txtWeaponDamageDropoff.Text = this.selectedWeapon.DamageDropoff.ToString(CultureInfo.InvariantCulture);
this.txtWeaponBaseDamagePerMinute.Text = this.selectedWeapon.FireRate < 0 ? "?" : (this.selectedWeapon.BaseDamage * this.selectedWeapon.FireRate).ToString(CultureInfo.InvariantCulture);
this.txtWeaponFireRate.Text = this.selectedWeapon.FireRate.ToString(CultureInfo.InvariantCulture);
this.txtWeaponArmorPenetration.Text = this.selectedWeapon.ArmorPenetration.ToString(CultureInfo.InvariantCulture) + " %";
this.txtWeaponDamageDropoff.Text = Math.Round(1d - this.selectedWeapon.DamageDropoff, 2).ToString(CultureInfo.InvariantCulture) + " %";
this.txtWeaponMaxRange.Text = this.selectedWeapon.MaxBulletRange.ToString(CultureInfo.InvariantCulture);
this.txtWeaponHeadshotModifier.Text = this.selectedWeapon.HeadshotModifier.ToString(CultureInfo.InvariantCulture);
this.txtWeaponHeadshotModifier.Text = this.selectedWeapon.DamageType != DamageType.Shock ? this.selectedWeapon.HeadshotModifier.ToString(CultureInfo.InvariantCulture) : placeholderText;
this.txtWeaponRunningSpeed.Text = this.selectedWeapon.RunningSpeed.ToString();
}
else
{
this.groupWeaponName.Header = "WEAPON-NAME";
this.txtWeaponBaseDamage.Text = "None";
this.txtWeaponArmorPenetration.Text = "None";
this.txtWeaponDamageDropoff.Text = "None";
this.txtWeaponMaxRange.Text = "None";
this.txtWeaponHeadshotModifier.Text = "None";
this.resetWeaponInfo();
}
}
private void resetWeaponInfo()
{
foreach (TextBlock x in this.stackWeaponInfo.Children)
x.Text = placeholderText;
}
private void resetNavInfo()
{
foreach (TextBlock x in this.stackNavInfo.Children)
x.Text = placeholderText;
}
#region events
private void rightZoomBorder_SizeChanged(object sender, SizeChangedEventArgs e)
{
@ -1588,6 +1625,8 @@ namespace Damage_Calculator
this.calculateAndUpdateShootingDamage();
else if (this.DrawMode == eDrawMode.Bomb)
calculateAndUpdateBombDamage();
this.calculateDistanceDuration();
}
private void comboWeapons_SelectionChanged(object sender, SelectionChangedEventArgs e)

View file

@ -15,6 +15,10 @@ namespace Shared
{
public string? CsgoPath { get; set; }
public static readonly float DuckModifier = 0.34f;
public static readonly float WalkModifier = 0.52f;
/// <summary>
/// Gets the prefixes allowed for maps when using <see cref="GetMaps"/>.
/// </summary>
@ -406,6 +410,38 @@ namespace Shared
gatheredAllInfo = false;
}
// Firing rate
if (weapon.FireRate == -1)
{
string cycleTime = attributes["cycletime"]?.Value!;
if (cycleTime != null)
{
// Firing rate field exists
if (double.TryParse(cycleTime, NumberStyles.Any, CultureInfo.InvariantCulture, out double ct))
{
weapon.FireRate = 60d / ct;
}
}
else
gatheredAllInfo = false;
}
// Running speed
if (weapon.RunningSpeed == -1)
{
string runningSpeed = attributes["max player speed"]?.Value!;
if (runningSpeed != null)
{
// Running speed field exists
if (int.TryParse(runningSpeed, NumberStyles.Any, CultureInfo.InvariantCulture, out int rs))
{
weapon.RunningSpeed = rs;
}
}
else
gatheredAllInfo = false;
}
// ================================================================== //
if (gatheredAllInfo || nextPrefab == null)

View file

@ -51,6 +51,16 @@ namespace Shared.Models
/// Used for damage multipliers, since shock damage deals the same damage on every hitgroup.
/// </summary>
public DamageType DamageType { get; set; }
/// <summary>
/// Gets or sets the fire rate of this weapon (60 / cycletime => because cycletime is the amount of seconds needed for the weapon to cycle)
/// </summary>
public double FireRate { get; set; } = -1;
/// <summary>
/// Gets or sets the maximum speed a player can run at while holding this weapon, in units per second.
/// </summary>
public int RunningSpeed { get; set; } = -1;
}
public enum DamageType { Bullet, Shock }