Added, Edit Things window, UDMF: added basic User Variable support. User variables are now automatically shown in the "Custom" tab, are marked with different color and are applied only to actors, which define them.

Fixed, Script Editor: auto-complete can now show the same term several times when it's case is different (like DECORATE's "Bright" keyword and "BRIGHT" flag).
Game configurations, ZDoom: updated "Scroll_Floor" and "Scroll_Ceiling" linedef action argument definitions.
Updated ZDoom_ACS.cfg (Ceiling_CrushAndRaiseSilentDist).
Updated ZDoom_DECORATE.cfg (A_SetChaseThreshold).
This commit is contained in:
MaxED 2016-02-08 21:51:03 +00:00
parent bd56f1db22
commit edcfbb0668
35 changed files with 558 additions and 173 deletions

View file

@ -2982,22 +2982,24 @@ zdoom
type = 11; type = 11;
enum enum
{ {
1 = "Texture only"; 0 = "Texture only";
2 = "Things only"; 1 = "Things only";
4 = "Both"; 2 = "Both";
} }
} }
arg3 arg3
{ {
title = "Horizontal Speed"; title = "Horizontal Speed";
default = 128;
type = 11; type = 11;
enum = "scroll_speeds"; enum = "sector_scroll_speeds_x";
} }
arg4 arg4
{ {
title = "Vertical Speed"; title = "Vertical Speed";
default = 128;
type = 11; type = 11;
enum = "scroll_speeds"; enum = "sector_scroll_speeds_y";
} }
} }
224 224
@ -3025,14 +3027,16 @@ zdoom
arg3 arg3
{ {
title = "Horizontal Speed"; title = "Horizontal Speed";
default = 128;
type = 11; type = 11;
enum = "scroll_speeds"; enum = "sector_scroll_speeds_x";
} }
arg4 arg4
{ {
title = "Vertical Speed"; title = "Vertical Speed";
default = 128;
type = 11; type = 11;
enum = "scroll_speeds"; enum = "sector_scroll_speeds_y";
} }
} }
225 225

View file

