mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 05:41:45 +00:00
Merge remote-tracking branch 'udb/master'
This commit is contained in:
commit
2b627b0e8a
5 changed files with 89 additions and 266 deletions
|
@ -222,26 +222,6 @@ secact_flagsrename
|
|||
}
|
||||
}
|
||||
|
||||
pathnode_flagsrename
|
||||
{
|
||||
DoomMapSetIO
|
||||
{
|
||||
8 = "Transition";
|
||||
}
|
||||
|
||||
HexenMapSetIO
|
||||
{
|
||||
8 = "Transition";
|
||||
16384 = "Invert Size Check";
|
||||
}
|
||||
|
||||
UniversalMapSetIO
|
||||
{
|
||||
ambush = "Transition";
|
||||
standing = "Invert Size Check";
|
||||
}
|
||||
}
|
||||
|
||||
// Default sector brightness levels
|
||||
sectorbrightness
|
||||
{
|
||||
|
|
|
@ -1284,41 +1284,6 @@ zdoom
|
|||
}
|
||||
}
|
||||
|
||||
9022
|
||||
{
|
||||
title = "Path Node";
|
||||
sprite = "internal:PathFollower";
|
||||
class = "PathNode";
|
||||
flagsrename { include("ZDoom_misc.cfg", "pathnode_flagsrename") }
|
||||
radius = 16;
|
||||
height = 56;
|
||||
arg0
|
||||
{
|
||||
title = "TID 1";
|
||||
type = 14;
|
||||
}
|
||||
arg1
|
||||
{
|
||||
title = "TID 2";
|
||||
type = 14;
|
||||
}
|
||||
arg2
|
||||
{
|
||||
title = "TID 3";
|
||||
type = 14;
|
||||
}
|
||||
arg3
|
||||
{
|
||||
title = "TID 4";
|
||||
type = 14;
|
||||
}
|
||||
arg4
|
||||
{
|
||||
title = "TID 5";
|
||||
type = 14;
|
||||
}
|
||||
}
|
||||
|
||||
9024
|
||||
{
|
||||
title = "Patrol Point";
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Connect Nodes`;
|
||||
|
||||
`#description Connects nodes to/from the first selected PathNode.`;
|
||||
|
||||
`#scriptoptions
|
||||
|
||||
direction
|
||||
{
|
||||
description = "Assignment Direction";
|
||||
default = 2;
|
||||
type = 11; // Enum
|
||||
enumvalues {
|
||||
0 = "To First";
|
||||
1 = "From First";
|
||||
2 = "Both";
|
||||
}
|
||||
}
|
||||
|
||||
doclear
|
||||
{
|
||||
description = "Clear first thing's arguments";
|
||||
default = "False";
|
||||
type = 3; // Boolean
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
let things = UDB.Map.getSelectedThings();
|
||||
|
||||
if(things.length < 2)
|
||||
UDB.die('You have to select at least 2 things.');
|
||||
|
||||
let dir = UDB.ScriptOptions.direction;
|
||||
let clr = UDB.ScriptOptions.doclear;
|
||||
|
||||
let receiver = things[0];
|
||||
|
||||
let pos = 0;
|
||||
|
||||
let i = 0;
|
||||
if (clr)
|
||||
{
|
||||
for (i; i < 5; i++)
|
||||
receiver.args[i] = 0;
|
||||
}
|
||||
|
||||
things.forEach(n =>
|
||||
{
|
||||
if (n != receiver)
|
||||
{
|
||||
if (dir > 0)
|
||||
{
|
||||
// look for the tid first, make sure it's not already assigned.
|
||||
let found = false;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (n.args[i] == receiver.tag)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Not found, so assign it.
|
||||
if (!found) for (i = 0; i < 5; i++)
|
||||
{
|
||||
|
||||
if (n.args[i] == 0)
|
||||
{
|
||||
n.args[i] = receiver.tag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if ((dir == 0 || dir == 2) && (pos < 5 && n.tag != 0))
|
||||
{
|
||||
|
||||
if (clr) // No special management necessary.
|
||||
{
|
||||
receiver.args[pos] = n.tag;
|
||||
pos++;
|
||||
}
|
||||
else // Look for a free spot.
|
||||
{
|
||||
let found = false;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (receiver.args[i] == n.tag)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
for (i = pos; i < 5; i++)
|
||||
{
|
||||
if (receiver.args[i] == 0)
|
||||
{
|
||||
receiver.args[i] = n.tag;
|
||||
pos = i;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,87 +0,0 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name New Path Node`;
|
||||
|
||||
`#description Creates a new node and assigns it a TID. If a Path Node is already selected, connects the two automatically.`;
|
||||
|
||||
`#scriptoptions
|
||||
|
||||
gridsnap
|
||||
{
|
||||
description = "Grid Snap";
|
||||
default = 1;
|
||||
type = 11; // enum
|
||||
enumvalues {
|
||||
0 = "Disabled";
|
||||
1 = "Enabled";
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
let mpos = UDB.Map.mousePosition;
|
||||
|
||||
if(!mpos.isFinite())
|
||||
UDB.die('Mouse cursor must be inside the map');
|
||||
|
||||
|
||||
let nodetype = 9022;
|
||||
let ntag = UDB.Map.getNewTag();
|
||||
let things = UDB.Map.getSelectedThings();
|
||||
|
||||
let node = UDB.Map.createThing(mpos, nodetype);
|
||||
if (UDB.ScriptOptions.gridsnap > 0)
|
||||
node.snapToGrid();
|
||||
node.tag = ntag;
|
||||
|
||||
let i = 0;
|
||||
let count = 0;
|
||||
if(things.length > 0)
|
||||
{
|
||||
things.forEach(n =>
|
||||
{
|
||||
if (n.type == nodetype)
|
||||
{
|
||||
// For the new node, assign the path IDs to it, up to max arguments.
|
||||
if (n.tag != 0 && count < 5)
|
||||
{
|
||||
node.args[count] = n.tag;
|
||||
count++;
|
||||
}
|
||||
// For the selected nodes, check for an empty slot.
|
||||
let pos = -1;
|
||||
|
||||
for(i = 0; i < 5; i++)
|
||||
{
|
||||
if (n.args[i] != 0)
|
||||
continue;
|
||||
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check if the tag is already used first.
|
||||
if (pos >= 0)
|
||||
{
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (n.args[i] == ntag)
|
||||
{
|
||||
pos = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Free slot, and unpresent. Set it in.
|
||||
if (pos >= 0)
|
||||
n.args[pos] = ntag;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
UDB.Map.clearSelectedThings();
|
||||
node.selected = true;
|
|
@ -24,9 +24,11 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
public bool IsMixin { get; internal set; }
|
||||
public bool IsExtension { get; internal set; }
|
||||
public List<ZScriptClassStructure> Extensions { get; internal set; }
|
||||
public bool IsFinal { get; internal set; }
|
||||
public List<string> PermittedInheritedClassNames { get; internal set; }
|
||||
|
||||
// these are used for parsing and error reporting
|
||||
public ZScriptParser Parser { get; internal set; }
|
||||
// these are used for parsing and error reporting
|
||||
public ZScriptParser Parser { get; internal set; }
|
||||
public Stream Stream { get; internal set; }
|
||||
public long Position { get; internal set; }
|
||||
public BinaryReader DataReader { get; internal set; }
|
||||
|
@ -36,7 +38,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
// textresourcepath
|
||||
public string TextResourcePath { get; internal set; }
|
||||
|
||||
internal ZScriptClassStructure(ZScriptParser parser, string classname, string replacesname, string parentname, bool ismixin, bool isextension, DecorateCategoryInfo region)
|
||||
internal ZScriptClassStructure(ZScriptParser parser, string classname, DecorateCategoryInfo region, string replacesname=null, string parentname=null, bool ismixin=false, bool isextension=false, bool isfinal=false, List<string> permittedinheritedclassnames=null)
|
||||
{
|
||||
Parser = parser;
|
||||
|
||||
|
@ -56,6 +58,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
IsMixin = ismixin;
|
||||
IsExtension = isextension;
|
||||
Extensions = new List<ZScriptClassStructure>();
|
||||
IsFinal = isfinal;
|
||||
PermittedInheritedClassNames = permittedinheritedclassnames == null ? new List<string>() : new List<string>(permittedinheritedclassnames); // for the "sealed" class modifier
|
||||
}
|
||||
|
||||
internal void RestoreStreamData()
|
||||
|
@ -100,6 +104,20 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
Parser.ReportError("Fatal: Class \"" + _cname + "\" is trying to inherit from \"" + _pname + "\" which does not exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure that the parent class isn't "final"
|
||||
if(_pstruct.IsFinal)
|
||||
{
|
||||
Parser.ReportError($"Fatal: Class \"{_cname}\" is trying to inherit from \"{_pname}\" which is final");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure we're allowed to inherit from parent class
|
||||
if(_pstruct.PermittedInheritedClassNames.Count > 0 && !_pstruct.PermittedInheritedClassNames.Contains(_cname.ToLowerInvariant()))
|
||||
{
|
||||
Parser.ReportError($"Fatal: Class \"{_cname}\" is not allowed to inherit from \"{_pname}\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else _pstruct = null;
|
||||
}
|
||||
|
@ -730,8 +748,10 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
ZScriptToken tok_native = null;
|
||||
ZScriptToken tok_scope = null;
|
||||
ZScriptToken tok_version = null;
|
||||
ZScriptToken tok_final = null;
|
||||
string[] class_scope_modifiers = new string[] { "clearscope", "ui", "play" };
|
||||
string[] other_modifiers = new string[] { "abstract" };
|
||||
List<string> permitted_inherited_class_names = new List<string>();
|
||||
while (true)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
|
@ -777,6 +797,20 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
|
||||
tok_native = token;
|
||||
}
|
||||
else if(token.Value.ToLowerInvariant() == "final")
|
||||
{
|
||||
if(tok_final != null)
|
||||
{
|
||||
ReportError("Cannot have two final keywords");
|
||||
return false;
|
||||
}
|
||||
|
||||
tok_final = token;
|
||||
}
|
||||
else if(token.Value.ToLowerInvariant() == "sealed")
|
||||
{
|
||||
permitted_inherited_class_names = ParseSealed();
|
||||
}
|
||||
else if (Array.IndexOf(class_scope_modifiers, token.Value.ToLowerInvariant()) >= 0)
|
||||
{
|
||||
if (tok_scope != null)
|
||||
|
@ -874,7 +908,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.
|
||||
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, false, region);
|
||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, region, (tok_replacename != null) ? tok_replacename.Value : null, (tok_parentname != null) ? tok_parentname.Value : null, false, false, tok_final != null, permitted_inherited_class_names);
|
||||
cls.Position = cpos;
|
||||
string clskey = cls.ClassName.ToLowerInvariant();
|
||||
if (allclasses.ContainsKey(clskey))
|
||||
|
@ -904,7 +938,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
return false;
|
||||
}
|
||||
|
||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, null, null, false, true, region);
|
||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, region, isextension: true);
|
||||
cls.Position = cpos;
|
||||
allclasses[clskey].Extensions.Add(cls);
|
||||
}
|
||||
|
@ -912,7 +946,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
{
|
||||
// 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
|
||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, null, null, true, false, region);
|
||||
// ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, null, null, true, false, false, null, region);
|
||||
ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, region, ismixin: true);
|
||||
cls.Position = cpos;
|
||||
string clskey = cls.ClassName.ToLowerInvariant();
|
||||
if(mixinclasses.ContainsKey(clskey))
|
||||
|
@ -930,9 +965,9 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
return true;
|
||||
}
|
||||
|
||||
// This parses the given decorate stream
|
||||
// Returns false on errors
|
||||
public override bool Parse(TextResourceData data, bool clearerrors)
|
||||
// This parses the given decorate stream
|
||||
// Returns false on errors
|
||||
public override bool Parse(TextResourceData data, bool clearerrors)
|
||||
{
|
||||
if (clearerrors) LastClasses = new HashSet<string>();
|
||||
|
||||
|
@ -1136,7 +1171,51 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool Finalize()
|
||||
/// <summary>
|
||||
/// Parses the class names after the "sealed" class modifier.
|
||||
/// </summary>
|
||||
/// <returns>A list of strings with the class names that can inherit this class</returns>
|
||||
private List<string> ParseSealed()
|
||||
{
|
||||
ZScriptToken token;
|
||||
List<string> permittedinheritedclassnames = new List<string>();
|
||||
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.OpenParen);
|
||||
if(token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected (, got " + ((Object)token ?? "<null>").ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if(token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected class name, got " + ((Object)token ?? "<null>").ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
permittedinheritedclassnames.Add(token.Value.ToLowerInvariant());
|
||||
|
||||
tokenizer.SkipWhitespace();
|
||||
token = tokenizer.ExpectToken(ZScriptTokenType.Comma, ZScriptTokenType.CloseParen);
|
||||
if(token == null || !token.IsValid)
|
||||
{
|
||||
ReportError("Expected , or ), got " + ((Object)token ?? "<null>").ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (token.Type == ZScriptTokenType.CloseParen)
|
||||
break;
|
||||
}
|
||||
|
||||
return permittedinheritedclassnames;
|
||||
}
|
||||
|
||||
public bool Finalize()
|
||||
{
|
||||
ClearError();
|
||||
|
||||
|
|
Loading…
Reference in a new issue