diff --git a/PVSFormat/AddZone.Designer.cs b/PVSFormat/AddZone.Designer.cs
new file mode 100644
index 0000000..e0f2199
--- /dev/null
+++ b/PVSFormat/AddZone.Designer.cs
@@ -0,0 +1,101 @@
+namespace PVSFormat
+{
+ partial class AddZone
+ {
+ ///
+ /// 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()
+ {
+ okButton = new System.Windows.Forms.Button();
+ cancelButton = new System.Windows.Forms.Button();
+ zoneIdNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ label1 = new System.Windows.Forms.Label();
+ ((System.ComponentModel.ISupportInitialize)zoneIdNumericUpDown).BeginInit();
+ SuspendLayout();
+ //
+ // okButton
+ //
+ okButton.Location = new System.Drawing.Point(12, 65);
+ okButton.Name = "okButton";
+ okButton.Size = new System.Drawing.Size(75, 23);
+ okButton.TabIndex = 0;
+ okButton.Text = "OK";
+ okButton.UseVisualStyleBackColor = true;
+ okButton.Click += okButton_Click;
+ //
+ // cancelButton
+ //
+ cancelButton.Location = new System.Drawing.Point(93, 65);
+ cancelButton.Name = "cancelButton";
+ cancelButton.Size = new System.Drawing.Size(75, 23);
+ cancelButton.TabIndex = 1;
+ cancelButton.Text = "Cancel";
+ cancelButton.UseVisualStyleBackColor = true;
+ cancelButton.Click += cancelButton_Click;
+ //
+ // zoneIdNumericUpDown
+ //
+ zoneIdNumericUpDown.Location = new System.Drawing.Point(42, 32);
+ zoneIdNumericUpDown.Maximum = new decimal(new int[] { 1024, 0, 0, 0 });
+ zoneIdNumericUpDown.Name = "zoneIdNumericUpDown";
+ zoneIdNumericUpDown.Size = new System.Drawing.Size(100, 23);
+ zoneIdNumericUpDown.TabIndex = 2;
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new System.Drawing.Point(41, 9);
+ label1.Name = "label1";
+ label1.Size = new System.Drawing.Size(104, 15);
+ label1.TabIndex = 3;
+ label1.Text = "Enter new zone ID:";
+ //
+ // AddZone
+ //
+ AcceptButton = okButton;
+ AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ CancelButton = cancelButton;
+ ClientSize = new System.Drawing.Size(184, 101);
+ Controls.Add(label1);
+ Controls.Add(zoneIdNumericUpDown);
+ Controls.Add(cancelButton);
+ Controls.Add(okButton);
+ FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ Name = "AddZone";
+ Text = "Add Zone";
+ ((System.ComponentModel.ISupportInitialize)zoneIdNumericUpDown).EndInit();
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.Button cancelButton;
+ private System.Windows.Forms.NumericUpDown zoneIdNumericUpDown;
+ private System.Windows.Forms.Label label1;
+ }
+}
\ No newline at end of file
diff --git a/PVSFormat/AddZone.cs b/PVSFormat/AddZone.cs
new file mode 100644
index 0000000..9cbc77a
--- /dev/null
+++ b/PVSFormat/AddZone.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Windows.Forms;
+
+namespace PVSFormat
+{
+ public partial class AddZone : Form
+ {
+ ulong zone;
+
+ public AddZone()
+ {
+ InitializeComponent();
+ }
+
+ public ulong GetNewZoneId()
+ {
+ ShowDialog();
+ return zone;
+ }
+
+ private void okButton_Click(object sender, EventArgs e)
+ {
+ zone = (ulong)zoneIdNumericUpDown.Value;
+ Close();
+ }
+
+ private void cancelButton_Click(object sender, EventArgs e)
+ {
+ Close();
+ }
+ }
+}
diff --git a/PVSFormat/AddZone.resx b/PVSFormat/AddZone.resx
new file mode 100644
index 0000000..a395bff
--- /dev/null
+++ b/PVSFormat/AddZone.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
\ No newline at end of file
diff --git a/PVSFormat/PVS.cs b/PVSFormat/PVS.cs
index f5e7e4d..ae3eca3 100644
--- a/PVSFormat/PVS.cs
+++ b/PVSFormat/PVS.cs
@@ -1,6 +1,8 @@
+using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
+using System.Numerics;
using BundleFormat;
using BundleUtilities;
using BurnoutImage;
@@ -8,204 +10,233 @@
namespace PVSFormat
{
- public struct ZonePoint
+ public struct ZoneList
{
- public float X;
- public float Y;
- public int Padding1; // Padding???
- public int Padding2; // Padding???
+ //public List Points; // Redundant; use Zones[zoneIndex].Points
+ public List Zones;
+ //public List ZonePointStarts; // Per-zone start point index. Unnecessary as they are always sequential multiples of 4
+ //public List ZonePointCounts; // Per-zone point count. Unnecessary as there are always 4 points
+ public uint TotalZones;
+ //public uint TotalPoints; // Unnecessary, calculated during writing
- public override string ToString()
+ public ZoneList()
{
- return "X: " + X + ", Y: " + Y + ", Padding1: " + Padding1 + ", Padding2: " + Padding2;
+ Zones = new();
+ //ZonePointStarts = new();
+ //ZonePointCounts = new();
}
}
- public enum NeighbourFlags
+ public struct Zone
{
- E_RENDERFLAG_NONE = 0x0,
- E_NEIGHBOURFLAG_RENDER = 0x1,
- E_NEIGHBOURFLAG_IMMEDIATE = 0x2,
- E_NEIGHBOURFLAG_RENDER_IMMEDIATE = 0x3,
- }
-
- public struct ZoneNeighbour
- {
- public int NeighborIndex;
- public uint NeighborPtr;
- public NeighbourFlags Flags;
- public int Padding1; // Padding???
- public int Padding2; // Padding???
+ public List Points;
+ //public List SafeNeighbours; // Unnecessary, always empty
+ public List UnsafeNeighbours;
+ public ulong ZoneId;
+ //public short ZoneType; // Unnecessary, always 0
+ //public short NumPoints; // Unnecessary, always 4
+ //public short NumSafeNeighbours; // Unnecessary, always 0
+ public short NumUnsafeNeighbours;
+ //public ulong Flags; // Unnecessary, always 0
- public override string ToString()
+ public Zone()
{
- return "NeighborIndex: " + NeighborIndex + ", Type: " + Flags + ", Unk1: " + Padding1 + ", Unk2: " + Padding2;
+ Points = new();
+ for (int i = 0; i < 400; i += 100)
+ Points.Add(new(i % 200, i > 100 ? 0 : 100)); // 0x0,100x0,0x100,100x100
+ //SafeNeighbours = new();
+ UnsafeNeighbours = new();
}
}
- public struct PVSZone
+ public struct Neighbour
{
- public uint Address;
- public uint PointsPtr;
- public uint SafeNeighboursPtr;
- public uint UnsafeNeighboursPtr;
- public uint Unknown;
- public long ZoneID;
- public short ZoneType;
- public short NumPoints;
- public short NumSafeNeighbours;
- public short NumUnsafeNeighbours;
- public int Flags;
- public int Padding1; // Padding???
- public int Padding2; // Padding???
- public int Padding3; // Padding???
-
- public List Points;
- public List UnsafeNeighbours;
+ //Zone Zone; // Redundant, replaced by ZoneId
+ public ulong ZoneId;
+ public NeighbourFlags Flags;
+ }
- public override string ToString()
- {
- return "ZoneID: " + ZoneID;
- }
+ [Flags]
+ public enum NeighbourFlags
+ {
+ E_RENDERFLAG_NONE = 0x0,
+ E_NEIGHBOURFLAG_RENDER = 0x1,
+ E_NEIGHBOURFLAG_IMMEDIATE = 0x2
}
public class PVS : IEntryData
{
- private Image _gameMap;
+ public ZoneList data;
- public uint PointsPtr;
- public uint ZonePtr;
- public uint ZonePointStart1;
- public uint ZonePointStart2;
- public uint ZonePointCount;
- public uint TotalZones;
- public uint TotalPoints;
- public uint Padding; // Padding???
- public List Zones;
-
- public PVS()
- {
- Zones = new List();
- }
-
- private void Clear()
- {
- PointsPtr = default;
- ZonePtr = default;
- ZonePointStart1 = default;
- ZonePointStart2 = default;
- ZonePointCount = default;
- TotalZones = default;
- TotalPoints = default;
-
- Zones.Clear();
- }
+ private Image _gameMap;
+ internal ulong selectedZoneId = ulong.MaxValue;
- public bool Read(BundleEntry entry, ILoader loader)
+ public bool Read(BundleEntry entry, ILoader loader = null)
{
- Clear();
+ data = new();
- Stream s = entry.MakeStream();
- BinaryReader2 br = new BinaryReader2(s);
+ BinaryReader2 br = new(entry.MakeStream());
br.BigEndian = entry.Console;
- PointsPtr = br.ReadUInt32();
- ZonePtr = br.ReadUInt32();
-
- ZonePointStart1 = br.ReadUInt32();
- ZonePointStart2 = br.ReadUInt32();
-
- ZonePointCount = br.ReadUInt32();
- TotalZones = br.ReadUInt32();
- TotalPoints = br.ReadUInt32();
- Padding = br.ReadUInt32();
-
- for (uint i = 0; i < ZonePointCount; i++)
+ // Get zone count
+ br.BaseStream.Position = 0x10;
+ data.TotalZones = br.ReadUInt32();
+
+ // Get zones
+ br.BaseStream.Position = 0x4;
+ br.BaseStream.Position = br.ReadUInt32();
+ long zonePos;
+ long unsafeNeighboursPos;
+ long unsafeNeighbourZonePos;
+ for (int i = 0; i < data.TotalZones; ++i)
{
- PVSZone pvsEntry = new PVSZone();
-
- pvsEntry.Address = (uint)br.BaseStream.Position;
- pvsEntry.PointsPtr = br.ReadUInt32();
- pvsEntry.SafeNeighboursPtr = br.ReadUInt32();
- pvsEntry.UnsafeNeighboursPtr = br.ReadUInt32();
- pvsEntry.Unknown = br.ReadUInt32();
- pvsEntry.ZoneID = br.ReadInt64();
- pvsEntry.ZoneType = br.ReadInt16();
- pvsEntry.NumPoints = br.ReadInt16();
- pvsEntry.NumSafeNeighbours = br.ReadInt16();
- pvsEntry.NumUnsafeNeighbours = br.ReadInt16();
- pvsEntry.Flags = br.ReadInt32();
- pvsEntry.Padding1 = br.ReadInt32();
- pvsEntry.Padding2 = br.ReadInt32();
- pvsEntry.Padding3 = br.ReadInt32();
-
- long pos = br.BaseStream.Position;
-
- br.BaseStream.Position = (long)pvsEntry.PointsPtr;
-
- pvsEntry.Points = new List();
- for (int j = 0; j < pvsEntry.NumPoints; j++)
- {
- ZonePoint data = new ZonePoint();
-
- data.X = br.ReadSingle();
- data.Y = br.ReadSingle();
- data.Padding1 = br.ReadInt32();
- data.Padding2 = br.ReadInt32();
+ Zone zone = new();
+ zonePos = br.BaseStream.Position;
- pvsEntry.Points.Add(data);
+ // Get points
+ br.BaseStream.Position = br.ReadUInt32();
+ for (int j = 0; j < 4; ++j)
+ {
+ zone.Points[j] = new(br.ReadSingle(), br.ReadSingle());
+ br.SkipUniquePadding(8);
}
- br.BaseStream.Position = (long) pvsEntry.UnsafeNeighboursPtr;
-
- pvsEntry.UnsafeNeighbours = new List();
- for (int j = 0; j < pvsEntry.NumUnsafeNeighbours; j++)
+ // Get unsafe neighbours
+ br.BaseStream.Position = zonePos + 0x1E;
+ zone.NumUnsafeNeighbours = br.ReadInt16();
+ br.BaseStream.Position = zonePos + 8;
+ unsafeNeighboursPos = br.ReadUInt32();
+ for (int j = 0; j < zone.NumUnsafeNeighbours; ++j)
{
- ZoneNeighbour data = new ZoneNeighbour();
+ Neighbour neighbour = new();
+ br.BaseStream.Position = unsafeNeighboursPos + 0x10 * j;
+ unsafeNeighbourZonePos = br.ReadUInt32();
+ neighbour.Flags = (NeighbourFlags)br.ReadUInt32();
+ br.BaseStream.Position = unsafeNeighbourZonePos + 0x10;
+ neighbour.ZoneId = br.ReadUInt64();
+ zone.UnsafeNeighbours.Add(neighbour);
+ }
- data.NeighborIndex = -1;
+ // Get zone ID
+ br.BaseStream.Position = zonePos + 0x10;
+ zone.ZoneId = br.ReadUInt64();
+ br.BaseStream.Position += 0x18; // Seek to next zone
- data.NeighborPtr = br.ReadUInt32();
- data.Flags = (NeighbourFlags)br.ReadInt32();
- data.Padding1 = br.ReadInt32();
- data.Padding2 = br.ReadInt32();
+ data.Zones.Add(zone);
+ }
- pvsEntry.UnsafeNeighbours.Add(data);
- }
+ br.Close();
- br.BaseStream.Position = pos;
+ _gameMap = GetGameMap(entry.Archive);
- Zones.Add(pvsEntry);
- }
+ return true;
+ }
- for (int i = 0; i < Zones.Count; i++)
+ public bool Write(BundleEntry entry)
+ {
+ MemoryStream ms = new MemoryStream();
+ BinaryWriter bw = new BinaryWriter(ms);
+
+ // Update neighbours in case of zone deletion
+ for (int i = 0; i < data.TotalZones; ++i)
{
- for (int k = 0; k < Zones[i].UnsafeNeighbours.Count; k++)
+ for (int j = 0; j < data.Zones[i].NumUnsafeNeighbours; ++j)
{
- ZoneNeighbour data = Zones[i].UnsafeNeighbours[k];
- uint ptr = data.NeighborPtr;
- for (int j = 0; j < Zones.Count; j++)
+ if (data.Zones.FindIndex(z => z.ZoneId == data.Zones[i].UnsafeNeighbours[j].ZoneId) == -1)
{
- if (Zones[j].Address == ptr)
- {
- data.NeighborIndex = j;
- Zones[i].UnsafeNeighbours[k] = data;
- break;
- }
+ Zone zone = data.Zones[i];
+ zone.UnsafeNeighbours.RemoveAt(j);
+ zone.NumUnsafeNeighbours--;
+ data.Zones[i] = zone;
}
}
}
- br.Close();
- s.Close();
+ // Get necessary information before writing
+ uint zonesPtr = 0x20;
+ uint zonesLength = data.TotalZones * 0x30;
+ uint neighboursPtr = zonesPtr + zonesLength;
+ uint neighborsLength = 0;
+ for (int i = 0; i < data.Zones.Count; ++i)
+ neighborsLength += (uint)data.Zones[i].NumUnsafeNeighbours * 0x10;
+ uint pointsPtr = neighboursPtr + neighborsLength;
+ uint pointsLength = (uint)(data.Zones.Count * 0x4 * 0x10);
+ uint zoneStartsPtr = pointsPtr + pointsLength;
+ uint zoneStartsLength = data.TotalZones * 0x4;
+ uint zoneCountsPtr = zoneStartsPtr + zoneStartsLength;
+ if (zoneCountsPtr % 0x10 != 0) // Align
+ zoneCountsPtr = (zoneCountsPtr & 0xFFFFFFF0) + 0x10;
+
+ // Write ZoneList
+ bw.Write(pointsPtr);
+ bw.Write(zonesPtr);
+ bw.Write(zoneStartsPtr);
+ bw.Write(zoneCountsPtr);
+ bw.Write(data.TotalZones);
+ bw.Write(data.TotalZones * 0x4);
+
+ // Write zones
+ uint neighboursPosition = 0;
+ for (int i = 0; i < data.TotalZones; ++i)
+ {
+ bw.BaseStream.Position = zonesPtr + i * 0x30;
+ bw.Write((uint)(pointsPtr + i * 0x4 * 0x10)); // Points
+ bw.Write(0); // Safe neighbours
+ if (data.Zones[i].NumUnsafeNeighbours == 0) // Unsafe neighbours
+ bw.Write(0);
+ else
+ bw.Write(neighboursPtr + neighboursPosition);
+ bw.Write(0); // Padding
+ bw.Write(data.Zones[i].ZoneId);
+ bw.Write((short)0); // Zone type
+ bw.Write((short)4); // Point count
+ bw.Write((short)0); // Safe neighbour count
+ bw.Write(data.Zones[i].NumUnsafeNeighbours); // Unsafe neighbour count
+ bw.Write(0); // Flags
+
+ // Write points
+ bw.BaseStream.Position = pointsPtr + i * 0x4 * 0x10;
+ for (int j = 0; j < 4; ++j)
+ {
+ bw.Write(data.Zones[i].Points[j].X);
+ bw.Write(data.Zones[i].Points[j].Y);
+ bw.BaseStream.Position += 0x8;
+ }
- _gameMap = GetGameMap(entry.Archive);
+ // Write neighbours
+ bw.BaseStream.Position = neighboursPtr + neighboursPosition;
+ for (int j = 0; j < data.Zones[i].NumUnsafeNeighbours; ++j)
+ {
+ ulong zoneId = data.Zones[i].UnsafeNeighbours[j].ZoneId;
+ int neighbourZoneIndex = data.Zones.FindIndex(z => z.ZoneId == zoneId);
+ uint neighbourZonePtr = (uint)(zonesPtr + neighbourZoneIndex * 0x30);
+ bw.Write(neighbourZonePtr);
+ bw.Write((uint)data.Zones[i].UnsafeNeighbours[j].Flags);
+ bw.BaseStream.Position += 0x8;
+ neighboursPosition += 0x10;
+ }
+ }
- return true;
- }
+ // Write zone start point indices
+ bw.BaseStream.Position = zoneStartsPtr;
+ for (int i = 0; i < data.TotalZones * 4; i += 4)
+ bw.Write(i);
+
+ // Write zone point counts
+ bw.BaseStream.Position = zoneCountsPtr;
+ for (int i = 0; i < data.TotalZones; ++i)
+ bw.Write((short)4);
+
+ bw.Align(16);
+
+ bw.Flush();
+ byte[] rawData = ms.ToArray();
+ bw.Close();
+ ms.Close();
+
+ entry.EntryBlocks[0].Data = rawData;
+ entry.Dirty = true;
- public bool Write(BundleEntry entry)
- {
return true;
}
@@ -216,10 +247,15 @@ public EntryType GetEntryType(BundleEntry entry)
public IEntryEditor GetEditor(BundleEntry entry)
{
- PVSEditor pvsForm = new PVSEditor();
+ PVSEditor pvsForm = new();
pvsForm.GameMap = _gameMap;
pvsForm.Open(this);
+ pvsForm.Edit += () =>
+ {
+ Write(entry);
+ };
+
return pvsForm;
}
@@ -241,9 +277,12 @@ private Image GetGameMap(BundleArchive archive)
if (descEntry1 == null)
{
string path = Path.GetDirectoryName(archive.Path) + Path.DirectorySeparatorChar + "GUITEXTURES.BIN";
- BundleArchive archive2 = BundleArchive.Read(path);
- if (archive2 != null)
- descEntry1 = archive2.GetEntryByID(id);
+ if (Path.Exists(path))
+ {
+ BundleArchive archive2 = BundleArchive.Read(path);
+ if (archive2 != null)
+ descEntry1 = archive2.GetEntryByID(id);
+ }
}
Image image = null;
diff --git a/PVSFormat/PVSEditControl.cs b/PVSFormat/PVSEditControl.cs
index 1c48678..1b5d6a7 100644
--- a/PVSFormat/PVSEditControl.cs
+++ b/PVSFormat/PVSEditControl.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using System.Drawing;
+using System.Numerics;
using System.Windows.Forms;
namespace PVSFormat
@@ -26,11 +28,17 @@ public PVS PVS
protected PointF CameraPosition;
protected PointF RenderOffset => new PointF(-CameraPosition.X + ClientRectangle.Width / 2.0f, -CameraPosition.Y + ClientRectangle.Height / 2.0f);
protected float MapSize => (RenderScale * 32);
- protected bool isHand;
protected bool isDragging;
protected Point lastMouse;
protected Point mousePos;
+ protected enum MapSectionType
+ {
+ Unloaded,
+ Current,
+ Neighbour
+ }
+
protected PointF MousePosOnMap
{
get
@@ -61,42 +69,58 @@ public PVSEditControl()
CameraPosition = new Point(0, 0);
}
- protected override void OnKeyDown(KeyEventArgs e)
+ // Get zone ID for UI update
+ public ulong GetZoneId()
{
- if (e.KeyData == Keys.Space)
- {
- isHand = true;
- UpdateCursor();
- }
- if (e.KeyData == Keys.Oemplus)
+ ulong id = ulong.MaxValue;
+ foreach (Zone zone in PVS.data.Zones)
{
- CameraPosition.X = 0;
- CameraPosition.Y = 0;
- Invalidate();
+ List points = new();
+ foreach (Vector2 point in zone.Points)
+ points.Add(new PointF(point.X, point.Y));
+ Polygon polygon = new Polygon(points);
+ if (MousePosOnMap.X >= polygon.MinX && MousePosOnMap.X < polygon.MaxX
+ && MousePosOnMap.Y >= polygon.MinY && MousePosOnMap.Y < polygon.MaxY)
+ {
+ id = zone.ZoneId;
+ break;
+ }
}
+ return id;
}
- protected override void OnKeyUp(KeyEventArgs e)
+ // Get zone index for UI update
+ public int GetZoneIndex(ulong zoneId)
{
- if (e.KeyData == Keys.Space)
- {
- isHand = false;
- lastMouse = new Point(0, 0);
- }
+ return PVS.data.Zones.FindIndex(z => z.ZoneId == zoneId);
+ }
- UpdateCursor();
+ // Get zone info for UI update
+ public List GetZonePoints(ulong zoneId)
+ {
+ List points = new();
+ foreach (Vector2 point in PVS.data.Zones[GetZoneIndex(zoneId)].Points)
+ points.Add(new Vector2(point.X, point.Y));
+ return points;
+ }
+
+ // Get zone neighbours for UI update
+ public List GetZoneNeighbours(ulong zoneId)
+ {
+ List neighbours = new();
+ foreach (Neighbour neighbour in PVS.data.Zones[GetZoneIndex(zoneId)].UnsafeNeighbours)
+ neighbours.Add(neighbour);
+ return neighbours;
}
protected override void OnMouseDown(MouseEventArgs e)
{
+ // Move the camera
if (e.Button == MouseButtons.Left)
{
lastMouse = e.Location;
- if (isHand)
- {
- isDragging = true;
- }
+ isDragging = true;
}
}
@@ -109,11 +133,29 @@ protected override void OnMouseUp(MouseEventArgs e)
}
}
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ // Reset the camera
+ if (e.KeyData == Keys.R)
+ {
+ RenderScale = 1;
+ CameraPosition.X = 0;
+ CameraPosition.Y = 0;
+ Invalidate();
+ }
+ }
+
+ protected override void OnKeyUp(KeyEventArgs e)
+ {
+ lastMouse = new Point(0, 0);
+ }
+
+ // Move the camera
protected override void OnMouseMove(MouseEventArgs e)
{
mousePos = e.Location;
Invalidate();
- if (isHand && isDragging)
+ if (isDragging)
{
Size difference = new Size(e.X - lastMouse.X, e.Y - lastMouse.Y);
lastMouse = new Point(e.X, e.Y);
@@ -123,6 +165,7 @@ protected override void OnMouseMove(MouseEventArgs e)
}
}
+ // Zoom
protected override void OnMouseWheel(MouseEventArgs e)
{
int wheelDelta = 120;
@@ -133,7 +176,7 @@ protected override void OnMouseWheel(MouseEventArgs e)
if (RenderScale < 1)
{
- RenderScale = oldScale;
+ RenderScale = 1;
}
else if (RenderScale > 500)
{
@@ -149,11 +192,6 @@ protected override void OnMouseWheel(MouseEventArgs e)
Invalidate();
}
- protected void UpdateCursor()
- {
- Cursor = isHand ? Cursors.SizeAll : Cursors.Arrow;
- }
-
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
@@ -194,20 +232,35 @@ protected void DrawPVS(Graphics g)
return;
// Draw all plates
- for (int i = 0; i < PVS.Zones.Count; i++)
+ int selectedZoneIndex = PVS.data.Zones.FindIndex(z => z.ZoneId == PVS.selectedZoneId);
+ for (int i = 0; i < PVS.data.Zones.Count; i++)
{
- PVSZone plate = PVS.Zones[i];
+ Zone plate = PVS.data.Zones[i];
+ if (selectedZoneIndex != -1)
+ {
+ if (i == selectedZoneIndex)
+ {
+ DrawMapSection(g, plate, MapSectionType.Current);
+ continue;
+ }
+ if (PVS.data.Zones[selectedZoneIndex].UnsafeNeighbours.FindIndex(n => n.ZoneId == plate.ZoneId) != -1)
+ {
+ DrawMapSection(g, plate, MapSectionType.Neighbour);
+ continue;
+ }
+ }
+
DrawMapSection(g, plate);
}
}
- protected void DrawMapSection(Graphics g, PVSZone entry)
+ protected void DrawMapSection(Graphics g, Zone entry, MapSectionType type = MapSectionType.Unloaded)
{
PointF[] points = new PointF[entry.Points.Count];
for (int i = 0; i < entry.Points.Count; i++)
{
- ZonePoint data = entry.Points[i];
+ Vector2 data = entry.Points[i];
points[i] = new PointF(data.X * Multiplier * RenderScale + RenderOffset.X, data.Y * Multiplier * RenderScale + RenderOffset.Y);
}
@@ -216,8 +269,10 @@ protected void DrawMapSection(Graphics g, PVSZone entry)
if (bounds.IntersectsWith(ClientRectangle))
{
-
- //g.FillPolygon(new SolidBrush(Color.IndianRed), points);
+ if (type == MapSectionType.Current)
+ g.FillPolygon(new SolidBrush(Color.FromArgb(127, 255, 0, 0)), points); // Red
+ else if (type == MapSectionType.Neighbour)
+ g.FillPolygon(new SolidBrush(Color.FromArgb(127, 255, 255, 0)), points); // Yellow
g.DrawPolygon(new Pen(Color.Cyan), points);
Font font;
@@ -241,7 +296,7 @@ protected void DrawMapSection(Graphics g, PVSZone entry)
}
float textScale = RenderScale / (Multiplier * 2) - times;
font = new Font(Font.FontFamily, textScale);
- infoText = entry.ZoneID.ToString();
+ infoText = entry.ZoneId.ToString();
textSize = g.MeasureString(infoText, font);
times++;
diff --git a/PVSFormat/PVSEditControl.resx b/PVSFormat/PVSEditControl.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/PVSFormat/PVSEditControl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
\ No newline at end of file
diff --git a/PVSFormat/PVSEditor.Designer.cs b/PVSFormat/PVSEditor.Designer.cs
index 0fd3f3a..7bcef33 100644
--- a/PVSFormat/PVSEditor.Designer.cs
+++ b/PVSFormat/PVSEditor.Designer.cs
@@ -1,4 +1,4 @@
-namespace PVSFormat
+namespace PVSFormat
{
partial class PVSEditor
{
@@ -28,73 +28,446 @@ protected override void Dispose(bool disposing)
///
private void InitializeComponent()
{
- this.stsMain = new System.Windows.Forms.StatusStrip();
- this.mnuMain = new System.Windows.Forms.MenuStrip();
- this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.pvsMain = new PVSFormat.PVSEditControl();
- this.mnuMain.SuspendLayout();
- this.SuspendLayout();
- //
- // stsMain
- //
- this.stsMain.Location = new System.Drawing.Point(0, 339);
- this.stsMain.Name = "stsMain";
- this.stsMain.Size = new System.Drawing.Size(524, 22);
- this.stsMain.TabIndex = 1;
- this.stsMain.Text = "statusStrip1";
- //
- // mnuMain
- //
- this.mnuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.debugToolStripMenuItem});
- this.mnuMain.Location = new System.Drawing.Point(0, 0);
- this.mnuMain.Name = "mnuMain";
- this.mnuMain.Size = new System.Drawing.Size(524, 24);
- this.mnuMain.TabIndex = 2;
- this.mnuMain.Text = "menuStrip1";
- //
- // debugToolStripMenuItem
- //
- this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
- this.debugToolStripMenuItem.Size = new System.Drawing.Size(54, 20);
- this.debugToolStripMenuItem.Text = "Debug";
- this.debugToolStripMenuItem.Click += new System.EventHandler(this.DebugToolStripMenuItem_Click);
+ pvsSplitContainer = new System.Windows.Forms.SplitContainer();
+ pvsMain = new PVSEditControl();
+ deleteZoneButton = new System.Windows.Forms.Button();
+ addZoneButton = new System.Windows.Forms.Button();
+ zonesListBox = new System.Windows.Forms.ListBox();
+ deleteNeighbourButton = new System.Windows.Forms.Button();
+ addNeighbourButton = new System.Windows.Forms.Button();
+ yLabel2 = new System.Windows.Forms.Label();
+ yLabel3 = new System.Windows.Forms.Label();
+ yLabel4 = new System.Windows.Forms.Label();
+ yLabel1 = new System.Windows.Forms.Label();
+ immediateCheckBox = new System.Windows.Forms.CheckBox();
+ renderCheckBox = new System.Windows.Forms.CheckBox();
+ zonesLabel = new System.Windows.Forms.Label();
+ neighboursListBox = new System.Windows.Forms.ListBox();
+ neighboursLabel = new System.Windows.Forms.Label();
+ xLabel2 = new System.Windows.Forms.Label();
+ point2YNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ point2XNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ xLabel3 = new System.Windows.Forms.Label();
+ point3YNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ point3XNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ xLabel4 = new System.Windows.Forms.Label();
+ point4YNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ point4XNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ xLabel1 = new System.Windows.Forms.Label();
+ point1YNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ point1XNumericUpDown = new System.Windows.Forms.NumericUpDown();
+ pointsLabel = new System.Windows.Forms.Label();
+ ((System.ComponentModel.ISupportInitialize)pvsSplitContainer).BeginInit();
+ pvsSplitContainer.Panel1.SuspendLayout();
+ pvsSplitContainer.Panel2.SuspendLayout();
+ pvsSplitContainer.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)point2YNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point2XNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point3YNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point3XNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point4YNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point4XNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point1YNumericUpDown).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)point1XNumericUpDown).BeginInit();
+ SuspendLayout();
+ //
+ // pvsSplitContainer
+ //
+ pvsSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+ pvsSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+ pvsSplitContainer.Location = new System.Drawing.Point(0, 0);
+ pvsSplitContainer.Name = "pvsSplitContainer";
+ //
+ // pvsSplitContainer.Panel1
+ //
+ pvsSplitContainer.Panel1.Controls.Add(pvsMain);
+ //
+ // pvsSplitContainer.Panel2
+ //
+ pvsSplitContainer.Panel2.Controls.Add(deleteZoneButton);
+ pvsSplitContainer.Panel2.Controls.Add(addZoneButton);
+ pvsSplitContainer.Panel2.Controls.Add(zonesListBox);
+ pvsSplitContainer.Panel2.Controls.Add(deleteNeighbourButton);
+ pvsSplitContainer.Panel2.Controls.Add(addNeighbourButton);
+ pvsSplitContainer.Panel2.Controls.Add(yLabel2);
+ pvsSplitContainer.Panel2.Controls.Add(yLabel3);
+ pvsSplitContainer.Panel2.Controls.Add(yLabel4);
+ pvsSplitContainer.Panel2.Controls.Add(yLabel1);
+ pvsSplitContainer.Panel2.Controls.Add(immediateCheckBox);
+ pvsSplitContainer.Panel2.Controls.Add(renderCheckBox);
+ pvsSplitContainer.Panel2.Controls.Add(zonesLabel);
+ pvsSplitContainer.Panel2.Controls.Add(neighboursListBox);
+ pvsSplitContainer.Panel2.Controls.Add(neighboursLabel);
+ pvsSplitContainer.Panel2.Controls.Add(xLabel2);
+ pvsSplitContainer.Panel2.Controls.Add(point2YNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(point2XNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(xLabel3);
+ pvsSplitContainer.Panel2.Controls.Add(point3YNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(point3XNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(xLabel4);
+ pvsSplitContainer.Panel2.Controls.Add(point4YNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(point4XNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(xLabel1);
+ pvsSplitContainer.Panel2.Controls.Add(point1YNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(point1XNumericUpDown);
+ pvsSplitContainer.Panel2.Controls.Add(pointsLabel);
+ pvsSplitContainer.Size = new System.Drawing.Size(784, 561);
+ pvsSplitContainer.SplitterDistance = 580;
+ pvsSplitContainer.TabIndex = 0;
//
// pvsMain
//
- this.pvsMain.BackColor = System.Drawing.Color.Black;
- this.pvsMain.Dock = System.Windows.Forms.DockStyle.Fill;
- this.pvsMain.Font = new System.Drawing.Font("Courier New", 10F);
- this.pvsMain.ForeColor = System.Drawing.Color.White;
- this.pvsMain.Location = new System.Drawing.Point(0, 24);
- this.pvsMain.Name = "pvsMain";
- this.pvsMain.PVS = null;
- this.pvsMain.Size = new System.Drawing.Size(524, 315);
- this.pvsMain.TabIndex = 3;
- this.pvsMain.Text = "pvsEditControl1";
+ pvsMain.BackColor = System.Drawing.Color.Black;
+ pvsMain.Dock = System.Windows.Forms.DockStyle.Fill;
+ pvsMain.Font = new System.Drawing.Font("Courier New", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+ pvsMain.ForeColor = System.Drawing.Color.White;
+ pvsMain.Location = new System.Drawing.Point(0, 0);
+ pvsMain.Name = "pvsMain";
+ pvsMain.PVS = null;
+ pvsMain.Size = new System.Drawing.Size(580, 561);
+ pvsMain.TabIndex = 0;
+ pvsMain.DoubleClick += pvsMain_DoubleClick;
+ //
+ // deleteZoneButton
+ //
+ deleteZoneButton.Enabled = false;
+ deleteZoneButton.Location = new System.Drawing.Point(136, 8);
+ deleteZoneButton.Name = "deleteZoneButton";
+ deleteZoneButton.Size = new System.Drawing.Size(48, 23);
+ deleteZoneButton.TabIndex = 28;
+ deleteZoneButton.Text = "Delete";
+ deleteZoneButton.UseVisualStyleBackColor = true;
+ deleteZoneButton.Click += deleteZoneButton_Click;
+ //
+ // addZoneButton
+ //
+ addZoneButton.Location = new System.Drawing.Point(16, 8);
+ addZoneButton.Name = "addZoneButton";
+ addZoneButton.Size = new System.Drawing.Size(48, 23);
+ addZoneButton.TabIndex = 27;
+ addZoneButton.Text = "Add";
+ addZoneButton.UseVisualStyleBackColor = true;
+ addZoneButton.Click += addZoneButton_Click;
+ //
+ // zonesListBox
+ //
+ zonesListBox.FormattingEnabled = true;
+ zonesListBox.ItemHeight = 15;
+ zonesListBox.Location = new System.Drawing.Point(12, 32);
+ zonesListBox.Name = "zonesListBox";
+ zonesListBox.Size = new System.Drawing.Size(177, 184);
+ zonesListBox.Sorted = true;
+ zonesListBox.TabIndex = 26;
+ zonesListBox.SelectedIndexChanged += zonesListBox_SelectedIndexChanged;
+ //
+ // deleteNeighbourButton
+ //
+ deleteNeighbourButton.Enabled = false;
+ deleteNeighbourButton.Location = new System.Drawing.Point(135, 353);
+ deleteNeighbourButton.Name = "deleteNeighbourButton";
+ deleteNeighbourButton.Size = new System.Drawing.Size(48, 23);
+ deleteNeighbourButton.TabIndex = 24;
+ deleteNeighbourButton.Text = "Delete";
+ deleteNeighbourButton.UseVisualStyleBackColor = true;
+ deleteNeighbourButton.Click += deleteNeighbourButton_Click;
+ //
+ // addNeighbourButton
+ //
+ addNeighbourButton.Enabled = false;
+ addNeighbourButton.Location = new System.Drawing.Point(15, 353);
+ addNeighbourButton.Name = "addNeighbourButton";
+ addNeighbourButton.Size = new System.Drawing.Size(48, 23);
+ addNeighbourButton.TabIndex = 23;
+ addNeighbourButton.Text = "Add";
+ addNeighbourButton.UseVisualStyleBackColor = true;
+ addNeighbourButton.Click += addNeighbourButton_Click;
+ //
+ // yLabel2
+ //
+ yLabel2.AutoSize = true;
+ yLabel2.Location = new System.Drawing.Point(100, 269);
+ yLabel2.Name = "yLabel2";
+ yLabel2.Size = new System.Drawing.Size(13, 15);
+ yLabel2.TabIndex = 22;
+ yLabel2.Text = "y";
+ //
+ // yLabel3
+ //
+ yLabel3.AutoSize = true;
+ yLabel3.Location = new System.Drawing.Point(100, 298);
+ yLabel3.Name = "yLabel3";
+ yLabel3.Size = new System.Drawing.Size(13, 15);
+ yLabel3.TabIndex = 21;
+ yLabel3.Text = "y";
+ //
+ // yLabel4
+ //
+ yLabel4.AutoSize = true;
+ yLabel4.Location = new System.Drawing.Point(100, 327);
+ yLabel4.Name = "yLabel4";
+ yLabel4.Size = new System.Drawing.Size(13, 15);
+ yLabel4.TabIndex = 20;
+ yLabel4.Text = "y";
+ //
+ // yLabel1
+ //
+ yLabel1.AutoSize = true;
+ yLabel1.Location = new System.Drawing.Point(100, 240);
+ yLabel1.Name = "yLabel1";
+ yLabel1.Size = new System.Drawing.Size(13, 15);
+ yLabel1.TabIndex = 19;
+ yLabel1.Text = "y";
+ //
+ // immediateCheckBox
+ //
+ immediateCheckBox.AutoSize = true;
+ immediateCheckBox.Enabled = false;
+ immediateCheckBox.Location = new System.Drawing.Point(97, 538);
+ immediateCheckBox.Name = "immediateCheckBox";
+ immediateCheckBox.Size = new System.Drawing.Size(83, 19);
+ immediateCheckBox.TabIndex = 18;
+ immediateCheckBox.Text = "Immediate";
+ immediateCheckBox.UseVisualStyleBackColor = true;
+ immediateCheckBox.CheckedChanged += immediateCheckBox_CheckedChanged;
+ //
+ // renderCheckBox
+ //
+ renderCheckBox.AutoSize = true;
+ renderCheckBox.Enabled = false;
+ renderCheckBox.Location = new System.Drawing.Point(23, 538);
+ renderCheckBox.Name = "renderCheckBox";
+ renderCheckBox.Size = new System.Drawing.Size(63, 19);
+ renderCheckBox.TabIndex = 17;
+ renderCheckBox.Text = "Render";
+ renderCheckBox.UseVisualStyleBackColor = true;
+ renderCheckBox.CheckedChanged += renderCheckBox_CheckedChanged;
+ //
+ // zonesLabel
+ //
+ zonesLabel.AutoSize = true;
+ zonesLabel.Location = new System.Drawing.Point(79, 12);
+ zonesLabel.Name = "zonesLabel";
+ zonesLabel.Size = new System.Drawing.Size(39, 15);
+ zonesLabel.TabIndex = 15;
+ zonesLabel.Text = "Zones";
+ //
+ // neighboursListBox
+ //
+ neighboursListBox.Enabled = false;
+ neighboursListBox.FormattingEnabled = true;
+ neighboursListBox.ItemHeight = 15;
+ neighboursListBox.Location = new System.Drawing.Point(11, 378);
+ neighboursListBox.Name = "neighboursListBox";
+ neighboursListBox.Size = new System.Drawing.Size(177, 154);
+ neighboursListBox.Sorted = true;
+ neighboursListBox.TabIndex = 14;
+ neighboursListBox.SelectedIndexChanged += neighboursListBox_SelectedIndexChanged;
+ //
+ // neighboursLabel
+ //
+ neighboursLabel.AutoSize = true;
+ neighboursLabel.Location = new System.Drawing.Point(64, 357);
+ neighboursLabel.Name = "neighboursLabel";
+ neighboursLabel.Size = new System.Drawing.Size(69, 15);
+ neighboursLabel.TabIndex = 13;
+ neighboursLabel.Text = "Neighbours";
+ //
+ // xLabel2
+ //
+ xLabel2.AutoSize = true;
+ xLabel2.Location = new System.Drawing.Point(10, 269);
+ xLabel2.Name = "xLabel2";
+ xLabel2.Size = new System.Drawing.Size(13, 15);
+ xLabel2.TabIndex = 12;
+ xLabel2.Text = "x";
+ //
+ // point2YNumericUpDown
+ //
+ point2YNumericUpDown.DecimalPlaces = 3;
+ point2YNumericUpDown.Enabled = false;
+ point2YNumericUpDown.Location = new System.Drawing.Point(115, 265);
+ point2YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point2YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point2YNumericUpDown.Name = "point2YNumericUpDown";
+ point2YNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point2YNumericUpDown.TabIndex = 11;
+ point2YNumericUpDown.ValueChanged += point2YNumericUpDown_ValueChanged;
+ //
+ // point2XNumericUpDown
+ //
+ point2XNumericUpDown.DecimalPlaces = 3;
+ point2XNumericUpDown.Enabled = false;
+ point2XNumericUpDown.Location = new System.Drawing.Point(24, 265);
+ point2XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point2XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point2XNumericUpDown.Name = "point2XNumericUpDown";
+ point2XNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point2XNumericUpDown.TabIndex = 10;
+ point2XNumericUpDown.ValueChanged += point2XNumericUpDown_ValueChanged;
+ //
+ // xLabel3
+ //
+ xLabel3.AutoSize = true;
+ xLabel3.Location = new System.Drawing.Point(10, 298);
+ xLabel3.Name = "xLabel3";
+ xLabel3.Size = new System.Drawing.Size(13, 15);
+ xLabel3.TabIndex = 9;
+ xLabel3.Text = "x";
+ //
+ // point3YNumericUpDown
+ //
+ point3YNumericUpDown.DecimalPlaces = 3;
+ point3YNumericUpDown.Enabled = false;
+ point3YNumericUpDown.Location = new System.Drawing.Point(115, 294);
+ point3YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point3YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point3YNumericUpDown.Name = "point3YNumericUpDown";
+ point3YNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point3YNumericUpDown.TabIndex = 8;
+ point3YNumericUpDown.ValueChanged += point3YNumericUpDown_ValueChanged;
+ //
+ // point3XNumericUpDown
+ //
+ point3XNumericUpDown.DecimalPlaces = 3;
+ point3XNumericUpDown.Enabled = false;
+ point3XNumericUpDown.Location = new System.Drawing.Point(24, 294);
+ point3XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point3XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point3XNumericUpDown.Name = "point3XNumericUpDown";
+ point3XNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point3XNumericUpDown.TabIndex = 7;
+ point3XNumericUpDown.ValueChanged += point3XNumericUpDown_ValueChanged;
+ //
+ // xLabel4
+ //
+ xLabel4.AutoSize = true;
+ xLabel4.Location = new System.Drawing.Point(10, 327);
+ xLabel4.Name = "xLabel4";
+ xLabel4.Size = new System.Drawing.Size(13, 15);
+ xLabel4.TabIndex = 6;
+ xLabel4.Text = "x";
+ //
+ // point4YNumericUpDown
+ //
+ point4YNumericUpDown.DecimalPlaces = 3;
+ point4YNumericUpDown.Enabled = false;
+ point4YNumericUpDown.Location = new System.Drawing.Point(115, 323);
+ point4YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point4YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point4YNumericUpDown.Name = "point4YNumericUpDown";
+ point4YNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point4YNumericUpDown.TabIndex = 5;
+ point4YNumericUpDown.ValueChanged += point4YNumericUpDown_ValueChanged;
+ //
+ // point4XNumericUpDown
+ //
+ point4XNumericUpDown.DecimalPlaces = 3;
+ point4XNumericUpDown.Enabled = false;
+ point4XNumericUpDown.Location = new System.Drawing.Point(24, 323);
+ point4XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point4XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point4XNumericUpDown.Name = "point4XNumericUpDown";
+ point4XNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point4XNumericUpDown.TabIndex = 4;
+ point4XNumericUpDown.ValueChanged += point4XNumericUpDown_ValueChanged;
+ //
+ // xLabel1
+ //
+ xLabel1.AutoSize = true;
+ xLabel1.Location = new System.Drawing.Point(10, 240);
+ xLabel1.Name = "xLabel1";
+ xLabel1.Size = new System.Drawing.Size(13, 15);
+ xLabel1.TabIndex = 3;
+ xLabel1.Text = "x";
+ //
+ // point1YNumericUpDown
+ //
+ point1YNumericUpDown.DecimalPlaces = 3;
+ point1YNumericUpDown.Enabled = false;
+ point1YNumericUpDown.Location = new System.Drawing.Point(115, 236);
+ point1YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point1YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point1YNumericUpDown.Name = "point1YNumericUpDown";
+ point1YNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point1YNumericUpDown.TabIndex = 2;
+ point1YNumericUpDown.ValueChanged += point1YNumericUpDown_ValueChanged;
+ //
+ // point1XNumericUpDown
+ //
+ point1XNumericUpDown.DecimalPlaces = 3;
+ point1XNumericUpDown.Enabled = false;
+ point1XNumericUpDown.Location = new System.Drawing.Point(24, 236);
+ point1XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
+ point1XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue });
+ point1XNumericUpDown.Name = "point1XNumericUpDown";
+ point1XNumericUpDown.Size = new System.Drawing.Size(70, 23);
+ point1XNumericUpDown.TabIndex = 1;
+ point1XNumericUpDown.ValueChanged += point1XNumericUpDown_ValueChanged;
+ //
+ // pointsLabel
+ //
+ pointsLabel.AutoSize = true;
+ pointsLabel.Location = new System.Drawing.Point(78, 218);
+ pointsLabel.Name = "pointsLabel";
+ pointsLabel.Size = new System.Drawing.Size(40, 15);
+ pointsLabel.TabIndex = 0;
+ pointsLabel.Text = "Points";
//
// PVSEditor
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(524, 361);
- this.Controls.Add(this.pvsMain);
- this.Controls.Add(this.stsMain);
- this.Controls.Add(this.mnuMain);
- this.MainMenuStrip = this.mnuMain;
- this.Name = "PVSEditor";
- this.Text = "PVSEditor";
- this.mnuMain.ResumeLayout(false);
- this.mnuMain.PerformLayout();
- this.ResumeLayout(false);
- this.PerformLayout();
-
+ FormClosing += PVSEditor_FormClosing;
+ AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ ClientSize = new System.Drawing.Size(784, 561);
+ Controls.Add(pvsSplitContainer);
+ Name = "PVSEditor";
+ Text = "PVS Editor";
+ pvsSplitContainer.Panel1.ResumeLayout(false);
+ pvsSplitContainer.Panel2.ResumeLayout(false);
+ pvsSplitContainer.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)pvsSplitContainer).EndInit();
+ pvsSplitContainer.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)point2YNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point2XNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point3YNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point3XNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point4YNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point4XNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point1YNumericUpDown).EndInit();
+ ((System.ComponentModel.ISupportInitialize)point1XNumericUpDown).EndInit();
+ ResumeLayout(false);
}
#endregion
- private System.Windows.Forms.StatusStrip stsMain;
- private System.Windows.Forms.MenuStrip mnuMain;
- private System.Windows.Forms.ToolStripMenuItem debugToolStripMenuItem;
+
+ private System.Windows.Forms.SplitContainer pvsSplitContainer;
+ private System.Windows.Forms.Label pointsLabel;
private PVSEditControl pvsMain;
+ private System.Windows.Forms.Label xLabel2;
+ private System.Windows.Forms.Label xLabel3;
+ private System.Windows.Forms.Label xLabel4;
+ private System.Windows.Forms.Label xLabel1;
+ private System.Windows.Forms.Label neighboursLabel;
+ private System.Windows.Forms.Label zonesLabel;
+ private System.Windows.Forms.NumericUpDown point1XNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point1YNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point2YNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point2XNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point3YNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point3XNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point4YNumericUpDown;
+ private System.Windows.Forms.NumericUpDown point4XNumericUpDown;
+ private System.Windows.Forms.ListBox neighboursListBox;
+ private System.Windows.Forms.CheckBox immediateCheckBox;
+ private System.Windows.Forms.CheckBox renderCheckBox;
+ private System.Windows.Forms.Label yLabel2;
+ private System.Windows.Forms.Label yLabel3;
+ private System.Windows.Forms.Label yLabel4;
+ private System.Windows.Forms.Label yLabel1;
+ private System.Windows.Forms.Button deleteNeighbourButton;
+ private System.Windows.Forms.Button addNeighbourButton;
+ private System.Windows.Forms.Button deleteZoneButton;
+ private System.Windows.Forms.Button addZoneButton;
+ private System.Windows.Forms.ListBox zonesListBox;
}
-}
\ No newline at end of file
+}
diff --git a/PVSFormat/PVSEditor.cs b/PVSFormat/PVSEditor.cs
index a5c0591..637eab5 100644
--- a/PVSFormat/PVSEditor.cs
+++ b/PVSFormat/PVSEditor.cs
@@ -1,4 +1,8 @@
+using System;
+using System.Collections.Generic;
using System.Drawing;
+using System.Linq;
+using System.Numerics;
using System.Windows.Forms;
using DebugHelper;
using PluginAPI;
@@ -7,6 +11,9 @@ namespace PVSFormat
{
public partial class PVSEditor : Form, IEntryEditor
{
+ public delegate void OnEdit();
+ public event OnEdit Edit;
+
private PVS _currentPVS;
public Image GameMap
@@ -24,6 +31,9 @@ public void UpdateDisplay()
{
//dbgMain.SelectedObject = _currentPVS;
pvsMain.PVS = _currentPVS;
+
+ foreach (Zone zone in pvsMain.PVS.data.Zones)
+ zonesListBox.Items.Add(zone.ZoneId.ToString("000"));
}
public void Open(PVS pvs)
@@ -33,9 +43,277 @@ public void Open(PVS pvs)
UpdateDisplay();
}
- private void DebugToolStripMenuItem_Click(object sender, System.EventArgs e)
+ private List GetZones()
+ {
+ return pvsMain.PVS.data.Zones;
+ }
+
+ private List GetPoints()
+ {
+ return pvsMain.PVS.data.Zones[pvsMain.GetZoneIndex(ulong.Parse(zonesListBox.SelectedItem.ToString()))].Points;
+ }
+
+ private List GetUnsafeNeighbours()
+ {
+ return pvsMain.PVS.data.Zones[pvsMain.GetZoneIndex(ulong.Parse(zonesListBox.SelectedItem.ToString()))].UnsafeNeighbours;
+ }
+
+ private void SelectZone(ulong zoneId)
+ {
+ neighboursListBox.Items.Clear();
+ renderCheckBox.Checked = false;
+ immediateCheckBox.Checked = false;
+
+ pvsMain.PVS.selectedZoneId = zoneId;
+
+ List points = pvsMain.GetZonePoints(zoneId);
+ List neighbours = pvsMain.GetZoneNeighbours(zoneId);
+
+ point1XNumericUpDown.Value = (decimal)points[0].X;
+ point1YNumericUpDown.Value = (decimal)points[0].Y;
+ point2XNumericUpDown.Value = (decimal)points[1].X;
+ point2YNumericUpDown.Value = (decimal)points[1].Y;
+ point3XNumericUpDown.Value = (decimal)points[2].X;
+ point3YNumericUpDown.Value = (decimal)points[2].Y;
+ point4XNumericUpDown.Value = (decimal)points[3].X;
+ point4YNumericUpDown.Value = (decimal)points[3].Y;
+
+ foreach (Neighbour neighbour in neighbours)
+ neighboursListBox.Items.Add(neighbour.ZoneId.ToString("000"));
+
+ point1XNumericUpDown.Enabled = true;
+ point1YNumericUpDown.Enabled = true;
+ point2XNumericUpDown.Enabled = true;
+ point2YNumericUpDown.Enabled = true;
+ point3XNumericUpDown.Enabled = true;
+ point3YNumericUpDown.Enabled = true;
+ point4XNumericUpDown.Enabled = true;
+ point4YNumericUpDown.Enabled = true;
+ neighboursListBox.Enabled = true;
+ addNeighbourButton.Enabled = true;
+ deleteNeighbourButton.Enabled = false;
+ renderCheckBox.Enabled = false;
+ immediateCheckBox.Enabled = false;
+ }
+
+ private void PVSEditor_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ pvsMain.PVS.selectedZoneId = ulong.MaxValue;
+ Edit?.Invoke();
+ }
+
+ private void pvsMain_DoubleClick(object sender, System.EventArgs e)
+ {
+ ulong zoneId = pvsMain.GetZoneId();
+ if (zoneId == ulong.MaxValue)
+ return;
+
+ zonesListBox.SelectedIndex = zonesListBox.FindStringExact(zoneId.ToString("000"));
+ }
+
+ private void zonesListBox_SelectedIndexChanged(object sender, System.EventArgs e)
+ {
+ if (zonesListBox.SelectedIndex == -1)
+ return;
+ ulong zoneId = ulong.Parse(zonesListBox.SelectedItem.ToString());
+ SelectZone(zoneId);
+
+ deleteZoneButton.Enabled = true;
+ }
+
+ private void addZoneButton_Click(object sender, System.EventArgs e)
+ {
+ var zones = GetZones();
+ ulong newZoneId;
+ while (true)
+ {
+ newZoneId = new AddZone().GetNewZoneId();
+ if (zones.FindIndex(z => z.ZoneId == newZoneId) != -1)
+ {
+ MessageBox.Show("A zone with ID " + newZoneId + " already exists.");
+ continue;
+ }
+ break;
+ }
+ Zone newZone = new();
+ newZone.ZoneId = newZoneId;
+ zones.Add(newZone);
+ pvsMain.PVS.data.TotalZones++;
+
+ zonesListBox.Items.Add(newZoneId.ToString("000"));
+ zonesListBox.SelectedIndex = zonesListBox.FindStringExact(newZoneId.ToString("000"));
+ if (zonesListBox.Items.Count == 1)
+ deleteZoneButton.Enabled = true;
+ }
+
+ private void deleteZoneButton_Click(object sender, System.EventArgs e)
+ {
+ int index = zonesListBox.SelectedIndex;
+ ulong zoneId = ulong.Parse(zonesListBox.Items[index].ToString());
+ GetZones().Remove(GetZones().Find(z => z.ZoneId == zoneId));
+ pvsMain.PVS.data.TotalZones--;
+
+ zonesListBox.Items.RemoveAt(index);
+ if (zonesListBox.Items.Count == 0)
+ {
+ deleteZoneButton.Enabled = false;
+ return;
+ }
+ if (index == zonesListBox.Items.Count)
+ zonesListBox.SelectedIndex = zonesListBox.Items.Count - 1;
+ else
+ zonesListBox.SelectedIndex = index;
+ }
+
+ private void point1XNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[0];
+ point.X = (float)point1XNumericUpDown.Value;
+ GetPoints()[0] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point1YNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[0];
+ point.Y = (float)point1YNumericUpDown.Value;
+ GetPoints()[0] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point2XNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[1];
+ point.X = (float)point2XNumericUpDown.Value;
+ GetPoints()[1] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point2YNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[1];
+ point.Y = (float)point2YNumericUpDown.Value;
+ GetPoints()[1] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point3XNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[2];
+ point.X = (float)point3XNumericUpDown.Value;
+ GetPoints()[2] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point3YNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[2];
+ point.Y = (float)point3YNumericUpDown.Value;
+ GetPoints()[2] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point4XNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[3];
+ point.X = (float)point4XNumericUpDown.Value;
+ GetPoints()[3] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void point4YNumericUpDown_ValueChanged(object sender, System.EventArgs e)
+ {
+ Vector2 point = GetPoints()[3];
+ point.Y = (float)point4YNumericUpDown.Value;
+ GetPoints()[3] = point;
+ pvsMain.Invalidate();
+ }
+
+ private void neighboursListBox_SelectedIndexChanged(object sender, System.EventArgs e)
+ {
+ if (neighboursListBox.SelectedIndex == -1)
+ return;
+ int neighbourIndex = GetUnsafeNeighbours().FindIndex(n => n.ZoneId == ulong.Parse(neighboursListBox.SelectedItem.ToString()));
+ Neighbour neighbour = GetUnsafeNeighbours()[neighbourIndex];
+ renderCheckBox.Checked = neighbour.Flags.HasFlag(NeighbourFlags.E_NEIGHBOURFLAG_RENDER);
+ immediateCheckBox.Checked = neighbour.Flags.HasFlag(NeighbourFlags.E_NEIGHBOURFLAG_IMMEDIATE);
+
+ if (neighboursListBox.Items.Count != 0)
+ deleteNeighbourButton.Enabled = true;
+ renderCheckBox.Enabled = true;
+ immediateCheckBox.Enabled = true;
+ }
+
+ private void addNeighbourButton_Click(object sender, System.EventArgs e)
+ {
+ ulong newZoneId = new AddZone().GetNewZoneId();
+ var neighbours = GetUnsafeNeighbours();
+ Neighbour newNeighbour = new();
+ newNeighbour.ZoneId = newZoneId;
+ neighbours.Add(newNeighbour);
+ int parentIndex = GetZones().FindIndex(z => z.ZoneId == ulong.Parse(zonesListBox.SelectedItem.ToString()));
+ Zone parent = GetZones()[parentIndex];
+ parent.NumUnsafeNeighbours++;
+ GetZones()[parentIndex] = parent;
+
+ neighboursListBox.Items.Add(newZoneId.ToString("000"));
+ neighboursListBox.SelectedIndex = neighboursListBox.FindStringExact(newZoneId.ToString("000"));
+ pvsMain.Invalidate();
+ if (neighboursListBox.Items.Count == 1)
+ deleteNeighbourButton.Enabled = true;
+ }
+
+ private void deleteNeighbourButton_Click(object sender, System.EventArgs e)
+ {
+ int index = neighboursListBox.SelectedIndex;
+ ulong zoneId = ulong.Parse(neighboursListBox.Items[index].ToString());
+ GetUnsafeNeighbours().Remove(GetUnsafeNeighbours().Find(n => n.ZoneId == zoneId));
+ int parentIndex = GetZones().FindIndex(z => z.ZoneId == ulong.Parse(zonesListBox.SelectedItem.ToString()));
+ Zone parent = GetZones()[parentIndex];
+ parent.NumUnsafeNeighbours--;
+ GetZones()[parentIndex] = parent;
+
+ neighboursListBox.Items.RemoveAt(index);
+ pvsMain.Invalidate();
+ if (neighboursListBox.Items.Count == 0)
+ {
+ deleteNeighbourButton.Enabled = false;
+ renderCheckBox.Enabled = false;
+ immediateCheckBox.Enabled = false;
+ renderCheckBox.Checked = false;
+ immediateCheckBox.Checked = false;
+ return;
+ }
+ if (index == neighboursListBox.Items.Count)
+ neighboursListBox.SelectedIndex = neighboursListBox.Items.Count - 1;
+ else
+ neighboursListBox.SelectedIndex = index;
+ }
+
+ private void renderCheckBox_CheckedChanged(object sender, System.EventArgs e)
+ {
+ if (neighboursListBox.SelectedIndex == -1)
+ return;
+ int neighbourIndex = GetUnsafeNeighbours().FindIndex(n => n.ZoneId == ulong.Parse(neighboursListBox.SelectedItem.ToString()));
+ Neighbour neighbour = GetUnsafeNeighbours()[neighbourIndex];
+ if (renderCheckBox.Checked)
+ neighbour.Flags |= NeighbourFlags.E_NEIGHBOURFLAG_RENDER;
+ else
+ neighbour.Flags &= ~NeighbourFlags.E_NEIGHBOURFLAG_RENDER;
+ GetUnsafeNeighbours()[neighbourIndex] = neighbour;
+ }
+
+ private void immediateCheckBox_CheckedChanged(object sender, System.EventArgs e)
{
- DebugUtil.ShowDebug(_currentPVS);
+ if (neighboursListBox.SelectedIndex == -1)
+ return;
+ int neighbourIndex = GetUnsafeNeighbours().FindIndex(n => n.ZoneId == ulong.Parse(neighboursListBox.SelectedItem.ToString()));
+ Neighbour neighbour = GetUnsafeNeighbours()[neighbourIndex];
+ if (immediateCheckBox.Checked)
+ neighbour.Flags |= NeighbourFlags.E_NEIGHBOURFLAG_IMMEDIATE;
+ else
+ neighbour.Flags &= ~NeighbourFlags.E_NEIGHBOURFLAG_IMMEDIATE;
+ GetUnsafeNeighbours()[neighbourIndex] = neighbour;
}
}
}
diff --git a/PVSFormat/PVSEditor.resx b/PVSFormat/PVSEditor.resx
index 411bc26..a395bff 100644
--- a/PVSFormat/PVSEditor.resx
+++ b/PVSFormat/PVSEditor.resx
@@ -1,24 +1,24 @@
-
@@ -117,10 +117,4 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 17, 17
-
-
- 111, 17
-
\ No newline at end of file
diff --git a/PVSFormat/Util/GeneralExtensions.cs b/PVSFormat/Util/GeneralExtensions.cs
deleted file mode 100644
index c2d99e5..0000000
--- a/PVSFormat/Util/GeneralExtensions.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using System.IO;
-using System.Text;
-
-namespace PVSFormat.Util
-{
- public static class GeneralExtensions
- {
- public static bool Matches(this string[] self, string[] other)
- {
- if (self.Length != other.Length)
- return false;
-
- for (int i = 0; i < self.Length; i++)
- {
- if (self[i] != other[i])
- return false;
- }
-
- return true;
- }
-
- public static string[] Rebuild(this string[] self, int size)
- {
- string[] result = new string[size];
- for (int i = 0; i < result.Length; i++)
- {
- if (i >= self.Length)
- {
- result[i] = "";
- continue;
- }
- result[i] = self[i];
- }
- return result;
- }
-
- public static string BuildString(this string[] self)
- {
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < self.Length; i++)
- {
- sb.Append(self[i] + "\r\n");
- }
-
- return sb.ToString();
- }
-
- public static string AsArrayIndexString(this int[] self)
- {
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < self.Length; i++)
- {
- sb.Append(self[i].ToString());
-
- if (i < self.Length - 1)
- sb.Append(", ");
- }
-
- return sb.ToString();
- }
-
- public static bool EOF(this BinaryReader self)
- {
- return self.BaseStream.Position >= self.BaseStream.Length;
- }
- }
-}