mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-11-05 05:24:26 +01:00
Add scenery list parser
This commit is contained in:
BIN
StarterNG/Assets/Logo/splash.png
Normal file
BIN
StarterNG/Assets/Logo/splash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
50
StarterNG/Classes/Scenery.cs
Normal file
50
StarterNG/Classes/Scenery.cs
Normal file
@@ -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<string> Lines;
|
||||
public List<Trainset> Trainsets;
|
||||
public string Group;
|
||||
public string Path;
|
||||
public Scenery(string path)
|
||||
{
|
||||
this.Path = path;
|
||||
Trainsets = new List<Trainset>();
|
||||
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<string> trainsetEntries = new List<string>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
155
StarterNG/Classes/Trainset.cs
Normal file
155
StarterNG/Classes/Trainset.cs
Normal file
@@ -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<Dynamic> Vehicles;
|
||||
public Trainset(string trainsetEntry)
|
||||
{
|
||||
|
||||
Vehicles = new List<Dynamic>();
|
||||
|
||||
List<string> 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;
|
||||
}
|
||||
@@ -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">
|
||||
<sukiUi:SukiSideMenu IsMenuExpanded="False">
|
||||
<sukiUi:SukiSideMenu.Items>
|
||||
<!-- SCENARIUSZE -->
|
||||
|
||||
@@ -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)
|
||||
|
||||
8
StarterNG/Properties/launchSettings.json
Normal file
8
StarterNG/Properties/launchSettings.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"StarterNG": {
|
||||
"commandName": "Project",
|
||||
"workingDirectory": "E:\\Hirek\\Games\\Steam\\steamapps\\common\\MaSzyna"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
@@ -30,10 +31,6 @@
|
||||
<PackageReference Include="SukiUI" Version="6.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Assets\Logo\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Assets\Logo\maszyna_black.svg" />
|
||||
<AvaloniaResource Include="Assets\Logo\maszyna_black.svg" />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
x:Class="StarterNG.Views.Scenarios">
|
||||
<Grid Margin="16" ColumnSpacing="16" RowSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200" />
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
@@ -17,18 +17,8 @@
|
||||
<RowDefinition Height="40" />
|
||||
</Grid.RowDefinitions>
|
||||
<sukiUi:GroupBox Grid.RowSpan="2" Header="Scenerie">
|
||||
<TreeView>
|
||||
<TreeViewItem Header="Bałtyk">
|
||||
<TreeViewItem Header="Bałtyk Euro 2012" />
|
||||
<TreeViewItem Header="Bałtyk SKM 1" />
|
||||
<TreeViewItem Header="Bałtyk SKM 2" />
|
||||
</TreeViewItem>
|
||||
<TreeViewItem Header="Linia 053">
|
||||
<TreeViewItem Header="Linia 053 - poranek" />
|
||||
<TreeViewItem Header="Linia 053 - południe" />
|
||||
<TreeViewItem Header="Linia 053 - wieczór" />
|
||||
<TreeViewItem Header="Linia 053 - noc" />
|
||||
</TreeViewItem>
|
||||
<TreeView Name="sceneryList">
|
||||
|
||||
</TreeView>
|
||||
</sukiUi:GroupBox>
|
||||
<sukiUi:GroupBox Grid.Column="1" Header="Pojazdy">
|
||||
|
||||
@@ -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<Scenery> sceneries;
|
||||
|
||||
public Scenarios()
|
||||
{
|
||||
InitializeComponent();
|
||||
sceneries = new List<Scenery>();
|
||||
|
||||
// load sceneries
|
||||
List<string> 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<string, TreeViewItem>();
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user