mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2024-11-14 16:41:26 +00:00
362 lines
No EOL
11 KiB
C#
362 lines
No EOL
11 KiB
C#
|
|
#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.Config;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.Types;
|
|
|
|
#endregion
|
|
|
|
//JBR A little more advanced version of ThingBrowserForm
|
|
namespace CodeImp.DoomBuilder.Windows
|
|
{
|
|
/// <summary>
|
|
/// Dialog window that allows setting up Thing properties.
|
|
/// </summary>
|
|
public partial class ThingBrowser2Form : DelayedForm
|
|
{
|
|
#region ================== Properties
|
|
|
|
public int SelectedType { get { return s_thingType; } }
|
|
public int SelectedParameter { get { return s_parameter; } }
|
|
public Dictionary<string, bool> SelectedFlags { get { return s_flags; } } // oh no... not read-only at all but atleast it's fast.
|
|
public float SelectedAngleDoom { get { return s_angleDoom; } }
|
|
public float SelectedPosZ { get { return s_posZ; } }
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
private bool m_ok;
|
|
private static int s_thingType = 1;
|
|
private static int s_parameter = 0;
|
|
private static Dictionary<string, bool> s_flags = new Dictionary<string, bool>();
|
|
private static int s_angleDoom = 0;
|
|
private static float s_posZ = 0f;
|
|
|
|
private ThingTypeInfo thinginfo;
|
|
private bool preventchanges;
|
|
private bool flagsvalue_ignore = false;
|
|
private bool flags_ignore = false;
|
|
|
|
//JBR Hold result
|
|
public struct Result
|
|
{
|
|
public readonly bool OK;
|
|
public readonly int Type;
|
|
public readonly int Parameter;
|
|
public readonly Dictionary<string, bool> Flags;
|
|
public readonly int AngleDoom;
|
|
public readonly float Z;
|
|
|
|
public Result(bool ok, int type, int parameter, Dictionary<string, bool> flags, int angledoom, float z)
|
|
{
|
|
this.OK = ok;
|
|
this.Type = type;
|
|
this.Parameter = parameter;
|
|
this.Flags = flags;
|
|
this.AngleDoom = angledoom;
|
|
this.Z = z;
|
|
}
|
|
|
|
public void Apply(Thing t)
|
|
{
|
|
t.SRB2Type = this.Type;
|
|
t.Parameter = this.Parameter;
|
|
foreach (KeyValuePair<string, bool> flag in this.Flags)
|
|
{
|
|
t.SetFlag(flag.Key, flag.Value);
|
|
}
|
|
t.Move(t.Position.x, t.Position.y, this.Z);
|
|
t.Rotate(this.AngleDoom);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor
|
|
|
|
// Constructor
|
|
public ThingBrowser2Form()
|
|
{
|
|
// Initialize
|
|
InitializeComponent();
|
|
m_ok = false;
|
|
|
|
preventchanges = true;
|
|
|
|
// Fill flags list
|
|
foreach(KeyValuePair<string, string> tf in General.Map.Config.ThingFlags)
|
|
flags.Add(tf.Value, tf.Key);
|
|
|
|
// Thing height?
|
|
posZ.Visible = General.Map.FormatInterface.HasThingHeight;
|
|
zlabel.Visible = General.Map.FormatInterface.HasThingHeight;
|
|
|
|
//mxd. Decimals allowed?
|
|
if(General.Map.FormatInterface.VertexDecimals > 0)
|
|
{
|
|
posZ.AllowDecimal = true;
|
|
}
|
|
|
|
// Setup types list
|
|
thingslist.Setup();
|
|
|
|
// Set type
|
|
thingslist.SelectType(s_thingType, s_parameter);
|
|
|
|
// Flags
|
|
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(s_thingType);
|
|
IDictionary<string, string> newFlags = (ti == null || ti.Flags.Count == 0) ? General.Map.Config.ThingFlags : ti.Flags;
|
|
flags.UpdateCheckboxes(newFlags, General.Map.Config.ThingFlags);
|
|
anglelabel.Text = (ti == null) ? "Angle:" : ti.AngleText + ":";
|
|
flagsvallabel.Text = (ti == null) ? "Flags value:" : ti.FlagsValueText + ":";
|
|
foreach (CheckBox c in flags.Checkboxes)
|
|
if (s_flags.ContainsKey(c.Tag.ToString())) c.Checked = s_flags[c.Tag.ToString()];
|
|
|
|
// Coordination
|
|
angle.Text = s_angleDoom.ToString();
|
|
|
|
// Z Position
|
|
posZ.Text = s_posZ.ToString();
|
|
posZ.AllowNegative = General.Map.FormatInterface.MinThingHeight < 0;
|
|
|
|
// Update...
|
|
flags.UpdateCheckboxes(newFlags, General.Map.Config.ThingFlags);
|
|
if (ti != null)
|
|
{
|
|
flagsvallabel.Text = ti.FlagsValueText + ":";
|
|
}
|
|
|
|
preventchanges = false;
|
|
|
|
angle_WhenTextChanged(angle, EventArgs.Empty);
|
|
flags_OnValueChanged(flags, EventArgs.Empty);
|
|
flagsvalue.Text = evaluateFlagsValue();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Methods
|
|
|
|
private string evaluateFlagsValue()
|
|
{
|
|
int i = 1;
|
|
int value = 0;
|
|
foreach (CheckBox box in flags.Checkboxes)
|
|
{
|
|
if (box.CheckState == CheckState.Indeterminate) return "";
|
|
if (box.CheckState == CheckState.Checked) value += i;
|
|
i *= 2;
|
|
}
|
|
|
|
if (General.Map.SRB2)
|
|
{
|
|
float z = posZ.GetResultFloat(s_posZ);
|
|
return (value + ((int)z << 4)).ToString();
|
|
}
|
|
else return value.ToString();
|
|
}
|
|
|
|
public Result GetThingResult()
|
|
{
|
|
return new Result(m_ok, s_thingType, s_parameter, s_flags, s_angleDoom, s_posZ);
|
|
}
|
|
|
|
// This browses for a thing type
|
|
// Returns the new thing type or the same thing type when cancelled
|
|
public static Result BrowseThing(IWin32Window owner)
|
|
{
|
|
ThingBrowser2Form f = new ThingBrowser2Form();
|
|
DialogResult result = f.ShowDialog(owner);
|
|
Result tr = f.GetThingResult();
|
|
f.Dispose();
|
|
return tr;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events
|
|
|
|
//mxd
|
|
private void thingtype_OnTypeDoubleClicked()
|
|
{
|
|
apply_Click(this, EventArgs.Empty);
|
|
}
|
|
|
|
// Angle text changes
|
|
private void angle_WhenTextChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
preventchanges = true;
|
|
anglecontrol.Angle = angle.GetResult(GZBuilder.Controls.AngleControl.NO_ANGLE);
|
|
preventchanges = false;
|
|
}
|
|
|
|
//mxd. Angle control clicked
|
|
private void anglecontrol_AngleChanged(object sender, EventArgs e)
|
|
{
|
|
if(preventchanges) return;
|
|
angle.Text = anglecontrol.Angle.ToString();
|
|
}
|
|
|
|
// Apply clicked
|
|
private void apply_Click(object sender, EventArgs e)
|
|
{
|
|
List<string> defaultflags = new List<string>();
|
|
|
|
// Verify the type
|
|
if(((thingslist.GetFullType(0) < General.Map.FormatInterface.MinThingType) || (thingslist.GetFullType(0) > General.Map.FormatInterface.MaxThingType)))
|
|
{
|
|
General.ShowWarningMessage("Thing type must be between " + General.Map.FormatInterface.MinThingType + " and " + General.Map.FormatInterface.MaxThingType + ".", MessageBoxButtons.OK);
|
|
return;
|
|
}
|
|
|
|
// Apply all flags
|
|
s_thingType = thingslist.GetResult(s_thingType);
|
|
s_parameter = thingslist.GetFullType(s_thingType) / 4096;
|
|
s_angleDoom = angle.GetResult(s_angleDoom);
|
|
s_posZ = posZ.GetResultFloat(s_posZ);
|
|
s_flags = new Dictionary<string, bool>();
|
|
foreach (CheckBox c in flags.Checkboxes)
|
|
{
|
|
s_flags.Add(c.Tag.ToString(), c.Checked);
|
|
}
|
|
m_ok = true;
|
|
|
|
// Done
|
|
this.DialogResult = DialogResult.OK;
|
|
this.Close();
|
|
}
|
|
|
|
// Cancel clicked
|
|
private void cancel_Click(object sender, EventArgs e)
|
|
{
|
|
// Be gone
|
|
this.DialogResult = DialogResult.Cancel;
|
|
this.Close();
|
|
}
|
|
|
|
//mxd
|
|
private void ThingBrowserAdvForm_Shown(object sender, EventArgs e)
|
|
{
|
|
thingslist.FocusTextbox();
|
|
}
|
|
|
|
// Help
|
|
private void ThingBrowserAdvForm_HelpRequested(object sender, HelpEventArgs hlpevent)
|
|
{
|
|
General.ShowHelp("w_thingedit.html");
|
|
hlpevent.Handled = true;
|
|
}
|
|
|
|
private void posZ_WhenTextChanged(object sender, EventArgs e)
|
|
{
|
|
if (preventchanges) return;
|
|
if (!flagsvalue_ignore)
|
|
{
|
|
flagsvalue_ignore = true;
|
|
flagsvalue.Text = evaluateFlagsValue();
|
|
flagsvalue_ignore = false;
|
|
}
|
|
}
|
|
|
|
private void flagsvalue_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (!flagsvalue_ignore && !string.IsNullOrEmpty(flagsvalue.Text))
|
|
{
|
|
flagsvalue_ignore = true;
|
|
int value = General.Clamp(flagsvalue.GetResult(0), 0, 0xFFFF);
|
|
int i = 1;
|
|
flags_ignore = true;
|
|
foreach (CheckBox box in flags.Checkboxes)
|
|
{
|
|
box.Checked = ((value & i) == i);
|
|
i *= 2;
|
|
}
|
|
flags_ignore = false;
|
|
flags_OnValueChanged(this, null);
|
|
|
|
if (General.Map.SRB2)
|
|
{
|
|
int z = value >> 4;
|
|
posZ.Text = z.ToString();
|
|
}
|
|
flagsvalue_ignore = false;
|
|
}
|
|
}
|
|
|
|
// Selected type changes
|
|
private void thingtype_OnTypeChanged(ThingTypeInfo value)
|
|
{
|
|
thinginfo = value;
|
|
|
|
//mxd. Update things
|
|
if(preventchanges) return;
|
|
|
|
if(((thingslist.GetResult(0) < General.Map.FormatInterface.MinThingType) || (thingslist.GetResult(0) > General.Map.FormatInterface.MaxThingType)))
|
|
return;
|
|
|
|
IDictionary<string, string> newFlags = (thinginfo == null || thinginfo.Flags.Count == 0) ? General.Map.Config.ThingFlags : thinginfo.Flags;
|
|
flags.UpdateCheckboxes(newFlags, General.Map.Config.ThingFlags);
|
|
anglelabel.Text = (thinginfo == null) ? "Angle:" : thinginfo.AngleText + ":";
|
|
flagsvallabel.Text = (thinginfo == null) ? "Flags value:" : thinginfo.FlagsValueText + ":";
|
|
}
|
|
|
|
//mxd
|
|
private void flags_OnValueChanged(object sender, EventArgs e)
|
|
{
|
|
if(flags_ignore || preventchanges) return;
|
|
|
|
// Gather enabled flags
|
|
HashSet<string> activeflags = new HashSet<string>();
|
|
foreach(CheckBox cb in flags.Checkboxes)
|
|
{
|
|
if(cb.CheckState != CheckState.Unchecked) activeflags.Add(cb.Tag.ToString());
|
|
}
|
|
|
|
// Check em
|
|
List<string> warnings = ThingFlagsCompare.CheckFlags(activeflags);
|
|
if(warnings.Count > 0)
|
|
{
|
|
//got missing flags
|
|
tooltip.SetToolTip(missingflags, string.Join(Environment.NewLine, warnings.ToArray()));
|
|
missingflags.Visible = true;
|
|
settingsgroup.ForeColor = Color.DarkRed;
|
|
return;
|
|
}
|
|
|
|
//everything is OK
|
|
missingflags.Visible = false;
|
|
settingsgroup.ForeColor = SystemColors.ControlText;
|
|
if (!flagsvalue_ignore)
|
|
{
|
|
flagsvalue_ignore = true;
|
|
flagsvalue.Text = evaluateFlagsValue();
|
|
flagsvalue_ignore = false;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |