diff --git a/StarterNG.sln b/StarterNG.sln index 7831d20..4165ee9 100644 --- a/StarterNG.sln +++ b/StarterNG.sln @@ -1,16 +1,28 @@  Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.1.11312.151 d18.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StarterNG", "StarterNG\StarterNG.csproj", "{D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|x64.ActiveCfg = Debug|x64 + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|x64.Build.0 = Debug|x64 {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|Any CPU.Build.0 = Release|Any CPU + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|x64.ActiveCfg = Release|x64 + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/StarterNG.sln.DotSettings.user b/StarterNG.sln.DotSettings.user index daa1893..6827f48 100644 --- a/StarterNG.sln.DotSettings.user +++ b/StarterNG.sln.DotSettings.user @@ -1,9 +1,15 @@  + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded - ForceIncluded \ No newline at end of file + ForceIncluded + E:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\amd64\MSBuild.exe + 1179648 \ No newline at end of file diff --git a/StarterNG/Assets/Logo/splash.png b/StarterNG/Assets/Logo/splash.png new file mode 100644 index 0000000..9b9fb57 Binary files /dev/null and b/StarterNG/Assets/Logo/splash.png differ diff --git a/StarterNG/Classes/Scenery.cs b/StarterNG/Classes/Scenery.cs new file mode 100644 index 0000000..dcb042d --- /dev/null +++ b/StarterNG/Classes/Scenery.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace StarterNG.Classes; + +public class Scenery +{ + public List Lines; + public List Trainsets; + public string Group; + public string Path; + public Scenery(string path) + { + this.Path = path; + Trainsets = new List(); + if (!File.Exists(path)) + throw new FileNotFoundException(path); + var encoding = Encoding.GetEncoding(1250); // Windows-1250 + string content = File.ReadAllText(path, encoding); + + // property scanning + var match = Regex.Match( + content, + @"^//\$l\s*([^\r\n]*)", + RegexOptions.Multiline + ); + this.Group = match.Success ? match.Groups[1].Value : null; + + + // parsing trainsets + List trainsetEntries = new List(); + Regex regex = new Regex( + @"trainset\b[\s\S]*?\bendtrainset\b", + RegexOptions.IgnoreCase + ); + int idx = 0; + content = regex.Replace(content, match => + { + trainsetEntries.Add(match.Value); + return $"{{{{{idx++}}}}}"; + }); + + foreach (string trainsetEntry in trainsetEntries) + { + Trainsets.Add(new Trainset(trainsetEntry)); + } + } +} \ No newline at end of file diff --git a/StarterNG/Classes/Trainset.cs b/StarterNG/Classes/Trainset.cs new file mode 100644 index 0000000..9679db9 --- /dev/null +++ b/StarterNG/Classes/Trainset.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using System.Text.RegularExpressions; + +namespace StarterNG.Classes; + +public enum eDriverType +{ + Headdriver, + Reardriver, + Passanger, + Nobody +} + +public class Trainset +{ + public string Name; + public string Track; + public float Offset; + public float Velocity; + public List Vehicles; + public Trainset(string trainsetEntry) + { + + Vehicles = new List(); + + List tokens = Regex + .Matches(trainsetEntry, @"\r\n|\n|[^\s]+") + .Select(m => m.Value) + .ToList(); + + for (int i = 0; i < tokens.Count; i++) + { + // handle comments + if (tokens[i].StartsWith("//")) + { + while (tokens[i] != "\n" && tokens.Count < i) i++; + } + + + // trainset properties + if (tokens[i] == "trainset") + { + i++; + this.Name = tokens[i++]; + this.Track = tokens[i++]; + this.Offset = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + this.Velocity = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + continue; + } + + // skip entire assignments block + if (tokens[i] == "assignments") + { + while (tokens[i] != "endassignment") i++; + } + + // load vehicles + if (tokens[i] == "node") + { + i++; // node keyword + Dynamic nodeDynamic = new Dynamic(); + nodeDynamic.RangeMax = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + nodeDynamic.RangeMin = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + nodeDynamic.Name = tokens[i++]; + i++; // dynamic keyword + nodeDynamic.DataFolder = tokens[i++]; + nodeDynamic.SkinFile = tokens[i++]; + nodeDynamic.MmdFile = tokens[i++]; + i++; // skip offset + string driverType = tokens[i++]; + switch (driverType) + { + case "headdriver": + nodeDynamic.DriverType = eDriverType.Headdriver; + break; + case "reardriver": + nodeDynamic.DriverType = eDriverType.Reardriver; + break; + case "passanger": + nodeDynamic.DriverType = eDriverType.Passanger; + break; + default: + nodeDynamic.DriverType = eDriverType.Nobody; + break; + } + + nodeDynamic.couplingData = (byte)int.Parse(tokens[i++].Split('.')[0]); + + nodeDynamic.Tail = ""; + while (tokens[i] != "enddynamic") + { + nodeDynamic.Tail += " " + tokens[i]; + i++; + } + + Vehicles.Add(nodeDynamic); + } + } + } + + public string GetTrainsetEntry() + { + string entry = ""; + + entry += "trainset "; + entry += this.Name + " "; + entry += this.Track + " "; + entry += this.Offset + " "; + entry += this.Velocity + " "; + entry += "\n"; + foreach (Dynamic vehicle in Vehicles) + { + string driverType = ""; + switch (vehicle.DriverType) + { + case eDriverType.Headdriver: + driverType = "headdriver"; + break; + case eDriverType.Reardriver: + driverType = "reardriver"; + break; + case eDriverType.Passanger: + driverType = "passanger"; + break; + default: + driverType = "nobody"; + break; + } + + entry += + $"node {vehicle.RangeMax} {vehicle.RangeMin} {vehicle.Name} dynamic {vehicle.DataFolder} {vehicle.SkinFile} {vehicle.MmdFile} {driverType} {vehicle.couplingData} {vehicle.Tail}\n"; + } + + + return entry; + } +} + +public class Dynamic +{ + public float RangeMax; + public float RangeMin; + public string Name; + public string DataFolder; + public string SkinFile; + public string MmdFile; + public string PathName; + public float Offset; + public eDriverType DriverType; + public byte couplingData; + public string Tail; +} \ No newline at end of file diff --git a/StarterNG/MainWindow.axaml b/StarterNG/MainWindow.axaml index 3cb8cc0..03ef0cc 100644 --- a/StarterNG/MainWindow.axaml +++ b/StarterNG/MainWindow.axaml @@ -8,7 +8,7 @@ xmlns:svg="clr-namespace:Avalonia.Svg;assembly=Avalonia.Svg" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:StarterNG.Views" BackgroundStyle="Bubble" - Title="MaSzyna - Symulator pojazdów szynowych" Height="600" Width="800"> + Title="MaSzyna - Symulator pojazdów szynowych" Height="800" Width="1000"> diff --git a/StarterNG/MainWindow.axaml.cs b/StarterNG/MainWindow.axaml.cs index d54f5f1..f281283 100644 --- a/StarterNG/MainWindow.axaml.cs +++ b/StarterNG/MainWindow.axaml.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.Text; using Avalonia.Controls; using Avalonia.Interactivity; using SukiUI.Controls; @@ -8,6 +9,7 @@ public partial class MainWindow : SukiWindow { public MainWindow() { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); InitializeComponent(); } private void linkClick(object? sender, RoutedEventArgs e) diff --git a/StarterNG/Properties/launchSettings.json b/StarterNG/Properties/launchSettings.json new file mode 100644 index 0000000..1a403fd --- /dev/null +++ b/StarterNG/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "StarterNG": { + "commandName": "Project", + "workingDirectory": "E:\\Hirek\\Games\\Steam\\steamapps\\common\\MaSzyna" + } + } +} \ No newline at end of file diff --git a/StarterNG/StarterNG.csproj b/StarterNG/StarterNG.csproj index e86cfd5..109fb63 100644 --- a/StarterNG/StarterNG.csproj +++ b/StarterNG/StarterNG.csproj @@ -6,6 +6,7 @@ true app.manifest true + AnyCPU;x64 x64 @@ -30,10 +31,6 @@ - - - - diff --git a/StarterNG/Views/Scenarios.axaml b/StarterNG/Views/Scenarios.axaml index 7bf33fd..aa41533 100644 --- a/StarterNG/Views/Scenarios.axaml +++ b/StarterNG/Views/Scenarios.axaml @@ -7,7 +7,7 @@ x:Class="StarterNG.Views.Scenarios"> - + @@ -17,18 +17,8 @@ - - - - - - - - - - - - + + diff --git a/StarterNG/Views/Scenarios.axaml.cs b/StarterNG/Views/Scenarios.axaml.cs index b5fc727..0da08ae 100644 --- a/StarterNG/Views/Scenarios.axaml.cs +++ b/StarterNG/Views/Scenarios.axaml.cs @@ -1,13 +1,73 @@ -using Avalonia; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using StarterNG.Classes; namespace StarterNG.Views; public partial class Scenarios : UserControl { + public List sceneries; + public Scenarios() { InitializeComponent(); + sceneries = new List(); + + // load sceneries + List scnFiles = Directory.GetFiles("scenery/", "*.scn").ToList(); + foreach (string scnFile in scnFiles) + { + // skip temp sceneries + if (Path.GetFileName(scnFile).StartsWith("$")) + continue; + + // Parse all files + sceneries.Add(new Scenery(scnFile)); + } + + var groupNodes = new Dictionary(); + + for (int i = 0; i < sceneries.Count; i++) + { + var scenery = sceneries[i]; + + // case 1: no group - put without parent + if (string.IsNullOrEmpty(scenery.Group)) + { + sceneryList.Items.Add(new TreeViewItem + { + Header = Path.GetFileNameWithoutExtension(scenery.Path), + Tag = i + }); + + continue; + } + + // case 2 - group scenery with others + if (!groupNodes.TryGetValue(scenery.Group, out var groupNode)) + { + groupNode = new TreeViewItem + { + Header = scenery.Group, + IsExpanded = true + }; + + groupNodes[scenery.Group] = groupNode; + sceneryList.Items.Add(groupNode); + } + + groupNode.Items.Add(new TreeViewItem + { + Header = Path.GetFileNameWithoutExtension(scenery.Path), + Tag = i + }); + } + + + } } \ No newline at end of file