mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 13:51:40 +00:00
175 lines
5.7 KiB
C#
Executable file
175 lines
5.7 KiB
C#
Executable file
#region === Copyright (c) 2010 Pascal van der Heiden ===
|
|
|
|
using System.Collections.Generic;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
using CodeImp.DoomBuilder.Map;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.BuilderModes
|
|
{
|
|
internal class EffectLineSlope : SectorEffect
|
|
{
|
|
// Linedef that is used to create this effect
|
|
private readonly Linedef l;
|
|
private Plane storedfloor; //mxd. SectorData recreates floor/ceiling planes before updating effects
|
|
private Plane storedceiling; //mxd
|
|
|
|
// Constructor
|
|
public EffectLineSlope(SectorData data, Linedef sourcelinedef) : base(data)
|
|
{
|
|
l = sourcelinedef;
|
|
|
|
// New effect added: This sector needs an update!
|
|
if(data.Mode.VisualSectorExists(data.Sector))
|
|
{
|
|
BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(data.Sector);
|
|
vs.UpdateSectorGeometry(true);
|
|
}
|
|
}
|
|
|
|
// This makes sure we are updated with the source linedef information
|
|
public override void Update()
|
|
{
|
|
if(l.Front == null || l.Back == null) return; //mxd
|
|
|
|
// Find the vertex furthest from the line
|
|
Vertex foundv = null;
|
|
double founddist = -1.0f;
|
|
foreach(Sidedef sd in data.Sector.Sidedefs)
|
|
{
|
|
Vertex v = sd.IsFront ? sd.Line.Start : sd.Line.End;
|
|
double d = l.DistanceToSq(v.Position, false);
|
|
if(d > founddist)
|
|
{
|
|
foundv = v;
|
|
founddist = d;
|
|
}
|
|
}
|
|
|
|
if(foundv == null) return; //mxd
|
|
bool updatesides = false;
|
|
|
|
// Align floor with back of line
|
|
if((l.Args[0] == 1) && (l.Front.Sector == data.Sector))
|
|
{
|
|
Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.FloorHeight);
|
|
Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.FloorHeight);
|
|
Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.FloorHeight);
|
|
data.Floor.plane = (l.SideOfLine(v3) < 0.0f ? new Plane(v1, v2, v3, true) : new Plane(v2, v1, v3, true));
|
|
|
|
//mxd. Update only when actually changed
|
|
if(storedfloor != data.Floor.plane)
|
|
{
|
|
storedfloor = data.Floor.plane;
|
|
updatesides = true;
|
|
}
|
|
}
|
|
// Align floor with front of line
|
|
else if((l.Args[0] == 2) && (l.Back.Sector == data.Sector))
|
|
{
|
|
Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.FloorHeight);
|
|
Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.FloorHeight);
|
|
Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.FloorHeight);
|
|
data.Floor.plane = (l.SideOfLine(v3) < 0.0f ? new Plane(v1, v2, v3, true) : new Plane(v2, v1, v3, true));
|
|
|
|
//mxd. Update only when actually changed
|
|
if(storedfloor != data.Floor.plane)
|
|
{
|
|
storedfloor = data.Floor.plane;
|
|
updatesides = true;
|
|
}
|
|
}
|
|
|
|
// Align ceiling with back of line
|
|
if((l.Args[1] == 1) && (l.Front.Sector == data.Sector))
|
|
{
|
|
Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.CeilHeight);
|
|
Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.CeilHeight);
|
|
Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.CeilHeight);
|
|
data.Ceiling.plane = (l.SideOfLine(v3) > 0.0f ? new Plane(v1, v2, v3, false) : new Plane(v2, v1, v3, false));
|
|
|
|
//mxd. Update only when actually changed
|
|
if(storedceiling != data.Ceiling.plane)
|
|
{
|
|
storedceiling = data.Ceiling.plane;
|
|
updatesides = true;
|
|
}
|
|
}
|
|
// Align ceiling with front of line
|
|
else if((l.Args[1] == 2) && (l.Back.Sector == data.Sector))
|
|
{
|
|
Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.CeilHeight);
|
|
Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.CeilHeight);
|
|
Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.CeilHeight);
|
|
data.Ceiling.plane = (l.SideOfLine(v3) > 0.0f ? new Plane(v1, v2, v3, false) : new Plane(v2, v1, v3, false));
|
|
|
|
//mxd. Update only when actually changed
|
|
if(storedceiling != data.Ceiling.plane)
|
|
{
|
|
storedceiling = data.Ceiling.plane;
|
|
updatesides = true;
|
|
}
|
|
}
|
|
|
|
//mxd. Update outer sidedef geometry
|
|
if(updatesides)
|
|
{
|
|
UpdateSectorSides(data.Sector);
|
|
|
|
// Update sectors with PlaneCopySlope Effect...
|
|
List<SectorData> toupdate = new List<SectorData>();
|
|
foreach(Sector s in data.UpdateAlso.Keys)
|
|
{
|
|
SectorData osd = data.Mode.GetSectorDataEx(s);
|
|
if(osd == null) continue;
|
|
foreach(SectorEffect e in osd.Effects)
|
|
{
|
|
if(e is EffectPlaneCopySlope)
|
|
{
|
|
toupdate.Add(osd);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Do it in 2 steps, because SectorData.Reset() may change SectorData.UpdateAlso collection...
|
|
foreach(SectorData sd in toupdate)
|
|
{
|
|
// Update PlaneCopySlope Effect...
|
|
sd.Reset(false);
|
|
|
|
// Update outer sides...
|
|
UpdateSectorSides(sd.Sector);
|
|
}
|
|
|
|
// Update all things in the sector
|
|
foreach(Thing t in General.Map.Map.Things)
|
|
{
|
|
if(t.Sector == data.Sector)
|
|
{
|
|
if(data.Mode.VisualThingExists(t))
|
|
{
|
|
// Update thing
|
|
BaseVisualThing vt = (BaseVisualThing)data.Mode.GetVisualThing(t);
|
|
vt.Changed = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//mxd
|
|
private void UpdateSectorSides(Sector s)
|
|
{
|
|
foreach(Sidedef side in s.Sidedefs)
|
|
{
|
|
if(side.Other != null && side.Other.Sector != null && data.Mode.VisualSectorExists(side.Other.Sector))
|
|
{
|
|
BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(side.Other.Sector);
|
|
vs.GetSidedefParts(side.Other).SetupAllParts();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|