From 8b72fc122093ffc22095091222900c435f396616 Mon Sep 17 00:00:00 2001 From: dexyfex Date: Wed, 14 Mar 2018 12:36:43 +1100 Subject: [PATCH] Editing points and portals in navmesh, improved DX error message --- .../GameFiles/FileTypes/YnvFile.cs | 232 +++++++++- CodeWalker.Core/GameFiles/GameFileCache.cs | 6 + CodeWalker.Core/GameFiles/Resources/Nav.cs | 101 ++-- CodeWalker.csproj | 18 + Project/Panels/EditYnvPanel.Designer.cs | 84 ++-- Project/Panels/EditYnvPanel.cs | 4 +- Project/Panels/EditYnvPointPanel.Designer.cs | 174 +++++++ Project/Panels/EditYnvPointPanel.cs | 150 ++++++ Project/Panels/EditYnvPointPanel.resx | 409 ++++++++++++++++ Project/Panels/EditYnvPolyPanel.Designer.cs | 38 +- Project/Panels/EditYnvPolyPanel.cs | 18 +- Project/Panels/EditYnvPortalPanel.Designer.cs | 437 ++++++++++++++++++ Project/Panels/EditYnvPortalPanel.cs | 311 +++++++++++++ Project/Panels/EditYnvPortalPanel.resx | 409 ++++++++++++++++ Project/Panels/ProjectExplorerPanel.cs | 72 +++ Project/ProjectForm.cs | 172 ++++++- Project/UndoStep.cs | 233 ++++++++++ Rendering/DirectX/DXManager.cs | 14 +- Utils/MapUtils.cs | 8 +- WorldForm.cs | 210 +++++++-- 20 files changed, 2931 insertions(+), 169 deletions(-) create mode 100644 Project/Panels/EditYnvPointPanel.Designer.cs create mode 100644 Project/Panels/EditYnvPointPanel.cs create mode 100644 Project/Panels/EditYnvPointPanel.resx create mode 100644 Project/Panels/EditYnvPortalPanel.Designer.cs create mode 100644 Project/Panels/EditYnvPortalPanel.cs create mode 100644 Project/Panels/EditYnvPortalPanel.resx diff --git a/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs index 1fd6ea1..8118c79 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YnvFile.cs @@ -116,6 +116,14 @@ namespace CodeWalker.GameFiles poly.Index = i; poly.CalculatePosition(); //calc poly center for display purposes.. Polys.Add(poly); + + if (poly.PortalType > 0) + { + if (poly.PortalType != 2) //seems to be what portal links need to understand.. + { } + + } + } } if (Nav.Portals != null) @@ -127,8 +135,8 @@ namespace CodeWalker.GameFiles YnvPortal portal = new YnvPortal(); portal.Init(this, portals[i]); portal.Index = i; - portal.Position1 = posoffset + portal._RawData.Position1.ToVector3() * aabbsize; - portal.Position2 = posoffset + portal._RawData.Position2.ToVector3() * aabbsize; + portal.PositionFrom = posoffset + portal._RawData.PositionFrom.ToVector3() * aabbsize; + portal.PositionTo = posoffset + portal._RawData.PositionTo.ToVector3() * aabbsize; Portals.Add(portal); } } @@ -194,7 +202,7 @@ namespace CodeWalker.GameFiles return data; } - public void BuildStructs() + private void BuildStructs() { Vector3 posoffset = Nav.SectorTree?.AABBMin.XYZ() ?? Vector3.Zero; Vector3 aabbsize = Nav.AABBSize; @@ -213,9 +221,32 @@ namespace CodeWalker.GameFiles { for (int i = 0; i < Polys.Count; i++) { + Polys[i].Index = i; polylist.Add(Polys[i].RawData); } } + var portallist = new List(); + if (Portals != null) + { + for (int i = 0; i < Portals.Count; i++) + { + var portal = Portals[i]; + var pdata = portal.RawData; + pdata.PositionFrom = NavMeshVertex.Create((portal.PositionFrom - posoffset) * aabbsizeinv); + pdata.PositionTo = NavMeshVertex.Create((portal.PositionTo - posoffset) * aabbsizeinv); + portallist.Add(pdata); + } + } + + if (Points != null) + { + for (int i = 0; i < Points.Count; i++) + { + var point = Points[i]; + var pdata = point.RawData; + pdata.Position = point.Position; + } + } if (Nav.Vertices == null) @@ -248,6 +279,9 @@ namespace CodeWalker.GameFiles Nav.Polys.RebuildList(polylist); + Nav.Portals = (portallist.Count > 0) ? portallist.ToArray() : null; + Nav.PortalsCount = (uint)(Nav.Portals?.Length ?? 0); + //TODO: update portal links data..... for (int i = 0; i < Nav.Polys.ListParts.Count; i++) //reassign part id's on all the polys... @@ -262,16 +296,126 @@ namespace CodeWalker.GameFiles } } + + + //Build Sector Tree + int depth = 0; + if ((Nav.ContentFlags & NavMeshFlags.Vehicle) == 0) depth = 2; + //vehicle navmesh has a single level, static has 3.. + + NavMeshSector orig = Nav.SectorTree; + NavMeshSector root = new NavMeshSector(); + root.SetAABBs(orig.AABBMin.XYZ(), orig.AABBMax.XYZ()); + + uint pointindex = 0; + + BuildSectorTree(root, depth, ref pointindex); + + Nav.SectorTree = root; + + } + + private void BuildSectorTree(NavMeshSector node, int depth, ref uint pointindex) + { + Vector3 min = node.AABBMin.XYZ(); + Vector3 max = node.AABBMax.XYZ(); + Vector3 cen = (min + max) * 0.5f; + + if (depth <= 0) + { + //go through polys and points and create new lists for this node + NavMeshSectorData data = new NavMeshSectorData(); + node.Data = data; + + data.PointsStartID = pointindex; + + if (Polys != null) + { + List polyids = new List(); + for (int i = 0; i < Polys.Count; i++) + { + var poly = Polys[i]; + var b = poly._RawData.CellAABB; + if (BoxOverlaps(b, node.CellAABB)) + { + polyids.Add((ushort)poly.Index); + } + } + if (polyids.Count > 0) + { + data.PolyIDs = polyids.ToArray(); + } + } + + if (Points != null) + { + List points = new List(); + for (int i = 0; i < Points.Count; i++) + { + var point = Points[i]; + if (IsInBox(point.Position, min, max)) + { + points.Add(point.RawData); + } + } + if (points.Count > 0) + { + data.Points = points.ToArray(); + pointindex += (uint)points.Count; + } + } + + } + else + { + //recurse quadtree... clockwise from +XY (top right) + int cdepth = depth - 1; + node.SubTree1 = new NavMeshSector(); + node.SubTree2 = new NavMeshSector(); + node.SubTree3 = new NavMeshSector(); + node.SubTree4 = new NavMeshSector(); + node.SubTree1.SetAABBs(new Vector3(cen.X, cen.Y, cen.Z), new Vector3(max.X, max.Y, max.Z)); //for some reason Z values seem to get arranged like this... + node.SubTree2.SetAABBs(new Vector3(cen.X, min.Y, 0.0f), new Vector3(max.X, cen.Y, 0.0f)); + node.SubTree3.SetAABBs(new Vector3(min.X, min.Y, min.Z), new Vector3(cen.X, cen.Y, cen.Z)); + node.SubTree4.SetAABBs(new Vector3(min.X, cen.Y, 0.0f), new Vector3(cen.X, max.Y, 0.0f)); + BuildSectorTree(node.SubTree1, cdepth, ref pointindex); + BuildSectorTree(node.SubTree2, cdepth, ref pointindex); + BuildSectorTree(node.SubTree3, cdepth, ref pointindex); + BuildSectorTree(node.SubTree4, cdepth, ref pointindex); + } + } + + private bool IsInBox(Vector3 p, Vector3 min, Vector3 max) + { + return (p.X >= min.X) && (p.X < max.X) && + (p.Y >= min.Y) && (p.Y < max.Y);// && + //(p.Z >= min.Z) && (p.Z < max.Z); + } + private bool BoxOverlaps(Vector3 bmin, Vector3 bmax, Vector3 min, Vector3 max) + { + return (bmax.X >= min.X) && (bmin.X <= max.X) && + (bmax.Y >= min.Y) && (bmin.Y <= max.Y);// && + //(bmax.Z >= min.Z) && (bmin.Z <= max.Z); + } + private bool BoxOverlaps(NavMeshAABB a, NavMeshAABB b) + { + return (a.MaxX >= b.MinX) && (a.MinX <= b.MaxX) && + (a.MaxY >= b.MinY) && (a.MinY <= b.MaxY); } - - - public bool RemovePoly(YnvPoly poly) { return false; } + public bool RemovePoint(YnvPoint point) + { + return false; + } + public bool RemovePortal(YnvPortal portal) + { + return false; + } @@ -298,9 +442,9 @@ namespace CodeWalker.GameFiles for (int i = 0; i < cnt; i++) { var portal = Portals[i]; - nv.Add(new Vector4(portal.Position1, 1.0f)); - v.Position = portal.Position1; lv.Add(v); - v.Position = portal.Position2; lv.Add(v); + nv.Add(new Vector4(portal.PositionFrom, 1.0f)); + v.Position = portal.PositionFrom; lv.Add(v); + v.Position = portal.PositionTo; lv.Add(v); } } @@ -434,8 +578,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 PortalID { get { return _RawData.PortalID; } set { _RawData.PortalID = value; } } - public byte PortalUnk { get { return _RawData.PortalUnk; } set { _RawData.PortalUnk = value; } } + public ushort PortalLinkID { get { return _RawData.PortalLinkID; } set { _RawData.PortalLinkID = value; } } + public byte PortalType { get { return _RawData.PortalType; } set { _RawData.PortalType = 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)); } } @@ -473,10 +617,6 @@ namespace CodeWalker.GameFiles public bool B30_SlopeNorthWest { get { return (_RawData.Unknown_28h.Value & 2097152) > 0; } set { _RawData.Unknown_28h = BitUtil.UpdateBit(_RawData.Unknown_28h.Value, 21, value); } } public bool B31_SlopeWest { get { return (_RawData.Unknown_28h.Value & 4194304) > 0; } set { _RawData.Unknown_28h = BitUtil.UpdateBit(_RawData.Unknown_28h.Value, 22, value); } } public bool B32_SlopeSouthWest { get { return (_RawData.Unknown_28h.Value & 8388608) > 0; } set { _RawData.Unknown_28h = BitUtil.UpdateBit(_RawData.Unknown_28h.Value, 23, value); } } - //public bool B33_PortalUnk1 { get { return (_RawData.PortalUnk & 1) > 0; } } - //public bool B34_PortalUnk2 { get { return (_RawData.PortalUnk & 2) > 0; } } - //public bool B35_PortalUnk3 { get { return (_RawData.PortalUnk & 4) > 0; } } - //public bool B36_PortalUnk4 { get { return (_RawData.PortalUnk & 8) > 0; } } public byte UnkX { get { return _RawData.Unknown_28h_8a; } set { _RawData.Unknown_28h_8a = value; } } public byte UnkY { get { return _RawData.Unknown_28h_8b; } set { _RawData.Unknown_28h_8b = value; } } @@ -547,13 +687,17 @@ 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.PortalUnk; + var u1 = _RawData.PortalType; //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? //if ((u1 & 8) > 0) colour.Red += 1.0f;//something file-specific? portal index related? + //colour.Red = (PortalID) / 65535.0f; //portal ID testing... portalID only valid when portalType > 0! + //colour.Green = (PortalID%5)/4.0f; + //colour.Blue = ((PortalID/5)%5)/4.0f; + colour.Alpha = 0.75f; @@ -606,10 +750,43 @@ namespace CodeWalker.GameFiles public YnvFile Ynv { get; set; } public NavMeshPortal RawData { get { return _RawData; } set { _RawData = value; } } - public Vector3 Position { get { return Position1; } set { Position1 = value; } } - public Vector3 Position1 { get; set; } - public Vector3 Position2 { get; set; } + public Vector3 Position { get { return PositionFrom; } set { PositionFrom = value; } } + public Vector3 PositionFrom { get; set; } + public Vector3 PositionTo { get; set; } + + public byte Angle { get { return _RawData.Angle; } set { _RawData.Angle = value; } } + public float Direction + { + get + { + return (float)Math.PI * 2.0f * Angle / 255.0f; + } + set + { + Angle = (byte)(value * 255.0f / ((float)Math.PI * 2.0f)); + } + } + public Quaternion Orientation + { + get { return Quaternion.RotationAxis(Vector3.UnitZ, Direction); } + set + { + Vector3 dir = value.Multiply(Vector3.UnitX); + float dira = (float)Math.Atan2(dir.Y, dir.X); + Direction = dira; + } + } + public int Index { get; set; } + public byte Type { get { return _RawData.Type; } set { _RawData.Type = value; } } + public ushort AreaIDFrom { get { return _RawData.AreaIDFrom; } set { _RawData.AreaIDFrom = value; } } + public ushort AreaIDTo { get { return _RawData.AreaIDTo; } set { _RawData.AreaIDTo = value; } } + public ushort PolyIDFrom1 { get { return _RawData.PolyIDFrom1; } set { _RawData.PolyIDFrom1 = value; } } + public ushort PolyIDFrom2 { get { return _RawData.PolyIDFrom2; } set { _RawData.PolyIDFrom2 = value; } } + public ushort PolyIDTo1 { get { return _RawData.PolyIDTo1; } set { _RawData.PolyIDTo1 = value; } } + public ushort PolyIDTo2 { get { return _RawData.PolyIDTo2; } set { _RawData.PolyIDTo2 = value; } } + public ushort Unk1 { get { return _RawData.FlagsUnk; } set { _RawData.FlagsUnk = value; } } + public byte Unk2 { get { return _RawData.AreaUnk; } set { _RawData.AreaUnk = value; } } public void Init(YnvFile ynv, NavMeshPortal portal) @@ -620,9 +797,15 @@ namespace CodeWalker.GameFiles public void SetPosition(Vector3 pos) { - Position = pos; + var delta = pos - PositionFrom; + PositionFrom = pos; + PositionTo += delta; //TODO: update _RawData positions! } + public void SetOrientation(Quaternion orientation) + { + Orientation = orientation; + } public override string ToString() { @@ -638,15 +821,16 @@ namespace CodeWalker.GameFiles public NavMeshPoint RawData { get { return _RawData; } set { _RawData = value; } } public Vector3 Position { get; set; } + public byte Angle { get { return _RawData.Angle; } set { _RawData.Angle = value; } } public float Direction { get { - return (float)Math.PI * 2.0f * _RawData.Angle / 255.0f; + return (float)Math.PI * 2.0f * Angle / 255.0f; } set { - _RawData.Angle = (byte)(value * 255.0f / ((float)Math.PI * 2.0f)); + Angle = (byte)(value * 255.0f / ((float)Math.PI * 2.0f)); } } public Quaternion Orientation @@ -661,7 +845,7 @@ namespace CodeWalker.GameFiles } public int Index { get; set; } - public byte Flags { get { return _RawData.Flags; } set { _RawData.Flags = value; } } + public byte Type { get { return _RawData.Type; } set { _RawData.Type = value; } } public void Init(YnvFile ynv, NavMeshPoint point) { @@ -681,7 +865,7 @@ namespace CodeWalker.GameFiles public override string ToString() { - return Index.ToString() + ": " + Flags.ToString(); + return Index.ToString() + ": " + Type.ToString(); } } diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs index b97d2f7..4752a07 100644 --- a/CodeWalker.Core/GameFiles/GameFileCache.cs +++ b/CodeWalker.Core/GameFiles/GameFileCache.cs @@ -1834,6 +1834,8 @@ namespace CodeWalker.GameFiles var mloa = arch as MloArchetype; if (mloa != null) { + Vector3 mlobbmin = Vector3.Zero; + Vector3 mlobbmax = Vector3.Zero; Vector3[] c = new Vector3[8]; var rooms = mloa.rooms; if (rooms != null) @@ -1876,8 +1878,12 @@ namespace CodeWalker.GameFiles } room.BBMin_CW = min; room.BBMax_CW = max; + mlobbmin = Vector3.Min(mlobbmin, min); + mlobbmax = Vector3.Max(mlobbmax, max); } } + mloa.BBMin = mlobbmin; + mloa.BBMax = mlobbmax; } } } diff --git a/CodeWalker.Core/GameFiles/Resources/Nav.cs b/CodeWalker.Core/GameFiles/Resources/Nav.cs index 59777c9..8f0e0c7 100644 --- a/CodeWalker.Core/GameFiles/Resources/Nav.cs +++ b/CodeWalker.Core/GameFiles/Resources/Nav.cs @@ -65,7 +65,7 @@ namespace CodeWalker.GameFiles public uint PolysCount { get; set; } public uint AreaID { get; set; } // X + Y*100 public uint TotalBytes { get; set; } - public uint SectorUnkCount { get; set; } + public uint PointsCount { get; set; } public uint PortalsCount { get; set; } public uint PortalLinksCount { get; set; } public uint Unused_154h { get; set; } // 0x00000000 @@ -120,7 +120,7 @@ namespace CodeWalker.GameFiles PolysCount = reader.ReadUInt32(); AreaID = reader.ReadUInt32(); TotalBytes = reader.ReadUInt32(); - SectorUnkCount = reader.ReadUInt32(); + PointsCount = reader.ReadUInt32(); PortalsCount = reader.ReadUInt32(); PortalLinksCount = reader.ReadUInt32(); Unused_154h = reader.ReadUInt32(); @@ -180,7 +180,7 @@ namespace CodeWalker.GameFiles writer.Write(PolysCount); writer.Write(AreaID); writer.Write(TotalBytes); - writer.Write(SectorUnkCount); + writer.Write(PointsCount); writer.Write(PortalsCount); writer.Write(PortalLinksCount); writer.Write(Unused_154h); @@ -570,8 +570,16 @@ namespace CodeWalker.GameFiles public short MinZ { get; set; } public short MaxZ { get; set; } - public Vector3 Min { get { return new Vector3(MinX / 4.0f, MinY / 4.0f, MinZ / 4.0f); } } - public Vector3 Max { get { return new Vector3(MaxX / 4.0f, MaxY / 4.0f, MaxZ / 4.0f); } } + public Vector3 Min + { + get { return new Vector3(MinX / 4.0f, MinY / 4.0f, MinZ / 4.0f); } + set { var v = value * 4.0f; MinX = (short)v.X; MinY = (short)v.Y; MinZ = (short)v.Z; } + } + public Vector3 Max + { + get { return new Vector3(MaxX / 4.0f, MaxY / 4.0f, MaxZ / 4.0f); } + set { var v = value * 4.0f; MaxX = (short)v.X; MaxY = (short)v.Y; MaxZ = (short)v.Z; } + } public override string ToString() { @@ -635,7 +643,7 @@ namespace CodeWalker.GameFiles public FlagsUint Unknown_24h { get; set; } public FlagsUint Unknown_28h { get; set; } public ushort PartFlags { get; set; } - public ushort PortalID { get; set; } + public ushort PortalLinkID { get; set; } //public int IndexUnk { get { return (IndexFlags >> 0) & 31; } } //always 0 @@ -643,7 +651,7 @@ namespace CodeWalker.GameFiles //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 PortalUnk { get { return (byte)((PartFlags >> 12) & 0xF); } set { PartFlags = (ushort)((PartFlags & 0x0FFF) | ((value & 0xF) << 12)); } } + public byte PortalType { get { return (byte)((PartFlags >> 12) & 0xF); } set { PartFlags = (ushort)((PartFlags & 0x0FFF) | ((value & 0xF) << 12)); } } public ushort Unknown_28h_16 { get { return (ushort)((Unknown_28h.Value & 0xFFFF)); } set { Unknown_28h = (Unknown_28h.Value & 0xFFFF0000) | (value & 0xFFFFu); } } @@ -664,8 +672,8 @@ namespace CodeWalker.GameFiles Unknown_28h.Hex + ", " + //PartFlags.ToString() + ", " + //PartUnk1.ToString() + ", " + PartID.ToString() + ", " + - PortalUnk.ToString() + ", " + - PortalID.ToString(); + PortalType.ToString() + ", " + + PortalLinkID.ToString(); } } @@ -750,6 +758,14 @@ namespace CodeWalker.GameFiles } + public void SetAABBs(Vector3 min, Vector3 max) + { + AABBMin = new Vector4(min, float.NaN); + AABBMax = new Vector4(max, float.NaN); + CellAABB = new NavMeshAABB() { Min = min, Max = max }; + } + + public override string ToString() { return "[Min: "+AABBMin.ToString() + "], [Max:" + AABBMax.ToString() + "]"; @@ -763,7 +779,7 @@ namespace CodeWalker.GameFiles get { return 32; } } - public uint UnkDataStartID { get; set; } + public uint PointsStartID { get; set; } public uint Unused_04h { get; set; } // 0x00000000 public ulong PolyIDsPointer { get; set; } public ulong PointsPointer { get; set; } @@ -779,7 +795,7 @@ namespace CodeWalker.GameFiles public override void Read(ResourceDataReader reader, params object[] parameters) { - UnkDataStartID = reader.ReadUInt32(); + PointsStartID = reader.ReadUInt32(); Unused_04h = reader.ReadUInt32(); PolyIDsPointer = reader.ReadUInt64(); PointsPointer = reader.ReadUInt64(); @@ -800,7 +816,7 @@ namespace CodeWalker.GameFiles PointsCount = (ushort)(Points?.Length ?? 0); - writer.Write(UnkDataStartID); + writer.Write(PointsStartID); writer.Write(Unused_04h); writer.Write(PolyIDsPointer); writer.Write(PointsPointer); @@ -830,7 +846,7 @@ namespace CodeWalker.GameFiles public override string ToString() { - return "(Polys: " + PolyIDsCount.ToString() + ", UnkOffset: " + UnkDataStartID.ToString() + ", UnkCount: " + PointsCount.ToString() + ")"; + return "(Polys: " + PolyIDsCount.ToString() + ", PointsCount: " + PointsCount.ToString() + ", PointsStartID: " + PointsStartID.ToString() + ")"; } } @@ -840,20 +856,28 @@ namespace CodeWalker.GameFiles public ushort Y { get; set; } public ushort Z { get; set; } public byte Angle { get; set; } - public byte Flags { get; set; } + public byte Type { get; set; } - public Vector3 Position { get { return ToVector3(); } } - - public Vector3 ToVector3() + public Vector3 Position { - const float usmax = ushort.MaxValue; - return new Vector3(X / usmax, Y / usmax, Z / usmax); + get + { + const float usmax = ushort.MaxValue; + return new Vector3(X / usmax, Y / usmax, Z / usmax); + } + set + { + const float usmax = ushort.MaxValue; + X = (ushort)(value.X * usmax); + Y = (ushort)(value.Y * usmax); + Z = (ushort)(value.Z * usmax); + } } public override string ToString() { - return Flags.ToString() + ": " + Angle.ToString() + ", " + Position.ToString(); + return Type.ToString() + ": " + Angle.ToString() + ", " + Position.ToString(); } @@ -863,31 +887,28 @@ namespace CodeWalker.GameFiles [TypeConverter(typeof(ExpandableObjectConverter))] public struct NavMeshPortal { - public uint TypeFlags { get; set; } - public NavMeshVertex Position1 { get; set; } - public NavMeshVertex Position2 { get; set; } - public ushort PolyID1a { get; set; } - public ushort PolyID1b { get; set; } - public ushort PolyID2a { get; set; } - public ushort PolyID2b { get; set; } + public byte Type { get; set; } + public byte Angle { get; set; } + public ushort FlagsUnk { get; set; } + public NavMeshVertex PositionFrom { get; set; } + public NavMeshVertex PositionTo { get; set; } + public ushort PolyIDFrom1 { get; set; } + public ushort PolyIDFrom2 { get; set; } + public ushort PolyIDTo1 { get; set; } + public ushort PolyIDTo2 { get; set; } public uint AreaFlags { get; set; } - public uint Type1 { get { return TypeFlags & 0xFF; } } - public uint Type2 { get { return (TypeFlags >> 8) & 0xF; } } - public uint Type3 { get { return (TypeFlags >> 12) & 0xF; } } - public uint Type4 { get { return (TypeFlags >> 16) & 0xFFFF; } } - - public ushort AreaID1 { get { return (ushort)(AreaFlags & 0x3FFF); } } - public ushort AreaID2 { get { return (ushort)((AreaFlags >> 14) & 0x3FFF); } } - public byte AreaUnk { get { return (byte)((AreaFlags >> 28) & 0xF); } } + public ushort AreaIDFrom { get { return (ushort)(AreaFlags & 0x3FFF); } set { AreaFlags = (AreaFlags & 0xFFFFC000) | (value & 0x3FFFu); } } + public ushort AreaIDTo { get { return (ushort)((AreaFlags >> 14) & 0x3FFF); } set { AreaFlags = (AreaFlags & 0xF0003FFF) | ((value & 0x3FFFu) << 14); } } + public byte AreaUnk { get { return (byte)((AreaFlags >> 28) & 0xF); } set { AreaFlags = (AreaFlags & 0x0FFFFFFF) | ((value & 0xFu) << 28); } } public override string ToString() { - return AreaID1.ToString() + ", " + AreaID2.ToString() + ", " + AreaUnk.ToString() + ", " + - PolyID1a.ToString() + ", " + PolyID1b.ToString() + ", " + - PolyID2a.ToString() + ", " + PolyID2b.ToString() + ", " + - Type1.ToString() + ", " + Type2.ToString() + ", " + Type3.ToString() + ", " + Type4.ToString() + ", " + - "(" + Position1.ToString() + " | " + Position2.ToString() + ")"; + return AreaIDFrom.ToString() + ", " + AreaIDTo.ToString() + ", " + AreaUnk.ToString() + ", " + + PolyIDFrom1.ToString() + ", " + PolyIDFrom2.ToString() + ", " + + PolyIDTo1.ToString() + ", " + PolyIDTo2.ToString() + ", " + + Type.ToString() + ", " + Angle.ToString() + ", " + FlagsUnk.ToString() + ", " + + "(" + PositionFrom.ToString() + " | " + PositionTo.ToString() + ")"; } } diff --git a/CodeWalker.csproj b/CodeWalker.csproj index c258d29..6d2938e 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -364,12 +364,24 @@ EditYnvPanel.cs + + Form + + + EditYnvPointPanel.cs + Form EditYnvPolyPanel.cs + + Form + + + EditYnvPortalPanel.cs + Form @@ -602,9 +614,15 @@ EditYnvPanel.cs + + EditYnvPointPanel.cs + EditYnvPolyPanel.cs + + EditYnvPortalPanel.cs + EditYtypPanel.cs diff --git a/Project/Panels/EditYnvPanel.Designer.cs b/Project/Panels/EditYnvPanel.Designer.cs index fd95f08..e98b59f 100644 --- a/Project/Panels/EditYnvPanel.Designer.cs +++ b/Project/Panels/EditYnvPanel.Designer.cs @@ -41,13 +41,13 @@ this.YnvPolyCountLabel = new System.Windows.Forms.Label(); this.YnvPortalCountLabel = new System.Windows.Forms.Label(); this.YnvPortalLinkCountLabel = new System.Windows.Forms.Label(); - this.YnvSectorUnkCountLabel = new System.Windows.Forms.Label(); + this.YnvPointCountLabel = new System.Windows.Forms.Label(); this.YnvByteCountLabel = new System.Windows.Forms.Label(); this.YnvFlagsGroupBox = new System.Windows.Forms.GroupBox(); - this.YnvFlagsVerticesCheckBox = new System.Windows.Forms.CheckBox(); - this.YnvFlagsPortalsCheckBox = new System.Windows.Forms.CheckBox(); - this.YnvFlagsVehicleCheckBox = new System.Windows.Forms.CheckBox(); this.YnvFlagsUnknownCheckBox = new System.Windows.Forms.CheckBox(); + this.YnvFlagsVehicleCheckBox = new System.Windows.Forms.CheckBox(); + this.YnvFlagsPortalsCheckBox = new System.Windows.Forms.CheckBox(); + this.YnvFlagsVerticesCheckBox = new System.Windows.Forms.CheckBox(); this.YnvVersionUnkHashTextBox = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); @@ -177,14 +177,14 @@ this.YnvPortalLinkCountLabel.TabIndex = 42; this.YnvPortalLinkCountLabel.Text = "Portal link count: 0"; // - // YnvSectorUnkCountLabel + // YnvPointCountLabel // - this.YnvSectorUnkCountLabel.AutoSize = true; - this.YnvSectorUnkCountLabel.Location = new System.Drawing.Point(358, 127); - this.YnvSectorUnkCountLabel.Name = "YnvSectorUnkCountLabel"; - this.YnvSectorUnkCountLabel.Size = new System.Drawing.Size(101, 13); - this.YnvSectorUnkCountLabel.TabIndex = 43; - this.YnvSectorUnkCountLabel.Text = "Sector unk count: 0"; + this.YnvPointCountLabel.AutoSize = true; + this.YnvPointCountLabel.Location = new System.Drawing.Point(358, 127); + this.YnvPointCountLabel.Name = "YnvPointCountLabel"; + this.YnvPointCountLabel.Size = new System.Drawing.Size(73, 13); + this.YnvPointCountLabel.TabIndex = 43; + this.YnvPointCountLabel.Text = "Point count: 0"; // // YnvByteCountLabel // @@ -208,27 +208,16 @@ this.YnvFlagsGroupBox.TabStop = false; this.YnvFlagsGroupBox.Text = "Content flags"; // - // YnvFlagsVerticesCheckBox + // YnvFlagsUnknownCheckBox // - this.YnvFlagsVerticesCheckBox.AutoSize = true; - this.YnvFlagsVerticesCheckBox.Location = new System.Drawing.Point(12, 19); - this.YnvFlagsVerticesCheckBox.Name = "YnvFlagsVerticesCheckBox"; - this.YnvFlagsVerticesCheckBox.Size = new System.Drawing.Size(64, 17); - this.YnvFlagsVerticesCheckBox.TabIndex = 0; - this.YnvFlagsVerticesCheckBox.Text = "Vertices"; - this.YnvFlagsVerticesCheckBox.UseVisualStyleBackColor = true; - this.YnvFlagsVerticesCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsVerticesCheckBox_CheckedChanged); - // - // YnvFlagsPortalsCheckBox - // - this.YnvFlagsPortalsCheckBox.AutoSize = true; - this.YnvFlagsPortalsCheckBox.Location = new System.Drawing.Point(12, 42); - this.YnvFlagsPortalsCheckBox.Name = "YnvFlagsPortalsCheckBox"; - this.YnvFlagsPortalsCheckBox.Size = new System.Drawing.Size(58, 17); - this.YnvFlagsPortalsCheckBox.TabIndex = 1; - this.YnvFlagsPortalsCheckBox.Text = "Portals"; - this.YnvFlagsPortalsCheckBox.UseVisualStyleBackColor = true; - this.YnvFlagsPortalsCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsPortalsCheckBox_CheckedChanged); + this.YnvFlagsUnknownCheckBox.AutoSize = true; + this.YnvFlagsUnknownCheckBox.Location = new System.Drawing.Point(12, 88); + this.YnvFlagsUnknownCheckBox.Name = "YnvFlagsUnknownCheckBox"; + this.YnvFlagsUnknownCheckBox.Size = new System.Drawing.Size(78, 17); + this.YnvFlagsUnknownCheckBox.TabIndex = 3; + this.YnvFlagsUnknownCheckBox.Text = "[Unknown]"; + this.YnvFlagsUnknownCheckBox.UseVisualStyleBackColor = true; + this.YnvFlagsUnknownCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsUnknownCheckBox_CheckedChanged); // // YnvFlagsVehicleCheckBox // @@ -241,16 +230,27 @@ this.YnvFlagsVehicleCheckBox.UseVisualStyleBackColor = true; this.YnvFlagsVehicleCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsVehicleCheckBox_CheckedChanged); // - // YnvFlagsUnknownCheckBox + // YnvFlagsPortalsCheckBox // - this.YnvFlagsUnknownCheckBox.AutoSize = true; - this.YnvFlagsUnknownCheckBox.Location = new System.Drawing.Point(12, 88); - this.YnvFlagsUnknownCheckBox.Name = "YnvFlagsUnknownCheckBox"; - this.YnvFlagsUnknownCheckBox.Size = new System.Drawing.Size(78, 17); - this.YnvFlagsUnknownCheckBox.TabIndex = 3; - this.YnvFlagsUnknownCheckBox.Text = "[Unknown]"; - this.YnvFlagsUnknownCheckBox.UseVisualStyleBackColor = true; - this.YnvFlagsUnknownCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsUnknownCheckBox_CheckedChanged); + this.YnvFlagsPortalsCheckBox.AutoSize = true; + this.YnvFlagsPortalsCheckBox.Location = new System.Drawing.Point(12, 42); + this.YnvFlagsPortalsCheckBox.Name = "YnvFlagsPortalsCheckBox"; + this.YnvFlagsPortalsCheckBox.Size = new System.Drawing.Size(58, 17); + this.YnvFlagsPortalsCheckBox.TabIndex = 1; + this.YnvFlagsPortalsCheckBox.Text = "Portals"; + this.YnvFlagsPortalsCheckBox.UseVisualStyleBackColor = true; + this.YnvFlagsPortalsCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsPortalsCheckBox_CheckedChanged); + // + // YnvFlagsVerticesCheckBox + // + this.YnvFlagsVerticesCheckBox.AutoSize = true; + this.YnvFlagsVerticesCheckBox.Location = new System.Drawing.Point(12, 19); + this.YnvFlagsVerticesCheckBox.Name = "YnvFlagsVerticesCheckBox"; + this.YnvFlagsVerticesCheckBox.Size = new System.Drawing.Size(64, 17); + this.YnvFlagsVerticesCheckBox.TabIndex = 0; + this.YnvFlagsVerticesCheckBox.Text = "Vertices"; + this.YnvFlagsVerticesCheckBox.UseVisualStyleBackColor = true; + this.YnvFlagsVerticesCheckBox.CheckedChanged += new System.EventHandler(this.YnvFlagsVerticesCheckBox_CheckedChanged); // // YnvVersionUnkHashTextBox // @@ -357,7 +357,7 @@ this.Controls.Add(this.label1); this.Controls.Add(this.YnvFlagsGroupBox); this.Controls.Add(this.YnvByteCountLabel); - this.Controls.Add(this.YnvSectorUnkCountLabel); + this.Controls.Add(this.YnvPointCountLabel); this.Controls.Add(this.YnvPortalLinkCountLabel); this.Controls.Add(this.YnvPortalCountLabel); this.Controls.Add(this.YnvPolyCountLabel); @@ -396,7 +396,7 @@ private System.Windows.Forms.Label YnvPolyCountLabel; private System.Windows.Forms.Label YnvPortalCountLabel; private System.Windows.Forms.Label YnvPortalLinkCountLabel; - private System.Windows.Forms.Label YnvSectorUnkCountLabel; + private System.Windows.Forms.Label YnvPointCountLabel; private System.Windows.Forms.Label YnvByteCountLabel; private System.Windows.Forms.GroupBox YnvFlagsGroupBox; private System.Windows.Forms.CheckBox YnvFlagsUnknownCheckBox; diff --git a/Project/Panels/EditYnvPanel.cs b/Project/Panels/EditYnvPanel.cs index 433f59f..9d63133 100644 --- a/Project/Panels/EditYnvPanel.cs +++ b/Project/Panels/EditYnvPanel.cs @@ -72,7 +72,7 @@ namespace CodeWalker.Project.Panels YnvPolyCountLabel.Text = "Poly count: -"; YnvPortalCountLabel.Text = "Portal count: -"; YnvPortalLinkCountLabel.Text = "Portal link count: -"; - YnvSectorUnkCountLabel.Text = "Sector unk count: -"; + YnvPointCountLabel.Text = "Sector unk count: -"; YnvByteCountLabel.Text = "Byte count: -"; YnvVersionUnkHashTextBox.Text = string.Empty; } @@ -95,7 +95,7 @@ namespace CodeWalker.Project.Panels YnvPolyCountLabel.Text = "Poly count: " + nv.PolysCount.ToString(); YnvPortalCountLabel.Text = "Portal count: " + nv.PortalsCount.ToString(); YnvPortalLinkCountLabel.Text = "Portal link count: " + nv.PortalLinksCount.ToString(); - YnvSectorUnkCountLabel.Text = "Sector unk count: " + nv.SectorUnkCount.ToString(); + YnvPointCountLabel.Text = "Point count: " + nv.PointsCount.ToString(); YnvByteCountLabel.Text = "Byte count: " + nv.TotalBytes.ToString(); YnvVersionUnkHashTextBox.Text = nv.VersionUnk2.ToString(); YnvAdjAreaIDsTextBox.Text = GetAdjAreaIDsString(nv.AdjAreaIDs.Values); diff --git a/Project/Panels/EditYnvPointPanel.Designer.cs b/Project/Panels/EditYnvPointPanel.Designer.cs new file mode 100644 index 0000000..17a7ff0 --- /dev/null +++ b/Project/Panels/EditYnvPointPanel.Designer.cs @@ -0,0 +1,174 @@ +namespace CodeWalker.Project.Panels +{ + partial class EditYnvPointPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditYnvPointPanel)); + this.DeletePointButton = new System.Windows.Forms.Button(); + this.AddToProjectButton = new System.Windows.Forms.Button(); + this.YnvPointGoToButton = new System.Windows.Forms.Button(); + this.YnvPointPositionTextBox = new System.Windows.Forms.TextBox(); + this.label55 = new System.Windows.Forms.Label(); + this.YnvPointTypeUpDown = new System.Windows.Forms.NumericUpDown(); + this.label49 = new System.Windows.Forms.Label(); + this.YnvPointAngleUpDown = new System.Windows.Forms.NumericUpDown(); + this.label1 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.YnvPointTypeUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.YnvPointAngleUpDown)).BeginInit(); + this.SuspendLayout(); + // + // DeletePointButton + // + this.DeletePointButton.Enabled = false; + this.DeletePointButton.Location = new System.Drawing.Point(120, 119); + this.DeletePointButton.Name = "DeletePointButton"; + this.DeletePointButton.Size = new System.Drawing.Size(90, 23); + this.DeletePointButton.TabIndex = 8; + this.DeletePointButton.Text = "Delete Point"; + this.DeletePointButton.UseVisualStyleBackColor = true; + this.DeletePointButton.Click += new System.EventHandler(this.DeletePointButton_Click); + // + // AddToProjectButton + // + this.AddToProjectButton.Enabled = false; + this.AddToProjectButton.Location = new System.Drawing.Point(24, 119); + this.AddToProjectButton.Name = "AddToProjectButton"; + this.AddToProjectButton.Size = new System.Drawing.Size(90, 23); + this.AddToProjectButton.TabIndex = 7; + this.AddToProjectButton.Text = "Add to Project"; + this.AddToProjectButton.UseVisualStyleBackColor = true; + this.AddToProjectButton.Click += new System.EventHandler(this.AddToProjectButton_Click); + // + // YnvPointGoToButton + // + this.YnvPointGoToButton.Location = new System.Drawing.Point(280, 10); + this.YnvPointGoToButton.Name = "YnvPointGoToButton"; + this.YnvPointGoToButton.Size = new System.Drawing.Size(68, 23); + this.YnvPointGoToButton.TabIndex = 2; + this.YnvPointGoToButton.Text = "Go to"; + this.YnvPointGoToButton.UseVisualStyleBackColor = true; + this.YnvPointGoToButton.Click += new System.EventHandler(this.YnvPointGoToButton_Click); + // + // YnvPointPositionTextBox + // + this.YnvPointPositionTextBox.Location = new System.Drawing.Point(74, 12); + this.YnvPointPositionTextBox.Name = "YnvPointPositionTextBox"; + this.YnvPointPositionTextBox.Size = new System.Drawing.Size(200, 20); + this.YnvPointPositionTextBox.TabIndex = 1; + this.YnvPointPositionTextBox.TextChanged += new System.EventHandler(this.YnvPointPositionTextBox_TextChanged); + // + // label55 + // + this.label55.AutoSize = true; + this.label55.Location = new System.Drawing.Point(21, 15); + this.label55.Name = "label55"; + this.label55.Size = new System.Drawing.Size(47, 13); + this.label55.TabIndex = 0; + this.label55.Text = "Position:"; + // + // YnvPointTypeUpDown + // + this.YnvPointTypeUpDown.Location = new System.Drawing.Point(74, 64); + this.YnvPointTypeUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.YnvPointTypeUpDown.Name = "YnvPointTypeUpDown"; + this.YnvPointTypeUpDown.Size = new System.Drawing.Size(74, 20); + this.YnvPointTypeUpDown.TabIndex = 6; + this.YnvPointTypeUpDown.ValueChanged += new System.EventHandler(this.YnvPointTypeUpDown_ValueChanged); + // + // label49 + // + this.label49.AutoSize = true; + this.label49.Location = new System.Drawing.Point(34, 66); + this.label49.Name = "label49"; + this.label49.Size = new System.Drawing.Size(34, 13); + this.label49.TabIndex = 5; + this.label49.Text = "Type:"; + // + // YnvPointAngleUpDown + // + this.YnvPointAngleUpDown.Location = new System.Drawing.Point(74, 38); + this.YnvPointAngleUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.YnvPointAngleUpDown.Name = "YnvPointAngleUpDown"; + this.YnvPointAngleUpDown.Size = new System.Drawing.Size(74, 20); + this.YnvPointAngleUpDown.TabIndex = 4; + this.YnvPointAngleUpDown.ValueChanged += new System.EventHandler(this.YnvPointAngleUpDown_ValueChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(18, 40); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(50, 13); + this.label1.TabIndex = 3; + this.label1.Text = "Rotation:"; + // + // EditYnvPointPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(434, 243); + this.Controls.Add(this.YnvPointAngleUpDown); + this.Controls.Add(this.label1); + this.Controls.Add(this.YnvPointTypeUpDown); + this.Controls.Add(this.label49); + this.Controls.Add(this.DeletePointButton); + this.Controls.Add(this.AddToProjectButton); + this.Controls.Add(this.YnvPointGoToButton); + this.Controls.Add(this.YnvPointPositionTextBox); + this.Controls.Add(this.label55); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EditYnvPointPanel"; + this.Text = "Edit Ynv Point"; + ((System.ComponentModel.ISupportInitialize)(this.YnvPointTypeUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.YnvPointAngleUpDown)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button DeletePointButton; + private System.Windows.Forms.Button AddToProjectButton; + private System.Windows.Forms.Button YnvPointGoToButton; + private System.Windows.Forms.TextBox YnvPointPositionTextBox; + private System.Windows.Forms.Label label55; + private System.Windows.Forms.NumericUpDown YnvPointTypeUpDown; + private System.Windows.Forms.Label label49; + private System.Windows.Forms.NumericUpDown YnvPointAngleUpDown; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/Project/Panels/EditYnvPointPanel.cs b/Project/Panels/EditYnvPointPanel.cs new file mode 100644 index 0000000..28c17ab --- /dev/null +++ b/Project/Panels/EditYnvPointPanel.cs @@ -0,0 +1,150 @@ +using CodeWalker.GameFiles; +using SharpDX; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CodeWalker.Project.Panels +{ + public partial class EditYnvPointPanel : ProjectPanel + { + public ProjectForm ProjectForm; + public YnvPoint YnvPoint { get; set; } + + private bool populatingui = false; + + public EditYnvPointPanel(ProjectForm projectForm) + { + ProjectForm = projectForm; + InitializeComponent(); + } + + public void SetYnvPoint(YnvPoint ynvPoint) + { + YnvPoint = ynvPoint; + Tag = ynvPoint; + UpdateFormTitle(); + UpdateYnvPointUI(); + } + + private void UpdateFormTitle() + { + Text = "Nav Point " + YnvPoint.Index.ToString(); + } + + + public void UpdateYnvPointUI() + { + if (YnvPoint == null) + { + ////YnvPointPanel.Enabled = false; + DeletePointButton.Enabled = false; + AddToProjectButton.Enabled = false; + YnvPointPositionTextBox.Text = string.Empty; + YnvPointAngleUpDown.Value = 0; + YnvPointTypeUpDown.Value = 0; + } + else + { + populatingui = true; + ////YnvPortalPanel.Enabled = true; + DeletePointButton.Enabled = ProjectForm.YnvExistsInProject(YnvPoint.Ynv); + AddToProjectButton.Enabled = !DeletePointButton.Enabled; + YnvPointPositionTextBox.Text = FloatUtil.GetVector3String(YnvPoint.Position); + YnvPointAngleUpDown.Value = YnvPoint.Angle; + YnvPointTypeUpDown.Value = YnvPoint.Type; + populatingui = false; + } + } + + private void YnvPointPositionTextBox_TextChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPoint == null) return; + Vector3 v = FloatUtil.ParseVector3String(YnvPointPositionTextBox.Text); + bool change = false; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPoint.Position != v) + { + YnvPoint.SetPosition(v); + ProjectForm.SetYnvHasChanged(true); + change = true; + } + } + if (change) + { + if (ProjectForm.WorldForm != null) + { + ProjectForm.WorldForm.SetWidgetPosition(YnvPoint.Position); + ProjectForm.WorldForm.UpdateNavPointGraphics(YnvPoint, false); + } + } + } + + private void YnvPointAngleUpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPoint == null) return; + byte ang = (byte)YnvPointAngleUpDown.Value; + bool change = false; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPoint.Angle != ang) + { + YnvPoint.Angle = ang; + ProjectForm.SetYnvHasChanged(true); + change = true; + } + } + if (change) + { + if (ProjectForm.WorldForm != null) + { + ProjectForm.WorldForm.SetWidgetRotation(YnvPoint.Orientation); + //ProjectForm.WorldForm.UpdateNavPointGraphics(YnvPoint, false); + } + } + } + + private void YnvPointTypeUpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPoint == null) return; + byte typ = (byte)YnvPointTypeUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPoint.Type != typ) + { + YnvPoint.Type = typ; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void YnvPointGoToButton_Click(object sender, EventArgs e) + { + if (YnvPoint == null) return; + if (ProjectForm.WorldForm == null) return; + ProjectForm.WorldForm.GoToPosition(YnvPoint.Position); + } + + private void AddToProjectButton_Click(object sender, EventArgs e) + { + if (YnvPoint == null) return; + ProjectForm.SetProjectItem(YnvPoint); + ProjectForm.AddYnvToProject(YnvPoint.Ynv); + } + + private void DeletePointButton_Click(object sender, EventArgs e) + { + MessageBox.Show("Delete Point TODO!"); + } + } +} diff --git a/Project/Panels/EditYnvPointPanel.resx b/Project/Panels/EditYnvPointPanel.resx new file mode 100644 index 0000000..1431f6b --- /dev/null +++ b/Project/Panels/EditYnvPointPanel.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAMAICAAAAAAGACoDAAANgAAABAQAAAAABgAaAMAAN4MAABAQAAAAAAYACgyAABGEAAAKAAAACAA + AABAAAAAAQAYAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv8/u3v+Pn6//7+/wAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AP7+/vX3/rzA3OHl9fz9/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7//+zv+3Z6qcLI5Pr7/wAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAP7+/+br+15in6+33vf5/wAAAAAAAAAAAAAAAP7+//7+/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3+//v8//v8//3+/wAAAAAAAAAAAAAAAAAAAP7+/+Ho+1dana20 + 4/b4/wAAAAAAAPz9//P2/+Tp/ezw/vz9/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7///X4 + /9Pa+tPa+/H1//z9/wAAAAAAAAAAAAAAAP7+/93k+SsscaSr3PX3/wAAAP7+//L1/7W98AcWgrvC8Pj6 + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/+bs/xohiAEJdrvF9+7y//z9/wAAAAAAAAAA + AP7+/9rh+CEkapmh0/T3/wAAAPj6/9HZ/AEHcgEEb9LZ+/r7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAP7//+/z/3F+zAAAXwQLcZai3fb4/wAAAAAAAAAAAP3+/97l/E9Tmaau4fT3/wAAAO/0/1dd + sAAAV7a/8/H1//7+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPr8/+jv/46Y3QUUf6Ot + 5PX4/wAAAAAAAAAAAP3+/9zj+3Z6wLe/7fX4/wAAAPD0/212xnaAzerw//z9/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv8/+/z/+Dm+/D0//z9/wAAAAAAAP7+//j6/9Pd+UhLjb/H + 9/D0//3+//n7/+nt/+jt//n7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AP7///7+//7+//7+/wAAAAAAAPr8/+7z/83W+ImU2A0UdFNarr/K9env//X4//z9//3+//7//wAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7///j6/+Pq/255 + xhckjE5XsVVftUlTqwAKeTA9nr3H8+7z//v8/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+//b4/9Tc+Sc0mRonj8rV/crX/ZSb48rX/brG8wwWgQAEdJei + 4efu//n7//7+//z9//z9//z9//z9//3+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAP3+//f5/+3y/+nv/+ft + /8vV+io2mImU2M7c/7vG9yIvlQAOfCg4mM3Y/s/c/4aR1AQRfGtzwtni/ebt/9vi/tri/tXd+9Tc+O3x + /vz9/wAAAAAAAAAAAAAAAAAAAAAAAPn6/87V+FVftkRPrFlnvSEqjQoUfmJvwWFvvg0TfQQIcxEchwAD + cy89n19rvVVitQwZgwAAaiMrkT9NqTVBoiw3mhQihig1mNLX+fv8/wAAAAAAAAAAAAAAAAAAAAAAAPb5 + /52l4EFLqoCK03yF0VBctGhyw52o5GVrvQAAaneBzsHM+jA3mhYgiTtIpJOf3ouW2AAAbmh0wbbA8bS+ + 7qiz5pCb16+56e/z//3+/wAAAAAAAAAAAAAAAAAAAAAAAPv8//H1/+vw/+zx/+nv/7/J9YqP3MbP/8LM + +hwqkFZftaCp5EhRrcTQ+9jj/8rW/UJMqn6J0ebt//X3//f5//b4//X3//f5//z9/wAAAAAAAAAAAAAA + AAAAAAAAAP7+//z9//3+/wAAAAAAAP3+/+7z/6at64iP3aWs7XN8zRIfhyUykp2o5MHM+oKM0xonjY6X + 2+jv//v8/wAAAP7+//n7//b5//r7//7//wAAAAAAAAAAAAAAAP7+//f5/+rw/9Pa9fL0/v7//wAAAAAA + APv8//H1/+Tr/7i/91liu0NPq0VQrS06m0NNqDdCoYqU1+nv//v8/wAAAAAAAPn7/9zi/qSt59ri/fL1 + //v8//7//wAAAPz9//D0/8rT+h0sjkVQrPD0/wAAAAAAAAAAAAAAAAAAAPz9/+7z/8LL9Jqk4aGq6LW/ + 8c3W9+Xs/vH1//v8/wAAAAAAAAAAAPf5/6at5gAAbxIfh6u16+Po/fr7/wAAAPb5/6ev5gAIeAAPernC + 8fX4/wAAAAAAAP3+//v8//z9/wAAAP3+//j6//P3//P2//b4//r8//7+//7+//v8//r8//3+/wAAAPv8 + /+Xr/nuIzwAAbBseg5Sb2fb5/wAAAPf5/8DF8pWe3d/n/vT3//39/wAAAPv8/+zx/87V9+3x/v3+/wAA + AP3+//j6//X4//v8/wAAAAAAAPn7/+Dm/snR9fD0//39//z8/fv8/+3y/8LK9aGq4dfd9/n7/wAAAPz9 + //b5//X4//v8/wAAAAAAAP7+/+7z/4aP1gEPet7k/f39/wAAAPf5/83U+ZCZ2u3x/v7+/wAAAPP3/215 + wgAJd7fB8/L1//7+/wAAAP3+//j6//f5//r8//7+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAPj6/87W/AAA + X2duue3y//7+/wAAAPD0/05asBQfidzj/P39/wAAAPX4/6Su6AAAXBccgtff/vv8/wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP3/3F8xhYli9Xe/fn6/wAAAAAAAO3y/1pltQAJd9be + /fv8/wAAAPz9/+rw/36I0Bknjs/W+vv8/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAPf5/8HI7tnf+/X4//7+/wAAAAAAAO/0/3R7xgAAb9ng/Pz9/wAAAAAAAPn7/+Ln/dLY+fP2//3+ + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3+//r7//v8//7+/wAAAAAAAAAA + APb4/7/F84eP0e/0//7+/wAAAAAAAP7+//z9//v8//3+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz9//b5//X4//v8/wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////w////4 + P///+D////g8//D4MH/geCB/4Dggf+A4IH/wOCD/+DAB//hgAf//gAP//wAAB/AAAAPwAAAD8AAAA/AA + AAfjAAEHgYADAQPgBwEDEAEBAghgAQwIIEH8CCB//Bggf/wYMH/8ODD///h/////////////KAAAABAA + AAAgAAAAAQAYAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///+vv/fL1/v///wAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///4+Vx7/F5v///wAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAP///4CHtrS62////////////////////wAAAAAAAAAAAP////H0/vf6/v// + /////////4yTwrrB4f///+zw+7rA6P39/////wAAAAAAAAAAAP///56l2BkcguXr/P///////42Uw8jO + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/ + /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA + AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/ + /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file diff --git a/Project/Panels/EditYnvPolyPanel.Designer.cs b/Project/Panels/EditYnvPolyPanel.Designer.cs index cce52d1..4830cec 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.PortalUnkUpDown = new System.Windows.Forms.NumericUpDown(); + this.PortalTypeUpDown = 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.PortalUnkUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PortalTypeUpDown)).BeginInit(); this.SuspendLayout(); // // AreaIDUpDown @@ -102,7 +102,7 @@ // // PortalIDUpDown // - this.PortalIDUpDown.Location = new System.Drawing.Point(338, 12); + this.PortalIDUpDown.Location = new System.Drawing.Point(346, 12); this.PortalIDUpDown.Maximum = new decimal(new int[] { 65535, 0, @@ -116,11 +116,11 @@ // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(281, 14); + this.label2.Location = new System.Drawing.Point(280, 14); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(51, 13); + this.label2.Size = new System.Drawing.Size(60, 13); this.label2.TabIndex = 5; - this.label2.Text = "Portal ID:"; + this.label2.Text = "Portal Link:"; // // FlagsCheckedListBox1 // @@ -273,34 +273,34 @@ this.AddToProjectButton.UseVisualStyleBackColor = true; this.AddToProjectButton.Click += new System.EventHandler(this.AddToProjectButton_Click); // - // PortalUnkUpDown + // PortalTypeUpDown // - this.PortalUnkUpDown.Location = new System.Drawing.Point(495, 12); - this.PortalUnkUpDown.Maximum = new decimal(new int[] { + this.PortalTypeUpDown.Location = new System.Drawing.Point(495, 12); + this.PortalTypeUpDown.Maximum = new decimal(new int[] { 15, 0, 0, 0}); - this.PortalUnkUpDown.Name = "PortalUnkUpDown"; - this.PortalUnkUpDown.Size = new System.Drawing.Size(57, 20); - this.PortalUnkUpDown.TabIndex = 8; - this.PortalUnkUpDown.ValueChanged += new System.EventHandler(this.PortalUnkUpDown_ValueChanged); + 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); // // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(431, 14); + this.label6.Location = new System.Drawing.Point(429, 14); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(58, 13); + this.label6.Size = new System.Drawing.Size(60, 13); this.label6.TabIndex = 7; - this.label6.Text = "Portal unk:"; + this.label6.Text = "Portal type:"; // // 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.PortalUnkUpDown); + this.Controls.Add(this.PortalTypeUpDown); 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.PortalUnkUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PortalTypeUpDown)).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 PortalUnkUpDown; + private System.Windows.Forms.NumericUpDown PortalTypeUpDown; 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 c77ab2c..595fc73 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; - PortalUnkUpDown.Value = 0; + PortalTypeUpDown.Value = 0; SetCheckedListBoxValues(FlagsCheckedListBox1, 0); SetCheckedListBoxValues(FlagsCheckedListBox2, 0); SetCheckedListBoxValues(FlagsCheckedListBox3, 0); @@ -64,8 +64,8 @@ namespace CodeWalker.Project.Panels AddToProjectButton.Enabled = !DeletePolyButton.Enabled; AreaIDUpDown.Value = YnvPoly.AreaID; PartIDUpDown.Value = YnvPoly.PartID; - PortalIDUpDown.Value = YnvPoly.PortalID; - PortalUnkUpDown.Value = YnvPoly.PortalUnk; + PortalIDUpDown.Value = YnvPoly.PortalLinkID; + PortalTypeUpDown.Value = YnvPoly.PortalType; SetCheckedListBoxValues(FlagsCheckedListBox1, YnvPoly.Flags1); SetCheckedListBoxValues(FlagsCheckedListBox2, YnvPoly.Flags2); SetCheckedListBoxValues(FlagsCheckedListBox3, YnvPoly.Flags3); @@ -144,24 +144,24 @@ namespace CodeWalker.Project.Panels ushort portalid = (ushort)PortalIDUpDown.Value; lock (ProjectForm.ProjectSyncRoot) { - if (YnvPoly.PortalID != portalid) + if (YnvPoly.PortalLinkID != portalid) { - YnvPoly.PortalID = portalid; + YnvPoly.PortalLinkID = portalid; ProjectForm.SetYnvHasChanged(true); } } } - private void PortalUnkUpDown_ValueChanged(object sender, EventArgs e) + private void PortalTypeUpDown_ValueChanged(object sender, EventArgs e) { if (populatingui) return; if (YnvPoly == null) return; - byte portalunk = (byte)PortalUnkUpDown.Value; + byte portalunk = (byte)PortalTypeUpDown.Value; lock (ProjectForm.ProjectSyncRoot) { - if (YnvPoly.PortalUnk != portalunk) + if (YnvPoly.PortalType != portalunk) { - YnvPoly.PortalUnk = portalunk; + YnvPoly.PortalType = portalunk; ProjectForm.SetYnvHasChanged(true); } } diff --git a/Project/Panels/EditYnvPortalPanel.Designer.cs b/Project/Panels/EditYnvPortalPanel.Designer.cs new file mode 100644 index 0000000..9748c81 --- /dev/null +++ b/Project/Panels/EditYnvPortalPanel.Designer.cs @@ -0,0 +1,437 @@ +namespace CodeWalker.Project.Panels +{ + partial class EditYnvPortalPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditYnvPortalPanel)); + this.AngleUpDown = new System.Windows.Forms.NumericUpDown(); + this.label1 = new System.Windows.Forms.Label(); + this.TypeUpDown = new System.Windows.Forms.NumericUpDown(); + this.label49 = new System.Windows.Forms.Label(); + this.DeletePortalButton = new System.Windows.Forms.Button(); + this.AddToProjectButton = new System.Windows.Forms.Button(); + this.GoToButton = new System.Windows.Forms.Button(); + this.PositionFromTextBox = new System.Windows.Forms.TextBox(); + this.label55 = new System.Windows.Forms.Label(); + this.PositionToTextBox = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.AreaIDFromUpDown = new System.Windows.Forms.NumericUpDown(); + this.label92 = new System.Windows.Forms.Label(); + this.AreaIDToUpDown = new System.Windows.Forms.NumericUpDown(); + this.label3 = new System.Windows.Forms.Label(); + this.PolyIDTo1UpDown = new System.Windows.Forms.NumericUpDown(); + this.label4 = new System.Windows.Forms.Label(); + this.PolyIDFrom1UpDown = new System.Windows.Forms.NumericUpDown(); + this.label5 = new System.Windows.Forms.Label(); + this.PolyIDTo2UpDown = new System.Windows.Forms.NumericUpDown(); + this.label6 = new System.Windows.Forms.Label(); + this.PolyIDFrom2UpDown = new System.Windows.Forms.NumericUpDown(); + this.label7 = new System.Windows.Forms.Label(); + this.Unk2UpDown = new System.Windows.Forms.NumericUpDown(); + this.label8 = new System.Windows.Forms.Label(); + this.Unk1UpDown = new System.Windows.Forms.NumericUpDown(); + this.label9 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.AngleUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.TypeUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.AreaIDFromUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.AreaIDToUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDTo1UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDFrom1UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDTo2UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDFrom2UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.Unk2UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.Unk1UpDown)).BeginInit(); + this.SuspendLayout(); + // + // AngleUpDown + // + this.AngleUpDown.Location = new System.Drawing.Point(96, 64); + this.AngleUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.AngleUpDown.Name = "AngleUpDown"; + this.AngleUpDown.Size = new System.Drawing.Size(71, 20); + this.AngleUpDown.TabIndex = 13; + this.AngleUpDown.ValueChanged += new System.EventHandler(this.AngleUpDown_ValueChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(40, 66); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(50, 13); + this.label1.TabIndex = 12; + this.label1.Text = "Rotation:"; + // + // TypeUpDown + // + this.TypeUpDown.Location = new System.Drawing.Point(256, 64); + this.TypeUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.TypeUpDown.Name = "TypeUpDown"; + this.TypeUpDown.Size = new System.Drawing.Size(71, 20); + this.TypeUpDown.TabIndex = 15; + this.TypeUpDown.ValueChanged += new System.EventHandler(this.TypeUpDown_ValueChanged); + // + // label49 + // + this.label49.AutoSize = true; + this.label49.Location = new System.Drawing.Point(216, 66); + this.label49.Name = "label49"; + this.label49.Size = new System.Drawing.Size(34, 13); + this.label49.TabIndex = 14; + this.label49.Text = "Type:"; + // + // DeletePortalButton + // + this.DeletePortalButton.Enabled = false; + this.DeletePortalButton.Location = new System.Drawing.Point(133, 215); + this.DeletePortalButton.Name = "DeletePortalButton"; + this.DeletePortalButton.Size = new System.Drawing.Size(90, 23); + this.DeletePortalButton.TabIndex = 17; + this.DeletePortalButton.Text = "Delete Portal"; + this.DeletePortalButton.UseVisualStyleBackColor = true; + this.DeletePortalButton.Click += new System.EventHandler(this.DeletePortalButton_Click); + // + // AddToProjectButton + // + this.AddToProjectButton.Enabled = false; + this.AddToProjectButton.Location = new System.Drawing.Point(37, 215); + this.AddToProjectButton.Name = "AddToProjectButton"; + this.AddToProjectButton.Size = new System.Drawing.Size(90, 23); + this.AddToProjectButton.TabIndex = 16; + this.AddToProjectButton.Text = "Add to Project"; + this.AddToProjectButton.UseVisualStyleBackColor = true; + this.AddToProjectButton.Click += new System.EventHandler(this.AddToProjectButton_Click); + // + // GoToButton + // + this.GoToButton.Location = new System.Drawing.Point(302, 10); + this.GoToButton.Name = "GoToButton"; + this.GoToButton.Size = new System.Drawing.Size(68, 23); + this.GoToButton.TabIndex = 11; + this.GoToButton.Text = "Go to"; + this.GoToButton.UseVisualStyleBackColor = true; + this.GoToButton.Click += new System.EventHandler(this.GoToButton_Click); + // + // PositionFromTextBox + // + this.PositionFromTextBox.Location = new System.Drawing.Point(96, 12); + this.PositionFromTextBox.Name = "PositionFromTextBox"; + this.PositionFromTextBox.Size = new System.Drawing.Size(200, 20); + this.PositionFromTextBox.TabIndex = 10; + this.PositionFromTextBox.TextChanged += new System.EventHandler(this.PositionFromTextBox_TextChanged); + // + // label55 + // + this.label55.AutoSize = true; + this.label55.Location = new System.Drawing.Point(17, 15); + this.label55.Name = "label55"; + this.label55.Size = new System.Drawing.Size(73, 13); + this.label55.TabIndex = 9; + this.label55.Text = "From Position:"; + // + // PositionToTextBox + // + this.PositionToTextBox.Location = new System.Drawing.Point(96, 38); + this.PositionToTextBox.Name = "PositionToTextBox"; + this.PositionToTextBox.Size = new System.Drawing.Size(200, 20); + this.PositionToTextBox.TabIndex = 19; + this.PositionToTextBox.TextChanged += new System.EventHandler(this.PositionToTextBox_TextChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(27, 41); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(63, 13); + this.label2.TabIndex = 18; + this.label2.Text = "To Position:"; + // + // AreaIDFromUpDown + // + this.AreaIDFromUpDown.Location = new System.Drawing.Point(96, 90); + this.AreaIDFromUpDown.Maximum = new decimal(new int[] { + 16383, + 0, + 0, + 0}); + this.AreaIDFromUpDown.Name = "AreaIDFromUpDown"; + this.AreaIDFromUpDown.Size = new System.Drawing.Size(71, 20); + this.AreaIDFromUpDown.TabIndex = 21; + this.AreaIDFromUpDown.ValueChanged += new System.EventHandler(this.AreaIDFromUpDown_ValueChanged); + // + // label92 + // + this.label92.AutoSize = true; + this.label92.Location = new System.Drawing.Point(18, 92); + this.label92.Name = "label92"; + this.label92.Size = new System.Drawing.Size(72, 13); + this.label92.TabIndex = 20; + this.label92.Text = "From Area ID:"; + // + // AreaIDToUpDown + // + this.AreaIDToUpDown.Location = new System.Drawing.Point(256, 90); + this.AreaIDToUpDown.Maximum = new decimal(new int[] { + 16383, + 0, + 0, + 0}); + this.AreaIDToUpDown.Name = "AreaIDToUpDown"; + this.AreaIDToUpDown.Size = new System.Drawing.Size(71, 20); + this.AreaIDToUpDown.TabIndex = 23; + this.AreaIDToUpDown.ValueChanged += new System.EventHandler(this.AreaIDToUpDown_ValueChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(188, 92); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(62, 13); + this.label3.TabIndex = 22; + this.label3.Text = "To Area ID:"; + // + // PolyIDTo1UpDown + // + this.PolyIDTo1UpDown.Location = new System.Drawing.Point(256, 116); + this.PolyIDTo1UpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.PolyIDTo1UpDown.Name = "PolyIDTo1UpDown"; + this.PolyIDTo1UpDown.Size = new System.Drawing.Size(71, 20); + this.PolyIDTo1UpDown.TabIndex = 27; + this.PolyIDTo1UpDown.ValueChanged += new System.EventHandler(this.PolyIDTo1UpDown_ValueChanged); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(181, 118); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(69, 13); + this.label4.TabIndex = 26; + this.label4.Text = "To Poly ID 1:"; + // + // PolyIDFrom1UpDown + // + this.PolyIDFrom1UpDown.Location = new System.Drawing.Point(96, 116); + this.PolyIDFrom1UpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.PolyIDFrom1UpDown.Name = "PolyIDFrom1UpDown"; + this.PolyIDFrom1UpDown.Size = new System.Drawing.Size(71, 20); + this.PolyIDFrom1UpDown.TabIndex = 25; + this.PolyIDFrom1UpDown.ValueChanged += new System.EventHandler(this.PolyIDFrom1UpDown_ValueChanged); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(11, 118); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(79, 13); + this.label5.TabIndex = 24; + this.label5.Text = "From Poly ID 1:"; + // + // PolyIDTo2UpDown + // + this.PolyIDTo2UpDown.Location = new System.Drawing.Point(256, 142); + this.PolyIDTo2UpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.PolyIDTo2UpDown.Name = "PolyIDTo2UpDown"; + this.PolyIDTo2UpDown.Size = new System.Drawing.Size(71, 20); + this.PolyIDTo2UpDown.TabIndex = 31; + this.PolyIDTo2UpDown.ValueChanged += new System.EventHandler(this.PolyIDTo2UpDown_ValueChanged); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(181, 144); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(69, 13); + this.label6.TabIndex = 30; + this.label6.Text = "To Poly ID 2:"; + // + // PolyIDFrom2UpDown + // + this.PolyIDFrom2UpDown.Location = new System.Drawing.Point(96, 142); + this.PolyIDFrom2UpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.PolyIDFrom2UpDown.Name = "PolyIDFrom2UpDown"; + this.PolyIDFrom2UpDown.Size = new System.Drawing.Size(71, 20); + this.PolyIDFrom2UpDown.TabIndex = 29; + this.PolyIDFrom2UpDown.ValueChanged += new System.EventHandler(this.PolyIDFrom2UpDown_ValueChanged); + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(11, 144); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(79, 13); + this.label7.TabIndex = 28; + this.label7.Text = "From Poly ID 2:"; + // + // Unk2UpDown + // + this.Unk2UpDown.Location = new System.Drawing.Point(256, 168); + this.Unk2UpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.Unk2UpDown.Name = "Unk2UpDown"; + this.Unk2UpDown.Size = new System.Drawing.Size(71, 20); + this.Unk2UpDown.TabIndex = 35; + this.Unk2UpDown.ValueChanged += new System.EventHandler(this.Unk2UpDown_ValueChanged); + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(211, 170); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(39, 13); + this.label8.TabIndex = 34; + this.label8.Text = "Unk 2:"; + // + // Unk1UpDown + // + this.Unk1UpDown.Location = new System.Drawing.Point(96, 168); + this.Unk1UpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.Unk1UpDown.Name = "Unk1UpDown"; + this.Unk1UpDown.Size = new System.Drawing.Size(71, 20); + this.Unk1UpDown.TabIndex = 33; + this.Unk1UpDown.ValueChanged += new System.EventHandler(this.Unk1UpDown_ValueChanged); + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(51, 170); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(39, 13); + this.label9.TabIndex = 32; + this.label9.Text = "Unk 1:"; + // + // EditYnvPortalPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(454, 295); + this.Controls.Add(this.Unk2UpDown); + this.Controls.Add(this.label8); + this.Controls.Add(this.Unk1UpDown); + this.Controls.Add(this.label9); + this.Controls.Add(this.PolyIDTo2UpDown); + this.Controls.Add(this.label6); + this.Controls.Add(this.PolyIDFrom2UpDown); + this.Controls.Add(this.label7); + this.Controls.Add(this.PolyIDTo1UpDown); + this.Controls.Add(this.label4); + this.Controls.Add(this.PolyIDFrom1UpDown); + this.Controls.Add(this.label5); + this.Controls.Add(this.AreaIDToUpDown); + this.Controls.Add(this.label3); + this.Controls.Add(this.AreaIDFromUpDown); + this.Controls.Add(this.label92); + this.Controls.Add(this.PositionToTextBox); + this.Controls.Add(this.label2); + this.Controls.Add(this.AngleUpDown); + this.Controls.Add(this.label1); + this.Controls.Add(this.TypeUpDown); + this.Controls.Add(this.label49); + this.Controls.Add(this.DeletePortalButton); + this.Controls.Add(this.AddToProjectButton); + this.Controls.Add(this.GoToButton); + this.Controls.Add(this.PositionFromTextBox); + this.Controls.Add(this.label55); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EditYnvPortalPanel"; + this.Text = "Edit Ynv Portal"; + ((System.ComponentModel.ISupportInitialize)(this.AngleUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.TypeUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.AreaIDFromUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.AreaIDToUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDTo1UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDFrom1UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDTo2UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyIDFrom2UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.Unk2UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.Unk1UpDown)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.NumericUpDown AngleUpDown; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown TypeUpDown; + private System.Windows.Forms.Label label49; + private System.Windows.Forms.Button DeletePortalButton; + private System.Windows.Forms.Button AddToProjectButton; + private System.Windows.Forms.Button GoToButton; + private System.Windows.Forms.TextBox PositionFromTextBox; + private System.Windows.Forms.Label label55; + private System.Windows.Forms.TextBox PositionToTextBox; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.NumericUpDown AreaIDFromUpDown; + private System.Windows.Forms.Label label92; + private System.Windows.Forms.NumericUpDown AreaIDToUpDown; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.NumericUpDown PolyIDTo1UpDown; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.NumericUpDown PolyIDFrom1UpDown; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.NumericUpDown PolyIDTo2UpDown; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.NumericUpDown PolyIDFrom2UpDown; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.NumericUpDown Unk2UpDown; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.NumericUpDown Unk1UpDown; + private System.Windows.Forms.Label label9; + } +} \ No newline at end of file diff --git a/Project/Panels/EditYnvPortalPanel.cs b/Project/Panels/EditYnvPortalPanel.cs new file mode 100644 index 0000000..97f3196 --- /dev/null +++ b/Project/Panels/EditYnvPortalPanel.cs @@ -0,0 +1,311 @@ +using CodeWalker.GameFiles; +using SharpDX; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CodeWalker.Project.Panels +{ + public partial class EditYnvPortalPanel : ProjectPanel + { + public ProjectForm ProjectForm; + public YnvPortal YnvPortal { get; set; } + + private bool populatingui = false; + + public EditYnvPortalPanel(ProjectForm projectForm) + { + ProjectForm = projectForm; + InitializeComponent(); + } + + public void SetYnvPortal(YnvPortal ynvPortal) + { + YnvPortal = ynvPortal; + Tag = ynvPortal; + UpdateFormTitle(); + UpdateYnvPortalUI(); + } + + private void UpdateFormTitle() + { + Text = "Nav Portal " + YnvPortal.Index.ToString(); + } + + + public void UpdateYnvPortalUI() + { + if (YnvPortal == null) + { + DeletePortalButton.Enabled = false; + AddToProjectButton.Enabled = false; + PositionFromTextBox.Text = string.Empty; + PositionToTextBox.Text = string.Empty; + AngleUpDown.Value = 0; + TypeUpDown.Value = 0; + AreaIDFromUpDown.Value = 0; + AreaIDToUpDown.Value = 0; + PolyIDFrom1UpDown.Value = 0; + PolyIDTo1UpDown.Value = 0; + PolyIDFrom2UpDown.Value = 0; + PolyIDTo2UpDown.Value = 0; + Unk1UpDown.Value = 0; + Unk2UpDown.Value = 0; + } + else + { + populatingui = true; + DeletePortalButton.Enabled = ProjectForm.YnvExistsInProject(YnvPortal.Ynv); + AddToProjectButton.Enabled = !DeletePortalButton.Enabled; + PositionFromTextBox.Text = FloatUtil.GetVector3String(YnvPortal.PositionFrom); + PositionToTextBox.Text = FloatUtil.GetVector3String(YnvPortal.PositionTo); + AngleUpDown.Value = YnvPortal.Angle; + TypeUpDown.Value = YnvPortal.Type; + AreaIDFromUpDown.Value = YnvPortal.AreaIDFrom; + AreaIDToUpDown.Value = YnvPortal.AreaIDTo; + PolyIDFrom1UpDown.Value = YnvPortal.PolyIDFrom1; + PolyIDTo1UpDown.Value = YnvPortal.PolyIDTo1; + PolyIDFrom2UpDown.Value = YnvPortal.PolyIDFrom2; + PolyIDTo2UpDown.Value = YnvPortal.PolyIDTo2; + Unk1UpDown.Value = YnvPortal.Unk1; + Unk2UpDown.Value = YnvPortal.Unk2; + populatingui = false; + } + } + + private void PositionFromTextBox_TextChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + Vector3 v = FloatUtil.ParseVector3String(PositionFromTextBox.Text); + bool change = false; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.PositionFrom != v) + { + YnvPortal.PositionFrom = v; + ProjectForm.SetYnvHasChanged(true); + change = true; + } + } + if (change) + { + if (ProjectForm.WorldForm != null) + { + ProjectForm.WorldForm.SetWidgetPosition(YnvPortal.Position); + ProjectForm.WorldForm.UpdateNavPortalGraphics(YnvPortal, false); + } + } + } + + private void PositionToTextBox_TextChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + Vector3 v = FloatUtil.ParseVector3String(PositionToTextBox.Text); + bool change = false; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.PositionTo != v) + { + YnvPortal.PositionTo = v; + ProjectForm.SetYnvHasChanged(true); + change = true; + } + } + if (change) + { + if (ProjectForm.WorldForm != null) + { + ProjectForm.WorldForm.SetWidgetPosition(YnvPortal.Position); + ProjectForm.WorldForm.UpdateNavPortalGraphics(YnvPortal, false); + } + } + } + + private void AngleUpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + byte ang = (byte)AngleUpDown.Value; + bool change = false; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.Angle != ang) + { + YnvPortal.Angle = ang; + ProjectForm.SetYnvHasChanged(true); + change = true; + } + } + if (change) + { + if (ProjectForm.WorldForm != null) + { + ProjectForm.WorldForm.SetWidgetRotation(YnvPortal.Orientation); + //ProjectForm.WorldForm.UpdateNavPortalGraphics(YnvPortal, false); + } + } + } + + private void TypeUpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + byte typ = (byte)TypeUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.Type != typ) + { + YnvPortal.Type = typ; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void AreaIDFromUpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort id = (ushort)AreaIDFromUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.AreaIDFrom != id) + { + YnvPortal.AreaIDFrom = id; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void AreaIDToUpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort id = (ushort)AreaIDToUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.AreaIDTo != id) + { + YnvPortal.AreaIDTo = id; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void PolyIDFrom1UpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort id = (ushort)PolyIDFrom1UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.PolyIDFrom1 != id) + { + YnvPortal.PolyIDFrom1 = id; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void PolyIDTo1UpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort id = (ushort)PolyIDTo1UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.PolyIDTo1 != id) + { + YnvPortal.PolyIDTo1 = id; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void PolyIDFrom2UpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort id = (ushort)PolyIDFrom2UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.PolyIDFrom2 != id) + { + YnvPortal.PolyIDFrom2 = id; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void PolyIDTo2UpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort id = (ushort)PolyIDTo2UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.PolyIDTo2 != id) + { + YnvPortal.PolyIDTo2 = id; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void Unk1UpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + ushort unk = (ushort)Unk1UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.Unk1 != unk) + { + YnvPortal.Unk1 = unk; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void Unk2UpDown_ValueChanged(object sender, EventArgs e) + { + if (populatingui) return; + if (YnvPortal == null) return; + byte unk = (byte)Unk2UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (YnvPortal.Unk2 != unk) + { + YnvPortal.Unk2 = unk; + ProjectForm.SetYnvHasChanged(true); + } + } + } + + private void GoToButton_Click(object sender, EventArgs e) + { + if (YnvPortal == null) return; + if (ProjectForm.WorldForm == null) return; + ProjectForm.WorldForm.GoToPosition(YnvPortal.Position); + } + + private void AddToProjectButton_Click(object sender, EventArgs e) + { + if (YnvPortal == null) return; + ProjectForm.SetProjectItem(YnvPortal); + ProjectForm.AddYnvToProject(YnvPortal.Ynv); + } + + private void DeletePortalButton_Click(object sender, EventArgs e) + { + MessageBox.Show("Delete Portal TODO!"); + } + } +} diff --git a/Project/Panels/EditYnvPortalPanel.resx b/Project/Panels/EditYnvPortalPanel.resx new file mode 100644 index 0000000..1431f6b --- /dev/null +++ b/Project/Panels/EditYnvPortalPanel.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/ + /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA + AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/ + /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file diff --git a/Project/Panels/ProjectExplorerPanel.cs b/Project/Panels/ProjectExplorerPanel.cs index d1d3a87..a27344b 100644 --- a/Project/Panels/ProjectExplorerPanel.cs +++ b/Project/Panels/ProjectExplorerPanel.cs @@ -274,6 +274,10 @@ namespace CodeWalker.Project.Panels n.Name = "EditPortal"; n.Tag = ynv; //this tag should get updated with the selected portal! + n = node.Nodes.Add("Edit Point"); + n.Name = "EditPoint"; + n.Tag = ynv; //this tag should get updated with the selected point! + } private void LoadTrainTrackTreeNodes(TrainTrack track, TreeNode node) @@ -640,6 +644,36 @@ namespace CodeWalker.Project.Panels //} //return null; } + public TreeNode FindNavPointTreeNode(YnvPoint p) + { + if (p == null) return null; + TreeNode ynvnode = FindYnvTreeNode(p.Ynv); + var pointnode = GetChildTreeNode(ynvnode, "EditPoint"); + if (pointnode == null) return null; + pointnode.Tag = p; + return pointnode; + //for (int i = 0; i < pointsnode.Nodes.Count; i++) + //{ + // TreeNode pnode = pointsnode.Nodes[i]; + // if (pnode.Tag == p) return pnode; + //} + //return null; + } + public TreeNode FindNavPortalTreeNode(YnvPortal p) + { + if (p == null) return null; + TreeNode ynvnode = FindYnvTreeNode(p.Ynv); + var portalnode = GetChildTreeNode(ynvnode, "EditPortal"); + if (portalnode == null) return null; + portalnode.Tag = p; + return portalnode; + //for (int i = 0; i < portalsnode.Nodes.Count; i++) + //{ + // TreeNode pnode = portalsnode.Nodes[i]; + // if (pnode.Tag == p) return pnode; + //} + //return null; + } public TreeNode FindTrainTrackTreeNode(TrainTrack track) { if (ProjectTreeView.Nodes.Count <= 0) return null; @@ -769,6 +803,44 @@ namespace CodeWalker.Project.Panels } } } + public void TrySelectNavPointTreeNode(YnvPoint point) + { + TreeNode tnode = FindNavPointTreeNode(point); + if (tnode == null) + { + tnode = FindYnvTreeNode(point?.Ynv); + } + if (tnode != null) + { + if (ProjectTreeView.SelectedNode == tnode) + { + OnItemSelected?.Invoke(point); + } + else + { + ProjectTreeView.SelectedNode = tnode; + } + } + } + public void TrySelectNavPortalTreeNode(YnvPortal portal) + { + TreeNode tnode = FindNavPortalTreeNode(portal); + if (tnode == null) + { + tnode = FindYnvTreeNode(portal?.Ynv); + } + if (tnode != null) + { + if (ProjectTreeView.SelectedNode == tnode) + { + OnItemSelected?.Invoke(portal); + } + else + { + ProjectTreeView.SelectedNode = tnode; + } + } + } public void TrySelectTrainNodeTreeNode(TrainTrackNode node) { TreeNode tnode = FindTrainNodeTreeNode(node); diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index 94e97fe..845b3dc 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -50,6 +50,8 @@ namespace CodeWalker.Project private YnvFile CurrentYnvFile; private YnvPoly CurrentNavPoly; + private YnvPoint CurrentNavPoint; + private YnvPortal CurrentNavPortal; private TrainTrack CurrentTrainTrack; private TrainTrackNode CurrentTrainNode; @@ -373,6 +375,20 @@ namespace CodeWalker.Project (panel) => { panel.SetYnvPoly(CurrentNavPoly); }, //updateFunc (panel) => { return panel.YnvPoly == CurrentNavPoly; }); //findFunc } + private void ShowEditYnvPointPanel(bool promote) + { + ShowPanel(promote, + () => { return new EditYnvPointPanel(this); }, //createFunc + (panel) => { panel.SetYnvPoint(CurrentNavPoint); }, //updateFunc + (panel) => { return panel.YnvPoint == CurrentNavPoint; }); //findFunc + } + private void ShowEditYnvPortalPanel(bool promote) + { + ShowPanel(promote, + () => { return new EditYnvPortalPanel(this); }, //createFunc + (panel) => { panel.SetYnvPortal(CurrentNavPortal); }, //updateFunc + (panel) => { return panel.YnvPortal == CurrentNavPortal; }); //findFunc + } private void ShowEditTrainTrackPanel(bool promote) { ShowPanel(promote, @@ -436,6 +452,14 @@ namespace CodeWalker.Project { ShowEditYnvPolyPanel(promote); } + else if (CurrentNavPoint != null) + { + ShowEditYnvPointPanel(promote); + } + else if (CurrentNavPortal != null) + { + ShowEditYnvPortalPanel(promote); + } else if (CurrentYnvFile != null) { ShowEditYnvPanel(promote); @@ -485,6 +509,8 @@ namespace CodeWalker.Project CurrentPathNode = item as YndNode; CurrentYnvFile = item as YnvFile; CurrentNavPoly = item as YnvPoly; + CurrentNavPoint = item as YnvPoint; + CurrentNavPortal = item as YnvPortal; CurrentTrainTrack = item as TrainTrack; CurrentTrainNode = item as TrainTrackNode; CurrentScenario = item as YmtFile; @@ -511,6 +537,14 @@ namespace CodeWalker.Project { CurrentYnvFile = CurrentNavPoly.Ynv; } + if (CurrentNavPoint != null) + { + CurrentYnvFile = CurrentNavPoint.Ynv; + } + if (CurrentNavPortal != null) + { + CurrentYnvFile = CurrentNavPortal.Ynv; + } if (CurrentTrainNode != null) { CurrentTrainTrack = CurrentTrainNode.Track; @@ -2165,6 +2199,30 @@ namespace CodeWalker.Project return poly == CurrentNavPoly; } + public void NewNavPoint(YnvPoint copy = null, bool copyposition = false)//TODO! + { + } + public bool DeleteNavPoint()//TODO! + { + return false; + } + public bool IsCurrentNavPoint(YnvPoint point) + { + return point == CurrentNavPoint; + } + + public void NewNavPortal(YnvPortal copy = null, bool copyposition = false)//TODO! + { + } + public bool DeleteNavPortal()//TODO! + { + return false; + } + public bool IsCurrentNavPortal(YnvPortal portal) + { + return portal == CurrentNavPortal; + } + public void NewTrainTrack() @@ -3759,12 +3817,14 @@ namespace CodeWalker.Project var pathnode = sel.PathNode; var pathlink = sel.PathLink; var navpoly = sel.NavPoly; + var navpoint = sel.NavPoint; + var navportal = sel.NavPortal; var trainnode = sel.TrainTrackNode; var scenariond = sel.ScenarioNode; var scenarioedge = sel.ScenarioEdge; YmapFile ymap = ent?.Ymap ?? cargen?.Ymap ?? grassbatch?.Ymap; YndFile ynd = pathnode?.Ynd; - YnvFile ynv = navpoly?.Ynv; + YnvFile ynv = navpoly?.Ynv ?? navpoint?.Ynv ?? navportal?.Ynv; TrainTrack traintrack = trainnode?.Track; YmtFile scenario = scenariond?.Ymt ?? scenarioedge?.Region?.Ymt; bool showcurrent = false; @@ -3793,6 +3853,14 @@ namespace CodeWalker.Project { ProjectExplorer?.TrySelectNavPolyTreeNode(navpoly); } + if (navpoint != CurrentNavPoint) + { + ProjectExplorer?.TrySelectNavPointTreeNode(navpoint); + } + if (navportal != CurrentNavPortal) + { + ProjectExplorer?.TrySelectNavPortalTreeNode(navportal); + } } else if (TrainTrackExistsInProject(traintrack)) { @@ -3825,6 +3893,8 @@ namespace CodeWalker.Project CurrentPathLink = pathlink; CurrentYnvFile = ynv; CurrentNavPoly = navpoly; + CurrentNavPoint = navpoint; + CurrentNavPortal = navportal; CurrentTrainTrack = traintrack; CurrentTrainNode = trainnode; CurrentScenario = scenario; @@ -3863,6 +3933,14 @@ namespace CodeWalker.Project { OnWorldNavPolyModified(sel.NavPoly); } + else if (sel.NavPoint != null) + { + OnWorldNavPointModified(sel.NavPoint); + } + else if (sel.NavPortal != null) + { + OnWorldNavPortalModified(sel.NavPortal); + } else if (sel.TrainTrackNode != null) { OnWorldTrainNodeModified(sel.TrainTrackNode); @@ -4064,6 +4142,98 @@ namespace CodeWalker.Project } catch { } } + private void OnWorldNavPointModified(YnvPoint point) + { + try + { + if (InvokeRequired) + { + BeginInvoke(new Action(() => { OnWorldNavPointModified(point); })); + } + else + { + if (point?.Ynv == null) return; + + if (CurrentProjectFile == null) + { + NewProject(); + } + + if (!YnvExistsInProject(point.Ynv)) + { + point.Ynv.HasChanged = true; + AddYnvToProject(point.Ynv); + ProjectExplorer?.TrySelectNavPointTreeNode(point); + } + + if (point != CurrentNavPoint) + { + CurrentNavPoint = point; + ProjectExplorer?.TrySelectNavPointTreeNode(point); + } + + if (point == CurrentNavPoint) + { + ShowEditYnvPointPanel(false); + + //////UpdateNavPointTreeNode(poly); + + if (point.Ynv != null) + { + SetYnvHasChanged(true); + } + } + + } + } + catch { } + } + private void OnWorldNavPortalModified(YnvPortal portal) + { + try + { + if (InvokeRequired) + { + BeginInvoke(new Action(() => { OnWorldNavPortalModified(portal); })); + } + else + { + if (portal?.Ynv == null) return; + + if (CurrentProjectFile == null) + { + NewProject(); + } + + if (!YnvExistsInProject(portal.Ynv)) + { + portal.Ynv.HasChanged = true; + AddYnvToProject(portal.Ynv); + ProjectExplorer?.TrySelectNavPortalTreeNode(portal); + } + + if (portal != CurrentNavPortal) + { + CurrentNavPortal = portal; + ProjectExplorer?.TrySelectNavPortalTreeNode(portal); + } + + if (portal == CurrentNavPortal) + { + ShowEditYnvPortalPanel(false); + + //////UpdateNavPortalTreeNode(poly); + + if (portal.Ynv != null) + { + SetYnvHasChanged(true); + } + } + + } + } + catch { } + } private void OnWorldTrainNodeModified(TrainTrackNode node) { try diff --git a/Project/UndoStep.cs b/Project/UndoStep.cs index 3c1dd6d..2a05baa 100644 --- a/Project/UndoStep.cs +++ b/Project/UndoStep.cs @@ -62,6 +62,7 @@ namespace CodeWalker.Project { Dictionary pathYnds = new Dictionary(); + Dictionary navYnvs = new Dictionary(); Dictionary trainTracks = new Dictionary(); Dictionary scenarioYmts = new Dictionary(); @@ -73,6 +74,18 @@ namespace CodeWalker.Project { pathYnds[item.PathNode.Ynd] = 1; } + if (item.NavPoly != null) + { + navYnvs[item.NavPoly.Ynv] = 1; + } + if (item.NavPoint != null) + { + navYnvs[item.NavPoint.Ynv] = 1; + } + if (item.NavPortal != null) + { + navYnvs[item.NavPortal.Ynv] = 1; + } if (item.TrainTrackNode != null) { trainTracks[item.TrainTrackNode.Track] = 1; @@ -88,6 +101,10 @@ namespace CodeWalker.Project { wf.UpdatePathYndGraphics(kvp.Key, true); } + foreach (var kvp in navYnvs) + { + wf.UpdateNavYnvGraphics(kvp.Key, true); + } foreach (var kvp in trainTracks) { wf.UpdateTrainTrackGraphics(kvp.Key, false); @@ -491,6 +508,222 @@ namespace CodeWalker.Project } + + public class NavPointPositionUndoStep : UndoStep + { + public YnvPoint Point { get; set; } + public Vector3 StartPosition { get; set; } + public Vector3 EndPosition { get; set; } + + public NavPointPositionUndoStep(YnvPoint point, Vector3 startpos, WorldForm wf) + { + Point = point; + StartPosition = startpos; + EndPosition = point?.Position ?? Vector3.Zero; + + UpdateGraphics(wf); //forces the update of the path graphics when it's moved... + } + + private void Update(WorldForm wf, ref MapSelection sel, Vector3 p) + { + Point?.SetPosition(p); + + if (Point != sel.NavPoint) + { + wf.SelectNavPoint(Point); + } + wf.SetWidgetPosition(p); + + + UpdateGraphics(wf); + } + + private void UpdateGraphics(WorldForm wf) + { + if (Point != null) + { + //Ynv graphics needs to be updated..... + wf.UpdateNavYnvGraphics(Point.Ynv, false); + } + } + + + public override void Undo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, StartPosition); + } + + public override void Redo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, EndPosition); + } + + public override string ToString() + { + return "NavPoint " + (Point?.ToString() ?? "") + ": Position"; + } + } + + public class NavPointRotationUndoStep : UndoStep + { + public YnvPoint Point { get; set; } + public Quaternion StartRotation { get; set; } + public Quaternion EndRotation { get; set; } + + public NavPointRotationUndoStep(YnvPoint point, Quaternion startrot, WorldForm wf) + { + Point = point; + StartRotation = startrot; + EndRotation = point?.Orientation ?? Quaternion.Identity; + + //UpdateGraphics(wf); + } + + + private void Update(WorldForm wf, ref MapSelection sel, Quaternion q) + { + Point?.SetOrientation(q); + + if (Point != sel.NavPoint) wf.SelectNavPoint(Point); + wf.SetWidgetRotation(q); + + //UpdateGraphics(wf); + } + + private void UpdateGraphics(WorldForm wf) + { + ////this function shouldn't actually be needed for rotating... + //if (Point != null) + //{ + // //Ynv graphics needs to be updated..... + // wf.UpdateNavYnvGraphics(Point.Ynv, false); + //} + } + + public override void Undo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, StartRotation); + } + + public override void Redo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, EndRotation); + } + + public override string ToString() + { + return "NavPoint " + (Point?.ToString() ?? "") + ": Rotation"; + } + } + + public class NavPortalPositionUndoStep : UndoStep + { + public YnvPortal Portal { get; set; } + public Vector3 StartPosition { get; set; } + public Vector3 EndPosition { get; set; } + + public NavPortalPositionUndoStep(YnvPortal portal, Vector3 startpos, WorldForm wf) + { + Portal = portal; + StartPosition = startpos; + EndPosition = portal?.Position ?? Vector3.Zero; + + UpdateGraphics(wf); //forces the update of the path graphics when it's moved... + } + + private void Update(WorldForm wf, ref MapSelection sel, Vector3 p) + { + Portal?.SetPosition(p); + + if (Portal != sel.NavPortal) + { + wf.SelectNavPortal(Portal); + } + wf.SetWidgetPosition(p); + + + UpdateGraphics(wf); + } + + private void UpdateGraphics(WorldForm wf) + { + if (Portal != null) + { + //Ynv graphics needs to be updated..... + wf.UpdateNavYnvGraphics(Portal.Ynv, false); + } + } + + + public override void Undo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, StartPosition); + } + + public override void Redo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, EndPosition); + } + + public override string ToString() + { + return "NavPortal " + (Portal?.ToString() ?? "") + ": Position"; + } + } + public class NavPortalRotationUndoStep : UndoStep + { + public YnvPortal Portal { get; set; } + public Quaternion StartRotation { get; set; } + public Quaternion EndRotation { get; set; } + + public NavPortalRotationUndoStep(YnvPortal portal, Quaternion startrot, WorldForm wf) + { + Portal = portal; + StartRotation = startrot; + EndRotation = portal?.Orientation ?? Quaternion.Identity; + + //UpdateGraphics(wf); + } + + + private void Update(WorldForm wf, ref MapSelection sel, Quaternion q) + { + Portal?.SetOrientation(q); + + if (Portal != sel.NavPortal) wf.SelectNavPortal(Portal); + wf.SetWidgetRotation(q); + + //UpdateGraphics(wf); + } + + private void UpdateGraphics(WorldForm wf) + { + ////this function shouldn't actually be needed for rotating... + //if (Point != null) + //{ + // //Ynv graphics needs to be updated..... + // wf.UpdateNavYnvGraphics(Point.Ynv, false); + //} + } + + public override void Undo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, StartRotation); + } + + public override void Redo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, EndRotation); + } + + public override string ToString() + { + return "NavPortal " + (Portal?.ToString() ?? "") + ": Rotation"; + } + } + + + public class TrainTrackNodePositionUndoStep : UndoStep { public TrainTrackNode Node { get; set; } diff --git a/Rendering/DirectX/DXManager.cs b/Rendering/DirectX/DXManager.cs index 7c6a1c9..e38d480 100644 --- a/Rendering/DirectX/DXManager.cs +++ b/Rendering/DirectX/DXManager.cs @@ -71,6 +71,7 @@ namespace CodeWalker.Rendering //#endif Device dev = null; SwapChain sc = null; + Exception exc = null; bool success = false; try @@ -78,7 +79,7 @@ namespace CodeWalker.Rendering Device.CreateWithSwapChain(DriverType.Hardware, flags, levels, scd, out dev, out sc); success = true; } - catch { } + catch(Exception ex) { exc = ex; } if (!success) { @@ -90,12 +91,17 @@ namespace CodeWalker.Rendering Device.CreateWithSwapChain(DriverType.Hardware, flags, levels, scd, out dev, out sc); success = true; } - catch { } + catch (Exception ex) { exc = ex; } } if (!success) { - throw new Exception("CodeWalker was unable to initialise the graphics device. Please ensure your system meets the minimum requirements and that your graphics drivers and DirectX are up to date."); + var msg = "CodeWalker was unable to initialise the graphics device. Please ensure your system meets the minimum requirements and that your graphics drivers and DirectX are up to date."; + if (exc != null) + { + msg += "\n\nException info: " + exc.ToString(); + } + throw new Exception(msg); } device = dev; @@ -130,7 +136,7 @@ namespace CodeWalker.Rendering } catch (Exception ex) { - MessageBox.Show("Unable to initialise DirectX11.\n" + ex.ToString()); + MessageBox.Show("Unable to initialise DirectX11.\n" + ex.Message, "CodeWalker - Error!"); return false; } } diff --git a/Utils/MapUtils.cs b/Utils/MapUtils.cs index 248bd90..fdadbca 100644 --- a/Utils/MapUtils.cs +++ b/Utils/MapUtils.cs @@ -587,7 +587,7 @@ namespace CodeWalker } else if (NavPortal != null) { - return Quaternion.Identity; + return NavPortal.Orientation; } else if (PathNode != null) { @@ -634,7 +634,7 @@ namespace CodeWalker } else if (NavPortal != null) { - return WidgetAxis.None; + return WidgetAxis.Z; } else if (PathNode != null) { @@ -787,6 +787,10 @@ namespace CodeWalker { NavPoint.SetOrientation(newrot); } + else if (NavPortal != null) + { + NavPortal.SetOrientation(newrot); + } else if (Audio != null) { Audio.SetOrientation(newrot); diff --git a/WorldForm.cs b/WorldForm.cs index 0ffc6cf..ed39dc4 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -179,6 +179,8 @@ namespace CodeWalker YmapCarGen CopiedCarGen = null; YndNode CopiedPathNode = null; YnvPoly CopiedNavPoly = null; + YnvPoint CopiedNavPoint = null; + YnvPortal CopiedNavPortal = null; TrainTrackNode CopiedTrainNode = null; ScenarioNode CopiedScenarioNode = null; @@ -1203,6 +1205,10 @@ namespace CodeWalker { ori = CurMouseHit.NavPoint.Orientation; } + if (CurMouseHit.NavPortal != null) + { + ori = CurMouseHit.NavPortal.Orientation; + } if (CurMouseHit.Audio != null) { ori = CurMouseHit.Audio.Orientation; @@ -1443,9 +1449,15 @@ namespace CodeWalker } if (selectionItem.NavPortal != null) { - camrel = selectionItem.NavPortal.Position - camera.Position; - } + var navp = selectionItem.NavPortal; + camrel = navp.Position - camera.Position; + //render direction arrow for NavPortal + ori = navp.Orientation; + float arrowlen = 2.0f; + float arrowrad = 0.25f; + Renderer.RenderSelectionArrowOutline(navp.Position, Vector3.UnitY, Vector3.UnitZ, ori, arrowlen, arrowrad, cgrn); + } if (selectionItem.Audio != null) { var au = selectionItem.Audio; @@ -1743,7 +1755,7 @@ namespace CodeWalker public void UpdateNavYnvGraphics(YnvFile ynv, bool fullupdate) { - + ynv.UpdateAllNodePositions(); ynv.UpdateTriangleVertices(); ynv.BuildBVH(); @@ -1758,6 +1770,18 @@ namespace CodeWalker //poly.Ynv.UpdateBvhForPoly(poly);//TODO! UpdateNavYnvGraphics(poly.Ynv, fullupdate); } + public void UpdateNavPointGraphics(YnvPoint point, bool fullupdate) + { + if (point == null) return; + //poly.Ynv.UpdateBvhForPoint(point);//TODO! + UpdateNavYnvGraphics(point.Ynv, fullupdate); + } + public void UpdateNavPortalGraphics(YnvPortal portal, bool fullupdate) + { + if (portal == null) return; + //poly.Ynv.UpdateBvhForPortal(portal);//TODO! + UpdateNavYnvGraphics(portal.Ynv, fullupdate); + } public void UpdateTrainTrackGraphics(TrainTrack tt, bool fullupdate) { @@ -4538,19 +4562,23 @@ namespace CodeWalker - + private bool CanMarkUndo() + { + if (SelectedItem.MultipleSelection) return true; + if (SelectedItem.EntityDef != null) return true; + if (SelectedItem.CarGenerator != null) return true; + if (SelectedItem.PathNode != null) return true; + //if (SelectedItem.NavPoly != null) return true; + if (SelectedItem.NavPoint != null) return true; + if (SelectedItem.NavPortal != null) return true; + if (SelectedItem.TrainTrackNode != null) return true; + if (SelectedItem.ScenarioNode != null) return true; + if (SelectedItem.Audio != null) return true; + return false; + } private void MarkUndoStart(Widget w) { - bool canundo = false; - if (SelectedItem.MultipleSelection) canundo = true; - if (SelectedItem.EntityDef != null) canundo = true; - if (SelectedItem.CarGenerator != null) canundo = true; - if (SelectedItem.PathNode != null) canundo = true; - //if (SelectedItem.NavPoly != null) hasval = true; - if (SelectedItem.TrainTrackNode != null) canundo = true; - if (SelectedItem.ScenarioNode != null) canundo = true; - if (SelectedItem.Audio != null) canundo = true; - if (!canundo) return; + if (!CanMarkUndo()) return; if (Widget is TransformWidget) { UndoStartPosition = Widget.Position; @@ -4560,19 +4588,13 @@ namespace CodeWalker } private void MarkUndoEnd(Widget w) { - bool canundo = false; - if (SelectedItem.MultipleSelection) canundo = true; - if (SelectedItem.EntityDef != null) canundo = true; - if (SelectedItem.CarGenerator != null) canundo = true; - if (SelectedItem.PathNode != null) canundo = true; - //if (SelectedItem.NavPoly != null) hasval = true; - if (SelectedItem.TrainTrackNode != null) canundo = true; - if (SelectedItem.ScenarioNode != null) canundo = true; - if (SelectedItem.Audio != null) canundo = true; - if (!canundo) return; + if (!CanMarkUndo()) return; var ent = SelectedItem.EntityDef; var cargen = SelectedItem.CarGenerator; var pathnode = SelectedItem.PathNode; + var navpoly = SelectedItem.NavPoly; + var navpoint = SelectedItem.NavPoint; + var navportal = SelectedItem.NavPortal; var trainnode = SelectedItem.TrainTrackNode; var scenarionode = SelectedItem.ScenarioNode; var audio = SelectedItem.Audio; @@ -4623,6 +4645,26 @@ namespace CodeWalker case WidgetMode.Position: s = new PathNodePositionUndoStep(pathnode, UndoStartPosition, this); break; } } + else if (navpoly != null) + { + //todo... + } + else if (navpoint != null) + { + switch (tw.Mode) + { + case WidgetMode.Position: s = new NavPointPositionUndoStep(navpoint, UndoStartPosition, this); break; + case WidgetMode.Rotation: s = new NavPointRotationUndoStep(navpoint, UndoStartRotation, this); break; + } + } + else if (navportal != null) + { + switch (tw.Mode) + { + case WidgetMode.Position: s = new NavPortalPositionUndoStep(navportal, UndoStartPosition, this); break; + case WidgetMode.Rotation: s = new NavPortalRotationUndoStep(navportal, UndoStartRotation, this); break; + } + } else if (trainnode != null) { switch (tw.Mode) @@ -4942,9 +4984,9 @@ namespace CodeWalker case MapSelectionMode.Entity: AddEntity(); break; case MapSelectionMode.CarGenerator: AddCarGen(); break; case MapSelectionMode.Path: AddPathNode(); break; - case MapSelectionMode.NavMesh: AddNavPoly(); break; + case MapSelectionMode.NavMesh: AddNavPoly(); break;//how to add points/portals? project window case MapSelectionMode.TrainTrack: AddTrainNode(); break; - case MapSelectionMode.Scenario: AddScenarioNode(); break; + case MapSelectionMode.Scenario: AddScenarioNode(); break; //how to add different node types? project window } } private void DeleteItem() @@ -4953,6 +4995,8 @@ namespace CodeWalker else if (SelectedItem.CarGenerator != null) DeleteCarGen(); else if (SelectedItem.PathNode != null) DeletePathNode(); else if (SelectedItem.NavPoly != null) DeleteNavPoly(); + else if (SelectedItem.NavPoint != null) DeleteNavPoint(); + else if (SelectedItem.NavPortal != null) DeleteNavPortal(); else if (SelectedItem.TrainTrackNode != null) DeleteTrainNode(); else if (SelectedItem.ScenarioNode != null) DeleteScenarioNode(); } @@ -4962,6 +5006,8 @@ namespace CodeWalker else if (SelectedItem.CarGenerator != null) CopyCarGen(); else if (SelectedItem.PathNode != null) CopyPathNode(); else if (SelectedItem.NavPoly != null) CopyNavPoly(); + else if (SelectedItem.NavPoint != null) CopyNavPoint(); + else if (SelectedItem.NavPortal != null) CopyNavPortal(); else if (SelectedItem.TrainTrackNode != null) CopyTrainNode(); else if (SelectedItem.ScenarioNode != null) CopyScenarioNode(); } @@ -4971,6 +5017,8 @@ namespace CodeWalker else if (CopiedCarGen != null) PasteCarGen(); else if (CopiedPathNode != null) PastePathNode(); else if (CopiedNavPoly != null) PasteNavPoly(); + else if (CopiedNavPoint != null) PasteNavPoint(); + else if (CopiedNavPortal != null) PasteNavPortal(); else if (CopiedTrainNode != null) PasteTrainNode(); else if (CopiedScenarioNode != null) PasteScenarioNode(); } @@ -4980,6 +5028,8 @@ namespace CodeWalker else if (SelectedItem.CarGenerator != null) CloneCarGen(); else if (SelectedItem.PathNode != null) ClonePathNode(); else if (SelectedItem.NavPoly != null) CloneNavPoly(); + else if (SelectedItem.NavPoint != null) CloneNavPoint(); + else if (SelectedItem.NavPortal != null) CloneNavPortal(); else if (SelectedItem.TrainTrackNode != null) CloneTrainNode(); else if (SelectedItem.ScenarioNode != null) CloneScenarioNode(); } @@ -5202,6 +5252,114 @@ namespace CodeWalker ProjectForm.NewNavPoly(SelectedItem.NavPoly, true); } + private void AddNavPoint() + { + if (ProjectForm == null) return; + ProjectForm.NewNavPoint(); + } + private void DeleteNavPoint() + { + var navpoint = SelectedItem.NavPoint; + if (navpoint == null) return; + + if ((ProjectForm != null) && (ProjectForm.IsCurrentNavPoint(navpoint))) + { + if (!ProjectForm.DeleteNavPoint()) + { + //MessageBox.Show("Unable to delete this nav point from the current project. Make sure the nav point's ynv exists in the current project."); + } + else + { + SelectItem(null); + } + } + else + { + //project not open, or nav point not selected there, just remove the point from the ynv... + var ynv = navpoint.Ynv; + if (!ynv.RemovePoint(navpoint)) + { + MessageBox.Show("Unable to remove nav point. NavMesh editing TODO!"); + } + else + { + UpdateNavPointGraphics(navpoint, false); + SelectItem(null); + } + } + } + private void CopyNavPoint() + { + CopiedNavPoint = SelectedItem.NavPoint; + ToolbarPasteButton.Enabled = (CopiedNavPoint != null) && ToolbarAddItemButton.Enabled; + } + private void PasteNavPoint() + { + if (CopiedNavPoint == null) return; + if (ProjectForm == null) return; + ProjectForm.NewNavPoint(CopiedNavPoint); + } + private void CloneNavPoint() + { + if (SelectedItem.NavPoint == null) return; + if (ProjectForm == null) return; + ProjectForm.NewNavPoint(SelectedItem.NavPoint, true); + } + + private void AddNavPortal() + { + if (ProjectForm == null) return; + ProjectForm.NewNavPortal(); + } + private void DeleteNavPortal() + { + var navportal = SelectedItem.NavPortal; + if (navportal == null) return; + + if ((ProjectForm != null) && (ProjectForm.IsCurrentNavPortal(navportal))) + { + if (!ProjectForm.DeleteNavPortal()) + { + //MessageBox.Show("Unable to delete this nav portal from the current project. Make sure the nav portal's ynv exists in the current project."); + } + else + { + SelectItem(null); + } + } + else + { + //project not open, or nav portal not selected there, just remove the portal from the ynv... + var ynv = navportal.Ynv; + if (!ynv.RemovePortal(navportal)) + { + MessageBox.Show("Unable to remove nav portal. NavMesh editing TODO!"); + } + else + { + UpdateNavPortalGraphics(navportal, false); + SelectItem(null); + } + } + } + private void CopyNavPortal() + { + CopiedNavPortal = SelectedItem.NavPortal; + ToolbarPasteButton.Enabled = (CopiedNavPortal != null) && ToolbarAddItemButton.Enabled; + } + private void PasteNavPortal() + { + if (CopiedNavPortal == null) return; + if (ProjectForm == null) return; + ProjectForm.NewNavPortal(CopiedNavPortal); + } + private void CloneNavPortal() + { + if (SelectedItem.NavPortal == null) return; + if (ProjectForm == null) return; + ProjectForm.NewNavPortal(SelectedItem.NavPortal, true); + } + private void AddTrainNode() { if (ProjectForm == null) return;