@ -661,6 +661,36 @@ enums
128 = "128: Very fast"; 128 = "128: Very fast";
} }
sector_scroll_speeds_x
{
0 = "0: West very fast";
16 = "16: West fast";
32 = "32: West normal";
64 = "64: West slow";
96 = "96: West very slow";
128 = "128: Don't scroll";
160 = "144: East very slow";
192 = "160: East slow";
224 = "176: East normal";
240 = "192: East fast";
256 = "256: East very fast";
}
sector_scroll_speeds_y
{
0 = "0: South very fast";
16 = "16: South fast";
32 = "32: South normal";
64 = "64: South slow";
96 = "96: South very slow";
128 = "128: Don't scroll";
160 = "144: North very slow";
192 = "160: North slow";
224 = "176: North normal";
240 = "192: North fast";
256 = "256: North very fast";
}
stair_speeds stair_speeds
{ {
2 = "2: Slow"; 2 = "2: Slow";

View file

@ -72,6 +72,7 @@ keywords
Ceiling_CrushAndRaiseA = "Ceiling_CrushAndRaiseA(tag, dspeed, uspeed, crush, crushmode)"; Ceiling_CrushAndRaiseA = "Ceiling_CrushAndRaiseA(tag, dspeed, uspeed, crush, crushmode)";
Ceiling_CrushAndRaiseDist = "Ceiling_CrushAndRaiseDist(tag, dist, speed, damage, crushmode)"; Ceiling_CrushAndRaiseDist = "Ceiling_CrushAndRaiseDist(tag, dist, speed, damage, crushmode)";
Ceiling_CrushAndRaiseSilentA = "Ceiling_CrushAndRaiseSilentA(tag, dspeed, uspeed, crush, crushmode)"; Ceiling_CrushAndRaiseSilentA = "Ceiling_CrushAndRaiseSilentA(tag, dspeed, uspeed, crush, crushmode)";
Ceiling_CrushAndRaiseSilentDist = "Ceiling_CrushAndRaiseSilentDist(tag, dist, speed, damage[, crushmode])";
Ceiling_CrushRaiseAndStay = "Ceiling_CrushRaiseAndStay(tag, speed, crush, crushmode)"; Ceiling_CrushRaiseAndStay = "Ceiling_CrushRaiseAndStay(tag, speed, crush, crushmode)";
Ceiling_CrushRaiseAndStayA = "Ceiling_CrushRaiseAndStayA(tag, dspeed, uspeed, crush, crushmode)"; Ceiling_CrushRaiseAndStayA = "Ceiling_CrushRaiseAndStayA(tag, dspeed, uspeed, crush, crushmode)";
Ceiling_CrushRaiseAndStaySilA = "Ceiling_CrushRaiseAndStaySilA(tag, dspeed, uspeed, crush, crushmode)"; Ceiling_CrushRaiseAndStaySilA = "Ceiling_CrushRaiseAndStaySilA(tag, dspeed, uspeed, crush, crushmode)";
@ -91,8 +92,8 @@ keywords
Ceiling_RaiseInstant = "Ceiling_RaiseInstant(tag, unused, height)"; Ceiling_RaiseInstant = "Ceiling_RaiseInstant(tag, unused, height)";
Ceiling_RaiseToNearest = "Ceiling_RaiseToNearest(tag, speed)"; Ceiling_RaiseToNearest = "Ceiling_RaiseToNearest(tag, speed)";
Ceiling_Waggle = "Ceiling_Waggle(tag, amp, freq, offset, time)"; Ceiling_Waggle = "Ceiling_Waggle(tag, amp, freq, offset, time)";
ChangeActorAngle = "ChangeActorAngle(int tid, fixed angle[, bool interpolate = false])\nSets the angle for the actors with the specified tid.\nIf tid is 0, it sets the angle for the activator of the script.\nangle: a fixed point angle in the range of 0.0 to 1.0 (N = 0.25, W = 0.5, S = 0.75, E = 1.0)."; ChangeActorAngle = "void ChangeActorAngle(int tid, fixed angle[, bool interpolate = false])\nSets the angle for the actors with the specified tid.\nIf tid is 0, it sets the angle for the activator of the script.\nangle: a fixed point angle in the range of 0.0 to 1.0 (N = 0.25, W = 0.5, S = 0.75, E = 1.0).";
ChangeActorPitch = "ChangeActorPitch(int tid, fixed pitch[, bool interpolate = false])\nSets the pitch for the actors with the specified tid. If tid is 0, it sets the pitch for the activator of the script.\npitch: a fixed point angle in the range of 0.0 to 1.0."; ChangeActorPitch = "void ChangeActorPitch(int tid, fixed pitch[, bool interpolate = false])\nSets the pitch for the actors with the specified tid. If tid is 0, it sets the pitch for the activator of the script.\npitch: a fixed point angle in the range of 0.0 to 1.0.";
ChangeActorRoll = "void ChangeActorRoll(int tid, fixed angle[, bool interpolate = false])"; ChangeActorRoll = "void ChangeActorRoll(int tid, fixed angle[, bool interpolate = false])";
ChangeCamera = "ChangeCamera(tid, who, revert)"; ChangeCamera = "ChangeCamera(tid, who, revert)";
ChangeCeiling = "void ChangeCeiling(int tag, str flatname)"; ChangeCeiling = "void ChangeCeiling(int tag, str flatname)";

View file

@ -178,6 +178,7 @@ keywords
A_ScreamAndUnblock = "A_ScreamAndUnblock"; A_ScreamAndUnblock = "A_ScreamAndUnblock";
A_SetAngle = "A_SetAngle(float angle[, int flags = 0[, int pointer = AAPTR_DEFAULT]])\nangle: the actor's new angle, in degrees.\nflags: SPF flags."; A_SetAngle = "A_SetAngle(float angle[, int flags = 0[, int pointer = AAPTR_DEFAULT]])\nangle: the actor's new angle, in degrees.\nflags: SPF flags.";
A_SetArg = "A_SetArg(int position, int value)"; A_SetArg = "A_SetArg(int position, int value)";
A_SetChaseThreshold = "A_SetChaseThreshold(int threshold[, bool setdefaultthreshhold = false[, int pointer = AAPTR_DEFAULT]])";
A_SetDamageType = "A_SetDamageType(str damagetype)"; A_SetDamageType = "A_SetDamageType(str damagetype)";
A_SetFloat = "A_SetFloat"; A_SetFloat = "A_SetFloat";
A_SetFloatSpeed = "A_SetFloatSpeed(float speed[, int pointer = AAPTR_DEFAULT])"; A_SetFloatSpeed = "A_SetFloatSpeed(float speed[, int pointer = AAPTR_DEFAULT])";
@ -347,14 +348,9 @@ keywords
frandom = "frandom[identifier](min, max)\nReturns a random floating point value between min and max."; frandom = "frandom[identifier](min, max)\nReturns a random floating point value between min and max.";
randompick = "randompick[identifier](int, ...)\nPicks a number from the numbers placed in it.\nThis can take an unlimited amount of parameters."; randompick = "randompick[identifier](int, ...)\nPicks a number from the numbers placed in it.\nThis can take an unlimited amount of parameters.";
frandompick = "frandompick[identifier](int, ...)\nSimilar to randompick but for float-point values."; frandompick = "frandompick[identifier](int, ...)\nSimilar to randompick but for float-point values.";
//State keywords //State functions
//Bright = "Bright";
CanRaise = "CanRaise";
Fast = "Fast";
Light = "Light(str lightname)"; Light = "Light(str lightname)";
NoDelay = "NoDelay";
Offset = "Offset(int x, int y)"; Offset = "Offset(int x, int y)";
Slow = "Slow";
//Special functions //Special functions
CheckClass = "bool CheckClass(str classname[, int ptr_select = AAPTR_DEFAULT[, bool match_superclass = false]])"; CheckClass = "bool CheckClass(str classname[, int ptr_select = AAPTR_DEFAULT[, bool match_superclass = false]])";
IsPointerEqual = "bool IsPointerEqual(int ptr_select1, int ptr_select2)"; IsPointerEqual = "bool IsPointerEqual(int ptr_select1, int ptr_select2)";
@ -363,6 +359,11 @@ keywords
properties properties
{ {
Actor; Actor;
enum;
const;
var;
int;
float;
//WFDS //WFDS
if; if;
else; else;
@ -373,7 +374,13 @@ properties
Wait; Wait;
Fail; Fail;
goto; goto;
//states: //State keywords
Bright;
CanRaise;
Fast;
Slow;
NoDelay;
//States
States; States;
Spawn:; Spawn:;
Idle:; Idle:;
@ -452,6 +459,8 @@ properties
Activation; Activation;
TeleFogSourceType; TeleFogSourceType;
TeleFogDestType; TeleFogDestType;
Threshold;
DefThreshold;
//Collision and 'Physics' //Collision and 'Physics'
Radius; Radius;
Height; Height;

View file

@ -242,7 +242,7 @@ namespace CodeImp.DoomBuilder.Controls
//mxd. this sets default value //mxd. this sets default value
public void SetDefaultValue() public void SetDefaultValue()
{ {
typehandler.SetDefaultValue(); typehandler.ApplyDefaultValue();
combobox.SelectedItem = null; combobox.SelectedItem = null;
combobox.Text = typehandler.GetStringValue(); combobox.Text = typehandler.GetStringValue();
combobox_Validating(this, new CancelEventArgs()); combobox_Validating(this, new CancelEventArgs());

View file

@ -171,6 +171,7 @@ namespace CodeImp.DoomBuilder.Controls
// Go for all rows // Go for all rows
bool foundrow = false; bool foundrow = false;
bool skiprow = false; //mxd
foreach(DataGridViewRow row in fieldslist.Rows) foreach(DataGridViewRow row in fieldslist.Rows)
{ {
// Row is a field? // Row is a field?
@ -181,11 +182,18 @@ namespace CodeImp.DoomBuilder.Controls
// Row name matches with field // Row name matches with field
if(frow.Name == f.Key) if(frow.Name == f.Key)
{ {
//mxd. User vars are set separately
if(frow.RowType == FieldsEditorRowType.USERVAR)
{
skiprow = true;
break;
}
// First time? // First time?
if(first) if(first)
{ {
// Set type when row is not fixed // Set type when row is not fixed
if(!frow.IsFixed) frow.ChangeType(f.Value.Type); if(frow.RowType == FieldsEditorRowType.DYNAMIC) frow.ChangeType(f.Value.Type);
// Apply value of field to row // Apply value of field to row
frow.Define(f.Value.Value); frow.Define(f.Value.Value);
@ -208,15 +216,17 @@ namespace CodeImp.DoomBuilder.Controls
} }
} }
//mxd. User vars are set separately
if(skiprow) continue;
// Row not found? // Row not found?
if(!foundrow) if(!foundrow)
{ {
// Make new row // Make new row
FieldsEditorRow frow = new FieldsEditorRow(fieldslist, f.Key, f.Value.Type, f.Value.Value); FieldsEditorRow frow = new FieldsEditorRow(fieldslist, f.Key, f.Value.Type, f.Value.Value, false);
fieldslist.Rows.Insert(fieldslist.Rows.Count - 1, frow); fieldslist.Rows.Insert(fieldslist.Rows.Count - 1, frow);
// When not the first, clear the field // When not the first, clear the field because the others did not define this one
// because the others did not define this one
if(!first) frow.Clear(); if(!first) frow.Clear();
} }
} }
@ -246,6 +256,82 @@ namespace CodeImp.DoomBuilder.Controls
Sort(); Sort();
} }
//mxd
public void SetUserVars(Dictionary<string, UniversalType> vars, UniFields fromfields, bool first)
{
foreach(KeyValuePair<string, UniversalType> group in vars)
{
// Go for all rows
bool foundrow = false;
TypeHandler vartype = General.Types.GetFieldHandler((int)group.Value, 0);
object value = fromfields.ContainsKey(group.Key) ? fromfields[group.Key].Value : vartype.GetDefaultValue();
foreach(DataGridViewRow row in fieldslist.Rows)
{
// Row is a field?
if(row is FieldsEditorRow)
{
FieldsEditorRow frow = row as FieldsEditorRow;
// Row name matches with user var?
if(frow.RowType == FieldsEditorRowType.USERVAR && frow.Name == group.Key)
{
// First time?
if(first)
{
frow.Define(value);
}
// Check if the value is different
else if(!frow.TypeHandler.GetValue().Equals(value))
{
// Clear the value in the row
frow.Define(value);
frow.Clear();
}
// Done
foundrow = true;
break;
}
}
}
// Row not found?
if(!foundrow)
{
// Make new row
object defaultvalue = vartype.GetDefaultValue();
FieldsEditorRow frow = new FieldsEditorRow(fieldslist, group.Key, (int)group.Value, defaultvalue, true);
if(!value.Equals(defaultvalue)) frow.Define(value);
fieldslist.Rows.Insert(fieldslist.Rows.Count - 1, frow);
}
}
// Now check for rows that the givens fields do NOT have
foreach(DataGridViewRow row in fieldslist.Rows)
{
// Row is a field?
if(row is FieldsEditorRow)
{
FieldsEditorRow frow = row as FieldsEditorRow;
// Don't undefine user var rows defined by other actor types
if(frow.RowType != FieldsEditorRowType.USERVAR || !vars.ContainsKey(frow.Name)) continue;
// Is this row defined previously?
if(frow.IsDefined)
{
// Check if this row can not be found in the fields at all
if(!fromfields.ContainsKey(frow.Name))
{
// It is not defined in these fields, undefine the value
frow.Undefine();
}
}
}
}
}
// This applies the current fields to a UniFields object // This applies the current fields to a UniFields object
public void Apply(UniFields tofields) public void Apply(UniFields tofields)
{ {
@ -259,6 +345,7 @@ namespace CodeImp.DoomBuilder.Controls
// Go for all rows // Go for all rows
bool foundrow = false; bool foundrow = false;
bool skiprow = false; //mxd
foreach(DataGridViewRow row in fieldslist.Rows) foreach(DataGridViewRow row in fieldslist.Rows)
{ {
// Row is a field and matches field name? // Row is a field and matches field name?
@ -266,6 +353,13 @@ namespace CodeImp.DoomBuilder.Controls
{ {
FieldsEditorRow frow = row as FieldsEditorRow; FieldsEditorRow frow = row as FieldsEditorRow;
//mxd. User vars are stored separately
if(frow.RowType == FieldsEditorRowType.USERVAR)
{
skiprow = true;
break;
}
// Field is defined? // Field is defined?
if(frow.IsDefined) if(frow.IsDefined)
{ {
@ -275,6 +369,9 @@ namespace CodeImp.DoomBuilder.Controls
} }
} }
//mxd. User vars are stored separately
if(skiprow) continue;
// No such row? // No such row?
if(!foundrow) if(!foundrow)
{ {
@ -292,7 +389,7 @@ namespace CodeImp.DoomBuilder.Controls
FieldsEditorRow frow = row as FieldsEditorRow; FieldsEditorRow frow = row as FieldsEditorRow;
// Field is defined and not empty? // Field is defined and not empty?
if(frow.IsDefined && !frow.IsEmpty) if(frow.RowType != FieldsEditorRowType.USERVAR && frow.IsDefined && !frow.IsEmpty)
{ {
// Apply field // Apply field
object oldvalue = null; object oldvalue = null;
@ -300,7 +397,7 @@ namespace CodeImp.DoomBuilder.Controls
tofields[frow.Name] = new UniValue(frow.TypeHandler.Index, frow.GetResult(oldvalue)); tofields[frow.Name] = new UniValue(frow.TypeHandler.Index, frow.GetResult(oldvalue));
// Custom row? // Custom row?
if(!frow.IsFixed) if(frow.RowType == FieldsEditorRowType.DYNAMIC)
{ {
// Write type to map configuration // Write type to map configuration
General.Map.Options.SetUniversalFieldType(elementname, frow.Name, frow.TypeHandler.Index); General.Map.Options.SetUniversalFieldType(elementname, frow.Name, frow.TypeHandler.Index);
@ -310,6 +407,38 @@ namespace CodeImp.DoomBuilder.Controls
} }
} }
//mxd
public void ApplyUserVars(Dictionary<string, UniversalType> vars, UniFields tofields)
{
// Apply user variables when target map element contains user var definition and the value is not default
foreach(DataGridViewRow row in fieldslist.Rows)
{
// Row is a field?
if(row is FieldsEditorRow)
{
FieldsEditorRow frow = row as FieldsEditorRow;
if(frow.RowType != FieldsEditorRowType.USERVAR || !vars.ContainsKey(frow.Name)) continue;
object oldvalue = (tofields.ContainsKey(frow.Name) ? tofields[frow.Name].Value : null);
object newvalue = frow.GetResult(oldvalue);
// Skip field when mixed values
if(newvalue == null) continue;
// Remove field
if(newvalue.Equals(frow.TypeHandler.GetDefaultValue()))
{
if(tofields.ContainsKey(frow.Name)) tofields.Remove(frow.Name);
}
// Add field
else if(!newvalue.Equals(oldvalue))
{
tofields[frow.Name] = new UniValue(frow.TypeHandler.Index, newvalue);
}
}
}
}
#endregion #endregion
#region ================== Events #region ================== Events
@ -377,8 +506,8 @@ namespace CodeImp.DoomBuilder.Controls
// First column? // First column?
if(e.ColumnIndex == 0) if(e.ColumnIndex == 0)
{ {
// Not a fixed field? // Dynamic field?
if((frow != null) && !frow.IsFixed) if((frow != null) && frow.RowType == FieldsEditorRowType.DYNAMIC)
{ {
lasteditfieldname = frow.Name; lasteditfieldname = frow.Name;
fieldslist.CurrentCell = fieldslist.SelectedRows[0].Cells[0]; fieldslist.CurrentCell = fieldslist.SelectedRows[0].Cells[0];
@ -399,21 +528,20 @@ namespace CodeImp.DoomBuilder.Controls
{ {
// Get the row // Get the row
FieldsEditorRow row = e.Row as FieldsEditorRow; FieldsEditorRow row = e.Row as FieldsEditorRow;
if(row == null) return;
// Fixed field? // Fixed/uservar field?
if(row.IsFixed) if(row.RowType == FieldsEditorRowType.FIXED || row.RowType == FieldsEditorRowType.USERVAR)
{ {
// Just undefine the field // Just undefine the field
row.Undefine(); row.Undefine();
e.Cancel = true; e.Cancel = true;
if(OnFieldUndefined != null) if(OnFieldUndefined != null) OnFieldUndefined(row.Name);
OnFieldUndefined(row.Name);
} }
else else
{ {
if(OnFieldDeleted != null) if(OnFieldDeleted != null) OnFieldDeleted(row.Name);
OnFieldDeleted(row.Name);
} }
} }
@ -428,10 +556,7 @@ namespace CodeImp.DoomBuilder.Controls
{ {
// Remove all text // Remove all text
fieldslist.Rows[e.RowIndex].Cells[0].Style.ForeColor = SystemColors.WindowText; fieldslist.Rows[e.RowIndex].Cells[0].Style.ForeColor = SystemColors.WindowText;
if(autoinsertuserprefix) fieldslist.Rows[e.RowIndex].Cells[0].Value = (autoinsertuserprefix ? FIELD_PREFIX_SUGGESTION : string.Empty);
fieldslist.Rows[e.RowIndex].Cells[0].Value = FIELD_PREFIX_SUGGESTION;
else
fieldslist.Rows[e.RowIndex].Cells[0].Value = "";
} }
} }
// Value cell? // Value cell?
@ -538,12 +663,11 @@ namespace CodeImp.DoomBuilder.Controls
int type = General.Map.Options.GetUniversalFieldType(elementname, validname, 0); int type = General.Map.Options.GetUniversalFieldType(elementname, validname, 0);
// Make new row // Make new row
frow = new FieldsEditorRow(fieldslist, validname, type, null); frow = new FieldsEditorRow(fieldslist, validname, type, null, false);
frow.Visible = false; frow.Visible = false;
fieldslist.Rows.Insert(e.RowIndex + 1, frow); fieldslist.Rows.Insert(e.RowIndex + 1, frow);
if(OnFieldInserted != null) if(OnFieldInserted != null) OnFieldInserted(validname);
OnFieldInserted(validname);
} }
} }
} }
@ -587,11 +711,8 @@ namespace CodeImp.DoomBuilder.Controls
row.Cells[0].Value = validname; row.Cells[0].Value = validname;
if(type != -1) frow.ChangeType(type); if(type != -1) frow.ChangeType(type);
if(OnFieldNameChanged != null) if(OnFieldNameChanged != null) OnFieldNameChanged(lasteditfieldname, validname);
OnFieldNameChanged(lasteditfieldname, validname); if(OnFieldTypeChanged != null) OnFieldTypeChanged(validname);
if(OnFieldTypeChanged != null)
OnFieldTypeChanged(validname);
} }
else else
{ {
@ -615,8 +736,7 @@ namespace CodeImp.DoomBuilder.Controls
// Changing field type? // Changing field type?
if((e.ColumnIndex == 1) && (frow != null)) if((e.ColumnIndex == 1) && (frow != null))
{ {
if(OnFieldTypeChanged != null) if(OnFieldTypeChanged != null) OnFieldTypeChanged(frow.Name);
OnFieldTypeChanged(frow.Name);
} }
// Changing field value? // Changing field value?
if((e.ColumnIndex == 2) && (frow != null)) if((e.ColumnIndex == 2) && (frow != null))
@ -649,7 +769,7 @@ namespace CodeImp.DoomBuilder.Controls
{ {
//mxd. Preserve fixed fields visibility setting //mxd. Preserve fixed fields visibility setting
FieldsEditorRow frow = (fieldslist.Rows[i] as FieldsEditorRow); FieldsEditorRow frow = (fieldslist.Rows[i] as FieldsEditorRow);
if(frow != null && frow.IsFixed) frow.Visible = showfixedfields; if(frow != null && frow.RowType == FieldsEditorRowType.FIXED) frow.Visible = showfixedfields;
else fieldslist.Rows[i].Visible = true; else fieldslist.Rows[i].Visible = true;
} }
} }
@ -730,17 +850,17 @@ namespace CodeImp.DoomBuilder.Controls
private void ApplyValue(FieldsEditorRow frow, object value) private void ApplyValue(FieldsEditorRow frow, object value)
{ {
// Defined? // Defined?
if((value != null) && (!frow.IsFixed || !frow.Info.Default.Equals(value))) if((value != null) && (frow.RowType == FieldsEditorRowType.DYNAMIC || frow.RowType == FieldsEditorRowType.USERVAR
|| !frow.Info.Default.Equals(value)))
{ {
frow.Define(value); frow.Define(value);
} }
else if(frow.IsFixed) else if(frow.RowType == FieldsEditorRowType.FIXED)
{ {
frow.Undefine(); frow.Undefine();
} }
if(OnFieldValueChanged != null) if(OnFieldValueChanged != null) OnFieldValueChanged(frow.Name);
OnFieldValueChanged(frow.Name);
} }
// This applies the contents of the enums combobox and hides (if opened) // This applies the contents of the enums combobox and hides (if opened)
@ -847,7 +967,7 @@ namespace CodeImp.DoomBuilder.Controls
foreach(var row in fieldslist.Rows) foreach(var row in fieldslist.Rows)
{ {
FieldsEditorRow frow = (row as FieldsEditorRow); FieldsEditorRow frow = (row as FieldsEditorRow);
if(frow != null && frow.IsFixed) frow.Visible = showfixedfields; if(frow != null && frow.RowType == FieldsEditorRowType.FIXED) frow.Visible = showfixedfields;
} }
} }

View file

@ -26,6 +26,23 @@ using CodeImp.DoomBuilder.Types;
namespace CodeImp.DoomBuilder.Controls namespace CodeImp.DoomBuilder.Controls
{ {
internal enum FieldsEditorRowType //mxd
{
// This is a fixed field defined in the game configuration
// The field cannot be deleted (delete will result in a reset)
// and cannot change type.
FIXED,
// This is an abstartct variable field enetered by user
// The field can be deleted and can change type.
DYNAMIC,
// This is a user variable field defined in actor's DECORATE
// The field cannot be deleted (delete will result in a reset)
// but can change type.
USERVAR,
}
internal class FieldsEditorRow : DataGridViewRow internal class FieldsEditorRow : DataGridViewRow
{ {
#region ================== Constants #region ================== Constants
@ -34,13 +51,11 @@ namespace CodeImp.DoomBuilder.Controls
#region ================== Variables #region ================== Variables
// This is true when for a fixed field as defined in the game configuration //mxd. Row type
// This means that the field cannot be deleted (delete will result in a reset) private readonly FieldsEditorRowType rowtype;
// and cannot change type.
private bool isfixed;
// Field information (only for fixed fields) // Field information (only for fixed fields)
private UniversalFieldInfo fieldinfo; private readonly UniversalFieldInfo fieldinfo;
// This is true when the field is defined. Cannot be false when this field // This is true when the field is defined. Cannot be false when this field
// is not fixed, because non-fixed fields are deleted from the list when undefined. // is not fixed, because non-fixed fields are deleted from the list when undefined.
@ -53,7 +68,7 @@ namespace CodeImp.DoomBuilder.Controls
#region ================== Properties #region ================== Properties
public bool IsFixed { get { return isfixed; } } public FieldsEditorRowType RowType { get { return rowtype; } } //mxd
public bool IsDefined { get { return isdefined; } } public bool IsDefined { get { return isdefined; } }
public bool IsEmpty { get { return (this.Cells[2].Value == null) || (this.Cells[2].Value.ToString().Length == 0); } } public bool IsEmpty { get { return (this.Cells[2].Value == null) || (this.Cells[2].Value.ToString().Length == 0); } }
public string Name { get { return this.Cells[0].Value.ToString(); } } public string Name { get { return this.Cells[0].Value.ToString(); } }
@ -73,7 +88,7 @@ namespace CodeImp.DoomBuilder.Controls
// Fixed // Fixed
this.fieldinfo = fixedfield; this.fieldinfo = fixedfield;
isfixed = true; this.rowtype = FieldsEditorRowType.FIXED; //mxd
// Type // Type
this.fieldtype = General.Types.GetFieldHandler(fixedfield); this.fieldtype = General.Types.GetFieldHandler(fixedfield);
@ -97,14 +112,11 @@ namespace CodeImp.DoomBuilder.Controls
} }
// Constructor for a non-fixed, defined field // Constructor for a non-fixed, defined field
public FieldsEditorRow(DataGridView view, string name, int type, object value) //mxd. Also for a user variable field.
public FieldsEditorRow(DataGridView view, string name, int type, object value, bool isuservar)
{ {
// Defined //mxd. Row type
this.DefaultCellStyle.ForeColor = SystemColors.WindowText; this.rowtype = (isuservar ? FieldsEditorRowType.USERVAR : FieldsEditorRowType.DYNAMIC);
isdefined = true;
// Non-fixed
isfixed = false;
// Type // Type
this.fieldtype = General.Types.GetFieldHandler(type, value); this.fieldtype = General.Types.GetFieldHandler(type, value);
@ -112,6 +124,31 @@ namespace CodeImp.DoomBuilder.Controls
// Make all cells // Make all cells
base.CreateCells(view); base.CreateCells(view);
//mxd. Our path splits here...
if(isuservar)
{
// Not defined
this.DefaultCellStyle.ForeColor = SystemColors.GrayText;
isdefined = false;
fieldtype.ApplyDefaultValue();
// Setup property cell
this.Cells[0].Value = name;
this.Cells[0].ReadOnly = true;
// Setup type cell
this.Cells[1].Value = fieldtype.GetDisplayType();
this.Cells[1].ReadOnly = true;
// Setup value cell
this.Cells[2].Value = fieldtype.GetStringValue();
}
else
{
// Defined
this.DefaultCellStyle.ForeColor = SystemColors.WindowText;
isdefined = true;
// Setup property cell // Setup property cell
this.Cells[0].Value = name; this.Cells[0].Value = name;
this.Cells[0].ReadOnly = true; this.Cells[0].ReadOnly = true;
@ -122,6 +159,7 @@ namespace CodeImp.DoomBuilder.Controls
// Setup value cell // Setup value cell
this.Cells[2].Value = fieldtype.GetStringValue(); this.Cells[2].Value = fieldtype.GetStringValue();
}
// We have no destructor // We have no destructor
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
@ -140,7 +178,7 @@ namespace CodeImp.DoomBuilder.Controls
fieldtype.Browse(parent); fieldtype.Browse(parent);
// This is a fixed field? // This is a fixed field?
if(isfixed) if(rowtype == FieldsEditorRowType.FIXED)
{ {
// Does this match the default setting? // Does this match the default setting?
if(fieldtype.GetValue().Equals(fieldinfo.Default)) if(fieldtype.GetValue().Equals(fieldinfo.Default))
@ -188,7 +226,7 @@ namespace CodeImp.DoomBuilder.Controls
this.Cells[2].Value = fieldtype.GetStringValue(); this.Cells[2].Value = fieldtype.GetStringValue();
// This is a fixed field? // This is a fixed field?
if(isfixed) if(rowtype == FieldsEditorRowType.FIXED)
{ {
// Does this match the default setting? // Does this match the default setting?
if(fieldtype.GetValue().Equals(fieldinfo.Default)) if(fieldtype.GetValue().Equals(fieldinfo.Default))
@ -201,15 +239,19 @@ namespace CodeImp.DoomBuilder.Controls
} }
// This undefines the field // This undefines the field
// ONLY VALID FOR FIXED FIELDS // ONLY VALID FOR FIXED AND USERVAR FIELDS
// You should just delete non-fixed fields // You should just delete non-fixed fields
public void Undefine() public void Undefine()
{ {
// Must be fixed! // Must be fixed!
if(!isfixed) throw new InvalidOperationException(); if(rowtype != FieldsEditorRowType.FIXED && rowtype != FieldsEditorRowType.USERVAR) throw new InvalidOperationException();
// Now undefined // Now undefined
if(rowtype == FieldsEditorRowType.USERVAR)
fieldtype.ApplyDefaultValue();
else
fieldtype.SetValue(fieldinfo.Default); fieldtype.SetValue(fieldinfo.Default);
this.Cells[2].Value = fieldtype.GetStringValue(); this.Cells[2].Value = fieldtype.GetStringValue();
this.DefaultCellStyle.ForeColor = SystemColors.GrayText; this.DefaultCellStyle.ForeColor = SystemColors.GrayText;
isdefined = false; isdefined = false;
@ -218,10 +260,13 @@ namespace CodeImp.DoomBuilder.Controls
// This defines the field // This defines the field
public void Define(object value) public void Define(object value)
{ {
//mxd. Don't count as defined when default value is passed
if(value.ToString() == fieldtype.GetDefaultValue().ToString()) return;
// Now defined // Now defined
fieldtype.SetValue(value); fieldtype.SetValue(value);
this.Cells[2].Value = fieldtype.GetStringValue(); this.Cells[2].Value = fieldtype.GetStringValue();
this.DefaultCellStyle.ForeColor = SystemColors.WindowText; this.DefaultCellStyle.ForeColor = (rowtype == FieldsEditorRowType.USERVAR ? SystemColors.HotTrack : SystemColors.WindowText);
isdefined = true; isdefined = true;
} }
@ -229,13 +274,12 @@ namespace CodeImp.DoomBuilder.Controls
public void ChangeType(int typeindex) public void ChangeType(int typeindex)
{ {
// Can't do this for a fixed field! // Can't do this for a fixed field!
if(isfixed) throw new InvalidOperationException(); if(rowtype == FieldsEditorRowType.FIXED) throw new InvalidOperationException();
// Different? // Different?
if(typeindex != fieldtype.Index) if(typeindex != fieldtype.Index)
{ {
// Change field type! // Change field type!
//TypeHandlerAttribute attrib = General.Types.GetAttribute(typeindex); //mxd
fieldtype = General.Types.GetFieldHandler(typeindex, this.Cells[2].Value); fieldtype = General.Types.GetFieldHandler(typeindex, this.Cells[2].Value);
this.Cells[1].Value = fieldtype.GetDisplayType(); this.Cells[1].Value = fieldtype.GetDisplayType();
} }

View file

@ -452,7 +452,7 @@ namespace CodeImp.DoomBuilder.Controls
int keywordsindex = lexercfg.ReadSetting(lexername + ".keywordsindex", -1); int keywordsindex = lexercfg.ReadSetting(lexername + ".keywordsindex", -1);
if(keywordsindex > -1) if(keywordsindex > -1)
{ {
StringBuilder keywordslist = new StringBuilder(""); StringBuilder keywordslist = new StringBuilder();
foreach(string k in scriptconfig.Keywords) foreach(string k in scriptconfig.Keywords)
{ {
if(keywordslist.Length > 0) keywordslist.Append(" "); if(keywordslist.Length > 0) keywordslist.Append(" ");
@ -460,7 +460,7 @@ namespace CodeImp.DoomBuilder.Controls
//mxd. Skip adding the keyword if we have a snippet with the same name //mxd. Skip adding the keyword if we have a snippet with the same name
if(!scriptconfig.Snippets.Contains(k)) if(!scriptconfig.Snippets.Contains(k))
autocompletedict.Add(k.ToUpperInvariant(), k + "?" + imageindex); autocompletedict.Add(k, k + "?" + imageindex);
} }
string words = keywordslist.ToString(); string words = keywordslist.ToString();
scriptedit.SetKeywords(keywordsindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); scriptedit.SetKeywords(keywordsindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant()));
@ -471,9 +471,9 @@ namespace CodeImp.DoomBuilder.Controls
int propertiesindex = lexercfg.ReadSetting(lexername + ".propertiesindex", -1); int propertiesindex = lexercfg.ReadSetting(lexername + ".propertiesindex", -1);
if(propertiesindex > -1) if(propertiesindex > -1)
{ {
StringBuilder propertieslist = new StringBuilder(""); StringBuilder propertieslist = new StringBuilder();
HashSet<string> addedprops = new HashSet<string>(); HashSet<string> addedprops = new HashSet<string>();
char[] dot = new[] {'.'}; char[] dot = {'.'};
foreach(string p in scriptconfig.Properties) foreach(string p in scriptconfig.Properties)
{ {
if(propertieslist.Length > 0) propertieslist.Append(" "); if(propertieslist.Length > 0) propertieslist.Append(" ");
@ -511,7 +511,9 @@ namespace CodeImp.DoomBuilder.Controls
} }
// Autocomplete doesn't mind '.' or ':' // Autocomplete doesn't mind '.' or ':'
autocompletedict[p.ToUpperInvariant()] = p + "?" + imageindex; // Skip adding the keyword if we have a snippet with the same name
if(!scriptconfig.Snippets.Contains(p))
autocompletedict.Add(p, p + "?" + imageindex);
} }
string words = propertieslist.ToString(); string words = propertieslist.ToString();
scriptedit.SetKeywords(propertiesindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); scriptedit.SetKeywords(propertiesindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant()));
@ -522,21 +524,17 @@ namespace CodeImp.DoomBuilder.Controls
int constantsindex = lexercfg.ReadSetting(lexername + ".constantsindex", -1); int constantsindex = lexercfg.ReadSetting(lexername + ".constantsindex", -1);
if(constantsindex > -1) if(constantsindex > -1)
{ {
StringBuilder constantslist = new StringBuilder(""); StringBuilder constantslist = new StringBuilder();
foreach(string c in scriptconfig.Constants) foreach(string c in scriptconfig.Constants)
{ {
if(autocompletedict.ContainsKey(c.ToUpperInvariant())) //mxd. This happens when there's a keyword and a constant with the same name... if(autocompletedict.ContainsKey(c)) continue; //mxd. This happens when there's a keyword and a constant with the same name...
{
General.ErrorLogger.Add(ErrorType.Error, "Constant '" + c + "' is double-defined in '" + scriptconfig.Description + "' script configuration!");
continue;
}
if(constantslist.Length > 0) constantslist.Append(" "); if(constantslist.Length > 0) constantslist.Append(" ");
constantslist.Append(c); constantslist.Append(c);
//mxd. Skip adding the constant if we have a snippet with the same name //mxd. Skip adding the constant if we have a snippet with the same name
if(!scriptconfig.Snippets.Contains(c)) if(!scriptconfig.Snippets.Contains(c))
autocompletedict.Add(c.ToUpperInvariant(), c + "?" + imageindex); autocompletedict.Add(c, c + "?" + imageindex);
} }
string words = constantslist.ToString(); string words = constantslist.ToString();
scriptedit.SetKeywords(constantsindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); scriptedit.SetKeywords(constantsindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant()));
@ -547,13 +545,12 @@ namespace CodeImp.DoomBuilder.Controls
int snippetindex = lexercfg.ReadSetting(lexername + ".snippetindex", -1); int snippetindex = lexercfg.ReadSetting(lexername + ".snippetindex", -1);
if(snippetindex > -1 && scriptconfig.Snippets.Count > 0) if(snippetindex > -1 && scriptconfig.Snippets.Count > 0)
{ {
StringBuilder snippetslist = new StringBuilder(""); StringBuilder snippetslist = new StringBuilder();
foreach(string c in scriptconfig.Snippets) foreach(string s in scriptconfig.Snippets)
{ {
if(autocompletedict.ContainsKey(c.ToUpperInvariant())) continue;
if(snippetslist.Length > 0) snippetslist.Append(" "); if(snippetslist.Length > 0) snippetslist.Append(" ");
snippetslist.Append(c); snippetslist.Append(s);
autocompletedict.Add(c.ToUpperInvariant(), c + "?" + imageindex); autocompletedict.Add(s, s + "?" + imageindex);
} }
string words = snippetslist.ToString(); string words = snippetslist.ToString();
scriptedit.SetKeywords(snippetindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); scriptedit.SetKeywords(snippetindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant()));

View file

@ -147,7 +147,7 @@ namespace CodeImp.DoomBuilder.Controls
// Boilderplate // Boilderplate
if(!General.CompiledScriptConfigs.ContainsKey(General.Map.Options.ScriptCompiler)) if(!General.CompiledScriptConfigs.ContainsKey(General.Map.Options.ScriptCompiler))
{ {
General.ShowErrorMessage("Unable to compile '" + inputfile + "'. Unable to find required script compiler configuration ('" + General.Map.Options.ScriptCompiler + "').", MessageBoxButtons.OK); General.ShowErrorMessage("Unable to compile \"" + inputfile + "\". Unable to find required script compiler configuration (\"" + General.Map.Options.ScriptCompiler + "\").", MessageBoxButtons.OK);
return; return;
} }
@ -232,7 +232,7 @@ namespace CodeImp.DoomBuilder.Controls
{ {
// Fail // Fail
compiler.Dispose(); compiler.Dispose();
errors.Add(new CompilerError("Output file '" + outputfile + "' doesn't exist.")); errors.Add(new CompilerError("Output file \"" + outputfile + "\" doesn't exist."));
panel.ShowErrors(errors); panel.ShowErrors(errors);
return; return;
} }
@ -247,7 +247,7 @@ namespace CodeImp.DoomBuilder.Controls
{ {
// Fail // Fail
compiler.Dispose(); compiler.Dispose();
errors.Add(new CompilerError("Unable to create library file '" + targetfilename + "'. " + e.GetType().Name + ": " + e.Message)); errors.Add(new CompilerError("Unable to create library file \"" + targetfilename + "\". " + e.GetType().Name + ": " + e.Message));
panel.ShowErrors(errors); panel.ShowErrors(errors);
return; return;
} }
@ -282,7 +282,7 @@ namespace CodeImp.DoomBuilder.Controls
catch(Exception e) catch(Exception e)
{ {
// Failed // Failed
General.ErrorLogger.Add(ErrorType.Error, "Cannot open file '" + filepathname + "' for writing. Make sure the path exists and that the file is not in use by another application."); General.ErrorLogger.Add(ErrorType.Error, "Cannot open file \"" + filepathname + "\" for writing. Make sure the path exists and that the file is not in use by another application.");
General.WriteLogLine(e.GetType().Name + ": " + e.Message); General.WriteLogLine(e.GetType().Name + ": " + e.Message);
General.ShowErrorMessage("Unable to open file \"" + filepathname + "\" for writing. Make sure the path exists and that the file is not in use by another application.", MessageBoxButtons.OK); General.ShowErrorMessage("Unable to open file \"" + filepathname + "\" for writing. Make sure the path exists and that the file is not in use by another application.", MessageBoxButtons.OK);
return false; return false;
@ -323,7 +323,7 @@ namespace CodeImp.DoomBuilder.Controls
catch(Exception e) catch(Exception e)
{ {
// Failed // Failed
General.ErrorLogger.Add(ErrorType.Error, "Cannot open file '" + filepathname + "' for reading. Make sure the path exists and that the file is not in use by another application."); General.ErrorLogger.Add(ErrorType.Error, "Cannot open file \"" + filepathname + "\" for reading. Make sure the path exists and that the file is not in use by another application.");
General.WriteLogLine(e.GetType().Name + ": " + e.Message); General.WriteLogLine(e.GetType().Name + ": " + e.Message);
General.ShowErrorMessage("Unable to open file \"" + filepathname + "\" for reading. Make sure the path exists and that the file is not in use by another application.", MessageBoxButtons.OK); General.ShowErrorMessage("Unable to open file \"" + filepathname + "\" for reading. Make sure the path exists and that the file is not in use by another application.", MessageBoxButtons.OK);
return false; return false;

View file

@ -102,6 +102,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0f;
}
#endregion #endregion
} }
} }

View file

@ -101,6 +101,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0;
}
#endregion #endregion
} }
} }

View file

@ -102,6 +102,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0f;
}
#endregion #endregion
} }
} }

View file

@ -93,7 +93,7 @@ namespace CodeImp.DoomBuilder.Types
public override int GetIntValue() public override int GetIntValue()
{ {
if(this.value) return 1; else return 0; return (this.value ? 1 : 0);
} }
public override string GetStringValue() public override string GetStringValue()
@ -107,6 +107,11 @@ namespace CodeImp.DoomBuilder.Types
return list; return list;
} }
public override object GetDefaultValue()
{
return false;
}
#endregion #endregion
} }
} }

View file

@ -113,6 +113,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString("X6"); return this.value.ToString("X6");
} }
public override object GetDefaultValue()
{
return 0;
}
#endregion #endregion
} }
} }

View file

@ -38,7 +38,7 @@ namespace CodeImp.DoomBuilder.Types
private EnumList list; private EnumList list;
private int value; private int value;
private int defaultValue; //mxd private int defaultvalue; //mxd
#endregion #endregion
@ -55,7 +55,7 @@ namespace CodeImp.DoomBuilder.Types
// When set up for an argument // When set up for an argument
public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo) public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo)
{ {
defaultValue = (int)arginfo.DefaultValue;//mxd defaultvalue = (int)arginfo.DefaultValue;//mxd
base.SetupArgument(attr, arginfo); base.SetupArgument(attr, arginfo);
// Keep enum list reference // Keep enum list reference
@ -100,9 +100,9 @@ namespace CodeImp.DoomBuilder.Types
} }
//mxd //mxd
public override void SetDefaultValue() public override void ApplyDefaultValue()
{ {
value = defaultValue; value = defaultvalue;
} }
public override object GetValue() public override object GetValue()
@ -120,6 +120,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return defaultvalue;
}
#endregion #endregion
} }
} }

View file

@ -140,7 +140,7 @@ namespace CodeImp.DoomBuilder.Types
} }
//mxd //mxd
public override void SetDefaultValue() public override void ApplyDefaultValue()
{ {
value = defaultvalue; value = defaultvalue;
} }
@ -190,6 +190,11 @@ namespace CodeImp.DoomBuilder.Types
return General.Types.GetAttribute((int)UniversalType.Integer); return General.Types.GetAttribute((int)UniversalType.Integer);
} }
public override object GetDefaultValue()
{
return defaultvalue;
}
#endregion #endregion
} }
} }

