Added LOCKDEFS parser.

Changed, Game Configurations: changed "basegame" value type from int to string.
Updated documentation.
This commit is contained in:
MaxED 2016-07-14 23:39:48 +00:00
parent baa303261a
commit 09e1eef95c
21 changed files with 282 additions and 48 deletions

View file

@ -1,6 +1,6 @@
// Default lump name for new map
defaultlumpname = "MAP01";
basegame = 1; //mxd: 0 - UNKNOWN, 1 - DOOM, 2 - HERETIC, 3 - HEXEN, 4 - STRIFE
basegame = "Doom";
// Decorate actors to include depending on actor game property
decorategames = "doom";

View file

@ -1,6 +1,6 @@
// Default lump name for new map
defaultlumpname = "E1M1";
basegame = 2;
basegame = "Heretic";
// Decorate actors to include depending on actor game property
decorategames = "heretic raven";

View file

@ -1,7 +1,7 @@
// Default lump name for new map
defaultlumpname = "MAP01";
skyflatname = "F_SKY";
basegame = 3;
basegame = "Hexen";
// Decorate actors to include depending on actor game property
decorategames = "hexen raven";

View file

@ -1,7 +1,7 @@
// Default lump name for new map
defaultlumpname = "MAP01";
skyflatname = "F_SKY001";
basegame = 4;
basegame = "Strife";
// Decorate actors to include depending on actor game property
decorategames = "strife";

View file

@ -1,5 +1,6 @@
// Default lump name for new map
defaultlumpname = "MAP01";
basegame = "Chex";
// Decorate actors to include depending on actor game property
decorategames = "chex";

View file

@ -1,5 +1,6 @@
// Default lump name for new map
defaultlumpname = "MAP01";
basegame = "Chex";
// Decorate actors to include depending on actor game property
decorategames = "chex";

View file

