diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index b591209..5c27028 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -1600,9 +1600,20 @@ namespace CodeWalker.GameFiles private void UpdateMloArchetype() { if (!(MloParent.Archetype is MloArchetype mloArchetype)) return; - if (Index >= mloArchetype.entities.Length) return; - MCEntityDef entity = mloArchetype.entities[Index]; + MCEntityDef entity = null; + if ((MloEntitySet?.Entities != null) && (MloEntitySet?.EntitySet?.Entities != null)) + { + var idx = MloEntitySet.Entities.IndexOf(this); + if ((idx < 0) || (idx >= MloEntitySet.EntitySet.Entities.Length)) return; + entity = MloEntitySet.EntitySet.Entities[idx]; + } + else + { + if (Index >= mloArchetype.entities.Length) return; + entity = mloArchetype.entities[Index]; + } + entity._Data.position = _CEntityDef.position; entity._Data.rotation = _CEntityDef.rotation; } diff --git a/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs b/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs index 59bfe45..38c2618 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs @@ -169,13 +169,6 @@ namespace CodeWalker.GameFiles { if (ent == null) return false; - MloInstanceData mloInstance = ent.MloParent?.MloInstance; - MCEntityDef ymcent = mloInstance?.TryGetArchetypeEntity(ent); - if (ymcent != null) - { - return true;//this entity already exists in this MLO... - } - if (roomIndex >= (rooms?.Length ?? 0)) { throw new ArgumentOutOfRangeException($"Room index {roomIndex} exceeds the amount of rooms in {Name}."); @@ -194,11 +187,9 @@ namespace CodeWalker.GameFiles if ((roomIndex >= 0) || (portalIndex >= 0)) { - if (entities == null) entities = new MCEntityDef[0]; - - List entList = entities.ToList(); + var entList = entities?.ToList() ?? new List(); + ent.Index = entList.Count; entList.Add(mcEntityDef); - ent.Index = entList.IndexOf(mcEntityDef); entities = entList.ToArray(); if (roomIndex >= 0) @@ -217,34 +208,60 @@ namespace CodeWalker.GameFiles else if (entsetIndex >= 0) { var entset = entitySets[entsetIndex]; - - //// in the case of entity sets, adding to the entity set instance adds to the base set.... so don't need to add it here.. - //entset.AddEntity(mcEntityDef); - MloInstanceEntitySet entseti = null; - mloInstance?.EntitySets.TryGetValue(entset._Data.name, out entseti); - ent.MloEntitySet = entseti; + var entList = entset.Entities?.ToList() ?? new List(); + entList.Add(mcEntityDef); + entset.Entities = entList.ToArray(); + + var locs = entset.Locations?.ToList() ?? new List(); + locs.Add(0);//choose a better default location? + entset.Locations = locs.ToArray(); + + + var mloInstance = ent.MloParent?.MloInstance; + if ((mloInstance?.EntitySets != null) && (entsetIndex < mloInstance.EntitySets.Length)) + { + ent.MloEntitySet = mloInstance.EntitySets[entsetIndex]; + } } else return false; + UpdateAllEntityIndexes(); return true; } - - - public bool RemoveEntity(YmapEntityDef ent) { + if (ent == null) return false; + + if ((ent.MloEntitySet?.Entities != null) && (ent.MloEntitySet?.EntitySet != null)) + { + var instents = ent.MloEntitySet.Entities; + var set = ent.MloEntitySet.EntitySet; + var idx = instents.IndexOf(ent); + if (idx >= 0) + { + var ents = set.Entities.ToList(); + ents.RemoveAt(idx); + set.Entities = ents.ToArray(); + + var locs = set.Locations.ToList(); + locs.RemoveAt(idx); + set.Locations = locs.ToArray(); + + UpdateAllEntityIndexes(); + return true; + } + return false; + } + if (ent.Index >= entities.Length) return false; - MCEntityDef delent = entities[ent.Index]; - MloInstanceData inst = ent.MloParent?.MloInstance; - if (inst == null) return false; - + var delent = entities[ent.Index]; if (delent != null) { - MCEntityDef[] newentities = new MCEntityDef[entities.Length - 1]; - bool didDel = false; + var newentities = new MCEntityDef[entities.Length - 1]; + var didDel = false; int index = 0; int delIndex = 0; for (int i = 0; i < entities.Length; i++) @@ -256,9 +273,8 @@ namespace CodeWalker.GameFiles continue; } - newentities[index] = entities[i]; - YmapEntityDef ymapEntityDef = inst.TryGetYmapEntity(newentities[index]); - if (ymapEntityDef != null) ymapEntityDef.Index = index; + var newent = entities[i]; + newentities[index] = newent; index++; } @@ -268,6 +284,7 @@ namespace CodeWalker.GameFiles { FixRoomIndexes(delIndex); FixPortalIndexes(delIndex); + UpdateAllEntityIndexes(); } return didDel; } @@ -275,7 +292,6 @@ namespace CodeWalker.GameFiles return false; } - public void AddRoom(MCMloRoomDef room) { if (room == null) return; @@ -294,6 +310,11 @@ namespace CodeWalker.GameFiles var newrooms = rooms.ToList(); newrooms.Remove(room); rooms = newrooms.ToArray(); + + for (int i = 0; i < rooms.Length; i++) + { + rooms[i].Index = i; + } } public void AddPortal(MCMloPortalDef portal) @@ -314,6 +335,11 @@ namespace CodeWalker.GameFiles var newportals = portals.ToList(); newportals.Remove(portal); portals = newportals.ToArray(); + + for (int i = 0; i < portals.Length; i++) + { + portals[i].Index = i; + } } public void AddEntitySet(MCMloEntitySet set) @@ -334,6 +360,13 @@ namespace CodeWalker.GameFiles var newsets = entitySets.ToList(); newsets.Remove(set); entitySets = newsets.ToArray(); + + for (int i = 0; i < entitySets.Length; i++) + { + entitySets[i].Index = i; + } + + UpdateAllEntityIndexes(); } @@ -357,7 +390,6 @@ namespace CodeWalker.GameFiles portal.AttachedObjects = newAttachedObjects.ToArray(); } } - private void FixRoomIndexes(int deletedIndex) { foreach (var room in rooms) @@ -376,6 +408,30 @@ namespace CodeWalker.GameFiles } } + private void UpdateAllEntityIndexes() + { + var index = 0; + if (entities != null) + { + for (int i = 0; i < entities.Length; i++) + { + entities[i].Index = index++; + } + } + if (entitySets != null) + { + for (int e = 0; e < entitySets.Length; e++) + { + var set = entitySets[e]; + if (set?.Entities == null) continue; + for (int i = 0; i < set.Entities.Length; i++) + { + set.Entities[i].Index = index++; + } + } + } + } + public void LoadChildren(Meta meta) { var centities = MetaTypes.ConvertDataArray(meta, MetaName.CEntityDef, _MloArchetypeDefData.entities); @@ -416,6 +472,7 @@ namespace CodeWalker.GameFiles { entitySets[i] = new MCMloEntitySet(meta, centitySets[i], this) { OwnerMlo = this, Index = i }; } + UpdateAllEntityIndexes(); } @@ -520,13 +577,12 @@ namespace CodeWalker.GameFiles public uint[] defaultEntitySets { get; set; } public YmapEntityDef[] Entities { get; set; } - public Dictionary EntitySets { get; set; } + public MloInstanceEntitySet[] EntitySets { get; set; } public MloInstanceData(YmapEntityDef owner, MloArchetype mloa) { Owner = owner; MloArch = mloa; - EntitySets = new Dictionary(); } public void CreateYmapEntities() @@ -538,7 +594,7 @@ namespace CodeWalker.GameFiles var entlist = new List(); for (int i = 0; i < ec; i++) { - YmapEntityDef e = CreateYmapEntity(Owner, MloArch.entities[i], i); + var e = CreateYmapEntity(Owner, MloArch.entities[i], i); entlist.Add(e); } @@ -547,32 +603,32 @@ namespace CodeWalker.GameFiles var entitySets = MloArch.entitySets; if (entitySets != null) { + EntitySets = new MloInstanceEntitySet[entitySets.Length]; for (int i = 0; i < entitySets.Length; i++) { var entitySet = entitySets[i]; + var instset = new MloInstanceEntitySet(entitySet, this); if (entitySet.Entities != null) { - EntitySets[entitySet._Data.name] = new MloInstanceEntitySet(entitySet, this); - MloInstanceEntitySet instset = EntitySets[entitySet._Data.name]; for (int j = 0; j < entitySet.Entities.Length; j++) { - YmapEntityDef e = CreateYmapEntity(Owner, entitySet.Entities[j], lasti); - EntitySets[entitySet._Data.name].Entities.Add(e); + var e = CreateYmapEntity(Owner, entitySet.Entities[j], lasti); + instset.Entities.Add(e); e.MloEntitySet = instset; lasti++; } } + EntitySets[i] = instset; } } - if ((defaultEntitySets != null) && (entitySets != null)) + if ((defaultEntitySets != null) && (EntitySets != null)) { for (var i = 0; i < defaultEntitySets.Length; i++) { uint index = defaultEntitySets[i]; - if (index >= entitySets.Length) continue; - MCMloEntitySet set = entitySets[index]; - MloInstanceEntitySet instset = EntitySets[set._Data.name]; + if (index >= EntitySets.Length) continue; + var instset = EntitySets[index]; instset.Visible = true; } } @@ -602,9 +658,10 @@ namespace CodeWalker.GameFiles if (EntitySets != null) { - foreach (var entitySet in EntitySets) + for (int e = 0; e < EntitySets.Length; e++) { - var entities = entitySet.Value.Entities; + var entitySet = EntitySets[e]; + var entities = entitySet.Entities; if (entities == null) continue; for (int i = 0; i < entities.Count; i++) @@ -699,26 +756,31 @@ namespace CodeWalker.GameFiles if (ymapEntity == null) return null; if (Owner?.Archetype == null) return null; if (!(Owner.Archetype is MloArchetype mloa)) return null; - if (ymapEntity.Index < mloa.entities.Length) + + var index = Array.FindIndex(Entities, x => x == ymapEntity); + if ((index >= 0) && (index < mloa.entities.Length)) { - return mloa.entities[ymapEntity.Index]; + return mloa.entities[index]; } - else + + if (EntitySets != null) { - var idx = ymapEntity.Index - mloa.entities.Length; - if (mloa.entitySets == null) return null; - for (int i = 0; i < mloa.entitySets.Length; i++) + for (int e = 0; e < EntitySets.Length; e++) { - var set = mloa.entitySets[i]; - if (set?.Entities == null) continue; - if (idx < set.Entities.Length) + var entset = EntitySets[e]; + var ents = entset.Entities; + var set = entset.EntitySet; + var setents = set?.Entities; + if ((ents == null) || (setents == null)) continue; + var idx = ents.IndexOf(ymapEntity); + if ((idx >= 0) && (idx < setents.Length)) { - return set.Entities[idx]; + return setents[idx]; } - idx -= set.Entities.Length; } - return null; } + + return null; } public YmapEntityDef TryGetYmapEntity(MCEntityDef mcEntity) @@ -733,17 +795,20 @@ namespace CodeWalker.GameFiles return Entities[index]; } - foreach (var entset in EntitySets.Values) + if (EntitySets != null) { - var ents = entset.Entities; - var set = entset.EntitySet; - var setents = set?.Entities; - if ((ents == null) || (setents == null)) continue; - - var idx = Array.FindIndex(setents, x => x == mcEntity); - if ((idx >= 0) && (idx < ents.Count)) + for (int e = 0; e < EntitySets.Length; e++) { - return ents[idx]; + var entset = EntitySets[e]; + var ents = entset.Entities; + var set = entset.EntitySet; + var setents = set?.Entities; + if ((ents == null) || (setents == null)) continue; + var idx = Array.FindIndex(setents, x => x == mcEntity); + if ((idx >= 0) && (idx < ents.Count)) + { + return ents[idx]; + } } } @@ -771,8 +836,24 @@ namespace CodeWalker.GameFiles for (int i = 0; i < Entities.Length; i++) { - YmapEntityDef e = Entities[i]; - UpdateEntity(e); + var ent = Entities[i]; + UpdateEntity(ent); + } + + if (EntitySets != null) + { + for (int e = 0; e < EntitySets.Length; e++) + { + var entset = EntitySets[e]; + if (entset?.Entities != null) + { + for (int i = 0; i < entset.Entities.Count; i++) + { + var ent = entset.Entities[i]; + UpdateEntity(ent); + } + } + } } } @@ -792,23 +873,27 @@ namespace CodeWalker.GameFiles if (e.MloEntitySet != null) { e.MloEntitySet.AddEntity(e); - return; } - - if (Entities == null) Entities = new YmapEntityDef[0]; - var entities = Entities.ToList(); - entities.Add(e); - Entities = entities.ToArray(); + else + { + if (Entities == null) Entities = new YmapEntityDef[0]; + var entities = Entities.ToList(); + entities.Add(e); + Entities = entities.ToArray(); + } + UpdateAllEntityIndexes(); } public bool DeleteEntity(YmapEntityDef ent) { + var del = false; if (ent.MloEntitySet != null) { - return ent.MloEntitySet.DeleteEntity(ent); + del = ent.MloEntitySet.DeleteEntity(ent); + UpdateAllEntityIndexes(); + return del; } - if (Entities == null) { throw new NullReferenceException("The Entities list returned null in our MloInstanceData. This could be an issue with initialization. The MloInstance probably doesn't exist."); @@ -819,13 +904,11 @@ namespace CodeWalker.GameFiles } int index = 0; - YmapEntityDef[] newentities = new YmapEntityDef[Entities.Length - 1]; - YmapEntityDef delentity = Entities[ent.Index]; - bool del = false; + var newentities = new YmapEntityDef[Entities.Length - 1]; for (int i = 0; i < Entities.Length; i++) { - if (Entities[i] == delentity) + if (i == ent.Index) { del = true; continue; @@ -836,36 +919,43 @@ namespace CodeWalker.GameFiles } if (del) { - if (Owner.Archetype is MloArchetype arch) - { - if (arch.RemoveEntity(ent)) - { - // Delete was successful... - Entities = newentities; - return true; - } - else throw new ArgumentException("The entity could not be removed from the MloArchetype! This shouldn't happen..."); - } - else throw new InvalidCastException("The owner of this archetype's archetype definition is not an MloArchetype. (wtf?)"); + Entities = newentities; + UpdateAllEntityIndexes(); + return true; } else throw new ArgumentException("The entity specified was not found in this MloInstance. It cannot be deleted."); } + public void AddEntitySet(MCMloEntitySet set) + { + var instset = new MloInstanceEntitySet(set, this); + var esets = EntitySets?.ToList() ?? new List(); + esets.Add(instset); + EntitySets = esets.ToArray(); + } + + public bool DeleteEntitySet(MCMloEntitySet set) + { + if (EntitySets == null) return false; + var esets = EntitySets.ToList(); + var rem = esets.RemoveAll(s => s.EntitySet == set); + EntitySets = esets.ToArray(); + UpdateAllEntityIndexes(); + return rem == 1; + } + public void UpdateDefaultEntitySets() { var list = new List(); - var mloarch = Owner?.Archetype as MloArchetype; - if (mloarch?.entitySets != null) + if (EntitySets != null) { - for (uint i = 0; i < mloarch.entitySets.Length; i++) + for (uint i = 0; i < EntitySets.Length; i++) { - var entset = mloarch.entitySets[i]; - MloInstanceEntitySet instset = null; - EntitySets.TryGetValue(entset._Data.name, out instset); - if (instset != null) + var entset = EntitySets[i]; + if (entset != null) { - if (instset.Visible) + if (entset.Visible) { list.Add(i); } @@ -875,6 +965,30 @@ namespace CodeWalker.GameFiles defaultEntitySets = list.ToArray(); } + + private void UpdateAllEntityIndexes() + { + var index = 0; + if (Entities != null) + { + for (int i = 0; i < Entities.Length; i++) + { + Entities[i].Index = index++; + } + } + if (EntitySets != null) + { + for (int e = 0; e < EntitySets.Length; e++) + { + var set = EntitySets[e]; + if (set?.Entities == null) continue; + for (int i = 0; i < set.Entities.Count; i++) + { + set.Entities[i].Index = index++; + } + } + } + } } [TypeConverter(typeof(ExpandableObjectConverter))] @@ -911,54 +1025,12 @@ namespace CodeWalker.GameFiles public void AddEntity(YmapEntityDef ent) { if (Entities == null) Entities = new List(); - ent.Index = Entities.Count; Entities.Add(ent); - if (EntitySet != null) - { - var ents = EntitySet.Entities.ToList(); - var ment = new MCEntityDef(ref ent._CEntityDef, Instance?.MloArch); - ents.Add(ment); - EntitySet.Entities = ents.ToArray(); - } - var locs = Locations?.ToList() ?? new List(); - locs.Add(0);//choose a better default location? - Locations = locs.ToArray(); } public bool DeleteEntity(YmapEntityDef ent) { - var locs = Locations; - if ((Entities == null) || (locs == null)) return false; - - var idx = Entities.IndexOf(ent); - if ((idx < 0) || (idx >= locs.Length)) return false; - - var newlocs = new uint[locs.Length-1]; - var j = 0; - for (int i = 0; i < locs.Length; i++) - { - if (i == idx) continue; - newlocs[j] = locs[i]; - j++; - } - Locations = newlocs; - - var i0 = (Entities.Count > 0) ? Entities[0].Index : 0; - - Entities.RemoveAt(idx); - - for (int i = 0; i < Entities.Count; i++) - { - Entities[i].Index = i0 + i; - } - - if (EntitySet?.Entities != null) - { - var ents = EntitySet.Entities.ToList(); - ents.RemoveAt(idx); - EntitySet.Entities = ents.ToArray(); - } - - return true; + if (Entities == null) return false; + return Entities.Remove(ent); } } diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs index d95cc7d..830585e 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs @@ -2604,7 +2604,7 @@ namespace CodeWalker.GameFiles { get { - return _Data.roomFrom.ToString() + " to " + _Data.roomTo.ToString(); + return Index.ToString() + ": " + _Data.roomFrom.ToString() + " to " + _Data.roomTo.ToString(); } } diff --git a/CodeWalker.Core/World/Space.cs b/CodeWalker.Core/World/Space.cs index 46f88ea..8dcafb2 100644 --- a/CodeWalker.Core/World/Space.cs +++ b/CodeWalker.Core/World/Space.cs @@ -1286,11 +1286,12 @@ namespace CodeWalker.World } if (mlodat.EntitySets != null) { - foreach (var entitysets in mlodat.EntitySets) + for (int e = 0; e < mlodat.EntitySets.Length; e++) { - var entityset = entitysets.Value; + var entityset = mlodat.EntitySets[e]; if (!entityset.Visible) continue; var entities = entityset.Entities; + if (entities == null) continue; for (int i = 0; i < entities.Count; i++) //should really improve this by using rooms! { var intent = entities[i]; @@ -1509,11 +1510,12 @@ namespace CodeWalker.World } if (mlodat.EntitySets != null) { - foreach (var entitysets in mlodat.EntitySets) + for (int e = 0; e < mlodat.EntitySets.Length; e++) { - var entityset = entitysets.Value; + var entityset = mlodat.EntitySets[e]; if (!entityset.Visible) continue; var entities = entityset.Entities; + if (entities == null) continue; for (int i = 0; i < entities.Count; i++) //should really improve this by using rooms! { var intent = entities[i]; diff --git a/Project/Panels/EditYmapEntityPanel.cs b/Project/Panels/EditYmapEntityPanel.cs index bd1f447..80c0eb5 100644 --- a/Project/Panels/EditYmapEntityPanel.cs +++ b/Project/Panels/EditYmapEntityPanel.cs @@ -130,10 +130,15 @@ namespace CodeWalker.Project.Panels MiloFloorIDTextBox.Text = milo.floorId.ToString(); MiloNumExitPortalsTextBox.Text = milo.numExitPortals.ToString(); MiloFlagsTextBox.Text = milo.MLOInstflags.ToString(); - foreach (var sets in CurrentEntity.MloInstance.EntitySets) + if (CurrentEntity.MloInstance.EntitySets != null) { - MloInstanceEntitySet set = sets.Value; - MiloEntitySetsListBox.Items.Add(set.EntitySet.ToString(), set.Visible); + foreach (var set in CurrentEntity.MloInstance.EntitySets) + { + if (set?.EntitySet != null) + { + MiloEntitySetsListBox.Items.Add(set.EntitySet.ToString(), set.Visible); + } + } } } else @@ -793,11 +798,9 @@ namespace CodeWalker.Project.Panels { if (populatingui) return; var inst = CurrentEntity?.MloInstance; - var mloarch = CurrentEntity?.Archetype as MloArchetype; - if ((inst != null) && (mloarch != null)) + if ((inst != null) && (inst.EntitySets != null) && (e.Index < inst.EntitySets.Length) && (e.Index >= 0)) { - MloInstanceEntitySet mloInstanceEntitySet = inst.EntitySets[mloarch.entitySets[e.Index]._Data.name]; - mloInstanceEntitySet.Visible = e.NewValue == CheckState.Checked; + inst.EntitySets[e.Index].Visible = e.NewValue == CheckState.Checked; return; } e.NewValue = CheckState.Unchecked; diff --git a/Project/Panels/EditYtypMloRoomPanel.cs b/Project/Panels/EditYtypMloRoomPanel.cs index f556510..11dd9b6 100644 --- a/Project/Panels/EditYtypMloRoomPanel.cs +++ b/Project/Panels/EditYtypMloRoomPanel.cs @@ -82,7 +82,7 @@ namespace CodeWalker.Project.Panels TreeNode tn = ProjectForm.ProjectExplorer?.FindMloRoomTreeNode(CurrentRoom); if (tn != null) { - tn.Text = CurrentRoom.RoomName; + tn.Text = CurrentRoom.Index.ToString() + ": " + CurrentRoom.RoomName; } UpdateFormTitle(); diff --git a/Project/Panels/ProjectExplorerPanel.cs b/Project/Panels/ProjectExplorerPanel.cs index f963f64..614874f 100644 --- a/Project/Panels/ProjectExplorerPanel.cs +++ b/Project/Panels/ProjectExplorerPanel.cs @@ -281,7 +281,7 @@ namespace CodeWalker.Project.Panels for (int j = 0; j < rooms.Length; j++) { var room = rooms[j]; - var roomnode = roomsnode.Nodes.Add(room.RoomName); + var roomnode = roomsnode.Nodes.Add(room.Index.ToString() + ": " + room.RoomName); roomnode.Tag = room; var roomentities = room.AttachedObjects; if ((roomentities != null) && (entities != null)) @@ -646,6 +646,10 @@ namespace CodeWalker.Project.Panels } public void SetYmapHasChanged(YmapFile ymap, bool changed) { + if (ymap != null) + { + ymap.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -670,6 +674,10 @@ namespace CodeWalker.Project.Panels } public void SetYtypHasChanged(YtypFile ytyp, bool changed) { + if (ytyp != null) + { + ytyp.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -694,6 +702,10 @@ namespace CodeWalker.Project.Panels } public void SetYndHasChanged(YndFile ynd, bool changed) { + if (ynd != null) + { + ynd.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -718,6 +730,10 @@ namespace CodeWalker.Project.Panels } public void SetYnvHasChanged(YnvFile ynv, bool changed) { + if (ynv != null) + { + ynv.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -742,6 +758,10 @@ namespace CodeWalker.Project.Panels } public void SetTrainTrackHasChanged(TrainTrack track, bool changed) { + if (track != null) + { + track.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -766,6 +786,10 @@ namespace CodeWalker.Project.Panels } public void SetScenarioHasChanged(YmtFile scenario, bool changed) { + if (scenario != null) + { + scenario.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -790,6 +814,10 @@ namespace CodeWalker.Project.Panels } public void SetAudioRelHasChanged(RelFile rel, bool changed) { + if (rel != null) + { + rel.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var pnode = ProjectTreeView.Nodes[0]; @@ -814,6 +842,10 @@ namespace CodeWalker.Project.Panels } public void SetGrassBatchHasChanged(YmapGrassInstanceBatch batch, bool changed) { + if (batch?.Ymap != null) + { + batch.Ymap.HasChanged = true; + } if (ProjectTreeView.Nodes.Count > 0) { var gbnode = FindGrassTreeNode(batch); @@ -1791,6 +1823,33 @@ namespace CodeWalker.Project.Panels tn.Parent.Nodes.Remove(tn); } } + public void RemoveMloRoomTreeNode(MCMloRoomDef room) + { + var tn = FindMloRoomTreeNode(room); + if ((tn != null) && (tn.Parent != null)) + { + tn.Parent.Text = "Rooms (" + (room.OwnerMlo?.rooms?.Length.ToString() ?? "0") + ")"; + tn.Parent.Nodes.Remove(tn); + } + } + public void RemoveMloPortalTreeNode(MCMloPortalDef portal) + { + var tn = FindMloPortalTreeNode(portal); + if ((tn != null) && (tn.Parent != null)) + { + tn.Parent.Text = "Portals (" + (portal.OwnerMlo?.portals?.Length.ToString() ?? "0") + ")"; + tn.Parent.Nodes.Remove(tn); + } + } + public void RemoveMloEntitySetTreeNode(MCMloEntitySet set) + { + var tn = FindMloEntitySetTreeNode(set); + if ((tn != null) && (tn.Parent != null)) + { + tn.Parent.Text = "Entity Sets (" + (set.OwnerMlo?.entitySets?.Length.ToString() ?? "0") + ")"; + tn.Parent.Nodes.Remove(tn); + } + } public void RemovePathNodeTreeNode(YndNode node) { var tn = FindPathNodeTreeNode(node); diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index 6f5e017..b9f02cf 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -706,7 +706,6 @@ namespace CodeWalker.Project if (instance != null) { CurrentEntity = instance.TryGetYmapEntity(CurrentMloEntity); - CurrentYmapFile = instance.Owner?.Ymap; } @@ -721,7 +720,6 @@ namespace CodeWalker.Project else { CurrentArchetype = CurrentEntity.Archetype; - CurrentYmapFile = CurrentEntity.Ymap; } } @@ -2339,45 +2337,50 @@ namespace CodeWalker.Project return; } + if ((CurrentMloEntity == null) && (CurrentEntity != null)) + { + CurrentMloEntity = mloInstance.TryGetArchetypeEntity(CurrentEntity); + } + if ((CurrentMloRoom == null) && (CurrentMloPortal == null) && (CurrentMloEntitySet == null)) { - if ((mloArch.rooms?.Length??0) <= 0) + if (CurrentMloEntity != null) { - MessageBox.Show($@"Mlo {mloArch.Name} has no rooms! Cannot create entity."); - return; + CurrentMloRoom = mloArch.GetEntityRoom(CurrentMloEntity); + CurrentMloPortal = mloArch.GetEntityPortal(CurrentMloEntity); + CurrentMloEntitySet = mloArch.GetEntitySet(CurrentMloEntity); + } + else + { + if ((mloArch.rooms?.Length??0) <= 0) + { + MessageBox.Show($@"Mlo {mloArch.Name} has no rooms! Cannot create entity."); + return; + } + CurrentMloRoom = mloArch.rooms[0]; } - CurrentMloRoom = mloArch?.GetEntityRoom(CurrentMloEntity); } int roomIndex = CurrentMloRoom?.Index ?? -1; - if (roomIndex >= 0) + if (roomIndex >= (mloArch.rooms?.Length ?? 0)) { - if (roomIndex >= (mloArch.rooms?.Length??0)) - { - MessageBox.Show($@"Room at index {roomIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has {(mloArch.rooms?.Length??0)} rooms."); - return; - } + MessageBox.Show($@"Room at index {roomIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has {(mloArch.rooms?.Length ?? 0)} rooms."); + return; } int portalIndex = CurrentMloPortal?.Index ?? -1; - if (portalIndex >= 0) + if (portalIndex >= (mloArch.portals?.Length ?? 0)) { - if (portalIndex >= (mloArch.portals?.Length??0)) - { - MessageBox.Show($@"Portal at index {portalIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has {(mloArch.portals?.Length??0)} portals."); - return; - } + MessageBox.Show($@"Portal at index {portalIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has {(mloArch.portals?.Length ?? 0)} portals."); + return; } int entsetIndex = CurrentMloEntitySet?.Index ?? -1; - if (entsetIndex >= 0) + if (entsetIndex >= (mloArch.entitySets?.Length ?? 0)) { - if (entsetIndex >= (mloArch.entitySets?.Length ?? 0)) - { - MessageBox.Show($@"EntitySet at index {entsetIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has {(mloArch.entitySets?.Length ?? 0)} entitySets."); - return; - } + MessageBox.Show($@"EntitySet at index {entsetIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has {(mloArch.entitySets?.Length ?? 0)} entitySets."); + return; } @@ -2418,8 +2421,8 @@ namespace CodeWalker.Project cent.rotation = rot.ToVector4(); var createindex = mloArch.entities.Length; - MCEntityDef ment = new MCEntityDef(ref cent, mloArch); - YmapEntityDef outEnt = mloInstance.CreateYmapEntity(mloInstance.Owner, ment, createindex); + var ment = new MCEntityDef(ref cent, mloArch); + var outEnt = mloInstance.CreateYmapEntity(mloInstance.Owner, ment, createindex); try { @@ -2428,14 +2431,14 @@ namespace CodeWalker.Project lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... { mloArch.AddEntity(outEnt, roomIndex, portalIndex, entsetIndex); - mloInstance.AddEntity(outEnt);//in the case of entitySets, this will add to the archetype entity set... weird and bad - should change this! + mloInstance.AddEntity(outEnt); outEnt.SetArchetype(GameFileCache.GetArchetype(cent.archetypeName)); } } else { mloArch.AddEntity(outEnt, roomIndex, portalIndex, entsetIndex); - mloInstance.AddEntity(outEnt);//in the case of entitySets, this will add to the archetype entity set... weird and bad - should change this! + mloInstance.AddEntity(outEnt); outEnt.SetArchetype(GameFileCache.GetArchetype(cent.archetypeName)); } } @@ -2445,14 +2448,17 @@ namespace CodeWalker.Project return; } + ment = mloInstance.TryGetArchetypeEntity(outEnt); + LoadProjectTree(); - ProjectExplorer?.TrySelectMloEntityTreeNode(mloInstance.TryGetArchetypeEntity(outEnt)); + ProjectExplorer?.TrySelectMloEntityTreeNode(ment); CurrentEntity = outEnt; + CurrentMloEntity = ment; CurrentYtypFile = CurrentEntity.MloParent?.Archetype?.Ytyp; } public void NewMloRoom(MCMloRoomDef copy = null) { - var mlo = CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo ?? (CurrentEntity?.MloParent.Archetype as MloArchetype); + var mlo = CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo ?? (CurrentEntity?.MloParent.Archetype as MloArchetype) ?? (CurrentArchetype as MloArchetype); if (mlo == null) return; if (copy == null) @@ -2488,7 +2494,7 @@ namespace CodeWalker.Project } public void NewMloPortal(MCMloPortalDef copy = null) { - var mlo = CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo ?? (CurrentEntity?.MloParent.Archetype as MloArchetype); + var mlo = CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo ?? (CurrentEntity?.MloParent.Archetype as MloArchetype) ?? (CurrentArchetype as MloArchetype); if (mlo == null) return; if (copy == null) @@ -2500,13 +2506,17 @@ namespace CodeWalker.Project if (copy != null) { portal._Data = copy._Data; - portal.Corners = (Vector4[])copy.Corners.Clone(); + portal.Corners = (Vector4[])copy.Corners?.Clone(); } else { portal._Data.roomFrom = 1; portal._Data.roomTo = 0; } + if (portal.Corners == null) + { + portal.Corners = new[] { new Vector4(0, 0, 0, float.NaN), new Vector4(0, 0, 1, float.NaN), new Vector4(0, 1, 1, float.NaN), new Vector4(0, 1, 0, float.NaN) }; + } mlo.AddPortal(portal); @@ -2522,7 +2532,7 @@ namespace CodeWalker.Project } public void NewMloEntitySet(MCMloEntitySet copy = null) { - var mlo = CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo ?? (CurrentEntity?.MloParent.Archetype as MloArchetype); + var mlo = CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo ?? (CurrentEntity?.MloParent.Archetype as MloArchetype) ?? (CurrentArchetype as MloArchetype); if (mlo == null) return; if (copy == null) @@ -2546,6 +2556,7 @@ namespace CodeWalker.Project var mloInstance = TryGetMloInstance(mlo); if (mloInstance != null) { + mloInstance.AddEntitySet(set); } LoadProjectTree(); @@ -2617,9 +2628,13 @@ namespace CodeWalker.Project MloInstanceData mloInstance = CurrentEntity.MloParent.MloInstance; if (mloInstance == null) return false; - var ent = CurrentEntity; - var mcEnt = mloInstance.TryGetArchetypeEntity(ent); + + var delent = CurrentEntity; //CurrentEntity could get changed when we remove the tree node.. + var delytyp = CurrentEntity.MloParent.Archetype.Ytyp; + var mcEnt = mloInstance.TryGetArchetypeEntity(CurrentEntity); + ProjectExplorer?.RemoveMloEntityTreeNode(mcEnt); + ProjectExplorer?.SetYtypHasChanged(delytyp, true); try { @@ -2627,13 +2642,15 @@ namespace CodeWalker.Project { lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... { - mloInstance.DeleteEntity(ent); + mloArchetype.RemoveEntity(delent); + mloInstance.DeleteEntity(delent); //WorldForm.SelectItem(null, null, null); } } else { - mloInstance.DeleteEntity(ent); + mloArchetype.RemoveEntity(delent); + mloInstance.DeleteEntity(delent); } } catch (Exception e) // various failures could happen so we'll use a trycatch for when an exception is thrown. @@ -2642,13 +2659,10 @@ namespace CodeWalker.Project return false; } - var delent = ent; - var delytyp = delent.MloParent.Archetype.Ytyp; - - ProjectExplorer?.SetYtypHasChanged(delytyp, true); ClosePanel((EditYmapEntityPanel p) => { return p.Tag == delent; }); CurrentEntity = null; + CurrentMloEntity = null; WorldForm.SelectItem(null); return true; @@ -2670,6 +2684,11 @@ namespace CodeWalker.Project { } + ProjectExplorer?.RemoveMloRoomTreeNode(CurrentMloRoom); + ProjectExplorer?.SetYtypHasChanged(mlo.Ytyp, true); + ClosePanel((EditYtypMloRoomPanel p) => { return p.Tag == CurrentMloRoom; }); + CurrentMloRoom = null; + return true; } public bool DeleteMloPortal() @@ -2689,6 +2708,11 @@ namespace CodeWalker.Project { } + ProjectExplorer?.RemoveMloPortalTreeNode(CurrentMloPortal); + ProjectExplorer?.SetYtypHasChanged(mlo.Ytyp, true); + ClosePanel((EditYtypMloPortalPanel p) => { return p.Tag == CurrentMloPortal; }); + CurrentMloPortal = null; + return true; } public bool DeleteMloEntitySet() @@ -2706,8 +2730,14 @@ namespace CodeWalker.Project var mloInstance = TryGetMloInstance(mlo); if (mloInstance != null) { + mloInstance.DeleteEntitySet(CurrentMloEntitySet); } + ProjectExplorer?.RemoveMloEntitySetTreeNode(CurrentMloEntitySet); + ProjectExplorer?.SetYtypHasChanged(mlo.Ytyp, true); + ClosePanel((EditYtypMloEntSetPanel p) => { return p.Tag == CurrentMloEntitySet; }); + CurrentMloEntitySet = null; + return true; } diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index 3b88ce4..05d014f 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -1958,12 +1958,13 @@ namespace CodeWalker.Rendering } if (ent.MloInstance.EntitySets != null) { - foreach (var entitysets in ent.MloInstance.EntitySets) + for (int e = 0; e < ent.MloInstance.EntitySets.Length; e++) { - var entityset = entitysets.Value; + var entityset = ent.MloInstance.EntitySets[e]; if (!entityset.VisibleOrForced) continue; var entities = entityset.Entities; + if (entities == null) continue; for (int i = 0; i < entities.Count; i++) { var intent = entities[i]; diff --git a/WorldForm.cs b/WorldForm.cs index bc9ef0f..3571735 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -5304,7 +5304,7 @@ namespace CodeWalker } else { - //project not open, or entity not selected there, just remove the entity from the ymap/nlo... + //project not open, or entity not selected there, just remove the entity from the ymap/mlo... var ymap = ent.Ymap; var instance = ent.MloParent?.MloInstance; if (ymap == null)