mirror of
https://github.com/MathiasLui/CSGO-Projects.git
synced 2025-05-06 22:01:18 +00:00
Change to Version 1.3.0 & NAV area support & restructure
* Adjusted help window * Moved all settings that get saved in a file into a single window in the Edit menu * Add NAV area support and Z coordinate * Add weapon and NAV info boxes * Changed copying coordinates to include the setpos_exact command for ease of use * Settings are now saved and loaded * Add map scale factor override and X/Y offset * Removed ability to hide right click/left click circles * Add various summaries * Add OverwriteMapping class as an overwrite object for a map, that gets loaded from the settings and applied to each map when loading them * Add Associated area to map points and Z height
This commit is contained in:
parent
3d99b1f68b
commit
c2d33f1816
26 changed files with 2151 additions and 381 deletions
|
@ -11,8 +11,8 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>27.ico</ApplicationIcon>
|
||||
<FileVersion>1.2.0.0</FileVersion>
|
||||
<AssemblyVersion>1.2.0.0</AssemblyVersion>
|
||||
<FileVersion>1.3.0.0</FileVersion>
|
||||
<AssemblyVersion>1.3.0.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Properties\AssemblyInfo.cs" />
|
||||
|
@ -42,6 +42,7 @@
|
|||
<ProjectReference Include="..\..\Shared\SteamHelpers\SteamHelpers\SteamHelpers.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.3.0" />
|
||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
|
@ -51,4 +52,9 @@
|
|||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="wndSettings.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
</Project>
|
48
DamageCalculator/DamageCalculator/Globals.cs
Normal file
48
DamageCalculator/DamageCalculator/Globals.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Damage_Calculator
|
||||
{
|
||||
public static class Globals
|
||||
{
|
||||
public static Settings Settings { get; set; } = new Settings();
|
||||
|
||||
public static void LoadSettings()
|
||||
{
|
||||
// Get path
|
||||
string pathToFile = System.IO.Path.Combine(MainWindow.FilesPath, Settings.SettingsFileName);
|
||||
|
||||
if (!System.IO.File.Exists(pathToFile))
|
||||
{
|
||||
Globals.SaveSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(Settings));
|
||||
using (var fs = new System.IO.FileStream(pathToFile, System.IO.FileMode.Open))
|
||||
{
|
||||
Globals.Settings = (Settings)serializer.Deserialize(fs);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveSettings()
|
||||
{
|
||||
// Get path
|
||||
string pathToFile = System.IO.Path.Combine(MainWindow.FilesPath, Settings.SettingsFileName);
|
||||
|
||||
if (!System.IO.Directory.Exists(MainWindow.FilesPath))
|
||||
// Make sure the folder exists before attempting to save the file
|
||||
System.IO.Directory.CreateDirectory(MainWindow.FilesPath);
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(Settings));
|
||||
using (var fs = new System.IO.FileStream(pathToFile, System.IO.FileMode.Create))
|
||||
{
|
||||
serializer.Serialize(fs, Globals.Settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,23 +13,35 @@
|
|||
<StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="Map selection" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="On the top you can select one of the maps that is available. Only the maps prefixed with 'de', 'cs', 'dz' and 'ar' are loaded. You can alter which of these are shown via the 'Map Filter' menu (Maps might not correspond with what you expect, for example the map 'Safehouse' starts with 'de_' and is thus treated like a defusal map.) The maps are loaded, if they have a radar file and a corresponding text file, and could be successfully converted from DDS. You can also type when you open the combobox, to quickly find a map." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
<TextBlock FontSize="16" Text="On the top you can select one of the maps that is available. Only the maps prefixed with 'de', 'cs', 'dz' and 'ar' are loaded. You can alter which of these are shown via the 'Map Filter' section in the 'Settings' menu (Maps might not correspond with what you expect, for example the map 'Safehouse' starts with 'de_' and is thus treated like a defusal map). The maps are loaded, if they have a radar file and a corresponding text file, and could be successfully converted from DDS. You can also type when you open the combobox, to quickly find a map." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Sidebar" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="On the side you can select the desired weapon, armor and the place where the shot will hit. If you select 'Bomb' mode at the top, you can only select if kevlar is worn. Explosions will always apply to the torso, so the selection is hidden. The resulting damage to body and kevlar is shown underneath. Also the 2D-cursor position is shown while hovering over the map. This can be copied to the clipboard by pressing Ctrl+C during hover." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
<TextBlock Text="Sidebar left" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="On the left side you can select the desired weapon, armor and the place where the shot will hit. If you select 'Bomb' mode at the top, you can only select whether kevlar is worn. Explosions will always apply to the torso, so the selection is hidden. The resulting damage to body and kevlar is shown underneath." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Sidebar right" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="On the right sidebar the current weapon's stats get displayed, as well as some info for the currently hovered NAV area (The layer it's on (if multiple areas overlap) starting at the lowest with 1, the amount of layers overlapping at that point, the area ID, the place name associated with the area, the percentage of the average height of all four points between lowest and highest area and the total amount of connecting areas to that area). Also the cursor position in in-game coordinates is shown while hovering over the map. Hovering over a NAV area will also show its Z coordinate (see 'NAV areas' help section). The corresponding teleport command can be copied to the clipboard by pressing Ctrl+C during hover." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Damage calculation" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="After selecting a weapon, calculation mode and armor type, and setting the two points, the damage to both the player and the player's armor can be seen on the left, as well as distance between the points on the top right. This distance will be 3D distance if both points were set on a NAV area, 2D map distance if at least one of them is not on a NAV area." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Top right info" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="The top right corner shows the distance in metres and units/inches, that is drawn on the map by the user." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Bottom left info" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="The bottom left hand corner shows, if the loaded map has a corresponding map (BSP) and nav (NAV) file inside of the '/csgo/maps' folder. It also shows the maximum bomb damage you can get unarmored, and the bomb radius calculated from that. These infos only exist for defusal maps." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
<TextBlock Text="Map info" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="The bottom right hand corner shows, if the loaded map has a corresponding map (BSP) and nav (NAV) file inside of the '/csgo/maps' folder. It also shows the maximum bomb damage you can get unarmored, and the bomb radius calculated from that. These infos only exist for defusal maps." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="NAV areas" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="If a map has a bot NAV mesh file associated with it, the NAV areas will be used to show the current height on the ground, wherever the mouse is hovering on the map. This value is a weighted sum of the height of all four points and should be most accurate, if all points are coplanar. To see where NAV areas exist, activate them in the settings. They will be coloured from lowest to highest based on their average height. In the settings you can also give a threshold of which areas to show. When you hover over a point where you have multiple NAV areas layered on top of eachother, use the PageUp and PageDown keys to move up and down layers. In rare cases the map might have wrong X and Y coordinates and/or a wrong map scale factor written in the map's text file. In that case the NAV areas will be offset from the actual map. To temporarily fix that you can go into the settings and change the current map's coordinates' offsets and the map scale factor override, the original file will be left unchanged." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Map" FontSize="24" Foreground="#FF0093E0" />
|
||||
<TextBlock FontSize="16" Text="The map in the middle shows the general spawn areas and bomb sites defined in the text file, as well as spawn positions and directions from the map file. The middle of a spawn is bright, if it's a priority spawn, otherwise dark, hostages however are filled with a red colour. All of these can be hidden in the 'View' menu on top, 2v2 spawns can be hidden separately, while all other spawn types are treated under 'general'. With a right click you set the first point on the map, and with a left click you set the second point, or the bomb position, depending on the mode. These are used to calculate damage on range. You can zoom with your mouse wheel, pan by holding spacebar while left click dragging, and reset the zoom by clicking down the mouse wheel." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
<TextBlock FontSize="16" Text="The map in the middle shows the general spawn areas and bomb sites defined in the text file, as well as spawn positions and directions from the map file and NAV areas, if activated and available. The middle of a spawn is bright, if it's a priority spawn, otherwise dark, hostages however are filled with a red colour. All of these can be hidden in the 'Settings' menu, 2v2 spawns can be hidden separately, while all other spawn types are treated as 'general'. With a left click you set the first (target or bomb, depending on the mode) point on the map, and with a right click you set the second (player) point. These are used to calculate damage over range. You can zoom with your mouse wheel, pan by holding spacebar while left click dragging, and reset the zoom by clicking down the mouse wheel." Margin="0,5,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Damage_Calculator"
|
||||
mc:Ignorable="d"
|
||||
Title="CS:GO Damage Calculator" Height="566" Width="877" MinHeight="700" MinWidth="700"
|
||||
Title="CS:GO Damage Calculator" Height="566" Width="1030" MinHeight="700" MinWidth="1000"
|
||||
Style="{DynamicResource CustomWindowStyle}"
|
||||
WindowStartupLocation="CenterScreen" Icon="27.ico"
|
||||
WindowState="Maximized"
|
||||
|
@ -15,28 +15,8 @@
|
|||
PreviewMouseDown="Window_PreviewMouseDown">
|
||||
<Grid>
|
||||
<Menu>
|
||||
<MenuItem Header="View">
|
||||
<MenuItem x:Name="mnuShowBombSites" StaysOpenOnClick="True" Header="Show bomb sites" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowSpawnAreas" StaysOpenOnClick="True" Header="Show spawn areas" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowStandardSpawns" StaysOpenOnClick="True" Header="Show standard spawns" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShow2v2Spawns" StaysOpenOnClick="True" Header="Show 2v2 spawns" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowHostageSpawns" StaysOpenOnClick="True" Header="Show hostage spawns" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuAllowNonPrioritySpawns" StaysOpenOnClick="True" Header="Allow non-priority spawns" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowDrawnMarkers" StaysOpenOnClick="True" Header="Show drawn markers" IsCheckable="True" IsChecked="True" Checked="visibilityMenu_CheckChanged" Unchecked="visibilityMenu_CheckChanged" />
|
||||
<Separator />
|
||||
<MenuItem Header="Themes">
|
||||
<MenuItem Header="Dark" Uid="0" Click="changeTheme_Click" />
|
||||
<MenuItem Header="Flashbang" Uid="1" Click="changeTheme_Click" />
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Map Filter">
|
||||
<MenuItem x:Name="mnuShowDefusalMaps" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show defusal maps" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowHostageMaps" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show hostage maps" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowArmsRaceMaps" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show arms race maps" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowDangerZoneMaps" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show danger zone maps" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowMapsMissingBsp" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show maps with missing map file" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowMapsMissingNav" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show maps with missing NAV file" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem x:Name="mnuShowMapsMissingAin" StaysOpenOnClick="True" IsCheckable="True" IsChecked="True" Header="Show maps with missing AIN file" Checked="filterMenu_CheckChanged" Unchecked="filterMenu_CheckChanged" />
|
||||
<MenuItem Header="Edit">
|
||||
<MenuItem x:Name="mnuOpenSettings" Header="Settings..." Click="mnuOpenSettings_Click" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem x:Name="mnuAbout" Header="About..." Uid="0" Click="mnuAbout_Click" />
|
||||
|
@ -51,6 +31,7 @@
|
|||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="160" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="250" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Left" Grid.Column="1" Margin="0,0,0,5">
|
||||
<TextBlock FontWeight="Bold" Text="Mode:" />
|
||||
|
@ -72,8 +53,9 @@
|
|||
<TextBlock x:Name="textDistanceUnits" Text="0" Margin="10,0,0,0" Foreground="IndianRed" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Rectangle x:Name="rectTop" VerticalAlignment="Top" Grid.Row="1" Height="1" Fill="White" Grid.ColumnSpan="2" />
|
||||
<Rectangle x:Name="rectSide" HorizontalAlignment="Left" Width="1" Grid.Row="1" Grid.Column="1" Fill="White" />
|
||||
<Rectangle x:Name="rectTop" VerticalAlignment="Top" Grid.Row="1" Height="1" Fill="White" Grid.ColumnSpan="3" />
|
||||
<Rectangle x:Name="rectLeftSide" HorizontalAlignment="Left" Width="1" Grid.Row="1" Grid.Column="1" Fill="White" />
|
||||
<Rectangle x:Name="rectRightSide" HorizontalAlignment="Right" Width="1" Grid.Row="1" Grid.Column="1" Fill="White" />
|
||||
<StackPanel x:Name="leftStackPanel" Margin="10,20,0,0" Grid.Row="1" VerticalAlignment="Top" HorizontalAlignment="Stretch">
|
||||
<StackPanel>
|
||||
<StackPanel>
|
||||
|
@ -102,48 +84,134 @@
|
|||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<GroupBox Header="Info" VerticalAlignment="Bottom" Grid.Row="1" Margin="10,0,0,10">
|
||||
<StackPanel>
|
||||
<StackPanel>
|
||||
<CheckBox x:Name="chkHasMapFile" Content="Has map file" IsEnabled="False" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox x:Name="chkHasNavFile" Content="Has NAV file" IsEnabled="False" />
|
||||
<TextBlock x:Name="txtNavFilePacked" FontSize="10" Margin="5,0,0,0" Text="(Packed)" Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox x:Name="chkHasAinFile" Content="Has AIN file" IsEnabled="False" />
|
||||
<TextBlock x:Name="txtAinFilePacked" FontSize="10" Margin="5,0,0,0" Text="(Packed)" Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
|
||||
<TextBlock Text="Max bomb damage:" />
|
||||
<TextBlock Margin="5,0,0,0" x:Name="txtBombMaxDamage" Text="0" Foreground="IndianRed" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Bomb radius:" />
|
||||
<TextBlock Margin="5,0,0,0" x:Name="txtBombRadius" Text="0" Foreground="IndianRed" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Cursor position:" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="X:" />
|
||||
<TextBlock x:Name="txtCursorX" Text="0" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Y:" />
|
||||
<TextBlock x:Name="txtCursorY" Text="0" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<local:ZoomBorder x:Name="rightZoomBorder" Grid.Row="1" Grid.Column="1" Margin="10" ClipToBounds="True" SizeChanged="rightZoomBorder_SizeChanged">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Image x:Name="mapImage" MouseLeftButtonUp="mapImage_MouseLeftButtonUp" HorizontalAlignment="Center" VerticalAlignment="Center" MouseRightButtonUp="mapImage_MouseRightButtonUp" LayoutUpdated="mapImage_LayoutUpdated" />
|
||||
<Canvas x:Name="pointsCanvas" Width="{Binding ActualWidth, ElementName=mapImage, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=mapImage, Mode=OneWay}" />
|
||||
<Canvas x:Name="mapCanvas" Width="{Binding ActualWidth, ElementName=mapImage, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=mapImage, Mode=OneWay}">
|
||||
<Canvas.CacheMode>
|
||||
<BitmapCache RenderAtScale="8" />
|
||||
</Canvas.CacheMode>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</local:ZoomBorder>
|
||||
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="2" Margin="10,0,10,10">
|
||||
<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>
|
||||
</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>
|
||||
</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>
|
||||
</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>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Map info" Margin="0,10,0,0">
|
||||
<StackPanel>
|
||||
<StackPanel>
|
||||
<CheckBox x:Name="chkHasMapFile" Content="Has map file" IsEnabled="False" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox x:Name="chkHasNavFile" Content="Has NAV file" IsEnabled="False" />
|
||||
<TextBlock x:Name="txtNavFilePacked" FontSize="10" Margin="5,0,0,0" Text="(Packed)" Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox x:Name="chkHasAinFile" Content="Has AIN file" IsEnabled="False" />
|
||||
<TextBlock x:Name="txtAinFilePacked" FontSize="10" Margin="5,0,0,0" Text="(Packed)" Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
|
||||
<TextBlock Text="Max bomb damage:" />
|
||||
<TextBlock Margin="5,0,0,0" x:Name="txtBombMaxDamage" Text="0" Foreground="IndianRed" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Bomb radius:" />
|
||||
<TextBlock Margin="5,0,0,0" x:Name="txtBombRadius" Text="0" Foreground="IndianRed" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,10,0,0">
|
||||
<TextBlock Text="Cursor position:" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="X:" />
|
||||
<TextBlock x:Name="txtCursorX" Text="0" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Y:" />
|
||||
<TextBlock x:Name="txtCursorY" Text="0" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Z:" />
|
||||
<TextBlock x:Name="txtCursorZ" Text="0" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid x:Name="gridLoading" Background="#B2000000" Visibility="Collapsed">
|
||||
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
|
|
File diff suppressed because it is too large
Load diff
49
DamageCalculator/DamageCalculator/Settings.cs
Normal file
49
DamageCalculator/DamageCalculator/Settings.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Damage_Calculator
|
||||
{
|
||||
public class Settings : ICloneable
|
||||
{
|
||||
[XmlIgnore]
|
||||
public static readonly string SettingsFileName = "settings.xml";
|
||||
|
||||
public Settings() { /* Do nothing */ }
|
||||
|
||||
// VISUAL SETTINGS
|
||||
|
||||
public REghZyFramework.Themes.ThemesController.ThemeTypes Theme { get; set; } = REghZyFramework.Themes.ThemesController.ThemeTypes.Dark;
|
||||
public List<Shared.Models.MapCustomOverwriteMapping> MapCoordinateOffsets { get; set; } = new();
|
||||
public bool ShowBombSites { get; set; } = true;
|
||||
public bool ShowSpawnAreas { get; set; } = true;
|
||||
public bool ShowStandardSpawns { get; set; } = true;
|
||||
public bool Show2v2Spawns { get; set; } = true;
|
||||
public bool ShowHostageSpawns { get; set; } = true;
|
||||
public bool AllowNonPrioritySpawns { get; set; } = true;
|
||||
public System.Windows.Media.Color NavLowColour { get; set; } = System.Windows.Media.Color.FromArgb(255, 20, 20, 20);
|
||||
public System.Windows.Media.Color NavHighColour { get; set; } = System.Windows.Media.Color.FromArgb(140, 255, 255, 255);
|
||||
public System.Windows.Media.Color NavHoverColour { get; set; } = System.Windows.Media.Color.FromArgb(140, 255, 165, 0);
|
||||
public Shared.NavDisplayModes NavDisplayMode { get; set; } = Shared.NavDisplayModes.None;
|
||||
public double ShowNavAreasAbove { get; set; } = 0;
|
||||
public double ShowNavAreasBelow { get; set; } = 1;
|
||||
|
||||
// MAP FILTERS
|
||||
|
||||
public bool ShowDefusalMaps { get; set; } = true;
|
||||
public bool ShowHostageMaps { get; set; } = true;
|
||||
public bool ShowArmsRaceMaps { get; set; } = true;
|
||||
public bool ShowDangerZoneMaps { get; set; } = true;
|
||||
public bool ShowMapsMissingBsp { get; set; } = true;
|
||||
public bool ShowMapsMissingNav { get; set; } = true;
|
||||
public bool ShowMapsMissingAin { get; set; } = true;
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
}
|
||||
}
|
95
DamageCalculator/DamageCalculator/wndSettings.xaml
Normal file
95
DamageCalculator/DamageCalculator/wndSettings.xaml
Normal file
|
@ -0,0 +1,95 @@
|
|||
<Window x:Class="Damage_Calculator.wndSettings"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Damage_Calculator"
|
||||
xmlns:ext="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d"
|
||||
Style="{DynamicResource CustomWindowStyle}"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="Settings" Height="677" Width="496" ResizeMode="NoResize" SizeToContent="WidthAndHeight">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="10">
|
||||
<GroupBox Header="Visuals" BorderBrush="DarkCyan">
|
||||
<StackPanel>
|
||||
<GroupBox Header="Themes" BorderBrush="DarkCyan">
|
||||
<StackPanel>
|
||||
<RadioButton x:Name="radioDarkTheme" Content="Dark" Uid="0" IsChecked="True" />
|
||||
<RadioButton x:Name="radioLightTheme" Content= "Flashbang" Uid="1" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<CheckBox x:Name="mnuShowBombSites" Content="Show bomb sites" />
|
||||
<CheckBox x:Name="mnuShowSpawnAreas" Content="Show spawn areas" />
|
||||
<CheckBox x:Name="mnuShowStandardSpawns" Content="Show standard spawns" />
|
||||
<CheckBox x:Name="mnuShow2v2Spawns" Content="Show 2v2 spawns" />
|
||||
<CheckBox x:Name="mnuShowHostageSpawns" Content="Show hostage spawns" />
|
||||
<CheckBox x:Name="mnuAllowNonPrioritySpawns" Content="Allow non-priority spawns" />
|
||||
<GroupBox Header="NAV areas" Margin="0,5,0,0" BorderBrush="DarkCyan">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="NAV display mode:" />
|
||||
<ComboBox x:Name="comboNavDisplayModes" Width="200" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
||||
<StackPanel>
|
||||
<Label Content="Colour for lowest:" Height="25" VerticalAlignment="Center" />
|
||||
<Label Content="Colour for highest:" Height="25" VerticalAlignment="Center" />
|
||||
<Label Content="Colour for hovered:" Height="25" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Width="200" >
|
||||
<ext:ColorPicker x:Name="colourNavLow" DropDownBackground="#222222" HeaderBackground="#222222" HeaderForeground="White" TabBackground="#222222" />
|
||||
<ext:ColorPicker x:Name="colourNavHigh" Margin="0,5,0,0" DropDownBackground="#222222" HeaderBackground="#222222" HeaderForeground="White" TabBackground="#222222" />
|
||||
<ext:ColorPicker x:Name="colourNavHover" Margin="0,5,0,0" DropDownBackground="#222222" HeaderBackground="#222222" HeaderForeground="White" TabBackground="#222222" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
||||
<Label Content="Draw NAV areas with height..." Height="25" VerticalAlignment="Center" />
|
||||
<StackPanel>
|
||||
<Label Content="Above:" Height="25" VerticalAlignment="Center" />
|
||||
<Label Content="Below:" Height="25" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Width="200" >
|
||||
<Slider x:Name="sliderNavAbove" Margin="0,5,0,0" IsSnapToTickEnabled="True" Minimum="0" Maximum="100" ValueChanged="sliderNav_ValueChanged" />
|
||||
<Slider x:Name="sliderNavBelow" Margin="0,5,0,0" IsSnapToTickEnabled="True" Minimum="0" Maximum="100" ValueChanged="sliderNav_ValueChanged" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Width="55" >
|
||||
<Label x:Name="txtNavAbove" Content="0 %" HorizontalContentAlignment="Right" />
|
||||
<Label x:Name="txtNavBelow" Content="0 %" HorizontalContentAlignment="Right" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<Label Content="Current map coords offset:" />
|
||||
<Label Content="X:" Margin="5,0,0,0" />
|
||||
<ext:IntegerUpDown x:Name="intCurrentMapCoordsOffsetX" Width="80" Margin="5,0,0,0" Value="0" Background="#222222" Foreground="White" />
|
||||
<Label Content="Y:" Margin="5,0,0,0" />
|
||||
<ext:IntegerUpDown x:Name="intCurrentMapCoordsOffsetY" Width="80" Margin="5,0,0,0" Value="0" Background="#222222" Foreground="White" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<Label Content="Current map multiplier override" />
|
||||
<ext:SingleUpDown x:Name="intCurrentMapMultiplierOverride" Width="80" Margin="5,0,0,0" Value="0" Background="#222222" Foreground="White" />
|
||||
<Label Content="0 = off, original =" Margin="5,0,0,0" />
|
||||
<Label x:Name="txtCurrentMapMultiplier" Padding="0,5" Content="0" />
|
||||
</StackPanel>
|
||||
<GroupBox Header="Map Filter" BorderBrush="IndianRed" Margin="0,10,0,0">
|
||||
<StackPanel>
|
||||
<CheckBox x:Name="mnuShowDefusalMaps" Content="Show defusal maps" />
|
||||
<CheckBox x:Name="mnuShowHostageMaps" Content="Show hostage maps" />
|
||||
<CheckBox x:Name="mnuShowArmsRaceMaps" Content="Show arms race maps" />
|
||||
<CheckBox x:Name="mnuShowDangerZoneMaps" Content="Show danger zone maps" />
|
||||
<CheckBox x:Name="mnuShowMapsMissingBsp" Content="Show maps with missing map file" />
|
||||
<CheckBox x:Name="mnuShowMapsMissingNav" Content="Show maps with missing NAV file" />
|
||||
<CheckBox x:Name="mnuShowMapsMissingAin" Content="Show maps with missing AIN file" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="10" Height="25">
|
||||
<Button x:Name="btnSave" Content="Save" Margin="0,0,5,0" Padding="10,0" Background="Green" Click="btnSave_Click" />
|
||||
<Button x:Name="btnCancel" Content="Cancel" Padding="10,0" Click="btnCancel_Click" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Window>
|
187
DamageCalculator/DamageCalculator/wndSettings.xaml.cs
Normal file
187
DamageCalculator/DamageCalculator/wndSettings.xaml.cs
Normal file
|
@ -0,0 +1,187 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Damage_Calculator
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for wndSettings.xaml
|
||||
/// </summary>
|
||||
public partial class wndSettings : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// The settings of this Window. When creating the Window this is a copy of the current settings to be modified.
|
||||
/// </summary>
|
||||
private Settings settings;
|
||||
|
||||
/// <summary>
|
||||
/// We need this to set the map coordinate offsets for each map respectively.
|
||||
/// </summary>
|
||||
private Shared.Models.CsgoMap currentMap = null;
|
||||
|
||||
private string getCurrentMapDDSName()
|
||||
{
|
||||
return System.IO.Path.GetFileNameWithoutExtension(currentMap.MapImagePath);
|
||||
}
|
||||
|
||||
public wndSettings(Shared.Models.CsgoMap currentMap)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.currentMap = currentMap;
|
||||
this.MaxHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
|
||||
this.settings = (Settings)Globals.Settings.Clone();
|
||||
this.fillSettings();
|
||||
}
|
||||
|
||||
private void fillSettings()
|
||||
{
|
||||
// We'll do it the old school way because I have a headache
|
||||
|
||||
// Visuals
|
||||
|
||||
// Theme
|
||||
switch (this.settings.Theme)
|
||||
{
|
||||
case REghZyFramework.Themes.ThemesController.ThemeTypes.Light:
|
||||
this.radioLightTheme.IsChecked = true;
|
||||
break;
|
||||
default:
|
||||
this.radioDarkTheme.IsChecked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
var mapOverrideItem = this.settings.MapCoordinateOffsets.FirstOrDefault(map => map.DDSFileName == this.getCurrentMapDDSName());
|
||||
if (mapOverrideItem != null)
|
||||
{
|
||||
this.intCurrentMapCoordsOffsetX.Value = (int)mapOverrideItem.CoordOffset.X;
|
||||
this.intCurrentMapCoordsOffsetY.Value = (int)mapOverrideItem.CoordOffset.Y;
|
||||
this.intCurrentMapMultiplierOverride.Value = mapOverrideItem.MapScale;
|
||||
}
|
||||
this.txtCurrentMapMultiplier.Content = this.currentMap.MapSizeMultiplier;
|
||||
|
||||
this.mnuShowBombSites.IsChecked = this.settings.ShowBombSites;
|
||||
this.mnuShowSpawnAreas.IsChecked = this.settings.ShowSpawnAreas;
|
||||
this.mnuShowStandardSpawns.IsChecked = this.settings.ShowStandardSpawns;
|
||||
this.mnuShow2v2Spawns.IsChecked = this.settings.Show2v2Spawns;
|
||||
this.mnuShowHostageSpawns.IsChecked = this.settings.ShowHostageSpawns;
|
||||
this.mnuAllowNonPrioritySpawns.IsChecked = this.settings.AllowNonPrioritySpawns;
|
||||
|
||||
this.colourNavLow.SelectedColor = this.settings.NavLowColour;
|
||||
this.colourNavHigh.SelectedColor = this.settings.NavHighColour;
|
||||
this.colourNavHover.SelectedColor = this.settings.NavHoverColour;
|
||||
|
||||
foreach(string navDisplayMode in Enum.GetNames(typeof(Shared.NavDisplayModes)))
|
||||
{
|
||||
comboNavDisplayModes.Items.Add(navDisplayMode);
|
||||
if (navDisplayMode == Enum.GetName(this.settings.NavDisplayMode))
|
||||
comboNavDisplayModes.SelectedItem = navDisplayMode;
|
||||
}
|
||||
|
||||
sliderNavAbove.Value = this.settings.ShowNavAreasAbove * 100f;
|
||||
sliderNavBelow.Value = this.settings.ShowNavAreasBelow * 100f;
|
||||
|
||||
// Map filter
|
||||
this.mnuShowDefusalMaps.IsChecked = this.settings.ShowDefusalMaps;
|
||||
this.mnuShowHostageMaps.IsChecked = this.settings.ShowHostageMaps;
|
||||
this.mnuShowArmsRaceMaps.IsChecked = this.settings.ShowArmsRaceMaps;
|
||||
this.mnuShowDangerZoneMaps.IsChecked = this.settings.ShowDangerZoneMaps;
|
||||
this.mnuShowMapsMissingBsp.IsChecked = this.settings.ShowMapsMissingBsp;
|
||||
this.mnuShowMapsMissingNav.IsChecked = this.settings.ShowMapsMissingNav;
|
||||
this.mnuShowMapsMissingAin.IsChecked = this.settings.ShowMapsMissingAin;
|
||||
}
|
||||
|
||||
private void saveSettings()
|
||||
{
|
||||
// Visuals
|
||||
|
||||
// Theme
|
||||
if ((bool)this.radioLightTheme.IsChecked)
|
||||
this.settings.Theme = REghZyFramework.Themes.ThemesController.ThemeTypes.Light;
|
||||
else
|
||||
this.settings.Theme = REghZyFramework.Themes.ThemesController.ThemeTypes.Dark;
|
||||
|
||||
Point newCoords = new Point
|
||||
{
|
||||
X = this.intCurrentMapCoordsOffsetX.Value ?? 0,
|
||||
Y = this.intCurrentMapCoordsOffsetY.Value ?? 0
|
||||
};
|
||||
|
||||
var mapOffsetsItem = this.settings.MapCoordinateOffsets.FirstOrDefault(map => map.DDSFileName == this.getCurrentMapDDSName());
|
||||
if (mapOffsetsItem != null)
|
||||
{
|
||||
mapOffsetsItem.CoordOffset = newCoords;
|
||||
mapOffsetsItem.MapScale = (float)this.intCurrentMapMultiplierOverride.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.settings.MapCoordinateOffsets.Add(new Shared.Models.MapCustomOverwriteMapping { DDSFileName = getCurrentMapDDSName(), CoordOffset = newCoords, MapScale = (float)this.intCurrentMapMultiplierOverride.Value });
|
||||
}
|
||||
this.currentMap.MapOverwrite.CoordOffset = newCoords;
|
||||
this.currentMap.MapOverwrite.MapScale = (float)this.intCurrentMapMultiplierOverride.Value;
|
||||
|
||||
this.settings.ShowBombSites = (bool)this.mnuShowBombSites.IsChecked;
|
||||
this.settings.ShowSpawnAreas = (bool)this.mnuShowSpawnAreas.IsChecked;
|
||||
this.settings.ShowStandardSpawns = (bool)this.mnuShowStandardSpawns.IsChecked;
|
||||
this.settings.Show2v2Spawns = (bool)this.mnuShow2v2Spawns.IsChecked;
|
||||
this.settings.ShowHostageSpawns = (bool)this.mnuShowHostageSpawns.IsChecked;
|
||||
this.settings.AllowNonPrioritySpawns = (bool)this.mnuAllowNonPrioritySpawns.IsChecked;
|
||||
|
||||
this.settings.NavLowColour = this.colourNavLow.SelectedColor ?? Globals.Settings.NavLowColour;
|
||||
this.settings.NavHighColour = this.colourNavHigh.SelectedColor ?? Globals.Settings.NavHighColour;
|
||||
this.settings.NavHoverColour = this.colourNavHover.SelectedColor ?? Globals.Settings.NavHoverColour;
|
||||
|
||||
this.settings.NavDisplayMode = (Shared.NavDisplayModes)Enum.Parse(typeof(Shared.NavDisplayModes), comboNavDisplayModes.SelectedItem.ToString());
|
||||
|
||||
this.settings.ShowNavAreasAbove = sliderNavAbove.Value / 100f;
|
||||
this.settings.ShowNavAreasBelow = sliderNavBelow.Value / 100f;
|
||||
|
||||
// Map filter
|
||||
this.settings.ShowDefusalMaps = (bool)this.mnuShowDefusalMaps.IsChecked;
|
||||
this.settings.ShowHostageMaps = (bool)this.mnuShowHostageMaps.IsChecked;
|
||||
this.settings.ShowArmsRaceMaps = (bool)this.mnuShowArmsRaceMaps.IsChecked;
|
||||
this.settings.ShowDangerZoneMaps = (bool)this.mnuShowDangerZoneMaps.IsChecked;
|
||||
this.settings.ShowMapsMissingBsp = (bool)this.mnuShowMapsMissingBsp.IsChecked;
|
||||
this.settings.ShowMapsMissingNav = (bool)this.mnuShowMapsMissingNav.IsChecked;
|
||||
this.settings.ShowMapsMissingAin = (bool)this.mnuShowMapsMissingAin.IsChecked;
|
||||
|
||||
Globals.Settings = this.settings;
|
||||
Globals.SaveSettings();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void btnSave_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.DialogResult = true; // Tell main window to reload with new settings
|
||||
this.saveSettings();
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void sliderNav_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (!this.IsInitialized)
|
||||
return;
|
||||
|
||||
if(sender == sliderNavBelow && sliderNavAbove.Value > sliderNavBelow.Value)
|
||||
sliderNavAbove.Value = sliderNavBelow.Value;
|
||||
else if (sender == sliderNavAbove && sliderNavBelow.Value < sliderNavAbove.Value)
|
||||
sliderNavBelow.Value = sliderNavAbove.Value;
|
||||
|
||||
txtNavAbove.Content = $"{this.sliderNavAbove.Value} %";
|
||||
txtNavBelow.Content = $"{this.sliderNavBelow.Value} %";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -422,7 +422,7 @@ namespace Shared
|
|||
/// </summary>
|
||||
/// <param name="bspFilePath">The absolute path to the BSP file.</param>
|
||||
/// <returns>A tuple containing whether nav or ain files were found, in that order.</returns>
|
||||
public (bool, bool) ReadIfPackedNavFilesInBsp(string bspFilePath)
|
||||
public (bool, bool, NavMesh) ReadIfPackedNavFilesInBsp(string bspFilePath)
|
||||
{
|
||||
bool navFound = false;
|
||||
bool ainFound = false;
|
||||
|
@ -446,26 +446,30 @@ namespace Shared
|
|||
}
|
||||
|
||||
if (readZipBytes == null)
|
||||
return (false, false);
|
||||
return (false, false, null!);
|
||||
|
||||
using (var stream = new MemoryStream(readZipBytes))
|
||||
{
|
||||
using(var zip = new ZipArchive(stream, ZipArchiveMode.Read))
|
||||
{
|
||||
foreach(var entry in zip.Entries)
|
||||
NavMesh? nav = null;
|
||||
foreach (var entry in zip.Entries)
|
||||
{
|
||||
if (entry.FullName.EndsWith(".nav"))
|
||||
{
|
||||
// Found a packed NAV file
|
||||
navFound = true;
|
||||
nav = NavFile.Parse(entry.Open());
|
||||
}
|
||||
if(entry.FullName.EndsWith(".ain"))
|
||||
// Found a packed AIN file
|
||||
ainFound = true;
|
||||
|
||||
if (navFound && ainFound)
|
||||
// If both already found, return prematurely
|
||||
return (true, true);
|
||||
return (true, true, nav!);
|
||||
}
|
||||
return (navFound, ainFound);
|
||||
return (navFound, ainFound, nav!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,5 +41,10 @@ namespace Shared
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float Map(float s, float a1, float a2, float b1, float b2)
|
||||
{
|
||||
return b1 + (s - a1) * (b2 - b1) / (a2 - a1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,8 @@ namespace Shared.Models
|
|||
public float BombBY { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The bomb damage in this map. By default it's 500.
|
||||
/// The bomb damage in this map.
|
||||
/// If not specified in a map, the default value is used, which is 500 units.
|
||||
/// </summary>
|
||||
public float BombDamage { get; set; } = 500;
|
||||
|
||||
|
@ -140,16 +141,39 @@ namespace Shared.Models
|
|||
/// </summary>
|
||||
public string? EntityList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Amount of CT spawns on this map, that have priority over other spawns.
|
||||
/// (For example getting filled first when playing competitive)
|
||||
/// </summary>
|
||||
public int AmountPrioritySpawnsCT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Amount of total CT spawns on this map.
|
||||
/// </summary>
|
||||
public int AmountSpawnsCT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Amount of T spawns on this map, that have priority over other spawns.
|
||||
/// (For example getting filled first when playing competitive)
|
||||
/// </summary>
|
||||
public int AmountPrioritySpawnsT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Amount of total T spawns on this map.
|
||||
/// </summary>
|
||||
public int AmountSpawnsT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Amount of possible hostages on this map.
|
||||
/// </summary>
|
||||
public int AmountHostages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X and Y offset of the coordinates relative to the map's given coordinates as well as a new map size multiplier.
|
||||
/// This is used to correct for inaccurate coordinates and scale in the map's associated text file.
|
||||
/// </summary>
|
||||
public MapCustomOverwriteMapping MapOverwrite { get; set; } = new();
|
||||
|
||||
public bool HasPrioritySpawnsT
|
||||
{
|
||||
get
|
||||
|
@ -167,5 +191,7 @@ namespace Shared.Models
|
|||
}
|
||||
|
||||
public List<PlayerSpawn> SpawnPoints { get; set; } = new List<PlayerSpawn>();
|
||||
|
||||
public NavMesh? NavMesh { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class MapCustomOverwriteMapping
|
||||
{
|
||||
public string? DDSFileName { get; set; } = string.Empty;
|
||||
public System.Windows.Point CoordOffset { get; set; }
|
||||
public float MapScale { get; set; } = 0;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,10 @@ namespace Shared.Models
|
|||
|
||||
public double PercentageY { get; set; }
|
||||
|
||||
public double Z { get; set; }
|
||||
|
||||
public int AssociatedAreaID { get; set; } = -1;
|
||||
|
||||
public double PercentageScale { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
37
Shared/SteamHelpers/SteamHelpers/Models/NavApproachSpot.cs
Normal file
37
Shared/SteamHelpers/SteamHelpers/Models/NavApproachSpot.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavApproachSpot
|
||||
{
|
||||
public NavApproachSpot() { /* Do nothing */ }
|
||||
|
||||
public NavApproachSpot(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.ApproachHereId = reader.ReadUInt32();
|
||||
this.ApproachPrevId = reader.ReadUInt32();
|
||||
this.ApproachType = reader.ReadByte();
|
||||
this.ApproachNextId = reader.ReadUInt32();
|
||||
this.ApproachHow = reader.ReadByte();
|
||||
}
|
||||
|
||||
public uint ApproachHereId { get; set; }
|
||||
|
||||
public uint ApproachPrevId { get; set; }
|
||||
|
||||
public byte ApproachType { get; set; }
|
||||
|
||||
public uint ApproachNextId { get; set; }
|
||||
|
||||
public byte ApproachHow { get; set; }
|
||||
}
|
||||
}
|
218
Shared/SteamHelpers/SteamHelpers/Models/NavArea.cs
Normal file
218
Shared/SteamHelpers/SteamHelpers/Models/NavArea.cs
Normal file
|
@ -0,0 +1,218 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavArea
|
||||
{
|
||||
public NavArea() { /* Do nothing */ }
|
||||
|
||||
public NavArea(uint navVersion, BinaryReader reader)
|
||||
{
|
||||
this.Parse(navVersion, reader);
|
||||
}
|
||||
|
||||
public void Parse(uint navVersion, BinaryReader reader)
|
||||
{
|
||||
this.ID = reader.ReadUInt32();
|
||||
|
||||
if (navVersion <= 8)
|
||||
this.AttributeBitField = BitConverter.GetBytes(reader.ReadByte());
|
||||
else if (navVersion <= 12)
|
||||
this.AttributeBitField = BitConverter.GetBytes(reader.ReadUInt16());
|
||||
else if (navVersion >= 13)
|
||||
this.AttributeBitField = BitConverter.GetBytes(reader.ReadUInt32());
|
||||
|
||||
this.NorthWestCorner = new Vector3(reader);
|
||||
this.SouthEastCorner = new Vector3(reader);
|
||||
this.NorthEastZ = reader.ReadSingle();
|
||||
this.SouthWestZ = reader.ReadSingle();
|
||||
|
||||
for(int i = 0; i < this.ConnectionData!.Length; i++)
|
||||
{
|
||||
this.ConnectionData[i] = new NavConnectionData(reader);
|
||||
}
|
||||
|
||||
// === HIDING SPOTS === //
|
||||
|
||||
this.HidingSpotCount = reader.ReadByte();
|
||||
|
||||
this.HidingSpots = new NavHidingSpot[this.HidingSpotCount];
|
||||
for(int i = 0; i < this.HidingSpots.Length; i++)
|
||||
{
|
||||
this.HidingSpots[i] = new NavHidingSpot(navVersion, reader);
|
||||
}
|
||||
|
||||
// === APPROACH SPOTS === //
|
||||
|
||||
if (navVersion < 15)
|
||||
{
|
||||
this.ApproachSpotCount = reader.ReadByte();
|
||||
|
||||
this.ApproachSpots = new NavApproachSpot[this.ApproachSpotCount];
|
||||
for (int i = 0; i < this.ApproachSpots.Length; i++)
|
||||
{
|
||||
this.ApproachSpots[i] = new NavApproachSpot(reader);
|
||||
}
|
||||
}
|
||||
|
||||
// === ENCOUNTER PATHS === //
|
||||
|
||||
this.EncounterPathCount = reader.ReadUInt32();
|
||||
|
||||
this.EncounterPaths = new NavEncounterPath[this.EncounterPathCount];
|
||||
for (int i = 0; i < this.EncounterPaths.Length; i++)
|
||||
{
|
||||
this.EncounterPaths[i] = new NavEncounterPath(reader);
|
||||
}
|
||||
|
||||
this.PlaceID = reader.ReadUInt16();
|
||||
|
||||
for(int i = 0; i < this.LadderIDSequence!.Length; i++)
|
||||
{
|
||||
this.LadderIDSequence[i] = new NavLadderIDSequence(reader);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.EarliestOccupyTimes!.Length; i++)
|
||||
{
|
||||
this.EarliestOccupyTimes[i] = reader.ReadSingle();
|
||||
}
|
||||
|
||||
if (navVersion >= 16)
|
||||
{
|
||||
for (int i = 0; i < this.LightIntensity!.Length; i++)
|
||||
{
|
||||
this.LightIntensity[i] = reader.ReadSingle();
|
||||
}
|
||||
}
|
||||
|
||||
// Called "Visible areas" in Valve's code
|
||||
this.AreaBindCount = reader.ReadUInt32();
|
||||
|
||||
this.AreaBindSequence = new NavAreaBind[this.AreaBindCount];
|
||||
for(int i = 0; i < this.AreaBindSequence.Length; i++)
|
||||
{
|
||||
this.AreaBindSequence[i] = new NavAreaBind(reader);
|
||||
}
|
||||
|
||||
this.InheritVisibilityFromAreaID = reader.ReadUInt32();
|
||||
|
||||
//this.CustomData = new IntPtr(BitConverter.ToInt64(reader.ReadBytes(IntPtr.Size)));
|
||||
byte garbageCount = reader.ReadByte();
|
||||
|
||||
reader.BaseStream.Position += garbageCount * 14;
|
||||
}
|
||||
|
||||
public uint ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version <= 8: unsigned char (1 byte)
|
||||
/// Version <= 12: unsigned short (2 bytes)
|
||||
/// Version >= 8: unsigned int (4 bytes)
|
||||
/// </summary>
|
||||
public byte[]? AttributeBitField { get; set; } = new byte[4];
|
||||
|
||||
public Vector3? MedianPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
float newX = (this.ActualNorthWestCorner!.X + this.ActualNorthEastCorner!.X + this.ActualSouthEastCorner!.X + this.ActualSouthWestCorner!.X) / 4;
|
||||
float newY = (this.ActualNorthWestCorner!.Y + this.ActualNorthEastCorner!.Y + this.ActualSouthEastCorner!.Y + this.ActualSouthWestCorner!.Y) / 4;
|
||||
float newZ = (this.ActualNorthWestCorner!.Z + this.ActualNorthEastCorner!.Z + this.ActualSouthEastCorner!.Z + this.ActualSouthWestCorner!.Z) / 4;
|
||||
return new Vector3 { X = newX, Y = newY, Z = newZ };
|
||||
}
|
||||
}
|
||||
|
||||
// I believe the corners are actually treated as if North was on the left of the map, I just changed the namings here to work with them more accurately
|
||||
public Vector3? ActualNorthWestCorner { get => this.NorthEastCorner; }
|
||||
public Vector3? ActualNorthEastCorner { get => this.SouthEastCorner; }
|
||||
public Vector3? ActualSouthEastCorner { get => this.SouthWestCorner; }
|
||||
public Vector3? ActualSouthWestCorner { get => this.NorthWestCorner; }
|
||||
|
||||
/// <summary>
|
||||
/// Actually South West?
|
||||
/// </summary>
|
||||
public Vector3? NorthWestCorner { get; set; } = Vector3.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Actually North East?
|
||||
/// </summary>
|
||||
public Vector3? SouthEastCorner { get; set; } = Vector3.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Actually North West?
|
||||
/// </summary>
|
||||
public Vector3? NorthEastCorner
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector3
|
||||
{
|
||||
X = this.NorthWestCorner?.X ?? 0,
|
||||
Y = this.SouthEastCorner?.Y ?? 0,
|
||||
Z = this.SouthWestZ
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually South East?
|
||||
/// </summary>
|
||||
public Vector3? SouthWestCorner
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector3
|
||||
{
|
||||
X = this.SouthEastCorner?.X ?? 0,
|
||||
Y = this.NorthWestCorner?.Y ?? 0,
|
||||
Z = this.NorthEastZ
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public float NorthEastZ { get; set; }
|
||||
|
||||
public float SouthWestZ { get; set; }
|
||||
|
||||
public NavConnectionData[]? ConnectionData { get; set; } = new NavConnectionData[4];
|
||||
|
||||
public byte HidingSpotCount { get; set; }
|
||||
|
||||
public NavHidingSpot[]? HidingSpots { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version < 15
|
||||
/// </summary>
|
||||
public byte ApproachSpotCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version < 15
|
||||
/// </summary>
|
||||
public NavApproachSpot[]? ApproachSpots { get; set; }
|
||||
|
||||
public uint EncounterPathCount { get; set; }
|
||||
|
||||
public NavEncounterPath[]? EncounterPaths { get; set; }
|
||||
|
||||
public ushort PlaceID { get; set; }
|
||||
|
||||
public NavLadderIDSequence[]? LadderIDSequence { get; set; } = new NavLadderIDSequence[2];
|
||||
|
||||
public float[]? EarliestOccupyTimes { get; set; } = new float[2];
|
||||
|
||||
public float[]? LightIntensity { get; set; } = new float[4];
|
||||
|
||||
public uint AreaBindCount { get; set; }
|
||||
|
||||
public NavAreaBind[]? AreaBindSequence { get; set; }
|
||||
|
||||
public uint InheritVisibilityFromAreaID { get; set; }
|
||||
|
||||
public IntPtr CustomData { get; set; }
|
||||
}
|
||||
}
|
28
Shared/SteamHelpers/SteamHelpers/Models/NavAreaBind.cs
Normal file
28
Shared/SteamHelpers/SteamHelpers/Models/NavAreaBind.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavAreaBind
|
||||
{
|
||||
public NavAreaBind() { /* Do nothing */ }
|
||||
|
||||
public NavAreaBind(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.TargetAreaID = reader.ReadUInt32();
|
||||
this.AttributeBitField = reader.ReadByte();
|
||||
}
|
||||
|
||||
public uint TargetAreaID { get; set; }
|
||||
|
||||
public byte AttributeBitField { get; set; }
|
||||
}
|
||||
}
|
31
Shared/SteamHelpers/SteamHelpers/Models/NavConnectionData.cs
Normal file
31
Shared/SteamHelpers/SteamHelpers/Models/NavConnectionData.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavConnectionData
|
||||
{
|
||||
public NavConnectionData(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Count = reader.ReadUInt32();
|
||||
|
||||
this.AreaIDs = new uint[this.Count];
|
||||
for(int i = 0; i < this.AreaIDs.Length; i++)
|
||||
{
|
||||
this.AreaIDs[i] = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
||||
public uint Count { get; set; }
|
||||
|
||||
public uint[]? AreaIDs { get; set; }
|
||||
}
|
||||
}
|
47
Shared/SteamHelpers/SteamHelpers/Models/NavEncounterPath.cs
Normal file
47
Shared/SteamHelpers/SteamHelpers/Models/NavEncounterPath.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavEncounterPath
|
||||
{
|
||||
public NavEncounterPath() { /* Do nothing */ }
|
||||
|
||||
public NavEncounterPath(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.EntryAreaID = reader.ReadUInt32();
|
||||
this.EntryDirection = reader.ReadByte();
|
||||
this.DestAreaID = reader.ReadUInt32();
|
||||
this.DestDirection = reader.ReadByte();
|
||||
|
||||
this.EncounterSpotCount = reader.ReadByte();
|
||||
|
||||
this.EncounterSpots = new NavEncounterSpot[this.EncounterSpotCount];
|
||||
for(int i = 0; i < this.EncounterSpots.Length; i++)
|
||||
{
|
||||
this.EncounterSpots[i] = new NavEncounterSpot(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public uint EntryAreaID { get; set; }
|
||||
|
||||
public byte EntryDirection { get; set; }
|
||||
|
||||
public uint DestAreaID { get; set; }
|
||||
|
||||
public byte DestDirection { get; set; }
|
||||
|
||||
|
||||
public byte EncounterSpotCount { get; set; }
|
||||
|
||||
public NavEncounterSpot[]? EncounterSpots { get; set; }
|
||||
}
|
||||
}
|
28
Shared/SteamHelpers/SteamHelpers/Models/NavEncounterSpot.cs
Normal file
28
Shared/SteamHelpers/SteamHelpers/Models/NavEncounterSpot.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavEncounterSpot
|
||||
{
|
||||
public NavEncounterSpot() { /* Do nothing */ }
|
||||
|
||||
public NavEncounterSpot(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.AreaID = reader.ReadUInt32();
|
||||
this.ParametricDistance = reader.ReadByte();
|
||||
}
|
||||
|
||||
public uint AreaID { get; set; }
|
||||
|
||||
public byte ParametricDistance { get; set; }
|
||||
}
|
||||
}
|
53
Shared/SteamHelpers/SteamHelpers/Models/NavHeader.cs
Normal file
53
Shared/SteamHelpers/SteamHelpers/Models/NavHeader.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavHeader
|
||||
{
|
||||
public uint MagicNumber { get; set; }
|
||||
|
||||
public uint Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version >= 10
|
||||
/// </summary>
|
||||
public uint SubVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version >= 4
|
||||
/// </summary>
|
||||
public uint SaveBspSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version >= 14
|
||||
/// </summary>
|
||||
public byte IsAnalyzed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version >= 5
|
||||
/// </summary>
|
||||
public ushort PlacesCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version >= 5
|
||||
/// </summary>
|
||||
public string[]? PlacesNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version > 11
|
||||
/// </summary>
|
||||
public byte HasUnnamedAreas { get; set; }
|
||||
|
||||
public uint AreaCount { get; set; }
|
||||
|
||||
public NavArea[]? NavAreas { get; set; }
|
||||
|
||||
public uint LadderCount { get; set; }
|
||||
|
||||
public NavLadder[]? Ladders { get; set; }
|
||||
}
|
||||
}
|
45
Shared/SteamHelpers/SteamHelpers/Models/NavHidingSpot.cs
Normal file
45
Shared/SteamHelpers/SteamHelpers/Models/NavHidingSpot.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
[Flags]
|
||||
public enum HidingSpotAttribute
|
||||
{
|
||||
IN_COVER = 0x01, // In a corner with good hard cover nearby
|
||||
GOOD_SNIPER_SPOT = 0x02, // Had at least one decent sniping corridor
|
||||
IDEAL_SNIPER_SPOT = 0x04, // Can see either very far, or a large area, or both
|
||||
EXPOSED = 0x08 // Spot in the open, usually on a ledge or cliff
|
||||
}
|
||||
|
||||
public class NavHidingSpot
|
||||
{
|
||||
public NavHidingSpot() { /* Do nothing */ }
|
||||
|
||||
public NavHidingSpot(uint navVersion, System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(navVersion, reader);
|
||||
}
|
||||
|
||||
public void Parse(uint navVersion, System.IO.BinaryReader reader)
|
||||
{
|
||||
if(navVersion >= 2)
|
||||
this.ID = reader.ReadUInt32();
|
||||
|
||||
if (navVersion >= 1)
|
||||
this.Position = new Vector3(reader);
|
||||
|
||||
if (navVersion >= 2)
|
||||
this.Attributes = reader.ReadByte();
|
||||
}
|
||||
|
||||
public uint ID { get; set; }
|
||||
|
||||
public Vector3? Position { get; set; }
|
||||
|
||||
public byte Attributes { get; set; }
|
||||
}
|
||||
}
|
56
Shared/SteamHelpers/SteamHelpers/Models/NavLadder.cs
Normal file
56
Shared/SteamHelpers/SteamHelpers/Models/NavLadder.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavLadder
|
||||
{
|
||||
public NavLadder() { /* Do nothing */ }
|
||||
|
||||
public NavLadder(BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(BinaryReader reader)
|
||||
{
|
||||
this.ID = reader.ReadUInt32();
|
||||
this.Width = reader.ReadSingle();
|
||||
this.Length = reader.ReadSingle();
|
||||
this.Top = new Vector3(reader);
|
||||
this.Bottom = new Vector3(reader);
|
||||
this.Direction = reader.ReadInt32();
|
||||
this.TopForwardAreaID = reader.ReadUInt32();
|
||||
this.TopLeftAreaID = reader.ReadUInt32();
|
||||
this.TopRightAreaID = reader.ReadUInt32();
|
||||
this.TopBehindAreaID = reader.ReadUInt32();
|
||||
this.BottomAreaID = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
public uint ID { get; set; }
|
||||
|
||||
public float Width { get; set; }
|
||||
|
||||
public float Length { get; set; }
|
||||
|
||||
public Vector3 Top { get; set; }
|
||||
|
||||
public Vector3 Bottom { get; set; }
|
||||
|
||||
public int Direction { get; set; }
|
||||
|
||||
public uint TopForwardAreaID { get; set; }
|
||||
|
||||
public uint TopLeftAreaID { get; set; }
|
||||
|
||||
public uint TopRightAreaID { get; set; }
|
||||
|
||||
public uint TopBehindAreaID { get; set; }
|
||||
|
||||
public uint BottomAreaID { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavLadderIDSequence
|
||||
{
|
||||
public NavLadderIDSequence() { /* Do nothing */ }
|
||||
|
||||
public NavLadderIDSequence(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.LadderCount = reader.ReadUInt32();
|
||||
|
||||
this.LadderIDs = new uint[this.LadderCount];
|
||||
for(int i = 0; i < this.LadderIDs.Length; i++)
|
||||
{
|
||||
this.LadderIDs[i] = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
||||
public uint LadderCount { get; set; }
|
||||
|
||||
public uint[]? LadderIDs { get; set; }
|
||||
}
|
||||
}
|
17
Shared/SteamHelpers/SteamHelpers/Models/NavMesh.cs
Normal file
17
Shared/SteamHelpers/SteamHelpers/Models/NavMesh.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shared.Models
|
||||
{
|
||||
public class NavMesh
|
||||
{
|
||||
public NavHeader? Header { get; set; } = new NavHeader();
|
||||
|
||||
public float? MinZ { get; set; }
|
||||
|
||||
public float? MaxZ { get; set; }
|
||||
}
|
||||
}
|
|
@ -8,12 +8,26 @@ namespace Shared.Models
|
|||
{
|
||||
public class Vector3
|
||||
{
|
||||
public Vector3() { /* Do nothing */ }
|
||||
|
||||
public Vector3(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.Parse(reader);
|
||||
}
|
||||
|
||||
public void Parse(System.IO.BinaryReader reader)
|
||||
{
|
||||
this.X = reader.ReadSingle();
|
||||
this.Y = reader.ReadSingle();
|
||||
this.Z = reader.ReadSingle();
|
||||
}
|
||||
|
||||
public float X { get; set; }
|
||||
|
||||
public float Y { get; set; }
|
||||
|
||||
public float Z { get; set; }
|
||||
|
||||
public static Vector3 Empty = new Vector3 { X = 0, Y = 0, Z = 0 };
|
||||
public static Vector3 Zero = new Vector3 { X = 0, Y = 0, Z = 0 };
|
||||
}
|
||||
}
|
||||
|
|
107
Shared/SteamHelpers/SteamHelpers/NavFile.cs
Normal file
107
Shared/SteamHelpers/SteamHelpers/NavFile.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Shared.Models;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
public enum NavDisplayModes { None, Wireframe, Filled }
|
||||
|
||||
public static class NavFile
|
||||
{
|
||||
public static NavMesh? Parse(byte[] navFile)
|
||||
{
|
||||
return NavFile.Parse(new MemoryStream(navFile));
|
||||
}
|
||||
|
||||
public static NavMesh? Parse(Stream stream)
|
||||
{
|
||||
NavMesh mesh = new NavMesh();
|
||||
|
||||
// We do this because ZIP file streams are not seekable
|
||||
using var memStream = new MemoryStream();
|
||||
stream.CopyTo(memStream);
|
||||
stream.Close();
|
||||
|
||||
using var reader = new BinaryReader(memStream);
|
||||
reader.BaseStream.Position = 0;
|
||||
|
||||
// Header is created when creating the nav mesh
|
||||
mesh.Header!.MagicNumber = reader.ReadUInt32();
|
||||
|
||||
if (mesh.Header.MagicNumber != 0xFEEDFACE)
|
||||
// Not a NAV file
|
||||
return null;
|
||||
|
||||
uint version = mesh.Header.Version = reader.ReadUInt32();
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"File is NAV file with version {version}");
|
||||
|
||||
if (version >= 10)
|
||||
mesh.Header.SubVersion = reader.ReadUInt32();
|
||||
|
||||
if(version >= 4)
|
||||
mesh.Header.SaveBspSize = reader.ReadUInt32();
|
||||
|
||||
if (version >= 14)
|
||||
mesh.Header.IsAnalyzed = reader.ReadByte();
|
||||
|
||||
if(version >= 5)
|
||||
{
|
||||
// Callouts ("Places")
|
||||
mesh.Header.PlacesCount = reader.ReadUInt16();
|
||||
|
||||
mesh.Header.PlacesNames = new string[mesh.Header.PlacesCount];
|
||||
for (int i = 0; i < mesh.Header.PlacesNames.Length; i++)
|
||||
{
|
||||
ushort len = reader.ReadUInt16();
|
||||
|
||||
mesh.Header.PlacesNames[i] = new(reader.ReadChars(len)[..^1]);
|
||||
}
|
||||
|
||||
if(version > 11)
|
||||
{
|
||||
mesh.Header.HasUnnamedAreas = reader.ReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
// PreLoadAreas() used here? What does it do? there is no size visible (that's what she said)
|
||||
|
||||
mesh.Header.AreaCount = reader.ReadUInt32();
|
||||
|
||||
mesh.Header.NavAreas = new NavArea[mesh.Header.AreaCount];
|
||||
for(int i = 0; i < mesh.Header.NavAreas.Length; i++)
|
||||
{
|
||||
mesh.Header.NavAreas[i] = new NavArea(version, reader);
|
||||
Vector3? median = mesh.Header.NavAreas[i].MedianPosition;
|
||||
|
||||
// Update max and min z for mapping if applying here
|
||||
if (mesh.MinZ == null || median!.Z < mesh.MinZ)
|
||||
{
|
||||
mesh.MinZ = median!.Z;
|
||||
}
|
||||
|
||||
if (mesh.MaxZ == null || median!.Z > mesh.MaxZ)
|
||||
{
|
||||
mesh.MaxZ = median!.Z;
|
||||
}
|
||||
}
|
||||
|
||||
if(version >= 6)
|
||||
{
|
||||
mesh.Header.LadderCount = reader.ReadUInt32();
|
||||
|
||||
mesh.Header.Ladders = new NavLadder[mesh.Header.LadderCount];
|
||||
for (int i = 0; i < mesh.Header.Ladders.Length; i++)
|
||||
{
|
||||
mesh.Header.Ladders[i] = new NavLadder(reader);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue