mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-25 21:31:14 +00:00
497 lines
No EOL
14 KiB
C#
Executable file
497 lines
No EOL
14 KiB
C#
Executable file
|
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
|
|
|
/*
|
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
|
* This program is released under GNU General Public License
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#endregion
|
|
|
|
#region ================== Namespaces
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.Types;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.Windows
|
|
{
|
|
internal partial class SectorEditForm : DelayedForm, ISectorEditForm
|
|
{
|
|
#region ================== Events
|
|
|
|
public event EventHandler OnValuesChanged; //mxd
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
private ICollection<Sector> sectors;
|
|
private List<SectorProperties> sectorprops; //mxd
|
|
private bool preventchanges; //mxd
|
|
private bool undocreated; //mxd
|
|
private bool oldmapischanged;
|
|
|
|
private struct SectorProperties //mxd
|
|
{
|
|
public readonly int Brightness;
|
|
public readonly int FloorHeight;
|
|
public readonly int CeilHeight;
|
|
public readonly string FloorTexture;
|
|
public readonly string CeilTexture;
|
|
|
|
public SectorProperties(Sector s)
|
|
{
|
|
Brightness = s.Brightness;
|
|
FloorHeight = s.FloorHeight;
|
|
CeilHeight = s.CeilHeight;
|
|
FloorTexture = s.FloorTexture;
|
|
CeilTexture = s.CeilTexture;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor
|
|
|
|
// Constructor
|
|
public SectorEditForm()
|
|
{
|
|
// Initialize
|
|
InitializeComponent();
|
|
|
|
// Fill effects list
|
|
effect.GeneralizedOptions = General.Map.Config.GenEffectOptions; //mxd
|
|
effect.AddInfo(General.Map.Config.SortedSectorEffects.ToArray());
|
|
|
|
// Initialize image selectors
|
|
floortex.Initialize();
|
|
ceilingtex.Initialize();
|
|
|
|
// Set steps for brightness field
|
|
brightness.StepValues = General.Map.Config.BrightnessLevels;
|
|
}
|
|
|
|
#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 List<SectorProperties>(); //mxd
|
|
|
|
//mxd. Set default height offset
|
|
heightoffset.Text = "0";
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Set all options to the first sector properties
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// Get first sector
|
|
Sector sc = General.GetByIndex(sectors, 0);
|
|
|
|
// 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;
|
|
|
|
// Action
|
|
tagSelector.Setup(UniversalType.SectorTag); //mxd
|
|
tagSelector.SetTag(sc.Tag);//mxd
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Now go for all sectors and change the options when a setting is different
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// Go for all sectors
|
|
foreach(Sector s in sectors)
|
|
{
|
|
// 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 = "";
|
|
}
|
|
|
|
// Action
|
|
if(s.Tag != sc.Tag) tagSelector.ClearTag(); //mxd
|
|
|
|
//mxd. Store initial properties
|
|
sectorprops.Add(new SectorProperties(s));
|
|
}
|
|
|
|
// Show sector height
|
|
UpdateSectorHeight();
|
|
|
|
preventchanges = false; //mxd
|
|
}
|
|
|
|
//mxd
|
|
private void MakeUndo()
|
|
{
|
|
if(undocreated) return;
|
|
undocreated = true;
|
|
|
|
//mxd. Make undo
|
|
General.Map.UndoRedo.CreateUndo("Edit " + (sectors.Count > 1 ? sectors.Count + " sectors" : "sector"));
|
|
}
|
|
|
|
// This updates the sector height field
|
|
private void UpdateSectorHeight()
|
|
{
|
|
int delta = 0;
|
|
int index = -1; //mxd
|
|
int i = 0; //mxd
|
|
|
|
// Check all selected sectors
|
|
foreach(Sector s in sectors)
|
|
{
|
|
if(index == -1)
|
|
{
|
|
// First sector in list
|
|
delta = s.CeilHeight - s.FloorHeight;
|
|
index = i; //mxd
|
|
}
|
|
else if(delta != (s.CeilHeight - s.FloorHeight))
|
|
{
|
|
// We can't show heights because the delta
|
|
// heights for the sectors is different
|
|
index = -1;
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
if(index > -1)
|
|
{
|
|
int fh = floorheight.GetResult(sectorprops[index].FloorHeight); //mxd
|
|
int ch = ceilingheight.GetResult(sectorprops[index].CeilHeight); //mxd
|
|
int height = ch - fh;
|
|
sectorheight.Text = height.ToString();
|
|
sectorheight.Visible = true;
|
|
sectorheightlabel.Visible = true;
|
|
}
|
|
else
|
|
{
|
|
sectorheight.Visible = false;
|
|
sectorheightlabel.Visible = false;
|
|
}
|
|
}
|
|
|
|
//mxd
|
|
private void UpdateCeilingHeight()
|
|
{
|
|
int i = 0;
|
|
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[i].CeilHeight - sectorprops[i].FloorHeight;
|
|
s.CeilHeight += offset * sign;
|
|
i++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Reset increment steps, otherwise it's just keep counting and counting
|
|
heightoffset.ResetIncrementStep();
|
|
|
|
//restore values
|
|
if (string.IsNullOrEmpty(ceilingheight.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.CeilHeight = sectorprops[i++].CeilHeight + 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.CeilHeight = ceilingheight.GetResult(sectorprops[i++].CeilHeight) + offset;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//mxd
|
|
private void UpdateFloorHeight()
|
|
{
|
|
int i = 0;
|
|
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[i].CeilHeight - sectorprops[i].FloorHeight;
|
|
s.FloorHeight += offset * sign;
|
|
i++;
|
|
}
|
|
}
|
|
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[i++].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[i++].FloorHeight) + offset;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events
|
|
|
|
// OK clicked
|
|
private void apply_Click(object sender, EventArgs e)
|
|
{
|
|
//mxd. Apply "Static" properties
|
|
// Verify the tag
|
|
tagSelector.ValidateTag(); //mxd
|
|
if((tagSelector.GetTag(0) < General.Map.FormatInterface.MinTag) || (tagSelector.GetTag(0) > General.Map.FormatInterface.MaxTag))
|
|
{
|
|
General.ShowWarningMessage("Sector tag must be between " + General.Map.FormatInterface.MinTag + " and " + General.Map.FormatInterface.MaxTag + ".", MessageBoxButtons.OK);
|
|
return;
|
|
}
|
|
|
|
// 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
|
|
int tagoffset = 0; //mxd
|
|
foreach(Sector s in sectors)
|
|
{
|
|
// Effects
|
|
if(!effect.Empty) s.Effect = effect.Value;
|
|
|
|
// Action
|
|
s.Tag = General.Clamp(tagSelector.GetSmartTag(s.Tag, tagoffset++), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag); //mxd
|
|
}
|
|
|
|
// Done
|
|
General.Map.IsChanged = true;
|
|
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty); //mxd
|
|
this.DialogResult = DialogResult.OK;
|
|
this.Close();
|
|
}
|
|
|
|
// Cancel clicked
|
|
private void cancel_Click(object sender, EventArgs e)
|
|
{
|
|
//mxd. perform undo
|
|
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();
|
|
}
|
|
|
|
// And be gone
|
|
this.DialogResult = DialogResult.Cancel;
|
|
this.Close();
|
|
}
|
|
|
|
|
|
// Browse Effect clicked
|
|
private void browseeffect_Click(object sender, EventArgs e)
|
|
{
|
|
effect.Value = EffectBrowserForm.BrowseEffect(this, effect.Value);
|
|
}
|
|
|
|
// Help
|
|
private void SectorEditForm_HelpRequested(object sender, HelpEventArgs hlpevent)
|
|
{
|
|
General.ShowHelp("w_sectoredit.html");
|
|
hlpevent.Handled = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== mxd. Realtime Events
|
|
|
|
// Ceiling height changes
|
|
private void ceilingheight_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
MakeUndo(); //mxd
|
|
|
|
UpdateCeilingHeight();
|
|
UpdateSectorHeight();
|
|
|
|
General.Map.IsChanged = true;
|
|
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
|
|
}
|
|
|
|
// Floor height changes
|
|
private void floorheight_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
MakeUndo(); //mxd
|
|
|
|
UpdateFloorHeight();
|
|
UpdateSectorHeight();
|
|
|
|
General.Map.IsChanged = true;
|
|
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
|
|
}
|
|
|
|
// Height offset changes
|
|
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 floortex_OnValueChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
MakeUndo(); //mxd
|
|
|
|
//restore values
|
|
if(string.IsNullOrEmpty(floortex.TextureName))
|
|
{
|
|
int i = 0;
|
|
foreach(Sector s in sectors) s.SetFloorTexture(sectorprops[i++].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 ceilingtex_OnValueChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
MakeUndo(); //mxd
|
|
|
|
//restore values
|
|
if(string.IsNullOrEmpty(ceilingtex.TextureName))
|
|
{
|
|
int i = 0;
|
|
foreach(Sector s in sectors) s.SetCeilTexture(sectorprops[i++].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 brightness_WhenTextChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
MakeUndo(); //mxd
|
|
int i = 0;
|
|
|
|
//restore values
|
|
if(string.IsNullOrEmpty(brightness.Text))
|
|
{
|
|
foreach(Sector s in sectors) s.Brightness = sectorprops[i++].Brightness;
|
|
|
|
}
|
|
else //update values
|
|
{
|
|
foreach(Sector s in sectors)
|
|
s.Brightness = General.Clamp(brightness.GetResult(sectorprops[i++].Brightness), General.Map.FormatInterface.MinBrightness, General.Map.FormatInterface.MaxBrightness);
|
|
}
|
|
|
|
General.Map.IsChanged = true;
|
|
if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
} |