overpy 9.5.14 → 9.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -4
- package/overpy.js +334 -65
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -791,6 +791,49 @@ content.toString();
|
|
|
791
791
|
|
|
792
792
|
The hook script does not need to declare a wrapper function; writing statements that transform `content` is enough.
|
|
793
793
|
|
|
794
|
+
## #!rulePrefix
|
|
795
|
+
|
|
796
|
+
Sets a prefix for all subsequent rules. The prefix is applied to the rule name using a template (by default, `[prefix] ruleName`).
|
|
797
|
+
|
|
798
|
+
If a `#!rulePrefix` directive is in an included file, it only takes effect for rules within that file (and its child includes, if they don't have their own `#!rulePrefix`), after the directive. When the included file ends, the prefix is restored to what it was before the include.
|
|
799
|
+
|
|
800
|
+
```hs
|
|
801
|
+
#!rulePrefix "Effects"
|
|
802
|
+
|
|
803
|
+
rule "Spawn particles":
|
|
804
|
+
#compiled rule name: [Effects] Spawn particles
|
|
805
|
+
|
|
806
|
+
#!rulePrefix ""
|
|
807
|
+
rule "Unprefixed rule":
|
|
808
|
+
#compiled rule name: Unprefixed rule
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
## #!rulePrefixTemplate
|
|
812
|
+
|
|
813
|
+
Defines a global template for how rule prefixes are applied to rule names. Can only be defined once and has effect on all rules (even those declared before it).
|
|
814
|
+
|
|
815
|
+
The template is an OverPy expression with the following variables:
|
|
816
|
+
|
|
817
|
+
- `$rule`: the current rule name
|
|
818
|
+
- `$isDelimiter`: true if the rule has `@Delimiter`
|
|
819
|
+
- `$prefix`: the current prefix
|
|
820
|
+
- `$file`: the file name without extension
|
|
821
|
+
- `$path`: the relative path to the main file (backslashes replaced by slashes)
|
|
822
|
+
- Titlecase/lower/upper variations: `$prefixTitle`, `$prefixUpper`, `$prefixLower`, `$fileTitle`, `$fileUpper`, `$fileLower`, `$pathTitle`, `$pathUpper`, `$pathLower`
|
|
823
|
+
|
|
824
|
+
Examples :
|
|
825
|
+
|
|
826
|
+
- `#!rulePrefixTemplate f"[{$prefix}] {$rule}" if $prefix and $rule else $rule` (default): adds the prefix in square brackets before the rule name, if the prefix and rule name are not empty. This is the default if this directive is unspecified.
|
|
827
|
+
- `#!rulePrefixTemplate f"[{$pathTitle.replace('_', ' ')}] {$rule}" if $rule and not $isDelimiter else $rule`": if you have an `heroes/junker_queen.opy` file, will yield rule names like `"[Heroes/Junker Queen] Spawn particles"`. This is the default if the directive is specified without an expression (just `#!rulePrefixTemplate`).
|
|
828
|
+
|
|
829
|
+
The expression has to evaluate to a string without arguments.
|
|
830
|
+
|
|
831
|
+
#!rulePrefix "effects"
|
|
832
|
+
|
|
833
|
+
rule "Spawn particles":
|
|
834
|
+
#compiled rule name: (EFFECTS) Spawn particles
|
|
835
|
+
```
|
|
836
|
+
|
|
794
837
|
# Advanced constructs
|
|
795
838
|
|
|
796
839
|
## Switches
|
|
@@ -911,9 +954,9 @@ OverPy will store the array in a string and automatically decompress it, which t
|
|
|
911
954
|
|
|
912
955
|
For more control over the compression (eg if you have separate arrays to compress), you can use the `compress` and `decompressNumbers`/`decompressVectors` functions.
|
|
913
956
|
|
|
914
|
-
## splitDictArray
|
|
957
|
+
## splitDictArray/tabular
|
|
915
958
|
|
|
916
|
-
|
|
959
|
+
`splitDictArray` maps an array of dictionaries to variables. For example:
|
|
917
960
|
|
|
918
961
|
```python
|
|
919
962
|
splitDictArray({
|
|
@@ -933,6 +976,16 @@ waveHeroes = [Hero.ANA, Hero.SOLDIER, Hero.HAMMOND]
|
|
|
933
976
|
waveLengths = [3, 8, null]
|
|
934
977
|
```
|
|
935
978
|
|
|
979
|
+
For a terser syntax, `tabular` can be used, where the second argument is a raw array (not an array of arrays!)
|
|
980
|
+
|
|
981
|
+
```
|
|
982
|
+
tabular([waveHeroes, waveLengths], [
|
|
983
|
+
Hero.ANA, 3,
|
|
984
|
+
Hero.SOLDIER, 8,
|
|
985
|
+
Hero.HAMMOND, null,
|
|
986
|
+
])
|
|
987
|
+
```
|
|
988
|
+
|
|
936
989
|
If the third argument is specified and set to `true`, string compression is automatically used for number and vector arrays.
|
|
937
990
|
|
|
938
991
|
## 2d/3d array assignment
|
|
@@ -1004,9 +1057,11 @@ This also means that, when used in a variable, you cannot use a translated strin
|
|
|
1004
1057
|
|
|
1005
1058
|
Last, you can use the `#!translateWithPlayerVar` directive to store the player's language in a variable using a rule which uses the `.startFacing()` function when the player spawns (the language is determined based on the player's facing direction).
|
|
1006
1059
|
|
|
1007
|
-
If using translations, this can save a lot of elements. However, it will make translated strings not display correctly for spectators
|
|
1060
|
+
If using translations, this can save a lot of elements. However, it will make translated strings not display correctly for spectators. There are two options if your gamemode must cater to spectators:
|
|
1061
|
+
- Either wrap the strings with the `__` function (which behaves the same as the `_` function, except it will not use the `__languageIndex__` player variable).
|
|
1062
|
+
- Or, if you are short on elements, do `#!translateWithPlayerVar noTlErr`. This disables `TlErr` (which may cause you to badly setup the translations, so test thoroughly if disabling it!) but makes the `__languageIndex__` be 0-indexed, which enables spectators to see the default language (but it will not be translated).
|
|
1008
1063
|
|
|
1009
|
-
If your gamemode changes the facing direction on spawn, you must modify it so that it changes it once `eventPlayer.__languageIndex__ != 1.1`.
|
|
1064
|
+
If your gamemode changes the facing direction on spawn, you must modify it so that it changes it once `eventPlayer.__languageIndex__ != 1.1` or 0.1 if using `noTlErr`.
|
|
1010
1065
|
|
|
1011
1066
|
The `___` function is the same as the `_` function, but will never resolve the translation, even if in a display action. You must wrap it with the `_` function to resolve it.
|
|
1012
1067
|
|
package/overpy.js
CHANGED
|
@@ -38423,9 +38423,9 @@ var LogicalLine = class {
|
|
|
38423
38423
|
var Token = class {
|
|
38424
38424
|
text;
|
|
38425
38425
|
fileStack;
|
|
38426
|
-
constructor(text,
|
|
38426
|
+
constructor(text, fileStack7) {
|
|
38427
38427
|
this.text = text;
|
|
38428
|
-
this.fileStack =
|
|
38428
|
+
this.fileStack = fileStack7;
|
|
38429
38429
|
this.fileStack[this.fileStack.length - 1].endCol = this.fileStack[this.fileStack.length - 1].startCol + this.text.split("\n")[this.text.split("\n").length - 1].length;
|
|
38430
38430
|
this.fileStack[this.fileStack.length - 1].endLine = this.fileStack[this.fileStack.length - 1].startLine + this.text.split("\n").length - 1;
|
|
38431
38431
|
}
|
|
@@ -38569,9 +38569,13 @@ ${scriptText}`, {
|
|
|
38569
38569
|
}
|
|
38570
38570
|
if (content2.startsWith("#!translateWithPlayerVar")) {
|
|
38571
38571
|
setUsePlayerVarForTranslations(true);
|
|
38572
|
-
|
|
38572
|
+
let args = content2.substring("#!translateWithPlayerVar".length).trim().split(" ");
|
|
38573
|
+
if (args.includes("noDetectionRule")) {
|
|
38573
38574
|
setGenerateRuleForTranslationsPlayerVar(false);
|
|
38574
38575
|
}
|
|
38576
|
+
if (args.includes("noTlErr")) {
|
|
38577
|
+
setTranslationUseTlErr(false);
|
|
38578
|
+
}
|
|
38575
38579
|
return;
|
|
38576
38580
|
}
|
|
38577
38581
|
if (content2.startsWith("#!disableInspector")) {
|
|
@@ -38658,6 +38662,25 @@ ${scriptText}`, {
|
|
|
38658
38662
|
);
|
|
38659
38663
|
return;
|
|
38660
38664
|
}
|
|
38665
|
+
if (content2.startsWith("#!rulePrefix ")) {
|
|
38666
|
+
let prefix = content2.substring("#!rulePrefix ".length).trim();
|
|
38667
|
+
addToken("__rulePrefix__");
|
|
38668
|
+
addToken("(");
|
|
38669
|
+
addToken(prefix);
|
|
38670
|
+
addToken(")");
|
|
38671
|
+
return;
|
|
38672
|
+
}
|
|
38673
|
+
if (content2.startsWith("#!rulePrefixTemplate")) {
|
|
38674
|
+
if (rulePrefixTemplate !== "") {
|
|
38675
|
+
error("A rule prefix template has already been defined");
|
|
38676
|
+
}
|
|
38677
|
+
let template = content2.substring("#!rulePrefixTemplate".length).trim() || `f"[{$pathTitle.replace('_', ' ')}] {$rule}" if $rule and not $isDelimiter else $rule`;
|
|
38678
|
+
setRulePrefixTemplate(template);
|
|
38679
|
+
let _rulePrefixTemplateFilestack = getFileStackCopy();
|
|
38680
|
+
_rulePrefixTemplateFilestack[_rulePrefixTemplateFilestack.length - 1].startCol = content2.indexOf(template) + 1;
|
|
38681
|
+
setRulePrefixTemplateFilestack(_rulePrefixTemplateFilestack);
|
|
38682
|
+
return;
|
|
38683
|
+
}
|
|
38661
38684
|
error("Unknown preprocessor directive '" + content2 + "'");
|
|
38662
38685
|
}
|
|
38663
38686
|
for (i = 0; i < content.length; moveCursor(1)) {
|
|
@@ -38753,7 +38776,11 @@ ${scriptText}`, {
|
|
|
38753
38776
|
staticMember: true,
|
|
38754
38777
|
fileStackMemberType: "normal"
|
|
38755
38778
|
});
|
|
38779
|
+
let pushLine = new LogicalLine(0, [new Token("__pushRulePrefixStack__", getFileStackCopy())]);
|
|
38780
|
+
let popLine = new LogicalLine(0, [new Token("__popRulePrefixStack__", getFileStackCopy())]);
|
|
38781
|
+
result.push(pushLine);
|
|
38756
38782
|
result.push(...tokenize(importedFileContent));
|
|
38783
|
+
result.push(popLine);
|
|
38757
38784
|
fileStack2.pop();
|
|
38758
38785
|
moveCursor(j2 - i - 1);
|
|
38759
38786
|
}
|
|
@@ -39587,13 +39614,13 @@ function parseAstMacro(macro) {
|
|
|
39587
39614
|
if (!(macro.name in astMacros)) {
|
|
39588
39615
|
error("Unknown macro '" + macro.name + "'", macro.fileStack);
|
|
39589
39616
|
}
|
|
39590
|
-
function setMacroFilestack(ast,
|
|
39591
|
-
ast.fileStack = [...
|
|
39617
|
+
function setMacroFilestack(ast, fileStack7) {
|
|
39618
|
+
ast.fileStack = [...fileStack7, ast.fileStack[ast.fileStack.length - 1]];
|
|
39592
39619
|
for (var arg of ast.args) {
|
|
39593
|
-
setMacroFilestack(arg,
|
|
39620
|
+
setMacroFilestack(arg, fileStack7);
|
|
39594
39621
|
}
|
|
39595
39622
|
for (var child of ast.children) {
|
|
39596
|
-
setMacroFilestack(child,
|
|
39623
|
+
setMacroFilestack(child, fileStack7);
|
|
39597
39624
|
}
|
|
39598
39625
|
}
|
|
39599
39626
|
let result = astMacros[macro.name].lines.map((line) => line.clone());
|
|
@@ -39962,31 +39989,31 @@ function getAstForArgDefault(arg) {
|
|
|
39962
39989
|
}
|
|
39963
39990
|
|
|
39964
39991
|
// src/utils/varNames.ts
|
|
39965
|
-
function translateSubroutineToPy(content,
|
|
39992
|
+
function translateSubroutineToPy(content, fileStack7) {
|
|
39966
39993
|
content = content.trim();
|
|
39967
39994
|
content = translateNameToAvoidKeywords(content, "subroutine");
|
|
39968
39995
|
if (subroutines.map((x) => x.name).includes(content)) {
|
|
39969
39996
|
return content;
|
|
39970
39997
|
}
|
|
39971
39998
|
if (defaultSubroutineNames.includes(content)) {
|
|
39972
|
-
addSubroutine(content, defaultSubroutineNames.indexOf(content),
|
|
39999
|
+
addSubroutine(content, defaultSubroutineNames.indexOf(content), fileStack7);
|
|
39973
40000
|
return content;
|
|
39974
40001
|
}
|
|
39975
40002
|
error("Unknown subroutine '" + content + "'");
|
|
39976
40003
|
}
|
|
39977
|
-
function translateSubroutineToWs(content,
|
|
40004
|
+
function translateSubroutineToWs(content, fileStack7) {
|
|
39978
40005
|
for (var i = 0; i < subroutines.length; i++) {
|
|
39979
40006
|
if (subroutines[i].name === content) {
|
|
39980
40007
|
return content;
|
|
39981
40008
|
}
|
|
39982
40009
|
}
|
|
39983
40010
|
if (defaultSubroutineNames.includes(content)) {
|
|
39984
|
-
addSubroutine(content, defaultSubroutineNames.indexOf(content),
|
|
40011
|
+
addSubroutine(content, defaultSubroutineNames.indexOf(content), fileStack7);
|
|
39985
40012
|
return content;
|
|
39986
40013
|
}
|
|
39987
40014
|
error("Undeclared subroutine '" + content + "'");
|
|
39988
40015
|
}
|
|
39989
|
-
function addSubroutine(content, index,
|
|
40016
|
+
function addSubroutine(content, index, fileStack7, isFromDefStatement = false) {
|
|
39990
40017
|
if (reservedSubroutineNames.includes(content)) {
|
|
39991
40018
|
error("Subroutine name '" + content + "' is a built-in function or keyword");
|
|
39992
40019
|
}
|
|
@@ -39994,7 +40021,7 @@ function addSubroutine(content, index, fileStack8, isFromDefStatement = false) {
|
|
|
39994
40021
|
subroutines.push({
|
|
39995
40022
|
name: content,
|
|
39996
40023
|
index: index ?? subroutines.length,
|
|
39997
|
-
fileStack:
|
|
40024
|
+
fileStack: fileStack7,
|
|
39998
40025
|
isFromDefStatement
|
|
39999
40026
|
});
|
|
40000
40027
|
}
|
|
@@ -40007,20 +40034,20 @@ function translateNameToAvoidKeywords(initialName, nameType) {
|
|
|
40007
40034
|
}
|
|
40008
40035
|
return initialName;
|
|
40009
40036
|
}
|
|
40010
|
-
function translateVarToPy(content, isGlobalVariable,
|
|
40037
|
+
function translateVarToPy(content, isGlobalVariable, fileStack7) {
|
|
40011
40038
|
content = content.trim();
|
|
40012
40039
|
content = translateNameToAvoidKeywords(content, isGlobalVariable ? "globalvar" : "playervar");
|
|
40013
40040
|
var varArray = isGlobalVariable ? globalVariables : playerVariables;
|
|
40014
40041
|
if (varArray.map((x) => x.name).includes(content)) {
|
|
40015
40042
|
return content;
|
|
40016
40043
|
} else if (defaultVarNames.includes(content)) {
|
|
40017
|
-
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content),
|
|
40044
|
+
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content), fileStack7);
|
|
40018
40045
|
return content;
|
|
40019
40046
|
} else {
|
|
40020
40047
|
error("Unknown variable '" + content + "'");
|
|
40021
40048
|
}
|
|
40022
40049
|
}
|
|
40023
|
-
function translateVarToWs(content, isGlobalVariable,
|
|
40050
|
+
function translateVarToWs(content, isGlobalVariable, fileStack7) {
|
|
40024
40051
|
var varArray = isGlobalVariable ? globalVariables : playerVariables;
|
|
40025
40052
|
for (var i = 0; i < varArray.length; i++) {
|
|
40026
40053
|
if (varArray[i].name === content) {
|
|
@@ -40028,12 +40055,12 @@ function translateVarToWs(content, isGlobalVariable, fileStack8) {
|
|
|
40028
40055
|
}
|
|
40029
40056
|
}
|
|
40030
40057
|
if (defaultVarNames.includes(content)) {
|
|
40031
|
-
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content),
|
|
40058
|
+
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content), fileStack7);
|
|
40032
40059
|
return content;
|
|
40033
40060
|
}
|
|
40034
40061
|
error("Undeclared " + (isGlobalVariable ? "global" : "player") + " variable '" + content + "'");
|
|
40035
40062
|
}
|
|
40036
|
-
function addVariable(content, isGlobalVariable, index,
|
|
40063
|
+
function addVariable(content, isGlobalVariable, index, fileStack7, initValue = null) {
|
|
40037
40064
|
if ((isGlobalVariable ? "" : ".") + content in astConstants) {
|
|
40038
40065
|
error("Variable name '" + content + "' is already declared as a macro");
|
|
40039
40066
|
}
|
|
@@ -40047,7 +40074,7 @@ function addVariable(content, isGlobalVariable, index, fileStack8, initValue = n
|
|
|
40047
40074
|
if (isGlobalVariable) {
|
|
40048
40075
|
globalVariables.push({
|
|
40049
40076
|
name: content,
|
|
40050
|
-
fileStack:
|
|
40077
|
+
fileStack: fileStack7,
|
|
40051
40078
|
index
|
|
40052
40079
|
});
|
|
40053
40080
|
if (initValue) {
|
|
@@ -40056,7 +40083,7 @@ function addVariable(content, isGlobalVariable, index, fileStack8, initValue = n
|
|
|
40056
40083
|
} else {
|
|
40057
40084
|
playerVariables.push({
|
|
40058
40085
|
name: content,
|
|
40059
|
-
fileStack:
|
|
40086
|
+
fileStack: fileStack7,
|
|
40060
40087
|
index
|
|
40061
40088
|
});
|
|
40062
40089
|
if (initValue) {
|
|
@@ -45604,7 +45631,7 @@ astParsingFunctions.__rule__ = function(content) {
|
|
|
45604
45631
|
foundLabel = true;
|
|
45605
45632
|
}
|
|
45606
45633
|
computeDistanceTo(content3.children[i3]);
|
|
45607
|
-
if (content3.children[i3].type !== "Label" && !["__enableOptimizations__", "__disableOptimizations__", "__enableOptimizeForSize__", "__disableOptimizeForSize__", "__enableOptimizeStrict__", "__disableOptimizeStrict__"].includes(content3.children[i3].name)) {
|
|
45634
|
+
if (content3.children[i3].type !== "Label" && !["__enableOptimizations__", "__disableOptimizations__", "__enableOptimizeForSize__", "__disableOptimizeForSize__", "__enableOptimizeStrict__", "__disableOptimizeStrict__", "__rulePrefix__", "__pushRulePrefixStack__", "__popRulePrefixStack__"].includes(content3.children[i3].name)) {
|
|
45608
45635
|
debug("Increasing distanceTo count for label " + label + ": function '" + content3.children[i3].name + "'");
|
|
45609
45636
|
count++;
|
|
45610
45637
|
}
|
|
@@ -45994,7 +46021,7 @@ function getAstForTranslatedString(content, replacements = []) {
|
|
|
45994
46021
|
let replacementNames = [];
|
|
45995
46022
|
let replacementMacro = "";
|
|
45996
46023
|
if (content.parent?.name === "spacesForString") {
|
|
45997
|
-
opyMacro += escapeString("\uFF34\uFF2C\uFF25\uFF52\uFF52\uEC48" + content.args.map((x) => getBestSpaces(Object.keys(spaces).map(Number), getStrVisualLength(x.name)).map((j) => spaces[j]).join("")).join("\uEC48"), false);
|
|
46024
|
+
opyMacro += escapeString((useTlErr ? "\uFF34\uFF2C\uFF25\uFF52\uFF52\uEC48" : "") + content.args.map((x) => getBestSpaces(Object.keys(spaces).map(Number), getStrVisualLength(x.name)).map((j) => spaces[j]).join("")).join("\uEC48"), false);
|
|
45998
46025
|
opyMacro += ".split(__overpyTranslationHelper__)";
|
|
45999
46026
|
} else if (isTranslatedStringLiteral) {
|
|
46000
46027
|
let separators = ["Vector.UP", "Vector.DOWN", "Vector.LEFT", "Vector.RIGHT", "Vector.FORWARD", "Vector.BACKWARD", "1876650.25", "1876651.25", "1876652.25", "1876653.25", "1876654.25", "1876655.25", "1876656.25", "1876657.25", "1876658.25", "1876659.25"];
|
|
@@ -46007,7 +46034,7 @@ function getAstForTranslatedString(content, replacements = []) {
|
|
|
46007
46034
|
"Vector.BACKWARD": "(0.00, 0.00, -1.00)"
|
|
46008
46035
|
};
|
|
46009
46036
|
let translationStrings = content.args.map((x) => x.name.replaceAll("{}", "{0}"));
|
|
46010
|
-
let rawString = "\uFF34\uFF2C\uFF25\uFF52\uFF52\uEC48" + translationStrings.join("\uEC48");
|
|
46037
|
+
let rawString = (useTlErr ? "\uFF34\uFF2C\uFF25\uFF52\uFF52\uEC48" : "") + translationStrings.join("\uEC48");
|
|
46011
46038
|
if (getUtf8Length(rawString) <= STR_MAX_LENGTH && replacements.length <= STR_MAX_ARGS) {
|
|
46012
46039
|
if (replacements.length > 0) {
|
|
46013
46040
|
replacementMacro = ".format(" + replacements.map((x, i) => "$arg" + i).join(", ") + ")";
|
|
@@ -47507,36 +47534,59 @@ astParsingFunctions.spacesForString = function(content) {
|
|
|
47507
47534
|
};
|
|
47508
47535
|
|
|
47509
47536
|
// src/compiler/functions/splitDictArray.ts
|
|
47510
|
-
astParsingFunctions.splitDictArray = function(content) {
|
|
47511
|
-
|
|
47512
|
-
|
|
47513
|
-
|
|
47514
|
-
|
|
47515
|
-
|
|
47516
|
-
|
|
47517
|
-
|
|
47518
|
-
|
|
47519
|
-
|
|
47520
|
-
|
|
47521
|
-
|
|
47522
|
-
|
|
47523
|
-
|
|
47524
|
-
|
|
47525
|
-
|
|
47526
|
-
let
|
|
47527
|
-
|
|
47528
|
-
for (let
|
|
47529
|
-
|
|
47530
|
-
|
|
47531
|
-
|
|
47532
|
-
|
|
47537
|
+
astParsingFunctions.splitDictArray = astParsingFunctions.tabular = function(content) {
|
|
47538
|
+
let variables = [];
|
|
47539
|
+
let arrays = [];
|
|
47540
|
+
if (content.name === "splitDictArray") {
|
|
47541
|
+
if (content.args[0].name !== "__dict__") {
|
|
47542
|
+
error("First argument of " + content.name + "() must be a dictionary", content.args[0].fileStack);
|
|
47543
|
+
}
|
|
47544
|
+
if (content.args[1].name !== "__array__") {
|
|
47545
|
+
error("Second argument of " + content.name + "() must be a literal array", content.args[1].fileStack);
|
|
47546
|
+
}
|
|
47547
|
+
for (let elem of content.args[1].args) {
|
|
47548
|
+
if (elem.name !== "__dict__") {
|
|
47549
|
+
error("Second argument of " + content.name + "() must be a literal array of dictionaries", elem.fileStack);
|
|
47550
|
+
}
|
|
47551
|
+
}
|
|
47552
|
+
variables = content.args[0].args.map((x) => x.args[1]);
|
|
47553
|
+
let variableKeys = content.args[0].args.map((x) => x.args[0].name);
|
|
47554
|
+
arrays = Array(variableKeys.length).fill(0).map(() => getAstForEmptyArray());
|
|
47555
|
+
for (let dict of content.args[1].args) {
|
|
47556
|
+
let dictKeys = dict.args.map((x) => x.args[0].name);
|
|
47557
|
+
let dictValues = dict.args.map((x) => x.args[1]);
|
|
47558
|
+
for (let [i, key] of variableKeys.entries()) {
|
|
47559
|
+
if (!dict.args.some((x) => x.args[0].name === key)) {
|
|
47560
|
+
arrays[i].args.push(getAstForNull());
|
|
47561
|
+
} else {
|
|
47562
|
+
arrays[i].args.push(dictValues[dictKeys.findIndex((x) => x === key)]);
|
|
47563
|
+
}
|
|
47533
47564
|
}
|
|
47534
|
-
|
|
47535
|
-
|
|
47536
|
-
|
|
47537
|
-
|
|
47565
|
+
for (let key of dictKeys) {
|
|
47566
|
+
if (!variableKeys.includes(key)) {
|
|
47567
|
+
error("Key '" + key + "' in dictionary is not defined in the first argument of " + content.name + "()", dict.fileStack);
|
|
47568
|
+
}
|
|
47538
47569
|
}
|
|
47539
47570
|
}
|
|
47571
|
+
} else {
|
|
47572
|
+
if (content.args[0].name !== "__array__") {
|
|
47573
|
+
error("First argument of " + content.name + "() must be a literal array", content.args[0].fileStack);
|
|
47574
|
+
}
|
|
47575
|
+
if (content.args[1].name !== "__array__") {
|
|
47576
|
+
error("Second argument of " + content.name + "() must be a literal array", content.args[1].fileStack);
|
|
47577
|
+
}
|
|
47578
|
+
variables = content.args[0].args;
|
|
47579
|
+
if (content.args[1].args.length % variables.length !== 0) {
|
|
47580
|
+
error("Second argument of " + content.name + "() must have a length that is a multiple of " + variables.length + " (length is " + content.args[1].args.length + ")", content.args[1].fileStack);
|
|
47581
|
+
}
|
|
47582
|
+
arrays = content.args[1].args.reduce((acc, x, i) => {
|
|
47583
|
+
let arrayIndex = i % variables.length;
|
|
47584
|
+
if (!acc[arrayIndex]) {
|
|
47585
|
+
acc[arrayIndex] = getAstForEmptyArray();
|
|
47586
|
+
}
|
|
47587
|
+
acc[arrayIndex].args.push(x);
|
|
47588
|
+
return acc;
|
|
47589
|
+
}, []);
|
|
47540
47590
|
}
|
|
47541
47591
|
if (content.args[2].name === "true") {
|
|
47542
47592
|
arrays = arrays.map((x) => {
|
|
@@ -47549,7 +47599,7 @@ astParsingFunctions.splitDictArray = function(content) {
|
|
|
47549
47599
|
}
|
|
47550
47600
|
let assignments = arrays.map((x, i) => new Ast2("__assignTo__", [variables[i], x]));
|
|
47551
47601
|
if (!content.parent) {
|
|
47552
|
-
error("Could not find parent of
|
|
47602
|
+
error("Could not find parent of " + content.name + "()");
|
|
47553
47603
|
}
|
|
47554
47604
|
content.parent.children.splice(content.parent.childIndex + 1, 0, ...assignments.slice(1));
|
|
47555
47605
|
return assignments[0];
|
|
@@ -47730,6 +47780,18 @@ function parseAstRules(rules) {
|
|
|
47730
47780
|
rulesResult.push(rule);
|
|
47731
47781
|
continue;
|
|
47732
47782
|
}
|
|
47783
|
+
if (rule.name === "__rulePrefix__") {
|
|
47784
|
+
rulesResult.push(rule);
|
|
47785
|
+
continue;
|
|
47786
|
+
}
|
|
47787
|
+
if (rule.name === "__pushRulePrefixStack__") {
|
|
47788
|
+
rulesResult.push(rule);
|
|
47789
|
+
continue;
|
|
47790
|
+
}
|
|
47791
|
+
if (rule.name === "__popRulePrefixStack__") {
|
|
47792
|
+
rulesResult.push(rule);
|
|
47793
|
+
continue;
|
|
47794
|
+
}
|
|
47733
47795
|
for (let i2 = 0; i2 < rule.children.length; i2++) {
|
|
47734
47796
|
setFileStack(rule.children[i2].fileStack);
|
|
47735
47797
|
if (rule.children[i2].name in astMacros) {
|
|
@@ -64456,11 +64518,24 @@ function astRulesToWs(rules) {
|
|
|
64456
64518
|
compiledRules.push("//Strict optimizations enabled\n");
|
|
64457
64519
|
continue;
|
|
64458
64520
|
}
|
|
64521
|
+
if (rule.name === "__rulePrefix__") {
|
|
64522
|
+
setCurrentRulePrefix(rule.args[0].args[0].name);
|
|
64523
|
+
continue;
|
|
64524
|
+
}
|
|
64525
|
+
if (rule.name === "__pushRulePrefixStack__") {
|
|
64526
|
+
pushRulePrefixStack();
|
|
64527
|
+
continue;
|
|
64528
|
+
}
|
|
64529
|
+
if (rule.name === "__popRulePrefixStack__") {
|
|
64530
|
+
popRulePrefixStack();
|
|
64531
|
+
continue;
|
|
64532
|
+
}
|
|
64459
64533
|
if (rule.ruleAttributes.isDisabled) {
|
|
64460
64534
|
result += tows("__disabled__", ruleKw) + " ";
|
|
64461
64535
|
}
|
|
64536
|
+
let finalRuleName = applyRulePrefixTemplate(rule);
|
|
64462
64537
|
result += tows("__rule__", ruleKw) + " (";
|
|
64463
|
-
result += escapeBadWords(escapeString(
|
|
64538
|
+
result += escapeBadWords(escapeString(finalRuleName, true));
|
|
64464
64539
|
result += ") {\n";
|
|
64465
64540
|
result += tabLevel(1) + tows("__event__", ruleKw) + " {\n";
|
|
64466
64541
|
result += tabLevel(2) + tows(rule.ruleAttributes.event, eventKw) + ";\n";
|
|
@@ -65129,6 +65204,70 @@ function splitCustomString(tokens, args) {
|
|
|
65129
65204
|
}
|
|
65130
65205
|
return new Ast2("__customString__", [new Ast2(result, [], [], "CustomStringLiteral")].concat(resultArgs));
|
|
65131
65206
|
}
|
|
65207
|
+
function applyRulePrefixTemplate(rule) {
|
|
65208
|
+
let ruleName = rule.ruleAttributes.name;
|
|
65209
|
+
let prefix = currentRulePrefix;
|
|
65210
|
+
let fileStackForRule = rule.fileStack;
|
|
65211
|
+
if (!prefix && !rulePrefixTemplate) {
|
|
65212
|
+
return ruleName;
|
|
65213
|
+
}
|
|
65214
|
+
let fileName = "";
|
|
65215
|
+
let filePath = "";
|
|
65216
|
+
for (let k = fileStackForRule.length - 1; k >= 0; k--) {
|
|
65217
|
+
if (fileStackForRule[k].path) {
|
|
65218
|
+
let fullPath = fileStackForRule[k].path.replace(/\\/g, "/");
|
|
65219
|
+
let baseName = fullPath.substring(fullPath.lastIndexOf("/") + 1);
|
|
65220
|
+
fileName = baseName.replace(/\.opy$/i, "");
|
|
65221
|
+
filePath = fullPath.startsWith(rootPath) ? fullPath.substring(rootPath.length) : fullPath;
|
|
65222
|
+
filePath = filePath.replace(/\.opy$/i, "");
|
|
65223
|
+
break;
|
|
65224
|
+
}
|
|
65225
|
+
}
|
|
65226
|
+
let template = rulePrefixTemplate || 'f"[{$prefix}] {$rule}" if $prefix and $rule else $rule';
|
|
65227
|
+
let argNames = [
|
|
65228
|
+
"$rule",
|
|
65229
|
+
"$prefix",
|
|
65230
|
+
"$file",
|
|
65231
|
+
"$path",
|
|
65232
|
+
"$isDelimiter",
|
|
65233
|
+
"$prefixTitle",
|
|
65234
|
+
"$prefixUpper",
|
|
65235
|
+
"$prefixLower",
|
|
65236
|
+
"$fileTitle",
|
|
65237
|
+
"$fileUpper",
|
|
65238
|
+
"$fileLower",
|
|
65239
|
+
"$pathTitle",
|
|
65240
|
+
"$pathUpper",
|
|
65241
|
+
"$pathLower"
|
|
65242
|
+
];
|
|
65243
|
+
let argValues = [
|
|
65244
|
+
ruleName,
|
|
65245
|
+
prefix,
|
|
65246
|
+
fileName,
|
|
65247
|
+
filePath,
|
|
65248
|
+
!!rule.ruleAttributes.isDelimiter,
|
|
65249
|
+
toTitleCase(prefix),
|
|
65250
|
+
prefix.toUpperCase(),
|
|
65251
|
+
prefix.toLowerCase(),
|
|
65252
|
+
toTitleCase(fileName),
|
|
65253
|
+
fileName.toUpperCase(),
|
|
65254
|
+
fileName.toLowerCase(),
|
|
65255
|
+
toTitleCase(filePath),
|
|
65256
|
+
filePath.toUpperCase(),
|
|
65257
|
+
filePath.toLowerCase()
|
|
65258
|
+
];
|
|
65259
|
+
let argAsts = argValues.map((v) => v === true || v === false ? getAstForBool(v) : getAstForCustomString(v));
|
|
65260
|
+
let oldFileStack = getFileStackCopy();
|
|
65261
|
+
fileStack2.push(...rulePrefixTemplateFilestack);
|
|
65262
|
+
let resultAst = parseOpyMacro(template, argNames, argAsts);
|
|
65263
|
+
resultAst.parent = new Ast2("__rulePrefix__");
|
|
65264
|
+
resultAst = parseAst(resultAst);
|
|
65265
|
+
setFileStack(oldFileStack);
|
|
65266
|
+
if (resultAst.name !== "__customString__" || resultAst.args.length > 1) {
|
|
65267
|
+
error("Could not resolve rule prefix template to a plain string");
|
|
65268
|
+
}
|
|
65269
|
+
return resultAst.args[0].name;
|
|
65270
|
+
}
|
|
65132
65271
|
|
|
65133
65272
|
// src/compiler/translations.ts
|
|
65134
65273
|
var import_pofile = __toESM(require_po());
|
|
@@ -65140,7 +65279,7 @@ function getLeadingAndTrailingWhitespace(str) {
|
|
|
65140
65279
|
trailingWhitespace
|
|
65141
65280
|
};
|
|
65142
65281
|
}
|
|
65143
|
-
function getTranslatedString(str, context,
|
|
65282
|
+
function getTranslatedString(str, context, fileStack7) {
|
|
65144
65283
|
let lineNb = null;
|
|
65145
65284
|
let fileName = null;
|
|
65146
65285
|
if (translationLanguages2.length === 0) {
|
|
@@ -65161,10 +65300,10 @@ function getTranslatedString(str, context, fileStack8) {
|
|
|
65161
65300
|
let { leadingWhitespace, actualString: actualStringWithNewlines, trailingWhitespace } = getLeadingAndTrailingWhitespace(str);
|
|
65162
65301
|
let lines = actualStringWithNewlines.split("\n").map((x) => getLeadingAndTrailingWhitespace(x));
|
|
65163
65302
|
let actualString = lines.map((x) => x.actualString).join("\n");
|
|
65164
|
-
for (let i =
|
|
65165
|
-
if (
|
|
65166
|
-
lineNb =
|
|
65167
|
-
fileName =
|
|
65303
|
+
for (let i = fileStack7.length - 1; i >= 0; i--) {
|
|
65304
|
+
if (fileStack7[i].name.endsWith(".opy")) {
|
|
65305
|
+
lineNb = fileStack7[i].startLine;
|
|
65306
|
+
fileName = fileStack7[i].name.replaceAll(/\\/g, "/").split("/").pop();
|
|
65168
65307
|
break;
|
|
65169
65308
|
}
|
|
65170
65309
|
}
|
|
@@ -65318,6 +65457,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65318
65457
|
setFileStack([
|
|
65319
65458
|
{
|
|
65320
65459
|
name: mainFileName || "<main>",
|
|
65460
|
+
path: rootPath + mainFileName,
|
|
65321
65461
|
startLine: 1,
|
|
65322
65462
|
startCol: 1,
|
|
65323
65463
|
endCol: null,
|
|
@@ -65379,7 +65519,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65379
65519
|
}
|
|
65380
65520
|
}).join("0");
|
|
65381
65521
|
if (usePlayerVarForTranslations) {
|
|
65382
|
-
addVariable("__languageIndex__", false, -1, getInternalFileStack(), tokenize("1.1")[0].tokens);
|
|
65522
|
+
addVariable("__languageIndex__", false, -1, getInternalFileStack(), tokenize(useTlErr ? "1.1" : "0.1")[0].tokens);
|
|
65383
65523
|
}
|
|
65384
65524
|
addVariable("__overpyTranslationHelper__", true, -1, getInternalFileStack(), tokenize(escapeString("\uEC480" + translationConstantString, false) + ".split(null[0])")[0].tokens);
|
|
65385
65525
|
}
|
|
@@ -65414,7 +65554,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65414
65554
|
@Event eachPlayer
|
|
65415
65555
|
@Condition eventPlayer.hasSpawned()
|
|
65416
65556
|
@Condition not eventPlayer.isDummy()
|
|
65417
|
-
@Condition eventPlayer.__languageIndex__ == 1.1
|
|
65557
|
+
@Condition eventPlayer.__languageIndex__ == ${useTlErr ? "1.1" : "0.1"}
|
|
65418
65558
|
eventPlayer.__languageIndex__.append(eventPlayer.getFacingDirection())
|
|
65419
65559
|
eventPlayer.startFacing(
|
|
65420
65560
|
directionFromAngles(10*${escapeString("\uEC480" + translationConstantString, false)}.split(null[0]).index(${translationLanguageConstantOpy}.split([])), 5),
|
|
@@ -65430,7 +65570,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65430
65570
|
|
|
65431
65571
|
eventPlayer.stopFacing()
|
|
65432
65572
|
eventPlayer.setFacing(eventPlayer.__languageIndex__.last(), Relativity.TO_WORLD)
|
|
65433
|
-
eventPlayer.__languageIndex__ = eventPlayer.__languageIndex__[0]
|
|
65573
|
+
eventPlayer.__languageIndex__ = eventPlayer.__languageIndex__${useTlErr ? "[0]" : " - 1"}
|
|
65434
65574
|
`;
|
|
65435
65575
|
translationSetupRule = tokenize(translationSetupRule);
|
|
65436
65576
|
translationSetupRule = parseLines(translationSetupRule)[0];
|
|
@@ -67758,10 +67898,10 @@ function parseType(tokens) {
|
|
|
67758
67898
|
var OpyError = class _OpyError extends Error {
|
|
67759
67899
|
fileStack;
|
|
67760
67900
|
severity = "error";
|
|
67761
|
-
constructor(message,
|
|
67901
|
+
constructor(message, fileStack7) {
|
|
67762
67902
|
super(message);
|
|
67763
67903
|
this.name = "OpyError";
|
|
67764
|
-
this.fileStack =
|
|
67904
|
+
this.fileStack = fileStack7;
|
|
67765
67905
|
Object.setPrototypeOf(this, _OpyError.prototype);
|
|
67766
67906
|
}
|
|
67767
67907
|
};
|
|
@@ -67921,12 +68061,12 @@ function getFileStackRange(tokens) {
|
|
|
67921
68061
|
result[result.length - 1].endCol = lastTokenFilestack.endCol;
|
|
67922
68062
|
return result;
|
|
67923
68063
|
}
|
|
67924
|
-
function displayFileStack(
|
|
67925
|
-
if (!
|
|
68064
|
+
function displayFileStack(fileStack7) {
|
|
68065
|
+
if (!fileStack7 || fileStack7.length === 0) {
|
|
67926
68066
|
return "";
|
|
67927
68067
|
}
|
|
67928
68068
|
let result = "";
|
|
67929
|
-
for (const file of
|
|
68069
|
+
for (const file of fileStack7.toReversed()) {
|
|
67930
68070
|
result += `
|
|
67931
68071
|
| `;
|
|
67932
68072
|
if (file.startLine !== null && file.startCol !== null) {
|
|
@@ -67961,6 +68101,9 @@ function upperCaseToCamelCase(str) {
|
|
|
67961
68101
|
result = result[0].toLowerCase() + result.substring(1);
|
|
67962
68102
|
return result;
|
|
67963
68103
|
}
|
|
68104
|
+
function toTitleCase(str) {
|
|
68105
|
+
return str.replace(/[\p{Letter}']+/gu, (txt) => txt.charAt(0).toUpperCase() + txt.substring(1));
|
|
68106
|
+
}
|
|
67964
68107
|
function isNumber(x) {
|
|
67965
68108
|
if (("" + x).trim() === "" || x === null) {
|
|
67966
68109
|
return false;
|
|
@@ -68481,6 +68624,23 @@ var opyInternalFuncs = {
|
|
|
68481
68624
|
"Vector"
|
|
68482
68625
|
]
|
|
68483
68626
|
},
|
|
68627
|
+
"__popRulePrefixStack__": {
|
|
68628
|
+
"args": null,
|
|
68629
|
+
"return": "void"
|
|
68630
|
+
},
|
|
68631
|
+
"__pushRulePrefixStack__": {
|
|
68632
|
+
"args": null,
|
|
68633
|
+
"return": "void"
|
|
68634
|
+
},
|
|
68635
|
+
"__rulePrefix__": {
|
|
68636
|
+
"args": [
|
|
68637
|
+
{
|
|
68638
|
+
"name": "prefix",
|
|
68639
|
+
"type": "CustomStringLiteral"
|
|
68640
|
+
}
|
|
68641
|
+
],
|
|
68642
|
+
"return": "void"
|
|
68643
|
+
},
|
|
68484
68644
|
"__rule__": {
|
|
68485
68645
|
"args": null,
|
|
68486
68646
|
"return": "void"
|
|
@@ -69220,6 +69380,8 @@ waveLengths = [3, 8, null]
|
|
|
69220
69380
|
\`\`\`
|
|
69221
69381
|
|
|
69222
69382
|
If the third argument is set to \`true\`, arrays will be compressed if they are arrays of literal numbers or vectors.
|
|
69383
|
+
|
|
69384
|
+
Also check the \`tabular\` function for a more concise syntax.
|
|
69223
69385
|
`,
|
|
69224
69386
|
"args": [
|
|
69225
69387
|
{
|
|
@@ -69266,6 +69428,48 @@ If the third argument is set to \`true\`, arrays will be compressed if they are
|
|
|
69266
69428
|
"isConstant": true,
|
|
69267
69429
|
"return": "unsigned int"
|
|
69268
69430
|
},
|
|
69431
|
+
"tabular": {
|
|
69432
|
+
"description": `
|
|
69433
|
+
Maps an array of arrays to variables (same as \`splitDictArray()\` with shorter syntax). For example:
|
|
69434
|
+
\`\`\`python
|
|
69435
|
+
tabular([waveHeroes,waveLengths], [
|
|
69436
|
+
Hero.ANA, 3,
|
|
69437
|
+
Hero.SOLDIER, 8,
|
|
69438
|
+
Hero.HAMMOND, null,
|
|
69439
|
+
])
|
|
69440
|
+
\`\`\`
|
|
69441
|
+
|
|
69442
|
+
Will yield the following:
|
|
69443
|
+
|
|
69444
|
+
\`\`\`python
|
|
69445
|
+
waveHeroes = [Hero.ANA, Hero.SOLDIER, Hero.HAMMOND]
|
|
69446
|
+
waveLengths = [3, 8, null]
|
|
69447
|
+
\`\`\`
|
|
69448
|
+
|
|
69449
|
+
If the third argument is set to \`true\`, arrays will be compressed if they are arrays of literal numbers or vectors.
|
|
69450
|
+
`,
|
|
69451
|
+
"args": [
|
|
69452
|
+
{
|
|
69453
|
+
"name": "variables",
|
|
69454
|
+
"description": "A dictionary mapping the keys to the variables to be assigned to.",
|
|
69455
|
+
"type": "Dict"
|
|
69456
|
+
},
|
|
69457
|
+
{
|
|
69458
|
+
"name": "values",
|
|
69459
|
+
"description": "An array of dictionaries describing the values to be assigned to the variables.",
|
|
69460
|
+
"type": {
|
|
69461
|
+
"Array": "Dict"
|
|
69462
|
+
}
|
|
69463
|
+
},
|
|
69464
|
+
{
|
|
69465
|
+
"name": "compress",
|
|
69466
|
+
"description": "Set to true to compress the arrays if they are arrays of literal numbers or vectors.",
|
|
69467
|
+
"type": "bool",
|
|
69468
|
+
"default": false
|
|
69469
|
+
}
|
|
69470
|
+
],
|
|
69471
|
+
"return": "void"
|
|
69472
|
+
},
|
|
69269
69473
|
".toArray": {
|
|
69270
69474
|
"description": "Get an array of the values of an enum.",
|
|
69271
69475
|
"args": [
|
|
@@ -69378,6 +69582,8 @@ var usePlayerVarForTranslations;
|
|
|
69378
69582
|
var setUsePlayerVarForTranslations = (use) => usePlayerVarForTranslations = use;
|
|
69379
69583
|
var generateRuleForTranslationsPlayerVar;
|
|
69380
69584
|
var setGenerateRuleForTranslationsPlayerVar = (generate) => generateRuleForTranslationsPlayerVar = generate;
|
|
69585
|
+
var useTlErr;
|
|
69586
|
+
var setTranslationUseTlErr = (use) => useTlErr = use;
|
|
69381
69587
|
var excludeVariablesInCompilation;
|
|
69382
69588
|
var setExcludeVariablesInCompilation = (exclude) => excludeVariablesInCompilation = exclude;
|
|
69383
69589
|
var globalvarInitRuleName;
|
|
@@ -69386,6 +69592,17 @@ var playervarInitRuleName;
|
|
|
69386
69592
|
var setPlayervarInitRuleName = (name) => playervarInitRuleName = name;
|
|
69387
69593
|
var disableInspector = false;
|
|
69388
69594
|
var setDisableInspector = (disable) => disableInspector = disable;
|
|
69595
|
+
var rulePrefixStack = [];
|
|
69596
|
+
var currentRulePrefix = "";
|
|
69597
|
+
var setCurrentRulePrefix = (prefix) => currentRulePrefix = prefix;
|
|
69598
|
+
var pushRulePrefixStack = () => rulePrefixStack.push(currentRulePrefix);
|
|
69599
|
+
var popRulePrefixStack = () => {
|
|
69600
|
+
currentRulePrefix = rulePrefixStack.pop() ?? "";
|
|
69601
|
+
};
|
|
69602
|
+
var rulePrefixTemplate = "";
|
|
69603
|
+
var setRulePrefixTemplate = (template) => rulePrefixTemplate = template;
|
|
69604
|
+
var rulePrefixTemplateFilestack = [];
|
|
69605
|
+
var setRulePrefixTemplateFilestack = (filestack) => rulePrefixTemplateFilestack = filestack;
|
|
69389
69606
|
var decompilerGotos;
|
|
69390
69607
|
var resetDecompilerGotos = () => decompilerGotos = [];
|
|
69391
69608
|
var nbTabs;
|
|
@@ -69449,6 +69666,7 @@ function resetGlobalVariables(language) {
|
|
|
69449
69666
|
translationLanguageConstantOpy = "";
|
|
69450
69667
|
usePlayerVarForTranslations = false;
|
|
69451
69668
|
generateRuleForTranslationsPlayerVar = true;
|
|
69669
|
+
useTlErr = true;
|
|
69452
69670
|
excludeVariablesInCompilation = false;
|
|
69453
69671
|
globalvarInitRuleName = "Initialize global variables";
|
|
69454
69672
|
playervarInitRuleName = "Initialize player variables";
|
|
@@ -69457,6 +69675,10 @@ function resetGlobalVariables(language) {
|
|
|
69457
69675
|
disableTranslationSourceLines = false;
|
|
69458
69676
|
usedMaps = /* @__PURE__ */ new Set();
|
|
69459
69677
|
postCompileHook = null;
|
|
69678
|
+
rulePrefixStack = [];
|
|
69679
|
+
currentRulePrefix = "";
|
|
69680
|
+
rulePrefixTemplate = "";
|
|
69681
|
+
rulePrefixTemplateFilestack = [];
|
|
69460
69682
|
}
|
|
69461
69683
|
var operatorPrecedence = {
|
|
69462
69684
|
"=": 1,
|
|
@@ -71899,6 +72121,8 @@ If using translations, this can save a lot of elements. However, it will make tr
|
|
|
71899
72121
|
If your gamemode changes the facing direction on spawn, you must modify it so that it changes it once \`eventPlayer.__languageIndex__ != 1.1\`.
|
|
71900
72122
|
|
|
71901
72123
|
You can specify \`noDetectionRule\` to not create the rule which sets the variable to the player's language, in which case you'll have to define the rule yourself; the variable must be set to the language as defined in the order specified in the \`#!translations\` directive, where the first language is index 1, and must be set to 1 by default if no language could be determined.
|
|
72124
|
+
|
|
72125
|
+
You can also specify \`noTlErr\` to have spectators view the default language when viewing a translated string (the \`__languageIndex__\` variable is now 0-indexed instead of 1-indexed). Keep in mind that, if translations aren't used properly, you may not see it if you playtest with the default language.
|
|
71902
72126
|
`
|
|
71903
72127
|
},
|
|
71904
72128
|
"extension": {
|
|
@@ -71940,6 +72164,51 @@ content.toString();
|
|
|
71940
72164
|
\`\`\`
|
|
71941
72165
|
`,
|
|
71942
72166
|
"snippet": 'postCompileHook "$0"'
|
|
72167
|
+
},
|
|
72168
|
+
"rulePrefix": {
|
|
72169
|
+
"description": `
|
|
72170
|
+
Sets a prefix for all subsequent rules in the current file and its included child files (unless overridden). The prefix is applied to the rule name using the rule prefix template.
|
|
72171
|
+
|
|
72172
|
+
If a \`#!rulePrefix\` directive is in an included file, it only takes effect for the rules within that file (and its child includes, if they don't have their own \`#!rulePrefix\`), after the directive.
|
|
72173
|
+
|
|
72174
|
+
Example:
|
|
72175
|
+
|
|
72176
|
+
\`\`\`hs
|
|
72177
|
+
#!rulePrefix "Effects"
|
|
72178
|
+
|
|
72179
|
+
rule "Spawn particles":
|
|
72180
|
+
#compiled rule name: [Effects] Spawn particles
|
|
72181
|
+
\`\`\`
|
|
72182
|
+
|
|
72183
|
+
To clear the prefix for subsequent rules, use an empty string:
|
|
72184
|
+
|
|
72185
|
+
\`\`\`hs
|
|
72186
|
+
#!rulePrefix ""
|
|
72187
|
+
\`\`\`
|
|
72188
|
+
`,
|
|
72189
|
+
"snippet": 'rulePrefix "$0"'
|
|
72190
|
+
},
|
|
72191
|
+
"rulePrefixTemplate": {
|
|
72192
|
+
"description": `
|
|
72193
|
+
Defines a global template for how rule prefixes are applied to rule names. Can only be defined once. Has effect on all rules, even those declared before this directive.
|
|
72194
|
+
|
|
72195
|
+
The template is an OverPy expression with the following variables:
|
|
72196
|
+
|
|
72197
|
+
- \`$rule\`: the current rule name
|
|
72198
|
+
- \`$isDelimiter\`: true if the rule is @Delimiter
|
|
72199
|
+
- \`$prefix\`: the current prefix (set via \`#!rulePrefix\`)
|
|
72200
|
+
- \`$file\`: the file name without extension
|
|
72201
|
+
- \`$path\`: the relative path to the main file (backslashes replaced by slashes)
|
|
72202
|
+
- Titlecase/lower/upper variations: \`$prefixTitle\`, \`$prefixUpper\`, \`$prefixLower\`, \`$fileTitle\`, \`$fileUpper\`, \`$fileLower\`, \`$pathTitle\`, \`$pathUpper\`, \`$pathLower\`
|
|
72203
|
+
|
|
72204
|
+
Examples :
|
|
72205
|
+
|
|
72206
|
+
- \`#!rulePrefixTemplate f"[{$prefix}] {$rule}" if $prefix and $rule else $rule\` (default): adds the prefix in square brackets before the rule name, if the prefix and rule name are not empty. This is the default if this directive is unspecified.
|
|
72207
|
+
- \`#!rulePrefixTemplate f"[{$pathTitle.replace('_', ' ')}] {$rule}" if $rule and not $isDelimiter else $rule\`": if you have an \`heroes/junker_queen.opy\` file, will yield rule names like "[Heroes/Junker Queen] Spawn particles". This is the default if the directive is specified without an expression (just \`#!rulePrefixTemplate\`).
|
|
72208
|
+
|
|
72209
|
+
The expression has to evaluate to a string without arguments.
|
|
72210
|
+
`,
|
|
72211
|
+
"snippet": "rulePrefixTemplate $0"
|
|
71943
72212
|
}
|
|
71944
72213
|
};
|
|
71945
72214
|
postLoadTasks.push({
|
package/package.json
CHANGED