overpy 9.6.2 → 9.6.4

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.
Files changed (3) hide show
  1. package/README.md +4 -2
  2. package/overpy.js +97 -34
  3. 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, will replace the existing macro instead of throwing an error. Can be useful for OOP-like projects where the same codebase is used for multiple different gamemodes.
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,6 +38600,10 @@ ${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
  addToken("__enableOptimizeForSize__");
38605
38609
  return;
@@ -38695,6 +38699,10 @@ ${scriptText}`, {
38695
38699
  setRulePrefixTemplateFilestack(_rulePrefixTemplateFilestack);
38696
38700
  return;
38697
38701
  }
38702
+ if (content2.startsWith("#!useVariableForCompressionAlphabet")) {
38703
+ setUseVariableForCompressionAlphabet(true);
38704
+ return;
38705
+ }
38698
38706
  if (content2.startsWith("#!debugElementCount")) {
38699
38707
  setDebugElementCount(true);
38700
38708
  return;
@@ -45143,8 +45151,9 @@ astParsingFunctions.__if__ = function(content) {
45143
45151
  }
45144
45152
  }
45145
45153
  }
45154
+ let isLoneIf = content.parent.childIndex === content.parent.children.length - 1 || content.parent.childIndex < content.parent.children.length - 1 && !["__elif__", "__else__"].includes(content.parent.children[content.parent.childIndex + 1].name);
45146
45155
  if (enableOptimization) {
45147
- if (content.children.length === 1 && (content.parent.childIndex === content.parent.children.length - 1 || content.parent.children[content.parent.childIndex + 1].name !== "__elif__" && content.parent.children[content.parent.childIndex + 1].name !== "__else__") && ["return", "loop", "__skip__"].includes(content.children[0].name)) {
45156
+ if (content.children.length === 1 && isLoneIf && ["return", "loop", "__skip__"].includes(content.children[0].name)) {
45148
45157
  if (currentRuleHasVariableGoto) {
45149
45158
  content.parent.children.splice(content.parent.childIndex + 1, 0, content.children[0], getAstForUselessInstruction());
45150
45159
  }
@@ -45166,7 +45175,7 @@ astParsingFunctions.__if__ = function(content) {
45166
45175
  makeChildrenUseless(content.children);
45167
45176
  }
45168
45177
  }
45169
- if (content.parent.childIndex === content.parent.children.length - 1 || content.parent.childIndex < content.parent.children.length - 1 && !["__elif__", "__else__"].includes(content.parent.children[content.parent.childIndex + 1].name)) {
45178
+ if (isLoneIf) {
45170
45179
  var includeEnd = true;
45171
45180
  if (enableOptimization && currentRuleEvent !== "__subroutine__" && content.parent.childIndex === content.parent.children.length - 1) {
45172
45181
  var root = content;
@@ -45182,6 +45191,16 @@ astParsingFunctions.__if__ = function(content) {
45182
45191
  }
45183
45192
  }
45184
45193
  }
45194
+ if (optimizeForSize2 && optimizeForSizeAggressive && (content.args[0].name === "__not__" || content.children.length === 1 && includeEnd && ["__equals__", "__inequals__", "__greaterThan__", "__greaterThanOrEquals__", "__lessThan__", "__lessThanOrEquals__"].includes(content.args[0].name))) {
45195
+ let label = "__label_if_" + getUniqueNumber() + "__";
45196
+ content.parent.children.splice(content.parent.childIndex + 1, 0, ...content.children, new Ast2(label, [], [], "Label"), getAstForUselessInstruction());
45197
+ if (content.args[0].name === "__not__") {
45198
+ content.args[0] = content.args[0].args[0];
45199
+ } else {
45200
+ content.args[0] = astParsingFunctions.__not__(new Ast2("__not__", [content.args[0]]));
45201
+ }
45202
+ return new Ast2("__skipIf__", [content.args[0], new Ast2("__distanceTo__", [new Ast2(label, [], [], "Label")])]);
45203
+ }
45185
45204
  if (includeEnd) {
45186
45205
  content.parent.children.splice(content.parent.childIndex + 1, 0, getAstForEnd());
45187
45206
  }
@@ -45409,6 +45428,14 @@ astParsingFunctions.__negate__ = function(content) {
45409
45428
  };
45410
45429
 
45411
45430
  // src/compiler/functions/__not__.ts
45431
+ var inverseComparisonMapping = {
45432
+ "__equals__": "__inequals__",
45433
+ "__inequals__": "__equals__",
45434
+ "__greaterThan__": "__lessThanOrEquals__",
45435
+ "__greaterThanOrEquals__": "__lessThan__",
45436
+ "__lessThan__": "__greaterThanOrEquals__",
45437
+ "__lessThanOrEquals__": "__greaterThan__"
45438
+ };
45412
45439
  astParsingFunctions.__not__ = function(content) {
45413
45440
  if (enableOptimization) {
45414
45441
  if (isDefinitelyFalsy(content.args[0])) {
@@ -45426,6 +45453,9 @@ astParsingFunctions.__not__ = function(content) {
45426
45453
  if (content.args[0].name === ".isDead") {
45427
45454
  return new Ast2(".isAlive", [content.args[0].args[0]]);
45428
45455
  }
45456
+ if (content.args[0].name in inverseComparisonMapping) {
45457
+ return new Ast2(inverseComparisonMapping[content.args[0].name], content.args[0].args);
45458
+ }
45429
45459
  }
45430
45460
  return content;
45431
45461
  };
@@ -46845,16 +46875,18 @@ function compressToString(compressionInfo) {
46845
46875
  }
46846
46876
  function getDecompressionAst(compressedString, compressionInfo) {
46847
46877
  let { minDecimalPlace, maxDecimalPlace, offset, arrayType } = compressionInfo;
46878
+ let formulaAlphabet = useVariableForCompressionAlphabet ? "__compressionAlphabet__" : "x.last()";
46879
+ let formulaCompressedArray = useVariableForCompressionAlphabet ? `$compressedString.split(null[0])` : `[e.concat(${escapeString(alphabet2, false)}) for e in $compressedString.split(null[0])]`;
46848
46880
  if (arrayType === "number") {
46849
- let decompressionFormula = Array(Math.ceil((maxDecimalPlace - minDecimalPlace) / 2)).fill(0).map((x, i) => i).map((x) => `${Math.pow(100, x + minDecimalPlace / 2)}*x.last().strIndex(x[0].charAt(${x}))`).join(" + ");
46850
- return parseOpyMacro(`[${decompressionFormula} - ${offset} for x in [e.concat(${escapeString(alphabet2, false)}) for e in $compressedString.split(null[0])]]`, ["$compressedString"], [compressedString]);
46881
+ let decompressionFormula = Array(Math.ceil((maxDecimalPlace - minDecimalPlace) / 2)).fill(0).map((x, i) => i).map((x) => `${Math.pow(100, x + minDecimalPlace / 2)}*${formulaAlphabet}.strIndex(x.charAt(${x}))`).join(" + ");
46882
+ return parseOpyMacro(`[${decompressionFormula} - ${offset} for x in ${formulaCompressedArray}]`, ["$compressedString"], [compressedString]);
46851
46883
  } else {
46852
46884
  let decompressionFormulas = Array(3).fill(0).map((_, h) => {
46853
46885
  return Array(Math.ceil((maxDecimalPlace - minDecimalPlace) / 2)).fill(0).map((x, i) => i).map((x) => `
46854
- ${Math.pow(100, x + minDecimalPlace / 2)}*x.last().strIndex(x[0].charAt(${x + Math.ceil((maxDecimalPlace - minDecimalPlace) / 2) * h}))
46886
+ ${Math.pow(100, x + minDecimalPlace / 2)}*${formulaAlphabet}.strIndex(x.charAt(${x + Math.ceil((maxDecimalPlace - minDecimalPlace) / 2) * h}))
46855
46887
  `).join(" + ");
46856
46888
  });
46857
- return parseOpyMacro(`[vect(${decompressionFormulas[0]},${decompressionFormulas[2]},${decompressionFormulas[1]}) - vect(1,1,1)*${offset} for x in [e.concat(${escapeString(alphabet2, false)}) for e in $compressedString.split(null[0])]]`, ["$compressedString"], [compressedString]);
46889
+ return parseOpyMacro(`[vect(${decompressionFormulas[0]},${decompressionFormulas[2]},${decompressionFormulas[1]}) - vect(1,1,1)*${offset} for x in ${formulaCompressedArray}]`, ["$compressedString"], [compressedString]);
46858
46890
  }
46859
46891
  }
46860
46892
  astParsingFunctions.compressed = function(content) {
@@ -47983,9 +48015,6 @@ function parseAstRules(rules) {
47983
48015
  }
47984
48016
  rulesResult.push(parseAst(rule));
47985
48017
  }
47986
- setOptimizationEnabled2(true);
47987
- setOptimizeStrict2(false);
47988
- setOptimizationForSize2(false);
47989
48018
  return rulesResult;
47990
48019
  }
47991
48020
  function parseAst(content) {
@@ -59649,7 +59678,10 @@ var valueFuncKw = (
59649
59678
  {
59650
59679
  "name": "condition",
59651
59680
  "description": "The mapping expression that is evaluated for each element of the copied array. Use the current array element value to reference the element of the array currently being considered.",
59652
- "type": "bool"
59681
+ "type": [
59682
+ "Object",
59683
+ "Array"
59684
+ ]
59653
59685
  }
59654
59686
  ],
59655
59687
  "isConstant": true,
@@ -64618,7 +64650,7 @@ function astRulesToWs(rules) {
64618
64650
  result += "}\n\n";
64619
64651
  incrementNbElements();
64620
64652
  let ruleElements = nbElements - elementsBefore;
64621
- if (debugElementCount) {
64653
+ if (debugElementCount && ruleElements > 1) {
64622
64654
  let { filePath } = getRuleFilePath(rule.fileStack);
64623
64655
  ruleElementCounts.push({ name: oldRuleName, file: filePath, elements: ruleElements });
64624
64656
  result = "//" + ruleElements + " element" + (ruleElements !== 1 ? "s" : "") + "\n" + result;
@@ -64630,9 +64662,6 @@ function astRulesToWs(rules) {
64630
64662
  ruleElementCounts.sort((a, b) => b.elements - a.elements);
64631
64663
  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";
64632
64664
  }
64633
- setOptimizationEnabled2(true);
64634
- setOptimizeStrict2(false);
64635
- setOptimizationForSize2(false);
64636
64665
  return { compiledRules, elementCountSummary };
64637
64666
  }
64638
64667
  function astRuleConditionToWs(condition) {
@@ -64958,19 +64987,32 @@ function astToWs(content) {
64958
64987
  if (content.args.length === 0) {
64959
64988
  incrementNbElements();
64960
64989
  return tows("__emptyArray__", valueKw);
64961
- } else if (optimizeForSize2 && content.parent?.name !== "createWorkshopSettingEnum" && content.args.every((x) => x.name === "__customString__" && x.args.length === 1)) {
64962
- let separator = "\uEC51";
64963
- let separatorAst = getAstForCustomString(separator);
64964
- let str = content.args.map((x) => x.args[0].name).join(separator);
64965
- if (!str.includes("0")) {
64966
- separator = "0";
64967
- separatorAst = new Ast2("__firstOf__", [getAstForNull()]);
64968
- } 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) {
64969
- separator = "(1.00, 0.00, 0.00)";
64970
- separatorAst = new Ast2("__firstOf__", [new Ast2("Vector.LEFT")]);
64971
- }
64972
- str = str.replaceAll("\uEC51", separator);
64973
- return astToWs(new Ast2(".split", [getAstForCustomString(str), separatorAst]));
64990
+ } else if (optimizeForSize2 && optimizeForSizeAggressive && content.parent?.name !== "createWorkshopSettingEnum") {
64991
+ if (content.args.every((x) => x.name === "__customString__" && x.args.length === 1)) {
64992
+ let separator = "\uEC51";
64993
+ let separatorAst = getAstForCustomString(separator);
64994
+ let str = content.args.map((x) => x.args[0].name).join(separator);
64995
+ if (!str.includes("0")) {
64996
+ separator = "0";
64997
+ separatorAst = new Ast2("__firstOf__", [getAstForNull()]);
64998
+ } 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) {
64999
+ separator = "(1.00, 0.00, 0.00)";
65000
+ separatorAst = new Ast2("__firstOf__", [new Ast2("Vector.LEFT")]);
65001
+ }
65002
+ str = str.replaceAll("\uEC51", separator);
65003
+ return astToWs(new Ast2(".split", [getAstForCustomString(str), separatorAst]));
65004
+ } else if (content.args.length >= 3 && content.args.every((x) => areAstsAlwaysEqual(x, content.args[0]))) {
65005
+ let estimatedElementCount = 1 + (content.args[0].name === "__customString__" ? 4 : content.args[0].args.length);
65006
+ if (estimatedElementCount === 1 && content.args.length >= 11 || estimatedElementCount === 2 && content.args.length >= 5 || estimatedElementCount === 3 && content.args.length >= 4 || estimatedElementCount >= 4) {
65007
+ return astToWs(new Ast2("__mappedArray__", [
65008
+ new Ast2(".split", [
65009
+ getAstForCustomString("0".repeat(content.args.length - 1)),
65010
+ new Ast2("__firstOf__", [getAstForNull()])
65011
+ ]),
65012
+ content.args[0]
65013
+ ]));
65014
+ }
65015
+ }
64974
65016
  }
64975
65017
  } else if (content.name === "chaseAtRate" || content.name === "chaseOverTime") {
64976
65018
  var newName = content.name === "chaseAtRate" ? "AtRate__" : "OverTime__";
@@ -65636,6 +65678,9 @@ async function compile(content, language = "en-US", _rootPath = "", _mainFileNam
65636
65678
  if (replacementForEmptyString === "variable") {
65637
65679
  addVariable("__emptyString__", true, -1, getInternalFileStack(), tokenize("[].charAt(null)")[0].tokens);
65638
65680
  }
65681
+ if (useVariableForCompressionAlphabet) {
65682
+ addVariable("__compressionAlphabet__", true, -1, getInternalFileStack(), tokenize(escapeString(alphabet2, false))[0].tokens);
65683
+ }
65639
65684
  if (translationLanguages2.length > 0) {
65640
65685
  setTranslatedStrings(importFromPoFiles());
65641
65686
  }
@@ -65787,7 +65832,13 @@ function compileRules(astRules) {
65787
65832
  if (DEBUG_MODE) {
65788
65833
  console.log(parsedAstRules);
65789
65834
  }
65835
+ setOptimizationEnabled2(true);
65836
+ setOptimizeStrict2(false);
65837
+ setOptimizationForSize2(false);
65790
65838
  var { compiledRules, elementCountSummary } = astRulesToWs(parsedAstRules);
65839
+ setOptimizationEnabled2(true);
65840
+ setOptimizeStrict2(false);
65841
+ setOptimizationForSize2(false);
65791
65842
  setFileStack(getInternalFileStack());
65792
65843
  var result = elementCountSummary + compiledCustomGameSettings;
65793
65844
  if (!excludeVariablesInCompilation) {
@@ -66616,7 +66667,7 @@ function parseLines(lines) {
66616
66667
  }
66617
66668
  }
66618
66669
  let enumMemberName = childrenLines[k].tokens[0].toString();
66619
- if (enumMemberName in enumMembers[args[0].name]) {
66670
+ if (enumMemberName in enumMembers[args[0].name] && !allowMacroRedeclaration) {
66620
66671
  error("Duplicate enum member '" + args[0].name + "." + enumMemberName + "''");
66621
66672
  }
66622
66673
  enumMembers[args[0].name][enumMemberName] = enumValue;
@@ -69106,7 +69157,7 @@ Wrapping a string with \`___\` has the same caveats as putting a translated stri
69106
69157
  return: "String"
69107
69158
  },
69108
69159
  "compressed": {
69109
- "description": "Compresses in-place the specified array of numbers or vectors into a string, then returns the decompressed array. Strings take much fewer elements, so use this function if you are running out of elements.\n\nNote that numbers will get rounded to 3 decimal places, and vectors to 2 decimal places.\n\nThis function is only effective once the array has at least 18 vectors or 26 numbers.\n\nThis function can be more effective than `compress()` and `decompressNumbers()` / `decompressVectors()`, as it can apply optimizations if all numbers have a low amount of significant digits or if they are all positive.",
69160
+ "description": "Compresses in-place the specified array of numbers or vectors into a string, then returns the decompressed array. Strings take much fewer elements, so use this function if you are running out of elements.\n\nNote that numbers will get rounded to 3 decimal places, and vectors to 2 decimal places.\n\nThis function is only effective once the array has at least 5 vectors or 7 numbers (depending on the complexity; use `#!debugElementCount` to compare).\n\nThis function can be more effective than `compress()` and `decompressNumbers()` / `decompressVectors()`, as it can apply optimizations if all numbers have a low amount of significant digits or if they are all positive.",
69110
69161
  "args": [
69111
69162
  {
69112
69163
  "name": "array",
@@ -69635,6 +69686,8 @@ var enableOptimization;
69635
69686
  var setOptimizationEnabled2 = (enabled) => enableOptimization = enabled;
69636
69687
  var optimizeForSize2;
69637
69688
  var setOptimizationForSize2 = (size) => optimizeForSize2 = size;
69689
+ var optimizeForSizeAggressive;
69690
+ var setOptimizationForSizeAggressive = (aggressive) => optimizeForSizeAggressive = aggressive;
69638
69691
  var optimizeStrict;
69639
69692
  var setOptimizeStrict2 = (strict) => optimizeStrict = strict;
69640
69693
  var macros = [];
@@ -69721,6 +69774,8 @@ var rulePrefixTemplate = "";
69721
69774
  var setRulePrefixTemplate = (template) => rulePrefixTemplate = template;
69722
69775
  var rulePrefixTemplateFilestack = [];
69723
69776
  var setRulePrefixTemplateFilestack = (filestack) => rulePrefixTemplateFilestack = filestack;
69777
+ var useVariableForCompressionAlphabet = false;
69778
+ var setUseVariableForCompressionAlphabet = (use) => useVariableForCompressionAlphabet = use;
69724
69779
  var decompilerGotos;
69725
69780
  var resetDecompilerGotos = () => decompilerGotos = [];
69726
69781
  var nbTabs;
@@ -69763,6 +69818,7 @@ function resetGlobalVariables(language) {
69763
69818
  compiledCustomGameSettings = "";
69764
69819
  enableOptimization = true;
69765
69820
  optimizeForSize2 = false;
69821
+ optimizeForSizeAggressive = false;
69766
69822
  optimizeStrict = false;
69767
69823
  uniqueNumber = 1;
69768
69824
  globalInitDirectives = [];
@@ -69800,6 +69856,7 @@ function resetGlobalVariables(language) {
69800
69856
  currentRulePrefix = "";
69801
69857
  rulePrefixTemplate = "";
69802
69858
  rulePrefixTemplateFilestack = [];
69859
+ useVariableForCompressionAlphabet = false;
69803
69860
  }
69804
69861
  var operatorPrecedence = {
69805
69862
  "=": 1,
@@ -72079,10 +72136,10 @@ var key;
72079
72136
  // src/data/opy/preprocessing.ts
72080
72137
  var preprocessingDirectives = {
72081
72138
  "allowMacroRedeclaration": {
72082
- "description": "If enabled, redefining a `macro` or `#!define` 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."
72139
+ "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."
72083
72140
  },
72084
72141
  "define": {
72085
- "description": '**Warning**: This directive performs a text-based replacement! Use `macro` or `const` 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',
72142
+ "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',
72086
72143
  "snippet": "define $0"
72087
72144
  },
72088
72145
  "debugElementCount": {
@@ -72110,13 +72167,16 @@ var preprocessingDirectives = {
72110
72167
  "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)."
72111
72168
  },
72112
72169
  "disableOptimizations": {
72113
- "description": "Disables all optimizations done by the compiler for the current block or file, up until the end of the block/file or the next `#!enableOptimizations` directive."
72170
+ "description": "Disables all optimizations done by the compiler for the current block, up until the end of the block or the next `#!enableOptimizations` directive."
72114
72171
  },
72115
72172
  "enableOptimizations": {
72116
72173
  "description": "Re-enables optimizations after a `#!disableOptimizations` directive. If no `#!disableOptimizations` directive was encountered, this directive does nothing."
72117
72174
  },
72118
72175
  "optimizeForSize": {
72119
- "description": "Prioritizes lowering the number of elements over optimizing the runtime. Effective for the current block or file, up until the end of the block/file or the next `#!disableOptimizeForSize` directive."
72176
+ "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."
72177
+ },
72178
+ "optimizeForSizeAggressive": {
72179
+ "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."
72120
72180
  },
72121
72181
  "disableOptimizeForSize": {
72122
72182
  "description": "Re-enables optimizations after a `#!optimizeForSize` directive. If no `#!optimizeForSize` directive was encountered, this directive does nothing."
@@ -72132,7 +72192,7 @@ Those optimizations (and others) will be disabled so that the behavior of the ga
72132
72192
 
72133
72193
  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.
72134
72194
 
72135
- This directive is effective for the current block or file, up until the end of the block/file or the next \`#!disableOptimizeStrict\` directive.`
72195
+ This directive is effective for the current block, up until the end of the block or the next \`#!disableOptimizeStrict\` directive.`
72136
72196
  },
72137
72197
  "disableOptimizeStrict": {
72138
72198
  "description": "Re-enables optimizations after a `#!optimizeStrict` directive. If no `#!optimizeStrict` directive was encountered, this directive does nothing."
@@ -72262,6 +72322,9 @@ You can specify \`noDetectionRule\` to not create the rule which sets the variab
72262
72322
  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.
72263
72323
  `
72264
72324
  },
72325
+ "useVariableForCompressionAlphabet": {
72326
+ "description": `If enabled, the compression functions will use a global variable \`__compressionAlphabet__\` instead of a hardcoded string for the alphabet, which will save further elements.`
72327
+ },
72265
72328
  "extension": {
72266
72329
  "description": "You shouldn't be reading this. Contact Zezombye if you can see this.",
72267
72330
  "snippet": "You shouldn't be reading this. Contact Zezombye if you can see this."
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "url": "https://github.com/Zezombye/overpy"
8
8
  },
9
9
  "description": "High-level language for the Overwatch Workshop, with decompilation and compilation.",
10
- "version": "9.6.2",
10
+ "version": "9.6.4",
11
11
  "readme": "README.md",
12
12
  "keywords": [
13
13
  "overpy",