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_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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue