From 88ae5688366622e5b075a3ed88ae51bf0fadc497 Mon Sep 17 00:00:00 2001 From: MaxED Date: Tue, 23 Sep 2014 21:34:50 +0000 Subject: [PATCH] Added: Map Analysis: added "Check texture alignment" check. Currently it works only in Doom/Hexen map formats. --- Source/Core/Geometry/Tools.cs | 51 ++++ .../Plugins/BuilderModes/BuilderModes.csproj | 2 + .../ErrorChecks/CheckTextureAlignment.cs | 278 ++++++++++++++++++ .../ErrorChecks/ResultTexturesMisaligned.cs | 96 ++++++ .../VisualModes/BaseVisualMode.cs | 66 +---- .../BuilderModes/VisualModes/VisualLower.cs | 2 +- .../VisualModes/VisualMiddleDouble.cs | 2 +- .../VisualModes/VisualMiddleSingle.cs | 2 +- .../BuilderModes/VisualModes/VisualUpper.cs | 2 +- 9 files changed, 440 insertions(+), 61 deletions(-) create mode 100644 Source/Plugins/BuilderModes/ErrorChecks/CheckTextureAlignment.cs create mode 100644 Source/Plugins/BuilderModes/ErrorChecks/ResultTexturesMisaligned.cs diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index e492131d..ce6aee52 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -1759,6 +1759,57 @@ namespace CodeImp.DoomBuilder.Geometry ((sd.LongLowTexture == texturelongname) && sd.LowRequired()) || ((sd.LongMiddleTexture == texturelongname) && (sd.MiddleRequired() || sd.LongMiddleTexture != MapSet.EmptyLongName)) ; } + + //mxd. This converts offsetY from/to "normalized" offset for given upper wall + public static float GetSidedefTopOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized) + { + if(side.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag) || side.Other == null || side.Other.Sector == null) + return offset; + + //if we don't have UpperUnpegged flag, normalize offset + float surfaceHeight = (side.Sector.CeilHeight - side.Other.Sector.CeilHeight) * scaleY; + + if(fromNormalized) return (float)Math.Round(offset + surfaceHeight); + return (float)Math.Round(offset - surfaceHeight); + } + + //mxd. This converts offsetY from/to "normalized" offset for given middle wall + public static float GetSidedefMiddleOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized) + { + if(!side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || side.Sector == null) + return offset; + + // If we have LowerUnpegged flag, normalize offset + // Absolute value is used because ceiling height of vavoom-type 3d floors + // is lower than floor height + float surfaceHeight = (Math.Abs(side.Sector.CeilHeight - side.Sector.FloorHeight)) * scaleY; + + if(fromNormalized) return (float)Math.Round(offset + surfaceHeight); + return (float)Math.Round(offset - surfaceHeight); + } + + //mxd. This converts offsetY from/to "normalized" offset for given lower wall + public static float GetSidedefBottomOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized) + { + float surfaceHeight; + if(side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag)) + { + if(side.Other == null || side.Other.Sector == null || side.Sector.CeilTexture != General.Map.Config.SkyFlatName || + side.Other.Sector.CeilTexture != General.Map.Config.SkyFlatName) + return offset; + + //normalize offset the way Doom does it when front and back sector's ceiling is sky + surfaceHeight = (side.Sector.CeilHeight - side.Other.Sector.CeilHeight) * scaleY; + } + else + { + //normalize offset + surfaceHeight = (side.Sector.CeilHeight - side.Other.Sector.FloorHeight) * scaleY; + } + + if(fromNormalized) return (float)Math.Round(offset + surfaceHeight); + return (float)Math.Round(offset - surfaceHeight); + } #endregion diff --git a/Source/Plugins/BuilderModes/BuilderModes.csproj b/Source/Plugins/BuilderModes/BuilderModes.csproj index 91714990..9acb5007 100644 --- a/Source/Plugins/BuilderModes/BuilderModes.csproj +++ b/Source/Plugins/BuilderModes/BuilderModes.csproj @@ -232,6 +232,7 @@ + @@ -242,6 +243,7 @@ + diff --git a/Source/Plugins/BuilderModes/ErrorChecks/CheckTextureAlignment.cs b/Source/Plugins/BuilderModes/ErrorChecks/CheckTextureAlignment.cs new file mode 100644 index 00000000..e22500bd --- /dev/null +++ b/Source/Plugins/BuilderModes/ErrorChecks/CheckTextureAlignment.cs @@ -0,0 +1,278 @@ +#region ================== Namespaces + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Threading; +using CodeImp.DoomBuilder.Data; +using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.VisualModes; + +#endregion + +namespace CodeImp.DoomBuilder.BuilderModes.ErrorChecks +{ + [ErrorChecker("Check texture alignment", true, 1000)] + public class CheckTextureAlignment : ErrorChecker + { + #region ================== Constants + + private const int PROGRESS_STEP = 100; + + #endregion + + #region ================== Constructor / Destructor + + // Constructor + public CheckTextureAlignment() + { + // Total progress is done when all lines are checked + SetTotalProgress(General.Map.Map.Linedefs.Count / PROGRESS_STEP); + } + + #endregion + + #region ================== Methods + + // This runs the check + public override void Run() + { + Dictionary> donesides = new Dictionary>(); + int progress = 0; + int stepprogress = 0; + bool udmf = General.Map.UDMF; + + // Go for all the liendefs + foreach(Linedef l in General.Map.Map.Linedefs) + { + // Check if not already done + if (donesides.ContainsKey(l.Index)) continue; + + // Check if we need to align any part of the front sidedef + if (l.Front != null) + { + CheckTopAlignment(l.Front, donesides, udmf); + CheckMiddleAlignment(l.Front, donesides, udmf); + CheckBottomAlignment(l.Front, donesides, udmf); + } + + // Check if we need to align any part of the back sidedef + if (l.Back != null) + { + CheckTopAlignment(l.Back, donesides, udmf); + CheckMiddleAlignment(l.Back, donesides, udmf); + CheckBottomAlignment(l.Back, donesides, udmf); + } + + // Handle thread interruption + try { Thread.Sleep(0); } catch(ThreadInterruptedException) { return; } + + // We are making progress! + if ((++progress / PROGRESS_STEP) > stepprogress) + { + stepprogress = (progress / PROGRESS_STEP); + AddProgress(1); + } + } + } + + #endregion + + #region ================== UDMF alignment checks + + private void CheckTopAlignment(Sidedef sidedef, Dictionary> donesides, bool udmf) + { + if (!sidedef.HighRequired() || sidedef.LongHighTexture == MapSet.EmptyLongName) return; + if (!udmf) + { + CheckClassicTopAlignment(sidedef, donesides); + return; + } + + } + + private void CheckMiddleAlignment(Sidedef sidedef, Dictionary> donesides, bool udmf) + { + if (!sidedef.MiddleRequired() || sidedef.LongMiddleTexture == MapSet.EmptyLongName) return; + if (!udmf) + { + CheckClassicMiddleAlignment(sidedef, donesides); + return; + } + + } + + private void CheckBottomAlignment(Sidedef sidedef, Dictionary> donesides, bool udmf) + { + if (!sidedef.LowRequired() || sidedef.LongLowTexture == MapSet.EmptyLongName) return; + if (!udmf) + { + CheckClassicBottomAlignment(sidedef, donesides); + return; + } + + } + + private void AddProcessedSides(Sidedef s1, Sidedef s2, Dictionary> donesides) + { + // Add them both ways + if (!donesides.ContainsKey(s1.Index)) donesides.Add(s1.Index, new Dictionary()); + donesides[s1.Index].Add(s2.Index, false); + + if (!donesides.ContainsKey(s2.Index)) donesides.Add(s2.Index, new Dictionary()); + donesides[s2.Index].Add(s1.Index, false); + } + + #endregion + + #region ================== Classic alignment checks + + private void CheckClassicTopAlignment(Sidedef sidedef, Dictionary> donesides) + { + int x = sidedef.OffsetX; + int y = (int)Tools.GetSidedefTopOffsetY(sidedef, sidedef.OffsetY, 1.0f, false); + CheckClassicAlignment(sidedef, x, y, BuilderModesTools.GetSidedefPartSize(sidedef, VisualGeometryType.WALL_UPPER), sidedef.HighTexture, donesides); + } + + private void CheckClassicMiddleAlignment(Sidedef sidedef, Dictionary> donesides) + { + int x = sidedef.OffsetX; + int y = (int)Tools.GetSidedefMiddleOffsetY(sidedef, sidedef.OffsetY, 1.0f, false); + CheckClassicAlignment(sidedef, x, y, BuilderModesTools.GetSidedefPartSize(sidedef, VisualGeometryType.WALL_MIDDLE), sidedef.MiddleTexture, donesides); + } + + private void CheckClassicBottomAlignment(Sidedef sidedef, Dictionary> donesides) + { + int x = sidedef.OffsetX; + int y = (int)Tools.GetSidedefBottomOffsetY(sidedef, sidedef.OffsetY, 1.0f, false); + CheckClassicAlignment(sidedef, x, y, BuilderModesTools.GetSidedefPartSize(sidedef, VisualGeometryType.WALL_LOWER), sidedef.LowTexture, donesides); + } + + private void CheckClassicAlignment(Sidedef sidedef, int offsetx, int offsety, Rectangle partsize, string texturename, Dictionary> donesides) + { + ImageData texture = General.Map.Data.GetTextureImage(texturename); + if (!texture.IsImageLoaded) return; + + float scalex = (General.Map.Config.ScaledTextureOffsets && !texture.WorldPanning) ? texture.Scale.x : 1.0f; + float scaley = (General.Map.Config.ScaledTextureOffsets && !texture.WorldPanning) ? texture.Scale.y : 1.0f; + + // Move offsets to proper range + offsetx %= texture.Width; + if (offsetx < 0) offsetx += texture.Width; + offsety %= texture.Height; + if (offsety < 0) offsety += texture.Height; + + // Check if current line is aligned to other sides + ICollection lines = (sidedef.IsFront ? sidedef.Line.Start.Linedefs : sidedef.Line.End.Linedefs); + Vertex v = sidedef.IsFront ? sidedef.Line.Start : sidedef.Line.End; + + foreach(Linedef line in lines) + { + if (line.Index == sidedef.Line.Index) continue; + + Sidedef target = null; + if (line.Front != null && line.End == v) target = line.Front; + else if (line.Back != null && line.Start == v) target = line.Back; + + // No target or laready processed? + if (target == null || (donesides.ContainsKey(sidedef.Index) && donesides[sidedef.Index].ContainsKey(target.Index))) + continue; + + // Get expected texture offsets + int alignedY = GetExpectedOffsetY(sidedef, target, texturename, texture.Height, scaley, partsize); + if (alignedY == int.MinValue) continue; // alignedY == int.MinValue means no textures on target and current source part match + + alignedY %= texture.Height; + if (alignedY < 0) alignedY += texture.Height; + + int alignedX = (target.OffsetX + (int)Math.Round(target.Line.Length / scalex)) % texture.Width; + if (alignedX < 0) alignedX += texture.Width; + + // Submit result if target offsets don't match expected ones + if (offsetx != alignedX || offsety != alignedY) + { +#if DEBUG //TODO: remove this + string msg = "Case 1: '"+texturename+"' source " + sidedef.Line.Index + " (" + (sidedef.IsFront ? "front" : "back") + + "), target " + target.Line.Index + " (" + (target.IsFront ? "front" : "back") + + "): expected: " + alignedX + ", " + alignedY + + "; actual [source]: " + offsetx + ", " + offsety; + + SubmitResult(new ResultTexturesMisaligned(sidedef, target, texturename, msg)); +#else + SubmitResult(new ResultTexturesMisaligned(sidedef, target, texturename)); +#endif + AddProcessedSides(sidedef, target, donesides); + } + } + + // Check if other sides are aligned to current side + lines = (sidedef.IsFront ? sidedef.Line.End.Linedefs : sidedef.Line.Start.Linedefs); + v = (sidedef.IsFront ? sidedef.Line.End : sidedef.Line.Start); + + foreach(Linedef line in lines) + { + if (line.Index == sidedef.Line.Index) continue; + + Sidedef target = null; + if (line.Front != null && line.Start == v) target = line.Front; + else if (line.Back != null && line.End == v) target = line.Back; + + // No target or laready processed? + if (target == null || (donesides.ContainsKey(sidedef.Index) && donesides[sidedef.Index].ContainsKey(target.Index))) + continue; + + // Get expected texture offsets + int alignedY = GetExpectedOffsetY(sidedef, target, texturename, texture.Height, scaley, partsize); + if (alignedY == int.MinValue) continue; // alignedY == int.MinValue means no textures on target and current source part match + + alignedY %= texture.Height; + if (alignedY < 0) alignedY += texture.Height; + + int alignedX = (target.OffsetX - (int)Math.Round(sidedef.Line.Length / scalex)) % texture.Width; + if (alignedX < 0) alignedX += texture.Width; + + // Submit result if target offsets don't match expected ones + if (offsetx != alignedX || offsety != alignedY) + { +#if DEBUG //TODO: remove this + string msg = "Case 2: '" + texturename + "' source " + sidedef.Line.Index + " (" + (sidedef.IsFront ? "front" : "back") + + "), target " + target.Line.Index + " (" + (target.IsFront ? "front" : "back") + + "): expected: " + alignedX + ", " + alignedY + + "; actual [source]: " + offsetx + ", " + offsety; + + SubmitResult(new ResultTexturesMisaligned(target, sidedef, texturename, msg)); +#else + SubmitResult(new ResultTexturesMisaligned(target, sidedef, texturename)); +#endif + AddProcessedSides(sidedef, target, donesides); + } + } + } + + private int GetExpectedOffsetY(Sidedef source, Sidedef target, string texturename, int textureheight, float scaleY, Rectangle partsize) + { + if (target.MiddleTexture == texturename + && partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_MIDDLE))) + { + return ((int)Tools.GetSidedefMiddleOffsetY(target, target.OffsetY, 1.0f, false) + (int)Math.Round((target.Sector.CeilHeight - source.Sector.CeilHeight) / scaleY)) % textureheight; + } + + if (target.HighTexture == texturename + && partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_UPPER))) + { + return ((int)Tools.GetSidedefTopOffsetY(target, target.OffsetY, 1.0f, false) + (int)Math.Round((target.Sector.CeilHeight - source.Sector.CeilHeight) / scaleY)) % textureheight; + } + + if (target.LowTexture == texturename + && partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_LOWER))) + { + return ((int)Tools.GetSidedefBottomOffsetY(target, target.OffsetY, 1.0f, false) + (int)Math.Round((target.Sector.CeilHeight - source.Sector.CeilHeight) / scaleY)) % textureheight; + } + + return int.MinValue; + } + + #endregion + } +} diff --git a/Source/Plugins/BuilderModes/ErrorChecks/ResultTexturesMisaligned.cs b/Source/Plugins/BuilderModes/ErrorChecks/ResultTexturesMisaligned.cs new file mode 100644 index 00000000..13e9e8d1 --- /dev/null +++ b/Source/Plugins/BuilderModes/ErrorChecks/ResultTexturesMisaligned.cs @@ -0,0 +1,96 @@ +#region ================== Namespaces + +using System; +using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.Rendering; + +#endregion + +namespace CodeImp.DoomBuilder.BuilderModes +{ + public class ResultTexturesMisaligned : ErrorResult + { + + #region ================== Variables + + private readonly Sidedef side1; + private readonly Sidedef side2; + private readonly string texturename; + + #endregion + + #region ================== Properties + + public override int Buttons { get { return 0; } } + + #endregion + + #region ================== Constructor / Destructor + +#if DEBUG //TODO: remove this + public ResultTexturesMisaligned(Sidedef side1, Sidedef side2, string texturename, string message) + { + // Initialize + this.side1 = side1; + this.side2 = side2; + this.texturename = texturename; + viewobjects.Add(side1.Line); + viewobjects.Add(side2.Line); + hidden = (side1.IgnoredErrorChecks.Contains(this.GetType()) && side2.IgnoredErrorChecks.Contains(this.GetType())); + description = "Textures are not aligned on given sidedefs. Some players may not like that.\n" + message; + } +#else + public ResultTexturesMisaligned(Sidedef side1, Sidedef side2, string texturename) + { + // Initialize + this.side1 = side1; + this.side2 = side2; + this.texturename = texturename; + viewobjects.Add(side1.Line); + viewobjects.Add(side2.Line); + hidden = (side1.IgnoredErrorChecks.Contains(this.GetType()) && side2.IgnoredErrorChecks.Contains(this.GetType())); + description = "Textures are not aligned on given sidedefs. Some players may not like that."; + } +#endif + + #endregion + + #region ================== Methods + + // This sets if this result is displayed in ErrorCheckForm (mxd) + internal override void Hide(bool hide) { + hidden = hide; + Type t = this.GetType(); + if (hide) + { + side1.IgnoredErrorChecks.Add(t); + side2.IgnoredErrorChecks.Add(t); + } + else + { + if(side1.IgnoredErrorChecks.Contains(t)) side1.IgnoredErrorChecks.Remove(t); + if(side2.IgnoredErrorChecks.Contains(t)) side2.IgnoredErrorChecks.Remove(t); + } + } + + // This must return the string that is displayed in the listbox + public override string ToString() + { + return "Texture '" + texturename + "' is not aligned on linedefs " + side1.Line.Index + " (" + (side1.IsFront ? "front" : "back") + + ") and " + side2.Line.Index + " (" + (side2.IsFront ? "front" : "back") + ")"; + } + + // Rendering + public override void PlotSelection(IRenderer2D renderer) + { + renderer.PlotLinedef(side1.Line, General.Colors.Selection); + renderer.PlotLinedef(side2.Line, General.Colors.Selection); + renderer.PlotVertex(side1.Line.Start, ColorCollection.VERTICES); + renderer.PlotVertex(side1.Line.End, ColorCollection.VERTICES); + renderer.PlotVertex(side2.Line.Start, ColorCollection.VERTICES); + renderer.PlotVertex(side2.Line.End, ColorCollection.VERTICES); + } + + #endregion + } +} diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index 35d3c241..218100aa 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -3262,10 +3262,10 @@ namespace CodeImp.DoomBuilder.BuilderModes float ystartalign = start.Sidedef.OffsetY; switch(start.GeometryType) { case VisualGeometryType.WALL_UPPER: - ystartalign += GetTopOffsetY(start.Sidedef, start.Sidedef.Fields.GetValue("offsety_top", 0.0f), first.scaleY, false);//mxd + ystartalign += Tools.GetSidedefTopOffsetY(start.Sidedef, start.Sidedef.Fields.GetValue("offsety_top", 0.0f), first.scaleY, false);//mxd break; case VisualGeometryType.WALL_MIDDLE: - ystartalign += GetMiddleOffsetY(start.Sidedef, start.Sidedef.Fields.GetValue("offsety_mid", 0.0f), first.scaleY, false);//mxd + ystartalign += Tools.GetSidedefMiddleOffsetY(start.Sidedef, start.Sidedef.Fields.GetValue("offsety_mid", 0.0f), first.scaleY, false);//mxd break; case VisualGeometryType.WALL_MIDDLE_3D: //mxd. 3d-floors are not affected by Lower/Upper unpegged flags ystartalign += first.controlSide.OffsetY - (start.Sidedef.Sector.CeilHeight - first.ceilingHeight); @@ -3273,7 +3273,7 @@ namespace CodeImp.DoomBuilder.BuilderModes ystartalign += first.controlSide.Fields.GetValue("offsety_mid", 0.0f); break; case VisualGeometryType.WALL_LOWER: - ystartalign += GetBottomOffsetY(start.Sidedef, start.Sidedef.Fields.GetValue("offsety_bottom", 0.0f), first.scaleY, false);//mxd + ystartalign += Tools.GetSidedefBottomOffsetY(start.Sidedef, start.Sidedef.Fields.GetValue("offsety_bottom", 0.0f), first.scaleY, false);//mxd break; } @@ -3362,9 +3362,9 @@ namespace CodeImp.DoomBuilder.BuilderModes offset = (float)Math.Round(offset); //mxd if(matchtop) - j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, GetTopOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd + j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, Tools.GetSidedefTopOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd if(matchbottom) - j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, GetBottomOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd + j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, Tools.GetSidedefBottomOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd if(matchmid) { //mxd. Side is part of a 3D floor? if(j.sidedef.Index != j.controlSide.Index) { @@ -3372,7 +3372,7 @@ namespace CodeImp.DoomBuilder.BuilderModes offset -= j.controlSide.Fields.GetValue("offsety_mid", 0.0f); j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, offset % texture.Height); } else { - offset = GetMiddleOffsetY(j.sidedef, offset, j.scaleY, true); + offset = Tools.GetSidedefMiddleOffsetY(j.sidedef, offset, j.scaleY, true); //mxd. Clamp offset if this part is middle single or wrapped middle double if(j.sidedef.Other == null || j.sidedef.IsFlagSet("wrapmidtex") || j.sidedef.Line.IsFlagSet("wrapmidtex")) { @@ -3423,9 +3423,9 @@ namespace CodeImp.DoomBuilder.BuilderModes offset = (float)Math.Round(offset); //mxd if(matchtop) - j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, GetTopOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd + j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, Tools.GetSidedefTopOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd if(matchbottom) - j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, GetBottomOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd + j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, Tools.GetSidedefBottomOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd if(matchmid) { //mxd. Side is part of a 3D floor? if(j.sidedef.Index != j.controlSide.Index) { @@ -3433,7 +3433,7 @@ namespace CodeImp.DoomBuilder.BuilderModes offset -= j.controlSide.Fields.GetValue("offsety_mid", 0.0f); j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, offset % texture.Height); //mxd } else { - j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, GetMiddleOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd + j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, Tools.GetSidedefMiddleOffsetY(j.sidedef, offset, j.scaleY, true) % texture.Height); //mxd } } } @@ -3501,54 +3501,6 @@ namespace CodeImp.DoomBuilder.BuilderModes return false; } - //mxd. This converts offsetY from/to "normalized" offset for given upper wall - internal float GetTopOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized) - { - if(side.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag) || side.Other == null || side.Other.Sector == null) - return offset; - - //if we don't have UpperUnpegged flag, normalize offset - float surfaceHeight = (side.Sector.CeilHeight - side.Other.Sector.CeilHeight) * scaleY; - - if(fromNormalized) return (float)Math.Round(offset + surfaceHeight); - return (float)Math.Round(offset - surfaceHeight); - } - - //mxd. This converts offsetY from/to "normalized" offset for given middle wall - internal float GetMiddleOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized) - { - if(!side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || side.Sector == null) - return offset; - - // If we have LowerUnpegged flag, normalize offset - // Absolute value is used because ceiling height of vavoom-type 3d floors - // is lower than floor height - float surfaceHeight = (Math.Abs(side.Sector.CeilHeight - side.Sector.FloorHeight)) * scaleY; - - if(fromNormalized) return (float)Math.Round(offset + surfaceHeight); - return (float)Math.Round(offset - surfaceHeight); - } - - //mxd. This converts offsetY from/to "normalized" offset for given lower wall - internal float GetBottomOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized) - { - float surfaceHeight; - if (side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag)) { - if (side.Other == null || side.Other.Sector == null || side.Sector.CeilTexture != General.Map.Config.SkyFlatName || - side.Other.Sector.CeilTexture != General.Map.Config.SkyFlatName) - return offset; - - //normalize offset the way Doom does it when front and back sector's ceiling is sky - surfaceHeight = (side.Sector.CeilHeight - side.Other.Sector.CeilHeight) * scaleY; - } else { - //normalize offset - surfaceHeight = (side.Sector.CeilHeight - side.Other.Sector.FloorHeight) * scaleY; - } - - if(fromNormalized) return (float)Math.Round(offset + surfaceHeight); - return (float)Math.Round(offset - surfaceHeight); - } - //mxd private List getControlSides(Sidedef side, bool udmf) { if(side.Other == null) return new List() { side }; diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualLower.cs b/Source/Plugins/BuilderModes/VisualModes/VisualLower.cs index 580fb5dc..226d0d5a 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualLower.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualLower.cs @@ -312,7 +312,7 @@ namespace CodeImp.DoomBuilder.BuilderModes float scaleY = (float)Texture.Height / (Sidedef.Other.Sector.FloorHeight - Sidedef.Sector.FloorHeight); UDMFTools.SetFloat(Sidedef.Fields, "scaley_bottom", scaleY, 1.0f); - float offsetY = mode.GetBottomOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; + float offsetY = Tools.GetSidedefBottomOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; UDMFTools.SetFloat(Sidedef.Fields, "offsety_bottom", offsetY, 0.0f); } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs index f1d627a8..f4783aff 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs @@ -361,7 +361,7 @@ namespace CodeImp.DoomBuilder.BuilderModes float scaleY = Texture.ScaledHeight / (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight); UDMFTools.SetFloat(Sidedef.Fields, "scaley_mid", scaleY, 1.0f); - float offsetY = mode.GetMiddleOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; + float offsetY = Tools.GetSidedefMiddleOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; UDMFTools.SetFloat(Sidedef.Fields, "offsety_mid", offsetY, 0.0f); } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleSingle.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleSingle.cs index 976ff571..1eb762be 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleSingle.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleSingle.cs @@ -303,7 +303,7 @@ namespace CodeImp.DoomBuilder.BuilderModes float scaleY = Texture.ScaledHeight / (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight); UDMFTools.SetFloat(Sidedef.Fields, "scaley_mid", scaleY, 1.0f); - float offsetY = mode.GetMiddleOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; + float offsetY = Tools.GetSidedefMiddleOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; UDMFTools.SetFloat(Sidedef.Fields, "offsety_mid", offsetY, 0.0f); } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualUpper.cs b/Source/Plugins/BuilderModes/VisualModes/VisualUpper.cs index 39ee4bea..c4cbadf8 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualUpper.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualUpper.cs @@ -306,7 +306,7 @@ namespace CodeImp.DoomBuilder.BuilderModes float scaleY = (float)Texture.Height / (Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight); UDMFTools.SetFloat(Sidedef.Fields, "scaley_top", scaleY, 1.0f); - float offsetY = mode.GetTopOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; + float offsetY = Tools.GetSidedefTopOffsetY(Sidedef, -Sidedef.OffsetY, scaleY, true) % Texture.Height; UDMFTools.SetFloat(Sidedef.Fields, "offsety_top", offsetY, 0.0f); }