2010-09-02 20:42:38 +00:00
|
|
|
#region === Copyright (c) 2010 Pascal van der Heiden ===
|
|
|
|
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
using System;
|
2010-09-02 20:42:38 +00:00
|
|
|
using System.Collections.Generic;
|
2015-04-14 11:33:57 +00:00
|
|
|
using CodeImp.DoomBuilder.GZBuilder.Data;
|
2010-09-02 20:42:38 +00:00
|
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
|
|
using CodeImp.DoomBuilder.Map;
|
|
|
|
using CodeImp.DoomBuilder.Rendering;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2012-11-27 21:12:20 +00:00
|
|
|
namespace CodeImp.DoomBuilder.BuilderModes
|
2010-09-02 20:42:38 +00:00
|
|
|
{
|
|
|
|
internal class SectorData
|
|
|
|
{
|
|
|
|
#region ================== Variables
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// VisualMode
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly BaseVisualMode mode;
|
2010-09-11 20:14:36 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
// Sector for which this data is
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly Sector sector;
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Levels have been updated?
|
|
|
|
private bool updated;
|
2010-09-02 20:42:38 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// This prevents recursion
|
|
|
|
private bool isupdating;
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// All planes in the sector that cast or are affected by light
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly List<SectorLevel> lightlevels;
|
2010-09-10 13:17:38 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Effects
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly List<SectorEffect> alleffects;
|
|
|
|
private readonly List<Effect3DFloor> extrafloors;
|
2016-04-19 20:40:42 +00:00
|
|
|
private readonly EffectGlowingFlat glowingflateffect; //mxd
|
2015-04-14 11:33:57 +00:00
|
|
|
|
|
|
|
internal GlowingFlatData CeilingGlow; //mxd
|
|
|
|
internal GlowingFlatData FloorGlow; //mxd
|
|
|
|
internal Plane FloorGlowPlane; //mxd
|
|
|
|
internal Plane CeilingGlowPlane; //mxd
|
2010-09-11 20:14:36 +00:00
|
|
|
|
|
|
|
// Sectors that must be updated when this sector is changed
|
|
|
|
// The boolean value is the 'includeneighbours' of the UpdateSectorGeometry function which
|
|
|
|
// indicates if the sidedefs of neighbouring sectors should also be rebuilt.
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly Dictionary<Sector, bool> updatesectors;
|
2010-09-03 15:12:07 +00:00
|
|
|
|
|
|
|
// Original floor and ceiling levels
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly SectorLevel floor;
|
2015-11-20 14:31:54 +00:00
|
|
|
private readonly SectorLevel floorbase; // mxd. Sector floor level, unaffected by glow / light properties transfer
|
2014-07-18 11:25:08 +00:00
|
|
|
private readonly SectorLevel ceiling;
|
2015-11-20 14:31:54 +00:00
|
|
|
private readonly SectorLevel ceilingbase; // mxd. Sector ceiling level, unaffected by glow / light properties transfer
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-17 06:11:56 +00:00
|
|
|
// This helps keeping track of changes
|
|
|
|
// otherwise we update ceiling/floor too much
|
|
|
|
private bool floorchanged;
|
|
|
|
private bool ceilingchanged;
|
|
|
|
|
2016-10-24 19:19:11 +00:00
|
|
|
//mxd. Absolute lights are not affected by brightness transfers...
|
|
|
|
private bool lightfloorabsolute;
|
|
|
|
private bool lightceilingabsolute;
|
|
|
|
private int lightfloor;
|
|
|
|
private int lightceiling;
|
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
#endregion
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
#region ================== Properties
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
public Sector Sector { get { return sector; } }
|
2010-09-11 20:14:36 +00:00
|
|
|
public bool Updated { get { return updated; } }
|
2010-09-17 06:11:56 +00:00
|
|
|
public bool FloorChanged { get { return floorchanged; } set { floorchanged |= value; } }
|
|
|
|
public bool CeilingChanged { get { return ceilingchanged; } set { ceilingchanged |= value; } }
|
2010-09-10 13:17:38 +00:00
|
|
|
public List<SectorLevel> LightLevels { get { return lightlevels; } }
|
2010-09-11 20:14:36 +00:00
|
|
|
public List<Effect3DFloor> ExtraFloors { get { return extrafloors; } }
|
2016-05-15 00:38:41 +00:00
|
|
|
public List<SectorEffect> Effects { get { return alleffects; } } //mxd
|
2010-09-03 15:12:07 +00:00
|
|
|
public SectorLevel Floor { get { return floor; } }
|
|
|
|
public SectorLevel Ceiling { get { return ceiling; } }
|
2010-09-11 20:14:36 +00:00
|
|
|
public BaseVisualMode Mode { get { return mode; } }
|
|
|
|
public Dictionary<Sector, bool> UpdateAlso { get { return updatesectors; } }
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
#endregion
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
#region ================== Constructor / Destructor
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
// Constructor
|
2010-09-03 15:12:07 +00:00
|
|
|
public SectorData(BaseVisualMode mode, Sector s)
|
2010-09-02 20:42:38 +00:00
|
|
|
{
|
|
|
|
// Initialize
|
2010-09-11 20:14:36 +00:00
|
|
|
this.mode = mode;
|
2010-09-02 20:42:38 +00:00
|
|
|
this.sector = s;
|
2010-09-11 20:14:36 +00:00
|
|
|
this.updated = false;
|
2010-09-17 06:11:56 +00:00
|
|
|
this.floorchanged = false;
|
|
|
|
this.ceilingchanged = false;
|
2010-09-10 13:17:38 +00:00
|
|
|
this.lightlevels = new List<SectorLevel>(2);
|
2010-09-11 20:14:36 +00:00
|
|
|
this.extrafloors = new List<Effect3DFloor>(1);
|
|
|
|
this.alleffects = new List<SectorEffect>(1);
|
|
|
|
this.updatesectors = new Dictionary<Sector, bool>(2);
|
|
|
|
this.floor = new SectorLevel(sector, SectorLevelType.Floor);
|
2015-11-20 14:31:54 +00:00
|
|
|
this.floorbase = new SectorLevel(sector, SectorLevelType.Floor); //mxd
|
2010-09-11 20:14:36 +00:00
|
|
|
this.ceiling = new SectorLevel(sector, SectorLevelType.Ceiling);
|
2015-11-20 14:31:54 +00:00
|
|
|
this.ceilingbase = new SectorLevel(sector, SectorLevelType.Ceiling); //mxd
|
2016-04-19 20:40:42 +00:00
|
|
|
this.glowingflateffect = new EffectGlowingFlat(this); //mxd
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Add ceiling and floor
|
|
|
|
lightlevels.Add(floor);
|
|
|
|
lightlevels.Add(ceiling);
|
2016-04-19 20:40:42 +00:00
|
|
|
|
|
|
|
BasicSetup();
|
2010-09-11 20:14:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Public Methods
|
|
|
|
|
|
|
|
// 3D Floor effect
|
|
|
|
public void AddEffect3DFloor(Linedef sourcelinedef)
|
|
|
|
{
|
|
|
|
Effect3DFloor e = new Effect3DFloor(this, sourcelinedef);
|
|
|
|
extrafloors.Add(e);
|
|
|
|
alleffects.Add(e);
|
2016-02-15 14:06:46 +00:00
|
|
|
|
|
|
|
//mxd. Extrafloor neighbours should be updated when extrafloor is changed
|
|
|
|
foreach(Sidedef sd in this.Sector.Sidedefs)
|
|
|
|
{
|
|
|
|
if(sd.Other != null && sd.Other.Sector != null)
|
|
|
|
AddUpdateSector(sd.Other.Sector, false);
|
|
|
|
}
|
2010-09-11 20:14:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Brightness level effect
|
|
|
|
public void AddEffectBrightnessLevel(Linedef sourcelinedef)
|
|
|
|
{
|
|
|
|
EffectBrightnessLevel e = new EffectBrightnessLevel(this, sourcelinedef);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
2015-04-01 12:51:26 +00:00
|
|
|
//mxd. Transfer Floor Brightness effect
|
|
|
|
public void AddEffectTransferFloorBrightness(Linedef sourcelinedef)
|
|
|
|
{
|
|
|
|
EffectTransferFloorBrightness e = new EffectTransferFloorBrightness(this, sourcelinedef);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
//mxd. Transfer Floor Brightness effect
|
|
|
|
public void AddEffectTransferCeilingBrightness(Linedef sourcelinedef)
|
|
|
|
{
|
|
|
|
EffectTransferCeilingBrightness e = new EffectTransferCeilingBrightness(this, sourcelinedef);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Line slope effect
|
|
|
|
public void AddEffectLineSlope(Linedef sourcelinedef)
|
|
|
|
{
|
|
|
|
EffectLineSlope e = new EffectLineSlope(this, sourcelinedef);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
2013-04-16 12:52:40 +00:00
|
|
|
//mxd. Plane copy slope effect
|
2014-05-19 13:33:38 +00:00
|
|
|
public void AddEffectPlaneClopySlope(Linedef sourcelinedef, bool front)
|
|
|
|
{
|
2014-05-06 08:21:10 +00:00
|
|
|
EffectPlaneCopySlope e = new EffectPlaneCopySlope(this, sourcelinedef, front);
|
2013-04-16 12:52:40 +00:00
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Copy slope effect
|
|
|
|
public void AddEffectCopySlope(Thing sourcething)
|
|
|
|
{
|
|
|
|
EffectCopySlope e = new EffectCopySlope(this, sourcething);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Thing line slope effect
|
|
|
|
public void AddEffectThingLineSlope(Thing sourcething)
|
|
|
|
{
|
|
|
|
EffectThingLineSlope e = new EffectThingLineSlope(this, sourcething);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
2010-09-14 19:14:44 +00:00
|
|
|
|
2014-01-20 11:44:41 +00:00
|
|
|
// Thing slope effect
|
|
|
|
public void AddEffectThingSlope(Thing sourcething)
|
|
|
|
{
|
|
|
|
EffectThingSlope e = new EffectThingSlope(this, sourcething);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
|
|
|
|
2010-09-14 19:14:44 +00:00
|
|
|
// Thing vertex slope effect
|
|
|
|
public void AddEffectThingVertexSlope(List<Thing> sourcethings, bool slopefloor)
|
|
|
|
{
|
|
|
|
EffectThingVertexSlope e = new EffectThingVertexSlope(this, sourcethings, slopefloor);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
2012-11-22 15:32:27 +00:00
|
|
|
|
2013-09-11 09:47:53 +00:00
|
|
|
//mxd. Add UDMF vertex offset effect
|
2014-05-19 13:33:38 +00:00
|
|
|
public void AddEffectVertexOffset()
|
|
|
|
{
|
2013-09-11 09:47:53 +00:00
|
|
|
EffectUDMFVertexOffset e = new EffectUDMFVertexOffset(this);
|
|
|
|
alleffects.Add(e);
|
|
|
|
}
|
2010-09-11 20:14:36 +00:00
|
|
|
|
|
|
|
// This adds a sector for updating
|
|
|
|
public void AddUpdateSector(Sector s, bool includeneighbours)
|
|
|
|
{
|
|
|
|
updatesectors[s] = includeneighbours;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This adds a sector level
|
|
|
|
public void AddSectorLevel(SectorLevel level)
|
|
|
|
{
|
|
|
|
// Note: Inserting before the end so that the ceiling stays
|
|
|
|
// at the end and the floor at the beginning
|
|
|
|
lightlevels.Insert(lightlevels.Count - 1, level);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This resets this sector data and all sectors that require updating after me
|
2016-02-15 18:53:56 +00:00
|
|
|
/*public void Reset()
|
2010-09-11 20:14:36 +00:00
|
|
|
{
|
2015-04-14 11:33:57 +00:00
|
|
|
if(isupdating) return;
|
2010-09-11 20:14:36 +00:00
|
|
|
isupdating = true;
|
|
|
|
|
|
|
|
// This is set to false so that this sector is rebuilt the next time it is needed!
|
|
|
|
updated = false;
|
|
|
|
|
2010-09-14 19:14:44 +00:00
|
|
|
// The visual sector associated is now outdated
|
|
|
|
if(mode.VisualSectorExists(sector))
|
|
|
|
{
|
|
|
|
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(sector);
|
|
|
|
vs.UpdateSectorGeometry(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Also reset the sectors that depend on this sector
|
2010-09-11 20:14:36 +00:00
|
|
|
foreach(KeyValuePair<Sector, bool> s in updatesectors)
|
|
|
|
{
|
|
|
|
SectorData sd = mode.GetSectorData(s.Key);
|
|
|
|
sd.Reset();
|
|
|
|
}
|
|
|
|
|
2016-02-15 18:53:56 +00:00
|
|
|
isupdating = false;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
//mxd. This marks this sector data and all sector datas that require updating as not updated
|
|
|
|
public void Reset(bool resetneighbours)
|
|
|
|
{
|
|
|
|
if(isupdating) return;
|
|
|
|
isupdating = true;
|
|
|
|
|
|
|
|
// This is set to false so that this sector is rebuilt the next time it is needed!
|
|
|
|
updated = false;
|
|
|
|
|
|
|
|
// The visual sector associated is now outdated
|
|
|
|
if(mode.VisualSectorExists(sector))
|
|
|
|
{
|
|
|
|
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(sector);
|
|
|
|
vs.Changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset the sectors that depend on this sector
|
|
|
|
if(resetneighbours)
|
|
|
|
{
|
|
|
|
foreach(KeyValuePair<Sector, bool> s in updatesectors)
|
|
|
|
{
|
|
|
|
SectorData sd = mode.GetSectorDataEx(s.Key);
|
|
|
|
if(sd != null) sd.Reset(s.Value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
isupdating = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This sets up the basic floor and ceiling, as they would be in normal Doom circumstances
|
|
|
|
private void BasicSetup()
|
|
|
|
{
|
2014-08-25 11:15:19 +00:00
|
|
|
//mxd
|
2014-10-17 11:55:08 +00:00
|
|
|
if(sector.FloorSlope.GetLengthSq() > 0 && !float.IsNaN(sector.FloorSlopeOffset / sector.FloorSlope.z))
|
2014-08-25 11:15:19 +00:00
|
|
|
{
|
|
|
|
// Sloped plane
|
|
|
|
floor.plane = new Plane(sector.FloorSlope, sector.FloorSlopeOffset);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Normal (flat) floor plane
|
|
|
|
floor.plane = new Plane(new Vector3D(0, 0, 1), -sector.FloorHeight);
|
|
|
|
}
|
|
|
|
|
2014-10-17 11:55:08 +00:00
|
|
|
if(sector.CeilSlope.GetLengthSq() > 0 && !float.IsNaN(sector.CeilSlopeOffset / sector.CeilSlope.z))
|
2014-08-25 11:15:19 +00:00
|
|
|
{
|
|
|
|
// Sloped plane
|
2014-10-17 11:55:08 +00:00
|
|
|
ceiling.plane = new Plane(sector.CeilSlope, sector.CeilSlopeOffset);
|
2014-08-25 11:15:19 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Normal (flat) ceiling plane
|
|
|
|
ceiling.plane = new Plane(new Vector3D(0, 0, -1), sector.CeilHeight);
|
|
|
|
}
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-15 20:41:40 +00:00
|
|
|
// Fetch ZDoom fields
|
|
|
|
int color = sector.Fields.GetValue("lightcolor", -1);
|
2016-10-24 19:19:11 +00:00
|
|
|
lightfloor = sector.Fields.GetValue("lightfloor", 0);
|
|
|
|
lightfloorabsolute = sector.Fields.GetValue("lightfloorabsolute", false);
|
|
|
|
lightceiling = sector.Fields.GetValue("lightceiling", 0);
|
|
|
|
lightceilingabsolute = sector.Fields.GetValue("lightceilingabsolute", false);
|
2010-09-15 20:41:40 +00:00
|
|
|
|
|
|
|
// Determine colors & light levels
|
2010-09-03 15:12:07 +00:00
|
|
|
PixelColor lightcolor = PixelColor.FromInt(color);
|
2016-10-24 19:19:11 +00:00
|
|
|
if(!lightfloorabsolute) lightfloor = sector.Brightness + lightfloor;
|
|
|
|
if(!lightceilingabsolute) lightceiling = sector.Brightness + lightceiling;
|
|
|
|
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightfloor));
|
|
|
|
PixelColor ceilingbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightceiling));
|
2010-09-03 15:12:07 +00:00
|
|
|
PixelColor floorcolor = PixelColor.Modulate(lightcolor, floorbrightness);
|
|
|
|
PixelColor ceilingcolor = PixelColor.Modulate(lightcolor, ceilingbrightness);
|
|
|
|
floor.color = floorcolor.WithAlpha(255).ToInt();
|
2010-09-06 06:09:22 +00:00
|
|
|
floor.brightnessbelow = sector.Brightness;
|
|
|
|
floor.colorbelow = lightcolor.WithAlpha(255);
|
2010-09-03 15:12:07 +00:00
|
|
|
ceiling.color = ceilingcolor.WithAlpha(255).ToInt();
|
|
|
|
ceiling.brightnessbelow = sector.Brightness;
|
2010-09-06 06:09:22 +00:00
|
|
|
ceiling.colorbelow = lightcolor.WithAlpha(255);
|
2015-11-20 14:31:54 +00:00
|
|
|
|
|
|
|
//mxd. Store a copy of initial settings
|
|
|
|
floor.CopyProperties(floorbase);
|
|
|
|
ceiling.CopyProperties(ceilingbase);
|
2016-03-25 14:06:00 +00:00
|
|
|
|
|
|
|
//mxd. We need sector brightness here, unaffected by custom ceiling brightness...
|
|
|
|
ceilingbase.brightnessbelow = sector.Brightness;
|
|
|
|
ceilingbase.color = PixelColor.FromInt(mode.CalculateBrightness(sector.Brightness)).WithAlpha(255).ToInt();
|
2016-04-19 20:40:42 +00:00
|
|
|
|
|
|
|
//mxd
|
|
|
|
glowingflateffect.Update();
|
2010-09-03 06:03:28 +00:00
|
|
|
}
|
2010-09-06 06:09:22 +00:00
|
|
|
|
2013-09-11 09:47:53 +00:00
|
|
|
//mxd
|
2014-12-03 23:15:26 +00:00
|
|
|
public void UpdateForced()
|
|
|
|
{
|
2013-09-11 09:47:53 +00:00
|
|
|
updated = false;
|
|
|
|
Update();
|
|
|
|
}
|
2012-05-11 12:28:20 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// When no geometry has been changed and no effects have been added or removed,
|
|
|
|
// you can call this again to update existing effects. The effects will update
|
|
|
|
// the existing SectorLevels to match with any changes.
|
|
|
|
public void Update()
|
2010-09-03 06:03:28 +00:00
|
|
|
{
|
2013-09-11 09:47:53 +00:00
|
|
|
if(isupdating || updated) return;
|
2010-09-11 20:14:36 +00:00
|
|
|
isupdating = true;
|
2010-09-09 21:16:16 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Set floor/ceiling to their original setup
|
|
|
|
BasicSetup();
|
2010-09-09 06:13:20 +00:00
|
|
|
|
2010-09-11 20:14:36 +00:00
|
|
|
// Update all effects
|
2015-04-14 11:33:57 +00:00
|
|
|
foreach(SectorEffect e in alleffects) e.Update();
|
2010-09-03 06:03:28 +00:00
|
|
|
|
2015-11-20 14:31:54 +00:00
|
|
|
//mxd. Do complicated light level shenanigans only when there are extrafloors
|
|
|
|
if(lightlevels.Count > 2)
|
2014-09-23 23:29:04 +00:00
|
|
|
{
|
2015-11-20 14:31:54 +00:00
|
|
|
// Sort the levels
|
2014-09-23 23:29:04 +00:00
|
|
|
SectorLevelComparer comparer = new SectorLevelComparer(sector);
|
2015-11-20 14:31:54 +00:00
|
|
|
lightlevels.Sort(0, lightlevels.Count, comparer);
|
2014-09-23 23:29:04 +00:00
|
|
|
|
2015-11-20 14:31:54 +00:00
|
|
|
// Now that we know the levels in this sector (and in the right order)
|
|
|
|
// we can determine the lighting in between and on the levels.
|
|
|
|
SectorLevel stored = ceilingbase;
|
2015-02-06 21:03:20 +00:00
|
|
|
|
2015-11-20 14:31:54 +00:00
|
|
|
//mxd. Special cases...
|
|
|
|
if(lightlevels[lightlevels.Count - 1].disablelighting)
|
2015-02-06 21:03:20 +00:00
|
|
|
{
|
2015-11-20 14:31:54 +00:00
|
|
|
lightlevels[lightlevels.Count - 1].colorbelow = stored.colorbelow;
|
|
|
|
lightlevels[lightlevels.Count - 1].brightnessbelow = stored.brightnessbelow;
|
2016-10-24 19:19:11 +00:00
|
|
|
lightlevels[lightlevels.Count - 1].color = GetLevelColor(stored, lightlevels[lightlevels.Count - 1]);
|
2015-02-06 21:03:20 +00:00
|
|
|
}
|
2015-04-01 12:51:26 +00:00
|
|
|
|
2015-11-20 14:31:54 +00:00
|
|
|
//mxd. Cast light properties from top to bottom
|
|
|
|
for(int i = lightlevels.Count - 2; i >= 0; i--)
|
2015-04-01 12:51:26 +00:00
|
|
|
{
|
2015-11-20 14:31:54 +00:00
|
|
|
SectorLevel l = lightlevels[i];
|
|
|
|
SectorLevel pl = lightlevels[i + 1];
|
|
|
|
|
2015-12-24 11:59:37 +00:00
|
|
|
// Glow levels don't cast light
|
|
|
|
if(pl.type == SectorLevelType.Glow && lightlevels.Count > i + 2) pl = lightlevels[i + 2];
|
|
|
|
|
2015-11-20 14:31:54 +00:00
|
|
|
if(l.lighttype == LightLevelType.TYPE1)
|
2015-04-01 12:51:26 +00:00
|
|
|
{
|
2015-11-20 14:31:54 +00:00
|
|
|
stored = pl;
|
2015-04-01 12:51:26 +00:00
|
|
|
}
|
2015-11-20 14:31:54 +00:00
|
|
|
// Use stored light params when "disablelighting" flag is set
|
|
|
|
else if(l.disablelighting)
|
2015-04-01 12:51:26 +00:00
|
|
|
{
|
|
|
|
l.colorbelow = stored.colorbelow;
|
2015-11-20 14:31:54 +00:00
|
|
|
l.brightnessbelow = stored.brightnessbelow;
|
2016-10-24 19:19:11 +00:00
|
|
|
l.color = GetLevelColor(stored, l);
|
2015-11-20 14:31:54 +00:00
|
|
|
}
|
|
|
|
else if(l.restrictlighting)
|
|
|
|
{
|
|
|
|
if(!pl.restrictlighting && pl != ceiling) stored = pl;
|
2016-10-24 19:19:11 +00:00
|
|
|
l.color = GetLevelColor(stored, l);
|
2015-11-20 14:31:54 +00:00
|
|
|
|
|
|
|
// This is the bottom side of extrafloor with "restrict lighting" flag. Make it cast stored light props.
|
|
|
|
if(l.type == SectorLevelType.Ceiling)
|
|
|
|
{
|
|
|
|
// Special case: 2 intersecting extrafloors with "restrictlighting" flag...
|
|
|
|
if(pl.restrictlighting && pl.type == SectorLevelType.Floor && pl.sector.Index != l.sector.Index)
|
|
|
|
{
|
|
|
|
// Use light and color settings from previous layer
|
|
|
|
l.colorbelow = pl.colorbelow;
|
|
|
|
l.brightnessbelow = pl.brightnessbelow;
|
2016-10-24 19:19:11 +00:00
|
|
|
l.color = GetLevelColor(pl, l);
|
2015-11-20 14:31:54 +00:00
|
|
|
|
|
|
|
// Also colorize previous layer using next higher level color
|
2016-10-24 19:19:11 +00:00
|
|
|
if(i + 2 < lightlevels.Count) pl.color = GetLevelColor(lightlevels[i + 2], pl);
|
2015-11-20 14:31:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
l.colorbelow = stored.colorbelow;
|
|
|
|
l.brightnessbelow = stored.brightnessbelow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Bottom TYPE1 border requires special handling...
|
|
|
|
else if(l.lighttype == LightLevelType.TYPE1_BOTTOM)
|
|
|
|
{
|
|
|
|
// Use brightness and color from previous light level when it's between TYPE1 and TYPE1_BOTTOM levels
|
|
|
|
if(pl.type == SectorLevelType.Light && pl.lighttype != LightLevelType.TYPE1)
|
|
|
|
{
|
|
|
|
l.brightnessbelow = pl.brightnessbelow;
|
|
|
|
l.colorbelow = pl.colorbelow;
|
|
|
|
}
|
|
|
|
// Use brightness and color from the light level above TYPE1 level
|
|
|
|
else if(stored.type == SectorLevelType.Light)
|
|
|
|
{
|
|
|
|
l.brightnessbelow = stored.brightnessbelow;
|
|
|
|
l.colorbelow = stored.colorbelow;
|
|
|
|
}
|
|
|
|
// Otherwise light values from the real ceiling are used
|
|
|
|
}
|
|
|
|
else if(l.lighttype == LightLevelType.UNKNOWN)
|
|
|
|
{
|
|
|
|
// Use stored light level when previous one has "disablelighting" flag
|
|
|
|
// or is the lower boundary of an extrafloor with "restrictlighting" flag
|
|
|
|
SectorLevel src = (pl.disablelighting || (pl.restrictlighting && pl.type == SectorLevelType.Ceiling) ? stored : pl);
|
2016-03-25 14:06:00 +00:00
|
|
|
|
|
|
|
// Don't change real ceiling light when previous level has "disablelighting" flag
|
|
|
|
// Don't change anything when light properties were reset before hitting floor (otherwise floor UDMF brightness will be lost)
|
|
|
|
if((src == ceilingbase && l == ceiling)
|
|
|
|
|| (src == ceiling && l == floor && src.LightPropertiesMatch(ceilingbase)))
|
2015-11-20 14:31:54 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// Transfer color and brightness if previous level has them
|
|
|
|
if(src.colorbelow.a > 0 && src.brightnessbelow != -1)
|
|
|
|
{
|
|
|
|
// Only surface brightness is retained when a glowing flat is used as extrafloor texture
|
2016-10-24 19:19:11 +00:00
|
|
|
if(!l.affectedbyglow) l.color = GetLevelColor(src, l);
|
2015-11-20 14:31:54 +00:00
|
|
|
|
|
|
|
// Transfer brightnessbelow and colorbelow if current level is not extrafloor top
|
|
|
|
if(!(l.extrafloor && l.type == SectorLevelType.Floor))
|
|
|
|
{
|
|
|
|
l.brightnessbelow = src.brightnessbelow;
|
|
|
|
l.colorbelow = src.colorbelow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Store bottom extrafloor level if it doesn't have "restrictlighting" or "restrictlighting" flags set
|
|
|
|
if(l.extrafloor && l.type == SectorLevelType.Ceiling && !l.restrictlighting && !l.disablelighting) stored = l;
|
2015-04-01 12:51:26 +00:00
|
|
|
}
|
2016-03-25 14:06:00 +00:00
|
|
|
|
|
|
|
// Reset lighting?
|
|
|
|
if(l.resetlighting) stored = ceilingbase;
|
2015-04-01 12:51:26 +00:00
|
|
|
}
|
2010-09-07 09:35:45 +00:00
|
|
|
}
|
2010-09-14 19:14:44 +00:00
|
|
|
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
//mxd. Apply ceiling glow effect?
|
|
|
|
if(CeilingGlow != null)
|
2015-04-14 11:33:57 +00:00
|
|
|
{
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
if(CeilingGlow.Fullbright) ceiling.color = PixelColor.INT_WHITE;
|
|
|
|
else if(CeilingGlow.Fullblack) ceiling.color = PixelColor.INT_BLACK;
|
2015-04-14 11:33:57 +00:00
|
|
|
}
|
|
|
|
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
//mxd. Apply floor glow effect?
|
2015-04-14 11:33:57 +00:00
|
|
|
if(FloorGlow != null)
|
|
|
|
{
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
// Update floor color
|
|
|
|
if(FloorGlow.Fullbright) floor.color = PixelColor.INT_WHITE;
|
|
|
|
else if(FloorGlow.Fullblack) floor.color = PixelColor.INT_BLACK;
|
|
|
|
|
|
|
|
// Update brightness
|
|
|
|
floor.brightnessbelow = (FloorGlow.Fullbright ? 255 : Math.Max(128, floor.brightnessbelow));
|
2015-04-14 11:33:57 +00:00
|
|
|
|
|
|
|
if(floor.colorbelow.ToInt() == 0)
|
|
|
|
{
|
|
|
|
byte bb = (byte)floor.brightnessbelow;
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
floor.colorbelow = new PixelColor(255, bb, bb, bb);
|
2015-04-14 11:33:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
|
|
|
//mxd
|
|
|
|
floor.affectedbyglow = (FloorGlow != null);
|
|
|
|
ceiling.affectedbyglow = (CeilingGlow != null);
|
|
|
|
|
2010-09-17 06:11:56 +00:00
|
|
|
floorchanged = false;
|
|
|
|
ceilingchanged = false;
|
|
|
|
updated = true;
|
2010-09-11 20:14:36 +00:00
|
|
|
isupdating = false;
|
2010-09-03 06:03:28 +00:00
|
|
|
}
|
2010-09-06 06:09:22 +00:00
|
|
|
|
|
|
|
// This returns the level above the given point
|
|
|
|
public SectorLevel GetLevelAbove(Vector3D pos)
|
|
|
|
{
|
|
|
|
SectorLevel found = null;
|
|
|
|
float dist = float.MaxValue;
|
|
|
|
|
2010-09-10 13:17:38 +00:00
|
|
|
foreach(SectorLevel l in lightlevels)
|
2010-09-06 06:09:22 +00:00
|
|
|
{
|
|
|
|
float d = l.plane.GetZ(pos) - pos.z;
|
|
|
|
if((d > 0.0f) && (d < dist))
|
|
|
|
{
|
|
|
|
dist = d;
|
|
|
|
found = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2015-04-01 12:51:26 +00:00
|
|
|
//mxd. This returns the level above the given point or the level given point is located on
|
|
|
|
public SectorLevel GetLevelAboveOrAt(Vector3D pos)
|
|
|
|
{
|
|
|
|
SectorLevel found = null;
|
|
|
|
float dist = float.MaxValue;
|
|
|
|
|
|
|
|
foreach(SectorLevel l in lightlevels)
|
|
|
|
{
|
|
|
|
float d = l.plane.GetZ(pos) - pos.z;
|
|
|
|
if((d >= 0.0f) && (d < dist))
|
|
|
|
{
|
|
|
|
dist = d;
|
|
|
|
found = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2010-09-08 06:09:03 +00:00
|
|
|
// This returns the level above the given point
|
|
|
|
public SectorLevel GetCeilingAbove(Vector3D pos)
|
|
|
|
{
|
|
|
|
SectorLevel found = null;
|
|
|
|
float dist = float.MaxValue;
|
|
|
|
|
2010-09-10 13:17:38 +00:00
|
|
|
foreach(SectorLevel l in lightlevels)
|
2010-09-08 06:09:03 +00:00
|
|
|
{
|
|
|
|
if(l.type == SectorLevelType.Ceiling)
|
|
|
|
{
|
|
|
|
float d = l.plane.GetZ(pos) - pos.z;
|
|
|
|
if((d > 0.0f) && (d < dist))
|
|
|
|
{
|
|
|
|
dist = d;
|
|
|
|
found = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2010-09-06 06:09:22 +00:00
|
|
|
// This returns the level below the given point
|
|
|
|
public SectorLevel GetLevelBelow(Vector3D pos)
|
|
|
|
{
|
|
|
|
SectorLevel found = null;
|
|
|
|
float dist = float.MaxValue;
|
|
|
|
|
2010-09-10 13:17:38 +00:00
|
|
|
foreach(SectorLevel l in lightlevels)
|
2010-09-06 06:09:22 +00:00
|
|
|
{
|
|
|
|
float d = pos.z - l.plane.GetZ(pos);
|
|
|
|
if((d > 0.0f) && (d < dist))
|
|
|
|
{
|
|
|
|
dist = d;
|
|
|
|
found = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2010-09-08 06:09:03 +00:00
|
|
|
// This returns the floor below the given point
|
|
|
|
public SectorLevel GetFloorBelow(Vector3D pos)
|
|
|
|
{
|
|
|
|
SectorLevel found = null;
|
|
|
|
float dist = float.MaxValue;
|
|
|
|
|
2010-09-10 13:17:38 +00:00
|
|
|
foreach(SectorLevel l in lightlevels)
|
2010-09-08 06:09:03 +00:00
|
|
|
{
|
|
|
|
if(l.type == SectorLevelType.Floor)
|
|
|
|
{
|
|
|
|
float d = pos.z - l.plane.GetZ(pos);
|
|
|
|
if((d > 0.0f) && (d < dist))
|
|
|
|
{
|
|
|
|
dist = d;
|
|
|
|
found = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
2016-04-22 13:28:23 +00:00
|
|
|
|
|
|
|
//mxd
|
2016-10-24 19:19:11 +00:00
|
|
|
private int GetLevelColor(SectorLevel src, SectorLevel target)
|
2016-04-22 13:28:23 +00:00
|
|
|
{
|
2016-10-24 19:19:11 +00:00
|
|
|
PixelColor brightness;
|
|
|
|
if(lightfloorabsolute && target == floor)
|
|
|
|
brightness = PixelColor.FromInt(mode.CalculateBrightness(lightfloor));
|
|
|
|
else if(lightceilingabsolute && target == ceiling)
|
|
|
|
brightness = PixelColor.FromInt(mode.CalculateBrightness(lightceiling));
|
|
|
|
else
|
|
|
|
brightness = PixelColor.FromInt(mode.CalculateBrightness(src.brightnessbelow));
|
|
|
|
|
2016-04-22 13:28:23 +00:00
|
|
|
PixelColor color = PixelColor.Modulate(src.colorbelow, brightness);
|
|
|
|
return color.WithAlpha(255).ToInt();
|
|
|
|
}
|
2010-09-03 15:12:07 +00:00
|
|
|
|
2010-09-02 20:42:38 +00:00
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|