UltimateZoneBuilder/Source/Core/Windows/ThingEditForm.cs
MaxED 16b97e1c83 Added GLDEFS and (Z)MAPINFO parsers.
Dynamic lights defined in GLDEFS are now rendered in Visual modes (currently only one light per Thing is supported).
Several values from (Z)MAPINFO are now used in Visual modes.
Added "Reload GLDEFS", "Reload (Z)MAPINFO" and "Reload MODELDEF" menu options (in "Tools" section).
MODELDEF parser now checks which model(s) is/are used in first frame.
Dynamic lights are now created with more meaningful default parameters.
Added errors and warnings indicator to main window.
2012-06-01 10:17:47 +00:00

387 lines
No EOL
12 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.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.IO;
using System.IO;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.GZBuilder.Data;
#endregion
namespace CodeImp.DoomBuilder.Windows
{
/// <summary>
/// Dialog window that allows viewing and editing of Thing properties.
/// </summary>
public partial class ThingEditForm : DelayedForm
{
#region ================== Variables
private ICollection<Thing> things;
private List<TreeNode> nodes;
private ThingTypeInfo thinginfo;
private bool preventchanges = false;
#endregion
#region ================== Properties
#endregion
#region ================== Constructor
// Constructor
public ThingEditForm()
{
// Initialize
InitializeComponent();
// Fill flags list
foreach(KeyValuePair<string, string> tf in General.Map.Config.ThingFlags)
flags.Add(tf.Value, tf.Key);
// Fill actions list
action.GeneralizedCategories = General.Map.Config.GenActionCategories;
action.AddInfo(General.Map.Config.SortedLinedefActions.ToArray());
// Fill universal fields list
fieldslist.ListFixedFields(General.Map.Config.ThingFields);
// Initialize custom fields editor
fieldslist.Setup("thing");
// Custom fields?
if(!General.Map.FormatInterface.HasCustomFields)
tabs.TabPages.Remove(tabcustom);
// Tag/Effects?
if(!General.Map.FormatInterface.HasThingAction && !General.Map.FormatInterface.HasThingTag)
tabs.TabPages.Remove(tabeffects);
// Thing height?
height.Visible = General.Map.FormatInterface.HasThingHeight;
heightlabel.Visible = General.Map.FormatInterface.HasThingHeight;
// Setup types list
thingtype.Setup();
}
// This sets up the form to edit the given things
public void Setup(ICollection<Thing> things)
{
Thing ft;
preventchanges = true;
// Keep this list
this.things = things;
if(things.Count > 1) this.Text = "Edit Things (" + things.Count + ")";
////////////////////////////////////////////////////////////////////////
// Set all options to the first thing properties
////////////////////////////////////////////////////////////////////////
ft = General.GetByIndex(things, 0);
// Set type
thingtype.SelectType(ft.Type);
// Flags
foreach(CheckBox c in flags.Checkboxes)
if(ft.Flags.ContainsKey(c.Tag.ToString())) c.Checked = ft.Flags[c.Tag.ToString()];
// Coordination
angle.Text = ft.AngleDoom.ToString();
height.Text = ((int)ft.Position.z).ToString();
// Action/tags
action.Value = ft.Action;
tag.Text = ft.Tag.ToString();
arg0.SetValue(ft.Args[0]);
arg1.SetValue(ft.Args[1]);
arg2.SetValue(ft.Args[2]);
arg3.SetValue(ft.Args[3]);
arg4.SetValue(ft.Args[4]);
// Custom fields
fieldslist.SetValues(ft.Fields, true);
////////////////////////////////////////////////////////////////////////
// Now go for all lines and change the options when a setting is different
////////////////////////////////////////////////////////////////////////
// Go for all things
foreach(Thing t in things)
{
// Type does not match?
if((thingtype.GetSelectedInfo() != null) &&
(thingtype.GetSelectedInfo().Index != t.Type))
thingtype.ClearSelectedType();
// Flags
foreach(CheckBox c in flags.Checkboxes)
{
if(t.Flags.ContainsKey(c.Tag.ToString()))
{
if(t.Flags[c.Tag.ToString()] != c.Checked)
{
c.ThreeState = true;
c.CheckState = CheckState.Indeterminate;
}
}
}
// Coordination
if(t.AngleDoom.ToString() != angle.Text) angle.Text = "";
if(((int)t.Position.z).ToString() != height.Text) height.Text = "";
// Action/tags
if(t.Action != action.Value) action.Empty = true;
if(t.Tag.ToString() != tag.Text) tag.Text = "";
if(t.Args[0] != arg0.GetResult(-1)) arg0.ClearValue();
if(t.Args[1] != arg1.GetResult(-1)) arg1.ClearValue();
if(t.Args[2] != arg2.GetResult(-1)) arg2.ClearValue();
if(t.Args[3] != arg3.GetResult(-1)) arg3.ClearValue();
if(t.Args[4] != arg4.GetResult(-1)) arg4.ClearValue();
// Custom fields
fieldslist.SetValues(t.Fields, false);
}
preventchanges = false;
}
#endregion
#region ================== Interface
// This finds a new (unused) tag
private void newtag_Click(object sender, EventArgs e)
{
tag.Text = General.Map.Map.GetNewTag().ToString();
}
// Selected type changes
private void thingtype_OnTypeChanged(ThingTypeInfo value)
{
thinginfo = value;
// Update preview image
if(thinginfo != null)
{
if(thinginfo.Sprite.ToLowerInvariant().StartsWith(DataManager.INTERNAL_PREFIX) &&
(thinginfo.Sprite.Length > DataManager.INTERNAL_PREFIX.Length))
{
General.DisplayZoomedImage(spritetex, General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetBitmap());
}
else if((thinginfo.Sprite.Length <= 8) && (thinginfo.Sprite.Length > 0))
{
General.DisplayZoomedImage(spritetex, General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetPreview());
}
else
{
spritetex.BackgroundImage = null;
}
}
else
{
spritetex.BackgroundImage = null;
}
// Update arguments
action_ValueChanges(this, EventArgs.Empty);
}
// Action changes
private void action_ValueChanges(object sender, EventArgs e)
{
int showaction = 0;
ArgumentInfo[] arginfo;
// Only when line type is known, otherwise use the thing arguments
if(General.Map.Config.LinedefActions.ContainsKey(action.Value)) showaction = action.Value;
if((showaction == 0) && (thinginfo != null)) arginfo = thinginfo.Args; else arginfo = General.Map.Config.LinedefActions[showaction].Args;
// Change the argument descriptions
arg0label.Text = arginfo[0].Title + ":";
arg1label.Text = arginfo[1].Title + ":";
arg2label.Text = arginfo[2].Title + ":";
arg3label.Text = arginfo[3].Title + ":";
arg4label.Text = arginfo[4].Title + ":";
arg0label.Enabled = arginfo[0].Used;
arg1label.Enabled = arginfo[1].Used;
arg2label.Enabled = arginfo[2].Used;
arg3label.Enabled = arginfo[3].Used;
arg4label.Enabled = arginfo[4].Used;
if(arg0label.Enabled) arg0.ForeColor = SystemColors.WindowText; else arg0.ForeColor = SystemColors.GrayText;
if(arg1label.Enabled) arg1.ForeColor = SystemColors.WindowText; else arg1.ForeColor = SystemColors.GrayText;
if(arg2label.Enabled) arg2.ForeColor = SystemColors.WindowText; else arg2.ForeColor = SystemColors.GrayText;
if(arg3label.Enabled) arg3.ForeColor = SystemColors.WindowText; else arg3.ForeColor = SystemColors.GrayText;
if(arg4label.Enabled) arg4.ForeColor = SystemColors.WindowText; else arg4.ForeColor = SystemColors.GrayText;
arg0.Setup(arginfo[0]);
arg1.Setup(arginfo[1]);
arg2.Setup(arginfo[2]);
arg3.Setup(arginfo[3]);
arg4.Setup(arginfo[4]);
// Zero all arguments when linedef action 0 (normal) is chosen
if(!preventchanges && (showaction == 0))
{
//mxd. If thing is light, set default light settings
int[] args = GZDoomLight.GetDefaultLightSettings(thingtype.GetResult(1));
if (args != null) {
arg0.SetValue(args[0]);
arg1.SetValue(args[1]);
arg2.SetValue(args[2]);
arg3.SetValue(args[3]);
arg4.SetValue(args[4]);
} else {
arg0.SetValue(0);
arg1.SetValue(0);
arg2.SetValue(0);
arg3.SetValue(0);
arg4.SetValue(0);
}
}
}
// Browse Action clicked
private void browseaction_Click(object sender, EventArgs e)
{
action.Value = ActionBrowserForm.BrowseAction(this, action.Value);
}
// Angle text changes
private void angle_TextChanged(object sender, EventArgs e)
{
anglecontrol.Value = angle.GetResult(int.MinValue);
}
// Angle control clicked
private void anglecontrol_ButtonClicked(object sender, EventArgs e)
{
angle.Text = anglecontrol.Value.ToString();
}
// 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;
this.DialogResult = DialogResult.OK;
this.Close();
}
// Cancel clicked
private void cancel_Click(object sender, EventArgs e)
{
// Be gone
this.DialogResult = DialogResult.Cancel;
this.Close();
}
// Help
private void ThingEditForm_HelpRequested(object sender, HelpEventArgs hlpevent)
{
General.ShowHelp("w_thingeditor.html");
hlpevent.Handled = true;
}
#endregion
}
}