Added preliminary DECALDEFS support. Parsing works, indexed decals and decal groups can be selected as the first argument of the Decal thing. Decals are not displayed in Visual Mode, decals without an index are not supported

This commit is contained in:
biwa 2020-10-11 22:36:07 +02:00
parent 3af704b7a6
commit 722c79d894
8 changed files with 464 additions and 0 deletions

View file

@ -925,6 +925,11 @@ enums
0 = "None";
}
decals
{
0 = "None";
}
sound_sequences
{
0 = "None";

View file

@ -1243,6 +1243,8 @@ zdoom
arg0
{
title = "Decal ID";
type = 11;
enum = "decals";
}
}

View file

@ -593,6 +593,8 @@
<Compile Include="Rendering\Renderer3D.cs" />
<Compile Include="VisualModes\VisualSector.cs" />
<Compile Include="Rendering\WorldVertex.cs" />
<Compile Include="ZDoom\DecalDefsParser.cs" />
<Compile Include="ZDoom\DecalInfo.cs" />
<Compile Include="ZDoom\DecorateActorStructure.cs" />
<Compile Include="ZDoom\DecorateStateGoto.cs" />
<Compile Include="ZDoom\DecorateStateStructure.cs" />

View file

@ -589,6 +589,8 @@
<Compile Include="Rendering\Renderer3D.cs" />
<Compile Include="VisualModes\VisualSector.cs" />
<Compile Include="Rendering\WorldVertex.cs" />
<Compile Include="ZDoom\DecalDefsParser.cs" />
<Compile Include="ZDoom\DecalInfo.cs" />
<Compile Include="ZDoom\DecorateActorStructure.cs" />
<Compile Include="ZDoom\DecorateStateGoto.cs" />
<Compile Include="ZDoom\DecorateStateStructure.cs" />

View file

@ -53,6 +53,7 @@ namespace CodeImp.DoomBuilder.Config
KEYCONF,
FONTDEFS,
ZSCRIPT,
DECALDEF,
}
internal class ScriptConfiguration : IComparable<ScriptConfiguration>

View file

