- Some refactoring

- Added action to slope selected floors/ceilings between selected slope handles (default key: Ctrl-F)
- Added Shift-W as default key to toggle visual slope picking
This commit is contained in:
biwa 2020-02-23 12:44:59 +01:00
parent 915d83c92a
commit 37e8154556
3 changed files with 124 additions and 45 deletions

View file

@ -1414,4 +1414,16 @@ togglevisualslopepicking
allowkeys = true;
allowmouse = true;
allowscroll = false;
default = 65623; // Shift-W
}
slopebetweenhandles
{
title = "Slope Between Handles";
category = "visual";
description = "Slopes the selected floors and ceilings between the selected slope handles.";
allowkeys = true;
allowmouse = true;
allowscroll = false;
default = 131142; // Ctrl-F
}

View file

@ -2080,6 +2080,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
return verts;
}
// This returns all selected slope handles, no doubles
private List<VisualSidedefSlope> GetSelectedSlopeHandles()
{
HashSet<VisualSidedefSlope> added = new HashSet<VisualSidedefSlope>();
List<VisualSidedefSlope> handles = new List<VisualSidedefSlope>();
foreach(IVisualEventReceiver i in selectedobjects)
{
VisualSidedefSlope handle = i as VisualSidedefSlope;
if(handle != null && !added.Contains(handle))
{
handles.Add(handle);
added.Add(handle);
}
}
// Add highlight?
if((selectedobjects.Count == 0) && (target.picked is VisualSidedefSlope))
{
VisualSidedefSlope handle = (VisualSidedefSlope)target.picked;
if (!added.Contains(handle)) handles.Add(handle);
}
return handles;
}
// This returns the IVisualEventReceiver on which the action must be performed
private IVisualEventReceiver GetTargetEventReceiver(bool targetonly)
@ -3980,6 +4006,43 @@ namespace CodeImp.DoomBuilder.BuilderModes
pickingmode = PickingMode.Default;
}
[BeginAction("slopebetweenhandles")]
public void SlopeBetweenHandles()
{
List<VisualSidedefSlope> handles = GetSelectedSlopeHandles();
if(handles.Count != 2)
{
General.Interface.DisplayStatus(StatusType.Warning, "You need to have exactly two slope handles selected to slope between them.");
return;
}
List<IVisualEventReceiver> selectedsectors = GetSelectedObjects(true, false, false, false, false);
if(selectedsectors.Count == 0)
{
General.Interface.DisplayStatus(StatusType.Warning, "You need to select floors or ceilings to slope between slope handles.");
return;
}
General.Map.UndoRedo.CreateUndo("Slope between slope handles");
// Create the new plane
Vector3D p1 = new Vector3D(handles[0].Sidedef.Line.Start.Position, handles[0].Level.plane.GetZ(handles[0].Sidedef.Line.Start.Position));
Vector3D p2 = new Vector3D(handles[0].Sidedef.Line.End.Position, handles[0].Level.plane.GetZ(handles[0].Sidedef.Line.End.Position));
Vector3D p3 = new Vector3D(handles[1].Sidedef.Line.Line.GetCoordinatesAt(0.5f), handles[1].Level.plane.GetZ(handles[1].Sidedef.Line.Line.GetCoordinatesAt(0.5f)));
Plane plane = new Plane(p1, p2, p3, true);
// Apply slope
foreach (BaseVisualGeometrySector bvgs in selectedsectors)
{
VisualSidedefSlope.ApplySlope(bvgs.Level, plane, this);
bvgs.Sector.UpdateSectorGeometry(true);
}
UpdateChangedObjects();
General.Interface.DisplayStatus(StatusType.Action, "Sloped between slope handles.");
}
#endregion
#region ================== Texture Alignment

View file

@ -213,6 +213,54 @@ namespace CodeImp.DoomBuilder.VisualModes
return handle;
}
public static void ApplySlope(SectorLevel level, Plane plane, BaseVisualMode mode)
{
bool applytoceiling = false;
Vector2D center = new Vector2D(level.sector.BBox.X + level.sector.BBox.Width / 2,
level.sector.BBox.Y + level.sector.BBox.Height / 2);
if (level.extrafloor)
{
// The top side of 3D floors is the ceiling of the sector, but it's a "floor" in UDB, so the
// ceiling of the control sector has to be modified
if (level.type == SectorLevelType.Floor)
applytoceiling = true;
}
else
{
if (level.type == SectorLevelType.Ceiling)
applytoceiling = true;
}
if (applytoceiling)
{
Plane downplane = plane.GetInverted();
level.sector.CeilSlope = downplane.Normal;
level.sector.CeilSlopeOffset = downplane.Offset;
level.sector.CeilHeight = (int)new Plane(level.sector.CeilSlope, level.sector.CeilSlopeOffset).GetZ(center);
}
else
{
level.sector.FloorSlope = plane.Normal;
level.sector.FloorSlopeOffset = plane.Offset;
level.sector.FloorHeight = (int)new Plane(level.sector.FloorSlope, level.sector.FloorSlopeOffset).GetZ(center);
}
// Rebuild sector
BaseVisualSector vs;
if (mode.VisualSectorExists(level.sector))
{
vs = (BaseVisualSector)mode.GetVisualSector(level.sector);
}
else
{
vs = mode.CreateBaseVisualSector(level.sector);
}
if (vs != null) vs.UpdateSectorGeometry(true);
}
#endregion
#region ================== Events
@ -274,51 +322,7 @@ namespace CodeImp.DoomBuilder.VisualModes
// Apply slope to surfaces
foreach (SectorLevel l in levels)
{
bool applytoceiling = false;
Vector2D center = new Vector2D(l.sector.BBox.X + l.sector.BBox.Width / 2,
l.sector.BBox.Y + l.sector.BBox.Height / 2);
if(l.extrafloor)
{
// The top side of 3D floors is the ceiling of the sector, but it's a "floor" in UDB, so the
// ceiling of the control sector has to be modified
if (l.type == SectorLevelType.Floor)
applytoceiling = true;
}
else
{
if (l.type == SectorLevelType.Ceiling)
applytoceiling = true;
}
if (applytoceiling)
{
Plane downplane = plane.GetInverted();
l.sector.CeilSlope = downplane.Normal;
l.sector.CeilSlopeOffset = downplane.Offset;
l.sector.CeilHeight = (int)new Plane(l.sector.CeilSlope, l.sector.CeilSlopeOffset).GetZ(center);
}
else
{
l.sector.FloorSlope = plane.Normal;
l.sector.FloorSlopeOffset = plane.Offset;
l.sector.FloorHeight = (int)new Plane(l.sector.FloorSlope, l.sector.FloorSlopeOffset).GetZ(center);
}
// Rebuild sector
BaseVisualSector vs;
if (mode.VisualSectorExists(l.sector))
{
vs = (BaseVisualSector)mode.GetVisualSector(l.sector);
}
else
{
vs = mode.CreateBaseVisualSector(l.sector);
}
if (vs != null) vs.UpdateSectorGeometry(true);
}
ApplySlope(l, plane, mode);
mode.SetActionResult("Changed slope.");
}