From 0e11478d7b498ded5411ba6dd3627a0097a8d84d Mon Sep 17 00:00:00 2001 From: dexy Date: Sat, 28 Dec 2019 23:24:36 +1100 Subject: [PATCH] MLO editing progress --- .../GameFiles/FileTypes/YmapFile.cs | 6 +- .../GameFiles/MetaTypes/Archetype.cs | 231 +++++++++++------- .../Panels/EditYtypMloEntSetPanel.Designer.cs | 30 ++- Project/Panels/EditYtypMloEntSetPanel.cs | 12 + .../Panels/EditYtypMloPortalPanel.Designer.cs | 37 ++- Project/Panels/EditYtypMloPortalPanel.cs | 12 + .../Panels/EditYtypMloRoomPanel.Designer.cs | 73 ++++-- Project/Panels/EditYtypMloRoomPanel.cs | 12 + Project/ProjectForm.cs | 230 +++++++++++------ WorldForm.cs | 10 +- 10 files changed, 450 insertions(+), 203 deletions(-) diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index 9b232d1..6021219 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -1380,7 +1380,7 @@ namespace CodeWalker.GameFiles //} IsMlo = true; - MloInstance = new MloInstanceData(); + MloInstance = new MloInstanceData(this, null);//is this necessary..? will get created in SetArchetype.. MloInstance.Instance = mlo; UpdateWidgetPosition(); @@ -1399,7 +1399,7 @@ namespace CodeWalker.GameFiles { //transform interior entities into world space... var mloa = Archetype as MloArchetype; - MloInstance = new MloInstanceData(); + MloInstance = new MloInstanceData(this, mloa); MloInstance._Instance = new CMloInstanceDef { CEntityDef = _CEntityDef }; if (mloa != null) { @@ -1411,7 +1411,7 @@ namespace CodeWalker.GameFiles Ymap.MloEntities = mloEntities.ToArray(); } - MloInstance.CreateYmapEntities(this, mloa); + MloInstance.CreateYmapEntities(); } if (BSRadius == 0.0f) diff --git a/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs b/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs index 5832bbb..59bfe45 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/Archetype.cs @@ -165,59 +165,73 @@ namespace CodeWalker.GameFiles _MloArchetypeDefData = arch.MloArchetypeDef; } - public bool AddEntity(YmapEntityDef ent, int roomIndex) + public bool AddEntity(YmapEntityDef ent, int roomIndex, int portalIndex = -1, int entsetIndex = -1) { if (ent == null) return false; - // entity already exists in our array. so we'll just add - // it to the instanced entities list and continue. MloInstanceData mloInstance = ent.MloParent?.MloInstance; MCEntityDef ymcent = mloInstance?.TryGetArchetypeEntity(ent); if (ymcent != null) { - return true; + return true;//this entity already exists in this MLO... } - if (roomIndex > rooms.Length) + if (roomIndex >= (rooms?.Length ?? 0)) { throw new ArgumentOutOfRangeException($"Room index {roomIndex} exceeds the amount of rooms in {Name}."); } + if (portalIndex >= (portals?.Length ?? 0)) + { + throw new ArgumentOutOfRangeException($"Portal index {portalIndex} exceeds the amount of portals in {Name}."); + } + if (entsetIndex >= (entitySets?.Length ?? 0)) + { + throw new ArgumentOutOfRangeException($"EntitySet index {entsetIndex} exceeds the amount of entitySets in {Name}."); + } var mcEntityDef = new MCEntityDef(ref ent._CEntityDef, this); - // Add the new entity def to the entities list. - AddEntity(ent, mcEntityDef); - // Update the attached objects in the room index specified. - AttachEntityToRoom(ent, roomIndex); + if ((roomIndex >= 0) || (portalIndex >= 0)) + { + if (entities == null) entities = new MCEntityDef[0]; + + List entList = entities.ToList(); + entList.Add(mcEntityDef); + ent.Index = entList.IndexOf(mcEntityDef); + entities = entList.ToArray(); + + if (roomIndex >= 0) + { + var attachedObjs = rooms[roomIndex].AttachedObjects?.ToList() ?? new List(); + attachedObjs.Add((uint)ent.Index); + rooms[roomIndex].AttachedObjects = attachedObjs.ToArray(); + } + if (portalIndex >= 0) + { + var attachedObjs = portals[portalIndex].AttachedObjects?.ToList() ?? new List(); + attachedObjs.Add((uint)ent.Index); + portals[portalIndex].AttachedObjects = attachedObjs.ToArray(); + } + } + 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; + } + else return false; + + return true; } - // attaches the specified ymap entity index to the room at roomIndex. - private void AttachEntityToRoom(YmapEntityDef ent, int roomIndex) - { - if (roomIndex > rooms.Length) - { - return; // the room index is bigger than the rooms we have... - } - var attachedObjs = rooms[roomIndex].AttachedObjects?.ToList() ?? new List(); - attachedObjs.Add((uint)ent.Index); - rooms[roomIndex].AttachedObjects = attachedObjs.ToArray(); - } - // Adds an entity to the entities array and then set's the index of the - // ymap entity to the index of the new MCEntityDef. - private void AddEntity(YmapEntityDef ent, MCEntityDef mcEntityDef) - { - if (ent == null || mcEntityDef == null) return; // no entity?... - // initialize the array. - if (entities == null) entities = new MCEntityDef[0]; - - List entList = entities.ToList(); - entList.Add(mcEntityDef); - ent.Index = entList.IndexOf(mcEntityDef); - entities = entList.ToArray(); - } public bool RemoveEntity(YmapEntityDef ent) { @@ -500,6 +514,7 @@ namespace CodeWalker.GameFiles public class MloInstanceData { public YmapEntityDef Owner { get; set; } + public MloArchetype MloArch { get; set; } public CMloInstanceDef _Instance; public CMloInstanceDef Instance { get { return _Instance; } set { _Instance = value; } } public uint[] defaultEntitySets { get; set; } @@ -507,28 +522,29 @@ namespace CodeWalker.GameFiles public YmapEntityDef[] Entities { get; set; } public Dictionary EntitySets { get; set; } - public MloInstanceData() + public MloInstanceData(YmapEntityDef owner, MloArchetype mloa) { + Owner = owner; + MloArch = mloa; EntitySets = new Dictionary(); } - public void CreateYmapEntities(YmapEntityDef owner, MloArchetype mloa) + public void CreateYmapEntities() { - Owner = owner; - if (owner == null) return; - if (mloa.entities == null) return; - var ec = mloa.entities.Length; + if (Owner == null) return; + if (MloArch?.entities == null) return; + var ec = MloArch.entities.Length; var entlist = new List(); for (int i = 0; i < ec; i++) { - YmapEntityDef e = CreateYmapEntity(owner, mloa.entities[i], i); + YmapEntityDef e = CreateYmapEntity(Owner, MloArch.entities[i], i); entlist.Add(e); } int lasti = ec; - var entitySets = mloa.entitySets; + var entitySets = MloArch.entitySets; if (entitySets != null) { for (int i = 0; i < entitySets.Length; i++) @@ -540,7 +556,7 @@ namespace CodeWalker.GameFiles MloInstanceEntitySet instset = EntitySets[entitySet._Data.name]; for (int j = 0; j < entitySet.Entities.Length; j++) { - YmapEntityDef e = CreateYmapEntity(owner, entitySet.Entities[j], lasti); + YmapEntityDef e = CreateYmapEntity(Owner, entitySet.Entities[j], lasti); EntitySets[entitySet._Data.name].Entities.Add(e); e.MloEntitySet = instset; lasti++; @@ -663,56 +679,6 @@ namespace CodeWalker.GameFiles } } - public bool DeleteEntity(YmapEntityDef ent) - { - if (ent.MloEntitySet != null) - { - return ent.MloEntitySet.DeleteEntity(ent); - } - - - 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."); - } - if (ent.Index >= Entities.Length) - { - throw new ArgumentOutOfRangeException("The index of the entity was greater than the amount of entities that exist in this MloInstance. Likely an issue with initializion."); - } - - int index = 0; - YmapEntityDef[] newentities = new YmapEntityDef[Entities.Length - 1]; - YmapEntityDef delentity = Entities[ent.Index]; - bool del = false; - - for (int i = 0; i < Entities.Length; i++) - { - if (Entities[i] == delentity) - { - del = true; - continue; - } - newentities[index] = Entities[i]; - newentities[index].Index = index; - index++; - } - 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?)"); - } - else throw new ArgumentException("The entity specified was not found in this MloInstance. It cannot be deleted."); - } - public YmapEntityDef CreateYmapEntity(YmapEntityDef owner, MCEntityDef ment, int index) { YmapEntityDef e = new YmapEntityDef(null, index, ref ment._Data); @@ -822,12 +788,69 @@ namespace CodeWalker.GameFiles public void AddEntity(YmapEntityDef e) { if (e == null) return; + + 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(); } + public bool DeleteEntity(YmapEntityDef ent) + { + if (ent.MloEntitySet != null) + { + return ent.MloEntitySet.DeleteEntity(ent); + } + + + 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."); + } + if (ent.Index >= Entities.Length) + { + throw new ArgumentOutOfRangeException("The index of the entity was greater than the amount of entities that exist in this MloInstance. Likely an issue with initializion."); + } + + int index = 0; + YmapEntityDef[] newentities = new YmapEntityDef[Entities.Length - 1]; + YmapEntityDef delentity = Entities[ent.Index]; + bool del = false; + + for (int i = 0; i < Entities.Length; i++) + { + if (Entities[i] == delentity) + { + del = true; + continue; + } + newentities[index] = Entities[i]; + newentities[index].Index = index; + index++; + } + 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?)"); + } + else throw new ArgumentException("The entity specified was not found in this MloInstance. It cannot be deleted."); + } + public void UpdateDefaultEntitySets() { var list = new List(); @@ -885,7 +908,22 @@ 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; @@ -913,6 +951,13 @@ namespace CodeWalker.GameFiles Entities[i].Index = i0 + i; } + if (EntitySet?.Entities != null) + { + var ents = EntitySet.Entities.ToList(); + ents.RemoveAt(idx); + EntitySet.Entities = ents.ToArray(); + } + return true; } } diff --git a/Project/Panels/EditYtypMloEntSetPanel.Designer.cs b/Project/Panels/EditYtypMloEntSetPanel.Designer.cs index e5c7625..411cc1e 100644 --- a/Project/Panels/EditYtypMloEntSetPanel.Designer.cs +++ b/Project/Panels/EditYtypMloEntSetPanel.Designer.cs @@ -39,6 +39,8 @@ this.label4 = new System.Windows.Forms.Label(); this.SelectedLocationEntityLabel = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); + this.AddEntityButton = new System.Windows.Forms.Button(); + this.DeleteButton = new System.Windows.Forms.Button(); this.SelectedLocationGroupBox.SuspendLayout(); this.SuspendLayout(); // @@ -89,7 +91,7 @@ this.LocationsListBox.FormattingEnabled = true; this.LocationsListBox.Location = new System.Drawing.Point(72, 50); this.LocationsListBox.Name = "LocationsListBox"; - this.LocationsListBox.Size = new System.Drawing.Size(200, 433); + this.LocationsListBox.Size = new System.Drawing.Size(200, 381); this.LocationsListBox.TabIndex = 10; this.LocationsListBox.SelectedIndexChanged += new System.EventHandler(this.LocationsListBox_SelectedIndexChanged); // @@ -147,11 +149,35 @@ this.label2.TabIndex = 10; this.label2.Text = "Entity:"; // + // AddEntityButton + // + this.AddEntityButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.AddEntityButton.Location = new System.Drawing.Point(72, 453); + this.AddEntityButton.Name = "AddEntityButton"; + this.AddEntityButton.Size = new System.Drawing.Size(95, 23); + this.AddEntityButton.TabIndex = 39; + this.AddEntityButton.Text = "Add Entity"; + this.AddEntityButton.UseVisualStyleBackColor = true; + this.AddEntityButton.Click += new System.EventHandler(this.AddEntityButton_Click); + // + // DeleteButton + // + this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.DeleteButton.Location = new System.Drawing.Point(313, 453); + this.DeleteButton.Name = "DeleteButton"; + this.DeleteButton.Size = new System.Drawing.Size(95, 23); + this.DeleteButton.TabIndex = 40; + this.DeleteButton.Text = "Delete Entity Set"; + this.DeleteButton.UseVisualStyleBackColor = true; + this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); + // // EditYtypMloEntSetPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(565, 505); + this.Controls.Add(this.AddEntityButton); + this.Controls.Add(this.DeleteButton); this.Controls.Add(this.SelectedLocationGroupBox); this.Controls.Add(this.LocationsListBox); this.Controls.Add(this.label1); @@ -180,5 +206,7 @@ private System.Windows.Forms.Label label2; private System.Windows.Forms.ComboBox SelectedLocationRoomCombo; private System.Windows.Forms.Label label4; + private System.Windows.Forms.Button AddEntityButton; + private System.Windows.Forms.Button DeleteButton; } } \ No newline at end of file diff --git a/Project/Panels/EditYtypMloEntSetPanel.cs b/Project/Panels/EditYtypMloEntSetPanel.cs index a241d9f..dc07e5e 100644 --- a/Project/Panels/EditYtypMloEntSetPanel.cs +++ b/Project/Panels/EditYtypMloEntSetPanel.cs @@ -166,6 +166,18 @@ namespace CodeWalker.Project.Panels } + private void AddEntityButton_Click(object sender, EventArgs e) + { + ProjectForm.SetProjectItem(CurrentEntitySet); + ProjectForm.NewMloEntity(); + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + ProjectForm.SetProjectItem(CurrentEntitySet); + ProjectForm.DeleteMloEntitySet(); + } + diff --git a/Project/Panels/EditYtypMloPortalPanel.Designer.cs b/Project/Panels/EditYtypMloPortalPanel.Designer.cs index 2f9e54e..a890aaf 100644 --- a/Project/Panels/EditYtypMloPortalPanel.Designer.cs +++ b/Project/Panels/EditYtypMloPortalPanel.Designer.cs @@ -44,6 +44,8 @@ this.CornersTextBox = new CodeWalker.WinForms.TextBoxFix(); this.label6 = new System.Windows.Forms.Label(); this.FlagsCheckedListBox = new System.Windows.Forms.CheckedListBox(); + this.AddEntityButton = new System.Windows.Forms.Button(); + this.DeleteButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // FlagsTextBox @@ -175,17 +177,17 @@ this.FlagsCheckedListBox.CheckOnClick = true; this.FlagsCheckedListBox.FormattingEnabled = true; this.FlagsCheckedListBox.Items.AddRange(new object[] { - "1 - Hide from outside", - "2 - Unk02", + "1 - Hide inside from outside", + "2 - Hide outside from inside", "4 - Mirror", "8 - Extra bloom", "16 - Unk05", - "32 - Unk06", + "32 - Use exterior LOD", "64 - Hide when door closed", "128 - Unk08", - "256 - Render sky light", + "256 - Mirror exterior portals", "512 - Unk10", - "1024 - Render exterior", + "1024 - Mirror limbo entities", "2048 - Unk12", "4096 - Unk13", "8192 - Unk14"}); @@ -195,11 +197,34 @@ this.FlagsCheckedListBox.TabIndex = 36; this.FlagsCheckedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.FlagsCheckedListBox_ItemCheck); // + // AddEntityButton + // + this.AddEntityButton.Location = new System.Drawing.Point(107, 372); + this.AddEntityButton.Name = "AddEntityButton"; + this.AddEntityButton.Size = new System.Drawing.Size(95, 23); + this.AddEntityButton.TabIndex = 37; + this.AddEntityButton.Text = "Add Entity"; + this.AddEntityButton.UseVisualStyleBackColor = true; + this.AddEntityButton.Click += new System.EventHandler(this.AddEntityButton_Click); + // + // DeleteButton + // + this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.DeleteButton.Location = new System.Drawing.Point(348, 372); + this.DeleteButton.Name = "DeleteButton"; + this.DeleteButton.Size = new System.Drawing.Size(95, 23); + this.DeleteButton.TabIndex = 38; + this.DeleteButton.Text = "Delete Portal"; + this.DeleteButton.UseVisualStyleBackColor = true; + this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); + // // EditYtypMloPortalPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(565, 505); + this.Controls.Add(this.AddEntityButton); + this.Controls.Add(this.DeleteButton); this.Controls.Add(this.FlagsCheckedListBox); this.Controls.Add(this.label6); this.Controls.Add(this.CornersTextBox); @@ -240,5 +265,7 @@ private WinForms.TextBoxFix CornersTextBox; private System.Windows.Forms.Label label6; private System.Windows.Forms.CheckedListBox FlagsCheckedListBox; + private System.Windows.Forms.Button AddEntityButton; + private System.Windows.Forms.Button DeleteButton; } } \ No newline at end of file diff --git a/Project/Panels/EditYtypMloPortalPanel.cs b/Project/Panels/EditYtypMloPortalPanel.cs index 325a2d1..83e61d6 100644 --- a/Project/Panels/EditYtypMloPortalPanel.cs +++ b/Project/Panels/EditYtypMloPortalPanel.cs @@ -252,5 +252,17 @@ namespace CodeWalker.Project.Panels ProjectForm.SetYtypHasChanged(true); } } + + private void AddEntityButton_Click(object sender, EventArgs e) + { + ProjectForm.SetProjectItem(CurrentPortal); + ProjectForm.NewMloEntity(); + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + ProjectForm.SetProjectItem(CurrentPortal); + ProjectForm.DeleteMloPortal(); + } } } diff --git a/Project/Panels/EditYtypMloRoomPanel.Designer.cs b/Project/Panels/EditYtypMloRoomPanel.Designer.cs index 7915d8a..90c1b0b 100644 --- a/Project/Panels/EditYtypMloRoomPanel.Designer.cs +++ b/Project/Panels/EditYtypMloRoomPanel.Designer.cs @@ -50,6 +50,8 @@ this.label8 = new System.Windows.Forms.Label(); this.ExteriorVisDepthTextBox = new CodeWalker.WinForms.TextBoxFix(); this.label9 = new System.Windows.Forms.Label(); + this.DeleteButton = new System.Windows.Forms.Button(); + this.AddEntityButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // label1 @@ -58,7 +60,7 @@ this.label1.Location = new System.Drawing.Point(60, 44); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(44, 13); - this.label1.TabIndex = 0; + this.label1.TabIndex = 3; this.label1.Text = "BB Min:"; // // label2 @@ -67,7 +69,7 @@ this.label2.Location = new System.Drawing.Point(57, 70); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(47, 13); - this.label2.TabIndex = 1; + this.label2.TabIndex = 5; this.label2.Text = "BB Max:"; // // MinBoundsTextBox @@ -77,7 +79,7 @@ this.MinBoundsTextBox.Location = new System.Drawing.Point(110, 41); this.MinBoundsTextBox.Name = "MinBoundsTextBox"; this.MinBoundsTextBox.Size = new System.Drawing.Size(231, 20); - this.MinBoundsTextBox.TabIndex = 2; + this.MinBoundsTextBox.TabIndex = 4; this.MinBoundsTextBox.TextChanged += new System.EventHandler(this.MinBoundsTextBox_TextChanged); // // MaxBoundsTextBox @@ -87,7 +89,7 @@ this.MaxBoundsTextBox.Location = new System.Drawing.Point(110, 67); this.MaxBoundsTextBox.Name = "MaxBoundsTextBox"; this.MaxBoundsTextBox.Size = new System.Drawing.Size(231, 20); - this.MaxBoundsTextBox.TabIndex = 3; + this.MaxBoundsTextBox.TabIndex = 6; this.MaxBoundsTextBox.TextChanged += new System.EventHandler(this.MaxBoundsTextBox_TextChanged); // // label3 @@ -96,7 +98,7 @@ this.label3.Location = new System.Drawing.Point(63, 18); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(41, 13); - this.label3.TabIndex = 4; + this.label3.TabIndex = 1; this.label3.Text = "Name: "; // // NameTextBox @@ -106,7 +108,7 @@ this.NameTextBox.Location = new System.Drawing.Point(110, 15); this.NameTextBox.Name = "NameTextBox"; this.NameTextBox.Size = new System.Drawing.Size(231, 20); - this.NameTextBox.TabIndex = 5; + this.NameTextBox.TabIndex = 2; this.NameTextBox.TextChanged += new System.EventHandler(this.NameTextBox_TextChanged); // // FlagsCheckedListBox @@ -117,18 +119,18 @@ this.FlagsCheckedListBox.Items.AddRange(new object[] { "1 - Unk01", "2 - Unk02", - "4 - Unk03", + "4 - Disable exterior shadows", "8 - Unk04", "16 - Unk05", "32 - Unk06", "64 - Unk07", "128 - Unk08", - "256 - Unk09", + "256 - Disable limbo portals", "512 - Unk10"}); this.FlagsCheckedListBox.Location = new System.Drawing.Point(352, 41); this.FlagsCheckedListBox.Name = "FlagsCheckedListBox"; this.FlagsCheckedListBox.Size = new System.Drawing.Size(201, 154); - this.FlagsCheckedListBox.TabIndex = 35; + this.FlagsCheckedListBox.TabIndex = 21; this.FlagsCheckedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.FlagsCheckedListBox_ItemCheck); // // FlagsTextBox @@ -137,7 +139,7 @@ this.FlagsTextBox.Location = new System.Drawing.Point(406, 15); this.FlagsTextBox.Name = "FlagsTextBox"; this.FlagsTextBox.Size = new System.Drawing.Size(147, 20); - this.FlagsTextBox.TabIndex = 34; + this.FlagsTextBox.TabIndex = 20; this.FlagsTextBox.TextChanged += new System.EventHandler(this.FlagsTextBox_TextChanged); // // label14 @@ -147,7 +149,7 @@ this.label14.Location = new System.Drawing.Point(365, 18); this.label14.Name = "label14"; this.label14.Size = new System.Drawing.Size(35, 13); - this.label14.TabIndex = 33; + this.label14.TabIndex = 19; this.label14.Text = "Flags:"; // // BlendTextBox @@ -157,7 +159,7 @@ this.BlendTextBox.Location = new System.Drawing.Point(110, 93); this.BlendTextBox.Name = "BlendTextBox"; this.BlendTextBox.Size = new System.Drawing.Size(231, 20); - this.BlendTextBox.TabIndex = 37; + this.BlendTextBox.TabIndex = 8; this.BlendTextBox.TextChanged += new System.EventHandler(this.BlendTextBox_TextChanged); // // label4 @@ -166,7 +168,7 @@ this.label4.Location = new System.Drawing.Point(67, 96); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(37, 13); - this.label4.TabIndex = 36; + this.label4.TabIndex = 7; this.label4.Text = "Blend:"; // // TimecycleTextBox @@ -176,7 +178,7 @@ this.TimecycleTextBox.Location = new System.Drawing.Point(110, 119); this.TimecycleTextBox.Name = "TimecycleTextBox"; this.TimecycleTextBox.Size = new System.Drawing.Size(231, 20); - this.TimecycleTextBox.TabIndex = 39; + this.TimecycleTextBox.TabIndex = 10; this.TimecycleTextBox.TextChanged += new System.EventHandler(this.TimecycleTextBox_TextChanged); // // label5 @@ -185,7 +187,7 @@ this.label5.Location = new System.Drawing.Point(46, 122); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(58, 13); - this.label5.TabIndex = 38; + this.label5.TabIndex = 9; this.label5.Text = "Timecycle:"; // // Timecycle2TextBox @@ -195,7 +197,7 @@ this.Timecycle2TextBox.Location = new System.Drawing.Point(110, 145); this.Timecycle2TextBox.Name = "Timecycle2TextBox"; this.Timecycle2TextBox.Size = new System.Drawing.Size(231, 20); - this.Timecycle2TextBox.TabIndex = 41; + this.Timecycle2TextBox.TabIndex = 12; this.Timecycle2TextBox.TextChanged += new System.EventHandler(this.Timecycle2TextBox_TextChanged); // // label6 @@ -204,7 +206,7 @@ this.label6.Location = new System.Drawing.Point(37, 148); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(67, 13); - this.label6.TabIndex = 40; + this.label6.TabIndex = 11; this.label6.Text = "Timecycle 2:"; // // PortalCountTextBox @@ -214,7 +216,7 @@ this.PortalCountTextBox.Location = new System.Drawing.Point(110, 171); this.PortalCountTextBox.Name = "PortalCountTextBox"; this.PortalCountTextBox.Size = new System.Drawing.Size(231, 20); - this.PortalCountTextBox.TabIndex = 43; + this.PortalCountTextBox.TabIndex = 14; this.PortalCountTextBox.TextChanged += new System.EventHandler(this.PortalCountTextBox_TextChanged); // // label7 @@ -223,7 +225,7 @@ this.label7.Location = new System.Drawing.Point(36, 174); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(68, 13); - this.label7.TabIndex = 42; + this.label7.TabIndex = 13; this.label7.Text = "Portal Count:"; // // FloorIDTextBox @@ -233,7 +235,7 @@ this.FloorIDTextBox.Location = new System.Drawing.Point(110, 197); this.FloorIDTextBox.Name = "FloorIDTextBox"; this.FloorIDTextBox.Size = new System.Drawing.Size(231, 20); - this.FloorIDTextBox.TabIndex = 45; + this.FloorIDTextBox.TabIndex = 16; this.FloorIDTextBox.TextChanged += new System.EventHandler(this.FloorIDTextBox_TextChanged); // // label8 @@ -242,7 +244,7 @@ this.label8.Location = new System.Drawing.Point(57, 200); this.label8.Name = "label8"; this.label8.Size = new System.Drawing.Size(47, 13); - this.label8.TabIndex = 44; + this.label8.TabIndex = 15; this.label8.Text = "Floor ID:"; // // ExteriorVisDepthTextBox @@ -252,7 +254,7 @@ this.ExteriorVisDepthTextBox.Location = new System.Drawing.Point(110, 223); this.ExteriorVisDepthTextBox.Name = "ExteriorVisDepthTextBox"; this.ExteriorVisDepthTextBox.Size = new System.Drawing.Size(231, 20); - this.ExteriorVisDepthTextBox.TabIndex = 47; + this.ExteriorVisDepthTextBox.TabIndex = 18; this.ExteriorVisDepthTextBox.TextChanged += new System.EventHandler(this.ExteriorVisDepthTextBox_TextChanged); // // label9 @@ -261,14 +263,37 @@ this.label9.Location = new System.Drawing.Point(10, 226); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(94, 13); - this.label9.TabIndex = 46; + this.label9.TabIndex = 17; this.label9.Text = "Exterior Vis Depth:"; // + // DeleteButton + // + this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.DeleteButton.Location = new System.Drawing.Point(352, 277); + this.DeleteButton.Name = "DeleteButton"; + this.DeleteButton.Size = new System.Drawing.Size(95, 23); + this.DeleteButton.TabIndex = 23; + this.DeleteButton.Text = "Delete Room"; + this.DeleteButton.UseVisualStyleBackColor = true; + this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); + // + // AddEntityButton + // + this.AddEntityButton.Location = new System.Drawing.Point(110, 277); + this.AddEntityButton.Name = "AddEntityButton"; + this.AddEntityButton.Size = new System.Drawing.Size(95, 23); + this.AddEntityButton.TabIndex = 22; + this.AddEntityButton.Text = "Add Entity"; + this.AddEntityButton.UseVisualStyleBackColor = true; + this.AddEntityButton.Click += new System.EventHandler(this.AddEntityButton_Click); + // // EditYtypMloRoomPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(565, 505); + this.Controls.Add(this.AddEntityButton); + this.Controls.Add(this.DeleteButton); this.Controls.Add(this.ExteriorVisDepthTextBox); this.Controls.Add(this.label9); this.Controls.Add(this.FloorIDTextBox); @@ -321,5 +346,7 @@ private System.Windows.Forms.Label label8; private WinForms.TextBoxFix ExteriorVisDepthTextBox; private System.Windows.Forms.Label label9; + private System.Windows.Forms.Button DeleteButton; + private System.Windows.Forms.Button AddEntityButton; } } \ No newline at end of file diff --git a/Project/Panels/EditYtypMloRoomPanel.cs b/Project/Panels/EditYtypMloRoomPanel.cs index 32674ed..f556510 100644 --- a/Project/Panels/EditYtypMloRoomPanel.cs +++ b/Project/Panels/EditYtypMloRoomPanel.cs @@ -262,5 +262,17 @@ namespace CodeWalker.Project.Panels } } } + + private void AddEntityButton_Click(object sender, EventArgs e) + { + ProjectForm.SetProjectItem(CurrentRoom); + ProjectForm.NewMloEntity(); + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + ProjectForm.SetProjectItem(CurrentRoom); + ProjectForm.DeleteMloRoom(); + } } } diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index d163748..6f5e017 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -894,9 +894,9 @@ namespace CodeWalker.Project //######## Public methods - // Possibly future proofing for procedural prop instances public bool CanPaintInstances() { + // Possibly future proofing for procedural prop instances if (CurrentGrassBatch != null) { if (CurrentGrassBatch.BrushEnabled) @@ -1657,7 +1657,7 @@ namespace CodeWalker.Project public bool DeleteEntity() { if (CurrentEntity == null) return false; - return CurrentYmapFile != null ? DeleteYmapEntity() : DeleteMloArchetypeEntity(); + return CurrentYmapFile != null ? DeleteYmapEntity() : DeleteMloEntity(); } private bool DeleteYmapEntity() @@ -2327,47 +2327,60 @@ namespace CodeWalker.Project { if ((CurrentArchetype == null) || !(CurrentArchetype is MloArchetype mloArch)) { - var arch = CurrentEntity?.MloParent.Archetype ?? CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo; - if (arch == null) - return; - - mloArch = arch as MloArchetype; - if (mloArch == null) - return; - + mloArch = (CurrentEntity?.MloParent.Archetype as MloArchetype) ?? CurrentMloRoom?.OwnerMlo ?? CurrentMloPortal?.OwnerMlo ?? CurrentMloEntitySet?.OwnerMlo; + if (mloArch == null) return; CurrentArchetype = mloArch; } - if (CurrentMloRoom == null) CurrentMloRoom = mloArch?.GetEntityRoom(CurrentMloEntity); - if (CurrentMloRoom == null) + var mloInstance = TryGetMloInstance(mloArch); + if (mloInstance == null) { + MessageBox.Show("Unable to find MLO instance for this interior! Try adding an MLO instance ymap to the project."); return; } - MloInstanceData mloInstance = TryGetMloInstance(mloArch); - if (mloInstance == null) return; - - if (mloArch.rooms.Length <= 0) + if ((CurrentMloRoom == null) && (CurrentMloPortal == null) && (CurrentMloEntitySet == null)) { - MessageBox.Show($@"Mlo {mloArch.Name} has no rooms! Cannot create entity."); - return; + if ((mloArch.rooms?.Length??0) <= 0) + { + MessageBox.Show($@"Mlo {mloArch.Name} has no rooms! Cannot create entity."); + return; + } + CurrentMloRoom = mloArch?.GetEntityRoom(CurrentMloEntity); } - int roomIndex = CurrentMloRoom.Index; - if (roomIndex < 0) + + int roomIndex = CurrentMloRoom?.Index ?? -1; + if (roomIndex >= 0) { - MessageBox.Show(@"Invalid room index."); - return; + 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; + } } - if (roomIndex >= mloArch.rooms.Length) + + int portalIndex = CurrentMloPortal?.Index ?? -1; + if (portalIndex >= 0) { - MessageBox.Show( - $@"Room at index {roomIndex} does not exist in {mloArch.Name}! {mloArch.Name} only has { - mloArch.rooms.Length - } rooms."); - return; + 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; + } } - + + int entsetIndex = CurrentMloEntitySet?.Index ?? -1; + if (entsetIndex >= 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; + } + } + + float spawndist = 5.0f; //use archetype BSradius if starting with a copy... if (copy != null) { @@ -2406,23 +2419,24 @@ namespace CodeWalker.Project var createindex = mloArch.entities.Length; MCEntityDef ment = new MCEntityDef(ref cent, mloArch); + YmapEntityDef outEnt = mloInstance.CreateYmapEntity(mloInstance.Owner, ment, createindex); - YmapEntityDef outEnt; try { if (WorldForm != null) { lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... { - // Add the entity to the mlo instance and archetype. - outEnt = mloInstance.CreateYmapEntity(mloInstance.Owner, ment, createindex); - mloArch.AddEntity(outEnt, roomIndex); + 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! + outEnt.SetArchetype(GameFileCache.GetArchetype(cent.archetypeName)); } } else { - outEnt = mloInstance.CreateYmapEntity(mloInstance.Owner, ment, createindex); - mloArch.AddEntity(outEnt, roomIndex); + 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! + outEnt.SetArchetype(GameFileCache.GetArchetype(cent.archetypeName)); } } catch(Exception e) @@ -2431,10 +2445,6 @@ namespace CodeWalker.Project return; } - - mloInstance.AddEntity(outEnt); - outEnt.SetArchetype(GameFileCache.GetArchetype(cent.archetypeName)); - LoadProjectTree(); ProjectExplorer?.TrySelectMloEntityTreeNode(mloInstance.TryGetArchetypeEntity(outEnt)); CurrentEntity = outEnt; @@ -2466,6 +2476,11 @@ namespace CodeWalker.Project mlo.AddRoom(room); + var mloInstance = TryGetMloInstance(mlo); + if (mloInstance != null) + { + } + LoadProjectTree(); ProjectExplorer?.TrySelectMloRoomTreeNode(room); CurrentMloRoom = room; @@ -2495,6 +2510,11 @@ namespace CodeWalker.Project mlo.AddPortal(portal); + var mloInstance = TryGetMloInstance(mlo); + if (mloInstance != null) + { + } + LoadProjectTree(); ProjectExplorer?.TrySelectMloPortalTreeNode(portal); CurrentMloPortal = portal; @@ -2517,17 +2537,66 @@ namespace CodeWalker.Project } else { - + JenkIndex.Ensure("NewEntitySet");//why is this here though + set._Data.name = JenkHash.GenHash("NewEntitySet"); } mlo.AddEntitySet(set); + var mloInstance = TryGetMloInstance(mlo); + if (mloInstance != null) + { + } + LoadProjectTree(); ProjectExplorer?.TrySelectMloEntitySetTreeNode(set); CurrentMloEntitySet = set; CurrentYtypFile = set?.OwnerMlo?.Ytyp; } - private bool DeleteMloArchetypeEntity() + public bool DeleteArchetype() + { + if (CurrentArchetype == null) return false; + if (CurrentArchetype.Ytyp != CurrentYtypFile) return false; + + if (MessageBox.Show("Are you sure you want to delete this archetype?\n" + CurrentArchetype._BaseArchetypeDef.name.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return true; + } + + bool res = false; + if (WorldForm != null) + { + lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... + { + res = CurrentArchetype.Ytyp.RemoveArchetype(CurrentArchetype); + //WorldForm.SelectItem(null, null, null); + } + } + else + { + res = CurrentArchetype.Ytyp.RemoveArchetype(CurrentArchetype); + } + if (!res) + { + MessageBox.Show("Archetype couldn't be removed!"); + return false; + } + + var delarch = CurrentArchetype; + var delytyp = delarch.Ytyp; + + RemoveProjectArchetype(delarch); + + ProjectExplorer?.RemoveArchetypeTreeNode(delarch); + ProjectExplorer?.SetYtypHasChanged(delytyp, true); + + ClosePanel((EditYtypArchetypePanel p) => { return p.Tag == delarch; }); + + CurrentArchetype = null; + + return true; + } + public bool DeleteMloEntity() { if (CurrentEntity?.MloParent?.Archetype?.Ytyp == null) return false; if (CurrentEntity.MloParent.Archetype.Ytyp != CurrentYtypFile) return false; @@ -2584,49 +2653,64 @@ namespace CodeWalker.Project return true; } - public bool DeleteArchetype() + public bool DeleteMloRoom() { - if (CurrentArchetype == null) return false; - if (CurrentArchetype.Ytyp != CurrentYtypFile) return false; + var mlo = CurrentMloRoom?.OwnerMlo; + if (mlo == null) return false; - if (MessageBox.Show("Are you sure you want to delete this archetype?\n" + CurrentArchetype._BaseArchetypeDef.name.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + if (MessageBox.Show("Are you sure you want to delete this room?\n" + CurrentMloRoom.Name + "\n\nDeleting existing rooms is generally not recommended, as it will mess up all the room IDs.\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) { return true; } - bool res = false; - if (WorldForm != null) + mlo.RemoveRoom(CurrentMloRoom); + + var mloInstance = TryGetMloInstance(mlo); + if (mloInstance != null) { - lock (WorldForm.RenderSyncRoot) //don't try to do this while rendering... - { - res = CurrentArchetype.Ytyp.RemoveArchetype(CurrentArchetype); - //WorldForm.SelectItem(null, null, null); - } } - else - { - res = CurrentArchetype.Ytyp.RemoveArchetype(CurrentArchetype); - } - if (!res) - { - MessageBox.Show("Archetype couldn't be removed!"); - return false; - } - - var delarch = CurrentArchetype; - var delytyp = delarch.Ytyp; - - RemoveProjectArchetype(delarch); - - ProjectExplorer?.RemoveArchetypeTreeNode(delarch); - ProjectExplorer?.SetYtypHasChanged(delytyp, true); - - ClosePanel((EditYtypArchetypePanel p) => { return p.Tag == delarch; }); - - CurrentArchetype = null; return true; } + public bool DeleteMloPortal() + { + var mlo = CurrentMloPortal?.OwnerMlo; + if (mlo == null) return false; + + if (MessageBox.Show("Are you sure you want to delete this portal?\n" + CurrentMloPortal.Name + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return true; + } + + mlo.RemovePortal(CurrentMloPortal); + + var mloInstance = TryGetMloInstance(mlo); + if (mloInstance != null) + { + } + + return true; + } + public bool DeleteMloEntitySet() + { + var mlo = CurrentMloEntitySet?.OwnerMlo; + if (mlo == null) return false; + + if (MessageBox.Show("Are you sure you want to delete this entity set?\n" + CurrentMloEntitySet.Name + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return true; + } + + mlo.RemoveEntitySet(CurrentMloEntitySet); + + var mloInstance = TryGetMloInstance(mlo); + if (mloInstance != null) + { + } + + return true; + } + private void AddProjectArchetypes(YtypFile ytyp) { if (ytyp?.AllArchetypes == null) return; diff --git a/WorldForm.cs b/WorldForm.cs index f96aa90..bc9ef0f 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -1274,11 +1274,11 @@ namespace CodeWalker { //immediately render the bounding box of the current selection. also, arrows. - const uint cred = 4278190335;// (uint)new Color4(1.0f, 0.0f, 0.0f, 1.0f).ToRgba(); - const uint cgrn = 4278255360;// (uint)new Color4(0.0f, 1.0f, 0.0f, 1.0f).ToRgba(); - const uint cblu = 4294901760;// (uint)new Color4(0.0f, 0.0f, 1.0f, 1.0f).ToRgba(); - const uint caqu = 4294967040;// (uint)new Color4(0.0f, 1.0f, 1.0f, 1.0f).ToRgba(); - //const uint cyel = 4278255615;// + const uint cred = 0xFF0000FF; + const uint cgrn = 0xFF00FF00; + const uint cblu = 0xFFFF0000; + const uint caqu = 0xFFFFFF00; + //const uint cyel = 0xFF00FFFF; if (ControlBrushEnabled && MouseRayCollision.Hit) {