View file

@ -34,7 +34,7 @@ namespace CodeImp.DoomBuilder.Types
private EnumList list; private EnumList list;
private EnumItem value; private EnumItem value;
private EnumItem defaultValue; //mxd private EnumItem defaultvalue; //mxd
#endregion #endregion
@ -50,7 +50,7 @@ namespace CodeImp.DoomBuilder.Types
// When set up for an argument // When set up for an argument
public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo) public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo)
{ {
defaultValue = new EnumItem(arginfo.DefaultValue.ToString(), arginfo.DefaultValue.ToString()); //mxd defaultvalue = new EnumItem(arginfo.DefaultValue.ToString(), arginfo.DefaultValue.ToString()); //mxd
base.SetupArgument(attr, arginfo); base.SetupArgument(attr, arginfo);
// Keep enum list reference // Keep enum list reference
@ -121,9 +121,9 @@ namespace CodeImp.DoomBuilder.Types
} }
//mxd //mxd
public override void SetDefaultValue() public override void ApplyDefaultValue()
{ {
value = defaultValue; value = defaultvalue;
} }
public override object GetValue() public override object GetValue()
@ -171,6 +171,11 @@ namespace CodeImp.DoomBuilder.Types
return General.Types.GetAttribute((int)UniversalType.String); return General.Types.GetAttribute((int)UniversalType.String);
} }
public override object GetDefaultValue()
{
return defaultvalue;
}
#endregion #endregion
} }
} }

View file

@ -70,6 +70,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value; return this.value;
} }
public override object GetDefaultValue()
{
return string.Empty;
}
#endregion #endregion
} }
} }

View file

@ -85,6 +85,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0f;
}
#endregion #endregion
} }
} }

View file

@ -34,7 +34,7 @@ namespace CodeImp.DoomBuilder.Types
#region ================== Variables #region ================== Variables
private int value; private int value;
private int defaultValue; //mxd private int defaultvalue; //mxd
#endregion #endregion
@ -47,7 +47,7 @@ namespace CodeImp.DoomBuilder.Types
//mxd //mxd
public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo) public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo)
{ {
defaultValue = (int)arginfo.DefaultValue; defaultvalue = (int)arginfo.DefaultValue;
base.SetupArgument(attr, arginfo); base.SetupArgument(attr, arginfo);
} }
@ -85,9 +85,9 @@ namespace CodeImp.DoomBuilder.Types
} }
//mxd //mxd
public override void SetDefaultValue() public override void ApplyDefaultValue()
{ {
value = defaultValue; value = defaultvalue;
} }
public override object GetValue() public override object GetValue()
@ -105,6 +105,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return defaultvalue;
}
#endregion #endregion
} }
} }

View file

@ -101,6 +101,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0;
}
#endregion #endregion
} }
} }

View file

@ -63,6 +63,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0;
}
#endregion #endregion
} }
} }

View file

@ -18,7 +18,7 @@ namespace CodeImp.DoomBuilder.Types
#region ================== Variables #region ================== Variables
private float value; private float value;
private bool randomValue; private bool randomvalue;
private float min; private float min;
private float max; private float max;
@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.Types
if(float.TryParse(parts[0], NumberStyles.Float, CultureInfo.CurrentCulture, out min) && if(float.TryParse(parts[0], NumberStyles.Float, CultureInfo.CurrentCulture, out min) &&
float.TryParse(parts[1], NumberStyles.Float, CultureInfo.CurrentCulture, out max)) float.TryParse(parts[1], NumberStyles.Float, CultureInfo.CurrentCulture, out max))
{ {
randomValue = (min != max); randomvalue = (min != max);
if(min == max) this.value = min; if(min == max) this.value = min;
else if(min > max) General.Swap(ref min, ref max); else if(min > max) General.Swap(ref min, ref max);
@ -91,22 +91,27 @@ namespace CodeImp.DoomBuilder.Types
public override object GetValue() public override object GetValue()
{ {
if(randomValue) return General.Random(min, max); //mxd if(randomvalue) return General.Random(min, max); //mxd
return this.value; return this.value;
} }
public override int GetIntValue() public override int GetIntValue()
{ {
if(randomValue) return (int)General.Random(min, max); //mxd if(randomvalue) return (int)General.Random(min, max); //mxd
return (int)this.value; return (int)this.value;
} }
public override string GetStringValue() public override string GetStringValue()
{ {
if(randomValue) return General.Random(min, max).ToString(CultureInfo.InvariantCulture); //mxd if(randomvalue) return General.Random(min, max).ToString(CultureInfo.InvariantCulture); //mxd
return this.value.ToString(CultureInfo.InvariantCulture); return this.value.ToString(CultureInfo.InvariantCulture);
} }
public override object GetDefaultValue()
{
return 0f;
}
#endregion #endregion
} }
} }

View file