@ -31,10 +31,10 @@
<b class="fat">thingclasshelp</b> (string) - <span class="red">GZDB only</span>.<br />
The URL to open when thing class name is clicked in the Thing Edit form. &quot;<strong>%K</strong>&quot; wildcard is replaced by <strong>classname</strong> property defined in thing definition or by DECORATE actor name.<br />
<br />
<b class="fat">basegame</b> (integer) [0 .. 4] - <span class="red">GZDB only</span>.<br />
<b class="fat">basegame</b> (string) - <span class="red">GZDB only</span>.<br />
Indicates which game the current configuration is based on. Used to load game-specific GLDEFS lumps (DOOMDEFS, HTICDEFS, HEXNDEFS or STRFDEFS). <br />
<b>Possible values:</b> 1 (DOOM), 2 (HERETIC), 3 (HEXEN) or 4 (STRIFE).<br />
Default value is <b>0</b> (don't load game-specific lumps).<br />
<b>Possible values:</b> &quot;Doom&quot;, &quot;Heretic&quot;, &quot;Hexen&quot;, &quot;Strife&quot; or &quot;Chex&quot;.<br />
If left unset, game-specific lumps won't be loaded.<br />
<br />
<b class="fat">engine</b> (string)<br />
Game engine/sourceport name. This is used as the UDMF namespace for UDMF map format interface. It currently has no other function.<br />

View file

@ -62,6 +62,8 @@
<h2>SNDSEQ:</h2>
Sound Sequence and Sound Sequence Group definitions are loaded and can be selected in the "Sound sequence" drop-down of the Edit Sector window (UDMF only).
<h2>LOCKDEFS:</h2>
Lock definitions are loaded. The values are used to populate &quot;<strong>keys</strong>&quot; Game Configuration enum.
<h2>TERRAIN:</h2>
Terrain names are loaded and used in the floor and ceiling "Terrain" drop-downs of the Edit Sector window (UDMF only).

View file

@ -881,7 +881,7 @@
</Compile>
<Compile Include="GZBuilder\Data\BoundingBox.cs" />
<Compile Include="GZBuilder\Data\EngineInfo.cs" />
<Compile Include="GZBuilder\Data\GameType.cs" />
<Compile Include="Config\GameType.cs" />
<Compile Include="GZBuilder\Data\DynamicLight.cs" />
<Compile Include="GZBuilder\Data\GlowingFlatData.cs" />
<Compile Include="GZBuilder\Data\LinedefColorPreset.cs" />
@ -899,6 +899,7 @@
<Compile Include="Geometry\Line3D.cs" />
<Compile Include="Data\Scripting\ScriptHandlerAttribute.cs" />
<Compile Include="ZDoom\DecorateCategoryInfo.cs" />
<Compile Include="ZDoom\LockDefsParser.cs" />
<Compile Include="ZDoom\Scripting\DecorateParserSE.cs" />
<Compile Include="ZDoom\GldefsParser.cs" />
<Compile Include="ZDoom\MapinfoParser.cs" />

View file

@ -45,9 +45,10 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Constructor
// Constructor for custom list
internal EnumList()
{
}
internal EnumList() { }
//mxd. Constructor for custom list
internal EnumList(int capacity) : base(capacity) { }
// Constructor to load from dictionary
internal EnumList(IDictionary dic)

View file

@ -159,7 +159,7 @@ namespace CodeImp.DoomBuilder.Config
private readonly List<ThingsFilter> thingfilters;
//mxd. Holds base game type (doom, heretic, hexen or strife)
private readonly GameType gametype;
private readonly string basegame;
#endregion
@ -281,7 +281,7 @@ namespace CodeImp.DoomBuilder.Config
public List<ThingsFilter> ThingsFilters { get { return thingfilters; } }
//mxd
public GameType GameType { get { return gametype; } }
public string BaseGame { get { return basegame; } }
#endregion
@ -328,8 +328,13 @@ namespace CodeImp.DoomBuilder.Config
configname = cfg.ReadSetting("game", "<unnamed game>");
//mxd
int gt = (cfg.ReadSetting("basegame", (int)GameType.UNKNOWN));
gametype = ( (gt > -1 && gt < Gldefs.GLDEFS_LUMPS_PER_GAME.Length) ? (GameType)gt : GameType.UNKNOWN);
basegame = cfg.ReadSetting("basegame", string.Empty).ToLowerInvariant();
if(!GameType.GameTypes.Contains(basegame))
{
if(!string.IsNullOrEmpty(basegame))
General.ErrorLogger.Add(ErrorType.Error, "Unknown basegame value specified in current Game Configuration: \"" + basegame + "\"");
basegame = GameType.UNKNOWN;
}
enginename = cfg.ReadSetting("engine", "");
defaultsavecompiler = cfg.ReadSetting("defaultsavecompiler", "");

View file

@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace CodeImp.DoomBuilder.Config
{
public struct GameType
{
public const string UNKNOWN = "UNKNOWN_GAME";
public const string DOOM = "doom";
public const string HERETIC = "heretic";
public const string HEXEN = "hexen";
public const string STRIFE = "strife";
public const string CHEX = "chex";
public static readonly HashSet<string> GameTypes = new HashSet<string> { DOOM, HERETIC, HEXEN, STRIFE, CHEX };
public static readonly Dictionary<string, string> GldefsLumpsPerGame = new Dictionary<string, string>
{
{ DOOM, "DOOMDEFS" },
{ HERETIC, "HTICDEFS" },
{ HEXEN, "HEXNDEFS" },
{ STRIFE, "STRFDEFS" },
{ CHEX, "DOOMDEFS" }, // Is that so?..
};
}
}

View file

@ -45,6 +45,7 @@ namespace CodeImp.DoomBuilder.Config
X11R6RGB,
CVARINFO,
SNDINFO,
LOCKDEFS,
}
internal class ScriptConfiguration : IComparable<ScriptConfiguration>

View file

@ -514,7 +514,7 @@ namespace CodeImp.DoomBuilder.Config
}
else if(actor.HasProperty("defaultalpha"))
{
this.alpha = (General.Map.Config.GameType == GameType.HERETIC ? 0.4f : 0.6f);
this.alpha = (General.Map.Config.BaseGame == GameType.HERETIC ? 0.4f : 0.6f);
this.alphabyte = (byte)(this.alpha * 255);
}

View file

