mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2025-02-06 07:41:01 +00:00
Changed, Draw Lines mode: line angles are now shown only when "Show guidelines" mode is enabled. Fixed, Draw Lines mode: in some cases "Snap to cardinal directions" mode was snapping only to diagonals. Fixed, Draw Lines mode: snap to geometry behaved incorrectly when "Snap to cardinal directions" mode was enabled. Changed, Things mode: dynamic light shape is now drawn using highlight color when a dynamic light thing is highlighted. Added more sanity checks to MODELDEFS parser.
1148 lines
48 KiB
C#
1148 lines
48 KiB
C#
#region ================== Namespaces
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.Rendering;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
using CodeImp.DoomBuilder.Editing;
|
|
using CodeImp.DoomBuilder.Windows;
|
|
using System.Drawing;
|
|
using CodeImp.DoomBuilder.Actions;
|
|
using CodeImp.DoomBuilder.BuilderModes.Interface;
|
|
|
|
#endregion
|
|
|
|
//JBR Vertex Slope Assistant mode
|
|
namespace CodeImp.DoomBuilder.BuilderModes
|
|
{
|
|
[EditMode(DisplayName = "Vertex Slope Assistant",
|
|
AllowCopyPaste = false,
|
|
Volatile = true)]
|
|
public sealed class VertexSlopeAssistMode : BaseClassicMode
|
|
{
|
|
#region ================== Constants
|
|
|
|
private const float LINE_THICKNESS = 1.2f;
|
|
private const float OVER_THICKNESS = 0.6f;
|
|
private const int MODE_SELECT = 0;
|
|
private const int MODE_ASSIGNGROUPS = 1;
|
|
private const int MODE_NEWPOINTS = 4; // This mode doesn't exist but tell which modes begin to set points
|
|
private const int MODE_NEWTAGGEDTRIANGLE = 4;
|
|
private const int MODE_NEWEMPTYTRIANGLE = 5;
|
|
private const int MODE_NEWGROUP = 6;
|
|
private const int MODE_MODGROUP = 7;
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
public int mode;
|
|
public bool createdUndo;
|
|
public TextLabel[] vertexnames;
|
|
public List<DrawnVertex> points;
|
|
public int expectedPoints;
|
|
|
|
// Groups selection
|
|
public List<int> overgroups;
|
|
public int overgroupoffset;
|
|
public int overTagID;
|
|
|
|
// Linedef stuff
|
|
public Linedef selectedLinedef;
|
|
public Linedef indexedLinedef;
|
|
public int indexedAction;
|
|
public List<int> indexedTags;
|
|
|
|
// Current mouse position
|
|
public Vector2D curmousepos;
|
|
|
|
public bool snaptogrid; // SHIFT to toggle
|
|
public bool snaptonearest; // CTRL to enable
|
|
public bool snaptocardinaldirection; //mxd. ALT-SHIFT to enable
|
|
|
|
#endregion
|
|
|
|
#region ================== Properties
|
|
|
|
// Just keep the base mode button checked
|
|
public override string EditModeButtonName { get { return General.Editing.PreviousStableMode.Name; } }
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor / Disposer
|
|
|
|
// Constructor
|
|
public VertexSlopeAssistMode(EditMode basemode)
|
|
{
|
|
vertexnames = new TextLabel[4];
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
vertexnames[i] = new TextLabel();
|
|
vertexnames[i].TransformCoords = true;
|
|
vertexnames[i].Location = new Vector2D(0f, 0f);
|
|
vertexnames[i].AlignX = TextAlignmentX.Center;
|
|
vertexnames[i].AlignY = TextAlignmentY.Middle;
|
|
vertexnames[i].Color = General.Colors.Highlight.WithAlpha(255);
|
|
}
|
|
points = new List<DrawnVertex>();
|
|
overgroups = new List<int>();
|
|
overgroupoffset = 0;
|
|
curmousepos = new Vector2D();
|
|
overTagID = -1;
|
|
expectedPoints = 3;
|
|
selectedLinedef = null;
|
|
indexedLinedef = null;
|
|
indexedAction = 0;
|
|
indexedTags = new List<int>();
|
|
SetMode(MODE_SELECT);
|
|
}
|
|
|
|
// Disposer
|
|
public override void Dispose()
|
|
{
|
|
// Not already disposed?
|
|
if(!isdisposed)
|
|
{
|
|
// Clean up
|
|
foreach (TextLabel tl in vertexnames) tl.Dispose();
|
|
|
|
// Done
|
|
base.Dispose();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Methods
|
|
|
|
public void CreateUndo()
|
|
{
|
|
if (!createdUndo)
|
|
{
|
|
General.Map.UndoRedo.CreateUndo("Vertex Slope Assistant");
|
|
createdUndo = true;
|
|
}
|
|
}
|
|
|
|
public void UpdateModeText()
|
|
{
|
|
if (mode == MODE_SELECT)
|
|
{
|
|
if (overTagID != -1)
|
|
BuilderPlug.Me.VertexSlopeAssistForm.ModeText = string.Format("Select/Edit group, Click to select tag {0}", overTagID);
|
|
else
|
|
BuilderPlug.Me.VertexSlopeAssistForm.ModeText = string.Format("Select/Edit group");
|
|
}
|
|
if (mode == MODE_ASSIGNGROUPS)
|
|
{
|
|
BuilderPlug.Me.VertexSlopeAssistForm.ModeText = string.Format("Double-Click on Group List to pick Vertex {0}", indexedTags.Count + 1);
|
|
}
|
|
if (mode == MODE_NEWTAGGEDTRIANGLE || mode == MODE_NEWEMPTYTRIANGLE)
|
|
{
|
|
BuilderPlug.Me.VertexSlopeAssistForm.ModeText = string.Format("Creating new triangle... Click to make point {0}", points.Count + 1);
|
|
}
|
|
if (mode == MODE_NEWGROUP)
|
|
{
|
|
BuilderPlug.Me.VertexSlopeAssistForm.ModeText = string.Format("Making new group... Click to make point {0}", points.Count + 1);
|
|
}
|
|
if (mode == MODE_MODGROUP)
|
|
{
|
|
BuilderPlug.Me.VertexSlopeAssistForm.ModeText = string.Format("Remaking group... Click to make point {0}", points.Count + 1);
|
|
}
|
|
}
|
|
|
|
public void SetMode(int newmode)
|
|
{
|
|
mode = newmode;
|
|
UpdateModeText();
|
|
points.Clear();
|
|
indexedTags.Clear();
|
|
selectedLinedef = null;
|
|
if (newmode != MODE_ASSIGNGROUPS) indexedLinedef = null;
|
|
}
|
|
|
|
public void CB_DrawNewTaggedTriangle(object sender, EventArgs eventArgs)
|
|
{
|
|
expectedPoints = 3;
|
|
SetMode(MODE_NEWTAGGEDTRIANGLE);
|
|
}
|
|
|
|
public void CB_DrawNewEmptyTriangle(object sender, EventArgs eventArgs)
|
|
{
|
|
expectedPoints = 3;
|
|
SetMode(MODE_NEWEMPTYTRIANGLE);
|
|
}
|
|
|
|
public void CB_TagGroup_Changed(object sender, EventArgs eventArgs)
|
|
{
|
|
if (mode != MODE_ASSIGNGROUPS)
|
|
SetMode(MODE_SELECT);
|
|
else
|
|
General.Interface.RedrawDisplay();
|
|
}
|
|
|
|
public void CB_TagGroup_Choosen(object sender, EventArgs eventArgs)
|
|
{
|
|
if (mode == MODE_ASSIGNGROUPS)
|
|
{
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
if (things != null && things.Count == 1)
|
|
{
|
|
DrawnVertex dv = new DrawnVertex();
|
|
dv.stitch = true;
|
|
dv.stitchline = true;
|
|
dv.pos = things[0].Position;
|
|
points.Add(dv);
|
|
indexedTags.Add(BuilderPlug.Me.VertexSlopeAssistForm.TagID);
|
|
if (indexedTags.Count >= 3)
|
|
{
|
|
if (indexedLinedef != null)
|
|
{
|
|
CreateUndo();
|
|
indexedLinedef.Tag = indexedTags[0];
|
|
indexedLinedef.SetFlag("8192", true);
|
|
if (indexedAction < 710) // 704, 705
|
|
{
|
|
indexedLinedef.Front.OffsetX = indexedTags[1];
|
|
indexedLinedef.Front.OffsetY = indexedTags[2];
|
|
}
|
|
else // 714, 715
|
|
{
|
|
indexedLinedef.Back.OffsetX = indexedTags[1];
|
|
indexedLinedef.Back.OffsetY = indexedTags[2];
|
|
}
|
|
indexedLinedef.Action = indexedAction;
|
|
General.Interface.DisplayStatus(StatusType.Action, string.Format("Action {0} and Tag {1} set to Linedef {2}.", indexedLinedef.Action, indexedLinedef.Tag, indexedLinedef.Index));
|
|
}
|
|
SetMode(MODE_SELECT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
General.Interface.DisplayStatus(StatusType.Warning, "Only single vertex slope groups can be assigned.");
|
|
}
|
|
UpdateModeText();
|
|
}
|
|
}
|
|
|
|
public void CB_TagGroup_NewTriangle(object sender, EventArgs eventArgs)
|
|
{
|
|
expectedPoints = 3;
|
|
SetMode(MODE_NEWGROUP);
|
|
}
|
|
|
|
public void CB_TagGroup_NewVertex(object sender, EventArgs eventArgs)
|
|
{
|
|
expectedPoints = 1;
|
|
SetMode(MODE_NEWGROUP);
|
|
}
|
|
|
|
public void CB_TagGroup_Modify(object sender, EventArgs eventArgs)
|
|
{
|
|
int vertices = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag();
|
|
if (vertices == 1)
|
|
expectedPoints = 1;
|
|
else
|
|
expectedPoints = 3;
|
|
SetMode(MODE_MODGROUP);
|
|
}
|
|
|
|
public void CB_TagGroup_ModifyAsTriangle(object sender, EventArgs eventArgs)
|
|
{
|
|
expectedPoints = 3;
|
|
SetMode(MODE_MODGROUP);
|
|
}
|
|
|
|
public void CB_TagGroup_ModifyAsVertex(object sender, EventArgs eventArgs)
|
|
{
|
|
expectedPoints = 1;
|
|
SetMode(MODE_MODGROUP);
|
|
}
|
|
|
|
public void CB_TagGroup_Tag(object sender, EventArgs eventArgs)
|
|
{
|
|
SetMode(MODE_SELECT);
|
|
int oldtag = BuilderPlug.Me.VertexSlopeAssistForm.TagID;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Hide();
|
|
int newtag = VertexSlopeAssistTagForm.RunDialog(BuilderPlug.Me.VertexSlopeAssistForm, oldtag);
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Show();
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Activate();
|
|
if (newtag != -1 && newtag != oldtag)
|
|
{
|
|
bool exists = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag(newtag) > 0;
|
|
if (exists)
|
|
{
|
|
General.Interface.DisplayStatus(StatusType.Warning, string.Format("Tag {0} already belongs to another group. Aborted retagging.", newtag));
|
|
}
|
|
else
|
|
{
|
|
CreateUndo();
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
if (things != null)
|
|
{
|
|
foreach (Thing t in things)
|
|
{
|
|
t.Rotate(newtag);
|
|
t.UpdateConfiguration();
|
|
}
|
|
}
|
|
General.Map.ThingsFilter.Update();
|
|
General.Map.Map.Update();
|
|
General.Map.IsChanged = true;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.TagID = newtag;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.CreateList();
|
|
BuilderPlug.Me.VertexSlopeAssistForm.UpdateForm();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void CB_TagGroup_Delete(object sender, EventArgs eventArgs)
|
|
{
|
|
CreateUndo();
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
if (things != null)
|
|
{
|
|
for (int i = things.Count - 1; i >= 0; i--)
|
|
{
|
|
things[i].Dispose();
|
|
}
|
|
}
|
|
General.Map.ThingsFilter.Update();
|
|
General.Map.Map.Update();
|
|
General.Map.IsChanged = true;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.CreateList();
|
|
BuilderPlug.Me.VertexSlopeAssistForm.UpdateForm();
|
|
SetMode(MODE_SELECT);
|
|
}
|
|
|
|
public void CB_ValueChanged(object sender, EventArgs eventArgs)
|
|
{
|
|
CreateUndo();
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
if (things != null)
|
|
{
|
|
CreateUndo();
|
|
if (things.Count >= 1)
|
|
{
|
|
things[0].Move(BuilderPlug.Me.VertexSlopeAssistForm.Vertex1);
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ)
|
|
ChangeVSlopeFlags(things[0], (int)BuilderPlug.Me.VertexSlopeAssistForm.Vertex1.z);
|
|
things[0].Parameter = BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ ? 1 : 0;
|
|
things[0].UpdateConfiguration();
|
|
}
|
|
if (things.Count >= 2)
|
|
{
|
|
things[1].Move(BuilderPlug.Me.VertexSlopeAssistForm.Vertex2);
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ)
|
|
ChangeVSlopeFlags(things[1], (int)BuilderPlug.Me.VertexSlopeAssistForm.Vertex2.z);
|
|
things[1].Parameter = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ ? 1 : 0;
|
|
things[1].UpdateConfiguration();
|
|
}
|
|
if (things.Count >= 3)
|
|
{
|
|
things[2].Move(BuilderPlug.Me.VertexSlopeAssistForm.Vertex3);
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ)
|
|
ChangeVSlopeFlags(things[2], (int)BuilderPlug.Me.VertexSlopeAssistForm.Vertex3.z);
|
|
things[2].Parameter = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ ? 1 : 0;
|
|
things[2].UpdateConfiguration();
|
|
}
|
|
General.Map.ThingsFilter.Update();
|
|
General.Map.Map.Update();
|
|
General.Map.IsChanged = true;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.UpdateForm();
|
|
SetMode(MODE_SELECT);
|
|
}
|
|
}
|
|
|
|
public void CB_Rotate_All_VSlopes(object sender, EventArgs eventArgs)
|
|
{
|
|
int vertices = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag();
|
|
if (vertices == 0 || vertices >= 3)
|
|
{
|
|
Vector3D v1 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex1;
|
|
Vector3D v2 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2;
|
|
Vector3D v3 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex1 = v2;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2 = v3;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3 = v1;
|
|
bool v1z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ;
|
|
bool v2z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ;
|
|
bool v3z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ = v2z;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ = v3z;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ = v1z;
|
|
CB_ValueChanged(sender, eventArgs);
|
|
}
|
|
}
|
|
|
|
public void CB_Flip_All_VSlopes(object sender, EventArgs eventArgs)
|
|
{
|
|
int vertices = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag();
|
|
if (vertices == 0 || vertices >= 3)
|
|
{
|
|
Vector3D v2 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2;
|
|
Vector3D v3 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2 = v3;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3 = v2;
|
|
bool v2z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ;
|
|
bool v3z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ = v3z;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ = v2z;
|
|
CB_ValueChanged(sender, eventArgs);
|
|
}
|
|
}
|
|
|
|
public void CB_Rotate_Height_VSlopes(object sender, EventArgs eventArgs)
|
|
{
|
|
int vertices = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag();
|
|
if (vertices == 0 || vertices >= 3)
|
|
{
|
|
Vector3D v1 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex1;
|
|
Vector3D v2 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2;
|
|
Vector3D v3 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex1 = new Vector3D(v1.x, v1.y, v2.z);
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2 = new Vector3D(v2.x, v2.y, v3.z);
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3 = new Vector3D(v3.x, v3.y, v1.z);
|
|
bool v1z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ;
|
|
bool v2z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ;
|
|
bool v3z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ = v2z;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ = v3z;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ = v1z;
|
|
CB_ValueChanged(sender, eventArgs);
|
|
}
|
|
}
|
|
|
|
public void CB_Flip_Height_VSlopes(object sender, EventArgs eventArgs)
|
|
{
|
|
int vertices = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag();
|
|
if (vertices == 0 || vertices >= 3)
|
|
{
|
|
Vector3D v2 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2;
|
|
Vector3D v3 = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2 = new Vector3D(v2.x, v2.y, v3.z);
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3 = new Vector3D(v3.x, v3.y, v2.z);
|
|
bool v2z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ;
|
|
bool v3z = BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ = v3z;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ = v2z;
|
|
CB_ValueChanged(sender, eventArgs);
|
|
}
|
|
}
|
|
|
|
public void CB_Context_Set(object sender, int action)
|
|
{
|
|
if (selectedLinedef != null && action >= 0)
|
|
{
|
|
if (action != 0)
|
|
{
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
if (things != null)
|
|
{
|
|
if (things.Count == 3)
|
|
{
|
|
// Set tag and action
|
|
CreateUndo();
|
|
selectedLinedef.Tag = BuilderPlug.Me.VertexSlopeAssistForm.TagID;
|
|
selectedLinedef.SetFlag("8192", false);
|
|
selectedLinedef.Action = action;
|
|
General.Interface.DisplayStatus(StatusType.Action, string.Format("Action {0} and Tag {1} set to Linedef {2}.", selectedLinedef.Action, selectedLinedef.Tag, selectedLinedef.Index));
|
|
}
|
|
else if (things.Count == 1)
|
|
{
|
|
// Prepare for indexing groups
|
|
indexedLinedef = selectedLinedef;
|
|
indexedAction = action;
|
|
SetMode(MODE_ASSIGNGROUPS);
|
|
DrawnVertex dv = new DrawnVertex();
|
|
dv.stitch = true;
|
|
dv.stitchline = true;
|
|
dv.pos = things[0].Position;
|
|
points.Add(dv);
|
|
indexedTags.Add(BuilderPlug.Me.VertexSlopeAssistForm.TagID);
|
|
UpdateModeText();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Clear tag and action
|
|
CreateUndo();
|
|
selectedLinedef.Tag = 0;
|
|
selectedLinedef.Action = 0;
|
|
General.Interface.DisplayStatus(StatusType.Action, string.Format("Cleared Action and Tag on Linedef {0}.", selectedLinedef.Index));
|
|
}
|
|
selectedLinedef = null;
|
|
General.Interface.RedrawDisplay();
|
|
}
|
|
if (action == -1)
|
|
{
|
|
// For some reason context menu emit a close before the option that user have choosen o_O
|
|
Timer delaytimer = new Timer();
|
|
delaytimer.Tick += (obj, e) =>
|
|
{
|
|
delaytimer.Stop();
|
|
selectedLinedef = null;
|
|
General.Interface.RedrawDisplay();
|
|
delaytimer.Dispose();
|
|
};
|
|
delaytimer.Interval = 20;
|
|
delaytimer.Start();
|
|
}
|
|
}
|
|
|
|
public void ChangeVSlopeFlags(Thing thing, int flags)
|
|
{
|
|
// SetFlagsValue doesn't set flags properly if thing's flags was properly initialized
|
|
thing.SetFlag("1", (flags & 1) == 1);
|
|
thing.SetFlag("2", (flags & 2) == 2);
|
|
thing.SetFlag("4", (flags & 4) == 4);
|
|
thing.SetFlag("8", (flags & 8) == 8);
|
|
thing.SetFlagsValue(flags);
|
|
}
|
|
|
|
public bool LineCollision(float p1x, float p1y, float p2x, float p2y, float px, float py, float epsilon)
|
|
{
|
|
float l1 = new Line2D(px, py, p1x, p1y).GetLength();
|
|
float l2 = new Line2D(px, py, p2x, p2y).GetLength();
|
|
float ln = new Line2D(p1x, p1y, p2x, p2y).GetLength();
|
|
return l1 + l2 <= ln + epsilon;
|
|
}
|
|
|
|
// http://www.jeffreythompson.org/collision-detection/tri-point.php
|
|
public bool TriangleCollision(float p1x, float p1y, float p2x, float p2y, float p3x, float p3y, float px, float py)
|
|
{
|
|
// get the area of the triangle
|
|
float areaOrig = Math.Abs((p2x - p1x) * (p3y - p1y) - (p3x - p1x) * (p2y - p1y));
|
|
|
|
// get the area of 3 triangles made between the point and the corners of the triangle
|
|
float area1 = Math.Abs((p1x - px) * (p2y - py) - (p2x - px) * (p1y - py));
|
|
float area2 = Math.Abs((p2x - px) * (p3y - py) - (p3x - px) * (p2y - py));
|
|
float area3 = Math.Abs((p3x - px) * (p1y - py) - (p1x - px) * (p3y - py));
|
|
|
|
// if the sum of the three areas equals the original, we're inside the triangle!
|
|
return (area1 + area2 + area3 == areaOrig);
|
|
}
|
|
|
|
private List<Vector2D> GetAffineThingsPosition(bool insideaffine, int vertices)
|
|
{
|
|
List<Vector2D> affined = new List<Vector2D>();
|
|
|
|
// If no need of inside affine just return the rounded points
|
|
if (!insideaffine || vertices != 3)
|
|
{
|
|
for (int i = 0; i < vertices; i++)
|
|
{
|
|
affined.Add(points[i].pos.GetRounded());
|
|
}
|
|
return affined;
|
|
}
|
|
|
|
Vector2D[] corners = new Vector2D[] {
|
|
points[0].pos.GetRounded(),
|
|
points[1].pos.GetRounded(),
|
|
points[2].pos.GetRounded()
|
|
};
|
|
|
|
// Move vertex slopes away from edges or corners.
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
Vector2D corner = new Vector2D(corners[i].x, corners[i].y);
|
|
|
|
// Find best cell... very slow but should get best result
|
|
Vector2D best = new Vector2D(corner);
|
|
float bestlen = 999f;
|
|
Vector2D point = new Vector2D();
|
|
for (int y = 0; y < 256; y++)
|
|
{
|
|
for (int x = 0; x < 256; x++)
|
|
{
|
|
// Point to test
|
|
point = corner + new Vector2D(x - 128, y - 128);
|
|
|
|
if (TriangleCollision(
|
|
corners[0].x, corners[0].y,
|
|
corners[1].x, corners[1].y,
|
|
corners[2].x, corners[2].y,
|
|
point.x, point.y))
|
|
{
|
|
// Good, we are inside the triangle atleast, now avoid the edges...
|
|
if (!LineCollision(
|
|
corners[0].x, corners[0].y,
|
|
corners[1].x, corners[1].y,
|
|
point.x, point.y, 0.001f) &&
|
|
!LineCollision(
|
|
corners[1].x, corners[1].y,
|
|
corners[2].x, corners[2].y,
|
|
point.x, point.y, 0.001f) &&
|
|
!LineCollision(
|
|
corners[2].x, corners[2].y,
|
|
corners[0].x, corners[0].y,
|
|
point.x, point.y, 0.001f))
|
|
{
|
|
// Cool, we test if this one is better then...
|
|
float len = (point - corner).GetLength();
|
|
if (len < bestlen)
|
|
{
|
|
best.x = point.x;
|
|
best.y = point.y;
|
|
bestlen = len;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
affined.Add(best);
|
|
}
|
|
|
|
return affined;
|
|
}
|
|
|
|
private void ApplyVSlopeChanges()
|
|
{
|
|
float[] heights = {
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex1.z,
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2.z,
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3.z
|
|
};
|
|
bool[] absZs = {
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex1AbsZ,
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex2AbsZ,
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Vertex3AbsZ
|
|
};
|
|
CreateUndo();
|
|
if (mode == MODE_NEWTAGGEDTRIANGLE)
|
|
{
|
|
List<Vector2D> newthings = GetAffineThingsPosition(BuilderPlug.Me.VertexSlopeAssistForm.AffineVSlopes, expectedPoints);
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
Thing tp = General.Map.Map.CreateThing();
|
|
if (tp != null)
|
|
{
|
|
General.Settings.ApplyDefaultThingSettings(tp);
|
|
tp.SRB2Type = 750;
|
|
tp.Parameter = 0;
|
|
tp.Rotate(BuilderPlug.Me.VertexSlopeAssistForm.TagID);
|
|
tp.Move(newthings[i].x, newthings[i].y, heights[i]);
|
|
if (absZs[i])
|
|
ChangeVSlopeFlags(tp, (int)heights[i]);
|
|
tp.Parameter = absZs[i] ? 1 : 0;
|
|
tp.UpdateConfiguration();
|
|
}
|
|
}
|
|
DrawnVertex dv = new DrawnVertex();
|
|
dv.stitch = true;
|
|
dv.stitchline = true;
|
|
dv.pos = points[0].pos;
|
|
points.Add(dv);
|
|
if (!Tools.DrawLines(points, true, BuilderPlug.Me.AutoAlignTextureOffsetsOnCreate))
|
|
{
|
|
General.Map.UndoRedo.WithdrawUndo();
|
|
}
|
|
else
|
|
{
|
|
// Snap to map format accuracy
|
|
General.Map.Map.SnapAllToAccuracy();
|
|
|
|
// Clear selection
|
|
General.Map.Map.ClearAllSelected();
|
|
|
|
// Update cached values
|
|
General.Map.Map.Update();
|
|
|
|
// Edit new sectors?
|
|
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
|
if (BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
|
General.Interface.ShowEditSectors(newsectors);
|
|
|
|
// Update the used textures
|
|
General.Map.Data.UpdateUsedTextures();
|
|
|
|
//mxd
|
|
General.Map.Renderer2D.UpdateExtraFloorFlag();
|
|
}
|
|
}
|
|
if (mode == MODE_NEWEMPTYTRIANGLE)
|
|
{
|
|
DrawnVertex dv = new DrawnVertex();
|
|
dv.stitch = true;
|
|
dv.stitchline = true;
|
|
dv.pos = points[0].pos;
|
|
points.Add(dv);
|
|
if (!Tools.DrawLines(points, true, BuilderPlug.Me.AutoAlignTextureOffsetsOnCreate))
|
|
{
|
|
General.Map.UndoRedo.WithdrawUndo();
|
|
}
|
|
|
|
// Snap to map format accuracy
|
|
General.Map.Map.SnapAllToAccuracy();
|
|
|
|
// Clear selection
|
|
General.Map.Map.ClearAllSelected();
|
|
|
|
// Update cached values
|
|
General.Map.Map.Update();
|
|
|
|
// Edit new sectors?
|
|
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
|
if (BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
|
General.Interface.ShowEditSectors(newsectors);
|
|
|
|
// Update the used textures
|
|
General.Map.Data.UpdateUsedTextures();
|
|
|
|
//mxd
|
|
General.Map.Renderer2D.UpdateExtraFloorFlag();
|
|
}
|
|
if (mode == MODE_NEWGROUP)
|
|
{
|
|
List<Vector2D> newthings = GetAffineThingsPosition(BuilderPlug.Me.VertexSlopeAssistForm.AffineVSlopes, expectedPoints);
|
|
for (int i = 0; i < expectedPoints; i++)
|
|
{
|
|
Thing tp = General.Map.Map.CreateThing();
|
|
if (tp != null)
|
|
{
|
|
General.Settings.ApplyDefaultThingSettings(tp);
|
|
tp.SRB2Type = 750;
|
|
tp.Parameter = 0;
|
|
tp.Rotate(BuilderPlug.Me.VertexSlopeAssistForm.TagID);
|
|
tp.Move(newthings[i].x, newthings[i].y, heights[i]);
|
|
if (absZs[i])
|
|
ChangeVSlopeFlags(tp, (int)heights[i]);
|
|
tp.Parameter = absZs[i] ? 1 : 0;
|
|
tp.UpdateConfiguration();
|
|
}
|
|
}
|
|
}
|
|
if (mode == MODE_MODGROUP)
|
|
{
|
|
List<Vector2D> newthings = GetAffineThingsPosition(BuilderPlug.Me.VertexSlopeAssistForm.AffineVSlopes, expectedPoints);
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
for (int i = 0; i < expectedPoints; i++)
|
|
{
|
|
if (things != null && i < things.Count)
|
|
{
|
|
things[i].Move(newthings[i]);
|
|
}
|
|
else
|
|
{
|
|
// Ops! Missing vertex slopes!
|
|
Thing tp = General.Map.Map.CreateThing();
|
|
if (tp != null)
|
|
{
|
|
General.Settings.ApplyDefaultThingSettings(tp);
|
|
tp.SRB2Type = 750;
|
|
tp.Parameter = 0;
|
|
tp.Rotate(BuilderPlug.Me.VertexSlopeAssistForm.TagID);
|
|
tp.Move(newthings[i].x, newthings[i].y, heights[i]);
|
|
if (absZs[i])
|
|
ChangeVSlopeFlags(tp, (int)heights[i]);
|
|
tp.Parameter = absZs[i] ? 1 : 0;
|
|
tp.UpdateConfiguration();
|
|
}
|
|
}
|
|
}
|
|
// Dispose extra vertex slopes
|
|
for (int i = things.Count - 1; i >= expectedPoints; i--)
|
|
{
|
|
things[i].Dispose();
|
|
}
|
|
}
|
|
General.Map.ThingsFilter.Update();
|
|
General.Map.Map.Update();
|
|
General.Map.IsChanged = true;
|
|
SetMode(MODE_SELECT);
|
|
BuilderPlug.Me.VertexSlopeAssistForm.CreateList();
|
|
BuilderPlug.Me.VertexSlopeAssistForm.UpdateForm();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events
|
|
|
|
public override void OnHelp()
|
|
{
|
|
General.ShowHelp("e_vertexslopeassist.html");
|
|
}
|
|
|
|
// Cancelled
|
|
public override void OnCancel()
|
|
{
|
|
// Cancel base class
|
|
base.OnCancel();
|
|
|
|
if (createdUndo)
|
|
{
|
|
General.Map.UndoRedo.WithdrawUndo();
|
|
}
|
|
|
|
// Return to base mode
|
|
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
|
|
}
|
|
|
|
// Mode engages
|
|
public override void OnEngage()
|
|
{
|
|
base.OnEngage();
|
|
renderer.SetPresentation(Presentation.Standard);
|
|
|
|
createdUndo = false;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnDrawNewTaggedTriangle += CB_DrawNewTaggedTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnDrawNewEmptyTriangle += CB_DrawNewEmptyTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupChanged += CB_TagGroup_Changed;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupChoosen += CB_TagGroup_Choosen;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupNewTriangle += CB_TagGroup_NewTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupNewVertex += CB_TagGroup_NewVertex;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupModify += CB_TagGroup_Modify;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupModifyAsTriangle += CB_TagGroup_ModifyAsTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupModifyAsVertex += CB_TagGroup_ModifyAsVertex;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupTag += CB_TagGroup_Tag;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupDelete += CB_TagGroup_Delete;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnValueChanged += CB_ValueChanged;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnRotateAll += CB_Rotate_All_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnFlipAll += CB_Flip_All_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnRotateHeight += CB_Rotate_Height_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnFlipHeight += CB_Flip_Height_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnContextSet += CB_Context_Set;
|
|
selectedLinedef = null;
|
|
|
|
// Show toolbox window
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Show((Form)General.Interface);
|
|
}
|
|
|
|
// Disenagaging
|
|
public override void OnDisengage()
|
|
{
|
|
base.OnDisengage();
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnDrawNewTaggedTriangle -= CB_DrawNewTaggedTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnDrawNewEmptyTriangle -= CB_DrawNewEmptyTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupChanged -= CB_TagGroup_Changed;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupChoosen -= CB_TagGroup_Choosen;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupNewTriangle -= CB_TagGroup_NewTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupNewVertex -= CB_TagGroup_NewVertex;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupModify -= CB_TagGroup_Modify;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupModifyAsTriangle -= CB_TagGroup_ModifyAsTriangle;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupModifyAsVertex -= CB_TagGroup_ModifyAsVertex;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupTag -= CB_TagGroup_Tag;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnGroupDelete -= CB_TagGroup_Delete;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnValueChanged -= CB_ValueChanged;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnRotateAll -= CB_Rotate_All_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnFlipAll -= CB_Flip_All_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnRotateHeight -= CB_Rotate_Height_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnFlipHeight -= CB_Flip_Height_VSlopes;
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OnContextSet -= CB_Context_Set;
|
|
|
|
// Hide toolbox window
|
|
BuilderPlug.Me.VertexSlopeAssistForm.Hide();
|
|
}
|
|
|
|
// This applies the curves and returns to the base mode
|
|
public override void OnAccept()
|
|
{
|
|
// Return to base mode
|
|
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
|
|
}
|
|
|
|
// Redrawing display
|
|
public override void OnRedrawDisplay()
|
|
{
|
|
renderer.RedrawSurface();
|
|
float vsize = (renderer.VertexSize + 1.0f) / renderer.Scale;
|
|
|
|
snaptocardinaldirection = General.Interface.ShiftState && General.Interface.AltState; //mxd
|
|
snaptogrid = (snaptocardinaldirection || General.Interface.ShiftState ^ General.Interface.SnapToGrid);
|
|
snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;
|
|
|
|
DrawnVertex curp = DrawGeometryMode.GetCurrentPosition(mousemappos, snaptonearest, snaptogrid, snaptocardinaldirection, false, renderer, points);
|
|
if (curp.pos.IsFinite()) curmousepos = curp.pos;
|
|
|
|
// Get selected tag things
|
|
List<Thing> things = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList();
|
|
bool tagvalid = (things != null && things.Count == 3);
|
|
PixelColor color = tagvalid ? General.Colors.Highlight : General.Colors.Selection;
|
|
|
|
// Render lines
|
|
if(renderer.StartPlotter(true))
|
|
{
|
|
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
|
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
|
renderer.Finish();
|
|
}
|
|
|
|
// Render things
|
|
if(renderer.StartThings(true))
|
|
{
|
|
renderer.RenderThingSet(General.Map.Map.Things, Presentation.THINGS_ALPHA);
|
|
renderer.RenderNiGHTSPath();
|
|
renderer.Finish();
|
|
}
|
|
|
|
// Render overlay
|
|
if(renderer.StartOverlay(true))
|
|
{
|
|
if (mode == MODE_SELECT && things != null)
|
|
{
|
|
if (things.Count >= 2)
|
|
{
|
|
for (int i = 1; i < things.Count; i++)
|
|
renderer.RenderLine(things[i - 1].Position, things[i].Position, LINE_THICKNESS, color, true);
|
|
renderer.RenderLine(things[things.Count - 1].Position, things[0].Position, LINE_THICKNESS, color, true);
|
|
if (tagvalid)
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
Thing t = things[i];
|
|
TextLabel tl = vertexnames[i];
|
|
tl.Location = things[i].Position;
|
|
tl.Text = (i + 1).ToString();
|
|
renderer.RenderRectangleFilled(new RectangleF(t.Position.x - vsize, t.Position.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
|
renderer.RenderText(tl);
|
|
}
|
|
}
|
|
}
|
|
else if (things.Count == 1)
|
|
{
|
|
Thing t = things[0];
|
|
TextLabel tl = vertexnames[0];
|
|
tl.Location = things[0].Position;
|
|
tl.Text = "1";
|
|
renderer.RenderRectangleFilled(new RectangleF(t.Position.x - vsize, t.Position.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
|
renderer.RenderText(tl);
|
|
}
|
|
}
|
|
|
|
if (mode == MODE_ASSIGNGROUPS)
|
|
{
|
|
for (int i = 1; i < points.Count; i++)
|
|
renderer.RenderLine(points[i - 1].pos, points[i].pos, LINE_THICKNESS, color, true);
|
|
if (points.Count > 0) {
|
|
if (things != null && things.Count == 1)
|
|
{
|
|
renderer.RenderLine(points[points.Count - 1].pos, things[0].Position, LINE_THICKNESS, color, true);
|
|
renderer.RenderLine(things[0].Position, points[0].pos, LINE_THICKNESS, color, true);
|
|
renderer.RenderRectangleFilled(new RectangleF(things[0].Position.x - vsize, things[0].Position.y - vsize, vsize * 4.0f, vsize * 4.0f), color, true);
|
|
}
|
|
}
|
|
for (int i = 0; i < points.Count; i++)
|
|
{
|
|
if (i >= 3) break;
|
|
Vector2D v = points[i].pos;
|
|
TextLabel tl = vertexnames[i];
|
|
tl.Location = points[i].pos;
|
|
tl.Text = (i + 1).ToString();
|
|
renderer.RenderRectangleFilled(new RectangleF(v.x - vsize, v.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
|
renderer.RenderText(tl);
|
|
}
|
|
}
|
|
|
|
if (mode >= MODE_NEWPOINTS)
|
|
{
|
|
for (int i = 1; i < points.Count; i++)
|
|
renderer.RenderLine(points[i - 1].pos, points[i].pos, LINE_THICKNESS, color, true);
|
|
if (points.Count > 0)
|
|
{
|
|
renderer.RenderLine(points[points.Count - 1].pos, curmousepos, LINE_THICKNESS, color, true);
|
|
renderer.RenderLine(curmousepos, points[0].pos, LINE_THICKNESS, color, true);
|
|
}
|
|
for (int i = 0; i < points.Count; i++)
|
|
{
|
|
if (i >= 3) break;
|
|
Vector2D v = points[i].pos;
|
|
TextLabel tl = vertexnames[i];
|
|
tl.Location = points[i].pos;
|
|
tl.Text = (i + 1).ToString();
|
|
renderer.RenderRectangleFilled(new RectangleF(v.x - vsize, v.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
|
renderer.RenderText(tl);
|
|
}
|
|
renderer.RenderRectangleFilled(new RectangleF(curmousepos.x - vsize, curmousepos.y - vsize, vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine, true);
|
|
}
|
|
else
|
|
{
|
|
foreach (int tag in overgroups)
|
|
{
|
|
PixelColor overcolor = General.Colors.Indication.WithAlpha(128);
|
|
List<Thing> overthings = BuilderPlug.Me.VertexSlopeAssistForm.GetThingsList(tag);
|
|
if (overthings.Count >= 2)
|
|
{
|
|
for (int i = 1; i < overthings.Count; i++)
|
|
renderer.RenderLine(overthings[i - 1].Position, overthings[i].Position, OVER_THICKNESS, overcolor, true);
|
|
renderer.RenderLine(overthings[overthings.Count - 1].Position, overthings[0].Position, OVER_THICKNESS, overcolor, true);
|
|
}
|
|
else
|
|
{
|
|
renderer.RenderThing(overthings[0], overcolor, Presentation.THINGS_ALPHA);
|
|
renderer.RenderRectangleFilled(new RectangleF(overthings[0].Position.x - vsize, overthings[0].Position.y - vsize, vsize * 2.0f, vsize * 2.0f), overcolor, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (selectedLinedef != null)
|
|
renderer.RenderLine(selectedLinedef.Start.Position, selectedLinedef.End.Position, LINE_THICKNESS, General.Colors.Linedefs, true);
|
|
|
|
if (indexedLinedef != null)
|
|
renderer.RenderLine(indexedLinedef.Start.Position, indexedLinedef.End.Position, LINE_THICKNESS, General.Colors.Linedefs, true);
|
|
|
|
renderer.Finish();
|
|
}
|
|
|
|
renderer.Present();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events (Mouse & Keyboard)
|
|
|
|
// Mouse moving
|
|
public override void OnMouseMove(MouseEventArgs e)
|
|
{
|
|
base.OnMouseMove(e);
|
|
if (panning) return; //mxd. Skip all this jazz while panning
|
|
|
|
if (mode < MODE_NEWPOINTS)
|
|
{
|
|
overgroups.Clear();
|
|
int newOverTagID = -1;
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.GetGroupsAt(mousemappos, ref overgroups, true, true) > 0)
|
|
{
|
|
newOverTagID = overgroups[overgroupoffset % overgroups.Count];
|
|
}
|
|
if (newOverTagID != overTagID)
|
|
{
|
|
overTagID = newOverTagID;
|
|
UpdateModeText();
|
|
}
|
|
}
|
|
|
|
General.Interface.RedrawDisplay();
|
|
}
|
|
|
|
// Mouse press
|
|
public override void OnMouseDown(MouseEventArgs e)
|
|
{
|
|
base.OnMouseDown(e);
|
|
if (panning) return;
|
|
|
|
if (mode == MODE_SELECT)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
overgroups.Clear();
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.GetGroupsAt(mousemappos, ref overgroups, true, true) > 0)
|
|
{
|
|
BuilderPlug.Me.VertexSlopeAssistForm.TagID = overgroups[overgroupoffset % overgroups.Count];
|
|
overgroupoffset++;
|
|
}
|
|
}
|
|
if (e.Button == MouseButtons.Right)
|
|
{
|
|
int vertices = BuilderPlug.Me.VertexSlopeAssistForm.VerticesInTag();
|
|
Linedef l = General.Map.Map.NearestLinedefRange(mousemappos, BuilderPlug.Me.HighlightRange / renderer.Scale);
|
|
selectedLinedef = l;
|
|
if (l != null)
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OpenContextLinedefMenu(Cursor.Position.X, Cursor.Position.Y, vertices == 1 || vertices == 3);
|
|
else
|
|
BuilderPlug.Me.VertexSlopeAssistForm.OpenContextGroupMenu(Cursor.Position.X, Cursor.Position.Y, vertices > 0);
|
|
General.Interface.RedrawDisplay();
|
|
}
|
|
UpdateModeText();
|
|
}
|
|
else if (mode == MODE_ASSIGNGROUPS)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
overgroups.Clear();
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.GetGroupsAt(mousemappos, ref overgroups, true, false) > 0)
|
|
{
|
|
BuilderPlug.Me.VertexSlopeAssistForm.TagID = overgroups[overgroupoffset % overgroups.Count];
|
|
overgroupoffset++;
|
|
}
|
|
}
|
|
if (e.Button == MouseButtons.Right)
|
|
{
|
|
SetMode(MODE_SELECT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
DrawnVertex dv = new DrawnVertex();
|
|
dv.stitch = true;
|
|
dv.stitchline = true;
|
|
dv.pos = curmousepos;
|
|
points.Add(dv);
|
|
if (points.Count == expectedPoints) ApplyVSlopeChanges();
|
|
General.Interface.RedrawDisplay();
|
|
UpdateModeText();
|
|
}
|
|
if (e.Button == MouseButtons.Right)
|
|
{
|
|
SetMode(MODE_SELECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
// When a key is released
|
|
public override void OnKeyUp(KeyEventArgs e)
|
|
{
|
|
base.OnKeyUp(e);
|
|
if ((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
|
|
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge)) ||
|
|
(snaptocardinaldirection != (General.Interface.AltState && General.Interface.ShiftState))) General.Interface.RedrawDisplay();
|
|
}
|
|
|
|
// When a key is pressed
|
|
public override void OnKeyDown(KeyEventArgs e)
|
|
{
|
|
base.OnKeyDown(e);
|
|
if ((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
|
|
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge)) ||
|
|
(snaptocardinaldirection != (General.Interface.AltState && General.Interface.ShiftState))) General.Interface.RedrawDisplay();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Actions
|
|
|
|
// Remove a point
|
|
[BeginAction("removepoint")]
|
|
public void RemovePoint()
|
|
{
|
|
if (points.Count > 0) points.RemoveAt(points.Count - 1);
|
|
if (indexedTags.Count > 0) indexedTags.RemoveAt(indexedTags.Count - 1);
|
|
UpdateModeText();
|
|
General.Interface.RedrawDisplay();
|
|
}
|
|
|
|
// Increase tag number
|
|
[BeginAction("increasebevel")]
|
|
public void IncreaseBevel()
|
|
{
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.TagID < General.Map.FormatInterface.MaxTag)
|
|
BuilderPlug.Me.VertexSlopeAssistForm.TagID++;
|
|
}
|
|
[BeginAction("increasesubdivlevel")]
|
|
public void IncreaseSubdivLevel()
|
|
{
|
|
IncreaseBevel();
|
|
}
|
|
|
|
// Decrease tag number
|
|
[BeginAction("decreasebevel")]
|
|
public void DecreaseBevel()
|
|
{
|
|
if (BuilderPlug.Me.VertexSlopeAssistForm.TagID > 0)
|
|
BuilderPlug.Me.VertexSlopeAssistForm.TagID--;
|
|
}
|
|
[BeginAction("decreasesubdivlevel")]
|
|
public void DecreaseSubdivLevel()
|
|
{
|
|
DecreaseBevel();
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|