mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Fixed, DECORATE support: "DistanceCheck" value is a CVAR name, not an actual value.
Internal: added CVARINFO parser.
This commit is contained in:
parent
fd0e1c754a
commit
952e895af0
10 changed files with 383 additions and 18 deletions
|
@ -811,6 +811,7 @@
|
|||
<Compile Include="Data\CameraTextureImage.cs" />
|
||||
<Compile Include="Data\ColorImage.cs" />
|
||||
<Compile Include="Data\ColormapImage.cs" />
|
||||
<Compile Include="Data\CvarsCollection.cs" />
|
||||
<Compile Include="Data\HiResImage.cs" />
|
||||
<Compile Include="Data\TEXTURESImage.cs" />
|
||||
<Compile Include="Data\PK3FileImage.cs" />
|
||||
|
@ -1026,6 +1027,7 @@
|
|||
</Compile>
|
||||
<Compile Include="ZDoom\ActorStructure.cs" />
|
||||
<Compile Include="ZDoom\AnimdefsParser.cs" />
|
||||
<Compile Include="ZDoom\CvarInfoParser.cs" />
|
||||
<Compile Include="ZDoom\PatchStructure.cs" />
|
||||
<Compile Include="ZDoom\ReverbsParser.cs" />
|
||||
<Compile Include="ZDoom\SndSeqParser.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<ScriptConfiguration>
|
||||
|
|
|
@ -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
|
||||
|
|
82
Source/Core/Data/CvarsCollection.cs
Normal file
82
Source/Core/Data/CvarsCollection.cs
Normal file
|
@ -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<string, int> Integers;
|
||||
internal readonly Dictionary<string, float> Floats;
|
||||
internal readonly Dictionary<string, PixelColor> Colors;
|
||||
internal readonly Dictionary<string, bool> Booleans;
|
||||
internal readonly Dictionary<string, string> Strings;
|
||||
private readonly HashSet<string> allnames;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
public CvarsCollection()
|
||||
{
|
||||
Integers = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
Floats = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase);
|
||||
Colors = new Dictionary<string, PixelColor>(StringComparer.OrdinalIgnoreCase);
|
||||
Booleans = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
Strings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
allnames = new HashSet<string>(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
|
||||
}
|
||||
}
|
|
@ -104,6 +104,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private string[] terrainnames;
|
||||
private string[] damagetypes;
|
||||
private Dictionary<string, PixelColor> knowncolors; // Colors parsed from X11R6RGB lump. Color names are lowercase without spaces
|
||||
private CvarsCollection cvars; // Variables parsed from CVARINFO
|
||||
|
||||
//mxd. Text resources
|
||||
private Dictionary<ScriptType, HashSet<TextResource>> textresources;
|
||||
|
@ -166,6 +167,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public string[] DamageTypes { get { return damagetypes; } }
|
||||
public Dictionary<string, PixelColor> KnownColors { get { return knowncolors; } }
|
||||
internal Dictionary<ScriptType, HashSet<TextResource>> TextResources { get { return textresources; } }
|
||||
internal CvarsCollection CVars { get { return cvars; } }
|
||||
|
||||
//mxd
|
||||
internal IEnumerable<DataReader> Containers { get { return containers; } }
|
||||
|
@ -340,6 +342,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
textresources = new Dictionary<ScriptType, HashSet<TextResource>>();
|
||||
damagetypes = new string[0];
|
||||
knowncolors = new Dictionary<string, PixelColor>(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<int, string> 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<TextResourceData> 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<TextResource>(parser.TextResources.Values);
|
||||
currentreader = null;
|
||||
|
||||
// Set as collection
|
||||
cvars = parser.Cvars;
|
||||
}
|
||||
|
||||
//mxd
|
||||
internal TextResourceData GetTextResourceData(string name)
|
||||
{
|
||||
|
|
|
@ -247,6 +247,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
//mxd. When implemented, this returns the X11R6RGB lump
|
||||
public abstract IEnumerable<TextResourceData> GetX11R6RGBData();
|
||||
|
||||
//mxd. When implemented, this returns the CVARINFO lump
|
||||
public abstract IEnumerable<TextResourceData> GetCvarInfoData();
|
||||
|
||||
//mxd. When implemented, this returns the list of voxel model names
|
||||
public abstract IEnumerable<string> GetVoxelNames();
|
||||
|
||||
|
|
|
@ -766,6 +766,28 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== CVARINFO (mxd)
|
||||
|
||||
public override IEnumerable<TextResourceData> GetCvarInfoData()
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
List<TextResourceData> result = new List<TextResourceData>();
|
||||
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
|
||||
|
|
|
@ -1044,6 +1044,13 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return GetAllLumps("X11R6RGB");
|
||||
}
|
||||
|
||||
//mxd
|
||||
public override IEnumerable<TextResourceData> GetCvarInfoData()
|
||||
{
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
return GetAllLumps("CVARINFO");
|
||||
}
|
||||
|
||||
//mxd
|
||||
private IEnumerable<TextResourceData> GetFirstLump(string name)
|
||||
{
|
||||
|
|
208
Source/Core/ZDoom/CvarInfoParser.cs
Normal file
208
Source/Core/ZDoom/CvarInfoParser.cs
Normal file
|
@ -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<string> knowntypes = new HashSet<string> { "int", "float", "color", "bool", "string" };
|
||||
while(SkipWhitespace(true))
|
||||
{
|
||||
string token = ReadToken().ToLowerInvariant();
|
||||
if(string.IsNullOrEmpty(token)) continue;
|
||||
|
||||
//<scope> [noarchive] <type> <name> [= <defaultvalue>];
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue