From c7696b0464e21c4c68d9dcafb58846e0bbb938b7 Mon Sep 17 00:00:00 2001 From: MaxED Date: Tue, 25 Aug 2015 22:05:14 +0000 Subject: [PATCH] Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length. Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes. Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it. Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported. Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...). Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly. Updated ZDoom_DECORATE.cfg. --- Build/Scripting/ZDoom_DECORATE.cfg | 2 + Source/Core/Config/ThingTypeInfo.cs | 29 ++++ Source/Core/Map/Thing.cs | 46 +++++-- Source/Core/Rendering/Renderer3D.cs | 26 +++- Source/Core/VisualModes/VisualThing.cs | 130 +++++++++++++++++- .../ClassicModes/DragGeometryMode.cs | 3 +- .../ClassicModes/DragThingsMode.cs | 3 +- .../ClassicModes/DrawCurveMode.cs | 38 ++--- .../ClassicModes/DrawGeometryMode.cs | 64 ++------- .../BuilderModes/ClassicModes/DrawGridMode.cs | 10 +- .../ClassicModes/DrawRectangleMode.cs | 19 ++- .../BuilderModes/ClassicModes/LinedefsMode.cs | 4 +- .../BuilderModes/ClassicModes/SectorsMode.cs | 10 +- .../BuilderModes/ClassicModes/ThingsMode.cs | 4 +- .../BuilderModes/ClassicModes/VerticesMode.cs | 4 +- .../Plugins/BuilderModes/General/HintLabel.cs | 52 +++++-- .../BuilderModes/General/LineLengthLabel.cs | 120 +++++++++++++--- .../Plugins/BuilderModes/Resources/Hints.cfg | 4 +- .../VisualModes/BaseVisualThing.cs | 80 +++++------ .../VisualModes/BaseVisualVertex.cs | 66 ++++----- .../VisualModes/NullVisualEventReceiver.cs | 3 +- 21 files changed, 489 insertions(+), 228 deletions(-) diff --git a/Build/Scripting/ZDoom_DECORATE.cfg b/Build/Scripting/ZDoom_DECORATE.cfg index 09162bbb..c14e1afa 100644 --- a/Build/Scripting/ZDoom_DECORATE.cfg +++ b/Build/Scripting/ZDoom_DECORATE.cfg @@ -184,6 +184,7 @@ keywords A_SetShootable = "A_SetShootable"; A_SetSolid = "A_SetSolid"; A_SetSpecial = "A_SetSpecial(int special, int arg0, int arg1, int arg2, int arg3, int arg4)"; + A_SetSpecies = "A_SetSpecies(str species [, int pointer = AAPTR_DEFAULT])"; A_SetSpeed = "A_SetSpeed(float speed[, int pointer = AAPTR_DEFAULT])"; A_SetTics = "A_SetTics(int tics)"; A_SetTranslucent = "A_SetTranslucent(float alpha[, int mode = 0])"; @@ -924,6 +925,7 @@ constants INVENTORY.TOSSED; INVENTORY.ALWAYSRESPAWN; INVENTORY.TRANSFER; + INVENTORY.NOTELEPORTFREEZE; //Weapons WEAPON.NOAUTOFIRE; WEAPON.READYSNDHALF; diff --git a/Source/Core/Config/ThingTypeInfo.cs b/Source/Core/Config/ThingTypeInfo.cs index e0ed2fd5..67011b51 100644 --- a/Source/Core/Config/ThingTypeInfo.cs +++ b/Source/Core/Config/ThingTypeInfo.cs @@ -64,8 +64,14 @@ namespace CodeImp.DoomBuilder.Config private readonly ArgumentInfo[] args; private readonly bool isknown; private readonly bool absolutez; + private bool xybillboard; //mxd private SizeF spritescale; private readonly bool locksprite; //mxd + + //mxd. GLOOME rendering settings + private Thing.SpriteRenderMode rendermode; + private bool rollsprite; + private bool sticktoplane; #endregion @@ -90,9 +96,15 @@ namespace CodeImp.DoomBuilder.Config public bool IsKnown { get { return isknown; } } public bool IsNull { get { return (index == 0); } } public bool AbsoluteZ { get { return absolutez; } } + public bool XYBillboard { get { return xybillboard; } } //mxd public SizeF SpriteScale { get { return spritescale; } } public string ClassName { get { return classname; } } //mxd. Need this to add model overrides for things defined in configs + //mxd. GLOOME rendering flags + public Thing.SpriteRenderMode RenderMode { get { return rendermode; } } + public bool RollSprite { get { return rollsprite; } } + public bool StickToPlane { get { return sticktoplane; } } + #endregion #region ================== Constructor / Disposer @@ -121,6 +133,7 @@ namespace CodeImp.DoomBuilder.Config this.args = new ArgumentInfo[Linedef.NUM_ARGS]; this.isknown = false; this.absolutez = false; + this.xybillboard = false; this.locksprite = false; //mxd // We have no destructor @@ -319,8 +332,14 @@ namespace CodeImp.DoomBuilder.Config this.fixedsize = other.fixedsize; this.fixedrotation = other.fixedrotation; //mxd this.absolutez = other.absolutez; + this.xybillboard = other.xybillboard; //mxd this.spritescale = new SizeF(other.spritescale.Width, other.spritescale.Height); + //mxd. Copy GLOOME properties + this.rendermode = other.rendermode; + this.sticktoplane = other.sticktoplane; + this.rollsprite = other.rollsprite; + // We have no destructor GC.SuppressFinalize(this); } @@ -406,6 +425,16 @@ namespace CodeImp.DoomBuilder.Config hangs = actor.GetFlagValue("spawnceiling", hangs); int blockvalue = (blocking > 0) ? blocking : 2; blocking = actor.GetFlagValue("solid", (blocking != 0)) ? blockvalue : 0; + xybillboard = actor.GetFlagValue("forcexybillboard", false); //mxd + + //mxd. GLOOME rendering flags. ORDER: WALLSPRITE -> FLOORSPRITE || CEILSPRITE + rollsprite = actor.GetFlagValue("rollsprite", false); + //TODO: in GLOOME +WALLSPRITE works only when +ROLLSPRITE is set? + if(rollsprite && actor.GetFlagValue("wallsprite", false)) rendermode = Thing.SpriteRenderMode.WALL_SPRITE; + else if(actor.GetFlagValue("floorsprite", false)) rendermode = Thing.SpriteRenderMode.FLOOR_SPRITE; + else if(actor.GetFlagValue("ceilsprite", false)) rendermode = Thing.SpriteRenderMode.CEILING_SPRITE; + if(rendermode == Thing.SpriteRenderMode.FLOOR_SPRITE || rendermode == Thing.SpriteRenderMode.CEILING_SPRITE) + sticktoplane = actor.GetFlagValue("sticktoplane", false); // Works only for Floor/Ceil sprites //mxd if(blocking > THING_BLOCKING_NONE) errorcheck = THING_ERROR_INSIDE_STUCK; diff --git a/Source/Core/Map/Thing.cs b/Source/Core/Map/Thing.cs index 53eb31fe..3a5aabe8 100644 --- a/Source/Core/Map/Thing.cs +++ b/Source/Core/Map/Thing.cs @@ -39,6 +39,18 @@ namespace CodeImp.DoomBuilder.Map #endregion + #region ================== Enums + + public enum SpriteRenderMode + { + NORMAL, + WALL_SPRITE, + FLOOR_SPRITE, + CEILING_SPRITE + } + + #endregion + #region ================== Variables // Map @@ -66,9 +78,12 @@ namespace CodeImp.DoomBuilder.Map private int roll; //mxd. Used in model rendering private float pitchrad; //mxd private float rollrad; //mxd - private bool isModel; //mxd + private bool ismodel; //mxd private bool highlighted; //mxd + //mxd. GLOOME rendering settings + private bool rollsprite; //mxd + // Configuration private float size; private float height; //mxd @@ -101,7 +116,7 @@ namespace CodeImp.DoomBuilder.Map public bool FixedSize { get { return fixedsize; } } public int Tag { get { return tag; } set { BeforePropsChange(); tag = value; if((tag < General.Map.FormatInterface.MinTag) || (tag > General.Map.FormatInterface.MaxTag)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } } public Sector Sector { get { return sector; } } - public bool IsModel { get { return isModel; } } //mxd + public bool IsModel { get { return ismodel; } } //mxd public bool IsDirectional { get { return directional; } } //mxd public bool Highlighted { get { return highlighted; } set { highlighted = value; } } //mxd @@ -237,7 +252,8 @@ namespace CodeImp.DoomBuilder.Map t.color = color; t.directional = directional; t.fixedsize = fixedsize; - t.isModel = isModel; //mxd + t.ismodel = ismodel; //mxd + t.rollsprite = rollsprite; //mxd base.CopyPropertiesTo(t); } @@ -437,7 +453,7 @@ namespace CodeImp.DoomBuilder.Map BeforePropsChange(); pitch = General.ClampAngle(newpitch); - pitchrad = ((isModel && General.Map.Data.ModeldefEntries[type].InheritActorPitch) ? Angle2D.DegToRad(pitch) : 0); + pitchrad = ((ismodel && General.Map.Data.ModeldefEntries[type].InheritActorPitch) ? Angle2D.DegToRad(pitch) : 0); if (type != General.Map.Config.Start3DModeThingType) General.Map.IsChanged = true; @@ -449,7 +465,7 @@ namespace CodeImp.DoomBuilder.Map BeforePropsChange(); roll = General.ClampAngle(newroll); - rollrad = ((isModel && General.Map.Data.ModeldefEntries[type].InheritActorRoll) ? Angle2D.DegToRad(roll) : 0); + rollrad = ( (rollsprite || (ismodel && General.Map.Data.ModeldefEntries[type].InheritActorRoll)) ? Angle2D.DegToRad(roll) : 0); if (type != General.Map.Config.Start3DModeThingType) General.Map.IsChanged = true; @@ -525,6 +541,7 @@ namespace CodeImp.DoomBuilder.Map } directional = ti.Arrow; //mxd + rollsprite = ti.RollSprite; //mxd UpdateCache(); //mxd } @@ -533,20 +550,25 @@ namespace CodeImp.DoomBuilder.Map { if (General.Map.Data == null) { - isModel = false; + ismodel = false; return; } - isModel = General.Map.Data.ModeldefEntries.ContainsKey(type); - if (isModel && General.Map.Data.ModeldefEntries[type].LoadState == ModelLoadState.None) - isModel = General.Map.Data.ProcessModel(type); + ismodel = General.Map.Data.ModeldefEntries.ContainsKey(type); + if (ismodel && General.Map.Data.ModeldefEntries[type].LoadState == ModelLoadState.None) + ismodel = General.Map.Data.ProcessModel(type); - if (isModel) + if(ismodel) { rollrad = (General.Map.Data.ModeldefEntries[type].InheritActorRoll ? Angle2D.DegToRad(roll) : 0); pitchrad = (General.Map.Data.ModeldefEntries[type].InheritActorPitch ? Angle2D.DegToRad(pitch) : 0); - } - else + } + else if(rollsprite) + { + rollrad = Angle2D.DegToRad(roll); + pitchrad = 0; + } + else { rollrad = 0; pitchrad = 0; diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index c368becc..f9139589 100644 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -938,10 +938,28 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Shaders.World3D.SetHighlightColor(CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)).ToArgb()); } - // Create the matrix for positioning / rotation - world = billboard - * Matrix.Scaling(t.Thing.ScaleX, t.Thing.ScaleX, t.Thing.ScaleY) - * t.Position; //mxd + //mxd. Create the matrix for positioning + if(t.Info.RenderMode == Thing.SpriteRenderMode.NORMAL) // Apply billboarding? + { + if(t.Info.XYBillboard) + { + world = Matrix.Translation(0f, 0f, -t.LocalCenterZ) * Matrix.RotationX(Angle2D.PI - General.Map.VisualCamera.AngleZ) * Matrix.Translation(0f, 0f, t.LocalCenterZ) + * billboard + * Matrix.Scaling(t.Thing.ScaleX, t.Thing.ScaleX, t.Thing.ScaleY) + * t.Position; + } + else + { + world = billboard + * Matrix.Scaling(t.Thing.ScaleX, t.Thing.ScaleX, t.Thing.ScaleY) + * t.Position; + } + } + else + { + world = Matrix.Scaling(t.Thing.ScaleX, t.Thing.ScaleX, t.Thing.ScaleY) + * t.Position; + } ApplyMatrices3D(); diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs index 10b17331..70c98c4d 100644 --- a/Source/Core/VisualModes/VisualThing.cs +++ b/Source/Core/VisualModes/VisualThing.cs @@ -26,6 +26,7 @@ using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Rendering; using SlimDX; using SlimDX.Direct3D9; +using Plane = CodeImp.DoomBuilder.Geometry.Plane; #endregion @@ -42,7 +43,10 @@ namespace CodeImp.DoomBuilder.VisualModes #region ================== Variables // Thing - private Thing thing; + private readonly Thing thing; + + //mxd. Info + protected ThingTypeInfo info; // Texture private ImageData texture; @@ -70,7 +74,7 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd private int cameraDistance3D; - private int thingHeight; + private int thingheight; //mxd. light properties private DynamicLightType lightType; @@ -82,6 +86,7 @@ namespace CodeImp.DoomBuilder.VisualModes private Vector3 position_v3; private float lightDelta; //used in light animation private Vector3[] boundingBox; + //gldefs light private Vector3 lightOffset; private int lightInterval; @@ -98,6 +103,7 @@ namespace CodeImp.DoomBuilder.VisualModes internal Matrix Position { get { return position; } } internal Matrix CageScales { get { return cagescales; } } internal int CageColor { get { return cagecolor; } } + public ThingTypeInfo Info { get { return info; } } //mxd //mxd internal int VertexColor { get { return vertices.Length > 0 ? vertices[0].c : 0;} } @@ -106,10 +112,11 @@ namespace CodeImp.DoomBuilder.VisualModes public Vector3 Center { get { if (isGldefsLight) return position_v3 + lightOffset; - return new Vector3(position_v3.X, position_v3.Y, position_v3.Z + thingHeight / 2); + return new Vector3(position_v3.X, position_v3.Y, position_v3.Z + thingheight / 2f); } } public Vector3D CenterV3D { get { return D3DDevice.V3D(Center); } } + public float LocalCenterZ { get { return thingheight / 2f; } } //mxd public Vector3 PositionV3 { get { return position_v3; } } public Vector3[] BoundingBox { get { return boundingBox; } } //mxd. light properties @@ -227,8 +234,7 @@ namespace CodeImp.DoomBuilder.VisualModes public void SetCageSize(float radius, float height) { cagescales = Matrix.Scaling(radius, radius, height); - //mxd - thingHeight = (int)height; + thingheight = (int)height; //mxd } /// @@ -256,13 +262,123 @@ namespace CodeImp.DoomBuilder.VisualModes } // This sets the vertices for the thing sprite - protected void SetVertices(ICollection verts) + protected void SetVertices(ICollection verts, Plane floor, Plane ceiling) { // Copy vertices vertices = new WorldVertex[verts.Count]; verts.CopyTo(vertices, 0); triangles = vertices.Length / 3; updategeo = true; + + //mxd. Do some GLOOME shenanigans... + int localcenterz = (int)(Thing.Height / 2); + Matrix m; + switch(info.RenderMode) + { + // Appied only when ROLLSPRITE flag is set (?) + case Thing.SpriteRenderMode.WALL_SPRITE: + m = Matrix.Translation(0f, 0f, -localcenterz) * Matrix.RotationY(Thing.RollRad) * Matrix.RotationZ(thing.Angle) * Matrix.Translation(0f, 0f, localcenterz); + for(int i = 0; i < vertices.Length; i++) + { + Vector4 transformed = Vector3.Transform(new Vector3(vertices[i].x, vertices[i].y, vertices[i].z), m); + vertices[i].x = transformed.X; + vertices[i].y = transformed.Y; + vertices[i].z = transformed.Z; + } + break; + + case Thing.SpriteRenderMode.FLOOR_SPRITE: + // TODO: thing angle is involved in this... somehow + Matrix floorrotation = (info.RollSprite ? Matrix.RotationY(Thing.RollRad) * Matrix.RotationX(Angle2D.PIHALF) : Matrix.RotationX(Angle2D.PIHALF)); + m = Matrix.Translation(0f, 0f, -localcenterz) * floorrotation * Matrix.Translation(0f, 0f, localcenterz); + for(int i = 0; i < vertices.Length; i++) + { + Vector4 transformed = Vector3.Transform(new Vector3(vertices[i].x, vertices[i].y, vertices[i].z), m); + vertices[i].x = transformed.X; + vertices[i].y = transformed.Y; + vertices[i].z = transformed.Z; + } + + // TODO: this won't work on things with AbsoluteZ flag + if(info.StickToPlane) + { + // Calculate vertical offset + float floorz = floor.GetZ(Thing.Position); + float ceilz = ceiling.GetZ(Thing.Position); + + if(!float.IsNaN(floorz) && !float.IsNaN(ceilz)) + { + float voffset; + if(info.Hangs) + { + float thingz = ceilz - Thing.Position.z + Thing.Height; + voffset = 0.01f - floorz - General.Clamp(thingz, 0, ceilz - floorz); + } + else + { + voffset = 0.01f - floorz - General.Clamp(Thing.Position.z, 0, ceilz - floorz); + } + + // Apply it + for(int i = 0; i < vertices.Length; i++) + vertices[i].z = floor.GetZ(vertices[i].x + Thing.Position.x, vertices[i].y + Thing.Position.y) + voffset; + } + } + break; + + case Thing.SpriteRenderMode.CEILING_SPRITE: + // TODO: thing angle is involved in this... somehow + Matrix ceilrotation = (info.RollSprite ? Matrix.RotationY(Thing.RollRad) * Matrix.RotationX(-Angle2D.PIHALF) : Matrix.RotationX(-Angle2D.PIHALF)); + m = Matrix.Translation(0f, 0f, -localcenterz) * ceilrotation * Matrix.Translation(0f, 0f, localcenterz); + for(int i = 0; i < vertices.Length; i++) + { + Vector4 transformed = Vector3.Transform(new Vector3(vertices[i].x, vertices[i].y, vertices[i].z), m); + vertices[i].x = transformed.X; + vertices[i].y = transformed.Y; + vertices[i].z = transformed.Z; + } + + // TODO: this won't work on things with AbsoluteZ flag + if(info.StickToPlane) + { + // Calculate vertical offset + float floorz = floor.GetZ(Thing.Position); + float ceilz = ceiling.GetZ(Thing.Position); + + if(!float.IsNaN(floorz) && !float.IsNaN(ceilz)) + { + float voffset; + if(info.Hangs) + { + float thingz = ceilz - Math.Max(0, Thing.Position.z) - Thing.Height; + voffset = -0.01f - General.Clamp(thingz, 0, ceilz - floorz); + } + else + { + voffset = -0.01f - floorz - General.Clamp(Thing.Position.z, 0, ceilz - floorz); + } + + // Apply it + for(int i = 0; i < vertices.Length; i++) + vertices[i].z = ceiling.GetZ(vertices[i].x + Thing.Position.x, vertices[i].y + Thing.Position.y) + voffset; + } + } + break; + + default: + if(info.RollSprite) + { + m = Matrix.Translation(0f, 0f, -localcenterz) * Matrix.RotationY(Thing.RollRad) * Matrix.Translation(0f, 0f, localcenterz); + for(int i = 0; i < vertices.Length; i++) + { + Vector4 transformed = Vector3.Transform(new Vector3(vertices[i].x, vertices[i].y, vertices[i].z), m); + vertices[i].x = transformed.X; + vertices[i].y = transformed.Y; + vertices[i].z = transformed.Z; + } + } + break; + } } // This updates the visual thing @@ -318,7 +434,7 @@ namespace CodeImp.DoomBuilder.VisualModes } else { - UpdateBoundingBox((int)thing.Size, thingHeight); + UpdateBoundingBox((int)thing.Size, thingheight); lightType = DynamicLightType.NONE; lightRadius = -1; diff --git a/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs index c4bb0f21..334a6907 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs @@ -220,8 +220,9 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd. If snap to cardinal directions is enabled, modify the offset if(snapcardinal) { - float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 22)) / 45 * 45); + float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90); offset = new Vector2D(0, -offset.GetLength()).GetRotated(angle); + snapgridincrement = true; // We don't want to move the geometry away from the cardinal directions } Vector2D oldpos = dragitem.Position; diff --git a/Source/Plugins/BuilderModes/ClassicModes/DragThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DragThingsMode.cs index edcdcfa5..c709a06a 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DragThingsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DragThingsMode.cs @@ -179,8 +179,9 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd. If snap to cardinal directions is enabled, modify the offset if(snapcardinal) { - float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 22)) / 45 * 45); + float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90); offset = new Vector2D(0, -offset.GetLength()).GetRotated(angle); + snapgridincrement = true; // We don't want to move Things away from the cardinal directions } Vector2D oldpos = dragitem.Position; diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs index bd8555cb..946d5f48 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs @@ -29,11 +29,11 @@ namespace CodeImp.DoomBuilder.BuilderModes { #region ================== Variables - private readonly HintLabel hintLabel; + private readonly HintLabel hintlabel; private Curve curve; private static int segmentLength = 32; - private const int minSegmentLength = 16; - private const int maxSegmentLength = 4096; //just some arbitrary number + private const int MIN_SEGMENT_LENGTH = 16; + private const int MAX_SEGMENT_LENGTH = 4096; //just some arbitrary number //interface private readonly DrawCurveOptionsPanel panel; @@ -44,16 +44,17 @@ namespace CodeImp.DoomBuilder.BuilderModes public DrawCurveMode() { - hintLabel = new HintLabel(); + hintlabel = new HintLabel(General.Colors.InfoLine); + labeluseoffset = false; //Options docker - panel = new DrawCurveOptionsPanel(minSegmentLength, maxSegmentLength); + panel = new DrawCurveOptionsPanel(MIN_SEGMENT_LENGTH, MAX_SEGMENT_LENGTH); panel.OnValueChanged += OptionsPanelOnValueChanged; } public override void Dispose() { - if(!isdisposed && hintLabel != null) hintLabel.Dispose(); + if(!isdisposed && hintlabel != null) hintlabel.Dispose(); base.Dispose(); } @@ -79,10 +80,10 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Update labels for already drawn lines for(int i = 0; i < labels.Count - 1; i++) - SetLabelPosition(labels[i], points[i].pos, points[i + 1].pos); + labels[i].Move(points[i].pos, points[i + 1].pos); // Update label for active line - SetLabelPosition(labels[labels.Count - 1], points[points.Count - 1].pos, curp.pos); + labels[labels.Count - 1].Move(points[points.Count - 1].pos, curp.pos); } // Render drawing lines @@ -141,10 +142,11 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(LineLengthLabel l in labels) renderer.RenderText(l.TextLabel); //Render info label - hintLabel.Start = new Vector2D(mousemappos.x + (32 / renderer.Scale), mousemappos.y - (16 / renderer.Scale)); - hintLabel.End = new Vector2D(mousemappos.x + (96 / renderer.Scale), mousemappos.y); - hintLabel.Text = "SEG LEN: " + segmentLength; - renderer.RenderText(hintLabel.TextLabel); + Vector2D start = new Vector2D(mousemappos.x + (32 / renderer.Scale), mousemappos.y - (16 / renderer.Scale)); + Vector2D end = new Vector2D(mousemappos.x + (96 / renderer.Scale), mousemappos.y); + hintlabel.Move(start, end); + hintlabel.Text = "SEG LEN: " + segmentLength; + renderer.RenderText(hintlabel.TextLabel); // Done renderer.Finish(); @@ -298,12 +300,12 @@ namespace CodeImp.DoomBuilder.BuilderModes [BeginAction("increasesubdivlevel")] protected virtual void IncreaseSubdivLevel() { - if(segmentLength < maxSegmentLength) + if(segmentLength < MAX_SEGMENT_LENGTH) { - int increment = Math.Max(minSegmentLength, segmentLength / 32 * 16); + int increment = Math.Max(MIN_SEGMENT_LENGTH, segmentLength / 32 * 16); segmentLength += increment; - if(segmentLength > maxSegmentLength) segmentLength = maxSegmentLength; + if(segmentLength > MAX_SEGMENT_LENGTH) segmentLength = MAX_SEGMENT_LENGTH; panel.SegmentLength = segmentLength; Update(); } @@ -312,12 +314,12 @@ namespace CodeImp.DoomBuilder.BuilderModes [BeginAction("decreasesubdivlevel")] protected virtual void DecreaseSubdivLevel() { - if(segmentLength > minSegmentLength) + if(segmentLength > MIN_SEGMENT_LENGTH) { - int increment = Math.Max(minSegmentLength, segmentLength / 32 * 16); + int increment = Math.Max(MIN_SEGMENT_LENGTH, segmentLength / 32 * 16); segmentLength -= increment; - if(segmentLength < minSegmentLength) segmentLength = minSegmentLength; + if(segmentLength < MIN_SEGMENT_LENGTH) segmentLength = MIN_SEGMENT_LENGTH; panel.SegmentLength = segmentLength; Update(); } diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs index 7194b0bd..54e5c33e 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs @@ -19,7 +19,6 @@ using System; using System.Collections.Generic; using System.Windows.Forms; -using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Windows; using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Rendering; @@ -66,6 +65,10 @@ namespace CodeImp.DoomBuilder.BuilderModes protected bool snaptonearest; // CTRL to enable protected bool snaptocardinaldirection; //mxd. ALT-SHIFT to enable protected static bool usefourcardinaldirections; + + //mxd. Labels display style + protected bool labelshowangle = true; + protected bool labeluseoffset = true; #endregion @@ -129,7 +132,6 @@ namespace CodeImp.DoomBuilder.BuilderModes { PixelColor stitchcolor = General.Colors.Highlight; PixelColor losecolor = General.Colors.Selection; - PixelColor color; snaptocardinaldirection = General.Interface.ShiftState && General.Interface.AltState; //mxd snaptogrid = (snaptocardinaldirection || General.Interface.ShiftState ^ General.Interface.SnapToGrid); @@ -142,17 +144,18 @@ namespace CodeImp.DoomBuilder.BuilderModes if(labels.Count > 0) { // Update labels for already drawn lines - for(int i = 0; i < labels.Count - 1; i++) - SetLabelPosition(labels[i], points[i].pos, points[i + 1].pos); + for(int i = 0; i < labels.Count - 1; i++) + labels[i].Move(points[i].pos, points[i + 1].pos); // Update label for active line - SetLabelPosition(labels[labels.Count - 1], points[points.Count - 1].pos, curp.pos); + labels[labels.Count - 1].Move(points[points.Count - 1].pos, curp.pos); } // Render drawing lines if(renderer.StartOverlay(true)) { // Go for all points to draw lines + PixelColor color; if(points.Count > 0) { // Render lines @@ -212,55 +215,6 @@ namespace CodeImp.DoomBuilder.BuilderModes Vector2D scaledPerpendicular = delta.GetPerpendicular().GetNormal().GetScaled(18f / renderer.Scale); renderer.RenderLine(middlePoint, new Vector2D(middlePoint.x - scaledPerpendicular.x, middlePoint.y - scaledPerpendicular.y), LINE_THICKNESS, color, true); } - - //mxd - protected void SetLabelPosition(LineLengthLabel label, Vector2D start, Vector2D end) - { - // Check if start/end point is on screen... - Vector2D lt = General.Map.Renderer2D.DisplayToMap(new Vector2D(0.0f, General.Map.Renderer2D.ViewportSize.Height)); - Vector2D rb = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Map.Renderer2D.ViewportSize.Width, 0.0f)); - RectangleF viewport = new RectangleF(lt.x, lt.y, rb.x - lt.x, rb.y - lt.y); - bool startvisible = viewport.Contains(start.x, start.y); - bool endvisible = viewport.Contains(end.x, end.y); - - // Do this only when one point is visible, an the other isn't - if((!startvisible && endvisible) || (startvisible && !endvisible)) - { - Line2D drawnline = new Line2D(start, end); - Line2D[] viewportsides = new[] { - new Line2D(lt, rb.x, lt.y), // top - new Line2D(lt.x, rb.y, rb.x, rb.y), // bottom - new Line2D(lt, lt.x, rb.y), // left - new Line2D(rb.x, lt.y, rb.x, rb.y), // right - }; - - float u; - foreach(Line2D side in viewportsides) - { - // Modify the start point so it stays on screen - if(!startvisible && side.GetIntersection(drawnline, out u)) - { - start = drawnline.GetCoordinatesAt(u); - break; - } - - // Modify the end point so it stays on screen - if(!endvisible && side.GetIntersection(drawnline, out u)) - { - end = drawnline.GetCoordinatesAt(u); - break; - } - } - } - - Vector2D perpendicular = (end - start).GetPerpendicular(); - float angle = perpendicular.GetAngle(); - float offset = label.TextLabel.TextSize.Width * Math.Abs((float)Math.Sin(angle)) + label.TextLabel.TextSize.Height * Math.Abs((float)Math.Cos(angle)); - perpendicular = perpendicular.GetNormal().GetScaled(offset / 2.0f / renderer.Scale); - - label.Start = start + perpendicular; - label.End = end + perpendicular; - } // This returns the aligned and snapped draw position public static DrawnVertex GetCurrentPosition(Vector2D mousemappos, bool snaptonearest, bool snaptogrid, bool snaptocardinal, IRenderer2D renderer, List points) @@ -464,7 +418,7 @@ namespace CodeImp.DoomBuilder.BuilderModes newpoint.stitch = stitch; newpoint.stitchline = stitchline; points.Add(newpoint); - labels.Add(new LineLengthLabel(true)); + labels.Add(new LineLengthLabel(labelshowangle, labeluseoffset)); Update(); // Check if point stitches with the first diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs index 4633ec5c..287502b5 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs @@ -238,7 +238,7 @@ namespace CodeImp.DoomBuilder.BuilderModes Vector2D[] labelCoords = new[] { start, new Vector2D(end.x, start.y), end, new Vector2D(start.x, end.y), start }; for(int i = 1; i < 5; i++) { - SetLabelPosition(labels[i - 1], labelCoords[i], labelCoords[i - 1]); + labels[i - 1].Move(labelCoords[i], labelCoords[i - 1]); renderer.RenderText(labels[i - 1].TextLabel); } @@ -248,9 +248,7 @@ namespace CodeImp.DoomBuilder.BuilderModes hintlabel.Text = "H: " + (slicesH - 1) + "; V: " + (slicesV - 1); if(width > hintlabel.Text.Length * vsize && height > 16 * vsize) { - float vPos = start.y + height / 2.0f; - hintlabel.Start = new Vector2D(start.x, vPos); - hintlabel.End = new Vector2D(end.x, vPos); + hintlabel.Move(start, end); renderer.RenderText(hintlabel.TextLabel); } } @@ -285,8 +283,8 @@ namespace CodeImp.DoomBuilder.BuilderModes if(points.Count == 1) { // Add labels - labels.AddRange(new[] { new LineLengthLabel(false), new LineLengthLabel(false), new LineLengthLabel(false), new LineLengthLabel(false) }); - hintlabel = new HintLabel(); + labels.AddRange(new[] { new LineLengthLabel(false, true), new LineLengthLabel(false, true), new LineLengthLabel(false, true), new LineLengthLabel(false, true) }); + hintlabel = new HintLabel(General.Colors.InfoLine); Update(); } else if(points[0].pos == points[1].pos) diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs index 1707e3ab..0c1b075c 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs @@ -29,7 +29,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { #region ================== Variables - protected HintLabel hintLabel; + protected HintLabel hintlabel; protected int bevelWidth; protected int currentBevelWidth; protected int subdivisions; @@ -61,8 +61,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void Dispose() { - if (!isdisposed && hintLabel != null) - hintLabel.Dispose(); + if (!isdisposed && hintlabel != null) hintlabel.Dispose(); base.Dispose(); } @@ -134,7 +133,7 @@ namespace CodeImp.DoomBuilder.BuilderModes Vector2D[] labelCoords = new[] { start, new Vector2D(end.x, start.y), end, new Vector2D(start.x, end.y), start }; for (int i = 1; i < 5; i++) { - SetLabelPosition(labels[i - 1], labelCoords[i], labelCoords[i - 1]); + labels[i - 1].Move(labelCoords[i], labelCoords[i - 1]); renderer.RenderText(labels[i - 1].TextLabel); } @@ -144,11 +143,9 @@ namespace CodeImp.DoomBuilder.BuilderModes //render hint if (width > 64 * vsize && height > 16 * vsize) { - float vPos = start.y + height / 2.0f; - hintLabel.Start = new Vector2D(start.x, vPos); - hintLabel.End = new Vector2D(end.x, vPos); - hintLabel.Text = GetHintText(); - renderer.RenderText(hintLabel.TextLabel); + hintlabel.Move(start, end); + hintlabel.Text = GetHintText(); + renderer.RenderText(hintlabel.TextLabel); } //and shape corners @@ -294,8 +291,8 @@ namespace CodeImp.DoomBuilder.BuilderModes if (points.Count == 1) //add point and labels { - labels.AddRange(new[] { new LineLengthLabel(false), new LineLengthLabel(false), new LineLengthLabel(false), new LineLengthLabel(false) }); - hintLabel = new HintLabel(); + labels.AddRange(new[] { new LineLengthLabel(false, true), new LineLengthLabel(false, true), new LineLengthLabel(false, true), new LineLengthLabel(false, true) }); + hintlabel = new HintLabel(General.Colors.InfoLine); Update(); } else if (points[0].pos == points[1].pos) //nothing is drawn diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index 3ecf1078..f1a254c0 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -83,7 +83,7 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Methods // This highlights a new item - protected void Highlight(Linedef l) + private void Highlight(Linedef l) { bool completeredraw = false; LinedefActionInfo action = null; @@ -988,7 +988,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // This creates a new vertex at the mouse position [BeginAction("insertitem", BaseAction = true)] - public virtual void InsertVertexAction() + public void InsertVertexAction() { // Start drawing mode DrawGeometryMode drawmode = new DrawGeometryMode(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs index cbfd2cee..86bbdb6f 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs @@ -53,11 +53,11 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Variables // Highlighted item - protected Sector highlighted; + private Sector highlighted; private Association highlightasso = new Association(); // Interface - protected bool editpressed; + private bool editpressed; // Labels private Dictionary labels; @@ -389,7 +389,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // This highlights a new item - protected void Highlight(Sector s) + private void Highlight(Sector s) { // Often we can get away by simply undrawing the previous // highlight and drawing the new highlight. But if associations @@ -482,7 +482,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // This selectes or deselects a sector - protected void SelectSector(Sector s, bool selectstate, bool update) + private void SelectSector(Sector s, bool selectstate, bool update) { bool selectionchanged = false; @@ -1429,7 +1429,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // This creates a new vertex at the mouse position [BeginAction("insertitem", BaseAction = true)] - public virtual void InsertVertexAction() + public void InsertVertexAction() { // Start drawing mode DrawGeometryMode drawmode = new DrawGeometryMode(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs index bf7d1a75..e09105db 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs @@ -216,7 +216,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // This highlights a new item - protected void Highlight(Thing t) + private void Highlight(Thing t) { LinedefActionInfo action = null; @@ -805,7 +805,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // This creates a new thing at the mouse position [BeginAction("insertitem", BaseAction = true)] - public virtual void InsertThing() + public void InsertThing() { // Mouse in window? if(mouseinside) diff --git a/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs b/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs index 3b854384..35a14713 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs @@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Variables // Highlighted item - protected Vertex highlighted; + private Vertex highlighted; private Vector2D insertpreview = new Vector2D(float.NaN, float.NaN); //mxd // Interface @@ -775,7 +775,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // This creates a new vertex at the mouse position [BeginAction("insertitem", BaseAction = true)] - public virtual void InsertVertexAction() { VerticesMode.InsertVertex(mousemappos, renderer.Scale); } + public void InsertVertexAction() { VerticesMode.InsertVertex(mousemappos, renderer.Scale); } public static void InsertVertex(Vector2D mousemappos, float rendererscale) { bool snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid; diff --git a/Source/Plugins/BuilderModes/General/HintLabel.cs b/Source/Plugins/BuilderModes/General/HintLabel.cs index 36322fb8..a390fb68 100644 --- a/Source/Plugins/BuilderModes/General/HintLabel.cs +++ b/Source/Plugins/BuilderModes/General/HintLabel.cs @@ -1,23 +1,57 @@ -using System.Drawing; +using System; +using System.Drawing; using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.Rendering; namespace CodeImp.DoomBuilder.BuilderModes { public class HintLabel : LineLengthLabel { - private string text = ""; - public string Text { get { return text; } set { text = value; Update(); } } + public string Text { get { return label.Text; } set { label.Text = value; } } - public HintLabel() : base(false) + public HintLabel() : base(false, false) { } + public HintLabel(PixelColor textcolor) : base(false, false) { - label.Color = General.Colors.InfoLine; + label.Color = textcolor; } - protected override void Update() + // We don't want any changes here + protected override void UpdateText() { } + + public override void Move(Vector2D start, Vector2D end) { - Vector2D delta = end - start; - label.Text = text; - label.Rectangle = new RectangleF(start.x + delta.x * 0.5f, start.y + delta.y * 0.5f, 0f, 0f); + // Store before making any adjustments to start/end... + this.start = start; + this.end = end; + + // Check if start/end point is on screen... + Vector2D lt = General.Map.Renderer2D.DisplayToMap(new Vector2D(0.0f, General.Map.Renderer2D.ViewportSize.Height)); + Vector2D rb = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Map.Renderer2D.ViewportSize.Width, 0.0f)); + RectangleF viewport = new RectangleF(lt.x, lt.y, rb.x - lt.x, rb.y - lt.y); + bool startvisible = viewport.Contains(start.x, start.y); + bool endvisible = viewport.Contains(end.x, end.y); + + // Get visile area + RectangleF labelrect; + if(!startvisible || !endvisible) + { + float minx = Math.Min(start.x, end.x); + float maxx = Math.Max(start.x, end.x); + float miny = Math.Min(start.y, end.y); + float maxy = Math.Max(start.y, end.y); + RectangleF labelarea = new RectangleF(minx, miny, maxx - minx, maxy - miny); + labelarea.Intersect(viewport); + + labelrect = new RectangleF(labelarea.X + labelarea.Width * 0.5f, labelarea.Y + labelarea.Height * 0.5f, 0f, 0f); + } + else + { + Vector2D delta = end - start; + labelrect = new RectangleF(start.x + delta.x * 0.5f, start.y + delta.y * 0.5f, 0f, 0f); + } + + // Apply changes + label.Rectangle = labelrect; } } } diff --git a/Source/Plugins/BuilderModes/General/LineLengthLabel.cs b/Source/Plugins/BuilderModes/General/LineLengthLabel.cs index f4dc10bf..b23fea20 100644 --- a/Source/Plugins/BuilderModes/General/LineLengthLabel.cs +++ b/Source/Plugins/BuilderModes/General/LineLengthLabel.cs @@ -40,24 +40,42 @@ namespace CodeImp.DoomBuilder.BuilderModes protected TextLabel label; protected Vector2D start; protected Vector2D end; - private readonly bool showAngle; //mxd + + //mxd. Display options + private bool showangle; + private bool offsetposition; #endregion #region ================== Properties public TextLabel TextLabel { get { return label; } } - public Vector2D Start { get { return start; } set { start = value; Update(); } } - public Vector2D End { get { return end; } set { end = value; Update(); } } + + //mxd. Display options + public bool ShowAngle { get { return showangle; } set { showangle = value; UpdateText(); } } + public bool OffsetPosition { get { return offsetposition; } set { offsetposition = value; Move(start, end); } } + public PixelColor TextColor { get { return label.Color; } set { label.Color = value; } } #endregion #region ================== Constructor / Disposer // Constructor - public LineLengthLabel(bool showAngle) + public LineLengthLabel() { - this.showAngle = showAngle; //mxd + this.showangle = true; + this.offsetposition = true; + + // Initialize + Initialize(); + } + + //mxd. Constructor + public LineLengthLabel(bool showangle, bool offsetposition) + { + this.showangle = showangle; + this.offsetposition = offsetposition; + // Initialize Initialize(); } @@ -65,13 +83,27 @@ namespace CodeImp.DoomBuilder.BuilderModes // Constructor public LineLengthLabel(Vector2D start, Vector2D end) { + this.showangle = true; //mxd + this.offsetposition = true; //mxd + + // Initialize + Initialize(); + Move(start, end); + } + + //mxd. Constructor + public LineLengthLabel(Vector2D start, Vector2D end, bool showangle, bool offsetposition) + { + this.showangle = showangle; + this.offsetposition = offsetposition; + // Initialize Initialize(); Move(start, end); } // Initialization - protected virtual void Initialize() + private void Initialize() { label = new TextLabel(TEXT_CAPACITY); label.AlignX = TextAlignmentX.Center; @@ -93,31 +125,85 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Methods // This updates the text - protected virtual void Update() + protected virtual void UpdateText() { Vector2D delta = end - start; - float length = delta.GetLength(); - //mxd - if(showAngle) + // Update label text + float length = delta.GetLength(); + if(showangle) { - int angle = General.ClampAngle((int)Math.Round(Angle2D.RadToDeg(delta.GetAngle()))); - label.Text = "l:" + length.ToString(VALUE_FORMAT) + "; a:" + angle; + int displayangle = General.ClampAngle((int)Math.Round(Angle2D.RadToDeg(delta.GetAngle()))); + label.Text = "l:" + length.ToString(VALUE_FORMAT) + "; a:" + displayangle; } else { label.Text = length.ToString(VALUE_FORMAT); } - - label.Rectangle = new RectangleF(start.x + delta.x * 0.5f, start.y + delta.y * 0.5f, 0f, 0f); } - // This moves the label - public void Move(Vector2D start, Vector2D end) + //mxd. This moves the label so it stays on screen and offsets it vertically so it doesn't overlap the line + public virtual void Move(Vector2D start, Vector2D end) { + // Store before making any adjustments to start/end... this.start = start; this.end = end; - Update(); + + // Update text label + UpdateText(); + + // Check if start/end point is on screen... + Vector2D lt = General.Map.Renderer2D.DisplayToMap(new Vector2D(0.0f, General.Map.Renderer2D.ViewportSize.Height)); + Vector2D rb = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Map.Renderer2D.ViewportSize.Width, 0.0f)); + RectangleF viewport = new RectangleF(lt.x, lt.y, rb.x - lt.x, rb.y - lt.y); + bool startvisible = viewport.Contains(start.x, start.y); + bool endvisible = viewport.Contains(end.x, end.y); + + // Do this only when one point is visible, an the other isn't + if((!startvisible && endvisible) || (startvisible && !endvisible)) + { + Line2D drawnline = new Line2D(start, end); + Line2D[] viewportsides = new[] { + new Line2D(lt, rb.x, lt.y), // top + new Line2D(lt.x, rb.y, rb.x, rb.y), // bottom + new Line2D(lt, lt.x, rb.y), // left + new Line2D(rb.x, lt.y, rb.x, rb.y), // right + }; + + float u; + foreach(Line2D side in viewportsides) + { + // Modify the start point so it stays on screen + if(!startvisible && side.GetIntersection(drawnline, out u)) + { + start = drawnline.GetCoordinatesAt(u); + break; + } + + // Modify the end point so it stays on screen + if(!endvisible && side.GetIntersection(drawnline, out u)) + { + end = drawnline.GetCoordinatesAt(u); + break; + } + } + } + + // Update label position + if(offsetposition) + { + Vector2D perpendicular = (end - start).GetPerpendicular(); + float angle = perpendicular.GetAngle(); + SizeF textsize = General.Map.GetTextSize(label.Text, label.Scale); + float offset = textsize.Width * Math.Abs((float)Math.Sin(angle)) + textsize.Height * Math.Abs((float)Math.Cos(angle)); + perpendicular = perpendicular.GetNormal().GetScaled(offset / 2.0f / General.Map.Renderer2D.Scale); + start += perpendicular; + end += perpendicular; + } + + // Apply changes + Vector2D delta = end - start; + label.Rectangle = new RectangleF(start.x + delta.x * 0.5f, start.y + delta.y * 0.5f, 0f, 0f); } #endregion diff --git a/Source/Plugins/BuilderModes/Resources/Hints.cfg b/Source/Plugins/BuilderModes/Resources/Hints.cfg index 340e2307..b46e1ee1 100644 --- a/Source/Plugins/BuilderModes/Resources/Hints.cfg +++ b/Source/Plugins/BuilderModes/Resources/Hints.cfg @@ -163,14 +163,14 @@ group general "Hold Shift to toggle grid snapping" "Hold Ctrl to toggle snapping to nearest vertex" "Hold Alt to snap by grid increment" -"Hold Alt - Shift to snap to 8 cardinal directions" +"Hold Alt - Shift to snap to 4 cardinal directions" class DragThingsMode group general "Hold Shift to toggle grid snapping" "Hold Ctrl to toggle snapping to nearest vertex" "Hold Alt to snap by grid increment" -"Hold Alt - Shift to snap to 8 cardinal directions" +"Hold Alt - Shift to snap to 4 cardinal directions" class DrawGeometryMode group general diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs index 99928151..8ebce66c 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs @@ -41,7 +41,6 @@ namespace CodeImp.DoomBuilder.BuilderModes private readonly BaseVisualMode mode; - private ThingTypeInfo info; private bool isloaded; private bool nointeraction; //mxd private ImageData sprite; @@ -55,14 +54,13 @@ namespace CodeImp.DoomBuilder.BuilderModes private int undoticket; // If this is set to true, the thing will be rebuilt after the action is performed. - protected bool changed; + private bool changed; #endregion #region ================== Properties public bool Changed { get { return changed; } set { changed |= value; } } - public ThingTypeInfo Info { get { return info; } } //mxd #endregion @@ -98,7 +96,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // This builds the thing geometry. Returns false when nothing was created. - public virtual bool Setup() + public bool Setup() { int sectorcolor = new PixelColor(255, 255, 255, 255).ToInt(); @@ -122,10 +120,14 @@ namespace CodeImp.DoomBuilder.BuilderModes if(sprite != null) { + Plane floor = new Plane(); //mxd + Plane ceiling = new Plane(); //mxd if(Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); - SectorLevel level = sd.GetLevelAboveOrAt(new Vector3D(Thing.Position.x, Thing.Position.y, Thing.Position.z + Thing.Sector.FloorHeight)); + floor = sd.Floor.plane; //mxd + ceiling = sd.Ceiling.plane; //mxd + SectorLevel level = sd.GetLevelAboveOrAt(new Vector3D(Thing.Position.x, Thing.Position.y, Thing.Position.z + sd.Floor.plane.GetZ(Thing.Position))); //mxd. Let's use point on floor plane instead of Thing.Sector.FloorHeight; if(nointeraction && level == null && sd.LightLevels.Count > 0) level = sd.LightLevels[sd.LightLevels.Count - 1]; //mxd. Use the light level of the highest surface when a thing is above highest sector level. if(level != null) { @@ -184,7 +186,7 @@ namespace CodeImp.DoomBuilder.BuilderModes verts[4] = verts[2]; verts[5] = new WorldVertex(+radius + offsetx, 0.0f, offsety, sectorcolor, 1.0f, 1.0f); } - SetVertices(verts); + SetVertices(verts, floor, ceiling); } else { @@ -202,7 +204,7 @@ namespace CodeImp.DoomBuilder.BuilderModes verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, sectorcolor, 1.0f, 1.0f); - SetVertices(verts); + SetVertices(verts, floor, ceiling); } } @@ -446,7 +448,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public virtual bool IsSelected() + public bool IsSelected() { return selected; } @@ -456,33 +458,33 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Events // Unused - public virtual void OnSelectBegin() { } - public virtual void OnEditBegin() { } - public virtual void OnMouseMove(MouseEventArgs e) { } - public virtual void OnChangeTargetBrightness(bool up) { } - public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } - public virtual void OnSelectTexture() { } - public virtual void OnCopyTexture() { } - public virtual void OnPasteTexture() { } - public virtual void OnCopyTextureOffsets() { } - public virtual void OnPasteTextureOffsets() { } - public virtual void OnTextureAlign(bool alignx, bool aligny) { } - public virtual void OnToggleUpperUnpegged() { } - public virtual void OnToggleLowerUnpegged() { } - public virtual void OnProcess(float deltatime) { } - public virtual void OnTextureFloodfill() { } - public virtual void OnInsert() { } - public virtual void OnTextureFit(FitTextureOptions options) { } //mxd - public virtual void ApplyTexture(string texture) { } - public virtual void ApplyUpperUnpegged(bool set) { } - public virtual void ApplyLowerUnpegged(bool set) { } - public virtual void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd + public void OnSelectBegin() { } + public void OnEditBegin() { } + public void OnMouseMove(MouseEventArgs e) { } + public void OnChangeTargetBrightness(bool up) { } + public void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } + public void OnSelectTexture() { } + public void OnCopyTexture() { } + public void OnPasteTexture() { } + public void OnCopyTextureOffsets() { } + public void OnPasteTextureOffsets() { } + public void OnTextureAlign(bool alignx, bool aligny) { } + public void OnToggleUpperUnpegged() { } + public void OnToggleLowerUnpegged() { } + public void OnProcess(float deltatime) { } + public void OnTextureFloodfill() { } + public void OnInsert() { } + public void OnTextureFit(FitTextureOptions options) { } //mxd + public void ApplyTexture(string texture) { } + public void ApplyUpperUnpegged(bool set) { } + public void ApplyLowerUnpegged(bool set) { } + public void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd // Return texture name - public virtual string GetTextureName() { return ""; } + public string GetTextureName() { return ""; } // Select or deselect - public virtual void OnSelectEnd() + public void OnSelectEnd() { if(this.selected) { @@ -497,7 +499,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd. Delete thing - public virtual void OnDelete() + public void OnDelete() { mode.CreateUndo("Delete thing"); mode.SetActionResult("Deleted a thing."); @@ -511,14 +513,14 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Copy properties - public virtual void OnCopyProperties() + public void OnCopyProperties() { BuilderPlug.Me.CopiedThingProps = new ThingProperties(Thing); mode.SetActionResult("Copied thing properties."); } // Paste properties - public virtual void OnPasteProperties() + public void OnPasteProperties() { if(BuilderPlug.Me.CopiedThingProps != null) { @@ -532,7 +534,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Edit button released - public virtual void OnEditEnd() + public void OnEditEnd() { if(General.Interface.IsActiveWindow) { @@ -564,7 +566,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public virtual void OnResetTextureOffset() + public void OnResetTextureOffset() { mode.CreateUndo("Reset thing scale"); mode.SetActionResult("Thing scale reset."); @@ -576,7 +578,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public virtual void OnResetLocalTextureOffset() + public void OnResetLocalTextureOffset() { mode.CreateUndo("Reset thing scale, pitch and roll"); mode.SetActionResult("Thing scale, pitch and roll reset."); @@ -590,7 +592,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Raise/lower thing - public virtual void OnChangeTargetHeight(int amount) + public void OnChangeTargetHeight(int amount) { if(General.Map.FormatInterface.HasThingHeight) { @@ -617,7 +619,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public virtual void OnChangeScale(int incrementX, int incrementY) + public void OnChangeScale(int incrementX, int incrementY) { if(!General.Map.UDMF || !sprite.IsImageLoaded) return; diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs index dc9f96e1..e5d4c3c4 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs @@ -14,7 +14,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { #region ================== Variables - protected BaseVisualMode mode; + private BaseVisualMode mode; private float cageradius2; private Vector3D boxp1; private Vector3D boxp2; @@ -111,7 +111,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public virtual bool IsSelected() + public bool IsSelected() { return selected; } @@ -226,38 +226,38 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Unused events // Unused - public virtual void OnSelectBegin() { } - public virtual void OnEditBegin() { } - public virtual void OnMouseMove(MouseEventArgs e) { } - public virtual void OnChangeTargetBrightness(bool up) { } - public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } - public virtual void OnChangeScale(int incrementX, int incrementY) { } - public virtual void OnSelectTexture() { } - public virtual void OnCopyTexture() { } - public virtual void OnPasteTexture() { } - public virtual void OnCopyTextureOffsets() { } - public virtual void OnPasteTextureOffsets() { } - public virtual void OnTextureAlign(bool alignx, bool aligny) { } - public virtual void OnTextureFit(FitTextureOptions options) { } //mxd - public virtual void OnToggleUpperUnpegged() { } - public virtual void OnToggleLowerUnpegged() { } - public virtual void OnResetTextureOffset() { } - public virtual void OnResetLocalTextureOffset() { } //mxd - public virtual void OnProcess(float deltatime) { } - public virtual void OnTextureFloodfill() { } - public virtual void OnInsert() { } - public virtual void ApplyTexture(string texture) { } - public virtual void ApplyUpperUnpegged(bool set) { } - public virtual void ApplyLowerUnpegged(bool set) { } - public virtual string GetTextureName() { return ""; } - public virtual void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd + public void OnSelectBegin() { } + public void OnEditBegin() { } + public void OnMouseMove(MouseEventArgs e) { } + public void OnChangeTargetBrightness(bool up) { } + public void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } + public void OnChangeScale(int incrementX, int incrementY) { } + public void OnSelectTexture() { } + public void OnCopyTexture() { } + public void OnPasteTexture() { } + public void OnCopyTextureOffsets() { } + public void OnPasteTextureOffsets() { } + public void OnTextureAlign(bool alignx, bool aligny) { } + public void OnTextureFit(FitTextureOptions options) { } //mxd + public void OnToggleUpperUnpegged() { } + public void OnToggleLowerUnpegged() { } + public void OnResetTextureOffset() { } + public void OnResetLocalTextureOffset() { } //mxd + public void OnProcess(float deltatime) { } + public void OnTextureFloodfill() { } + public void OnInsert() { } + public void ApplyTexture(string texture) { } + public void ApplyUpperUnpegged(bool set) { } + public void ApplyLowerUnpegged(bool set) { } + public string GetTextureName() { return ""; } + public void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd #endregion #region ================== Events // Select or deselect - public virtual void OnSelectEnd() + public void OnSelectEnd() { if(this.selected) { @@ -272,14 +272,14 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Copy properties - public virtual void OnCopyProperties() + public void OnCopyProperties() { BuilderPlug.Me.CopiedVertexProps = new VertexProperties(vertex); mode.SetActionResult("Copied vertex properties."); } // Paste properties - public virtual void OnPasteProperties() + public void OnPasteProperties() { if(BuilderPlug.Me.CopiedVertexProps != null) { @@ -295,7 +295,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } //Delete key pressed - remove zoffset field - public virtual void OnDelete() + public void OnDelete() { mode.CreateUndo("Clear vertex height offset"); mode.SetActionResult("Cleared vertex height offset."); @@ -323,7 +323,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Edit button released - public virtual void OnEditEnd() + public void OnEditEnd() { if(General.Interface.IsActiveWindow) { @@ -365,7 +365,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Raise/lower thing - public virtual void OnChangeTargetHeight(int amount) + public void OnChangeTargetHeight(int amount) { if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) undoticket = mode.CreateUndo("Change vertex height"); diff --git a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs index fdb30b81..d815edb7 100644 --- a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs @@ -25,7 +25,6 @@ namespace CodeImp.DoomBuilder.BuilderModes // This doesn't do jack shit. internal class NullVisualEventReceiver : IVisualEventReceiver { - public NullVisualEventReceiver() { } public void OnSelectBegin() { } public void OnSelectEnd() { } public void OnEditBegin() { } @@ -34,7 +33,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public void OnChangeTargetHeight(int amount) { } public void OnChangeTargetBrightness(bool up) { } public void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } - public virtual void OnChangeScale(int incrementX, int incrementY) { } //mxd + public void OnChangeScale(int incrementX, int incrementY) { } //mxd public void OnResetTextureOffset() { } public void OnResetLocalTextureOffset() { } //mxd public void OnSelectTexture() { }