mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
@working on decorate support
This commit is contained in:
parent
76ec8a8c98
commit
54940886fd
19 changed files with 608 additions and 142 deletions
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "doom";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "doom";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "doom";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "doom";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "doom";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "heretic raven";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "hexen raven";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ testparameters = "-iwad \"%WP\" -skill \"%S\" -file \"%AP\" \"%F\" +map %L %NM";
|
|||
defaultsavecompiler = "zdbsp_normal";
|
||||
defaulttestcompiler = "zdbsp_fast";
|
||||
|
||||
// Decorate actors to include depending on actor game property
|
||||
decorategames = "strife";
|
||||
|
||||
// Skill levels
|
||||
skills
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
private int makedooraction;
|
||||
private int[] makedoorargs;
|
||||
private bool linetagindicatesectors;
|
||||
private string decorategames;
|
||||
|
||||
// Skills
|
||||
private List<SkillInfo> skills;
|
||||
|
@ -143,6 +144,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
public int MakeDoorAction { get { return makedooraction; } }
|
||||
public int[] MakeDoorArgs { get { return makedoorargs; } }
|
||||
public bool LineTagIndicatesSectors { get { return linetagindicatesectors ; } }
|
||||
public string DecorateGames { get { return decorategames; } }
|
||||
|
||||
// Skills
|
||||
public List<SkillInfo> Skills { get { return skills; } }
|
||||
|
@ -238,6 +240,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
makedoortrack = cfg.ReadSetting("makedoortrack", "-");
|
||||
makedooraction = cfg.ReadSetting("makedooraction", 0);
|
||||
linetagindicatesectors = cfg.ReadSetting("linetagindicatesectors", false);
|
||||
decorategames = cfg.ReadSetting("decorategames", "");
|
||||
for(int i = 0; i < Linedef.NUM_ARGS; i++) makedoorargs[i] = cfg.ReadSetting("makedoorarg" + i.ToString(CultureInfo.InvariantCulture), 0);
|
||||
|
||||
// Flags have special (invariant culture) conversion
|
||||
|
|
|
@ -84,7 +84,31 @@ namespace CodeImp.DoomBuilder.Config
|
|||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
|
||||
// Constructor
|
||||
internal ThingCategory(string name, string title)
|
||||
{
|
||||
// Initialize
|
||||
this.name = name;
|
||||
this.title = title;
|
||||
this.things = new List<ThingTypeInfo>();
|
||||
|
||||
// Set default properties
|
||||
this.sprite = "";
|
||||
this.sorted = true;
|
||||
this.color = 18;
|
||||
this.arrow = 1;
|
||||
this.width = 10;
|
||||
this.height = 20;
|
||||
this.hangs = 0;
|
||||
this.blocking = 0;
|
||||
this.errorcheck = 1;
|
||||
this.fixedsize = false;
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
internal ThingCategory(Configuration cfg, string name)
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ using CodeImp.DoomBuilder.Data;
|
|||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Decorate;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -170,10 +171,65 @@ namespace CodeImp.DoomBuilder.Config
|
|||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
internal ThingTypeInfo(ThingCategory cat, ActorStructure actor)
|
||||
{
|
||||
// Initialize
|
||||
this.index = actor.DoomEdNum;
|
||||
this.category = cat;
|
||||
this.title = "Unnamed";
|
||||
|
||||
// Read properties
|
||||
this.sprite = cat.Sprite;
|
||||
this.color = cat.Color;
|
||||
this.arrow = (cat.Arrow != 0);
|
||||
this.width = cat.Width;
|
||||
this.height = cat.Height;
|
||||
this.hangs = (cat.Hangs != 0);
|
||||
this.blocking = cat.Blocking;
|
||||
this.errorcheck = cat.ErrorCheck;
|
||||
this.fixedsize = cat.FixedSize;
|
||||
|
||||
// Apply settings from actor
|
||||
ModifyByDecorateActor(actor);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
|
||||
// This updates the properties from a decorate actor
|
||||
internal void ModifyByDecorateActor(ActorStructure actor)
|
||||
{
|
||||
// Set the title
|
||||
if(actor.Tag != null)
|
||||
title = actor.Tag;
|
||||
else
|
||||
title = actor.ClassName;
|
||||
|
||||
// Set sprite
|
||||
sprite = actor.FindSuitableSprite();
|
||||
|
||||
if(this.sprite.Length <= 8)
|
||||
this.spritelongname = Lump.MakeLongName(this.sprite);
|
||||
else
|
||||
this.spritelongname = long.MaxValue;
|
||||
|
||||
// Size
|
||||
width = actor.Radius;
|
||||
height = actor.Height;
|
||||
|
||||
// Safety
|
||||
if(this.width < 8f) this.width = 8f;
|
||||
|
||||
// Options
|
||||
hangs = actor.GetFlagValue("spawnceiling", false);
|
||||
blocking = actor.GetFlagValue("solid", false) ? 2 : 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -915,6 +915,23 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// No such patch found
|
||||
return null;
|
||||
}
|
||||
|
||||
// This tests if a given sprite can be found
|
||||
internal bool GetSpriteExists(string pname)
|
||||
{
|
||||
if(!string.IsNullOrEmpty(pname))
|
||||
{
|
||||
// Go for all opened containers
|
||||
for(int i = containers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// This contain provides this patch?
|
||||
if(containers[i].GetSpriteExists(pname)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// No such patch found
|
||||
return false;
|
||||
}
|
||||
|
||||
// This loads the internal sprites
|
||||
private void LoadInternalSprites()
|
||||
|
@ -1036,40 +1053,83 @@ namespace CodeImp.DoomBuilder.Data
|
|||
DecorateParser parser;
|
||||
int counter = 0;
|
||||
|
||||
// Create the parser
|
||||
parser = new DecorateParser();
|
||||
parser.OnInclude = LoadDecorateFromLocation;
|
||||
|
||||
// Go for all opened containers
|
||||
foreach(DataReader dr in containers)
|
||||
// Only load these when the game configuration supports the use of decorate
|
||||
if(!string.IsNullOrEmpty(General.Map.Config.DecorateGames))
|
||||
{
|
||||
// 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;
|
||||
Stream decodata = dr.GetDecorateData("DECORATE");
|
||||
if(decodata != null)
|
||||
// Create the parser
|
||||
parser = new DecorateParser();
|
||||
parser.OnInclude = LoadDecorateFromLocation;
|
||||
|
||||
// Go for all opened containers
|
||||
foreach(DataReader dr in containers)
|
||||
{
|
||||
// Parse the data
|
||||
decodata.Seek(0, SeekOrigin.Begin);
|
||||
parser.Parse(decodata, "DECORATE");
|
||||
|
||||
// Check for errors
|
||||
if(parser.HasError)
|
||||
// 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;
|
||||
Stream decodata = dr.GetDecorateData("DECORATE");
|
||||
if(decodata != null)
|
||||
{
|
||||
General.WriteLogLine("ERROR: Unable to parse DECORATE data from location " + dr.Location.location + "!");
|
||||
General.WriteLogLine("ERROR: " + parser.ErrorDescription + " on line " + parser.ErrorLine + " in '" + parser.ErrorSource + "'");
|
||||
break;
|
||||
// Parse the data
|
||||
decodata.Seek(0, SeekOrigin.Begin);
|
||||
parser.Parse(decodata, "DECORATE");
|
||||
|
||||
// Check for errors
|
||||
if(parser.HasError)
|
||||
{
|
||||
General.WriteLogLine("ERROR: Unable to parse DECORATE data from location " + dr.Location.location + "!");
|
||||
General.WriteLogLine("ERROR: " + parser.ErrorDescription + " on line " + parser.ErrorLine + " in '" + parser.ErrorSource + "'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentreader = null;
|
||||
|
||||
if(!parser.HasError)
|
||||
{
|
||||
// Find the decorate category
|
||||
ThingCategory cat = null;
|
||||
foreach(ThingCategory c in thingcategories)
|
||||
{
|
||||
if(c.Name == "decorate")
|
||||
{
|
||||
cat = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Go for all actors in the decorate to make things or update things
|
||||
foreach(ActorStructure actor in parser.Actors)
|
||||
{
|
||||
// Check if we want to add this actor
|
||||
if(actor.DoomEdNum > 0)
|
||||
{
|
||||
// Check if we can find this thing in our existing collection
|
||||
if(thingtypes.ContainsKey(actor.DoomEdNum))
|
||||
{
|
||||
// Update the thing
|
||||
thingtypes[actor.DoomEdNum].ModifyByDecorateActor(actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make the decorate category if needed
|
||||
if(cat == null)
|
||||
{
|
||||
cat = new ThingCategory("decorate", "Decorate");
|
||||
thingcategories.Add(cat);
|
||||
}
|
||||
|
||||
// Add new thing
|
||||
ThingTypeInfo t = new ThingTypeInfo(cat, actor);
|
||||
cat.AddThing(t);
|
||||
thingtypes.Add(t.Index, t);
|
||||
}
|
||||
|
||||
// Count
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentreader = null;
|
||||
|
||||
if(!parser.HasError)
|
||||
{
|
||||
// Go for all actors in the decorate
|
||||
// TODO
|
||||
counter = parser.Actors.Count;
|
||||
}
|
||||
|
||||
// Output info
|
||||
|
@ -1079,7 +1139,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// This loads Decorate data from a specific file or lump name
|
||||
private void LoadDecorateFromLocation(DecorateParser parser, string location)
|
||||
{
|
||||
General.WriteLogLine("Including DECORATE resource '" + location + "'...");
|
||||
//General.WriteLogLine("Including DECORATE resource '" + location + "'...");
|
||||
Stream decodata = currentreader.GetDecorateData(location);
|
||||
if(decodata != null)
|
||||
{
|
||||
|
|
|
@ -118,9 +118,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
#endregion
|
||||
|
||||
#region ================== Sprites
|
||||
|
||||
|
||||
// When implemented, this returns the sprite lump
|
||||
public virtual Stream GetSpriteData(string pname) { return null; }
|
||||
|
||||
// When implemented, this checks if the given sprite lump exists
|
||||
public virtual bool GetSpriteExists(string pname) { return false; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -76,27 +76,37 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This returns all files in a given directory
|
||||
protected override string[] GetAllFiles(string path)
|
||||
protected override string[] GetAllFiles(string path, bool subfolders)
|
||||
{
|
||||
if(Directory.Exists(path))
|
||||
return Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||
{
|
||||
if(subfolders)
|
||||
return Directory.GetFiles(path, "*", SearchOption.AllDirectories);
|
||||
else
|
||||
return Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||
}
|
||||
else
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
// This returns all files in a given directory that match the given extension
|
||||
protected override string[] GetFilesWithExt(string path, string extension)
|
||||
protected override string[] GetFilesWithExt(string path, string extension, bool subfolders)
|
||||
{
|
||||
if(Directory.Exists(path))
|
||||
return Directory.GetFiles(path, "*." + extension, SearchOption.TopDirectoryOnly);
|
||||
{
|
||||
if(subfolders)
|
||||
return Directory.GetFiles(path, "*." + extension, SearchOption.AllDirectories);
|
||||
else
|
||||
return Directory.GetFiles(path, "*." + extension, SearchOption.TopDirectoryOnly);
|
||||
}
|
||||
else
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
// This finds the first file that has the specific name, regardless of file extension
|
||||
protected override string FindFirstFile(string path, string beginswith)
|
||||
protected override string FindFirstFile(string path, string beginswith, bool subfolders)
|
||||
{
|
||||
string[] files = GetAllFiles(path);
|
||||
string[] files = GetAllFiles(path, subfolders);
|
||||
foreach(string f in files)
|
||||
{
|
||||
if(string.Compare(Path.GetFileNameWithoutExtension(f), beginswith, true) == 0)
|
||||
|
@ -107,9 +117,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This finds the first file that has the specific name
|
||||
protected override string FindFirstFileWithExt(string path, string beginswith)
|
||||
protected override string FindFirstFileWithExt(string path, string beginswith, bool subfolders)
|
||||
{
|
||||
string[] files = GetAllFiles(path);
|
||||
string[] files = GetAllFiles(path, subfolders);
|
||||
foreach(string f in files)
|
||||
{
|
||||
if(string.Compare(Path.GetFileName(f), beginswith, true) == 0)
|
||||
|
|
|
@ -119,60 +119,107 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This returns all files in a given directory
|
||||
protected override string[] GetAllFiles(string path)
|
||||
protected override string[] GetAllFiles(string path, bool subfolders)
|
||||
{
|
||||
List<string> matches = new List<string>();
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
if(subfolders)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(Path.GetFileName(f).Length > 0))
|
||||
matches.Add(f);
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) &&
|
||||
(Path.GetFileName(f).Length > 0))
|
||||
matches.Add(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(Path.GetFileName(f).Length > 0))
|
||||
matches.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
return matches.ToArray();
|
||||
}
|
||||
|
||||
// This returns all files in a given directory that match the given extension
|
||||
protected override string[] GetFilesWithExt(string path, string extension)
|
||||
protected override string[] GetFilesWithExt(string path, string extension, bool subfolders)
|
||||
{
|
||||
List<string> matches = new List<string>();
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
string lowext = "." + extension.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
if(subfolders)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && f.EndsWith(lowext))
|
||||
matches.Add(f);
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) && f.EndsWith(lowext))
|
||||
matches.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && f.EndsWith(lowext))
|
||||
matches.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
return matches.ToArray();
|
||||
}
|
||||
|
||||
// This finds the first file that has the specific name, regardless of file extension
|
||||
protected override string FindFirstFile(string path, string beginswith)
|
||||
protected override string FindFirstFile(string path, string beginswith, bool subfolders)
|
||||
{
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
string lowbegin = beginswith.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
if(subfolders)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(string.Compare(Path.GetFileNameWithoutExtension(f), lowbegin) == 0))
|
||||
return f;
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) &&
|
||||
(string.Compare(Path.GetFileNameWithoutExtension(f), lowbegin) == 0))
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(string.Compare(Path.GetFileNameWithoutExtension(f), lowbegin) == 0))
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// This finds the first file that has the specific name
|
||||
protected override string FindFirstFileWithExt(string path, string beginswith)
|
||||
protected override string FindFirstFileWithExt(string path, string beginswith, bool subfolders)
|
||||
{
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
string lowbegin = beginswith.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
if(subfolders)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(string.Compare(Path.GetFileName(f), lowbegin) == 0))
|
||||
return f;
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if(Path.GetDirectoryName(f).StartsWith(lowpath, true, CultureInfo.InvariantCulture) &&
|
||||
(string.Compare(Path.GetFileName(f), lowbegin) == 0))
|
||||
return f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(string.Compare(Path.GetFileName(f), lowbegin) == 0))
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
this.spritespath = Path.Combine(rootpath, SPRITES_DIR);
|
||||
|
||||
// Load all WAD files in the root as WAD resources
|
||||
string[] wadfiles = GetFilesWithExt(rootpath, "wad");
|
||||
string[] wadfiles = GetFilesWithExt(rootpath, "wad", false);
|
||||
wads = new List<WADReader>(wadfiles.Length);
|
||||
foreach(string w in wadfiles)
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// Load TEXTURE1 lump file
|
||||
List<ImageData> imgset = new List<ImageData>();
|
||||
string texture1file = FindFirstFile(rootpath, "TEXTURE1");
|
||||
string texture1file = FindFirstFile(rootpath, "TEXTURE1", false);
|
||||
if((texture1file != null) && FileExists(texture1file))
|
||||
{
|
||||
MemoryStream filedata = LoadFile(texture1file);
|
||||
|
@ -202,7 +202,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// Load TEXTURE2 lump file
|
||||
string texture2file = FindFirstFile(rootpath, "TEXTURE2");
|
||||
string texture2file = FindFirstFile(rootpath, "TEXTURE2", false);
|
||||
if((texture2file != null) && FileExists(texture2file))
|
||||
{
|
||||
MemoryStream filedata = LoadFile(texture2file);
|
||||
|
@ -234,7 +234,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// If none of the wads provides patch names, let's see if we can
|
||||
string pnamesfile = FindFirstFile(rootpath, "PNAMES");
|
||||
string pnamesfile = FindFirstFile(rootpath, "PNAMES", false);
|
||||
if((pnamesfile != null) && FileExists(pnamesfile))
|
||||
{
|
||||
MemoryStream pnamesdata = LoadFile(pnamesfile);
|
||||
|
@ -261,7 +261,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// Find in patches directory
|
||||
string filename = FindFirstFile(patchespath, pname);
|
||||
string filename = FindFirstFile(patchespath, pname, true);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return LoadFile(filename);
|
||||
|
@ -326,7 +326,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// Find in sprites directory
|
||||
string filename = FindFirstFile(spritespath, pfilename);
|
||||
string filename = FindFirstFile(spritespath, pfilename, true);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return LoadFile(filename);
|
||||
|
@ -335,6 +335,31 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
// This checks if the given sprite exists
|
||||
public override bool GetSpriteExists(string pname)
|
||||
{
|
||||
string pfilename = pname.Replace('\\', '^');
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Find in any of the wad files
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if(wads[i].GetSpriteExists(pname)) return true;
|
||||
}
|
||||
|
||||
// Find in sprites directory
|
||||
string filename = FindFirstFile(spritespath, pfilename, true);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -357,7 +382,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
string filename = Path.GetFileName(pname);
|
||||
string pathname = Path.GetDirectoryName(pname);
|
||||
string fullpath = Path.Combine(rootpath, pathname);
|
||||
string foundfile = filename.IndexOf('.') > -1 ? FindFirstFileWithExt(fullpath, filename) : FindFirstFile(fullpath, filename);
|
||||
string foundfile = filename.IndexOf('.') > -1 ? FindFirstFileWithExt(fullpath, filename, false) : FindFirstFile(fullpath, filename, false);
|
||||
if((foundfile != null) && FileExists(foundfile))
|
||||
{
|
||||
return LoadFile(foundfile);
|
||||
|
@ -377,9 +402,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
List<ImageData> images = new List<ImageData>();
|
||||
string[] files;
|
||||
string name;
|
||||
|
||||
|
||||
// Go for all files
|
||||
files = GetAllFiles(path);
|
||||
files = GetAllFiles(path, false);
|
||||
foreach(string f in files)
|
||||
{
|
||||
// Make the texture name from filename without extension
|
||||
|
@ -423,16 +448,16 @@ namespace CodeImp.DoomBuilder.Data
|
|||
protected abstract bool FileExists(string filename);
|
||||
|
||||
// This must return all files in a given directory
|
||||
protected abstract string[] GetAllFiles(string path);
|
||||
protected abstract string[] GetAllFiles(string path, bool subfolders);
|
||||
|
||||
// This must return all files in a given directory that match the given extension
|
||||
protected abstract string[] GetFilesWithExt(string path, string extension);
|
||||
protected abstract string[] GetFilesWithExt(string path, string extension, bool subfolders);
|
||||
|
||||
// This must find the first file that has the specific name, regardless of file extension
|
||||
protected abstract string FindFirstFile(string path, string beginswith);
|
||||
protected abstract string FindFirstFile(string path, string beginswith, bool subfolders);
|
||||
|
||||
// This must find the first file that has the specific name
|
||||
protected abstract string FindFirstFileWithExt(string path, string beginswith);
|
||||
protected abstract string FindFirstFileWithExt(string path, string beginswith, bool subfolders);
|
||||
|
||||
// This must load an entire file in memory and returns the stream
|
||||
// NOTE: Callers are responsible for disposing the stream!
|
||||
|
|
|
@ -421,10 +421,23 @@ namespace CodeImp.DoomBuilder.Data
|
|||
lump = file.FindLump(pname);
|
||||
if(lump != null) return lump.Stream; else return null;
|
||||
}
|
||||
|
||||
|
||||
// This checks if the given sprite exists
|
||||
public override bool GetSpriteExists(string pname)
|
||||
{
|
||||
Lump lump;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Find the lump
|
||||
lump = file.FindLump(pname);
|
||||
return (lump != null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Sprite
|
||||
#region ================== Things
|
||||
|
||||
// This finds and returns a sprite stream
|
||||
public override Stream GetDecorateData(string pname)
|
||||
|
|
|
@ -35,6 +35,8 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
{
|
||||
#region ================== Constants
|
||||
|
||||
private readonly string[] SPRITE_POSTFIXES = new string[] {"2C8", "2D8", "2A8", "2B8", "1C1", "1D1", "1A1", "1B1", "A2", "A1", "A0", "2", "1", "0" };
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -43,6 +45,7 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
private string classname;
|
||||
private string inheritclass;
|
||||
private string replaceclass;
|
||||
private List<string> games;
|
||||
private int doomednum = -1;
|
||||
|
||||
// Flags
|
||||
|
@ -55,19 +58,24 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
// nothing that tells you if it is a value or another property)
|
||||
private int radius;
|
||||
private int height;
|
||||
private string tag;
|
||||
|
||||
// States
|
||||
private List<StateStructure> states;
|
||||
private Dictionary<string, StateStructure> states;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public Dictionary<string, bool> Flags { get { return flags; } }
|
||||
public string Name { get { return classname; } }
|
||||
public string ClassName { get { return classname; } }
|
||||
public string InheritsClass { get { return inheritclass; } }
|
||||
public string ReplacesClass { get { return replaceclass; } }
|
||||
public List<string> Games { get { return games; } }
|
||||
public int DoomEdNum { get { return doomednum; } }
|
||||
public int Radius { get { return radius; } }
|
||||
public int Height { get { return height; } }
|
||||
public int DoomEdNum { get { return doomednum; } }
|
||||
public string Tag { get { return tag; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -78,7 +86,11 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
{
|
||||
// Initialize
|
||||
flags = new Dictionary<string, bool>();
|
||||
states = new List<StateStructure>();
|
||||
states = new Dictionary<string, StateStructure>();
|
||||
inheritclass = "actor";
|
||||
replaceclass = null;
|
||||
games = new List<string>();
|
||||
tag = null;
|
||||
|
||||
// First next token is the class name
|
||||
parser.SkipWhitespace(true);
|
||||
|
@ -88,7 +100,7 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
parser.ReportError("Expected actor class name");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Parse tokens before entering the actor scope
|
||||
while(parser.SkipWhitespace(true))
|
||||
{
|
||||
|
@ -106,6 +118,15 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
parser.ReportError("Expected class name to inherit from");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the actor to inherit from
|
||||
ActorStructure other = parser.GetArchivedActorByName(inheritclass);
|
||||
if(other != null)
|
||||
InheritFrom(other);
|
||||
else
|
||||
General.WriteLogLine("WARNING: Unable to find the DECORATE class '" + inheritclass + "' to inherit from, while parsing '" + classname + "'");
|
||||
}
|
||||
}
|
||||
else if(token == "replaces")
|
||||
{
|
||||
|
@ -118,6 +139,10 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if(token == "native")
|
||||
{
|
||||
// Igore this token
|
||||
}
|
||||
else if(token == "{")
|
||||
{
|
||||
// Actor scope begins here,
|
||||
|
@ -143,6 +168,7 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
}
|
||||
|
||||
// Now parse the contents of actor structure
|
||||
string previoustoken = "";
|
||||
while(parser.SkipWhitespace(true))
|
||||
{
|
||||
string token = parser.ReadToken();
|
||||
|
@ -157,7 +183,7 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
{
|
||||
// Add the flag with its value
|
||||
flagname = flagname.ToLowerInvariant();
|
||||
flags.Add(flagname, flagvalue);
|
||||
flags[flagname] = flagvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -165,45 +191,44 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if((token == "action") || (token == "native"))
|
||||
{
|
||||
// We don't need this, ignore up to the first next ;
|
||||
while(parser.SkipWhitespace(true))
|
||||
{
|
||||
string t = parser.ReadToken();
|
||||
if((t == ";") || (t == null)) break;
|
||||
}
|
||||
}
|
||||
else if(token == "states")
|
||||
{
|
||||
// Now parse actor states until we reach the end of the states structure
|
||||
while(parser.SkipWhitespace(true))
|
||||
{
|
||||
string statename = parser.ReadToken();
|
||||
if(!string.IsNullOrEmpty(statename))
|
||||
string statetoken = parser.ReadToken();
|
||||
if(!string.IsNullOrEmpty(statetoken))
|
||||
{
|
||||
// Start of scope?
|
||||
if(statename == "{")
|
||||
if(statetoken == "{")
|
||||
{
|
||||
// This is fine
|
||||
}
|
||||
// End of scope?
|
||||
else if(statename == "}")
|
||||
else if(statetoken == "}")
|
||||
{
|
||||
// Done with the states,
|
||||
// break out of this parse loop
|
||||
break;
|
||||
}
|
||||
else
|
||||
// State label?
|
||||
else if(statetoken == ":")
|
||||
{
|
||||
// Next token must be a :
|
||||
parser.SkipWhitespace(true);
|
||||
string labeltoken = parser.ReadToken();
|
||||
if(!string.IsNullOrEmpty(statename))
|
||||
if(!string.IsNullOrEmpty(previoustoken))
|
||||
{
|
||||
if(labeltoken == ":")
|
||||
{
|
||||
// Parse actor state
|
||||
StateStructure st = new StateStructure(parser, statename);
|
||||
states.Add(st);
|
||||
if(parser.HasError) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.ReportError("Expected state label colon");
|
||||
return;
|
||||
}
|
||||
// Parse actor state
|
||||
StateStructure st = new StateStructure(parser, previoustoken);
|
||||
if(parser.HasError) return;
|
||||
states[previoustoken.ToLowerInvariant()] = st;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -211,6 +236,11 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep token
|
||||
previoustoken = statetoken;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -225,36 +255,59 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
// break out of this parse loop
|
||||
break;
|
||||
}
|
||||
else
|
||||
// Known property with a single value?
|
||||
else if((token == "radius") || (token == "height") || (token == "tag"))
|
||||
{
|
||||
// This must be a property
|
||||
|
||||
// Is this a known property?
|
||||
if((token == "radius") || (token == "height"))
|
||||
// Next token is the property value to set
|
||||
parser.SkipWhitespace(true);
|
||||
string value = parser.ReadToken();
|
||||
if(!string.IsNullOrEmpty(value))
|
||||
{
|
||||
// Next token is the property value to set
|
||||
parser.SkipWhitespace(true);
|
||||
string value = parser.ReadToken();
|
||||
if(!string.IsNullOrEmpty(value))
|
||||
// Try parsing as integer value
|
||||
int intvalue;
|
||||
int.TryParse(value, out intvalue);
|
||||
|
||||
// Set the property
|
||||
switch(token)
|
||||
{
|
||||
// Try parsing as integer value
|
||||
int intvalue;
|
||||
int.TryParse(value, out intvalue);
|
||||
|
||||
// Set the property
|
||||
if(token == "radius")
|
||||
radius = intvalue;
|
||||
else if(token == "height")
|
||||
height = intvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't find the property value!
|
||||
parser.ReportError("Expected a value for property '" + token + "'");
|
||||
return;
|
||||
case "radius": radius = intvalue; break;
|
||||
case "height": height = intvalue; break;
|
||||
case "tag": tag = value; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't find the property value!
|
||||
parser.ReportError("Expected a value for property '" + token + "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Monster property?
|
||||
else if(token == "monster")
|
||||
{
|
||||
// This sets certain flags we are interested in
|
||||
flags["solid"] = true;
|
||||
}
|
||||
// Game property?
|
||||
else if(token == "game")
|
||||
{
|
||||
// Include all tokens on the same line
|
||||
games.Clear();
|
||||
while(parser.SkipWhitespace(false))
|
||||
{
|
||||
string v = parser.ReadToken();
|
||||
if(v == null)
|
||||
{
|
||||
parser.ReportError("Unexpected end of structure");
|
||||
return;
|
||||
}
|
||||
if(v == "\n") break;
|
||||
games.Add(v.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
|
||||
// Keep token
|
||||
previoustoken = token;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,6 +315,94 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This is called to inherit properties from another actor
|
||||
private void InheritFrom(ActorStructure baseactor)
|
||||
{
|
||||
this.flags = new Dictionary<string, bool>(baseactor.flags);
|
||||
this.height = baseactor.height;
|
||||
this.radius = baseactor.radius;
|
||||
this.games = new List<string>(baseactor.games);
|
||||
this.states = new Dictionary<string, StateStructure>(baseactor.states);
|
||||
}
|
||||
|
||||
// This returns the status of a flag
|
||||
public bool GetFlagValue(string flag, bool defaultvalue)
|
||||
{
|
||||
if(flags.ContainsKey(flag))
|
||||
return flags[flag];
|
||||
else
|
||||
return defaultvalue;
|
||||
}
|
||||
|
||||
// This checks if this actor is meant for the current decorate game support
|
||||
public bool CheckActorSupported()
|
||||
{
|
||||
// Check if we want to include this actor
|
||||
string includegames = General.Map.Config.DecorateGames.ToLowerInvariant();
|
||||
bool includeactor = (games.Count == 0);
|
||||
foreach(string g in games)
|
||||
includeactor |= includegames.Contains(g);
|
||||
|
||||
return includeactor;
|
||||
}
|
||||
|
||||
// This finds the best suitable sprite to use
|
||||
public string FindSuitableSprite()
|
||||
{
|
||||
string sprite = "";
|
||||
|
||||
// Try the idle state
|
||||
if(states.ContainsKey("idle"))
|
||||
{
|
||||
StateStructure s = states["idle"];
|
||||
if(!string.IsNullOrEmpty(s.FirstSprite))
|
||||
sprite = s.FirstSprite;
|
||||
}
|
||||
|
||||
// Try the see state
|
||||
if(string.IsNullOrEmpty(sprite) && states.ContainsKey("see"))
|
||||
{
|
||||
StateStructure s = states["see"];
|
||||
if(!string.IsNullOrEmpty(s.FirstSprite))
|
||||
sprite = s.FirstSprite;
|
||||
}
|
||||
|
||||
// Try the inactive state
|
||||
if(string.IsNullOrEmpty(sprite) && states.ContainsKey("inactive"))
|
||||
{
|
||||
StateStructure s = states["inactive"];
|
||||
if(!string.IsNullOrEmpty(s.FirstSprite))
|
||||
sprite = s.FirstSprite;
|
||||
}
|
||||
|
||||
// Still no sprite found? then just pick the first we can find
|
||||
if(string.IsNullOrEmpty(sprite))
|
||||
{
|
||||
foreach(StateStructure s in states.Values)
|
||||
{
|
||||
if(!string.IsNullOrEmpty(s.FirstSprite))
|
||||
{
|
||||
sprite = s.FirstSprite;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(sprite))
|
||||
{
|
||||
// The sprite name is not actually complete, we still have to append
|
||||
// the direction characters to it. Find an existing sprite with direction.
|
||||
foreach(string postfix in SPRITE_POSTFIXES)
|
||||
{
|
||||
if(General.Map.Data.GetSpriteExists(sprite + postfix))
|
||||
return sprite + postfix;
|
||||
}
|
||||
}
|
||||
|
||||
// No sprite found
|
||||
return "";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,17 +42,20 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
#endregion
|
||||
|
||||
#region ================== Constants
|
||||
|
||||
|
||||
// Parsing
|
||||
private const string WHITESPACE = "\n \t\r";
|
||||
private const string SPECIALTOKEN = ":{}+-\n";
|
||||
private const string SPECIALTOKEN = ":{}+-\n;";
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
// Objects
|
||||
private List<ActorStructure> actors;
|
||||
// These are actors we want to keep
|
||||
private Dictionary<string, ActorStructure> actors;
|
||||
|
||||
// These are all parsed actors, also those from other games
|
||||
private Dictionary<string, ActorStructure> archivedactors;
|
||||
|
||||
// Input data stream
|
||||
private Stream datastream;
|
||||
|
@ -70,7 +73,7 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
|
||||
internal Stream DataStream { get { return datastream; } }
|
||||
internal BinaryReader DataReader { get { return datareader; } }
|
||||
public ICollection<ActorStructure> Actors { get { return actors; } }
|
||||
public ICollection<ActorStructure> Actors { get { return actors.Values; } }
|
||||
public int ErrorLine { get { return errorline; } }
|
||||
public string ErrorDescription { get { return errordesc; } }
|
||||
public string ErrorSource { get { return errorsource; } }
|
||||
|
@ -84,14 +87,15 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
public DecorateParser()
|
||||
{
|
||||
// Initialize
|
||||
actors = new List<ActorStructure>();
|
||||
actors = new Dictionary<string, ActorStructure>();
|
||||
archivedactors = new Dictionary<string, ActorStructure>();
|
||||
errordesc = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
|
||||
#region ================== Parsing
|
||||
|
||||
// This parses the given decorate stream
|
||||
// Returns false on errors
|
||||
public bool Parse(Stream stream, string sourcefilename)
|
||||
|
@ -117,8 +121,26 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
// Read actor structure
|
||||
ActorStructure actor = new ActorStructure(this);
|
||||
if(this.HasError) break;
|
||||
General.WriteLogLine("Added actor '" + actor.Name + "' from '" + localsourcename + "'");
|
||||
actors.Add(actor);
|
||||
|
||||
// Add the actor
|
||||
archivedactors[actor.ClassName.ToLowerInvariant()] = actor;
|
||||
if(actor.CheckActorSupported())
|
||||
actors[actor.ClassName.ToLowerInvariant()] = actor;
|
||||
|
||||
// Replace an actor?
|
||||
if(actor.ReplacesClass != null)
|
||||
{
|
||||
if(GetArchivedActorByName(actor.ReplacesClass) != null)
|
||||
archivedactors[actor.ReplacesClass.ToLowerInvariant()] = actor;
|
||||
else
|
||||
General.WriteLogLine("WARNING: Unable to find the DECORATE class '" + actor.ReplacesClass + "' to replace, while parsing '" + actor.ClassName + "'");
|
||||
|
||||
if(actor.CheckActorSupported())
|
||||
{
|
||||
if(GetActorByName(actor.ReplacesClass) != null)
|
||||
actors[actor.ReplacesClass.ToLowerInvariant()] = actor;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(objdeclaration == "#include")
|
||||
{
|
||||
|
@ -145,22 +167,34 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if((objdeclaration == "const") || (objdeclaration == "native"))
|
||||
{
|
||||
// We don't need this, ignore up to the first next ;
|
||||
while(SkipWhitespace(true))
|
||||
{
|
||||
string t = ReadToken();
|
||||
if((t == ";") || (t == null)) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown structure!
|
||||
// Best we can do now is just find the first { and the follow the scopes until the matching } is found
|
||||
// Best we can do now is just find the first { and then
|
||||
// follow the scopes until the matching } is found
|
||||
string token2;
|
||||
do
|
||||
{
|
||||
SkipWhitespace(true);
|
||||
if(!SkipWhitespace(true)) break;
|
||||
token2 = ReadToken();
|
||||
if(token2 == null) break;
|
||||
}
|
||||
while(token2 != "{");
|
||||
int scopelevel = 1;
|
||||
do
|
||||
{
|
||||
SkipWhitespace(true);
|
||||
if(!SkipWhitespace(true)) break;
|
||||
token2 = ReadToken();
|
||||
if(token2 == null) break;
|
||||
if(token2 == "{") scopelevel++;
|
||||
if(token2 == "}") scopelevel--;
|
||||
}
|
||||
|
@ -325,5 +359,31 @@ namespace CodeImp.DoomBuilder.Decorate
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This returns an actor by name
|
||||
// Returns null when actor cannot be found
|
||||
public ActorStructure GetActorByName(string name)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
if(actors.ContainsKey(name))
|
||||
return actors[name];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// This returns an actor by name
|
||||
// Returns null when actor cannot be found
|
||||
internal ActorStructure GetArchivedActorByName(string name)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
if(archivedactors.ContainsKey(name))
|
||||
return archivedactors[name];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue