mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-22 20:02:48 +00:00
Added, DECORATE support: #region blocks are now used as thing categories ("//$Category" actor block definition overrides these). Additional category-wide special comments are now available (see documentation).
Updated documentation ("DECORATE keys" page).
This commit is contained in:
parent
b1e5d8b5be
commit
74f749fd68
10 changed files with 268 additions and 47 deletions
|
@ -25,8 +25,8 @@ keywords
|
|||
{
|
||||
//Editor special comments
|
||||
//These are handled in a different fascion: key is replaced with the value and the caret is placed at [EP] position
|
||||
$Angled = "$Angled";
|
||||
$NotAngled = "$NotAngled";
|
||||
$Angled = "//$Angled";
|
||||
$NotAngled = "//$NotAngled";
|
||||
$Category = "//$Category \"[EP]\"";
|
||||
$Sprite = "//$Sprite \"[EP]\"";
|
||||
$IgnoreRenderstyle = "//$IgnoreRenderstyle";
|
||||
|
@ -59,6 +59,13 @@ keywords
|
|||
$Color = "//$Color ";
|
||||
$Obsolete = "//$Obsolete \"[EP]\"";
|
||||
$GZDB_SKIP = "//$GZDB_SKIP";
|
||||
//Editor special comments for thing categories ($Sprite and $Color are already defined above)
|
||||
$Sort = "//$Sort ";
|
||||
$Arrow = "//$Arrow ";
|
||||
$Error = "//$Error ";
|
||||
$FixedSize = "//$FixedSize ";
|
||||
$FixedRotation = "//$FixedRotation ";
|
||||
$AbsoluteZ = "//$AbsoluteZ ";
|
||||
//Preprocessor directives
|
||||
#Include = "#Include";
|
||||
#region = "#region";
|
||||
|
|
|
@ -15,7 +15,17 @@
|
|||
<h1>DECORATE keys</h1>
|
||||
</div>
|
||||
<div id="contents">
|
||||
<p> Doom Builder 2 includes a DECORATE parser used to obtain relevant information (such as editor number, Radius, Height, Scale, and so on) from custom actors. Additional information can be conveyed with keys in the form of special comments inserted within an actor's declaration block:<br />
|
||||
<p>GZDoom Builder includes a DECORATE parser used to obtain relevant information (such as editor number, Radius, Height, Scale, and so on) from custom actors.<br />
|
||||
<br /><br />
|
||||
<span class="big">Global definitions (GZDB only):</span>
|
||||
<br />
|
||||
Additional information can be conveyed with keys in the form of special comments inserted in the global DECORATE block:<br /><br />
|
||||
<strong>//$GZDB_SKIP</strong><br />
|
||||
DECORATE parser will stop parsing a file after encountering this comment. This can be used to speedup the parsing process by skipping files, which don't contain placeable actor definitions.<br />
|
||||
<br /><br />
|
||||
<span class="big">Actor definitions:</span>
|
||||
<br />Additional information can be conveyed with keys in the form of special comments inserted within an actor's declaration block:<br />
|
||||
|
||||
<br />
|
||||
<strong>//$Angled</strong> - <span class="red">GZDB only</span>.<br />
|
||||
<strong>//$NotAngled</strong> - <span class="red">GZDB only</span>.<br />
|
||||
|
@ -50,7 +60,7 @@
|
|||
<strong><a name="argenum" id="argenum"></a>//$ArgNEnum <string or structure></strong> - <span class="red">GZDB only</span>.<br />
|
||||
Allows to specify an enum for this argument. This can be either a name of an enum defined in the Game Configuration, or an explicit enum definition. This property can only be used in conjunction with "<strong>//$ArgN</strong>" property.<br />
|
||||
<br />
|
||||
<strong>//$Color <color index></strong> - <span class="red">GZDB only</span>.<br />
|
||||
<strong><a name="color" id="color"></a>//$Color <color index></strong> - <span class="red">GZDB only</span>.<br />
|
||||
Allows to override category color for this actor. Possible values are:
|
||||
<ul>
|
||||
<li> 0 - <span style="color:#696969">█</span> Dark Gray;</li>
|
||||
|
@ -71,16 +81,11 @@
|
|||
<li>15 - <span style="color:#F5F5F5">█</span> White;</li>
|
||||
<li>16 - <span style="color:#FFB6C1">█</span> Pink;</li>
|
||||
<li>17 - <span style="color:#FF8C00">█</span> Light Orange;</li>
|
||||
<li>18 - <span style="color:#BDB76B">█</span> Light Brown (default);</li>
|
||||
<li>18 - <span style="color:#BDB76B">█</span> Light Brown (<strong>default</strong>);</li>
|
||||
<li>19 - <span style="color:#DAA520">█</span> Orange;</li>
|
||||
</ul>
|
||||
<strong>//$Obsolete <reason></strong> - <span class="red">GZDB only</span>.<br />
|
||||
Marks the thing as obsolete. It will be detected by "Check obsolete things" <a href="e_mapanalysis.html">Map Analysis Mode</a> check and will be marked in the <a href="w_thingedit.html">Thing Properties Window</a> and the Thing Info panel.<br />
|
||||
<br /><br />
|
||||
|
||||
<h3>Additionaly, you can use the following special comments in the global block:</h3><br />
|
||||
<strong>//$GZDB_SKIP</strong> - <span class="red">GZDB only</span>.<br />
|
||||
DECORATE parser will stop parsing a file after encountering this comment. This can be used to speedup the parsing process by skipping files, which don't contain placeable actor definitions.<br />
|
||||
<br />
|
||||
<strong>Note:</strong> It is a good idea to include the Doom Editor Number after the actor definition if you want it to show in Doom Builder, even if it is replacing a standard Doom actor.<br />
|
||||
<br />
|
||||
|
@ -136,6 +141,59 @@ actor SuperGiantImpBall : DoomImpBall
|
|||
Scale 8.0
|
||||
Damage 30
|
||||
}
|
||||
</pre>
|
||||
<br /><br />
|
||||
<span class="big">Category definitions (GZDB only):</span><br />
|
||||
<br />
|
||||
Thing categories can be defined in DECORATE using <strong>#region</strong> / <strong>#endregion</strong> blocks. Region name is used as thing category title. "<strong>//$Category</strong>" actor block definition overrides these. Additional information can be conveyed with keys in the form of special comments inserted within <strong>#region</strong> / <strong>#endregion</strong> block (these keys replicate Game Configuration <a href="gc_thingsettings.html#catdefs">thing category properties</a> with a slightly different syntax):<br />
|
||||
<br />
|
||||
<b class="fat">//$Sorted</b> (integer) [0 .. 1]<br />
|
||||
When set to 1, items in this category will be sorted by title.<br />
|
||||
<br />
|
||||
<b class="fat">//$Color</b> (integer) [0 .. 19]<br />
|
||||
Sets the color used by things in this category.<br />Uses the same values as "<strong>//$Color</strong>" <a href="#color">thing definition</a>.<br />
|
||||
|
||||
<p><b class="fat">//$Arrow</b> (integer) [0 .. 1]<br />
|
||||
When set to 1, thing angle will be shown as an arrow in Classic and Visual modes.<br />
|
||||
<br />
|
||||
<b class="fat">//$Sprite</b> (string)<br />
|
||||
Sets the sprite graphic to use when rendering this thing or things in this category. This should be fully qualified sprite name without file extension, like "CPOSA2".<br />
|
||||
You can also use images from the"Sprites" directory by prefixing an image name without extension with "internal:", like so: "internal:Actor".<br />
|
||||
<br />
|
||||
<b class="fat">//$Error</b> (integer) [0 .. 2]<br />
|
||||
Sets the stuck things error checking mode to use on this thing. <br />
|
||||
Possible values are:
|
||||
|
||||
<ul>
|
||||
<li>0 - Don't check this thing.</li>
|
||||
<li>1 - Check if the thing is outside of map geometry.</li>
|
||||
<li>2 - Check if the thing is outside of map geometry or stuck in another thing.</li>
|
||||
</ul>
|
||||
Default value is<strong> 1</strong>.<br />
|
||||
<br />
|
||||
<b class="fat">//$FixedSize</b> (boolean)<br />
|
||||
When set to true, thing will be rendered as sizeless in Classic and Visual modes.<br />
|
||||
<br />
|
||||
<b class="fat">//$FixedRotation</b> (boolean)<br />
|
||||
When set to true, thing's angle won't be changed when rotating things using Edit Selection mode.<br />
|
||||
<br />
|
||||
<b class="fat">//$AbsoluteZ</b> (boolean)<br />
|
||||
When set to true, thing's vertical position will be used as an absolute value instead of distance from floor/ceiling in Visual mode.<br />
|
||||
<br />
|
||||
<strong>Example:</strong><br />
|
||||
<pre>
|
||||
#region Imp Balls
|
||||
//$Color 4
|
||||
//$Sprite "BALLS0"
|
||||
|
||||
actor SuperGiantImpBall : DoomImpBall
|
||||
{
|
||||
//$Title "I'm in the 'Imp Balls' group!"
|
||||
Scale 8.0
|
||||
Damage 30
|
||||
}
|
||||
|
||||
#endregion
|
||||
</pre>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -71,7 +71,7 @@ thingrenderstyles
|
|||
<b class="fat">sorted</b> (integer) [0 .. 1]<br />
|
||||
When set to 1, items in this category will be sorted by title.<br />
|
||||
<br />
|
||||
<span class="big">Thing and Thing Category definitions:</span><br />
|
||||
<span class="big"><a name="catdefs" id="catdefs"></a>Thing and Thing Category definitions:</span><br />
|
||||
These settings can be used inside of both thing category and thing definitions.<br />
|
||||
<br />
|
||||
<b class="fat">color</b> (integer) [0 .. 19]<br />
|
||||
|
@ -96,7 +96,7 @@ thingrenderstyles
|
|||
<li>15 - <span style="color:#F5F5F5">█</span> White;</li>
|
||||
<li>16 - <span style="color:#FFB6C1">█</span> Pink;</li>
|
||||
<li>17 - <span style="color:#FF8C00">█</span> Light Orange;</li>
|
||||
<li>18 - <span style="color:#BDB76B">█</span> Light Brown (default);</li>
|
||||
<li>18 - <span style="color:#BDB76B">█</span> Light Brown (<strong>default</strong>);</li>
|
||||
<li>19 - <span style="color:#DAA520">█</span> Orange;</li>
|
||||
</ul>
|
||||
<p><b class="fat">arrow</b> (integer) [0 .. 1]<br />
|
||||
|
|
|
@ -891,6 +891,7 @@
|
|||
<Compile Include="Rendering\VisualVertexHandle.cs" />
|
||||
<Compile Include="Geometry\Line3D.cs" />
|
||||
<Compile Include="Data\Scripting\ScriptHandlerAttribute.cs" />
|
||||
<Compile Include="ZDoom\DecorateCategoryInfo.cs" />
|
||||
<Compile Include="ZDoom\Scripting\DecorateParserSE.cs" />
|
||||
<Compile Include="ZDoom\GldefsParser.cs" />
|
||||
<Compile Include="ZDoom\MapinfoParser.cs" />
|
||||
|
|
|
@ -21,6 +21,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.ZDoom;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -96,7 +97,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
internal ThingCategory(ThingCategory parent, string name, string title)
|
||||
internal ThingCategory(ThingCategory parent, string name, string title, DecorateCategoryInfo catinfo)
|
||||
{
|
||||
// Initialize
|
||||
this.name = name;
|
||||
|
@ -143,6 +144,19 @@ namespace CodeImp.DoomBuilder.Config
|
|||
this.spritescale = 1.0f;
|
||||
}
|
||||
|
||||
//mxd. Apply DecorateCategoryInfo overrides...
|
||||
if(catinfo != null && catinfo.Properties.Count > 0)
|
||||
{
|
||||
this.sprite = catinfo.GetPropertyValueString("$sprite", 0, this.sprite);
|
||||
this.sorted = (catinfo.GetPropertyValueInt("$sort", 0, (this.sorted ? 1 : 0)) != 0);
|
||||
this.color = catinfo.GetPropertyValueInt("$color", 0, this.color);
|
||||
this.arrow = catinfo.GetPropertyValueInt("$arrow", 0, this.arrow);
|
||||
this.errorcheck = catinfo.GetPropertyValueInt("$error", 0, this.errorcheck);
|
||||
this.fixedsize = catinfo.GetPropertyValueBool("$fixedsize", 0, this.fixedsize);
|
||||
this.fixedrotation = catinfo.GetPropertyValueBool("$fixedrotation", 0, this.fixedrotation);
|
||||
this.absolutez = catinfo.GetPropertyValueBool("$absolutez", 0, this.absolutez);
|
||||
}
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public const string INTERNAL_PREFIX = "internal:";
|
||||
public const int CLASIC_IMAGE_NAME_LENGTH = 8; //mxd
|
||||
private const int MAX_SKYTEXTURE_SIZE = 2048; //mxd
|
||||
internal static readonly char[] CATEGORY_SPLITTER = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; //mxd
|
||||
|
||||
private long UNKNOWN_THING; //mxd
|
||||
private long MISSING_THING; //mxd
|
||||
|
@ -1735,7 +1736,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private int LoadDecorateThings(Dictionary<int, string> spawnnumsoverride, Dictionary<int, string> doomednumsoverride)
|
||||
{
|
||||
int counter = 0;
|
||||
char[] catsplitter = { Path.AltDirectorySeparatorChar }; //mxd
|
||||
|
||||
// Create new parser
|
||||
decorate = new DecorateParser { OnInclude = LoadDecorateFromLocation };
|
||||
|
@ -1792,13 +1792,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Check if we want to add this actor
|
||||
if(actor.DoomEdNum > 0)
|
||||
{
|
||||
string catname = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$category"));
|
||||
string[] catnames; //mxd
|
||||
if(string.IsNullOrEmpty(catname.Trim()))
|
||||
catnames = new[] { "decorate" };
|
||||
else
|
||||
catnames = catname.Split(catsplitter, StringSplitOptions.RemoveEmptyEntries); //mxd
|
||||
|
||||
// Check if we can find this thing in our existing collection
|
||||
if(thingtypes.ContainsKey(actor.DoomEdNum))
|
||||
{
|
||||
|
@ -1808,7 +1801,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
else
|
||||
{
|
||||
// Find the category to put the actor in
|
||||
ThingCategory cat = GetThingCategory(null, thingcategories, catnames); //mxd
|
||||
ThingCategory cat = GetThingCategory(null, thingcategories, GetCategoryInfo(actor)); //mxd
|
||||
|
||||
// Add new thing
|
||||
ThingTypeInfo t = new ThingTypeInfo(cat, actor);
|
||||
|
@ -1864,14 +1857,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(actor != null)
|
||||
{
|
||||
// Find the category to put the actor in
|
||||
string catname = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$category"));
|
||||
string[] catnames; //mxd
|
||||
if(string.IsNullOrEmpty(catname.Trim()))
|
||||
catnames = new[] { "decorate" };
|
||||
else
|
||||
catnames = catname.Split(catsplitter, StringSplitOptions.RemoveEmptyEntries); //mxd
|
||||
|
||||
ThingCategory cat = GetThingCategory(null, thingcategories, catnames); //mxd
|
||||
ThingCategory cat = GetThingCategory(null, thingcategories, GetCategoryInfo(actor)); //mxd
|
||||
|
||||
// Add a new ThingTypeInfo, replacing already existing one if necessary
|
||||
ThingTypeInfo info = new ThingTypeInfo(cat, actor, group.Key);
|
||||
|
@ -1965,17 +1951,21 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
//mxd
|
||||
private static ThingCategory GetThingCategory(ThingCategory parent, List<ThingCategory> categories, string[] catnames)
|
||||
private static ThingCategory GetThingCategory(ThingCategory parent, List<ThingCategory> categories, DecorateCategoryInfo catinfo)
|
||||
{
|
||||
// Find the category to put the actor in
|
||||
ThingCategory cat = null;
|
||||
string catname = catnames[0].ToLowerInvariant().Trim();
|
||||
string catname = (catinfo.Category.Count > 0 ? catinfo.Category[0].Trim().ToLowerInvariant() : string.Empty); //catnames[0].ToLowerInvariant().Trim();
|
||||
if(string.IsNullOrEmpty(catname)) catname = "decorate";
|
||||
|
||||
// First search by Title...
|
||||
foreach(ThingCategory c in categories)
|
||||
{
|
||||
if(c.Title.ToLowerInvariant() == catname) cat = c;
|
||||
if(string.Equals(c.Title, catname, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
cat = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Make full name
|
||||
|
@ -1986,30 +1976,59 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
foreach(ThingCategory c in categories)
|
||||
{
|
||||
if(c.Name.ToLowerInvariant() == catname) cat = c;
|
||||
if(string.Equals(c.Name, catname, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
cat = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make the category if needed
|
||||
if(cat == null)
|
||||
{
|
||||
string cattitle = catnames[0].Trim();
|
||||
string cattitle = (catinfo.Category.Count > 0 ? catinfo.Category[0].Trim() : string.Empty);
|
||||
if(string.IsNullOrEmpty(cattitle)) cattitle = "Decorate";
|
||||
cat = new ThingCategory(parent, catname, cattitle);
|
||||
cat = new ThingCategory(parent, catname, cattitle, catinfo);
|
||||
categories.Add(cat); // ^.^
|
||||
}
|
||||
|
||||
// Still have subcategories?
|
||||
if(catnames.Length > 1)
|
||||
if(catinfo.Category.Count > 1)
|
||||
{
|
||||
string[] remainingnames = new string[catnames.Length - 1];
|
||||
Array.Copy(catnames, 1, remainingnames, 0, remainingnames.Length);
|
||||
return GetThingCategory(cat, cat.Children, remainingnames);
|
||||
catinfo.Category.RemoveAt(0);
|
||||
return GetThingCategory(cat, cat.Children, catinfo);
|
||||
}
|
||||
|
||||
return cat;
|
||||
}
|
||||
|
||||
//mxd
|
||||
private static DecorateCategoryInfo GetCategoryInfo(ActorStructure actor)
|
||||
{
|
||||
string catname = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$category")).Trim();
|
||||
|
||||
DecorateCategoryInfo catinfo = new DecorateCategoryInfo();
|
||||
if(string.IsNullOrEmpty(catname))
|
||||
{
|
||||
if(actor.CategoryInfo != null)
|
||||
{
|
||||
catinfo.Category = new List<string>(actor.CategoryInfo.Category);
|
||||
catinfo.Properties = new Dictionary<string, List<string>>(actor.CategoryInfo.Properties);
|
||||
}
|
||||
else
|
||||
{
|
||||
catinfo.Category = new List<string> { "Decorate" };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
catinfo.Category = catname.Split(CATEGORY_SPLITTER, StringSplitOptions.RemoveEmptyEntries).ToList(); //mxd
|
||||
}
|
||||
|
||||
return catinfo;
|
||||
}
|
||||
|
||||
// This loads Decorate data from a specific file or lump name
|
||||
private void LoadDecorateFromLocation(DecorateParser parser, string location)
|
||||
{
|
||||
|
|
|
@ -55,6 +55,9 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
private Dictionary<string, List<string>> props;
|
||||
private readonly Dictionary<string, UniversalType> uservars; //mxd
|
||||
|
||||
//mxd. Categories
|
||||
private DecorateCategoryInfo catinfo;
|
||||
|
||||
// States
|
||||
private Dictionary<string, StateStructure> states;
|
||||
|
||||
|
@ -70,15 +73,17 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
public ActorStructure BaseClass { get { return baseclass; } }
|
||||
internal int DoomEdNum { get { return doomednum; } set { doomednum = value; } }
|
||||
public Dictionary<string, UniversalType> UserVars { get { return uservars; } } //mxd
|
||||
internal DecorateCategoryInfo CategoryInfo { get { return catinfo; } } //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
internal ActorStructure(DecorateParser parser)
|
||||
internal ActorStructure(DecorateParser parser, DecorateCategoryInfo catinfo)
|
||||
{
|
||||
// Initialize
|
||||
this.catinfo = catinfo; //mxd
|
||||
flags = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
props = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
states = new Dictionary<string, StateStructure>(StringComparer.OrdinalIgnoreCase);
|
||||
|
|
72
Source/Core/ZDoom/DecorateCategoryInfo.cs
Normal file
72
Source/Core/ZDoom/DecorateCategoryInfo.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.ZDoom
|
||||
{
|
||||
internal class DecorateCategoryInfo
|
||||
{
|
||||
#region ================== Properties
|
||||
|
||||
public List<string> Category;
|
||||
public Dictionary<string, List<string>> Properties;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
public DecorateCategoryInfo()
|
||||
{
|
||||
Category = new List<string>(1);
|
||||
Properties = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
public string GetPropertyValueString(string propname, int valueindex, string defaultvalue) { return GetPropertyValueString(propname, valueindex, defaultvalue, true); }
|
||||
public string GetPropertyValueString(string propname, int valueindex, string defaultvalue, bool stripquotes)
|
||||
{
|
||||
if(Properties.ContainsKey(propname) && (Properties[propname].Count > valueindex))
|
||||
return (stripquotes ? ZDTextParser.StripQuotes(Properties[propname][valueindex]) : Properties[propname][valueindex]);
|
||||
return defaultvalue;
|
||||
}
|
||||
|
||||
public bool GetPropertyValueBool(string propname, int valueindex, bool defaultvalue)
|
||||
{
|
||||
string str = GetPropertyValueString(propname, valueindex, string.Empty, false).ToLowerInvariant();
|
||||
return (string.IsNullOrEmpty(str) ? defaultvalue : str == "true");
|
||||
}
|
||||
|
||||
public int GetPropertyValueInt(string propname, int valueindex, int defaultvalue)
|
||||
{
|
||||
string str = GetPropertyValueString(propname, valueindex, string.Empty, false);
|
||||
|
||||
// It can be negative...
|
||||
if(str == "-" && Properties.Count > valueindex + 1)
|
||||
str += GetPropertyValueString(propname, valueindex + 1, String.Empty, false);
|
||||
|
||||
int intvalue;
|
||||
return (int.TryParse(str, NumberStyles.Integer, CultureInfo.InvariantCulture, out intvalue) ? intvalue : defaultvalue);
|
||||
}
|
||||
|
||||
public float GetPropertyValueFloat(string propname, int valueindex, float defaultvalue)
|
||||
{
|
||||
string str = GetPropertyValueString(propname, valueindex, string.Empty, false);
|
||||
|
||||
// It can be negative...
|
||||
if(str == "-" && Properties.Count > valueindex + 1)
|
||||
str += GetPropertyValueString(propname, valueindex + 1, string.Empty, false);
|
||||
|
||||
float fvalue;
|
||||
return (float.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out fvalue) ? fvalue : defaultvalue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -100,6 +100,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
// Syntax
|
||||
whitespace = "\n \t\r\u00A0"; //mxd. non-breaking space is also space :)
|
||||
specialtokens = ":{}[]()+-\n;,";
|
||||
skipregions = false; //mxd
|
||||
|
||||
// Initialize
|
||||
actors = new Dictionary<string, ActorStructure>(StringComparer.OrdinalIgnoreCase);
|
||||
|
@ -142,6 +143,9 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
// Cannot process?
|
||||
if(!base.Parse(data, clearerrors)) return false;
|
||||
|
||||
//mxd. Region-as-category stuff...
|
||||
List<DecorateCategoryInfo> regions = new List<DecorateCategoryInfo>(); //mxd
|
||||
|
||||
// Keep local data
|
||||
Stream localstream = datastream;
|
||||
string localsourcename = sourcename;
|
||||
|
@ -163,7 +167,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
case "actor":
|
||||
{
|
||||
// Read actor structure
|
||||
ActorStructure actor = new ActorStructure(this);
|
||||
ActorStructure actor = new ActorStructure(this, (regions.Count > 0 ? regions[regions.Count - 1] : null));
|
||||
if(this.HasError) return false;
|
||||
|
||||
// Add the actor
|
||||
|
@ -290,13 +294,52 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
}
|
||||
break;
|
||||
|
||||
//mxd. Region-as-category handling
|
||||
case "#region":
|
||||
SkipWhitespace(false);
|
||||
string cattitle = ReadLine();
|
||||
if(!string.IsNullOrEmpty(cattitle))
|
||||
{
|
||||
// Make new category info
|
||||
string[] parts = cattitle.Split(DataManager.CATEGORY_SPLITTER, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
DecorateCategoryInfo info = new DecorateCategoryInfo();
|
||||
if(regions.Count > 0)
|
||||
{
|
||||
// Preserve nesting
|
||||
info.Category.AddRange(regions[regions.Count - 1].Category);
|
||||
info.Properties = new Dictionary<string, List<string>>(regions[regions.Count - 1].Properties);
|
||||
}
|
||||
info.Category.AddRange(parts);
|
||||
|
||||
// Add to collection
|
||||
regions.Add(info);
|
||||
}
|
||||
break;
|
||||
|
||||
//mxd. Region-as-category handling
|
||||
case "#endregion":
|
||||
if(regions.Count > 0)
|
||||
regions.RemoveAt(regions.Count - 1);
|
||||
else
|
||||
LogWarning("Unexpected #endregion token");
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
//mxd. In some special cases (like the whole actor commented using "//") our special comments will be detected here...
|
||||
if(objdeclaration.StartsWith("$"))
|
||||
{
|
||||
// So skip the whole line, then carry on
|
||||
if(regions.Count > 0)
|
||||
{
|
||||
// Store region property
|
||||
regions[regions.Count - 1].Properties[objdeclaration] = new List<string> { (SkipWhitespace(false) ? ReadLine() : "") };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip the whole line, then carry on
|
||||
ReadLine();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
// Parsing
|
||||
protected string whitespace = "\n \t\r\u00A0\0"; //mxd. non-breaking space is also space :)
|
||||
protected string specialtokens = ":{}+-\n;";
|
||||
protected bool skipregions; //mxd
|
||||
|
||||
// Input data stream
|
||||
protected Stream datastream;
|
||||
|
@ -90,6 +91,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
errordesc = null;
|
||||
textresources = new Dictionary<string, TextResource>(StringComparer.OrdinalIgnoreCase); //mxd
|
||||
untrackedtextresources = new HashSet<string>(StringComparer.OrdinalIgnoreCase); //mxd
|
||||
skipregions = true; //mxd
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -276,7 +278,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
}
|
||||
}
|
||||
//mxd. Region/endregion handling
|
||||
else if(c == '#')
|
||||
else if(skipregions && c == '#')
|
||||
{
|
||||
string s = ReadToken(false).ToLowerInvariant();
|
||||
if(s == "region" || s == "endregion")
|
||||
|
|
Loading…
Reference in a new issue