Merge branch '2dflatalign' into 'master'

Display flat alignment in classic (2D) modes.

Closes #1

See merge request STJr/ZoneBuilder!1
This commit is contained in:
sphere 2021-03-13 17:22:23 -05:00
commit f60aa6c42f
6 changed files with 243 additions and 7 deletions

View file

@ -105,6 +105,9 @@ namespace CodeImp.DoomBuilder.Editing
// Disposing
private bool isdisposed;
// Keep track of changed linedef tags for hacky flat alignment
private static List<int> linedeftags = new List<int>();
#endregion
#region ================== Properties
@ -713,7 +716,22 @@ namespace CodeImp.DoomBuilder.Editing
General.Map.Data.UpdateUsedTextures();
General.MainWindow.RefreshInfo();
//General.MainWindow.RedrawDisplay();
// (Re)set hacky flat alignment
foreach (Linedef l in General.Map.Map.Linedefs)
if (l.Marked && (l.IsFlatAlignment || l.Action == 0))
{
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
linedeftags.Add(l.Tag);
}
foreach (Sector s in General.Map.Map.Sectors)
if (linedeftags.Contains(s.Tag) || s.Marked)
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
// Map changed!
General.Map.IsChanged = true;
@ -857,7 +875,22 @@ namespace CodeImp.DoomBuilder.Editing
General.Map.Data.UpdateUsedTextures();
General.MainWindow.RefreshInfo();
//General.MainWindow.RedrawDisplay();
// (Re)set hacky flat alignment
foreach (Linedef l in General.Map.Map.Linedefs)
if (l.Marked && (l.IsFlatAlignment || l.Action == 0))
{
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
linedeftags.Add(l.Tag);
}
foreach (Sector s in General.Map.Map.Sectors)
if (linedeftags.Contains(s.Tag) || s.Marked)
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
// Map changed!
General.Map.IsChanged = true;
@ -1010,6 +1043,7 @@ namespace CodeImp.DoomBuilder.Editing
{
int index; ds.rInt(out index);
Linedef l = General.Map.Map.GetLinedefByIndex(index);
linedeftags.Add(l.Tag);
l.ReadWrite(ds);
l.Marked = true;
}

View file

@ -401,7 +401,20 @@ namespace CodeImp.DoomBuilder.Windows
}
MakeUndo(); //mxd
// Get tagged sectors and old tag (hack for flat alignment)
int oldtag = 0;
Dictionary<int, List<Sector>> sectortags = new Dictionary<int, List<Sector>>();
foreach (Sector s in General.Map.Map.Sectors)
{
foreach (int tag in s.Tags)
{
if (tag == 0) continue;
if (!sectortags.ContainsKey(tag)) sectortags[tag] = new List<Sector>();
sectortags[tag].Add(s);
}
}
// Go for all the lines
int tagoffset = 0; //mxd
foreach(Linedef l in lines)
@ -409,8 +422,9 @@ namespace CodeImp.DoomBuilder.Windows
// Apply chosen activation flag
if(activation.SelectedIndex > -1)
l.Activate = (activation.SelectedItem as LinedefActivateInfo).Index;
// Action/tags
oldtag = l.Tag;
l.Tag = General.Clamp(tagSelector.GetSmartTag(l.Tag, tagoffset++), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag); //mxd
if(!action.Empty) l.Action = action.Value;
@ -466,11 +480,31 @@ namespace CodeImp.DoomBuilder.Windows
}
}
}
// (Re)set hacky flat alignment
if (sectortags.ContainsKey(l.Tag))
{
foreach (Sector s in sectortags[l.Tag])
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
}
if (sectortags.ContainsKey(oldtag) && oldtag != l.Tag)
{
foreach (Sector s in sectortags[oldtag])
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
}
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
// Update the used textures
General.Map.Data.UpdateUsedTextures();
// Done
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty); //mxd
@ -527,8 +561,25 @@ namespace CodeImp.DoomBuilder.Windows
LinedefActionInfo li = General.Map.Config.GetLinedefActionInfo(action.Value);
IDictionary<string, string> newFlags = (li == null || li.Flags.Count == 0) ? General.Map.Config.LinedefFlags : li.Flags;
flags.UpdateCheckboxes(newFlags);
}
}
// (Re)set hacky flat alignment
foreach (Linedef l in lines)
{
if (l.Tag == 0)
{
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
else
foreach (Sector s in General.Map.Map.Sectors)
if (s.Tag == l.Tag)
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
}
}
}
// Browse Action clicked
private void browseaction_Click(object sender, EventArgs e)
@ -574,6 +625,23 @@ namespace CodeImp.DoomBuilder.Windows
l.SetFlag(c.Tag.ToString(), false);
}
// (Re)set hacky flat alignment
if (l.IsFlatAlignment)
{
if (l.Tag == 0)
{
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
else
foreach (Sector s in General.Map.Map.Sectors)
if (s.Tag == l.Tag)
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
}
i++;
}
@ -787,6 +855,23 @@ namespace CodeImp.DoomBuilder.Windows
}
}
// (Re)set hacky flat alignment
if (l.IsFlatAlignment && l.IsFlagSet("8192"))
{
if (l.Tag == 0)
{
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
else
foreach (Sector s in General.Map.Map.Sectors)
if (s.Tag == l.Tag)
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
}
i++;
}

View file

@ -324,6 +324,10 @@ namespace CodeImp.DoomBuilder.Windows
// Action
s.Tag = General.Clamp(tagSelector.GetSmartTag(s.Tag, tagoffset++), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag); //mxd
// Update hacky flat alignment
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
// Done

View file