@ -14,8 +14,8 @@ namespace CodeImp.DoomBuilder.Types
#region ================== Variables #region ================== Variables
private int value; private int value;
private int defaultValue; private int defaultvalue;
private bool randomValue; private bool randomvalue;
private int min; private int min;
private int max; private int max;
@ -29,7 +29,7 @@ namespace CodeImp.DoomBuilder.Types
public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo) public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo)
{ {
defaultValue = (int)arginfo.DefaultValue; defaultvalue = (int)arginfo.DefaultValue;
base.SetupArgument(attr, arginfo); base.SetupArgument(attr, arginfo);
//mxd. We don't want to store this type //mxd. We don't want to store this type
@ -74,7 +74,7 @@ namespace CodeImp.DoomBuilder.Types
if(int.TryParse(parts[0], NumberStyles.Integer, CultureInfo.CurrentCulture, out min) && if(int.TryParse(parts[0], NumberStyles.Integer, CultureInfo.CurrentCulture, out min) &&
int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.CurrentCulture, out max)) int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.CurrentCulture, out max))
{ {
randomValue = (min != max); randomvalue = (min != max);
if(min == max) this.value = min; if(min == max) this.value = min;
else if(min > max) General.Swap(ref min, ref max); else if(min > max) General.Swap(ref min, ref max);
} }
@ -89,29 +89,34 @@ namespace CodeImp.DoomBuilder.Types
} }
//mxd //mxd
public override void SetDefaultValue() public override void ApplyDefaultValue()
{ {
value = defaultValue; value = defaultvalue;
} }
public override object GetValue() public override object GetValue()
{ {
if(randomValue) return General.Random(min, max); //mxd if(randomvalue) return General.Random(min, max); //mxd
return this.value; return this.value;
} }
public override int GetIntValue() public override int GetIntValue()
{ {
if(randomValue) return General.Random(min, max); //mxd if(randomvalue) return General.Random(min, max); //mxd
return this.value; return this.value;
} }
public override string GetStringValue() public override string GetStringValue()
{ {
if(randomValue) return General.Random(min, max).ToString(CultureInfo.InvariantCulture); //mxd if(randomvalue) return General.Random(min, max).ToString(CultureInfo.InvariantCulture); //mxd
return this.value.ToString(CultureInfo.InvariantCulture); return this.value.ToString(CultureInfo.InvariantCulture);
} }
public override object GetDefaultValue()
{
return defaultvalue;
}
#endregion #endregion
} }
} }

View file

@ -101,6 +101,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0;
}
#endregion #endregion
} }
} }

View file

@ -170,7 +170,7 @@ namespace CodeImp.DoomBuilder.Types
} }
//mxd //mxd
public override void SetDefaultValue() public override void ApplyDefaultValue()
{ {
value = defaultvalue; value = defaultvalue;
} }
@ -197,6 +197,11 @@ namespace CodeImp.DoomBuilder.Types
return (this.value != null ? this.value.Title : "0: No Tag"); return (this.value != null ? this.value.Title : "0: No Tag");
} }
public override object GetDefaultValue()
{
return defaultvalue;
}
// This returns an enum list // This returns an enum list
public override EnumList GetEnumList() public override EnumList GetEnumList()
{ {

View file

@ -68,8 +68,7 @@ namespace CodeImp.DoomBuilder.Types
public override int GetIntValue() public override int GetIntValue()
{ {
int result; int result;
if(int.TryParse(this.value, out result)) return result; return (int.TryParse(this.value, out result) ? result : 0);
else return 0;
} }
public override string GetStringValue() public override string GetStringValue()
@ -77,6 +76,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value; return this.value;
} }
public override object GetDefaultValue()
{
return string.Empty;
}
#endregion #endregion
} }
} }

View file

@ -70,6 +70,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value; return this.value;
} }
public override object GetDefaultValue()
{
return string.Empty;
}
#endregion #endregion
} }
} }

View file

@ -91,6 +91,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value; return this.value;
} }
public override object GetDefaultValue()
{
return string.Empty;
}
#endregion #endregion
} }
} }

View file

@ -101,6 +101,11 @@ namespace CodeImp.DoomBuilder.Types
return this.value.ToString(); return this.value.ToString();
} }
public override object GetDefaultValue()
{
return 0;
}
#endregion #endregion
} }
} }

View file

@ -120,12 +120,15 @@ namespace CodeImp.DoomBuilder.Types
public abstract void SetValue(object value); public abstract void SetValue(object value);
//mxd. This should replace current value with the default one //mxd. This should replace current value with the default one
public virtual void SetDefaultValue() { } public virtual void ApplyDefaultValue() { }
// This must return the value as one of the primitive data types // This must return the value as one of the primitive data types
// supported by UDMF: int, string, float or bool // supported by UDMF: int, string, float or bool
public abstract object GetValue(); public abstract object GetValue();
//mxd. This should return the default value
public abstract object GetDefaultValue();
// This must return the value as integer (for arguments) // This must return the value as integer (for arguments)
public virtual int GetIntValue() public virtual int GetIntValue()
{ {
@ -136,9 +139,7 @@ namespace CodeImp.DoomBuilder.Types
public abstract string GetStringValue(); public abstract string GetStringValue();
// This is called when the user presses the browse button // This is called when the user presses the browse button
public virtual void Browse(IWin32Window parent) public virtual void Browse(IWin32Window parent) { }
{
}
// This must returns an enum list when IsEnumerable is true // This must returns an enum list when IsEnumerable is true
public virtual EnumList GetEnumList() public virtual EnumList GetEnumList()

View file

@ -199,6 +199,11 @@ namespace CodeImp.DoomBuilder.Windows
posY.ButtonStep = General.Map.Grid.GridSize; posY.ButtonStep = General.Map.Grid.GridSize;
posZ.ButtonStep = General.Map.Grid.GridSize; posZ.ButtonStep = General.Map.Grid.GridSize;
//mxd. User vars. Should be done before adding regular fields
ThingTypeInfo fti = General.Map.Data.GetThingInfoEx(ft.Type);
if(fti != null && fti.Actor != null && fti.Actor.UserVars.Count > 0)
fieldslist.SetUserVars(fti.Actor.UserVars, ft.Fields, true);
// Custom fields // Custom fields
fieldslist.SetValues(ft.Fields, true); fieldslist.SetValues(ft.Fields, true);
commenteditor.SetValues(ft.Fields, true); commenteditor.SetValues(ft.Fields, true);
@ -272,6 +277,11 @@ namespace CodeImp.DoomBuilder.Windows
//mxd. Arguments //mxd. Arguments
argscontrol.SetValue(t, false); argscontrol.SetValue(t, false);
//mxd. User vars. Should be done before adding regular fields
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
if(ti != null && ti.Actor != null && ti.Actor.UserVars.Count > 0)
fieldslist.SetUserVars(ti.Actor.UserVars, t.Fields, false);
//mxd. Custom fields //mxd. Custom fields
fieldslist.SetValues(t.Fields, false); fieldslist.SetValues(t.Fields, false);
commenteditor.SetValues(t.Fields, false); //mxd. Comments commenteditor.SetValues(t.Fields, false); //mxd. Comments
@ -294,16 +304,6 @@ namespace CodeImp.DoomBuilder.Windows
//mxd. Store initial properties //mxd. Store initial properties
thingprops.Add(new ThingProperties(t)); thingprops.Add(new ThingProperties(t));
//mxd. add user vars
/*if(info != null && info.Actor != null && info.Actor.UserVars.Count > 0)
{
foreach(string s in info.Actor.UserVars)
{
if(!t.Fields.ContainsKey(s))
fieldslist.SetValue(s, 0, CodeImp.DoomBuilder.Types.UniversalType.Integer);
}
}*/
} }
preventchanges = false; preventchanges = false;
@ -490,6 +490,11 @@ namespace CodeImp.DoomBuilder.Windows
if(!string.IsNullOrEmpty(score.Text)) if(!string.IsNullOrEmpty(score.Text))
UniFields.SetInteger(t.Fields, "score", score.GetResult(t.Fields.GetValue("score", 0)), 0); UniFields.SetInteger(t.Fields, "score", score.GetResult(t.Fields.GetValue("score", 0)), 0);
//mxd. User vars. Should be called after fieldslist.Apply()
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
if(ti != null && ti.Actor != null && ti.Actor.UserVars.Count > 0)
fieldslist.ApplyUserVars(ti.Actor.UserVars, t.Fields);
color.ApplyTo(t.Fields, t.Fields.GetValue("fillcolor", 0)); color.ApplyTo(t.Fields, t.Fields.GetValue("fillcolor", 0));
//mxd. Comments //mxd. Comments

