From 952e895af0439e43b7cf912bd78fc129c6db15f7 Mon Sep 17 00:00:00 2001 From: MaxED Date: Wed, 13 Apr 2016 14:11:35 +0000 Subject: [PATCH] Fixed, DECORATE support: "DistanceCheck" value is a CVAR name, not an actual value. Internal: added CVARINFO parser. --- Source/Core/Builder.csproj | 2 + Source/Core/Config/ScriptConfiguration.cs | 27 +-- Source/Core/Config/ThingTypeInfo.cs | 14 +- Source/Core/Data/CvarsCollection.cs | 82 +++++++++ Source/Core/Data/DataManager.cs | 35 +++- Source/Core/Data/DataReader.cs | 3 + Source/Core/Data/PK3StructuredReader.cs | 22 +++ Source/Core/Data/WADReader.cs | 7 + Source/Core/ZDoom/CvarInfoParser.cs | 208 ++++++++++++++++++++++ Source/Core/ZDoom/X11R6RGBParser.cs | 1 - 10 files changed, 383 insertions(+), 18 deletions(-) create mode 100644 Source/Core/Data/CvarsCollection.cs create mode 100644 Source/Core/ZDoom/CvarInfoParser.cs diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 8f63f38d..1f3e8566 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -811,6 +811,7 @@ + @@ -1026,6 +1027,7 @@ + diff --git a/Source/Core/Config/ScriptConfiguration.cs b/Source/Core/Config/ScriptConfiguration.cs index 1d73c45a..e8d33473 100644 --- a/Source/Core/Config/ScriptConfiguration.cs +++ b/Source/Core/Config/ScriptConfiguration.cs @@ -30,19 +30,20 @@ namespace CodeImp.DoomBuilder.Config //mxd public enum ScriptType { - UNKNOWN = 0, - ACS = 1, - MODELDEF = 2, - DECORATE = 3, - GLDEFS = 4, - SNDSEQ = 5, - MAPINFO = 6, - VOXELDEF = 7, - TEXTURES = 8, - ANIMDEFS = 9, - REVERBS = 10, - TERRAIN = 11, - X11R6RGB = 12, + UNKNOWN, + ACS, + MODELDEF, + DECORATE, + GLDEFS, + SNDSEQ, + MAPINFO, + VOXELDEF, + TEXTURES, + ANIMDEFS, + REVERBS, + TERRAIN, + X11R6RGB, + CVARINFO, } internal class ScriptConfiguration : IComparable diff --git a/Source/Core/Config/ThingTypeInfo.cs b/Source/Core/Config/ThingTypeInfo.cs index 376824f1..0882f240 100644 --- a/Source/Core/Config/ThingTypeInfo.cs +++ b/Source/Core/Config/ThingTypeInfo.cs @@ -475,11 +475,19 @@ namespace CodeImp.DoomBuilder.Config if(actor.HasPropertyWithValue("radius")) radius = actor.GetPropertyValueInt("radius", 0); if(actor.HasPropertyWithValue("height")) height = actor.GetPropertyValueInt("height", 0); - //mxd. DistanceCheck. We'll need squared value + //mxd. DistanceCheck. The value is CVAR. Also we'll need squared value if(actor.HasPropertyWithValue("distancecheck")) { - distancechecksq = actor.GetPropertyValueInt("distancecheck", 0); - distancechecksq = (distancechecksq == 0 ? int.MaxValue : distancechecksq * distancechecksq); + string cvarname = actor.GetPropertyValueString("distancecheck", 0); + if(!General.Map.Data.CVars.Integers.ContainsKey(cvarname)) + { + General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". DistanceCheck property references undefined cvar \"" + cvarname + "\""); + distancechecksq = int.MaxValue; + } + else + { + distancechecksq = (int)Math.Pow(General.Map.Data.CVars.Integers[cvarname], 2); + } } //mxd. Renderstyle diff --git a/Source/Core/Data/CvarsCollection.cs b/Source/Core/Data/CvarsCollection.cs new file mode 100644 index 00000000..5b236f19 --- /dev/null +++ b/Source/Core/Data/CvarsCollection.cs @@ -0,0 +1,82 @@ +#region ================== Namespaces + +using System; +using System.Collections.Generic; +using CodeImp.DoomBuilder.Rendering; + +#endregion + +namespace CodeImp.DoomBuilder.Data +{ + internal class CvarsCollection + { + #region ================== Variables + + internal readonly Dictionary Integers; + internal readonly Dictionary Floats; + internal readonly Dictionary Colors; + internal readonly Dictionary Booleans; + internal readonly Dictionary Strings; + private readonly HashSet allnames; + + #endregion + + #region ================== Constructor + + public CvarsCollection() + { + Integers = new Dictionary(StringComparer.OrdinalIgnoreCase); + Floats = new Dictionary(StringComparer.OrdinalIgnoreCase); + Colors = new Dictionary(StringComparer.OrdinalIgnoreCase); + Booleans = new Dictionary(StringComparer.OrdinalIgnoreCase); + Strings = new Dictionary(StringComparer.OrdinalIgnoreCase); + allnames = new HashSet(StringComparer.OrdinalIgnoreCase); + } + + #endregion + + #region ================== Methods + + public bool AddValue(string name, int value) + { + if(allnames.Contains(name)) return false; + allnames.Add(name); + Integers.Add(name, value); + return true; + } + + public bool AddValue(string name, float value) + { + if(allnames.Contains(name)) return false; + allnames.Add(name); + Floats.Add(name, value); + return true; + } + + public bool AddValue(string name, PixelColor value) + { + if(allnames.Contains(name)) return false; + allnames.Add(name); + Colors.Add(name, value); + return true; + } + + public bool AddValue(string name, bool value) + { + if(allnames.Contains(name)) return false; + allnames.Add(name); + Booleans.Add(name, value); + return true; + } + + public bool AddValue(string name, string value) + { + if(allnames.Contains(name)) return false; + allnames.Add(name); + Strings.Add(name, value); + return true; + } + + #endregion + } +} diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 7bbaacc8..7d17d249 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -104,6 +104,7 @@ namespace CodeImp.DoomBuilder.Data private string[] terrainnames; private string[] damagetypes; private Dictionary knowncolors; // Colors parsed from X11R6RGB lump. Color names are lowercase without spaces + private CvarsCollection cvars; // Variables parsed from CVARINFO //mxd. Text resources private Dictionary> textresources; @@ -166,6 +167,7 @@ namespace CodeImp.DoomBuilder.Data public string[] DamageTypes { get { return damagetypes; } } public Dictionary KnownColors { get { return knowncolors; } } internal Dictionary> TextResources { get { return textresources; } } + internal CvarsCollection CVars { get { return cvars; } } //mxd internal IEnumerable Containers { get { return containers; } } @@ -340,6 +342,7 @@ namespace CodeImp.DoomBuilder.Data textresources = new Dictionary>(); damagetypes = new string[0]; knowncolors = new Dictionary(StringComparer.OrdinalIgnoreCase); + cvars = new CvarsCollection(); //mxd // Load texture sets foreach(DefinedTextureSet ts in General.Map.ConfigSettings.TextureSets) @@ -416,9 +419,10 @@ namespace CodeImp.DoomBuilder.Data LoadSprites(cachedparsers); cachedparsers = null; //mxd - //mxd. Load MAPINFO. Should happen before parisng DECORATE + //mxd. Load MAPINFO and CVARINFO. Should happen before parisng DECORATE Dictionary spawnnums, doomednums; LoadMapInfo(out spawnnums, out doomednums); + LoadCvarInfo(); int thingcount = LoadDecorateThings(spawnnums, doomednums); int spritecount = LoadThingSprites(); @@ -613,6 +617,7 @@ namespace CodeImp.DoomBuilder.Data textresources = null; //mxd damagetypes = null; //mxd knowncolors = null; //mxd + cvars = null; //mxd texturenames = null; flatnames = null; imageque = null; @@ -2577,6 +2582,34 @@ namespace CodeImp.DoomBuilder.Data knowncolors = parser.KnownColors; } + //mxd. This loads CVARINFO lumps + private void LoadCvarInfo() + { + CvarInfoParser parser = new CvarInfoParser(); + + foreach(DataReader dr in containers) + { + currentreader = dr; + IEnumerable streams = dr.GetCvarInfoData(); + + // Parse the data + foreach(TextResourceData data in streams) + { + parser.Parse(data, true); + + // Report errors? + if(parser.HasError) parser.LogError(); + } + } + + // Add to text resources collection + textresources[parser.ScriptType] = new HashSet(parser.TextResources.Values); + currentreader = null; + + // Set as collection + cvars = parser.Cvars; + } + //mxd internal TextResourceData GetTextResourceData(string name) { diff --git a/Source/Core/Data/DataReader.cs b/Source/Core/Data/DataReader.cs index bf9e74de..42ac1a0e 100644 --- a/Source/Core/Data/DataReader.cs +++ b/Source/Core/Data/DataReader.cs @@ -247,6 +247,9 @@ namespace CodeImp.DoomBuilder.Data //mxd. When implemented, this returns the X11R6RGB lump public abstract IEnumerable GetX11R6RGBData(); + //mxd. When implemented, this returns the CVARINFO lump + public abstract IEnumerable GetCvarInfoData(); + //mxd. When implemented, this returns the list of voxel model names public abstract IEnumerable GetVoxelNames(); diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs index e70381f6..5b088758 100644 --- a/Source/Core/Data/PK3StructuredReader.cs +++ b/Source/Core/Data/PK3StructuredReader.cs @@ -766,6 +766,28 @@ namespace CodeImp.DoomBuilder.Data #endregion + #region ================== CVARINFO (mxd) + + public override IEnumerable GetCvarInfoData() + { + // Error when suspended + if(issuspended) throw new Exception("Data reader is suspended"); + + List result = new List(); + string[] files = GetAllFilesWithTitle("", "CVARINFO", false); + + // Add to collection + foreach(string s in files) + result.Add(new TextResourceData(this, LoadFile(s), s, true)); + + // Find in any of the wad files + foreach(WADReader wr in wads) result.AddRange(wr.GetCvarInfoData()); + + return result; + } + + #endregion + #region ================== Methods // This loads the images in this directory diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs index 06437efd..4d2294d4 100644 --- a/Source/Core/Data/WADReader.cs +++ b/Source/Core/Data/WADReader.cs @@ -1044,6 +1044,13 @@ namespace CodeImp.DoomBuilder.Data return GetAllLumps("X11R6RGB"); } + //mxd + public override IEnumerable GetCvarInfoData() + { + if(issuspended) throw new Exception("Data reader is suspended"); + return GetAllLumps("CVARINFO"); + } + //mxd private IEnumerable GetFirstLump(string name) { diff --git a/Source/Core/ZDoom/CvarInfoParser.cs b/Source/Core/ZDoom/CvarInfoParser.cs new file mode 100644 index 00000000..f0ad7c47 --- /dev/null +++ b/Source/Core/ZDoom/CvarInfoParser.cs @@ -0,0 +1,208 @@ +#region ================== Namespaces + +using System.Collections.Generic; +using System.Globalization; +using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.Data; +using CodeImp.DoomBuilder.Rendering; + +#endregion + +namespace CodeImp.DoomBuilder.ZDoom +{ + internal sealed class CvarInfoParser : ZDTextParser + { + #region ================== Variables + + private CvarsCollection cvars; + + #endregion + + #region ================== Properties + + internal override ScriptType ScriptType { get { return ScriptType.CVARINFO; } } + + public CvarsCollection Cvars { get { return cvars; } } + + #endregion + + #region ================== Constructor + + internal CvarInfoParser() + { + cvars = new CvarsCollection(); + } + + #endregion + + #region ================== Parsing + + public override bool Parse(TextResourceData data, bool clearerrors) + { + // Already parsed? + if(!base.AddTextResource(data)) + { + if(clearerrors) ClearError(); + return true; + } + + // Cannot process? + if(!base.Parse(data, clearerrors)) return false; + + // Continue until at the end of the stream + HashSet knowntypes = new HashSet { "int", "float", "color", "bool", "string" }; + while(SkipWhitespace(true)) + { + string token = ReadToken().ToLowerInvariant(); + if(string.IsNullOrEmpty(token)) continue; + + // [noarchive] [= ]; + switch(token) + { + case "user": case "server": + // Type + SkipWhitespace(true); + string type = ReadToken().ToLowerInvariant(); + + // Can be "noarchive" keyword + if(type == "noarchive") + { + SkipWhitespace(true); + type = ReadToken().ToLowerInvariant(); + } + + if(!knowntypes.Contains(type)) + { + ReportError("Unknown cvar type"); + return false; + } + + // Name + SkipWhitespace(true); + string name = ReadToken(); + + if(string.IsNullOrEmpty(name)) + { + ReportError("Expected cvar name"); + return false; + } + + // Either "=" or ";" + SkipWhitespace(true); + token = ReadToken(); + + switch(token) + { + case "=": + SkipWhitespace(true); + string value = ReadToken(); + + if(string.IsNullOrEmpty(value)) + { + ReportError("Expected \"" + name + "\" cvar value"); + return false; + } + + // Add to collection + if(!AddValue(name, type, value)) return false; + + // Next should be ";" + if(!NextTokenIs(";")) return false; + break; + + case ";": + if(!AddValue(name, type, string.Empty)) return false; + break; + } + + break; + + default: + ReportError("Unknown keyword"); + return false; + } + } + + return true; + } + + private bool AddValue(string name, string type, string value) + { + switch(type) + { + case "int": + int iv = 0; + if(!string.IsNullOrEmpty(value) && !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out iv)) + { + ReportError("Cvar \"" + name + "\" has invalid integer value: \"" + value + "\""); + return false; + } + if(!cvars.AddValue(name, iv)) + { + ReportError("Cvar \"" + name + "\" is double defined"); + return false; + } + break; + + case "float": + float fv = 0f; + if(!string.IsNullOrEmpty(value) && !float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out fv)) + { + ReportError("Cvar \"" + name + "\" has invalid decimal value: \"" + value + "\""); + return false; + } + if(!cvars.AddValue(name, fv)) + { + ReportError("Cvar \"" + name + "\" is double defined"); + return false; + } + break; + + case "color": + PixelColor cv = new PixelColor(); + if(!string.IsNullOrEmpty(value) && !GetColorFromString(value, ref cv)) + { + ReportError("Cvar \"" + name + "\" has invalid color value: \"" + value + "\""); + return false; + } + if(!cvars.AddValue(name, cv)) + { + ReportError("Cvar \"" + name + "\" is double defined"); + return false; + } + break; + + case "bool": + bool bv = false; + if(!string.IsNullOrEmpty(value)) + { + string sv = value.ToLowerInvariant(); + if(sv != "true" && sv != "false") + { + ReportError("Cvar \"" + name + "\" has invalid boolean value: \"" + value + "\""); + return false; + } + bv = (sv == "true"); + } + if(!cvars.AddValue(name, bv)) + { + ReportError("Cvar \"" + name + "\" is double defined"); + return false; + } + break; + + case "string": + if(!cvars.AddValue(name, StripQuotes(value))) + { + ReportError("Cvar \"" + name + "\" is double defined"); + return false; + } + break; + } + + return true; + } + + #endregion + } +} diff --git a/Source/Core/ZDoom/X11R6RGBParser.cs b/Source/Core/ZDoom/X11R6RGBParser.cs index 18bec45d..9fb3a6cb 100644 --- a/Source/Core/ZDoom/X11R6RGBParser.cs +++ b/Source/Core/ZDoom/X11R6RGBParser.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Rendering;