diff --git a/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs index 7658eed..f24ceb0 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs @@ -115,14 +115,6 @@ namespace CodeWalker.GameFiles poly.Init(this, polys[i]); poly.Index = i; Polys.Add(poly); - - if (poly.PortalType > 0) - { - if (poly.PortalType != 2) //seems to be what portal links need to understand.. - { } - - } - } } if (Nav.Portals != null) @@ -212,6 +204,7 @@ namespace CodeWalker.GameFiles var edgelist = new List(); var polylist = new List(); var portallist = new List(); + var portallinks = new List(); var vertdict = new Dictionary(); var blankedgepart1 = new NavMeshEdgePart() { Value = 0x0FFFE1 };//1, -, 1, 0 @@ -243,6 +236,12 @@ namespace CodeWalker.GameFiles edgelist.Add(e); } poly._RawData.IndexCount = vc; + poly._RawData.PortalLinkID = (uint)portallinks.Count;//these shouldn't be directly editable! + poly._RawData.PortalLinkCount = (byte)(poly.PortalLinks?.Length ?? 0); + if (poly.PortalLinks != null) + { + portallinks.AddRange(poly.PortalLinks); + } poly.Index = i;//this should be redundant... polylist.Add(poly.RawData); } @@ -303,7 +302,8 @@ namespace CodeWalker.GameFiles Nav.Portals = (portallist.Count > 0) ? portallist.ToArray() : null; Nav.PortalsCount = (uint)(Nav.Portals?.Length ?? 0); - //TODO: update portal links data..... + Nav.PortalLinks = (portallinks.Count > 0) ? portallinks.ToArray() : null; + Nav.PortalLinksCount = (uint)(Nav.PortalLinks?.Length ?? 0); for (int i = 0; i < Nav.Polys.ListParts.Count; i++) //reassign part id's on all the polys... @@ -572,8 +572,8 @@ namespace CodeWalker.GameFiles public ushort AreaID { get { return _RawData.AreaID; } set { _RawData.AreaID = value; } } public ushort PartID { get { return _RawData.PartID; } set { _RawData.PartID = value; } } - public ushort PortalLinkID { get { return _RawData.PortalLinkID; } set { _RawData.PortalLinkID = value; } } - public byte PortalType { get { return _RawData.PortalType; } set { _RawData.PortalType = value; } } + public uint PortalLinkID { get { return _RawData.PortalLinkID; } set { _RawData.PortalLinkID = value; } } + public byte PortalLinkCount { get { return _RawData.PortalLinkCount; } set { _RawData.PortalLinkCount = value; } } public byte Flags1 { get { return (byte)(_RawData.Unknown_00h & 0xFF); } set { _RawData.Unknown_00h = (ushort)((_RawData.Unknown_00h & 0xFF00) | (value & 0xFF)); } } public byte Flags2 { get { return (byte)((_RawData.Unknown_24h.Value >> 0) & 0xFF); } set { _RawData.Unknown_24h = ((_RawData.Unknown_24h.Value & 0xFFFFFF00u) | ((value & 0xFFu) << 0)); } } public byte Flags3 { get { return (byte)((_RawData.Unknown_24h.Value >> 9) & 0xFF); } set { _RawData.Unknown_24h = ((_RawData.Unknown_24h.Value & 0xFFFE01FFu) | ((value & 0xFFu) << 9)); } } @@ -621,6 +621,7 @@ namespace CodeWalker.GameFiles public ushort[] Indices { get; set; } public Vector3[] Vertices { get; set; } public NavMeshEdge[] Edges { get; set; } + public ushort[] PortalLinks { get; set; } public void Init(YnvFile ynv, NavMeshPoly poly) @@ -629,6 +630,7 @@ namespace CodeWalker.GameFiles RawData = poly; LoadIndices(); + LoadPortalLinks(); CalculatePosition(); //calc poly center for display purposes.. } @@ -669,6 +671,30 @@ namespace CodeWalker.GameFiles } } + public void LoadPortalLinks() + { + if (PortalLinkCount == 0) + { return; } + var links = Ynv.Nav?.PortalLinks; + if (links == null) + { return; } + + var ll = links.Length; + + PortalLinks = new ushort[PortalLinkCount]; + + int offset = (int)PortalLinkID; + for (int i = 0; i < PortalLinkCount; i++) + { + int idx = offset + i; + PortalLinks[i] = (idx < ll) ? links[idx] : (ushort)0; + } + + if (PortalLinkCount != 2) + { }//debug + + } + public void SetPosition(Vector3 pos) { @@ -725,7 +751,7 @@ namespace CodeWalker.GameFiles //if ((u5 & 8388608) > 0) colour.Red += 1.0f; //slope facing -X,-Y (southwest) //if (u5 >= 16777216) { } //other bits unused - var u1 = _RawData.PortalType; + var u1 = _RawData.PortalLinkCount; //if ((u1 & 1) > 0) colour.Red += 1.0f; //portal - don't interact? //if ((u1 & 2) > 0) colour.Green += 1.0f; //portal - ladder/fence interaction? //if ((u1 & 4) > 0) colour.Blue += 1.0f; //portal - fence interaction / go away from? diff --git a/CodeWalker.Core/GameFiles/Resources/Nav.cs b/CodeWalker.Core/GameFiles/Resources/Nav.cs index d28ef25..95aa63b 100644 --- a/CodeWalker.Core/GameFiles/Resources/Nav.cs +++ b/CodeWalker.Core/GameFiles/Resources/Nav.cs @@ -643,16 +643,16 @@ namespace CodeWalker.GameFiles public NavMeshAABB CellAABB { get; set; } public FlagsUint Unknown_24h { get; set; } public FlagsUint Unknown_28h { get; set; } - public ushort PartFlags { get; set; } - public ushort PortalLinkID { get; set; } + public uint PartFlags { get; set; } //public int IndexUnk { get { return (IndexFlags >> 0) & 31; } } //always 0 public int IndexCount { get { return (IndexFlags >> 5); } set { IndexFlags = (ushort)((IndexFlags & 31) | ((value & 0x7FF) << 5)); } } //public int PartUnk1 { get { return (PartFlags >> 0) & 0xF; } } //always 0 - public ushort PartID { get { return (ushort)((PartFlags >> 4) & 0xFF); } set { PartFlags = (ushort)((PartFlags & 0xF00F) | ((value & 0xFF) << 4)); } } - public byte PortalType { get { return (byte)((PartFlags >> 12) & 0xF); } set { PartFlags = (ushort)((PartFlags & 0x0FFF) | ((value & 0xF) << 12)); } } + public ushort PartID { get { return (ushort)((PartFlags >> 4) & 0xFF); } set { PartFlags = ((PartFlags & 0xFFFFF00F) | (((uint)value & 0xFF) << 4)); } } + public byte PortalLinkCount { get { return (byte)((PartFlags >> 12) & 0x7); } set { PartFlags = ((PartFlags & 0xFFFF8FFF) | (((uint)value & 0x7) << 12)); } } + public uint PortalLinkID { get { return ((PartFlags >> 15) & 0x1FFFF); } set { PartFlags = ((PartFlags & 0x7FFF) | ((value & 0x1FFFF) << 15)); } } public ushort Unknown_28h_16 { get { return (ushort)((Unknown_28h.Value & 0xFFFF)); } set { Unknown_28h = (Unknown_28h.Value & 0xFFFF0000) | (value & 0xFFFFu); } } @@ -673,7 +673,7 @@ namespace CodeWalker.GameFiles Unknown_28h.Hex + ", " + //PartFlags.ToString() + ", " + //PartUnk1.ToString() + ", " + PartID.ToString() + ", " + - PortalType.ToString() + ", " + + PortalLinkCount.ToString() + ", " + PortalLinkID.ToString(); } } diff --git a/Project/Panels/EditYnvPolyPanel.Designer.cs b/Project/Panels/EditYnvPolyPanel.Designer.cs index 4830cec..6d7bf3a 100644 --- a/Project/Panels/EditYnvPolyPanel.Designer.cs +++ b/Project/Panels/EditYnvPolyPanel.Designer.cs @@ -46,14 +46,14 @@ this.label4 = new System.Windows.Forms.Label(); this.DeletePolyButton = new System.Windows.Forms.Button(); this.AddToProjectButton = new System.Windows.Forms.Button(); - this.PortalTypeUpDown = new System.Windows.Forms.NumericUpDown(); + this.PortalCountUpDown = new System.Windows.Forms.NumericUpDown(); this.label6 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.AreaIDUpDown)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.PartIDUpDown)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.PortalIDUpDown)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.UnkXUpDown)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.UnkYUpDown)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.PortalTypeUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PortalCountUpDown)).BeginInit(); this.SuspendLayout(); // // AreaIDUpDown @@ -273,34 +273,34 @@ this.AddToProjectButton.UseVisualStyleBackColor = true; this.AddToProjectButton.Click += new System.EventHandler(this.AddToProjectButton_Click); // - // PortalTypeUpDown + // PortalCountUpDown // - this.PortalTypeUpDown.Location = new System.Drawing.Point(495, 12); - this.PortalTypeUpDown.Maximum = new decimal(new int[] { + this.PortalCountUpDown.Location = new System.Drawing.Point(495, 12); + this.PortalCountUpDown.Maximum = new decimal(new int[] { 15, 0, 0, 0}); - this.PortalTypeUpDown.Name = "PortalTypeUpDown"; - this.PortalTypeUpDown.Size = new System.Drawing.Size(57, 20); - this.PortalTypeUpDown.TabIndex = 8; - this.PortalTypeUpDown.ValueChanged += new System.EventHandler(this.PortalTypeUpDown_ValueChanged); + this.PortalCountUpDown.Name = "PortalCountUpDown"; + this.PortalCountUpDown.Size = new System.Drawing.Size(57, 20); + this.PortalCountUpDown.TabIndex = 8; + this.PortalCountUpDown.ValueChanged += new System.EventHandler(this.PortalCountUpDown_ValueChanged); // // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(429, 14); + this.label6.Location = new System.Drawing.Point(424, 14); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(60, 13); + this.label6.Size = new System.Drawing.Size(67, 13); this.label6.TabIndex = 7; - this.label6.Text = "Portal type:"; + this.label6.Text = "Portal count:"; // // EditYnvPolyPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(562, 404); - this.Controls.Add(this.PortalTypeUpDown); + this.Controls.Add(this.PortalCountUpDown); this.Controls.Add(this.label6); this.Controls.Add(this.DeletePolyButton); this.Controls.Add(this.AddToProjectButton); @@ -327,7 +327,7 @@ ((System.ComponentModel.ISupportInitialize)(this.PortalIDUpDown)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.UnkXUpDown)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.UnkYUpDown)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.PortalTypeUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PortalCountUpDown)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -352,7 +352,7 @@ private System.Windows.Forms.Label label4; private System.Windows.Forms.Button DeletePolyButton; private System.Windows.Forms.Button AddToProjectButton; - private System.Windows.Forms.NumericUpDown PortalTypeUpDown; + private System.Windows.Forms.NumericUpDown PortalCountUpDown; private System.Windows.Forms.Label label6; } } \ No newline at end of file diff --git a/Project/Panels/EditYnvPolyPanel.cs b/Project/Panels/EditYnvPolyPanel.cs index 595fc73..17b54d2 100644 --- a/Project/Panels/EditYnvPolyPanel.cs +++ b/Project/Panels/EditYnvPolyPanel.cs @@ -48,7 +48,7 @@ namespace CodeWalker.Project.Panels AreaIDUpDown.Value = 0; PartIDUpDown.Value = 0; PortalIDUpDown.Value = 0; - PortalTypeUpDown.Value = 0; + PortalCountUpDown.Value = 0; SetCheckedListBoxValues(FlagsCheckedListBox1, 0); SetCheckedListBoxValues(FlagsCheckedListBox2, 0); SetCheckedListBoxValues(FlagsCheckedListBox3, 0); @@ -65,7 +65,7 @@ namespace CodeWalker.Project.Panels AreaIDUpDown.Value = YnvPoly.AreaID; PartIDUpDown.Value = YnvPoly.PartID; PortalIDUpDown.Value = YnvPoly.PortalLinkID; - PortalTypeUpDown.Value = YnvPoly.PortalType; + PortalCountUpDown.Value = YnvPoly.PortalLinkCount; SetCheckedListBoxValues(FlagsCheckedListBox1, YnvPoly.Flags1); SetCheckedListBoxValues(FlagsCheckedListBox2, YnvPoly.Flags2); SetCheckedListBoxValues(FlagsCheckedListBox3, YnvPoly.Flags3); @@ -152,16 +152,16 @@ namespace CodeWalker.Project.Panels } } - private void PortalTypeUpDown_ValueChanged(object sender, EventArgs e) + private void PortalCountUpDown_ValueChanged(object sender, EventArgs e) { if (populatingui) return; if (YnvPoly == null) return; - byte portalunk = (byte)PortalTypeUpDown.Value; + byte portalcount = (byte)PortalCountUpDown.Value; lock (ProjectForm.ProjectSyncRoot) { - if (YnvPoly.PortalType != portalunk) + if (YnvPoly.PortalLinkCount != portalcount) { - YnvPoly.PortalType = portalunk; + YnvPoly.PortalLinkCount = portalcount; ProjectForm.SetYnvHasChanged(true); } }