@ -423,6 +423,7 @@ namespace CodeImp.DoomBuilder.Data
Dictionary<int, string> spawnnums, doomednums;
LoadMapInfo(out spawnnums, out doomednums);
LoadCvarInfo();
LoadLockDefs();
int thingcount = LoadDecorateThings(spawnnums, doomednums);
int spritecount = LoadThingSprites();
@ -2366,7 +2367,7 @@ namespace CodeImp.DoomBuilder.Data
{
currentreader = dr;
parser.ClearIncludesList();
IEnumerable<TextResourceData> streams = dr.GetGldefsData(General.Map.Config.GameType);
IEnumerable<TextResourceData> streams = dr.GetGldefsData(General.Map.Config.BaseGame);
foreach(TextResourceData data in streams)
{
@ -2771,6 +2772,52 @@ namespace CodeImp.DoomBuilder.Data
cvars = parser.Cvars;
}
//mxd. This loads LOCKDEFS lumps
private void LoadLockDefs()
{
LockDefsParser parser = new LockDefsParser();
foreach(DataReader dr in containers)
{
currentreader = dr;
IEnumerable<TextResourceData> streams = dr.GetLockDefsData();
// 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;
// Apply to the enums list?
EnumList keys = parser.GetLockDefs();
if(keys.Count > 0)
{
keys.Insert(0, new EnumItem("0", "None"));
General.Map.Config.Enums["keys"] = keys;
// Update all ArgumentInfos...
foreach(ThingTypeInfo info in thingtypes.Values)
{
foreach(ArgumentInfo ai in info.Args)
if(ai.Enum.Name == "keys") ai.Enum = General.Map.Config.Enums["keys"];
}
foreach(LinedefActionInfo info in General.Map.Config.LinedefActions.Values)
{
foreach(ArgumentInfo ai in info.Args)
if(ai.Enum.Name == "keys") ai.Enum = General.Map.Config.Enums["keys"];
}
}
}
//mxd
internal TextResourceData GetTextResourceData(string name)
{

View file

@ -229,7 +229,7 @@ namespace CodeImp.DoomBuilder.Data
public abstract IEnumerable<TextResourceData> GetMapinfoData();
//mxd. When implemented, this returns GLDEFS lumps
public abstract IEnumerable<TextResourceData> GetGldefsData(GameType gametype);
public abstract IEnumerable<TextResourceData> GetGldefsData(string basegame);
//mxd. When implemented, this returns REVERBS lumps
public abstract IEnumerable<TextResourceData> GetReverbsData();
@ -255,6 +255,9 @@ namespace CodeImp.DoomBuilder.Data
//mxd. When implemented, this returns CVARINFO lumps
public abstract IEnumerable<TextResourceData> GetCvarInfoData();
//mxd. When implemented, this returns LOCKDEFS lumps
public abstract IEnumerable<TextResourceData> GetLockDefsData();
//mxd. When implemented, this returns the list of voxel model names
public abstract HashSet<string> GetVoxelNames();

View file

@ -19,8 +19,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using CodeImp.DoomBuilder.GZBuilder.Data;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.ZDoom;
#endregion
@ -630,7 +629,7 @@ namespace CodeImp.DoomBuilder.Data
#region ================== GLDEFS (mxd)
//mxd
public override IEnumerable<TextResourceData> GetGldefsData(GameType gametype)
public override IEnumerable<TextResourceData> GetGldefsData(string basegame)
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
@ -641,9 +640,9 @@ namespace CodeImp.DoomBuilder.Data
List<string> files = new List<string>();
// Try to load game specific GLDEFS first
if(gametype != GameType.UNKNOWN)
if(basegame != GameType.UNKNOWN)
{
string lumpname = Gldefs.GLDEFS_LUMPS_PER_GAME[(int)gametype];
string lumpname = GameType.GldefsLumpsPerGame[basegame];
files.AddRange(GetAllFilesWhichTitleStartsWith("", lumpname, false));
}
@ -655,7 +654,7 @@ namespace CodeImp.DoomBuilder.Data
result.Add(new TextResourceData(this, LoadFile(s), s, true));
// Find in any of the wad files
foreach(WADReader wr in wads) result.AddRange(wr.GetGldefsData(gametype));
foreach(WADReader wr in wads) result.AddRange(wr.GetGldefsData(basegame));
return result;
}
@ -816,6 +815,28 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== Lockdefs (mxd)
public override IEnumerable<TextResourceData> GetLockDefsData()
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
List<TextResourceData> result = new List<TextResourceData>();
string[] files = GetAllFilesWithTitle("", "LOCKDEFS", 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.GetLockDefsData());
return result;
}
#endregion
#region ================== Methods
// This loads the images in this directory

View file

@ -1034,16 +1034,16 @@ namespace CodeImp.DoomBuilder.Data
}
//mxd
public override IEnumerable<TextResourceData> GetGldefsData(GameType gametype)
public override IEnumerable<TextResourceData> GetGldefsData(string basegame)
{
if(issuspended) throw new Exception("Data reader is suspended");
List<TextResourceData> result = new List<TextResourceData>();
// Try to load game specific GLDEFS first
if(gametype != GameType.UNKNOWN)
if(basegame != GameType.UNKNOWN)
{
string lumpname = Gldefs.GLDEFS_LUMPS_PER_GAME[(int)gametype];
string lumpname = GameType.GldefsLumpsPerGame[basegame];
result.AddRange(GetAllLumps(lumpname));
}
@ -1108,6 +1108,13 @@ namespace CodeImp.DoomBuilder.Data
return GetAllLumps("CVARINFO");
}
//mxd
public override IEnumerable<TextResourceData> GetLockDefsData()
{
if(issuspended) throw new Exception("Data reader is suspended");
return GetAllLumps("LOCKDEFS");
}
//mxd
private IEnumerable<TextResourceData> GetFirstLump(string name)
{

View file

@ -1,17 +0,0 @@

namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public enum GameType
{
UNKNOWN = 0,
DOOM = 1,
HERETIC = 2,
HEXEN = 3,
STRIFE = 4,
}
public struct Gldefs
{
public static readonly string[] GLDEFS_LUMPS_PER_GAME = { "UNKNOWN_GAME", "DOOMDEFS", "HTICDEFS", "HEXNDEFS", "STRFDEFS" };
}
}

View file

@ -0,0 +1,137 @@
using System.Collections.Generic;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data;
namespace CodeImp.DoomBuilder.ZDoom
{
internal sealed class LockDefsParser :ZDTextParser
{
internal override ScriptType ScriptType { get { return ScriptType.LOCKDEFS; } }
private Dictionary<int, string> locks;
public LockDefsParser()
{
locks = new Dictionary<int, string>();
}
public override bool Parse(TextResourceData data, bool clearerrors)
{
//mxd. 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
int locknum = -1;
string locktitle = string.Empty;
string game = string.Empty;
int bracelevel = 0;
while(SkipWhitespace(true))
{
string token = ReadToken().ToLowerInvariant();
if(string.IsNullOrEmpty(token)) continue;
switch(token)
{
case "clearlocks":
if(bracelevel == 0)
{
locks.Clear();
}
else
{
ReportError("Unexpected \"CLEARLOCKS\" keyword");
return false;
}
break;
// LOCK locknumber [game]
case "lock":
SkipWhitespace(false);
if(!ReadSignedInt(ref locknum))
{
ReportError("Expected lock number");
return false;
}
//wiki: The locknumber must be in the 1-to-255 range
if(locknum < 1 || locknum > 255)
{
ReportError("The locknumber must be in the 1-to-255 range, but is " + locknum);
return false;
}
SkipWhitespace(true);
token = ReadToken().ToLowerInvariant();
if(!string.IsNullOrEmpty(token))
{
if(token == "{")
{
bracelevel++;
}
//Should be game
else if(!GameType.GameTypes.Contains(token))
{
LogWarning("Lock " + locknum + " is defined for unknown game \"" + token + "\"");
}
else
{
game = token;
}
}
break;
case "$title":
SkipWhitespace(false);
locktitle = StripQuotes(ReadToken(false));
break;
case "{":
bracelevel++;
break;
case "}":
if(--bracelevel > 0) continue;
// Add to collection?
if(locknum > 0 && (string.IsNullOrEmpty(game) || General.Map.Config.BaseGame == game))
{
// No custom title given?
if(string.IsNullOrEmpty(locktitle)) locktitle = "Lock " + locknum;
if(locks.ContainsKey(locknum))
LogWarning("Lock " + locknum + " is double-defined as \"" + locks[locknum] + "\" and \"" + locktitle + "\"");
locks[locknum] = locktitle;
}
// Reset values
locknum = -1;
locktitle = string.Empty;
game = string.Empty;
break;
}
}
return true;
}
public EnumList GetLockDefs()
{
EnumList result = new EnumList(locks.Count);
foreach(KeyValuePair<int, string> group in locks)
result.Add(new EnumItem(group.Key.ToString(), group.Value));
return result;
}
}
}

View file

@ -52,19 +52,19 @@ namespace CodeImp.DoomBuilder.ZDoom
switch(token)
{
case "ifheretic":
skipdefinitions = (General.Map.Config.GameType != GameType.HERETIC);
skipdefinitions = (General.Map.Config.BaseGame != GameType.HERETIC);
break;
case "ifhexen":
skipdefinitions = (General.Map.Config.GameType != GameType.HEXEN);
skipdefinitions = (General.Map.Config.BaseGame != GameType.HEXEN);
break;
case "ifstrife":
skipdefinitions = (General.Map.Config.GameType != GameType.STRIFE);
skipdefinitions = (General.Map.Config.BaseGame != GameType.STRIFE);
break;
case "ifdoom": // TODO: is it even a thing?..
skipdefinitions = (General.Map.Config.GameType != GameType.DOOM);
skipdefinitions = (General.Map.Config.BaseGame != GameType.DOOM);
break;
case "terrain":