mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 05:41:45 +00:00
Added SNDINFO parser. Currently only the "$ambient" command is parsed. The values are used to update the titles of "Ambient Sound NN" things and to populate "ambient_sounds" Game Configuration enum.
Fixed, DECORATE parser: actors, which used "replaces" keyword and didn't have DoomEdNum were ignored. Updated documentation ("(G)ZDoom text lumps support" page).
This commit is contained in:
parent
082a718bce
commit
578135cad4
12 changed files with 260 additions and 30 deletions
|
@ -861,6 +861,17 @@ enums
|
|||
75 = "75%";
|
||||
100 = "100%";
|
||||
}
|
||||
|
||||
ambient_sounds
|
||||
{
|
||||
0 = "None";
|
||||
}
|
||||
|
||||
sound_sequences
|
||||
{
|
||||
0 = "None";
|
||||
255 = "Default";
|
||||
}
|
||||
|
||||
setadd
|
||||
{
|
||||
|
|
|
@ -114,10 +114,7 @@ zdoom
|
|||
{
|
||||
title = "Sound Sequence Index";
|
||||
type = 11;
|
||||
enum
|
||||
{
|
||||
255 = "Default";
|
||||
}
|
||||
enum = "sound_sequences";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,6 +190,8 @@ zdoom
|
|||
arg0
|
||||
{
|
||||
title = "Ambient Sound Index";
|
||||
type = 11;
|
||||
enum = "ambient_sounds";
|
||||
}
|
||||
arg1
|
||||
{
|
||||
|
@ -221,6 +220,8 @@ zdoom
|
|||
arg0
|
||||
{
|
||||
title = "Sound Sequence Index";
|
||||
type = 11;
|
||||
enum = "sound_sequences";
|
||||
}
|
||||
arg1
|
||||
{
|
||||
|
@ -235,6 +236,8 @@ zdoom
|
|||
arg0
|
||||
{
|
||||
title = "Ambient Sound Index";
|
||||
type = 11;
|
||||
enum = "ambient_sounds";
|
||||
}
|
||||
arg1
|
||||
{
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
Both new and old MAPINFO definition styles are supported.<br />
|
||||
You can use "<strong>//$GZDB_SKIP</strong>" special comment to abort parsing of the current file.<br />
|
||||
<strong>DoomEdNum</strong> overrides are supported.<br />
|
||||
<strong>SpawnNums</strong> overrides are supported. The values are used to update "spawnthing" Game Configuration enum.<br /><br />
|
||||
<strong>SpawnNums</strong> overrides are supported. The values are used to update "<strong>spawnthing</strong>" Game Configuration enum.<br />
|
||||
<br />
|
||||
In addition, following values from (Z)MAPINFO are supported by Visual mode:
|
||||
<ul>
|
||||
<li>fade;</li>
|
||||
|
@ -55,6 +56,9 @@
|
|||
<h2>REVERBS:</h2>
|
||||
Sound environment definitions are loaded and can be used in the <a href="features/classic_modes/mode_soundenvironment.html">Sound Environment Mode</a>.
|
||||
|
||||
<h2>SNDINFO:</h2>
|
||||
Ambient sound definitions are loaded. The values are used to update the titles of "<strong>Ambient Sound NN</strong>" things and to populate "<strong>ambient_sounds</strong>" Game Configuration enum.
|
||||
|
||||
<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).
|
||||
|
||||
|
|
|
@ -1035,6 +1035,7 @@
|
|||
<Compile Include="ZDoom\CvarInfoParser.cs" />
|
||||
<Compile Include="ZDoom\PatchStructure.cs" />
|
||||
<Compile Include="ZDoom\ReverbsParser.cs" />
|
||||
<Compile Include="ZDoom\SndInfoParser.cs" />
|
||||
<Compile Include="ZDoom\SndSeqParser.cs" />
|
||||
<Compile Include="ZDoom\StateGoto.cs" />
|
||||
<Compile Include="ZDoom\TerrainParser.cs" />
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
TERRAIN,
|
||||
X11R6RGB,
|
||||
CVARINFO,
|
||||
SNDINFO,
|
||||
}
|
||||
|
||||
internal class ScriptConfiguration : IComparable<ScriptConfiguration>
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
#region ================== Properties
|
||||
|
||||
public int Index { get { return index; } }
|
||||
public string Title { get { return title; } }
|
||||
public string Title { get { return title; } internal set { title = value; } } //mxd. Added setter
|
||||
public string Sprite { get { return sprite; } }
|
||||
public SpriteFrameInfo[] SpriteFrame { get { return spriteframe; } }
|
||||
public ActorStructure Actor { get { return actor; } }
|
||||
|
@ -405,7 +405,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
#region ================== Methods
|
||||
|
||||
// This updates the properties from a decorate actor
|
||||
internal void ModifyByDecorateActor(ActorStructure actor)
|
||||
internal void ModifyByDecorateActor(ActorStructure actor) { ModifyByDecorateActor(actor, false); } //mxd
|
||||
internal void ModifyByDecorateActor(ActorStructure actor, bool replacetitle)
|
||||
{
|
||||
// Keep reference to actor
|
||||
this.actor = actor;
|
||||
|
@ -420,7 +421,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
if(!tag.StartsWith("\"$")) title = tag; //mxd. Don't use LANGUAGE keywords.
|
||||
}
|
||||
|
||||
if(string.IsNullOrEmpty(title)) title = actor.ClassName;
|
||||
if(string.IsNullOrEmpty(title) || replacetitle) title = actor.ClassName;
|
||||
|
||||
//mxd. Color override?
|
||||
if(actor.HasPropertyWithValue("$color"))
|
||||
|
|
|
@ -432,6 +432,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
//mxd. Load more stuff
|
||||
LoadReverbs();
|
||||
LoadSndSeq();
|
||||
LoadSndInfo();
|
||||
LoadVoxels();
|
||||
Dictionary<string, int> actorsbyclass = CreateActorsByClassList();
|
||||
LoadModeldefs(actorsbyclass);
|
||||
|
@ -1785,12 +1786,26 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Apply to collection
|
||||
damagetypes = new string[dtypes.Count];
|
||||
dtypes.CopyTo(damagetypes);
|
||||
|
||||
// Step 0. Create ThingTypeInfo by classname collection...
|
||||
Dictionary<string, ThingTypeInfo> thingtypesbyclass = new Dictionary<string, ThingTypeInfo>(thingtypes.Count, StringComparer.OrdinalIgnoreCase);
|
||||
foreach(ThingTypeInfo info in thingtypes.Values)
|
||||
if(!string.IsNullOrEmpty(info.ClassName)) thingtypesbyclass[info.ClassName] = info;
|
||||
|
||||
// Step 1. Go for all actors in the decorate to make things or update things
|
||||
foreach(ActorStructure actor in decorate.Actors)
|
||||
{
|
||||
//mxd. Apply "replaces" DECORATE override...
|
||||
if(!string.IsNullOrEmpty(actor.ReplacesClass) && thingtypesbyclass.ContainsKey(actor.ReplacesClass))
|
||||
{
|
||||
// Update info
|
||||
thingtypesbyclass[actor.ReplacesClass].ModifyByDecorateActor(actor, true);
|
||||
|
||||
// Count
|
||||
counter++;
|
||||
}
|
||||
// Check if we want to add this actor
|
||||
if(actor.DoomEdNum > 0)
|
||||
else if(actor.DoomEdNum > 0)
|
||||
{
|
||||
// Check if we can find this thing in our existing collection
|
||||
if(thingtypes.ContainsKey(actor.DoomEdNum))
|
||||
|
@ -1818,13 +1833,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(doomednumsoverride.Count > 0)
|
||||
{
|
||||
List<int> toremove = new List<int>();
|
||||
Dictionary<string, ThingTypeInfo> thingtypesbyclass = new Dictionary<string, ThingTypeInfo>();
|
||||
foreach(KeyValuePair<int, ThingTypeInfo> group in thingtypes)
|
||||
{
|
||||
if(string.IsNullOrEmpty(group.Value.ClassName)) continue;
|
||||
thingtypesbyclass[group.Value.ClassName.ToLowerInvariant()] = group.Value;
|
||||
}
|
||||
|
||||
foreach(KeyValuePair<int, string> group in doomednumsoverride)
|
||||
{
|
||||
// Remove thing from the list?
|
||||
|
@ -2093,7 +2101,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(!string.IsNullOrEmpty(ti.Value.ClassName))
|
||||
{
|
||||
if(actors.ContainsKey(ti.Value.ClassName) && actors[ti.Value.ClassName] != ti.Key)
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Actor \"" + ti.Value.ClassName + "\" has several editor numbers! Only the last one (" + ti.Key + ") will be used.");
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Actor \"" + ti.Value.ClassName + "\" has several editor numbers (" + actors[ti.Value.ClassName] + " and " + ti.Key + "). Only the last one will be used.");
|
||||
actors[ti.Value.ClassName] = ti.Key;
|
||||
}
|
||||
}
|
||||
|
@ -2451,6 +2459,81 @@ namespace CodeImp.DoomBuilder.Data
|
|||
reverbs = parser.GetReverbs();
|
||||
}
|
||||
|
||||
//mxd. This loads SNDINFO
|
||||
private void LoadSndInfo()
|
||||
{
|
||||
// Bail out when not supported by current game configuration
|
||||
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
|
||||
|
||||
SndInfoParser parser = new SndInfoParser();
|
||||
foreach(DataReader dr in containers)
|
||||
{
|
||||
currentreader = dr;
|
||||
IEnumerable<TextResourceData> streams = dr.GetSndInfoData();
|
||||
|
||||
// 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;
|
||||
|
||||
// Anything to do?
|
||||
if(parser.AmbientSounds.Count > 0)
|
||||
{
|
||||
// Update or create the main enums list
|
||||
Dictionary<int, EnumItem> configenums = new Dictionary<int, EnumItem>();
|
||||
if(General.Map.Config.Enums.ContainsKey("ambient_sounds"))
|
||||
{
|
||||
foreach(EnumItem item in General.Map.Config.Enums["ambient_sounds"])
|
||||
configenums.Add(item.GetIntValue(), item);
|
||||
}
|
||||
if(configenums.ContainsKey(0)) configenums.Remove(0);
|
||||
|
||||
foreach(KeyValuePair<int, string> group in parser.AmbientSounds)
|
||||
{
|
||||
configenums[group.Key] = new EnumItem(group.Key.ToString(), group.Value);
|
||||
}
|
||||
|
||||
// Store results in "ambient_sounds" enum
|
||||
EnumList newenums = new EnumList();
|
||||
newenums.AddRange(configenums.Values);
|
||||
newenums.Sort((a, b) => a.Title.CompareTo(b.Title)); // Sort by title
|
||||
newenums.Insert(0, new EnumItem("0", "None")); // Add "None" value
|
||||
General.Map.Config.Enums["ambient_sounds"] = newenums;
|
||||
|
||||
// Update all ArgumentInfos...
|
||||
foreach(ThingTypeInfo info in thingtypes.Values)
|
||||
{
|
||||
foreach(ArgumentInfo ai in info.Args)
|
||||
if(ai.Enum.Name == "ambient_sounds") ai.Enum = newenums;
|
||||
}
|
||||
|
||||
foreach(LinedefActionInfo info in General.Map.Config.LinedefActions.Values)
|
||||
{
|
||||
foreach(ArgumentInfo ai in info.Args)
|
||||
if(ai.Enum.Name == "ambient_sounds") ai.Enum = newenums;
|
||||
}
|
||||
|
||||
// Update "Ambient Sound XX" thing names. Hardcoded for things 14001 - 14064 for now...
|
||||
for(int i = 14001; i < 14065; i++)
|
||||
{
|
||||
int ambsoundindex = i - 14000;
|
||||
if(!configenums.ContainsKey(ambsoundindex) || !thingtypes.ContainsKey(i) || !string.IsNullOrEmpty(thingtypes[i].ClassName)) continue;
|
||||
|
||||
// Update title
|
||||
thingtypes[i].Title += " (" + configenums[ambsoundindex] + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. This loads SNDSEQ
|
||||
private void LoadSndSeq()
|
||||
{
|
||||
|
@ -2473,7 +2556,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Add to text resources collection
|
||||
// Add to text resources collection
|
||||
textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values);
|
||||
currentreader = null;
|
||||
soundsequences = parser.GetSoundSequences();
|
||||
|
|
|
@ -221,37 +221,40 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#region ================== Decorate, Modeldef, Mapinfo, Gldefs, etc...
|
||||
|
||||
// When implemented, this returns the DECORATE lump
|
||||
// When implemented, this returns DECORATE lumps
|
||||
public abstract IEnumerable<TextResourceData> GetDecorateData(string pname);
|
||||
|
||||
//mxd. When implemented, this returns the MODELDEF lump
|
||||
//mxd. When implemented, this returns MODELDEF lumps
|
||||
public abstract IEnumerable<TextResourceData> GetModeldefData();
|
||||
|
||||
//mxd. When implemented, this returns the MAPINFO lump
|
||||
//mxd. When implemented, this returns MAPINFO lumps
|
||||
public abstract IEnumerable<TextResourceData> GetMapinfoData();
|
||||
|
||||
//mxd. When implemented, this returns the GLDEFS lump
|
||||
//mxd. When implemented, this returns GLDEFS lumps
|
||||
public abstract IEnumerable<TextResourceData> GetGldefsData(GameType gametype);
|
||||
|
||||
//mxd. When implemented, this returns the REVERBS lump
|
||||
//mxd. When implemented, this returns REVERBS lumps
|
||||
public abstract IEnumerable<TextResourceData> GetReverbsData();
|
||||
|
||||
//mxd. When implemented, this returns the VOXELDEF lump
|
||||
//mxd. When implemented, this returns VOXELDEF lumps
|
||||
public abstract IEnumerable<TextResourceData> GetVoxeldefData();
|
||||
|
||||
//mxd. When implemented, this returns the SNDSEQ lump
|
||||
//mxd. When implemented, this returns SNDINFO lumps
|
||||
public abstract IEnumerable<TextResourceData> GetSndInfoData();
|
||||
|
||||
//mxd. When implemented, this returns SNDSEQ lumps
|
||||
public abstract IEnumerable<TextResourceData> GetSndSeqData();
|
||||
|
||||
//mxd. When implemented, this returns the ANIMDEFS lump
|
||||
//mxd. When implemented, this returns ANIMDEFS lumps
|
||||
public abstract IEnumerable<TextResourceData> GetAnimdefsData();
|
||||
|
||||
//mxd. When implemented, this returns the TERRAIN lump
|
||||
//mxd. When implemented, this returns TERRAIN lumps
|
||||
public abstract IEnumerable<TextResourceData> GetTerrainData();
|
||||
|
||||
//mxd. When implemented, this returns the X11R6RGB lump
|
||||
//mxd. When implemented, this returns X11R6RGB lumps
|
||||
public abstract IEnumerable<TextResourceData> GetX11R6RGBData();
|
||||
|
||||
//mxd. When implemented, this returns the CVARINFO lump
|
||||
//mxd. When implemented, this returns CVARINFO lumps
|
||||
public abstract IEnumerable<TextResourceData> GetCvarInfoData();
|
||||
|
||||
//mxd. When implemented, this returns the list of voxel model names
|
||||
|
|
|
@ -675,6 +675,28 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== SNDINFO (mxd)
|
||||
|
||||
public override IEnumerable<TextResourceData> GetSndInfoData()
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
List<TextResourceData> result = new List<TextResourceData>();
|
||||
string[] files = GetAllFilesWithTitle("", "SNDINFO", 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.GetSndInfoData());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== SNDSEQ (mxd)
|
||||
|
||||
public override IEnumerable<TextResourceData> GetSndSeqData()
|
||||
|
|
|
@ -1047,6 +1047,13 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return GetAllLumps("REVERBS");
|
||||
}
|
||||
|
||||
//mxd
|
||||
public override IEnumerable<TextResourceData> GetSndInfoData()
|
||||
{
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
return GetAllLumps("SNDINFO");
|
||||
}
|
||||
|
||||
//mxd
|
||||
public override IEnumerable<TextResourceData> GetSndSeqData()
|
||||
{
|
||||
|
|
|
@ -331,7 +331,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
int arrlen = -1;
|
||||
if(!parser.ReadSignedInt(ref arrlen))
|
||||
{
|
||||
parser.ReportError("Expected User Array length, but got \"" + next + "\"");
|
||||
parser.ReportError("Expected User Array length");
|
||||
return;
|
||||
}
|
||||
if(arrlen < 1)
|
||||
|
|
94
Source/Core/ZDoom/SndInfoParser.cs
Normal file
94
Source/Core/ZDoom/SndInfoParser.cs
Normal file
|
@ -0,0 +1,94 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System.Collections.Generic;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.ZDoom
|
||||
{
|
||||
internal sealed class SndInfoParser : ZDTextParser
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private Dictionary<int, string> ambientsounds;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
internal override ScriptType ScriptType { get { return ScriptType.SNDINFO; } }
|
||||
|
||||
internal Dictionary<int, string> AmbientSounds { get { return ambientsounds; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
public SndInfoParser()
|
||||
{
|
||||
specialtokens = "";
|
||||
ambientsounds = new Dictionary<int, string>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Parsing
|
||||
|
||||
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
|
||||
while(SkipWhitespace(true))
|
||||
{
|
||||
string token = ReadToken().ToLowerInvariant();
|
||||
if(string.IsNullOrEmpty(token)) continue;
|
||||
|
||||
switch(token)
|
||||
{
|
||||
//$ambient <index> <logicalsound> [type] <mode> <volume>
|
||||
case "$ambient":
|
||||
// Read index
|
||||
SkipWhitespace(true);
|
||||
int index = -1;
|
||||
if(!ReadSignedInt(ref index) || index < 0)
|
||||
{
|
||||
// Not numeric!
|
||||
ReportError("Expected ambient sound index");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read name
|
||||
SkipWhitespace(true);
|
||||
string logicalsound = StripQuotes(ReadToken(false));
|
||||
if(string.IsNullOrEmpty(logicalsound))
|
||||
{
|
||||
ReportError("Expected ambient sound logicalname");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add to collection
|
||||
if(ambientsounds.ContainsKey(index))
|
||||
LogWarning("Ambient sound " + index + " is double-defined as \"" + ambientsounds[index] + "\" and \"" + logicalsound + "\"");
|
||||
|
||||
ambientsounds[index] = logicalsound;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue