overpy 9.5.13 → 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 +335 -68
- 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
|
@@ -20415,7 +20415,6 @@ var customGameSettingsSchema = (
|
|
|
20415
20415
|
"mercy",
|
|
20416
20416
|
"moira",
|
|
20417
20417
|
"roadhog",
|
|
20418
|
-
"sojourn",
|
|
20419
20418
|
"symmetra",
|
|
20420
20419
|
"torbjorn",
|
|
20421
20420
|
"winston",
|
|
@@ -38424,9 +38423,9 @@ var LogicalLine = class {
|
|
|
38424
38423
|
var Token = class {
|
|
38425
38424
|
text;
|
|
38426
38425
|
fileStack;
|
|
38427
|
-
constructor(text,
|
|
38426
|
+
constructor(text, fileStack7) {
|
|
38428
38427
|
this.text = text;
|
|
38429
|
-
this.fileStack =
|
|
38428
|
+
this.fileStack = fileStack7;
|
|
38430
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;
|
|
38431
38430
|
this.fileStack[this.fileStack.length - 1].endLine = this.fileStack[this.fileStack.length - 1].startLine + this.text.split("\n").length - 1;
|
|
38432
38431
|
}
|
|
@@ -38570,9 +38569,13 @@ ${scriptText}`, {
|
|
|
38570
38569
|
}
|
|
38571
38570
|
if (content2.startsWith("#!translateWithPlayerVar")) {
|
|
38572
38571
|
setUsePlayerVarForTranslations(true);
|
|
38573
|
-
|
|
38572
|
+
let args = content2.substring("#!translateWithPlayerVar".length).trim().split(" ");
|
|
38573
|
+
if (args.includes("noDetectionRule")) {
|
|
38574
38574
|
setGenerateRuleForTranslationsPlayerVar(false);
|
|
38575
38575
|
}
|
|
38576
|
+
if (args.includes("noTlErr")) {
|
|
38577
|
+
setTranslationUseTlErr(false);
|
|
38578
|
+
}
|
|
38576
38579
|
return;
|
|
38577
38580
|
}
|
|
38578
38581
|
if (content2.startsWith("#!disableInspector")) {
|
|
@@ -38659,6 +38662,25 @@ ${scriptText}`, {
|
|
|
38659
38662
|
);
|
|
38660
38663
|
return;
|
|
38661
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
|
+
}
|
|
38662
38684
|
error("Unknown preprocessor directive '" + content2 + "'");
|
|
38663
38685
|
}
|
|
38664
38686
|
for (i = 0; i < content.length; moveCursor(1)) {
|
|
@@ -38754,7 +38776,11 @@ ${scriptText}`, {
|
|
|
38754
38776
|
staticMember: true,
|
|
38755
38777
|
fileStackMemberType: "normal"
|
|
38756
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);
|
|
38757
38782
|
result.push(...tokenize(importedFileContent));
|
|
38783
|
+
result.push(popLine);
|
|
38758
38784
|
fileStack2.pop();
|
|
38759
38785
|
moveCursor(j2 - i - 1);
|
|
38760
38786
|
}
|
|
@@ -39588,13 +39614,13 @@ function parseAstMacro(macro) {
|
|
|
39588
39614
|
if (!(macro.name in astMacros)) {
|
|
39589
39615
|
error("Unknown macro '" + macro.name + "'", macro.fileStack);
|
|
39590
39616
|
}
|
|
39591
|
-
function setMacroFilestack(ast,
|
|
39592
|
-
ast.fileStack = [...
|
|
39617
|
+
function setMacroFilestack(ast, fileStack7) {
|
|
39618
|
+
ast.fileStack = [...fileStack7, ast.fileStack[ast.fileStack.length - 1]];
|
|
39593
39619
|
for (var arg of ast.args) {
|
|
39594
|
-
setMacroFilestack(arg,
|
|
39620
|
+
setMacroFilestack(arg, fileStack7);
|
|
39595
39621
|
}
|
|
39596
39622
|
for (var child of ast.children) {
|
|
39597
|
-
setMacroFilestack(child,
|
|
39623
|
+
setMacroFilestack(child, fileStack7);
|
|
39598
39624
|
}
|
|
39599
39625
|
}
|
|
39600
39626
|
let result = astMacros[macro.name].lines.map((line) => line.clone());
|
|
@@ -39963,31 +39989,31 @@ function getAstForArgDefault(arg) {
|
|
|
39963
39989
|
}
|
|
39964
39990
|
|
|
39965
39991
|
// src/utils/varNames.ts
|
|
39966
|
-
function translateSubroutineToPy(content,
|
|
39992
|
+
function translateSubroutineToPy(content, fileStack7) {
|
|
39967
39993
|
content = content.trim();
|
|
39968
39994
|
content = translateNameToAvoidKeywords(content, "subroutine");
|
|
39969
39995
|
if (subroutines.map((x) => x.name).includes(content)) {
|
|
39970
39996
|
return content;
|
|
39971
39997
|
}
|
|
39972
39998
|
if (defaultSubroutineNames.includes(content)) {
|
|
39973
|
-
addSubroutine(content, defaultSubroutineNames.indexOf(content),
|
|
39999
|
+
addSubroutine(content, defaultSubroutineNames.indexOf(content), fileStack7);
|
|
39974
40000
|
return content;
|
|
39975
40001
|
}
|
|
39976
40002
|
error("Unknown subroutine '" + content + "'");
|
|
39977
40003
|
}
|
|
39978
|
-
function translateSubroutineToWs(content,
|
|
40004
|
+
function translateSubroutineToWs(content, fileStack7) {
|
|
39979
40005
|
for (var i = 0; i < subroutines.length; i++) {
|
|
39980
40006
|
if (subroutines[i].name === content) {
|
|
39981
40007
|
return content;
|
|
39982
40008
|
}
|
|
39983
40009
|
}
|
|
39984
40010
|
if (defaultSubroutineNames.includes(content)) {
|
|
39985
|
-
addSubroutine(content, defaultSubroutineNames.indexOf(content),
|
|
40011
|
+
addSubroutine(content, defaultSubroutineNames.indexOf(content), fileStack7);
|
|
39986
40012
|
return content;
|
|
39987
40013
|
}
|
|
39988
40014
|
error("Undeclared subroutine '" + content + "'");
|
|
39989
40015
|
}
|
|
39990
|
-
function addSubroutine(content, index,
|
|
40016
|
+
function addSubroutine(content, index, fileStack7, isFromDefStatement = false) {
|
|
39991
40017
|
if (reservedSubroutineNames.includes(content)) {
|
|
39992
40018
|
error("Subroutine name '" + content + "' is a built-in function or keyword");
|
|
39993
40019
|
}
|
|
@@ -39995,7 +40021,7 @@ function addSubroutine(content, index, fileStack8, isFromDefStatement = false) {
|
|
|
39995
40021
|
subroutines.push({
|
|
39996
40022
|
name: content,
|
|
39997
40023
|
index: index ?? subroutines.length,
|
|
39998
|
-
fileStack:
|
|
40024
|
+
fileStack: fileStack7,
|
|
39999
40025
|
isFromDefStatement
|
|
40000
40026
|
});
|
|
40001
40027
|
}
|
|
@@ -40008,20 +40034,20 @@ function translateNameToAvoidKeywords(initialName, nameType) {
|
|
|
40008
40034
|
}
|
|
40009
40035
|
return initialName;
|
|
40010
40036
|
}
|
|
40011
|
-
function translateVarToPy(content, isGlobalVariable,
|
|
40037
|
+
function translateVarToPy(content, isGlobalVariable, fileStack7) {
|
|
40012
40038
|
content = content.trim();
|
|
40013
40039
|
content = translateNameToAvoidKeywords(content, isGlobalVariable ? "globalvar" : "playervar");
|
|
40014
40040
|
var varArray = isGlobalVariable ? globalVariables : playerVariables;
|
|
40015
40041
|
if (varArray.map((x) => x.name).includes(content)) {
|
|
40016
40042
|
return content;
|
|
40017
40043
|
} else if (defaultVarNames.includes(content)) {
|
|
40018
|
-
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content),
|
|
40044
|
+
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content), fileStack7);
|
|
40019
40045
|
return content;
|
|
40020
40046
|
} else {
|
|
40021
40047
|
error("Unknown variable '" + content + "'");
|
|
40022
40048
|
}
|
|
40023
40049
|
}
|
|
40024
|
-
function translateVarToWs(content, isGlobalVariable,
|
|
40050
|
+
function translateVarToWs(content, isGlobalVariable, fileStack7) {
|
|
40025
40051
|
var varArray = isGlobalVariable ? globalVariables : playerVariables;
|
|
40026
40052
|
for (var i = 0; i < varArray.length; i++) {
|
|
40027
40053
|
if (varArray[i].name === content) {
|
|
@@ -40029,12 +40055,12 @@ function translateVarToWs(content, isGlobalVariable, fileStack8) {
|
|
|
40029
40055
|
}
|
|
40030
40056
|
}
|
|
40031
40057
|
if (defaultVarNames.includes(content)) {
|
|
40032
|
-
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content),
|
|
40058
|
+
addVariable(content, isGlobalVariable, defaultVarNames.indexOf(content), fileStack7);
|
|
40033
40059
|
return content;
|
|
40034
40060
|
}
|
|
40035
40061
|
error("Undeclared " + (isGlobalVariable ? "global" : "player") + " variable '" + content + "'");
|
|
40036
40062
|
}
|
|
40037
|
-
function addVariable(content, isGlobalVariable, index,
|
|
40063
|
+
function addVariable(content, isGlobalVariable, index, fileStack7, initValue = null) {
|
|
40038
40064
|
if ((isGlobalVariable ? "" : ".") + content in astConstants) {
|
|
40039
40065
|
error("Variable name '" + content + "' is already declared as a macro");
|
|
40040
40066
|
}
|
|
@@ -40048,7 +40074,7 @@ function addVariable(content, isGlobalVariable, index, fileStack8, initValue = n
|
|
|
40048
40074
|
if (isGlobalVariable) {
|
|
40049
40075
|
globalVariables.push({
|
|
40050
40076
|
name: content,
|
|
40051
|
-
fileStack:
|
|
40077
|
+
fileStack: fileStack7,
|
|
40052
40078
|
index
|
|
40053
40079
|
});
|
|
40054
40080
|
if (initValue) {
|
|
@@ -40057,7 +40083,7 @@ function addVariable(content, isGlobalVariable, index, fileStack8, initValue = n
|
|
|
40057
40083
|
} else {
|
|
40058
40084
|
playerVariables.push({
|
|
40059
40085
|
name: content,
|
|
40060
|
-
fileStack:
|
|
40086
|
+
fileStack: fileStack7,
|
|
40061
40087
|
index
|
|
40062
40088
|
});
|
|
40063
40089
|
if (initValue) {
|
|
@@ -41780,7 +41806,7 @@ var heroKw = (
|
|
|
41780
41806
|
"junkerQueen": {
|
|
41781
41807
|
"secondaryFire": {
|
|
41782
41808
|
"guid": "00000000D3A4",
|
|
41783
|
-
"en-US": "Jagged Blade",
|
|
41809
|
+
"en-US": "Jagged Blade Gracie",
|
|
41784
41810
|
"de-DE": "Gezackte Klinge",
|
|
41785
41811
|
"es-ES": "Cuchilla dentada",
|
|
41786
41812
|
"es-MX": "Hoja dentada",
|
|
@@ -43030,7 +43056,6 @@ var heroKw = (
|
|
|
43030
43056
|
},
|
|
43031
43057
|
"sojourn": {
|
|
43032
43058
|
"secondaryFire": {
|
|
43033
|
-
"guid": "00000000796B",
|
|
43034
43059
|
"en-US": "Charged Shot"
|
|
43035
43060
|
},
|
|
43036
43061
|
"ability1": {
|
|
@@ -45606,7 +45631,7 @@ astParsingFunctions.__rule__ = function(content) {
|
|
|
45606
45631
|
foundLabel = true;
|
|
45607
45632
|
}
|
|
45608
45633
|
computeDistanceTo(content3.children[i3]);
|
|
45609
|
-
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)) {
|
|
45610
45635
|
debug("Increasing distanceTo count for label " + label + ": function '" + content3.children[i3].name + "'");
|
|
45611
45636
|
count++;
|
|
45612
45637
|
}
|
|
@@ -45996,7 +46021,7 @@ function getAstForTranslatedString(content, replacements = []) {
|
|
|
45996
46021
|
let replacementNames = [];
|
|
45997
46022
|
let replacementMacro = "";
|
|
45998
46023
|
if (content.parent?.name === "spacesForString") {
|
|
45999
|
-
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);
|
|
46000
46025
|
opyMacro += ".split(__overpyTranslationHelper__)";
|
|
46001
46026
|
} else if (isTranslatedStringLiteral) {
|
|
46002
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"];
|
|
@@ -46009,7 +46034,7 @@ function getAstForTranslatedString(content, replacements = []) {
|
|
|
46009
46034
|
"Vector.BACKWARD": "(0.00, 0.00, -1.00)"
|
|
46010
46035
|
};
|
|
46011
46036
|
let translationStrings = content.args.map((x) => x.name.replaceAll("{}", "{0}"));
|
|
46012
|
-
let rawString = "\uFF34\uFF2C\uFF25\uFF52\uFF52\uEC48" + translationStrings.join("\uEC48");
|
|
46037
|
+
let rawString = (useTlErr ? "\uFF34\uFF2C\uFF25\uFF52\uFF52\uEC48" : "") + translationStrings.join("\uEC48");
|
|
46013
46038
|
if (getUtf8Length(rawString) <= STR_MAX_LENGTH && replacements.length <= STR_MAX_ARGS) {
|
|
46014
46039
|
if (replacements.length > 0) {
|
|
46015
46040
|
replacementMacro = ".format(" + replacements.map((x, i) => "$arg" + i).join(", ") + ")";
|
|
@@ -47509,36 +47534,59 @@ astParsingFunctions.spacesForString = function(content) {
|
|
|
47509
47534
|
};
|
|
47510
47535
|
|
|
47511
47536
|
// src/compiler/functions/splitDictArray.ts
|
|
47512
|
-
astParsingFunctions.splitDictArray = function(content) {
|
|
47513
|
-
|
|
47514
|
-
|
|
47515
|
-
|
|
47516
|
-
|
|
47517
|
-
|
|
47518
|
-
|
|
47519
|
-
|
|
47520
|
-
|
|
47521
|
-
|
|
47522
|
-
|
|
47523
|
-
|
|
47524
|
-
|
|
47525
|
-
|
|
47526
|
-
|
|
47527
|
-
|
|
47528
|
-
let
|
|
47529
|
-
|
|
47530
|
-
for (let
|
|
47531
|
-
|
|
47532
|
-
|
|
47533
|
-
|
|
47534
|
-
|
|
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
|
+
}
|
|
47535
47564
|
}
|
|
47536
|
-
|
|
47537
|
-
|
|
47538
|
-
|
|
47539
|
-
|
|
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
|
+
}
|
|
47540
47569
|
}
|
|
47541
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
|
+
}, []);
|
|
47542
47590
|
}
|
|
47543
47591
|
if (content.args[2].name === "true") {
|
|
47544
47592
|
arrays = arrays.map((x) => {
|
|
@@ -47551,7 +47599,7 @@ astParsingFunctions.splitDictArray = function(content) {
|
|
|
47551
47599
|
}
|
|
47552
47600
|
let assignments = arrays.map((x, i) => new Ast2("__assignTo__", [variables[i], x]));
|
|
47553
47601
|
if (!content.parent) {
|
|
47554
|
-
error("Could not find parent of
|
|
47602
|
+
error("Could not find parent of " + content.name + "()");
|
|
47555
47603
|
}
|
|
47556
47604
|
content.parent.children.splice(content.parent.childIndex + 1, 0, ...assignments.slice(1));
|
|
47557
47605
|
return assignments[0];
|
|
@@ -47732,6 +47780,18 @@ function parseAstRules(rules) {
|
|
|
47732
47780
|
rulesResult.push(rule);
|
|
47733
47781
|
continue;
|
|
47734
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
|
+
}
|
|
47735
47795
|
for (let i2 = 0; i2 < rule.children.length; i2++) {
|
|
47736
47796
|
setFileStack(rule.children[i2].fileStack);
|
|
47737
47797
|
if (rule.children[i2].name in astMacros) {
|
|
@@ -64458,11 +64518,24 @@ function astRulesToWs(rules) {
|
|
|
64458
64518
|
compiledRules.push("//Strict optimizations enabled\n");
|
|
64459
64519
|
continue;
|
|
64460
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
|
+
}
|
|
64461
64533
|
if (rule.ruleAttributes.isDisabled) {
|
|
64462
64534
|
result += tows("__disabled__", ruleKw) + " ";
|
|
64463
64535
|
}
|
|
64536
|
+
let finalRuleName = applyRulePrefixTemplate(rule);
|
|
64464
64537
|
result += tows("__rule__", ruleKw) + " (";
|
|
64465
|
-
result += escapeBadWords(escapeString(
|
|
64538
|
+
result += escapeBadWords(escapeString(finalRuleName, true));
|
|
64466
64539
|
result += ") {\n";
|
|
64467
64540
|
result += tabLevel(1) + tows("__event__", ruleKw) + " {\n";
|
|
64468
64541
|
result += tabLevel(2) + tows(rule.ruleAttributes.event, eventKw) + ";\n";
|
|
@@ -65131,6 +65204,70 @@ function splitCustomString(tokens, args) {
|
|
|
65131
65204
|
}
|
|
65132
65205
|
return new Ast2("__customString__", [new Ast2(result, [], [], "CustomStringLiteral")].concat(resultArgs));
|
|
65133
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
|
+
}
|
|
65134
65271
|
|
|
65135
65272
|
// src/compiler/translations.ts
|
|
65136
65273
|
var import_pofile = __toESM(require_po());
|
|
@@ -65142,7 +65279,7 @@ function getLeadingAndTrailingWhitespace(str) {
|
|
|
65142
65279
|
trailingWhitespace
|
|
65143
65280
|
};
|
|
65144
65281
|
}
|
|
65145
|
-
function getTranslatedString(str, context,
|
|
65282
|
+
function getTranslatedString(str, context, fileStack7) {
|
|
65146
65283
|
let lineNb = null;
|
|
65147
65284
|
let fileName = null;
|
|
65148
65285
|
if (translationLanguages2.length === 0) {
|
|
@@ -65163,10 +65300,10 @@ function getTranslatedString(str, context, fileStack8) {
|
|
|
65163
65300
|
let { leadingWhitespace, actualString: actualStringWithNewlines, trailingWhitespace } = getLeadingAndTrailingWhitespace(str);
|
|
65164
65301
|
let lines = actualStringWithNewlines.split("\n").map((x) => getLeadingAndTrailingWhitespace(x));
|
|
65165
65302
|
let actualString = lines.map((x) => x.actualString).join("\n");
|
|
65166
|
-
for (let i =
|
|
65167
|
-
if (
|
|
65168
|
-
lineNb =
|
|
65169
|
-
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();
|
|
65170
65307
|
break;
|
|
65171
65308
|
}
|
|
65172
65309
|
}
|
|
@@ -65320,6 +65457,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65320
65457
|
setFileStack([
|
|
65321
65458
|
{
|
|
65322
65459
|
name: mainFileName || "<main>",
|
|
65460
|
+
path: rootPath + mainFileName,
|
|
65323
65461
|
startLine: 1,
|
|
65324
65462
|
startCol: 1,
|
|
65325
65463
|
endCol: null,
|
|
@@ -65381,7 +65519,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65381
65519
|
}
|
|
65382
65520
|
}).join("0");
|
|
65383
65521
|
if (usePlayerVarForTranslations) {
|
|
65384
|
-
addVariable("__languageIndex__", false, -1, getInternalFileStack(), tokenize("1.1")[0].tokens);
|
|
65522
|
+
addVariable("__languageIndex__", false, -1, getInternalFileStack(), tokenize(useTlErr ? "1.1" : "0.1")[0].tokens);
|
|
65385
65523
|
}
|
|
65386
65524
|
addVariable("__overpyTranslationHelper__", true, -1, getInternalFileStack(), tokenize(escapeString("\uEC480" + translationConstantString, false) + ".split(null[0])")[0].tokens);
|
|
65387
65525
|
}
|
|
@@ -65416,7 +65554,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65416
65554
|
@Event eachPlayer
|
|
65417
65555
|
@Condition eventPlayer.hasSpawned()
|
|
65418
65556
|
@Condition not eventPlayer.isDummy()
|
|
65419
|
-
@Condition eventPlayer.__languageIndex__ == 1.1
|
|
65557
|
+
@Condition eventPlayer.__languageIndex__ == ${useTlErr ? "1.1" : "0.1"}
|
|
65420
65558
|
eventPlayer.__languageIndex__.append(eventPlayer.getFacingDirection())
|
|
65421
65559
|
eventPlayer.startFacing(
|
|
65422
65560
|
directionFromAngles(10*${escapeString("\uEC480" + translationConstantString, false)}.split(null[0]).index(${translationLanguageConstantOpy}.split([])), 5),
|
|
@@ -65432,7 +65570,7 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
|
|
|
65432
65570
|
|
|
65433
65571
|
eventPlayer.stopFacing()
|
|
65434
65572
|
eventPlayer.setFacing(eventPlayer.__languageIndex__.last(), Relativity.TO_WORLD)
|
|
65435
|
-
eventPlayer.__languageIndex__ = eventPlayer.__languageIndex__[0]
|
|
65573
|
+
eventPlayer.__languageIndex__ = eventPlayer.__languageIndex__${useTlErr ? "[0]" : " - 1"}
|
|
65436
65574
|
`;
|
|
65437
65575
|
translationSetupRule = tokenize(translationSetupRule);
|
|
65438
65576
|
translationSetupRule = parseLines(translationSetupRule)[0];
|
|
@@ -67760,10 +67898,10 @@ function parseType(tokens) {
|
|
|
67760
67898
|
var OpyError = class _OpyError extends Error {
|
|
67761
67899
|
fileStack;
|
|
67762
67900
|
severity = "error";
|
|
67763
|
-
constructor(message,
|
|
67901
|
+
constructor(message, fileStack7) {
|
|
67764
67902
|
super(message);
|
|
67765
67903
|
this.name = "OpyError";
|
|
67766
|
-
this.fileStack =
|
|
67904
|
+
this.fileStack = fileStack7;
|
|
67767
67905
|
Object.setPrototypeOf(this, _OpyError.prototype);
|
|
67768
67906
|
}
|
|
67769
67907
|
};
|
|
@@ -67923,12 +68061,12 @@ function getFileStackRange(tokens) {
|
|
|
67923
68061
|
result[result.length - 1].endCol = lastTokenFilestack.endCol;
|
|
67924
68062
|
return result;
|
|
67925
68063
|
}
|
|
67926
|
-
function displayFileStack(
|
|
67927
|
-
if (!
|
|
68064
|
+
function displayFileStack(fileStack7) {
|
|
68065
|
+
if (!fileStack7 || fileStack7.length === 0) {
|
|
67928
68066
|
return "";
|
|
67929
68067
|
}
|
|
67930
68068
|
let result = "";
|
|
67931
|
-
for (const file of
|
|
68069
|
+
for (const file of fileStack7.toReversed()) {
|
|
67932
68070
|
result += `
|
|
67933
68071
|
| `;
|
|
67934
68072
|
if (file.startLine !== null && file.startCol !== null) {
|
|
@@ -67963,6 +68101,9 @@ function upperCaseToCamelCase(str) {
|
|
|
67963
68101
|
result = result[0].toLowerCase() + result.substring(1);
|
|
67964
68102
|
return result;
|
|
67965
68103
|
}
|
|
68104
|
+
function toTitleCase(str) {
|
|
68105
|
+
return str.replace(/[\p{Letter}']+/gu, (txt) => txt.charAt(0).toUpperCase() + txt.substring(1));
|
|
68106
|
+
}
|
|
67966
68107
|
function isNumber(x) {
|
|
67967
68108
|
if (("" + x).trim() === "" || x === null) {
|
|
67968
68109
|
return false;
|
|
@@ -68483,6 +68624,23 @@ var opyInternalFuncs = {
|
|
|
68483
68624
|
"Vector"
|
|
68484
68625
|
]
|
|
68485
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
|
+
},
|
|
68486
68644
|
"__rule__": {
|
|
68487
68645
|
"args": null,
|
|
68488
68646
|
"return": "void"
|
|
@@ -69222,6 +69380,8 @@ waveLengths = [3, 8, null]
|
|
|
69222
69380
|
\`\`\`
|
|
69223
69381
|
|
|
69224
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.
|
|
69225
69385
|
`,
|
|
69226
69386
|
"args": [
|
|
69227
69387
|
{
|
|
@@ -69268,6 +69428,48 @@ If the third argument is set to \`true\`, arrays will be compressed if they are
|
|
|
69268
69428
|
"isConstant": true,
|
|
69269
69429
|
"return": "unsigned int"
|
|
69270
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
|
+
},
|
|
69271
69473
|
".toArray": {
|
|
69272
69474
|
"description": "Get an array of the values of an enum.",
|
|
69273
69475
|
"args": [
|
|
@@ -69380,6 +69582,8 @@ var usePlayerVarForTranslations;
|
|
|
69380
69582
|
var setUsePlayerVarForTranslations = (use) => usePlayerVarForTranslations = use;
|
|
69381
69583
|
var generateRuleForTranslationsPlayerVar;
|
|
69382
69584
|
var setGenerateRuleForTranslationsPlayerVar = (generate) => generateRuleForTranslationsPlayerVar = generate;
|
|
69585
|
+
var useTlErr;
|
|
69586
|
+
var setTranslationUseTlErr = (use) => useTlErr = use;
|
|
69383
69587
|
var excludeVariablesInCompilation;
|
|
69384
69588
|
var setExcludeVariablesInCompilation = (exclude) => excludeVariablesInCompilation = exclude;
|
|
69385
69589
|
var globalvarInitRuleName;
|
|
@@ -69388,6 +69592,17 @@ var playervarInitRuleName;
|
|
|
69388
69592
|
var setPlayervarInitRuleName = (name) => playervarInitRuleName = name;
|
|
69389
69593
|
var disableInspector = false;
|
|
69390
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;
|
|
69391
69606
|
var decompilerGotos;
|
|
69392
69607
|
var resetDecompilerGotos = () => decompilerGotos = [];
|
|
69393
69608
|
var nbTabs;
|
|
@@ -69451,6 +69666,7 @@ function resetGlobalVariables(language) {
|
|
|
69451
69666
|
translationLanguageConstantOpy = "";
|
|
69452
69667
|
usePlayerVarForTranslations = false;
|
|
69453
69668
|
generateRuleForTranslationsPlayerVar = true;
|
|
69669
|
+
useTlErr = true;
|
|
69454
69670
|
excludeVariablesInCompilation = false;
|
|
69455
69671
|
globalvarInitRuleName = "Initialize global variables";
|
|
69456
69672
|
playervarInitRuleName = "Initialize player variables";
|
|
@@ -69459,6 +69675,10 @@ function resetGlobalVariables(language) {
|
|
|
69459
69675
|
disableTranslationSourceLines = false;
|
|
69460
69676
|
usedMaps = /* @__PURE__ */ new Set();
|
|
69461
69677
|
postCompileHook = null;
|
|
69678
|
+
rulePrefixStack = [];
|
|
69679
|
+
currentRulePrefix = "";
|
|
69680
|
+
rulePrefixTemplate = "";
|
|
69681
|
+
rulePrefixTemplateFilestack = [];
|
|
69462
69682
|
}
|
|
69463
69683
|
var operatorPrecedence = {
|
|
69464
69684
|
"=": 1,
|
|
@@ -71901,6 +72121,8 @@ If using translations, this can save a lot of elements. However, it will make tr
|
|
|
71901
72121
|
If your gamemode changes the facing direction on spawn, you must modify it so that it changes it once \`eventPlayer.__languageIndex__ != 1.1\`.
|
|
71902
72122
|
|
|
71903
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.
|
|
71904
72126
|
`
|
|
71905
72127
|
},
|
|
71906
72128
|
"extension": {
|
|
@@ -71942,6 +72164,51 @@ content.toString();
|
|
|
71942
72164
|
\`\`\`
|
|
71943
72165
|
`,
|
|
71944
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"
|
|
71945
72212
|
}
|
|
71946
72213
|
};
|
|
71947
72214
|
postLoadTasks.push({
|
package/package.json
CHANGED