@ -517,6 +517,30 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
else
{
// Update hacky flat alignment
foreach (Linedef l in General.Map.Map.LinedefsFromMarkedVertices(true, true, true))
{
if (l.IsFlatAlignment)
{
if (l.Tag == 0)
{
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
else
{
foreach (Sector s in General.Map.Map.Sectors)
if (s.Tag == l.Tag)
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
}
}
}
}
// Update cached values
General.Map.Map.Update();

View file

@ -935,14 +935,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(sel != null)
{
List<int> linedeftags = new List<int>();
// Apply properties to selection
string rest = (sel.Count == 1 ? "a single linedef" : sel.Count + " linedefs"); //mxd
General.Map.UndoRedo.CreateUndo("Paste properties to " + rest);
foreach(Linedef l in sel)
{
if (l.Tag != 0) linedeftags.Add(l.Tag);
BuilderPlug.Me.CopiedLinedefProps.Apply(l, false);
l.UpdateCache();
if (l.IsFlatAlignment && l.Tag != 0) linedeftags.Add(l.Tag);
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
foreach (Sector s in General.Map.Map.Sectors)
if (linedeftags.Contains(s.Tag))
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
General.Interface.DisplayStatus(StatusType.Action, "Pasted properties to " + rest + ".");
// Update and redraw
@ -980,14 +991,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
PastePropertiesOptionsForm form = new PastePropertiesOptionsForm();
if(form.Setup(MapElementType.LINEDEF) && form.ShowDialog(General.Interface) == DialogResult.OK)
{
List<int> linedeftags = new List<int>();
// Apply properties to selection
string rest = (sel.Count == 1 ? "a single linedef" : sel.Count + " linedefs");
General.Map.UndoRedo.CreateUndo("Paste properties with options to " + rest);
foreach(Linedef l in sel)
{
if (l.Tag != 0) linedeftags.Add(l.Tag);
BuilderPlug.Me.CopiedLinedefProps.Apply(l, true);
l.UpdateCache();
if (l.IsFlatAlignment && l.Tag != 0) linedeftags.Add(l.Tag);
l.Front.Sector.UpdateFloorSurface();
l.Front.Sector.UpdateCeilingSurface();
}
foreach (Sector s in General.Map.Map.Sectors)
if (linedeftags.Contains(s.Tag))
{
s.UpdateFloorSurface();
s.UpdateCeilingSurface();
}
General.Interface.DisplayStatus(StatusType.Action, "Pasted properties with options to " + rest + ".");
// Update and redraw

View file

@ -323,6 +323,27 @@ namespace CodeImp.DoomBuilder.BuilderModes
copiedsectorprops = null;
}
// Full credit to Justburner for the actual math
private void HandleSurfaceFlatAlignment(Linedef l, Sector s, FlatVertex[] vertices, ImageData img)
{
bool useoffsets = l.IsFlagSet("8192");
float xoffset = useoffsets ? l.Front.OffsetX : -l.Start.Position.x;
float yoffset = useoffsets ? -l.Front.OffsetY : -l.Start.Position.y;
float rotation = General.ClampAngle(90f - l.Angle * Angle2D.PIDEG);
// Affine offset, this got me a few headaches of why both rotation and offset didn't worked at same time
float rotationrad = rotation / Angle2D.PIDEG;
float cos = (float)Math.Cos(rotationrad);
float sin = (float)Math.Sin(rotationrad);
float rx = cos * xoffset - sin * yoffset;
float ry = sin * xoffset + cos * yoffset;
xoffset = rx;
yoffset = -ry;
Vector2D offset = new Vector2D(xoffset, yoffset);
SetupSurfaceVertices(vertices, s, img, offset, new Vector2D(1.0f, 1.0f), rotation, -1, 0, false);
}
#endregion
#region ================== Events
@ -375,6 +396,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
vertices[i].u = vertices[i].u * sw;
vertices[i].v = -vertices[i].v * sh;
}
bool sidealignment = false;
foreach (Sidedef side in s.Sidedefs)
{
if (side.Line.IsFlatAlignment && !side.Line.IsFlagSet("2048") && side.Line.Tag == 0 && side.Line.Front.Sector == s)
{
sidealignment = true;
HandleSurfaceFlatAlignment(side.Line, s, vertices, img);
}
}
if (!sidealignment)
{
if (s.Tag != 0)
{
foreach (Linedef l in General.Map.Map.Linedefs)
if (l.IsFlatAlignment && !l.IsFlagSet("2048") && (l.Tag == s.Tag))
HandleSurfaceFlatAlignment(l, s, vertices, img);
}
else
SetupSurfaceVertices(vertices, s, img, new Vector2D(0.0f, 0.0f), new Vector2D(1.0f, 1.0f), 0.0f, -1, 0, false);
}
}
}
}
@ -427,6 +471,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
vertices[i].u = vertices[i].u * sw;
vertices[i].v = -vertices[i].v * sh;
}
bool sidealignment = false;
foreach (Sidedef side in s.Sidedefs)
{
if (side.Line.IsFlatAlignment && !side.Line.IsFlagSet("4096") && side.Line.Tag == 0 && side.Line.Front.Sector == s)
{
sidealignment = true;
HandleSurfaceFlatAlignment(side.Line, s, vertices, img);
}
}
if (!sidealignment)
{
if (s.Tag != 0)
{
foreach (Linedef l in General.Map.Map.Linedefs)
if (l.IsFlatAlignment && !l.IsFlagSet("4096") && (l.Tag == s.Tag))
HandleSurfaceFlatAlignment(l, s, vertices, img);
}
else
SetupSurfaceVertices(vertices, s, img, new Vector2D(0.0f, 0.0f), new Vector2D(1.0f, 1.0f), 0.0f, -1, 0, false);
}
}
}
}