//mxd. This changes slope angle. Amount is in radians! protected override void ChangeAngle(float amount) { mode.CreateUndo("Change ceiling slope angle", UndoGroup.AngleChange, Sector.Sector.Index); Sector.Sector.SetFlag(General.Map.FormatInterface.SectorFlags.Sloped, true, false); Sector.Sector.CeilingSlope = General.Clamp(Sector.Sector.CeilingSlope - amount, General.Map.FormatInterface.MinSlope, General.Map.FormatInterface.MaxSlope); mode.SetActionResult("Changed ceiling slope angle to " + Math.Round(Angle2D.RadToDeg(Sector.Sector.CeilingSlope) - 90, 1) + "."); }
//mxd. This calculates wall brightness level with doom-style shading public int CalculateBrightness(int level, Sidedef sd) { if (level < 253 && sd != null) { bool evenlighting = General.Map.Data.MapInfo.EvenLighting; bool smoothlighting = General.Map.Data.MapInfo.SmoothLighting; //check for possiburu UDMF overrides if (General.Map.UDMF) { if (sd.IsFlagSet("lightabsolute") && sd.Fields.ContainsKey("light")) { evenlighting = true; } else { if (sd.IsFlagSet("nofakecontrast")) { evenlighting = true; } if (sd.IsFlagSet("smoothlighting")) { smoothlighting = true; } } } if (!evenlighting) { //all walls are shaded by their angle if (smoothlighting) { float ammount = Math.Abs((float)Math.Sin(sd.Angle)); int hAmmount = (int)((1.0f - ammount) * General.Map.Data.MapInfo.HorizWallShade); int vAmmount = (int)(ammount * General.Map.Data.MapInfo.VertWallShade); level = General.Clamp(level - hAmmount - vAmmount, 0, 255); } else //only horizontal/verticel walls are shaded { switch ((int)Angle2D.RadToDeg(sd.Angle)) { // Horizontal wall case 90: case 270: level = General.Clamp(level + General.Map.Data.MapInfo.HorizWallShade, 0, 255); break; // Vertical wall case 180: case 0: level = General.Clamp(level + General.Map.Data.MapInfo.VertWallShade, 0, 255); break; } } } } return(CalculateBrightness(level)); }
//mxd. This updates the sprite frame to be rendered internal void UpdateSpriteFrame() { if (textures.Length != 8) { spriteframe = 0; } else { spriteframe = (General.ClampAngle((int)Angle2D.RadToDeg((General.Map.VisualCamera.Position - thing.Position).GetAngleXY()) - thing.AngleDoom + 292)) / 45; // Convert to [0..7] range; 292 == 270 + 45/2 } }
internal SlopeArchForm(SlopeArcher slopearcher) { InitializeComponent(); this.slopearcher = slopearcher; oldtheta = originaltheta = Math.Round(Angle2D.RadToDeg(this.slopearcher.Theta), 2); oldoffset = originaloffset = Math.Round(Angle2D.RadToDeg(this.slopearcher.OffsetAngle), 2); oldscale = originalscale = this.slopearcher.Scale; originalheightoffset = this.slopearcher.HeightOffset; theta.Text = originaltheta.ToString(); offset.Text = originaloffset.ToString(); scale.Text = (originalscale * 100.0).ToString(); heightoffset.Text = originalheightoffset.ToString(); }
// This updates the text protected virtual void UpdateText() { Vector2D delta = end - start; // Update label text float length = delta.GetLength(); if (showangle) { 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); } }
// This sets the dynamic values public void ShowCurrentValues(Vector2D pos, Vector2D relpos, Vector2D size, Vector2D relsize, float rotation) { // Set values this.abspos = pos; this.relpos = relpos; this.abssize = size; this.relsize = relsize; this.absrotate = Angle2D.RadToDeg(rotation); // Set controls absposx.Text = pos.x.ToString("0.#"); absposy.Text = pos.y.ToString("0.#"); relposx.Text = relpos.x.ToString("0.#"); relposy.Text = relpos.y.ToString("0.#"); abssizex.Text = size.x.ToString("0.#"); abssizey.Text = size.y.ToString("0.#"); relsizex.Text = relsize.x.ToString("0.#"); relsizey.Text = relsize.y.ToString("0.#"); absrot.Text = this.absrotate.ToString("0.#"); userinput = false; }
// Texture offset change public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { if (horizontal == 0 && vertical == 0) { return; //mxd } //mxd if (!General.Map.UDMF) { General.Interface.DisplayStatus(StatusType.Warning, "Floor/ceiling texture offsets cannot be changed in this map format!"); return; } if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) { undoticket = mode.CreateUndo("Change texture offsets"); } //mxd changed = true; //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) { //already correct } 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; } } // Apply offsets MoveTextureOffset(-horizontal, -vertical); // Rebuild sector BaseVisualSector vs; if (mode.VisualSectorExists(level.sector)) { vs = (BaseVisualSector)mode.GetVisualSector(level.sector); } else { //mxd. Need this to apply changes to 3d-floor even if control sector doesn't exist as BaseVisualSector vs = mode.CreateBaseVisualSector(level.sector); } if (vs != null) { vs.UpdateSectorGeometry(false); } }
// Apply clicked private void apply_Click(object sender, EventArgs e) { List <string> defaultflags = new List <string>(); string undodesc = "thing"; // Verify the tag if (General.Map.FormatInterface.HasThingTag && ((tag.GetResult(0) < General.Map.FormatInterface.MinTag) || (tag.GetResult(0) > General.Map.FormatInterface.MaxTag))) { General.ShowWarningMessage("Thing tag must be between " + General.Map.FormatInterface.MinTag + " and " + General.Map.FormatInterface.MaxTag + ".", MessageBoxButtons.OK); return; } // Verify the type if (((thingtype.GetResult(0) < General.Map.FormatInterface.MinThingType) || (thingtype.GetResult(0) > General.Map.FormatInterface.MaxThingType))) { General.ShowWarningMessage("Thing type must be between " + General.Map.FormatInterface.MinThingType + " and " + General.Map.FormatInterface.MaxThingType + ".", MessageBoxButtons.OK); return; } // Verify the action if (General.Map.FormatInterface.HasThingAction && ((action.Value < General.Map.FormatInterface.MinAction) || (action.Value > General.Map.FormatInterface.MaxAction))) { General.ShowWarningMessage("Thing action must be between " + General.Map.FormatInterface.MinAction + " and " + General.Map.FormatInterface.MaxAction + ".", MessageBoxButtons.OK); return; } // Make undo if (things.Count > 1) { undodesc = things.Count + " things"; } General.Map.UndoRedo.CreateUndo("Edit " + undodesc); // Go for all the things foreach (Thing t in things) { // Thing type index t.Type = General.Clamp(thingtype.GetResult(t.Type), General.Map.FormatInterface.MinThingType, General.Map.FormatInterface.MaxThingType); // Coordination t.Rotate(angle.GetResult(t.AngleDoom)); t.Move(t.Position.x, t.Position.y, (float)height.GetResult((int)t.Position.z)); // Apply all flags foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { t.SetFlag(c.Tag.ToString(), true); } else if (c.CheckState == CheckState.Unchecked) { t.SetFlag(c.Tag.ToString(), false); } } // Action/tags t.Tag = tag.GetResult(t.Tag); if (!action.Empty) { t.Action = action.Value; } t.Args[0] = arg0.GetResult(t.Args[0]); t.Args[1] = arg1.GetResult(t.Args[1]); t.Args[2] = arg2.GetResult(t.Args[2]); t.Args[3] = arg3.GetResult(t.Args[3]); t.Args[4] = arg4.GetResult(t.Args[4]); // Custom fields fieldslist.Apply(t.Fields); // Update settings t.UpdateConfiguration(); } // Set as defaults foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { defaultflags.Add(c.Tag.ToString()); } } General.Settings.DefaultThingType = thingtype.GetResult(General.Settings.DefaultThingType); General.Settings.DefaultThingAngle = Angle2D.DegToRad((float)angle.GetResult((int)Angle2D.RadToDeg(General.Settings.DefaultThingAngle) - 90) + 90); General.Settings.SetDefaultThingFlags(defaultflags); // Done General.Map.IsChanged = true; Cleanup(); this.DialogResult = DialogResult.OK; this.Close(); }
// This makes sure we are updated with the source linedef information public override void Update() { ThingData td = data.Mode.GetThingData(thing); Thing t = thing; // Floor slope thing if (t.Type == 9502) { t.DetermineSector(data.Mode.BlockMap); if (t.Sector != null) { //mxd. Vertex zheight overrides this effect if (General.Map.UDMF && t.Sector.Sidedefs.Count == 3) { foreach (Sidedef side in t.Sector.Sidedefs) { if (!double.IsNaN(side.Line.Start.ZFloor) || !double.IsNaN(side.Line.End.ZFloor)) { return; } } } double angle = Angle2D.DoomToReal((int)Angle2D.RadToDeg(t.Angle)); double vangle = Angle2D.DegToRad(General.Clamp(t.Args[0], 0, 180)); //mxd. Don't underestimate user stupidity (or curiosity)! Vector2D point = new Vector2D(t.Position.x + Math.Cos(angle) * Math.Sin(vangle), t.Position.y + Math.Sin(angle) * Math.Sin(vangle)); Vector2D perpendicular = new Line2D(t.Position, point).GetPerpendicular(); Vector3D v1 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.FloorHeight); Vector3D v2 = new Vector3D( point.x + perpendicular.x, point.y + perpendicular.y, t.Position.z + t.Sector.FloorHeight + Math.Cos(vangle) ); Vector3D v3 = new Vector3D( point.x - perpendicular.x, point.y - perpendicular.y, t.Position.z + t.Sector.FloorHeight + Math.Cos(vangle) ); SectorData sd = data.Mode.GetSectorData(t.Sector); sd.AddUpdateSector(data.Sector, true); if (!sd.Updated) { sd.Update(); } td.AddUpdateSector(t.Sector, true); sd.Floor.plane = new Plane(v1, v2, v3, true); } } // Ceiling slope thing else if (t.Type == 9503) { t.DetermineSector(data.Mode.BlockMap); if (t.Sector != null) { //mxd. Vertex zheight overrides this effect if (General.Map.UDMF && t.Sector.Sidedefs.Count == 3) { foreach (Sidedef side in t.Sector.Sidedefs) { if (!double.IsNaN(side.Line.Start.ZCeiling) || !double.IsNaN(side.Line.End.ZCeiling)) { return; } } } double angle = Angle2D.DoomToReal((int)Angle2D.RadToDeg(t.Angle)); double vangle = Angle2D.DegToRad(General.Clamp(t.Args[0], 0, 180)); //mxd. Don't underestimate user stupidity (or curiosity)! Vector2D point = new Vector2D(t.Position.x + Math.Cos(angle) * Math.Sin(vangle), t.Position.y + Math.Sin(angle) * Math.Sin(vangle)); Vector2D perpendicular = new Line2D(t.Position, point).GetPerpendicular(); Vector3D v1 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.CeilHeight); Vector3D v2 = new Vector3D( point.x + perpendicular.x, point.y + perpendicular.y, t.Position.z + t.Sector.CeilHeight + Math.Cos(vangle) ); Vector3D v3 = new Vector3D( point.x - perpendicular.x, point.y - perpendicular.y, t.Position.z + t.Sector.CeilHeight + Math.Cos(vangle) ); SectorData sd = data.Mode.GetSectorData(t.Sector); sd.AddUpdateSector(data.Sector, true); if (!sd.Updated) { sd.Update(); } td.AddUpdateSector(t.Sector, true); sd.Ceiling.plane = new Plane(v1, v2, v3, false); } } }
// Apply clicked private void apply_Click(object sender, EventArgs e) { MakeUndo(); List <string> defaultflags = new List <string>(); // Verify the tag if (General.Map.FormatInterface.HasThingTag) //mxd { tagSelector.ValidateTag(); //mxd if (((tagSelector.GetTag(0) < General.Map.FormatInterface.MinTag) || (tagSelector.GetTag(0) > General.Map.FormatInterface.MaxTag))) { General.ShowWarningMessage("Thing tag must be between " + General.Map.FormatInterface.MinTag + " and " + General.Map.FormatInterface.MaxTag + ".", MessageBoxButtons.OK); return; } } // Verify the type if (!string.IsNullOrEmpty(thingtype.TypeStringValue) && ((thingtype.GetResult(0) < General.Map.FormatInterface.MinThingType) || (thingtype.GetResult(0) > General.Map.FormatInterface.MaxThingType))) { General.ShowWarningMessage("Thing type must be between " + General.Map.FormatInterface.MinThingType + " and " + General.Map.FormatInterface.MaxThingType + ".", MessageBoxButtons.OK); return; } // Verify the action if (General.Map.FormatInterface.HasThingAction && ((action.Value < General.Map.FormatInterface.MinAction) || (action.Value > General.Map.FormatInterface.MaxAction))) { General.ShowWarningMessage("Thing action must be between " + General.Map.FormatInterface.MinAction + " and " + General.Map.FormatInterface.MaxAction + ".", MessageBoxButtons.OK); return; } // Go for all the things int offset = 0; //mxd foreach (Thing t in things) { // Coordination if (cbRandomAngle.Checked) //mxd { int newangle = General.Random(0, 359); if (General.Map.Config.DoomThingRotationAngles) { newangle = newangle / 45 * 45; } t.Rotate(newangle); } //mxd. Check position float px = General.Clamp(t.Position.x, General.Map.Config.LeftBoundary, General.Map.Config.RightBoundary); float py = General.Clamp(t.Position.y, General.Map.Config.BottomBoundary, General.Map.Config.TopBoundary); if (t.Position.x != px || t.Position.y != py) { t.Move(new Vector2D(px, py)); } // Apply all flags foreach (CheckBox c in flags.Checkboxes) { switch (c.CheckState) { case CheckState.Checked: t.SetFlag(c.Tag.ToString(), true); break; case CheckState.Unchecked: t.SetFlag(c.Tag.ToString(), false); break; } } // Action/tags t.Tag = General.Clamp(tagSelector.GetSmartTag(t.Tag, offset), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag); //mxd if (!action.Empty) { t.Action = action.Value; } //mxd. Apply args argscontrol.Apply(t, offset); // Update settings t.UpdateConfiguration(); //mxd. Increase offset... offset++; } // Set as defaults foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { defaultflags.Add(c.Tag.ToString()); } } General.Settings.DefaultThingType = thingtype.GetResult(General.Settings.DefaultThingType); General.Settings.DefaultThingAngle = Angle2D.DegToRad((float)angle.GetResult((int)Angle2D.RadToDeg(General.Settings.DefaultThingAngle) - 90) + 90); General.Settings.SetDefaultThingFlags(defaultflags); // Done General.Map.IsChanged = true; if (OnValuesChanged != null) { OnValuesChanged(this, EventArgs.Empty); //mxd } this.DialogResult = DialogResult.OK; this.Close(); }
// Apply clicked private void apply_Click(object sender, EventArgs e) { //mxd. Make Undo MakeUndo(); List <string> defaultflags = new List <string>(); // Verify the tag if (General.Map.FormatInterface.HasThingTag) //mxd { tagSelector.ValidateTag(); //mxd if (((tagSelector.GetTag(0) < General.Map.FormatInterface.MinTag) || (tagSelector.GetTag(0) > General.Map.FormatInterface.MaxTag))) { General.ShowWarningMessage("Thing tag must be between " + General.Map.FormatInterface.MinTag + " and " + General.Map.FormatInterface.MaxTag + ".", MessageBoxButtons.OK); return; } } // Verify the type if (!string.IsNullOrEmpty(thingtype.TypeStringValue) && ((thingtype.GetResult(0) < General.Map.FormatInterface.MinThingType) || (thingtype.GetResult(0) > General.Map.FormatInterface.MaxThingType))) { General.ShowWarningMessage("Thing type must be between " + General.Map.FormatInterface.MinThingType + " and " + General.Map.FormatInterface.MaxThingType + ".", MessageBoxButtons.OK); return; } // Verify the action if (General.Map.FormatInterface.HasThingAction && ((action.Value < General.Map.FormatInterface.MinAction) || (action.Value > General.Map.FormatInterface.MaxAction))) { General.ShowWarningMessage("Thing action must be between " + General.Map.FormatInterface.MinAction + " and " + General.Map.FormatInterface.MaxAction + ".", MessageBoxButtons.OK); return; } // Go for all the things int offset = 0; //mxd foreach (Thing t in things) { // Coordination //mxd. Randomize rotations? if (cbrandomangle.Checked) { int newangle = General.Random(0, 359); if (General.Map.Config.DoomThingRotationAngles) { newangle = newangle / 45 * 45; } t.Rotate(newangle); } if (cbrandompitch.Checked) { t.SetPitch(General.Random(0, 359)); } if (cbrandomroll.Checked) { t.SetRoll(General.Random(0, 359)); } //mxd. Check position double px = General.Clamp(t.Position.x, General.Map.Config.LeftBoundary, General.Map.Config.RightBoundary); double py = General.Clamp(t.Position.y, General.Map.Config.BottomBoundary, General.Map.Config.TopBoundary); if (t.Position.x != px || t.Position.y != py) { t.Move(new Vector2D(px, py)); } // Action/tags t.Tag = General.Clamp(tagSelector.GetSmartTag(t.Tag, offset), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag); //mxd if (!action.Empty) { t.Action = action.Value; } //mxd. Apply args argscontrol.Apply(t, offset); //mxd. Custom fields fieldslist.Apply(t.Fields); if (!string.IsNullOrEmpty(conversationID.Text)) { UniFields.SetInteger(t.Fields, "conversation", conversationID.GetResult(t.Fields.GetValue("conversation", 0)), 0); } if (!string.IsNullOrEmpty(floatbobphase.Text)) { UniFields.SetInteger(t.Fields, "floatbobphase", General.Clamp(floatbobphase.GetResult(t.Fields.GetValue("floatbobphase", -1)), -1, 63), -1); } if (!string.IsNullOrEmpty(gravity.Text)) { UniFields.SetFloat(t.Fields, "gravity", gravity.GetResultFloat(t.Fields.GetValue("gravity", 1.0)), 1.0); } if (!string.IsNullOrEmpty(health.Text)) { UniFields.SetInteger(t.Fields, "health", health.GetResult(t.Fields.GetValue("health", 1)), 1); } if (!string.IsNullOrEmpty(score.Text)) { UniFields.SetInteger(t.Fields, "score", score.GetResult(t.Fields.GetValue("score", 0)), 0); } //mxd. User vars. Should be called after fieldslist.Apply() ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type); if (ti != null && ti.Actor != null && ti.Actor.UserVars.Count > 0) { fieldslist.ApplyUserVars(ti.Actor.UserVars, t.Fields); } color.ApplyTo(t.Fields, t.Fields.GetValue("fillcolor", 0)); //mxd. Comments commenteditor.Apply(t.Fields); // Update settings t.UpdateConfiguration(); //mxd. Increase offset... offset++; } // Set as defaults foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { defaultflags.Add(c.Tag.ToString()); } } General.Settings.DefaultThingType = thingtype.GetResult(General.Settings.DefaultThingType); General.Settings.DefaultThingAngle = Angle2D.DegToRad((float)angle.GetResult((int)Angle2D.RadToDeg(General.Settings.DefaultThingAngle) - 90) + 90); General.Settings.SetDefaultThingFlags(defaultflags); // Done General.Map.IsChanged = true; if (OnValuesChanged != null) { OnValuesChanged(this, EventArgs.Empty); //mxd } this.DialogResult = DialogResult.OK; this.Close(); }
// OK clicked private void apply_Click(object sender, EventArgs e) { // Verify properties if (!VerifyValue(hitag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sector hitag")) { return; } if (!VerifyValue(lotag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sector lotag")) { return; } if (!VerifyValue(extra.GetResult(0), General.Map.FormatInterface.MinExtra, General.Map.FormatInterface.MaxExtra, "Sector extra")) { return; } if (!VerifyValue(ceilpalette.GetResult(0), 0, 255, "Ceiling palette")) { return; } if (!VerifyValue(floorpalette.GetResult(0), 0, 255, "Floor palette")) { return; } // Make undo General.Map.UndoRedo.CreateUndo("Edit " + (sectors.Count > 1 ? sectors.Count + " sectors" : "sector")); // Collect flags... Dictionary <string, CheckState> floorflagsstate = new Dictionary <string, CheckState>(); foreach (CheckBox c in floorflags.Checkboxes) { floorflagsstate[c.Tag.ToString()] = c.CheckState; } Dictionary <string, CheckState> ceilflagsstate = new Dictionary <string, CheckState>(); foreach (CheckBox c in ceilflags.Checkboxes) { ceilflagsstate[c.Tag.ToString()] = c.CheckState; } // Update slope flags? float ceilslopedeg = ceilslope.GetResultFloat(VALUE_MISMATCH); if (ceilslopedeg != VALUE_MISMATCH) { ceilflagsstate[General.Map.FormatInterface.SectorFlags.Sloped] = (ceilslopedeg != 0 ? CheckState.Checked : CheckState.Unchecked); } float floorslopedeg = floorslope.GetResultFloat(VALUE_MISMATCH); if (floorslopedeg != VALUE_MISMATCH) { floorflagsstate[General.Map.FormatInterface.SectorFlags.Sloped] = (floorslopedeg != 0 ? CheckState.Checked : CheckState.Unchecked); } // Go for all sectors foreach (Sector s in sectors) { // Floor/ceiling s.FloorHeight = floorheight.GetResult(s.FloorHeight); s.CeilingHeight = ceilheight.GetResult(s.CeilingHeight); s.Visibility = visibility.GetResult(s.Visibility); // Ceiling foreach (KeyValuePair <string, CheckState> group in ceilflagsstate) { switch (group.Value) { case CheckState.Checked: s.SetFlag(group.Key, true, false); break; case CheckState.Unchecked: s.SetFlag(group.Key, false, false); break; } } s.CeilingTileIndex = General.Clamp(ceiltex.GetResult(s.CeilingTileIndex), General.Map.FormatInterface.MinTileIndex, General.Map.FormatInterface.MaxTileIndex); s.CeilingOffsetX = General.Wrap(ceiloffsetx.GetResult(s.CeilingOffsetX), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset); s.CeilingOffsetY = General.Wrap(ceiloffsety.GetResult(s.CeilingOffsetY), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset); s.CeilingShade = General.Clamp(ceilshade.GetResult(s.CeilingShade), General.Map.FormatInterface.MinShade, General.Map.FormatInterface.MaxShade); s.CeilingPaletteIndex = ceilpalette.GetResult(s.CeilingPaletteIndex); s.CeilingSlope = General.Clamp(Angle2D.DegToRad(ceilslope.GetResultFloat(Angle2D.RadToDeg(s.CeilingSlope) - 90) + 90), General.Map.FormatInterface.MinSlope, General.Map.FormatInterface.MaxSlope); // Floor foreach (KeyValuePair <string, CheckState> group in floorflagsstate) { switch (group.Value) { case CheckState.Checked: s.SetFlag(group.Key, true, true); break; case CheckState.Unchecked: s.SetFlag(group.Key, false, true); break; } } s.FloorTileIndex = General.Clamp(floortex.GetResult(s.FloorTileIndex), General.Map.FormatInterface.MinTileIndex, General.Map.FormatInterface.MaxTileIndex); s.FloorOffsetX = General.Wrap(flooroffsetx.GetResult(s.FloorOffsetX), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset); s.FloorOffsetY = General.Wrap(flooroffsety.GetResult(s.FloorOffsetY), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset); s.FloorShade = General.Clamp(floorshade.GetResult(s.FloorShade), General.Map.FormatInterface.MinShade, General.Map.FormatInterface.MaxShade); s.FloorPaletteIndex = floorpalette.GetResult(s.FloorPaletteIndex); s.FloorSlope = General.Clamp(Angle2D.DegToRad(floorslope.GetResultFloat(Angle2D.RadToDeg(s.FloorSlope) - 90) + 90), General.Map.FormatInterface.MinSlope, General.Map.FormatInterface.MaxSlope); // Identification s.HiTag = hitag.GetResult(s.HiTag); s.LoTag = lotag.GetResult(s.LoTag); s.Extra = extra.GetResult(s.Extra); } // Update the used textures General.Map.Data.UpdateUsedImages(); // Done General.Map.IsChanged = true; this.DialogResult = DialogResult.OK; this.Close(); }
//mxd protected void AlignTextureToClosestLine(bool alignx, bool aligny) { if (!(mode.HighlightedObject is BaseVisualSector)) { return; } // Do we need to align this? (and also grab texture scale while we are at it) float scaleX, scaleY; bool isFloor = (geometrytype == VisualGeometryType.FLOOR); if (mode.HighlightedTarget is VisualFloor) { VisualFloor target = (VisualFloor)mode.HighlightedTarget; // Check texture if (target.Sector.Sector.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture)) { return; } scaleX = target.Sector.Sector.Fields.GetValue("xscalefloor", 1.0f); scaleY = target.Sector.Sector.Fields.GetValue("yscalefloor", 1.0f); } else { VisualCeiling target = (VisualCeiling)mode.HighlightedTarget; // Check texture if (target.Sector.Sector.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture)) { return; } scaleX = target.Sector.Sector.Fields.GetValue("xscaleceiling", 1.0f); scaleY = target.Sector.Sector.Fields.GetValue("yscaleceiling", 1.0f); } //find a linedef to align to Vector2D hitpos = mode.GetHitPosition(); if (!hitpos.IsFinite()) { return; } //align to line of highlighted sector, which is closest to hitpos Sector highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector; List <Linedef> lines = new List <Linedef>(); foreach (Sidedef side in highlightedSector.Sidedefs) { lines.Add(side.Line); } Linedef targetLine = MapSet.NearestLinedef(lines, hitpos); if (targetLine == null) { return; } bool isFront = targetLine.SideOfLine(hitpos) > 0; Sector.Sector.Fields.BeforeFieldsChange(); //find an angle to rotate texture float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1); if (!isFront) { sourceAngle = General.ClampAngle(sourceAngle + 180); } //update angle UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f); //set scale UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f); //update offset float distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position); float distToEnd = Vector2D.Distance(hitpos, targetLine.End.Position); Vector2D offset = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle)); if (alignx) { if (Texture != null && Texture.IsImageLoaded) { offset.x %= Texture.Width / scaleX; } UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f); } if (aligny) { if (Texture != null && Texture.IsImageLoaded) { offset.y %= Texture.Height / scaleY; } UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f); } //update geometry Sector.UpdateSectorGeometry(false); }
// Texture offset change public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { if (horizontal == 0 && vertical == 0) { return; //mxd } //mxd if (!General.Map.UDMF) { General.Interface.DisplayStatus(StatusType.Warning, "Floor/ceiling texture offsets cannot be changed in this map format!"); return; } if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) { undoticket = mode.CreateUndo("Change texture offsets"); } //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) { //already correct } 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; } } // Apply offsets MoveTextureOffset(new Point(-horizontal, -vertical)); // Update sector geometry Sector s = GetControlSector(); if (s.Index != Sector.Sector.Index) { s.UpdateNeeded = true; s.UpdateCache(); mode.GetSectorData(s).Update(); BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(s); vs.UpdateSectorGeometry(false); vs.Rebuild(); } Sector.Sector.UpdateNeeded = true; Sector.Sector.UpdateCache(); Sector.UpdateSectorGeometry(false); Sector.Rebuild(); }
// This moves the selected things relatively // Returns true when things has actually moved private bool MoveThingsRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal) { //mxd. If snap to cardinal directions is enabled, modify the offset if (snapcardinal) { 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; Vector2D tl, br; // don't move if the offset contains invalid data if (!offset.IsFinite()) { return(false); } // Find the outmost things tl = br = oldpositions[0]; for (int i = 0; i < oldpositions.Count; i++) { if (oldpositions[i].x < tl.x) { tl.x = (int)oldpositions[i].x; } if (oldpositions[i].x > br.x) { br.x = (int)oldpositions[i].x; } if (oldpositions[i].y > tl.y) { tl.y = (int)oldpositions[i].y; } if (oldpositions[i].y < br.y) { br.y = (int)oldpositions[i].y; } } // Snap to nearest? if (snapnearest) { // Find nearest unselected item within selection range Thing nearest = MapSet.NearestThingSquareRange(unselectedthings, mousemappos, BuilderPlug.Me.StitchRange / renderer.Scale); if (nearest != null) { // Move the dragged item dragitem.Move((Vector2D)nearest.Position); // Adjust the offset offset = (Vector2D)nearest.Position - dragitemposition; // Do not snap to grid! snapgrid = false; snapgridincrement = false; //mxd } } // Snap to grid? if (snapgrid || snapgridincrement) { // Move the dragged item dragitem.Move(dragitemposition + offset); // Snap item to grid increment (mxd) if (snapgridincrement) { dragitem.Move(General.Map.Grid.SnappedToGrid(dragitemposition + offset) - dragstartoffset); } else // Or to the grid itself { dragitem.SnapToGrid(); } // Adjust the offset offset += (Vector2D)dragitem.Position - (dragitemposition + offset); } // Make sure the offset is inside the map boundaries if (offset.x + tl.x < General.Map.Config.LeftBoundary) { offset.x = General.Map.Config.LeftBoundary - tl.x; } if (offset.x + br.x > General.Map.Config.RightBoundary) { offset.x = General.Map.Config.RightBoundary - br.x; } if (offset.y + tl.y > General.Map.Config.TopBoundary) { offset.y = General.Map.Config.TopBoundary - tl.y; } if (offset.y + br.y < General.Map.Config.BottomBoundary) { offset.y = General.Map.Config.BottomBoundary - br.y; } // Drag item moved? if ((!snapgrid && !snapgridincrement) || ((Vector2D)dragitem.Position != oldpos)) { int i = 0; // Move selected geometry foreach (Thing t in selectedthings) { // Move vertex from old position relative to the // mouse position change since drag start t.Move(oldpositions[i] + offset); // Next i++; } // Moved return(true); } else { // No changes return(false); } }
//mxd protected void AlignTextureToClosestLine(bool alignx, bool aligny) { if (!(mode.HighlightedObject is BaseVisualSector)) { return; } // Do we need to align this? (and also grab texture scale while we are at it) float scaleX, scaleY; bool isFloor = (geometrytype == VisualGeometryType.FLOOR); if (mode.HighlightedTarget is VisualFloor) { Sector target; VisualFloor vf = (VisualFloor)mode.HighlightedTarget; // Use the control sector if the floor belongs to a 3D floor if (vf.ExtraFloor == null) { target = vf.Sector.Sector; } else { target = vf.GetControlSector(); } // Check texture if (target.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture)) { return; } scaleX = target.Fields.GetValue("xscalefloor", 1.0f); scaleY = target.Fields.GetValue("yscalefloor", 1.0f); } else { Sector target; VisualCeiling vc = (VisualCeiling)mode.HighlightedTarget; // Use the control sector if the ceiling belongs to a 3D floor if (vc.ExtraFloor == null) { target = vc.Sector.Sector; } else { target = vc.GetControlSector(); } // Check texture if (target.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture)) { return; } scaleX = target.Fields.GetValue("xscaleceiling", 1.0f); scaleY = target.Fields.GetValue("yscaleceiling", 1.0f); } //find a linedef to align to Vector2D hitpos = mode.GetHitPosition(); if (!hitpos.IsFinite()) { return; } //align to line of highlighted sector, which is closest to hitpos Sector highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector; List <Linedef> lines = new List <Linedef>(); foreach (Sidedef side in highlightedSector.Sidedefs) { lines.Add(side.Line); } Linedef targetLine = MapSet.NearestLinedef(lines, hitpos); if (targetLine == null) { return; } bool isFront = targetLine.SideOfLine(hitpos) > 0; Sector.Sector.Fields.BeforeFieldsChange(); //find an angle to rotate texture float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1); if (!isFront) { sourceAngle = General.ClampAngle(sourceAngle + 180); } //update angle UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f); // Scale texture if it's a slope and the appropriate option is set if (level.plane.Normal.z != 1.0f && BuilderPlug.Me.ScaleTexturesOnSlopes != 2) { Vector2D basescale = new Vector2D(1.0f, 1.0f); // User wants to use the current scale as a base? if (BuilderPlug.Me.ScaleTexturesOnSlopes == 1) { basescale.x = scaleX; basescale.y = scaleY; } // Create a unit vector of the direction of the target line in 3D space Vector3D targetlinevector = new Line3D(new Vector3D(targetLine.Start.Position, level.plane.GetZ(targetLine.Start.Position)), new Vector3D(targetLine.End.Position, level.plane.GetZ(targetLine.End.Position))).GetDelta().GetNormal(); // Get a perpendicular vector of the target line in 3D space. This is used to get the slope angle relative to the target line Vector3D targetlineperpendicular = Vector3D.CrossProduct(targetlinevector, level.plane.Normal); if (alignx) { scaleX = Math.Abs(basescale.x * (1.0f / (float)Math.Cos(targetlinevector.GetAngleZ()))); } if (aligny) { scaleY = Math.Abs(basescale.y * (1.0f / (float)Math.Cos(targetlineperpendicular.GetAngleZ()))); } } //set scale UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f); //update offset float distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position); float distToEnd = Vector2D.Distance(hitpos, targetLine.End.Position); Vector2D offset = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle)); if (alignx) { if (Texture != null && Texture.IsImageLoaded) { offset.x %= Texture.Width / scaleX; } UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f); } if (aligny) { if (Texture != null && Texture.IsImageLoaded) { offset.y %= Texture.Height / scaleY; } UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f); } //update geometry Sector.UpdateSectorGeometry(false); }
// This moves the selected geometry relatively // Returns true when geometry has actually moved private bool MoveGeometryRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal) { //mxd. If snap to cardinal directions is enabled, modify the offset if (snapcardinal) { double 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; Vector2D anchorpos = dragitemposition + offset; Vector2D tl, br; // don't move if the offset contains invalid data if (!offset.IsFinite()) { return(false); } // Find the outmost vertices tl = br = oldpositions[0]; for (int i = 0; i < oldpositions.Count; i++) { if (oldpositions[i].x < tl.x) { tl.x = (int)oldpositions[i].x; } if (oldpositions[i].x > br.x) { br.x = (int)oldpositions[i].x; } if (oldpositions[i].y > tl.y) { tl.y = (int)oldpositions[i].y; } if (oldpositions[i].y < br.y) { br.y = (int)oldpositions[i].y; } } // Snap to nearest? if (snapnearest) { // Find nearest unselected vertex within range Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale); if (nv != null) { // Move the dragged item dragitem.Move(nv.Position); // Adjust the offset offset = nv.Position - dragitemposition; // Do not snap to grid! snapgrid = false; snaptogridincrement = false; //mxd } else { // Find the nearest unselected line within range Linedef nl = MapSet.NearestLinedefRange(snaptolines, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale); if (nl != null) { // Snap to grid? if (snapgrid || snapgridincrement) { // Get grid intersection coordinates List <Vector2D> coords = nl.GetGridIntersections(snapgridincrement ? dragstartoffset : new Vector2D(), General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY); // mxd. Do the rest only if we actually have some coordinates if (coords.Count > 0) { // Find nearest grid intersection double found_distance = double.MaxValue; Vector2D found_coord = new Vector2D(); foreach (Vector2D v in coords) { Vector2D delta = anchorpos - v; if (delta.GetLengthSq() < found_distance) { found_distance = delta.GetLengthSq(); found_coord = v; } } // Move the dragged item dragitem.Move(found_coord); // Align to line here offset = found_coord - dragitemposition; // Do not snap to grid anymore snapgrid = false; snapgridincrement = false; //mxd } } else { // Move the dragged item dragitem.Move(nl.NearestOnLine(anchorpos)); // Align to line here offset = nl.NearestOnLine(anchorpos) - dragitemposition; } } } } // Snap to grid or grid increment? if (snapgrid || snapgridincrement) { // Move the dragged item dragitem.Move(anchorpos); // Snap item to grid increment if (snapgridincrement) //mxd { dragitem.Move(General.Map.Grid.SnappedToGrid(dragitem.Position) - dragstartoffset); } else // Or to the grid itself { dragitem.SnapToGrid(); } // Adjust the offset offset += dragitem.Position - anchorpos; } // Make sure the offset is inside the map boundaries if (offset.x + tl.x < General.Map.Config.LeftBoundary) { offset.x = General.Map.Config.LeftBoundary - tl.x; } if (offset.x + br.x > General.Map.Config.RightBoundary) { offset.x = General.Map.Config.RightBoundary - br.x; } if (offset.y + tl.y > General.Map.Config.TopBoundary) { offset.y = General.Map.Config.TopBoundary - tl.y; } if (offset.y + br.y < General.Map.Config.BottomBoundary) { offset.y = General.Map.Config.BottomBoundary - br.y; } // Drag item moved? if ((!snapgrid && !snapgridincrement) || (dragitem.Position != oldpos)) { int i = 0; // Move selected geometry foreach (Vertex v in selectedverts) { // Move vertex from old position relative to the mouse position change since drag start v.Move(oldpositions[i++] + offset); } //mxd. Move selected things i = 0; foreach (Thing t in thingstodrag) { t.Move(oldthingpositions[i++] + offset); } // Update labels int index = 0; foreach (Linedef l in unstablelines) { labels[index++].Move(l.Start.Position, l.End.Position); } // Moved return(true); } // No changes return(false); }
// This makes sure we are updated with the source linedef information public override void Update() { SectorData sd = data.Mode.GetSectorData(linedef.Front.Sector); if (!sd.Updated) { sd.Update(); } sd.AddUpdateSector(data.Sector, true); if (floor == null) { floor = new SectorLevel(sd.Floor); data.AddSectorLevel(floor); } if (ceiling == null) { ceiling = new SectorLevel(sd.Ceiling); data.AddSectorLevel(ceiling); } // For non-vavoom types, we must switch the level types if (linedef.Args[1] != (int)FloorTypes.VavoomStyle) { //mxd. check for Swimmable/RenderInside/RenderAdditive flags renderadditive = (linedef.Args[2] & (int)Flags.RenderAdditive) == (int)Flags.RenderAdditive; renderinside = ((((linedef.Args[1] & (int)FloorTypes.Swimmable) == (int)FloorTypes.Swimmable) && (linedef.Args[1] & (int)FloorTypes.NonSolid) != (int)FloorTypes.NonSolid)) || ((linedef.Args[1] & (int)FloorTypes.RenderInside) == (int)FloorTypes.RenderInside); ignorebottomheight = ((linedef.Args[2] & (int)Flags.IgnoreBottomHeight) == (int)Flags.IgnoreBottomHeight); vavoomtype = false; alpha = General.Clamp(linedef.Args[3], 0, 255); sd.Ceiling.CopyProperties(floor); sd.Floor.CopyProperties(ceiling); floor.type = SectorLevelType.Floor; floor.plane = sd.Ceiling.plane.GetInverted(); ceiling.type = SectorLevelType.Ceiling; ceiling.plane = (ignorebottomheight ? sd.Ceiling.plane : sd.Floor.plane.GetInverted()); //mxd. Use upper plane when "ignorebottomheight" flag is set //mxd clipsides = (!renderinside && !renderadditive && alpha > 254 && !ignorebottomheight); // A 3D floor's color is always that of the sector it is placed in // (unless it's affected by glow) - mxd if (sd.CeilingGlow == null || !sd.CeilingGlow.Fullbright) { floor.color = 0; } } else { vavoomtype = true; renderadditive = false; //mxd clipsides = true; //mxd floor.type = SectorLevelType.Ceiling; floor.plane = sd.Ceiling.plane; ceiling.type = SectorLevelType.Floor; ceiling.plane = sd.Floor.plane; alpha = 255; // A 3D floor's color is always that of the sector it is placed in // (unless it's affected by glow) - mxd if (sd.FloorGlow == null || !sd.FloorGlow.Fullbright) { ceiling.color = 0; } } // Apply alpha floor.alpha = alpha; ceiling.alpha = alpha; //mxd floor.extrafloor = true; ceiling.extrafloor = true; floor.splitsides = !clipsides; ceiling.splitsides = (!clipsides && !ignorebottomheight); // if "ignorebottomheight" flag is set, both ceiling and floor will be at the same level and sidedef clipping with floor level will fail resulting in incorrect light props transfer in some cases //mxd. Check slopes, cause GZDoom can't handle sloped translucent 3d floors... sloped3dfloor = ((alpha < 255 || renderadditive) && (Angle2D.RadToDeg(ceiling.plane.Normal.GetAngleZ()) != 270 || Angle2D.RadToDeg(floor.plane.Normal.GetAngleZ()) != 90)); // Do not adjust light? (works only for non-vavoom types) if (!vavoomtype) { bool disablelighting = ((linedef.Args[2] & (int)Flags.DisableLighting) == (int)Flags.DisableLighting); //mxd bool restrictlighting = ((linedef.Args[2] & (int)Flags.RestrictLighting) == (int)Flags.RestrictLighting); //mxd floor.resetlighting = ((linedef.Args[2] & (int)Flags.ResetLighting) == (int)Flags.ResetLighting); //mxd if (disablelighting || restrictlighting) { floor.restrictlighting = restrictlighting; //mxd floor.disablelighting = disablelighting; //mxd if (disablelighting) //mxd { floor.color = 0; floor.brightnessbelow = -1; floor.colorbelow = PixelColor.FromInt(0); } ceiling.disablelighting = disablelighting; //mxd ceiling.restrictlighting = restrictlighting; //mxd ceiling.color = 0; ceiling.brightnessbelow = -1; ceiling.colorbelow = PixelColor.FromInt(0); } } }
// Apply clicked private void apply_Click(object sender, EventArgs e) { // Verify properties if (!VerifyValue(hitag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sprite hitag")) { return; } if (!VerifyValue(lotag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sprite lotag")) { return; } if (!VerifyValue(extra.GetResult(0), General.Map.FormatInterface.MinExtra, General.Map.FormatInterface.MaxExtra, "Sprite extra")) { return; } if (!VerifyValue(palette.GetResult(0), 0, 255, "Sprite palette")) { return; } // Verify the coordinates int px = posx.GetResult(0); int py = -posy.GetResult(0); if ((px < General.Map.FormatInterface.MinCoordinate) || (px > General.Map.FormatInterface.MaxCoordinate) || (py < General.Map.FormatInterface.MinCoordinate) || (py > General.Map.FormatInterface.MaxCoordinate)) { General.ShowWarningMessage("Sprite coordinates must be between " + General.Map.FormatInterface.MinCoordinate + " and " + General.Map.FormatInterface.MaxCoordinate + ".", MessageBoxButtons.OK); return; } // Make undo General.Map.UndoRedo.CreateUndo("Edit " + (sprites.Count > 1 ? sprites.Count + " sprites" : "sprite")); // Collect flags... Dictionary <string, CheckState> flagsstate = new Dictionary <string, CheckState>(); foreach (CheckBox c in flags.Checkboxes) { flagsstate[c.Tag.ToString()] = c.CheckState; } bool applyposition = (posx.ApplyMode != NumericTextboxApplyMode.NO_VALUE || posy.ApplyMode != NumericTextboxApplyMode.NO_VALUE || posz.ApplyMode != NumericTextboxApplyMode.NO_VALUE); bool applyvelocity = (velx.ApplyMode != NumericTextboxApplyMode.NO_VALUE || vely.ApplyMode != NumericTextboxApplyMode.NO_VALUE || velz.ApplyMode != NumericTextboxApplyMode.NO_VALUE); // Apply to all sprites... foreach (Thing s in sprites) { // Type s.TileIndex = General.Clamp(tex.GetResult(s.TileIndex), General.Map.FormatInterface.MinTileIndex, General.Map.FormatInterface.MaxTileIndex); // Properties s.OffsetX = General.Wrap(offsetx.GetResult(s.OffsetX), General.Map.FormatInterface.MinSpriteOffset, General.Map.FormatInterface.MaxSpriteOffset); s.OffsetY = General.Wrap(offsety.GetResult(s.OffsetY), General.Map.FormatInterface.MinSpriteOffset, General.Map.FormatInterface.MaxSpriteOffset); s.RepeatX = General.Clamp(repeatx.GetResult(s.RepeatX), General.Map.FormatInterface.MinSpriteRepeat, General.Map.FormatInterface.MaxSpriteRepeat); s.RepeatY = General.Clamp(repeaty.GetResult(s.RepeatY), General.Map.FormatInterface.MinSpriteRepeat, General.Map.FormatInterface.MaxSpriteRepeat); s.Shade = General.Clamp(shade.GetResult(s.Shade), General.Map.FormatInterface.MinShade, General.Map.FormatInterface.MaxShade); s.PaletteIndex = palette.GetResult(s.PaletteIndex); s.Owner = owner.GetResult(s.Owner); // Position and velocity if (applyposition) { s.Move(new Vector3D(posx.GetResultFloat(s.Position.x), -posy.GetResultFloat(-s.Position.y), posz.GetResultFloat(s.Position.z))); } if (applyvelocity) { s.Velocity = new Vector3D(velx.GetResultFloat(s.Velocity.x), vely.GetResultFloat(s.Velocity.y), velz.GetResultFloat(s.Velocity.z)); } // Angle s.Angle = Angle2D.DegToRad(General.Wrap(angle.GetResultFloat(Angle2D.RadToDeg(s.Angle)), 0f, 359f)); // Identification s.HiTag = hitag.GetResult(s.HiTag); s.LoTag = lotag.GetResult(s.LoTag); s.Extra = extra.GetResult(s.Extra); // Flags foreach (KeyValuePair <string, CheckState> group in flagsstate) { switch (group.Value) { case CheckState.Checked: s.SetFlag(group.Key, true); break; case CheckState.Unchecked: s.SetFlag(group.Key, false); break; } } // Update settings s.UpdateConfiguration(); } // Update defaults var defaultflags = new List <string>(); foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { defaultflags.Add(c.Tag.ToString()); } } General.Map.Config.DefaultSpriteTile = spritetype.GetResult(General.Map.Config.DefaultSpriteTile); General.Map.Config.DefaultSpriteAngle = Angle2D.DegToRad((float)angle.GetResult((int)Angle2D.RadToDeg(General.Map.Config.DefaultSpriteAngle) - 90) + 90); General.Map.Config.DefaultSpriteFlags = defaultflags; // Done General.Map.IsChanged = true; this.DialogResult = DialogResult.OK; this.Close(); }
//mxd public virtual void OnChangeScale(int incrementX, int incrementY) { if (!General.Map.UDMF || !Texture.IsImageLoaded) { return; } changed = true; if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) { undoticket = mode.CreateUndo("Change texture scale"); } // Adjust to camera view 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) { ChangeTextureScale(incrementX, incrementY); } else if (angle > 225) { ChangeTextureScale(incrementY, incrementX); } else if (angle > 135) { ChangeTextureScale(incrementX, incrementY); } else { ChangeTextureScale(incrementY, incrementX); } // Rebuild sector BaseVisualSector vs; if (mode.VisualSectorExists(level.sector)) { vs = (BaseVisualSector)mode.GetVisualSector(level.sector); } else { //mxd. Need this to apply changes to 3d-floor even if control sector doesn't exist as BaseVisualSector vs = mode.CreateBaseVisualSector(level.sector); } if (vs != null) { vs.UpdateSectorGeometry(false); } }
// This shows the info public void ShowInfo(Thing s) { infopanel.Text = " Sprite " + s.Index + (s.Sector != null ? " (sector " + s.Sector.Index + ") " : " "); General.DisplayZoomedImage(spritetex, General.Map.Data.GetImageData(s.TileIndex).GetPreview()); spritename.Text = s.TileIndex.ToString(); var info = General.Map.Data.GetSpriteInfoEx(s.TileIndex); bool havedefinedtype = (info != null); type.Text = (havedefinedtype ? info.Title : "--"); type.Enabled = havedefinedtype; typelabel.Enabled = havedefinedtype; // Determine z info to show s.DetermineSector(); string zinfo = (s.Sector != null ? s.Position.z + s.Sector.FloorPlane.GetZ(s.Position) : s.Position.z).ToString(); position.Text = s.Position.x + ", " + (-s.Position.y) + ", " + zinfo; angle.Text = (int)Math.Round(Angle2D.RadToDeg(s.Angle)) + "\u00B0"; clipdistance.Text = s.ClipDistance.ToString(); owner.Text = s.Owner.ToString(); offsetx.Text = s.OffsetX.ToString(); offsety.Text = s.OffsetY.ToString(); repeatx.Text = s.RepeatX.ToString(); repeaty.Text = s.RepeatY.ToString(); hitag.Text = s.HiTag.ToString(); lotag.Text = s.LoTag.ToString(); extra.Text = s.Extra.ToString(); shade.Text = s.Shade.ToString(); palette.Text = s.PaletteIndex.ToString(); // Disable identification labels when showing default values hitag.Enabled = s.HiTag > 0; hitaglabel.Enabled = s.HiTag > 0; lotag.Enabled = s.LoTag > 0; lotaglabel.Enabled = s.LoTag > 0; extra.Enabled = s.Extra != -1; extralabel.Enabled = s.Extra != -1; owner.Enabled = s.Owner != -1; ownerlabel.Enabled = s.Owner != -1; offsetx.Enabled = s.OffsetX != 0; offsetxlabel.Enabled = s.OffsetX != 0; offsety.Enabled = s.OffsetY != 0; offsetylabel.Enabled = s.OffsetY != 0; repeatx.Enabled = s.RepeatX != 0; repeatxlabel.Enabled = s.RepeatX != 0; repeaty.Enabled = s.RepeatY != 0; repeatylabel.Enabled = s.RepeatY != 0; palette.Enabled = s.PaletteIndex > 0; palettelabel.Enabled = s.PaletteIndex > 0; // Flags List <string> flagnames = new List <string>(); foreach (KeyValuePair <string, string> group in General.Map.Config.SpriteFlags) { if (s.IsFlagSet(group.Key)) { flagnames.Add(group.Value); } } flags.Setup(flagnames); // Show the whole thing this.Show(); this.Update(); }
// This is called to update UV dragging protected virtual void UpdateDragUV() { float u_ray = 1.0f; // Calculate intersection position this.Level.plane.GetIntersection(General.Map.VisualCamera.Position, General.Map.VisualCamera.Target, ref u_ray); Vector3D intersect = General.Map.VisualCamera.Position + (General.Map.VisualCamera.Target - General.Map.VisualCamera.Position) * u_ray; // Calculate offsets Vector3D dragdelta = intersect - dragorigin; float offsetx = dragdelta.x; float offsety = dragdelta.y; bool lockX = General.Interface.CtrlState && !General.Interface.ShiftState; bool lockY = !General.Interface.CtrlState && General.Interface.ShiftState; if (lockX || lockY) { float camAngle = Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY); if (camAngle > 315 || camAngle < 46) { if (lockX) { offsetx = 0; } if (lockY) { offsety = 0; } } else if (camAngle > 225) { if (lockX) { offsety = 0; } if (lockY) { offsetx = 0; } } else if (camAngle > 135) { if (lockX) { offsetx = 0; } if (lockY) { offsety = 0; } } else { if (lockX) { offsety = 0; } if (lockY) { offsetx = 0; } } } //mxd. Modify offsets based on surface and camera angles float angle; 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); // Calculate deltas int deltax, deltay; if (General.Interface.CtrlState && General.Interface.ShiftState) { //mxd. Clamp to grid size? int newoffsetx = startoffsetx - (int)Math.Round(offsetx); int newoffsety = startoffsety + (int)Math.Round(offsety); deltax = prevoffsetx - newoffsetx; deltay = prevoffsety - newoffsety; if (Math.Abs(deltax) >= General.Map.Grid.GridSize) { deltax = General.Map.Grid.GridSize * Math.Sign(deltax); prevoffsetx = newoffsetx; } else { deltax = 0; } if (Math.Abs(deltay) >= General.Map.Grid.GridSize) { deltay = General.Map.Grid.GridSize * Math.Sign(deltay); prevoffsety = newoffsety; } else { deltay = 0; } } else { int newoffsetx = startoffsetx - (int)Math.Round(offsetx); int newoffsety = startoffsety + (int)Math.Round(offsety); deltax = prevoffsetx - newoffsetx; deltay = prevoffsety - newoffsety; prevoffsetx = newoffsetx; prevoffsety = newoffsety; } //mxd. Apply offset? if (deltax != 0 || deltay != 0) { mode.ApplyFlatOffsetChange(deltax, deltay); } mode.ShowTargetInfo(); }
// This returns the aligned and snapped draw position public static DrawnVertex GetCurrentPosition(Vector2D mousemappos, bool snaptonearest, bool snaptogrid, bool snaptocardinal, bool usefourcardinaldirections, IRenderer2D renderer, List <DrawnVertex> points) { DrawnVertex p = new DrawnVertex(); p.stitch = true; //mxd. Setting these to false seems to be a good way to create invalid geometry... p.stitchline = true; //mxd snaptocardinal = (snaptocardinal && points.Count > 0); //mxd. Don't snap to cardinal when there are no points //mxd. If snap to cardinal directions is enabled and we have points, modify mouse position Vector2D vm, gridoffset; if (snaptocardinal) { Vector2D offset = mousemappos - points[points.Count - 1].pos; float angle; if (usefourcardinaldirections) { angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()))) / 90 * 90 + 45); } else { angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 22)) / 45 * 45); } offset = new Vector2D(0, -offset.GetLength()).GetRotated(angle); vm = points[points.Count - 1].pos + offset; //mxd. We need to be snapped relative to initial position Vector2D prev = points[points.Count - 1].pos; gridoffset = prev - General.Map.Grid.SnappedToGrid(prev); } else { vm = mousemappos; gridoffset = new Vector2D(); } float vrange = BuilderPlug.Me.StitchRange / renderer.Scale; // Snap to nearest? if (snaptonearest) { // Go for all drawn points foreach (DrawnVertex v in points) { if (Vector2D.DistanceSq(vm, v.pos) < (vrange * vrange)) { p.pos = v.pos; return(p); } } // Try the nearest vertex Vertex nv = General.Map.Map.NearestVertexSquareRange(vm, vrange); if (nv != null) { //mxd. Line angle must stay the same if (snaptocardinal) { Line2D ourline = new Line2D(points[points.Count - 1].pos, vm); if (Math.Round(ourline.GetSideOfLine(nv.Position), 1) == 0) { p.pos = nv.Position; return(p); } } else { p.pos = nv.Position; return(p); } } // Try the nearest linedef. mxd. We'll need much bigger stitch distance when snapping to cardinal directions Linedef nl = General.Map.Map.NearestLinedefRange(vm, BuilderPlug.Me.StitchRange / renderer.Scale); if (nl != null) { //mxd. Line angle must stay the same if (snaptocardinal) { Line2D ourline = new Line2D(points[points.Count - 1].pos, vm); Line2D nearestline = new Line2D(nl.Start.Position, nl.End.Position); Vector2D intersection = Line2D.GetIntersectionPoint(nearestline, ourline, false); if (!float.IsNaN(intersection.x)) { // Intersection is on nearestline? float u = Line2D.GetNearestOnLine(nearestline.v1, nearestline.v2, intersection); if (u < 0f || u > 1f) { } else { p.pos = new Vector2D((float)Math.Round(intersection.x, General.Map.FormatInterface.VertexDecimals), (float)Math.Round(intersection.y, General.Map.FormatInterface.VertexDecimals)); return(p); } } } // Snap to grid? else if (snaptogrid) { // Get grid intersection coordinates List <Vector2D> coords = nl.GetGridIntersections(General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY); // Find nearest grid intersection bool found = false; float found_distance = float.MaxValue; Vector2D found_coord = new Vector2D(); foreach (Vector2D v in coords) { Vector2D delta = vm - v; if (delta.GetLengthSq() < found_distance) { found_distance = delta.GetLengthSq(); found_coord = v; found = true; } } if (found) { // Align to the closest grid intersection p.pos = found_coord; return(p); } } else { // Aligned to line p.pos = nl.NearestOnLine(vm); return(p); } } } else { // Always snap to the first drawn vertex so that the user can finish a complete sector without stitching if (points.Count > 0) { if (Vector2D.DistanceSq(vm, points[0].pos) < (vrange * vrange)) { p.pos = points[0].pos; return(p); } } } // if the mouse cursor is outside the map bondaries check if the line between the last set point and the // mouse cursor intersect any of the boundary lines. If it does, set the position to this intersection if (points.Count > 0 && (mousemappos.x < General.Map.Config.LeftBoundary || mousemappos.x > General.Map.Config.RightBoundary || mousemappos.y > General.Map.Config.TopBoundary || mousemappos.y < General.Map.Config.BottomBoundary)) { Line2D dline = new Line2D(mousemappos, points[points.Count - 1].pos); bool foundintersection = false; float u = 0.0f; List <Line2D> blines = new List <Line2D>(); // lines for left, top, right and bottom boundaries blines.Add(new Line2D(General.Map.Config.LeftBoundary, General.Map.Config.BottomBoundary, General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary)); blines.Add(new Line2D(General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary, General.Map.Config.RightBoundary, General.Map.Config.TopBoundary)); blines.Add(new Line2D(General.Map.Config.RightBoundary, General.Map.Config.TopBoundary, General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary)); blines.Add(new Line2D(General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary, General.Map.Config.LeftBoundary, General.Map.Config.BottomBoundary)); // check for intersections with boundaries for (int i = 0; i < blines.Count; i++) { if (!foundintersection) { // only check for intersection if the last set point is not on the // line we are checking against if (blines[i].GetSideOfLine(points[points.Count - 1].pos) != 0.0f) { foundintersection = blines[i].GetIntersection(dline, out u); } } } // if there was no intersection set the position to the last set point if (!foundintersection) { vm = points[points.Count - 1].pos; } else { vm = dline.GetCoordinatesAt(u); } } // Snap to grid? if (snaptogrid) { // Aligned to grid p.pos = General.Map.Grid.SnappedToGrid(vm - gridoffset) + gridoffset; // special handling if (p.pos.x > General.Map.Config.RightBoundary) { p.pos.x = General.Map.Config.RightBoundary; } if (p.pos.y < General.Map.Config.BottomBoundary) { p.pos.y = General.Map.Config.BottomBoundary; } return(p); } else { // Normal position p.pos.x = (float)Math.Round(vm.x); //mxd p.pos.y = (float)Math.Round(vm.y); //mxd return(p); } }
//mxd protected void AlignTextureToSlopeLine(Linedef slopeSource, float slopeAngle, bool isFront, bool alignx, bool aligny) { bool isFloor = (geometrytype == VisualGeometryType.FLOOR); Sector.Sector.Fields.BeforeFieldsChange(); float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(slopeSource.Angle) + 90 : -Angle2D.RadToDeg(slopeSource.Angle) - 90), 1); if (isFloor) { if ((isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight) || (!isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight)) { sourceAngle = General.ClampAngle(sourceAngle + 180); } } else { if ((isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight) || (!isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight)) { sourceAngle = General.ClampAngle(sourceAngle + 180); } } //update angle UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f); //update scaleY string xScaleKey = (isFloor ? "xscalefloor" : "xscaleceiling"); string yScaleKey = (isFloor ? "yscalefloor" : "yscaleceiling"); float scaleX = Sector.Sector.Fields.GetValue(xScaleKey, 1.0f); float scaleY; //set scale if (aligny) { scaleY = (float)Math.Round(scaleX * (1 / (float)Math.Cos(slopeAngle)), 2); UniFields.SetFloat(Sector.Sector.Fields, yScaleKey, scaleY, 1.0f); } else { scaleY = Sector.Sector.Fields.GetValue(yScaleKey, 1.0f); } //update texture offsets Vector2D offset; if (isFloor) { 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; } } else { 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 && Texture.IsImageLoaded) { offset.x %= Texture.Width / scaleX; } UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f); } if (aligny) { if (Texture != null && Texture.IsImageLoaded) { offset.y %= Texture.Height / scaleY; } UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f); } //update geometry Sector.UpdateSectorGeometry(false); }
// This sets up the form to edit the given sectors public void Setup(ICollection <Sector> sectors) { // Keep this list this.sectors = sectors; if (sectors.Count > 1) { this.Text = "Edit sectors (" + sectors.Count + ")"; } // Use the first sector as a reference BuildSector first = new BuildSector(General.GetFirst(sectors)); Dictionary <string, int> intflagsceiling = new Dictionary <string, int>(); Dictionary <string, int> intflagsfloor = new Dictionary <string, int>(); foreach (var group in General.Map.Config.SectorFlags) { intflagsceiling[group.Key] = (first.CeilingFlags.ContainsKey(group.Key) && first.CeilingFlags[group.Key] ? 1 : 0); intflagsfloor[group.Key] = (first.FloorFlags.ContainsKey(group.Key) && first.FloorFlags[group.Key] ? 1 : 0); } // Go for all sectors to compare properties foreach (Sector s in sectors) { // Floor/ceiling if (first.FloorHeight != s.FloorHeight) { first.FloorHeight = VALUE_MISMATCH; } if (first.CeilingHeight != s.CeilingHeight) { first.CeilingHeight = VALUE_MISMATCH; } if (first.Visibility != s.Visibility) { first.Visibility = VALUE_MISMATCH; } // Identification if (first.HiTag != s.HiTag) { first.HiTag = VALUE_MISMATCH; } if (first.LoTag != s.LoTag) { first.LoTag = VALUE_MISMATCH; } if (first.Extra != s.Extra) { first.Extra = VALUE_MISMATCH; } // Ceiling foreach (string flagname in General.Map.Config.SectorFlags.Keys) { int flag = (s.IsFlagSet(flagname, false) ? 1 : 0); if (flag != intflagsceiling[flagname]) { intflagsceiling[flagname] = VALUE_MISMATCH; } } if (first.CeilingTileIndex != s.CeilingTileIndex) { first.CeilingTileIndex = VALUE_MISMATCH; } if (first.CeilingOffsetX != s.CeilingOffsetX) { first.CeilingOffsetX = VALUE_MISMATCH; } if (first.CeilingOffsetY != s.CeilingOffsetY) { first.CeilingOffsetY = VALUE_MISMATCH; } if (first.CeilingShade != s.CeilingShade) { first.CeilingShade = VALUE_MISMATCH; } if (first.CeilingPaletteIndex != s.CeilingPaletteIndex) { first.CeilingPaletteIndex = VALUE_MISMATCH; } if (first.CeilingSlope != s.CeilingSlope) { first.CeilingSlope = VALUE_MISMATCH; } // Floor foreach (string flagname in General.Map.Config.SectorFlags.Keys) { int flag = (s.IsFlagSet(flagname, true) ? 1 : 0); if (flag != intflagsfloor[flagname]) { intflagsfloor[flagname] = VALUE_MISMATCH; } } if (first.FloorTileIndex != s.FloorTileIndex) { first.FloorTileIndex = VALUE_MISMATCH; } if (first.FloorOffsetX != s.FloorOffsetX) { first.FloorOffsetX = VALUE_MISMATCH; } if (first.FloorOffsetY != s.FloorOffsetY) { first.FloorOffsetY = VALUE_MISMATCH; } if (first.FloorShade != s.FloorShade) { first.FloorShade = VALUE_MISMATCH; } if (first.FloorPaletteIndex != s.FloorPaletteIndex) { first.FloorPaletteIndex = VALUE_MISMATCH; } if (first.FloorSlope != s.FloorSlope) { first.FloorSlope = VALUE_MISMATCH; } } // Update interface this.SuspendLayout(); // Floor/ceiling if (first.FloorHeight != VALUE_MISMATCH) { floorheight.Text = first.FloorHeight.ToString(); } if (first.CeilingHeight != VALUE_MISMATCH) { ceilheight.Text = first.CeilingHeight.ToString(); } if (first.Visibility != VALUE_MISMATCH) { visibility.Text = first.Visibility.ToString(); } // Identification //TODO: handlers if (first.HiTag != VALUE_MISMATCH) { hitag.Text = first.HiTag.ToString(); } if (first.LoTag != VALUE_MISMATCH) { lotag.Text = first.LoTag.ToString(); } if (first.Extra != VALUE_MISMATCH) { extra.Text = first.Extra.ToString(); } // Ceiling foreach (CheckBox c in ceilflags.Checkboxes) { switch (intflagsceiling[c.Tag.ToString()]) { case 1: c.Checked = true; break; case VALUE_MISMATCH: c.ThreeState = true; c.CheckState = CheckState.Indeterminate; break; } } ceiltex.TextureName = (first.CeilingTileIndex != VALUE_MISMATCH ? first.CeilingTileIndex.ToString() : ""); if (first.CeilingOffsetX != VALUE_MISMATCH) { ceiloffsetx.Text = first.CeilingOffsetX.ToString(); } if (first.CeilingOffsetY != VALUE_MISMATCH) { ceiloffsety.Text = first.CeilingOffsetY.ToString(); } if (first.CeilingShade != VALUE_MISMATCH) { ceilshade.Text = first.CeilingShade.ToString(); } if (first.CeilingPaletteIndex != VALUE_MISMATCH) { ceilpalette.Text = first.CeilingPaletteIndex.ToString(); } if (first.CeilingSlope != VALUE_MISMATCH) { ceilslope.Text = ((float)Math.Round(General.Wrap(Angle2D.RadToDeg(first.CeilingSlope) - 90, -90, 90), 1)).ToString(); } // Floor foreach (CheckBox c in floorflags.Checkboxes) { switch (intflagsfloor[c.Tag.ToString()]) { case 1: c.Checked = true; break; case VALUE_MISMATCH: c.ThreeState = true; c.CheckState = CheckState.Indeterminate; break; } } floortex.TextureName = (first.FloorTileIndex != VALUE_MISMATCH ? first.FloorTileIndex.ToString() : ""); if (first.FloorOffsetX != VALUE_MISMATCH) { flooroffsetx.Text = first.FloorOffsetX.ToString(); } if (first.FloorOffsetY != VALUE_MISMATCH) { flooroffsety.Text = first.FloorOffsetY.ToString(); } if (first.FloorShade != VALUE_MISMATCH) { floorshade.Text = first.FloorShade.ToString(); } if (first.FloorPaletteIndex != VALUE_MISMATCH) { floorpalette.Text = first.FloorPaletteIndex.ToString(); } if (first.FloorSlope != VALUE_MISMATCH) { floorslope.Text = ((float)Math.Round(General.Wrap(Angle2D.RadToDeg(first.FloorSlope) - 90, -90, 90), 1)).ToString(); } this.ResumeLayout(); // Show sector height UpdateSectorHeight(); }
// This restores all sectors to original values private void RestoreSectors() { int index = 0; foreach (Sector s in selection) { SectorInfo si = sectorinfo[index]; s.Fields.BeforeFieldsChange(); s.Fields[RotationName] = new UniValue(UniversalType.AngleDegreesFloat, Angle2D.RadToDeg(si.rotation)); s.Fields[XScaleName] = new UniValue(UniversalType.Float, si.scale.x); s.Fields[YScaleName] = new UniValue(UniversalType.Float, si.scale.y); s.Fields[XOffsetName] = new UniValue(UniversalType.Float, si.offset.x); s.Fields[YOffsetName] = new UniValue(UniversalType.Float, -si.offset.y); s.UpdateNeeded = true; s.UpdateCache(); index++; } }
// This shows the info public void ShowInfo(Sector s) { // Lookup effect description in config if (s.LoTag != 0 && General.Map.Config.SectorEffects.ContainsKey(s.LoTag)) { lotag.Text = General.Map.Config.SectorEffects[s.LoTag].ToString(); lotaglabel.Text = "Effect:"; } else { lotag.Text = s.LoTag.ToString(); lotaglabel.Text = "LoTag:"; } // Sector info sectorinfo.Text = " Sector " + s.Index + " (" + (s.Sidedefs != null ? s.Sidedefs.Count.ToString() : "no") + " walls)"; firstwall.Text = (s.FirstWall != null ? s.FirstWall.Index.ToString() : "--"); hitag.Text = s.HiTag.ToString(); extra.Text = s.Extra.ToString(); ceiling.Text = s.CeilingHeight.ToString(); floor.Text = s.FloorHeight.ToString(); height.Text = (s.CeilingHeight - s.FloorHeight).ToString(); visibility.Text = s.Visibility.ToString(); // Floor info General.DisplayZoomedImage(floortex, General.Map.Data.GetImageData(s.FloorTileIndex).GetPreview()); floorname.Text = s.FloorTileIndex.ToString(); flooroffsetx.Text = s.FloorOffsetX.ToString(); flooroffsety.Text = s.FloorOffsetY.ToString(); floorshade.Text = s.FloorShade.ToString(); floorpalette.Text = s.FloorPaletteIndex.ToString(); floorslope.Text = Math.Round(General.Wrap(Angle2D.RadToDeg(s.FloorSlope) - 90, -90, 90), 1) + "\u00B0"; // Ceiling info General.DisplayZoomedImage(ceiltex, General.Map.Data.GetImageData(s.CeilingTileIndex).GetPreview()); ceilname.Text = s.CeilingTileIndex.ToString(); ceiloffsetx.Text = s.CeilingOffsetX.ToString(); ceiloffsety.Text = s.CeilingOffsetY.ToString(); ceilshade.Text = s.CeilingShade.ToString(); ceilpalette.Text = s.CeilingPaletteIndex.ToString(); ceilslope.Text = Math.Round(General.Wrap(Angle2D.RadToDeg(s.CeilingSlope) - 90, -90, 90), 1) + "\u00B0"; // Disable identification labels when showing default values hitag.Enabled = s.HiTag > 0; hitaglabel.Enabled = s.HiTag > 0; lotag.Enabled = s.LoTag > 0; lotaglabel.Enabled = s.LoTag > 0; extra.Enabled = s.Extra != -1; extralabel.Enabled = s.Extra != -1; flooroffsetx.Enabled = s.FloorOffsetX != 0; flooroffsetxlabel.Enabled = s.FloorOffsetX != 0; flooroffsety.Enabled = s.FloorOffsetY != 0; flooroffsetylabel.Enabled = s.FloorOffsetY != 0; ceiloffsetx.Enabled = s.CeilingOffsetX != 0; ceiloffsetxlabel.Enabled = s.CeilingOffsetX != 0; ceiloffsety.Enabled = s.CeilingOffsetY != 0; ceiloffsetylabel.Enabled = s.CeilingOffsetY != 0; floorpalette.Enabled = s.FloorPaletteIndex > 0; floorpalettelabel.Enabled = s.FloorPaletteIndex > 0; bool floorsloped = (s.FloorSloped && s.FloorSlope != 0); floorslope.Enabled = floorsloped; floorslopelabel.Enabled = floorsloped; ceilpalette.Enabled = s.CeilingPaletteIndex > 0; ceilpalettelabel.Enabled = s.CeilingPaletteIndex > 0; bool ceilsloped = (s.CeilingSloped && s.CeilingSlope != 0); ceilslope.Enabled = ceilsloped; ceilslopelabel.Enabled = ceilsloped; // Floor flags List <string> floorflagnames = new List <string>(); foreach (KeyValuePair <string, string> group in General.Map.Config.SectorFlags) { if (s.IsFlagSet(group.Key, true)) { floorflagnames.Add(group.Value); } } floorflags.Setup(floorflagnames); // Ceiling flags List <string> ceilingflagnames = new List <string>(); foreach (KeyValuePair <string, string> group in General.Map.Config.SectorFlags) { if (s.IsFlagSet(group.Key, false)) { ceilingflagnames.Add(group.Value); } } ceilingflags.Setup(ceilingflagnames); // Resize and reposition if (floorflagnames.Count > 0) { ceilinggroup.Left = floorflags.Right + floorflags.Margin.Right + ceilinggroup.Margin.Left; } else { ceilinggroup.Left = floorgroup.Right + floorgroup.Margin.Right + ceilinggroup.Margin.Left; } if (ceilingflagnames.Count > 0) { ceilingflags.Left = ceilinggroup.Right + ceilinggroup.Margin.Right + ceilingflags.Margin.Left; this.Width = ceilingflags.Right + ceilingflags.Margin.Right; } else { this.Width = ceilinggroup.Right + ceilinggroup.Margin.Right; } // Show the whole thing this.Show(); this.Update(); }