mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-06-20 15:26:08 +00:00
Refactored GRFFile Implementation
This commit is contained in:
@@ -7,8 +7,87 @@ namespace PckStudio.Classes.FileTypes
|
||||
{
|
||||
public class GRFFile
|
||||
{
|
||||
private GRFTag _root = null;
|
||||
public GRFTag RootTag => _root;
|
||||
public static readonly string[] ValidGameRules = new string[]
|
||||
{
|
||||
"MapOptions",
|
||||
"ApplySchematic",
|
||||
"GenerateStructure",
|
||||
"GenerateBox",
|
||||
"PlaceBlock",
|
||||
"PlaceContainer",
|
||||
"PlaceSpawner",
|
||||
"BiomeOverride",
|
||||
"StartFeature",
|
||||
"AddItem",
|
||||
"AddEnchantment",
|
||||
"WeighedTreasureItem",
|
||||
"RandomItemSet",
|
||||
"DistributeItems",
|
||||
"WorldPosition",
|
||||
"LevelRules",
|
||||
"NamedArea",
|
||||
"ActiveChunkArea",
|
||||
"TargetArea",
|
||||
"ScoreRing",
|
||||
"ThermalArea",
|
||||
"PlayerBoundsVolume",
|
||||
"Killbox",
|
||||
"BlockLayer",
|
||||
"UseBlock",
|
||||
"CollectItem",
|
||||
"CompleteAll",
|
||||
"UpdatePlayer",
|
||||
"OnGameStartSpawnPositions",
|
||||
"OnInitialiseWorld",
|
||||
"SpawnPositionSet",
|
||||
"PopulateContainer",
|
||||
"DegradationSequence",
|
||||
"RandomDissolveDegrade",
|
||||
"DirectionalDegrade",
|
||||
"GrantPermissions",
|
||||
"AllowIn",
|
||||
"LayerGeneration",
|
||||
"LayerAsset",
|
||||
"AnyCombinationOf",
|
||||
"CombinationDefinition",
|
||||
"Variations",
|
||||
"BlockDef",
|
||||
"LayerSize",
|
||||
"UniformSize",
|
||||
"RandomizeSize",
|
||||
"LinearBlendSize",
|
||||
"LayerShape",
|
||||
"BasicShape",
|
||||
"StarShape",
|
||||
"PatchyShape",
|
||||
"RingShape",
|
||||
"SpiralShape",
|
||||
"LayerFill",
|
||||
"BasicLayerFill",
|
||||
"CurvedLayerFill",
|
||||
"WarpedLayerFill",
|
||||
"LayerTheme",
|
||||
"NullTheme",
|
||||
"FilterTheme",
|
||||
"ShaftsTheme",
|
||||
"BasicPatchesTheme",
|
||||
"BlockStackTheme",
|
||||
"RainbowTheme",
|
||||
"TerracottaTheme",
|
||||
"FunctionPatchesTheme",
|
||||
"SimplePatchesTheme",
|
||||
"CarpetTrapTheme",
|
||||
"MushroomBlockTheme",
|
||||
"TextureTheme",
|
||||
"SchematicTheme",
|
||||
"BlockCollisionException",
|
||||
"Powerup",
|
||||
"Checkpoint",
|
||||
"CustomBeacon",
|
||||
"ActiveViewArea",
|
||||
};
|
||||
|
||||
public readonly GameRule Root = null;
|
||||
public int Crc => _crc;
|
||||
public bool IsWorld => _isWorld;
|
||||
|
||||
@@ -23,14 +102,22 @@ namespace PckStudio.Classes.FileTypes
|
||||
ZlibRleCrc = 3,
|
||||
}
|
||||
|
||||
public class GRFTag
|
||||
{
|
||||
private GRFTag _parent = null;
|
||||
private Dictionary<string, string> _parameters = new Dictionary<string, string>();
|
||||
/// <summary>
|
||||
/// Initializes a new GRFFile as a non-world grf file
|
||||
/// </summary>
|
||||
public GRFFile() : this(-1, false)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Contains all valid Parameter names
|
||||
/// </summary>
|
||||
public GRFFile(int crc, bool isWolrd)
|
||||
{
|
||||
Root = new GameRule("__ROOT__", null);
|
||||
_crc = crc;
|
||||
_isWorld = isWolrd;
|
||||
}
|
||||
|
||||
public class GameRule
|
||||
{
|
||||
/// <summary> Contains all valid Parameter names </summary>
|
||||
public static readonly string[] ValidParameters = new string[]
|
||||
{
|
||||
"plus_x",
|
||||
@@ -139,116 +226,35 @@ namespace PckStudio.Classes.FileTypes
|
||||
"beam_length",
|
||||
};
|
||||
|
||||
public static readonly string[] ValidGameRules = new string[]
|
||||
{
|
||||
"MapOptions",
|
||||
"ApplySchematic",
|
||||
"GenerateStructure",
|
||||
"GenerateBox",
|
||||
"PlaceBlock",
|
||||
"PlaceContainer",
|
||||
"PlaceSpawner",
|
||||
"BiomeOverride",
|
||||
"StartFeature",
|
||||
"AddItem",
|
||||
"AddEnchantment",
|
||||
"WeighedTreasureItem",
|
||||
"RandomItemSet",
|
||||
"DistributeItems",
|
||||
"WorldPosition",
|
||||
"LevelRules",
|
||||
"NamedArea",
|
||||
"ActiveChunkArea",
|
||||
"TargetArea",
|
||||
"ScoreRing",
|
||||
"ThermalArea",
|
||||
"PlayerBoundsVolume",
|
||||
"Killbox",
|
||||
"BlockLayer",
|
||||
"UseBlock",
|
||||
"CollectItem",
|
||||
"CompleteAll",
|
||||
"UpdatePlayer",
|
||||
"OnGameStartSpawnPositions",
|
||||
"OnInitialiseWorld",
|
||||
"SpawnPositionSet",
|
||||
"PopulateContainer",
|
||||
"DegradationSequence",
|
||||
"RandomDissolveDegrade",
|
||||
"DirectionalDegrade",
|
||||
"GrantPermissions",
|
||||
"AllowIn",
|
||||
"LayerGeneration",
|
||||
"LayerAsset",
|
||||
"AnyCombinationOf",
|
||||
"CombinationDefinition",
|
||||
"Variations",
|
||||
"BlockDef",
|
||||
"LayerSize",
|
||||
"UniformSize",
|
||||
"RandomizeSize",
|
||||
"LinearBlendSize",
|
||||
"LayerShape",
|
||||
"BasicShape",
|
||||
"StarShape",
|
||||
"PatchyShape",
|
||||
"RingShape",
|
||||
"SpiralShape",
|
||||
"LayerFill",
|
||||
"BasicLayerFill",
|
||||
"CurvedLayerFill",
|
||||
"WarpedLayerFill",
|
||||
"LayerTheme",
|
||||
"NullTheme",
|
||||
"FilterTheme",
|
||||
"ShaftsTheme",
|
||||
"BasicPatchesTheme",
|
||||
"BlockStackTheme",
|
||||
"RainbowTheme",
|
||||
"TerracottaTheme",
|
||||
"FunctionPatchesTheme",
|
||||
"SimplePatchesTheme",
|
||||
"CarpetTrapTheme",
|
||||
"MushroomBlockTheme",
|
||||
"TextureTheme",
|
||||
"SchematicTheme",
|
||||
"BlockCollisionException",
|
||||
"Powerup",
|
||||
"Checkpoint",
|
||||
"CustomBeacon",
|
||||
"ActiveViewArea",
|
||||
};
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public GRFTag Parent => _parent;
|
||||
public Dictionary<string, string> Parameters => _parameters;
|
||||
public List<GRFTag> Tags { get; set; } = new List<GRFTag>();
|
||||
|
||||
public GRFTag(string name, GRFTag parent)
|
||||
public GameRule Parent { get; } = null;
|
||||
public Dictionary<string, string> Parameters { get; } = new Dictionary<string, string>();
|
||||
public List<GameRule> SubRules { get; } = new List<GameRule>();
|
||||
|
||||
public GameRule(string name, GameRule parent)
|
||||
{
|
||||
Name = name;
|
||||
_parent = parent;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
public GRFTag AddTag(string gameRuleName) => AddTag(gameRuleName, false);
|
||||
public GameRule AddRule(string gameRuleName) => AddRule(gameRuleName, false);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new tag to its child tags
|
||||
/// </summary>
|
||||
/// <summary>Adds a new gamerule</summary>
|
||||
/// <param name="gameRuleName">Game rule to add</param>
|
||||
/// <param name="validate">Wether to check the given game rule</param>
|
||||
/// <returns>The Added GRFTag</returns>
|
||||
public GRFTag AddTag(string gameRuleName, bool validate)
|
||||
public GameRule AddRule(string gameRuleName, bool validate)
|
||||
{
|
||||
if (validate && !ValidGameRules.Contains(gameRuleName)) return null;
|
||||
var tag = new GRFTag(gameRuleName, this);
|
||||
Tags.Add(tag);
|
||||
var tag = new GameRule(gameRuleName, this);
|
||||
SubRules.Add(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public GRFTag AddTag(string gameRuleName, params KeyValuePair<string,string>[] parameters)
|
||||
public GameRule AddRule(string gameRuleName, params KeyValuePair<string,string>[] parameters)
|
||||
{
|
||||
var tag = AddTag(gameRuleName); // should never return null unless its called with the validate bool set to true
|
||||
var tag = AddRule(gameRuleName); // should never return null unless its called with the validate bool set to true
|
||||
foreach(var param in parameters)
|
||||
{
|
||||
tag.Parameters[param.Key] = param.Value;
|
||||
@@ -257,29 +263,15 @@ namespace PckStudio.Classes.FileTypes
|
||||
}
|
||||
}
|
||||
|
||||
public GRFTag AddTag(string gameRuleName)
|
||||
=> AddTag(gameRuleName, false);
|
||||
|
||||
public GRFTag AddTag(string gameRuleName, bool validate)
|
||||
=> _root.AddTag(gameRuleName, validate);
|
||||
|
||||
public GRFTag AddTag(string gameRuleName, params KeyValuePair<string, string>[] parameters)
|
||||
=> _root.AddTag(gameRuleName, parameters);
|
||||
|
||||
public GRFFile(int crc, bool isWolrd)
|
||||
{
|
||||
_root = new GRFTag("__ROOT__", null);
|
||||
_crc = crc;
|
||||
_isWorld = isWolrd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new GRFFile as a non-world grf file
|
||||
/// </summary>
|
||||
public GRFFile() : this(-1, false)
|
||||
{
|
||||
}
|
||||
public void AddGameRules(IEnumerable<GameRule> gameRules) => Root.SubRules.AddRange(gameRules);
|
||||
|
||||
public GameRule AddRule(string gameRuleName)
|
||||
=> AddRule(gameRuleName, false);
|
||||
|
||||
public GameRule AddRule(string gameRuleName, bool validate)
|
||||
=> Root.AddRule(gameRuleName, validate);
|
||||
|
||||
public GameRule AddRule(string gameRuleName, params KeyValuePair<string, string>[] parameters)
|
||||
=> Root.AddRule(gameRuleName, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,17 +11,18 @@ namespace PckStudio.Classes.IO.GRF
|
||||
{
|
||||
internal class GRFFileReader : StreamDataReader
|
||||
{
|
||||
internal List<string> TagNames;
|
||||
internal GRFFile _file;
|
||||
private IList<string> StringLookUpTable;
|
||||
private GRFFile _file;
|
||||
|
||||
public static GRFFile Read(Stream stream)
|
||||
{
|
||||
return new GRFFileReader().read(stream);
|
||||
return new GRFFileReader().ReadFromStream(stream);
|
||||
}
|
||||
|
||||
private GRFFileReader() : base(false)
|
||||
{ }
|
||||
|
||||
private GRFFile read(Stream stream)
|
||||
private GRFFile ReadFromStream(Stream stream)
|
||||
{
|
||||
stream = ReadHeader(stream);
|
||||
ReadBody(stream);
|
||||
@@ -82,8 +83,10 @@ namespace PckStudio.Classes.IO.GRF
|
||||
|
||||
private void ReadBody(Stream stream)
|
||||
{
|
||||
ReadTagNames(stream);
|
||||
ReadRootTag(stream);
|
||||
ReadStringLookUpTable(stream);
|
||||
string Name = GetString(stream);
|
||||
Console.WriteLine($"[{nameof(GRFFile)}] Root Name: {Name}");
|
||||
ReadGameRuleHierarchy(stream, _file.Root);
|
||||
}
|
||||
|
||||
private Stream DecompressZLX(Stream compressedStream)
|
||||
@@ -98,44 +101,34 @@ namespace PckStudio.Classes.IO.GRF
|
||||
return outputstream;
|
||||
}
|
||||
|
||||
private void ReadTagNames(Stream stream)
|
||||
private void ReadStringLookUpTable(Stream stream)
|
||||
{
|
||||
int name_count = ReadInt(stream);
|
||||
TagNames = new List<string>(name_count);
|
||||
StringLookUpTable = new List<string>(name_count);
|
||||
for (int i = 0; i < name_count; i++)
|
||||
{
|
||||
string s = ReadString(stream);
|
||||
TagNames.Add(s);
|
||||
//Console.WriteLine(s);
|
||||
StringLookUpTable.Add(s);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadRootTag(Stream stream)
|
||||
{
|
||||
string Name = GetTagName(stream);
|
||||
Console.WriteLine($"[GRFFileReader] root_name: {Name}");
|
||||
_file.RootTag.Tags = ReadGRFTreeHierarchy(stream, _file.RootTag).ToList();
|
||||
}
|
||||
|
||||
private IEnumerable<GRFFile.GRFTag> ReadGRFTreeHierarchy(Stream stream, GRFFile.GRFTag parent)
|
||||
private void ReadGameRuleHierarchy(Stream stream, GRFFile.GameRule parent)
|
||||
{
|
||||
_ = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||
int count = ReadInt(stream);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string parameterName = GetTagName(stream);
|
||||
int parameterCount = ReadInt(stream);
|
||||
var tag = new GRFFile.GRFTag(parameterName, parent);
|
||||
for (int j = 0; j < parameterCount; j++)
|
||||
(string Name, int Count) parameter = (GetString(stream), ReadInt(stream));
|
||||
var rule = parent.AddRule(parameter.Name);
|
||||
for (int j = 0; j < parameter.Count; j++)
|
||||
{
|
||||
tag.Parameters.Add(GetTagName(stream), ReadString(stream));
|
||||
rule.Parameters.Add(GetString(stream), ReadString(stream));
|
||||
}
|
||||
tag.Tags = ReadGRFTreeHierarchy(stream, tag).ToList();
|
||||
yield return tag;
|
||||
ReadGameRuleHierarchy(stream, rule);
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
private string GetTagName(Stream stream) => TagNames[ReadInt(stream)];
|
||||
private string GetString(Stream stream) => StringLookUpTable[ReadInt(stream)];
|
||||
|
||||
private string ReadString(Stream stream)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace PckStudio.Classes.IO.GRF
|
||||
|
||||
public static void Write(in Stream stream, GRFFile grfFile, GRFFile.eCompressionType compressionType)
|
||||
{
|
||||
new GRFFileWriter(grfFile, compressionType).write(stream);
|
||||
new GRFFileWriter(grfFile, compressionType).WriteToStream(stream);
|
||||
}
|
||||
|
||||
private GRFFileWriter(GRFFile grfFile, GRFFile.eCompressionType compressionType) : base(false)
|
||||
@@ -30,10 +30,18 @@ namespace PckStudio.Classes.IO.GRF
|
||||
throw new NotImplementedException("World grf saving is currently unsupported");
|
||||
_grfFile = grfFile;
|
||||
LUT = new List<string>();
|
||||
PrepareLookUpTable(_grfFile.RootTag, LUT);
|
||||
PrepareLookUpTable(_grfFile.Root, LUT);
|
||||
}
|
||||
|
||||
private void write(Stream stream)
|
||||
private void PrepareLookUpTable(GRFFile.GameRule tag, List<string> LUT)
|
||||
{
|
||||
if (!LUT.Contains(tag.Name)) LUT.Add(tag.Name);
|
||||
tag.SubRules.ForEach(tag => PrepareLookUpTable(tag, LUT));
|
||||
foreach (var param in tag.Parameters)
|
||||
if (!LUT.Contains(param.Key)) LUT.Add(param.Key);
|
||||
}
|
||||
|
||||
private void WriteToStream(Stream stream)
|
||||
{
|
||||
WriteHeader(stream);
|
||||
using (var uncompressed_stream = new MemoryStream())
|
||||
@@ -107,8 +115,9 @@ namespace PckStudio.Classes.IO.GRF
|
||||
private void WriteBody(Stream stream)
|
||||
{
|
||||
WriteTagLookUpTable(stream);
|
||||
WriteRuleNameAndCount(stream, _grfFile.RootTag.Name, _grfFile.RootTag.Tags.Count);
|
||||
WriteGameRules(stream, _grfFile.RootTag.Tags);
|
||||
SetString(stream, _grfFile.Root.Name);
|
||||
WriteInt(stream, _grfFile.Root.SubRules.Count);
|
||||
WriteGameRuleHierarchy(stream, _grfFile.Root);
|
||||
}
|
||||
|
||||
private void WriteTagLookUpTable(Stream stream)
|
||||
@@ -117,41 +126,25 @@ namespace PckStudio.Classes.IO.GRF
|
||||
LUT.ForEach( s => WriteString(stream, s) );
|
||||
}
|
||||
|
||||
private void PrepareLookUpTable(GRFFile.GRFTag tag, List<string> LUT)
|
||||
private void WriteGameRuleHierarchy(Stream stream, GRFFile.GameRule rule)
|
||||
{
|
||||
if (!LUT.Contains(tag.Name)) LUT.Add(tag.Name);
|
||||
tag.Tags.ForEach( tag => PrepareLookUpTable(tag, LUT));
|
||||
foreach (var param in tag.Parameters)
|
||||
if (!LUT.Contains(param.Key)) LUT.Add(param.Key);
|
||||
}
|
||||
|
||||
private void WriteGameRules(Stream stream, List<GRFFile.GRFTag> tags)
|
||||
{
|
||||
foreach(var tag in tags)
|
||||
{
|
||||
WriteRuleNameAndCount(stream, tag.Name, tag.Parameters.Count);
|
||||
foreach (var param in tag.Parameters) WriteParameter(stream, param);
|
||||
WriteInt(stream, tag.Tags.Count);
|
||||
WriteGameRules(stream, tag.Tags);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteRuleNameAndCount(Stream stream, string name, int count)
|
||||
{
|
||||
WriteRuleName(stream, name);
|
||||
WriteInt(stream, count);
|
||||
SetString(stream, rule.Name);
|
||||
WriteInt(stream, rule.Parameters.Count);
|
||||
foreach (var param in rule.Parameters) WriteParameter(stream, param);
|
||||
WriteInt(stream, rule.SubRules.Count);
|
||||
rule.SubRules.ForEach(subrule => WriteGameRuleHierarchy(stream, subrule));
|
||||
}
|
||||
|
||||
private void WriteParameter(Stream stream, KeyValuePair<string, string> param)
|
||||
{
|
||||
WriteRuleName(stream, param.Key);
|
||||
SetString(stream, param.Key);
|
||||
WriteString(stream, param.Value);
|
||||
}
|
||||
|
||||
private void WriteRuleName(Stream stream, string name)
|
||||
private void SetString(Stream stream, string s)
|
||||
{
|
||||
int i = LUT.IndexOf(name);
|
||||
if (i == -1) throw new Exception("No index found for: " + name);
|
||||
int i = LUT.IndexOf(s);
|
||||
if (i == -1) throw new Exception(nameof(s));
|
||||
WriteInt(stream, i);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,47 +56,46 @@ namespace PckStudio.Forms.Editor
|
||||
private void OnLoad(object sender, EventArgs e)
|
||||
{
|
||||
RPC.SetPresence("GRF Editor", "Editing a GRF File");
|
||||
loadGRFTreeView(GrfTreeView.Nodes, _file.RootTag);
|
||||
loadGRFTreeView(GrfTreeView.Nodes, _file.Root);
|
||||
}
|
||||
|
||||
private void OnExit(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
RPC.SetPresence("Sitting alone", "Program by PhoenixARC");
|
||||
RPC.SetPresence("An Open Source .PCK File Editor", "Program by PhoenixARC");
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void loadGRFTreeView(TreeNodeCollection root, GRFFile.GRFTag parentTag)
|
||||
private void loadGRFTreeView(TreeNodeCollection root, GRFFile.GameRule parentRule)
|
||||
{
|
||||
foreach (var tag in parentTag.Tags)
|
||||
foreach (var rule in parentRule.SubRules)
|
||||
{
|
||||
TreeNode node = new TreeNode(tag.Name);
|
||||
node.Tag = tag;
|
||||
TreeNode node = new TreeNode(rule.Name);
|
||||
node.Tag = rule;
|
||||
root.Add(node);
|
||||
loadGRFTreeView(node.Nodes, tag);
|
||||
loadGRFTreeView(node.Nodes, rule);
|
||||
}
|
||||
}
|
||||
|
||||
private void GrfTreeView_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
if (e.Node == null || !(e.Node.Tag is GRFFile.GRFTag)) return;
|
||||
ReloadParameterTreeView();
|
||||
if (e.Node is TreeNode t && t.Tag is GRFFile.GameRule)
|
||||
ReloadParameterTreeView();
|
||||
}
|
||||
|
||||
private void ReloadParameterTreeView()
|
||||
{
|
||||
GrfParametersTreeView.Nodes.Clear();
|
||||
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag)) return;
|
||||
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
|
||||
foreach (var Pair in grfTag.Parameters)
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule rule)
|
||||
foreach (var param in rule.Parameters)
|
||||
{
|
||||
GrfParametersTreeView.Nodes.Add(new TreeNode($"{Pair.Key}: {Pair.Value}") { Tag = Pair});
|
||||
GrfParametersTreeView.Nodes.Add(new TreeNode($"{param.Key}: {param.Value}") { Tag = param});
|
||||
}
|
||||
}
|
||||
|
||||
private void addDetailContextMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag)) return;
|
||||
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
|
||||
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GameRule)) return;
|
||||
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GameRule;
|
||||
AddParameter prompt = new AddParameter();
|
||||
if (prompt.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
@@ -112,9 +111,9 @@ namespace PckStudio.Forms.Editor
|
||||
|
||||
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GRFTag grfTag &&
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule rule &&
|
||||
GrfParametersTreeView.SelectedNode is TreeNode paramNode && paramNode.Tag is KeyValuePair<string, string> pair &&
|
||||
grfTag.Parameters.ContainsKey(pair.Key) && grfTag.Parameters.Remove(pair.Key))
|
||||
rule.Parameters.ContainsKey(pair.Key) && rule.Parameters.Remove(pair.Key))
|
||||
{
|
||||
ReloadParameterTreeView();
|
||||
return;
|
||||
@@ -130,13 +129,13 @@ namespace PckStudio.Forms.Editor
|
||||
|
||||
private void GrfDetailsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
|
||||
{
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GRFTag grfTag &&
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule rule &&
|
||||
GrfParametersTreeView.SelectedNode is TreeNode paramNode && paramNode.Tag is KeyValuePair<string, string> param)
|
||||
{
|
||||
AddParameter prompt = new AddParameter(param.Key, param.Value, false);
|
||||
if (prompt.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
grfTag.Parameters[prompt.ParameterName] = prompt.ParameterValue;
|
||||
rule.Parameters[prompt.ParameterName] = prompt.ParameterValue;
|
||||
ReloadParameterTreeView();
|
||||
}
|
||||
}
|
||||
@@ -144,10 +143,10 @@ namespace PckStudio.Forms.Editor
|
||||
|
||||
private void addGameRuleToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
bool isValidNode = GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GRFTag;
|
||||
GRFFile.GRFTag parentTag = isValidNode
|
||||
? GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag
|
||||
: _file.RootTag;
|
||||
bool isValidNode = GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule;
|
||||
GRFFile.GameRule parentRule = isValidNode
|
||||
? GrfTreeView.SelectedNode.Tag as GRFFile.GameRule
|
||||
: _file.Root;
|
||||
|
||||
TreeNodeCollection root = isValidNode
|
||||
? GrfTreeView.SelectedNode.Nodes
|
||||
@@ -156,12 +155,12 @@ namespace PckStudio.Forms.Editor
|
||||
using (RenamePrompt prompt = new RenamePrompt(""))
|
||||
{
|
||||
prompt.OKButton.Text = "Add";
|
||||
if (MessageBox.Show($"Add Game Rule to {parentTag.Name}", "Attention",
|
||||
if (MessageBox.Show($"Add Game Rule to {parentRule.Name}", "Attention",
|
||||
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes &&
|
||||
prompt.ShowDialog() == DialogResult.OK &&
|
||||
!string.IsNullOrWhiteSpace(prompt.NewText))
|
||||
{
|
||||
var tag = parentTag.AddTag(prompt.NewText);
|
||||
var tag = parentRule.AddRule(prompt.NewText);
|
||||
TreeNode node = new TreeNode(tag.Name);
|
||||
node.Tag = tag;
|
||||
root.Add(node);
|
||||
@@ -171,16 +170,16 @@ namespace PckStudio.Forms.Editor
|
||||
|
||||
private void removeGameRuleToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GRFTag tag && removeTag(tag))
|
||||
if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule tag && removeTag(tag))
|
||||
t.Remove();
|
||||
}
|
||||
|
||||
private bool removeTag(GRFFile.GRFTag tag)
|
||||
private bool removeTag(GRFFile.GameRule rule)
|
||||
{
|
||||
_ = tag.Parent ?? throw new ArgumentNullException(nameof(tag.Parent));
|
||||
foreach (var subTag in tag.Tags.ToList())
|
||||
_ = rule.Parent ?? throw new ArgumentNullException(nameof(rule.Parent));
|
||||
foreach (var subTag in rule.SubRules.ToList())
|
||||
return removeTag(subTag);
|
||||
return tag.Parent.Tags.Remove(tag);
|
||||
return rule.Parent.SubRules.Remove(rule);
|
||||
}
|
||||
|
||||
private void GrfTreeView_KeyDown(object sender, KeyEventArgs e)
|
||||
|
||||
@@ -904,14 +904,14 @@ namespace PckStudio
|
||||
InitializeTexturePack(packId, packVersion, packName, res);
|
||||
var gameRuleFile = new PCKFile.FileData("GameRules.grf", 7);
|
||||
var grfFile = new GRFFile();
|
||||
grfFile.AddTag("MapOptions",
|
||||
grfFile.AddRule("MapOptions",
|
||||
new KeyValuePair<string, string>("seed", "0"),
|
||||
new KeyValuePair<string, string>("baseSaveName", string.Empty),
|
||||
new KeyValuePair<string, string>("flatworld", "false"),
|
||||
new KeyValuePair<string, string>("texturePackId", packId.ToString())
|
||||
);
|
||||
grfFile.AddTag("LevelRules")
|
||||
.AddTag("UpdatePlayer",
|
||||
grfFile.AddRule("LevelRules")
|
||||
.AddRule("UpdatePlayer",
|
||||
new KeyValuePair<string, string>("yRot", "0"),
|
||||
new KeyValuePair<string, string>("xRot", "0"),
|
||||
new KeyValuePair<string, string>("spawnX", "0"),
|
||||
|
||||
Reference in New Issue
Block a user