View file

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Types;
#endregion #endregion
@ -52,7 +53,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// Properties // Properties
private Dictionary<string, List<string>> props; private Dictionary<string, List<string>> props;
private readonly List<string> userVars; //mxd private readonly Dictionary<string, UniversalType> uservars; //mxd
// States // States
private Dictionary<string, StateStructure> states; private Dictionary<string, StateStructure> states;
@ -68,7 +69,7 @@ namespace CodeImp.DoomBuilder.ZDoom
public string ReplacesClass { get { return replaceclass; } } public string ReplacesClass { get { return replaceclass; } }
public ActorStructure BaseClass { get { return baseclass; } } public ActorStructure BaseClass { get { return baseclass; } }
internal int DoomEdNum { get { return doomednum; } set { doomednum = value; } } internal int DoomEdNum { get { return doomednum; } set { doomednum = value; } }
public List<string> UserVars { get { return userVars; } } //mxd public Dictionary<string, UniversalType> UserVars { get { return uservars; } } //mxd
#endregion #endregion
@ -78,10 +79,10 @@ namespace CodeImp.DoomBuilder.ZDoom
internal ActorStructure(DecorateParser parser) internal ActorStructure(DecorateParser parser)
{ {
// Initialize // Initialize
flags = new Dictionary<string, bool>(StringComparer.Ordinal); flags = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
props = new Dictionary<string, List<string>>(StringComparer.Ordinal); props = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
states = new Dictionary<string, StateStructure>(StringComparer.Ordinal); states = new Dictionary<string, StateStructure>(StringComparer.OrdinalIgnoreCase);
userVars = new List<string>();//mxd uservars = new Dictionary<string, UniversalType>(StringComparer.OrdinalIgnoreCase);//mxd
bool done = false; //mxd bool done = false; //mxd
// Always define a game property, but default to 0 values // Always define a game property, but default to 0 values
@ -163,7 +164,7 @@ namespace CodeImp.DoomBuilder.ZDoom
else if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out doomednum)) // Check if numeric else if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out doomednum)) // Check if numeric
{ {
// Not numeric! // Not numeric!
parser.ReportError("Expected editor thing number or start of actor scope while parsing '" + classname + "'"); parser.ReportError("Expected editor thing number or start of actor scope while parsing \"" + classname + "\"");
return; return;
} }
break; break;
@ -271,18 +272,87 @@ namespace CodeImp.DoomBuilder.ZDoom
break; break;
case "var": //mxd case "var": //mxd
while(parser.SkipWhitespace(true)) // Type
parser.SkipWhitespace(true);
string typestr = parser.ReadToken().ToUpperInvariant();
UniversalType type = UniversalType.EnumOption; // There is no Unknown type, so let's use something impossiburu...
switch(typestr)
{ {
string t = parser.ReadToken(); case "INT":
if(string.IsNullOrEmpty(t) || t == ";") break; type = UniversalType.Integer;
if(t.StartsWith("user_") && !userVars.Contains(t)) break;
userVars.Add(t);
default:
parser.LogWarning("Unknown user variable type");
break;
}
// Name
parser.SkipWhitespace(true);
string name = parser.ReadToken();
if(string.IsNullOrEmpty(name))
{
parser.ReportError("Expected User Variable name");
return;
}
if(!name.StartsWith("user_", StringComparison.OrdinalIgnoreCase))
{
parser.ReportError("User Variable name must start with \"user_\" prefix");
return;
}
if(uservars.ContainsKey(name))
{
parser.ReportError("User Variable \"" + name + "\" is double-defined");
return;
}
if(!skipsuper && baseclass != null && baseclass.uservars.ContainsKey(name))
{
parser.ReportError("User variable \"" + name + "\" is already defined in one of the parent classes");
return;
}
// Rest
parser.SkipWhitespace(true);
string next = parser.ReadToken();
if(next == "[") // that's User Array. Let's skip it...
{
int arrlen = -1;
if(!parser.ReadSignedInt(ref arrlen))
{
parser.ReportError("Expected User Array length, but got \"" + next + "\"");
return;
}
if(arrlen < 1)
{
parser.ReportError("User Array length must be a positive value");
return;
}
if(!parser.NextTokenIs("]") || !parser.NextTokenIs(";"))
{
return;
}
}
else if(next != ";")
{
parser.ReportError("Expected \";\", but got \"" + next + "\"");
return;
}
else
{
// Add to collection
uservars.Add(name, type);
} }
break; break;
case "}": case "}":
// Actor scope ends here, //mxd. Get user vars from the BaseClass, if we have one
// break out of this parse loop if(!skipsuper && baseclass != null && baseclass.uservars.Count > 0)
{
foreach(var group in baseclass.uservars)
uservars.Add(group.Key, group.Value);
}
// Actor scope ends here, break out of this parse loop
done = true; done = true;
break; break;
@ -414,7 +484,7 @@ namespace CodeImp.DoomBuilder.ZDoom
} }
} }
parser.LogWarning("Unable to find '" + inheritclass + "' class to inherit from, while parsing '" + classname + ":" + doomednum + "'"); parser.LogWarning("Unable to find \"" + inheritclass + "\" class to inherit from, while parsing \"" + classname + ":" + doomednum + "\"");
} }
} }
@ -554,7 +624,7 @@ namespace CodeImp.DoomBuilder.ZDoom
/// </summary> /// </summary>
public Dictionary<string, StateStructure> GetAllStates() public Dictionary<string, StateStructure> GetAllStates()
{ {
Dictionary<string, StateStructure> list = new Dictionary<string, StateStructure>(states); Dictionary<string, StateStructure> list = new Dictionary<string, StateStructure>(states, StringComparer.OrdinalIgnoreCase);
if(!skipsuper && (baseclass != null)) if(!skipsuper && (baseclass != null))
{ {

View file

@ -86,7 +86,7 @@ namespace CodeImp.DoomBuilder.ZDoom
{ {
// Syntax // Syntax
whitespace = "\n \t\r\u00A0"; //mxd. non-breaking space is also space :) whitespace = "\n \t\r\u00A0"; //mxd. non-breaking space is also space :)
specialtokens = ":{}+-\n;,"; specialtokens = ":{}[]+-\n;,";
// Initialize // Initialize
actors = new Dictionary<string, ActorStructure>(StringComparer.OrdinalIgnoreCase); actors = new Dictionary<string, ActorStructure>(StringComparer.OrdinalIgnoreCase);

View file

@ -201,7 +201,7 @@ namespace CodeImp.DoomBuilder.ZDoom
if(datastream.Position == datastream.Length) //mxd if(datastream.Position == datastream.Length) //mxd
{ {
// ZDoom doesn't give even a warning message about this, so we shouldn't report error or fail parsing. // ZDoom doesn't give even a warning message about this, so we shouldn't report error or fail parsing.
General.ErrorLogger.Add(ErrorType.Warning, "DECORATE warning in '" + sourcename + "', line " + GetCurrentLineNumber() + ". Block comment is not closed."); General.ErrorLogger.Add(ErrorType.Warning, "DECORATE warning in \"" + sourcename + "\", line " + GetCurrentLineNumber() + ". Block comment is not closed.");
return false; return false;
} }
@ -441,7 +441,7 @@ namespace CodeImp.DoomBuilder.ZDoom
if(string.Compare(token, expectedtoken, true) != 0) if(string.Compare(token, expectedtoken, true) != 0)
{ {
if(reporterror) ReportError("Expected '" + expectedtoken + "', but got '" + token + "'"); if(reporterror) ReportError("Expected \"" + expectedtoken + "\", but got \"" + token + "\"");
// Rewind so this structure can be read again // Rewind so this structure can be read again
DataStream.Seek(-token.Length - 1, SeekOrigin.Current); DataStream.Seek(-token.Length - 1, SeekOrigin.Current);
@ -531,16 +531,16 @@ namespace CodeImp.DoomBuilder.ZDoom
{ {
// Add a warning // Add a warning
int errline = (datastream != null ? GetCurrentLineNumber() : CompilerError.NO_LINE_NUMBER); int errline = (datastream != null ? GetCurrentLineNumber() : CompilerError.NO_LINE_NUMBER);
General.ErrorLogger.Add(ErrorType.Warning, GetLanguageType() + " warning in '" + sourcename General.ErrorLogger.Add(ErrorType.Warning, GetLanguageType() + " warning in \"" + sourcename
+ (errline != CompilerError.NO_LINE_NUMBER ? "', line " + (errline + 1) : "'") + ". " + (errline != CompilerError.NO_LINE_NUMBER ? "\", line " + (errline + 1) : "\"") + ". "
+ message + "."); + message + ".");
} }
//mxd. This adds an error to the ErrorLogger //mxd. This adds an error to the ErrorLogger
public void LogError() public void LogError()
{ {
General.ErrorLogger.Add(ErrorType.Error, GetLanguageType() + " error in '" + errorsource General.ErrorLogger.Add(ErrorType.Error, GetLanguageType() + " error in \"" + errorsource
+ (errorline != CompilerError.NO_LINE_NUMBER ? "', line " + (errorline + 1) : "'") + ". " + (errorline != CompilerError.NO_LINE_NUMBER ? "\", line " + (errorline + 1) : "\"") + ". "
+ errordesc + "."); + errordesc + ".");
} }
@ -611,7 +611,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// includefilename references something above the root? // includefilename references something above the root?
if(index-- < 0) if(index-- < 0)
{ {
ReportError("Unable to construct rooted path from '" + includefilename + "'"); ReportError("Unable to construct rooted path from \"" + includefilename + "\"");
return string.Empty; return string.Empty;
} }