mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
Added, Game configurations: added "ignoreddirectories" parameter. It lists directory names to be ignored when loading PK3/PK7/Directory resources.
Added, Game configurations: added "ignoredextensions" parameter. It lists file extensions to be ignored when loading PK3/PK7/Directory resources. Updated: sector triangulation logic now works ~20% faster. Changed: a case when a pk3/pk7 archive contains several entries with identical filename is now treated as a warning, not as an error. Fixed, Visual mode: absolute floor/ceiling brightness should not be affected by brightness transfer effects (like 3d floors). Fixed, Draw Lines mode: in some cases unclosed sectors were created when several points were successively drawn at the same location. Updated documentation.
This commit is contained in:
parent
0b853c9d30
commit
9908e41197
8 changed files with 158 additions and 67 deletions
|
@ -27,6 +27,12 @@ bottomboundary = -32768;
|
|||
longtexturenames = false;
|
||||
|
||||
|
||||
//mxd. These directory names are ignored when loading PK3/PK7/Directory resources
|
||||
ignoreddirectories = ".svn .git";
|
||||
|
||||
|
||||
//mxd. Files with these extensions are ignored when loading PK3/PK7/Directory resources
|
||||
ignoredextensions = "wad pk3 pk7 bak backup1 backup2 backup3 zip rar 7z";
|
||||
|
||||
// Things used by the editor
|
||||
thingtypes
|
||||
|
|
|
@ -81,7 +81,6 @@ skills
|
|||
damagetypes = "None BFGSplash Drowning Slime";
|
||||
</pre>
|
||||
<br />
|
||||
|
||||
<b class="fat">internalsoundnames</b> (string) - <span class="red">GZDB only</span>.<br />
|
||||
Space-separated list of built-in logical sound names. These names won't trigger an editor warning when they are not bound to actual sounds in SNDINFO.<br />
|
||||
<br />
|
||||
|
@ -90,7 +89,22 @@ damagetypes = "None BFGSplash Drowning Slime";
|
|||
internalsoundnames = "*death *xdeath *wimpydeath *crazydeath *burndeath";
|
||||
</pre>
|
||||
<br />
|
||||
|
||||
<b class="fat">ignoredextensions</b> (string) - <span class="red">GZDB only</span>.<br />
|
||||
Space-separated list of file extensions. Files with these extensions will be ignored when loading PK3/PK7/Directory resources.<br />
|
||||
<br />
|
||||
<strong>Example:</strong>
|
||||
<pre>
|
||||
ignoredextensions = "wad pk3 pk7 bak backup1 backup2 backup3 zip rar 7z";
|
||||
</pre>
|
||||
<br />
|
||||
<b class="fat">ignoreddirectories</b> (string) - <span class="red">GZDB only</span>.<br />
|
||||
Space-separated list of directory names. These directory names are ignored when loading PK3/PK7/Directory resources. This applies to top level directories only.<br />
|
||||
<br />
|
||||
<strong>Example:</strong>
|
||||
<pre>
|
||||
ignoreddirectories = ".svn .git";
|
||||
</pre>
|
||||
<br />
|
||||
<b class="fat">linetagindicatesectors</b> (boolean)<br />
|
||||
When <b>true</b>, Doom Builder will highlight sectors associated with the same tag number when a line is highlighted. This is only really useful for Doom format maps, because Hexen format and UDMF format has no single tag on linedefs (in those formats, the arguments of the linedef's action can be tags, which also works to highlight sectors).<br />
|
||||
Default value is <b>false</b>.<br />
|
||||
|
|
|
@ -160,6 +160,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
|
||||
//mxd. Internal sounds. These logical sound names won't trigger a warning when they are not bound to actual sounds in SOUNDINFO.
|
||||
private HashSet<string> internalsoundnames;
|
||||
|
||||
//mxd. Stuff to ignore
|
||||
private HashSet<string> ignoreddirectories;
|
||||
private HashSet<string> ignoredextensions;
|
||||
|
||||
// Defaults
|
||||
private readonly List<DefinedTextureSet> texturesets;
|
||||
|
@ -291,6 +295,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
//mxd. Internal sounds
|
||||
internal HashSet<string> InternalSoundNames { get { return internalsoundnames; } }
|
||||
|
||||
//mxd. Stuff to ignore
|
||||
internal HashSet<string> IgnoredFileExtensions { get { return ignoredextensions; } }
|
||||
internal HashSet<string> IgnoredDirectoryNames { get { return ignoreddirectories; } }
|
||||
|
||||
// Defaults
|
||||
internal List<DefinedTextureSet> TextureSets { get { return texturesets; } }
|
||||
public List<ThingsFilter> ThingsFilters { get { return thingfilters; } }
|
||||
|
@ -438,6 +446,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
damagetypes = new HashSet<string>(cfg.ReadSetting("damagetypes", "None").Split(splitter, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
|
||||
internalsoundnames = new HashSet<string>(cfg.ReadSetting("internalsoundnames", string.Empty).Split(splitter, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
//mxd. Load stuff to ignore
|
||||
ignoreddirectories = new HashSet<string>(cfg.ReadSetting("ignoreddirectories", string.Empty).Split(splitter, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
|
||||
ignoredextensions = new HashSet<string>(cfg.ReadSetting("ignoredextensions", string.Empty).Split(splitter, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// Things
|
||||
LoadThingFlags();
|
||||
LoadDefaultThingFlags();
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
archive = null;
|
||||
|
||||
// Make files list
|
||||
files = new DirectoryFilesList(fileentries);
|
||||
files = new DirectoryFilesList(dl.GetDisplayName(), fileentries);
|
||||
|
||||
// Initialize without path (because we use paths relative to the PK3 file)
|
||||
Initialize();
|
||||
|
|
|
@ -374,18 +374,18 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
Vertex found = null;
|
||||
|
||||
// Go for all sides to find the right-most side
|
||||
foreach(KeyValuePair<Sidedef, bool> sd in sides)
|
||||
foreach(Sidedef sd in sides.Keys)
|
||||
{
|
||||
// First found?
|
||||
if((found == null) && !ignores.ContainsKey(sd.Key.Line.Start)) found = sd.Key.Line.Start;
|
||||
if((found == null) && !ignores.ContainsKey(sd.Key.Line.End)) found = sd.Key.Line.End;
|
||||
if((found == null) && !ignores.ContainsKey(sd.Line.Start)) found = sd.Line.Start;
|
||||
if((found == null) && !ignores.ContainsKey(sd.Line.End)) found = sd.Line.End;
|
||||
|
||||
// Compare?
|
||||
if(found != null)
|
||||
{
|
||||
// Check if more to the right than the previous found
|
||||
if((sd.Key.Line.Start.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Key.Line.Start)) found = sd.Key.Line.Start;
|
||||
if((sd.Key.Line.End.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Key.Line.End)) found = sd.Key.Line.End;
|
||||
if((sd.Line.Start.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Line.Start)) found = sd.Line.Start;
|
||||
if((sd.Line.End.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Line.End)) found = sd.Line.End;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,11 +779,16 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// This checks if a given ear is a valid (no intersections from reflex vertices)
|
||||
private static bool CheckValidEar(EarClipVertex[] t, LinkedList<EarClipVertex> reflexes)
|
||||
{
|
||||
//mxd
|
||||
Vector2D pos0 = t[0].Position;
|
||||
Vector2D pos1 = t[1].Position;
|
||||
Vector2D pos2 = t[2].Position;
|
||||
|
||||
// Go for all reflex vertices
|
||||
foreach(EarClipVertex rv in reflexes)
|
||||
{
|
||||
// Not one of the triangle corners?
|
||||
if((rv.Position != t[0].Position) && (rv.Position != t[1].Position) && (rv.Position != t[2].Position))
|
||||
if((rv.Position != pos0) && (rv.Position != pos1) && (rv.Position != pos2))
|
||||
{
|
||||
// Return false on intersection
|
||||
if(PointInsideTriangle(t, rv.MainListNode)) return false;
|
||||
|
@ -797,11 +802,12 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// This returns the 3-vertex array triangle for an ear
|
||||
private static EarClipVertex[] GetTriangle(EarClipVertex v)
|
||||
{
|
||||
EarClipVertex[] t = new EarClipVertex[3];
|
||||
t[0] = (v.MainListNode.Previous == null) ? v.MainListNode.List.Last.Value : v.MainListNode.Previous.Value;
|
||||
t[1] = v;
|
||||
t[2] = (v.MainListNode.Next == null) ? v.MainListNode.List.First.Value : v.MainListNode.Next.Value;
|
||||
return t;
|
||||
return new []
|
||||
{
|
||||
(v.MainListNode.Previous == null) ? v.MainListNode.List.Last.Value : v.MainListNode.Previous.Value,
|
||||
v,
|
||||
(v.MainListNode.Next == null) ? v.MainListNode.List.First.Value : v.MainListNode.Next.Value
|
||||
};
|
||||
}
|
||||
|
||||
// This checks if a vertex is reflex (corner > 180 deg) or convex (corner < 180 deg)
|
||||
|
@ -820,18 +826,23 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// If the triangle has no area, there can never be a point inside
|
||||
if(TriangleHasArea(t))
|
||||
{
|
||||
float lineside01 = Line2D.GetSideOfLine(t[0].Position, t[1].Position, p.Value.Position);
|
||||
float lineside12 = Line2D.GetSideOfLine(t[1].Position, t[2].Position, p.Value.Position);
|
||||
float lineside20 = Line2D.GetSideOfLine(t[2].Position, t[0].Position, p.Value.Position);
|
||||
//mxd
|
||||
Vector2D pos0 = t[0].Position;
|
||||
Vector2D pos1 = t[1].Position;
|
||||
Vector2D pos2 = t[2].Position;
|
||||
|
||||
float lineside01 = Line2D.GetSideOfLine(pos0, pos1, p.Value.Position);
|
||||
float lineside12 = Line2D.GetSideOfLine(pos1, pos2, p.Value.Position);
|
||||
float lineside20 = Line2D.GetSideOfLine(pos2, pos0, p.Value.Position);
|
||||
float u_on_line = 0.5f;
|
||||
|
||||
// If point p is on the line of an edge, find out where on the edge segment p is.
|
||||
if(lineside01 == 0.0f)
|
||||
u_on_line = Line2D.GetNearestOnLine(t[0].Position, t[1].Position, p.Value.Position);
|
||||
u_on_line = Line2D.GetNearestOnLine(pos0, pos1, p.Value.Position);
|
||||
else if(lineside12 == 0.0f)
|
||||
u_on_line = Line2D.GetNearestOnLine(t[1].Position, t[2].Position, p.Value.Position);
|
||||
u_on_line = Line2D.GetNearestOnLine(pos1, pos2, p.Value.Position);
|
||||
else if(lineside20 == 0.0f)
|
||||
u_on_line = Line2D.GetNearestOnLine(t[2].Position, t[0].Position, p.Value.Position);
|
||||
u_on_line = Line2D.GetNearestOnLine(pos2, pos0, p.Value.Position);
|
||||
|
||||
// If any of the lineside results are 0 then that means the point p lies on that edge and we
|
||||
// need to test if the lines adjacent to the point p are in the triangle or not.
|
||||
|
@ -877,9 +888,10 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// Line is inside triangle, because p2 is
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test if p2 is on an edge of the triangle and if it is we would
|
||||
// like to know where on the edge segment p2 is
|
||||
else if(s01 == 0.0f)
|
||||
if(s01 == 0.0f)
|
||||
{
|
||||
p2_on_edge = Line2D.GetNearestOnLine(t[0].Position, t[1].Position, p2);
|
||||
p1_on_same_edge = Line2D.GetSideOfLine(t[0].Position, t[1].Position, p1);
|
||||
|
@ -912,13 +924,10 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
Line2D t20 = new Line2D(t[2].Position, t[0].Position);
|
||||
float pu, pt;
|
||||
|
||||
// Test intersections
|
||||
t01.GetIntersection(p, out pu, out pt);
|
||||
if(!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f)) return true;
|
||||
t12.GetIntersection(p, out pu, out pt);
|
||||
if(!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f)) return true;
|
||||
t20.GetIntersection(p, out pu, out pt);
|
||||
if(!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f)) return true;
|
||||
//mxd. Test intersections
|
||||
if(t01.GetIntersection(p, out pu, out pt)) return true;
|
||||
if(t12.GetIntersection(p, out pu, out pt)) return true;
|
||||
if(t20.GetIntersection(p, out pu, out pt)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -926,24 +935,33 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// This checks if the triangle has an area greater than 0
|
||||
private static bool TriangleHasArea(EarClipVertex[] t)
|
||||
{
|
||||
return ((t[0].Position.x * (t[1].Position.y - t[2].Position.y) +
|
||||
t[1].Position.x * (t[2].Position.y - t[0].Position.y) +
|
||||
t[2].Position.x * (t[0].Position.y - t[1].Position.y)) != 0.0f);
|
||||
Vector2D tp0 = t[0].Position;
|
||||
Vector2D tp1 = t[1].Position;
|
||||
Vector2D tp2 = t[2].Position;
|
||||
|
||||
return ((tp0.x * (tp1.y - tp2.y) +
|
||||
tp1.x * (tp2.y - tp0.y) +
|
||||
tp2.x * (tp0.y - tp1.y)) != 0.0f);
|
||||
}
|
||||
|
||||
// This adds an array of vertices
|
||||
private static void AddTriangleToList(EarClipVertex[] triangle, List<Vector2D> verticeslist, List<Sidedef> sidedefslist, bool last)
|
||||
{
|
||||
// Create triangle
|
||||
verticeslist.Add(triangle[0].Position);
|
||||
sidedefslist.Add(triangle[0].Sidedef);
|
||||
verticeslist.Add(triangle[1].Position);
|
||||
sidedefslist.Add(triangle[1].Sidedef);
|
||||
verticeslist.Add(triangle[2].Position);
|
||||
if(!last) sidedefslist.Add(null); else sidedefslist.Add(triangle[2].Sidedef);
|
||||
//mxd
|
||||
EarClipVertex v0 = triangle[0];
|
||||
EarClipVertex v1 = triangle[1];
|
||||
EarClipVertex v2 = triangle[2];
|
||||
|
||||
// Create triangle
|
||||
verticeslist.Add(v0.Position);
|
||||
sidedefslist.Add(v0.Sidedef);
|
||||
verticeslist.Add(v1.Position);
|
||||
sidedefslist.Add(v1.Sidedef);
|
||||
verticeslist.Add(v2.Position);
|
||||
sidedefslist.Add(!last ? null : v2.Sidedef);
|
||||
|
||||
// Modify the first earclipvertex of this triangle, it no longer lies along a sidedef
|
||||
triangle[0].Sidedef = null;
|
||||
v0.Sidedef = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -29,11 +29,6 @@ namespace CodeImp.DoomBuilder.IO
|
|||
{
|
||||
#region ================== Constants (mxd)
|
||||
|
||||
private static HashSet<string> EXLUDE_EXTENSIONS = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"wad", "pk3", "pk7", "bak", "backup1", "backup2", "backup3", "zip", "rar", "7z"
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -68,17 +63,26 @@ namespace CodeImp.DoomBuilder.IO
|
|||
wadentries.Add(file);
|
||||
continue;
|
||||
}
|
||||
if(EXLUDE_EXTENSIONS.Contains(e.extension)) continue;
|
||||
|
||||
if(entries.ContainsKey(e.filepathname))
|
||||
throw new IOException("Multiple files with the same filename in the same directory are not allowed. See: \"" + e.filepathname + "\"");
|
||||
|
||||
if(General.Map.Config.IgnoredFileExtensions.Contains(e.extension)) continue;
|
||||
|
||||
bool skipfolder = false;
|
||||
foreach(string ef in General.Map.Config.IgnoredDirectoryNames)
|
||||
{
|
||||
if(e.path.StartsWith(ef + Path.DirectorySeparatorChar))
|
||||
{
|
||||
skipfolder = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(skipfolder) continue;
|
||||
|
||||
entries.Add(e.filepathname, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor for custom list
|
||||
public DirectoryFilesList(ICollection<DirectoryFileEntry> sourceentries)
|
||||
public DirectoryFilesList(string resourcename, ICollection<DirectoryFileEntry> sourceentries)
|
||||
{
|
||||
entries = new Dictionary<string, DirectoryFileEntry>(sourceentries.Count, StringComparer.OrdinalIgnoreCase);
|
||||
wadentries = new List<string>();
|
||||
|
@ -89,10 +93,26 @@ namespace CodeImp.DoomBuilder.IO
|
|||
wadentries.Add(e.filepathname);
|
||||
continue;
|
||||
}
|
||||
if(EXLUDE_EXTENSIONS.Contains(e.extension)) continue;
|
||||
|
||||
if(General.Map.Config.IgnoredFileExtensions.Contains(e.extension)) continue;
|
||||
|
||||
bool skipfolder = false;
|
||||
foreach(string ef in General.Map.Config.IgnoredDirectoryNames)
|
||||
{
|
||||
if(e.path.StartsWith(ef + Path.DirectorySeparatorChar))
|
||||
{
|
||||
skipfolder = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(skipfolder) continue;
|
||||
|
||||
if(entries.ContainsKey(e.filepathname))
|
||||
throw new IOException("Multiple files with the same filename in the same directory are not allowed. See: \"" + e.filepathname + "\"");
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Resource \"" + resourcename + "\" contains multiple files with the same filename. See: \"" + e.filepathname + "\"");
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.Add(e.filepathname, e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -545,6 +545,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
pos.y > General.Map.Config.TopBoundary || pos.y < General.Map.Config.BottomBoundary)
|
||||
return false;
|
||||
|
||||
//mxd. Avoid zero-length lines...
|
||||
if(points.Count > 0)
|
||||
{
|
||||
Vector2D delta = points[points.Count - 1].pos - pos;
|
||||
if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f))
|
||||
return true;
|
||||
}
|
||||
|
||||
DrawnVertex newpoint = new DrawnVertex();
|
||||
newpoint.pos = pos;
|
||||
newpoint.stitch = stitch;
|
||||
|
|
|
@ -56,6 +56,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
private bool floorchanged;
|
||||
private bool ceilingchanged;
|
||||
|
||||
//mxd. Absolute lights are not affected by brightness transfers...
|
||||
private bool lightfloorabsolute;
|
||||
private bool lightceilingabsolute;
|
||||
private int lightfloor;
|
||||
private int lightceiling;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -288,17 +294,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// Fetch ZDoom fields
|
||||
int color = sector.Fields.GetValue("lightcolor", -1);
|
||||
int flight = sector.Fields.GetValue("lightfloor", 0);
|
||||
bool fabs = sector.Fields.GetValue("lightfloorabsolute", false);
|
||||
int clight = sector.Fields.GetValue("lightceiling", 0);
|
||||
bool cabs = sector.Fields.GetValue("lightceilingabsolute", false);
|
||||
lightfloor = sector.Fields.GetValue("lightfloor", 0);
|
||||
lightfloorabsolute = sector.Fields.GetValue("lightfloorabsolute", false);
|
||||
lightceiling = sector.Fields.GetValue("lightceiling", 0);
|
||||
lightceilingabsolute = sector.Fields.GetValue("lightceilingabsolute", false);
|
||||
|
||||
// Determine colors & light levels
|
||||
PixelColor lightcolor = PixelColor.FromInt(color);
|
||||
if(!fabs) flight = sector.Brightness + flight;
|
||||
if(!cabs) clight = sector.Brightness + clight;
|
||||
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(flight));
|
||||
PixelColor ceilingbrightness = PixelColor.FromInt(mode.CalculateBrightness(clight));
|
||||
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));
|
||||
PixelColor floorcolor = PixelColor.Modulate(lightcolor, floorbrightness);
|
||||
PixelColor ceilingcolor = PixelColor.Modulate(lightcolor, ceilingbrightness);
|
||||
floor.color = floorcolor.WithAlpha(255).ToInt();
|
||||
|
@ -357,7 +363,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
lightlevels[lightlevels.Count - 1].colorbelow = stored.colorbelow;
|
||||
lightlevels[lightlevels.Count - 1].brightnessbelow = stored.brightnessbelow;
|
||||
lightlevels[lightlevels.Count - 1].color = GetLevelColor(stored);
|
||||
lightlevels[lightlevels.Count - 1].color = GetLevelColor(stored, lightlevels[lightlevels.Count - 1]);
|
||||
}
|
||||
|
||||
//mxd. Cast light properties from top to bottom
|
||||
|
@ -378,12 +384,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
l.colorbelow = stored.colorbelow;
|
||||
l.brightnessbelow = stored.brightnessbelow;
|
||||
l.color = GetLevelColor(stored);
|
||||
l.color = GetLevelColor(stored, l);
|
||||
}
|
||||
else if(l.restrictlighting)
|
||||
{
|
||||
if(!pl.restrictlighting && pl != ceiling) stored = pl;
|
||||
l.color = GetLevelColor(stored);
|
||||
l.color = GetLevelColor(stored, l);
|
||||
|
||||
// This is the bottom side of extrafloor with "restrict lighting" flag. Make it cast stored light props.
|
||||
if(l.type == SectorLevelType.Ceiling)
|
||||
|
@ -394,10 +400,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Use light and color settings from previous layer
|
||||
l.colorbelow = pl.colorbelow;
|
||||
l.brightnessbelow = pl.brightnessbelow;
|
||||
l.color = GetLevelColor(pl);
|
||||
l.color = GetLevelColor(pl, l);
|
||||
|
||||
// Also colorize previous layer using next higher level color
|
||||
if(i + 2 < lightlevels.Count) pl.color = GetLevelColor(lightlevels[i + 2]);
|
||||
if(i + 2 < lightlevels.Count) pl.color = GetLevelColor(lightlevels[i + 2], pl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -439,7 +445,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
if(src.colorbelow.a > 0 && src.brightnessbelow != -1)
|
||||
{
|
||||
// Only surface brightness is retained when a glowing flat is used as extrafloor texture
|
||||
if(!l.affectedbyglow) l.color = GetLevelColor(src);
|
||||
if(!l.affectedbyglow) l.color = GetLevelColor(src, l);
|
||||
|
||||
// Transfer brightnessbelow and colorbelow if current level is not extrafloor top
|
||||
if(!(l.extrafloor && l.type == SectorLevelType.Floor))
|
||||
|
@ -594,9 +600,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
//mxd
|
||||
private int GetLevelColor(SectorLevel src)
|
||||
private int GetLevelColor(SectorLevel src, SectorLevel target)
|
||||
{
|
||||
PixelColor brightness = PixelColor.FromInt(mode.CalculateBrightness(src.brightnessbelow));
|
||||
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));
|
||||
|
||||
PixelColor color = PixelColor.Modulate(src.colorbelow, brightness);
|
||||
return color.WithAlpha(255).ToInt();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue