From 38ffc861cba7141f7a4ca89fc3b42465da65307c Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Mon, 16 Jan 2017 00:00:45 +0200 Subject: [PATCH] Internal: started implementing ZScript parser. Nothing works for now, aside from the actual parsing code. --- Source/Core/Builder.csproj | 2 + Source/Core/Config/ScriptConfiguration.cs | 1 + Source/Core/Data/DataManager.cs | 72 ++++++++++++++++++- Source/Core/Data/DataReader.cs | 7 +- Source/Core/Data/PK3StructuredReader.cs | 52 ++++++++++++-- Source/Core/Data/WADReader.cs | 18 ++++- Source/Core/ZDoom/ZDTextParser.cs | 4 +- .../StairSectorBuilder.csproj | 4 +- 8 files changed, 148 insertions(+), 12 deletions(-) diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 0673468c..1a87cb30 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -520,6 +520,8 @@ + + diff --git a/Source/Core/Config/ScriptConfiguration.cs b/Source/Core/Config/ScriptConfiguration.cs index 59b7fd1b..abdd5659 100755 --- a/Source/Core/Config/ScriptConfiguration.cs +++ b/Source/Core/Config/ScriptConfiguration.cs @@ -52,6 +52,7 @@ namespace CodeImp.DoomBuilder.Config GAMEINFO, KEYCONF, FONTDEFS, + ZSCRIPT, } internal class ScriptConfiguration : IComparable diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index d2ff7663..2e083b1d 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -136,6 +136,7 @@ namespace CodeImp.DoomBuilder.Data // Things combined with things created from Decorate private DecorateParser decorate; + private ZScriptParser zscript; private List thingcategories; private Dictionary thingtypes; @@ -191,6 +192,7 @@ namespace CodeImp.DoomBuilder.Data public List ThingCategories { get { return thingcategories; } } public ICollection ThingTypes { get { return thingtypes.Values; } } public DecorateParser Decorate { get { return decorate; } } + public ZScriptParser ZScript { get { return zscript; } } internal ICollection TextureSets { get { return texturesets; } } internal ICollection ResourceTextureSets { get { return resourcetextures; } } internal AllTextureSet AllTextureSet { get { return alltextures; } } @@ -444,7 +446,7 @@ namespace CodeImp.DoomBuilder.Data //mxd. Load Script Editor-only stuff... LoadExtraTextLumps(); - int thingcount = LoadDecorateThings(spawnnums, doomednums); + int thingcount = LoadZScriptThings(spawnnums, doomednums) + LoadDecorateThings(spawnnums, doomednums); int spritecount = LoadThingSprites(); LoadInternalSprites(); LoadInternalTextures(); //mxd @@ -1819,6 +1821,57 @@ namespace CodeImp.DoomBuilder.Data #region ================== Things + private int LoadZScriptThings(Dictionary spawnnumsoverride, Dictionary doomednumsoverride) + { + int counter = 0; + + // Create new parser + zscript = new ZScriptParser { OnInclude = LoadZScriptFromLocation }; + + // Only load these when the game configuration supports the use of decorate + if (!string.IsNullOrEmpty(General.Map.Config.DecorateGames)) + { + // Go for all opened containers + foreach (DataReader dr in containers) + { + // Load Decorate info cumulatively (the last Decorate is added to the previous) + // I'm not sure if this is the right thing to do though. + currentreader = dr; + IEnumerable streams = dr.GetDecorateData("ZSCRIPT"); + foreach (TextResourceData data in streams) + { + // Parse the data + data.Stream.Seek(0, SeekOrigin.Begin); + zscript.Parse(data, true); + + //mxd. DECORATE lumps are interdepandable. Can't carry on... + if (zscript.HasError) + { + zscript.LogError(); + break; + } + } + } + + //mxd. Add to text resources collection + scriptresources[zscript.ScriptType] = new HashSet(zscript.ScriptResources.Values); + currentreader = null; + + if (!zscript.HasError) + { + + } + else + { + // Return after adding parsed resources + return counter; + } + } + + // Output info + return counter; + } + // This loads the things from Decorate private int LoadDecorateThings(Dictionary spawnnumsoverride, Dictionary doomednumsoverride) { @@ -2145,6 +2198,23 @@ namespace CodeImp.DoomBuilder.Data } } } + + private void LoadZScriptFromLocation(ZScriptParser parser, string location) + { + IEnumerable streams = currentreader.GetZScriptData(location); + foreach (TextResourceData data in streams) + { + // Parse this data + parser.Parse(data, false); + + //mxd. DECORATE lumps are interdepandable. Can't carry on... + if (parser.HasError) + { + parser.LogError(); + return; + } + } + } // This gets thing information by index public ThingTypeInfo GetThingInfo(int thingtype) diff --git a/Source/Core/Data/DataReader.cs b/Source/Core/Data/DataReader.cs index 87af37a7..dd12dd0e 100755 --- a/Source/Core/Data/DataReader.cs +++ b/Source/Core/Data/DataReader.cs @@ -222,8 +222,11 @@ namespace CodeImp.DoomBuilder.Data // When implemented, this returns DECORATE lumps public abstract IEnumerable GetDecorateData(string pname); - //mxd. When implemented, this returns MAPINFO lumps - public abstract IEnumerable GetMapinfoData(); + // [ZZ] When implemented, this returns ZSCRIPT lumps + public abstract IEnumerable GetZScriptData(string pname); + + //mxd. When implemented, this returns MAPINFO lumps + public abstract IEnumerable GetMapinfoData(); //mxd. When implemented, this returns GLDEFS lumps public abstract IEnumerable GetGldefsData(string basegame); diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs index 1f421657..34466f7d 100755 --- a/Source/Core/Data/PK3StructuredReader.cs +++ b/Source/Core/Data/PK3StructuredReader.cs @@ -524,12 +524,56 @@ namespace CodeImp.DoomBuilder.Data return result; } - #endregion + #endregion - #region ================== VOXELDEF (mxd) + #region ================== ZSCRIPT - //mxd. This returns the list of voxels, which can be used without VOXELDEF definition - public override HashSet GetVoxelNames() + // This finds and returns ZSCRIPT streams + public override IEnumerable GetZScriptData(string pname) + { + // Error when suspended + if (issuspended) throw new Exception("Data reader is suspended"); + + List result = new List(); + string[] allfilenames; + + // Find in root directory + string filename = Path.GetFileName(pname); + string pathname = Path.GetDirectoryName(pname); + + if (filename.IndexOf('.') > -1) + { + string fullname = Path.Combine(pathname, filename); + if (FileExists(fullname)) + { + allfilenames = new string[1]; + allfilenames[0] = Path.Combine(pathname, filename); + } + else + { + allfilenames = new string[0]; + General.ErrorLogger.Add(ErrorType.Warning, "Unable to load ZSCRIPT file \"" + fullname + "\""); + } + } + else + allfilenames = GetAllFilesWithTitle(pathname, filename, false); + + foreach (string foundfile in allfilenames) + result.Add(new TextResourceData(this, LoadFile(foundfile), foundfile, true)); + + // Find in any of the wad files + for (int i = wads.Count - 1; i >= 0; i--) + result.AddRange(wads[i].GetZScriptData(pname)); + + return result; + } + + #endregion + + #region ================== VOXELDEF (mxd) + + //mxd. This returns the list of voxels, which can be used without VOXELDEF definition + public override HashSet GetVoxelNames() { // Error when suspended if(issuspended) throw new Exception("Data reader is suspended"); diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs index 95838151..a063f3a6 100755 --- a/Source/Core/Data/WADReader.cs +++ b/Source/Core/Data/WADReader.cs @@ -1017,8 +1017,22 @@ namespace CodeImp.DoomBuilder.Data return new List {result[result.Count - 1]}; } - //mxd. Should be only one entry per wad - public override IEnumerable GetMapinfoData() + // [ZZ] This finds and returns ZSCRIPT streams + public override IEnumerable GetZScriptData(string pname) + { + if (issuspended) throw new Exception("Data reader is suspended"); + List result = GetAllLumpsData(pname); //mxd + + //mxd. Return ALL DECORATE lumps + if (result.Count == 0 || string.Compare(pname, "ZSCRIPT", StringComparison.OrdinalIgnoreCase) == 0) + return result; + + //mxd. Return THE LAST include lump, because that's the way ZDoom seems to operate + return new List { result[result.Count - 1] }; + } + + //mxd. Should be only one entry per wad + public override IEnumerable GetMapinfoData() { if(issuspended) throw new Exception("Data reader is suspended"); diff --git a/Source/Core/ZDoom/ZDTextParser.cs b/Source/Core/ZDoom/ZDTextParser.cs index 9369b909..3dcb3d31 100755 --- a/Source/Core/ZDoom/ZDTextParser.cs +++ b/Source/Core/ZDoom/ZDTextParser.cs @@ -62,7 +62,7 @@ namespace CodeImp.DoomBuilder.ZDoom private string errordesc; private string errorsource; // Rooted path to the troubling file private string shorterrorsource; //mxd. Resource name + filename - private long prevstreamposition; //mxd. Text stream position storted before performing ReadToken. + protected long prevstreamposition; //mxd. Text stream position storted before performing ReadToken. //mxd. Text lumps protected string textresourcepath; @@ -757,7 +757,7 @@ namespace CodeImp.DoomBuilder.ZDoom protected int GetCurrentLineNumber() { long pos = datastream.Position; - long finishpos = Math.Min(prevstreamposition, pos); + long finishpos = (prevstreamposition >= 0 ? Math.Min(prevstreamposition, pos) : pos); long readpos = 0; int linenumber = -1; diff --git a/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj b/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj index 300f68f3..a55483f5 100755 --- a/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj +++ b/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj @@ -75,7 +75,9 @@ True Resources.resx - + + Form + StairSectorBuilderForm.cs