mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-17 01:22:18 +00:00
ZScript: added support for extending classes. Resolves #597
This commit is contained in:
parent
be84f19da1
commit
45dc796dca
1 changed files with 88 additions and 21 deletions
|
@ -22,6 +22,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
public ZScriptActorStructure Actor { get; internal set; }
|
public ZScriptActorStructure Actor { get; internal set; }
|
||||||
internal DecorateCategoryInfo Region;
|
internal DecorateCategoryInfo Region;
|
||||||
public bool IsMixin { get; internal set; }
|
public bool IsMixin { get; internal set; }
|
||||||
|
public bool IsExtension { get; internal set; }
|
||||||
|
public List<ZScriptClassStructure> Extensions { get; internal set; }
|
||||||
|
|
||||||
// these are used for parsing and error reporting
|
// these are used for parsing and error reporting
|
||||||
public ZScriptParser Parser { get; internal set; }
|
public ZScriptParser Parser { get; internal set; }
|
||||||
|
@ -34,7 +36,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
// textresourcepath
|
// textresourcepath
|
||||||
public string TextResourcePath { get; internal set; }
|
public string TextResourcePath { get; internal set; }
|
||||||
|
|
||||||
internal ZScriptClassStructure(ZScriptParser parser, string classname, string replacesname, string parentname, bool ismixin, DecorateCategoryInfo region)
|
internal ZScriptClassStructure(ZScriptParser parser, string classname, string replacesname, string parentname, bool ismixin, bool isextension, DecorateCategoryInfo region)
|
||||||
{
|
{
|
||||||
Parser = parser;
|
Parser = parser;
|
||||||
|
|
||||||
|
@ -52,6 +54,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
Region = region;
|
Region = region;
|
||||||
|
|
||||||
IsMixin = ismixin;
|
IsMixin = ismixin;
|
||||||
|
IsExtension = isextension;
|
||||||
|
Extensions = new List<ZScriptClassStructure>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RestoreStreamData()
|
internal void RestoreStreamData()
|
||||||
|
@ -97,7 +101,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
if (ReplacementName != null) log_inherits += ((log_inherits.Length > 0) ? ", " : "") + "replaces " + ReplacementName;
|
if (ReplacementName != null) log_inherits += ((log_inherits.Length > 0) ? ", " : "") + "replaces " + ReplacementName;
|
||||||
if (log_inherits.Length > 0) log_inherits = " (" + log_inherits + ")";
|
if (log_inherits.Length > 0) log_inherits = " (" + log_inherits + ")";
|
||||||
|
|
||||||
if (isactor || IsMixin)
|
if (isactor || IsMixin || IsExtension)
|
||||||
{
|
{
|
||||||
Actor = new ZScriptActorStructure(Parser, Region, ClassName, ReplacementName, ParentName);
|
Actor = new ZScriptActorStructure(Parser, Region, ClassName, ReplacementName, ParentName);
|
||||||
if (Parser.HasError)
|
if (Parser.HasError)
|
||||||
|
@ -106,26 +110,29 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check actor replacement.
|
if (!IsExtension)
|
||||||
Parser.archivedactors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
{
|
||||||
Parser.realarchivedactors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
// check actor replacement.
|
||||||
if (Actor.CheckActorSupported())
|
Parser.archivedactors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
||||||
Parser.actors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
Parser.realarchivedactors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
||||||
|
if (Actor.CheckActorSupported())
|
||||||
|
Parser.actors[Actor.ClassName.ToLowerInvariant()] = Actor;
|
||||||
|
|
||||||
// Replace an actor?
|
// Replace an actor?
|
||||||
if (Actor.ReplacesClass != null)
|
if (Actor.ReplacesClass != null)
|
||||||
{
|
{
|
||||||
if (Parser.GetArchivedActorByName(Actor.ReplacesClass, false) != null)
|
if (Parser.GetArchivedActorByName(Actor.ReplacesClass, false) != null)
|
||||||
Parser.archivedactors[Actor.ReplacesClass.ToLowerInvariant()] = Actor;
|
Parser.archivedactors[Actor.ReplacesClass.ToLowerInvariant()] = Actor;
|
||||||
else
|
else
|
||||||
Parser.LogWarning("Unable to find \"" + Actor.ReplacesClass + "\" class to replace, while parsing \"" + Actor.ClassName + "\"");
|
Parser.LogWarning("Unable to find \"" + Actor.ReplacesClass + "\" class to replace, while parsing \"" + Actor.ClassName + "\"");
|
||||||
|
|
||||||
if (Actor.CheckActorSupported() && Parser.GetActorByName(Actor.ReplacesClass) != null)
|
if (Actor.CheckActorSupported() && Parser.GetActorByName(Actor.ReplacesClass) != null)
|
||||||
Parser.actors[Actor.ReplacesClass.ToLowerInvariant()] = Actor;
|
Parser.actors[Actor.ReplacesClass.ToLowerInvariant()] = Actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Add to current text resource
|
//mxd. Add to current text resource
|
||||||
if (!Parser.scriptresources[TextResourcePath].Entries.Contains(Actor.ClassName)) Parser.scriptresources[TextResourcePath].Entries.Add(Actor.ClassName);
|
if (!Parser.scriptresources[TextResourcePath].Entries.Contains(Actor.ClassName)) Parser.scriptresources[TextResourcePath].Entries.Add(Actor.ClassName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parser.LogWarning(string.Format("Parsed {0}class {1}{2}", isactor?"actor ":"", ClassName, log_inherits));
|
//Parser.LogWarning(string.Format("Parsed {0}class {1}{2}", isactor?"actor ":"", ClassName, log_inherits));
|
||||||
|
@ -750,7 +757,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
// now if we are a class, and we inherit actor, parse this entry as an actor. don't process extensions.
|
// now if we are a class, and we inherit actor, parse this entry as an actor. don't process extensions.
|
||||||
if (!isstruct && !extend && !mixin)
|
if (!isstruct && !extend && !mixin)
|
||||||
{
|
{
|
||||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, (tok_replacename != null) ? tok_replacename.Value : null, (tok_parentname != null) ? tok_parentname.Value : null, false, region);
|
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, (tok_replacename != null) ? tok_replacename.Value : null, (tok_parentname != null) ? tok_parentname.Value : null, false, false, region);
|
||||||
cls.Position = cpos;
|
cls.Position = cpos;
|
||||||
string clskey = cls.ClassName.ToLowerInvariant();
|
string clskey = cls.ClassName.ToLowerInvariant();
|
||||||
if (allclasses.ContainsKey(clskey))
|
if (allclasses.ContainsKey(clskey))
|
||||||
|
@ -762,11 +769,32 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
allclasses.Add(cls.ClassName.ToLowerInvariant(), cls);
|
allclasses.Add(cls.ClassName.ToLowerInvariant(), cls);
|
||||||
allclasseslist.Add(cls);
|
allclasseslist.Add(cls);
|
||||||
}
|
}
|
||||||
|
else if(!isstruct && extend)
|
||||||
|
{
|
||||||
|
string clskey = tok_classname.Value.ToLowerInvariant();
|
||||||
|
|
||||||
|
if(!allclasses.ContainsKey(clskey))
|
||||||
|
{
|
||||||
|
ReportError("Trying to extend class " + tok_classname.Value + " before it was defined");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GZDoom doesn't allow extending classes that are from another archive
|
||||||
|
if(!allclasses[clskey].DataLocation.Equals(datalocation))
|
||||||
|
{
|
||||||
|
ReportError("Trying to extend class " + tok_classname.Value + " that's not part of data location \"" + datalocation + "\", but \"" + allclasses[clskey].DataLocation + "\"");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, null, null, false, true, region);
|
||||||
|
cls.Position = cpos;
|
||||||
|
allclasses[clskey].Extensions.Add(cls);
|
||||||
|
}
|
||||||
else if (mixin)
|
else if (mixin)
|
||||||
{
|
{
|
||||||
// This is a bit ugly. We're treating mixin classes as actors, even though they aren't. But otherwise the parser
|
// This is a bit ugly. We're treating mixin classes as actors, even though they aren't. But otherwise the parser
|
||||||
// doesn't parse all the actor info we need
|
// doesn't parse all the actor info we need
|
||||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, null, null, true, region);
|
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, null, null, true, false, region);
|
||||||
cls.Position = cpos;
|
cls.Position = cpos;
|
||||||
string clskey = cls.ClassName.ToLowerInvariant();
|
string clskey = cls.ClassName.ToLowerInvariant();
|
||||||
if(mixinclasses.ContainsKey(clskey))
|
if(mixinclasses.ContainsKey(clskey))
|
||||||
|
@ -987,6 +1015,11 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
{
|
{
|
||||||
if (!cls.Process())
|
if (!cls.Process())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Process extensions
|
||||||
|
foreach (ZScriptClassStructure extension in cls.Extensions)
|
||||||
|
if (!extension.Process())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse mixin class data
|
// Parse mixin class data
|
||||||
|
@ -1113,6 +1146,40 @@ namespace CodeImp.DoomBuilder.ZDoom
|
||||||
actor.flags["solid"] = true;
|
actor.flags["solid"] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extensions. https://zdoom.org/wiki/ZScript_classes#Extending_Classes
|
||||||
|
if (cls.Extensions.Count > 0)
|
||||||
|
{
|
||||||
|
foreach(ZScriptClassStructure extension in cls.Extensions)
|
||||||
|
{
|
||||||
|
ActorStructure extenseionactor = extension.Actor;
|
||||||
|
|
||||||
|
if (extenseionactor == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// States
|
||||||
|
if (extenseionactor.states.ContainsKey("spawn"))
|
||||||
|
actor.states["spawn"] = extenseionactor.GetState("spawn");
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
if (extenseionactor.props.ContainsKey("height"))
|
||||||
|
actor.props["height"] = new List<string>(extenseionactor.props["height"]);
|
||||||
|
|
||||||
|
if (extenseionactor.props.ContainsKey("radius"))
|
||||||
|
actor.props["radius"] = new List<string>(extenseionactor.props["radius"]);
|
||||||
|
|
||||||
|
// Flags
|
||||||
|
if (extenseionactor.flags.ContainsKey("spawnceiling"))
|
||||||
|
actor.flags["spawnceiling"] = true;
|
||||||
|
|
||||||
|
if (extenseionactor.flags.ContainsKey("solid"))
|
||||||
|
actor.flags["solid"] = true;
|
||||||
|
|
||||||
|
// user_ variables
|
||||||
|
foreach (string uservarname in extenseionactor.uservars.Keys)
|
||||||
|
actor.uservars[uservarname] = extenseionactor.uservars[uservarname];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue