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:
MaxED 2016-05-18 20:31:40 +00:00
parent 8ee504f9cf
commit 77611bd8d3
18 changed files with 353 additions and 174 deletions

View file

@ -308,6 +308,7 @@ keywords
A_Recoil = "A_Recoil(float force)";
A_ZoomFactor = "A_ZoomFactor[(float zoom = 1.0[, int flags = 0])]\nflags: ZOOM flags.";
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
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\"]]]]]]]]]])]";
@ -1343,4 +1344,8 @@ constants
GZF_3DRESTRICT;
GZF_NOPORTALS;
GZF_NO3DFLOOR;
//A_WeaponOffset flags
WOF_KEEPX;
WOF_KEEPY;
WOF_ADD;
}

View file

@ -22,7 +22,11 @@
</div>
<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>
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:
@ -53,6 +57,15 @@
<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).
<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>
<h2>MODELDEF:</h2>

View file

@ -107,7 +107,9 @@ namespace CodeImp.DoomBuilder.Geometry
//mxd. Useful when debugging...
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

View file

@ -2157,6 +2157,63 @@ namespace CodeImp.DoomBuilder.Geometry
#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)
/// <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
// 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)
{
// Line is now inside a sector?
Vector2D testpoint = line.GetSidePoint(line.Front == null);
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
// Line is now inside a sector? (check from the missing side!)
Sector nearest = FindPotentialSector(line, (line.Front == null), outersides);
if(nearest != null)
{
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;
}
}
// We can reattach our line!
if(nearest != null) linesectorref[line] = nearest;
}
// 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)
{
// Side is inside a sector?
Vector2D testpoint = side.Line.GetSidePoint(side.IsFront);
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
sidenearestsideref[side] = null; // This side will be removed in phase 2
Sector nearest = FindPotentialSector(side.Line, side.IsFront, outersides);
// We can reattach our side!
if(nearest != null)
{
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 && 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
}
}
if(side.Sector != nearest) sidesectorref[side] = nearest; // This side will be reattached in phase 2
else sidesectorref.Remove(side); // This side is already attached where it needs to be
}
else
{
sidesectorref[side] = null; // This side will be removed in phase 2
}
}
// 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.
foreach(KeyValuePair<Linedef, Sidedef> group in linenearestsideref)
// Key is dragged single-sided line, value is a sector dragged line ended up in.
foreach(KeyValuePair<Linedef, Sector> group in linesectorref)
{
Linedef line = group.Key;
// 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
Sidedef propssource = ((line.Front ?? line.Back) ?? group.Value);
Sidedef propssource = (line.Front ?? line.Back);
propssource.CopyPropertiesTo(newside);
newside.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
// Key is outer sidedef of dragged geometry, value is nearset side of a sector dragged side ended up in.
foreach(KeyValuePair<Sidedef, Sidedef> group in sidenearestsideref)
// Key is outer sidedef of dragged geometry, value is a sector dragged side ended up in.
foreach(KeyValuePair<Sidedef, Sector> group in sidesectorref)
{
if(group.Value == null)
{
@ -2472,7 +2484,7 @@ namespace CodeImp.DoomBuilder.Geometry
else
{
// Reattach side
group.Key.SetSector(group.Value.Sector);
group.Key.SetSector(group.Value);
group.Key.RemoveUnneededTextures(true, true, true);
}
}
@ -2481,6 +2493,27 @@ namespace CodeImp.DoomBuilder.Geometry
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
#region ================== Misc Exported Functions

View file

@ -1073,23 +1073,23 @@ namespace CodeImp.DoomBuilder.Map
public bool Join(Linedef other)
{
// Check which lines were 2 sided
bool l1was2s = ((other.Front != null) && (other.Back != null));
bool l2was2s = ((this.Front != null) && (this.Back != null));
bool otherwas2s = ((other.Front != null) && (other.Back != null));
bool thiswas2s = ((this.Front != null) && (this.Back != null));
// Get sector references
Sector l1fs = other.front != null ? other.front.Sector : null;
Sector l1bs = other.back != null ? other.back.Sector : null;
Sector l2fs = this.front != null ? this.front.Sector : null;
Sector l2bs = this.back != null ? this.back.Sector : null;
Sector otherfs = (other.front != null ? other.front.Sector : null);
Sector otherbs = (other.back != null ? other.back.Sector : null);
Sector thisfs = (this.front != null ? this.front.Sector : null);
Sector thisbs = (this.back != null ? this.back.Sector : null);
// This line has no sidedefs?
if((l2fs == null) && (l2bs == null))
if((thisfs == null) && (thisbs == null))
{
// We have no sidedefs, so we have no influence
// Nothing to change on the other line
}
// 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
// Copy my sidedefs to the other
@ -1110,44 +1110,44 @@ namespace CodeImp.DoomBuilder.Map
else
{
// Compare front sectors
if((l1fs != null) && (l1fs == l2fs))
if((otherfs != null) && (otherfs == thisfs))
{
// Copy textures
if(other.front != null) other.front.AddTexturesTo(this.back);
if(this.front != null) this.front.AddTexturesTo(other.back);
// Change sidedefs
if(!JoinChangeSidedefs(other, true, back)) return false;
// Change sidedefs?
if(back != null && !JoinChangeSidedefs(other, true, back)) return false;
}
// Compare back sectors
else if((l1bs != null) && (l1bs == l2bs))
else if((otherbs != null) && (otherbs == thisbs))
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.front);
if(this.back != null) this.back.AddTexturesTo(other.front);
// Change sidedefs
if(!JoinChangeSidedefs(other, false, front)) return false;
// Change sidedefs?
if(front != null && !JoinChangeSidedefs(other, false, front)) return false;
}
// Compare front and back
else if((l1fs != null) && (l1fs == l2bs))
else if((otherfs != null) && (otherfs == thisbs))
{
// Copy textures
if(other.front != null) other.front.AddTexturesTo(this.front);
if(this.back != null) this.back.AddTexturesTo(other.back);
// Change sidedefs
if(!JoinChangeSidedefs(other, true, front)) return false;
// Change sidedefs?
if(front != null && !JoinChangeSidedefs(other, true, front)) return false;
}
// Compare back and front
else if((l1bs != null) && (l1bs == l2fs))
else if((otherbs != null) && (otherbs == thisfs))
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.back);
if(this.front != null) this.front.AddTexturesTo(other.front);
// Change sidedefs
if(!JoinChangeSidedefs(other, false, back)) return false;
// Change sidedefs?
if(back != null && !JoinChangeSidedefs(other, false, back)) return false;
}
else
{
@ -1158,20 +1158,18 @@ namespace CodeImp.DoomBuilder.Map
if(this.start == other.end)
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.front);
if(this.back != null) this.back.AddTexturesTo(other.front);
// Change sidedefs
if(!JoinChangeSidedefs(other, false, front)) return false;
// Change sidedefs?
if(front != null && !JoinChangeSidedefs(other, false, front)) return false;
}
else
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.back);
if(this.front != null) this.front.AddTexturesTo(other.front);
// Change sidedefs
if(!JoinChangeSidedefs(other, false, back)) return false;
// Change sidedefs?
if(back != null && !JoinChangeSidedefs(other, false, back)) return false;
}
}
// This line single sided?
@ -1180,21 +1178,27 @@ namespace CodeImp.DoomBuilder.Map
// Other line with its back to this?
if(other.start == this.end)
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.front);
if(this.back != null) this.back.AddTexturesTo(other.front);
//mxd. Marked sector means other side belongs to a sector being moved...
if(otherbs == null || !otherbs.Marked)
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.front);
// Change sidedefs
if(!JoinChangeSidedefs(other, false, front)) return false;
// Change sidedefs
if(!JoinChangeSidedefs(other, false, front)) return false;
}
}
else
{
// Copy textures
if(other.front != null) other.front.AddTexturesTo(this.front);
if(this.back != null) this.back.AddTexturesTo(other.back);
//mxd. Marked sector means other side belongs to a sector being moved...
if(otherfs == null || !otherfs.Marked)
{
// Copy textures
if(other.front != null) other.front.AddTexturesTo(this.front);
// Change sidedefs
if(!JoinChangeSidedefs(other, true, front)) return false;
// Change sidedefs
if(!JoinChangeSidedefs(other, true, front)) return false;
}
}
}
else
@ -1202,33 +1206,64 @@ namespace CodeImp.DoomBuilder.Map
// This line with its back to the other?
if(this.start == other.end)
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.front);
if(this.back != null) this.back.AddTexturesTo(other.front);
//mxd. Marked sector means other side belongs to a sector being moved...
//mxd. Attach our front to other back?
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
if(!JoinChangeSidedefs(other, false, front)) return false;
// Change sidedefs (replace other back with our front)
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
{
// Copy textures
if(other.back != null) other.back.AddTexturesTo(this.back);
if(this.front != null) this.front.AddTexturesTo(other.front);
//mxd. Marked sector means other side belongs to a sector being moved...
//mxd. Attach our back to other back?
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
if(!JoinChangeSidedefs(other, false, back)) return false;
// Change sidedefs
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
if( (!l1was2s && ((other.Front != null) && (other.Back != null))) ||
(l1was2s && ((other.Front == null) || (other.Back == null))) )
if( (!otherwas2s && (other.Front != null && other.Back != null)) ||
(otherwas2s && (other.Front == null || other.Back == null)) )
other.ApplySidedFlags();
// Remove unneeded textures
if(other.front != null) other.front.RemoveUnneededTextures(!(l1was2s && l2was2s));
if(other.back != null) other.back.RemoveUnneededTextures(!(l1was2s && l2was2s));
if(other.front != null) other.front.RemoveUnneededTextures(!(otherwas2s && thiswas2s));
if(other.back != null) other.back.RemoveUnneededTextures(!(otherwas2s && thiswas2s));
}
// If either of the two lines was selected, keep the other selected
@ -1287,7 +1322,13 @@ namespace CodeImp.DoomBuilder.Map
// String representation
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;
#endif
}
#endregion

View file

@ -2167,8 +2167,7 @@ namespace CodeImp.DoomBuilder.Map
if(l1.Index == l2.Index) continue;
// Sharing vertices?
if((l1.End == l2.End) ||
(l1.End == l2.Start))
if(l1.End == l2.End || l1.End == l2.Start)
{
bool oppositedirection = (l1.End == l2.Start);
bool l2marked = l2.Marked;
@ -2183,8 +2182,8 @@ namespace CodeImp.DoomBuilder.Map
{
l1.FrontInterior = l2.FrontInterior ^ oppositedirection;
}
// If l1 is marked as new geometry, we may need to flip it to preserve
// orientation of the original geometry, and update its FrontInterior
// If l1 is marked as new geometry, we may need to flip it to preserve
// orientation of the original geometry, and update its FrontInterior
else if(l1.Marked)
{
if(oppositedirection)
@ -2209,8 +2208,7 @@ namespace CodeImp.DoomBuilder.Map
if(l1.Index == l2.Index) continue;
// Sharing vertices?
if((l1.Start == l2.End) ||
(l1.Start == l2.Start))
if(l1.Start == l2.End || l1.Start == l2.Start)
{
bool oppositedirection = (l1.Start == l2.End);
bool l2marked = l2.Marked;
@ -2225,8 +2223,8 @@ namespace CodeImp.DoomBuilder.Map
{
l1.FrontInterior = l2.FrontInterior ^ oppositedirection;
}
// If l1 is marked as new geometry, we may need to flip it to preserve
// orientation of the original geometry, and update its FrontInterior
// If l1 is marked as new geometry, we may need to flip it to preserve
// orientation of the original geometry, and update its FrontInterior
else if(l1.Marked)
{
if(oppositedirection)
@ -3098,17 +3096,6 @@ namespace CodeImp.DoomBuilder.Map
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
/// <summary>This returns a sector if given coordinates are inside one.</summary>
public Sector GetSectorByCoordinates(Vector2D pos, VisualBlockMap blockmap)

View file

@ -568,7 +568,7 @@ namespace CodeImp.DoomBuilder.Map
// This requires the sector triangulation to be up-to-date!
private RectangleF CreateBBox()
{
if(sidedefs.Count == 0) return new RectangleF(); //mxd
if(sidedefs.Count == 0) return new RectangleF(); //mxd
// Setup
float left = float.MaxValue;
@ -576,29 +576,29 @@ namespace CodeImp.DoomBuilder.Map
float right = 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)
foreach(Sidedef s in sidedefs)
{
//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 > 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 > bottom) bottom = s.Line.Start.Position.y;
processed.Add(s.Line.Start, false);
processed.Add(s.Line.Start);
}
//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 > 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 > 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
public override string ToString()
{
#if DEBUG
return "Sector " + listindex + (marked ? " (marked)" : ""); //mxd
#else
return "Sector " + listindex;
#endif
}
#endregion

View file

@ -633,6 +633,17 @@ namespace CodeImp.DoomBuilder.Map
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

View file

@ -329,7 +329,11 @@ namespace CodeImp.DoomBuilder.Map
// String representation
public override string ToString()
{
#if DEBUG
return "Vertex (" + pos + (marked ? "; marked" : "") + ")";
#else
return "Vertex (" + pos + ")";
#endif
}
#endregion

View file

@ -419,8 +419,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Move selected geometry to final position
MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptogridincrement, snaptonearest, snaptocardinaldirection);
//mxd. Used in Linedef.Join()...
General.Map.Map.MarkSelectedSectors(true, true);
// Stitch geometry
if(snaptonearest) General.Map.Map.StitchGeometry();
General.Map.Map.StitchGeometry();
// Make corrections for backward 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)));
}
}
// 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;
}
}

View file

@ -102,6 +102,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(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
base.OnDisengage();
@ -114,12 +118,21 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
if(unstablelines.Count == 0)
{
// Add sectors, which have all their linedefs selected
// (otherwise those would be destroyed after moving the selection)
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
// 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);
// 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
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

View file

@ -129,6 +129,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Process outer sidedefs
Tools.AdjustOuterSidedefs(toadjust, new HashSet<Linedef>(selectedlines));
// Split outer sectors
Tools.SplitOuterSectors(selectedlines);
}
// If only a single sector was selected, deselect it now

View file

@ -91,7 +91,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Select vertices from marks
General.Map.Map.ClearSelectedVertices();
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
base.OnDisengage();
@ -99,15 +107,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(!cancelled)
{
//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
// (otherwise those would be destroyed after moving the selection)
HashSet<Linedef> selectedlines = new HashSet<Linedef>(General.Map.Map.LinedefsFromMarkedVertices(false, true, false));
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
// Get new lines from linedef marks...
HashSet<Linedef> newlines = new HashSet<Linedef>(General.Map.Map.GetMarkedLinedefs(true));
// Process outer sidedefs
Tools.AdjustOuterSidedefs(toadjust, selectedlines);
// Marked lines were created during linedef splitting
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

View file

@ -248,6 +248,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update cached values
General.Map.Map.Update();
//mxd. Outer sectors may require some splittin...
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
// Edit new sectors?
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))

View file

@ -767,6 +767,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update cached values
General.Map.Map.Update();
//mxd. Outer sectors may require some splittin...
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
// Edit new sectors?
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))

View file

@ -92,7 +92,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.UndoRedo.CreateUndo("Grid draw");
// 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 a = (word[0] == 'u' ? "an " : "a ");
@ -114,6 +114,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Clear selection
General.Map.Map.ClearAllSelected();
//mxd. Outer sectors may require some splittin...
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
// Edit new sectors?
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
General.Interface.ShowEditSectors(newsectors);

View file

@ -385,6 +385,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update cached values
General.Map.Map.Update();
//mxd. Outer sectors may require some splittin...
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
// Edit new sectors?
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))

View file

@ -1480,23 +1480,42 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Stitch geometry
if(snaptonearest) General.Map.Map.StitchGeometry();
General.Map.Map.StitchGeometry();
// Make corrections for backward 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
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
HashSet<Sector> affectedsectors = new HashSet<Sector>(General.Map.Map.GetSelectedSectors(true));
affectedsectors.UnionWith(General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines));
Tools.AdjustOuterSidedefs(affectedsectors, new HashSet<Linedef>(selectedlines));
if(changedlines.Count > 0)
{
// 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
General.Map.Data.UpdateUsedTextures();
General.Map.Map.Update();