diff --git a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs index a77c853fa842c585e740aaa04e1239793d6bf592..ce20fce4b7f788007fdac8515f2bdd1d2961d7d7 100644 --- a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs @@ -190,7 +190,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // toolStripMenuItem2 // this.toolStripMenuItem2.Name = "toolStripMenuItem2"; - this.toolStripMenuItem2.Size = new System.Drawing.Size(146, 6); + this.toolStripMenuItem2.Size = new System.Drawing.Size(149, 6); + this.toolStripMenuItem2.Visible = false; // // thingsmenu // diff --git a/Source/Plugins/BuilderModes/Resources/Actions.cfg b/Source/Plugins/BuilderModes/Resources/Actions.cfg index 55c9c70dd949221dd9dcdd677ffda1380e90a36a..2cd49f05678f5b9a7a3acc92d8f389035f186aab 100644 --- a/Source/Plugins/BuilderModes/Resources/Actions.cfg +++ b/Source/Plugins/BuilderModes/Resources/Actions.cfg @@ -844,6 +844,18 @@ pasteproperties allowscroll = true; } +//mxd +toggleslope +{ + title = "Toggle Slope"; + category = "visual"; + description = "Toggles Slope for selected surfaces. Select or highlight upper/lower walls to add a slope. Select or highlight floors or ceilings to remove slope."; + allowkeys = true; + allowmouse = true; + allowscroll = true; + default = 262227; //Alt-S +} + placevisualstart { title = "Place Visual Mode Camera"; diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs index 56e49bf87a85c1b74f35d6b587fe950417847222..86186c4a12d779bbb1ef6a486d38d0a064357e5e 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs @@ -124,16 +124,17 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd. Modify offsets based on surface and camera angles if (General.Map.UDMF) { - float angle = 0; - if(GeometryType == VisualGeometryType.CEILING && level.sector.Fields.ContainsKey("rotationceiling")) - angle = Angle2D.DegToRad((float)level.sector.Fields["rotationceiling"].Value);// * (float)Math.PI / 180f; - else if(GeometryType == VisualGeometryType.FLOOR && level.sector.Fields.ContainsKey("rotationfloor")) - angle = Angle2D.DegToRad((float)level.sector.Fields["rotationfloor"].Value);// *(float)Math.PI / 180f; - - Vector2D v = new Vector2D(offsetx, offsety).GetRotated(angle); - Point p = getTranslatedTextureOffset(new Point((int)Math.Round(v.x), (int)Math.Round(v.y))); - offsetx = p.X; - offsety = p.Y; + float angle = 0; + + if(GeometryType == VisualGeometryType.CEILING) + angle = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0f)); + else + angle = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0f)); + + Vector2D v = new Vector2D(offsetx, offsety).GetRotated(angle); + + offsetx = (int)Math.Round(v.x); + offsety = (int)Math.Round(v.y); } // Apply offsets @@ -151,27 +152,6 @@ namespace CodeImp.DoomBuilder.BuilderModes return level.sector; } - //mxd. Modify texture offsets based on camera angle (so "movetextureleft" action always moves texture more or less "left" etc.) - protected Point getTranslatedTextureOffset(Point p) { - Point tp = new Point(); - int camAngle = (int)Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY);// * 180f / (float)Math.PI); - - if (camAngle > 315 || camAngle < 46) { - tp = p; - } else if (camAngle > 225) { - tp.Y = p.X; - tp.X = -p.Y; - } else if (camAngle > 135) { - tp.X = -p.X; - tp.Y = -p.Y; - }else{ - tp.Y = -p.X; - tp.X = p.Y; - } - - return tp; - } - //mxd protected void onTextureChanged() { if(level.sector == this.Sector.Sector) { @@ -206,7 +186,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Unused public virtual void OnEditBegin() { } - public virtual void OnTextureAlign(bool alignx, bool aligny) { } + //public virtual void OnTextureAlign(bool alignx, bool aligny) { } public virtual void OnToggleUpperUnpegged() { } public virtual void OnToggleLowerUnpegged() { } public virtual void OnResetTextureOffset() { } @@ -387,6 +367,41 @@ namespace CodeImp.DoomBuilder.BuilderModes } } } + + //mxd. Auto-align texture offsets + public virtual void OnTextureAlign(bool alignx, bool aligny) { + if(!General.Map.UDMF) return; + + //create undo + string rest = string.Empty; + if(alignx && aligny) rest = "(X and Y)"; + else if(alignx) rest = "(X)"; + else rest = "(Y)"; + + mode.CreateUndo("Auto-align textures " + rest); + mode.SetActionResult("Auto-aligned textures " + rest + "."); + + //get selection + List<VisualGeometry> selection = mode.GetSelectedSurfaces(); + + //align textures on slopes + foreach(VisualGeometry vg in selection) { + if(vg.GeometryType == VisualGeometryType.FLOOR || vg.GeometryType == VisualGeometryType.CEILING) { + if(vg.GeometryType == VisualGeometryType.FLOOR) + ((VisualFloor)vg).AlignTexture(alignx, aligny); + else + ((VisualCeiling)vg).AlignTexture(alignx, aligny); + + vg.Sector.Sector.UpdateNeeded = true; + vg.Sector.Sector.UpdateCache(); + } + } + + // Map is changed + General.Map.Map.Update(); + General.Map.IsChanged = true; + General.Interface.RefreshInfo(); + } // Copy properties public virtual void OnCopyProperties() @@ -506,24 +521,49 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Texture offset change - public virtual void OnChangeTextureOffset(int horizontal, int vertical) + public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { //mxd - if (General.Map.UDMF) { - if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) - undoticket = mode.CreateUndo("Change texture offsets"); + if (!General.Map.UDMF) { + General.ShowErrorMessage("Floor/ceiling texture offsets cannot be changed in this map format!", MessageBoxButtons.OK); + return; + } - // Apply offsets - MoveTextureOffset(new Point(-horizontal, -vertical)); + if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) + undoticket = mode.CreateUndo("Change texture offsets"); - mode.SetActionResult("Changed texture offsets by " + -horizontal + ", " + -vertical + "."); + //mxd + if(doSurfaceAngleCorrection) { + Point p = new Point(horizontal, vertical); + float angle = Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY); + if(GeometryType == VisualGeometryType.CEILING) { + angle += level.sector.Fields.GetValue("rotationceiling", 0f); + } else + angle += level.sector.Fields.GetValue("rotationfloor", 0f); + + angle = General.ClampAngle(angle); + + if(angle > 315 || angle < 46) { + + } else if(angle > 225) { + vertical = p.X; + horizontal = -p.Y; + } else if(angle > 135) { + horizontal = -p.X; + vertical = -p.Y; + } else { + vertical = -p.X; + horizontal = p.Y; + } + } - // Update sector geometry - Sector.UpdateSectorGeometry(false); - Sector.Rebuild(); - } else { - General.ShowErrorMessage("Floor/ceiling texture offsets cannot be changed in this map format!", MessageBoxButtons.OK); - } + // Apply offsets + MoveTextureOffset(new Point(-horizontal, -vertical)); + mode.SetActionResult("Changed texture offsets by " + (-horizontal) + ", " + (-vertical) + "."); + + // Update sector geometry + Sector.UpdateSectorGeometry(false); + Sector.Rebuild(); } #endregion diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs index 785a1452f36b68037cfbd728461b39101db55175..dbbbbce40f1596459806e51c287a61d1471dd840 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs @@ -756,11 +756,17 @@ namespace CodeImp.DoomBuilder.BuilderModes } } - // Auto-align texture X offsets + // Auto-align texture offsets public virtual void OnTextureAlign(bool alignx, bool aligny) { - mode.CreateUndo("Auto-align textures"); - mode.SetActionResult("Auto-aligned textures."); + //mxd + string rest = string.Empty; + if(alignx && aligny) rest = "(X and Y)"; + else if(alignx) rest = "(X)"; + else rest = "(Y)"; + + mode.CreateUndo("Auto-align textures " + rest); + mode.SetActionResult("Auto-aligned textures " + rest + "."); // Make sure the texture is loaded (we need the texture size) if(!base.Texture.IsImageLoaded) base.Texture.LoadImage(); @@ -1068,7 +1074,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Texture offset change - public virtual void OnChangeTextureOffset(int horizontal, int vertical) + public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) undoticket = mode.CreateUndo("Change texture offsets"); diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index 125472f86c49ceaac3b39ed28678ee7abdac6f84..76397e7009c702d176df9c19bf6b3159f3eb8703 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -1229,7 +1229,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(!donesides.ContainsKey((i as BaseVisualGeometrySidedef).Sidedef)) { - i.OnChangeTextureOffset(dx, dy); + i.OnChangeTextureOffset(dx, dy, false); donesides.Add((i as BaseVisualGeometrySidedef).Sidedef, 0); } } @@ -1247,7 +1247,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(!donesectors.ContainsKey((i as BaseVisualGeometrySector).Sector.Sector)) { - i.OnChangeTextureOffset(dx, dy); + i.OnChangeTextureOffset(dx, dy, false); donesectors.Add((i as BaseVisualGeometrySector).Sector.Sector, 0); } } @@ -2015,7 +2015,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(-1, 0); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(-1, 0, true); PostAction(); } @@ -2024,7 +2024,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(1, 0); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(1, 0, true); PostAction(); } @@ -2033,7 +2033,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, -1); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, -1, true); PostAction(); } @@ -2042,7 +2042,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, 1); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, 1, true); PostAction(); } @@ -2051,7 +2051,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(-8, 0); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(-8, 0, true); PostAction(); } @@ -2060,7 +2060,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(8, 0); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(8, 0, true); PostAction(); } @@ -2069,7 +2069,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, -8); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, -8, true); PostAction(); } @@ -2078,7 +2078,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { PreAction(UndoGroup.TextureOffsetChange); List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, 8); + foreach (IVisualEventReceiver i in objs) i.OnChangeTextureOffset(0, 8, true); PostAction(); } @@ -2474,6 +2474,129 @@ namespace CodeImp.DoomBuilder.BuilderModes UpdateChangedObjects(); ShowTargetInfo(); } + + //mxd + [BeginAction("toggleslope")] + public void ToggleSlope() { + List<VisualGeometry> selection = GetSelectedSurfaces(); + + if(selection.Count == 0) { + General.Interface.DisplayStatus(StatusType.Warning, "Toggle Slope action requires selected surfaces!"); + return; + } + + bool update = false; + List<BaseVisualSector> toUpdate = new List<BaseVisualSector>(); + General.Map.UndoRedo.CreateUndo("Toggle Slope"); + + //check selection + foreach(VisualGeometry vg in selection) { + update = false; + + //assign/remove action + if(vg.GeometryType == VisualGeometryType.WALL_BOTTOM) { + if(vg.Sidedef.Line.Action == 0 || (vg.Sidedef.Line.Action == 181 && vg.Sidedef.Line.Args[0] == 0)) { + //check if the sector already has floor slopes + foreach(Sidedef side in vg.Sidedef.Sector.Sidedefs) { + if(side == vg.Sidedef || side.Line.Action != 181) + continue; + + int arg = (side == side.Line.Front ? 1 : 2); + + if(side.Line.Args[0] == arg) { + //if only floor is affected, remove action + if(side.Line.Args[1] == 0) + side.Line.Action = 0; + else //clear floor alignment + side.Line.Args[0] = 0; + } + } + + //set action + vg.Sidedef.Line.Action = 181; + vg.Sidedef.Line.Args[0] = (vg.Sidedef == vg.Sidedef.Line.Front ? 1 : 2); + update = true; + } + } else if(vg.GeometryType == VisualGeometryType.WALL_UPPER) { + if(vg.Sidedef.Line.Action == 0 || (vg.Sidedef.Line.Action == 181 && vg.Sidedef.Line.Args[1] == 0)) { + //check if the sector already has ceiling slopes + foreach(Sidedef side in vg.Sidedef.Sector.Sidedefs) { + if(side == vg.Sidedef || side.Line.Action != 181) + continue; + + int arg = (side == side.Line.Front ? 1 : 2); + + if(side.Line.Args[1] == arg) { + //if only ceiling is affected, remove action + if(side.Line.Args[0] == 0) + side.Line.Action = 0; + else //clear ceiling alignment + side.Line.Args[1] = 0; + } + } + + //set action + vg.Sidedef.Line.Action = 181; + vg.Sidedef.Line.Args[1] = (vg.Sidedef == vg.Sidedef.Line.Front ? 1 : 2); + update = true; + } + } else if(vg.GeometryType == VisualGeometryType.CEILING) { + //check if the sector has ceiling slopes + foreach(Sidedef side in vg.Sector.Sector.Sidedefs) { + if(side.Line.Action != 181) + continue; + + int arg = (side == side.Line.Front ? 1 : 2); + + if(side.Line.Args[1] == arg) { + //if only ceiling is affected, remove action + if(side.Line.Args[0] == 0) + side.Line.Action = 0; + else //clear ceiling alignment + side.Line.Args[1] = 0; + + update = true; + } + } + } else if(vg.GeometryType == VisualGeometryType.FLOOR) { + //check if the sector has floor slopes + foreach(Sidedef side in vg.Sector.Sector.Sidedefs) { + if(side.Line.Action != 181) + continue; + + int arg = (side == side.Line.Front ? 1 : 2); + + if(side.Line.Args[0] == arg) { + //if only floor is affected, remove action + if(side.Line.Args[1] == 0) + side.Line.Action = 0; + else //clear floor alignment + side.Line.Args[0] = 0; + + update = true; + } + } + } + + //add to update list + if(update) + toUpdate.Add(vg.Sector as BaseVisualSector); + } + + //update changed geometry + if(toUpdate.Count > 0) { + RebuildElementData(); + + foreach(BaseVisualSector vs in toUpdate) + vs.UpdateSectorGeometry(true); + + UpdateChangedObjects(); + ClearSelection(); + ShowTargetInfo(); + } + + General.Interface.DisplayStatus(StatusType.Action, "Toggled Slope for " + toUpdate.Count + (toUpdate.Count == 1 ? " surface." : " surfaces.")); + } #endregion diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs index 93c66881b48c502abcf40c70578e7005a48ccc86..3cc4af74d8027fa9bd4c21ce732b5efcbc064084 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs @@ -438,7 +438,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public virtual void OnEditBegin() { } public virtual void OnMouseMove(MouseEventArgs e) { } public virtual void OnChangeTargetBrightness(bool up) { } - public virtual void OnChangeTextureOffset(int horizontal, int vertical) { } + public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } public virtual void OnSelectTexture() { } public virtual void OnCopyTexture() { } public virtual void OnPasteTexture() { } diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs index 10ba209d86a566017dd0ca8863e1b021c4181a81..bccbbbc10ebb8810d5adb147fa2773673d1e2601 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs @@ -204,7 +204,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public virtual void OnEditBegin() { } public virtual void OnMouseMove(MouseEventArgs e) { } public virtual void OnChangeTargetBrightness(bool up) { } - public virtual void OnChangeTextureOffset(int horizontal, int vertical) { } + public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } public virtual void OnSelectTexture() { } public virtual void OnCopyTexture() { } public virtual void OnPasteTexture() { } diff --git a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs index bbf0b4c582c38f1b90af0125154173a011d16cbd..a6efd89cfbe535e211968e3fab7d7ddf5ad405a2 100644 --- a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs @@ -32,7 +32,7 @@ namespace CodeImp.DoomBuilder.BuilderModes void OnMouseMove(MouseEventArgs e); void OnChangeTargetHeight(int amount); void OnChangeTargetBrightness(bool up); - void OnChangeTextureOffset(int horizontal, int vertical); + void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection); void OnResetTextureOffset(); void OnSelectTexture(); void OnCopyTexture(); diff --git a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs index 021fbc5ca1d522bbfefe0bbfd037ecd599e733a9..701ae46ab599038a18d5f31a5126a40a0a6244b8 100644 --- a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs @@ -57,7 +57,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { } - public void OnChangeTextureOffset(int horizontal, int vertical) + public void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs index 49684fde8128c299c5e55c731fa130df47fa00da..01f6c0ba60f0b82b533f70b9c41aea05a94577e7 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs @@ -179,7 +179,6 @@ namespace CodeImp.DoomBuilder.BuilderModes s.Fields.BeforeFieldsChange(); float oldx = s.Fields.GetValue("xpanningceiling", 0.0f); float oldy = s.Fields.GetValue("ypanningceiling", 0.0f); - xy = getTranslatedTextureOffset(xy); s.Fields["xpanningceiling"] = new UniValue(UniversalType.Float, oldx + (float)xy.X); s.Fields["ypanningceiling"] = new UniValue(UniversalType.Float, oldy + (float)xy.Y); s.UpdateNeeded = true; @@ -376,6 +375,96 @@ namespace CodeImp.DoomBuilder.BuilderModes vs.Ceiling.SelectNeighbours(select, withSameTexture, withSameHeight); } } + + //mxd + public void AlignTexture(bool alignx, bool aligny) { + if(!General.Map.UDMF) return; + + float slopeAngle = level.plane.Normal.GetAngleZ() - Angle2D.PIHALF; + + if(slopeAngle == 0) return; //it's a horizontal plane + + //find slope source linedef + Linedef slopeSource = null; + bool isFront = false; + + foreach(Sidedef side in Sector.Sector.Sidedefs) { + if(side.Line.Action == 181) { + if(side.Line.Args[1] == 1 && side.Line.Front != null && side.Line.Front == side) { + slopeSource = side.Line; + isFront = true; + break; + } else if(side.Line.Args[1] == 2 && side.Line.Back != null && side.Line.Back == side) { + slopeSource = side.Line; + break; + } + } + } + + if(slopeSource == null) return; + + Sector.Sector.Fields.BeforeFieldsChange(); + + //match rotation + float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(slopeSource.Angle) + 90 : -Angle2D.RadToDeg(slopeSource.Angle) - 90), 1); + + if((isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight) || + (!isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight)) { + sourceAngle = General.ClampAngle(sourceAngle + 180); + } + + if(sourceAngle != 0) { + if(!Sector.Sector.Fields.ContainsKey("rotationceiling")) + Sector.Sector.Fields.Add("rotationceiling", new UniValue(UniversalType.Float, sourceAngle)); + else + Sector.Sector.Fields["rotationceiling"].Value = sourceAngle; + } else if(Sector.Sector.Fields.ContainsKey("rotationceiling")) { + Sector.Sector.Fields.Remove("rotationceiling"); + } + + //update scaleY + float scaleX = Sector.Sector.Fields.GetValue("xscaleceiling", 1.0f); + float scaleY = (float)Math.Round(scaleX * (1 / (float)Math.Cos(slopeAngle)), 2); + + if(aligny) { + if(Sector.Sector.Fields.ContainsKey("yscaleceiling")) + Sector.Sector.Fields["yscaleceiling"].Value = scaleY; + else + Sector.Sector.Fields.Add("yscaleceiling", new UniValue(UniversalType.Float, scaleY)); + } + + //update texture offsets + Vector2D offset; + if((isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight) || + (!isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight)) { + offset = slopeSource.End.Position; + } else { + offset = slopeSource.Start.Position; + } + + offset = offset.GetRotated(Angle2D.DegToRad(sourceAngle)); + + if(alignx) { + if(Texture != null) offset.x %= Texture.Width / scaleX; + + if(Sector.Sector.Fields.ContainsKey("xpanningceiling")) + Sector.Sector.Fields["xpanningceiling"].Value = (float)Math.Round(-offset.x); + else + Sector.Sector.Fields.Add("xpanningceiling", new UniValue(UniversalType.Float, (float)Math.Round(-offset.x))); + } + + if(aligny) { + if(Texture != null) offset.y %= Texture.Height / scaleY; + + if(Sector.Sector.Fields.ContainsKey("ypanningceiling")) + Sector.Sector.Fields["ypanningceiling"].Value = (float)Math.Round(offset.y); + else + Sector.Sector.Fields.Add("ypanningceiling", new UniValue(UniversalType.Float, (float)Math.Round(offset.y))); + } + + //update geometry + Sector.UpdateSectorGeometry(false); + } #endregion } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs index ed0083ca2018cf3dd4ff6e4d2475e95499f2b308..f6f1f9c650442e5f42587a3ec534fc71c80341a0 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs @@ -87,20 +87,14 @@ namespace CodeImp.DoomBuilder.BuilderModes s.Fields.GetValue("yscalefloor", 1.0f)); //Load floor texture - //if((s.FloorTexture.Length > 0) && (s.FloorTexture[0] != '-')) { - base.Texture = General.Map.Data.GetFlatImage(s.LongFloorTexture); - if(base.Texture == null) { - base.Texture = General.Map.Data.MissingTexture3D; - setuponloadedtexture = s.LongFloorTexture; - } else { - if(!base.Texture.IsImageLoaded) - setuponloadedtexture = s.LongFloorTexture; - } - /*} else { - // Use missing texture + base.Texture = General.Map.Data.GetFlatImage(s.LongFloorTexture); + if(base.Texture == null) { base.Texture = General.Map.Data.MissingTexture3D; - setuponloadedtexture = 0; - }*/ + setuponloadedtexture = s.LongFloorTexture; + } else { + if(!base.Texture.IsImageLoaded) + setuponloadedtexture = s.LongFloorTexture; + } // Determine texture scale if(base.Texture.IsImageLoaded) @@ -178,7 +172,6 @@ namespace CodeImp.DoomBuilder.BuilderModes s.Fields.BeforeFieldsChange(); float oldx = s.Fields.GetValue("xpanningfloor", 0.0f); float oldy = s.Fields.GetValue("ypanningfloor", 0.0f); - xy = getTranslatedTextureOffset(xy); s.Fields["xpanningfloor"] = new UniValue(UniversalType.Float, oldx + (float)xy.X); s.Fields["ypanningfloor"] = new UniValue(UniversalType.Float, oldy + (float)xy.Y); s.UpdateNeeded = true; @@ -339,6 +332,95 @@ namespace CodeImp.DoomBuilder.BuilderModes vs.Floor.SelectNeighbours(select, withSameTexture, withSameHeight); } } + + //mxd + public void AlignTexture(bool alignx, bool aligny) { + if(!General.Map.UDMF) return; + + float slopeAngle = level.plane.Normal.GetAngleZ() - Angle2D.PIHALF; + + if(slopeAngle == 0) return; //it's a horizontal plane + + //find slope source linedef + Linedef slopeSource = null; + bool isFront = false; + + foreach(Sidedef side in Sector.Sector.Sidedefs) { + if(side.Line.Action == 181) { + if(side.Line.Args[0] == 1 && side.Line.Front != null && side.Line.Front == side) { + slopeSource = side.Line; + isFront = true; + break; + } else if(side.Line.Args[0] == 2 && side.Line.Back != null && side.Line.Back == side) { + slopeSource = side.Line; + break; + } + } + } + + if(slopeSource == null) return; + + Sector.Sector.Fields.BeforeFieldsChange(); + + float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(slopeSource.Angle) + 90 : -Angle2D.RadToDeg(slopeSource.Angle) - 90), 1); + + if((isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight) || + (!isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight)) { + sourceAngle = General.ClampAngle(sourceAngle + 180); + } + + if(sourceAngle != 0) { + if(!Sector.Sector.Fields.ContainsKey("rotationfloor")) + Sector.Sector.Fields.Add("rotationfloor", new UniValue(UniversalType.Float, sourceAngle)); + else + Sector.Sector.Fields["rotationfloor"].Value = sourceAngle; + } else if(Sector.Sector.Fields.ContainsKey("rotationfloor")) { + Sector.Sector.Fields.Remove("rotationfloor"); + } + + //update scaleY + float scaleX = Sector.Sector.Fields.GetValue("xscalefloor", 1.0f); + float scaleY = (float)Math.Round(scaleX * (1 / (float)Math.Cos(slopeAngle)), 2); + + if(aligny) { + if(Sector.Sector.Fields.ContainsKey("yscalefloor")) + Sector.Sector.Fields["yscalefloor"].Value = scaleY; + else + Sector.Sector.Fields.Add("yscalefloor", new UniValue(UniversalType.Float, scaleY)); + } + + //update texture offsets + Vector2D offset; + if((isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight) || + (!isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight)) { + offset = slopeSource.End.Position; + } else { + offset = slopeSource.Start.Position; + } + + offset = offset.GetRotated(Angle2D.DegToRad(sourceAngle)); + + if(alignx) { + if(Texture != null) offset.x %= Texture.Width / scaleX; + + if(Sector.Sector.Fields.ContainsKey("xpanningfloor")) + Sector.Sector.Fields["xpanningfloor"].Value = (float)Math.Round(-offset.x); + else + Sector.Sector.Fields.Add("xpanningfloor", new UniValue(UniversalType.Float, (float)Math.Round(-offset.x))); + } + + if(aligny) { + if(Texture != null) offset.y %= Texture.Height / scaleY; + + if(Sector.Sector.Fields.ContainsKey("ypanningfloor")) + Sector.Sector.Fields["ypanningfloor"].Value = (float)Math.Round(offset.y); + else + Sector.Sector.Fields.Add("ypanningfloor", new UniValue(UniversalType.Float, (float)Math.Round(offset.y))); + } + + //update geometry + Sector.UpdateSectorGeometry(false); + } #endregion } diff --git a/Source/Plugins/ColorPicker/Windows/LightColorPicker.cs b/Source/Plugins/ColorPicker/Windows/LightColorPicker.cs index 6f25b28177a508f486ae2c155ea1a360240a506c..9b373aa98140093a85d16b7e3974b639f94d8631 100644 --- a/Source/Plugins/ColorPicker/Windows/LightColorPicker.cs +++ b/Source/Plugins/ColorPicker/Windows/LightColorPicker.cs @@ -339,6 +339,7 @@ namespace CodeImp.DoomBuilder.ColorPicker.Windows { private void colorPickerControl1_OnOkPressed(object sender, EventArgs e) { this.DialogResult = DialogResult.OK; + General.Interface.RefreshInfo(); Close(); } diff --git a/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs b/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs index 4ac34f61fd743551c692b60ab30098b355776c07..958583c445eb5c5feb21f987a54cca8fd625f945 100644 --- a/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs +++ b/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs @@ -514,6 +514,7 @@ namespace CodeImp.DoomBuilder.UDMFControls } removeDefaultValues(); + General.Interface.RefreshInfo(); this.DialogResult = DialogResult.OK; Close(); }