diff --git a/Build/Configurations/Includes/Hexen_linedefs.cfg b/Build/Configurations/Includes/Hexen_linedefs.cfg index 5fbd3fe4882bdc4c4da44529eb584df28ff3c484..3dd84d31f68a0bc811b2c0425e65a13888aaa9c5 100644 --- a/Build/Configurations/Includes/Hexen_linedefs.cfg +++ b/Build/Configurations/Includes/Hexen_linedefs.cfg @@ -1453,9 +1453,9 @@ teleport arg0 { - title = "Target MapSpot Tag"; + title = "Target Teleport Dest. Tag"; type = 14; - targetclasses = "MapSpot,MapSpotGravity"; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg1 @@ -1472,9 +1472,9 @@ teleport arg0 { - title = "Target MapSpot Tag"; + title = "Target Teleport Dest. Tag"; type = 14; - targetclasses = "MapSpot,MapSpotGravity"; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg1 diff --git a/Build/Configurations/Includes/ZDoom_linedefs.cfg b/Build/Configurations/Includes/ZDoom_linedefs.cfg index b01071882340346ee53bab89104b3138dba57d78..60b8ac26a1e222ef8edf3850594e02591f2172f7 100644 --- a/Build/Configurations/Includes/ZDoom_linedefs.cfg +++ b/Build/Configurations/Includes/ZDoom_linedefs.cfg @@ -2128,9 +2128,9 @@ zdoom arg0 { - title = "Target MapSpot Tag"; + title = "Target Teleport Dest. Tag"; type = 14; - targetclasses = "MapSpot,MapSpotGravity"; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg1 { @@ -2196,17 +2196,20 @@ zdoom arg0 { title = "Thing Tag"; + tooltip = "The TID of the actor(s) to teleport.\nIf 0, teleports the activator only."; type = 14; } arg1 { title = "Source Teleport Dest. Tag"; type = 14; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg2 { title = "Target Teleport Dest. Tag"; type = 14; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg3 { @@ -2233,15 +2236,15 @@ zdoom } arg1 { - title = "Source MapSpot Tag"; + title = "Source Tag"; + tooltip = "The spot relative to which to teleport."; type = 14; - targetclasses = "MapSpot,MapSpotGravity"; } arg2 { - title = "Target MapSpot Tag"; + title = "Target Teleport Dest. Tag"; type = 14; - targetclasses = "MapSpot,MapSpotGravity"; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg3 { @@ -2252,6 +2255,7 @@ zdoom arg4 { title = "Group Thing Tag"; + tooltip = "The TID of the thing(s) to teleport.\nIf 0, teleports all actors in the sector"; type = 14; } } @@ -2262,9 +2266,9 @@ zdoom arg0 { - title = "Target MapSpot Tag"; + title = "Target Teleport Dest. Tag"; type = 14; - targetclasses = "MapSpot,MapSpotGravity"; + targetclasses = "TeleportDest,TeleportDest2,TeleportDest3"; } arg1 { diff --git a/Source/Core/Controls/DebugConsole.cs b/Source/Core/Controls/DebugConsole.cs index 832c566209bcb1f7e9f5886479f059567e6090f8..2ad24761c5517f065621ebb31ff2c48a6d882313 100644 --- a/Source/Core/Controls/DebugConsole.cs +++ b/Source/Core/Controls/DebugConsole.cs @@ -41,6 +41,7 @@ namespace CodeImp.DoomBuilder private DebugMessageType filters; private static long starttime = -1; + private static int counter; private static DebugConsole me; #endregion @@ -159,6 +160,24 @@ namespace CodeImp.DoomBuilder starttime = -1; } + public static void IncrementCounter() { IncrementCounter(1); } + public static void IncrementCounter(int incrementby) + { + counter += incrementby; + } + + public static void ResetCounter(string message) + { + if(message.Contains("%")) + message = message.Replace("%", counter.ToString()); + else + message = message.TrimEnd() + ": " + counter; + + WriteLine(DebugMessageType.SPECIAL, message); + + counter = 0; + } + public static void StartProfiler() { #if PROFILE diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 1646ef8adc25057eceb28ffeecededcfe31e64ed..1c402e569da834384b4279ff8ec924cd53fd368d 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -590,7 +590,7 @@ namespace CodeImp.DoomBuilder.Data palette = null; //mxd. Dispose models - foreach(KeyValuePair<int, ModelData> i in modeldefentries) i.Value.Dispose(); + foreach(ModelData md in modeldefentries.Values) md.Dispose(); // Dispose containers foreach(DataReader c in containers) c.Dispose(); @@ -2052,7 +2052,7 @@ namespace CodeImp.DoomBuilder.Data public void ReloadModeldef() { if(modeldefentries != null) - foreach(KeyValuePair<int, ModelData> group in modeldefentries) group.Value.Dispose(); + foreach(ModelData md in modeldefentries.Values) md.Dispose(); // Bail out when not supported by current game configuration if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return; @@ -2105,16 +2105,14 @@ namespace CodeImp.DoomBuilder.Data General.MainWindow.DisplayReady(); } - //mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created + //mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed private void LoadModeldefs(Dictionary<string, int> actorsbyclass) { - //if no actors defined in DECORATE or game config... + // Abort if no classnames are defined in DECORATE or game config... if(actorsbyclass.Count == 0) return; - Dictionary<string, ModelData> modeldefentriesbyname = new Dictionary<string, ModelData>(StringComparer.Ordinal); ModeldefParser parser = new ModeldefParser(actorsbyclass); - - foreach(DataReader dr in containers) + foreach(DataReader dr in containers) { currentreader = dr; @@ -2122,30 +2120,21 @@ namespace CodeImp.DoomBuilder.Data foreach(TextResourceData data in streams) { // Parse the data - if(parser.Parse(data, true)) - { - foreach(KeyValuePair<string, ModelData> g in parser.Entries) - { - if(modeldefentriesbyname.ContainsKey(g.Key)) - General.ErrorLogger.Add(ErrorType.Warning, "Model definition for actor \"" + g.Key + "\" is double defined in \"" + Path.Combine(data.Source.Location.GetDisplayName(), data.Filename) + "\""); - - modeldefentriesbyname[g.Key] = g.Value; - } - } + parser.Parse(data, true); // Modeldefs are independable, so parsing fail in one file should not affect the others if(parser.HasError) parser.LogError(); } } - //mxd. Add to text resources collection + // Add to text resources collection textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values); currentreader = null; - foreach(KeyValuePair<string, ModelData> e in modeldefentriesbyname) + foreach(KeyValuePair<string, ModelData> e in parser.Entries) { if(actorsbyclass.ContainsKey(e.Key)) - modeldefentries[actorsbyclass[e.Key]] = modeldefentriesbyname[e.Key]; + modeldefentries[actorsbyclass[e.Key]] = parser.Entries[e.Key]; else if(!decorate.ActorsByClass.ContainsKey(e.Key)) General.ErrorLogger.Add(ErrorType.Warning, "MODELDEF model \"" + e.Key + "\" doesn't match any Decorate actor class"); } @@ -2228,7 +2217,7 @@ namespace CodeImp.DoomBuilder.Data } } - //mxd. Add to text resources collection + // Add to text resources collection textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values); currentreader = null; diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index 99921f33f353bdc7d690350348b5761b9c98b5b0..2ecba643472e618c472a5fe7a884a43192ca1129 100644 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -354,9 +354,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 int ofsEnd = br.ReadInt32(); //Relative offset from SURFACE_START to where the Surface object ends. // Sanity check - if(frame < 0 || frame > numFrames) + if(frame < 0 || frame >= numFrames) { - return "invalid frame number! (frame number: " + frame + ", total frames: " + numFrames + ")"; + return "frame " + frame + " is outside of model's frame range [0.." + (numFrames - 1) + "]"; } // Polygons @@ -453,15 +453,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 int num_frames = br.ReadInt32(); //Total number of frames // Sanity checks - if(num_frames == 0) + if(frame < 0 || frame >= num_frames) { - result.Errors = "model has 0 frames."; - return result; - } - - if(num_frames < frame || frame < 0) - { - result.Errors = "invalid target frame! (target frame: " + frame + ", total frames: " + num_frames + ")"; + result.Errors = "frame " + frame + " is outside of model's frame range [0.." + (num_frames - 1) + "]"; return result; } diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index fd2e41b5dcceb03989c7282d4989a57f2324df9f..269d0da28cd570ac614f514e0e2455123f3e5f84 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -1833,6 +1833,14 @@ namespace CodeImp.DoomBuilder.Geometry ((sd.LongMiddleTexture == texturelongname) && (sd.MiddleRequired() || sd.LongMiddleTexture != MapSet.EmptyLongName)) ; } + //mxd. This checks if any of the sidedef texture match the given textures + public static bool SidedefTextureMatch(Sidedef sd, HashSet<long> texturelongnames) + { + return (texturelongnames.Contains(sd.LongHighTexture) && sd.HighRequired()) || + (texturelongnames.Contains(sd.LongLowTexture) && sd.LowRequired()) || + (texturelongnames.Contains(sd.LongMiddleTexture) && (sd.MiddleRequired() || sd.LongMiddleTexture != MapSet.EmptyLongName)); + } + //mxd. This converts offsetY from/to "normalized" offset for given wall part public static float GetSidedefOffsetY(Sidedef side, VisualGeometryType part, float offset, float scaleY, bool fromNormalized) { diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index eb0b31efc1e91e19a292fc18d82d0d739e59b9ff..4076670c451f0e3ccfcfbd6fa5748e38cad3b3ec 100644 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -1603,11 +1603,8 @@ namespace CodeImp.DoomBuilder.Rendering public void RenderText(TextLabel label) { //mxd. Update the text if needed - RectangleF bbox = label.Update(translatex, translatey, scale, -scale); - - //mxd. Have graphics / on screen? - if(label.VertexBuffer == null || (bbox.Right < 0.1f) || (bbox.Left > windowsize.Width) || (bbox.Bottom < 0.1f) || (bbox.Top > windowsize.Height)) - return; + label.Update(translatex, translatey, scale, -scale); + if(label.SkipRendering) return; // Set renderstates for rendering graphics.Device.SetRenderState(RenderState.CullMode, Cull.None); @@ -1637,18 +1634,8 @@ namespace CodeImp.DoomBuilder.Rendering foreach(TextLabel label in labels) { // Update the text if needed - RectangleF bbox = label.Update(translatex, translatey, scale, -scale); - - // Have graphics / on screen? - if(label.VertexBuffer == null || (bbox.Right < 0.1f) || (bbox.Left > windowsize.Width) || (bbox.Bottom < 0.1f) || (bbox.Top > windowsize.Height)) - { - label.SkipRendering = true; - skipped++; - } - else - { - label.SkipRendering = false; - } + label.Update(translatex, translatey, scale, -scale); + if(label.SkipRendering) skipped++; } if(labels.Count == skipped) return; diff --git a/Source/Core/Rendering/TextLabel.cs b/Source/Core/Rendering/TextLabel.cs index e3f50e11af203a8294b1af69ae4f59f6fa2a9528..26f35fcd2e5902506d6e4fd474515efed7f05eac 100644 --- a/Source/Core/Rendering/TextLabel.cs +++ b/Source/Core/Rendering/TextLabel.cs @@ -47,7 +47,6 @@ namespace CodeImp.DoomBuilder.Rendering // Text settings private string text; private RectangleF rect; - private RectangleF absview; //mxd private bool transformcoords; private PixelColor color; private PixelColor backcolor; @@ -63,6 +62,9 @@ namespace CodeImp.DoomBuilder.Rendering private float lasttranslatey; private float lastscalex; private float lastscaley; + + //mxd. Rendering + private bool skiprendering; // Disposing private bool isdisposed; @@ -90,7 +92,7 @@ namespace CodeImp.DoomBuilder.Rendering public bool DrawBackground { get { return drawbg; } set { if(drawbg != value) { drawbg = value; textureupdateneeded = true; } } } //mxd internal Texture Texture { get { return texture; } } //mxd internal VertexBuffer VertexBuffer { get { return textbuffer; } } - internal bool SkipRendering; //mxd + internal bool SkipRendering { get { return skiprendering; } } //mxd // Disposing public bool IsDisposed { get { return isdisposed; } } @@ -116,6 +118,10 @@ namespace CodeImp.DoomBuilder.Rendering // Register as resource General.Map.Graphics.RegisterResource(this); + + //mxd. Create the buffer + this.textbuffer = new VertexBuffer(General.Map.Graphics.Device, 4 * FlatVertex.Stride, + Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default); // We have no destructor GC.SuppressFinalize(this); @@ -143,7 +149,7 @@ namespace CodeImp.DoomBuilder.Rendering #region ================== Methods // This updates the text if needed - internal RectangleF Update(float translatex, float translatey, float scalex, float scaley) + internal void Update(float translatex, float translatey, float scalex, float scaley) { // Check if transformation changed and needs to be updated if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey || @@ -156,30 +162,6 @@ namespace CodeImp.DoomBuilder.Rendering updateneeded = true; } - //mxd. Update texture if needed - if(textureupdateneeded) - { - // Get rid of old texture - if(texture != null) - { - texture.Dispose(); - texture = null; - } - - // Create label image - Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg); - textsize = img.Size; - - // Create texture - MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096); - img.Save(memstream, ImageFormat.Bmp); - memstream.Seek(0, SeekOrigin.Begin); - - texture = Texture.FromStream(General.Map.Graphics.Device, memstream, (int)memstream.Length, - img.Size.Width, img.Size.Height, 1, Usage.None, Format.Unknown, - Pool.Managed, General.Map.Graphics.PostFilter, General.Map.Graphics.MipGenerateFilter, 0); - } - // Update if needed if(updateneeded || textureupdateneeded) { @@ -187,6 +169,7 @@ namespace CodeImp.DoomBuilder.Rendering if(text.Length > 0) { // Transform? + RectangleF absview; if(transformcoords) { // Calculate absolute coordinates @@ -202,6 +185,37 @@ namespace CodeImp.DoomBuilder.Rendering absview = rect; } + //mxd. Skip when not on screen... + RectangleF abssize = absview; + abssize.Inflate(textsize.Width / 2, textsize.Height / 2); + Size windowsize = General.Map.Graphics.RenderTarget.ClientSize; + skiprendering = (abssize.Right < 0.1f) || (abssize.Left > windowsize.Width) || (abssize.Bottom < 0.1f) || (abssize.Top > windowsize.Height); + if(skiprendering) return; + + //mxd. Update texture if needed + if(textureupdateneeded) + { + // Get rid of old texture + if(texture != null) + { + texture.Dispose(); + texture = null; + } + + // Create label image + Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg); + textsize = img.Size; + + // Create texture + MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096); + img.Save(memstream, ImageFormat.Bmp); + memstream.Seek(0, SeekOrigin.Begin); + + texture = Texture.FromStream(General.Map.Graphics.Device, memstream, (int)memstream.Length, + img.Size.Width, img.Size.Height, 1, Usage.None, Format.Unknown, + Pool.Managed, General.Map.Graphics.PostFilter, General.Map.Graphics.MipGenerateFilter, 0); + } + // Align the text horizontally float beginx = 0; switch(alignx) @@ -220,14 +234,6 @@ namespace CodeImp.DoomBuilder.Rendering case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - textsize.Height; break; } - // Do we have to make a new buffer? - if(textbuffer == null) - { - // Create the buffer - textbuffer = new VertexBuffer(General.Map.Graphics.Device, 4 * FlatVertex.Stride, - Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default); - } - //mxd. Lock the buffer using(DataStream stream = textbuffer.Lock(0, 4 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock)) { @@ -241,16 +247,14 @@ namespace CodeImp.DoomBuilder.Rendering else { // No faces in polygon - if(textbuffer != null) textbuffer.Dispose(); //mxd textsize = new SizeF(); + skiprendering = true; //mxd } // Text updated updateneeded = false; textureupdateneeded = false; //mxd } - - return absview; //mxd } //mxd diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index e7bb2214b5da4dc449efef284504ed5ff97e3ab0..8a653f9e693a646590897d4d9b58126e2a1595b7 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -606,7 +606,10 @@ namespace CodeImp.DoomBuilder.BuilderModes if(requiredsize > group.Key.Labels[i].radius) { requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale; - l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]); + if(requiredsize > group.Key.Labels[i].radius) + l.Text = (requiredsize > group.Key.Labels[i].radius * 4 ? string.Empty : "+"); + else + l.Text = group.Value[1]; } else { diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs index 22762e57ede03f25ee6484fd772be92bac1609f5..6ddd127772165613eb244ef417e08e0411763155 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs @@ -197,6 +197,9 @@ namespace CodeImp.DoomBuilder.BuilderModes List<TextLabel> torender = new List<TextLabel>(orderedselection.Count); foreach(Sector s in orderedselection) { + //mxd. Self-referencing (and probably some other) sectors don't have labels... + if(labels[s].Length == 0) continue; + // Render labels TextLabel[] labelarray = labels[s]; float requiredsize = (labelarray[0].TextSize.Height / 2) / renderer.Scale; @@ -238,7 +241,10 @@ namespace CodeImp.DoomBuilder.BuilderModes if(requiredsize > group.Key.Labels[i].radius) { requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale; - l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]); + if(requiredsize > group.Key.Labels[i].radius) + l.Text = (requiredsize > group.Key.Labels[i].radius * 4 ? string.Empty : "+"); + else + l.Text = group.Value[1]; } else { diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs index 5db17cb70e5a116c609cb85a631b440eedcc3c82..29252531456a0cdf91f6c1bac4e90f86083f8bb3 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs @@ -277,7 +277,10 @@ namespace CodeImp.DoomBuilder.BuilderModes if(requiredsize > group.Key.Labels[i].radius) { requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale; - l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]); + if(requiredsize > group.Key.Labels[i].radius) + l.Text = (requiredsize > group.Key.Labels[i].radius * 4 ? string.Empty : "+"); + else + l.Text = group.Value[1]; } else { @@ -541,14 +544,14 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd. Update helper lines UpdateHelperObjects(); + //mxd. Update selection info + UpdateSelectionInfo(); + // Update display General.Interface.RedrawDisplay(); } } } - - //mxd. Update selection info - UpdateSelectionInfo(); } editpressed = false; @@ -964,9 +967,20 @@ namespace CodeImp.DoomBuilder.BuilderModes Vector2D v = thing.Position; TextLabel l = new TextLabel(); l.TransformCoords = true; - l.Rectangle = new RectangleF(v.x - thing.Size + 1, v.y + thing.Size - 1, 0f, 0f); - l.AlignX = TextAlignmentX.Left; - l.AlignY = TextAlignmentY.Top; + + if(thing.FixedSize) + { + l.Rectangle = new RectangleF(v.x, v.y, 0f, 0f); + l.AlignX = TextAlignmentX.Center; + l.AlignY = TextAlignmentY.Middle; + } + else + { + l.Rectangle = new RectangleF(v.x - thing.Size + 1, v.y + thing.Size - 1, 0f, 0f); + l.AlignX = TextAlignmentX.Left; + l.AlignY = TextAlignmentY.Top; + } + l.Color = (thing == highlighted ? General.Colors.Selection : General.Colors.Highlight); l.Backcolor = General.Colors.Background.WithAlpha(255); l.DrawBackground = true; diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index a6835e4ec38226b5ced4d00e84e9315c96044497..18fe57b6e10f2c39f56bace491806b06507728bb 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -3732,6 +3732,9 @@ namespace CodeImp.DoomBuilder.BuilderModes first.controlSide = start.Sidedef; } + //mxd + HashSet<long> texturehashes = new HashSet<long> { texture.LongName }; + first.forward = true; todo.Push(first); @@ -3761,11 +3764,11 @@ namespace CodeImp.DoomBuilder.BuilderModes // Add sidedefs forward (connected to the right vertex) Vertex v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; - AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texture.LongName, false); + AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texturehashes, false); // Add sidedefs backward (connected to the left vertex) v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; - AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texture.LongName, false); + AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texturehashes, false); } else { @@ -3787,11 +3790,11 @@ namespace CodeImp.DoomBuilder.BuilderModes // Add sidedefs backward (connected to the left vertex) Vertex v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; - AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texture.LongName, false); + AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texturehashes, false); // Add sidedefs forward (connected to the right vertex) v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; - AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texture.LongName, false); + AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texturehashes, false); } } } @@ -3821,6 +3824,24 @@ namespace CodeImp.DoomBuilder.BuilderModes else first.controlSide = start.Sidedef; + //mxd. We potentially need to deal with 2 textures (because of long and short texture names)... + HashSet<long> texturehashes = new HashSet<long> { texture.LongName }; + switch(start.GeometryType) + { + case VisualGeometryType.WALL_LOWER: + texturehashes.Add(first.controlSide.LongLowTexture); + break; + + case VisualGeometryType.WALL_MIDDLE: + case VisualGeometryType.WALL_MIDDLE_3D: + texturehashes.Add(first.controlSide.LongMiddleTexture); + break; + + case VisualGeometryType.WALL_UPPER: + texturehashes.Add(first.controlSide.LongHighTexture); + break; + } + //mxd List<BaseVisualGeometrySidedef> selectedVisualSides = new List<BaseVisualGeometrySidedef>(); if(checkSelectedSidedefParts && !singleselection) @@ -3904,9 +3925,9 @@ namespace CodeImp.DoomBuilder.BuilderModes // Get the align job to do SidedefAlignJob j = todo.Pop(); - bool matchtop = (!j.sidedef.Marked && (!singleselection || j.sidedef.LongHighTexture == texture.LongName) && j.sidedef.HighRequired()); - bool matchbottom = (!j.sidedef.Marked && (!singleselection || j.sidedef.LongLowTexture == texture.LongName) && j.sidedef.LowRequired()); - bool matchmid = ((!singleselection || j.controlSide.LongMiddleTexture == texture.LongName) && (j.controlSide.MiddleRequired() || j.controlSide.LongMiddleTexture != MapSet.EmptyLongName)); //mxd + bool matchtop = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongHighTexture)) && j.sidedef.HighRequired()); + bool matchbottom = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongLowTexture)) && j.sidedef.LowRequired()); + bool matchmid = ((!singleselection || texturehashes.Contains(j.controlSide.LongMiddleTexture)) && (j.controlSide.MiddleRequired() || j.controlSide.LongMiddleTexture != MapSet.EmptyLongName)); //mxd //mxd. If there's a selection, check if matched part is actually selected if(checkSelectedSidedefParts && !singleselection) @@ -4037,11 +4058,11 @@ namespace CodeImp.DoomBuilder.BuilderModes // Add sidedefs backward (connected to the left vertex) v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; - AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texture.LongName, true); + AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texturehashes, true); // Add sidedefs forward (connected to the right vertex) v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; - AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texture.LongName, true); + AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texturehashes, true); } else { @@ -4133,17 +4154,17 @@ namespace CodeImp.DoomBuilder.BuilderModes // Add sidedefs forward (connected to the right vertex) v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; - AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texture.LongName, true); + AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texturehashes, true); // Add sidedefs backward (connected to the left vertex) v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; - AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texture.LongName, true); + AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texturehashes, true); } } } // This adds the matching, unmarked sidedefs from a vertex for texture alignment - private void AddSidedefsForAlignment(Stack<SidedefAlignJob> stack, Vertex v, bool forward, float offsetx, float scaleY, long texturelongname, bool udmf) + private void AddSidedefsForAlignment(Stack<SidedefAlignJob> stack, Vertex v, bool forward, float offsetx, float scaleY, HashSet<long> texturelongnames, bool udmf) { foreach(Linedef ld in v.Linedefs) { @@ -4156,7 +4177,7 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(Sidedef s in controlSides) { - if(!singleselection || Tools.SidedefTextureMatch(s, texturelongname)) + if(!singleselection || Tools.SidedefTextureMatch(s, texturelongnames)) { SidedefAlignJob nj = new SidedefAlignJob(); nj.forward = forward; @@ -4174,7 +4195,7 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(Sidedef s in controlSides) { - if(!singleselection || Tools.SidedefTextureMatch(s, texturelongname)) + if(!singleselection || Tools.SidedefTextureMatch(s, texturelongnames)) { SidedefAlignJob nj = new SidedefAlignJob(); nj.forward = forward; diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs index 8de6f796e1bdf2c338e3e19b9f3cda2ae6370f0a..089527faf11881084cc658e8228b1cd0108ac8a3 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs @@ -239,6 +239,10 @@ namespace CodeImp.DoomBuilder.BuilderModes if(translucent && !othertranslucent && !ef.ClipSidedefs) continue; if(ef.ClipSidedefs == extrafloor.ClipSidedefs || ef.ClipSidedefs) { + //TODO: find out why ef can be not updated at this point + //TODO: [this crashed on me once when performing auto-align on myriad of textures on BoA C1M0] + if(ef.Floor == null || ef.Ceiling == null) ef.Update(); + int num = polygons.Count; for(int pi = 0; pi < num; pi++) {