@ -437,6 +437,9 @@ namespace CodeImp.DoomBuilder.Data
LoadCvarInfo();
LoadLockDefs();
// Load DECALDEF
LoadDecalDefs();
//mxd. Load Script Editor-only stuff...
LoadExtraTextLumps();
@ -2818,6 +2821,65 @@ namespace CodeImp.DoomBuilder.Data
}
}
/// <summary>
/// Load DECALDEF decal definitions
/// </summary>
private void LoadDecalDefs()
{
// Bail out when not supported by current game configuration
if (string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
DecalDefsParser parser = new DecalDefsParser();
foreach(DataReader dr in containers)
{
currentreader = dr; // Why?
IEnumerable<TextResourceData> streams = dr.GetTextLumpData(ScriptType.DECALDEF, false, false);
// Parse the data
foreach(TextResourceData data in streams)
{
parser.Parse(data, true);
// Report errors?
if (parser.HasError) parser.LogError();
}
}
currentreader = null; // Why?
if(parser.Decals.Count > 0)
{
// Update or create the main enums list
Dictionary<int, EnumItem> configenums = new Dictionary<int, EnumItem>();
if (General.Map.Config.Enums.ContainsKey("decals"))
{
foreach (EnumItem item in General.Map.Config.Enums["decals"])
configenums.Add(item.GetIntValue(), item);
}
if (configenums.ContainsKey(0)) configenums.Remove(0);
foreach (KeyValuePair<int, DecalInfo> group in parser.GetDecalDefsById())
{
configenums[group.Key] = new EnumItem(group.Key.ToString(), group.Value.Description);
}
// Store results in "decals" enum
EnumList newenums = new EnumList();
newenums.AddRange(configenums.Values);
newenums.Sort();
newenums.Insert(0, new EnumItem("0", "None"));
General.Map.Config.Enums["decals"] = newenums;
// Update all ArgumentInfos...
foreach (ThingTypeInfo info in thingtypes.Values)
{
foreach (ArgumentInfo ai in info.Args)
if (ai.Enum.Name == "decals") ai.Enum = newenums;
}
}
}
//mxd. This collects ZDoom text lumps, which are not used by the editor anywhere outside the Script Editor
private void LoadExtraTextLumps()
{

View file

@ -0,0 +1,172 @@
#region ================== Copyright (c) 2020 Boris Iwanski
/*
* This program is free software: you can redistribute it and/or modify
*
* it under the terms of the GNU General Public License as published by
*
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.If not, see<http://www.gnu.org/licenses/>.
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data;
#endregion
namespace CodeImp.DoomBuilder.ZDoom
{
internal sealed class DecalDefsParser : ZDTextParser
{
#region ================== Variables
private Dictionary<string, DecalInfo> decals = new Dictionary<string, DecalInfo>();
#endregion
#region ================== Properties
internal override ScriptType ScriptType { get { return ScriptType.DECALDEF; } }
public Dictionary<string, DecalInfo> Decals { get { return decals; } }
#endregion
#region ================== Constructors
/// <summary>
/// Constructor
/// </summary>
public DecalDefsParser()
{
}
#endregion
#region ================== Methods
/// <summary>
/// Parses DECALDEF data
/// </summary>
/// <param name="data">The data to parse</param>
/// <param name="clearerrors">If errors should be cleared</param>
/// <returns>true if paring worked, otherwise false</returns>
public override bool Parse(TextResourceData data, bool clearerrors)
{
if(!AddTextResource(data))
{
if (clearerrors) ClearError();
return true;
}
// Cannot process?
if (!base.Parse(data, clearerrors)) return false;
while(SkipWhitespace(true))
{
string token = ReadToken().ToLowerInvariant();
if (string.IsNullOrEmpty(token)) continue;
switch(token)
{
case "decal":
case "decalgroup":
DecalInfo.DecalType type = token == "decal" ? DecalInfo.DecalType.DECAL : DecalInfo.DecalType.DECALGROUP;
string decalname;
int decalid = -1;
SkipWhitespace(false);
token = ReadToken();
if (!string.IsNullOrEmpty(token))
decalname = token;
else
{
ReportError("Expected decal name, got nothing");
return false;
}
SkipWhitespace(false);
// Try to read the optional decal id
token = ReadToken();
if(!string.IsNullOrEmpty(token))
{
ReadSignedInt(token, ref decalid);
}
SkipWhitespace(true);
DecalInfo di = new DecalInfo(decalname, decalid, type);
if (!di.Parse(this))
return false;
decals.Add(decalname, di);
break;
}
}
return true;
}
/// <summary>
/// Finishes parsing, getting the DecalInfo of chidren of decal groups
/// </summary>
public void Finish()
{
foreach(DecalInfo di in decals.Values)
{
if(di.Type == DecalInfo.DecalType.DECALGROUP && di.Children.Count > 0)
{
foreach(string childname in di.Children.Keys)
{
if(decals.ContainsKey(childname))
{
di.Children[childname] = decals[childname];
break;
}
}
}
}
}
/// <summary>
/// Gets the parsed DECALDEF data by id
/// </summary>
/// <returns>EnumList of parsed decals</returns>
public Dictionary<int, DecalInfo> GetDecalDefsById()
{
Dictionary<int, DecalInfo> dict = new Dictionary<int, DecalInfo>();
foreach (DecalInfo di in decals.Values)
{
if(di.Index != -1)
dict.Add(di.Index, di);
}
return dict;
}
#endregion
}
}

View file

@ -0,0 +1,218 @@
#region ================== Copyright (c) 2020 Boris Iwanski
/*
* This program is free software: you can redistribute it and/or modify
*
* it under the terms of the GNU General Public License as published by
*
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.If not, see<http://www.gnu.org/licenses/>.
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#endregion
namespace CodeImp.DoomBuilder.ZDoom
{
public class DecalInfo
{
#region ================== Enums
public enum DecalType
{
DECAL,
DECALGROUP
}
#endregion
#region ================== Variables
private string name;
private string picturename = string.Empty;
private int index;
private string description;
private DecalType type;
private Dictionary<string, DecalInfo> childdecals = new Dictionary<string, DecalInfo>(); // Children of decal groups
#endregion
#region ================== Properties
public string Name { get { return name; } }
public string PictureName { get { return picturename; } }
public int Index { get { return index; } }
public DecalType Type { get { return type; } }
public string Description { get { return description; } }
public Dictionary<string, DecalInfo> Children { get { return childdecals; } }
#endregion
#region ================== Constructor
public DecalInfo(string name, int index, DecalType type)
{
this.name = name;
this.index = index;
this.type = type;
description = index.ToString() + ": " + name;
}
#endregion
#region ================== Methods
internal void SetPictureName(string picturename)
{
this.picturename = picturename;
}
/// <summary>
/// Parse a decal or decalgroup definition
/// </summary>
/// <param name="parser"></param>
/// <returns></returns>
internal bool Parse(DecalDefsParser parser)
{
switch(type)
{
case DecalType.DECAL:
return ParseDecal(parser);
case DecalType.DECALGROUP:
return ParseDecalGroup(parser);
}
return false;
}
/// <summary>
/// Parses a decal definition
/// </summary>
/// <param name="parser">the DecalDefsParser that right before the decal definition block</param>
/// <returns></returns>
private bool ParseDecal(DecalDefsParser parser)
{
parser.SkipWhitespace(true);
string token = parser.ReadToken();
if (token != "{")
{
parser.ReportError("Expected \"{\", got " + token);
return false;
}
while (true)
{
parser.SkipWhitespace(true);
token = parser.ReadToken().ToLowerInvariant();
if (string.IsNullOrEmpty(token))
{
parser.ReportError("Expected property of }, got nothing");
return false;
}
// Decal ends here
if (token == "}")
{
break;
}
switch (token)
{
case "pic":
parser.SkipWhitespace(false);
token = parser.ReadToken();
if (string.IsNullOrEmpty(token))
{
parser.ReportError("Expected image name, got nothing");
return false;
}
picturename = token;
break;
}
}
return true;
}
/// <summary>
/// Parses a decalgroup defition
/// </summary>
/// <param name="parser">The DecalDefsParser that right before the decalgroup definition block</param>
/// <returns></returns>
private bool ParseDecalGroup(DecalDefsParser parser)
{
parser.SkipWhitespace(true);
string token = parser.ReadToken();
if (token != "{")
{
parser.ReportError("Expected \"{\", got " + token);
return false;
}
while (true)
{
parser.SkipWhitespace(true);
token = parser.ReadToken().ToLowerInvariant();
if (string.IsNullOrEmpty(token))
{
parser.ReportError("Expected property of }, got nothing");
return false;
}
// Decal ends here
if (token == "}")
{
break;
}
// Add name of child to the list of children
childdecals.Add(token, null);
// Read the probability wheight. We don't use it, though
int weight = 0;
parser.SkipWhitespace(false);
token = parser.ReadToken();
if(string.IsNullOrEmpty(token) || !parser.ReadSignedInt(token, ref weight))
{
parser.ReportError("Expected probability weight as number, got \"" + token + "\"");
return false;
}
}
return true;
}
#endregion
}
}