https://wiki.kolmafia.us/api.php?action=feedcontributions&user=Philmasterplus&feedformat=atomKolmafia - User contributions [en]2024-03-29T10:02:32ZUser contributionsMediaWiki 1.35.0https://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9106JavaScript Support2021-08-31T13:49:42Z<p>Philmasterplus: /* Code Checking */ Update ESLint config</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Object destructuring in assignments (variable declarations are OK)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Shorthand property names (in object literals)<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia, and prevents ESLint from complaining about KoLmafia builtins.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"globals": {<br />
"Promise": "off",<br />
"Proxy": "off",<br />
"Reflect": "off",<br />
"Bounty": "readonly",<br />
"Class": "readonly",<br />
"Coinmaster": "readonly",<br />
"Effect": "readonly",<br />
"Element": "readonly",<br />
"Familiar": "readonly",<br />
"Item": "readonly",<br />
"Location": "readonly",<br />
"Monster": "readonly",<br />
"Phylum": "readonly",<br />
"Servant": "readonly",<br />
"Skill": "readonly",<br />
"Slot": "readonly",<br />
"Stat": "readonly",<br />
"Thrall": "readonly"<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-syntax": [<br />
"error",<br />
{<br />
"selector": "AssignmentExpression > ObjectPattern",<br />
"message": "Rhino does not support object destructuring in assignments (variable declarations are OK)"<br />
},<br />
{<br />
"selector": "AssignmentPattern",<br />
"message": "Rhino does not support default values for function parameters and array/object destructuring"<br />
},<br />
{<br />
"selector": "ClassDeclaration, ClassExpression",<br />
"message": "Rhino does not support ES2015 classes"<br />
},<br />
{<br />
"selector": ":matches(ForInStatement, ForOfStatement, ForStatement) > VariableDeclaration[kind=const]",<br />
"message": "Rhino does not support const declarations in the head of for-loops"<br />
},<br />
{<br />
"selector": "ObjectExpression > Property[shorthand=true]",<br />
"message": "Rhino does not support shorthand object properties"<br />
},<br />
{<br />
"selector": "Property[computed=true]",<br />
"message": "Rhino does not support computed object properties"<br />
},<br />
{<br />
"selector": "RestElement, SpreadElement",<br />
"message": "Rhino does not support spread/rest syntax"<br />
},<br />
{<br />
"selector": "TemplateLiteral",<br />
"message": "Rhino does not support template string literals"<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9105JavaScript Support2021-08-11T08:28:33Z<p>Philmasterplus: /* Code Checking */ Update ESLint config</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Object destructuring in assignments (variable declarations are OK)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Shorthand property names (in object literals)<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia, and prevents ESLint from complaining about KoLmafia builtins.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"globals": {<br />
"Promise": "off",<br />
"Proxy": "off",<br />
"Reflect": "off",<br />
"Bounty": "readonly",<br />
"Class": "readonly",<br />
"Coinmaster": "readonly",<br />
"Effect": "readonly",<br />
"Element": "readonly",<br />
"Familiar": "readonly",<br />
"Item": "readonly",<br />
"Location": "readonly",<br />
"Monster": "readonly",<br />
"Phylum": "readonly",<br />
"Servant": "readonly",<br />
"Skill": "readonly",<br />
"Slot": "readonly",<br />
"Stat": "readonly",<br />
"Thrall": "readonly"<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-syntax": [<br />
"error",<br />
{<br />
"selector": "AssignmentExpression > ObjectPattern",<br />
"message": "Rhino does not support object destructuring in assignments (variable declarations are OK)"<br />
},<br />
{<br />
"selector": "AssignmentPattern",<br />
"message": "Rhino does not support default values for function parameters and array/object destructuring"<br />
},<br />
{<br />
"selector": "ClassDeclaration, ClassExpression",<br />
"message": "Rhino does not support ES2015 classes"<br />
},<br />
{<br />
"selector": ":matches(ForInStatement, ForOfStatement, ForStatement) > VariableDeclaration[kind=const]",<br />
"message": "Rhino does not support const declarations in the head of for-loops"<br />
},<br />
{<br />
"selector": "ObjectExpression > Property[shorthand=true]",<br />
"message": "Rhino does not support shorthand object properties"<br />
},<br />
{<br />
"selector": "Property[computed=true]",<br />
"message": "Rhino does not support computed object properties"<br />
},<br />
{<br />
"selector": "RestElement",<br />
"message": "Rhino does not support spread/rest syntax"<br />
},<br />
{<br />
"selector": "TemplateLiteral",<br />
"message": "Rhino does not support template string literals"<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9104JavaScript Support2021-08-10T11:10:40Z<p>Philmasterplus: /* Code Checking */ Update ESLint config</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Object destructuring in assignments (variable declarations are OK)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Shorthand property names (in object literals)<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia, and prevents ESLint from complaining about KoLmafia builtins.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"globals": {<br />
"Promise": "off",<br />
"Proxy": "off",<br />
"Reflect": "off",<br />
"Bounty": "readonly",<br />
"Class": "readonly",<br />
"Coinmaster": "readonly",<br />
"Effect": "readonly",<br />
"Element": "readonly",<br />
"Familiar": "readonly",<br />
"Item": "readonly",<br />
"Location": "readonly",<br />
"Monster": "readonly",<br />
"Phylum": "readonly",<br />
"Servant": "readonly",<br />
"Skill": "readonly",<br />
"Slot": "readonly",<br />
"Stat": "readonly",<br />
"Thrall": "readonly"<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-syntax": [<br />
"error",<br />
{<br />
"selector": "AssignmentExpression > ObjectPattern",<br />
"message": "Rhino does not support object destructuring in assignments (variable declarations are OK)"<br />
},<br />
{<br />
"selector": "AssignmentPattern",<br />
"message": "Rhino does not support default values for function parameters and array/object destructuring"<br />
},<br />
{<br />
"selector": "ClassDeclaration, ClassExpression",<br />
"message": "Rhino does not support ES2015 classes"<br />
},<br />
{<br />
"selector": "ObjectExpression > Property[shorthand=true]",<br />
"message": "Rhino does not support shorthand object properties"<br />
},<br />
{<br />
"selector": "Property[computed=true]",<br />
"message": "Rhino does not support computed object properties"<br />
},<br />
{<br />
"selector": "RestElement",<br />
"message": "Rhino does not support spread/rest syntax"<br />
},<br />
{<br />
"selector": "TemplateLiteral",<br />
"message": "Rhino does not support template string literals"<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9103JavaScript Support2021-08-10T08:36:21Z<p>Philmasterplus: Shorthand properties are not supported yet!</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Shorthand property names (in object literals)<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia, and prevents ESLint from complaining about KoLmafia builtins.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"globals": {<br />
"Promise": "off",<br />
"Proxy": "off",<br />
"Reflect": "off",<br />
"Bounty": "readonly",<br />
"Class": "readonly",<br />
"Coinmaster": "readonly",<br />
"Effect": "readonly",<br />
"Element": "readonly",<br />
"Familiar": "readonly",<br />
"Item": "readonly",<br />
"Location": "readonly",<br />
"Monster": "readonly",<br />
"Phylum": "readonly",<br />
"Servant": "readonly",<br />
"Skill": "readonly",<br />
"Slot": "readonly",<br />
"Stat": "readonly",<br />
"Thrall": "readonly"<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-syntax": [<br />
"error",<br />
{<br />
"selector": "AssignmentPattern",<br />
"message": "Rhino does not support default values for function parameters and array/object destructuring"<br />
},<br />
{<br />
"selector": "ClassDeclaration, ClassExpression",<br />
"message": "Rhino does not support ES2015 classes"<br />
},<br />
{<br />
"selector": "ObjectExpression > Property[shorthand=true]",<br />
"message": "Rhino does not support shorthand object properties"<br />
},<br />
{<br />
"selector": "Property[computed=true]",<br />
"message": "Rhino does not support computed object properties"<br />
},<br />
{<br />
"selector": "RestElement",<br />
"message": "Rhino does not support spread/rest syntax"<br />
},<br />
{<br />
"selector": "TemplateLiteral",<br />
"message": "Rhino does not support template string literals"<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9102JavaScript Support2021-08-10T07:21:30Z<p>Philmasterplus: /* Code Checking */ Update ESLint config</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia, and prevents ESLint from complaining about KoLmafia builtins.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"globals": {<br />
"Promise": "off",<br />
"Proxy": "off",<br />
"Reflect": "off",<br />
"Bounty": "readonly",<br />
"Class": "readonly",<br />
"Coinmaster": "readonly",<br />
"Effect": "readonly",<br />
"Element": "readonly",<br />
"Familiar": "readonly",<br />
"Item": "readonly",<br />
"Location": "readonly",<br />
"Monster": "readonly",<br />
"Phylum": "readonly",<br />
"Servant": "readonly",<br />
"Skill": "readonly",<br />
"Slot": "readonly",<br />
"Stat": "readonly",<br />
"Thrall": "readonly"<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-syntax": [<br />
"error",<br />
{<br />
"selector": "AssignmentPattern",<br />
"message": "Rhino does not support default values for function parameters and array/object destructuring"<br />
},<br />
{<br />
"selector": "ClassDeclaration, ClassExpression",<br />
"message": "Rhino does not support ES2015 classes"<br />
},<br />
{<br />
"selector": "Property[computed=true]",<br />
"message": "Rhino does not support computed object properties"<br />
},<br />
{<br />
"selector": "RestElement",<br />
"message": "Rhino does not support spread/rest syntax"<br />
},<br />
{<br />
"selector": "TemplateLiteral",<br />
"message": "Rhino does not support template string literals"<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9101JavaScript Support2021-08-10T06:56:04Z<p>Philmasterplus: /* Code Checking */ Update ESLint config</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia, and prevents ESLint from complaining about KoLmafia builtins.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"globals": {<br />
"Promise": "off",<br />
"Proxy": "off",<br />
"Reflect": "off",<br />
"Bounty": "readonly",<br />
"Class": "readonly",<br />
"Coinmaster": "readonly",<br />
"Effect": "readonly",<br />
"Element": "readonly",<br />
"Familiar": "readonly",<br />
"Item": "readonly",<br />
"Location": "readonly",<br />
"Monster": "readonly",<br />
"Phylum": "readonly",<br />
"Servant": "readonly",<br />
"Skill": "readonly",<br />
"Slot": "readonly",<br />
"Stat": "readonly",<br />
"Thrall": "readonly"<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-syntax": [<br />
"error",<br />
"AssignmentPattern",<br />
"ClassDeclaration",<br />
"ClassExpression",<br />
"RestElement",<br />
"TemplateLiteral"<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9100JavaScript Support2021-08-10T06:22:28Z<p>Philmasterplus: </p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Code Checking ==<br />
<br />
You can set up [https://eslint.org/ ESLint] to check your code for errors.<br />
<br />
The following ESLint configuration (<code>.eslintrc.json</code>) checks if your JavaScript code uses features unsupported by KoLmafia.<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"env": {<br />
"commonjs": true,<br />
"es6": true<br />
},<br />
"parserOptions": {<br />
"ecmaVersion": 6<br />
},<br />
"rules": {<br />
"no-restricted-globals": ["error", "Promise", "Proxy", "Reflect"],<br />
"no-restricted-syntax": [<br />
"error",<br />
"AssignmentPattern",<br />
"ClassDeclaration",<br />
"ClassExpression",<br />
"RestElement",<br />
"TemplateLiteral"<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note that this is unnecessary if you use a transpiler to convert modern JavaScript code to Rhino-compatible syntax.<br />
<br />
== Transpiling ==<br />
<br />
Various tools as Babel, Webpack, and TypeScript can convert modern JavaScript code (or another programming language) to legacy syntax supported by Rhino. These tools are called "transpilers". These tools allow you to enjoy the convenience and safety of modern language features, while still generating code that runs on KoLmafia.<br />
<br />
=== [https://babeljs.io/ Babel] ===<br />
<br />
Babel 7.15.0 supports Rhino as a compilation target.<br />
<br />
The following config file (<code>babel.config.json</code>) will convert modern JavaScript syntax to Rhino-compatible ES5+:<br />
<br />
<syntaxhighlight lang="json"><br />
{<br />
"presets": [<br />
[<br />
"@babel/preset-env",<br />
{<br />
"modules": false,<br />
"targets": {<br />
"rhino": "1.7.13"<br />
}<br />
}<br />
]<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== [https://www.typescriptlang.org/ TypeScript] ===<br />
<br />
TypeScript is a statically typed programming language that can be transpiled to JavaScript.<br />
<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=JavaScript_Support&diff=9099JavaScript Support2021-08-10T05:04:54Z<p>Philmasterplus: Add unsupported syntax</p>
<hr />
<div>As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported, too! '''This support is still experimental - you have been warned.'''<br />
<br />
== Basics ==<br />
<br />
=== Library Functions ===<br />
All functions in the ASH runtime library are available inside the built-in <code>kolmafia</code> module. To use these functions, you must use the <code>require()</code> function to import them:<br />
<br />
<syntaxhighlight lang="js"><br />
const { print, myName() } = require("kolmafia");<br />
print("Hello, " + myName());<br />
<br />
// Alternative<br />
const kolmafia = require("kolmafia");<br />
kolmafia.print("Hello, " + kolmafia.myName());<br />
</syntaxhighlight><br />
<br />
The <code>require()</code> function is usually called once at the top of the script.<br />
<br />
Names of ASH functions are converted to [[wikipedia:CamelCase|camelCase]]. For example, {{f|print_html}} in ASH becomes <code>printHtml()</code> in JavaScript:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | ASH<br />
! style="width: 50%" | JavaScript<br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="d"><br />
print_html("<b>Some text</b>");<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { printHtml } = require("kolmafia");<br />
print("<b>Some text</b>");<br />
</syntaxhighlight><br />
|}<br />
<br />
When directly executing inline JavaScript code with the <code>js</code> or <code>jsq</code> commands, all library functions are already imported for you, so you don't have to import them:<br />
<br />
> js print("My name is " + myName())<br />
My name is <playername><br />
<br />
=== Importing and Exporting ===<br />
KoLmafia uses the [[wikipedia:CommonJS|CommonJS]] module system, similar to [[wikipedia:Node.js|Node.js]]. You can export functions and values from one JavaScript file and import them from another JavaScript file:<br />
<br />
{| class="wikitable"<br />
! style="width: 50%" | <code>source.js</code><br />
! style="width: 50%" | <code>runner.js</code><br />
|- style="vertical-align: top"<br />
|<br />
<syntaxhighlight lang="js"><br />
const { print } = require("kolmafia");<br />
module.exports.hello = function hello() {<br />
print("Hello, world!");<br />
};<br />
</syntaxhighlight><br />
|<br />
<syntaxhighlight lang="js"><br />
const { hello } = require("./source.js");<br />
hello();<br />
</syntaxhighlight><br />
|}<br />
<br />
Check out [https://flaviocopes.com/commonjs/ this guide] for more examples.<br />
<br />
You can export a function named <code>main()</code> to run it only when the script is invoked directly. When your script is imported by another script, the <code>main()</code> function will be ignored.<br />
<br />
You can also import ASH scripts from JavaScript code. For details, see [[JavaScript Support#ASH_and_JavaScript_Interoperability|ASH and JavaScript Interoperability]].<br />
<br />
=== Data Type Classes ===<br />
All [[Data Types#Special Datatypes|enumerated data types]] in ASH are available as classes in JavaScript. For example, {{type|monster}} is available as the <code>Monster</code> class, and {{type|item}} is available as the <code>Item</code> class.<br />
<br />
Each enumerated class has the following static methods:<br />
<br />
* <code><ClassName>.get()</code> takes a number or string and returns an object of the class.<br />
** For example, <code>Monster.get("fiendish can of asparagus")</code> is equivalent to <code>$monster[ fiendish can of asparagus ]</code> in ASH. <code>Item.get(1)</code> is equivalent to <code>$item[ 1 ]</code>.<br />
** This also accepts string representations of integers. For example, <code>Item.get(5)</code> and <code>Item.get("5")</code> return the same result.<br />
* <code><ClassName>.get()</code> can also take an array of numbers and strings, and return an array of objects.<br />
** For example, <code>Item.get(["seal-clubbing club", "pail", 5])</code> is similar to <code>$items[ seal-clubbing club, pail, 5 ]</code> in ASH. However, the JavaScript version returns an array of objects, instead of a boolean map.<br />
** Passing an empty array returns an empty array (i.e. <code>Item.get([])</code> is ''not'' the same as <code>$items[]</code>).<br />
* <code><ClassName>.all()</code> takes no argument and returns all possible values of the class.<br />
** For example, <code>Monster.all()</code> returns an array of all known monsters. This is similar to <code>$monsters[]</code> in ASH.<br />
<br />
Enumerated objects support the <code>toString()</code> method, which acts like the {{f|to_string}} ASH function.<br />
<br />
To retrieve the numeric ID of enumerated objects, use the {{f|to_int|toInt}} library function:<br />
<br />
<syntaxhighlight lang="js"><br />
let item = Item.get("filthy lucre");<br />
let itemId = toInt(item);<br />
</syntaxhighlight><br />
<br />
=== Other ===<br />
* ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.<br />
* You can look at the type reference for the JS version of the ASH runtime library with <code>jsref</code>, which works just like <code>ashref</code>.<br />
<br />
== ASH and JavaScript Interoperability ==<br />
<br />
JavaScript scripts can <code>require()</code> ASH scripts and use their functions. When an ASH script is <code>require()</code>-ed by JavaScript code, KoLmafia will execute top-level code, but only export functions in the top-level scope. ASH variables are not exported.<br />
<br />
For example, you can use [[Zlib]] if it is installed:<br />
<br />
<syntaxhighlight lang="js" line><br />
const { getvar } = require("zlib.ash");<br />
let myvar = getvar("SOME_VAR_NAME");<br />
</syntaxhighlight><br />
<br />
ASH scripts cannot <code>import</code> JavaScript scripts.<br />
<br />
== JavaScript Version and Features ==<br />
KoLmafia uses the [[wikipedia:Rhino (JavaScript engine)|Rhino]] engine to execute JavaScript code. Rhino supports an older version of JavaScript called "ES5", plus some features from newer versions. This means that many JavaScript features that work in web browsers might not work in KoLmafia.<br />
<br />
Here is an incomplete list of post-ES5 features supported by Rhino ([https://kolmafia.us/threads/javascript-bugs.25638/post-160384 source]):<br />
<br />
=== Supported ===<br />
* Syntax<br />
** <code>let</code> and (partially) <code>const</code><br />
*** Does not support block-level scoping or temporal dead zones, meaning that you cannot use <code>const</code> for loop variables. <code>for (const a in obj) { ... }</code> is a syntax error.<br />
** Array/object destructuring (but spread/rest syntax (<code>...</code>) is ''not'' supported)<br />
** <code>for...of</code> loop<br />
** Arrow functions: <code>() => {}</code><br />
** Octal and binary literals<br />
* Features<br />
** Symbol<br />
** Set, Map, WeakSet, WeakMap<br />
** ES2015 methods in Array, Math, Number, Object, String<br />
** <code>Array.prototype.includes()</code><br />
** <code>String.prototype.padStart()/padEnd()/trimStart()/trimEnd()</code><br />
** TypedArray: Can be constructed, but most TypedArray-specific methods are unavailable.<br />
<br />
=== Unsupported ===<br />
* Syntax<br />
** Spread/rest syntax (<code>...</code>)<br />
** Template string literals: Backtick string literals (<code>``</code>) are not a syntax error, but are treated as plain string literals.<br />
** Classes<br />
** ECMAScript modules (<code>import</code>/<code>export</code>)<br />
** Default function parameters<br />
** Computed property names<br />
** Exponentiation operator (<code>**</code>)<br />
** Async/Await<br />
** Trailing commas in function definitions (oddly, trailing commas are supported in function ''calls'')<br />
* Features<br />
** Promise<br />
** Proxy<br />
** Reflect<br />
<br />
=== Other ===<br />
Most JavaScript globals available in browsers and/or server-side environments like Node.js are ''not'' available. This includes <code>alert()</code>, <code>console.log()</code>, and <code>setTimeout()</code>.<br />
<br />
== Transpiling ==<br />
<br />
Folks with experience doing JavaScript web development are likely well-acquainted with tools such as Babel, Webpack, and TypeScript. These tools allow you to write modern JavaScript code. and can transpile the code down to an older version of JS supported by a particular engine. That approach works well with Rhino.<br />
<br />
* Babel: As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.<br />
<br />
=== TypeScript ===<br />
If you use TypeScript without Babel, you can set the <code>[https://www.typescriptlang.org/tsconfig#target target]</code> to <kbd>"ES5"</kbd>.<br />
<br />
TypeScript does not provide [[wikipedia:Polyfill (programming)|polyfills]] for modern JavaScript APIs missing in Rhino. To use them, you must supply your own.<br />
<br />
To avoid accidentally using any missing APIs, we recommend using the following configuration for your <code>tsconfig.json</code>:<br />
<br />
<syntaxhighlight lang="js"><br />
{<br />
"compilerOptions": {<br />
// JavaScript APIs supported by Rhino 1.7.13<br />
// See https://mozilla.github.io/rhino/compat/engines.html for more info<br />
"lib": [<br />
"ES5",<br />
"ES2015.Collection",<br />
"ES2015.Core",<br />
"ES2015.Generator",<br />
"ES2015.Iterable",<br />
"ES2015.Symbol",<br />
"ES2015.Symbol.WellKnown",<br />
"ES2016.Array.Include",<br />
"ES2017.String",<br />
"ES2019.String"<br />
],<br />
// Rhino uses require() instead of import/export<br />
// Note: If you use Webpack or Rollup, change this to "ES2015"<br />
"module": "CommonJS",<br />
// Rhino supports ES5+<br />
// Note: If you use Babel with TypeScript, change this to "ESNext"<br />
"target": "ES5"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
If you use a bundler such as [https://webpack.js.org/ Webpack] or [https://rollupjs.org/ Rollup], you should change the <code>module</code> to <kbd>"ES2015"</kbd>, and let the bundlers convert your code to CommonJS.<br />
<br />
== History ==<br />
* [https://kolmafia.us/threads/20520-this-is-a-big-patch-to-set-up-consult-scripts-lifecycle-scripts-choiceadventurescript.25660/ r20520]: Lifecycle scripts now support JavaScript.<br />
* [https://kolmafia.us/threads/20620-remove-valueof-as-per-philmasterplus.25845/ r20620]: Enumerated objects no longer provide a custom <code>valueOf()</code> method. Use {{f|to_int|toInt}} instead.<br />
* [https://kolmafia.us/threads/20780-javascript-runtime-no-longer-interrupts-when-library-functions-return-false.26174/ r20780]: When calling ASH runtime library functions from JavaScript, functions that return a {{type|boolean}} will return <code>false</code> on failure instead of throwing a string as an exception.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=IntelliJ_Setup&diff=9098IntelliJ Setup2021-08-02T09:43:49Z<p>Philmasterplus: Update guide, adding screenshots from IntelliJ IDEA 2021.2 Community edition</p>
<hr />
<div>[https://www.jetbrains.com/idea/ IntelliJ IDEA] is an IDE for developing Java applications. This guide assumes that you have a recent enough version of Java JDK, Ant, and IntelliJ IDEA. Completing [[Compiling from Source]] is a requirement for this guide, although experienced developers can skip to whatever step is appropriate.<br />
<br />
The following instructions are based on IntelliJ IDEA 2021.2 Community Edition. Instructions for other versions/editions of IntelliJ may be slightly different.<br />
<br />
== Create a Project ==<br />
=== Choice 1: Create a new project ===<br />
''If you already have a working copy of KoLmafia's source code, you can go to choice 2 instead.''<br />
<br />
# Start IntelliJ IDEA. In the ''Welcome to IntelliJ IDEA'' dialog, click '''Get from VCS'''.<br>[[File:Intellij-setup-c2021.2-welcome.png|300px]]<br />
# In the ''Get from Version Control'' dialog, select the '''Repository URL''' tab.<br />
## In ''Version control'', select '''Subversion'''.<br>[[File:Intellij-setup-c2021.2-get-from-vcs.png|300px]]<br />
## Add a new repository location. To do so, click the '''+''' button next to ''Repositories''.<br>[[File:Intellij-setup-c2021.2-get-from-vcs-subversion.png|300px]]<br />
### In the ''New Repository Location'' popup, enter the URL to KoLmafia's Subversion repository. Currently, this is https://svn.code.sf.net/p/kolmafia/code.<br>[[File:Intellij-setup-c2021.2-new-repository-location.png|200px]]<br />
### Click '''OK''' to close the popup.<br />
## Once the repository has been added, '''click the repository URL to highlight it''', then click '''Check Out'''.<br>[[File:Intellij-setup-c2021.2-get-from-vcs-check-out.png|300px]]<br />
# If the ''Destination Directory'' popup appears, choose a directory to check out the working copy.<br>''Caution'': Don't choose a common directory like <samp>C:\Users\&lt;username&gt;\Documents</samp>. Instead, create a new directory under it (by clicking the folder icon) and give it an appropriate name (e.g. <samp>kolmafia</samp>).<br>[[File:Intellij-setup-c2021.2-choose-working-copy-dir.png|200px]]<br>Click '''OK''' to continue.<br />
# If the ''SVN Checkout Options'' popup appears, leave everything as-is and click '''OK'''.<br />
# If the ''Subversion Working Copy Format'' popup appears, choose the latest version (which is <samp>1.8 format</samp> as of writing) and click '''OK'''.<br />
# IntelliJ will generate a new project. If it asks you whether to add <code>kolmafia.iml</code> to Subversion, you may click '''Cancel''' to skip it.<br />
<br />
=== Choice 2: Load an existing working copy into IntelliJ ===<br />
# From the IntelliJ IDEA '''File''' Menu, choose '''New'''>'''New Project from Existing Sources...'''<br />
#Choose the directory with the kolmafia build.xml file and press '''Open'''<br />
#Choose '''Create Project from Existing Sources''' and press '''Next'''<br />
#Enter the name KoLmafia and press '''Next'''<br />
#Verify that the project is visible to IDEA and press Finish<br />
<br />
=== Add the Ant Build File ===<br />
# Open the Ant Toolbar Item (typically on the right side, and not very large)<br />
# Click the '''+''' button to add a build file<br />
# Choose build.xml from the file selector and press Open<br />
# Verify that a list of ANT targets appears in the Ant Toolbar<br />
<br />
== Configure Project ==<br />
=== Check Project Settings ===<br />
# In the top menu, select '''File''' > '''Project Structure...''' to launch the ''Project Structure'' dialog.<br />
# In the left menu, select '''Project Settings''' > '''Project'''<br />
## set the '''Name''' to <kbd>kolmafia</kbd><br />
## set the '''Project SDK''' to a version installed on your system. '''This must be at least 1.8'''.<br />
## set the project language level to '''8'''<br />
## set the project compiler output path to the <kbd>&lt;project dir&gt;\build</kbd> subdirectory<br>[[File:Intellij-setup-c2021.2-project-structure-project.png|300px]]<br />
# In the left menu, select '''Project Settings''' > '''Libraries'''<br />
## Add a project library with the name <kbd>kol-library-jars</kbd>:<br />
### Click the '''+''' button (''New Project Library''), then select '''Java''' to add a new project library<br>[[File:Intellij-setup-c2021.2-project-structure-libraries-new.png|300px]]<br />
### If the ''Select Library Files'' popup appears, navigate to <code>&lt;project dir&gt;\lib\jar</code> directory and select ''all'' JAR files. You can <kbd>shift</kbd>+click the first and last JAR files to select multiple files at once.<br>[[File:Intellij-setup-c2021.2-project-structure-libraries-select-jars.png|300px]]<br>Click '''OK''' to close the popup.<br />
### If the ''Choose Modules'' popup appears, ensure that <samp>kolmafia</samp> is highlighted, then click '''OK'''.<br>[[File:Intellij-setup-c2021.2-project-structure-libraries-choose-modules.png|300px]]<br />
### If you followed the steps above, IntelliJ will create a project library using the name of the first JAR file.<br>To rename it, select the library, then select the '''Name''' field and enter <kbd>kol-library-jars</kbd>.<div><ul><li style="display: inline-block;"> [[File:Intellij-setup-c2021.2-project-structure-libraries-rename-library.png|thumb|none|300px|Before renaming]]</li><li style="display: inline-block;"> [[File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png|thumb|none|300px|After renaming]]</li></ul></div><br />
## Repeat the steps above to add a project library with the name <kbd>kol-source-jars</kbd>, selecting all JAR files under <code>&lt;project dir&gt;\src\jar\</code>.<br />
## Repeat the steps above to add a project library with the name <kbd>kol-test-jars</kbd>, selecting all JAR files under <code>&lt;project dir&gt;\lib\testjar\</code>.<br />
## Click '''Apply'''.<br />
# In the left menu, select '''Project Settings''' > '''Modules'''<br />
## Select the '''Dependencies''' tab<br />
### If you followed the instructions so far, this section will have libraries with incorrect names (i.e. using the names of the first JAR file in each library). Select them all and click '''-''' to remove them.<br>[[File:Intellij-setup-c2021.2-project-structure-modules-remove-bad-libraries.png|300px]]<br />
### Add the correct project libraries by clicking '''+''', then '''Library'''.<br>[[File:Intellij-setup-c2021.2-project-structure-modules-add-library.png|300px]]<br />
#### In the ''Choose Libraries'' dialog, select all project libraries we added so far, then click '''Add Selected'''.<br>[[File:Intellij-setup-c2021.2-project-structure-modules-choose-libraries.png|300px]]<br />
## Select the '''Sources''' tab<br />
### Right-click the '''lib''' and '''src''' folders. If the and verify that each is marked as ''Sources''<br />
### Right-click the '''test''' folder. If the folder is not marked as '''Tests''', click the menu item to check it.<br>[[File:Intellij-setup-c2021.2-project-structure-modules-sources.png|300px]]<br />
## Select the '''Paths''' tab<br />
### Select '''Inherit project compile output path'''<br>[[File:Intellij-setup-c2021.2-project-structure-modules-paths.png|300px]]<br />
# Click '''OK''' to close the ''Project Structure'' dialog<br />
<br />
=== Add Run/Debug Configuration ===<br />
# In the top menu, select '''Run''' > '''Edit Configurations...''' to launch the ''Run/Debug Configurations'' dialog.<br />
# Click the '''+''' button, then choose '''Application''' to add a new configuration<br />
# In the '''Name''' Field, enter "KoLmafia"<br />
# Click the icon that looks like a document ("Browse...") to the right of the '''Main Class''' field.<br />
## If the ''Choose Main Class'' popup appears, wait until IntelliJ populates the list of possible main classes, then choose '''<samp>KoLmafia</samp>''' and click '''OK'''<br />
# Add any VM or program arguments needed (typically none)<br />
# Enter the working directory. This is where KoLmafia will store your user data when launched from inside IntelliJ (e.g. <samp>C:\Users\&lt;user&gt;\Documents\kolmafia-workdir</samp>).<br>''Caution'': This should be different from the project directory!<br />
# Add the "before launch" tasks:<br />
## Click '''Modify options''' at the top right and select '''Add before launch task'''<br />
## Add the '''set.released.false''' Ant task:<br />
### Click the '''+''' button to the right of ''Before launch'', then '''Run Ant target'''.<br />
### If the ''Choose Ant Target to Execute'' popup appears, select '''set.released.false''' and click '''OK'''.<br />
## Repeat the steps above to add the '''set.version''' Ant task<br />
## Repeat the steps above to add the '''unset.properties''' Ant task<br />
## Drag-and-drop the tasks to ensure that each task is executed in the following order: <br />
### Run Ant target 'set.released.false'<br />
### Run Ant target 'set.version'<br />
### Build<br />
### Run Ant target 'unset.properties'<br />
# Click '''OK''' to close the ''Run/Debug Configurations'' dialog.<br />
<br />
Test by pressing the Run arrow next to your config name in the toolbar at the top of the window.<br />
<br />
== Optional Steps ==<br />
* Setup SVN to update from IntelliJ (can still be done from the command line or a tool)<br />
*# TODO: FIXME...<br />
* To use the Reformat Code feature, download the [[:File:KoLMafia Style.xml|KoLMafia Style Definitions]] and import them in the IntelliJ Code Style Preferences.</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-modules-paths.png&diff=9097File:Intellij-setup-c2021.2-project-structure-modules-paths.png2021-08-02T09:24:28Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-modules-sources.png&diff=9096File:Intellij-setup-c2021.2-project-structure-modules-sources.png2021-08-02T09:21:29Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-modules-choose-libraries.png&diff=9095File:Intellij-setup-c2021.2-project-structure-modules-choose-libraries.png2021-08-02T09:15:27Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-modules-add-library.png&diff=9094File:Intellij-setup-c2021.2-project-structure-modules-add-library.png2021-08-02T09:14:35Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-modules-remove-bad-libraries.png&diff=9093File:Intellij-setup-c2021.2-project-structure-modules-remove-bad-libraries.png2021-08-02T09:10:33Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes and arrows added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes and arrows added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:FileIntellij-setup-c2021.2-project-structure-libraries-renamed.png&diff=9092File:FileIntellij-setup-c2021.2-project-structure-libraries-renamed.png2021-08-02T08:41:41Z<p>Philmasterplus: Philmasterplus moved page File:FileIntellij-setup-c2021.2-project-structure-libraries-renamed.png to File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png</p>
<hr />
<div>#REDIRECT [[File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png&diff=9091File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png2021-08-02T08:41:41Z<p>Philmasterplus: Philmasterplus moved page File:FileIntellij-setup-c2021.2-project-structure-libraries-renamed.png to File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png&diff=9090File:Intellij-setup-c2021.2-project-structure-libraries-renamed.png2021-08-02T08:38:13Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-libraries-rename-library.png&diff=9089File:Intellij-setup-c2021.2-project-structure-libraries-rename-library.png2021-08-02T08:34:32Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-libraries-choose-modules.png&diff=9088File:Intellij-setup-c2021.2-project-structure-libraries-choose-modules.png2021-08-02T08:31:05Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-libraries-select-jars.png&diff=9087File:Intellij-setup-c2021.2-project-structure-libraries-select-jars.png2021-08-02T08:27:49Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-libraries-new.png&diff=9086File:Intellij-setup-c2021.2-project-structure-libraries-new.png2021-08-02T08:21:29Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes and arrows added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes and arrows added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-project-structure-project.png&diff=9085File:Intellij-setup-c2021.2-project-structure-project.png2021-08-02T08:13:43Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-choose-working-copy-dir.png&diff=9084File:Intellij-setup-c2021.2-choose-working-copy-dir.png2021-08-02T08:06:34Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-get-from-vcs-check-out.png&diff=9083File:Intellij-setup-c2021.2-get-from-vcs-check-out.png2021-08-02T08:00:15Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes and arrows added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes and arrows added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-new-repository-location--original.png&diff=9082File:Intellij-setup-c2021.2-new-repository-location--original.png2021-08-02T07:56:57Z<p>Philmasterplus: Philmasterplus moved page File:Intellij-setup-c2021.2-new-repository-location--original.png to File:Intellij-setup-c2021.2-new-repository-location.png</p>
<hr />
<div>#REDIRECT [[File:Intellij-setup-c2021.2-new-repository-location.png]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-new-repository-location.png&diff=9081File:Intellij-setup-c2021.2-new-repository-location.png2021-08-02T07:56:57Z<p>Philmasterplus: Philmasterplus moved page File:Intellij-setup-c2021.2-new-repository-location--original.png to File:Intellij-setup-c2021.2-new-repository-location.png</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-new-repository-location.png&diff=9080File:Intellij-setup-c2021.2-new-repository-location.png2021-08-02T07:56:40Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-get-from-vcs-subversion.png&diff=9079File:Intellij-setup-c2021.2-get-from-vcs-subversion.png2021-08-02T07:55:30Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes and arrows added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes and arrows added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-get-from-vcs.png&diff=9078File:Intellij-setup-c2021.2-get-from-vcs.png2021-08-02T07:53:13Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10
Yellow boxes and arrows added for emphasis</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10<br />
Yellow boxes and arrows added for emphasis</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-welcome.png&diff=9077File:Intellij-setup-c2021.2-welcome.png2021-08-02T07:44:29Z<p>Philmasterplus: Philmasterplus uploaded a new version of File:Intellij-setup-c2021.2-welcome.png</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=File:Intellij-setup-c2021.2-welcome.png&diff=9076File:Intellij-setup-c2021.2-welcome.png2021-08-02T07:38:02Z<p>Philmasterplus: Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</p>
<hr />
<div>== Summary ==<br />
Screenshot from IntelliJ IDEA 2021.2 Community Edition on Windows 10</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Operators&diff=9075Operators2021-07-28T06:30:03Z<p>Philmasterplus: /* Relational Operators */ Add info on string comparisons, add approximately equal operator</p>
<hr />
<div>{{TOCright}}<br />
==Mathematical Operators==<br />
<br />
The following mathematical operators are used in KoLmafia:<br />
{{<br />
eztable|<br />
{{eztr|{{eztd| + |Addition|Performs addition and string concatenation}}}}<br />
{{eztr|{{eztd| - |Subtraction|Performs subtraction}}}}<br />
{{eztr|{{eztd| * |Multiplication|Performs multiplication}}}}<br />
{{eztr|{{eztd| / |Division|Performs division}}}}<br />
{{eztr|{{eztd| % |Modulo|Returns the remainder after division}}}}<br />
{{eztr|{{eztd| ** |Exponent|Performs exponentiation}}}}<br />
}}<br />
Note that, with the exception of using <nowiki>"+"</nowiki> for string concatenation, these operators can only be used on int or float datatypes.<br />
<br />
==Bitwise Operators==<br />
<br />
The following mathematical operators are used for operating on the bits of integers. The logical operators (&, |, ^) work either with booleans or integers while the others operate upon integers only. If the operands are booleans, then result will also be a boolean. <br />
{{<br />
eztable|<br />
{{eztr|{{eztd| <nowiki>&</nowiki> |and|a & b}}}}<br />
{{eztr|{{eztd| <nowiki>|</nowiki> |or|a <nowiki>|</nowiki> b}}}}<br />
{{eztr|{{eztd| <nowiki>^</nowiki> |XOR|a <nowiki>^</nowiki> b}}}}<br />
{{eztr|{{eztd| ~ |not|~a}}}}<br />
{{eztr|{{eztd| << |left shift|a << b}}}}<br />
{{eztr|{{eztd| >> |right shift|a >> b}}}}<br />
{{eztr|{{eztd| <nowiki>&=</nowiki> |and|<nowiki>a &= b --> a = a & b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>|=</nowiki> |or|<nowiki>a |= b --> a = a | b</nowiki>}}}}<br />
{{eztr|{{eztd| >>> |unsigned right shift|a >>> b}}}}<br />
}}<br />
<br />
==Assignment Operators==<br />
The following assignment operators are used in KoLmafia (let a = left operand, b = right operand):<br />
{{<br />
eztable|<br />
{{eztr|{{eztd| <nowiki>=</nowiki> |<nowiki>a = b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>+=</nowiki> |<nowiki>a = a + b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>-=</nowiki> |<nowiki>a = a - b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>*=</nowiki> |<nowiki>a = a * b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>/=</nowiki> |<nowiki>a = a / b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>%=</nowiki> |<nowiki>a = a % b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>**=</nowiki> |<nowiki>a = a ** b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>^=</nowiki> |<nowiki>a = a ^ b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>>>=</nowiki> |<nowiki>a = a >> b</nowiki>}}}}<br />
{{eztr|{{eztd| <nowiki>>>>=</nowiki> |<nowiki>a = a >>> b</nowiki>}}}}<br />
}}<br />
Of these, only += and = are usable for strings. See [[Operators#Mathematical Operators|Mathematical Operators]] for information regarding the basic Mathematical Operators.<br />
<br />
==Relational Operators==<br />
<br />
To follow these examples, a basic understanding of the concepts found on [[Control Structures]] would be helpful.<br />
<br />
In order to create more complex if statements, we need to understand the basic relational operators:<br />
{{<br />
eztable|<br />
{{eztr|{{eztd| <nowiki>==</nowiki> |equal to}}}}<br />
{{eztr|{{eztd| <nowiki>!=</nowiki> |not equal to}}}}<br />
{{eztr|{{eztd| <nowiki><</nowiki> |less than}}}}<br />
{{eztr|{{eztd| <nowiki>></nowiki> |greater than}}}}<br />
{{eztr|{{eztd| <nowiki><=</nowiki> |less than or equal to}}}}<br />
{{eztr|{{eztd| <nowiki>>=</nowiki> |greater than or equal to}}}}<br />
{{eztr|{{eztd| <nowiki>≈</nowiki> |approximately equal to}}}}<br />
}}<br />
Note that you cannot mix most datatypes within a comparison or KoLmafia will abort with an error, with the exception of mixing types int and float, where KoLmafia will do a transparent type conversion behind-the-scenes. If you need to compare different datatypes, use one or more of the [[Datatype Conversions|Datatype Conversion]] functions.<br />
{{<br />
CodeSample|<br />
code=<br />
<syntaxhighlight><br />
if ( true == true )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( true == false )<br />
{<br />
print( "This line does NOT get printed." );<br />
}<br />
if ( 1 == 1.0 )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( 1 == 2 )<br />
{<br />
print( "This line does NOT get printed." );<br />
}<br />
if ( "Hello" == "hello" )<br />
{<br />
print( "This line does NOT get printed." );<br />
}<br />
</syntaxhighlight>}}<br />
<br />
As of [https://kolmafia.us/threads/16180-when-parsing-a-bounty-object-in-ash-make-case-insensitive-string-compariso.18981/ r16180], the equality (<code>==</code>) and inequality (<code>!=</code>) operators compare strings case-sensitively.<br />
<br />
The "approximately equal" operator (<code>≈</code>) was introduced in [https://kolmafia.us/threads/16284-add-an-ash-operator-to-perform-an-approximately-equal-comparison.19116/ r16284]. When comparing two strings, it compares them case-insensitively. When comparing other data types, it behaves like the equality operator (<code>==</code>).<br />
<br />
{{CodeSample|<br />
description=Another exception is with strings. If the '''first''' datatype is a string, and the second isn't, the latter will be silently converted into a string. Remember that strings are compared alphabetically (with the alphabet here being the characters' [https://www.asciitable.com/ ASCII value]), just like in a dictionary, in which "smaller" means "would come before".|<br />
code=<br />
<syntaxhighlight><br />
if ( "a" < "b" )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( "apple" < "b" )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( "1" < 2 )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( "1487" < 2 )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( "a" < 2 )<br />
{<br />
print( "This line does NOT get printed." );<br />
}<br />
<br />
if ( "3" == 3 )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
if ( "3.0" == 3 )<br />
{<br />
print( "This line does NOT get printed." );<br />
}<br />
if ( 3 == "3" )<br />
{<br />
print( "This GENERATES AN ERROR!" );<br />
}<br />
<br />
if ( "true" == true )<br />
{<br />
print( "This line DOES get printed." );<br />
}<br />
</syntaxhighlight>|<br />
moreinfo=Take the habit of always converting your datatypes to avoid unexpected problems.}}<br />
<br />
==Boolean Operators==<br />
{{<br />
eztable|<br />
{{eztr|{{eztd| <nowiki>&&</nowiki> |and}}}}<br />
{{eztr|{{eztd| <nowiki>||</nowiki> |or}}}}<br />
{{eztr|{{eztd| <nowiki>!</nowiki> |not}}}}<br />
}}<br />
Note that the above operators only work with boolean values & datatypes. To make use of them with other datatypes, you will either need to first perform a [[Datatype Conversions|Datatype Conversion]], or you will need to nest your operations such that a boolean value is used with the boolean operators.<br />
{{<br />
CodeSample|<br />
code=<br />
<syntaxhighlight><br />
if ( true && true )<br />
{<br />
print( "This line DOES get printed (both possibilities proved true)." );<br />
}<br />
if ( true && false )<br />
{<br />
print( "This line does NOT get printed (only one possibility proved true)." );<br />
}<br />
if ( true || false )<br />
{<br />
print( "This line DOES get printed (since at least one of the possibilities proved true)." );<br />
}<br />
if ( ! false )<br />
{<br />
print( "This line DOES get printed (since the not operator converted false to true)." );<br />
}<br />
</syntaxhighlight>}}<br />
<br />
====Notes====<br />
ASH uses [https://en.wikipedia.org/wiki/Short-circuit_evaluation Short-circuit_evaluation].<br><br />
What this means is that in both of these examples, expensive_function() is not evaluated (i.e. is skipped):<br />
<br />
{{<br />
CodeSample|<br />
code=<br />
<syntaxhighlight><br />
if ( false && expensive_function() ) {<br />
...<br />
}<br />
</syntaxhighlight>}}<br />
{{<br />
CodeSample|<br />
code=<br />
<syntaxhighlight><br />
if ( true || expensive_function() ) {<br />
...<br />
}<br />
</syntaxhighlight>}}<br />
<br />
==Operator Precedence==<br />
<br />
KoLmafia follows [http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html Java's Operator Precedence rules] with a few exceptions.<br />
<br />
(The exceptions being operators that exist in only one or the other; operators that exist in both have the same precedence in both.)<br />
<br />
{{<br />
eztable|<br />
{{eztr|{{eztd|14| <nowiki>(reserved for postfix ++ and --)</nowiki> }}}}<br />
{{eztr|{{eztd|13| <nowiki>! ~ contains remove (reserved for prefix ++ and --)</nowiki> }}}}<br />
{{eztr|{{eztd|12| <nowiki>**</nowiki> }}}}<br />
{{eztr|{{eztd|11| <nowiki>* / %</nowiki> }}}}<br />
{{eztr|{{eztd|10| <nowiki>+ -</nowiki> }}}}<br />
{{eztr|{{eztd| 9| <nowiki><< >> >>></nowiki> }}}}<br />
{{eztr|{{eztd|8| <nowiki>< > <= >=</nowiki> }}}}<br />
{{eztr|{{eztd|7| <nowiki>== !=</nowiki> }}}}<br />
{{eztr|{{eztd|6| <nowiki>&</nowiki> }}}}<br />
{{eztr|{{eztd|5| <nowiki>^</nowiki> (xor) }}}}<br />
{{eztr|{{eztd|5| <nowiki>|</nowiki> }}}}<br />
{{eztr|{{eztd|3| <nowiki>&&</nowiki> }}}}<br />
{{eztr|{{eztd|2| <nowiki>||</nowiki> }}}}<br />
{{eztr|{{eztd|1|(reserved for <nowiki>?:</nowiki>(ternary conditional))}}}}<br />
{{eztr|{{eztd|0| (reserved for assignments)}}}}<br />
}}<br />
<br />
Statements inside a () pair are always evaluated first, then in order of precedence as listed above (highest number precedence first), then left-to-right.<br />
{{<br />
CodeSample|<br />
code=<br />
<syntaxhighlight><br />
if ( true || true && false )<br />
{<br />
print( "This line DOES get printed." );<br />
// && has highest precedence<br />
// true or (true && false) returns true<br />
}<br />
if ( ( true && false ) && true )<br />
{<br />
print( "This line does NOT get printed." );<br />
// ( true && false ) is evaluated first since it is inside of parentheses<br />
// so we end up evaluating ( false && true ) which returns false<br />
}<br />
if ( true && ! ( true && false ) )<br />
{<br />
print( "This line DOES get printed." );<br />
// ( true && false ) is evaluated first since it is inside of parentheses<br />
// the ! operator converts the false from ( true && false ) to true<br />
// ( true && true ) returns true<br />
}<br />
</syntaxhighlight>}}<br />
[[Category:Scripting]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Zlib&diff=9074Zlib2021-07-28T06:21:25Z<p>Philmasterplus: /* String Functions */ Update equals()</p>
<hr />
<div>{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}<br />
{{Attention|<br />
This page details the use of functions in a script library. The information here is only useful to those who have followed the included steps to make use of these functions; they are not built-in to KoLmafia.<br />
}}<br />
== About ZLib ==<br />
ZLib is a function library intended to make life easier for both script authors and script users. A more detailed introduction, as well as instructions on installing it and other details, can be found in the [http://kolmafia.us/showthread.php?2072 ZLib thread].<br />
<br />
== String Functions ==<br />
<br />
{{HideLink|excise}}{{Function|<br />
name=excise|<br />
return_type=string|<br />
parameter1={{Param|string|source}}|<br />
parameter2={{Param|string|start}}|<br />
parameter3={{Param|string|end}}|<br />
p1desc=The original {{pspan|source}} string|<br />
p2desc={{pspan|start}} after this string|<br />
p3desc={{pspan|end}} before this string|<br />
}}<br />
This function returns a portion of the {{pspan|source}} string, from after the first occurrence of {{pspan|start}} to just before the first occurrence of {{pspan|end}}. If either {{pspan|start}} or {{pspan|end}} are missing, it will return an empty string. You can also supply either {{pspan|start}} or {{pspan|end}} as blank strings to specify the actual start or end of the {{pspan|source}} string.<br />
<br />
{{HideLink|equals}}{{Function|<br />
name=equals|<br />
return_type=boolean|<br />
parameter1={{Param|string|s1}}|<br />
parameter2={{Param|string|s2}}|<br />
p1desc={{pspan|s1}} is a string.|<br />
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|<br />
}}<br />
Compares two strings case-sensitively.<br />
<br />
Note: This function was invented when string comparison operators (<code>==</code> and <code>!=</code>) were case-insensitive. As of [https://kolmafia.us/threads/16180-when-parsing-a-bounty-object-in-ash-make-case-insensitive-string-compariso.18981/ r16180], ASH strings are compared case-sensitively, which makes this function no longer necessary.<br />
<br />
{{HideLink|vprint}}{{Function|<br />
name=vprint|<br />
return_type=boolean|<br />
parameter1={{Param|string|message}}|<br />
parameter2={{Param|int|level}}|<br />
}}<br />
{{Function|<br />
name=vprint|<br />
return_type=boolean|<br />
parameter1={{Param|string|message}}|<br />
parameter2={{Param|string|color}}|<br />
parameter3={{Param|int|level}}|<br />
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|<br />
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|<br />
}}<br />
This function is an enhanced version of the ASH function {{f|print}}. The {{pspan|message}} and optional {{pspan|color}} parameters are exactly like in print(), but the {{pspan|level}} parameter gives you a lot of additional control. Specifically, it allows you to control the return value, specify the verbosity level of the output, and maybe even abort the script.<br />
<br />
First, the return value. If level is positive, it returns true. If negative, it returns false. If level is 0, vprint() will abort with the specified message. You can see now that vprint effectively replaces both {{f|abort}} and print. I recommend it as your go-to function anytime you need to show anything in the CLI, for any reason.<br />
<br />
Having a boolean return value (as opposed to ASH's print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code. For example:<br />
{{CodeSample|<br />
code=<br />
<syntaxhighlight><br />
// add debugging info to an if check:<br />
if (somevar == 2 && vprint("somevar equals 2",10)) dosomething();<br />
// add additional info to a return true/false:<br />
if (everythingsgreat) return vprint("Everything's great!",7);<br />
else return vprint("Everything is not great.",-7);<br />
</syntaxhighlight>}}<br />
<br />
Secondly, level represents the verbosity of the message. ZLib includes a script setting called "verbosity". Users can adjust this value to specify how verbose they want scripts to be. If they set it to 1, they want the script to print almost nothing -- only the most important messages. If they set it to 10, they want it to print a lot of details. The level of each vprint command thus determines whether or not the message will actually be printed. If the absolute value of level is more than verbosity, the message will not be printed. For example, a user with the default verbosity of 3 would not see any of the example messages given above. This allows users to control the chattiness of scripts, and allows authors to include helpful debugging print statements which can be shown by setting verbosity high.<br />
<br />
'''Recommendations for Verbosity Levels in vprint()'''<br />
<br />
0: abort error<br />
<br />
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically "silent mode"<br />
<br />
+/- 2: important and useful info -- this should generally be your base level for your most important messages<br />
<br />
+/- 4: interesting but non-essential information<br />
<br />
+/- 6: info which an overly curious person might like to see on their CLI<br />
<br />
+/- 10: details which are only helpful for debugging, such as "begin/end functionname()" or "current value of variable: value"<br />
<br />
<br />
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don't prefer to see all the details. In addition, it allows users to specify a verbosity of 0 to see ONLY mafia output (no script output at all), which could prove handy.<br />
<br />
The color parameter is optional. If you omit it, the default color is black for positive values of level, and red for negative values. Usually, you won't be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.<br />
<br />
{{HideLink|vprint_html}}{{Function|<br />
name=vprint_html|<br />
return_type=boolean|<br />
parameter1={{Param|string|message}}|<br />
parameter2={{Param|int|level}}|<br />
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|<br />
p2desc={{pspan|level}} is a verbosity reference|<br />
}}<br />
Same as vprint() above, but wraps {{f|print_html}}.<br />
<br />
{{HideLink|normalized}}{{Function|<br />
name=normalized|<br />
return_type=string|<br />
parameter1={{Param|string|mixvar}}|<br />
parameter2={{Param|string|type}}|<br />
}}{{Function|<br />
name=normalized|<br />
return_type=string|<br />
parameter1={{Param|string|mixvar}}|<br />
parameter2={{Param|string|type}}|<br />
parameter3={{Param|string|glue}}|<br />
p1desc={{pspan|mixvar}} is the string to normalize|<br />
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant. You can also specify "list of <type>", for a comma-delimited list of the given type.|<br />
p3desc={{pspan|glue}} is only relevant for lists of a type. You can specify the delimiter (which could be necessary if dealing with list entries that have commas in them). Defaults to ", ".|<br />
}}<br />
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized("badger", "familiar") would return "Astral Badger". It can also normalize comma-delimited lists of any of these types if you specify "list of <type>" for {{pspan|type}}. For example, normalized("bloop, dair go, possess", "list of monster") would return "Blooper, Dairy Goat, Possessed Silverware Drawer".<br />
<br />
{{HideLink|join}}{{Function|<br />
name=join|<br />
return_type=string|<br />
parameter1={{Param|string [int]|pieces|ag=t}}|<br />
parameter2={{Param|string|glue}}|<br />
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|<br />
p2desc={{pspan|glue}} is the string to put between the pieces.|<br />
}}<br />
This function is the opposite of the ASH function {{f|split_string}}. It joins {{pspan|pieces}} together, inserting {{pspan|glue}} between each piece, and returns the assembly as a single string. Useful for working with comma-delimited lists (or anything-delimited lists, actually).<br />
<br />
{{HideLink|list_contains}}{{Function|<br />
name=list_contains|<br />
return_type=boolean|<br />
parameter1={{Param|string|stringlist}}|<br />
parameter2={{Param|string|needle}}|<br />
}}<br />
{{Function|<br />
name=list_contains|<br />
return_type=boolean|<br />
parameter1={{Param|string|stringlist}}|<br />
parameter2={{Param|string|needle}}|<br />
parameter3={{Param|string|glue}}|<br />
p1desc={{pspan|stringlist}} is a glue-delimited string list such as returned by join().|<br />
p2desc={{pspan|needle}} is the entry to check for.|<br />
p3desc={{pspan|glue}} is optional (defaults to ", ") and represents the delimiter for the list.|<br />
}}<br />
Returns true if {{pspan|list}} contains {{pspan|needle}}. Avoids false positives which could result from using contains_text().<br />
<br />
{{HideLink|list_add}}{{Function|<br />
name=list_add|<br />
return_type=string|<br />
parameter1={{Param|string|stringlist}}|<br />
parameter2={{Param|string|add}}|<br />
}}<br />
{{Function|<br />
name=list_add|<br />
return_type=string|<br />
parameter1={{Param|string|stringlist}}|<br />
parameter2={{Param|string|add}}|<br />
parameter3={{Param|string|glue}}|<br />
p1desc={{pspan|stringlist}} is a glue-delimited string list such as returned by join() above.|<br />
p2desc={{pspan|add}} is the entry to add to the list.|<br />
p3desc={{pspan|glue}} is optional (defaults to ", ") and represents the delimiter for the list.|<br />
}}<br />
Adds unique entry {{pspan|add}} to a {{pspan|glue}}-delimited {{pspan|list}}, and returns the modified list. If the entry already exists in the list, another entry will not be added. For example, list_add("a, b, c","d") would return "a, b, c, d", but list_add("a, b, c", "a") would return "a, b, c", since the entry "a" already exists.<br />
<br />
{{HideLink|list_remove}}{{Function|<br />
name=list_remove|<br />
return_type=string|<br />
parameter1={{Param|string|stringlist}}|<br />
parameter2={{Param|string|del}}|<br />
}}<br />
{{Function|<br />
name=list_remove|<br />
return_type=string|<br />
parameter1={{Param|string|stringlist}}|<br />
parameter2={{Param|string|del}}|<br />
parameter3={{Param|string|glue}}|<br />
p1desc={{pspan|stringlist}} is a glue-delimited string list such as returned by join() above.|<br />
p2desc={{pspan|del}} is the entry to remove from the list.|<br />
p3desc={{pspan|glue}} is optional (defaults to ", ") and represents the delimiter for the list.|<br />
}}<br />
Removes {{pspan|del}} from {{pspan|glue}}-delimited {{pspan|list}}, and returns the modified list. It will remove all instances of {{pspan|del}}. For example, list_remove("a, b, c","a") would return "b, c", and list_remove("a, a, b, b, c, c", "a") would return "b, b, c, c".<br />
<br />
{{HideLink|rnum}}{{Function|<br />
name=rnum|<br />
return_type=string|<br />
parameter1={{Param|int|n}}|<br />
}}<br />
{{Function|<br />
name=rnum|<br />
return_type=string|<br />
parameter1={{Param|float|n}}|<br />
}}<br />
{{Function|<br />
name=rnum|<br />
return_type=string|<br />
parameter1={{Param|float|n}}|<br />
parameter2={{Param|int|place}}|<br />
p1desc={{pspan|n}} is a number|<br />
p2desc={{pspan|place}} is the number of decimal places to round to|<br />
}}<br />
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user's computer's region. For ints, this means it adds grouping separators where appropriate. For floats, it also rounds to the nearest {{pspan|place}} after the decimal. Default {{pspan|place}} for the float-only version is 2, although it may display fewer digits if they are 0's. Examples: rnum(12580) => "12,580", rnum(3.14152964,3) => "3.142", rnum(4.00008) => "4", rnum(123456789.87654321) => "123,456,789.88". Recommended as a substitute for to_string(int).<br />
<br />
== Number Functions ==<br />
<br />
{{HideLink|abs}}{{Function|<br />
name=abs|<br />
return_type=float|<br />
parameter1={{Param|float|n}}|<br />
p1desc={{pspan|n}} is any number.|<br />
}}<br />
Returns the absolute value of the number {{pspan|n}}. Don't worry if you are working with integers, it will still work just fine. This function already exists in many programming languages; ZLib makes it handily available in ASH.<br />
<br />
{{HideLink|minmax}}{{Function|<br />
name=minmax|<br />
return_type=float|<br />
parameter1={{Param|float|a}}|<br />
parameter2={{Param|float|min}}|<br />
parameter3={{Param|float|max}}|<br />
p1desc={{pspan|a}} is the original number|<br />
p2desc={{pspan|min}} is the minimum return value|<br />
p3desc={{pspan|max}} is the maximum return value|<br />
}}<br />
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}. Another function common to many languages.<br />
<br />
{{HideLink|set_avg}}{{Function|<br />
name=set_avg|<br />
return_type=void|<br />
parameter1={{Param|float|to_add}}|<br />
parameter2={{Param|string|which_prop}}|<br />
p1desc={{pspan|to_add}} is the data point to add|<br />
p2desc={{pspan|which_prop}} is the property to add data to|<br />
}}<br />
Useful for adding spading to scripts. Adds one more statistic to an average value being stored in a property. For example, calling this function three times with the values 2, 4, and 6 for {{pspan|to_add}} would result in the property {{pspan|which_prop}} containing "4.0:3", with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.<br />
<br />
{{HideLink|get_avg}}{{Function|<br />
name=get_avg|<br />
return_type=float|<br />
parameter1={{Param|string|which_prop}}|<br />
p1desc={{pspan|which_prop}} is the property to access|<br />
}}<br />
Returns an average value set by set_avg().<br />
<br />
{{HideLink|eval}}{{Function|<br />
name=eval|<br />
return_type=float|<br />
parameter1={{Param|string|expression}}|<br />
parameter2={{Param|float [string]|values|ag=t}}|<br />
p1desc={{pspan|expression}} is the base expression|<br />
p2desc={{pspan|values}} is a map of values to replace|<br />
}}<br />
By Jason Harper. Evaluates {{pspan|expression}} as a math expression, and allows you to substitute {{pspan|values}} for variables, as described in much greater detail here. Brief documentation is also included in ZLib. (NB: This section needs more infoz.)<br />
<br />
== Script Functions ==<br />
<br />
{{HideLink|check_version}}{{Function|<br />
name=check_version|<br />
return_type=string|<br />
parameter1={{Param|string|soft}}|<br />
parameter2={{Param|string|proj}}|<br />
parameter3={{Param|int|thread}}|<br />
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|<br />
p2desc={{pspan|proj}} is the name of the SVN project name to check.|<br />
p3desc={{pspan|thread}} is the script's thread number on kolmafia.us|<br />
}}<br />
{{Function|<br />
name=check_version|<br />
return_type=string|<br />
parameter1={{Param|string|soft}}|<br />
parameter2={{Param|string|prop}}|<br />
parameter3={{Param|string|this_version}}|<br />
parameter4={{Param|int|thread}}|<br />
p1desc={{pspan|soft}} is as above.|<br />
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|<br />
p3desc={{pspan|this_version}} is the version of the script currently running|<br />
p4desc={{pspan|thread}} is as above.|<br />
}}<br />
Server-friendly once-daily version-checking. There are two versions of this function, one for SVN and one for forum threads. The three-parameter SVN version uses mafia's SVN client to check if a previously checked-out SVN project is current and if not, it updates it automatically, meaning the script will be current the next time it runs. In the event that a user has checked the option for mafia to automatically update all projects on login, it detects that the script has updated and prints an informative message with a link to the script's kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.<br />
<br />
For the four-parameter forum thread version, it visits the specified {{pspan|thread}} on the kolmafia.us forums to find the current version of your script. The thread must include <nowiki>"<b></nowiki>{{pspan|soft}} {{pspan|version}}<nowiki></b>"</nowiki> for the version info to be successfully parsed. Optionally, you may include <nowiki>"[requires revision XXXX]"</nowiki> somewhere in your post if you want to indicate a required minimum revision of mafia. If a new version is available, it alerts the user in large text and provides an update link.<br />
<br />
The return value of both versions is a blank string unless an update is/was found, in which case it is a <nowiki><div class='versioninfo'></nowiki> containing the update message. This allows this function to work equally well for relay scripts. The current version/revision (and the last date checked) is stored in a data file "zversions.txt". Example:<br />
{{CodeSample|<br />
code=<br />
<syntaxhighlight><br />
check_version("Hardcore Checklist","checklist","1.2.7",1045);<br />
</syntaxhighlight>}}<br />
<br />
{{HideLink|load_current_map}}{{Function|<br />
name=load_current_map|<br />
return_type=boolean|<br />
parameter1={{Param|string|map_name}}|<br />
parameter2={{Param|aggregate|destination}}|<br />
p1desc={{pspan|map_name}} is the name of the map, without the file extension|<br />
p2desc={{pspan|destination}} is a previously-declared map to load with data|<br />
}}<br />
Acts as a wrapper for the built-in {{f|file_to_map}} with automatic update capability. The first time the function is called for a given map each day, it will check [http://zachbardon.com/mafiatools/autoupdate.php Zarqon's Map Manager] to see if an update for the given {{pspan|map_name}} is available, and if so will load from there. Otherwise, it merely loads it from disk. (Note: you should not include a file extension, such as ".txt" in the {{pspan|map_name}} parameter.)<br />
<br />
{{HideLink|setvar}}{{Function|<br />
name=setvar|<br />
return_type=void|<br />
parameter1={{Param|string|varname}}|<br />
parameter2={{Param|mixed|dfault}}|<br />
p1desc={{pspan|name}} is the name of the setting|<br />
p2desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|<br />
}}<br />
This function ensures that a ZLib script setting called {{pspan|name}} exists. If not, it adds it and the default value specified in {{pspan|dfault}} to vars_defaults.txt. Also, if the setting has been changed from its default value, it normalizes the value according to the type of {{pspan|dfault}}, but otherwise does nothing. Note that this function is for initializing defaults, not for editing existing settings. That is done by calling ZLib in the CLI or running a setting editor tool such as Prefref Plus.<br />
<br />
{{HideLink|getvar}}{{Function|<br />
name=getvar|<br />
return_type=string|<br />
parameter1={{Param|string|varname}}|<br />
p1desc={{pspan|name}} is the setting to retrieve the value of|<br />
}}<br />
This function returns the value of the specified script setting. Authors are encouraged to use this rather than a direct vars[] lookup, since values which have not been changed from the default will eventually not be present in vars[].<br />
<br />
==== For Users ====<br />
<br />
* Script settings are now all saved in one place, separate from mafia properties. I've read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.<br />
* Script settings are independent from scripts. This means that you will no longer need to edit scripts to adjust your settings. Further, when you download a script update, the script will still use your saved settings and you won't need to reset them.<br />
* To see all of your current settings, type "zlib vars" in the CLI. You can also type "zlib <whatever>" to see a list of current settings and values containing <whatever>. To change a setting, type "zlib settingname = value". If you're adjusting threshold, you can use "up" or "down" as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia properties (possibly more so since you don't need to open a text file to find setting names!).<br />
* If for some reason you prefer to open a text file, all ZLib setting default values are stored in vars_defaults.txt in your data directory. Your character's ZLib settings that have been changed from default are stored in a file called vars_myname.txt in your data directory.<br />
* Scripts that use Zlib script settings will initialize the settings -- saving their default value and type in vars_defaults.txt -- when you run them for the first time. Attempting to edit a nonexisting setting won't work, so you'll need to run a script once (then, usually, mash the ESC key before it actually does anything) before you can configure it. Script documentation should tell you which settings to change to get your desired behavior.<br />
<br />
==== For Script Authors ====<br />
<br />
* Use setvar() to initialize a setting that your script will reference. To reference the setting, use getvar() and convert from string to whichever type the setting is supposed to be. Accessing vars[] or vardefaults[] directly is not recommended, as a value may exist in one but not the other, or both.<br />
* Script settings may now be used across scripts, in exactly the same way that mafia properties are. Basically, this works almost exactly like mafia properties, except that new settings can only be created by setvar() or manually editing the file ("zlib nonexistentsetting = value" will fail).<br />
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.<br />
* Script authors can now test for a setting's existence in vardefaults[], which means you can check to see if a user has used a given script. It's almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!<br />
* Scripts with overlapping or related functionality can be designed to access a single shared setting, in much the same way that my scripts have until now all shared a "threshold" mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.<br />
* Settings are intended to be set only by users, not scripts. If you want a persistent variable that a script will use, consider static variables. However, there may be cases where a script needs to edit a setting (i.e. a relay script specifically for editing settings). To alter a setting, change the map entry directly with vars["propertyToChange"] = newValue, followed by updatevars() to update the map with the new setting. If you don't use updatevars(), the change will not stick.<br />
<br />
==== Functional Details ====<br />
<br />
When importing ZLib, it loads the setting defaults from vars_defaults.txt and a map of your script settings that have been changed from vars_myname.txt. To access a script setting within an ASH script, use getvar(varname).<br />
<br />
When a script calls setvar("threshold",4), ZLib checks to see if a setting called "threshold" already exists. If so, since dfault is an integer, it ensures that the value is an integer using normalize() (saving changes if necessary), but unless normalization changed the value, nothing else happens. If "threshold" does not exist, it initializes its default value to 4, its type to int, and saves those defaults back to vars_defaults.txt. The setting may now be accessed by getvar() or edited using ZLib in the CLI.<br />
<br />
==== Choosing Setting Names ====<br />
<br />
The file of script settings will contain all script settings, sorted alphabetically. Also, there is no way to detect if a setting is unused, so if you decide to change the name, the old setting will never be deleted. '''Please think carefully about your setting names.''' If you have a setting named "setting1", a user will probably not have a clue which script that is for or what it does. True, this can be overcome with documentation, but it is far better to have settings that make sense just by looking at them.<br />
<br />
'''Recommendations:'''<br />
<br />
1. Use a name that clearly identifies what the setting is/does.<br />
<br />
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:<br />
<br />
{{CodeSample|<br />
code=<br />
<syntaxhighlight><br />
setvar("ocw_warplan","optimal");<br />
setvar("ocw_change_to_meat",true);<br />
setvar("ocw_nunspeed",false);<br />
setvar("defaultoutfit","current");<br />
setvar("ocw_f_default","zombie");<br />
setvar("ocw_m_default","");<br />
</syntaxhighlight>}}<br />
Those settings which are specific to OCW are prefixed with "ocw_" so as to be found together in the settings file. However, some of the settings are usable across scripts, and are not so prefixed. For example, the "defaultoutfit" is used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.<br />
<br />
== Adventuring Functions ==<br />
<br />
{{HideLink|be_good}}{{Function|<br />
name=be_good|<br />
return_type=boolean|<br />
parameter1={{Param|string|johnny}}|<br />
}}<br />
{{Function|<br />
name=be_good|<br />
return_type=boolean|<br />
parameter1={{Param|item|johnny}}|<br />
}}<br />
{{Function|<br />
name=be_good|<br />
return_type=boolean|<br />
parameter1={{Param|familiar|johnny}}|<br />
}}<br />
{{Function|<br />
name=be_good|<br />
return_type=boolean|<br />
parameter1={{Param|skill|johnny}}|<br />
p1desc={{pspan|johnny}} is the thing you want to check|<br />
}}<br />
This function, originally created to check whether items were allowed in the Bees Hate You path (hence the name), has been expanded to an all-purpose check to see whether something is acceptable in your current path. For example, in a Trendy path, or any of the newer paths that have similar restrictions, outdated items would not be_good. Likewise, during Bees Hate You, a familiar containing a 'b' would not be_good. In Fistcore, anything you hold in your hands is not allowed. In an Avatar of Boris run, your normal permed skills are not active. And so forth.<br />
<br />
{{HideLink|qprop}}{{Function|<br />
name=qprop|<br />
return_type=boolean|<br />
parameter1={{Param|string|test}}|<br />
p1desc={{pspan|test}} is a basic logical expression using a quest property|<br />
}}<br />
Simplifies checking mafia's quest tracking properties ("prefref quest" in the CLI will reveal them). You should supply {{pspan|test}} like so:<br />
<br />
<quest property> <logical operator> <possible property value><br />
<br />
For instance:<br />
To check that a quest is complete: qprop("questLXXSomequest == finished")<br />
To check that a quest has reached or passed "step2": qprop("questLXXSomequest >= step2")<br />
To check that a quest is not complete: qprop("questLXXSomequest != finished")<br />
To check that a quest hasn't reached step3 yet: qprop("questLXXSomequest < step3")<br />
<br />
The function converts these text properties to numbers internally, so to save the function a completely insignificant amount of milliseconds (and more importantly yourself a little typing) you can also just use numbers directly instead of text values, where "step3" is 3, "unstarted" is -1, "started" is 0, and "finished" is 999. Thus, the last example above would also work as qprop("questLXXSomequest < 3").<br />
<br />
One more bit of shorthand: you can supply only the property name by itself to check whether the quest is finished. The first example above would also work as qprop("questLXXSomequest").<br />
<br />
{{HideLink|mall_val}}{{Function|<br />
name=mall_val|<br />
return_type=int|<br />
parameter1={{Param|item|it}}|<br />
parameter2={{Param|float|expirydays}}|<br />
parameter3={{Param|boolean|combatsafe}}|<br />
p1desc={{pspan|it}} is the item being valued.|<br />
p2desc={{pspan|expirydays}} is optional, default 0. It represents the age at which {{f|historical_price}} is no longer valid, after which {{f|mall_price}} is used.|<br />
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|<br />
}}<br />
The ASH functions {{f|mall_price}}, {{f|historical_price}}, and {{f|historical_age}} are often combined to save server hits when checking for the price of multiple items. Scripts will use the historical price if it is fairly recent, or hit the server with mall_price if it is too old. This function wraps all of that up, and even adds a flag for getting item values during combat (when you don't have mall access). You'll generally call this with only one of the two parameters.<br />
<br />
If you want to only use historical_price: mall_val(someitem, true)<br />
If you want to only use mall price: mall_val(someitem,0)<br />
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)<br />
<br />
{{HideLink|sell_val}}{{Function|<br />
name=sell_val|<br />
return_type=int|<br />
parameter1={{Param|item|it}}|<br />
parameter2={{Param|float|expirydays}}|<br />
parameter3={{Param|boolean|combatsafe}}|<br />
p1desc={{pspan|it}} is the item being valued.|<br />
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|<br />
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|<br />
}}<br />
This function is concerned with the meat you could realistically expect to get from selling the item. It returns mall_val, unless the mall value is at minimum, meaning it's junk which probably won't sell. In that case it returns the item's autosell value.<br />
<br />
{{HideLink|have_item}}{{Function|<br />
name=have_item|<br />
return_type=int|<br />
parameter1={{Param|string|to_lookup}}|<br />
p1desc={{pspan|to_lookup}} is the item to count|<br />
}}<br />
A residual function, used by the following and probably in several other scripts. Returns the amount of an item you have both in your inventory and equipped. Similar but not equivalent to the ASH function {{f|available_amount}}, since this function completely ignores your closet and storage.<br />
<br />
{{HideLink|braindrop}}{{Function|<br />
name=braindrop|<br />
return_type=item|<br />
parameter1={{Param|monster|patient}}|<br />
p1desc={{pspan|patient}} is the monster under inquiry|<br />
}}<br />
Returns the brain dropped by {{pspan|patient}} in Zombiecore. All five types of brains are properly accounted for, as well as monsters that drop no brains. Will always return $item[none] outside of Zombiecore.<br />
<br />
{{HideLink|kadrop}}{{Function|<br />
name=kadrop|<br />
return_type=float|<br />
parameter1={{Param|monster|m}}|<br />
p1desc={{pspan|m}} is the monster under inquiry|<br />
}}<br />
Returns the amount of ka dropped by {{pspan|m}} as Ed the Undying, accounting for priest servants and the crown of Ed. Will always return 0 outside of Edcore.<br />
<br />
{{HideLink|is_goal}}{{Function|<br />
name=is_goal|<br />
return_type=boolean|<br />
parameter1={{Param|stat|whichstat}}|<br />
p1desc={{pspan|whichstat}} is the stat to check|<br />
}}<br />
The ASH function {{f|is_goal}} takes an item parameter and returns true if the given item is a goal. ZLib extends that function by also including a version which accepts a stat as a parameter. Stats can be goals when a user or script sets "level X" or "X muscle" as a goal.<br />
<br />
{{HideLink|isxpartof}}{{Function|<br />
name=isxpartof|<br />
return_type=float|<br />
parameter1={{Param|item|child}}|<br />
parameter2={{Param|item|ancestor}}|<br />
p1desc={{pspan|child}} is the ingredient/component you want to check.|<br />
p2desc={{pspan|ancestor}} is the concoction you want to check.|<br />
}}<br />
In the sentence "child is X part of ancestor", this function returns X. It assumes the minimum amount of other ingredients necessary. For example, isxpartof($item[white pixel], $item[digital key]) returns 0.033333335 (1/30), since 30 white pixels are needed to make a digital key. However, isxpartof($item[red pixel], $item[digital key]) returns 0.03125 (1/32), assuming 1 each of green and blue pixels and 29 other white pixels (rather than 30 each RGB pixels -- 1/90). This function is used by has_goal(item) but may have uses in your own script.<br />
<br />
{{HideLink|has_goal}}{{Function|<br />
name=has_goal|<br />
return_type=float|<br />
parameter1={{Param|item|check_me}}|<br />
}}<br />
{{Function|<br />
name=has_goal|<br />
return_type=float|<br />
parameter1={{Param|monster|check_me}}|<br />
}}<br />
{{Function|<br />
name=has_goal|<br />
return_type=float|<br />
parameter1={{Param|location|check_me}}|<br />
p1desc={{pspan|check_me}} is the item, monster or locationto check|<br />
}}<br />
At the base of this function is the item parameter version, which returns the chance that the item {{pspan|check_me}} is or results in a goal. If the item is itself a goal, returns 1.0. Otherwise, returns what percentage of a goal the item is, which could be nonzero in two cases: 1) you could get a goal by using the item (returns the chance of success), or 2) the item is an ingredient of a goal. For example, with a goal of black pepper, has_goal($item[black picnic basket]) would return 0.58.<br />
<br />
When supplied a monster as the parameter for {{pspan|check_me}}, returns the percent chance that encountering the given monster will result in a goal, taking into account +items, pickpocket availability (and +pickpocket), and Torso. For instance, with no +item and black pepper as a goal, has_goal($monster[black widow]) would return 0.087 (0.58 basket contains pepper * 0.15 basket drop rate). Also note that it will add multiple goals together, so with white pixels as a goal, a Blooper would return 2.1.<br />
<br />
When supplied a location as the parameter for {{pspan|check_me}}, returns the chance that adventuring at a given location will yield a goal. For our black pepper example, has_goal($location[black forest]) would return 0.0174 (0.2 black widow appearance rate * 0.087 chance that a widow has black pepper). Presently this accounts for combat frequency modifiers but not Olfaction, and it will be off for areas with noncombats that grant goals, because it assumes that all noncombats do not yield items.<br />
<br />
These functions also have an optional boolean parameter, usespec. If supplied as true, these functions will use speculative values. (See "whatif")<br />
<br />
{{HideLink|obtain}}{{Function|<br />
name=obtain|<br />
return_type=boolean|<br />
parameter1={{Param|int|qty}}|<br />
parameter2={{Param|string|condition}}|<br />
parameter3={{Param|location|place}}|<br />
}}<br />
{{Function|<br />
name=obtain|<br />
return_type=boolean|<br />
parameter1={{Param|int|qty}}|<br />
parameter2={{Param|string|condition}}|<br />
parameter3={{Param|location|place}}|<br />
parameter4={{Param|string|filter}}|<br />
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|<br />
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|<br />
p3desc={{pspan|place}} is the location to adventure to obtain your goal|<br />
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|<br />
}}<br />
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk's, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.<br />
<br />
{{HideLink|use_upto}}{{Function|<br />
name=use_upto|<br />
return_type=boolean|<br />
parameter1={{Param|int|qty}}|<br />
parameter2={{Param|item|thing}}|<br />
parameter3={{Param|boolean|purchase}}|<br />
p1desc={{pspan|qty}} is the quantity to use|<br />
p2desc={{pspan|thing}} is the item to use|<br />
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don't already have {{pspan|qty}}|<br />
}}<br />
Gets (if purchase is true) and uses {{pspan|qty}} of the item(s) {{pspan|thing}} if possible. Otherwise, uses as many as you have up to {{pspan|qty}}.<br />
<br />
{{HideLink|resist}}{{Function|<br />
name=resist|<br />
return_type=boolean|<br />
parameter1={{Param|element|resist_it}}|<br />
parameter2={{Param|boolean|really}}|<br />
p1desc={{pspan|resist_it}} is the element to resist|<br />
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|<br />
}}<br />
Returns whether you are able to resist a given element {{pspan|resist_it}}, or if {{pspan|really}} is true, attempts to actually achieve that resistance (casting buffs, changing gear, or equipping your Exotic Parrot) and returns its success.<br />
<br />
{{HideLink|my_defstat}}{{Function|<br />
name=my_defstat|<br />
return_type=int|<br />
parameter1={{Param|boolean|usespec}}|<br />
p1desc={{pspan|usespec}} is optional. If true, uses speculative values rather than real values.|<br />
}}<br />
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.<br />
<br />
{{HideLink|get_safemox}}{{Function|<br />
name=get_safemox|<br />
return_type=int|<br />
parameter1={{Param|location|where}}|<br />
p1desc={{pspan|where}} is the location to check for safe moxie|<br />
}}<br />
Using mafia's location/monster data, returns the safe moxie of a given zone {{pspan|where}}.<br />
<br />
{{HideLink|auto_mcd}}{{Function|<br />
name=auto_mcd|<br />
return_type=boolean|<br />
parameter1={{Param|int|check_me}}|<br />
}}<br />
{{Function|<br />
name=auto_mcd|<br />
return_type=boolean|<br />
parameter1={{Param|monster|check_me}}|<br />
}}<br />
{{Function|<br />
name=auto_mcd|<br />
return_type=boolean|<br />
parameter1={{Param|location|check_me}}|<br />
p1desc={{pspan|check_me}} is the int, monster or location to check|<br />
}}<br />
If your ZLib setting "automcd" is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib "threshold" setting. Does not adjust for MCD-sensitive areas (certain bosses, Slime Tube), or areas with no known combats. Returns true unless KoLmafia is unable to do so, even though the script thinks it should be capable (still returns true if you can't currently access an mcd-changing device).<br />
<br />
{{HideLink|best_fam}}{{Function|<br />
name=best_fam|<br />
return_type=familiar|<br />
parameter1={{Param|string|type}}|<br />
p1desc={{pspan|type}} is the type of familiar ability to check for|<br />
}}<br />
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib "is_100_run" setting is anything other than $familiar[none], returns that familiar (so you don't have to make the check in your script).<br />
<br />
== Kmail Functions ==<br />
<br />
{{HideLink|load_kmail}}{{Function|<br />
name=load_kmail|<br />
return_type=void|<br />
parameter1={{Param|string|calledby}}|<br />
p1desc={{pspan|calledby}} is optional and allows you to specify the name of the script calling this function, which will be submitted when the script visits api.php. The default value is "ZLib-powered-script".|<br />
}}<br />
This function parses your kmail inbox in a single server hit and loads it into the global variable "mail", which is of type kmessage[int]. A kmessage is a record type, with the following fields:<br />
{{CodeSample|<br />
code=<br />
<syntaxhighlight><br />
record kmessage {<br />
int id; // message id<br />
string type; // possible values observed thus far: normal, giftshop<br />
int fromid; // sender's playerid (0 for npc's)<br />
int azunixtime; // KoL server's unix timestamp<br />
string message; // including items/meat gained<br />
int[item] items; // items included in the message<br />
int meat; // meat included in the message<br />
string fromname; // sender's playername<br />
string localtime; // your local time according to your KoL account, human-readable string<br />
};<br />
</syntaxhighlight>}}<br />
<br />
Thus, after calling this function your inbox is very easy to work with. You can foreach over each message if you like, accessing the fields for details.<br />
<br />
{{HideLink|process_kmail}}{{Function|<br />
name=process_kmail|<br />
return_type=void|<br />
parameter1={{Param|string|functionname}}|<br />
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|<br />
}}<br />
If you liked load_kmail(), you'll like this even better. First off, this function loads your kmail into the mail variable if you haven't already done so. Next, it calls a function named {{pspan|functionname}} on each kmail message. The function must be at top level, accept a single kmessage parameter, and return a boolean. For each kmail in your inbox, if the called function returns true, that message will be deleted once all messages have been processed.<br />
<br />
Here's a simple example which will delete all messages from your lovely Pen Pal:<br />
{{CodeSample|<br />
code=<br />
<syntaxhighlight><br />
boolean no_penpal(kmessage m) {<br />
return (m.fromname == "Your Pen Pal");<br />
}<br />
process_kmail("no_penpal");<br />
</syntaxhighlight>}}<br />
<br />
{{HideLink|send_gift}}{{Function|<br />
name=send_gift|<br />
return_type=boolean|<br />
parameter1={{Param|string|recipient}}|<br />
parameter2={{Param|string|message}}|<br />
parameter3={{Param|int|meat}}|<br />
parameter4={{Param|int [item]|goodies|ag=t}}|<br />
}}<br />
{{Function|<br />
name=send_gift|<br />
return_type=boolean|<br />
parameter1={{Param|string|recipient}}|<br />
parameter2={{Param|string|message}}|<br />
parameter3={{Param|int|meat}}|<br />
parameter4={{Param|int [item]|goodies|ag=t}}|<br />
parameter5={{Param|string|inside_note}}|<br />
p1desc={{pspan|recipient}} is the player to send to|<br />
p2desc={{pspan|message}} is the outside message|<br />
p3desc={{pspan|meat}} is the amount of meat to send|<br />
p4desc={{pspan|goodies}} is a map of items & amounts to send|<br />
p5desc={{pspan|inside_note}} is an optional inside message|<br />
}}<br />
Sends a gift to a player. Able to split large amounts of items. Returns true if the package is sent and false if not. See kmail() below.<br />
<br />
{{HideLink|kmail}}{{Function|<br />
name=kmail|<br />
return_type=boolean|<br />
parameter1={{Param|string|recipient}}|<br />
parameter2={{Param|string|message}}|<br />
parameter3={{Param|int|meat}}|<br />
}}<br />
{{Function|<br />
name=kmail|<br />
return_type=boolean|<br />
parameter1={{Param|string|recipient}}|<br />
parameter2={{Param|string|message}}|<br />
parameter3={{Param|int|meat}}|<br />
parameter4={{Param|int [item]|goodies|ag=t}}|<br />
}}<br />
{{Function|<br />
name=kmail|<br />
return_type=boolean|<br />
parameter1={{Param|string|recipient}}|<br />
parameter2={{Param|string|message}}|<br />
parameter3={{Param|int|meat}}|<br />
parameter4={{Param|int [item]|goodies|ag=t}}|<br />
parameter5={{Param|string|inside_note}}|<br />
p1desc={{pspan|recipient}} is the player to send to|<br />
p2desc={{pspan|message}} is the outside message|<br />
p3desc={{pspan|meat}} is the amount of meat to send|<br />
p4desc={{pspan|goodies}} is an optional map of items & amounts to send|<br />
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|<br />
}}<br />
{{Function|<br />
name=kmail|<br />
return_type=boolean|<br />
parameter1={{Param|kmessage|km}}|<br />
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format. The only thing unusual here is that the "fromname" field will be used as the recipient. The other fields will be used appropriately to call the above kmail function.|<br />
}}<br />
Sends a kmail to player {{pspan|recipient}}, returning true if the kmail is successfully sent. Handles splitting the {{pspan|message}} into multiple messages if the number of item types in {{pspan|goodies}} is too large. Returns the result of send_gift() if the intended {{pspan|recipient}} is unable to receive the {{pspan|message}} due to being in HC or somesuch. Note that you can also specify the {{pspan|inside_note}} to be used inside gifts in that case. Use "\n" to specify a new line in the {{pspan|message}}.<br />
<br />
[[Category:Scripting]][[Category:ASH Function Libraries]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Drink&diff=9072Drink2021-07-13T14:33:30Z<p>Philmasterplus: Add Template:SeeAlso/Booze Management</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=drink<br />
|function1.return_type=boolean<br />
|function1.description=Attempts to drink the {{pspan|booze}} item(s).<br />
|function1.param1=booze<br />
|function1.param1.type=item<br />
|function1.param1.description=Item to drink<br />
|function1.param2=qty<br />
|function1.param2.type=int<br />
|function1.param2.description=Amount to drink<br />
|function1.param2.optional=yes<br />
|function1.param2.default=1<br />
|function2.return_type=boolean<br />
|function2.description=Attempts to drink {{pspan|qty}} of {{pspan|booze}}.<br />
|function2.param1=qty<br />
|function2.param1.type=int<br />
|function2.param1.description=Amount to drink<br />
|function2.param2=booze<br />
|function2.param2.type=item<br />
|function2.param2.description=Item to drink<br />
|description=<p>Attempts to drink {{pspan|qty}} amount of the {{pspan|booze}} item. Returns <code>true</code> for drinkable items and <code>false</code> for items that are not. (The return value does not reflect whether or not the items were actually consumed.)</p><br />
<br />
<p>You can also "drink" drink helper items (e.g. {{kolwiki|divine champagne flute}}) to queue them before drinking the actual booze item. Drink helpers can be identified with {{f|item_type}}, which returns <code>"drink helper"</code> for such items. To cancel all queued drink helpers, call {{f|clear_booze_helper}}.</p><br />
<br />
<p>If this command will cause you to overdrink, KoLmafia will show a warning dialog. Using this command without Ode to Booze active will also show a warning, if you have the skill and the MP required to cast it.</p><br />
|code1={{CodeSample|<br />
title=Code Sample|<br />
description=Drinks as many tangaritas as possible without getting drunk.|<br />
code={{{!}} class="wikitable" style="margin: auto"<br />
! ASH !! JavaScript<br />
{{!}}-<br />
{{!}}<br />
<syntaxhighlight lang="d" line highlight="2"><br />
int amount = floor((inebriety_limit() - my_inebriety()) / 4);<br />
drink(amount, $item[tangarita]);<br />
</syntaxhighlight><br />
{{!}}<br />
<syntaxhighlight lang="javascript" line highlight="4"><br />
const { drink, inebrietyLimit, myInebriety } = require("kolmafia");<br />
<br />
const amount = Math.floor((inebrietyLimit() - myInebriety()) / 4);<br />
drink(amount, Item.get('tangarita'));<br />
</syntaxhighlight><br />
{{!}}}<br />
}}<br />
|cli_equiv=The CLI command <code>drink</code> works similarly.<br />
|see_also={{SeeAlso/Booze Management}}<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Clear_booze_helper&diff=9071Clear booze helper2021-07-13T14:33:26Z<p>Philmasterplus: Add Template:SeeAlso/Booze Management</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=clear_booze_helper<br />
|function1.return_type=void<br />
|function1.description=Clears all queued booze helper items.<br />
|description=<p>Clears all booze helper items that were queued with {{f|drink}}. This allows you to cancel a booze helper and possible queue another one.</p><br />
<br />
<p>This function was added in [https://kolmafia.us/threads/20796-add-runtime-library-functions-clear_food_helper-and-clear_booze_helper.26203/ r20796].</p><br />
|see_also={{SeeAlso/Booze Management}}<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Eat&diff=9070Eat2021-07-13T14:32:22Z<p>Philmasterplus: Add Template:SeeAlso/Food Management</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=eat<br />
|function1.return_type=boolean<br />
|function1.description=Attempts to eat the {{pspan|food}} item(s).<br />
|function1.param1=food<br />
|function1.param1.type=item<br />
|function1.param1.description=Item to eat<br />
|function1.param2=qty<br />
|function1.param2.type=int<br />
|function1.param2.description=Amount to eat<br />
|function1.param2.optional=yes<br />
|function1.param2.default=1<br />
|function2.return_type=boolean<br />
|function2.description=Attempts to eat {{pspan|qty}} of {{pspan|item}}.<br />
|function2.param1=qty<br />
|function2.param1.type=int<br />
|function2.param1.description=Amount to eat<br />
|function2.param2=food<br />
|function2.param2.type=item<br />
|function2.param2.description=Item to eat<br />
|description=<p>Attempts to eat {{pspan|qty}} amount of the {{pspan|food}} item. Returns <code>true</code> for edible items and <code>false</code> for items that are not. (The return value does not reflect whether or not the items were actually consumed.)</p><br />
<br />
<p>You can also "eat" food helper items (e.g. {{kolwiki|Ol' Scratch's salad fork}}) to queue them before eating the actual food item. Food helpers can be identified with {{f|item_type}}, which returns <code>"food helper"</code> for such items. To cancel all queued food helpers, call {{f|clear_food_helper}}.</p><br />
<br />
<p>If you can use {{kolwiki|milk of magnesium}} but haven't used one yet, this command will show a warning dialog.</p><br />
|code1={{CodeSample|<br />
title=Code Sample|<br />
description=Eats as many olive lo meins as possible.|<br />
code={{{!}} class="wikitable" style="margin: auto"<br />
! ASH !! JavaScript<br />
{{!}}-<br />
{{!}}<br />
<syntaxhighlight lang="d" line highlight="2"><br />
int amount = (fullness_limit() - my_fullness()) / 3;<br />
eat(amount, $item[olive lo mein]);<br />
</syntaxhighlight><br />
{{!}}<br />
<syntaxhighlight lang="javascript" line highlight="4"><br />
const { eat, fullnessLimit, myFullness } = require("kolmafia");<br />
<br />
const amount = Math.floor((fullnessLimit() - myFullness()) / 4);<br />
drink(amount, Item.get('olive lo mein'));<br />
</syntaxhighlight><br />
{{!}}}<br />
}}<br />
|cli_equiv=The CLI command <code>eat</code> works similarly.<br />
|see_also={{SeeAlso/Food Management}}<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Clear_food_helper&diff=9069Clear food helper2021-07-13T14:31:52Z<p>Philmasterplus: Add Template:SeeAlso/Food Management</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=clear_food_helper<br />
|function1.return_type=void<br />
|function1.description=Clears all queued food helper items.<br />
|description=<p>Clears all food helper items that were queued with {{f|eat}}. This allows you to cancel a food helper and possibly queue another one.</p><br />
<br />
<p>This function was added in [https://kolmafia.us/threads/20796-add-runtime-library-functions-clear_food_helper-and-clear_booze_helper.26203/ r20796].</p><br />
|see_also={{SeeAlso/Food Management}}<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Template:SeeAlso/Booze_Management&diff=9068Template:SeeAlso/Booze Management2021-07-13T14:31:02Z<p>Philmasterplus: Created page with "<onlyinclude>{{SeeAlso|can_drink|clear_booze_helper|drink|drinksilent|overdrink}}</onlyinclude>Category:SeeAlso Templates"</p>
<hr />
<div><onlyinclude>{{SeeAlso|can_drink|clear_booze_helper|drink|drinksilent|overdrink}}</onlyinclude>[[Category:SeeAlso Templates]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Template:SeeAlso/Food_Management&diff=9067Template:SeeAlso/Food Management2021-07-13T14:30:28Z<p>Philmasterplus: Created page with "<onlyinclude>{{SeeAlso|can_eat|clear_food_helper|eat|eatsilent}}</onlyinclude>Category:SeeAlso Templates"</p>
<hr />
<div><onlyinclude>{{SeeAlso|can_eat|clear_food_helper|eat|eatsilent}}</onlyinclude>[[Category:SeeAlso Templates]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Ash_Functions&diff=9066Ash Functions2021-07-13T14:28:06Z<p>Philmasterplus: /* c */ Add clear_booze_helper(), clear_food_helper()</p>
<hr />
<div>{{TOCright}}<br />
Master list of all ASH functions. All functions as of r20745 are listed; this list is intended to be kept current, but it is possible that some functions added since the above revision may be missing. (Please feel free to add in any you notice.)<br />
The CLI command "[[ashref]]" shows every implemented ash function for your mafia version.<br />
===a===<br />
{{FunctionEmbed|abort|format=signature}}<br />
{{FunctionEmbed|add_item_condition|format=signature}}<br />
{{Flink|boolean|adv1|location|{{opt|int}}|{{opt|string}}}}<br />
{{Flink|int|adv_cost|skill}}<br />
{{Flink|boolean|adventure|int|location|{{opt|string}}}}<br />
{{Flink|boolean|adventure|location|int|{{opt|string}}}}<br />
{{FunctionEmbed|all_monsters_with_id|format=signature}}<br />
{{Flink|string [int]|all_normal_outfits}}<br />
{{Flink|float [monster]|appearance_rates|location|{{opt|boolean}}}}<br />
{{Flink|buffer|append|buffer|string}}<br />
{{Flink|buffer|append_replacement|matcher|buffer|string}}<br />
{{Flink|buffer|append_tail|matcher|buffer}}<br />
{{Flink|buffer|attack}}<br />
{{Flink|boolean|autosell|int|item}}<br />
{{Flink|boolean|autosell|item|int}}<br />
{{Flink|int|autosell_price|item}}<br />
{{Flink|int|available_amount|item}}<br />
{{FunctionEmbed|available_choice_options}}<br />
{{Flink|string [string, string]|available_choice_select_inputs|int}}<br />
{{Flink|string [string]|available_choice_text_inputs|int}}<br />
{{Flink|int|available_pocket|monster}}<br />
{{Flink|int|available_pocket|effect}}<br />
{{Flink|int|available_pocket|item}}<br />
{{Flink|int|available_pocket|stat}}<br />
<br />
===b===<br />
{{Flink|boolean|batch_close}}<br />
{{Flink|void|batch_open}}<br />
{{Flink|boolean|bjornify_familiar|familiar}}<br />
{{Flink|boolean|black_market_available}}<br />
{{Flink|boolean|boolean_modifier|{{opt|string}}|string}}<br />
{{Flink|boolean|boolean_modifier|effect|string}}<br />
{{Flink|boolean|boolean_modifier|item|string}}<br />
{{Flink|int|buffed_hit_stat}}<br />
{{FunctionEmbed|buffer_to_file|format=signature}}<br />
{{Flink|boolean|buy|coinmaster|item}}<br />
{{Flink|boolean|buy|{{opt|coinmaster}}|int|item}}<br />
{{Flink|boolean|buy|item|{{opt|int}}|{{opt|int}}}}<br />
{{Flink|int|buy|int|item|int}}<br />
{{Flink|int|buy_price|coinmaster|item}}<br />
{{Flink|boolean|buy_using_storage|int|item}}<br />
{{Flink|int|buy_using_storage|int|item|int}}<br />
{{Flink|int|buy_using_storage|item|int|int}}<br />
{{Flink|boolean|buys_item|coinmaster|item}}<br />
<br />
===c===<br />
{{Flink|boolean|can_drink}}<br />
{{Flink|boolean|can_eat}}<br />
{{Flink|boolean|can_equip|familiar|{{opt|item}}}}<br />
{{Flink|boolean|can_equip|item}}<br />
{{Flink|boolean|can_faxbot|monster}}<br />
{{Flink|boolean|can_interact}}<br />
{{Flink|boolean|can_still_steal}}<br />
{{Flink|boolean|canadia_available}}<br />
{{Flink|item [0]|candy_for_tier|int|{{opt|int}}}}<br />
{{Flink|int|ceil|float}}<br />
{{Flink|boolean|change_mcd|int}}<br />
{{Flink|string|char_at|string|int}}<br />
{{Flink|void|chat_clan|string|{{opt|string}}}}<br />
{{Flink|void|chat_macro|string}}<br />
{{Flink|void|chat_notify|string|string}}<br />
{{Flink|void|chat_private|string|string}}<br />
{{Flink|boolean|chew|int|item}}<br />
{{Flink|boolean|chew|item|{{opt|int}}}}<br />
{{Flink|boolean|choice_follows_fight}}<br />
{{Flink|class|class_modifier|string|string}}<br />
{{Flink|class|class_modifier|item|string}}<br />
{{Flink|void|clear|aggregate}}<br />
{{FunctionEmbed|clear_booze_helper|format=signature}}<br />
{{FunctionEmbed|clear_food_helper|format=signature}}<br />
{{FunctionEmbed|cli_execute|format=signature}}<br />
{{FunctionEmbed|cli_execute_output|format=signature}}<br />
{{Flink|int|closet_amount|item}}<br />
{{Flink|int|combat_mana_cost_modifier}}<br />
{{Flink|float|combat_rate_modifier}}<br />
{{FunctionEmbed|contains_text|format=signature}}<br />
{{Flink|void|council}}<br />
{{Flink|int|count|aggregate}}<br />
{{Flink|int|craft|string|int|item|item}}<br />
{{Flink|string|craft_type|item}}<br />
{{Flink|int|creatable_amount|item}}<br />
{{Flink|int|creatable_turns|item|{{opt|int}}|{{opt|boolean}}}}<br />
{{Flink|boolean|create|int|item}}<br />
{{Flink|boolean|create|item|{{opt|int}}}}<br />
{{Flink|matcher|create_matcher|string|string}}<br />
{{Flink|stat|current_hit_stat}}<br />
{{Flink|int|current_mcd}}<br />
{{Flink|int [string]|current_pvp_stances}}<br />
{{Flink|int|current_rad_sickness}}<br />
{{Flink|int|current_round}}<br />
<br />
===d===<br />
{{Flink|element|dad_sea_monkee_weakness|int}}<br />
{{Flink|item|daily_special}}<br />
{{Flink|float|damage_absorption_percent}}<br />
{{Flink|int|damage_reduction}}<br />
{{Flink|int|date_to_timestamp|string|string}}<br />
{{Flink|void|debugprint|string}}<br />
{{Flink|buffer|delete|buffer|int|int}}<br />
{{Flink|effect|desc_to_effect|string}}<br />
{{Flink|item|desc_to_item|string}}<br />
{{Flink|void|disable|string}}<br />
{{Flink|boolean|dispensary_available}}<br />
{{Flink|int|display_amount|item}}<br />
{{FunctionEmbed|drink|format=signature}}<br />
{{Flink|boolean|drinksilent|int|item}}<br />
{{Flink|boolean|drinksilent|item|{{opt|int}}}}<br />
{{Flink|void|dump|any|{{opt|string}}}}<br />
<br />
===e===<br />
{{FunctionEmbed|eat|format=signature}}<br />
{{Flink|boolean|eatsilent|int|item}}<br />
{{Flink|boolean|eatsilent|item|{{opt|int}}}}<br />
{{Flink|effect|effect_modifier|string|string}}<br />
{{Flink|effect|effect_modifier|item|string}}<br />
{{Flink|boolean [int]|effect_pockets}}<br />
{{Flink|float|elemental_resistance|{{opt|element}}}}<br />
{{Flink|float|elemental_resistance|monster}}<br />
{{Flink|boolean|empty_closet}}<br />
{{Flink|void|enable|string}}<br />
{{Flink|int|end|matcher|{{opt|int}}}}<br />
{{FunctionEmbed|ends_with|format=signature}}<br />
{{Flink|boolean|enthrone_familiar|familiar}}<br />
{{Flink|string|entity_decode|string}}<br />
{{Flink|string|entity_encode|string}}<br />
{{Flink|boolean|equip|item|{{opt|slot}}}}<br />
{{Flink|boolean|equip|slot|item}}<br />
{{Flink|boolean|equip_all_familiars}}<br />
{{Flink|int|equipped_amount|item}}<br />
{{Flink|item|equipped_item|slot}}<br />
{{Flink|string|eudora}}<br />
{{Flink|boolean|eudora|string}}<br />
{{Flink|string|every_card_name|strict_string}}<br />
{{Flink|int|expected_damage|{{opt|monster}}}}<br />
{{Flink|float|experience_bonus}}<br />
{{Flink|float|expression_eval|string}}<br />
{{Flink|int [item]|extract_items|string}}<br />
{{Flink|int|extract_meat|string}}<br />
<br />
===f===<br />
{{Flink|item|familiar_equipment|familiar}}<br />
{{Flink|item|familiar_equipped_equipment|familiar}}<br />
{{Flink|int|familiar_weight|familiar}}<br />
{{Flink|boolean [familiar]|favorite_familiars|}}<br />
{{Flink|boolean|faxbot|monster|{{opt|string}}}}<br />
{{Flink|boolean|fight_follows_choice}}<br />
{{FunctionEmbed|file_to_array|format=signature}}<br />
{{FunctionEmbed|file_to_buffer|format=signature}}<br />
{{Flink|boolean|file_to_map|string|aggregate|{{opt|boolean}}}}<br />
{{Flink|boolean|find|matcher}}<br />
{{Flink|int|floor|float}}<br />
{{Flink|boolean|florist_available}}<br />
{{Flink|boolean|flush_monster_manuel_cache}}<br />
{{Flink|string|form_field|string}}<br />
{{Flink|string [string]|form_fields}}<br />
{{Flink|string|format_date_time|string|string|string}}<br />
{{Flink|boolean|friars_available}}<br />
{{Flink|int|fuel_cost|skill}}<br />
{{Flink|int|fullness_limit}}<br />
<br />
===g===<br />
{{Flink|int|gameday_to_int}}<br />
{{Flink|string|gameday_to_string}}<br />
{{Flink|int|gametime_to_int}}<br />
{{Flink|boolean [string] |get_all_properties|string|boolean}}<br />
{{Flink|int|get_auto_attack}}<br />
{{Flink|int [item]|get_campground}}<br />
{{Flink|string |get_ccs_action|int}}<br />
{{Flink|int [item]|get_chateau}}<br />
{{Flink|int|get_clan_id}}<br />
{{Flink|int [item]|get_clan_lounge}}<br />
{{Flink|string|get_clan_name}}<br />
{{Flink|int [string]|get_clan_rumpus}}<br />
{{Flink|int [item]|get_closet}}<br />
{{Flink|string|get_counters|string|int|int}}<br />
{{Flink|string [int]|get_custom_outfits}}<br />
{{Flink|item|get_dwelling}}<br />
{{Flink|string [location, 3]|get_florist_plants}}<br />
{{Flink|int [item]|get_free_pulls}}<br />
{{Flink|int|get_fuel}}<br />
{{Flink|string [int]|get_goals}}<br />
{{Flink|boolean|get_ignore_zone_warnings}}<br />
{{Flink|int [item]|get_ingredients|item}}<br />
{{Flink|int [item]|get_inventory}}<br />
{{Flink|boolean [monster]|get_location_monsters|location}}<br />
{{Flink|monster [monster]|get_monster_mapping|{{opt|string}}}}<br />
{{Flink|monster [int]|get_monsters|location}}<br />
{{Flink|string [int]|get_moods}}<br />
{{Flink|string [int]|get_outfits}}<br />
{{Flink|string|get_path}}<br />
{{Flink|string|get_path_full}}<br />
{{Flink|string|get_path_variables}}<br />
{{Flink|string|get_player_id|string}}<br />
{{Flink|string|get_player_name|int}}<br />
{{Flink|int|get_power|item}}<br />
{{Flink|string|get_property|string|{{opt|boolean}}}}<br />
{{Flink|int [item]|get_related|item|string}}<br />
{{Flink|int|get_revision}}<br />
{{Flink|int [item]|get_shop}}<br />
{{Flink|string [0]|get_shop_log}}<br />
{{Flink|string string int [0]|get_stack_trace}}<br />
{{Flink|int [item]|get_stash}}<br />
{{Flink|int [item]|get_storage}}<br />
{{Flink|string|get_version}}<br />
{{Flink|string|get_workshed}}<br />
{{Flink|boolean|gnomads_available}}<br />
{{Flink|boolean|goal_exists|string}}<br />
{{Flink|string|group|matcher|{{opt|int}}}}<br />
{{Flink|string|group|matcher|string}}<br />
{{Flink|int|group_count|matcher}}<br />
{{Flink|boolean [string]|group_names|matcher}}<br />
{{Flink|string [int, int]|group_string|string|string}}<br />
{{Flink|boolean|guild_available}}<br />
{{Flink|boolean|guild_store_available}}<br />
<br />
===h===<br />
{{Flink|boolean|handling_choice}}<br />
{{Flink|boolean|have_bartender}}<br />
{{Flink|boolean|have_chef}}<br />
{{Flink|boolean|have_display}}<br />
{{Flink|int|have_effect|effect}}<br />
{{Flink|boolean|have_equipped|item}}<br />
{{Flink|boolean|have_familiar|familiar}}<br />
{{Flink|boolean|have_mushroom_plot}}<br />
{{Flink|boolean|have_outfit|string}}<br />
{{Flink|boolean|have_servant|servant}}<br />
{{Flink|boolean|have_shop}}<br />
{{Flink|boolean|have_skill|skill}}<br />
{{Flink|boolean|hedge_maze|string}}<br />
{{Flink|boolean|hermit|int|item}}<br />
{{Flink|boolean|hermit|item|int}}<br />
{{Flink|boolean|hidden_temple_unlocked}}<br />
{{Flink|boolean|hippy_stone_broken}}<br />
{{Flink|boolean|hippy_store_available}}<br />
{{FunctionEmbed|historical_age}}<br />
{{FunctionEmbed|historical_price}}<br />
{{Flink|string|holiday}}<br />
{{Flink|int|hp_cost|skill}}<br />
<br />
===i===<br />
{{Flink|monster|image_to_monster|strict_string}}<br />
{{Flink|boolean|in_bad_moon}}<br />
{{Flink|boolean|in_hardcore}}<br />
{{Flink|boolean|in_moxie_sign}}<br />
{{Flink|boolean|in_multi_fight}}<br />
{{Flink|boolean|in_muscle_sign}}<br />
{{Flink|boolean|in_mysticality_sign}}<br />
{{Flink|string|inaccessible_reason|coinmaster}}<br />
{{FunctionEmbed|index_of|format=signature}}<br />
{{Flink|int|inebriety_limit}}<br />
{{Flink|float|initiative_modifier}}<br />
{{Flink|buffer|insert|buffer|int|string}}<br />
{{Flink|boolean|is_accessible|coinmaster}}<br />
{{Flink|boolean|is_banished|monster}}<br />
{{Flink|boolean|is_coinmaster_item|item}}<br />
{{FunctionEmbed|is_dark_mode}}<br />
{{Flink|boolean|is_discardable|item}}<br />
{{Flink|boolean|is_displayable|item}}<br />
{{Flink|boolean|is_familiar_equipment_locked}}<br />
{{Flink|boolean|is_giftable|item}}<br />
{{Flink|boolean|is_goal|item}}<br />
{{Flink|boolean|is_integer|string}}<br />
{{Flink|boolean|is_npc_item|item}}<br />
{{Flink|boolean|is_online|string}}<br />
{{Flink|boolean|is_tradeable|item}}<br />
{{Flink|boolean|is_trendy|item/familiar/skill/string}}<br />
{{Flink|boolean|is_unrestricted|item/familiar/skill/string}}<br />
{{Flink|boolean|is_wearing_outfit|string}}<br />
{{Flink|int|item_amount|item}}<br />
{{Flink|float|item_drop_modifier}}<br />
{{Flink|int [item]|item_drops|{{opt|monster}}}}<br />
{{Flink|item int string [int]|item_drops_array|{{opt|monster}}}}<br />
{{Flink|boolean [int]|item_pockets}}<br />
{{Flink|string|item_type|item}}<br />
<br />
===j===<br />
{{Flink|boolean [int]|joke_pockets}}<br />
{{flink|int|jump_chance|{{opt|monster}}|{{opt|int}}|{{opt|int}}}}<br />
{{flink|int|jump_chance|location|{{opt|int}}|{{opt|int}}}}<br />
<br />
===k===<br />
{{flink|boolean|knoll_available}}<br />
<br />
===l===<br />
{{Flink|int|last_choice}}<br />
{{Flink|int|last_decision}}<br />
{{FunctionEmbed|last_index_of|format=signature}}<br />
{{Flink|string|last_item_message}}<br />
{{Flink|monster|last_monster}}<br />
{{Flink|string|last_skill_message}}<br />
{{Flink|string|leetify|string}}<br />
{{Flink|int|length|string}}<br />
{{Flink|int|lightning_cost|skill}}<br />
{{Flink|string|limit_mode}}<br />
{{Flink|buffer|load_html|string}}<br />
{{Flink|void|lock_familiar_equipment|boolean}}<br />
{{Flink|float|log_n|float|{{opt|float}}}}<br />
{{Flink|void|logprint|string}}<br />
<br />
===m===<br />
{{Flink|string|make_url|string|boolean|boolean}}<br />
{{FunctionEmbed|mall_price}}<br />
{{FunctionEmbed|mall_prices}}<br />
{{Flink|int|mana_cost_modifier}}<br />
{{Flink|boolean|map_to_file|aggregate|string|{{opt|boolean}}}}<br />
{{Flink|float|max|float ...}}<br />
{{Flink|int|max|int ...}}<br />
{{Flink|boolean|maximize|string|boolean}}<br />
{{Flink|boolean|maximize|string|int|int|boolean}}<br />
{{Flink|{string string float effect item skill} [int]|maximize|string|int|int|boolean|boolean}}<br />
{{Flink|int|meat_drop|{{opt|monster}}}}<br />
{{Flink|float|meat_drop_modifier}}<br />
{{Flink|int [int]|meat_pockets}}<br />
{{Flink|float|min|float ...}}<br />
{{Flink|int|min|int ...}}<br />
{{Flink|item|minstrel_instrument}}<br />
{{Flink|int|minstrel_level}}<br />
{{Flink|boolean|minstrel_quest}}<br />
{{Flink|float|modifier_eval|string}}<br />
{{Flink|int|monster_attack|{{opt|monster}}}}<br />
{{Flink|int|monster_defense|{{opt|monster}}}}<br />
{{Flink|element|monster_element|{{opt|monster}}}}<br />
{{Flink|float|monster_eval|string}}<br />
{{Flink|int|monster_factoids_available|monster|boolean}}<br />
{{Flink|int|monster_hp|{{opt|monster}}}}<br />
{{Flink|int|monster_initiative|{{opt|monster}}}}<br />
{{Flink|int|monster_level_adjustment}}<br />
{{Flink|string|monster_manuel_text|monster}}<br />
{{Flink|phylum|monster_phylum|{{opt|monster}}}}<br />
{{Flink|boolean [int]|monster_pockets}}<br />
{{Flink|void|mood_execute|int}}<br />
{{Flink|string [0]|mood_list}}<br />
{{Flink|int|moon_light}}<br />
{{Flink|int|moon_phase}}<br />
{{Flink|int|mp_cost|skill}}<br />
{{Flink|int|my_absorbs}}<br />
{{Flink|int|my_adventures}}<br />
{{Flink|int|my_ascensions}}<br />
{{Flink|int|my_audience}}<br />
{{Flink|int|my_basestat|stat}}<br />
{{Flink|familiar|my_bjorned_familiar}}<br />
{{Flink|int|my_buffedstat|stat}}<br />
{{Flink|class|my_class}}<br />
{{Flink|int|my_closet_meat}}<br />
{{Flink|string|my_companion}}<br />
{{Flink|int|my_daycount}}<br />
{{Flink|int|my_discomomentum}}<br />
{{Flink|familiar|my_effective_familiar}}<br />
{{Flink|int [effect]|my_effects}}<br />
{{Flink|familiar|my_enthroned_familiar}}<br />
{{Flink|familiar|my_familiar}}<br />
{{Flink|int|my_fullness}}<br />
{{Flink|int|my_fury}}<br />
{{Flink|string|my_garden_type}}<br />
{{Flink|string|my_hash}}<br />
{{Flink|int|my_hp}}<br />
{{Flink|string|my_id}}<br />
{{Flink|int|my_inebriety}}<br />
{{Flink|int|my_level}}<br />
{{Flink|int|my_lightning}}<br />
{{Flink|location|my_location}}<br />
{{Flink|string|my_mask}}<br />
{{Flink|int|my_maxfury}}<br />
{{Flink|int|my_maxhp}}<br />
{{Flink|int|my_maxmp}}<br />
{{Flink|int|my_maxpp}}<br />
{{Flink|int|my_meat}}<br />
{{Flink|int|my_mp}}<br />
{{Flink|string|my_name}}<br />
{{Flink|string|my_path}}<br />
{{Flink|int|my_path_id}}<br />
{{Flink|familiar|my_poke_fam|int}}<br />
{{Flink|int|my_pp}}<br />
{{Flink|stat|my_primestat}}<br />
{{Flink|int|my_rain}}<br />
{{Flink|int|my_robot_energy}}<br />
{{Flink|int|my_robot_scraps}}<br />
{{Flink|servant|my_servant}}<br />
{{Flink|int|my_session_adv}}<br />
{{Flink|int [item]|my_session_items}}<br />
{{Flink|int|my_session_items|item}}<br />
{{Flink|int|my_session_meat}}<br />
{{Flink|string|my_sign}}<br />
{{Flink|int|my_soulsauce}}<br />
{{Flink|int|my_spleen_use}}<br />
{{Flink|int|my_storage_meat}}<br />
{{Flink|thrall|my_thrall}}<br />
{{Flink|int|my_thunder}}<br />
{{Flink|int|my_turncount}}<br />
{{Flink|vykea|my_vykea_companion}}<br />
<br />
===n===<br />
{{Flink|int|now_to_int}}<br />
{{Flink|string|now_to_string|string}}<br />
{{Flink|int|npc_price|item}}<br />
{{Flink|string|numberology_prize|int}}<br />
{{Flink|float|numeric_modifier|effect|string}}<br />
{{Flink|float|numeric_modifier|familiar|string|int|item}}<br />
{{Flink|float|numeric_modifier|item|string}}<br />
{{Flink|float|numeric_modifier|skill|string}}<br />
{{Flink|float|numeric_modifier|{{opt|string}}|string}}<br />
<br />
===o===<br />
{{Flink|boolean|outfit|string}}<br />
{{Flink|item [int]|outfit_pieces|string}}<br />
{{Flink|string|outfit_tattoo|{{opt|string}}}}<br />
{{FunctionEmbed|overdrink|format=signature}}<br />
<br />
===p===<br />
{{Flink|string|path_id_to_name|int}}<br />
{{Flink|int|path_name_to_id|string}}<br />
{{Flink|boolean|pick_pocket|monster}}<br />
{{Flink|int [effect]|pick_pocket|effect}}<br />
{{Flink|int [item]|pick_pocket|item}}<br />
{{Flink|int [stat]|pick_pocket|stat}}<br />
{{Flink|boolean|pick_pocket|int}}<br />
{{Flink|boolean [int]|picked_pockets}}<br />
{{Flink|boolean [int]|picked_scraps}}<br />
{{Flink|int [effect]|pocket_effects|int}}<br />
{{Flink|int [item]|pocket_items|int}}<br />
{{Flink|string|pocket_joke|int}}<br />
{{Flink|string [int]|pocket_meat|int}}<br />
{{Flink|monster|pocket_monster|int}}<br />
{{Flink|string [int]|pocket_poem|int}}<br />
{{Flink|string [int]|pocket_scrap|int}}<br />
{{Flink|int [stat]|pocket_stats|int}}<br />
{{Flink|int [int]|poem_pockets}}<br />
{{Flink|int [int]|potential_pockets|effect/item/monster/stat}}<br />
{{Flink|void|print|{{opt|string}}|{{opt|string}}}}<br />
{{Flink|void|print_html|string}}<br />
{{FunctionEmbed|property_default_value|format=signature}}<br />
{{FunctionEmbed|property_exists|format=signature}}<br />
{{FunctionEmbed|property_has_default|format=signature}}<br />
{{Flink|int|pulls_remaining}}<br />
{{Flink|boolean|put_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|put_closet|item|{{opt|int}}}}<br />
{{Flink|boolean|put_display|int|item}}<br />
{{Flink|boolean|put_display|item|int}}<br />
{{Flink|boolean|put_shop|int|int|{{opt|int}}|item}}<br />
{{Flink|boolean|put_shop_using_storage|int|int|{{opt|int}}|item}}<br />
{{Flink|boolean|put_stash|int|item}}<br />
{{Flink|boolean|put_stash|item|int}}<br />
{{Flink|int|pvp_attacks_left}}<br />
<br />
===r===<br />
{{Flink|int|rain_cost|skill}}<br />
{{Flink|int|random|int}}<br />
{{Flink|int|raw_damage_absorption}}<br />
{{Flink|boolean|refresh_shop}}<br />
{{Flink|boolean|refresh_stash}}<br />
{{Flink|boolean|refresh_status}}<br />
{{Flink|void|remove_item_condition|int|item}}<br />
{{Flink|void|remove_item_condition|item|int}}<br />
{{FunctionEmbed|remove_property|format=signature}}<br />
{{FunctionEmbed|rename_property|format=signature}}<br />
{{Flink|boolean|replace|buffer|int|int|string}}<br />
{{Flink|string|replace_all|matcher|string}}<br />
{{Flink|string|replace_first|matcher|string}}<br />
{{Flink|buffer|replace_string|buffer|string|string}}<br />
{{Flink|buffer|replace_string|string|string|string}}<br />
{{Flink|boolean|reprice_shop|int|{{opt|int}}|item}}<br />
{{Flink|matcher|reset|matcher|{{opt|string}}}}<br />
{{Flink|boolean [int]|restoration_pockets}}<br />
{{Flink|boolean|restore_hp|int}}<br />
{{Flink|boolean|restore_mp|int}}<br />
{{Flink|boolean|retrieve_item|int|item}}<br />
{{Flink|boolean|retrieve_item|item|{{opt|int}}}}<br />
{{Flink|int [int]|reverse_numberology|{{opt|int|int}}}}<br />
{{Flink|int|rollover}}<br />
{{Flink|int|round|float}}<br />
{{FunctionEmbed|run_choice|format=signature}}<br />
{{Flink|buffer|run_combat|{{opt|string}}}}<br />
{{Flink|buffer|run_turn}}<br />
{{Flink|buffer|runaway}}<br />
<br />
===s===<br />
{{Flink|int [int]|scrap_pockets}}<br />
{{Flink|boolean|sell|coinmaster|int|item}}<br />
{{Flink|int|sell_price|coinmaster|item}}<br />
{{Flink|boolean|sells_item|coinmaster|item}}<br />
{{Flink|string [int]|session_logs|{{opt|string}}|{{opt|string}}|int}}<br />
{{Flink|void|set_auto_attack|int/string}}<br />
{{Flink|void|set_length|buffer|int}}<br />
{{Flink|void|set_location|location}}<br />
{{Flink|void|set_property|string|string}}<br />
{{Flink|int|shop_amount|item}}<br />
{{Flink|int|shop_limit|item}}<br />
{{Flink|int|shop_price|item}}<br />
{{Flink|skill|skill_modifier|item|string}}<br />
{{Flink|skill|skill_modifier|string|string}}<br />
{{Flink|int|slash_count|item}}<br />
{{Flink|int|soulsauce_cost|skill}}<br />
{{Flink|int|spleen_limit}}<br />
{{Flink|string [int]|split_string|string|{{opt|string}}}}<br />
{{Flink|float|square_root|float}}<br />
{{Flink|int|start|matcher|{{opt|int}}}}<br />
{{FunctionEmbed|starts_with|format=signature}}<br />
{{Flink|int|stash_amount|item}}<br />
{{Flink|stat|stat_bonus_today}}<br />
{{Flink|stat|stat_bonus_tomorrow}}<br />
{{Flink|stat|stat_modifier|effect|string}}<br />
{{Flink|buffer|steal}}<br />
{{Flink|int|stills_available}}<br />
{{Flink|void|stop_counter|string}}<br />
{{Flink|int|storage_amount|item}}<br />
{{Flink|string|string_modifier|{{opt|string}}|string}}<br />
{{Flink|skill|stun_skill}}<br />
{{Flink|string|substring|string|int|{{opt|int}}}}<br />
{{Flink|boolean|svn_at_head|string}}<br />
{{Flink|boolean|svn_exists|string}}<br />
{{Flink|{string int string int string}|svn_info|string}}<br />
{{Flink|boolean|sweet_synthesis|effect|{{opt|int}}}}<br />
{{Flink|boolean|sweet_synthesis|int|effect|{{opt|int}}}}<br />
{{Flink|boolean|sweet_synthesis|{{opt|int}}|item|item}}<br />
{{Flink|item [0]|sweet_synthesis_pair|effect|{{opt|item}}|{{opt|int}}}}<br />
{{Flink|effect|sweet_synthesis_result|item|item}}<br />
<br />
===t===<br />
{{Flink|boolean|take_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|take_closet|item|{{opt|int}}}}<br />
{{Flink|boolean|take_display|int|item}}<br />
{{Flink|boolean|take_display|item|int}}<br />
{{Flink|boolean|take_shop|{{opt|int}}|item}}<br />
{{Flink|boolean|take_stash|int|item}}<br />
{{Flink|boolean|take_stash|item|int}}<br />
{{Flink|boolean|take_storage|int|item}}<br />
{{Flink|boolean|take_storage|item|int}}<br />
{{Flink|int|tavern|{{opt|string}}}}<br />
{{Flink|buffer|throw_item|item}}<br />
{{Flink|buffer|throw_items|item|item}}<br />
{{Flink|int|thunder_cost|skill}}<br />
{{Flink|string|time_to_string}}<br />
{{Flink|string|timestamp_to_date|int|string}}<br />
{{Flink|boolean|to_boolean|any}}<br />
{{Flink|bounty|to_bounty|strict_string}}<br />
{{Flink|class|to_class|strict_string/int}}<br />
{{Flink|coinmaster|to_coinmaster|strict_string}}<br />
{{Flink|effect|to_effect|int/skill/strict_string}}<br />
{{Flink|element|to_element|strict_string}}<br />
{{Flink|familiar|to_familiar|int/strict_string}}<br />
{{Flink|float|to_float|any}}<br />
{{Flink|int|to_int|any}}<br />
{{Flink|item|to_item|int/strict_string}}<br />
{{Flink|item|to_item|string|int}}<br />
{{Flink|string|to_json|aggregate}}<br />
{{Flink|location|to_location|int/strict_string}}<br />
{{Flink|string|to_lower_case|string}}<br />
{{Flink|monster|to_monster|int/strict_string}}<br />
{{Flink|phylum|to_phylum|string}}<br />
{{Flink|string|to_plural|item}}<br />
{{Flink|servant|to_servant|int/strict_string}}<br />
{{Flink|skill|to_skill|effect/int}}<br />
{{Flink|skill|to_skill|strict_string|{{opt|strict_string}}}}<br />
{{Flink|slot|to_slot|item/strict_string}}<br />
{{Flink|stat|to_stat|strict_string}}<br />
{{Flink|string|to_string|any}}<br />
{{Flink|thrall|to_thrall|int/strict_string}}<br />
{{Flink|string|to_upper_case|string}}<br />
{{Flink|string|to_url|location}}<br />
{{Flink|vykea|to_vykea|strict_string}}<br />
{{Flink|string|today_to_string}}<br />
{{Flink|int|total_free_rests}}<br />
{{Flink|int|total_turns_played}}<br />
{{Flink|boolean|tower_door}}<br />
{{Flink|void|traceprint|string}}<br />
{{Flink|int|truncate|float}}<br />
{{Flink|int|turns_per_cast|skill}}<br />
{{Flink|int|turns_played}}<br />
{{Flink|buffer|twiddle}}<br />
<br />
===u===<br />
{{Flink|item|unusual_construct_disc}}<br />
{{Flink|void|update_candy_prices}}<br />
{{Flink|string|url_decode|string}}<br />
{{Flink|string|url_encode|string}}<br />
{{Flink|boolean|use|int|item}}<br />
{{Flink|boolean|use|item|{{opt|int}}}}<br />
{{Flink|boolean|use_familiar|familiar}}<br />
{{Flink|boolean|use_servant|servant}}<br />
{{Flink|boolean|use_skill|int|skill|{{opt|string}}}}<br />
{{Flink|boolean|use_skill|skill|int|{{opt|string}}}}<br />
{{Flink|buffer|use_skill|skill}}<br />
{{Flink|boolean|user_confirm|string}}<br />
{{Flink|boolean|user_confirm|string|int|boolean}}<br />
<br />
===v===<br />
{{Flink|boolean|visit|coinmaster}}<br />
{{FunctionEmbed|visit_url}}<br />
{{Flink|boolean [string]|voting_booth_initiatives|class|int|int}}<br />
{{Flink|boolean [string]|voting_booth_initiatives|int|int|int}}<br />
<br />
===w===<br />
{{Flink|void|wait|int}}<br />
{{Flink|void|waitq|int}}<br />
{{Flink|int|weapon_hands|item}}<br />
{{Flink|stat|weapon_type|item}}<br />
{{Flink|int|weight_adjustment}}<br />
{{Flink|boolean|white_citadel_available}}<br />
{{Flink|boolean [string]|who_clan}}<br />
{{Flink|boolean|will_usually_dodge}}<br />
{{Flink|boolean|will_usually_miss}}<br />
{{Flink|void|write|string}}<br />
{{Flink|void|writeln|string}}<br />
<br />
===x===<br />
{{Flink|string[int]|xpath|string|string}}<br />
<br />
[[Category:Scripting]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Item_Management&diff=9065Item Management2021-07-13T14:26:51Z<p>Philmasterplus: /* Acquiring & Using Items */ Add clear_booze_helper(), clear_food_helper()</p>
<hr />
<div>{{TOCright}}<br />
==Informational==<br />
{{Flink|int|my_meat|desc=Returns the amount of meat you have on hand.}}<br />
{{Flink|int|my_closet_meat|desc=Returns the amount of meat you have in your Colossal Closet.}}<br />
{{Flink|int|my_storage_meat|desc=Returns the amount of meat you have in Hagnk's Ancestral Mini-Storage.}}<br />
{{Flink|int|pulls_remaining|desc=Returns the number of pulls you can make from storage, or 0 if not applicable.}}<br />
{{Flink|boolean|have_chef|desc=Returns true if you have a chef-boxen at your campground.}}<br />
{{Flink|boolean|have_bartender|desc=Returns true if you have a bartender-boxen at your campground.}}<br />
{{Flink|int [item]|get_campground|desc=Returns a map of your campground items.}}<br />
{{Flink|int [item]|get_clan_lounge|desc=Returns a map of your Clan VIP Lounge items.}}<br />
{{Flink|item|get_dwelling|desc=Returns the item corresponding with your dwelling.}}<br />
{{Flink|boolean|have_mushroom_plot|desc=Returns true if and only if you've purchased a mushroom plot this run.}}<br />
{{Flink|int|stills_available|desc=Returns the number of Nash Crosby's Still uses left for the day (0 if not accessible).}}<br />
{{Flink|string|item_type|item|desc=Returns the type of item specified.}}<br />
{{Flink|int|item_amount|item}}<br />
{{Flink|int|closet_amount|item}}<br />
{{Flink|int|display_amount|item}}<br />
{{Flink|int|equipped_amount|item}}<br />
{{Flink|int|shop_amount|item}}<br />
{{Flink|int [item]|get_shop|desc=Returns entire contents of shop and quantity of each item}}<br />
{{Flink|int|stash_amount|item|}}<br />
{{Flink|int|storage_amount|item|desc=These 7 functions return the total number available of a given item in the respective section of your inventory.}}<br />
{{Flink|int|available_amount|item|desc=Returns the total number available of a given item in all inventory sections accessible to your character based on current restrictions.}}<br />
{{Flink|int|creatable_amount|item|desc=Returns the amount of the item that you are capable of creating given your current inventory and skills.}}<br />
{{Flink|int [item]|get_ingredients|item|desc=Returns a map where each key is one of the required ingredients, with the integer value the number required. If you don't have the skills needed to make the item, it will return an empty map.}}<br />
{{Flink|string|craft_type|item|desc=Returns a string identifying how an item is crafted and any other requirements for creating it.}}<br />
{{Flink|int [item]|get_inventory|desc=Returns a map where each key is an item in your inventory, with the integer value its quantity.}}<br />
{{Flink|int [item]|get_related|item|string|desc=Returns associated items in a zap or fold group (see page for details).}}<br />
[[File:Item category.png|frame|You can categorize items in KoL using [[is tradeable|is_tradeable()]], [[is giftable|is_giftable()]], and [[is displayable|is_displayable()]].]]<br />
{{Flink|boolean|is_tradeable|item|desc=Returns whether the item can be placed in the mall.}}<br />
{{Flink|boolean|is_giftable|item|desc=Returns whether the item can be traded in a gift package.}}<br />
{{Flink|boolean|is_displayable|item|desc=Returns whether the item can be put in a display case (true for all but quest items).}}<br />
{{Flink|boolean|is_discardable|item|desc=Returns whether the item can be discarded or autosold.}}<br />
{{Flink|boolean|have_shop|desc=Returns whether you have a mall store.}}<br />
{{Flink|boolean|have_display|desc=Returns whether you have a display case.}}<br />
{{Flink|boolean|is_npc_item|item|desc=Returns whether the item can be bought from an NPC store.}}<br />
{{Flink|void|refresh_stash|desc=Takes a new look at the contents of your clan stash, as that section of inventory cannot be internally tracked due to access by others.}}<br />
{{Flink|void|refresh_shop|desc=Takes a new look at the contents of your mall store, as that section of inventory cannot be internally tracked due to access by others.}}<br />
{{Flink|int|shop_price|item|desc=Returns the current price for the given item if it is present in your mall store.}}<br />
{{Flink|int|npc_price|item|desc=Returns the current price of the given item if it can currently be bought from an NPC store.}}<br />
{{Flink|int|autosell_price|item|desc=Returns the autosell price of the item (0 for items that cannot be autosold).}}<br />
{{Flink|int|get_power|item|desc=Returns the power of the item (0 for items that don't have a power).}}<br />
{{Flink|string|to_plural|item|desc=Returns the plural of an item as a string.}}<br />
{{Flink|int|meat_drop|{{opt|monster}}|desc=Returns a certain monster's base meat drop.}}<br />
{{Flink|int [item]|item_drops|{{opt|monster}}|desc=Returns an array of a certain monster's base item drops, keying item to drop rate. Has certain limitations detailed on individual page.}}<br />
{{Flink|record [int]|item_drops_array|{{opt|monster}}|desc=Returns an array of records holding information regarding a certain monster's base item drops.}}<br />
<br />
===Mall Prices===<br />
{{FunctionEmbed|historical_age|desc=yes}}<br />
{{FunctionEmbed|historical_price|desc=yes}}<br />
{{FunctionEmbed|mall_price|desc=yes}}<br />
{{FunctionEmbed|mall_prices|desc=yes}}<br />
<br />
==Moving Items Around==<br />
{{Flink|boolean|empty_closet|desc=Remove every item from the closet in a single server hit.}}<br />
{{Flink|boolean|put_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|put_display|int|item}}<br />
{{Flink|boolean|put_stash|int|item}}<br />
{{Flink|boolean|take_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|take_display|int|item}}<br />
{{Flink|boolean|take_stash|int|item}}<br />
{{Flink|boolean|take_storage|int|item|desc=Attempts to take or put the specified item in the appropriate section of your inventory, and returns its success.<br />If the item parameter is omitted from put_closet() or take_closet(), meat is transferred instead of an item.}}<br />
{{Flink|boolean|put_shop|int|int|{{opt|int}}|item}}<br />
{{Flink|boolean|take_shop|{{opt|int}}|item|desc=Adds or removes items in your store and returns success.}}<br />
<br />
==Acquiring & Using Items==<br />
{{Flink|boolean|autosell|int|item|desc=Attempts to autosell the given items and reports success.}}<br />
{{Flink|boolean|buy|{{opt|coinmaster}}|int|item}}<br />
{{Flink|int|buy|int|item|int|desc=Tries to purchase the specified items.}}<br />
{{Flink|boolean|buy_using_storage|int|item}}<br />
{{Flink|int|buy_using_storage|int|item|int|desc=Tries to purchase the specified items using meat in Hangks.}}<br />
{{FunctionEmbed|clear_booze_helper|desc=yes}}<br />
{{FunctionEmbed|clear_food_helper|desc=yes}}<br />
{{Flink|boolean|create|int|item|desc=Attempts to create the specified items, following your KoLmafia settings regarding purchases to gather ingredients & require boxen.}}<br />
{{FunctionEmbed|drink|desc=yes}}<br />
{{FunctionEmbed|eat|desc=yes}}<br />
{{Flink|boolean|eatsilent|int|item|desc=Attempts to eat items as specified.}}<br />
{{Flink|boolean|chew|int|item|desc=Attempts to chew spleen items as specified and reports success.}}<br />
{{Flink|boolean|hermit|int|item|desc=Trades worthless items (buying and using chewing gum if needed) to the hermit for specified items (see page for details).}}<br />
{{Flink|boolean|use|int|item|desc=Attempts to use items as specified and reports success.}}<br />
{{FunctionEmbed|overdrink|format=signature|desc=yes}}<br />
{{Flink|boolean|retrieve_item|int|item|desc=Uses KoLmafia internal logic to gather items (see page for details).}}<br />
{{Flink|int|craft|string|int|item|item|desc=Raw crafting that obeys KoLmafia settings (see page for details).}}<br />
{{Flink|string|last_item_message|desc=Returns message that KoL reports in the event of error.}}<br />
<br />
==Coinmaster Control==<br />
Some items can be bought from or sold to various "coinmasters" which are like shops that deal in a currency other than meat. These coinmasters include the Dimemaster and Quartermaster during the Island War, the Hermit, the Mr. Store and many others. Some relevant information can be found in [[proxy records]] for the item and coinmaster data types. The rest is controlled by the following functions.<br />
<br />
===Inquiries===<br />
{{Flink|coinmaster|to_coinmaster|string|desc=Converts a string to a valid coinmaster.}}<br />
{{Flink|boolean|is_coinmaster_item|item|desc=Is a given item acquirable from a coinmster.}}<br />
{{Flink|boolean|buys_item|coinmaster|item|desc=Is a specific item acquirable from the named coinmster.}}<br />
{{Flink|int|buy_price|coinmaster|item|desc=What is the coinmaster's purchase price for an item.}}<br />
{{Flink|boolean|sells_item|coinmaster|item|desc=Is a specific item sellable to the named coinmster.}}<br />
{{Flink|int|sell_price|coinmaster|item|desc=What is the coinmaster's selling price for an item.}}<br />
<br />
===Coinmaster transactions===<br />
{{Flink|boolean|is_accessible|coinmaster|desc=Is a given coinmaster currently accessible.}}<br />
{{Flink|string|inaccessible_reason|coinmaster|desc=The reason a given coinmaster is currently inaccessible.}}<br />
{{Flink|boolean|visit|coinmaster|desc=Refreshes information at a coinmaster.}}<br />
{{Flink|boolean|buy|coinmaster|int|item|desc=Buys an item from a coinmaster.}}<br />
{{Flink|boolean|sell|coinmaster|int|item|desc=Sells an item to a coinmaster.}}<br />
<br />
===Sweet Synthesis===<br />
{{Flink|item [int]|candy_for_tier|int|{{opt|int}}|desc=Returns all the candy to create a given tier of effect.}}<br />
{{Flink|item [int]|sweet_synthesis_pairing|effect|item|{{opt|int}}|desc=Find a second candy to synthesize.}}<br />
{{Flink|item [int]|sweet_synthesis_pair|effect|{{opt|int}}|desc=Picks a pair of candies to synthesize for an effect.}}<br />
{{Flink|effect|sweet_synthesis_result|item|item|desc=Show result of synthesis.}}<br />
{{Flink|boolean|sweet_synthesis|item|item|desc=Synthesize specified candies.}}<br />
{{Flink|boolean|sweet_synthesis|effect|{{opt|int}}|desc=Picks a pair of candies and synthesizes them for the effect.}}<br />
<br />
<br />
[[Category:Scripting]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Clear_booze_helper&diff=9064Clear booze helper2021-07-13T14:25:58Z<p>Philmasterplus: Created page with "<onlyinclude>{{{{{format|Function2}}} |name=clear_booze_helper |function1.return_type=void |function1.description=Clears all queued booze helper items. |description=<p>Clears..."</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=clear_booze_helper<br />
|function1.return_type=void<br />
|function1.description=Clears all queued booze helper items.<br />
|description=<p>Clears all booze helper items that were queued with {{f|drink}}. This allows you to cancel a booze helper and possible queue another one.</p><br />
<br />
<p>This function was added in [https://kolmafia.us/threads/20796-add-runtime-library-functions-clear_food_helper-and-clear_booze_helper.26203/ r20796].</p><br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Clear_food_helper&diff=9063Clear food helper2021-07-13T14:23:38Z<p>Philmasterplus: </p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=clear_food_helper<br />
|function1.return_type=void<br />
|function1.description=Clears all queued food helper items.<br />
|description=<p>Clears all food helper items that were queued with {{f|eat}}. This allows you to cancel a food helper and possibly queue another one.</p><br />
<br />
<p>This function was added in [https://kolmafia.us/threads/20796-add-runtime-library-functions-clear_food_helper-and-clear_booze_helper.26203/ r20796].</p><br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Clear_food_helper&diff=9062Clear food helper2021-07-13T14:22:23Z<p>Philmasterplus: Created page with "<onlyinclude>{{{{{format|Function2}}} |name=clear_food_helper |function1.return_type=void |function1.description=Clears all queued food helper items. |description=<p>Clears al..."</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=clear_food_helper<br />
|function1.return_type=void<br />
|function1.description=Clears all queued food helper items.<br />
|description=<p>Clears all food helper items that were queued with {{f|eat}}. This allows </p><br />
<br />
<p>This function was added in [https://kolmafia.us/threads/20796-add-runtime-library-functions-clear_food_helper-and-clear_booze_helper.26203/ r20796].</p><br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Item_Management&diff=9061Item Management2021-07-13T14:19:07Z<p>Philmasterplus: Use Template:FunctionEmbed for drink(), eat()</p>
<hr />
<div>{{TOCright}}<br />
==Informational==<br />
{{Flink|int|my_meat|desc=Returns the amount of meat you have on hand.}}<br />
{{Flink|int|my_closet_meat|desc=Returns the amount of meat you have in your Colossal Closet.}}<br />
{{Flink|int|my_storage_meat|desc=Returns the amount of meat you have in Hagnk's Ancestral Mini-Storage.}}<br />
{{Flink|int|pulls_remaining|desc=Returns the number of pulls you can make from storage, or 0 if not applicable.}}<br />
{{Flink|boolean|have_chef|desc=Returns true if you have a chef-boxen at your campground.}}<br />
{{Flink|boolean|have_bartender|desc=Returns true if you have a bartender-boxen at your campground.}}<br />
{{Flink|int [item]|get_campground|desc=Returns a map of your campground items.}}<br />
{{Flink|int [item]|get_clan_lounge|desc=Returns a map of your Clan VIP Lounge items.}}<br />
{{Flink|item|get_dwelling|desc=Returns the item corresponding with your dwelling.}}<br />
{{Flink|boolean|have_mushroom_plot|desc=Returns true if and only if you've purchased a mushroom plot this run.}}<br />
{{Flink|int|stills_available|desc=Returns the number of Nash Crosby's Still uses left for the day (0 if not accessible).}}<br />
{{Flink|string|item_type|item|desc=Returns the type of item specified.}}<br />
{{Flink|int|item_amount|item}}<br />
{{Flink|int|closet_amount|item}}<br />
{{Flink|int|display_amount|item}}<br />
{{Flink|int|equipped_amount|item}}<br />
{{Flink|int|shop_amount|item}}<br />
{{Flink|int [item]|get_shop|desc=Returns entire contents of shop and quantity of each item}}<br />
{{Flink|int|stash_amount|item|}}<br />
{{Flink|int|storage_amount|item|desc=These 7 functions return the total number available of a given item in the respective section of your inventory.}}<br />
{{Flink|int|available_amount|item|desc=Returns the total number available of a given item in all inventory sections accessible to your character based on current restrictions.}}<br />
{{Flink|int|creatable_amount|item|desc=Returns the amount of the item that you are capable of creating given your current inventory and skills.}}<br />
{{Flink|int [item]|get_ingredients|item|desc=Returns a map where each key is one of the required ingredients, with the integer value the number required. If you don't have the skills needed to make the item, it will return an empty map.}}<br />
{{Flink|string|craft_type|item|desc=Returns a string identifying how an item is crafted and any other requirements for creating it.}}<br />
{{Flink|int [item]|get_inventory|desc=Returns a map where each key is an item in your inventory, with the integer value its quantity.}}<br />
{{Flink|int [item]|get_related|item|string|desc=Returns associated items in a zap or fold group (see page for details).}}<br />
[[File:Item category.png|frame|You can categorize items in KoL using [[is tradeable|is_tradeable()]], [[is giftable|is_giftable()]], and [[is displayable|is_displayable()]].]]<br />
{{Flink|boolean|is_tradeable|item|desc=Returns whether the item can be placed in the mall.}}<br />
{{Flink|boolean|is_giftable|item|desc=Returns whether the item can be traded in a gift package.}}<br />
{{Flink|boolean|is_displayable|item|desc=Returns whether the item can be put in a display case (true for all but quest items).}}<br />
{{Flink|boolean|is_discardable|item|desc=Returns whether the item can be discarded or autosold.}}<br />
{{Flink|boolean|have_shop|desc=Returns whether you have a mall store.}}<br />
{{Flink|boolean|have_display|desc=Returns whether you have a display case.}}<br />
{{Flink|boolean|is_npc_item|item|desc=Returns whether the item can be bought from an NPC store.}}<br />
{{Flink|void|refresh_stash|desc=Takes a new look at the contents of your clan stash, as that section of inventory cannot be internally tracked due to access by others.}}<br />
{{Flink|void|refresh_shop|desc=Takes a new look at the contents of your mall store, as that section of inventory cannot be internally tracked due to access by others.}}<br />
{{Flink|int|shop_price|item|desc=Returns the current price for the given item if it is present in your mall store.}}<br />
{{Flink|int|npc_price|item|desc=Returns the current price of the given item if it can currently be bought from an NPC store.}}<br />
{{Flink|int|autosell_price|item|desc=Returns the autosell price of the item (0 for items that cannot be autosold).}}<br />
{{Flink|int|get_power|item|desc=Returns the power of the item (0 for items that don't have a power).}}<br />
{{Flink|string|to_plural|item|desc=Returns the plural of an item as a string.}}<br />
{{Flink|int|meat_drop|{{opt|monster}}|desc=Returns a certain monster's base meat drop.}}<br />
{{Flink|int [item]|item_drops|{{opt|monster}}|desc=Returns an array of a certain monster's base item drops, keying item to drop rate. Has certain limitations detailed on individual page.}}<br />
{{Flink|record [int]|item_drops_array|{{opt|monster}}|desc=Returns an array of records holding information regarding a certain monster's base item drops.}}<br />
<br />
===Mall Prices===<br />
{{FunctionEmbed|historical_age|desc=yes}}<br />
{{FunctionEmbed|historical_price|desc=yes}}<br />
{{FunctionEmbed|mall_price|desc=yes}}<br />
{{FunctionEmbed|mall_prices|desc=yes}}<br />
<br />
==Moving Items Around==<br />
{{Flink|boolean|empty_closet|desc=Remove every item from the closet in a single server hit.}}<br />
{{Flink|boolean|put_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|put_display|int|item}}<br />
{{Flink|boolean|put_stash|int|item}}<br />
{{Flink|boolean|take_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|take_display|int|item}}<br />
{{Flink|boolean|take_stash|int|item}}<br />
{{Flink|boolean|take_storage|int|item|desc=Attempts to take or put the specified item in the appropriate section of your inventory, and returns its success.<br />If the item parameter is omitted from put_closet() or take_closet(), meat is transferred instead of an item.}}<br />
{{Flink|boolean|put_shop|int|int|{{opt|int}}|item}}<br />
{{Flink|boolean|take_shop|{{opt|int}}|item|desc=Adds or removes items in your store and returns success.}}<br />
<br />
==Acquiring & Using Items==<br />
{{Flink|boolean|autosell|int|item|desc=Attempts to autosell the given items and reports success.}}<br />
{{Flink|boolean|buy|{{opt|coinmaster}}|int|item}}<br />
{{Flink|int|buy|int|item|int|desc=Tries to purchase the specified items.}}<br />
{{Flink|boolean|buy_using_storage|int|item}}<br />
{{Flink|int|buy_using_storage|int|item|int|desc=Tries to purchase the specified items using meat in Hangks.}}<br />
{{Flink|boolean|create|int|item|desc=Attempts to create the specified items, following your KoLmafia settings regarding purchases to gather ingredients & require boxen.}}<br />
{{FunctionEmbed|drink|desc=yes}}<br />
{{FunctionEmbed|eat|desc=yes}}<br />
{{Flink|boolean|eatsilent|int|item|desc=Attempts to eat items as specified.}}<br />
{{Flink|boolean|chew|int|item|desc=Attempts to chew spleen items as specified and reports success.}}<br />
{{Flink|boolean|hermit|int|item|desc=Trades worthless items (buying and using chewing gum if needed) to the hermit for specified items (see page for details).}}<br />
{{Flink|boolean|use|int|item|desc=Attempts to use items as specified and reports success.}}<br />
{{FunctionEmbed|overdrink|format=signature|desc=yes}}<br />
{{Flink|boolean|retrieve_item|int|item|desc=Uses KoLmafia internal logic to gather items (see page for details).}}<br />
{{Flink|int|craft|string|int|item|item|desc=Raw crafting that obeys KoLmafia settings (see page for details).}}<br />
{{Flink|string|last_item_message|desc=Returns message that KoL reports in the event of error.}}<br />
<br />
==Coinmaster Control==<br />
Some items can be bought from or sold to various "coinmasters" which are like shops that deal in a currency other than meat. These coinmasters include the Dimemaster and Quartermaster during the Island War, the Hermit, the Mr. Store and many others. Some relevant information can be found in [[proxy records]] for the item and coinmaster data types. The rest is controlled by the following functions.<br />
<br />
===Inquiries===<br />
{{Flink|coinmaster|to_coinmaster|string|desc=Converts a string to a valid coinmaster.}}<br />
{{Flink|boolean|is_coinmaster_item|item|desc=Is a given item acquirable from a coinmster.}}<br />
{{Flink|boolean|buys_item|coinmaster|item|desc=Is a specific item acquirable from the named coinmster.}}<br />
{{Flink|int|buy_price|coinmaster|item|desc=What is the coinmaster's purchase price for an item.}}<br />
{{Flink|boolean|sells_item|coinmaster|item|desc=Is a specific item sellable to the named coinmster.}}<br />
{{Flink|int|sell_price|coinmaster|item|desc=What is the coinmaster's selling price for an item.}}<br />
<br />
===Coinmaster transactions===<br />
{{Flink|boolean|is_accessible|coinmaster|desc=Is a given coinmaster currently accessible.}}<br />
{{Flink|string|inaccessible_reason|coinmaster|desc=The reason a given coinmaster is currently inaccessible.}}<br />
{{Flink|boolean|visit|coinmaster|desc=Refreshes information at a coinmaster.}}<br />
{{Flink|boolean|buy|coinmaster|int|item|desc=Buys an item from a coinmaster.}}<br />
{{Flink|boolean|sell|coinmaster|int|item|desc=Sells an item to a coinmaster.}}<br />
<br />
===Sweet Synthesis===<br />
{{Flink|item [int]|candy_for_tier|int|{{opt|int}}|desc=Returns all the candy to create a given tier of effect.}}<br />
{{Flink|item [int]|sweet_synthesis_pairing|effect|item|{{opt|int}}|desc=Find a second candy to synthesize.}}<br />
{{Flink|item [int]|sweet_synthesis_pair|effect|{{opt|int}}|desc=Picks a pair of candies to synthesize for an effect.}}<br />
{{Flink|effect|sweet_synthesis_result|item|item|desc=Show result of synthesis.}}<br />
{{Flink|boolean|sweet_synthesis|item|item|desc=Synthesize specified candies.}}<br />
{{Flink|boolean|sweet_synthesis|effect|{{opt|int}}|desc=Picks a pair of candies and synthesizes them for the effect.}}<br />
<br />
<br />
[[Category:Scripting]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Ash_Functions&diff=9060Ash Functions2021-07-13T14:17:59Z<p>Philmasterplus: Use Template:FunctionEmbed for drink(), eat()</p>
<hr />
<div>{{TOCright}}<br />
Master list of all ASH functions. All functions as of r20745 are listed; this list is intended to be kept current, but it is possible that some functions added since the above revision may be missing. (Please feel free to add in any you notice.)<br />
The CLI command "[[ashref]]" shows every implemented ash function for your mafia version.<br />
===a===<br />
{{FunctionEmbed|abort|format=signature}}<br />
{{FunctionEmbed|add_item_condition|format=signature}}<br />
{{Flink|boolean|adv1|location|{{opt|int}}|{{opt|string}}}}<br />
{{Flink|int|adv_cost|skill}}<br />
{{Flink|boolean|adventure|int|location|{{opt|string}}}}<br />
{{Flink|boolean|adventure|location|int|{{opt|string}}}}<br />
{{FunctionEmbed|all_monsters_with_id|format=signature}}<br />
{{Flink|string [int]|all_normal_outfits}}<br />
{{Flink|float [monster]|appearance_rates|location|{{opt|boolean}}}}<br />
{{Flink|buffer|append|buffer|string}}<br />
{{Flink|buffer|append_replacement|matcher|buffer|string}}<br />
{{Flink|buffer|append_tail|matcher|buffer}}<br />
{{Flink|buffer|attack}}<br />
{{Flink|boolean|autosell|int|item}}<br />
{{Flink|boolean|autosell|item|int}}<br />
{{Flink|int|autosell_price|item}}<br />
{{Flink|int|available_amount|item}}<br />
{{FunctionEmbed|available_choice_options}}<br />
{{Flink|string [string, string]|available_choice_select_inputs|int}}<br />
{{Flink|string [string]|available_choice_text_inputs|int}}<br />
{{Flink|int|available_pocket|monster}}<br />
{{Flink|int|available_pocket|effect}}<br />
{{Flink|int|available_pocket|item}}<br />
{{Flink|int|available_pocket|stat}}<br />
<br />
===b===<br />
{{Flink|boolean|batch_close}}<br />
{{Flink|void|batch_open}}<br />
{{Flink|boolean|bjornify_familiar|familiar}}<br />
{{Flink|boolean|black_market_available}}<br />
{{Flink|boolean|boolean_modifier|{{opt|string}}|string}}<br />
{{Flink|boolean|boolean_modifier|effect|string}}<br />
{{Flink|boolean|boolean_modifier|item|string}}<br />
{{Flink|int|buffed_hit_stat}}<br />
{{FunctionEmbed|buffer_to_file|format=signature}}<br />
{{Flink|boolean|buy|coinmaster|item}}<br />
{{Flink|boolean|buy|{{opt|coinmaster}}|int|item}}<br />
{{Flink|boolean|buy|item|{{opt|int}}|{{opt|int}}}}<br />
{{Flink|int|buy|int|item|int}}<br />
{{Flink|int|buy_price|coinmaster|item}}<br />
{{Flink|boolean|buy_using_storage|int|item}}<br />
{{Flink|int|buy_using_storage|int|item|int}}<br />
{{Flink|int|buy_using_storage|item|int|int}}<br />
{{Flink|boolean|buys_item|coinmaster|item}}<br />
<br />
===c===<br />
{{Flink|boolean|can_drink}}<br />
{{Flink|boolean|can_eat}}<br />
{{Flink|boolean|can_equip|familiar|{{opt|item}}}}<br />
{{Flink|boolean|can_equip|item}}<br />
{{Flink|boolean|can_faxbot|monster}}<br />
{{Flink|boolean|can_interact}}<br />
{{Flink|boolean|can_still_steal}}<br />
{{Flink|boolean|canadia_available}}<br />
{{Flink|item [0]|candy_for_tier|int|{{opt|int}}}}<br />
{{Flink|int|ceil|float}}<br />
{{Flink|boolean|change_mcd|int}}<br />
{{Flink|string|char_at|string|int}}<br />
{{Flink|void|chat_clan|string|{{opt|string}}}}<br />
{{Flink|void|chat_macro|string}}<br />
{{Flink|void|chat_notify|string|string}}<br />
{{Flink|void|chat_private|string|string}}<br />
{{Flink|boolean|chew|int|item}}<br />
{{Flink|boolean|chew|item|{{opt|int}}}}<br />
{{Flink|boolean|choice_follows_fight}}<br />
{{Flink|class|class_modifier|string|string}}<br />
{{Flink|class|class_modifier|item|string}}<br />
{{Flink|void|clear|aggregate}}<br />
{{FunctionEmbed|cli_execute|format=signature}}<br />
{{FunctionEmbed|cli_execute_output|format=signature}}<br />
{{Flink|int|closet_amount|item}}<br />
{{Flink|int|combat_mana_cost_modifier}}<br />
{{Flink|float|combat_rate_modifier}}<br />
{{FunctionEmbed|contains_text|format=signature}}<br />
{{Flink|void|council}}<br />
{{Flink|int|count|aggregate}}<br />
{{Flink|int|craft|string|int|item|item}}<br />
{{Flink|string|craft_type|item}}<br />
{{Flink|int|creatable_amount|item}}<br />
{{Flink|int|creatable_turns|item|{{opt|int}}|{{opt|boolean}}}}<br />
{{Flink|boolean|create|int|item}}<br />
{{Flink|boolean|create|item|{{opt|int}}}}<br />
{{Flink|matcher|create_matcher|string|string}}<br />
{{Flink|stat|current_hit_stat}}<br />
{{Flink|int|current_mcd}}<br />
{{Flink|int [string]|current_pvp_stances}}<br />
{{Flink|int|current_rad_sickness}}<br />
{{Flink|int|current_round}}<br />
<br />
===d===<br />
{{Flink|element|dad_sea_monkee_weakness|int}}<br />
{{Flink|item|daily_special}}<br />
{{Flink|float|damage_absorption_percent}}<br />
{{Flink|int|damage_reduction}}<br />
{{Flink|int|date_to_timestamp|string|string}}<br />
{{Flink|void|debugprint|string}}<br />
{{Flink|buffer|delete|buffer|int|int}}<br />
{{Flink|effect|desc_to_effect|string}}<br />
{{Flink|item|desc_to_item|string}}<br />
{{Flink|void|disable|string}}<br />
{{Flink|boolean|dispensary_available}}<br />
{{Flink|int|display_amount|item}}<br />
{{FunctionEmbed|drink|format=signature}}<br />
{{Flink|boolean|drinksilent|int|item}}<br />
{{Flink|boolean|drinksilent|item|{{opt|int}}}}<br />
{{Flink|void|dump|any|{{opt|string}}}}<br />
<br />
===e===<br />
{{FunctionEmbed|eat|format=signature}}<br />
{{Flink|boolean|eatsilent|int|item}}<br />
{{Flink|boolean|eatsilent|item|{{opt|int}}}}<br />
{{Flink|effect|effect_modifier|string|string}}<br />
{{Flink|effect|effect_modifier|item|string}}<br />
{{Flink|boolean [int]|effect_pockets}}<br />
{{Flink|float|elemental_resistance|{{opt|element}}}}<br />
{{Flink|float|elemental_resistance|monster}}<br />
{{Flink|boolean|empty_closet}}<br />
{{Flink|void|enable|string}}<br />
{{Flink|int|end|matcher|{{opt|int}}}}<br />
{{FunctionEmbed|ends_with|format=signature}}<br />
{{Flink|boolean|enthrone_familiar|familiar}}<br />
{{Flink|string|entity_decode|string}}<br />
{{Flink|string|entity_encode|string}}<br />
{{Flink|boolean|equip|item|{{opt|slot}}}}<br />
{{Flink|boolean|equip|slot|item}}<br />
{{Flink|boolean|equip_all_familiars}}<br />
{{Flink|int|equipped_amount|item}}<br />
{{Flink|item|equipped_item|slot}}<br />
{{Flink|string|eudora}}<br />
{{Flink|boolean|eudora|string}}<br />
{{Flink|string|every_card_name|strict_string}}<br />
{{Flink|int|expected_damage|{{opt|monster}}}}<br />
{{Flink|float|experience_bonus}}<br />
{{Flink|float|expression_eval|string}}<br />
{{Flink|int [item]|extract_items|string}}<br />
{{Flink|int|extract_meat|string}}<br />
<br />
===f===<br />
{{Flink|item|familiar_equipment|familiar}}<br />
{{Flink|item|familiar_equipped_equipment|familiar}}<br />
{{Flink|int|familiar_weight|familiar}}<br />
{{Flink|boolean [familiar]|favorite_familiars|}}<br />
{{Flink|boolean|faxbot|monster|{{opt|string}}}}<br />
{{Flink|boolean|fight_follows_choice}}<br />
{{FunctionEmbed|file_to_array|format=signature}}<br />
{{FunctionEmbed|file_to_buffer|format=signature}}<br />
{{Flink|boolean|file_to_map|string|aggregate|{{opt|boolean}}}}<br />
{{Flink|boolean|find|matcher}}<br />
{{Flink|int|floor|float}}<br />
{{Flink|boolean|florist_available}}<br />
{{Flink|boolean|flush_monster_manuel_cache}}<br />
{{Flink|string|form_field|string}}<br />
{{Flink|string [string]|form_fields}}<br />
{{Flink|string|format_date_time|string|string|string}}<br />
{{Flink|boolean|friars_available}}<br />
{{Flink|int|fuel_cost|skill}}<br />
{{Flink|int|fullness_limit}}<br />
<br />
===g===<br />
{{Flink|int|gameday_to_int}}<br />
{{Flink|string|gameday_to_string}}<br />
{{Flink|int|gametime_to_int}}<br />
{{Flink|boolean [string] |get_all_properties|string|boolean}}<br />
{{Flink|int|get_auto_attack}}<br />
{{Flink|int [item]|get_campground}}<br />
{{Flink|string |get_ccs_action|int}}<br />
{{Flink|int [item]|get_chateau}}<br />
{{Flink|int|get_clan_id}}<br />
{{Flink|int [item]|get_clan_lounge}}<br />
{{Flink|string|get_clan_name}}<br />
{{Flink|int [string]|get_clan_rumpus}}<br />
{{Flink|int [item]|get_closet}}<br />
{{Flink|string|get_counters|string|int|int}}<br />
{{Flink|string [int]|get_custom_outfits}}<br />
{{Flink|item|get_dwelling}}<br />
{{Flink|string [location, 3]|get_florist_plants}}<br />
{{Flink|int [item]|get_free_pulls}}<br />
{{Flink|int|get_fuel}}<br />
{{Flink|string [int]|get_goals}}<br />
{{Flink|boolean|get_ignore_zone_warnings}}<br />
{{Flink|int [item]|get_ingredients|item}}<br />
{{Flink|int [item]|get_inventory}}<br />
{{Flink|boolean [monster]|get_location_monsters|location}}<br />
{{Flink|monster [monster]|get_monster_mapping|{{opt|string}}}}<br />
{{Flink|monster [int]|get_monsters|location}}<br />
{{Flink|string [int]|get_moods}}<br />
{{Flink|string [int]|get_outfits}}<br />
{{Flink|string|get_path}}<br />
{{Flink|string|get_path_full}}<br />
{{Flink|string|get_path_variables}}<br />
{{Flink|string|get_player_id|string}}<br />
{{Flink|string|get_player_name|int}}<br />
{{Flink|int|get_power|item}}<br />
{{Flink|string|get_property|string|{{opt|boolean}}}}<br />
{{Flink|int [item]|get_related|item|string}}<br />
{{Flink|int|get_revision}}<br />
{{Flink|int [item]|get_shop}}<br />
{{Flink|string [0]|get_shop_log}}<br />
{{Flink|string string int [0]|get_stack_trace}}<br />
{{Flink|int [item]|get_stash}}<br />
{{Flink|int [item]|get_storage}}<br />
{{Flink|string|get_version}}<br />
{{Flink|string|get_workshed}}<br />
{{Flink|boolean|gnomads_available}}<br />
{{Flink|boolean|goal_exists|string}}<br />
{{Flink|string|group|matcher|{{opt|int}}}}<br />
{{Flink|string|group|matcher|string}}<br />
{{Flink|int|group_count|matcher}}<br />
{{Flink|boolean [string]|group_names|matcher}}<br />
{{Flink|string [int, int]|group_string|string|string}}<br />
{{Flink|boolean|guild_available}}<br />
{{Flink|boolean|guild_store_available}}<br />
<br />
===h===<br />
{{Flink|boolean|handling_choice}}<br />
{{Flink|boolean|have_bartender}}<br />
{{Flink|boolean|have_chef}}<br />
{{Flink|boolean|have_display}}<br />
{{Flink|int|have_effect|effect}}<br />
{{Flink|boolean|have_equipped|item}}<br />
{{Flink|boolean|have_familiar|familiar}}<br />
{{Flink|boolean|have_mushroom_plot}}<br />
{{Flink|boolean|have_outfit|string}}<br />
{{Flink|boolean|have_servant|servant}}<br />
{{Flink|boolean|have_shop}}<br />
{{Flink|boolean|have_skill|skill}}<br />
{{Flink|boolean|hedge_maze|string}}<br />
{{Flink|boolean|hermit|int|item}}<br />
{{Flink|boolean|hermit|item|int}}<br />
{{Flink|boolean|hidden_temple_unlocked}}<br />
{{Flink|boolean|hippy_stone_broken}}<br />
{{Flink|boolean|hippy_store_available}}<br />
{{FunctionEmbed|historical_age}}<br />
{{FunctionEmbed|historical_price}}<br />
{{Flink|string|holiday}}<br />
{{Flink|int|hp_cost|skill}}<br />
<br />
===i===<br />
{{Flink|monster|image_to_monster|strict_string}}<br />
{{Flink|boolean|in_bad_moon}}<br />
{{Flink|boolean|in_hardcore}}<br />
{{Flink|boolean|in_moxie_sign}}<br />
{{Flink|boolean|in_multi_fight}}<br />
{{Flink|boolean|in_muscle_sign}}<br />
{{Flink|boolean|in_mysticality_sign}}<br />
{{Flink|string|inaccessible_reason|coinmaster}}<br />
{{FunctionEmbed|index_of|format=signature}}<br />
{{Flink|int|inebriety_limit}}<br />
{{Flink|float|initiative_modifier}}<br />
{{Flink|buffer|insert|buffer|int|string}}<br />
{{Flink|boolean|is_accessible|coinmaster}}<br />
{{Flink|boolean|is_banished|monster}}<br />
{{Flink|boolean|is_coinmaster_item|item}}<br />
{{FunctionEmbed|is_dark_mode}}<br />
{{Flink|boolean|is_discardable|item}}<br />
{{Flink|boolean|is_displayable|item}}<br />
{{Flink|boolean|is_familiar_equipment_locked}}<br />
{{Flink|boolean|is_giftable|item}}<br />
{{Flink|boolean|is_goal|item}}<br />
{{Flink|boolean|is_integer|string}}<br />
{{Flink|boolean|is_npc_item|item}}<br />
{{Flink|boolean|is_online|string}}<br />
{{Flink|boolean|is_tradeable|item}}<br />
{{Flink|boolean|is_trendy|item/familiar/skill/string}}<br />
{{Flink|boolean|is_unrestricted|item/familiar/skill/string}}<br />
{{Flink|boolean|is_wearing_outfit|string}}<br />
{{Flink|int|item_amount|item}}<br />
{{Flink|float|item_drop_modifier}}<br />
{{Flink|int [item]|item_drops|{{opt|monster}}}}<br />
{{Flink|item int string [int]|item_drops_array|{{opt|monster}}}}<br />
{{Flink|boolean [int]|item_pockets}}<br />
{{Flink|string|item_type|item}}<br />
<br />
===j===<br />
{{Flink|boolean [int]|joke_pockets}}<br />
{{flink|int|jump_chance|{{opt|monster}}|{{opt|int}}|{{opt|int}}}}<br />
{{flink|int|jump_chance|location|{{opt|int}}|{{opt|int}}}}<br />
<br />
===k===<br />
{{flink|boolean|knoll_available}}<br />
<br />
===l===<br />
{{Flink|int|last_choice}}<br />
{{Flink|int|last_decision}}<br />
{{FunctionEmbed|last_index_of|format=signature}}<br />
{{Flink|string|last_item_message}}<br />
{{Flink|monster|last_monster}}<br />
{{Flink|string|last_skill_message}}<br />
{{Flink|string|leetify|string}}<br />
{{Flink|int|length|string}}<br />
{{Flink|int|lightning_cost|skill}}<br />
{{Flink|string|limit_mode}}<br />
{{Flink|buffer|load_html|string}}<br />
{{Flink|void|lock_familiar_equipment|boolean}}<br />
{{Flink|float|log_n|float|{{opt|float}}}}<br />
{{Flink|void|logprint|string}}<br />
<br />
===m===<br />
{{Flink|string|make_url|string|boolean|boolean}}<br />
{{FunctionEmbed|mall_price}}<br />
{{FunctionEmbed|mall_prices}}<br />
{{Flink|int|mana_cost_modifier}}<br />
{{Flink|boolean|map_to_file|aggregate|string|{{opt|boolean}}}}<br />
{{Flink|float|max|float ...}}<br />
{{Flink|int|max|int ...}}<br />
{{Flink|boolean|maximize|string|boolean}}<br />
{{Flink|boolean|maximize|string|int|int|boolean}}<br />
{{Flink|{string string float effect item skill} [int]|maximize|string|int|int|boolean|boolean}}<br />
{{Flink|int|meat_drop|{{opt|monster}}}}<br />
{{Flink|float|meat_drop_modifier}}<br />
{{Flink|int [int]|meat_pockets}}<br />
{{Flink|float|min|float ...}}<br />
{{Flink|int|min|int ...}}<br />
{{Flink|item|minstrel_instrument}}<br />
{{Flink|int|minstrel_level}}<br />
{{Flink|boolean|minstrel_quest}}<br />
{{Flink|float|modifier_eval|string}}<br />
{{Flink|int|monster_attack|{{opt|monster}}}}<br />
{{Flink|int|monster_defense|{{opt|monster}}}}<br />
{{Flink|element|monster_element|{{opt|monster}}}}<br />
{{Flink|float|monster_eval|string}}<br />
{{Flink|int|monster_factoids_available|monster|boolean}}<br />
{{Flink|int|monster_hp|{{opt|monster}}}}<br />
{{Flink|int|monster_initiative|{{opt|monster}}}}<br />
{{Flink|int|monster_level_adjustment}}<br />
{{Flink|string|monster_manuel_text|monster}}<br />
{{Flink|phylum|monster_phylum|{{opt|monster}}}}<br />
{{Flink|boolean [int]|monster_pockets}}<br />
{{Flink|void|mood_execute|int}}<br />
{{Flink|string [0]|mood_list}}<br />
{{Flink|int|moon_light}}<br />
{{Flink|int|moon_phase}}<br />
{{Flink|int|mp_cost|skill}}<br />
{{Flink|int|my_absorbs}}<br />
{{Flink|int|my_adventures}}<br />
{{Flink|int|my_ascensions}}<br />
{{Flink|int|my_audience}}<br />
{{Flink|int|my_basestat|stat}}<br />
{{Flink|familiar|my_bjorned_familiar}}<br />
{{Flink|int|my_buffedstat|stat}}<br />
{{Flink|class|my_class}}<br />
{{Flink|int|my_closet_meat}}<br />
{{Flink|string|my_companion}}<br />
{{Flink|int|my_daycount}}<br />
{{Flink|int|my_discomomentum}}<br />
{{Flink|familiar|my_effective_familiar}}<br />
{{Flink|int [effect]|my_effects}}<br />
{{Flink|familiar|my_enthroned_familiar}}<br />
{{Flink|familiar|my_familiar}}<br />
{{Flink|int|my_fullness}}<br />
{{Flink|int|my_fury}}<br />
{{Flink|string|my_garden_type}}<br />
{{Flink|string|my_hash}}<br />
{{Flink|int|my_hp}}<br />
{{Flink|string|my_id}}<br />
{{Flink|int|my_inebriety}}<br />
{{Flink|int|my_level}}<br />
{{Flink|int|my_lightning}}<br />
{{Flink|location|my_location}}<br />
{{Flink|string|my_mask}}<br />
{{Flink|int|my_maxfury}}<br />
{{Flink|int|my_maxhp}}<br />
{{Flink|int|my_maxmp}}<br />
{{Flink|int|my_maxpp}}<br />
{{Flink|int|my_meat}}<br />
{{Flink|int|my_mp}}<br />
{{Flink|string|my_name}}<br />
{{Flink|string|my_path}}<br />
{{Flink|int|my_path_id}}<br />
{{Flink|familiar|my_poke_fam|int}}<br />
{{Flink|int|my_pp}}<br />
{{Flink|stat|my_primestat}}<br />
{{Flink|int|my_rain}}<br />
{{Flink|int|my_robot_energy}}<br />
{{Flink|int|my_robot_scraps}}<br />
{{Flink|servant|my_servant}}<br />
{{Flink|int|my_session_adv}}<br />
{{Flink|int [item]|my_session_items}}<br />
{{Flink|int|my_session_items|item}}<br />
{{Flink|int|my_session_meat}}<br />
{{Flink|string|my_sign}}<br />
{{Flink|int|my_soulsauce}}<br />
{{Flink|int|my_spleen_use}}<br />
{{Flink|int|my_storage_meat}}<br />
{{Flink|thrall|my_thrall}}<br />
{{Flink|int|my_thunder}}<br />
{{Flink|int|my_turncount}}<br />
{{Flink|vykea|my_vykea_companion}}<br />
<br />
===n===<br />
{{Flink|int|now_to_int}}<br />
{{Flink|string|now_to_string|string}}<br />
{{Flink|int|npc_price|item}}<br />
{{Flink|string|numberology_prize|int}}<br />
{{Flink|float|numeric_modifier|effect|string}}<br />
{{Flink|float|numeric_modifier|familiar|string|int|item}}<br />
{{Flink|float|numeric_modifier|item|string}}<br />
{{Flink|float|numeric_modifier|skill|string}}<br />
{{Flink|float|numeric_modifier|{{opt|string}}|string}}<br />
<br />
===o===<br />
{{Flink|boolean|outfit|string}}<br />
{{Flink|item [int]|outfit_pieces|string}}<br />
{{Flink|string|outfit_tattoo|{{opt|string}}}}<br />
{{FunctionEmbed|overdrink|format=signature}}<br />
<br />
===p===<br />
{{Flink|string|path_id_to_name|int}}<br />
{{Flink|int|path_name_to_id|string}}<br />
{{Flink|boolean|pick_pocket|monster}}<br />
{{Flink|int [effect]|pick_pocket|effect}}<br />
{{Flink|int [item]|pick_pocket|item}}<br />
{{Flink|int [stat]|pick_pocket|stat}}<br />
{{Flink|boolean|pick_pocket|int}}<br />
{{Flink|boolean [int]|picked_pockets}}<br />
{{Flink|boolean [int]|picked_scraps}}<br />
{{Flink|int [effect]|pocket_effects|int}}<br />
{{Flink|int [item]|pocket_items|int}}<br />
{{Flink|string|pocket_joke|int}}<br />
{{Flink|string [int]|pocket_meat|int}}<br />
{{Flink|monster|pocket_monster|int}}<br />
{{Flink|string [int]|pocket_poem|int}}<br />
{{Flink|string [int]|pocket_scrap|int}}<br />
{{Flink|int [stat]|pocket_stats|int}}<br />
{{Flink|int [int]|poem_pockets}}<br />
{{Flink|int [int]|potential_pockets|effect/item/monster/stat}}<br />
{{Flink|void|print|{{opt|string}}|{{opt|string}}}}<br />
{{Flink|void|print_html|string}}<br />
{{FunctionEmbed|property_default_value|format=signature}}<br />
{{FunctionEmbed|property_exists|format=signature}}<br />
{{FunctionEmbed|property_has_default|format=signature}}<br />
{{Flink|int|pulls_remaining}}<br />
{{Flink|boolean|put_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|put_closet|item|{{opt|int}}}}<br />
{{Flink|boolean|put_display|int|item}}<br />
{{Flink|boolean|put_display|item|int}}<br />
{{Flink|boolean|put_shop|int|int|{{opt|int}}|item}}<br />
{{Flink|boolean|put_shop_using_storage|int|int|{{opt|int}}|item}}<br />
{{Flink|boolean|put_stash|int|item}}<br />
{{Flink|boolean|put_stash|item|int}}<br />
{{Flink|int|pvp_attacks_left}}<br />
<br />
===r===<br />
{{Flink|int|rain_cost|skill}}<br />
{{Flink|int|random|int}}<br />
{{Flink|int|raw_damage_absorption}}<br />
{{Flink|boolean|refresh_shop}}<br />
{{Flink|boolean|refresh_stash}}<br />
{{Flink|boolean|refresh_status}}<br />
{{Flink|void|remove_item_condition|int|item}}<br />
{{Flink|void|remove_item_condition|item|int}}<br />
{{FunctionEmbed|remove_property|format=signature}}<br />
{{FunctionEmbed|rename_property|format=signature}}<br />
{{Flink|boolean|replace|buffer|int|int|string}}<br />
{{Flink|string|replace_all|matcher|string}}<br />
{{Flink|string|replace_first|matcher|string}}<br />
{{Flink|buffer|replace_string|buffer|string|string}}<br />
{{Flink|buffer|replace_string|string|string|string}}<br />
{{Flink|boolean|reprice_shop|int|{{opt|int}}|item}}<br />
{{Flink|matcher|reset|matcher|{{opt|string}}}}<br />
{{Flink|boolean [int]|restoration_pockets}}<br />
{{Flink|boolean|restore_hp|int}}<br />
{{Flink|boolean|restore_mp|int}}<br />
{{Flink|boolean|retrieve_item|int|item}}<br />
{{Flink|boolean|retrieve_item|item|{{opt|int}}}}<br />
{{Flink|int [int]|reverse_numberology|{{opt|int|int}}}}<br />
{{Flink|int|rollover}}<br />
{{Flink|int|round|float}}<br />
{{FunctionEmbed|run_choice|format=signature}}<br />
{{Flink|buffer|run_combat|{{opt|string}}}}<br />
{{Flink|buffer|run_turn}}<br />
{{Flink|buffer|runaway}}<br />
<br />
===s===<br />
{{Flink|int [int]|scrap_pockets}}<br />
{{Flink|boolean|sell|coinmaster|int|item}}<br />
{{Flink|int|sell_price|coinmaster|item}}<br />
{{Flink|boolean|sells_item|coinmaster|item}}<br />
{{Flink|string [int]|session_logs|{{opt|string}}|{{opt|string}}|int}}<br />
{{Flink|void|set_auto_attack|int/string}}<br />
{{Flink|void|set_length|buffer|int}}<br />
{{Flink|void|set_location|location}}<br />
{{Flink|void|set_property|string|string}}<br />
{{Flink|int|shop_amount|item}}<br />
{{Flink|int|shop_limit|item}}<br />
{{Flink|int|shop_price|item}}<br />
{{Flink|skill|skill_modifier|item|string}}<br />
{{Flink|skill|skill_modifier|string|string}}<br />
{{Flink|int|slash_count|item}}<br />
{{Flink|int|soulsauce_cost|skill}}<br />
{{Flink|int|spleen_limit}}<br />
{{Flink|string [int]|split_string|string|{{opt|string}}}}<br />
{{Flink|float|square_root|float}}<br />
{{Flink|int|start|matcher|{{opt|int}}}}<br />
{{FunctionEmbed|starts_with|format=signature}}<br />
{{Flink|int|stash_amount|item}}<br />
{{Flink|stat|stat_bonus_today}}<br />
{{Flink|stat|stat_bonus_tomorrow}}<br />
{{Flink|stat|stat_modifier|effect|string}}<br />
{{Flink|buffer|steal}}<br />
{{Flink|int|stills_available}}<br />
{{Flink|void|stop_counter|string}}<br />
{{Flink|int|storage_amount|item}}<br />
{{Flink|string|string_modifier|{{opt|string}}|string}}<br />
{{Flink|skill|stun_skill}}<br />
{{Flink|string|substring|string|int|{{opt|int}}}}<br />
{{Flink|boolean|svn_at_head|string}}<br />
{{Flink|boolean|svn_exists|string}}<br />
{{Flink|{string int string int string}|svn_info|string}}<br />
{{Flink|boolean|sweet_synthesis|effect|{{opt|int}}}}<br />
{{Flink|boolean|sweet_synthesis|int|effect|{{opt|int}}}}<br />
{{Flink|boolean|sweet_synthesis|{{opt|int}}|item|item}}<br />
{{Flink|item [0]|sweet_synthesis_pair|effect|{{opt|item}}|{{opt|int}}}}<br />
{{Flink|effect|sweet_synthesis_result|item|item}}<br />
<br />
===t===<br />
{{Flink|boolean|take_closet|int|{{opt|item}}}}<br />
{{Flink|boolean|take_closet|item|{{opt|int}}}}<br />
{{Flink|boolean|take_display|int|item}}<br />
{{Flink|boolean|take_display|item|int}}<br />
{{Flink|boolean|take_shop|{{opt|int}}|item}}<br />
{{Flink|boolean|take_stash|int|item}}<br />
{{Flink|boolean|take_stash|item|int}}<br />
{{Flink|boolean|take_storage|int|item}}<br />
{{Flink|boolean|take_storage|item|int}}<br />
{{Flink|int|tavern|{{opt|string}}}}<br />
{{Flink|buffer|throw_item|item}}<br />
{{Flink|buffer|throw_items|item|item}}<br />
{{Flink|int|thunder_cost|skill}}<br />
{{Flink|string|time_to_string}}<br />
{{Flink|string|timestamp_to_date|int|string}}<br />
{{Flink|boolean|to_boolean|any}}<br />
{{Flink|bounty|to_bounty|strict_string}}<br />
{{Flink|class|to_class|strict_string/int}}<br />
{{Flink|coinmaster|to_coinmaster|strict_string}}<br />
{{Flink|effect|to_effect|int/skill/strict_string}}<br />
{{Flink|element|to_element|strict_string}}<br />
{{Flink|familiar|to_familiar|int/strict_string}}<br />
{{Flink|float|to_float|any}}<br />
{{Flink|int|to_int|any}}<br />
{{Flink|item|to_item|int/strict_string}}<br />
{{Flink|item|to_item|string|int}}<br />
{{Flink|string|to_json|aggregate}}<br />
{{Flink|location|to_location|int/strict_string}}<br />
{{Flink|string|to_lower_case|string}}<br />
{{Flink|monster|to_monster|int/strict_string}}<br />
{{Flink|phylum|to_phylum|string}}<br />
{{Flink|string|to_plural|item}}<br />
{{Flink|servant|to_servant|int/strict_string}}<br />
{{Flink|skill|to_skill|effect/int}}<br />
{{Flink|skill|to_skill|strict_string|{{opt|strict_string}}}}<br />
{{Flink|slot|to_slot|item/strict_string}}<br />
{{Flink|stat|to_stat|strict_string}}<br />
{{Flink|string|to_string|any}}<br />
{{Flink|thrall|to_thrall|int/strict_string}}<br />
{{Flink|string|to_upper_case|string}}<br />
{{Flink|string|to_url|location}}<br />
{{Flink|vykea|to_vykea|strict_string}}<br />
{{Flink|string|today_to_string}}<br />
{{Flink|int|total_free_rests}}<br />
{{Flink|int|total_turns_played}}<br />
{{Flink|boolean|tower_door}}<br />
{{Flink|void|traceprint|string}}<br />
{{Flink|int|truncate|float}}<br />
{{Flink|int|turns_per_cast|skill}}<br />
{{Flink|int|turns_played}}<br />
{{Flink|buffer|twiddle}}<br />
<br />
===u===<br />
{{Flink|item|unusual_construct_disc}}<br />
{{Flink|void|update_candy_prices}}<br />
{{Flink|string|url_decode|string}}<br />
{{Flink|string|url_encode|string}}<br />
{{Flink|boolean|use|int|item}}<br />
{{Flink|boolean|use|item|{{opt|int}}}}<br />
{{Flink|boolean|use_familiar|familiar}}<br />
{{Flink|boolean|use_servant|servant}}<br />
{{Flink|boolean|use_skill|int|skill|{{opt|string}}}}<br />
{{Flink|boolean|use_skill|skill|int|{{opt|string}}}}<br />
{{Flink|buffer|use_skill|skill}}<br />
{{Flink|boolean|user_confirm|string}}<br />
{{Flink|boolean|user_confirm|string|int|boolean}}<br />
<br />
===v===<br />
{{Flink|boolean|visit|coinmaster}}<br />
{{FunctionEmbed|visit_url}}<br />
{{Flink|boolean [string]|voting_booth_initiatives|class|int|int}}<br />
{{Flink|boolean [string]|voting_booth_initiatives|int|int|int}}<br />
<br />
===w===<br />
{{Flink|void|wait|int}}<br />
{{Flink|void|waitq|int}}<br />
{{Flink|int|weapon_hands|item}}<br />
{{Flink|stat|weapon_type|item}}<br />
{{Flink|int|weight_adjustment}}<br />
{{Flink|boolean|white_citadel_available}}<br />
{{Flink|boolean [string]|who_clan}}<br />
{{Flink|boolean|will_usually_dodge}}<br />
{{Flink|boolean|will_usually_miss}}<br />
{{Flink|void|write|string}}<br />
{{Flink|void|writeln|string}}<br />
<br />
===x===<br />
{{Flink|string[int]|xpath|string|string}}<br />
<br />
[[Category:Scripting]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Eat&diff=9059Eat2021-07-13T14:16:37Z<p>Philmasterplus: Rewrite page to use Template:Function2. Also add info on clear_food_helper().</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=eat<br />
|function1.return_type=boolean<br />
|function1.description=Attempts to eat the {{pspan|food}} item(s).<br />
|function1.param1=food<br />
|function1.param1.type=item<br />
|function1.param1.description=Item to eat<br />
|function1.param2=qty<br />
|function1.param2.type=int<br />
|function1.param2.description=Amount to eat<br />
|function1.param2.optional=yes<br />
|function1.param2.default=1<br />
|function2.return_type=boolean<br />
|function2.description=Attempts to eat {{pspan|qty}} of {{pspan|item}}.<br />
|function2.param1=qty<br />
|function2.param1.type=int<br />
|function2.param1.description=Amount to eat<br />
|function2.param2=food<br />
|function2.param2.type=item<br />
|function2.param2.description=Item to eat<br />
|description=<p>Attempts to eat {{pspan|qty}} amount of the {{pspan|food}} item. Returns <code>true</code> for edible items and <code>false</code> for items that are not. (The return value does not reflect whether or not the items were actually consumed.)</p><br />
<br />
<p>You can also "eat" food helper items (e.g. {{kolwiki|Ol' Scratch's salad fork}}) to queue them before eating the actual food item. Food helpers can be identified with {{f|item_type}}, which returns <code>"food helper"</code> for such items. To cancel all queued food helpers, call {{f|clear_food_helper}}.</p><br />
<br />
<p>If you can use {{kolwiki|milk of magnesium}} but haven't used one yet, this command will show a warning dialog.</p><br />
|code1={{CodeSample|<br />
title=Code Sample|<br />
description=Eats as many olive lo meins as possible.|<br />
code={{{!}} class="wikitable" style="margin: auto"<br />
! ASH !! JavaScript<br />
{{!}}-<br />
{{!}}<br />
<syntaxhighlight lang="d" line highlight="2"><br />
int amount = (fullness_limit() - my_fullness()) / 3;<br />
eat(amount, $item[olive lo mein]);<br />
</syntaxhighlight><br />
{{!}}<br />
<syntaxhighlight lang="javascript" line highlight="4"><br />
const { eat, fullnessLimit, myFullness } = require("kolmafia");<br />
<br />
const amount = Math.floor((fullnessLimit() - myFullness()) / 4);<br />
drink(amount, Item.get('olive lo mein'));<br />
</syntaxhighlight><br />
{{!}}}<br />
}}<br />
|cli_equiv=The CLI command <code>eat</code> works similarly.<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Drink&diff=9058Drink2021-07-13T14:11:17Z<p>Philmasterplus: Add missing parameter type information</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=drink<br />
|function1.return_type=boolean<br />
|function1.description=Attempts to drink the {{pspan|booze}} item(s).<br />
|function1.param1=booze<br />
|function1.param1.type=item<br />
|function1.param1.description=Item to drink<br />
|function1.param2=qty<br />
|function1.param2.type=int<br />
|function1.param2.description=Amount to drink<br />
|function1.param2.optional=yes<br />
|function1.param2.default=1<br />
|function2.return_type=boolean<br />
|function2.description=Attempts to drink {{pspan|qty}} of {{pspan|booze}}.<br />
|function2.param1=qty<br />
|function2.param1.type=int<br />
|function2.param1.description=Amount to drink<br />
|function2.param2=booze<br />
|function2.param2.type=item<br />
|function2.param2.description=Item to drink<br />
|description=<p>Attempts to drink {{pspan|qty}} amount of the {{pspan|booze}} item. Returns <code>true</code> for drinkable items and <code>false</code> for items that are not. (The return value does not reflect whether or not the items were actually consumed.)</p><br />
<br />
<p>You can also "drink" drink helper items (e.g. {{kolwiki|divine champagne flute}}) to queue them before drinking the actual booze item. Drink helpers can be identified with {{f|item_type}}, which returns <code>"drink helper"</code> for such items. To cancel all queued drink helpers, call {{f|clear_booze_helper}}.</p><br />
<br />
<p>If this command will cause you to overdrink, KoLmafia will show a warning dialog. Using this command without Ode to Booze active will also show a warning, if you have the skill and the MP required to cast it.</p><br />
|code1={{CodeSample|<br />
title=Code Sample|<br />
description=Drinks as many tangaritas as possible without getting drunk.|<br />
code={{{!}} class="wikitable" style="margin: auto"<br />
! ASH !! JavaScript<br />
{{!}}-<br />
{{!}}<br />
<syntaxhighlight lang="d" line highlight="2"><br />
int amount = floor((inebriety_limit() - my_inebriety()) / 4);<br />
drink(amount, $item[tangarita]);<br />
</syntaxhighlight><br />
{{!}}<br />
<syntaxhighlight lang="javascript" line highlight="4"><br />
const { drink, inebrietyLimit, myInebriety } = require("kolmafia");<br />
<br />
const amount = Math.floor((inebrietyLimit() - myInebriety()) / 4);<br />
drink(amount, Item.get('tangarita'));<br />
</syntaxhighlight><br />
{{!}}}<br />
}}<br />
|cli_equiv=The CLI command <code>drink</code> works similarly.<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Template:Function2&diff=9057Template:Function22021-07-13T14:10:19Z<p>Philmasterplus: Add missing description for function1.param1.type</p>
<hr />
<div><includeonly>{{TOCright}}{{DISPLAYTITLE:{{{name}}}}}{{#if: {{{needscode|}}}|{{CodeRequest}}}}{{#if: {{{improvecode|}}}|{{CodeRequest|better=yes}}}}<br />
{{#if: {{{name|}}}||{{error|Parameter 'name' is missing for User:Philmasterplus/TemplateSandbox2}}}}<br />
<h2>Function Syntax</h2><br />
{{#if: {{{function1.return_type|}}}<br />
|<p>{{FunctionDeclaration|name={{{name}}}|func=1|desc=yes|param_desc=yes}}</p>}}<br />
{{#if: {{{function2.return_type|}}}<br />
|<p>{{FunctionDeclaration|name={{{name}}}|func=2|desc=yes|param_desc=yes}}</p>}}<br />
{{#if: {{{function3.return_type|}}}<br />
|<p>{{FunctionDeclaration|name={{{name}}}|func=3|desc=yes|param_desc=yes}}</p>}}<br />
{{#if: {{{function4.return_type|}}}<br />
|<p>{{FunctionDeclaration|name={{{name}}}|func=4|desc=yes|param_desc=yes}}</p>}}<br />
{{#if: {{{function5.return_type|}}}<br />
|<p>{{FunctionDeclaration|name={{{name}}}|func=5|desc=yes|param_desc=yes}}</p>}}<br />
{{{description}}}<br />
{{#if: {{{code1|}}}|{{{code1}}}}}{{#if: {{{code2|}}}|{{{code2}}}}}{{#if: {{{code3|}}}|{{{code3}}}}}{{#if: {{{code4|}}}|{{{code4}}}}}{{#if: {{{code5|}}}|{{{code5}}}}}<br />
{{#if: {{{cli_equiv|}}}|<br />
<h2>CLI Equivalent</h2><br />
{{{cli_equiv}}}}}<br />
{{#if: {{{see_also|}}}|{{{see_also|}}}}}<br />
{{#if: {{{more_info|}}}|<br />
<h2>More Information</h2><br />
{{{more_info}}}}}<br />
{{#if: {{{special|}}}|<br />
<h2>Special</h2><br />
{{{special}}}}}<br />
[[Category:Ash Functions]]<br />
</includeonly><noinclude><br />
<templatedata><br />
{<br />
"description": "Replacement for Template:FunctionPage. Must be used with data-driven function pages.",<br />
"params": {<br />
"name": {<br />
"label": "ASH function name",<br />
"description": "Name of the ASH function. This should match the function page name.",<br />
"required": true,<br />
"type": "line",<br />
"example": "visit_url"<br />
},<br />
"description": {<br />
"label": "Description",<br />
"description": "Long description that covers all functions. Note: Use <p></p> to separate paragraphs, because double line breaks don't work",<br />
"required": true,<br />
"type": "content"<br />
},<br />
"function1.description": {<br />
"label": "Function 1, description",<br />
"description": "Short description for the overloaded function 1 (and so on for functions 2 through 3)",<br />
"required": true,<br />
"type": "content",<br />
"example": "Visits a web page and returns its HTML source."<br />
},<br />
"function1.return_type": {<br />
"label": "Function 1, return type",<br />
"description": "Return type of the overloaded function 1.",<br />
"required": true,<br />
"type": "line",<br />
"example": "buffer"<br />
},<br />
"function1.param1": {<br />
"label": "Function 1, parameter 1",<br />
"description": "Name of the parameter 1 of the overloaded function 1 (and so on for parameters 2 through 5).",<br />
"type": "line",<br />
"example": "url"<br />
},<br />
"function1.param1.type": {<br />
"label": "Function 1, parameter 1 type",<br />
"description": "Data type of the parameter 1 of the overloaded function 1.",<br />
"type": "line",<br />
"example": "int"<br />
},<br />
"function1.param1.description": {<br />
"label": "Function 1, parameter 1 description",<br />
"description": "Description of parameter 1 of the overloaded function 1.",<br />
"type": "content",<br />
"example": "URL of the page to visit. If a relative URL is provided, it is treated as an in-game page."<br />
},<br />
"function1.param1.optional": {<br />
"label": "Function 1, parameter 1 is optional?",<br />
"description": "\"yes\" = optional. Any non-empty string will do, but please use \"yes\" to make standardization easier.",<br />
"type": "line",<br />
"example": "yes"<br />
},<br />
"function1.param1.default": {<br />
"label": "Function 1, parameter 1 default value",<br />
"description": "If this is specified, function1.param1.optional must be \"yes\"",<br />
"type": "line",<br />
"example": "\"\""<br />
},<br />
"code1": {<br />
"label": "Example code 1",<br />
"description": "Example code showing how to use this function. Use [[Template:CodeSample]] to create sample code. (Same for code2 through code5)",<br />
"type": "content"<br />
},<br />
"cli_equiv": {<br />
"label": "Equivalent gCLI command",<br />
"description": "If provided, must be a gCLI command that provides functionality equivalent to this function.",<br />
"type": "line"<br />
},<br />
"see_also": {<br />
"label": "See Also section",<br />
"description": "If provided, this is used as the content for the See Also section. Use [[Template:SeeAlso]] to build a See Also section.",<br />
"type": "content"<br />
},<br />
"more_info": {<br />
"label": "More Information section",<br />
"description": "If provided, this is used as the content for the More Information section",<br />
"type": "content"<br />
},<br />
"special": {<br />
"label": "Special section",<br />
"description": "If provided, this is used as the content for the Special section",<br />
"type": "content"<br />
},<br />
"needscode": {<br />
"label": "Needs code samples?",<br />
"description": "If set to \"yes\", adds a \"needs code samples\" banner and categorizes the page under [[Category:Needs Code Sample]].",<br />
"type": "line"<br />
},<br />
"improvecode": {<br />
"label": "Needs improved code samples?",<br />
"description": "If set to \"yes\", adds a \"needs better code samples\" banner and categorizes the page under [[Category:Needs Code Sample]].",<br />
"type": "line"<br />
}<br />
}<br />
}<br />
</templatedata><br />
<br />
==Notes==<br />
This template is not meant to be used directly, but rather through the use of <pre>{{{format|Function2}}}</pre> in a data-driven function page.<br />
<br />
Use this as the starting point for a data-driven function page:<br />
<br />
<pre><br />
&lt;onlyinclude&gt;{{{{{format|Function2}}}<br />
|name=<br />
|function1.return_type=<br />
|function1.description=<br />
|function1.param1=<br />
|function1.param1.type=<br />
|function1.param1.optional=<br />
|function1.param1.default=<br />
|function1.param1.description=<br />
|function1.param2=<br />
|function1.param2.type=<br />
|function1.param2.optional=<br />
|function1.param2.default=<br />
|function1.param2.description=<br />
|function1.param3=<br />
|function1.param3.type=<br />
|function1.param3.optional=<br />
|function1.param3.default=<br />
|function1.param3.description=<br />
|function1.param4=<br />
|function1.param4.type=<br />
|function1.param4.optional=<br />
|function1.param4.default=<br />
|function1.param4.description=<br />
|function1.param5=<br />
|function1.param5.type=<br />
|function1.param5.optional=<br />
|function1.param5.default=<br />
|function1.param5.description=<br />
|function2.return_type=<br />
|function2.description=<br />
|function2.param1=<br />
|function2.param1.type=<br />
|function2.param1.optional=<br />
|function2.param1.default=<br />
|function2.param1.description=<br />
|function2.param2=<br />
|function2.param2.type=<br />
|function2.param2.optional=<br />
|function2.param2.default=<br />
|function2.param2.description=<br />
|function2.param3=<br />
|function2.param3.type=<br />
|function2.param3.optional=<br />
|function2.param3.default=<br />
|function2.param3.description=<br />
|function2.param4=<br />
|function2.param4.type=<br />
|function2.param4.optional=<br />
|function2.param4.default=<br />
|function2.param4.description=<br />
|function2.param5=<br />
|function2.param5.type=<br />
|function2.param5.optional=<br />
|function2.param5.default=<br />
|function2.param5.description=<br />
|function3.return_type=<br />
|function3.description=<br />
|function3.param1=<br />
|function3.param1.type=<br />
|function3.param1.optional=<br />
|function3.param1.default=<br />
|function3.param1.description=<br />
|function3.param2=<br />
|function3.param2.type=<br />
|function3.param2.optional=<br />
|function3.param2.default=<br />
|function3.param2.description=<br />
|function3.param3=<br />
|function3.param3.type=<br />
|function3.param3.optional=<br />
|function3.param3.default=<br />
|function3.param3.description=<br />
|function3.param4=<br />
|function3.param4.type=<br />
|function3.param4.optional=<br />
|function3.param4.default=<br />
|function3.param4.description=<br />
|function3.param5=<br />
|function3.param5.type=<br />
|function3.param5.optional=<br />
|function3.param5.default=<br />
|function3.param5.description=<br />
|function4.return_type=<br />
|function4.description=<br />
|function4.param1=<br />
|function4.param1.type=<br />
|function4.param1.optional=<br />
|function4.param1.default=<br />
|function4.param1.description=<br />
|function4.param2=<br />
|function4.param2.type=<br />
|function4.param2.optional=<br />
|function4.param2.default=<br />
|function4.param2.description=<br />
|function4.param3=<br />
|function4.param3.type=<br />
|function4.param3.optional=<br />
|function4.param3.default=<br />
|function4.param3.description=<br />
|function4.param4=<br />
|function4.param4.type=<br />
|function4.param4.optional=<br />
|function4.param4.default=<br />
|function4.param4.description=<br />
|function4.param5=<br />
|function4.param5.type=<br />
|function4.param5.optional=<br />
|function4.param5.default=<br />
|function4.param5.description=<br />
|function5.return_type=<br />
|function5.description=<br />
|function5.param1=<br />
|function5.param1.type=<br />
|function5.param1.optional=<br />
|function5.param1.default=<br />
|function5.param1.description=<br />
|function5.param2=<br />
|function5.param2.type=<br />
|function5.param2.optional=<br />
|function5.param2.default=<br />
|function5.param2.description=<br />
|function5.param3=<br />
|function5.param3.type=<br />
|function5.param3.optional=<br />
|function5.param3.default=<br />
|function5.param3.description=<br />
|function5.param4=<br />
|function5.param4.type=<br />
|function5.param4.optional=<br />
|function5.param4.default=<br />
|function5.param4.description=<br />
|function5.param5=<br />
|function5.param5.type=<br />
|function5.param5.optional=<br />
|function5.param5.default=<br />
|function5.param5.description=<br />
|description=<br />
|code1={{CodeSample<br />
|title=Code Samples<br />
|description=<br />
|code=<br />
|moreinfo=<br />
}}<br />
|code2={{CodeSample<br />
|description=<br />
|code=<br />
|moreinfo=<br />
}}<br />
|code3={{CodeSample<br />
|description=<br />
|code=<br />
|moreinfo=<br />
}}<br />
|code4={{CodeSample<br />
|description=<br />
|code=<br />
|moreinfo=<br />
}}<br />
|code5={{CodeSample<br />
|description=<br />
|code=<br />
|moreinfo=<br />
}}<br />
|see_also={{SeeAlso|}}<br />
|cli_equiv=<br />
|more_info=<br />
|special=<br />
|{{{1|}}}<br />
}}&lt;/onlyinclude&gt;<br />
&lt;!-- Add an appropriate function subcategory here, e.g. [[Category:Adventuring]],<br />
then delete this comment --&gt;<br />
</pre><br />
<br />
Data-driven function pages are incompatible with old-style function pages (i.e. ones that use [[Template:FunctionPage]]).<br />
<br />
[[Category:Basic Templates]]<br />
</noinclude></div>Philmasterplushttps://wiki.kolmafia.us/index.php?title=Drink&diff=9056Drink2021-07-13T14:06:30Z<p>Philmasterplus: Fix template error</p>
<hr />
<div><onlyinclude>{{{{{format|Function2}}}<br />
|name=drink<br />
|function1.return_type=boolean<br />
|function1.description=Attempts to drink the {{pspan|booze}} item(s).<br />
|function1.param1=booze<br />
|function1.param1.description=Item to drink<br />
|function1.param2=qty<br />
|function1.param2.description=Amount to drink<br />
|function1.param2.optional=yes<br />
|function1.param2.default=1<br />
|function2.return_type=boolean<br />
|function2.description=Attempts to drink {{pspan|qty}} of {{pspan|booze}}.<br />
|function2.param1=qty<br />
|function2.param1.description=Amount to drink<br />
|function2.param2=booze<br />
|function2.param2.description=Item to drink<br />
|description=<p>Attempts to drink {{pspan|qty}} amount of the {{pspan|booze}} item. Returns <code>true</code> for drinkable items and <code>false</code> for items that are not. (The return value does not reflect whether or not the items were actually consumed.)</p><br />
<br />
<p>You can also "drink" drink helper items (e.g. {{kolwiki|divine champagne flute}}) to queue them before drinking the actual booze item. Drink helpers can be identified with {{f|item_type}}, which returns <code>"drink helper"</code> for such items. To cancel all queued drink helpers, call {{f|clear_booze_helper}}.</p><br />
<br />
<p>If this command will cause you to overdrink, KoLmafia will show a warning dialog. Using this command without Ode to Booze active will also show a warning, if you have the skill and the MP required to cast it.</p><br />
|code1={{CodeSample|<br />
title=Code Sample|<br />
description=Drinks as many tangaritas as possible without getting drunk.|<br />
code={{{!}} class="wikitable" style="margin: auto"<br />
! ASH !! JavaScript<br />
{{!}}-<br />
{{!}}<br />
<syntaxhighlight lang="d" line highlight="2"><br />
int amount = floor((inebriety_limit() - my_inebriety()) / 4);<br />
drink(amount, $item[tangarita]);<br />
</syntaxhighlight><br />
{{!}}<br />
<syntaxhighlight lang="javascript" line highlight="4"><br />
const { drink, inebrietyLimit, myInebriety } = require("kolmafia");<br />
<br />
const amount = Math.floor((inebrietyLimit() - myInebriety()) / 4);<br />
drink(amount, Item.get('tangarita'));<br />
</syntaxhighlight><br />
{{!}}}<br />
}}<br />
|cli_equiv=The CLI command <code>drink</code> works similarly.<br />
}}<br />
</onlyinclude><br />
[[Category:Item Management]]</div>Philmasterplus