UltimateZoneBuilder/Source/Core/Windows/SectorEditFormUDMF.cs
biwa 95f5c719b7 Sector/Linedef/Thing/Vertex Edit Form: the map will not be marked as changed anymore when canceling changes made in the forms, when the map wasn't marked as changed before
Copying map elements doesn't mark the map as changed anymore if the map wasn't marked as changed before copying
2021-04-01 23:31:52 +02:00

2157 lines
71 KiB
C#
Executable file

#region ================== Namespaces
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Types;
#endregion
namespace CodeImp.DoomBuilder.Windows
{
internal partial class SectorEditFormUDMF : DelayedForm
{
#region ================== Events
public event EventHandler OnValuesChanged; //mxd
#endregion
#region ================== Constants
private const string NO_SOUND_SEQUENCE = "None"; //mxd
private const string NO_TERRAIN = "Default"; //mxd
private const string NO_DAMAGETYPE = "None"; //mxd
#endregion
#region ================== Variables
private ICollection<Sector> sectors;
private Dictionary<Sector, SectorProperties> sectorprops; //mxd
private bool preventchanges; //mxd
private bool undocreated; //mxd
private StepsList anglesteps; //mxd
private readonly List<string> renderstyles; //mxd
private readonly List<string> portalrenderstyles; //mxd
//mxd. Slope pivots
private Vector2D globalslopepivot;
private Dictionary<Sector, Vector2D> slopepivots;
private bool oldmapischanged;
#endregion
#region ================== Structs
private struct SectorProperties //mxd
{
public readonly int Brightness;
public readonly int FloorHeight;
public readonly int CeilHeight;
public readonly string FloorTexture;
public readonly string CeilTexture;
//UDMF stuff
public readonly int LightColor;
public readonly int FadeColor;
public readonly int FogDensity;
//public float Desaturation;
//UDMF Ceiling
public readonly double CeilOffsetX;
public readonly double CeilOffsetY;
public readonly double CeilScaleX;
public readonly double CeilScaleY;
//public float CeilAlpha;
public readonly double CeilRotation;
public readonly int CeilBrightness;
public readonly bool CeilLightAbsoulte;
public readonly int CeilGlowColor;
public readonly double CeilGlowHeight;
//UDMF Floor
public readonly double FloorOffsetX;
public readonly double FloorOffsetY;
public readonly double FloorScaleX;
public readonly double FloorScaleY;
//public float FloorAlpha;
public readonly double FloorRotation;
public readonly int FloorBrightness;
public readonly bool FloorLightAbsoulte;
public readonly int FloorGlowColor;
public readonly double FloorGlowHeight;
//UDMF slopes. Angles are in degrees
public readonly Vector3D FloorSlope;
public readonly Vector3D CeilSlope;
public readonly double FloorSlopeAngleXY;
public readonly double FloorSlopeAngleZ;
public readonly double FloorSlopeOffset;
public readonly double CeilSlopeAngleXY;
public readonly double CeilSlopeAngleZ;
public readonly double CeilSlopeOffset;
//[ZZ] UDMF Doom64 sector colors
public readonly int D64ColorCeiling;
public readonly int D64ColorWallTop;
public readonly int D64ColorWallBottom;
public readonly int D64ColorFloor;
public readonly int D64ColorThings;
public SectorProperties(Sector s)
{
Brightness = s.Brightness;
FloorHeight = s.FloorHeight;
CeilHeight = s.CeilHeight;
FloorTexture = s.FloorTexture;
CeilTexture = s.CeilTexture;
//UDMF stuff
LightColor = UniFields.GetInteger(s.Fields, "lightcolor", PixelColor.INT_WHITE_NO_ALPHA);
FadeColor = UniFields.GetInteger(s.Fields, "fadecolor", 0);
FogDensity = UniFields.GetInteger(s.Fields, "fogdensity", 0);
//UDMF Ceiling
CeilOffsetX = UniFields.GetFloat(s.Fields, "xpanningceiling", 0.0);
CeilOffsetY = UniFields.GetFloat(s.Fields, "ypanningceiling", 0.0);
CeilScaleX = UniFields.GetFloat(s.Fields, "xscaleceiling", 1.0);
CeilScaleY = UniFields.GetFloat(s.Fields, "yscaleceiling", 1.0);
//CeilAlpha = UniFields.GetFloat(s.Fields, "alphaceiling", 1.0f);
CeilRotation = s.Fields.GetValue("rotationceiling", 0.0);
CeilBrightness = s.Fields.GetValue("lightceiling", 0);
CeilLightAbsoulte = s.Fields.GetValue("lightceilingabsolute", false);
CeilGlowColor = s.Fields.GetValue("ceilingglowcolor", 0);
CeilGlowHeight = s.Fields.GetValue("ceilingglowheight", 0.0);
//UDMF Floor
FloorOffsetX = UniFields.GetFloat(s.Fields, "xpanningfloor", 0.0);
FloorOffsetY = UniFields.GetFloat(s.Fields, "ypanningfloor", 0.0);
FloorScaleX = UniFields.GetFloat(s.Fields, "xscalefloor", 1.0);
FloorScaleY = UniFields.GetFloat(s.Fields, "yscalefloor", 1.0);
//FloorAlpha = UniFields.GetFloat(s.Fields, "alphafloor", 1.0f);
FloorRotation = s.Fields.GetValue("rotationfloor", 0.0);
FloorBrightness = s.Fields.GetValue("lightfloor", 0);
FloorLightAbsoulte = s.Fields.GetValue("lightfloorabsolute", false);
FloorGlowColor = s.Fields.GetValue("floorglowcolor", 0);
FloorGlowHeight = s.Fields.GetValue("floorglowheight", 0.0);
//UDMF slopes
if(s.FloorSlope.GetLengthSq() > 0)
{
FloorSlopeAngleXY = General.ClampAngle(Math.Round(Angle2D.RadToDeg(s.FloorSlope.GetAngleXY()) - 180, 1));
FloorSlopeAngleZ = -Math.Round(Angle2D.RadToDeg(s.FloorSlope.GetAngleZ()) - 90, 1);
FloorSlopeOffset = (double.IsNaN(s.FloorSlopeOffset) ? s.FloorHeight : s.FloorSlopeOffset);
}
else
{
FloorSlopeAngleXY = 0;
FloorSlopeAngleZ = 0;
FloorSlopeOffset = -s.FloorHeight;
}
FloorSlope = s.FloorSlope;
if(s.CeilSlope.GetLengthSq() > 0)
{
CeilSlopeAngleXY = General.ClampAngle(Math.Round(Angle2D.RadToDeg(s.CeilSlope.GetAngleXY()) - 180, 1));
CeilSlopeAngleZ = -Math.Round(270 - Angle2D.RadToDeg(s.CeilSlope.GetAngleZ()), 1);
CeilSlopeOffset = (double.IsNaN(s.CeilSlopeOffset) ? s.CeilHeight : s.CeilSlopeOffset);
}
else
{
CeilSlopeAngleXY = 0;
CeilSlopeAngleZ = 0;
CeilSlopeOffset = s.CeilHeight;
}
CeilSlope = s.CeilSlope;
D64ColorCeiling = s.Fields.GetValue("color_ceiling", PixelColor.INT_WHITE_NO_ALPHA);
D64ColorWallTop = s.Fields.GetValue("color_walltop", PixelColor.INT_WHITE_NO_ALPHA);
D64ColorThings = s.Fields.GetValue("color_sprites", PixelColor.INT_WHITE_NO_ALPHA);
D64ColorWallBottom = s.Fields.GetValue("color_wallbottom", PixelColor.INT_WHITE_NO_ALPHA);
D64ColorFloor = s.Fields.GetValue("color_floor", PixelColor.INT_WHITE_NO_ALPHA);
}
}
#endregion
#region ================== Constructor
public SectorEditFormUDMF()
{
InitializeComponent();
//mxd. Load settings
if(General.Settings.StoreSelectedEditTab)
{
int activetab = General.Settings.ReadSetting("windows." + configname + ".activetab", 0);
tabs.SelectTab(activetab);
}
// Fill flags list
foreach(KeyValuePair<string, string> lf in General.Map.Config.SectorFlags)
flags.Add(lf.Value, lf.Key);
flags.Enabled = General.Map.Config.SectorFlags.Count > 0;
// Fill floor protal flags list
foreach(KeyValuePair<string, string> lf in General.Map.Config.FloorPortalFlags)
floorportalflags.Add(lf.Value, lf.Key);
floorportalflags.Enabled = General.Map.Config.FloorPortalFlags.Count > 0;
// Fill ceiling protal flags list
foreach(KeyValuePair<string, string> lf in General.Map.Config.CeilingPortalFlags)
ceilportalflags.Add(lf.Value, lf.Key);
ceilportalflags.Enabled = General.Map.Config.CeilingPortalFlags.Count > 0;
// Setup renderstyles
if(General.Map.Config.SectorRenderStyles.Count > 0)
{
string[] rskeys = new string[General.Map.Config.SectorRenderStyles.Count];
General.Map.Config.SectorRenderStyles.Keys.CopyTo(rskeys, 0);
renderstyles = new List<string>(rskeys);
}
else
{
renderstyles = new List<string>();
}
floorRenderStyle.Enabled = (renderstyles.Count > 0);
labelfloorrenderstyle.Enabled = (renderstyles.Count > 0);
ceilRenderStyle.Enabled = (renderstyles.Count > 0);
labelceilrenderstyle.Enabled = (renderstyles.Count > 0);
// Fill renderstyles
foreach(string name in General.Map.Config.SectorRenderStyles.Values)
{
floorRenderStyle.Items.Add(name);
ceilRenderStyle.Items.Add(name);
}
// Setup portal renderstyles
if(General.Map.Config.SectorPortalRenderStyles.Count > 0)
{
string[] rskeys = new string[General.Map.Config.SectorPortalRenderStyles.Count];
General.Map.Config.SectorPortalRenderStyles.Keys.CopyTo(rskeys, 0);
portalrenderstyles = new List<string>(rskeys);
}
else
{
portalrenderstyles = new List<string>();
}
floorportalrenderstyle.Enabled = (portalrenderstyles.Count > 0);
floorportalrenderstylelabel.Enabled = (portalrenderstyles.Count > 0);
ceilportalrenderstyle.Enabled = (portalrenderstyles.Count > 0);
ceilportalrenderstylelabel.Enabled = (portalrenderstyles.Count > 0);
// Fill portal renderstyles
foreach(string name in General.Map.Config.SectorPortalRenderStyles.Values)
{
floorportalrenderstyle.Items.Add(name);
ceilportalrenderstyle.Items.Add(name);
}
// Fill effects list
effect.GeneralizedOptions = General.Map.Config.GenEffectOptions; //mxd
effect.AddInfo(General.Map.Config.SortedSectorEffects.ToArray());
// Fill sound sequences list
soundsequence.Items.Add(NO_SOUND_SEQUENCE);
soundsequence.Items.AddRange(General.Map.Data.SoundSequences);
// Fill damagetype list
damagetype.Items.Add(NO_DAMAGETYPE);
damagetype.Items.AddRange(General.Map.Data.DamageTypes);
// Fill terrain type lists
ceilterrain.Items.Add(NO_TERRAIN);
ceilterrain.Items.AddRange(General.Map.Data.TerrainNames);
floorterrain.Items.Add(NO_TERRAIN);
floorterrain.Items.AddRange(General.Map.Data.TerrainNames);
// Initialize custom fields editor
fieldslist.Setup("sector");
// Fill universal fields list
fieldslist.ListFixedFields(General.Map.Config.SectorFields);
// Initialize image selectors
floortex.Initialize();
ceilingtex.Initialize();
// Set steps for brightness field
brightness.StepValues = General.Map.Config.BrightnessLevels;
// Apply settings
ceilScale.LinkValues = General.Settings.ReadSetting("windows." + configname + ".linkceilingscale", false);
floorScale.LinkValues = General.Settings.ReadSetting("windows." + configname + ".linkfloorscale", false);
cbUseCeilLineAngles.Checked = General.Settings.ReadSetting("windows." + configname + ".useceillineangles", false);
cbUseFloorLineAngles.Checked = General.Settings.ReadSetting("windows." + configname + ".usefloorlineangles", false);
ceilingslopecontrol.UseLineAngles = General.Settings.ReadSetting("windows." + configname + ".useceilslopelineangles", false);
floorslopecontrol.UseLineAngles = General.Settings.ReadSetting("windows." + configname + ".usefloorslopelineangles", false);
ceilingslopecontrol.PivotMode = (SlopePivotMode)General.Settings.ReadSetting("windows." + configname + ".ceilpivotmode", (int)SlopePivotMode.LOCAL);
floorslopecontrol.PivotMode = (SlopePivotMode)General.Settings.ReadSetting("windows." + configname + ".floorpivotmode", (int)SlopePivotMode.LOCAL);
}
#endregion
#region ================== Methods
// This sets up the form to edit the given sectors
public void Setup(ICollection<Sector> sectors)
{
preventchanges = true; //mxd
oldmapischanged = General.Map.IsChanged;
undocreated = false;
// Keep this list
this.sectors = sectors;
if(sectors.Count > 1) this.Text = "Edit Sectors (" + sectors.Count + ")";
sectorprops = new Dictionary<Sector, SectorProperties>(sectors.Count); //mxd
//mxd. Set default height offset
heightoffset.Text = "0";
CreateHelperProps(sectors); //mxd
////////////////////////////////////////////////////////////////////////
// Set all options to the first sector properties
////////////////////////////////////////////////////////////////////////
// Get first sector
Sector sc = General.GetByIndex(sectors, 0);
// Flags
foreach(CheckBox c in flags.Checkboxes)
if(sc.Flags.ContainsKey(c.Tag.ToString())) c.Checked = sc.Flags[c.Tag.ToString()];
// Portal flags
foreach(CheckBox c in floorportalflags.Checkboxes)
if(sc.Flags.ContainsKey(c.Tag.ToString())) c.Checked = sc.Flags[c.Tag.ToString()];
foreach(CheckBox c in ceilportalflags.Checkboxes)
if(sc.Flags.ContainsKey(c.Tag.ToString())) c.Checked = sc.Flags[c.Tag.ToString()];
// Effects
effect.Value = sc.Effect;
brightness.Text = sc.Brightness.ToString();
// Floor/ceiling
floorheight.Text = sc.FloorHeight.ToString();
ceilingheight.Text = sc.CeilHeight.ToString();
floortex.TextureName = sc.FloorTexture;
ceilingtex.TextureName = sc.CeilTexture;
// UDMF stuff
// Texture offsets
ceilOffsets.SetValuesFrom(sc.Fields, true);
floorOffsets.SetValuesFrom(sc.Fields, true);
// Texture scale
ceilScale.SetValuesFrom(sc.Fields, true);
floorScale.SetValuesFrom(sc.Fields, true);
// Texture rotation
double ceilAngle = sc.Fields.GetValue("rotationceiling", 0.0);
double floorAngle = sc.Fields.GetValue("rotationfloor", 0.0);
ceilRotation.Text = ceilAngle.ToString();
floorRotation.Text = floorAngle.ToString();
ceilAngleControl.Angle = General.ClampAngle(360 - (int)ceilAngle);
floorAngleControl.Angle = General.ClampAngle(360 - (int)floorAngle);
// Texture brightness
ceilBrightness.Text = sc.Fields.GetValue("lightceiling", 0).ToString();
floorBrightness.Text = sc.Fields.GetValue("lightfloor", 0).ToString();
ceilLightAbsolute.Checked = sc.Fields.GetValue("lightceilingabsolute", false);
floorLightAbsolute.Checked = sc.Fields.GetValue("lightfloorabsolute", false);
// Portal alpha
alphaceiling.Text = General.Clamp(sc.Fields.GetValue("alphaceiling", 1.0), 0.0, 1.0).ToString();
alphafloor.Text = General.Clamp(sc.Fields.GetValue("alphafloor", 1.0), 0.0, 1.0).ToString();
// Reflectivity
ceiling_reflect.Text = General.Clamp(sc.Fields.GetValue("ceiling_reflect", 0.0), 0.0, 1.0).ToString();
floor_reflect.Text = General.Clamp(sc.Fields.GetValue("floor_reflect", 0.0), 0.0, 1.0).ToString();
// Fog density
fogdensity.Text = General.Clamp(sc.Fields.GetValue("fogdensity", 0), 0, 510).ToString();
// Floor/ceiling glow
int ceilingglowcolorval = sc.Fields.GetValue("ceilingglowcolor", 0);
int floorglowcolorval = sc.Fields.GetValue("floorglowcolor", 0);
ceilingglowcolor.SetValueFrom(sc.Fields, true);
floorglowcolor.SetValueFrom(sc.Fields, true);
// Floor/ceiling glow height
ceilingglowheight.Text = sc.Fields.GetValue("ceilingglowheight", 0.0).ToString();
floorglowheight.Text = sc.Fields.GetValue("floorglowheight", 0.0).ToString();
// Render style
ceilRenderStyle.SelectedIndex = renderstyles.IndexOf(sc.Fields.GetValue("renderstyleceiling", "translucent"));
floorRenderStyle.SelectedIndex = renderstyles.IndexOf(sc.Fields.GetValue("renderstylefloor", "translucent"));
// Portal render style
if (portalrenderstyles.Count > 0)
{
ceilportalrenderstyle.SelectedIndex = portalrenderstyles.IndexOf(sc.Fields.GetValue("portal_ceil_overlaytype", portalrenderstyles[0]));
floorportalrenderstyle.SelectedIndex = portalrenderstyles.IndexOf(sc.Fields.GetValue("portal_floor_overlaytype", portalrenderstyles[0]));
}
// Damage
damagetype.Text = sc.Fields.GetValue("damagetype", NO_DAMAGETYPE);
damageamount.Text = sc.Fields.GetValue("damageamount", 0).ToString();
damageinterval.Text = sc.Fields.GetValue("damageinterval", 32).ToString();
leakiness.Text = General.Clamp(sc.Fields.GetValue("leakiness", 0), 0, 256).ToString();
// Terrain
ceilterrain.Text = sc.Fields.GetValue("ceilingterrain", NO_TERRAIN);
floorterrain.Text = sc.Fields.GetValue("floorterrain", NO_TERRAIN);
// Misc
soundsequence.Text = sc.Fields.GetValue("soundsequence", NO_SOUND_SEQUENCE);
gravity.Text = sc.Fields.GetValue("gravity", 1.0).ToString();
desaturation.Text = General.Clamp(sc.Fields.GetValue("desaturation", 0.0), 0.0, 1.0).ToString();
// Sector colors
fadeColor.SetValueFrom(sc.Fields, true);
lightColor.SetValueFrom(sc.Fields, true);
// [ZZ]
ceilingColor.SetValueFrom(sc.Fields, true);
upperWallColor.SetValueFrom(sc.Fields, true);
thingsColor.SetValueFrom(sc.Fields, true);
lowerWallColor.SetValueFrom(sc.Fields, true);
floorColor.SetValueFrom(sc.Fields, true);
// Slopes
SetupFloorSlope(sc, true);
SetupCeilingSlope(sc, true);
// Custom fields
fieldslist.SetValues(sc.Fields, true);
// Comments
commenteditor.SetValues(sc.Fields, true);
anglesteps = new StepsList();
////////////////////////////////////////////////////////////////////////
// Now go for all sectors and change the options when a setting is different
////////////////////////////////////////////////////////////////////////
// Go for all sectors
foreach(Sector s in sectors)
{
// Flags
SetupFlags(flags, s);
SetupFlags(ceilportalflags, s);
SetupFlags(floorportalflags, s);
// Effects
if(s.Effect != effect.Value) effect.Empty = true;
if(s.Brightness.ToString() != brightness.Text) brightness.Text = "";
// Floor/Ceiling
if(s.FloorHeight.ToString() != floorheight.Text) floorheight.Text = "";
if(s.CeilHeight.ToString() != ceilingheight.Text) ceilingheight.Text = "";
if(s.FloorTexture != floortex.TextureName)
{
floortex.MultipleTextures = true; //mxd
floortex.TextureName = "";
}
if(s.CeilTexture != ceilingtex.TextureName)
{
ceilingtex.MultipleTextures = true; //mxd
ceilingtex.TextureName = "";
}
// UDMF stuff
// Texture offsets
ceilOffsets.SetValuesFrom(s.Fields, false);
floorOffsets.SetValuesFrom(s.Fields, false);
// Texture scale
ceilScale.SetValuesFrom(s.Fields, false);
floorScale.SetValuesFrom(s.Fields, false);
// Texture rotation
if(s.Fields.GetValue("rotationceiling", 0.0).ToString() != ceilRotation.Text)
{
ceilRotation.Text = "";
ceilAngleControl.Angle = AngleControlEx.NO_ANGLE;
}
if(s.Fields.GetValue("rotationfloor", 0.0).ToString() != floorRotation.Text)
{
floorRotation.Text = "";
floorAngleControl.Angle = AngleControlEx.NO_ANGLE;
}
// Texture brightness
if(s.Fields.GetValue("lightceiling", 0).ToString() != ceilBrightness.Text) ceilBrightness.Text = "";
if(s.Fields.GetValue("lightfloor", 0).ToString() != floorBrightness.Text) floorBrightness.Text = "";
if(s.Fields.GetValue("lightceilingabsolute", false) != ceilLightAbsolute.Checked)
{
ceilLightAbsolute.ThreeState = true;
ceilLightAbsolute.CheckState = CheckState.Indeterminate;
}
if(s.Fields.GetValue("lightfloorabsolute", false) != floorLightAbsolute.Checked)
{
floorLightAbsolute.ThreeState = true;
floorLightAbsolute.CheckState = CheckState.Indeterminate;
}
// Portal alpha
if(s.Fields.GetValue("alphaceiling", 1.0).ToString() != alphaceiling.Text) alphaceiling.Text = "";
if(s.Fields.GetValue("alphafloor", 1.0).ToString() != alphafloor.Text) alphafloor.Text = "";
// Reflectivity
if(s.Fields.GetValue("ceiling_reflect", 0.0).ToString() != ceiling_reflect.Text) ceiling_reflect.Text = "";
if(s.Fields.GetValue("floor_reflect", 0.0).ToString() != floor_reflect.Text) floor_reflect.Text = "";
// Fog density
if(s.Fields.GetValue("fogdensity", 0).ToString() != fogdensity.Text) fogdensity.Text = "";
// Floor/ceiling glow
if(floorglowcolorval != s.Fields.GetValue("floorglowcolor", 0)) floorglowcolorval = 0;
if(ceilingglowcolorval != s.Fields.GetValue("ceilingglowcolor", 0)) ceilingglowcolorval = 0;
ceilingglowcolor.SetValueFrom(s.Fields, false);
floorglowcolor.SetValueFrom(s.Fields, false);
// Floor/ceiling glow height
if(s.Fields.GetValue("ceilingglowheight", 0.0).ToString() != ceilingglowheight.Text) ceilingglowheight.Text = "";
if(s.Fields.GetValue("floorglowheight", 0.0).ToString() != floorglowheight.Text) floorglowheight.Text = "";
// Render style
if(ceilRenderStyle.SelectedIndex > -1 && ceilRenderStyle.SelectedIndex != renderstyles.IndexOf(s.Fields.GetValue("renderstyleceiling", "translucent")))
ceilRenderStyle.SelectedIndex = -1;
if(floorRenderStyle.SelectedIndex > -1 && floorRenderStyle.SelectedIndex != renderstyles.IndexOf(s.Fields.GetValue("renderstylefloor", "translucent")))
floorRenderStyle.SelectedIndex = -1;
// Portal render style
if(ceilportalrenderstyle.SelectedIndex > -1 && ceilportalrenderstyle.SelectedIndex != portalrenderstyles.IndexOf(s.Fields.GetValue("portal_ceil_overlaytype", portalrenderstyles[0])))
ceilportalrenderstyle.SelectedIndex = -1;
if(floorportalrenderstyle.SelectedIndex > -1 && floorportalrenderstyle.SelectedIndex != portalrenderstyles.IndexOf(s.Fields.GetValue("portal_floor_overlaytype", portalrenderstyles[0])))
floorportalrenderstyle.SelectedIndex = -1;
// Damage
if(damagetype.SelectedIndex > -1 && s.Fields.GetValue("damagetype", NO_DAMAGETYPE) != damagetype.Text)
damagetype.SelectedIndex = -1;
if(s.Fields.GetValue("damageamount", 0).ToString() != damageamount.Text) damageamount.Text = "";
if(s.Fields.GetValue("damageinterval", 32).ToString() != damageinterval.Text) damageinterval.Text = "";
if(s.Fields.GetValue("leakiness", 0).ToString() != leakiness.Text) leakiness.Text = "";
// Terrain
if(ceilterrain.SelectedIndex > -1 && s.Fields.GetValue("ceilingterrain", NO_TERRAIN) != ceilterrain.Text)
ceilterrain.SelectedIndex = -1;
if(floorterrain.SelectedIndex > -1 && s.Fields.GetValue("floorterrain", NO_TERRAIN) != floorterrain.Text)
floorterrain.SelectedIndex = -1;
// Misc
if(soundsequence.SelectedIndex > -1 && s.Fields.GetValue("soundsequence", NO_SOUND_SEQUENCE) != soundsequence.Text)
soundsequence.SelectedIndex = -1;
if(s.Fields.GetValue("gravity", 1.0).ToString() != gravity.Text) gravity.Text = "";
if(s.Fields.GetValue("desaturation", 0.0).ToString() != desaturation.Text) desaturation.Text = "";
// Sector colors
fadeColor.SetValueFrom(s.Fields, false);
lightColor.SetValueFrom(s.Fields, false);
// [ZZ]
ceilingColor.SetValueFrom(s.Fields, false);
upperWallColor.SetValueFrom(s.Fields, false);
thingsColor.SetValueFrom(s.Fields, false);
lowerWallColor.SetValueFrom(s.Fields, false);
floorColor.SetValueFrom(s.Fields, false);
// Slopes
SetupFloorSlope(s, false);
SetupCeilingSlope(s, false);
// Custom fields
fieldslist.SetValues(s.Fields, false);
//mxd. Comments
commenteditor.SetValues(s.Fields, false);
//mxd. Angle steps
foreach(Sidedef side in s.Sidedefs)
{
int angle;
if(side.Line.Front != null && side.Index == side.Line.Front.Index)
angle = General.ClampAngle(270 - side.Line.AngleDeg);
else
angle = General.ClampAngle(90 - side.Line.AngleDeg);
if(!anglesteps.Contains(angle)) anglesteps.Add(angle);
}
}
//mxd. Glow is disabled?
if (floorglowcolorval == -1)
floorGlowEnabled.Checked = false;
if (ceilingglowcolorval == -1)
ceilingGlowEnabled.Checked = false;
//mxd. Update "Reset" buttons...
if(ceiling_reflect.Text == "0") reset_ceiling_reflect.Visible = false;
if(floor_reflect.Text == "0") reset_floor_reflect.Visible = false;
if(ceilingglowheight.Text == "0") resetceilingglowheight.Visible = false;
if(floorglowheight.Text == "0") resetfloorglowheight.Visible = false;
//mxd. Cause Graf was not into non-zero default glow height...
UpdateCeilingGlowHeightWarning();
UpdateFloorGlowHeightWarning();
//mxd. Setup tags
tagsselector.SetValues(sectors);
//mxd. Update slope controls
ceilingslopecontrol.UpdateControls();
floorslopecontrol.UpdateControls();
// Show sector height
UpdateSectorHeight();
//mxd. Update brightness reset buttons
resetceillight.Visible = (ceilLightAbsolute.CheckState != CheckState.Unchecked || ceilBrightness.GetResult(0) != 0);
resetfloorlight.Visible = (floorLightAbsolute.CheckState != CheckState.Unchecked || floorBrightness.GetResult(0) != 0);
//mxd. Angle steps
anglesteps.Sort();
if(cbUseCeilLineAngles.Checked) ceilRotation.StepValues = anglesteps;
if(cbUseFloorLineAngles.Checked) floorRotation.StepValues = anglesteps;
if(ceilingslopecontrol.UseLineAngles) ceilingslopecontrol.StepValues = anglesteps;
if(floorslopecontrol.UseLineAngles) floorslopecontrol.StepValues = anglesteps;
//mxd. Comments
commenteditor.FinishSetup();
preventchanges = false; //mxd
}
//mxd
private static void SetupFlags(CheckboxArrayControl control, Sector s)
{
foreach(CheckBox c in control.Checkboxes)
{
if(c.CheckState == CheckState.Indeterminate) continue; //mxd
if(s.IsFlagSet(c.Tag.ToString()) != c.Checked)
{
c.ThreeState = true;
c.CheckState = CheckState.Indeterminate;
}
}
}
//mxd
private static void ApplyFlags(CheckboxArrayControl control, Sector s)
{
foreach(CheckBox c in control.Checkboxes)
{
switch(c.CheckState)
{
case CheckState.Checked: s.SetFlag(c.Tag.ToString(), true); break;
case CheckState.Unchecked: s.SetFlag(c.Tag.ToString(), false); break;
}
}
}
//mxd
private static void ApplyFloatProperty(ButtonsNumericTextbox control, Sector s, float defaultvalue)
{
if(!string.IsNullOrEmpty(control.Text))
{
double ceilAlphaVal = General.Clamp(control.GetResultFloat(s.Fields.GetValue(control.Name, defaultvalue)), 0.0, 1.0);
UniFields.SetFloat(s.Fields, control.Name, ceilAlphaVal, defaultvalue);
}
}
//mxd
private void MakeUndo()
{
if(undocreated) return;
undocreated = true;
//mxd. Make undo
General.Map.UndoRedo.CreateUndo("Edit " + (sectors.Count > 1 ? sectors.Count + " sectors" : "sector"));
foreach(Sector s in sectors) s.Fields.BeforeFieldsChange();
}
// mxd
private void CreateHelperProps(ICollection<Sector> sectors)
{
slopepivots = new Dictionary<Sector, Vector2D>(sectors.Count);
foreach(Sector s in sectors)
{
if(slopepivots.ContainsKey(s)) continue;
Vector2D pivot = new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2);
globalslopepivot += pivot;
slopepivots.Add(s, pivot);
// Store initial properties
sectorprops.Add(s, new SectorProperties(s));
}
globalslopepivot /= sectors.Count;
}
// This updates the sector height field
private void UpdateSectorHeight()
{
int delta = int.MinValue;
// Check all selected sectors
foreach(Sector s in sectors)
{
if(delta == int.MinValue)
{
// First sector in list
delta = s.CeilHeight - s.FloorHeight;
}
else if(delta != (s.CeilHeight - s.FloorHeight))
{
// We can't show heights because the delta
// heights for the sectors is different
delta = int.MinValue;
break;
}
}
if(delta != int.MinValue)
{
sectorheight.Text = delta.ToString();
sectorheight.Visible = true;
sectorheightlabel.Visible = true;
}
else
{
sectorheight.Visible = false;
sectorheightlabel.Visible = false;
}
}
//mxd
private void UpdateCeilingHeight()
{
int offset;
if(heightoffset.Text == "++" || heightoffset.Text == "--") // Raise or lower by sector height
{
int sign = (heightoffset.Text == "++" ? 1 : -1);
foreach(Sector s in sectors)
{
offset = sectorprops[s].CeilHeight - sectorprops[s].FloorHeight;
s.CeilHeight += offset * sign;
}
}
else
{
//restore values
if(string.IsNullOrEmpty(ceilingheight.Text))
{
// Reset increment steps, otherwise it's just keep counting and counting
heightoffset.ResetIncrementStep();
foreach (Sector s in sectors)
{
// To get the steps for ---/+++ into effect the offset has to be retrieved again for each sector
offset = heightoffset.GetResult(0);
s.CeilHeight = sectorprops[s].CeilHeight + offset;
}
}
else //update values
{
// Reset increment steps, otherwise it's just keep counting and counting
heightoffset.ResetIncrementStep();
foreach (Sector s in sectors)
{
// To get the steps for ---/+++ into effect the offset has to be retrieved again for each sector
offset = heightoffset.GetResult(0);
s.CeilHeight = ceilingheight.GetResult(sectorprops[s].CeilHeight) + offset;
}
}
}
}
//mxd
private void UpdateFloorHeight()
{
int offset;
if(heightoffset.Text == "++" || heightoffset.Text == "--")
{
// Raise or lower by sector height
int sign = (heightoffset.Text == "++" ? 1 : -1);
foreach(Sector s in sectors)
{
offset = sectorprops[s].CeilHeight - sectorprops[s].FloorHeight;
s.FloorHeight += offset * sign;
}
}
else
{
// Reset increment steps, otherwise it's just keep counting and counting
heightoffset.ResetIncrementStep();
//restore values
if(string.IsNullOrEmpty(floorheight.Text))
{
foreach(Sector s in sectors)
{
// To get the steps for ---/+++ into effect the offset has to be retrieved again for each sector
offset = heightoffset.GetResult(0);
s.FloorHeight = sectorprops[s].FloorHeight + offset;
}
}
else //update values
{
foreach(Sector s in sectors)
{
// To get the steps for ---/+++ into effect the offset has to be retrieved again for each sector
offset = heightoffset.GetResult(0);
s.FloorHeight = floorheight.GetResult(sectorprops[s].FloorHeight) + offset;
}
}
}
}
#endregion
#region ================== Events
private void apply_Click(object sender, EventArgs e)
{
// Verify the effect
if((effect.Value < General.Map.FormatInterface.MinEffect) || (effect.Value > General.Map.FormatInterface.MaxEffect))
{
General.ShowWarningMessage("Sector effect must be between " + General.Map.FormatInterface.MinEffect + " and " + General.Map.FormatInterface.MaxEffect + ".", MessageBoxButtons.OK);
return;
}
MakeUndo(); //mxd
// Go for all sectors
foreach(Sector s in sectors)
{
// Apply all flags
ApplyFlags(flags, s);
ApplyFlags(ceilportalflags, s);
ApplyFlags(floorportalflags, s);
// Effects
if(!effect.Empty) s.Effect = effect.Value;
// Fields
fieldslist.Apply(s.Fields);
//mxd. Comments
commenteditor.Apply(s.Fields);
// Portal alpha
ApplyFloatProperty(alphaceiling, s, 1.0f);
ApplyFloatProperty(alphafloor, s, 1.0f);
// Reflectivity
ApplyFloatProperty(ceiling_reflect, s, 0.0f);
ApplyFloatProperty(floor_reflect, s, 0.0f);
// Renderstyle
if(renderstyles.Count > 0)
{
if(ceilRenderStyle.SelectedIndex > -1)
UniFields.SetString(s.Fields, "renderstyleceiling", renderstyles[ceilRenderStyle.SelectedIndex], "translucent");
if(floorRenderStyle.SelectedIndex > -1)
UniFields.SetString(s.Fields, "renderstylefloor", renderstyles[floorRenderStyle.SelectedIndex], "translucent");
}
// Portal renderstyles
if(portalrenderstyles.Count > 0)
{
if(ceilportalrenderstyle.SelectedIndex > -1)
UniFields.SetString(s.Fields, "portal_ceil_overlaytype", portalrenderstyles[ceilportalrenderstyle.SelectedIndex], portalrenderstyles[0]);
if(floorportalrenderstyle.SelectedIndex > -1)
UniFields.SetString(s.Fields, "portal_floor_overlaytype", portalrenderstyles[floorportalrenderstyle.SelectedIndex], portalrenderstyles[0]);
}
//Damage
if(!string.IsNullOrEmpty(damagetype.Text))
UniFields.SetString(s.Fields, "damagetype", damagetype.Text, NO_DAMAGETYPE);
if(!string.IsNullOrEmpty(damageamount.Text))
UniFields.SetInteger(s.Fields, "damageamount", damageamount.GetResult(s.Fields.GetValue("damageamount", 0)), 0);
if(!string.IsNullOrEmpty(damageinterval.Text))
UniFields.SetInteger(s.Fields, "damageinterval", damageinterval.GetResult(s.Fields.GetValue("damageinterval", 32)), 32);
if(!string.IsNullOrEmpty(leakiness.Text))
UniFields.SetInteger(s.Fields, "leakiness", General.Clamp(leakiness.GetResult(s.Fields.GetValue("leakiness", 0)), 0, 256), 0);
//Terrain
if(!string.IsNullOrEmpty(ceilterrain.Text))
UniFields.SetString(s.Fields, "ceilingterrain", ceilterrain.Text, NO_TERRAIN);
if(!string.IsNullOrEmpty(floorterrain.Text))
UniFields.SetString(s.Fields, "floorterrain", floorterrain.Text, NO_TERRAIN);
// Misc
if(!string.IsNullOrEmpty(soundsequence.Text))
UniFields.SetString(s.Fields, "soundsequence", soundsequence.Text, NO_SOUND_SEQUENCE);
if(!string.IsNullOrEmpty(gravity.Text))
UniFields.SetFloat(s.Fields, "gravity", gravity.GetResultFloat(s.Fields.GetValue("gravity", 1.0)), 1.0);
if(!string.IsNullOrEmpty(desaturation.Text))
{
double val = General.Clamp(desaturation.GetResultFloat(s.Fields.GetValue("desaturation", 0.0)), 0.0, 1.0);
UniFields.SetFloat(s.Fields, "desaturation", val, 0.0);
}
// Clear horizontal slopes
double diff = Math.Abs(Math.Round(s.FloorSlopeOffset) - s.FloorSlopeOffset);
if (Math.Abs(s.FloorSlope.z) == 1.0 && diff < 0.000000001)
{
s.FloorHeight = -Convert.ToInt32(s.FloorSlopeOffset);
s.FloorSlope = new Vector3D();
s.FloorSlopeOffset = double.NaN;
}
diff = Math.Abs(Math.Round(s.CeilSlopeOffset) - s.CeilSlopeOffset);
if (Math.Abs(s.CeilSlope.z) == 1.0 && diff < 0.000000001)
{
s.CeilHeight = Convert.ToInt32(s.CeilSlopeOffset);
s.CeilSlope = new Vector3D();
s.CeilSlopeOffset = double.NaN;
}
}
//mxd. Apply tags
tagsselector.ApplyTo(sectors);
// Update the used textures
General.Map.Data.UpdateUsedTextures();
// Done
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty); //mxd
this.DialogResult = DialogResult.OK;
this.Close();
}
private void cancel_Click(object sender, EventArgs e)
{
//mxd. Let's pretend nothing of this really happened...
if (undocreated)
{
General.Map.UndoRedo.WithdrawUndo();
// Changing certain properties of the sector, like floor/ceiling textures will set General.Map.IsChanged to true.
// But if cancel is pressed and the changes are discarded, and the map was not changed before, we have to force
// General.Map.IsChanged back to false
if (General.Map.IsChanged && oldmapischanged == false)
General.Map.ForceMapIsChangedFalse();
}
// Be gone
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private void browseeffect_Click(object sender, EventArgs e)
{
effect.Value = EffectBrowserForm.BrowseEffect(this, effect.Value);
}
//mxd
private void SectorEditFormUDMF_FormClosing(object sender, FormClosingEventArgs e)
{
// Save settings
General.Settings.WriteSetting("windows." + configname + ".activetab", tabs.SelectedIndex);
General.Settings.WriteSetting("windows." + configname + ".linkceilingscale", ceilScale.LinkValues);
General.Settings.WriteSetting("windows." + configname + ".linkfloorscale", floorScale.LinkValues);
General.Settings.WriteSetting("windows." + configname + ".useceillineangles", cbUseCeilLineAngles.Checked);
General.Settings.WriteSetting("windows." + configname + ".usefloorlineangles", cbUseFloorLineAngles.Checked);
General.Settings.WriteSetting("windows." + configname + ".useceilslopelineangles", ceilingslopecontrol.UseLineAngles);
General.Settings.WriteSetting("windows." + configname + ".usefloorslopelineangles", floorslopecontrol.UseLineAngles);
General.Settings.WriteSetting("windows." + configname + ".ceilpivotmode", (int)ceilingslopecontrol.PivotMode);
General.Settings.WriteSetting("windows." + configname + ".floorpivotmode", (int)floorslopecontrol.PivotMode);
}
private void SectorEditFormUDMF_HelpRequested(object sender, HelpEventArgs hlpevent)
{
General.ShowHelp("w_sectoredit.html");
hlpevent.Handled = true;
}
private void tabcustom_MouseEnter(object sender, EventArgs e)
{
fieldslist.Focus();
}
private void ceilAngleControl_AngleChanged(object sender, EventArgs e)
{
ceilRotation.Text = (General.ClampAngle(360 - ceilAngleControl.Angle)).ToString();
}
private void floorAngleControl_AngleChanged(object sender, EventArgs e)
{
floorRotation.Text = (General.ClampAngle(360 - floorAngleControl.Angle)).ToString();
}
private void cbUseCeilLineAngles_CheckedChanged(object sender, EventArgs e)
{
ceilRotation.ButtonStepsWrapAround = cbUseCeilLineAngles.Checked;
ceilRotation.StepValues = (cbUseCeilLineAngles.Checked ? anglesteps : null);
}
private void cbUseFloorLineAngles_CheckedChanged(object sender, EventArgs e)
{
floorRotation.ButtonStepsWrapAround = cbUseFloorLineAngles.Checked;
floorRotation.StepValues = (cbUseFloorLineAngles.Checked ? anglesteps : null);
}
private void resetfloorterrain_Click(object sender, EventArgs e)
{
floorterrain.Focus();
floorterrain.Text = NO_TERRAIN;
}
private void floorterrain_TextChanged(object sender, EventArgs e)
{
resetfloorterrain.Visible = (floorterrain.Text != NO_TERRAIN);
}
private void floorterrain_MouseDown(object sender, MouseEventArgs e)
{
if(floorterrain.Text == NO_TERRAIN) floorterrain.SelectAll();
}
private void resetceilterrain_Click(object sender, EventArgs e)
{
ceilterrain.Focus();
ceilterrain.Text = NO_TERRAIN;
}
private void ceilterrain_TextChanged(object sender, EventArgs e)
{
resetceilterrain.Visible = (ceilterrain.Text != NO_TERRAIN);
}
private void ceilterrain_MouseDown(object sender, MouseEventArgs e)
{
if(ceilterrain.Text == NO_TERRAIN) ceilterrain.SelectAll();
}
private void resetdamagetype_Click(object sender, EventArgs e)
{
damagetype.Focus();
damagetype.Text = NO_DAMAGETYPE;
}
private void damagetype_TextChanged(object sender, EventArgs e)
{
resetdamagetype.Visible = (damagetype.Text != NO_DAMAGETYPE);
}
private void damagetype_MouseDown(object sender, MouseEventArgs e)
{
if(damagetype.Text == NO_DAMAGETYPE) damagetype.SelectAll();
}
private void resetsoundsequence_Click(object sender, EventArgs e)
{
soundsequence.Focus();
soundsequence.Text = NO_SOUND_SEQUENCE;
}
private void soundsequence_TextChanged(object sender, EventArgs e)
{
resetsoundsequence.Visible = (soundsequence.Text != NO_SOUND_SEQUENCE);
}
private void soundsequence_MouseDown(object sender, MouseEventArgs e)
{
if(soundsequence.Text == NO_SOUND_SEQUENCE) soundsequence.SelectAll();
}
private void ceiling_reflect_WhenTextChanged(object sender, EventArgs e)
{
reset_ceiling_reflect.Visible = (string.IsNullOrEmpty(ceiling_reflect.Text) || ceiling_reflect.GetResultFloat(0.0f) != 0.0f);
}
private void floor_reflect_WhenTextChanged(object sender, EventArgs e)
{
reset_floor_reflect.Visible = (string.IsNullOrEmpty(floor_reflect.Text) || floor_reflect.GetResultFloat(0.0f) != 0.0f);
}
private void reset_ceiling_reflect_Click(object sender, EventArgs e)
{
ceiling_reflect.Focus();
ceiling_reflect.Text = "0";
}
private void reset_floor_reflect_Click(object sender, EventArgs e)
{
floor_reflect.Focus();
floor_reflect.Text = "0";
}
private void alphaceiling_WhenTextChanged(object sender, EventArgs e)
{
resetalphaceiling.Visible = (string.IsNullOrEmpty(alphaceiling.Text) || alphaceiling.GetResultFloat(1.0f) != 1.0f);
}
private void alphafloor_WhenTextChanged(object sender, EventArgs e)
{
resetalphafloor.Visible = (string.IsNullOrEmpty(alphafloor.Text) || alphafloor.GetResultFloat(1.0f) != 1.0f);
}
private void resetalphafloor_Click(object sender, EventArgs e)
{
alphafloor.Focus();
alphafloor.Text = "1";
}
private void resetalphaceiling_Click(object sender, EventArgs e)
{
alphaceiling.Focus();
alphaceiling.Text = "1";
}
#endregion
#region ================== Sector Realtime events (mxd)
private void ceilingheight_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
UpdateCeilingHeight();
UpdateSectorHeight();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorheight_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
UpdateFloorHeight();
UpdateSectorHeight();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void heightoffset_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
UpdateFloorHeight();
UpdateCeilingHeight();
UpdateSectorHeight();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void brightness_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
brightness.ResetIncrementStep();
//restore values
if (string.IsNullOrEmpty(brightness.Text))
{
foreach(Sector s in sectors)
s.Brightness = sectorprops[s].Brightness;
}
else //update values
{
foreach(Sector s in sectors)
s.Brightness = General.Clamp(brightness.GetResult(sectorprops[s].Brightness), General.Map.FormatInterface.MinBrightness, General.Map.FormatInterface.MaxBrightness);
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilingtex_OnValueChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
//restore values
if(string.IsNullOrEmpty(ceilingtex.TextureName))
{
foreach(Sector s in sectors)
s.SetCeilTexture(sectorprops[s].CeilTexture);
}
else //update values
{
foreach(Sector s in sectors)
s.SetCeilTexture(ceilingtex.GetResult(s.CeilTexture));
}
// Update the used textures
General.Map.Data.UpdateUsedTextures();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floortex_OnValueChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
//restore values
if(string.IsNullOrEmpty(floortex.TextureName))
{
foreach(Sector s in sectors)
s.SetFloorTexture(sectorprops[s].FloorTexture);
}
else //update values
{
foreach(Sector s in sectors)
s.SetFloorTexture(floortex.GetResult(s.FloorTexture));
}
// Update the used textures
General.Map.Data.UpdateUsedTextures();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorRotation_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
floorRotation.ResetIncrementStep();
//restore values
if (string.IsNullOrEmpty(floorRotation.Text))
{
floorAngleControl.Angle = AngleControlEx.NO_ANGLE;
foreach(Sector s in sectors)
{
UniFields.SetFloat(s.Fields, "rotationfloor", sectorprops[s].FloorRotation, 0.0);
s.UpdateNeeded = true;
}
}
else //update values
{
floorAngleControl.Angle = (int)General.ClampAngle(360 - floorRotation.GetResultFloat(0));
foreach(Sector s in sectors)
{
UniFields.SetFloat(s.Fields, "rotationfloor", floorRotation.GetResultFloat(sectorprops[s].FloorRotation), 0.0);
s.UpdateNeeded = true;
}
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilRotation_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
ceilRotation.ResetIncrementStep();
//restore values
if (string.IsNullOrEmpty(ceilRotation.Text))
{
ceilAngleControl.Angle = AngleControlEx.NO_ANGLE;
foreach(Sector s in sectors)
{
UniFields.SetFloat(s.Fields, "rotationceiling", sectorprops[s].CeilRotation, 0.0);
s.UpdateNeeded = true;
}
}
else //update values
{
ceilAngleControl.Angle = (int)General.ClampAngle(360 - ceilRotation.GetResultFloat(0));
foreach(Sector s in sectors)
{
UniFields.SetFloat(s.Fields, "rotationceiling", ceilRotation.GetResultFloat(sectorprops[s].CeilRotation), 0.0);
s.UpdateNeeded = true;
}
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void lightColor_OnValueChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
foreach(Sector s in sectors)
{
lightColor.ApplyTo(s.Fields, sectorprops[s].LightColor);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void fadeColor_OnValueChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
foreach(Sector s in sectors)
{
fadeColor.ApplyTo(s.Fields, sectorprops[s].FadeColor);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
#endregion
#region ================== Ceiling/Floor realtime events (mxd)
private void ceilOffsets_OnValuesChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
ceilOffsets.ResetIncrementStep();
foreach (Sector s in sectors)
{
ceilOffsets.ApplyTo(s.Fields, General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset, sectorprops[s].CeilOffsetX, sectorprops[s].CeilOffsetY);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorOffsets_OnValuesChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
floorOffsets.ResetIncrementStep();
foreach (Sector s in sectors)
{
floorOffsets.ApplyTo(s.Fields, General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset, sectorprops[s].FloorOffsetX, sectorprops[s].FloorOffsetY);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilScale_OnValuesChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
ceilScale.ResetIncrementStep();
foreach (Sector s in sectors)
{
ceilScale.ApplyTo(s.Fields, General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset, sectorprops[s].CeilScaleX, sectorprops[s].CeilScaleY);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorScale_OnValuesChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
floorScale.ResetIncrementStep();
foreach (Sector s in sectors)
{
floorScale.ApplyTo(s.Fields, General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset, sectorprops[s].FloorScaleX, sectorprops[s].FloorScaleY);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilBrightness_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
ceilBrightness.ResetIncrementStep();
//restore values
if (string.IsNullOrEmpty(ceilBrightness.Text))
{
foreach(Sector s in sectors)
{
UniFields.SetInteger(s.Fields, "lightceiling", sectorprops[s].CeilBrightness, 0);
s.UpdateNeeded = true;
}
}
else //update values
{
foreach(Sector s in sectors)
{
bool absolute = false;
switch(ceilLightAbsolute.CheckState)
{
case CheckState.Indeterminate:
absolute = s.Fields.GetValue("lightceilingabsolute", false);
break;
case CheckState.Checked:
absolute = true;
break;
}
int value = General.Clamp(ceilBrightness.GetResult(sectorprops[s].CeilBrightness), (absolute ? 0 : -255), 255);
UniFields.SetInteger(s.Fields, "lightceiling", value, 0);
s.UpdateNeeded = true;
}
}
resetceillight.Visible = (ceilLightAbsolute.CheckState != CheckState.Unchecked || ceilBrightness.Text != "0");
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorBrightness_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
// Reset increment steps, otherwise it's just keep counting and counting
floorBrightness.ResetIncrementStep();
//restore values
if (string.IsNullOrEmpty(floorBrightness.Text))
{
foreach(Sector s in sectors)
{
UniFields.SetInteger(s.Fields, "lightfloor", sectorprops[s].FloorBrightness, 0);
s.UpdateNeeded = true;
}
}
else //update values
{
foreach(Sector s in sectors)
{
bool absolute = false;
switch(floorLightAbsolute.CheckState)
{
case CheckState.Indeterminate:
absolute = s.Fields.GetValue("lightfloorabsolute", false);
break;
case CheckState.Checked:
absolute = true;
break;
}
int value = General.Clamp(floorBrightness.GetResult(sectorprops[s].FloorBrightness), (absolute ? 0 : -255), 255);
UniFields.SetInteger(s.Fields, "lightfloor", value, 0);
s.UpdateNeeded = true;
}
}
resetfloorlight.Visible = (floorLightAbsolute.CheckState != CheckState.Unchecked || floorBrightness.Text != "0");
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilLightAbsolute_CheckedChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
if(ceilLightAbsolute.Checked)
{
foreach(Sector s in sectors)
{
s.Fields["lightceilingabsolute"] = new UniValue(UniversalType.Boolean, true);
s.UpdateNeeded = true;
}
}
else if(ceilLightAbsolute.CheckState == CheckState.Indeterminate)
{
foreach(Sector s in sectors)
{
if(sectorprops[s].CeilLightAbsoulte)
{
s.Fields["lightceilingabsolute"] = new UniValue(UniversalType.Boolean, true);
s.UpdateNeeded = true;
}
else if(s.Fields.ContainsKey("lightceilingabsolute"))
{
s.Fields.Remove("lightceilingabsolute");
s.UpdateNeeded = true;
}
}
}
else
{
foreach(Sector s in sectors)
{
if(s.Fields.ContainsKey("lightceilingabsolute"))
{
s.Fields.Remove("lightceilingabsolute");
s.UpdateNeeded = true;
}
}
}
resetceillight.Visible = (ceilLightAbsolute.CheckState != CheckState.Unchecked || ceilBrightness.Text != "0");
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorLightAbsolute_CheckedChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
if(floorLightAbsolute.Checked)
{
foreach(Sector s in sectors)
{
s.Fields["lightfloorabsolute"] = new UniValue(UniversalType.Boolean, true);
s.UpdateNeeded = true;
}
}
else if(floorLightAbsolute.CheckState == CheckState.Indeterminate)
{
foreach(Sector s in sectors)
{
if(sectorprops[s].FloorLightAbsoulte)
{
s.Fields["lightfloorabsolute"] = new UniValue(UniversalType.Boolean, true);
s.UpdateNeeded = true;
}
else if(s.Fields.ContainsKey("lightfloorabsolute"))
{
s.Fields.Remove("lightfloorabsolute");
s.UpdateNeeded = true;
}
}
}
else
{
foreach(Sector s in sectors)
{
if(s.Fields.ContainsKey("lightfloorabsolute"))
{
s.Fields.Remove("lightfloorabsolute");
s.UpdateNeeded = true;
}
}
}
resetfloorlight.Visible = (floorLightAbsolute.CheckState != CheckState.Unchecked || floorBrightness.Text != "0");
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void resetceillight_Click(object sender, EventArgs e)
{
MakeUndo(); //mxd
preventchanges = true;
ceilLightAbsolute.Checked = false;
ceilBrightness.Text = "0";
foreach(Sector s in sectors)
{
if(s.Fields.ContainsKey("lightceilingabsolute")) s.Fields.Remove("lightceilingabsolute");
if(s.Fields.ContainsKey("lightceiling")) s.Fields.Remove("lightceiling");
}
preventchanges = false;
resetceillight.Visible = false;
ceilBrightness.Focus();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void resetfloorlight_Click(object sender, EventArgs e)
{
MakeUndo(); //mxd
preventchanges = true;
floorLightAbsolute.Checked = false;
floorBrightness.Text = "0";
foreach(Sector s in sectors)
{
if(s.Fields.ContainsKey("lightfloorabsolute")) s.Fields.Remove("lightfloorabsolute");
if(s.Fields.ContainsKey("lightfloor")) s.Fields.Remove("lightfloor");
}
preventchanges = false;
resetfloorlight.Visible = false;
floorBrightness.Focus();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void fogdensity_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo();
// Reset increment steps, otherwise it's just keep counting and counting
fogdensity.ResetIncrementStep();
// Restore values
if (string.IsNullOrEmpty(fogdensity.Text))
{
foreach(Sector s in sectors)
{
UniFields.SetInteger(s.Fields, "fogdensity", sectorprops[s].FogDensity, 0);
s.UpdateNeeded = true;
}
}
else // Update values
{
foreach(Sector s in sectors)
{
int value = General.Clamp(fogdensity.GetResult(sectorprops[s].FogDensity), 0, 510);
UniFields.SetInteger(s.Fields, "fogdensity", value, 0);
s.UpdateNeeded = true;
}
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
#endregion
#region ================== Slope Utility (mxd)
private void SetupFloorSlope(Sector s, bool first)
{
if(s.FloorSlope.GetLengthSq() > 0)
{
double anglexy = General.ClampAngle(Math.Round(Angle2D.RadToDeg(s.FloorSlope.GetAngleXY()) - 180, 1));
double anglez = -Math.Round(Angle2D.RadToDeg(s.FloorSlope.GetAngleZ()) - 90, 1);
double offset = Math.Round(GetVirtualSlopeOffset(s, floorslopecontrol.PivotMode, true), 1);
if(anglexy >= 180 && anglez < 0)
{
anglexy -= 180;
anglez = -anglez;
}
floorslopecontrol.SetValues(anglexy, anglez, offset, first);
}
else
{
floorslopecontrol.SetValues(0.0, 0.0, s.FloorHeight, first);
}
}
private void SetupCeilingSlope(Sector s, bool first)
{
if(s.CeilSlope.GetLengthSq() > 0)
{
double anglexy = General.ClampAngle(Math.Round(Angle2D.RadToDeg(s.CeilSlope.GetAngleXY()) - 180, 1));
double anglez = -(270 - Math.Round(Angle2D.RadToDeg(s.CeilSlope.GetAngleZ()), 1));
double offset = Math.Round(GetVirtualSlopeOffset(s, ceilingslopecontrol.PivotMode, false), 1);
if(anglexy >= 180 && anglez < 0)
{
anglexy -= 180;
anglez = -anglez;
}
ceilingslopecontrol.SetValues(anglexy, anglez, offset, first);
}
else
{
ceilingslopecontrol.SetValues(0.0, 0.0, s.CeilHeight, first);
}
}
// Gets the offset to be displayed in a SectorSlopeControl
private double GetVirtualSlopeOffset(Sector s, SlopePivotMode mode, bool floor)
{
double offset = (floor ? s.FloorSlopeOffset : s.CeilSlopeOffset);
if(double.IsNaN(offset))
{
offset = (floor ? s.FloorHeight : s.CeilHeight);
}
Vector3D normal = (floor ? s.FloorSlope : s.CeilSlope);
if(normal.GetLengthSq() > 0)
{
Vector3D center = GetSectorCenter(s, 0, mode);
Plane p = new Plane(normal, offset);
return p.GetZ(center);
}
return offset;
}
// Gets the offset to be displayed in a SectorSlopeControl
private double GetInitialVirtualSlopeOffset(Sector s, SlopePivotMode mode, bool floor)
{
double offset = (floor ? sectorprops[s].FloorSlopeOffset : sectorprops[s].CeilSlopeOffset);
Vector3D normal = (floor ? sectorprops[s].FloorSlope : sectorprops[s].CeilSlope);
if(normal.GetLengthSq() > 0)
{
Vector3D center = GetSectorCenter(s, 0, mode);
Plane p = new Plane(normal, offset);
return p.GetZ(center);
}
return offset;
}
private Vector3D GetSectorCenter(Sector s, double offset, SlopePivotMode mode)
{
switch(mode)
{
case SlopePivotMode.GLOBAL: //translate from the center of selection
return new Vector3D(globalslopepivot, offset);
case SlopePivotMode.LOCAL: //translate from sector's bounding box center
return new Vector3D(slopepivots[s], offset);
case SlopePivotMode.ORIGIN: //don't translate
return new Vector3D(0, 0, offset);
default:
throw new NotImplementedException("Unknown SlopePivotMode: " + (int)mode);
}
}
#endregion
#region ================== Slopes realtime events (mxd)
private void ceilingslopecontrol_OnAnglesChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
//Set or restore values
foreach(Sector s in sectors)
{
double anglexy = General.ClampAngle(ceilingslopecontrol.GetAngleXY(sectorprops[s].CeilSlopeAngleXY) + 270);
double anglez = -(ceilingslopecontrol.GetAngleZ(sectorprops[s].CeilSlopeAngleZ) + 90);
double virtualoffset = GetInitialVirtualSlopeOffset(s, ceilingslopecontrol.PivotMode, false);
Vector3D center = GetSectorCenter(s, ceilingslopecontrol.GetOffset(virtualoffset), ceilingslopecontrol.PivotMode);
Plane p = new Plane(center, Angle2D.DegToRad(anglexy), Angle2D.DegToRad(anglez), false);
s.CeilSlope = p.Normal;
s.CeilSlopeOffset = p.Offset;
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorslopecontrol_OnAnglesChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo(); //mxd
//Set or restore values
foreach(Sector s in sectors)
{
double anglexy = General.ClampAngle(floorslopecontrol.GetAngleXY(sectorprops[s].FloorSlopeAngleXY) + 90);
double anglez = -(floorslopecontrol.GetAngleZ(sectorprops[s].FloorSlopeAngleZ) + 90);
double virtualoffset = GetInitialVirtualSlopeOffset(s, floorslopecontrol.PivotMode, true);
Vector3D center = GetSectorCenter(s, floorslopecontrol.GetOffset(virtualoffset), floorslopecontrol.PivotMode);
Plane p = new Plane(center, Angle2D.DegToRad(anglexy), Angle2D.DegToRad(anglez), true);
s.FloorSlope = p.Normal;
s.FloorSlopeOffset = p.Offset;
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
// Update displayed ceiling offset value
private void ceilingslopecontrol_OnPivotModeChanged(object sender, EventArgs e)
{
MakeUndo(); //mxd
bool first = true;
foreach(Sector s in sectors)
{
SetupCeilingSlope(s, first);
first = false;
}
}
// Update displayed floor offset value
private void floorslopecontrol_OnPivotModeChanged(object sender, EventArgs e)
{
MakeUndo(); //mxd
bool first = true;
foreach(Sector s in sectors)
{
SetupFloorSlope(s, first);
first = false;
}
}
private void ceilingslopecontrol_OnResetClicked(object sender, EventArgs e)
{
MakeUndo(); //mxd
Sector fs = General.GetByIndex(sectors, 0);
Plane p = new Plane(fs.CeilSlope, fs.CeilSlopeOffset);
fs.UpdateBBox();
ceilingslopecontrol.SetOffset((int)Math.Round(p.GetZ(fs.BBox.X + fs.BBox.Width / 2, fs.BBox.Y + fs.BBox.Height / 2)), true);
foreach(Sector s in sectors)
{
s.UpdateBBox();
p = new Plane(s.CeilSlope, s.CeilSlopeOffset);
s.CeilHeight = (int)Math.Round(p.GetZ(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
s.CeilSlope = new Vector3D();
s.CeilSlopeOffset = double.NaN;
s.UpdateNeeded = true;
ceilingslopecontrol.SetOffset(s.CeilHeight, false);
}
ceilingslopecontrol.UpdateOffset();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorslopecontrol_OnResetClicked(object sender, EventArgs e)
{
MakeUndo(); //mxd
Sector fs = General.GetByIndex(sectors, 0);
Plane p = new Plane(fs.FloorSlope, fs.FloorSlopeOffset);
fs.UpdateBBox();
floorslopecontrol.SetOffset((int)Math.Round(p.GetZ(fs.BBox.X + fs.BBox.Width / 2, fs.BBox.Y + fs.BBox.Height / 2)), true);
foreach(Sector s in sectors)
{
s.UpdateBBox();
p = new Plane(s.FloorSlope, s.FloorSlopeOffset);
s.FloorHeight = (int)Math.Round(p.GetZ(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
s.FloorSlope = new Vector3D();
s.FloorSlopeOffset = double.NaN;
s.UpdateNeeded = true;
floorslopecontrol.SetOffset(s.FloorHeight, false);
}
floorslopecontrol.UpdateOffset();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilingslopecontrol_OnUseLineAnglesChanged(object sender, EventArgs e)
{
ceilingslopecontrol.StepValues = (ceilingslopecontrol.UseLineAngles ? anglesteps : null);
}
private void floorslopecontrol_OnUseLineAnglesChanged(object sender, EventArgs e)
{
floorslopecontrol.StepValues = (floorslopecontrol.UseLineAngles ? anglesteps : null);
}
#endregion
#region ================== Glow realtime events (mxd)
private void UpdateCeilingGlowHeightWarning()
{
ceilingglowheightrequired.Visible = (ceilingglowcolor.Color.WithAlpha(0).ToInt() != ceilingglowcolor.DefaultValue
&& ceilingglowheight.GetResultFloat(0f) == 0f);
}
private void UpdateFloorGlowHeightWarning()
{
floorglowheightrequired.Visible = (floorglowcolor.Color.WithAlpha(0).ToInt() != floorglowcolor.DefaultValue
&& floorglowheight.GetResultFloat(0f) == 0f);
}
private void ceilingglowcolor_OnValueChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo();
foreach(Sector s in sectors)
{
ceilingglowcolor.ApplyTo(s.Fields, sectorprops[s].CeilGlowColor);
s.UpdateNeeded = true;
}
// Show height warning?
UpdateCeilingGlowHeightWarning();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorglowcolor_OnValueChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo();
foreach(Sector s in sectors)
{
floorglowcolor.ApplyTo(s.Fields, sectorprops[s].FloorGlowColor);
s.UpdateNeeded = true;
}
// Show height warning?
UpdateFloorGlowHeightWarning();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilingglowheight_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo();
// Restore values
if(string.IsNullOrEmpty(ceilingglowheight.Text))
{
foreach(Sector s in sectors)
{
UniFields.SetFloat(s.Fields, "ceilingglowheight", sectorprops[s].CeilGlowHeight, 0.0);
s.UpdateNeeded = true;
}
}
else // Update values
{
foreach(Sector s in sectors)
{
double value = General.Clamp(ceilingglowheight.GetResultFloat(sectorprops[s].CeilGlowHeight), 0.0, double.MaxValue);
UniFields.SetFloat(s.Fields, "ceilingglowheight", value, 0.0);
s.UpdateNeeded = true;
}
}
// Update "Reset" button
resetceilingglowheight.Visible = (ceilingglowheight.GetResultFloat(0.0) != 0.0);
// Show height warning?
UpdateCeilingGlowHeightWarning();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void floorglowheight_WhenTextChanged(object sender, EventArgs e)
{
if(preventchanges) return;
MakeUndo();
// Restore values
if(string.IsNullOrEmpty(floorglowheight.Text))
{
foreach(Sector s in sectors)
{
UniFields.SetFloat(s.Fields, "floorglowheight", sectorprops[s].FloorGlowHeight, 0.0);
s.UpdateNeeded = true;
}
}
else // Update values
{
foreach(Sector s in sectors)
{
double value = General.Clamp(floorglowheight.GetResultFloat(sectorprops[s].FloorGlowHeight), 0.0, double.MaxValue);
UniFields.SetFloat(s.Fields, "floorglowheight", value, 0.0);
s.UpdateNeeded = true;
}
}
// Update "Reset" button
resetfloorglowheight.Visible = (floorglowheight.GetResultFloat(0.0) != 0.0);
// Show height warning?
UpdateFloorGlowHeightWarning();
General.Map.IsChanged = true;
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
private void ceilingGlowEnabled_CheckedChanged(object sender, EventArgs e)
{
if (preventchanges) return;
MakeUndo();
// Update controls
ceilingglowcolor.Enabled = ceilingGlowEnabled.Checked;
ceilingglowcolor.Color = PixelColor.FromInt(0);
ceilingglowheight.Enabled = ceilingGlowEnabled.Checked;
ceilingglowheightlabel.Enabled = ceilingGlowEnabled.Checked;
if (!ceilingGlowEnabled.Checked)
{
// Set glow color to -1
foreach (Sector s in sectors)
{
UniFields.SetInteger(s.Fields, "ceilingglowcolor", -1, 0);
s.UpdateNeeded = true;
}
// Hide height warning
ceilingglowheightrequired.Visible = false;
// Trigger update
General.Map.IsChanged = true;
if (OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
else
{
// Trigger update to restore/update values
ceilingglowcolor_OnValueChanged(this, EventArgs.Empty);
}
}
private void floorGlowEnabled_CheckedChanged(object sender, EventArgs e)
{
if (preventchanges) return;
MakeUndo();
// Update controls
floorglowcolor.Enabled = floorGlowEnabled.Checked;
floorglowcolor.Color = PixelColor.FromInt(0);
floorglowheight.Enabled = floorGlowEnabled.Checked;
floorglowheightlabel.Enabled = floorGlowEnabled.Checked;
if (!floorGlowEnabled.Checked)
{
// Set glow color to -1
foreach (Sector s in sectors)
{
UniFields.SetInteger(s.Fields, "floorglowcolor", -1, 0);
s.UpdateNeeded = true;
}
// Hide height warning
floorglowheightrequired.Visible = false;
// Trigger update
General.Map.IsChanged = true;
if (OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
else
{
// Trigger glow color update to restore/update values
floorglowcolor_OnValueChanged(this, EventArgs.Empty);
}
}
private void resetceilingglowheight_Click(object sender, EventArgs e)
{
ceilingglowheight.Focus();
ceilingglowheight.Text = "0";
}
private void resetfloorglowheight_Click(object sender, EventArgs e)
{
floorglowheight.Focus();
floorglowheight.Text = "0";
}
#endregion
#region ================== D64 colors realtime events (mxd)
// generic function: use sender
private void d64color_OnValueChanged(object sender, EventArgs e)
{
if (preventchanges) return;
MakeUndo();
ColorFieldsControl colorCtl = (ColorFieldsControl)sender;
foreach (Sector s in sectors)
{
int prevv = PixelColor.INT_WHITE_NO_ALPHA;
SectorProperties props = sectorprops[s];
switch (colorCtl.Field)
{
case "color_ceiling":
prevv = props.D64ColorCeiling;
break;
case "color_walltop":
prevv = props.D64ColorWallTop;
break;
case "color_sprites":
prevv = props.D64ColorThings;
break;
case "color_wallbottom":
prevv = props.D64ColorWallBottom;
break;
case "color_floor":
prevv = props.D64ColorFloor;
break;
}
colorCtl.ApplyTo(s.Fields, prevv);
s.UpdateNeeded = true;
}
General.Map.IsChanged = true;
if (OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
}
#endregion
}
}