- Fixed several issues where slopes were not shown correctly in visual mode

This commit is contained in:
biwa 2019-10-06 21:56:55 +02:00
parent 6aa82e2ad9
commit c255a6e957
3 changed files with 156 additions and 131 deletions

View file

@ -756,8 +756,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
internal void RebuildElementData()
{
HashSet<Sector> effectsectors = null; //mxd
List<Linedef>[] slopelinedefpass = new List<Linedef>[] { new List<Linedef>(), new List<Linedef>() };
List<Thing>[] slopethingpass = new List<Thing>[] { new List<Thing>(), new List<Thing>() };
if(!General.Settings.EnhancedRenderingEffects) //mxd
if (!General.Settings.EnhancedRenderingEffects) //mxd
{
// Store all sectors with effects
if(sectordata != null && sectordata.Count > 0)
@ -778,6 +780,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
Dictionary<int, List<Sector>> sectortags = new Dictionary<int, List<Sector>>();
Dictionary<int, List<Linedef>> linetags = new Dictionary<int, List<Linedef>>();
sectordata = new Dictionary<Sector, SectorData>(General.Map.Map.Sectors.Count);
thingdata = new Dictionary<Thing, ThingData>(General.Map.Map.Things.Count);
@ -814,64 +817,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Find interesting linedefs (such as line slopes)
foreach(Linedef l in General.Map.Map.Linedefs)
// This also determines which slope lines belong to pass one and pass two. See https://zdoom.org/wiki/Slope
foreach (Linedef l in General.Map.Map.Linedefs)
{
// Builds a cache of linedef ids/tags. Used for slope things. Use linedef tags in UDMF
if(General.Map.UDMF)
{
foreach(int tag in l.Tags)
{
if (!linetags.ContainsKey(tag)) linetags[tag] = new List<Linedef>();
linetags[tag].Add(l);
}
}
//mxd. Rewritten to use action ID instead of number
if(l.Action == 0 || !General.Map.Config.LinedefActions.ContainsKey(l.Action)) continue;
if (l.Action == 0 || !General.Map.Config.LinedefActions.ContainsKey(l.Action)) continue;
switch(General.Map.Config.LinedefActions[l.Action].Id.ToLowerInvariant())
{
// ========== Line Set Identification (121) (see https://zdoom.org/wiki/Line_SetIdentification) ==========
// Builds a cache of linedef ids/tags. Used for slope things. Only used for Hexen format
case "line_setidentification":
int tag = l.Args[0] + l.Args[4] * 256;
if (!linetags.ContainsKey(tag)) linetags[tag] = new List<Linedef>();
linetags[tag].Add(l);
break;
// ========== Plane Align (181) (see http://zdoom.org/wiki/Plane_Align) ==========
case "plane_align":
if(((l.Args[0] == 1) || (l.Args[1] == 1)) && (l.Front != null))
{
SectorData sd = GetSectorData(l.Front.Sector);
sd.AddEffectLineSlope(l);
}
if(((l.Args[0] == 2) || (l.Args[1] == 2)) && (l.Back != null))
{
SectorData sd = GetSectorData(l.Back.Sector);
sd.AddEffectLineSlope(l);
}
slopelinedefpass[0].Add(l);
break;
// ========== Plane Copy (118) (mxd) (see http://zdoom.org/wiki/Plane_Copy) ==========
case "plane_copy":
{
//check the flags...
bool floorCopyToBack = false;
bool floorCopyToFront = false;
bool ceilingCopyToBack = false;
bool ceilingCopyToFront = false;
if(l.Args[4] > 0 && l.Args[4] != 3 && l.Args[4] != 12)
{
floorCopyToBack = (l.Args[4] & 1) == 1;
floorCopyToFront = (l.Args[4] & 2) == 2;
ceilingCopyToBack = (l.Args[4] & 4) == 4;
ceilingCopyToFront = (l.Args[4] & 8) == 8;
}
// Copy slope to front sector
if(l.Front != null)
{
if( (l.Args[0] > 0 || l.Args[1] > 0) || (l.Back != null && (floorCopyToFront || ceilingCopyToFront)) )
{
SectorData sd = GetSectorData(l.Front.Sector);
sd.AddEffectPlaneClopySlope(l, true);
}
}
// Copy slope to back sector
if(l.Back != null)
{
if( (l.Args[2] > 0 || l.Args[3] > 0) || (l.Front != null && (floorCopyToBack || ceilingCopyToBack)) )
{
SectorData sd = GetSectorData(l.Back.Sector);
sd.AddEffectPlaneClopySlope(l, false);
}
}
}
slopelinedefpass[1].Add(l);
break;
// ========== Sector 3D floor (160) (see http://zdoom.org/wiki/Sector_Set3dFloor) ==========
@ -959,31 +938,55 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
// Find interesting things (such as sector slopes)
//TODO: rewrite using classnames instead of numbers
foreach(Thing t in General.Map.Map.Things)
// Pass one for linedefs
foreach (Linedef l in slopelinedefpass[0])
{
switch(t.Type)
//mxd. Rewritten to use action ID instead of number
if (l.Action == 0 || !General.Map.Config.LinedefActions.ContainsKey(l.Action)) continue;
switch (General.Map.Config.LinedefActions[l.Action].Id.ToLowerInvariant())
{
// ========== Plane Align (181) (see http://zdoom.org/wiki/Plane_Align) ==========
case "plane_align":
if (((l.Args[0] == 1) || (l.Args[1] == 1)) && (l.Front != null))
{
SectorData sd = GetSectorData(l.Front.Sector);
sd.AddEffectLineSlope(l);
}
if (((l.Args[0] == 2) || (l.Args[1] == 2)) && (l.Back != null))
{
SectorData sd = GetSectorData(l.Back.Sector);
sd.AddEffectLineSlope(l);
}
break;
}
}
// Find interesting things (such as sector slopes)
// Pass one of slope things, and determine which one are for pass two
//TODO: rewrite using classnames instead of numbers
foreach (Thing t in General.Map.Map.Things)
{
switch (t.Type)
{
// ========== Copy slope ==========
case 9511:
case 9510:
t.DetermineSector(blockmap);
if(t.Sector != null)
{
SectorData sd = GetSectorData(t.Sector);
sd.AddEffectCopySlope(t);
}
slopethingpass[1].Add(t);
break;
// ========== Thing line slope ==========
case 9501:
case 9500:
t.DetermineSector(blockmap);
if(t.Sector != null)
if(linetags.ContainsKey(t.Args[0]))
{
SectorData sd = GetSectorData(t.Sector);
sd.AddEffectThingLineSlope(t);
foreach(Linedef ld in linetags[t.Args[0]])
{
if (ld.Line.GetSideOfLine(t.Position) < 0.0f)
GetSectorData(ld.Front.Sector).AddEffectThingLineSlope(t, ld.Front);
else if (ld.Back != null)
GetSectorData(ld.Back.Sector).AddEffectThingLineSlope(t, ld.Back);
}
}
break;
@ -991,7 +994,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
case 9503:
case 9502:
t.DetermineSector(blockmap);
if(t.Sector != null)
if (t.Sector != null)
{
SectorData sd = GetSectorData(t.Sector);
sd.AddEffectThingSlope(t);
@ -1000,6 +1003,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
// Pass two of slope things
//TODO: rewrite using classnames instead of numbers
foreach (Thing t in slopethingpass[1])
{
switch (t.Type)
{
// ========== Copy slope ==========
case 9511:
case 9510:
t.DetermineSector(blockmap);
if (t.Sector != null)
{
SectorData sd = GetSectorData(t.Sector);
sd.AddEffectCopySlope(t);
}
break;
}
}
// Find sectors with 3 vertices, because they can be sloped
foreach (Sector s in General.Map.Map.Sectors)
{
@ -1044,6 +1066,54 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
// Pass two for linedefs
foreach (Linedef l in slopelinedefpass[1])
{
if (l.Action == 0 || !General.Map.Config.LinedefActions.ContainsKey(l.Action)) continue;
switch (General.Map.Config.LinedefActions[l.Action].Id.ToLowerInvariant())
{
// ========== Plane Copy (118) (mxd) (see http://zdoom.org/wiki/Plane_Copy) ==========
case "plane_copy":
{
//check the flags...
bool floorCopyToBack = false;
bool floorCopyToFront = false;
bool ceilingCopyToBack = false;
bool ceilingCopyToFront = false;
if (l.Args[4] > 0 && l.Args[4] != 3 && l.Args[4] != 12)
{
floorCopyToBack = (l.Args[4] & 1) == 1;
floorCopyToFront = (l.Args[4] & 2) == 2;
ceilingCopyToBack = (l.Args[4] & 4) == 4;
ceilingCopyToFront = (l.Args[4] & 8) == 8;
}
// Copy slope to front sector
if (l.Front != null)
{
if ((l.Args[0] > 0 || l.Args[1] > 0) || (l.Back != null && (floorCopyToFront || ceilingCopyToFront)))
{
SectorData sd = GetSectorData(l.Front.Sector);
sd.AddEffectPlaneClopySlope(l, true);
}
}
// Copy slope to back sector
if (l.Back != null)
{
if ((l.Args[2] > 0 || l.Args[3] > 0) || (l.Front != null && (floorCopyToBack || ceilingCopyToBack)))
{
SectorData sd = GetSectorData(l.Back.Sector);
sd.AddEffectPlaneClopySlope(l, false);
}
}
}
break;
}
}
}
#endregion

View file

@ -13,11 +13,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
// The thing is in the sector that must receive the slope and the
// Thing's arg 0 indicates the linedef to start the slope at.
private Thing thing;
private Sidedef sidedef;
// Constructor
public EffectThingLineSlope(SectorData data, Thing sourcething) : base(data)
public EffectThingLineSlope(SectorData data, Thing sourcething, Sidedef sourcesidedef) : base(data)
{
thing = sourcething;
sidedef = sourcesidedef;
// New effect added: This sector needs an update!
if(data.Mode.VisualSectorExists(data.Sector))
@ -35,79 +37,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
ThingData td = data.Mode.GetThingData(thing);
Thing t = thing;
// Find the tagged line
Linedef ld = null;
foreach(Linedef l in General.Map.Map.Linedefs)
{
if(l.Tags.Contains(t.Args[0]))
{
ld = l;
break;
}
}
Linedef ld = sidedef.Line;
if(ld != null)
{
if(t.Type == 9500)
{
// Slope the floor from the linedef to thing
t.DetermineSector(data.Mode.BlockMap);
if(t.Sector != null)
{
Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.FloorHeight);
if(ld.SideOfLine(t.Position) < 0.0f)
{
Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Front.Sector.FloorHeight);
Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Front.Sector.FloorHeight);
SectorData sd = data.Mode.GetSectorData(ld.Front.Sector);
SectorData sd = data.Mode.GetSectorData(sidedef.Sector);
Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, sd.Floor.plane.GetZ(ld.Start.Position));
Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, sd.Floor.plane.GetZ(ld.End.Position));
Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + sd.Floor.plane.GetZ(t.Position));
sd.AddUpdateSector(data.Sector, true);
if(!sd.Updated) sd.Update();
td.AddUpdateSector(ld.Front.Sector, true);
if (!sd.Updated) sd.Update();
td.AddUpdateSector(sidedef.Sector, true);
sd.Floor.plane = new Plane(v1, v2, v3, true);
}
else
{
Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Back.Sector.FloorHeight);
Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Back.Sector.FloorHeight);
SectorData sd = data.Mode.GetSectorData(ld.Back.Sector);
sd.AddUpdateSector(data.Sector, true);
if(!sd.Updated) sd.Update();
td.AddUpdateSector(ld.Back.Sector, true);
sd.Floor.plane = new Plane(v2, v1, v3, true);
}
}
}
else if(t.Type == 9501)
{
// Slope the ceiling from the linedef to thing
t.DetermineSector(data.Mode.BlockMap);
if(t.Sector != null)
{
td.AddUpdateSector(t.Sector, true);
Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.CeilHeight);
if(ld.SideOfLine(t.Position) < 0.0f)
{
Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Front.Sector.CeilHeight);
Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Front.Sector.CeilHeight);
SectorData sd = data.Mode.GetSectorData(ld.Front.Sector);
SectorData sd = data.Mode.GetSectorData(sidedef.Sector);
Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, sd.Ceiling.plane.GetZ(ld.Start.Position));
Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, sd.Ceiling.plane.GetZ(ld.End.Position));
Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + sd.Ceiling.plane.GetZ(t.Position));
sd.AddUpdateSector(data.Sector, true);
td.AddUpdateSector(ld.Front.Sector, true);
if(!sd.Updated) sd.Update();
if (!sd.Updated) sd.Update();
td.AddUpdateSector(sidedef.Sector, true);
sd.Ceiling.plane = new Plane(v1, v2, v3, false);
}
else
{
Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Back.Sector.CeilHeight);
Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Back.Sector.CeilHeight);
SectorData sd = data.Mode.GetSectorData(ld.Back.Sector);
sd.AddUpdateSector(data.Sector, true);
td.AddUpdateSector(ld.Back.Sector, true);
if(!sd.Updated) sd.Update();
sd.Ceiling.plane = new Plane(v2, v1, v3, false);
}
}
}
}
}
}

View file

@ -177,9 +177,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Thing line slope effect
public void AddEffectThingLineSlope(Thing sourcething)
public void AddEffectThingLineSlope(Thing sourcething, Sidedef sourcesidedef)
{
EffectThingLineSlope e = new EffectThingLineSlope(this, sourcething);
EffectThingLineSlope e = new EffectThingLineSlope(this, sourcething, sourcesidedef);
alleffects.Add(e);
}