From 12933f8a3515699548dc3b7f3517fba0380a168d Mon Sep 17 00:00:00 2001 From: MattFiler Date: Mon, 2 Jan 2023 18:40:25 +0000 Subject: [PATCH 1/4] add composite constructor --- .../Scripts/CATHODE/CommandsPAK/Components/Composite.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs index 935cc0b..3e78cae 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs @@ -12,6 +12,14 @@ namespace CATHODE.Scripting [Serializable] public class Composite { + public Composite() { } + public Composite(string name) + { + shortGUID = ShortGuidUtils.GenerateRandom(); + this.name = name; + unknownPair = new OffsetPair(0, 0); + } + public ShortGuid shortGUID; //The id when this composite is used as an entity in another composite public string name = ""; //The string name of the composite From 51186947a6fc248fd8fa0b05b85a89345cb3211c Mon Sep 17 00:00:00 2001 From: MattFiler Date: Mon, 2 Jan 2023 20:07:38 +0000 Subject: [PATCH 2/4] misc composite creation improvements --- CathodeLib/Scripts/CATHODE/Commands.cs | 52 ++++++++++++------- .../CommandsPAK/Components/Composite.cs | 9 +++- .../CATHODE/CommandsPAK/Components/Entity.cs | 16 +++++- .../CommandsPAK/Components/Parameter.cs | 3 +- .../CommandsPAK/Components/ParameterData.cs | 11 ++-- .../CommandsPAK/Helpers/ShortGuidUtils.cs | 6 ++- 6 files changed, 69 insertions(+), 28 deletions(-) diff --git a/CathodeLib/Scripts/CATHODE/Commands.cs b/CathodeLib/Scripts/CATHODE/Commands.cs index 21138ad..2fe71c5 100644 --- a/CathodeLib/Scripts/CATHODE/Commands.cs +++ b/CathodeLib/Scripts/CATHODE/Commands.cs @@ -1,12 +1,14 @@ //#define DO_PRETTY_COMPOSITES using CATHODE.Scripting; +using CATHODE.Scripting.Internal; using CathodeLib; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; namespace CATHODE { @@ -19,10 +21,11 @@ public class Commands : CathodeFile // - Root Instance (the map's entry composite, usually containing entities that call mission/environment composites) // - Global Instance (the main data handler for keeping track of mission number, etc - kinda like a big singleton) // - Pause Menu Instance - private ShortGuid[] _entryPoints; + private ShortGuid[] _entryPoints = null; private Composite[] _entryPointObjects = null; - private List _composites = null; + public List Composites { get { return _composites; } } + private List _composites = new List(); public Commands(string path) : base(path) { } @@ -30,7 +33,7 @@ public Commands(string path) : base(path) { } /* Save all changes back out */ override public bool Save() { - if (_entryPoints == null || _entryPoints.Length != 3 || _entryPoints[0] == null) + if (_entryPoints == null || _entryPoints[0].val == null) return false; BinaryWriter writer = new BinaryWriter(File.OpenWrite(_filepath)); @@ -38,7 +41,12 @@ override public bool Save() //Write entry points for (int i = 0; i < 3; i++) - Utilities.Write(writer, _entryPoints[i]); + { + if (_entryPoints[i].val == null || GetComposite(_entryPoints[i]) == null) + writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 }); + else + Utilities.Write(writer, _entryPoints[i]); + } //Write placeholder info for parameter/composite offsets int offsetToRewrite = (int)writer.BaseStream.Position; @@ -1074,6 +1082,15 @@ override protected bool Load() #endregion #region ACCESSORS + /* Add a new composite */ + public Composite AddComposite(string name, bool isRoot = false) + { + Composite comp = new Composite(name); + _composites.Add(comp); + if (isRoot) SetRootComposite(comp); + return comp; + } + /* Return a list of filenames for composites in the CommandsPAK archive */ public string[] GetCompositeNames() { @@ -1082,26 +1099,16 @@ public string[] GetCompositeNames() return toReturn; } - /* Find the a script entry object by name */ - public int GetFileIndex(string FileName) + /* Get an individual composite */ + public Composite GetComposite(string name) { - for (int i = 0; i < _composites.Count; i++) if (_composites[i].name == FileName || _composites[i].name == FileName.Replace('/', '\\')) return i; - return -1; + return _composites.FirstOrDefault(o => o.name == name || o.name == name.Replace('/', '\\')); } - - /* Get an individual composite */ public Composite GetComposite(ShortGuid id) { if (id.val == null) return null; return _composites.FirstOrDefault(o => o.shortGUID == id); } - public Composite GetCompositeByIndex(int index) - { - return (index >= _composites.Count || index < 0) ? null : _composites[index]; - } - - /* Get all composites */ - public List Composites { get { return _composites; } } /* Get entry point composite objects */ public Composite[] EntryPoints @@ -1117,9 +1124,16 @@ public Composite[] EntryPoints } /* Set the root composite for this COMMANDS.PAK (the root of the level - GLOBAL and PAUSEMENU are also instanced) */ - public void SetRootComposite(ShortGuid id) + public void SetRootComposite(Composite composite) + { + SetRootComposite(composite.shortGUID); + } + public void SetRootComposite(ShortGuid compositeID) { - _entryPoints[0] = id; + if (_entryPoints == null) + _entryPoints = new ShortGuid[3]; + + _entryPoints[0] = compositeID; _entryPointObjects = null; } #endregion diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs index 3e78cae..0a1cfd0 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs @@ -1,4 +1,5 @@ -using System; +using CATHODE.Scripting.Internal; +using System; using System.Collections.Generic; using System.Linq; #if UNITY_EDITOR || UNITY_STANDALONE @@ -62,6 +63,12 @@ public void SortEntities() } /* Add a new function entity */ + public FunctionEntity AddFunction(FunctionType function, bool autopopulateParameters = false) + { + FunctionEntity func = new FunctionEntity(function, autopopulateParameters); + functions.Add(func); + return func; + } public FunctionEntity AddFunction(string function, bool autopopulateParameters = false) { FunctionEntity func = new FunctionEntity(function, autopopulateParameters); diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs index aec1d05..ca3f27c 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs @@ -1,5 +1,6 @@ using CATHODE.Assets.Utilities; using CATHODE.Scripting; +using CATHODE.Scripting.Internal; using CathodeLib; using CathodeLib.Properties; using System; @@ -9,7 +10,7 @@ using System.Linq; using System.Runtime.InteropServices; -namespace CATHODE.Scripting +namespace CATHODE.Scripting.Internal { /* An entity in a composite */ [Serializable] @@ -95,6 +96,9 @@ public void RemoveParameterLink(string parameter, Entity childEntity, string chi childLinks.RemoveAll(o => o.parentParamID == parameter_id && o.childID == childEntity.shortGUID && o.childParamID == childParameter_id); } } +} +namespace CATHODE.Scripting +{ [Serializable] public class VariableEntity : Entity { @@ -174,6 +178,11 @@ public FunctionEntity(ShortGuid function, bool autoGenerateParameters = false) : this.function = function; if (autoGenerateParameters) EntityUtils.ApplyDefaults(this); } + public FunctionEntity(FunctionType function, bool autoGenerateParameters = false) : base(EntityVariant.FUNCTION) + { + this.function = CommandsUtils.GetFunctionTypeGUID(function); + if (autoGenerateParameters) EntityUtils.ApplyDefaults(this); + } public FunctionEntity(ShortGuid shortGUID, ShortGuid function, bool autoGenerateParameters = false) : base(shortGUID, EntityVariant.FUNCTION) { @@ -185,6 +194,11 @@ public FunctionEntity(ShortGuid shortGUID, string function, bool autoGeneratePar this.function = ShortGuidUtils.Generate(function); if (autoGenerateParameters) EntityUtils.ApplyDefaults(this); } + public FunctionEntity(ShortGuid shortGUID, FunctionType function, bool autoGenerateParameters = false) : base(shortGUID, EntityVariant.FUNCTION) + { + this.function = CommandsUtils.GetFunctionTypeGUID(function); + if (autoGenerateParameters) EntityUtils.ApplyDefaults(this); + } public ShortGuid function; //Translates to string via ShortGuidUtils.FindString public List resources = new List(); //TODO: can we replace this with a cResource to save duplicating functionality? diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Parameter.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Parameter.cs index 063af40..84c4014 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Parameter.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Parameter.cs @@ -1,4 +1,5 @@ -using System; +using CATHODE.Scripting.Internal; +using System; using System.Collections.Generic; using System.Text; diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ParameterData.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ParameterData.cs index b6c59fb..e53d8d4 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ParameterData.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ParameterData.cs @@ -1,11 +1,10 @@ -using CathodeLib; -using CathodeLib.Properties; +using CATHODE.Scripting.Internal; +using CathodeLib; using System; using System.Collections.Generic; -using System.IO; using System.Linq; -namespace CATHODE.Scripting +namespace CATHODE.Scripting.Internal { /* Data which can be used within a parameter */ [Serializable] @@ -136,6 +135,10 @@ public object Clone() } } } +} + +namespace CATHODE.Scripting +{ [Serializable] public class cTransform : ParameterData { diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Helpers/ShortGuidUtils.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Helpers/ShortGuidUtils.cs index 4714397..ca713e5 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Helpers/ShortGuidUtils.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Helpers/ShortGuidUtils.cs @@ -64,8 +64,10 @@ public static string FindString(ShortGuid guid) /* Generate a random unique ShortGuid */ public static ShortGuid GenerateRandom() { - //TODO: we should really check the caches here to make sure it IS random, and then go again if not - return Generate(DateTime.Now.ToString("G") + (new Random()).Next(0, 9999)); + string guid = DateTime.Now.ToString("G") + (new Random()).Next(0, 9999); + while (vanilla.cache.ContainsKey(guid) || custom.cache.ContainsKey(guid)) + guid += "_"; + return Generate(guid); } /* Cache a pre-generated ShortGuid */ From b9a66cf754f5015134527184ea68b9b343fdc711 Mon Sep 17 00:00:00 2001 From: MattFiler Date: Mon, 2 Jan 2023 22:25:03 +0000 Subject: [PATCH 3/4] nicely handle entry point issues --- CathodeLib/Scripts/CATHODE/Commands.cs | 50 ++++++++++++++++--- .../CommandsPAK/Components/Composite.cs | 2 +- .../CATHODE/CommandsPAK/Components/Entity.cs | 6 ++- .../Components/ResourceReference.cs | 8 +-- 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/CathodeLib/Scripts/CATHODE/Commands.cs b/CathodeLib/Scripts/CATHODE/Commands.cs index 2fe71c5..d28bd0d 100644 --- a/CathodeLib/Scripts/CATHODE/Commands.cs +++ b/CathodeLib/Scripts/CATHODE/Commands.cs @@ -33,8 +33,40 @@ public Commands(string path) : base(path) { } /* Save all changes back out */ override public bool Save() { - if (_entryPoints == null || _entryPoints[0].val == null) - return false; + //Validate entry points and composite count + if (_composites.Count == 0) return false; + if (_entryPoints == null) _entryPoints = new ShortGuid[3]; + if (_entryPoints[0].val == null && _entryPoints[1].val == null && _entryPoints[2].val == null && _composites.Count == 0) return false; + + //If we have composites but the entry points are broken, correct them first! + if (GetComposite(_entryPoints[2]) == null) + { + Composite pausemenu = GetComposite("PAUSEMENU"); + if (pausemenu == null) + { + Console.WriteLine("WARNING: PAUSEMENU composite does not exist! Creating blank placeholder."); + pausemenu = AddComposite("PAUSEMENU"); + pausemenu.shortGUID = new ShortGuid("FE-7B-FE-B3"); + } + _entryPoints[2] = pausemenu.shortGUID; + } + if (GetComposite(_entryPoints[1]) == null) + { + Composite global = GetComposite("GLOBAL"); + if (global == null) + { + Console.WriteLine("WARNING: GLOBAL composite does not exist! Creating blank placeholder. This may cause issues with GLOBAL references."); + global = AddComposite("GLOBAL"); + global.shortGUID = new ShortGuid("1D-2E-CE-E5"); + } + _entryPoints[1] = global.shortGUID; + } + if (GetComposite(_entryPoints[0]) == null) + { + Console.WriteLine("WARNING: Entry point was not set! Defaulting to composite at index zero."); + _entryPoints[0] = _composites[0].shortGUID; + } + RefreshEntryPointObjects(); BinaryWriter writer = new BinaryWriter(File.OpenWrite(_filepath)); writer.BaseStream.SetLength(0); @@ -428,7 +460,7 @@ override public bool Save() break; case ResourceType.COLLISION_MAPPING: writer.Write(resourceReferences[p].startIndex); - writer.Write(resourceReferences[p].entityID.val); + writer.Write(resourceReferences[p].collisionID.val); break; case ResourceType.ANIMATED_MODEL: case ResourceType.DYNAMIC_PHYSICS_SYSTEM: @@ -867,7 +899,7 @@ override protected bool Load() break; case ResourceType.COLLISION_MAPPING: resource.startIndex = reader.ReadInt32(); //COLLISION.MAP entry index? - resource.entityID = new ShortGuid(reader); //ID which maps to the entity using the resource (?) - check GetFriendlyName + resource.collisionID = new ShortGuid(reader); //ID which maps to *something* break; case ResourceType.ANIMATED_MODEL: case ResourceType.DYNAMIC_PHYSICS_SYSTEM: @@ -1117,8 +1149,7 @@ public Composite[] EntryPoints { if (_entryPoints == null) return null; if (_entryPointObjects != null) return _entryPointObjects; - _entryPointObjects = new Composite[_entryPoints.Length]; - for (int i = 0; i < _entryPoints.Length; i++) _entryPointObjects[i] = GetComposite(_entryPoints[i]); + RefreshEntryPointObjects(); return _entryPointObjects; } } @@ -1169,6 +1200,13 @@ private List PruneParameterList(List parameters) } return prunedList; } + + /* Refresh the composite pointers for our entry points */ + private void RefreshEntryPointObjects() + { + _entryPointObjects = new Composite[_entryPoints.Length]; + for (int i = 0; i < _entryPoints.Length; i++) _entryPointObjects[i] = GetComposite(_entryPoints[i]); + } #endregion /* -- */ diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs index 0a1cfd0..5aa2533 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Composite.cs @@ -18,7 +18,7 @@ public Composite(string name) { shortGUID = ShortGuidUtils.GenerateRandom(); this.name = name; - unknownPair = new OffsetPair(0, 0); + unknownPair = new OffsetPair(5, 6); //TODO: what on earth this this? } public ShortGuid shortGUID; //The id when this composite is used as an entity in another composite diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs index ca3f27c..18c2ff8 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/Entity.cs @@ -9,6 +9,7 @@ using System.Diagnostics.SymbolStore; using System.Linq; using System.Runtime.InteropServices; +using System.Xml.Linq; namespace CATHODE.Scripting.Internal { @@ -56,9 +57,12 @@ public Parameter GetParameter(ShortGuid id) /* Add a data-supplying parameter to the entity */ public Parameter AddParameter(string name, ParameterData data, ParameterVariant variant = ParameterVariant.PARAMETER) + { + return AddParameter(ShortGuidUtils.Generate(name), data, variant); + } + public Parameter AddParameter(ShortGuid id, ParameterData data, ParameterVariant variant = ParameterVariant.PARAMETER) { //TODO: we are limiting data-supplying params to ONE per entity here - is this correct? I think links are the only place where you can have multiple of the same. - ShortGuid id = ShortGuidUtils.Generate(name); Parameter param = GetParameter(id); if (param == null) { diff --git a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ResourceReference.cs b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ResourceReference.cs index 769711d..6beeb25 100644 --- a/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ResourceReference.cs +++ b/CathodeLib/Scripts/CATHODE/CommandsPAK/Components/ResourceReference.cs @@ -36,7 +36,7 @@ public ResourceReference(ResourceType type) if (x.entryType != y.entryType) return false; if (x.startIndex != y.startIndex) return false; if (x.count != y.count) return false; - if (x.entityID != y.entityID) return false; + if (x.collisionID != y.collisionID) return false; return true; } @@ -59,7 +59,7 @@ public override bool Equals(object obj) entryType == reference.entryType && startIndex == reference.startIndex && count == reference.count && - EqualityComparer.Default.Equals(entityID, reference.entityID); + EqualityComparer.Default.Equals(collisionID, reference.collisionID); } public override int GetHashCode() @@ -71,7 +71,7 @@ public override int GetHashCode() hashCode = hashCode * -1521134295 + entryType.GetHashCode(); hashCode = hashCode * -1521134295 + startIndex.GetHashCode(); hashCode = hashCode * -1521134295 + count.GetHashCode(); - hashCode = hashCode * -1521134295 + entityID.GetHashCode(); + hashCode = hashCode * -1521134295 + collisionID.GetHashCode(); return hashCode; } @@ -84,6 +84,6 @@ public override int GetHashCode() public int startIndex = -1; public int count = 1; - public ShortGuid entityID = new ShortGuid("FF-FF-FF-FF"); + public ShortGuid collisionID = new ShortGuid("FF-FF-FF-FF"); } } From 89478a61fbc36574a2a168e540ea180c0bb11574 Mon Sep 17 00:00:00 2001 From: MattFiler Date: Mon, 2 Jan 2023 22:25:52 +0000 Subject: [PATCH 4/4] bump version --- CathodeLib/CathodeLib.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CathodeLib/CathodeLib.csproj b/CathodeLib/CathodeLib.csproj index a9d2119..47cb426 100644 --- a/CathodeLib/CathodeLib.csproj +++ b/CathodeLib/CathodeLib.csproj @@ -10,10 +10,10 @@ Matt Filer Provides support for parsing and writing common Alien: Isolation formats from the Cathode engine. Matt Filer 2023 - 0.3.0 + 0.3.1 Library - 0.3.0.0 - 0.3.0.0 + 0.3.1.0 + 0.3.1.0 False