overpy 9.6.3 → 9.6.5
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 +4 -2
- package/overpy.js +94 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -596,7 +596,7 @@ Suppresses the specified warnings globally across the program. Warnings must be
|
|
|
596
596
|
|
|
597
597
|
## #!allowMacroRedeclaration
|
|
598
598
|
|
|
599
|
-
If specified,
|
|
599
|
+
If specified, allows redefining a `macro`, `#!define` or `enum` member. Can be useful for OOP-like projects where the same codebase is used for multiple different gamemodes.
|
|
600
600
|
|
|
601
601
|
## #!debugElementCount
|
|
602
602
|
|
|
@@ -616,7 +616,7 @@ You can check [here](https://github.com/Zezombye/overpy/issues/33) for a list of
|
|
|
616
616
|
|
|
617
617
|
The `#!disableOptimizations` directive can be used to disable all optimizations done by the compiler. Should be only used for debugging, if you suspect that OverPy has bugs in its optimizations, or if you want to generate an unoptimized instruction for some reason.
|
|
618
618
|
|
|
619
|
-
The `#!optimizeForSize` directive prioritizes lowering the number of elements over optimizing the runtime (see [here](https://github.com/Zezombye/overpy/issues/238) for a list of optimizations).
|
|
619
|
+
The `#!optimizeForSize` directive prioritizes lowering the number of elements over optimizing the runtime (see [here](https://github.com/Zezombye/overpy/issues/238) for a list of optimizations). You can use `#!optimizeForSizeAggressive` (applied codebase-wide and MUST be used alongside `#!optimizeForSize`) for even more optimizations if you really need to squeeze every last element, at the cost of readability.
|
|
620
620
|
|
|
621
621
|
The `#!optimizeStrict` directive disables some optimizations that may cause issues in extreme cases of type conversion. For example:
|
|
622
622
|
|
|
@@ -956,6 +956,8 @@ OverPy will store the array in a string and automatically decompress it, which t
|
|
|
956
956
|
|
|
957
957
|
For more control over the compression (eg if you have separate arrays to compress), you can use the `compress` and `decompressNumbers`/`decompressVectors` functions.
|
|
958
958
|
|
|
959
|
+
You can also use the `#!useVariableForCompressionAlphabet` compiler option to use a global variable `__compressionAlphabet__` instead of a hardcoded string for the alphabet, which will save further elements.
|
|
960
|
+
|
|
959
961
|
## splitDictArray/tabular
|
|
960
962
|
|
|
961
963
|
`splitDictArray` maps an array of dictionaries to variables. For example:
|
package/overpy.js
CHANGED
|
@@ -38600,20 +38600,24 @@ ${scriptText}`, {
|
|
|
38600
38600
|
setPlayervarInitRuleName(unescapeString(ruleName, true));
|
|
38601
38601
|
return;
|
|
38602
38602
|
}
|
|
38603
|
+
if (content2.startsWith("#!optimizeForSizeAggressive")) {
|
|
38604
|
+
setOptimizationForSizeAggressive(true);
|
|
38605
|
+
return;
|
|
38606
|
+
}
|
|
38603
38607
|
if (content2.startsWith("#!optimizeForSize")) {
|
|
38604
|
-
|
|
38608
|
+
currentLine.tokens.push(new Token("__enableOptimizeForSize__", getFileStackCopy()));
|
|
38605
38609
|
return;
|
|
38606
38610
|
}
|
|
38607
38611
|
if (content2.startsWith("#!disableOptimizeForSize")) {
|
|
38608
|
-
|
|
38612
|
+
currentLine.tokens.push(new Token("__disableOptimizeForSize__", getFileStackCopy()));
|
|
38609
38613
|
return;
|
|
38610
38614
|
}
|
|
38611
38615
|
if (content2.startsWith("#!optimizeStrict")) {
|
|
38612
|
-
|
|
38616
|
+
currentLine.tokens.push(new Token("__enableOptimizeStrict__", getFileStackCopy()));
|
|
38613
38617
|
return;
|
|
38614
38618
|
}
|
|
38615
38619
|
if (content2.startsWith("#!disableOptimizeStrict")) {
|
|
38616
|
-
|
|
38620
|
+
currentLine.tokens.push(new Token("__disableOptimizeStrict__", getFileStackCopy()));
|
|
38617
38621
|
return;
|
|
38618
38622
|
}
|
|
38619
38623
|
if (content2.startsWith("#!setupTx") || content2.startsWith("#!setupTags")) {
|
|
@@ -38678,10 +38682,10 @@ ${scriptText}`, {
|
|
|
38678
38682
|
}
|
|
38679
38683
|
if (content2.startsWith("#!rulePrefix ")) {
|
|
38680
38684
|
let prefix = content2.substring("#!rulePrefix ".length).trim();
|
|
38681
|
-
|
|
38682
|
-
|
|
38683
|
-
|
|
38684
|
-
|
|
38685
|
+
currentLine.tokens.push(new Token("__rulePrefix__", getFileStackCopy()));
|
|
38686
|
+
currentLine.tokens.push(new Token("(", getFileStackCopy()));
|
|
38687
|
+
currentLine.tokens.push(new Token(prefix, getFileStackCopy()));
|
|
38688
|
+
currentLine.tokens.push(new Token(")", getFileStackCopy()));
|
|
38685
38689
|
return;
|
|
38686
38690
|
}
|
|
38687
38691
|
if (content2.startsWith("#!rulePrefixTemplate")) {
|
|
@@ -39682,6 +39686,10 @@ var Ast2 = class _Ast {
|
|
|
39682
39686
|
//Used for translated strings, if set to true then player var won't be used
|
|
39683
39687
|
forceNotResolvingTranslation;
|
|
39684
39688
|
//Used for translated strings, if true then the resulting string array won't be indexed and will need to be indexed later on with the _() function
|
|
39689
|
+
isGotoInSameScope;
|
|
39690
|
+
//Used for gotos, if true then the goto doesn't jump to another scope and can be optimized more easily. For now, only set on automatically generated gotos
|
|
39691
|
+
isSwitchIf;
|
|
39692
|
+
//true if it is the "if true" from a switch
|
|
39685
39693
|
argIndex = 0;
|
|
39686
39694
|
childIndex = 0;
|
|
39687
39695
|
wasParsed = false;
|
|
@@ -39757,6 +39765,8 @@ var Ast2 = class _Ast {
|
|
|
39757
39765
|
clone.numValue = this.numValue;
|
|
39758
39766
|
clone.stringTokens = structuredClone(this.stringTokens);
|
|
39759
39767
|
clone.isSpectatorTranslation = this.isSpectatorTranslation;
|
|
39768
|
+
clone.isGotoInSameScope = this.isGotoInSameScope;
|
|
39769
|
+
clone.isSwitchIf = this.isSwitchIf;
|
|
39760
39770
|
return clone;
|
|
39761
39771
|
}
|
|
39762
39772
|
};
|
|
@@ -39876,6 +39886,15 @@ function astContainsFunctions(ast, functionNames, errorOnTrue = false) {
|
|
|
39876
39886
|
}
|
|
39877
39887
|
return false;
|
|
39878
39888
|
}
|
|
39889
|
+
function astIsInLambdaFunction(ast) {
|
|
39890
|
+
if (!ast.parent) {
|
|
39891
|
+
return false;
|
|
39892
|
+
}
|
|
39893
|
+
if (["__filteredArray__", "__mappedArray__"].includes(ast.parent.name) && ast.parent.argIndex === 1) {
|
|
39894
|
+
return true;
|
|
39895
|
+
}
|
|
39896
|
+
return astIsInLambdaFunction(ast.parent);
|
|
39897
|
+
}
|
|
39879
39898
|
function astIsLiteral(ast) {
|
|
39880
39899
|
if (typeof ast.type === "string" && !["Hero", "Map", "Gamemode", "Team", "Button", "Color"].includes(ast.type)) {
|
|
39881
39900
|
if (["IntLiteral", "UnsignedIntLiteral", "SignedIntLiteral", "FloatLiteral", "UnsignedFloatLiteral", "SignedFloatLiteral", "GlobalVariable", "PlayerVariable", "Subroutine", "HeroLiteral", "MapLiteral", "GamemodeLiteral", "TeamLiteral", "ButtonLiteral", "StringLiteral", "LocalizedStringLiteral", "CustomStringLiteral"].concat(Object.keys(constantValues)).includes(ast.type)) {
|
|
@@ -44944,6 +44963,9 @@ astParsingFunctions.__equals__ = function(content) {
|
|
|
44944
44963
|
|
|
44945
44964
|
// src/compiler/functions/__filteredArray__.ts
|
|
44946
44965
|
astParsingFunctions.__filteredArray__ = function(content) {
|
|
44966
|
+
if (astIsInLambdaFunction(content)) {
|
|
44967
|
+
error("Cannot nest .filter() or .map()");
|
|
44968
|
+
}
|
|
44947
44969
|
if (enableOptimization) {
|
|
44948
44970
|
if (!optimizeForSize2) {
|
|
44949
44971
|
if (!astContainsFunctions(content.args[1], ["__currentArrayElement__", "__currentArrayIndex__"])) {
|
|
@@ -45187,7 +45209,7 @@ astParsingFunctions.__if__ = function(content) {
|
|
|
45187
45209
|
}
|
|
45188
45210
|
}
|
|
45189
45211
|
}
|
|
45190
|
-
if (optimizeForSize2 && (content.args[0].name === "__not__" || content.children.length === 1 && includeEnd && ["__equals__", "__inequals__", "__greaterThan__", "__greaterThanOrEquals__", "__lessThan__", "__lessThanOrEquals__"].includes(content.args[0].name))) {
|
|
45212
|
+
if (optimizeForSize2 && optimizeForSizeAggressive && (content.args[0].name === "__not__" || content.children.length === 1 && includeEnd && ["__equals__", "__inequals__", "__greaterThan__", "__greaterThanOrEquals__", "__lessThan__", "__lessThanOrEquals__"].includes(content.args[0].name))) {
|
|
45191
45213
|
let label = "__label_if_" + getUniqueNumber() + "__";
|
|
45192
45214
|
content.parent.children.splice(content.parent.childIndex + 1, 0, ...content.children, new Ast2(label, [], [], "Label"), getAstForUselessInstruction());
|
|
45193
45215
|
if (content.args[0].name === "__not__") {
|
|
@@ -45195,7 +45217,9 @@ astParsingFunctions.__if__ = function(content) {
|
|
|
45195
45217
|
} else {
|
|
45196
45218
|
content.args[0] = astParsingFunctions.__not__(new Ast2("__not__", [content.args[0]]));
|
|
45197
45219
|
}
|
|
45198
|
-
|
|
45220
|
+
let skip = new Ast2("__skipIf__", [content.args[0], new Ast2("__distanceTo__", [new Ast2(label, [], [], "Label")])]);
|
|
45221
|
+
skip.isGotoInSameScope = true;
|
|
45222
|
+
return skip;
|
|
45199
45223
|
}
|
|
45200
45224
|
if (includeEnd) {
|
|
45201
45225
|
content.parent.children.splice(content.parent.childIndex + 1, 0, getAstForEnd());
|
|
@@ -45307,6 +45331,9 @@ astParsingFunctions.__map__ = function(content) {
|
|
|
45307
45331
|
|
|
45308
45332
|
// src/compiler/functions/__mappedArray__.ts
|
|
45309
45333
|
astParsingFunctions.__mappedArray__ = function(content) {
|
|
45334
|
+
if (astIsInLambdaFunction(content)) {
|
|
45335
|
+
error("Cannot nest .filter() or .map()");
|
|
45336
|
+
}
|
|
45310
45337
|
if (enableOptimization) {
|
|
45311
45338
|
if (content.args[1].name === "__currentArrayElement__") {
|
|
45312
45339
|
return content.args[0];
|
|
@@ -45532,10 +45559,10 @@ astParsingFunctions.__rule__ = function(content) {
|
|
|
45532
45559
|
function iterateOnRuleActions(children) {
|
|
45533
45560
|
for (let i2 = 0; i2 < children.length; i2++) {
|
|
45534
45561
|
setFileStack(content.fileStack);
|
|
45535
|
-
if (children[i2].name === "__skip__" && children[i2].args[0].name !== "__distanceTo__" || children[i2].name === "__skipIf__" && children[i2].args[1].name !== "__distanceTo__") {
|
|
45562
|
+
if ((children[i2].name === "__skip__" && children[i2].args[0].name !== "__distanceTo__" || children[i2].name === "__skipIf__" && children[i2].args[1].name !== "__distanceTo__") && !children[i2].isGotoInSameScope) {
|
|
45536
45563
|
isRelativeGotoEncountered = true;
|
|
45537
45564
|
}
|
|
45538
|
-
if (children[i2].name === "__skip__" || children[i2].name === "__skipIf__") {
|
|
45565
|
+
if ((children[i2].name === "__skip__" || children[i2].name === "__skipIf__") && !children[i2].isGotoInSameScope) {
|
|
45539
45566
|
isGotoEncountered = true;
|
|
45540
45567
|
}
|
|
45541
45568
|
if (content.type === "Label") {
|
|
@@ -45545,7 +45572,7 @@ astParsingFunctions.__rule__ = function(content) {
|
|
|
45545
45572
|
declaredLabels.push(content.name);
|
|
45546
45573
|
}
|
|
45547
45574
|
iterateOnRuleActions(children[i2].children);
|
|
45548
|
-
if (!isRelativeGotoEncountered) {
|
|
45575
|
+
if (!isRelativeGotoEncountered && !children[i2].isSwitchIf) {
|
|
45549
45576
|
if (children[i2].name === "pass") {
|
|
45550
45577
|
children.splice(i2, 1);
|
|
45551
45578
|
i2--;
|
|
@@ -45815,7 +45842,10 @@ astParsingFunctions.__switch__ = function(content) {
|
|
|
45815
45842
|
error("Parent is undefined in __switch__");
|
|
45816
45843
|
}
|
|
45817
45844
|
content.parent.children.splice(content.parent.childIndex + 1, 0, ...casesChildren);
|
|
45818
|
-
|
|
45845
|
+
let skip = new Ast2("__skip__", [new Ast2("__valueInArray__", [new Ast2("__array__", caseOffsets), new Ast2("__add__", [getAstFor1(), new Ast2(".index", [new Ast2("__array__", switchCaseArgs), content.args[0]])])])]);
|
|
45846
|
+
skip.isGotoInSameScope = true;
|
|
45847
|
+
var result = new Ast2("__if__", [getAstForTrue()], [skip]);
|
|
45848
|
+
result.isSwitchIf = true;
|
|
45819
45849
|
result.doNotReparse = true;
|
|
45820
45850
|
return result;
|
|
45821
45851
|
};
|
|
@@ -48011,9 +48041,6 @@ function parseAstRules(rules) {
|
|
|
48011
48041
|
}
|
|
48012
48042
|
rulesResult.push(parseAst(rule));
|
|
48013
48043
|
}
|
|
48014
|
-
setOptimizationEnabled2(true);
|
|
48015
|
-
setOptimizeStrict2(false);
|
|
48016
|
-
setOptimizationForSize2(false);
|
|
48017
48044
|
return rulesResult;
|
|
48018
48045
|
}
|
|
48019
48046
|
function parseAst(content) {
|
|
@@ -64661,9 +64688,6 @@ function astRulesToWs(rules) {
|
|
|
64661
64688
|
ruleElementCounts.sort((a, b) => b.elements - a.elements);
|
|
64662
64689
|
elementCountSummary = "/* Element count: (total " + nbElements + ")\n\n" + ruleElementCounts.map((r) => ("" + r.elements).padStart(5, " ") + ": rule " + escapeString(r.name, false) + (r.file ? " (" + r.file + ")" : "")).join("\n") + "\n\n*/\n\n";
|
|
64663
64690
|
}
|
|
64664
|
-
setOptimizationEnabled2(true);
|
|
64665
|
-
setOptimizeStrict2(false);
|
|
64666
|
-
setOptimizationForSize2(false);
|
|
64667
64691
|
return { compiledRules, elementCountSummary };
|
|
64668
64692
|
}
|
|
64669
64693
|
function astRuleConditionToWs(condition) {
|
|
@@ -64989,19 +65013,32 @@ function astToWs(content) {
|
|
|
64989
65013
|
if (content.args.length === 0) {
|
|
64990
65014
|
incrementNbElements();
|
|
64991
65015
|
return tows("__emptyArray__", valueKw);
|
|
64992
|
-
} else if (optimizeForSize2 && content.parent?.name !== "createWorkshopSettingEnum"
|
|
64993
|
-
|
|
64994
|
-
|
|
64995
|
-
|
|
64996
|
-
|
|
64997
|
-
|
|
64998
|
-
|
|
64999
|
-
|
|
65000
|
-
|
|
65001
|
-
|
|
65002
|
-
|
|
65003
|
-
|
|
65004
|
-
|
|
65016
|
+
} else if (optimizeForSize2 && optimizeForSizeAggressive && content.parent?.name !== "createWorkshopSettingEnum") {
|
|
65017
|
+
if (content.args.every((x) => x.name === "__customString__" && x.args.length === 1)) {
|
|
65018
|
+
let separator = "\uEC51";
|
|
65019
|
+
let separatorAst = getAstForCustomString(separator);
|
|
65020
|
+
let str = content.args.map((x) => x.args[0].name).join(separator);
|
|
65021
|
+
if (!str.includes("0")) {
|
|
65022
|
+
separator = "0";
|
|
65023
|
+
separatorAst = new Ast2("__firstOf__", [getAstForNull()]);
|
|
65024
|
+
} else if (!str.includes("(1.00, 0.00, 0.00)") && getUtf8Length(str) % (STR_MAX_LENGTH - "{0}".length) + content.args.length * ("(1.00, 0.00, 0.00)".length - "\uEC51".length) <= STR_MAX_LENGTH) {
|
|
65025
|
+
separator = "(1.00, 0.00, 0.00)";
|
|
65026
|
+
separatorAst = new Ast2("__firstOf__", [new Ast2("Vector.LEFT")]);
|
|
65027
|
+
}
|
|
65028
|
+
str = str.replaceAll("\uEC51", separator);
|
|
65029
|
+
return astToWs(new Ast2(".split", [getAstForCustomString(str), separatorAst]));
|
|
65030
|
+
} else if (!astIsInLambdaFunction(content) && content.args.length >= 3 && content.args.every((x) => areAstsAlwaysEqual(x, content.args[0]))) {
|
|
65031
|
+
let estimatedElementCount = 1 + (content.args[0].name === "__customString__" ? 4 : content.args[0].args.length);
|
|
65032
|
+
if (estimatedElementCount === 1 && content.args.length >= 11 || estimatedElementCount === 2 && content.args.length >= 5 || estimatedElementCount === 3 && content.args.length >= 4 || estimatedElementCount >= 4) {
|
|
65033
|
+
return astToWs(new Ast2("__mappedArray__", [
|
|
65034
|
+
new Ast2(".split", [
|
|
65035
|
+
getAstForCustomString("0".repeat(content.args.length - 1)),
|
|
65036
|
+
new Ast2("__firstOf__", [getAstForNull()])
|
|
65037
|
+
]),
|
|
65038
|
+
content.args[0]
|
|
65039
|
+
]));
|
|
65040
|
+
}
|
|
65041
|
+
}
|
|
65005
65042
|
}
|
|
65006
65043
|
} else if (content.name === "chaseAtRate" || content.name === "chaseOverTime") {
|
|
65007
65044
|
var newName = content.name === "chaseAtRate" ? "AtRate__" : "OverTime__";
|
|
@@ -65057,13 +65094,17 @@ function astToWs(content) {
|
|
|
65057
65094
|
content.name = newName;
|
|
65058
65095
|
} else if (content.name === "__globalVar__") {
|
|
65059
65096
|
incrementNbElements();
|
|
65097
|
+
content.argIndex = 0;
|
|
65060
65098
|
return tows("__global__", valueKw) + "." + astToWs(content.args[0]);
|
|
65061
65099
|
} else if (content.name === "__number__") {
|
|
65062
65100
|
incrementNbElements(2);
|
|
65063
65101
|
return trimNb(content.args[0].name);
|
|
65064
65102
|
} else if (content.name === "__playerVar__") {
|
|
65065
65103
|
incrementNbElements();
|
|
65066
|
-
|
|
65104
|
+
content.argIndex = 0;
|
|
65105
|
+
let result2 = "(" + astToWs(content.args[0]) + ").";
|
|
65106
|
+
content.argIndex = 1;
|
|
65107
|
+
return result2 + astToWs(content.args[1]);
|
|
65067
65108
|
} else if (content.name === "ceil") {
|
|
65068
65109
|
content.name = "__round__";
|
|
65069
65110
|
content.args = [content.args[0], new Ast2("__roundUp__", [], [], "__Rounding__")];
|
|
@@ -65193,6 +65234,7 @@ function astToWs(content) {
|
|
|
65193
65234
|
if (content.args[i].type === "void") {
|
|
65194
65235
|
error("Expected a value, but got " + functionNameToString(content.args[i]) + " which is an action", content.args[i].fileStack);
|
|
65195
65236
|
}
|
|
65237
|
+
content.argIndex = i;
|
|
65196
65238
|
result += astToWs(content.args[i]);
|
|
65197
65239
|
if (content.type === "void") {
|
|
65198
65240
|
incrementNbElements(Math.floor(nbHeroesInValue / 2));
|
|
@@ -65821,7 +65863,13 @@ function compileRules(astRules) {
|
|
|
65821
65863
|
if (DEBUG_MODE) {
|
|
65822
65864
|
console.log(parsedAstRules);
|
|
65823
65865
|
}
|
|
65866
|
+
setOptimizationEnabled2(true);
|
|
65867
|
+
setOptimizeStrict2(false);
|
|
65868
|
+
setOptimizationForSize2(false);
|
|
65824
65869
|
var { compiledRules, elementCountSummary } = astRulesToWs(parsedAstRules);
|
|
65870
|
+
setOptimizationEnabled2(true);
|
|
65871
|
+
setOptimizeStrict2(false);
|
|
65872
|
+
setOptimizationForSize2(false);
|
|
65825
65873
|
setFileStack(getInternalFileStack());
|
|
65826
65874
|
var result = elementCountSummary + compiledCustomGameSettings;
|
|
65827
65875
|
if (!excludeVariablesInCompilation) {
|
|
@@ -66650,7 +66698,7 @@ function parseLines(lines) {
|
|
|
66650
66698
|
}
|
|
66651
66699
|
}
|
|
66652
66700
|
let enumMemberName = childrenLines[k].tokens[0].toString();
|
|
66653
|
-
if (enumMemberName in enumMembers[args[0].name]) {
|
|
66701
|
+
if (enumMemberName in enumMembers[args[0].name] && !allowMacroRedeclaration) {
|
|
66654
66702
|
error("Duplicate enum member '" + args[0].name + "." + enumMemberName + "''");
|
|
66655
66703
|
}
|
|
66656
66704
|
enumMembers[args[0].name][enumMemberName] = enumValue;
|
|
@@ -69669,6 +69717,8 @@ var enableOptimization;
|
|
|
69669
69717
|
var setOptimizationEnabled2 = (enabled) => enableOptimization = enabled;
|
|
69670
69718
|
var optimizeForSize2;
|
|
69671
69719
|
var setOptimizationForSize2 = (size) => optimizeForSize2 = size;
|
|
69720
|
+
var optimizeForSizeAggressive;
|
|
69721
|
+
var setOptimizationForSizeAggressive = (aggressive) => optimizeForSizeAggressive = aggressive;
|
|
69672
69722
|
var optimizeStrict;
|
|
69673
69723
|
var setOptimizeStrict2 = (strict) => optimizeStrict = strict;
|
|
69674
69724
|
var macros = [];
|
|
@@ -69799,6 +69849,7 @@ function resetGlobalVariables(language) {
|
|
|
69799
69849
|
compiledCustomGameSettings = "";
|
|
69800
69850
|
enableOptimization = true;
|
|
69801
69851
|
optimizeForSize2 = false;
|
|
69852
|
+
optimizeForSizeAggressive = false;
|
|
69802
69853
|
optimizeStrict = false;
|
|
69803
69854
|
uniqueNumber = 1;
|
|
69804
69855
|
globalInitDirectives = [];
|
|
@@ -72116,10 +72167,10 @@ var key;
|
|
|
72116
72167
|
// src/data/opy/preprocessing.ts
|
|
72117
72168
|
var preprocessingDirectives = {
|
|
72118
72169
|
"allowMacroRedeclaration": {
|
|
72119
|
-
"description": "If enabled, redefining a `macro` or
|
|
72170
|
+
"description": "If enabled, redefining a `macro`, `#!define` or `enum` member will not throw an error but will overwrite the previous definition. Can be useful for OOP-like projects where the same codebase is used for multiple different gamemodes."
|
|
72120
72171
|
},
|
|
72121
72172
|
"define": {
|
|
72122
|
-
"description": '**Warning**: This directive performs a text-based replacement! Use `macro`
|
|
72173
|
+
"description": '**Warning**: This directive performs a text-based replacement! Use `macro` instead, unless absolutely necessary.\n\nCreates a macro, like in C/C++. Macros must be defined before any code. Examples:\n\n #!define currentSectionWalls A\n #!define GAME_NOT_STARTED 3`\n\nFunction macros are supported as well:\n\n #!define getFirstAvailableMei() [player for player in getPlayers(Team.2) if not player.isFighting][0]\n #!define spawnMei(type, location) getFirstAvailableMei().meiType = type\\\n wait(0.1)\\\n getFirstAvailableMei().teleport(location)\\\n getFirstAvailableMei().isFighting = true\n\nNote the usage of the backslashed lines.\n\nJS scripts can be inserted with the special `__script__` function:\n\n #!define addFive(x) __script__("addfive.js")\n\nwhere the `addfive.js` script contains `x+5` (no `return`).\n\nArguments of JS scripts are inserted automatically at the beginning (so `addFive(123)` would cause `var x = 123;` to be inserted). The script is then evaluated using `eval()`.\n\nA `vect()` function is also inserted, so that `vect(1,2,3)` returns an object with the correct properties and `toString()` function.\n\nWhen resolving the macro, the indentation on the macro call is prepended to each line of the replacement.\n',
|
|
72123
72174
|
"snippet": "define $0"
|
|
72124
72175
|
},
|
|
72125
72176
|
"debugElementCount": {
|
|
@@ -72147,13 +72198,16 @@ var preprocessingDirectives = {
|
|
|
72147
72198
|
"description": "Add a rule to obtain an unsanitized '<' character which can be used to create <tx> and <fg> tags.\n\n**WARNING**: The inserted rule creates a dummy bot then immediately destroys it. This has the side effect of triggering each-player rules and may break your gamemode (though if properly coded, it shouldn't).\n\nThe `__holygrail__` variable can be used to obtain the raw '<' character, although it is not necessary as OverPy will automatically take care of the conversion, meaning you can put raw texture tags in strings.\n\nFor color, use the <fgRRGGBBAA> tag, where RR/GG/BB are the hex color value, and AA is the hex transparency value (00 = transparent, FF = opaque).\nExample: `print('<fgFF0000FF>Red text</fg>')`.\n\nFor textures, use the <TX> standalone tag, with the texture id as seen in https://workshop.codes/wiki/articles/tx-reference-sheet.\nExample: `print('<TXC0000000002DD21>')` will display the mouse cursor texture.\n\nAdditionally, you can use the `Texture` enum (such as `Texture.MOUSE_CURSOR`), and OverPy will automatically optimize it.\n\nOverPy will also replace `'<tx1234>'` to the correct full texture id, but only if the entire tag is inside a string (`'<tx{}>'.format(id)` will not work, but `'<tx{}>'.format(1234)` will)."
|
|
72148
72199
|
},
|
|
72149
72200
|
"disableOptimizations": {
|
|
72150
|
-
"description": "Disables all optimizations done by the compiler for the current block
|
|
72201
|
+
"description": "Disables all optimizations done by the compiler for the current block, up until the end of the block or the next `#!enableOptimizations` directive."
|
|
72151
72202
|
},
|
|
72152
72203
|
"enableOptimizations": {
|
|
72153
72204
|
"description": "Re-enables optimizations after a `#!disableOptimizations` directive. If no `#!disableOptimizations` directive was encountered, this directive does nothing."
|
|
72154
72205
|
},
|
|
72155
72206
|
"optimizeForSize": {
|
|
72156
|
-
"description": "Prioritizes lowering the number of elements over optimizing the runtime. Effective for the current block
|
|
72207
|
+
"description": "Prioritizes lowering the number of elements over optimizing the runtime. Effective for the current block, up until the end of the block or the next `#!disableOptimizeForSize` directive."
|
|
72208
|
+
},
|
|
72209
|
+
"optimizeForSizeAggressive": {
|
|
72210
|
+
"description": "Enables aggressive optimizations for size, which may significantly lower the readability of the code (for now, replacing `if` by `skip if` in some cases and automatically compressing arrays).\n\n**NOTE:** This directive is applied for the whole codebase and MUST be used alongside `#!optimizeForSize` for it to have an effect."
|
|
72157
72211
|
},
|
|
72158
72212
|
"disableOptimizeForSize": {
|
|
72159
72213
|
"description": "Re-enables optimizations after a `#!optimizeForSize` directive. If no `#!optimizeForSize` directive was encountered, this directive does nothing."
|
|
@@ -72169,7 +72223,7 @@ Those optimizations (and others) will be disabled so that the behavior of the ga
|
|
|
72169
72223
|
|
|
72170
72224
|
This directive is added by default upon decompilation. Only remove it if you are sure that your gamemode does not rely on type conversion tricks. It is recommended to use a website such as http://diffchecker.com to compare the differences in the output when enabling/disabling this directive.
|
|
72171
72225
|
|
|
72172
|
-
This directive is effective for the current block
|
|
72226
|
+
This directive is effective for the current block, up until the end of the block or the next \`#!disableOptimizeStrict\` directive.`
|
|
72173
72227
|
},
|
|
72174
72228
|
"disableOptimizeStrict": {
|
|
72175
72229
|
"description": "Re-enables optimizations after a `#!optimizeStrict` directive. If no `#!optimizeStrict` directive was encountered, this directive does nothing."
|
package/package.json
CHANGED