mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-22 20:02:48 +00:00
Added: sectors are now split into multiple sectors when their shape is divided into several closed shapes by drawing new geometry or dragging existing geometry using Edit Selection and Drag Geometry modes.
Fixed: in some cases sidedefs belonging to linedefs, which were moved on top of existing linedefs, were incorrectly reassigned when applying Edit Selection and Drag Geometry modes. Fixed: Tag Explorer update fix from R2630 was accidentally placed in an UDMF-only if-block. Updated ZDoom_DECORATE.cfg (A_WeaponOffset). Updated documentation ("(G)ZDoom text lumps support" page).
This commit is contained in:
parent
8ee504f9cf
commit
77611bd8d3
18 changed files with 353 additions and 174 deletions
|
@ -308,6 +308,7 @@ keywords
|
||||||
A_Recoil = "A_Recoil(float force)";
|
A_Recoil = "A_Recoil(float force)";
|
||||||
A_ZoomFactor = "A_ZoomFactor[(float zoom = 1.0[, int flags = 0])]\nflags: ZOOM flags.";
|
A_ZoomFactor = "A_ZoomFactor[(float zoom = 1.0[, int flags = 0])]\nflags: ZOOM flags.";
|
||||||
A_SetCrosshair = "A_SetCrosshair(int number)";
|
A_SetCrosshair = "A_SetCrosshair(int number)";
|
||||||
|
A_WeaponOffset = "A_WeaponOffset[(float x = 0[, float y = 32[, int flags = 0])]\nflags: WOF flags.";
|
||||||
//Weapon attack functions
|
//Weapon attack functions
|
||||||
A_Punch = "A_Punch";
|
A_Punch = "A_Punch";
|
||||||
A_Saw = "A_Saw[(str fullsound = \"weapons/sawfull\"[, str hitsound = \"weapons/sawhit\"[, int damage = 0[, str pufftype = \"BulletPuff\"[, int flags = 0[, float range = 65.0[, float spread_xy = 2.8125[, float spread_z = 0.0[, float lifesteal = 0.0[, int lifestealmax = 0[, str armorbonustype = \"ArmorBonus\"]]]]]]]]]])]";
|
A_Saw = "A_Saw[(str fullsound = \"weapons/sawfull\"[, str hitsound = \"weapons/sawhit\"[, int damage = 0[, str pufftype = \"BulletPuff\"[, int flags = 0[, float range = 65.0[, float spread_xy = 2.8125[, float spread_z = 0.0[, float lifesteal = 0.0[, int lifestealmax = 0[, str armorbonustype = \"ArmorBonus\"]]]]]]]]]])]";
|
||||||
|
@ -1343,4 +1344,8 @@ constants
|
||||||
GZF_3DRESTRICT;
|
GZF_3DRESTRICT;
|
||||||
GZF_NOPORTALS;
|
GZF_NOPORTALS;
|
||||||
GZF_NO3DFLOOR;
|
GZF_NO3DFLOOR;
|
||||||
|
//A_WeaponOffset flags
|
||||||
|
WOF_KEEPX;
|
||||||
|
WOF_KEEPY;
|
||||||
|
WOF_ADD;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="contents">
|
<div id="contents">
|
||||||
<p>GZDoom Builder will automatically load data from the following lumps if they are present in the map's resources.</p>
|
<p>GZDoom Builder will automatically load data from the following lumps if they are present in the map's resources:</p>
|
||||||
|
<h2>DECORATE:</h2>
|
||||||
|
Actor definitions are loaded and used to poulate Things list. Extra parameters can be assigned using <a href="../gc_decoratekeys.html">special comments</a>.<br />
|
||||||
|
DamageTypes are loaded and used in the "Damage Type" drop-down of the Edit Sector window (UDMF only).
|
||||||
|
|
||||||
<a name="textures" id="textures"></a><h2>TEXTURES:</h2>
|
<a name="textures" id="textures"></a><h2>TEXTURES:</h2>
|
||||||
You can use "<strong>//$GZDB_SKIP</strong>" special comment to abort parsing of the current file. Useful if you don't want textures from certain files or parts of files to show up in the <a href="w_imagesbrowser.html">Image Browser</a> or want to increase resource loading speed.<br /><br />
|
You can use "<strong>//$GZDB_SKIP</strong>" special comment to abort parsing of the current file. Useful if you don't want textures from certain files or parts of files to show up in the <a href="w_imagesbrowser.html">Image Browser</a> or want to increase resource loading speed.<br /><br />
|
||||||
GZDoom Builder adds support for the following TEXTURES parameters:
|
GZDoom Builder adds support for the following TEXTURES parameters:
|
||||||
|
@ -53,6 +57,15 @@
|
||||||
|
|
||||||
<h2>SNDSEQ:</h2>
|
<h2>SNDSEQ:</h2>
|
||||||
Sound Sequence and Sound Sequence Group definitions are loaded and can be selected in the "Sound sequence" drop-down of the Edit Sector window (UDMF only).
|
Sound Sequence and Sound Sequence Group definitions are loaded and can be selected in the "Sound sequence" drop-down of the Edit Sector window (UDMF only).
|
||||||
|
|
||||||
|
<h2>TERRAIN:</h2>
|
||||||
|
Terrain names are loaded and used in the floor and ceiling "Terrain" drop-downs of the Edit Sector window (UDMF only).
|
||||||
|
|
||||||
|
<h2>X11R6RGB:</h2>
|
||||||
|
Colors are loaded and used by other text parsers where appropriate.
|
||||||
|
|
||||||
|
<h2>CVARINFO:</h2>
|
||||||
|
CVARs are loaded. Currently the editor uses them only for "DistanceCheck" DECORATE property support.
|
||||||
|
|
||||||
<a name="modeldef" id="modeldef"></a>
|
<a name="modeldef" id="modeldef"></a>
|
||||||
<h2>MODELDEF:</h2>
|
<h2>MODELDEF:</h2>
|
||||||
|
|
|
@ -107,7 +107,9 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
//mxd. Useful when debugging...
|
//mxd. Useful when debugging...
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return line + " (" + (front ? "front" : "back") + ")";
|
Sidedef side = (front ? line.Front : line.Back);
|
||||||
|
Sector sector = (side != null ? side.Sector : null);
|
||||||
|
return line + " (" + (front ? "front" : "back") + ")" + (sector != null ? ", Sector " + sector.Index : "");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2157,6 +2157,63 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Sectors (mxd)
|
||||||
|
|
||||||
|
public static void SplitOuterSectors(IEnumerable<Linedef> drawnlines)
|
||||||
|
{
|
||||||
|
Dictionary<Sector, HashSet<Sidedef>> sectorsidesref = new Dictionary<Sector, HashSet<Sidedef>>();
|
||||||
|
|
||||||
|
// Create drawn lines per sector collection
|
||||||
|
foreach(Linedef l in drawnlines)
|
||||||
|
{
|
||||||
|
if(l.Front != null && l.Front.Sector != null)
|
||||||
|
{
|
||||||
|
if(!sectorsidesref.ContainsKey(l.Front.Sector)) sectorsidesref.Add(l.Front.Sector, new HashSet<Sidedef>());
|
||||||
|
sectorsidesref[l.Front.Sector].Add(l.Front);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l.Back != null && l.Back.Sector != null)
|
||||||
|
{
|
||||||
|
if(!sectorsidesref.ContainsKey(l.Back.Sector)) sectorsidesref.Add(l.Back.Sector, new HashSet<Sidedef>());
|
||||||
|
sectorsidesref[l.Back.Sector].Add(l.Back);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split sectors
|
||||||
|
foreach(KeyValuePair<Sector, HashSet<Sidedef>> group in sectorsidesref)
|
||||||
|
{
|
||||||
|
// Sector has all sides selected?
|
||||||
|
if(group.Key.Sidedefs.Count == group.Value.Count)
|
||||||
|
{
|
||||||
|
group.Key.Marked = true; // Sometimes those are not marked...
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process all sides
|
||||||
|
foreach(Sidedef side in group.Value)
|
||||||
|
{
|
||||||
|
// Sector was already split?
|
||||||
|
if(side.Sector != group.Key) continue;
|
||||||
|
|
||||||
|
// Find drawing interior
|
||||||
|
List<LinedefSide> sides = FindPotentialSectorAt(side.Line, side.IsFront);
|
||||||
|
|
||||||
|
// Number of potential sides fewer than the sector has?
|
||||||
|
if(sides != null && sides.Count > 0 && sides.Count < group.Key.Sidedefs.Count)
|
||||||
|
{
|
||||||
|
Sector newsector = MakeSector(sides, null, false);
|
||||||
|
if(newsector != null)
|
||||||
|
{
|
||||||
|
newsector.UpdateCache();
|
||||||
|
group.Key.UpdateCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region ================== Linedefs (mxd)
|
#region ================== Linedefs (mxd)
|
||||||
|
|
||||||
/// <summary>Flips sector linedefs so they all face either inward or outward.</summary>
|
/// <summary>Flips sector linedefs so they all face either inward or outward.</summary>
|
||||||
|
@ -2349,91 +2406,46 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
// These steps must be done in 2 phases, otherwise we'll end up getting sidedefs modified in a previous adjustment loop step
|
// These steps must be done in 2 phases, otherwise we'll end up getting sidedefs modified in a previous adjustment loop step
|
||||||
|
|
||||||
// Find sidedefs to join singlesided lines
|
// Find sidedefs to join singlesided lines
|
||||||
Dictionary<Linedef, Sidedef> linenearestsideref = new Dictionary<Linedef, Sidedef>();
|
Dictionary<Linedef, Sector> linesectorref = new Dictionary<Linedef, Sector>();
|
||||||
foreach(Linedef line in singlesidedlines)
|
foreach(Linedef line in singlesidedlines)
|
||||||
{
|
{
|
||||||
// Line is now inside a sector?
|
// Line is now inside a sector? (check from the missing side!)
|
||||||
Vector2D testpoint = line.GetSidePoint(line.Front == null);
|
Sector nearest = FindPotentialSector(line, (line.Front == null), outersides);
|
||||||
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
|
|
||||||
|
|
||||||
if(nearest != null)
|
// We can reattach our line!
|
||||||
{
|
if(nearest != null) linesectorref[line] = nearest;
|
||||||
Linedef nl = null;
|
|
||||||
float distance = float.MaxValue;
|
|
||||||
|
|
||||||
// Find nearest linedef
|
|
||||||
foreach(Sidedef ns in nearest.Sidedefs)
|
|
||||||
{
|
|
||||||
float d = ns.Line.SafeDistanceToSq(testpoint, true);
|
|
||||||
if(d < distance)
|
|
||||||
{
|
|
||||||
// This one is closer
|
|
||||||
nl = ns.Line;
|
|
||||||
distance = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find nearest sidedef
|
|
||||||
if(nl != null)
|
|
||||||
{
|
|
||||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
|
||||||
if(ns != null) linenearestsideref[line] = ns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find sidedefs to join outer sides
|
// Find sidedefs to join outer sides
|
||||||
Dictionary<Sidedef, Sidedef> sidenearestsideref = new Dictionary<Sidedef, Sidedef>();
|
Dictionary<Sidedef, Sector> sidesectorref = new Dictionary<Sidedef, Sector>();
|
||||||
foreach(Sidedef side in outersides)
|
foreach(Sidedef side in outersides)
|
||||||
{
|
{
|
||||||
// Side is inside a sector?
|
// Side is inside a sector?
|
||||||
Vector2D testpoint = side.Line.GetSidePoint(side.IsFront);
|
Sector nearest = FindPotentialSector(side.Line, side.IsFront, outersides);
|
||||||
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
|
|
||||||
sidenearestsideref[side] = null; // This side will be removed in phase 2
|
|
||||||
|
|
||||||
|
// We can reattach our side!
|
||||||
if(nearest != null)
|
if(nearest != null)
|
||||||
{
|
{
|
||||||
Linedef nl = null;
|
if(side.Sector != nearest) sidesectorref[side] = nearest; // This side will be reattached in phase 2
|
||||||
float distance = float.MaxValue;
|
else sidesectorref.Remove(side); // This side is already attached where it needs to be
|
||||||
|
}
|
||||||
// Find nearest linedef
|
else
|
||||||
foreach(Sidedef ns in nearest.Sidedefs)
|
{
|
||||||
{
|
sidesectorref[side] = null; // This side will be removed in phase 2
|
||||||
float d = ns.Line.SafeDistanceToSq(testpoint, true);
|
|
||||||
if(d < distance)
|
|
||||||
{
|
|
||||||
// This one is closer
|
|
||||||
nl = ns.Line;
|
|
||||||
distance = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find nearest sidedef
|
|
||||||
if(nl != null)
|
|
||||||
{
|
|
||||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
|
||||||
if(ns != null && ns.Sector != null)
|
|
||||||
{
|
|
||||||
if(side.Sector != ns.Sector)
|
|
||||||
sidenearestsideref[side] = ns; // This side will be reattached in phase 2
|
|
||||||
else
|
|
||||||
sidenearestsideref.Remove(side); // This side is already attached where it needs to be
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check single-sided lines. Add new sidedefs if necessary
|
// Check single-sided lines. Add new sidedefs if necessary
|
||||||
// Key is dragged single-sided line, value is the nearset side of a sector dragged line ended up in.
|
// Key is dragged single-sided line, value is a sector dragged line ended up in.
|
||||||
foreach(KeyValuePair<Linedef, Sidedef> group in linenearestsideref)
|
foreach(KeyValuePair<Linedef, Sector> group in linesectorref)
|
||||||
{
|
{
|
||||||
Linedef line = group.Key;
|
Linedef line = group.Key;
|
||||||
|
|
||||||
// Create new sidedef
|
// Create new sidedef
|
||||||
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, group.Value.Sector);
|
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, group.Value);
|
||||||
|
|
||||||
// Copy props from the other side
|
// Copy props from the other side
|
||||||
Sidedef propssource = ((line.Front ?? line.Back) ?? group.Value);
|
Sidedef propssource = (line.Front ?? line.Back);
|
||||||
propssource.CopyPropertiesTo(newside);
|
propssource.CopyPropertiesTo(newside);
|
||||||
newside.RemoveUnneededTextures(true, true, true);
|
newside.RemoveUnneededTextures(true, true, true);
|
||||||
newside.Other.RemoveUnneededTextures(true, true, true);
|
newside.Other.RemoveUnneededTextures(true, true, true);
|
||||||
|
@ -2450,8 +2462,8 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check outer sidedefs. Remove/change sector if necessary
|
// Check outer sidedefs. Remove/change sector if necessary
|
||||||
// Key is outer sidedef of dragged geometry, value is nearset side of a sector dragged side ended up in.
|
// Key is outer sidedef of dragged geometry, value is a sector dragged side ended up in.
|
||||||
foreach(KeyValuePair<Sidedef, Sidedef> group in sidenearestsideref)
|
foreach(KeyValuePair<Sidedef, Sector> group in sidesectorref)
|
||||||
{
|
{
|
||||||
if(group.Value == null)
|
if(group.Value == null)
|
||||||
{
|
{
|
||||||
|
@ -2472,7 +2484,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Reattach side
|
// Reattach side
|
||||||
group.Key.SetSector(group.Value.Sector);
|
group.Key.SetSector(group.Value);
|
||||||
group.Key.RemoveUnneededTextures(true, true, true);
|
group.Key.RemoveUnneededTextures(true, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2481,6 +2493,27 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd
|
||||||
|
private static Sector FindPotentialSector(Linedef line, bool front, HashSet<Sidedef> sidestoexclude)
|
||||||
|
{
|
||||||
|
List<LinedefSide> sectorsides = FindPotentialSectorAt(line, front);
|
||||||
|
if(sectorsides == null) return null;
|
||||||
|
|
||||||
|
// Filter outersides from the list, proceed only if all sectorsides reference the same sector
|
||||||
|
Sector result = null;
|
||||||
|
foreach(LinedefSide sectorside in sectorsides)
|
||||||
|
{
|
||||||
|
Sidedef target = (sectorside.Front ? sectorside.Line.Front : sectorside.Line.Back);
|
||||||
|
if(target != null && !sidestoexclude.Contains(target))
|
||||||
|
{
|
||||||
|
if(result == null) result = target.Sector;
|
||||||
|
else if(result != target.Sector) return null; // Fial...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Misc Exported Functions
|
#region ================== Misc Exported Functions
|
||||||
|
|
|
@ -1073,23 +1073,23 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
public bool Join(Linedef other)
|
public bool Join(Linedef other)
|
||||||
{
|
{
|
||||||
// Check which lines were 2 sided
|
// Check which lines were 2 sided
|
||||||
bool l1was2s = ((other.Front != null) && (other.Back != null));
|
bool otherwas2s = ((other.Front != null) && (other.Back != null));
|
||||||
bool l2was2s = ((this.Front != null) && (this.Back != null));
|
bool thiswas2s = ((this.Front != null) && (this.Back != null));
|
||||||
|
|
||||||
// Get sector references
|
// Get sector references
|
||||||
Sector l1fs = other.front != null ? other.front.Sector : null;
|
Sector otherfs = (other.front != null ? other.front.Sector : null);
|
||||||
Sector l1bs = other.back != null ? other.back.Sector : null;
|
Sector otherbs = (other.back != null ? other.back.Sector : null);
|
||||||
Sector l2fs = this.front != null ? this.front.Sector : null;
|
Sector thisfs = (this.front != null ? this.front.Sector : null);
|
||||||
Sector l2bs = this.back != null ? this.back.Sector : null;
|
Sector thisbs = (this.back != null ? this.back.Sector : null);
|
||||||
|
|
||||||
// This line has no sidedefs?
|
// This line has no sidedefs?
|
||||||
if((l2fs == null) && (l2bs == null))
|
if((thisfs == null) && (thisbs == null))
|
||||||
{
|
{
|
||||||
// We have no sidedefs, so we have no influence
|
// We have no sidedefs, so we have no influence
|
||||||
// Nothing to change on the other line
|
// Nothing to change on the other line
|
||||||
}
|
}
|
||||||
// Other line has no sidedefs?
|
// Other line has no sidedefs?
|
||||||
else if((l1fs == null) && (l1bs == null))
|
else if((otherfs == null) && (otherbs == null))
|
||||||
{
|
{
|
||||||
// The other has no sidedefs, so it has no influence
|
// The other has no sidedefs, so it has no influence
|
||||||
// Copy my sidedefs to the other
|
// Copy my sidedefs to the other
|
||||||
|
@ -1110,44 +1110,44 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Compare front sectors
|
// Compare front sectors
|
||||||
if((l1fs != null) && (l1fs == l2fs))
|
if((otherfs != null) && (otherfs == thisfs))
|
||||||
{
|
{
|
||||||
// Copy textures
|
// Copy textures
|
||||||
if(other.front != null) other.front.AddTexturesTo(this.back);
|
if(other.front != null) other.front.AddTexturesTo(this.back);
|
||||||
if(this.front != null) this.front.AddTexturesTo(other.back);
|
if(this.front != null) this.front.AddTexturesTo(other.back);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs?
|
||||||
if(!JoinChangeSidedefs(other, true, back)) return false;
|
if(back != null && !JoinChangeSidedefs(other, true, back)) return false;
|
||||||
}
|
}
|
||||||
// Compare back sectors
|
// Compare back sectors
|
||||||
else if((l1bs != null) && (l1bs == l2bs))
|
else if((otherbs != null) && (otherbs == thisbs))
|
||||||
{
|
{
|
||||||
// Copy textures
|
// Copy textures
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.front);
|
if(other.back != null) other.back.AddTexturesTo(this.front);
|
||||||
if(this.back != null) this.back.AddTexturesTo(other.front);
|
if(this.back != null) this.back.AddTexturesTo(other.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs?
|
||||||
if(!JoinChangeSidedefs(other, false, front)) return false;
|
if(front != null && !JoinChangeSidedefs(other, false, front)) return false;
|
||||||
}
|
}
|
||||||
// Compare front and back
|
// Compare front and back
|
||||||
else if((l1fs != null) && (l1fs == l2bs))
|
else if((otherfs != null) && (otherfs == thisbs))
|
||||||
{
|
{
|
||||||
// Copy textures
|
// Copy textures
|
||||||
if(other.front != null) other.front.AddTexturesTo(this.front);
|
if(other.front != null) other.front.AddTexturesTo(this.front);
|
||||||
if(this.back != null) this.back.AddTexturesTo(other.back);
|
if(this.back != null) this.back.AddTexturesTo(other.back);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs?
|
||||||
if(!JoinChangeSidedefs(other, true, front)) return false;
|
if(front != null && !JoinChangeSidedefs(other, true, front)) return false;
|
||||||
}
|
}
|
||||||
// Compare back and front
|
// Compare back and front
|
||||||
else if((l1bs != null) && (l1bs == l2fs))
|
else if((otherbs != null) && (otherbs == thisfs))
|
||||||
{
|
{
|
||||||
// Copy textures
|
// Copy textures
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.back);
|
if(other.back != null) other.back.AddTexturesTo(this.back);
|
||||||
if(this.front != null) this.front.AddTexturesTo(other.front);
|
if(this.front != null) this.front.AddTexturesTo(other.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs?
|
||||||
if(!JoinChangeSidedefs(other, false, back)) return false;
|
if(back != null && !JoinChangeSidedefs(other, false, back)) return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1158,20 +1158,18 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
if(this.start == other.end)
|
if(this.start == other.end)
|
||||||
{
|
{
|
||||||
// Copy textures
|
// Copy textures
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.front);
|
|
||||||
if(this.back != null) this.back.AddTexturesTo(other.front);
|
if(this.back != null) this.back.AddTexturesTo(other.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs?
|
||||||
if(!JoinChangeSidedefs(other, false, front)) return false;
|
if(front != null && !JoinChangeSidedefs(other, false, front)) return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Copy textures
|
// Copy textures
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.back);
|
|
||||||
if(this.front != null) this.front.AddTexturesTo(other.front);
|
if(this.front != null) this.front.AddTexturesTo(other.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs?
|
||||||
if(!JoinChangeSidedefs(other, false, back)) return false;
|
if(back != null && !JoinChangeSidedefs(other, false, back)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This line single sided?
|
// This line single sided?
|
||||||
|
@ -1180,21 +1178,27 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// Other line with its back to this?
|
// Other line with its back to this?
|
||||||
if(other.start == this.end)
|
if(other.start == this.end)
|
||||||
{
|
{
|
||||||
// Copy textures
|
//mxd. Marked sector means other side belongs to a sector being moved...
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.front);
|
if(otherbs == null || !otherbs.Marked)
|
||||||
if(this.back != null) this.back.AddTexturesTo(other.front);
|
{
|
||||||
|
// Copy textures
|
||||||
|
if(other.back != null) other.back.AddTexturesTo(this.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs
|
||||||
if(!JoinChangeSidedefs(other, false, front)) return false;
|
if(!JoinChangeSidedefs(other, false, front)) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Copy textures
|
//mxd. Marked sector means other side belongs to a sector being moved...
|
||||||
if(other.front != null) other.front.AddTexturesTo(this.front);
|
if(otherfs == null || !otherfs.Marked)
|
||||||
if(this.back != null) this.back.AddTexturesTo(other.back);
|
{
|
||||||
|
// Copy textures
|
||||||
|
if(other.front != null) other.front.AddTexturesTo(this.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs
|
||||||
if(!JoinChangeSidedefs(other, true, front)) return false;
|
if(!JoinChangeSidedefs(other, true, front)) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1202,33 +1206,64 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// This line with its back to the other?
|
// This line with its back to the other?
|
||||||
if(this.start == other.end)
|
if(this.start == other.end)
|
||||||
{
|
{
|
||||||
// Copy textures
|
//mxd. Marked sector means other side belongs to a sector being moved...
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.front);
|
//mxd. Attach our front to other back?
|
||||||
if(this.back != null) this.back.AddTexturesTo(other.front);
|
if(otherbs == null || !otherbs.Marked)
|
||||||
|
{
|
||||||
|
// Copy textures
|
||||||
|
if(other.back != null) other.back.AddTexturesTo(this.front);
|
||||||
|
if(this.back != null) this.back.AddTexturesTo(other.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs (replace other back with our front)
|
||||||
if(!JoinChangeSidedefs(other, false, front)) return false;
|
if(front != null && !JoinChangeSidedefs(other, false, front)) return false;
|
||||||
|
}
|
||||||
|
//mxd. Attach our back to other front?
|
||||||
|
else if(otherfs == null || !otherfs.Marked)
|
||||||
|
{
|
||||||
|
// Copy textures
|
||||||
|
if(other.front != null) other.front.AddTexturesTo(this.back);
|
||||||
|
if(this.front != null) this.front.AddTexturesTo(other.back);
|
||||||
|
|
||||||
|
// Change sidedefs (replace other back with our front)
|
||||||
|
if(back != null && !JoinChangeSidedefs(other, true, back)) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Both lines face the same way
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Copy textures
|
//mxd. Marked sector means other side belongs to a sector being moved...
|
||||||
if(other.back != null) other.back.AddTexturesTo(this.back);
|
//mxd. Attach our back to other back?
|
||||||
if(this.front != null) this.front.AddTexturesTo(other.front);
|
if(otherbs == null || !otherbs.Marked)
|
||||||
|
{
|
||||||
|
// Copy textures
|
||||||
|
if(other.back != null) other.back.AddTexturesTo(this.back);
|
||||||
|
if(this.front != null) this.front.AddTexturesTo(other.front);
|
||||||
|
|
||||||
// Change sidedefs
|
// Change sidedefs
|
||||||
if(!JoinChangeSidedefs(other, false, back)) return false;
|
if(back != null && !JoinChangeSidedefs(other, false, back)) return false;
|
||||||
|
}
|
||||||
|
//mxd. Attach our front to other front?
|
||||||
|
else if(otherfs == null || !otherfs.Marked)
|
||||||
|
{
|
||||||
|
// Copy textures
|
||||||
|
if(other.front != null) other.front.AddTexturesTo(this.front);
|
||||||
|
if(this.back != null) this.back.AddTexturesTo(other.back);
|
||||||
|
|
||||||
|
// Change sidedefs
|
||||||
|
if(front != null && !JoinChangeSidedefs(other, true, front)) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply single/double sided flags if the double-sided-ness changed
|
// Apply single/double sided flags if the double-sided-ness changed
|
||||||
if( (!l1was2s && ((other.Front != null) && (other.Back != null))) ||
|
if( (!otherwas2s && (other.Front != null && other.Back != null)) ||
|
||||||
(l1was2s && ((other.Front == null) || (other.Back == null))) )
|
(otherwas2s && (other.Front == null || other.Back == null)) )
|
||||||
other.ApplySidedFlags();
|
other.ApplySidedFlags();
|
||||||
|
|
||||||
// Remove unneeded textures
|
// Remove unneeded textures
|
||||||
if(other.front != null) other.front.RemoveUnneededTextures(!(l1was2s && l2was2s));
|
if(other.front != null) other.front.RemoveUnneededTextures(!(otherwas2s && thiswas2s));
|
||||||
if(other.back != null) other.back.RemoveUnneededTextures(!(l1was2s && l2was2s));
|
if(other.back != null) other.back.RemoveUnneededTextures(!(otherwas2s && thiswas2s));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If either of the two lines was selected, keep the other selected
|
// If either of the two lines was selected, keep the other selected
|
||||||
|
@ -1287,7 +1322,13 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// String representation
|
// String representation
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
string starttext = (start != null ? " (" + start : string.Empty);
|
||||||
|
string endtext = (end != null ? ", " + end + ")" : string.Empty);
|
||||||
|
return "Linedef " + listindex + (marked ? " (marked)" : "") + starttext + endtext; //mxd
|
||||||
|
#else
|
||||||
return "Linedef " + listindex;
|
return "Linedef " + listindex;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -2167,8 +2167,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
if(l1.Index == l2.Index) continue;
|
if(l1.Index == l2.Index) continue;
|
||||||
|
|
||||||
// Sharing vertices?
|
// Sharing vertices?
|
||||||
if((l1.End == l2.End) ||
|
if(l1.End == l2.End || l1.End == l2.Start)
|
||||||
(l1.End == l2.Start))
|
|
||||||
{
|
{
|
||||||
bool oppositedirection = (l1.End == l2.Start);
|
bool oppositedirection = (l1.End == l2.Start);
|
||||||
bool l2marked = l2.Marked;
|
bool l2marked = l2.Marked;
|
||||||
|
@ -2183,8 +2182,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
{
|
{
|
||||||
l1.FrontInterior = l2.FrontInterior ^ oppositedirection;
|
l1.FrontInterior = l2.FrontInterior ^ oppositedirection;
|
||||||
}
|
}
|
||||||
// If l1 is marked as new geometry, we may need to flip it to preserve
|
// If l1 is marked as new geometry, we may need to flip it to preserve
|
||||||
// orientation of the original geometry, and update its FrontInterior
|
// orientation of the original geometry, and update its FrontInterior
|
||||||
else if(l1.Marked)
|
else if(l1.Marked)
|
||||||
{
|
{
|
||||||
if(oppositedirection)
|
if(oppositedirection)
|
||||||
|
@ -2209,8 +2208,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
if(l1.Index == l2.Index) continue;
|
if(l1.Index == l2.Index) continue;
|
||||||
|
|
||||||
// Sharing vertices?
|
// Sharing vertices?
|
||||||
if((l1.Start == l2.End) ||
|
if(l1.Start == l2.End || l1.Start == l2.Start)
|
||||||
(l1.Start == l2.Start))
|
|
||||||
{
|
{
|
||||||
bool oppositedirection = (l1.Start == l2.End);
|
bool oppositedirection = (l1.Start == l2.End);
|
||||||
bool l2marked = l2.Marked;
|
bool l2marked = l2.Marked;
|
||||||
|
@ -2225,8 +2223,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
{
|
{
|
||||||
l1.FrontInterior = l2.FrontInterior ^ oppositedirection;
|
l1.FrontInterior = l2.FrontInterior ^ oppositedirection;
|
||||||
}
|
}
|
||||||
// If l1 is marked as new geometry, we may need to flip it to preserve
|
// If l1 is marked as new geometry, we may need to flip it to preserve
|
||||||
// orientation of the original geometry, and update its FrontInterior
|
// orientation of the original geometry, and update its FrontInterior
|
||||||
else if(l1.Marked)
|
else if(l1.Marked)
|
||||||
{
|
{
|
||||||
if(oppositedirection)
|
if(oppositedirection)
|
||||||
|
@ -3098,17 +3096,6 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd
|
|
||||||
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
|
||||||
public Sector GetSectorByCoordinates(Vector2D pos, HashSet<Sector> sectorsToExclude)
|
|
||||||
{
|
|
||||||
foreach(Sector s in sectors)
|
|
||||||
{
|
|
||||||
if(!sectorsToExclude.Contains(s) && s.Intersect(pos)) return s;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
||||||
public Sector GetSectorByCoordinates(Vector2D pos, VisualBlockMap blockmap)
|
public Sector GetSectorByCoordinates(Vector2D pos, VisualBlockMap blockmap)
|
||||||
|
|
|
@ -568,7 +568,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// This requires the sector triangulation to be up-to-date!
|
// This requires the sector triangulation to be up-to-date!
|
||||||
private RectangleF CreateBBox()
|
private RectangleF CreateBBox()
|
||||||
{
|
{
|
||||||
if(sidedefs.Count == 0) return new RectangleF(); //mxd
|
if(sidedefs.Count == 0) return new RectangleF(); //mxd
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
float left = float.MaxValue;
|
float left = float.MaxValue;
|
||||||
|
@ -576,29 +576,29 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
float right = float.MinValue;
|
float right = float.MinValue;
|
||||||
float bottom = float.MinValue;
|
float bottom = float.MinValue;
|
||||||
|
|
||||||
Dictionary<Vertex, bool> processed = new Dictionary<Vertex, bool>(); //mxd
|
HashSet<Vertex> processed = new HashSet<Vertex>(); //mxd
|
||||||
|
|
||||||
//mxd. This way bbox will be created even if triangulation failed (sector with 2 or less sidedefs and 2 vertices)
|
//mxd. This way bbox will be created even if triangulation failed (sector with 2 or less sidedefs and 2 vertices)
|
||||||
foreach(Sidedef s in sidedefs)
|
foreach(Sidedef s in sidedefs)
|
||||||
{
|
{
|
||||||
//start...
|
//start...
|
||||||
if(!processed.ContainsKey(s.Line.Start))
|
if(!processed.Contains(s.Line.Start))
|
||||||
{
|
{
|
||||||
if(s.Line.Start.Position.x < left) left = s.Line.Start.Position.x;
|
if(s.Line.Start.Position.x < left) left = s.Line.Start.Position.x;
|
||||||
if(s.Line.Start.Position.x > right) right = s.Line.Start.Position.x;
|
if(s.Line.Start.Position.x > right) right = s.Line.Start.Position.x;
|
||||||
if(s.Line.Start.Position.y < top) top = s.Line.Start.Position.y;
|
if(s.Line.Start.Position.y < top) top = s.Line.Start.Position.y;
|
||||||
if(s.Line.Start.Position.y > bottom) bottom = s.Line.Start.Position.y;
|
if(s.Line.Start.Position.y > bottom) bottom = s.Line.Start.Position.y;
|
||||||
processed.Add(s.Line.Start, false);
|
processed.Add(s.Line.Start);
|
||||||
}
|
}
|
||||||
|
|
||||||
//end...
|
//end...
|
||||||
if(!processed.ContainsKey(s.Line.End))
|
if(!processed.Contains(s.Line.End))
|
||||||
{
|
{
|
||||||
if(s.Line.End.Position.x < left) left = s.Line.End.Position.x;
|
if(s.Line.End.Position.x < left) left = s.Line.End.Position.x;
|
||||||
if(s.Line.End.Position.x > right) right = s.Line.End.Position.x;
|
if(s.Line.End.Position.x > right) right = s.Line.End.Position.x;
|
||||||
if(s.Line.End.Position.y < top) top = s.Line.End.Position.y;
|
if(s.Line.End.Position.y < top) top = s.Line.End.Position.y;
|
||||||
if(s.Line.End.Position.y > bottom) bottom = s.Line.End.Position.y;
|
if(s.Line.End.Position.y > bottom) bottom = s.Line.End.Position.y;
|
||||||
processed.Add(s.Line.End, false);
|
processed.Add(s.Line.End);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,7 +791,11 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// String representation
|
// String representation
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return "Sector " + listindex + (marked ? " (marked)" : ""); //mxd
|
||||||
|
#else
|
||||||
return "Sector " + listindex;
|
return "Sector " + listindex;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -633,6 +633,17 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
|
|
||||||
General.Map.IsChanged = true;
|
General.Map.IsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd. String representation
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return "Sidedef " + listindex + (marked ? " (marked)" : "") + " (Line " + linedef.Index + (linedef.Marked ? " (marked)" : "") + ", Sector " + sector.Index + (sector.Marked ? " (marked)" : "") + ")";
|
||||||
|
#else
|
||||||
|
return "Sidedef " + listindex;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -329,7 +329,11 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// String representation
|
// String representation
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return "Vertex (" + pos + (marked ? "; marked" : "") + ")";
|
||||||
|
#else
|
||||||
return "Vertex (" + pos + ")";
|
return "Vertex (" + pos + ")";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -419,8 +419,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Move selected geometry to final position
|
// Move selected geometry to final position
|
||||||
MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptogridincrement, snaptonearest, snaptocardinaldirection);
|
MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptogridincrement, snaptonearest, snaptocardinaldirection);
|
||||||
|
|
||||||
|
//mxd. Used in Linedef.Join()...
|
||||||
|
General.Map.Map.MarkSelectedSectors(true, true);
|
||||||
|
|
||||||
// Stitch geometry
|
// Stitch geometry
|
||||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
General.Map.Map.StitchGeometry();
|
||||||
|
|
||||||
// Make corrections for backward linedefs
|
// Make corrections for backward linedefs
|
||||||
MapSet.FlipBackwardLinedefs(General.Map.Map.Linedefs);
|
MapSet.FlipBackwardLinedefs(General.Map.Map.Linedefs);
|
||||||
|
@ -516,17 +519,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
s.CeilSlopeOffset = -Vector3D.DotProduct(s.CeilSlope, new Vector3D(center + offset, ceiling.GetZ(center)));
|
s.CeilSlopeOffset = -Vector3D.DotProduct(s.CeilSlope, new Vector3D(center + offset, ceiling.GetZ(center)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update cached values
|
|
||||||
General.Map.Map.Update();
|
|
||||||
|
|
||||||
//mxd. Let the plugins know
|
|
||||||
General.Editing.AcceptMode();
|
|
||||||
|
|
||||||
// Done
|
|
||||||
Cursor.Current = Cursors.Default;
|
|
||||||
General.Map.IsChanged = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update cached values
|
||||||
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
//mxd. Let the plugins know
|
||||||
|
General.Editing.AcceptMode();
|
||||||
|
|
||||||
|
// Done
|
||||||
|
Cursor.Current = Cursors.Default;
|
||||||
|
General.Map.IsChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||||
foreach(Vertex v in verts) v.Selected = true;
|
foreach(Vertex v in verts) v.Selected = true;
|
||||||
|
|
||||||
|
//mxd. Mark moved sectors (used in Linedef.Join())
|
||||||
|
HashSet<Sector> draggeddsectors = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
|
||||||
|
foreach(Sector s in draggeddsectors) s.Marked = true;
|
||||||
|
|
||||||
// Perform normal disengage
|
// Perform normal disengage
|
||||||
base.OnDisengage();
|
base.OnDisengage();
|
||||||
|
|
||||||
|
@ -114,12 +118,21 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
if(unstablelines.Count == 0)
|
if(unstablelines.Count == 0)
|
||||||
{
|
{
|
||||||
// Add sectors, which have all their linedefs selected
|
// Get new lines from linedef marks...
|
||||||
// (otherwise those would be destroyed after moving the selection)
|
HashSet<Linedef> newlines = new HashSet<Linedef>(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
|
|
||||||
|
// Marked lines were created during linedef splitting
|
||||||
|
HashSet<Linedef> changedlines = new HashSet<Linedef>(selectedlines);
|
||||||
|
changedlines.UnionWith(newlines);
|
||||||
|
|
||||||
|
// Add sectors, which have all their linedefs selected (otherwise those would be destroyed after moving the selection)
|
||||||
|
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(changedlines);
|
||||||
|
|
||||||
// Process outer sidedefs
|
// Process outer sidedefs
|
||||||
Tools.AdjustOuterSidedefs(toadjust, new HashSet<Linedef>(selectedlines));
|
Tools.AdjustOuterSidedefs(toadjust, changedlines);
|
||||||
|
|
||||||
|
// Split outer sectors
|
||||||
|
Tools.SplitOuterSectors(changedlines);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If only a single linedef was selected, deselect it now
|
// If only a single linedef was selected, deselect it now
|
||||||
|
|
|
@ -129,6 +129,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Process outer sidedefs
|
// Process outer sidedefs
|
||||||
Tools.AdjustOuterSidedefs(toadjust, new HashSet<Linedef>(selectedlines));
|
Tools.AdjustOuterSidedefs(toadjust, new HashSet<Linedef>(selectedlines));
|
||||||
|
|
||||||
|
// Split outer sectors
|
||||||
|
Tools.SplitOuterSectors(selectedlines);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If only a single sector was selected, deselect it now
|
// If only a single sector was selected, deselect it now
|
||||||
|
|
|
@ -91,7 +91,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Select vertices from marks
|
// Select vertices from marks
|
||||||
General.Map.Map.ClearSelectedVertices();
|
General.Map.Map.ClearSelectedVertices();
|
||||||
General.Map.Map.SelectMarkedVertices(true, true);
|
General.Map.Map.SelectMarkedVertices(true, true);
|
||||||
|
|
||||||
|
//mxd. Mark stable lines now (marks will be carried to split lines by MapSet.StitchGeometry())
|
||||||
|
HashSet<Linedef> stablelines = (!cancelled ? new HashSet<Linedef>(General.Map.Map.LinedefsFromMarkedVertices(false, true, false)) : new HashSet<Linedef>());
|
||||||
|
foreach(Linedef l in stablelines) l.Marked = true;
|
||||||
|
|
||||||
|
//mxd. Mark moved sectors (used in Linedef.Join())
|
||||||
|
HashSet<Sector> draggeddsectors = (!cancelled ? General.Map.Map.GetUnselectedSectorsFromLinedefs(stablelines) : new HashSet<Sector>());
|
||||||
|
foreach(Sector s in draggeddsectors) s.Marked = true;
|
||||||
|
|
||||||
// Perform normal disengage
|
// Perform normal disengage
|
||||||
base.OnDisengage();
|
base.OnDisengage();
|
||||||
|
|
||||||
|
@ -99,15 +107,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(!cancelled)
|
if(!cancelled)
|
||||||
{
|
{
|
||||||
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
if(selectedverts.Count > 1 && unstablelines.Count == 0)
|
if(stablelines.Count > 0 && unstablelines.Count == 0)
|
||||||
{
|
{
|
||||||
// Add sectors, which have all their linedefs selected
|
// Get new lines from linedef marks...
|
||||||
// (otherwise those would be destroyed after moving the selection)
|
HashSet<Linedef> newlines = new HashSet<Linedef>(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
HashSet<Linedef> selectedlines = new HashSet<Linedef>(General.Map.Map.LinedefsFromMarkedVertices(false, true, false));
|
|
||||||
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
|
|
||||||
|
|
||||||
// Process outer sidedefs
|
// Marked lines were created during linedef splitting
|
||||||
Tools.AdjustOuterSidedefs(toadjust, selectedlines);
|
HashSet<Linedef> changedlines = new HashSet<Linedef>(stablelines);
|
||||||
|
changedlines.UnionWith(newlines);
|
||||||
|
|
||||||
|
// Get sectors, which have all their linedefs selected (otherwise those would be destroyed after moving the selection)
|
||||||
|
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(changedlines);
|
||||||
|
|
||||||
|
if(changedlines.Count > 0)
|
||||||
|
{
|
||||||
|
// Process outer sidedefs
|
||||||
|
Tools.AdjustOuterSidedefs(toadjust, changedlines);
|
||||||
|
|
||||||
|
// Split outer sectors
|
||||||
|
Tools.SplitOuterSectors(changedlines);
|
||||||
|
|
||||||
|
// Additional verts may've been created
|
||||||
|
if(selectedverts.Count > 1)
|
||||||
|
{
|
||||||
|
foreach(Linedef l in changedlines)
|
||||||
|
{
|
||||||
|
l.Start.Selected = true;
|
||||||
|
l.End.Selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If only a single vertex was selected, deselect it now
|
// If only a single vertex was selected, deselect it now
|
||||||
|
|
|
@ -248,6 +248,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Update cached values
|
// Update cached values
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
//mxd. Outer sectors may require some splittin...
|
||||||
|
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
|
|
||||||
// Edit new sectors?
|
// Edit new sectors?
|
||||||
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
||||||
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
||||||
|
|
|
@ -767,6 +767,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Update cached values
|
// Update cached values
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
//mxd. Outer sectors may require some splittin...
|
||||||
|
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
|
|
||||||
// Edit new sectors?
|
// Edit new sectors?
|
||||||
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
||||||
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
General.Map.UndoRedo.CreateUndo("Grid draw");
|
General.Map.UndoRedo.CreateUndo("Grid draw");
|
||||||
|
|
||||||
// Make an analysis and show info
|
// Make an analysis and show info
|
||||||
string[] adjectives = new[] { "gloomy", "sad", "unhappy", "lonely", "troubled", "depressed", "heartsick", "glum", "pessimistic", "bitter", "downcast" }; // aaand my english vocabulary ends here :)
|
string[] adjectives = { "gloomy", "sad", "unhappy", "lonely", "troubled", "depressed", "heartsick", "glum", "pessimistic", "bitter", "downcast" }; // aaand my english vocabulary ends here :)
|
||||||
string word = adjectives[new Random().Next(adjectives.Length - 1)];
|
string word = adjectives[new Random().Next(adjectives.Length - 1)];
|
||||||
string a = (word[0] == 'u' ? "an " : "a ");
|
string a = (word[0] == 'u' ? "an " : "a ");
|
||||||
|
|
||||||
|
@ -114,6 +114,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Clear selection
|
// Clear selection
|
||||||
General.Map.Map.ClearAllSelected();
|
General.Map.Map.ClearAllSelected();
|
||||||
|
|
||||||
|
//mxd. Outer sectors may require some splittin...
|
||||||
|
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
|
|
||||||
// Edit new sectors?
|
// Edit new sectors?
|
||||||
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
||||||
General.Interface.ShowEditSectors(newsectors);
|
General.Interface.ShowEditSectors(newsectors);
|
||||||
|
|
|
@ -385,6 +385,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Update cached values
|
// Update cached values
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
//mxd. Outer sectors may require some splittin...
|
||||||
|
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
|
|
||||||
// Edit new sectors?
|
// Edit new sectors?
|
||||||
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
|
||||||
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
||||||
|
|
|
@ -1480,23 +1480,42 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stitch geometry
|
// Stitch geometry
|
||||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
General.Map.Map.StitchGeometry();
|
||||||
|
|
||||||
// Make corrections for backward linedefs
|
// Make corrections for backward linedefs
|
||||||
MapSet.FlipBackwardLinedefs(General.Map.Map.Linedefs);
|
MapSet.FlipBackwardLinedefs(General.Map.Map.Linedefs);
|
||||||
|
|
||||||
|
// Snap to map format accuracy
|
||||||
|
General.Map.Map.SnapAllToAccuracy(General.Map.UDMF && usepreciseposition);
|
||||||
|
|
||||||
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
if(unstablelines.Count == 0)
|
if(unstablelines.Count == 0)
|
||||||
{
|
{
|
||||||
|
// Update cached values
|
||||||
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
// Get new lines from linedef marks...
|
||||||
|
HashSet<Linedef> newlines = new HashSet<Linedef>(General.Map.Map.GetMarkedLinedefs(true));
|
||||||
|
|
||||||
|
// Marked lines were created during linedef splitting
|
||||||
|
HashSet<Linedef> changedlines = new HashSet<Linedef>(selectedlines);
|
||||||
|
changedlines.UnionWith(newlines);
|
||||||
|
|
||||||
// Update outer sides of the selection
|
// Update outer sides of the selection
|
||||||
HashSet<Sector> affectedsectors = new HashSet<Sector>(General.Map.Map.GetSelectedSectors(true));
|
if(changedlines.Count > 0)
|
||||||
affectedsectors.UnionWith(General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines));
|
{
|
||||||
Tools.AdjustOuterSidedefs(affectedsectors, new HashSet<Linedef>(selectedlines));
|
// Get affected sectors
|
||||||
|
HashSet<Sector> affectedsectors = new HashSet<Sector>(General.Map.Map.GetSelectedSectors(true));
|
||||||
|
affectedsectors.UnionWith(General.Map.Map.GetUnselectedSectorsFromLinedefs(changedlines));
|
||||||
|
|
||||||
|
// Process outer sidedefs
|
||||||
|
Tools.AdjustOuterSidedefs(affectedsectors, new HashSet<Linedef>(changedlines));
|
||||||
|
|
||||||
|
// Split outer sectors
|
||||||
|
Tools.SplitOuterSectors(changedlines);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snap to map format accuracy
|
|
||||||
General.Map.Map.SnapAllToAccuracy(General.Map.UDMF && usepreciseposition);
|
|
||||||
|
|
||||||
// Update cached values
|
// Update cached values
|
||||||
General.Map.Data.UpdateUsedTextures();
|
General.Map.Data.UpdateUsedTextures();
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
|
|
Loading…
Reference in a new issue