Added functionality to duplicate 3D floor control sectors of selected sectors and paste selected sectors with the new control sectors assigned

This commit is contained in:
biwa 2020-06-13 00:24:24 +02:00
parent a6dbd2c258
commit 4fbcc11418
6 changed files with 150 additions and 9 deletions

View file

@ -225,7 +225,7 @@ namespace CodeImp.DoomBuilder.Editing
}
// This performs the copy. Returns false when copy was cancelled.
private static bool DoCopySelection(string desc)
public static bool DoCopySelection(string desc)
{
// Check if possible to copy/paste
if(General.Editing.Mode.Attributes.AllowCopyPaste)
@ -285,7 +285,7 @@ namespace CodeImp.DoomBuilder.Editing
}
// This performs the paste. Returns false when paste was cancelled.
private static void DoPasteSelection(PasteOptions options)
public static void DoPasteSelection(PasteOptions options)
{
// Check if possible to copy/paste
if(General.Editing.Mode.Attributes.AllowCopyPaste)

View file

@ -155,4 +155,14 @@ select3dfloorcontrolsector
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
duplicate3dfloorgeometry
{
title = "Duplicate and paste geometry";
category = "threedfloorplugin";
description = "Duplicates and pastes selected geometry and its 3D floors";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}

View file

@ -218,6 +218,13 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
}
public bool CreateGeometry(List<int> tagblacklist)
{
int newtag;
return CreateGeometry(tagblacklist, false, out newtag);
}
public bool CreateGeometry(List<int> tagblacklist, bool forcenewtag, out int newtag)
{
List<DrawnVertex> drawnvertices = new List<DrawnVertex>();
List<Vertex> vertices = new List<Vertex>();
@ -225,6 +232,8 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
Vector3D slopebottomthingpos = new Vector3D(0, 0, 0);
Line2D slopeline = new Line2D(0, 0, 0, 0);
newtag = -1;
drawnvertices = BuilderPlug.Me.ControlSectorArea.GetNewControlSectorVertices();
if (Tools.DrawLines(drawnvertices) == false)
@ -257,9 +266,9 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
// With multiple tag support in UDMF only one tag is needed, so bind it right away
if (General.Map.UDMF == true)
{
if (isnew)
if (isnew || forcenewtag)
{
udmftag = BuilderPlug.Me.ControlSectorArea.GetNewSectorTag(tagblacklist);
newtag = udmftag = BuilderPlug.Me.ControlSectorArea.GetNewSectorTag(tagblacklist);
tagblacklist.Add(udmftag);
}

View file

@ -40,6 +40,7 @@ using CodeImp.DoomBuilder.Types;
using CodeImp.DoomBuilder.BuilderModes;
using CodeImp.DoomBuilder.BuilderModes.Interface;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Config;
// using CodeImp.DoomBuilder.GZBuilder.Geometry;
#endregion
@ -1176,7 +1177,29 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
SelectSector(highlighted, true, true);
}
return base.OnCopyBegin();
General.Map.Map.MarkAllSelectedGeometry(true, false, true, true, false);
return General.Map.Map.GetMarkedSectors(true).Count > 0;
}
public override bool OnPasteBegin(PasteOptions options)
{
return true;
}
// This is called when something was pasted.
public override void OnPasteEnd(PasteOptions options)
{
General.Map.Map.ClearAllSelected();
General.Map.Map.SelectMarkedGeometry(true, true);
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
// Switch to EditSelectionMode
EditSelectionMode editmode = new EditSelectionMode();
editmode.Pasting = true;
editmode.UpdateSlopes = true;
editmode.PasteOptions = options;
General.Editing.ChangeMode(editmode);
}
// When undo is used
@ -1460,6 +1483,98 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
General.Interface.DisplayStatus(StatusType.Info, String.Format("3D floor control sector selected. {0} sector(s) selected.", General.Map.Map.GetSelectedSectors(true).Count));
}
[BeginAction("duplicate3dfloorgeometry")]
public void Duplicate3DFloorGeometry()
{
List<Sector> selectedsectors;
List<ThreeDFloor> duplicatethreedfloors;
Dictionary<int, int> tagreplacements = new Dictionary<int, int>();
List<int> tagblacklist = new List<int>();
// No selection made? But we have a highlight!
if ((General.Map.Map.GetSelectedSectors(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
SelectSector(highlighted, true, true);
}
selectedsectors = General.Map.Map.GetSelectedSectors(true).ToList();
// Get the 3D floors we need to duplicate
duplicatethreedfloors = BuilderPlug.GetThreeDFloors(selectedsectors);
// Create a list of all tags used by the control sectors. This is necessary so that
// tags that will be assigned to not yet existing geometry will not be used
foreach (ThreeDFloor tdf in threedfloors)
foreach (int tag in tdf.Tags)
if (!tagblacklist.Contains(tag))
tagblacklist.Add(tag);
if (duplicatethreedfloors.Count == 0)
return;
General.Map.UndoRedo.CreateUndo("Duplicate 3D floor control sectors before pasting");
// Create a new control sector for each 3D floor that needs to be duplicated. Force it to generate
// a new tag, and store the old (current) and new tag
foreach (ThreeDFloor tdf in duplicatethreedfloors)
{
int newtag;
int oldtag = tdf.UDMFTag;
if(tdf.CreateGeometry(new List<int>(), true, out newtag))
{
tagreplacements[oldtag] = newtag;
}
else
{
General.Interface.DisplayStatus(StatusType.Warning, "Could not create 3D floor control sector geometry");
General.Map.UndoRedo.WithdrawUndo();
return;
}
}
// Replace the old tags of the selected sectors with the new tags
foreach (Sector s in selectedsectors)
{
foreach (int oldtag in tagreplacements.Keys)
{
if (s.Tags.Contains(oldtag))
{
s.Tags.Remove(oldtag);
s.Tags.Add(tagreplacements[oldtag]);
}
}
}
// Store the selected sectors (with the new tags) in the clipboard
if(!CopyPasteManager.DoCopySelection("3D floor test copy!"))
{
General.Interface.DisplayStatus(StatusType.Warning, "Something failed trying to copy the selection");
General.Map.UndoRedo.WithdrawUndo();
return;
}
// Now set the tags of the selected sectors back to the old tags
foreach(Sector s in selectedsectors)
{
foreach(int oldtag in tagreplacements.Keys)
{
if(s.Tags.Contains(tagreplacements[oldtag]))
{
s.Tags.Remove(tagreplacements[oldtag]);
s.Tags.Add(oldtag);
}
}
}
// For this operation we have to make sure the tags and actions are not changed, no matter
// what the user preference is, otherwise it will not work
PasteOptions po = new PasteOptions() { ChangeTags = 0, RemoveActions = false };
CopyPasteManager.DoPasteSelection(po);
}
#endregion
}
}

