diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs index 7c5fe8d..eec6a3d 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs @@ -4743,7 +4743,7 @@ namespace CodeWalker.GameFiles public byte TypeId { get { return _Data.iType; } set { _Data.iType = value; } } - public ScenarioTypeRef? Type { get; set; } + public ScenarioTypeRef Type { get; set; } public byte ModelSetId { get { return _Data.ModelSetId; } set { _Data.ModelSetId = value; } } public AmbientModelSet ModelSet { get; set; } @@ -5327,7 +5327,7 @@ namespace CodeWalker.GameFiles public Vector3 Position { get { return _Data.Position; } set { _Data.Position = value; } } public MetaHash Unk1 { get { return _Data.Unk_2602393771; } set { _Data.Unk_2602393771 = value; } } public MetaHash TypeHash { get { return _Data.ScenarioType; } set { _Data.ScenarioType = value; } } - public ScenarioTypeRef? Type { get; set; } + public ScenarioTypeRef Type { get; set; } public bool NotFirst { get { return _Data.Unk_407126079_NotFirst == 1; } set { _Data.Unk_407126079_NotFirst = (byte)(value ? 1 : 0); } } public bool NotLast { get { return _Data.Unk_1308720135_NotLast == 1; } set { _Data.Unk_1308720135_NotLast = (byte)(value ? 1 : 0); } } diff --git a/CodeWalker.Core/World/Scenarios.cs b/CodeWalker.Core/World/Scenarios.cs index 8be95ba..3d30654 100644 --- a/CodeWalker.Core/World/Scenarios.cs +++ b/CodeWalker.Core/World/Scenarios.cs @@ -208,22 +208,7 @@ namespace CodeWalker.World if (tpind < typhashes.Length) { var hash = typhashes[tpind]; - var st = types.GetScenarioType(hash); - if (st != null) - { - scp.Type = new ScenarioTypeRef(st); - } - else - { - var stg = types.GetScenarioTypeGroup(hash); - if (stg != null) - { - scp.Type = new ScenarioTypeRef(stg); - } - else - { } - } - + scp.Type = types.GetScenarioTypeRef(hash); isveh = scp.Type?.IsVehicle ?? false; //TODO: make a warning about this if scp.Type is null? } else @@ -292,22 +277,7 @@ namespace CodeWalker.World if ((hash != 0) && (hash != 493038497)) { bool isveh = false; - var st = types.GetScenarioType(hash); - if (st != null) - { - spn.Type = new ScenarioTypeRef(st); - } - else - { - var stg = types.GetScenarioTypeGroup(hash); - if (stg != null) - { - spn.Type = new ScenarioTypeRef(stg); - } - else - { } - } - + spn.Type = types.GetScenarioTypeRef(hash); isveh = spn.Type?.IsVehicle ?? false; if (isveh) { } @@ -1087,10 +1057,10 @@ namespace CodeWalker.World int interiorid = 0; int groupid = 0; int imapid = 0; - if ((mp.Type != null) && (!typeNames.TryGetValue(mp.Type.Value.NameHash, out typeid))) + if ((mp.Type != null) && (!typeNames.TryGetValue(mp.Type.NameHash, out typeid))) { typeid = typeNames.Count; - typeNames[mp.Type.Value.NameHash] = typeid; + typeNames[mp.Type.NameHash] = typeid; } if (mp.ModelSet != null) { @@ -1179,10 +1149,10 @@ namespace CodeWalker.World int interiorid = 0; int groupid = 0; int imapid = 0; - if ((mp.Type != null) && (!typeNames.TryGetValue(mp.Type.Value.NameHash, out typeid))) + if ((mp.Type != null) && (!typeNames.TryGetValue(mp.Type.NameHash, out typeid))) { typeid = typeNames.Count; - typeNames[mp.Type.Value.NameHash] = typeid; + typeNames[mp.Type.NameHash] = typeid; } if (mp.ModelSet != null) { @@ -1521,6 +1491,7 @@ namespace CodeWalker.World { private object SyncRoot = new object(); //keep this thread-safe.. technically shouldn't be necessary, but best to be safe + private Dictionary TypeRefs { get; set; } private Dictionary Types { get; set; } private Dictionary TypeGroups { get; set; } private Dictionary PropSets { get; set; } @@ -1540,6 +1511,16 @@ namespace CodeWalker.World PedModelSets = LoadModelSets(gfc, "common:\\data\\ai\\ambientpedmodelsets.meta"); VehicleModelSets = LoadModelSets(gfc, "common:\\data\\ai\\vehiclemodelsets.meta"); AnimGroups = LoadAnimGroups(gfc, "common:\\data\\ai\\conditionalanims.meta"); + + TypeRefs = new Dictionary(); + foreach (var kvp in Types) + { + TypeRefs[kvp.Key] = new ScenarioTypeRef(kvp.Value); + } + foreach (var kvp in TypeGroups) + { + TypeRefs[kvp.Key] = new ScenarioTypeRef(kvp.Value); + } } } @@ -1664,6 +1645,14 @@ namespace CodeWalker.World var setsxml = xml.DocumentElement; var items = setsxml.SelectNodes("ModelSets/Item"); + + var noneset = new AmbientModelSet(); + noneset.Name = "NONE"; + noneset.NameLower = "none"; + noneset.NameHash = JenkHash.GenHash("none"); + sets[noneset.NameHash] = noneset; + + foreach (XmlNode item in items) { AmbientModelSet set = new AmbientModelSet(); @@ -1712,6 +1701,16 @@ namespace CodeWalker.World + public ScenarioTypeRef GetScenarioTypeRef(uint hash) + { + lock (SyncRoot) + { + if (TypeRefs == null) return null; + ScenarioTypeRef st; + TypeRefs.TryGetValue(hash, out st); + return st; + } + } public ScenarioType GetScenarioType(uint hash) { lock (SyncRoot) @@ -1791,6 +1790,14 @@ namespace CodeWalker.World } } + public ScenarioTypeRef[] GetScenarioTypeRefs() + { + lock (SyncRoot) + { + if (TypeRefs == null) return null; + return TypeRefs.Values.ToArray(); + } + } public ScenarioType[] GetScenarioTypes() { lock (SyncRoot) @@ -1842,12 +1849,13 @@ namespace CodeWalker.World } - /// - /// Represents a scenario type that may either be a or a . - /// Used with CScenarioChainingNode and CScenarioPoint. - /// - [TypeConverter(typeof(ExpandableObjectConverter))] public struct ScenarioTypeRef + [TypeConverter(typeof(ExpandableObjectConverter))] public class ScenarioTypeRef { + /// + /// Represents a scenario type that may either be a or a . + /// Used with CScenarioChainingNode and CScenarioPoint. + /// + public string Name => IsGroup ? Group.Name : Type.Name; public string NameLower => IsGroup ? Group.NameLower : Type.NameLower; public MetaHash NameHash => IsGroup ? Group.NameHash : Type.NameHash; @@ -1859,12 +1867,6 @@ namespace CodeWalker.World public ScenarioType Type { get; } public ScenarioTypeGroup Group { get; } - public ScenarioTypeRef(ScenarioTypeRef typeRef) - { - IsGroup = typeRef.IsGroup; - Type = typeRef.Type; - Group = typeRef.Group; - } public ScenarioTypeRef(ScenarioType type) { @@ -1884,26 +1886,6 @@ namespace CodeWalker.World { return Name; } - - public override bool Equals(object obj) - { - return obj is ScenarioTypeRef other && other == this; - } - - public override int GetHashCode() - { - return NameHash.GetHashCode(); - } - - public static bool operator ==(ScenarioTypeRef a, ScenarioTypeRef b) - { - return a.NameHash == b.NameHash; - } - - public static bool operator !=(ScenarioTypeRef a, ScenarioTypeRef b) - { - return a.NameHash != b.NameHash; - } } [TypeConverter(typeof(ExpandableObjectConverter))] public class ScenarioType diff --git a/CodeWalker/Project/Panels/EditScenarioNodePanel.cs b/CodeWalker/Project/Panels/EditScenarioNodePanel.cs index 2502b44..65c9fae 100644 --- a/CodeWalker/Project/Panels/EditScenarioNodePanel.cs +++ b/CodeWalker/Project/Panels/EditScenarioNodePanel.cs @@ -130,12 +130,9 @@ namespace CodeWalker.Project.Panels if (types == null) { return; } - var stypes = types.GetScenarioTypes(); + var stypes = types.GetScenarioTypeRefs(); if (stypes == null) return; - var stgroups = types.GetScenarioTypeGroups(); - if (stgroups == null) return; - var pmsets = types.GetPedModelSets(); if (pmsets == null) return; @@ -150,17 +147,9 @@ namespace CodeWalker.Project.Panels ScenarioChainNodeTypeComboBox.Items.Add(""); foreach (var stype in stypes) { - ScenarioTypeRef? typeRef = new ScenarioTypeRef(stype); - ScenarioPointTypeComboBox.Items.Add(typeRef); - ScenarioClusterPointTypeComboBox.Items.Add(typeRef); - ScenarioChainNodeTypeComboBox.Items.Add(typeRef); - } - foreach (var stgroup in stgroups) - { - ScenarioTypeRef? typeRef = new ScenarioTypeRef(stgroup); - ScenarioPointTypeComboBox.Items.Add(typeRef); - ScenarioClusterPointTypeComboBox.Items.Add(typeRef); - ScenarioChainNodeTypeComboBox.Items.Add(typeRef); + ScenarioPointTypeComboBox.Items.Add(stype); + ScenarioClusterPointTypeComboBox.Items.Add(stype); + ScenarioChainNodeTypeComboBox.Items.Add(stype); } ScenarioPointModelSetComboBox.Items.Clear(); @@ -838,7 +827,7 @@ namespace CodeWalker.Project.Panels if (populatingui) return; if (CurrentScenarioNode == null) return; if (CurrentScenarioNode.MyPoint == null) return; - ScenarioTypeRef? stype = ScenarioPointTypeComboBox.SelectedItem as ScenarioTypeRef?; + ScenarioTypeRef stype = ScenarioPointTypeComboBox.SelectedItem as ScenarioTypeRef; lock (ProjectForm.ProjectSyncRoot) { if (CurrentScenarioNode.MyPoint.Type != stype) @@ -1722,7 +1711,7 @@ namespace CodeWalker.Project.Panels if (populatingui) return; if (CurrentScenarioNode == null) return; if (CurrentScenarioNode.ChainingNode == null) return; - ScenarioTypeRef? stype = ScenarioChainNodeTypeComboBox.SelectedItem as ScenarioTypeRef?; + ScenarioTypeRef stype = ScenarioChainNodeTypeComboBox.SelectedItem as ScenarioTypeRef; lock (ProjectForm.ProjectSyncRoot) { if (CurrentScenarioNode.ChainingNode.Type != stype) @@ -2144,7 +2133,7 @@ namespace CodeWalker.Project.Panels if (populatingui) return; if (CurrentScenarioNode == null) return; if (CurrentScenarioNode.ClusterMyPoint == null) return; - ScenarioTypeRef? stype = ScenarioClusterPointTypeComboBox.SelectedItem as ScenarioTypeRef?; + ScenarioTypeRef stype = ScenarioClusterPointTypeComboBox.SelectedItem as ScenarioTypeRef; lock (ProjectForm.ProjectSyncRoot) { if (CurrentScenarioNode.ClusterMyPoint.Type != stype) diff --git a/CodeWalker/Project/ProjectForm.cs b/CodeWalker/Project/ProjectForm.cs index f8bc134..be55ca3 100644 --- a/CodeWalker/Project/ProjectForm.cs +++ b/CodeWalker/Project/ProjectForm.cs @@ -6143,10 +6143,10 @@ namespace CodeWalker.Project if (f.ShowDialog() == DialogResult.Cancel) return; var stypes = Scenarios.ScenarioTypes; //these are loaded by Scenarios.Init - ScenarioType defaulttype = null; + ScenarioTypeRef defaulttype = null; if (stypes != null) { - defaulttype = stypes.GetScenarioType(1194480618); //"drive"; + defaulttype = stypes.GetScenarioTypeRef(1194480618); //"drive"; } AmbientModelSet defaultmodelset = null; @@ -6184,7 +6184,7 @@ namespace CodeWalker.Project var action = CScenarioChainingEdge__eAction.Move; var navMode = CScenarioChainingEdge__eNavMode.Direct; var navSpeed = CScenarioChainingEdge__eNavSpeed.Unk_00_3279574318; - var stype = new ScenarioTypeRef(defaulttype); + var stype = defaulttype; var modelset = defaultmodelset; var flags = defaultflags; var ok = true; @@ -6216,22 +6216,10 @@ namespace CodeWalker.Project if (vals.Length > 6) { var sthash = JenkHash.GenHash(vals[6].Trim().ToLowerInvariant()); - var st = stypes?.GetScenarioType(sthash); - if (st != null) + stype = stypes?.GetScenarioTypeRef(sthash); + if (stype == null) { - stype = new ScenarioTypeRef(st); - } - else - { - var stg = stypes?.GetScenarioTypeGroup(sthash); - if (stg != null) - { - stype = new ScenarioTypeRef(stg); - } - else - { - stype = new ScenarioTypeRef(defaulttype); - } + stype = defaulttype; } } if (vals.Length > 7) diff --git a/CodeWalker/WorldForm.cs b/CodeWalker/WorldForm.cs index acbb530..eee41d1 100644 --- a/CodeWalker/WorldForm.cs +++ b/CodeWalker/WorldForm.cs @@ -1412,7 +1412,11 @@ namespace CodeWalker MCScenarioPoint vpoint = sn.MyPoint ?? sn.ClusterMyPoint; if ((vpoint != null) && (vpoint?.Type?.IsVehicle ?? false)) { - var vhash = vpoint.ModelSet?.NameHash ?? vpoint.Type?.VehicleModelSetHash ?? 0; + var vhash = vpoint.ModelSet?.NameHash ?? 493038497;//"none" + if ((vhash == 0) || (vhash == 493038497)) + { + vhash = vpoint.Type?.VehicleModelSetHash ?? 0; + } if ((vhash == 0) && (sn.ChainingNode?.Chain?.Edges != null) && (sn.ChainingNode.Chain.Edges.Length > 0)) { var fedge = sn.ChainingNode.Chain.Edges[0]; //for chain nodes, show the first node's model... @@ -1420,7 +1424,11 @@ namespace CodeWalker if (fnode != null) { vpoint = fnode.MyPoint ?? fnode.ClusterMyPoint; - vhash = vpoint.ModelSet?.NameHash ?? vpoint.Type?.VehicleModelSetHash ?? 0; + vhash = vpoint.ModelSet?.NameHash ?? 493038497;//"none" + if ((vhash == 0) || (vhash == 493038497)) + { + vhash = vpoint.Type?.VehicleModelSetHash ?? 0; + } } }