View file

@ -100,6 +100,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Switch to EditSelectionMode
EditSelectionMode editmode = new EditSelectionMode();
editmode.Pasting = true;
editmode.UpdateSlopes = false;
editmode.PasteOptions = options;
General.Editing.ChangeMode(editmode);
}

View file

@ -212,7 +212,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Options
private bool snaptogrid; // SHIFT to toggle
private bool snaptonearest; // CTRL to enable
private bool snaptonearest; // CTRL to enable
private bool updateslopes;
#endregion
@ -222,6 +224,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
public bool Pasting { get { return pasting; } set { pasting = value; } }
public PasteOptions PasteOptions { get { return pasteoptions; } set { pasteoptions = value.Copy(); } }
public bool UpdateSlopes { get { return updateslopes; } set { updateslopes = value; } }
//mxd. Modification
internal bool UsePrecisePosition { get { return usepreciseposition; } set { usepreciseposition = value; } }
@ -246,6 +250,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
// Initialize
mode = ModifyMode.None;
updateslopes = true;
}
//mxd. Another constructor. Used indirectly from ImportObjAsTerrainMode.OnAccept.
@ -254,6 +259,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Initialize
this.pasting = pasting;
this.mode = ModifyMode.None;
this.updateslopes = true;
}
// Disposer
@ -1591,7 +1597,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Create cache of 3D floor control sectors that reference the selected sectors. Only do it if not pasting, since the slopes
// will only be updated when not pasting, since it'd otherwise screw up the original slopes
if (!pasting)
if (updateslopes)
{
foreach (Linedef ld in General.Map.Map.Linedefs)
{
@ -1646,7 +1652,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Update the slopes of 3D floor control sectors. Only do it if not pasting, since it'd otherwise screw up the original slopes
if (!pasting && controlsectors.ContainsKey(s))
if (updateslopes && controlsectors.ContainsKey(s))
{
foreach (Sector cs in controlsectors[s])
{
@ -1699,7 +1705,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Update the slopes of 3D floor control sectors. Only do it if not pasting, since it'd otherwise screw up the original slopes
if (!pasting && controlsectors.ContainsKey(s))
if (updateslopes && controlsectors.ContainsKey(s))
{
foreach (Sector cs in controlsectors[s])
{